[gtk+/wip/attente/popup-at: 4/4] mir: implement gdk_window_move_to_rect ()



commit 0c48e723c90633e11d5e90e8c93e8a2d336d2c8f
Author: William Hua <william hua canonical com>
Date:   Mon Jul 4 15:31:16 2016 -0400

    mir: implement gdk_window_move_to_rect ()
    
    https://bugzilla.gnome.org/show_bug.cgi?id=756579

 gdk/mir/gdkmirwindowimpl.c |  130 ++++++++++++++++++++++++++++++++++++++------
 1 files changed, 114 insertions(+), 16 deletions(-)
---
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 5ca9d89..40bfac8 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -46,6 +46,11 @@ struct _GdkMirWindowImpl
   gint transient_x;
   gint transient_y;
 
+  /* Anchor rectangle */
+  gboolean has_rect;
+  MirRectangle rect;
+  MirEdgeAttachment edge;
+
   /* Desired surface attributes */
   GdkWindowTypeHint type_hint;
   MirSurfaceState surface_state;
@@ -171,6 +176,8 @@ create_mir_surface (GdkDisplay *display,
                     gint width,
                     gint height,
                     GdkWindowTypeHint type,
+                    const MirRectangle *rect,
+                    MirEdgeAttachment edge,
                     MirBufferUsage buffer_usage)
 {
   MirSurface *parent_surface = NULL;
@@ -178,7 +185,7 @@ create_mir_surface (GdkDisplay *display,
   MirConnection *connection;
   MirPixelFormat format;
   MirSurface *surface;
-  MirRectangle rect;
+  MirRectangle real_rect;
 
   connection = gdk_mir_display_get_mir_connection (display);
   format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
@@ -202,6 +209,25 @@ create_mir_surface (GdkDisplay *display,
         }
     }
 
+  if (rect)
+    {
+      real_rect = *rect;
+
+      while (parent && !gdk_window_has_native (parent) && gdk_window_get_effective_parent (parent))
+        {
+          real_rect.left += parent->x;
+          real_rect.top += parent->y;
+          parent = gdk_window_get_effective_parent (parent);
+        }
+    }
+  else
+    {
+      real_rect.left = x;
+      real_rect.top = y;
+      real_rect.width = 1;
+      real_rect.height = 1;
+    }
+
   switch (type)
     {
       case GDK_WINDOW_TYPE_HINT_DIALOG:
@@ -216,17 +242,13 @@ create_mir_surface (GdkDisplay *display,
       case GDK_WINDOW_TYPE_HINT_POPUP_MENU:
       case GDK_WINDOW_TYPE_HINT_TOOLBAR:
       case GDK_WINDOW_TYPE_HINT_COMBO:
-        rect.left = x;
-        rect.top = y;
-        rect.width = 1;
-        rect.height = 1;
         spec = mir_connection_create_spec_for_menu (connection,
                                                     width,
                                                     height,
                                                     format,
                                                     parent_surface,
-                                                    &rect,
-                                                    mir_edge_attachment_any);
+                                                    &real_rect,
+                                                    edge);
         break;
       case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
       case GDK_WINDOW_TYPE_HINT_UTILITY:
@@ -239,16 +261,12 @@ create_mir_surface (GdkDisplay *display,
       case GDK_WINDOW_TYPE_HINT_DND:
       case GDK_WINDOW_TYPE_HINT_TOOLTIP:
       case GDK_WINDOW_TYPE_HINT_NOTIFICATION:
-        rect.left = x;
-        rect.top = y;
-        rect.width = 1;
-        rect.height = 1;
         spec = mir_connection_create_spec_for_tooltip (connection,
                                                        width,
                                                        height,
                                                        format,
                                                        parent_surface,
-                                                       &rect);
+                                                       &real_rect);
         break;
       case GDK_WINDOW_TYPE_HINT_NORMAL:
       case GDK_WINDOW_TYPE_HINT_DESKTOP:
@@ -328,10 +346,15 @@ ensure_surface_full (GdkWindow *window,
    */
   window_ref = _gdk_mir_event_source_get_window_reference (window);
 
-  impl->surface = create_mir_surface (gdk_window_get_display (window), impl->transient_for,
-                                      impl->transient_x, impl->transient_y,
-                                      window->width, window->height,
+  impl->surface = create_mir_surface (gdk_window_get_display (window),
+                                      impl->transient_for,
+                                      impl->transient_x,
+                                      impl->transient_y,
+                                      window->width,
+                                      window->height,
                                       impl->type_hint,
+                                      impl->has_rect ? &impl->rect : NULL,
+                                      impl->edge,
                                       buffer_usage);
 
   /* FIXME: can't make an initial resize event */
@@ -615,8 +638,9 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
   /* Transient windows can move wherever they want */
   if (with_move)
     {
-      if (x != impl->transient_x || y != impl->transient_y)
+      if (impl->has_rect || x != impl->transient_x || y != impl->transient_y)
         {
+          impl->has_rect = FALSE;
           impl->transient_x = x;
           impl->transient_y = y;
           recreate_surface = TRUE;
@@ -639,6 +663,79 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
     }
 }
 
+static MirEdgeAttachment
+get_edge_for_anchors (GdkGravity     rect_anchor,
+                      GdkGravity     window_anchor,
+                      GdkAnchorHints anchor_hints)
+{
+  MirEdgeAttachment edge = 0;
+
+  if (anchor_hints & GDK_ANCHOR_FLIP_X)
+    edge |= mir_edge_attachment_vertical;
+
+  if (anchor_hints & GDK_ANCHOR_FLIP_Y)
+    edge |= mir_edge_attachment_horizontal;
+
+  return edge;
+}
+
+static void
+get_rect_for_edge (MirRectangle       *out_rect,
+                   const GdkRectangle *in_rect,
+                   MirEdgeAttachment   edge,
+                   GdkWindow          *window)
+{
+  out_rect->left = in_rect->x;
+  out_rect->top = in_rect->y;
+  out_rect->width = in_rect->width;
+  out_rect->height = in_rect->height;
+
+  switch (edge)
+    {
+    case mir_edge_attachment_vertical:
+      out_rect->left += window->shadow_right;
+      out_rect->top -= window->shadow_top;
+      out_rect->width -= window->shadow_left + window->shadow_right;
+      out_rect->height += window->shadow_top + window->shadow_bottom;
+      break;
+
+    case mir_edge_attachment_horizontal:
+      out_rect->left -= window->shadow_left;
+      out_rect->top += window->shadow_bottom;
+      out_rect->width += window->shadow_left + window->shadow_right;
+      out_rect->height -= window->shadow_top + window->shadow_bottom;
+      break;
+
+    default:
+      break;
+    }
+}
+
+static void
+gdk_mir_window_impl_move_to_rect (GdkWindow          *window,
+                                  const GdkRectangle *rect,
+                                  GdkGravity          rect_anchor,
+                                  GdkGravity          window_anchor,
+                                  GdkAnchorHints      anchor_hints,
+                                  gint                rect_anchor_dx,
+                                  gint                rect_anchor_dy)
+{
+  GdkMirWindowImpl *impl = GDK_MIR_WINDOW_IMPL (window->impl);
+
+  impl->edge = get_edge_for_anchors (rect_anchor, window_anchor, anchor_hints);
+  get_rect_for_edge (&impl->rect, rect, impl->edge, window);
+  impl->has_rect = TRUE;
+
+  ensure_no_surface (window);
+
+  g_signal_emit_by_name (window,
+                         "moved-to-rect",
+                         NULL,
+                         NULL,
+                         FALSE,
+                         FALSE);
+}
+
 static void
 gdk_mir_window_impl_set_background (GdkWindow       *window,
                                     cairo_pattern_t *pattern)
@@ -1524,6 +1621,7 @@ gdk_mir_window_impl_class_init (GdkMirWindowImplClass *klass)
   impl_class->restack_under = gdk_mir_window_impl_restack_under;
   impl_class->restack_toplevel = gdk_mir_window_impl_restack_toplevel;
   impl_class->move_resize = gdk_mir_window_impl_move_resize;
+  impl_class->move_to_rect = gdk_mir_window_impl_move_to_rect;
   impl_class->set_background = gdk_mir_window_impl_set_background;
   impl_class->get_events = gdk_mir_window_impl_get_events;
   impl_class->set_events = gdk_mir_window_impl_set_events;


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