[gtk/wip/matthiasc/popup4: 93/93] x11: Make popups move with their parent



commit 9c25319932b03061d033157af15a48cf3ec5979a
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Apr 22 16:35:23 2019 +0000

    x11: Make popups move with their parent
    
    This is another step towards implementing
    popup semantics for X11.

 gdk/x11/gdkdisplay-x11.c | 10 +++++--
 gdk/x11/gdkprivate-x11.h |  2 ++
 gdk/x11/gdksurface-x11.c | 75 +++++++++++++++++++++++++++++++++++++++---------
 gdk/x11/gdksurface-x11.h |  5 ++++
 4 files changed, 77 insertions(+), 15 deletions(-)
---
diff --git a/gdk/x11/gdkdisplay-x11.c b/gdk/x11/gdkdisplay-x11.c
index 5b3f7c74cd..51462ad7d1 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -985,8 +985,14 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
            }
          if (!is_substructure)
            {
-             surface->x = event->configure.x;
-             surface->y = event->configure.y;
+              if (surface->x != event->configure.x ||
+                  surface->y != event->configure.y)
+                {
+                  surface->x = event->configure.x;
+                  surface->y = event->configure.y;
+
+                  gdk_x11_surface_move_popups (surface);
+                }
 
               if (surface_impl->unscaled_width != xevent->xconfigure.width ||
                   surface_impl->unscaled_height != xevent->xconfigure.height)
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 2e2b420560..7ac948b5bb 100644
--- a/gdk/x11/gdkprivate-x11.h
+++ b/gdk/x11/gdkprivate-x11.h
@@ -227,6 +227,8 @@ void _gdk_x11_cursor_display_finalize (GdkDisplay *display);
 
 void _gdk_x11_surface_register_dnd (GdkSurface *window);
 
+void gdk_x11_surface_move_popups (GdkSurface *surface);
+
 GdkDrag        * _gdk_x11_surface_drag_begin (GdkSurface          *window,
                                               GdkDevice          *device,
                                               GdkContentProvider *content,
diff --git a/gdk/x11/gdksurface-x11.c b/gdk/x11/gdksurface-x11.c
index 74b6e2b622..3c94a34a2b 100644
--- a/gdk/x11/gdksurface-x11.c
+++ b/gdk/x11/gdksurface-x11.c
@@ -425,12 +425,20 @@ gdk_x11_surface_end_frame (GdkSurface *surface)
 static void
 gdk_x11_surface_finalize (GObject *object)
 {
+  GdkSurface *surface;
   GdkX11Surface *impl;
 
   g_return_if_fail (GDK_IS_X11_SURFACE (object));
 
+  surface = GDK_SURFACE (object);
   impl = GDK_X11_SURFACE (object);
 
+  if (surface->parent)
+    {
+      GdkX11Surface *parent_impl = GDK_X11_SURFACE (surface->parent);
+      parent_impl->popups = g_list_remove (parent_impl->popups, surface);
+    }
+
   if (impl->toplevel->in_frame)
     unhook_surface_changed (GDK_SURFACE (impl));
 
@@ -900,6 +908,12 @@ _gdk_x11_display_create_surface (GdkDisplay     *display,
 
   gdk_surface_freeze_toplevel_updates (surface);
 
+  if (parent)
+    {
+      GdkX11Surface *parent_impl = GDK_X11_SURFACE (parent);
+      parent_impl->popups = g_list_prepend (parent_impl->popups, surface);
+    }
+
   return surface;
 }
 
@@ -1232,8 +1246,8 @@ gdk_x11_surface_hide (GdkSurface *surface)
 
 static inline void
 x11_surface_move (GdkSurface *surface,
-                 gint       x,
-                 gint       y)
+                  gint        x,
+                  gint        y)
 {
   GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
@@ -1245,6 +1259,12 @@ x11_surface_move (GdkSurface *surface,
     {
       surface->x = x;
       surface->y = y;
+
+      if (surface->parent)
+        {
+          impl->offset_x = surface->x - surface->parent->x;
+          impl->offset_y = surface->y - surface->parent->y;
+        }
     }
 }
 
@@ -1284,10 +1304,10 @@ x11_surface_resize (GdkSurface *surface,
 
 static inline void
 x11_surface_move_resize (GdkSurface *surface,
-                        gint       x,
-                        gint       y,
-                        gint       width,
-                        gint       height)
+                         gint        x,
+                         gint        y,
+                         gint        width,
+                         gint        height)
 {
   GdkX11Surface *impl = GDK_X11_SURFACE (surface);
 
@@ -1315,6 +1335,12 @@ x11_surface_move_resize (GdkSurface *surface,
       surface->height = height;
 
       _gdk_x11_surface_update_size (GDK_X11_SURFACE (surface));
+
+      if (surface->parent)
+        {
+          impl->offset_x = surface->x - surface->parent->x;
+          impl->offset_y = surface->y - surface->parent->y;
+        }
     }
   else
     {
@@ -1325,11 +1351,11 @@ x11_surface_move_resize (GdkSurface *surface,
 
 static void
 gdk_x11_surface_move_resize (GdkSurface *surface,
-                            gboolean   with_move,
-                            gint       x,
-                            gint       y,
-                            gint       width,
-                            gint       height)
+                             gboolean    with_move,
+                             gint        x,
+                             gint        y,
+                             gint        width,
+                             gint        height)
 {
   if (with_move && (width < 0 && height < 0))
     x11_surface_move (surface, x, y);
@@ -1342,6 +1368,29 @@ gdk_x11_surface_move_resize (GdkSurface *surface,
     }
 }
 
+static void gdk_x11_surface_raise (GdkSurface *surface);
+
+void
+gdk_x11_surface_move_popups (GdkSurface *parent)
+{
+  GdkX11Surface *impl = GDK_X11_SURFACE (parent);
+  GList *l;
+
+  for (l = impl->popups; l; l = l->next)
+    {
+      GdkX11Surface *popup_impl = l->data;
+      GdkSurface *popup = GDK_SURFACE (popup_impl);
+
+      x11_surface_move (popup, 
+                        parent->x + popup_impl->offset_x,
+                        parent->y + popup_impl->offset_y);
+      /* FIXME: We need to work harder to maintain
+       * the stacking order properly
+       */
+      gdk_x11_surface_raise (popup);
+    }
+}
+
 void
 _gdk_x11_surface_set_surface_scale (GdkSurface *surface,
                                  int scale)
@@ -1391,8 +1440,8 @@ gdk_x11_surface_raise (GdkSurface *surface)
 
 static void
 gdk_x11_surface_restack_toplevel (GdkSurface *surface,
-                                GdkSurface *sibling,
-                                gboolean   above)
+                                  GdkSurface *sibling,
+                                  gboolean    above)
 {
   XWindowChanges changes;
 
diff --git a/gdk/x11/gdksurface-x11.h b/gdk/x11/gdksurface-x11.h
index 6ffdbf24e6..c051d10d82 100644
--- a/gdk/x11/gdksurface-x11.h
+++ b/gdk/x11/gdksurface-x11.h
@@ -75,6 +75,11 @@ struct _GdkX11Surface
 #if defined (HAVE_XCOMPOSITE) && defined(HAVE_XDAMAGE) && defined (HAVE_XFIXES)
   Damage damage;
 #endif
+
+  int offset_x;
+  int offset_y;
+
+  GList *popups;
 };
  
 struct _GdkX11SurfaceClass 


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