forked from AuroraMiddleware/gtk
x11: Implement popup surfaces
Make them use o-r windows, and move with their parent. 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.
This commit is contained in:
parent
99783c7fb7
commit
6f1c32b3eb
@ -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;
|
||||
|
@ -223,6 +223,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,
|
||||
|
@ -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));
|
||||
|
||||
@ -842,7 +850,8 @@ _gdk_x11_display_create_surface (GdkDisplay *display,
|
||||
xattributes.colormap = gdk_x11_display_get_window_colormap (display_x11);
|
||||
xattributes_mask |= CWColormap;
|
||||
|
||||
if (surface->surface_type == GDK_SURFACE_TEMP)
|
||||
if (surface->surface_type == GDK_SURFACE_TEMP ||
|
||||
surface->surface_type == GDK_SURFACE_POPUP)
|
||||
{
|
||||
xattributes.save_under = True;
|
||||
xattributes.override_redirect = True;
|
||||
@ -899,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;
|
||||
}
|
||||
|
||||
@ -1231,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);
|
||||
|
||||
@ -1244,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1283,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);
|
||||
|
||||
@ -1314,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
|
||||
{
|
||||
@ -1324,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);
|
||||
@ -1341,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)
|
||||
@ -1390,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;
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user