Support environment variable GDK_WIN32_FONT_RESOLUTION that can be set to
a desired dpi (72, 96, 130, etc) to override system settings. Useful for
debugging, since changing system font scaling requires the user to log off
and log on again.
https://bugzilla.gnome.org/show_bug.cgi?id=734038
Use (cairo) input shape of the window to check whether a point is inside or not
inside the window.
If it is, let the default window procedure do its thing (which seems to be
working all right in all known cases).
If it isn't, override the default window procedure and tell WM what we think.
Don't do any of the above if the window has CSD-incompatible styles (WS_BORDER
or WS_THICKFRAME).
This is a crude kind of substitute for window input shape support (which W32
does not seem to have). Still probably enough to be positive about input shapes
support.
https://bugzilla.gnome.org/show_bug.cgi?id=733679
Delay the keyboard settings creation until we're delivering the key
press. This means we don't have to create the settings for a server that
sends us repeat information.
This function currently calls gdk_win32_window_shape_combine_region(),
which is wrong, because it leads to SetWindowRgn() being called with
non-NULL region, which makes W32 disable theming (particularly - decoration
theming), which makes decorations revert back to old GDI-drawn Windows 2000
variant, which looks out of place and interacts *badly* with alpha channel
(because GDI).
https://bugzilla.gnome.org/show_bug.cgi?id=733671
xdg-shell has moved on and replaced set_margin with set_window_geometry.
To properly support set_window_geometry requires a full rewrite of how
we've been dealing with toplevel windows for now, so just don't set any
margin until we can have a proper toplevel window abstraction in GTK+.
Some windows, like GtkWindow and some other apps, set a transparent
background. The guarantee for begin_paint_region is that there should
be a full clear to the specified background color, not a composite
against what was there before.
This fixes repaint artifacts in Wayland and Weston in a better way than
76922c169f.
gdk_x11_display_set_window_scale() affects the interpretation of the
Xft/DPI XSETTING - it is substituted inside GDK with the value of
Gdk/UnscaledDPI xsetting. However, this change is not propagated to
GTK+ and from GTK+ back to gdk_screen_set_resolution() until the
main loop is run.
Fix this by handling the screen resolution directly in gdk/x11.
This requires duplication of code between GDK and GTK+ since we still
have to handle DPI in GTK+ in the case that GdkSettings:gtk-xft-dpi
is set by the application.
https://bugzilla.gnome.org/show_bug.cgi?id=733076
The way that GtkTextView et al pop up their context menu is to first
query to see if the clipboard has some text, and if so, enable the Paste
menu item. But since the Wayland backend hasn't had the greatest
selection and clipboard code, the callback for the clipboard got dropped
on the floor.
Add some simple code to respond to the TARGETS selection.
This makes right-clicking on a GtkTextView work fine.
The resize grip code in GTK+ likes to call gdk_window_raise a lot. The
unfortunate side effect of gdk_window_raise is that it queues an
invalidation on the entire window, even if it's already the topmost
child.
Add a return value to gdk_window_raise_internal, and only queue the
invalidation if the raise had an effect.
Otherwise, a user that calls gdk_window_resize (window, 0, 0); over and
over won't properly fizzle out, and will queue a redraw. Clipped, but
still. These redraws can be chatty on some platforms like Wayland, and
there's no good reason to not avoid them.
This was the case for resize grips.
This reverts commit b875572f2a.
Apps like Abiword, gnumeric and gnome-chess, and toolkits like
ClutterGTK were all using this for various purposes, and this made them
break. Bring back this feature for now.
It still won't work under Wayland.
Apps had quite a bit of difficulty getting used to the new rules.
While we weren't expecting anything too deadly, it seemed that
gnumeric and Abiword both used gdk_cairo_create like this.
If a window both has an impl and its impl_window is of type offscreen,
that must mean that it is the offscreen window, and the impl window is
itself. We can reduce the indirection here and make it more clear.
Since the Win32 code never actually called InvalidateRgn or used the
Win32 update area at all, that meant the only thing that could possibly
invalidate the window was the Win32 window manager as part of scrolling
or resizing, which would also send it a WM_PAINT message.
But the WM_PAINT handling called BeginPaint / EndPaint, which clears the
update area completely! We also draw out-of-band, not directly when
handling WM_PAINT, so there's no way that the update area inside the
Win32 WM would match our local one.
There is no possible way that this queue_antiexpose implementation could
do anything. Remove it.
We removed the parameter from callers and from the implementation, but
not from the signature up top. I didn't notice because the branch I was
working on removed the signature entirely.
This code is only called with the current paint region as its argument.
Instead of having to copy it and do a no-op intersect against itself,
just use the current paint directly.
cairo_surface_create_for_rectangle takes a ref on the parent surface,
so we need to drop ours.
Rename get_window_surface to ref_window_surface to make the code more
clear and to stop this error from happening again.
Previously, each begin_paint_region added to a stack of current paints,
and when end_paint was called, the paint was popped off of the stack and
the surface was composited into the parent paint surface.
However, the code was broken in the case of a backend like Wayland which
didn't keep track of nested calls and simply wiped and returned the
native impl backing surface every time.
Since this feature is flat out unused by GTK+ and we don't want to
really support tricksy things like these for other clients, just remove
the feature. If somebody does call begin_paint_region more than once,
warn and return without doing anything.
Traditionally, the way painting was done in GTK+ was with the
"expose-event" handler, where you'd use GDK methods to do drawing on
your surface. In GTK+ 2.24, we added cairo support with gdk_cairo_create,
so you could paint your graphics with cairo.
Since then, we've added client-side windows, double buffering, the paint
clock, and various other enhancements, and the modern way to do drawing
is to connect to the "draw" signal on GtkWidget, which hands you a
cairo_t. To do double-buffering, the cairo_t we hand you is actually on
a secret surface, not the actual backing store of the window, and when
the draw handler completes we blit it into the main backing store
atomically.
The code to do this is with the APIs gdk_window_begin_paint_region,
which creates the temporary surface, and gdk_window_end_paint which
blits it back into the backing store. GTK+'s implementation of the
"draw" signal uses these APIs.
We've always sort-of supported people calling gdk_cairo_create
"outside" of a begin_paint / end_paint like old times, but then you're
not getting the benefit of double-buffering, and it's harder for GDK to
optimize.
Additionally, newer backends like Mir and Wayland can't actually support
this model, since they're based on double-buffering and swapping buffers
at various points in time. If we hand you a random cairo_t, we have no
idea when is a good time to swap.
Remove support for this.
This is technically a GDK API break: a warning is added in cases where
gdk_cairo_create is called outside of a paint cycle, and the returned
surface is a dummy that won't ever be composited back onto the main
surface. Testing with complex applications like Ardour didn't produce
any warnings.
gtk_widget_set_double_buffered is now deprecated, and we don't support
non-double-buffered widgets. This means that under normal circumstances,
paints are never outside of a begin_paint / end_paint sequence, which
natively-double-buffered backends like Wayland can't possibly support.
Weston releases buffers almost immediately after they're done, which
means that GTK+ doesn't use a temporary surface and instead paints
directly onto the SHM backing store that Weston will use.
Normally, after painting to the temporary surface, GTK+ *replaces*
the existing backing surface with CAIRO_OPERATOR_SOURCE. However,
if we immediately paint to the backing surface, it might have junk
from the last paint in it. So clear out the backing surface whenever
somebody calls begin_paint_region().
Maybe we should just always use the temporary surface like the X11
codepath, since that prevents us from having to do weird things like
this, but oh well.
wl_surfaces can't switch roles, so destroying the xdg_surface but not
the wl_surface means that we could get an error when trying to re-map
the surface.
We could fix this by not destroying the xdg resource and only do it at
finalization time, but it's just as easy to just create a new wl_surface.
Since the xdg roles are a special case of the surface, some compositors
like Weston destroy them automatically when the wl_surface is destroyed.
Thus, we need to destroy these first.
The Wayland compositor is completely allowed to send us configure
events for the same size, and this validly happens if we're changing
states. Fizzle these out.
Having the same, usable, default appearance acroll platforms
trumps having a more-or-less working native theme. The default
will be Adwaita on all platforms. The native ms-windows theme
is of course still available.
Weston numbers its touch sequences ids starting from 0, thus simply
setting the GtkEvents touch.sequence to the touch id value typically
causes gdk_event_get_event_sequence to return NULL. Unfortunately this
confuses other parts of GDK.
As both weston & mutter keep the sequence id between 0..max_dev_touches
-1 simply use + 1 to keep the id > 0. While this isn't entirely correct
(compositor could send -1 as the touch id), this keeps the touch id in
gtk tied to the touch id from weston which is useful for debugging. A
more thorough solution could be done when it turns out this is an issue
in practise
https://bugzilla.gnome.org/show_bug.cgi?id=731371
There are plans to add session-dependent defaults to GSettings
(based on the newly standardized XDG_CURRENT_DESKTOP); until
then, the WM uses a different schema for its button-layout
setting in classic mode. So for the time being, do the same
and pick the alternative schema when XDG_CURRENT_DESKTOP
indicates that we are in a classic session.
(It's not pretty, but hopefully won't be with us for too long ...)
https://bugzilla.gnome.org/show_bug.cgi?id=731273
Pick up the setting from the org.gnome.desktop.wm.preferences schema
if available. It is slightly more involved than other settings, as
the actual button names used in the schema differ from the ones we
use, so we need an additional translation step.
https://bugzilla.gnome.org/show_bug.cgi?id=731273
When the pointer cursor is updated on CSW, lookup for either a device
cursor, or a global one. It would previously lookup for windows with
a global cursor, and then check if it had a device cursor, which would
skip windows with only device cursors set, and unexpectedly set the
global cursor.
This avoids a bunch of policy problems with deciding how to lay
out the window menu under different WMs.
For now, we use the special event _GTK_SHOW_WINDOW_MENU, but we
hope to have this standardized in wm-spec quite soon, as KDE wants
it as well.
All the globals we care about should appear before doing anything
else, up-front, so a single round-trip after adding the registry
should be more than enough.
Since you can't take grabs on unmapped windows, GtkMenu takes a grab on
the menu in a convoluted way: it first grabs another window, shows the
menu window, and then transfers the grab over to the GtkMenu widget.
For normal menubars, this is perfectly fine, as the first window it grabs
is our toplevel, and that gets picked up in our transient path. For
GtkMenuButton or other spurious uses of gtk_menu_popup, it creates a new
temporary input-only window which it takes the grab on, known as the "grab
transfer window". Since this window isn't a transient-for of our new menu
widget window, the grab isn't noticed when we go to show it, and thus the
menu ends up as a new toplevel.
Add a special hack to GtkMenu and the Wayland backend which lets us notice
this "grab transfer window", and include it in our grab finding path.
It's sort of terrible to have to hack up the widgets instead of just the
backend, but the alternative would be an entirely new window type which is
managed correctly by GDK. I don't want to write that.