[gtk+] mir: use mir_surface_spec_set_placement for menus



commit b09b69472b15bd27ec9da6cbb3a98073c05bb88a
Author: William Hua <william hua canonical com>
Date:   Fri Jan 27 14:46:10 2017 -0500

    mir: use mir_surface_spec_set_placement for menus
    
    This API was added to Mir for GTK menus, combo boxes, etc.

 gdk/mir/gdkmirwindowimpl.c |  240 +++++++++++++++++++++++++++++---------------
 1 files changed, 159 insertions(+), 81 deletions(-)
---
diff --git a/gdk/mir/gdkmirwindowimpl.c b/gdk/mir/gdkmirwindowimpl.c
index 386a964..25242f6 100644
--- a/gdk/mir/gdkmirwindowimpl.c
+++ b/gdk/mir/gdkmirwindowimpl.c
@@ -80,10 +80,15 @@ struct _GdkMirWindowImpl
   gint transient_x;
   gint transient_y;
 
-  /* Anchor rectangle */
-  gboolean has_rect;
-  MirRectangle rect;
-  MirEdgeAttachment edge;
+  /* gdk_window_move_to_rect */
+  gboolean            has_rect;
+  GdkRectangle        rect;
+  MirRectangle        mir_rect;
+  MirPlacementGravity rect_anchor;
+  MirPlacementGravity window_anchor;
+  MirPlacementHints   anchor_hints;
+  gint                rect_anchor_dx;
+  gint                rect_anchor_dy;
 
   /* Desired surface attributes */
   GdkWindowTypeHint type_hint;
@@ -299,16 +304,12 @@ create_window_type_spec (GdkDisplay *display,
                          gint height,
                          gboolean modal,
                          GdkWindowTypeHint type,
-                         const MirRectangle *rect,
-                         MirEdgeAttachment edge,
                          MirBufferUsage buffer_usage)
 {
-  MirPixelFormat format;
-  MirSurface *parent_surface = NULL;
   MirConnection *connection = gdk_mir_display_get_mir_connection (display);
-  MirRectangle real_rect;
-
-  format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
+  MirSurface *parent_surface = NULL;
+  MirPixelFormat format;
+  MirRectangle rect;
 
   if (parent && parent->impl)
     {
@@ -329,24 +330,12 @@ create_window_type_spec (GdkDisplay *display,
         }
     }
 
-  if (rect)
-    {
-      real_rect = *rect;
+  format = _gdk_mir_display_get_pixel_format (display, buffer_usage);
 
-      while (parent && !gdk_window_has_native (parent) && gdk_window_get_parent (parent))
-        {
-          real_rect.left += parent->x;
-          real_rect.top += parent->y;
-          parent = gdk_window_get_parent (parent);
-        }
-    }
-  else
-    {
-      real_rect.left = x;
-      real_rect.top = y;
-      real_rect.width = 1;
-      real_rect.height = 1;
-    }
+  rect.left = x;
+  rect.top = y;
+  rect.width = 1;
+  rect.height = 1;
 
   switch (type)
     {
@@ -380,9 +369,8 @@ create_window_type_spec (GdkDisplay *display,
                                                     height,
                                                     format,
                                                     parent_surface,
-                                                    &real_rect,
-                                                    edge);
-        break;
+                                                    &rect,
+                                                    0);
       case GDK_WINDOW_TYPE_HINT_SPLASHSCREEN:
       case GDK_WINDOW_TYPE_HINT_UTILITY:
         return mir_connection_create_spec_for_modal_dialog (connection,
@@ -429,15 +417,16 @@ static MirSurfaceSpec*
 create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
 {
   MirSurfaceSpec *spec = NULL;
+  GdkWindow *parent;
 
   spec = create_window_type_spec (impl->display,
                                   impl->transient_for,
-                                  impl->transient_x, impl->transient_y,
-                                  window->width, window->height,
+                                  impl->transient_x,
+                                  impl->transient_y,
+                                  window->width,
+                                  window->height,
                                   impl->modal,
                                   impl->type_hint,
-                                  impl->has_rect ? &impl->rect : NULL,
-                                  impl->has_rect ? impl->edge : mir_edge_attachment_any,
                                   impl->buffer_usage);
 
   mir_surface_spec_set_name (spec, impl->title);
@@ -445,6 +434,32 @@ create_spec (GdkWindow *window, GdkMirWindowImpl *impl)
 
   apply_geometry_hints (spec, impl);
 
+  if (impl->has_rect)
+    {
+      impl->mir_rect.left = impl->rect.x;
+      impl->mir_rect.top = impl->rect.y;
+      impl->mir_rect.width = impl->rect.width;
+      impl->mir_rect.height = impl->rect.height;
+
+      parent = impl->transient_for;
+
+      while (parent && !gdk_window_has_native (parent))
+        {
+          impl->mir_rect.left += parent->x;
+          impl->mir_rect.top += parent->y;
+
+          parent = gdk_window_get_parent (parent);
+        }
+
+      mir_surface_spec_set_placement (spec,
+                                      &impl->mir_rect,
+                                      impl->rect_anchor,
+                                      impl->window_anchor,
+                                      impl->anchor_hints,
+                                      impl->rect_anchor_dx,
+                                      impl->rect_anchor_dy);
+    }
+
   return spec;
 }
 
@@ -832,52 +847,117 @@ gdk_mir_window_impl_move_resize (GdkWindow *window,
     }
 }
 
-static MirEdgeAttachment
-get_edge_for_anchors (GdkGravity     rect_anchor,
-                      GdkGravity     window_anchor,
-                      GdkAnchorHints anchor_hints)
+static MirPlacementGravity
+get_mir_placement_gravity (GdkGravity gravity)
 {
-  MirEdgeAttachment edge = 0;
+  switch (gravity)
+    {
+    case GDK_GRAVITY_STATIC:
+    case GDK_GRAVITY_NORTH_WEST:
+      return mir_placement_gravity_northwest;
+    case GDK_GRAVITY_NORTH:
+      return mir_placement_gravity_north;
+    case GDK_GRAVITY_NORTH_EAST:
+      return mir_placement_gravity_northeast;
+    case GDK_GRAVITY_WEST:
+      return mir_placement_gravity_west;
+    case GDK_GRAVITY_CENTER:
+      return mir_placement_gravity_center;
+    case GDK_GRAVITY_EAST:
+      return mir_placement_gravity_east;
+    case GDK_GRAVITY_SOUTH_WEST:
+      return mir_placement_gravity_southwest;
+    case GDK_GRAVITY_SOUTH:
+      return mir_placement_gravity_south;
+    case GDK_GRAVITY_SOUTH_EAST:
+      return mir_placement_gravity_southeast;
+    }
+
+  g_warn_if_reached ();
+
+  return mir_placement_gravity_center;
+}
+
+static MirPlacementHints
+get_mir_placement_hints (GdkAnchorHints hints)
+{
+  MirPlacementHints mir_hints = 0;
+
+  if (hints & GDK_ANCHOR_FLIP_X)
+    mir_hints |= mir_placement_hints_flip_x;
 
-  if (anchor_hints & GDK_ANCHOR_FLIP_X)
-    edge |= mir_edge_attachment_vertical;
+  if (hints & GDK_ANCHOR_FLIP_Y)
+    mir_hints |= mir_placement_hints_flip_y;
 
-  if (anchor_hints & GDK_ANCHOR_FLIP_Y)
-    edge |= mir_edge_attachment_horizontal;
+  if (hints & GDK_ANCHOR_SLIDE_X)
+    mir_hints |= mir_placement_hints_slide_x;
 
-  return edge;
+  if (hints & GDK_ANCHOR_SLIDE_Y)
+    mir_hints |= mir_placement_hints_slide_y;
+
+  if (hints & GDK_ANCHOR_RESIZE_X)
+    mir_hints |= mir_placement_hints_resize_x;
+
+  if (hints & GDK_ANCHOR_RESIZE_Y)
+    mir_hints |= mir_placement_hints_resize_y;
+
+  return mir_hints;
 }
 
-static void
-get_rect_for_edge (MirRectangle       *out_rect,
-                   const GdkRectangle *in_rect,
-                   MirEdgeAttachment   edge,
-                   GdkWindow          *window)
+static gint
+get_window_shadow_dx (GdkWindow  *window,
+                      GdkGravity  window_anchor)
 {
-  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 (window_anchor)
+    {
+    case GDK_GRAVITY_STATIC:
+    case GDK_GRAVITY_NORTH_WEST:
+    case GDK_GRAVITY_WEST:
+    case GDK_GRAVITY_SOUTH_WEST:
+      return -window->shadow_left;
+
+    case GDK_GRAVITY_NORTH:
+    case GDK_GRAVITY_CENTER:
+    case GDK_GRAVITY_SOUTH:
+      return (window->shadow_right - window->shadow_left) / 2;
+
+    case GDK_GRAVITY_NORTH_EAST:
+    case GDK_GRAVITY_EAST:
+    case GDK_GRAVITY_SOUTH_EAST:
+      return window->shadow_right;
+    }
 
-  switch (edge)
+  g_warn_if_reached ();
+
+  return 0;
+}
+
+static gint
+get_window_shadow_dy (GdkWindow  *window,
+                      GdkGravity  window_anchor)
+{
+  switch (window_anchor)
     {
-    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;
+    case GDK_GRAVITY_STATIC:
+    case GDK_GRAVITY_NORTH_WEST:
+    case GDK_GRAVITY_NORTH:
+    case GDK_GRAVITY_NORTH_EAST:
+      return -window->shadow_top;
+
+    case GDK_GRAVITY_WEST:
+    case GDK_GRAVITY_CENTER:
+    case GDK_GRAVITY_EAST:
+      return (window->shadow_bottom - window->shadow_top) / 2;
+
+    case GDK_GRAVITY_SOUTH_WEST:
+    case GDK_GRAVITY_SOUTH:
+    case GDK_GRAVITY_SOUTH_EAST:
+      return window->shadow_bottom;
     }
+
+  g_warn_if_reached ();
+
+  return 0;
 }
 
 static void
@@ -891,18 +971,16 @@ gdk_mir_window_impl_move_to_rect (GdkWindow          *window,
 {
   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;
+  impl->rect = *rect;
+  impl->rect_anchor = get_mir_placement_gravity (rect_anchor);
+  impl->window_anchor = get_mir_placement_gravity (window_anchor);
+  impl->anchor_hints = get_mir_placement_hints (anchor_hints);
+  impl->rect_anchor_dx = rect_anchor_dx + get_window_shadow_dx (window, window_anchor);
+  impl->rect_anchor_dy = rect_anchor_dy + get_window_shadow_dy (window, window_anchor);
 
-  ensure_no_surface (window);
-
-  g_signal_emit_by_name (window,
-                         "moved-to-rect",
-                         NULL,
-                         NULL,
-                         FALSE,
-                         FALSE);
+  if (impl->surface && !impl->pending_spec_update)
+    update_surface_spec (window);
 }
 
 static GdkEventMask


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