GdkDragSurface-backed widgets are not parented to an existing widget,
unlike popovers, and like toplevels. This means that there's nobody to
actively call gdk_drag_surface_present() to update the size, and
GdkDragSurface should do it on its own, just like GdkToplevel.
This commit implements this for the Wayland backend.
Similarly to GdkToplevel, GdkDragSurface's compute-size should be called
by backends to query the current surface size, and should be connected
to by widget implementations (like GtkDragIcon) to report the current
size.
GdkDragSurface-backed widgets are not parented to an existing widget,
unlike popovers, and like toplevels. This means that there's nobody to
actively call gdk_drag_surface_present() to update the size, and
GdkDragSurface should do it on its own, just like GdkToplevel.
Doing it on hide() is not enough, since in some edge cases we didn't
ever actually map, we just attempted to compute the size, e.g. in
response to a ConfigureNotify event, then the window was destroyed.
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2678
In certain scenarios, address the issue where gnome.compile_resources
fails to transmit the present source directory. This is most notably
visible with MSBuild.
The split-up of gdksurface-wayland.c introduced a protocol violation
when it didn't make sure xdg_surface was destroyed after the role
objects (xdg_popup / xdg_toplevel). Fix that.
Fixes: 2a463baed0 ("wayland: Rearrange the surface code")
The availability of wl_surface.offset depends on the compositor, so we
can't call it unconditionally. Add a version check to so we only call
offset if we know we won't raise a protocol error.
Fixes: 0eb791eaaa ("Make mask nodes more versatile")
The API docs outline why quite well.
This should make it possible to do saving of textures to image files
without any private API with the same featureset that GTK uses.
Also remove the gsktextureprivate.h include where
gdk_texture_get_format() was the only reason for it.
We no longer need to make much distinction between multiple logical
devices, plus it breaks esp. with the Xwayland input device distribution.
Just iterate across all devices and reset their scroll valuators.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/4160
This is a bit spaghetti right now, since seats and devices were
heavily entangled there are a number of crossed private API calls that
should ideally not be there.
Let this be a first step, so more bits may move from the seat
implementation to devices.
This file, event though a clump of input-y objects, has more of
seats than anything else. Rename it so that we can start splitting
these objects out of it.
This is currently just used as a convenience storage of the startup ID
between the GtkApplication and the GtkWindow (after it's ready to notify
on it).
This could be untangled in the GTK layers so there is no involvement
from GDK in keeping the startup ID around, in the mean time just deprecate
these gdk_wayland* API calls.
... and use this check in gdk_gl_context_make_current() and
gdk_gl_context_get_current() to make sure the context really is still
current.
The context no longer being current can happen when external GL
implementations make their own contexts current in the same threads GDK
contexts are used in.
And that can happen for example by WebKit.
Theoretically, this should also allow external EGL code to run in X11
applications when GDK chooses to use GLX, but I didn't try it.
Fixes#5392
When checking characteristics of the context
for downloading, we were using self->context,
even though we are using a possibly different
context for downloading.
Pass the right context along and use it.
File may not have paths, and we should handle
that without incident. While we are at it, add
some logging so GDK_DEBUG=dnd gives us enough
output to see what is going on.
Instead of adding events to the application event queue, dispatch
them directly to the right display. We know this when the event is
to be dispatched.
This is the same as used for the `sendEvent` method in `GdkMacosWindow`.
To achieve this I factored out the generic NSEvent to GdkEvent translation.
We can send an event directly, when we receive it in the GdkMacosWindow
directly from the OS.
By passing the events during a (midal-ish) drag operation to the main loop,
we're able to keep up with what's happening. This allows the internal
drag state (GtkDragSource) to be updated and be done when the drag is
done.
The Drag data should pass through the macos pasteboard system.
We need to provide some pasteboard type. Let's make it a "URL",
which is a pretty generic type anyway.
The handling is done similar to drag targets.
Note that dragging is a modal action on macos: no events
are sent to the main window. This could cause trouble when
we finish the drag, and not finish the gesture in GTK.
This will make it easier to reuse from drag integration so that we don't
require clipboards for everything.
We will need to subclass the pasteboard provider twice, however, both
for clipboard and dragging.
Clang was complaining that we never use the
value stored in mime_type. Just don't store it,
we are only interested in the side-effect
(interning the string).
We have various layers where we store the startup ID for a request,
since this API does not have a GdkToplevel that we can refer about
for the Wayland platform, this is the most obvious candidate to
start untangling these various layers.
Deprecate this call, it is already unused in the gtk/ side.
In the way towards deprecating gdk_display_notify_startup_complete(),
make gdk_toplevel_set_startup_id() on X11 perform this piece of messaging
itself. It should be harmless that the message is emitted twice, if
callers do still use that API.
This call has everything to perform activation as specified by the
xdg_activation protocol, notably a surface to activate as opposed to
gdk_display_notify_startup_complete().
Make activation happen here, so that the surface gets activated when
its gets a startup ID assigned.
The owner_events=TRUE grab makes GDK on X11 see events happening
outside every client window as received on the grab window.
Additionally check that the pointer is inside the grab window
(i.e. it received GDK_CROSSING_NORMAL crossing events for the
core pointer) in order to handle clicks happening outside client
windows.
These new paths are expected to be a no-op on Wayland, and to
also work for touchscreen input on X11, due to emulated pointer
events.
Try to get a native file:// URI instead of any other GVFS
scheme, for interoperability with apps only handling file:// URIs.
This is what GTK3 Nautilus and Thunar do, so apps should be tuned
for this behavior.
See also https://bugzilla.xfce.org/show_bug.cgi?id=13845Fixes: #5422
A Drag surface does not have a parent surface. Therefore, if we initialize
it with one, it's inheriting the frame clock from the parent, but the
drag surface is not linked to the parent. Once the drag surface is destroyed,
it's disposing the frame clock, which results in a "frozen" application.
This is an extra safeguard that avoids grabbing resources longer than
nessecary. It also ensures the resource is removed from the drag,
so it is not freed again.
Currently, the GdkSurfaceX11 implementation relies that the upper
layers hid the surface before destruction, and that no
GdkSurfaceClass.compute_resize happened between them. If these
circumstances happened, there would be a compute_size timeout left
dangling after the surface got destroyed, poking at incorrect data
later on. Something that looks like this was reported in the
recent mutter-x11-frames "SSD frames server":
mutter-x11-frames:423016): GLib-GObject-WARNING **: 19:41:16.869: invalid unclassed pointer in cast to 'GtkWindow'
Thread 1 "mutter-x11-fram" received signal SIGTRAP, Trace/breakpoint trap.
g_logv (log_domain=0x7ffff7f7c4f8 "GLib-GObject", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=<optimized out>) at ../../../glib/gmessages.c:1433
1433 ../../../glib/gmessages.c: No such file or directory.
(gdb) bt
#0 g_logv (log_domain=0x7ffff7f7c4f8 "GLib-GObject", log_level=G_LOG_LEVEL_WARNING, format=<optimized out>, args=<optimized out>) at ../../../glib/gmessages.c:1433
#1 0x00007ffff73470ff in g_log (log_domain=log_domain@entry=0x7ffff7f7c4f8 "GLib-GObject", log_level=log_level@entry=G_LOG_LEVEL_WARNING, format=format@entry=0x7ffff7f84da8 "invalid unclassed pointer in cast to '%s'")
at ../../../glib/gmessages.c:1471
#2 0x00007ffff7f72892 in g_type_check_instance_cast (type_instance=type_instance@entry=0x5555558e04b0, iface_type=<optimized out>) at ../../../gobject/gtype.c:4144
#3 0x00007ffff791e77d in toplevel_compute_size (toplevel=<optimized out>, size=0x7fffffffe170, widget=0x5555558e04b0) at ../../../gtk/gtkwindow.c:4227
#4 0x00007ffff7f4f3b0 in g_closure_invoke (closure=0x555555898cc0, return_value=return_value@entry=0x0, n_param_values=2, param_values=param_values@entry=0x7fffffffdeb0, invocation_hint=invocation_hint@entry=0x7fffffffde30)
at ../../../gobject/gclosure.c:832
#5 0x00007ffff7f62076 in signal_emit_unlocked_R
(node=node@entry=0x55555588feb0, detail=detail@entry=0, instance=instance@entry=0x55555560e990, emission_return=emission_return@entry=0x0, instance_and_params=instance_and_params@entry=0x7fffffffdeb0)
at ../../../gobject/gsignal.c:3796
#6 0x00007ffff7f68bf5 in g_signal_emit_valist (instance=<optimized out>, signal_id=<optimized out>, detail=<optimized out>, var_args=var_args@entry=0x7fffffffe050) at ../../../gobject/gsignal.c:3549
#7 0x00007ffff7f68dbf in <emit signal ??? on instance 0x55555560e990 [GdkX11Toplevel]> (instance=<optimized out>, signal_id=<optimized out>, detail=detail@entry=0) at ../../../gobject/gsignal.c:3606
#8 0x00007ffff7a8de96 in gdk_toplevel_notify_compute_size (toplevel=<optimized out>, size=size@entry=0x7fffffffe170) at ../../../gdk/gdktoplevel.c:112
#9 0x00007ffff7a4b15a in compute_toplevel_size (surface=surface@entry=0x55555560e990 [GdkX11Toplevel], update_geometry=update_geometry@entry=1, width=width@entry=0x7fffffffe220, height=height@entry=0x7fffffffe224)
at ../../../gdk/x11/gdksurface-x11.c:281
#10 0x00007ffff7a4c3b2 in compute_size_idle (user_data=0x55555560e990) at ../../../gdk/x11/gdksurface-x11.c:356
#11 0x00007ffff733f67f in g_main_dispatch (context=0x55555563f6e0) at ../../../glib/gmain.c:3444
#12 g_main_context_dispatch (context=context@entry=0x55555563f6e0) at ../../../glib/gmain.c:4162
#13 0x00007ffff733fa38 in g_main_context_iterate (context=0x55555563f6e0, block=block@entry=1, dispatch=dispatch@entry=1, self=<optimized out>) at ../../../glib/gmain.c:4238
#14 0x00007ffff733fcef in g_main_loop_run (loop=loop@entry=0x5555560874a0) at ../../../glib/gmain.c:4438
#15 0x0000555555557de0 in main (argc=<optimized out>, argv=<optimized out>) at ../src/frames/main.c:68
It perhaps makes sense to warn in these situations, but either way
it sounds like gdk_surface_x11_finalize() could enforce the correct
behavior by ensuring there is no dangling timeouts/data. This commit
does that.
The argument to xdg_activation_token_v1_set_surface is documented to be the
surface requesting the activation, not the surface to be activated, which is
given later when calling xdg_activation_v1_activate.
(c.f. 36cee4bdbc)
Use the same logic as in gdk_wayland_app_launch_context_get_startup_notify_id,
i.e. if we have a surface with focus, set that, otherwise set NULL.
This fixes requesting urgent/focus on wlroots (compositors like Sway, etc.),
which was blocked as the surface requesting the activation didn't have focus.
Signed-off-by: Joan Bruguera <joanbrugueram@gmail.com>
By using wl_output_release(), GDK lets the compositor to clean up the
output global more nicely.
For example, currently, most compositors remove the global and then
destroy it later after N seconds expire. With this, the compositor could
experiment with destroying the output global once all its resources are
destroyed.
this is to prevent gdk from causing a segfault, when getting event axes
for events that don't have them (i.e. attempting to get pressure from a
mice input device).
GDK_TOUCH_END deserves the same treatment than GDK_BUTTON_RELEASE, since it's
subject to the same circumstances (popping up a menu on long press would be
immediately dismissed on release if we handled them there). Ideally, we would
want to match releases that we obtained a press for while grabbed, but as
the popup is also dismissed on GDK_BUTTON_PRESS/GDK_TOUCH_BEGIN, there's no
use for this tracking.
And GDK_TOUCH_CANCEL sounds weird as a reason to dismiss popups, just like
crossing events would.
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2512
clang complained that we may end up jumping
to the cleanup code without initializing data
in the jpeg code. Always initialize data to
NULL to prevent that eventuality.
GTK knows when a surface is modally blocked and automatically drops
button press and release events, so do not block input in advance
from WM_MOUSEACTIVATE.
This is largely adapted from commit 83027c68f1 ("11: Implement
inhibit_system_shortcuts API"), with similar rationale:
To implement the inhibit_system_shortcuts API on X11, we emulate the
same behavior using grabs on the keyboard.
To avoid keeping active grabs on the keyboard that would affect
other X11 applications even when the surface isn't focused, the X11
implementation takes care of releasing the grabs as soon as the
toplevel loses focus.
Note that Windows has low-level keyboard hooks that could help achieve
the expected behaviour. This is implemented by spice-gtk & gtk-vnc for
example, but correctness isn't obvious. I left a TODO comment.
This patch helps implementing remote desktop widgets with GTK4, since
currently on win32 backend Alt-Tab and such are always left to the
system unless there is keyboard grab (which can't be requested by the
client API anymore, afaict).
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
There's 2 things broken here:
- The mask was calculated on top of the GDK button (i.e. skipping
4-7 buttons), so GDK_BUTTON4_MASK and GDK_BUTTON5_MASK were not
assigned. This is now calculated on the (continuous) BTN_ evcodes
so it is guaranteed that the next 2 physical buttons (i.e.
back/forward) get these two places in the mask assigned.
- Furthermore, these buttons would be pushed to places in the
modifier mask that they didn't belong to. It is now checked hard
that only the first 5 buttons enable a modifier flag.
Overall, this ensures that no event masks with bonkers values are
forwarded, and that no stale implicit grabs are left after additional
buttons are pressed.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5301
This makes GtkSettings values on X11 match what we get on
other backends.
Reporting size settings in logical pixels (i.e for scale
== 1) is useful for properly supporting mixed-DPI setups.
As X11 doesn't support mixed-DPI setups anyway, XSettings
doesn't bother providing logical values. Thus we scale
from physical to logical values ourselves.
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5223
Fixes https://gitlab.gnome.org/GNOME/gtk/-/issues/5230
When getting the serial for primary/clipboard selections we used a
function that largely relied on a GdkEvent being passed. We have
another available function that looks up the most recent serial
given the ongoing touch/tablet input as well.
This is the second best, compared to actually knowing the
input/device from the event that was received by the UI an triggered
the clipboard operation, and is already in use in other places
(e.g. window dragging). It is valid for these situations too.
Closes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5250
Use newlines rather than spaces to separate file paths (or uri's)
when serializing text/plain files. There isn't a matching
deserializer, so we can do this in isolation. Newlines
seem to make more sense when pasting into a text editor etc.
Fixes: https://gitlab.gnome.org/GNOME/gtk/-/issues/5240
As documented on MSDN:
> Unlike the WM_LBUTTONUP, WM_MBUTTONUP, and WM_RBUTTONUP messages, an
> application should return TRUE from this message if it processes it.
Empty/zero bounds are sent by the Wayland compositor if there are no
valid bounds to report, e.g. if there are no connected monitors. Report
this to GTK, which uses this to clamp calculated sizes, as INT_MAX, so
that clamping isn't done until there are actual valid bounds to clamp
to.
This fixes clients sometimes shrinking to their minimum size during
hotplugs or after having suspended the session.