From f78585b7c35cbe07b5cf921a871d59299dcfa355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 13 Mar 2017 14:33:06 +0800 Subject: [PATCH 1/2] wayland: Make beep requests go through the GdkDisplay This way we can add things like throttling. https://bugzilla.gnome.org/show_bug.cgi?id=778188 --- gdk/wayland/gdkdisplay-wayland.c | 19 ++++++++++++++++--- gdk/wayland/gdkprivate-wayland.h | 5 +++++ gdk/wayland/gdkwindow-wayland.c | 18 +++++++++--------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index 784cfbecc411..d7fb684bd69b 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -656,10 +656,12 @@ gdk_wayland_display_get_default_screen (GdkDisplay *display) return GDK_WAYLAND_DISPLAY (display)->screen; } -static void -gdk_wayland_display_beep (GdkDisplay *display) +void +gdk_wayland_display_system_bell (GdkDisplay *display, + GdkWindow *window) { GdkWaylandDisplay *display_wayland; + struct gtk_surface1 *gtk_surface; g_return_if_fail (GDK_IS_DISPLAY (display)); @@ -668,7 +670,18 @@ gdk_wayland_display_beep (GdkDisplay *display) if (!display_wayland->gtk_shell) return; - gtk_shell1_system_bell (display_wayland->gtk_shell, NULL); + if (window) + gtk_surface = gdk_wayland_window_get_gtk_surface (window); + else + gtk_surface = NULL; + + gtk_shell1_system_bell (display_wayland->gtk_shell, gtk_surface); +} + +static void +gdk_wayland_display_beep (GdkDisplay *display) +{ + gdk_wayland_display_system_bell (display, NULL); } static void diff --git a/gdk/wayland/gdkprivate-wayland.h b/gdk/wayland/gdkprivate-wayland.h index a95c925ca138..fde7632d38f5 100644 --- a/gdk/wayland/gdkprivate-wayland.h +++ b/gdk/wayland/gdkprivate-wayland.h @@ -83,6 +83,9 @@ void _gdk_wayland_display_get_maximal_cursor_size (GdkDisplay *display, gboolean _gdk_wayland_display_supports_cursor_alpha (GdkDisplay *display); gboolean _gdk_wayland_display_supports_cursor_color (GdkDisplay *display); +void gdk_wayland_display_system_bell (GdkDisplay *display, + GdkWindow *window); + struct wl_buffer *_gdk_wayland_cursor_get_buffer (GdkCursor *cursor, guint image_index, int *hotspot_x, @@ -271,6 +274,8 @@ EGLSurface gdk_wayland_window_get_egl_surface (GdkWindow *window, EGLSurface gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window, EGLConfig config); +struct gtk_surface1 * gdk_wayland_window_get_gtk_surface (GdkWindow *window); + void gdk_wayland_seat_set_global_cursor (GdkSeat *seat, GdkCursor *cursor); diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c index ffc9f94a009c..1f93f6c9c598 100644 --- a/gdk/wayland/gdkwindow-wayland.c +++ b/gdk/wayland/gdkwindow-wayland.c @@ -958,15 +958,8 @@ gdk_window_impl_wayland_end_paint (GdkWindow *window) static gboolean gdk_window_impl_wayland_beep (GdkWindow *window) { - GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl); - GdkWaylandDisplay *display_wayland = - GDK_WAYLAND_DISPLAY (gdk_window_get_display (window)); - - if (!display_wayland->gtk_shell) - return FALSE; - - gtk_shell1_system_bell (display_wayland->gtk_shell, - impl->display_server.gtk_surface); + gdk_wayland_display_system_bell (gdk_window_get_display (window), + window); return TRUE; } @@ -3891,6 +3884,13 @@ gdk_wayland_window_get_dummy_egl_surface (GdkWindow *window, return impl->dummy_egl_surface; } +struct gtk_surface1 * +gdk_wayland_window_get_gtk_surface (GdkWindow *window) +{ + g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), NULL); + + return GDK_WINDOW_IMPL_WAYLAND (window->impl)->display_server.gtk_surface; +} /** * gdk_wayland_window_set_use_custom_surface: -- 2.9.4 From 376ff1ae607db3e3ae47e8caeb8e8bce98c56f54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonas=20=C3=85dahl?= Date: Mon, 13 Mar 2017 14:42:38 +0800 Subject: [PATCH 2/2] wayland: Throttle system bell requests If a bad behaving application tries to make the window/display beep too often, throttle the beep requests so that we don't end up filling the Wayland socket queue. The throttle is set to 50 beeps per second, which far more beeps than will ever make any sense from a user experience point of view, but will avoid terminating due to an excessive amount of requests. https://bugzilla.gnome.org/show_bug.cgi?id=778188 --- gdk/wayland/gdkdisplay-wayland.c | 9 +++++++++ gdk/wayland/gdkdisplay-wayland.h | 2 ++ 2 files changed, 11 insertions(+) diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c index d7fb684bd69b..3c8eedbfdae8 100644 --- a/gdk/wayland/gdkdisplay-wayland.c +++ b/gdk/wayland/gdkdisplay-wayland.c @@ -80,6 +80,8 @@ * ]| */ +#define MIN_SYSTEM_BELL_DELAY_MS 20 + static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *display_wayland); G_DEFINE_TYPE (GdkWaylandDisplay, gdk_wayland_display, GDK_TYPE_DISPLAY) @@ -662,6 +664,7 @@ gdk_wayland_display_system_bell (GdkDisplay *display, { GdkWaylandDisplay *display_wayland; struct gtk_surface1 *gtk_surface; + gint64 now_ms; g_return_if_fail (GDK_IS_DISPLAY (display)); @@ -675,6 +678,12 @@ gdk_wayland_display_system_bell (GdkDisplay *display, else gtk_surface = NULL; + now_ms = g_get_monotonic_time () / 1000; + if (now_ms - display_wayland->last_bell_time_ms < MIN_SYSTEM_BELL_DELAY_MS) + return; + + display_wayland->last_bell_time_ms = now_ms; + gtk_shell1_system_bell (display_wayland->gtk_shell, gtk_surface); } diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h index a9fd4831a49c..3ae114e048fb 100644 --- a/gdk/wayland/gdkdisplay-wayland.h +++ b/gdk/wayland/gdkdisplay-wayland.h @@ -110,6 +110,8 @@ struct _GdkWaylandDisplay GPtrArray *monitors; + gint64 last_bell_time_ms; + /* egl info */ EGLDisplay egl_display; int egl_major_version; -- 2.9.4