If the grab window is destroyed the grab will be implicitly removed,
although we won't get GdkSeat:ungrab called in order to clear our
internal window<->seat relation entirely. Setting a weak ref will
nullify the pointer we keep on the seat to the window, avoiding the
expected crashes.
Due to implicit grabs, we basically can guarantee that the pointer
won't have any buttons pressed at the time of wl_pointer.enter.
Seems like a good place to unset any button modifiers that might
have been left stale by compositor grabs.
And use it to handle kinetic scrolling in the GtkScrolledWindow.
However, dropping the delta check causes the X11-based kinetic
scroll to break since we don't have the stop event here. Correct handling of
xf86-input-libinput-based scroll events is still being discussed.
https://bugzilla.gnome.org/show_bug.cgi?id=756729
This adds support for the new wl_pointer events available in v5.
The wl_pointer.axis_source events can be ignored for the purposes here, the
main reason they exist is so that the combination of axis_source=finger and
axis_stop triggers kinetic scrolling. We don't need to care about the source,
axis_stop is enough for us to tell us when we're scrolling.
The wl_pointer.frame events group events together and is intended as a
mechanism to coalesce events together. This for example allows us to now
send a single GTK scroll event for a diagonal scroll. Previously, the two
wl_pointer.axis events had to be handled separately.
The wl_pointer.axis_discrete event sends mouse wheel clicks where
appropriate, and is translated into up/down/left/right scroll events.
https://bugzilla.gnome.org/show_bug.cgi?id=756729
When a cursor is specified in gdk_seat_grab(), the cursor is reverted as
soon as the pointer enters or leaves another window.
To avoid this issue, store the grab cursor separately, so we force-apply
it in ::set_window_cursor(). Also, unset early the seat info from the
window on gdk_seat_ungrab(), so the next time switch_to_pointer_grab()
happens we end up picking the cursor set for the window underneath the
pointer window.
Based on a patch by Olivier Fourdan <ofourdan@redhat.com>.
https://bugzilla.gnome.org/show_bug.cgi?id=760213
We no longer need a grabbed seat, instead we'll just use the default
seat if this happens, not without first warning and recommending
gdk_seat_grab() for the operation.
https://bugzilla.gnome.org/show_bug.cgi?id=759309
This allows GDK to unset the grab itself. Also, make sure we unset
the "pointer emulating" touch on the device if this is the
pointer emulating sequence.
https://bugzilla.gnome.org/show_bug.cgi?id=759309
GdkWaylandDeviceData conceptually gathers the data that belongs to
a seat, so it's been renamed (although the old typedef stays, plenty
of refactoring is due here...).
The methods in GdkSeatClass have also been implemented, the most
remarkable is ::grab, which ensures the grab is performed on all
the relevant "master" devices.
https://bugzilla.gnome.org/show_bug.cgi?id=759309
Instead of having our own copy of the pointer gestures XML file, use
the one installed by wayland-protocols.
Since pointer gestures is an unstable protocol, it went through the
unstable protocol naming convention changes, which is reflected in this
commit.
https://bugzilla.gnome.org/show_bug.cgi?id=758634
After the grab is finished, we would expect an enter event, and
GDK updating internally the cursor for that window and device.
This means there is no need at all to store it separately in the
backend.
As a side effect, animated cursors are now also possible on grab
icons.
https://bugzilla.gnome.org/show_bug.cgi?id=735847
If the buffer of a cursor is NULL, for example if its an empty cursor,
just set the cursor surface to NULL as well. Not doing this we'll use
uninitialized hotspot coordinates, dimensions and scales.
https://bugzilla.gnome.org/show_bug.cgi?id=758025
This GdkDragContext should be created even if we don't have pointer
capabilities. Make it created on add_seat(), and only set the device
on wl_seat.capabilities, so it can be set to either master pointer.
https://bugzilla.gnome.org/show_bug.cgi?id=741066
Now that we have multiple master pointers, this call may pick the wrong one.
Instead, pick the GdkWaylandDeviceData from the first device, and pick the
master pointer from there.
The common GDK code accounts for "pointer emulating" touch sequences to be
synchronized with the pointer position by the windowing system.
However on Wayland pointer and touch are completely independent, the backend
attempts to implement pointer emulation, but doesn't account for the
possible crossing events happening when the user switches from pointer to
touch or the opposite.
In order to fix this, and to ensure we don't have to interact with the
master pointer (which backs the wl_pointer), separate the touch interface
to have its own master pointer, and ensure crossing events are emitted on
it, so the picture of an "emulated pointer" is complete above the backend.
Inspired in a former patch by Jonny Lamb <jonnylamb@gnome.org>
https://bugzilla.gnome.org/show_bug.cgi?id=750845
We were using that range for the extra buttons after left/right/middle,
while this is harmless for clients not handling extra buttons (we
used to translate those button events into scroll events in x11 anyway)
this will be unexpected for clients that do handle additional mouse
buttons themselves (eg. back/forward buttons present in some mice).
In order to remain compatible with X11, those need to be assigned from
button 8 onwards.
Also, include input.h, and stop using magic numbers here.
https://bugzilla.gnome.org/show_bug.cgi?id=758072
GDK_NOTIFY_ANCESTOR would happen when the pointer crosses across a direct
parent/child. However nonlinear events are more likely, specially when
the pointer moves across toplevels (either different apps, or menus being
popped up over the pointer position).
This makes popping up comboboxes and other menus that fall over the pointer
position possible. With the previous detail the GtkMenu code misinterpreted
the crossing event, making it think the button release coming right after
should dismiss the popup, which made menus just flash on the screen unless
you kept the button pressed.
keyboard_handle_leave() might be called with a NULL surface resource
(for example if the surface was destroyed after the event was sent). If
so, we should still deal with the keyboard focus lost event, otherwise
we will both leak (the keyboard_focus GdkWindow reference) and miss
stopping the key repeat timer.
https://bugzilla.gnome.org/show_bug.cgi?id=755927
gdk_wayland_device_update_window_cursor() is inconsistently returning
TRUE/FALSE, despite the timeout being always replaced for new cursor
frames. This could end up in these timeouts being "leaked" and running
as long as the window has an animated cursor.
Fix this by making it really sure we return G_SOURCE_REMOVE, although
now we keep track of animation delays, so the timeout will be reused
for constant time animations.
When receiving a selection or when a drag icon enter a window, it was
targeted at a specific window. Lets emit the GDK_OWNER_CHANGE event
only for this window, instead of broadcasting.
Broadcasting has some nasty side effects. For example, if there was n
GdkWindows, and one would for every "owner-change" signal handler
receive n signals about the owner being changed.
An example of where this went a bit out of hand was gnome-terminal,
which added one listener per terminal window. This meant that if
one had m number of terminal windows, each time any one would loose or
gain keyboard focus, O(m^2) owner-change events would be emitted.
https://bugzilla.gnome.org/show_bug.cgi?id=754158
On wayland, the gestures protocol defines a wl_pointer_gestures global
object, that will match in number with wl_seats, swipe and pinch
interfaces can be obtained from it, which events are translated into
GdkEventTouchpadSwipe/Pinch events.
And force the ungrab on it, instead of the slave, in the case of
local DnD drop. This avoids confusions on the pointer events spawn
from DnD, as GDK doesn't think anymore those are from a slave device.
Most namely, it fixes the stuck grab when finishing DnD on the
same app it was started from.
We currently only hold the last offer received, which is wrong, as both
are independent and have different life cycles.
This means we have to store per-selection wl_data_offer and targets, and
maintain these as appropriate from the clipboard/DnD specific entry points.
On X11 this is something the windowing system does for us, which the
wayland backend should emulate, being grabs completely client-side.
So, if the grab and current focus windows differ, make sure we emit
focus/crossing events as it corresponds to the grab device.
This was being done so only on pointers. Internally, a GdkDeviceGrabInfo
is kept for each of the master pointer/keyboard, failing to do this for
keyboards results in a stuck keyboard grab.
https://bugzilla.gnome.org/show_bug.cgi?id=748892
On wl_keyboard.key/modifiers, we're just forgetting about currently
pressed mouse buttons. Fix this by storing button and key modifiers
separately, and put these together when creating the GdkEvents.
I was getting really weird values for scale for the blank cursor used
when hiding the cursor in a GtkEntry when typing, this was caused
by gdk_wayland_device_update_window_cursor sending random values
when the returned buffer was NULL.
We fix this by just not sending any buffer or scale updates in this
case.
During drag operations from another client, we currently set no window as
the DnD source. There's paths in upper layers though that rely on it being
set, just that we don't trigger these yet.
Support scaling of cursors created from themes. The default scale is
always 1, but if the pointer cursor surface enters an output with a
higher scale, load the larger version of the cursor theme and use the
image from that theme.
This assumes the theme size is set to one that fits with an output scale
= 1.
https://bugzilla.gnome.org/show_bug.cgi?id=746141
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