[gtk+/gtk-3-22] wayland: avoid 0 width/height anchor rectangle



commit 9a5ffcd1b5d5bbbf5c440c7a441e1901c1cae766
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Thu Jan 12 18:08:32 2017 +0100

    wayland: avoid 0 width/height anchor rectangle
    
    Passing a rectangle with zero width or height to xdg_shell-v6
    set_anchor_rect() will cause a protocol error and terminate the client,
    as with gedit when pressing the Win key.
    
    Reason for this is because the rectangle used to set the anchor comes
    from gtk_text_layout_get_iter_location() which uses the pango layout
    width/height, which can be empty if there is not character at the given
    location.
    
    Make sure we don't use 0 as width or height as an anchor rectangle to
    avoid the protocol error, and compensate the logical position of the
    given rectangle if the size is changed, so that the actual position
    remains as expected by the client.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=777176

 gdk/wayland/gdkwindow-wayland.c |   30 ++++++++++++++++++++++++++++++
 1 files changed, 30 insertions(+), 0 deletions(-)
---
diff --git a/gdk/wayland/gdkwindow-wayland.c b/gdk/wayland/gdkwindow-wayland.c
index 8fce48b..d629288 100644
--- a/gdk/wayland/gdkwindow-wayland.c
+++ b/gdk/wayland/gdkwindow-wayland.c
@@ -2668,6 +2668,34 @@ gdk_window_wayland_move_resize (GdkWindow *window,
     gdk_wayland_window_maybe_configure (window, width, height, impl->scale);
 }
 
+/* Avoid zero width/height as this is a protocol error */
+static void
+sanitize_anchor_rect (GdkWindow    *window,
+                      GdkRectangle *rect)
+{
+  gint original_width = rect->width;
+  gint original_height = rect->height;
+  GdkWindow *parent = get_popup_parent (window);
+
+  rect->width  = MAX (1, rect->width);
+  rect->height = MAX (1, rect->height);
+  rect->x -= rect->width - original_width;
+  rect->y -= rect->height - original_height;
+
+  /* Make sure the anchor rectangle does not extend outside the window
+   * geometry of the parent surface.
+   */
+  if (parent)
+    {
+      GdkRectangle geometry;
+
+      /* The rectangle is relative to the parent window geometry */
+      gdk_wayland_window_get_window_geometry (parent, &geometry);
+      rect->x = CLAMP (rect->x, 0, geometry.width);
+      rect->y = CLAMP (rect->y, 0, geometry.height);
+    }
+}
+
 static void
 gdk_window_wayland_move_to_rect (GdkWindow          *window,
                                  const GdkRectangle *rect,
@@ -2680,6 +2708,8 @@ gdk_window_wayland_move_to_rect (GdkWindow          *window,
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
 
   impl->pending_move_to_rect.rect = *rect;
+  sanitize_anchor_rect (window, &impl->pending_move_to_rect.rect);
+
   impl->pending_move_to_rect.rect_anchor = rect_anchor;
   impl->pending_move_to_rect.window_anchor = window_anchor;
   impl->pending_move_to_rect.anchor_hints = anchor_hints;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]