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.
Wayland's mechanism tells us all of our new states, rather than
telling us which ones were added and removed. Add a new private
interface so that we can simply specify the new states as a
bitfield directly rather than having to compute which ones were
added and removed.
Rendering doesn't do much about clipping drawing operations to the window shape,
although invalidation applies the shape to every window, leaving possibly trails
of "overrendered" content. So ensure the shape portions get invalidated too when
the window is moved/resized.
https://bugzilla.gnome.org/show_bug.cgi?id=729095
It may happen that the received clipboard data is empty, but
if it's of type image/bmp, gtk+ will crash:
gdk_property_change: 00030AD4 GDK_SELECTION image/bmp REPLACE 8*0 bits:
... delayed rendering
gdk_selection_send_notify_for_display: 00030AD4 CLIPBOARD image/bmp
GDK_SELECTION (no-op)
_gdk_win32_selection_convert_to_dib: 1252003C image/bmp
Program received signal SIGSEGV, Segmentation fault.
0x749a9f40 in msvcrt!memmove () from C:\Windows\syswow64\msvcrt.dll
Thread 1 (Thread 2248.0x1b34):
target=0xc07b) at gdkselection-win32.c:1292
at gdkevents-win32.c:3498
wparam=8, lparam=0) at gdkevents-win32.c:232
message=773, wparam=8, lparam=0)
at gdkevents-win32.c:263
C:\Windows\syswow64\user32.dll
C:\Users\rugoosse\AppData\Local\virt-viewer\bin\libpangocairo-1.0-0.dll
wparam=0, lparam=-1687549457)
at gdkevents-win32.c:248
C:\Users\rugoosse\AppData\Local\virt-viewer\bin\libpangocairo-1.0-0.dll
https://bugzilla.gnome.org/show_bug.cgi?id=728745
The events are routed through a new slave device with type
GDK_SOURCE_TOUCHSCREEN, minimal tracking of touches is done
to keep the state for each of those.
https://bugzilla.gnome.org/show_bug.cgi?id=728426
The master pointer/keyboard pair should never disappear or be
inconsistent. The seat capabilities are now reflected through
slave devices, those may come and go freely as the seat
capabilities change. This also enables adding further capabilities
to handle eg. touch.
https://bugzilla.gnome.org/show_bug.cgi?id=728426
Get monitor on which the most of the window is located (nearest monitor if
window is not on screen), get its work area (area not occupied by taskbar or
any other bars) and use that for maxsize.
Previous default of 30000 meant that windows maximized onto full screen,
even covering the area where taskbar is.
https://bugzilla.gnome.org/show_bug.cgi?id=726592
...on Windows 8+ and when the system setting for non-Unicode programs do
not match the language version of Windows by falling back to using Pango.
This ensures that the correct font is used during these scenarios, so that
we minimize the risk of seeing garbled characters for texts that the system
code page does not support due to system peculiarties. There might be a
way to support gtk-font-name handling using the native Windows APIs
directly on Windows 8+, but that needs to be investigated.
https://bugzilla.gnome.org/show_bug.cgi?id=726298
The compositing that is meant here is really specific to the
X11 Composite extension, and does not apply to Wayland.
This is very rarely used functionality anyway, and none of
the other backends support it.
Theoretically, we apply the shape mask client-side ourselves
with an ARGB32 pixmap and intersect it to get a union shape,
but I don't particularly care enough to write that code.
Realistic application code using bounding shapes in 2014 is
quite rare.
It seems that some backends implemented get_root_origin wrong
and returned the client window coordinates, not the frame window
coordinates. Since it's possible to implement generically for all
windows, let's do that instead of having a separate impl vfunc.
Lots of code, including dragging code in GtkWindow, use these
fields. Setting them to 0 causes lots of strange and weird bugs.
Use the same "hack" from query_device_state of just using
win_x / win_y for now. We'll convert this to the proper fake root
coordinate system used by get_root_coords in the next commit.
And the counterpart to unmaximize when dragging a maximized window, if
touch devices aren't going to use EWMH moveresize, having this one at least
makes things feel a bit less awkward.
https://bugzilla.gnome.org/show_bug.cgi?id=709914
Sadly, EWMH moveresize mechanism can't work with touch devices for two
reasons:
1) As a mutter implementation detail, the device is queried in order
to check whether the dragging button is still pressed. Touch devices
won't report the button 1 being pressed through pointer emulation.
2) Even bypassing that check, on X11 touch events are selected prior
to sequences being started, either through XISelectEvents or
XIGrabTouchBegin, no late registering through active grabs is allowed,
as WMs do on reaction to EWMH moveresize messages.
So for the time being, make touch devices fallback on emulated window
dragging, which at least allows for moving windows.
https://bugzilla.gnome.org/show_bug.cgi?id=709914
Add gdk_device_get_last_event_window(), and use to implement the window
tracking we need for synthesizing crossing events for sensitivity changes
and gtk grabs, rather than keeping the information in qdata and updating
it based when GTK+ gets events.
https://bugzilla.gnome.org/show_bug.cgi?id=726187
eb1ab0dac2 removed support for authentication
based on crypt()-hashed passwords but it didn't remove the header.
Finish up with the removal.
This allows the broadway backend to build on FreeBSD (which has no
crypt.h).
https://bugzilla.gnome.org/show_bug.cgi?id=726149
window->x / window->y are in "root window coordinates", e.g. relative
to the topmost toplevel. However, the coordinates in get_xdg_popup are
relative to the passed-in surface, so we need to do the reverse
translation here.
We have a hack in the XSETTINGS code to substitute gtk-xft-dpi
with gdk-unscaled-dpi unless the screen has a fixed window scale,
in which case we just use gtk-xft-dpi.
But if the screen is changed to have a fixed window scale, then
the substituted value of gdk-unscaled-dpi will stick around until
the next (coincidental) change to XSETTINGS. To fix this, force
an immediate reread of the XSETTINGS property when
gdk_x11_display_set_window_scale() is used.
https://bugzilla.gnome.org/show_bug.cgi?id=725754
The point of GdkWindowImpl::get_root_coords is to translate the passed
in coordinates against the passed-in impl window. For a child window,
in fact, window->abs_x and window->abs_y already track the child
window's coordinates against the impl window.
If we pass in a child window, and backends don't explicitly get the impl
window from it, we'll double-count the child window.
Really, we should *always* be passing impl windows to backends, and
never child windows. However, I'm a bit worried for regressions late
in the cycle if we want to fix up the rest of the callers, like
gdk_window_get_geometry, so I'm only going to touch get_root_coords
for now after careful review of all the backends.
GtkWindow calls set_shadow_width then maps the window, meaning
that we never set the margin. Save it when we set and then set
it when we create the XDG surface.
Instead of destroying the surface in the backend if this is
unable to resize, let the core code do it, and do it properly.
Based on a patch by Benjamin Otte.
https://bugzilla.gnome.org/show_bug.cgi?id=725172
The code in GDK is incredibly broken and nobody is quite sure what's
right-side-up and what's upside down, but this breaks mutter-wayland
now, so let's remove it. It might leak, but we should probably do a
full restructuring of GDK drawing to fix it.
Like in other backends (except X) we can't resize cairo image surfaces
so let's sync the code here with what the other backends do.
This prevents the painting machinery above us to paint on the wrong
buffer.
https://bugzilla.gnome.org/show_bug.cgi?id=724968
We can't destroy buffers if they're in-use by the compositor. Well,
technically we can, but that is considered undefined by Wayland and
mutter won't cope with it very well -- it simply kills the client.
To solve this, we need to delay the destroy operation until the
compositor tells us that it's released the buffer. To do this, hold
an extra ref on the cairo surface as long as the surface is in-use
by the compositor.
This prevents warnings like
(gtk3-demo:14948): Gdk-CRITICAL **: _gdk_frame_clock_thaw: assertion 'GDK_IS_FRAME_CLOCK (clock)' failed
(gtk3-demo:14948): Gdk-CRITICAL **: gdk_frame_clock_get_timings: assertion 'GDK_IS_FRAME_CLOCK (frame_clock)' failed
We need to do this, as the compositor might have already sent us a frame
event, in-flight, at the same time we destroy our window. In this case, we'll
receive the then-in-flight "done" event, and then warn as we try to look
up the frame clock on a destroyed window.