[gtk/wip/matthiasc/popup4: 101/110] x11: Make popups move with their parent
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/matthiasc/popup4: 101/110] x11: Make popups move with their parent
- Date: Tue, 23 Apr 2019 19:09:28 +0000 (UTC)
commit bbdc20290ceaa57c9e14b8219e4fc3e2d30c0d93
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.
We do a sort-of ok job on stacking order
here - whenever the parent window gets a
ConfigureNotify, we just restack all popups
directly on top of their parent. This is good
enough to keep popups on top of their parent
while we drag it around, and it gets the popup
to disappear when raising another window on
top of the parent.
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..7fd21ccb0d 100644
--- a/gdk/x11/gdkdisplay-x11.c
+++ b/gdk/x11/gdkdisplay-x11.c
@@ -985,8 +985,12 @@ 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;
+ }
if (surface_impl->unscaled_width != xevent->xconfigure.width ||
surface_impl->unscaled_height != xevent->xconfigure.height)
@@ -1007,6 +1011,8 @@ gdk_x11_display_translate_event (GdkEventTranslator *translator,
if (surface->resize_count == 0)
_gdk_x11_moveresize_configure_done (display, surface);
}
+
+ gdk_x11_surface_update_popups (surface);
}
}
break;
diff --git a/gdk/x11/gdkprivate-x11.h b/gdk/x11/gdkprivate-x11.h
index 2e2b420560..5539d51ba1 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_update_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..a3d28dae93 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_restack_toplevel (GdkSurface *surface,
+ GdkSurface *sibling,
+ gboolean above);
+
+void
+gdk_x11_surface_update_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);
+ int new_x = parent->x + popup_impl->offset_x;
+ int new_y = parent->y + popup_impl->offset_y;
+
+ if (new_x != popup->x || new_y != popup->y)
+ x11_surface_move (popup, new_x, new_y);
+ gdk_x11_surface_restack_toplevel (popup, parent, TRUE);
+ }
+}
+
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]