wayland: Add API for setting an exported as a parent

Add an API that enables an application to, given an exported window
handle, set its own window as a transient of the window associated with
the exported window handle.

https://bugzilla.gnome.org/show_bug.cgi?id=769788
This commit is contained in:
Jonas Ådahl 2016-07-13 15:24:19 +08:00 committed by Matthias Clasen
parent f98c9fec6c
commit 340b5964dd
4 changed files with 81 additions and 0 deletions

View File

@ -440,6 +440,12 @@ gdk_registry_handle_global (void *data,
wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_exporter_v1_interface, 1);
}
else if (strcmp (interface, "zxdg_importer_v1") == 0)
{
display_wayland->xdg_importer =
wl_registry_bind (display_wayland->wl_registry, id,
&zxdg_importer_v1_interface, 1);
}
else
handled = FALSE;

View File

@ -76,6 +76,7 @@ struct _GdkWaylandDisplay
struct gtk_primary_selection_device_manager *primary_selection_manager;
struct zwp_tablet_manager_v2 *tablet_manager;
struct zxdg_exporter_v1 *xdg_exporter;
struct zxdg_importer_v1 *xdg_importer;
GList *async_roundtrips;

View File

@ -73,6 +73,10 @@ gboolean gdk_wayland_window_export_handle (GdkWindow
GDK_AVAILABLE_IN_3_22
void gdk_wayland_window_unexport_handle (GdkWindow *window);
GDK_AVAILABLE_IN_3_22
gboolean gdk_wayland_window_set_transient_for_exported (GdkWindow *window,
char *parent_handle_str);
G_END_DECLS
#endif /* __GDK_WAYLAND_WINDOW_H__ */

View File

@ -203,6 +203,8 @@ struct _GdkWindowImplWayland
gpointer user_data;
GDestroyNotify destroy_func;
} exported;
struct zxdg_imported_v1 *imported_transient_for;
};
struct _GdkWindowImplWaylandClass
@ -224,6 +226,8 @@ static void gdk_wayland_window_sync_margin (GdkWindow *window);
static void gdk_wayland_window_sync_input_region (GdkWindow *window);
static void gdk_wayland_window_sync_opaque_region (GdkWindow *window);
static void unset_transient_for_exported (GdkWindow *window);
GType _gdk_window_impl_wayland_get_type (void);
G_DEFINE_TYPE (GdkWindowImplWayland, _gdk_window_impl_wayland, GDK_TYPE_WINDOW_IMPL)
@ -2321,6 +2325,8 @@ gdk_wayland_window_hide_surface (GdkWindow *window)
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_window_get_display (window));
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
unset_transient_for_exported (window);
if (impl->display_server.wl_surface)
{
if (impl->dummy_egl_surface)
@ -2983,6 +2989,8 @@ gdk_wayland_window_set_transient_for (GdkWindow *window,
return;
}
unset_transient_for_exported (window);
if (impl->display_server.wl_subsurface)
unmap_subsurface (window);
@ -3915,3 +3923,65 @@ gdk_wayland_window_unexport_handle (GdkWindow *window)
g_clear_pointer (&impl->exported.user_data,
impl->exported.destroy_func);
}
static void
unset_transient_for_exported (GdkWindow *window)
{
GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
g_clear_pointer (&impl->imported_transient_for, zxdg_imported_v1_destroy);
}
static void
xdg_imported_destroyed (void *data,
struct zxdg_imported_v1 *zxdg_imported_v1)
{
GdkWindow *window = data;
unset_transient_for_exported (window);
}
static const struct zxdg_imported_v1_listener xdg_imported_listener = {
xdg_imported_destroyed,
};
/**
* gdk_wayland_window_set_transient_for_exported:
*
* Stability: unstable
*/
gboolean
gdk_wayland_window_set_transient_for_exported (GdkWindow *window,
char *parent_handle_str)
{
GdkWindowImplWayland *impl;
GdkWaylandDisplay *display_wayland;
GdkDisplay *display = gdk_window_get_display (window);
g_return_val_if_fail (GDK_IS_WAYLAND_WINDOW (window), FALSE);
g_return_val_if_fail (GDK_IS_WAYLAND_DISPLAY (display), FALSE);
impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
display_wayland = GDK_WAYLAND_DISPLAY (display);
g_return_val_if_fail (impl->display_server.xdg_surface, FALSE);
if (!display_wayland->xdg_importer)
{
g_warning ("Server is missing xdg_foreign support");
return FALSE;
}
gdk_window_set_transient_for (window, NULL);
impl->imported_transient_for =
zxdg_importer_v1_import (display_wayland->xdg_importer, parent_handle_str);
zxdg_imported_v1_add_listener (impl->imported_transient_for,
&xdg_imported_listener,
window);
zxdg_imported_v1_set_parent_of (impl->imported_transient_for,
impl->display_server.wl_surface);
return TRUE;
}