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