Blob Blame History Raw
From f78585b7c35cbe07b5cf921a871d59299dcfa355 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jonas=20=C3=85dahl?= <jadahl@gmail.com>
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?= <jadahl@gmail.com>
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