As far as possible, use per-display debug flags.
This will minimize the debug spew that we get from
the inspector if it is running on a separate display.
Instead, pass the source window to gdk_drag_begin().
Also make Wayland use this window instead of the one under the pointer
(though those 2 Windows are most likely the same anyway).
Without selections, drags can't have them either.
Also included is removing the selection from GtkSelectionData.
Includes a bunch of crude cleanups to Wayland code that no longer has to
care about selection atoms.
Instead of just passing the GdkContentFormats, we are now passing the
GdkContentProvider to gdk_drag_begin().
This means that GDK itself can now query the data from the provider
directly instead of having to send selection events.
Use this to provide the private API gdk_drag_context_write() that allows
backends to pass an output stream that this data will be written to.
Implement this as the mechanism for providing drag data on Wayland.
And to make this all work, implement a content provider named
GtkDragContent that is implemented by reverting to the old DND
drag-data-get machinery inside GTK, so for widgets everything works just
like before.
Instead, pass the actions as part of gdk_drag_begin() and insist DND is
always managed.
A new side effect is that gdk_drag_begin() can now return %NULL.
This is the replacement for selection usage.
Backend implementations for X11 (missing support for backwards compat
formats like COMPOUND_TEXT) and Wayland are included.
GTK code should be adapted to use gdk_drop_read_*() functions instead
of gtk_drag_get_data().
Make sure the API reflects the idea that GdkContentFormats is a set
containing mime types. In particular, treat the object itself as a
plural - it's named content format`S' after all - and therefor use
the correct verb form.
Also make GdkContentFormats keep an array instead of a list, now that
it's immutable.
Drop the screen argument from gdk_dnd_find_window_for_screen
and rename the function to gdk_dnd_find_window. The screen
argument does not add anything here since the drag context
is already tied to the display. Update all backends, and
update all callers.
This patch makes that work using 1 of 2 options:
1. Add all missing enums to the switch statement
or
2. Cast the switch argument to a uint to avoid having to do that (mostly
for GdkEventType).
I even found a bug while doing that: clearing a GtkImage with a surface
did not notify thae surface property.
The reason for enabling this flag even though it is tedious at times is
that it is very useful when adding values to an enum, because it makes
GTK immediately warn about all the switch statements where this enum is
relevant.
And I expect changes to enums to be frequent during the GTK4 development
cycle.
And with it, gtk_widget_get_visual() and gtk_widget_set_visual() are
gone.
We now always use the RGBA visual (if available) and otherwise fall back
to the system visual.
Always associate a drag context with a GdkDisplay and use that when
getting a cursor for a given action.
If we don't do this, dragging on a window that doesn't use the default
display will make us use cursors from the wrong display.
https://bugzilla.gnome.org/show_bug.cgi?id=765565
The naming of pointers to GdkWaylandDisplay's were inconsistent.
Running the following commands in gtk+/gdk/wayland illustrate the
inconsistency:
$ grep -r '\<display_wayland\>' *.[ch] | wc -l
195
$ grep -r '\<wayland_display\>' *.[ch] | wc -l
81
This patch renames all occurrences of "wayland_display" to
"display_wayland". This is also consistent with naming in the X11
backend. A couple of whitespace changes were done as well in places
where the rename was already done, that added line breaks to long lines
that stood out.
https://bugzilla.gnome.org/show_bug.cgi?id=765474
We were just relying on the drag context finalize() to destroy
the window. But with garbage-collected bindings, that might
not happen as soon as we like, so explicitly hide the window
when the drag ends successfully.
https://bugzilla.gnome.org/show_bug.cgi?id=763659
The way gdk_drag_status() may be called multiple times during the
processing of drag and drop events throughout the widget hierarchy
brings some superfluous messaging going in, esp. when it's the last
request the one we want to honor, yet we emit messaging requests on
all.
This is barely appreciable in the X11 backend, but due to the design
of the wayland protocol, quick series of changes like this it have
some self-amplificating consequences which may end up flooding the
connection.
We can delegate this to a late "commit" call, performed within GDK
event management. This way gdk_drag_status() calls may be cached
and only result in windowing messaging once per ::drag-motion or
::drag-data-received event. Emitting the final status will also
avoid spurious action changes on the compositor and the other peer.
https://bugzilla.gnome.org/show_bug.cgi?id=763298
We should conform to a minimal set of reasons for the gtk side to emit
a better GtkDragResult than GTK_DRAG_RESULT_ERROR. This fixes the notebook
tab DnD feature, where we rely on GTK_DRAG_RESULT_NO_TARGET.
In the wayland side, unfortunately we can't honor either NO_TARGET nor
USER_CANCELLED, we don't know of the latter, so we could return false
positives on the former.
https://bugzilla.gnome.org/show_bug.cgi?id=761954
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.
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
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
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 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.
gdk_wayland_drop_context_set_status() can't do much else currently besides
picking a mimetype (the first one is currently chosen). This may incorrectly
unset the mimetype chosen on .receive(), so the transfer is cancelled before
it even starts.
At the time drop_reply happens, we should have already picked a mimetype
along the way, so only cover for accepted=FALSE in order to unset it.