Right now we handle buffer releases coming from the
compositor in a central place. We add a listener when
first creating the shared buffers.
This is problematic because a buffer can only have
one listener on it at once so users of the buffer
can't get notified when it's released.
This commit moves the buffer listener code from the
centrally managed display code to the cursor and window
code.
https://bugzilla.gnome.org/show_bug.cgi?id=761312
The client and compositor share access to the window
pixel buffers. After the client hands off (commits)
the buffer to the compositor it's not supposed to write
to it again until it's released by the compositor.
The code tries to deal with this contention by allocating
a temporary buffer and using that in the mean time. This
temporary buffer is allocated by a higher layer of the code
when begin_paint returns TRUE. Unfortunately, that layer of
the code has no idea when the buffer is released, so it ends
up blitting the temporary buffer back to the shared buffer
prematurely.
This commit changes begin_paint to always return FALSE.
A future commit will address the contention problem in
a different way.
https://bugzilla.gnome.org/show_bug.cgi?id=761312
There are a few places where we destroy a cairo surface and
then nullify it. This commit changes those to use
g_clear_pointer instead.
It also drops a cairo_surface_finish call that is unnecessary
https://bugzilla.gnome.org/show_bug.cgi?id=761312
The name surface is really overloaded when dealing
with wayland windows.
To alleviate ambiguity, this commit changes the name
of the "surface" and "subsurface" members to have
a wl_ prefix.
https://bugzilla.gnome.org/show_bug.cgi?id=761312
Temp windows without parent are used frequently in our testsuite;
using g_warning on them causes the tests to fail, which is not
useful. Reduce the warning to a g_message.
It looks like the gnome-continuous headers haven't quite
caught up yet, so try __NR_memfd_create instead.
If that doesn't work, i'll likely just add in a fallback
code path.
The tmpdir is used for a wide assortment of things, and
can easily fill up. If it fills then desktop will start
crashing with SIGBUS errors.
This commit changes the shm pool allocation code, to use
memfd_create, instead, so the shared memory files will
be anonymous and not associated with /tmp
https://bugzilla.gnome.org/show_bug.cgi?id=761095
create_shm_pool doesn't need the width or height, it just needs
the total size. By passing it in, we're requiring it to redo
stride calculation unnecessarily.
This commit drops the width and height parameters and makes the
function just take the total size directly.
https://bugzilla.gnome.org/show_bug.cgi?id=760897
Right now, we assume the stride for the image surface needs to
be 4 byte aligned. This is, in fact, true, but it's better to
ask cairo for the alignment requirement directly rather than
assume we know the alignment rules.
This commit changes the code to use cairo_format_stride_for_width
to calculate a suitable rowstride for pixman.
https://bugzilla.gnome.org/show_bug.cgi?id=760897
create_shm_pool unlinks the temporary file a little,
too late. It should be unlinked before ftruncate()
is called for two reasons:
1) if ftruncate fails, the file is currently not
getting cleaned up at all
2) in theory, if the file is public some other process
could muck with it
This commit just moves the unlink call a little higher
up.
https://bugzilla.gnome.org/show_bug.cgi?id=760897
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 destroy the widget that is wrapped around the drag window
when the object data on the drag context gets cleared. Destroying
the window before that happens leads to unpleasantries. E.g. we may
try to access the frame clock, which doesn't exist anymore, and
things go downhill from there. So, keep the window alive for
a little longer.
X11 has the notions of "transient for group", and while it's an ICCCM
violation, it's commonly used and documented that a window manager
would treat a window with transient_for set to None to transient for all
windows of its group.
gtk uses this when an application sets a dialog type window but does not
specify an explicit transient.
While this works on X11, there is no such thing as groups in Wayland and
the closest equivalent which is set_parent() in xdg-shell takes only one
parent. This is what is used for modal dialogs.
To get something similar in behavior to what is available on X11, a
solution is to update the parent() of the dialogs without transient when
the active surface changes.
Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=759161
Quite a few applications use GTK_WINDOW_POPUP to create various
temporary windows and place then on screen. That works fine on X11 but
on Wayland there is no global coordinate system for regular surfaces.
If the application is using a gdk temp window and set a parent with
gtk_window_transient_for(), the gdk wayland backend has all it needs to
create a subsurface that can be placed at will by the application.
Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=759738
Always returning a left_ptr if we can't find anything better
broke firefox application-specific fallback for missing cursors.
Keep that working by only doing the fallback for the CSS cursor
names, not for things like hashes.
https://bugzilla.gnome.org/show_bug.cgi?id=760141
In most places, we can do with the pointer/keyboard of the default seat
instead of the client pointer. We can also remove some code from
gdk_input_init() because we know for sure there's no floating devices to
care about here.
Gdk Wayland backend walks up the transient windows tree, but does not
check for cycles when doing so.
As a result, if two or more windows are transient to each other, the
Wayland gdk backend will enter an infinite loop.
While this is clearly a bug in the application, gtk+/gdk should be more
robust and handle such errors more gracefully.
To avoid looping infinitely at various point in the code, check for a
possible loop when setting the transient relationship and deny the
request to set a window transient for another if that would create a
loop.
Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=759299
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
On some systems, the gtk settings are not used properly for wayland.
Indeed, g_settings_schema_source_get_default is used, and as the docs says it,
"all lookups performed against the default source should probably be done
recursively.".
https://bugzilla.gnome.org/show_bug.cgi?id=759409
Add a variant of gdk_drag_begin that takes the start position
in addition to the device. All backend implementation have been
updated to accept (and ignore) the new arguments.
Subsequent commits will make use of the data in some backends.
In Wayland, the hotspot of a DND icon is set using the buffer offset in
wl_buffer.attach. To implement this, add a private API to cause the
next wl_surface.attach to offset the new buffer with a given offset.
Setting a DND icon hotspot sets this offset while also queuing a redraw
of the window to trigger the wl_surface.attach.
https://bugzilla.gnome.org/show_bug.cgi?id=759168
In Wayland, the hotspot of a DND icon is set using the buffer offset in
wl_buffer.attach. To implement this, add a private API to cause the
next wl_surface.attach to offset the new buffer with a given offset.
Setting a DND icon hotspot sets this offset while also queuing a redraw
of the window to trigger the wl_surface.attach.
https://bugzilla.gnome.org/show_bug.cgi?id=759168
gdk-wayland backend would not re-configure a surface when its size and
scale match the known size and scale.
But there might be a pending xdg_surface_configure() that would revert
this change so we should re-configure even if the currently known
size/scale match, otherwise we may end up with a wrong size after the
xdg_surface_configure() is received.
Bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=758901
If we "release" the button first, the drag will be eventually cancelled,
we must first signal GDK_DROP_FINISHED, and then release the button so
the success status prevails.
It doesn't make a lot of sense to have this stored as data offer data,
rather together with the source_targets array, which is what we're
poking here in the end.
https://bugzilla.gnome.org/show_bug.cgi?id=758713
Dissociate ownership from our maintenance of wl_data_source objects.
The only place where ownership must be updated together is
data_source.cancelled, for the other places GDK should take care of
setting up the right ownership, even if at a different order than
we'd expect here.
This fixes GTK+ apps on wayland being locally confused about the
current selection ownership. Because gtk_selection_add_targets()
results in a wl_data_source being created, and ownership being
updated right away, early callers of this will change the ownership
even if the widget it's being called on didn't explicitly request
the selection ownership yet.
https://bugzilla.gnome.org/show_bug.cgi?id=758660
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
Other backends take care of the cairo surface destruction in
GdkWindow::destroy. We must do the same here, or the cairo_surface
and its corresponding wl_buffer are left dangling.
https://bugzilla.gnome.org/show_bug.cgi?id=747295
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
We use the high-level gdk_device_get_window_at_position() to figure
out the window, although this one actually tries to find out the
current window under the device coordinates, which might well fall
outside the window, so NULL is returned in those cases.
Fix this by using the lower level _gdk_device_window_at_position()
that will return the toplevel without further lookups, so is more
desirable here.
https://bugzilla.gnome.org/show_bug.cgi?id=758250
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
Make sure the wayland backend sets a new geometry when the client
resizes itself, otherwise the compositor won't be notified and may
revert to the old size on state changes.
Thanks to Jasper St. Pierre <jstpierre@mecheye.net> who pointed out the
problem in gtk+.
bugzilla: https://bugzilla.gnome.org/show_bug.cgi?id=755051
If a GtkMenu (or something else that is mapped as a xdg_popup) tries to
use a subsurface window as a parent, it will be terminated by the
compositor due to protocol violation. So to avoid this, if a parent
window is not a xdg_popup or xdg_surface, i.e. a wl_subsurface, then
traverse up the transient parents until we find the right popup parent.
https://bugzilla.gnome.org/show_bug.cgi?id=756780
Tooltips tend to be placed on top of a parent surface with a given
relative coordinate, and without any input focus. So lets map them as
subsurfaces.
https://bugzilla.gnome.org/show_bug.cgi?id=756496
Restructure the mapping procedure so that its known up front what the
expected way mapping is to be done (subsurface, popup or stand alone),
and warn if it fails to actually map in such a way (for example a popup
without a parent or device grab, a tooltip without a parent).
https://bugzilla.gnome.org/show_bug.cgi?id=756496
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.
If the shared context is in legacy mode, or if the creation of a core
profile context failed, we fall back to an EGL context in compatibility
mode.
Since we're relying on a fairly new EGL implementation for Wayland, we
don't fall back to the older EGL API, and instead we always require the
EGL_KHR_create_context extension.
https://bugzilla.gnome.org/show_bug.cgi?id=756142
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.
Initially the subsurface will be in synchronized mode and we will leave
it like this until the first time the parent surface has been committed.
The reason for this is because the subsurface position will be applied
as part of the parent surface state, and we need to synchronize the
initial position with the initial frame, so that we don't accidentally
draw the subsurface at the default position (0, 0) which would happen in
desynchronized mode if the subsurface content is committed before the
next parent surface commit.
https://bugzilla.gnome.org/show_bug.cgi?id=754839
If we are using gl for drawing, we don't have a shm surface,
so don't assert that we do. Instead, only call shm-specific
apis when they make sense.
This fixes a crash when showing popovers over a GtkGLArea,
as seen in gdkgears.
https://bugzilla.gnome.org/show_bug.cgi?id=754143
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
The code in _gdk_wayland_window_dispose was not safe against
being called twice - it would call g_hash_table_destroy twice
on the known_globals hash table, the second time operating on
freed memory. It was also leaking the list of async_roundtrips.
After fixing both of these issues, the displayclose testcase
now works on Wayland.
We call gdk_wayland_window_hide_surface when the window gets
destroyed, and in this case, the frame clock might not exist
anymore.
This was showing up in the displayclose testcase.
While we do not have subwindows in Wayland, we do create an
artificial root window. When the display is closed, the root
window gets destroyed, causing recursing to be true for the
toplevel windows.
As the protocol is still considered unstable (meaning not backward
compatible), we should, as stated in the protocol, only bind the version
advertised is the version we implement.
https://bugzilla.gnome.org/show_bug.cgi?id=753856
Prior to this patch, the ID of the GtkApplication was always used for
clients which were GtkApplications. This would only be guaranteed to be
correct for D-Bus activatable programs. As a result, all
non-D-Bus-activatable applications would set the wrong ID making the
shell unable to find the corresponding .desktop file.
This change makes it so that the GDK backend always uses the name
passed to g_set_prgname, or the default value if not explicitly set, as
this more often corresponds to the .desktop file.
This means that in order to make D-Bus activatable applications set the
correct application ID, they must, for now, manually call
g_set_prgname() with their application ID (basename of the .desktop
file).
If g_get_prgname() returns NULL, fallback to gdk_get_program_class()
even though it will most likely never be correct according to the
xdg_surface.set_app_id specification.
https://bugzilla.gnome.org/show_bug.cgi?id=746435
wl_log() currently logs using G_LOG_LEVEL_ERROR
(which is fatal). The wayland client library doesn't
expect this behavior. It uses wl_log to log recoverable
errors.
This commit changes the log level to G_LOG_LEVEL_DEBUG
instead.
https://bugzilla.gnome.org/show_bug.cgi?id=753635
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.
Only a drag context which was created with 'drag_begin' will be
guaranteed to have a source window at all times. Thus, in finalize we
cannot assume we can retrieve a GdkDisplay from the source_window
pointer since it may be NULL. Though, the display is only needed for
contexts created via 'drag_begin' thus we can retrieve it after
checking that is the case.
https://bugzilla.gnome.org/show_bug.cgi?id=749339
We need to be mapped to have a gtk_surface and thus be able to do
requests on it so we need to save the modal hint and apply it when we
get mapped so that code that sets the hint before showing a window
doesn't get ignored.
https://bugzilla.gnome.org/show_bug.cgi?id=753138