From 0b60e553dc22e2fd8ac9cb5618774a5effd8e459 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Sun, 13 Oct 2024 09:50:38 -0400 Subject: [PATCH] wayland: Add support for the system bell protocol This is an upstream protocol providing equivalent functionality as the system bell request in gtk-shell. This commit includes a copy of xdg-system-bell-v1.xml, since we don't depend on wayland-protocols 1.38 yet. --- gdk/wayland/gdkdisplay-wayland.c | 35 ++++++++++--- gdk/wayland/gdkdisplay-wayland.h | 2 + gdk/wayland/meson.build | 5 ++ gdk/wayland/protocol/xdg-system-bell-v1.xml | 58 +++++++++++++++++++++ gtk/inspector/general.c | 4 +- 5 files changed, 94 insertions(+), 10 deletions(-) create mode 100644 gdk/wayland/protocol/xdg-system-bell-v1.xml diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index b75824dce4..48a5f0acb7 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -548,6 +548,12 @@ gdk_registry_handle_global (void *data, &wp_single_pixel_buffer_manager_v1_interface, MIN (version, 1)); } + else if (strcmp (interface, xdg_system_bell_v1_interface.name) == 0) + { + display_wayland->system_bell = + wl_registry_bind (display_wayland->wl_registry, id, + &xdg_system_bell_v1_interface, 1); + } g_hash_table_insert (display_wayland->known_globals, GUINT_TO_POINTER (id), g_strdup (interface)); @@ -768,6 +774,7 @@ gdk_wayland_display_dispose (GObject *object) g_clear_pointer (&display_wayland->linux_dmabuf, zwp_linux_dmabuf_v1_destroy); g_clear_pointer (&display_wayland->dmabuf_formats_info, dmabuf_formats_info_free); g_clear_pointer (&display_wayland->color, gdk_wayland_color_free); + g_clear_pointer (&display_wayland->system_bell, xdg_system_bell_v1_destroy); g_clear_pointer (&display_wayland->shm, wl_shm_destroy); g_clear_pointer (&display_wayland->wl_registry, wl_registry_destroy); @@ -814,23 +821,32 @@ gdk_wayland_display_get_name (GdkDisplay *display) void gdk_wayland_display_system_bell (GdkDisplay *display, - GdkSurface *window) + GdkSurface *surface) { GdkWaylandDisplay *display_wayland; - struct gtk_surface1 *gtk_surface; + struct gtk_surface1 *gtk_surface = NULL; + struct wl_surface *wl_surface = NULL; gint64 now_ms; g_return_if_fail (GDK_IS_DISPLAY (display)); display_wayland = GDK_WAYLAND_DISPLAY (display); - if (!display_wayland->gtk_shell) + if (!display_wayland->gtk_shell && + !display_wayland->system_bell) return; - if (window && GDK_IS_WAYLAND_TOPLEVEL (window)) - gtk_surface = gdk_wayland_toplevel_get_gtk_surface (GDK_WAYLAND_TOPLEVEL (window)); - else - gtk_surface = NULL; + if (surface) + { + if (GDK_IS_WAYLAND_TOPLEVEL (surface)) + { + GdkWaylandToplevel *toplevel = GDK_WAYLAND_TOPLEVEL (surface); + + gtk_surface = gdk_wayland_toplevel_get_gtk_surface (toplevel); + } + + wl_surface = gdk_wayland_surface_get_wl_surface (surface); + } now_ms = g_get_monotonic_time () / 1000; if (now_ms - display_wayland->last_bell_time_ms < MIN_SYSTEM_BELL_DELAY_MS) @@ -838,7 +854,10 @@ gdk_wayland_display_system_bell (GdkDisplay *display, display_wayland->last_bell_time_ms = now_ms; - gtk_shell1_system_bell (display_wayland->gtk_shell, gtk_surface); + if (display_wayland->system_bell) + xdg_system_bell_v1_ring (display_wayland->system_bell, wl_surface); + else + gtk_shell1_system_bell (display_wayland->gtk_shell, gtk_surface); } static void diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index 9b23f54178..70f2013730 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -106,6 +107,7 @@ struct _GdkWaylandDisplay struct zxdg_shell_v6 *zxdg_shell_v6; struct xdg_wm_dialog_v1 *xdg_wm_dialog; struct gtk_shell1 *gtk_shell; + struct xdg_system_bell_v1 *system_bell; struct wl_data_device_manager *data_device_manager; struct wl_subcompositor *subcompositor; struct zwp_pointer_gestures_v1 *pointer_gestures; diff --git a/gdk/wayland/meson.build b/gdk/wayland/meson.build index 706da22c83..498302984e 100644 --- a/gdk/wayland/meson.build +++ b/gdk/wayland/meson.build @@ -151,6 +151,11 @@ proto_sources = [ 'stability': 'private', 'version': 4, }, + { + 'name': 'xdg-system-bell', + 'stability': 'private', + 'version': 1, + }, ] gdk_wayland_gen_headers = [] diff --git a/gdk/wayland/protocol/xdg-system-bell-v1.xml b/gdk/wayland/protocol/xdg-system-bell-v1.xml new file mode 100644 index 0000000000..f00508de85 --- /dev/null +++ b/gdk/wayland/protocol/xdg-system-bell-v1.xml @@ -0,0 +1,58 @@ + + + + Copyright © 2016, 2023 Red Hat + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice (including the next + paragraph) shall be included in all copies or substantial portions of the + Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + + + + This global interface enables clients to ring the system bell. + + Warning! The protocol described in this file is currently in the testing + phase. Backward compatible changes may be added together with the + corresponding interface version bump. Backward incompatible changes can + only be done by creating a new major version of the extension. + + + + + Notify that the object will no longer be used. + + + + + + This requests rings the system bell on behalf of a client. How ringing + the bell is implemented is up to the compositor. It may be an audible + sound, a visual feedback of some kind, or any other thing including + nothing. + + The passed surface should correspond to a toplevel like surface role, + or be null, meaning the client doesn't have a particular toplevel it + wants to associate the bell ringing with. See the xdg-shell protocol + extension for a toplevel like surface role. + + + + + diff --git a/gtk/inspector/general.c b/gtk/inspector/general.c index 1752759150..9af0ecafb6 100644 --- a/gtk/inspector/general.c +++ b/gtk/inspector/general.c @@ -697,8 +697,8 @@ add_wayland_protocols (GdkDisplay *display, append_wayland_protocol_row (gen, (struct wl_proxy *)d->viewporter); append_wayland_protocol_row (gen, (struct wl_proxy *)d->presentation); append_wayland_protocol_row (gen, (struct wl_proxy *)d->single_pixel_buffer); - if (d->color) - append_wayland_protocol_row (gen, gdk_wayland_color_get_color_manager (d->color)); + append_wayland_protocol_row (gen, d->color ? gdk_wayland_color_get_color_manager (d->color) : NULL); + append_wayland_protocol_row (gen, (struct wl_proxy *)d->system_bell); } } #endif