We need to use this in the code path where we make the context
non-current during destroy, because at that point the window
could be destroyed and gdk_window_get_display() would return
NULL.
This is not really needed. The gl context is totally tied to the
window it is created from by virtue of sharing the context with the
paint context of that window and that context always has the visual
of the window (which we already can get).
Also, all user visible contexts are essentially offscreen contexts, so
a visual doesn't make sense for them. They only use FBOs which have
whatever format that the users sets up.
To properly support multithreaded use we use a global GPrivate
to track the current context. Since we also don't need to track
the current context on the display we move gdk_display_destroy_gl_context
to GdkGLContext::discard.
wayland doesn't strictly follow the XDG_RUNTIME_DIR spec by falling back
to another directory in case the runtime dir is not properly set.
When this variable is unset, wayland will log an error to us, which we
treat as fatal, aborting the entire program.
Skip ourselves all the trouble and don't try to bring up the wayland
backend when we know it will fail in this way.
https://bugzilla.gnome.org/show_bug.cgi?id=738873
Its not really reasonable to handle failures to make_current, it
basically only happens if you pass invalid arguments to it, and
thats not something we trap on similar things on the X drawing side.
If GL is not supported that should be handled by the context creation
failing, and anything going wrong after that is essentially a critical
(or an async X error).
We make user facing gl contexts not attached to a surface if possible,
or attached to dummy surfaces. This means nothing can accidentally
read/write to the toplevel back buffer.
Currently writing wl_data_offer data into the fd is 1) synchronous, which
is noticeable when transferring large amounts of data, and 2) buggy, write()
error checking is done on the accumulator, breaking both the written data
accounting and error checking itself.
Fix both by making writes asynchonous through GOutputStream, the operation
is spun off and either finished, or cancelled if new data is stored in the
selection while the transfer is active.
The list of devices was being scanned over incorrectly, causing us to
never actually fetch the keymap from the keyboard, as the keyboard was
the second device in the list, not the first.
This causes us to create a new temporary keymap every time, which is
quite expensive, because it involves parsing the entire XKB
file. Scanning the list correctly will cause us to use the XKB rules
file that was passed to us.
A surface may be hidden when a frame is already scheduled, which may cause
crashes on on_frame_clock_after_paint() when calling commit() on a NULL
surface. To fix this, ensure commit_pending is also set to FALSE when the
surface is gone.
https://bugzilla.gnome.org/show_bug.cgi?id=735226
Only static cursors are supported in gdk_device_grab() so far. Obey the
cursor that gdk_device_grab() specifies, which may be different to
the pointer window one. As soon as the grab is gone, the pointer window
cursor will be restored as usual.
https://bugzilla.gnome.org/show_bug.cgi?id=735831
On DnD, pointer_handle_leave may be triggered without the pointer actually
leaving the window, and pointer_handle_enter() happening after intra-window
DnD won't actually manage to update the cursor (it does nothing directly,
and to the upper layers the cursor is still the same and consistent, so no
attempt will happen).
To fix this, keep the pointer cursor on leave, and ensure it is updated
on enter. The pointer cursor will be updated to any current new one through
the enter/motion events generated if it needs be.
https://bugzilla.gnome.org/show_bug.cgi?id=735831
cairo_surface_destroy() is called after the buffer is released, for every
wl_buffer. Windows usually reference their cairo surface before rendering,
so that extra reference is consumed after the buffer is released, so do
the same with cursor surfaces and add an extra reference whenever a cursor
surface change is about to be scheduled.
Otherwise, the GdkWaylandCursor is left with an invalid cairo_surface_t,
which causes crashes the next time it is used.
https://bugzilla.gnome.org/show_bug.cgi?id=735830
On wayland the DnD surface must be created early when starting the drag
operation, so offer API for GTK+ to get the GdkWindow used as a DnD
surface on the drag operation.
https://bugzilla.gnome.org/show_bug.cgi?id=697855
The wl_data_source is retrieved from the selection object for the DnD
selection, and used to initiate a drag. When the drag is finished, a
button release or touch end event is synthesized to finish the DnD
operation after the compositor grab is gone.
https://bugzilla.gnome.org/show_bug.cgi?id=697855
The wayland specific clipboard functions have been replaced by something
more similar to the hooking the win32 backend does, which allows for just
using the default GtkClipboard code in GTK+. As a consequence, the
wayland-specific GtkClipboard implementation is now gone.
https://bugzilla.gnome.org/show_bug.cgi?id=697855
This has been made to work similarly to X11, requests for the data device
contents are notified through GDK_SELECTION_REQUEST events, the data stored
in the GDK_SELECTION property as a reaction to that event is then stored
into the wayland selection implementation, and written to the fd when
requested/available.
https://bugzilla.gnome.org/show_bug.cgi?id=697855
This implementation makes the destination side of selections work
similarly to X11's, gdk_selection_convert() triggers data fetching,
which is notified through GDK_SELECTION_NOTIFY events on arrival,
the buffered data is then available through gdk_selection_property_get().
https://bugzilla.gnome.org/show_bug.cgi?id=697855
Subsurface position is deemed part of the state of the parent surface, so
ensure wl_surface_commit() happens on the parent surface if none is
scheduled, so the repositioning takes place.
The latest implicit grab serial is used in order to start the compositor
grab, If it belongs to a touch event, remove that touch sequence, as the
rest of the sequence will be gone for good.
This avoids stale sequences (and implicit grab info) after a window is
moved/resized.
https://bugzilla.gnome.org/show_bug.cgi?id=731380
_gdk_wayland_device_get_button_press_serial() has been replaced by
_gdk_wayland_device_get_implicit_grab_serial(), which takes a touch/pointer
event and figures out the relevant serial, and
_gdk_wayland_device_get_last_implicit_grab_serial() which returns
the most recent serial.
The button press serial was currently used when operating popping up
xdg_shell/surface popups and window menus, so this is now touch aware, of
some sort.
https://bugzilla.gnome.org/show_bug.cgi?id=734374
If the compositor sends a keymap that fails on "compilation",
xkb_keymap_new_from_string() returns NULL, which makes xkb_state_new()
crash when assuming there is a keymap.
In these cases, gdk must remain with a xkb_state to handle modifiers/keys
properly, so warn about the invalid keymap string, and keep the previous
keymap (currently initialized to "us")
https://bugzilla.gnome.org/show_bug.cgi?id=735389
To all effects each window has its own "root" coordinates system, so set
toplevels at 0,0 in that coordinate system, so root coordinate calculations
are locally right.
https://bugzilla.gnome.org/show_bug.cgi?id=729215
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.
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+.
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.
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.
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.
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
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.