summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garnacho <carlosg@gnome.org>2018-04-06 15:47:50 +0200
committerCarlos Garnacho <carlosg@gnome.org>2018-04-23 21:31:19 +0200
commit8df2a1452cf48b724fd3f3e0b72e5175553febe5 (patch)
tree33df3627e73cca3f6c40acb879e711e43d0fa2c5
parentb12c92e206398f200faa58b5dc928be8342c2561 (diff)
downloadmutter-8df2a1452cf48b724fd3f3e0b72e5175553febe5.tar.gz
wayland: Notify actively of xwayland window/surface associations
Instead of scheduling a meta_later, keep track of the unassociated windows, and look for matches as soon as the MetaWaylandSurface is created on our side. This will ensure the surface is given the Xwayland role before receiving the first wl_surface.commit.
-rw-r--r--src/wayland/meta-wayland-private.h2
-rw-r--r--src/wayland/meta-wayland-surface.c2
-rw-r--r--src/wayland/meta-wayland.c62
-rw-r--r--src/wayland/meta-wayland.h7
-rw-r--r--src/wayland/meta-xwayland.c71
-rw-r--r--src/wayland/meta-xwayland.h4
6 files changed, 85 insertions, 63 deletions
diff --git a/src/wayland/meta-wayland-private.h b/src/wayland/meta-wayland-private.h
index 8ff853687..bfb27cdf6 100644
--- a/src/wayland/meta-wayland-private.h
+++ b/src/wayland/meta-wayland-private.h
@@ -72,6 +72,8 @@ struct _MetaWaylandCompositor
MetaWaylandSeat *seat;
MetaWaylandTabletManager *tablet_manager;
+
+ GHashTable *scheduled_surface_associations;
};
#endif /* META_WAYLAND_PRIVATE_H */
diff --git a/src/wayland/meta-wayland-surface.c b/src/wayland/meta-wayland-surface.c
index 41ad8bc2b..604d47e96 100644
--- a/src/wayland/meta-wayland-surface.c
+++ b/src/wayland/meta-wayland-surface.c
@@ -1322,6 +1322,8 @@ meta_wayland_surface_create (MetaWaylandCompositor *compositor,
surface->outputs_to_destroy_notify_id = g_hash_table_new (NULL, NULL);
surface->shortcut_inhibited_seats = g_hash_table_new (NULL, NULL);
+ meta_wayland_compositor_notify_surface_id (compositor, id, surface);
+
return surface;
}
diff --git a/src/wayland/meta-wayland.c b/src/wayland/meta-wayland.c
index bab6b4ac4..63326fd9b 100644
--- a/src/wayland/meta-wayland.c
+++ b/src/wayland/meta-wayland.c
@@ -46,6 +46,7 @@
#include "meta-wayland-inhibit-shortcuts.h"
#include "meta-wayland-inhibit-shortcuts-dialog.h"
#include "meta-xwayland-grab-keyboard.h"
+#include "meta-xwayland.h"
static MetaWaylandCompositor _meta_wayland_compositor;
static char *_display_name_override;
@@ -306,6 +307,8 @@ meta_wayland_compositor_init (MetaWaylandCompositor *compositor)
{
memset (compositor, 0, sizeof (MetaWaylandCompositor));
wl_list_init (&compositor->frame_callbacks);
+
+ compositor->scheduled_surface_associations = g_hash_table_new (NULL, NULL);
}
void
@@ -482,3 +485,62 @@ meta_wayland_compositor_flush_clients (MetaWaylandCompositor *compositor)
{
wl_display_flush_clients (compositor->wayland_display);
}
+
+static void on_scheduled_association_unmanaged (MetaWindow *window,
+ gpointer user_data);
+
+static void
+meta_wayland_compositor_remove_surface_association (MetaWaylandCompositor *compositor,
+ int id)
+{
+ MetaWindow *window;
+
+ window = g_hash_table_lookup (compositor->scheduled_surface_associations,
+ GINT_TO_POINTER (id));
+ if (window)
+ {
+ g_signal_handlers_disconnect_by_func (window,
+ on_scheduled_association_unmanaged,
+ GINT_TO_POINTER (id));
+ g_hash_table_remove (compositor->scheduled_surface_associations,
+ GINT_TO_POINTER (id));
+ }
+}
+
+static void
+on_scheduled_association_unmanaged (MetaWindow *window,
+ gpointer user_data)
+{
+ MetaWaylandCompositor *compositor = meta_wayland_compositor_get_default ();
+
+ meta_wayland_compositor_remove_surface_association (compositor,
+ GPOINTER_TO_INT (user_data));
+}
+
+void
+meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor,
+ int id,
+ MetaWindow *window)
+{
+ g_signal_connect (window, "unmanaged",
+ G_CALLBACK (on_scheduled_association_unmanaged),
+ GINT_TO_POINTER (id));
+ g_hash_table_insert (compositor->scheduled_surface_associations,
+ GINT_TO_POINTER (id), window);
+}
+
+void
+meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor,
+ int id,
+ MetaWaylandSurface *surface)
+{
+ MetaWindow *window;
+
+ window = g_hash_table_lookup (compositor->scheduled_surface_associations,
+ GINT_TO_POINTER (id));
+ if (window)
+ {
+ meta_xwayland_associate_window_with_surface (window, surface);
+ meta_wayland_compositor_remove_surface_association (compositor, id);
+ }
+}
diff --git a/src/wayland/meta-wayland.h b/src/wayland/meta-wayland.h
index d5795c1c2..1391bcd20 100644
--- a/src/wayland/meta-wayland.h
+++ b/src/wayland/meta-wayland.h
@@ -65,5 +65,12 @@ gboolean meta_wayland_compositor_is_shortcuts_inhibited (MetaWayl
void meta_wayland_compositor_flush_clients (MetaWaylandCompositor *compositor);
+void meta_wayland_compositor_schedule_surface_association (MetaWaylandCompositor *compositor,
+ int id,
+ MetaWindow *window);
+void meta_wayland_compositor_notify_surface_id (MetaWaylandCompositor *compositor,
+ int id,
+ MetaWaylandSurface *surface);
+
#endif
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index c3baaff05..955c57262 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -60,9 +60,9 @@ G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
meta_wayland_surface_role_xwayland,
META_TYPE_WAYLAND_ACTOR_SURFACE)
-static void
-associate_window_with_surface (MetaWindow *window,
- MetaWaylandSurface *surface)
+void
+meta_xwayland_associate_window_with_surface (MetaWindow *window,
+ MetaWaylandSurface *surface)
{
MetaDisplay *display = window->display;
@@ -110,58 +110,13 @@ associate_window_with_surface_id (MetaXWaylandManager *manager,
if (resource)
{
MetaWaylandSurface *surface = wl_resource_get_user_data (resource);
- associate_window_with_surface (window, surface);
+ meta_xwayland_associate_window_with_surface (window, surface);
return TRUE;
}
else
return FALSE;
}
-typedef struct {
- MetaXWaylandManager *manager;
- MetaWindow *window;
- guint32 surface_id;
- guint later_id;
-} AssociateWindowWithSurfaceOp;
-
-static void associate_window_with_surface_window_unmanaged (MetaWindow *window,
- AssociateWindowWithSurfaceOp *op);
-static void
-associate_window_with_surface_op_free (AssociateWindowWithSurfaceOp *op)
-{
- if (op->later_id != 0)
- meta_later_remove (op->later_id);
- g_signal_handlers_disconnect_by_func (op->window,
- (gpointer) associate_window_with_surface_window_unmanaged,
- op);
- g_free (op);
-}
-
-static void
-associate_window_with_surface_window_unmanaged (MetaWindow *window,
- AssociateWindowWithSurfaceOp *op)
-{
- associate_window_with_surface_op_free (op);
-}
-
-static gboolean
-associate_window_with_surface_later (gpointer user_data)
-{
- AssociateWindowWithSurfaceOp *op = user_data;
-
- op->later_id = 0;
-
- if (!associate_window_with_surface_id (op->manager, op->window, op->surface_id))
- {
- /* Not here? Oh well... nothing we can do */
- g_warning ("Unknown surface ID %d (from window %s)", op->surface_id, op->window->desc);
- }
-
- associate_window_with_surface_op_free (op);
-
- return G_SOURCE_REMOVE;
-}
-
void
meta_xwayland_handle_wl_surface_id (MetaWindow *window,
guint32 surface_id)
@@ -171,21 +126,11 @@ meta_xwayland_handle_wl_surface_id (MetaWindow *window,
if (!associate_window_with_surface_id (manager, window, surface_id))
{
- /* No surface ID yet... it should arrive after the next
- * iteration through the loop, so queue a later and see
- * what happens.
+ /* No surface ID yet, schedule this association for whenever the
+ * surface is made known.
*/
- AssociateWindowWithSurfaceOp *op = g_new0 (AssociateWindowWithSurfaceOp, 1);
- op->manager = manager;
- op->window = window;
- op->surface_id = surface_id;
- op->later_id = meta_later_add (META_LATER_BEFORE_REDRAW,
- associate_window_with_surface_later,
- op,
- NULL);
-
- g_signal_connect (op->window, "unmanaged",
- G_CALLBACK (associate_window_with_surface_window_unmanaged), op);
+ meta_wayland_compositor_schedule_surface_association (compositor,
+ surface_id, window);
}
}
diff --git a/src/wayland/meta-xwayland.h b/src/wayland/meta-xwayland.h
index 5c404a921..6812ce72b 100644
--- a/src/wayland/meta-xwayland.h
+++ b/src/wayland/meta-xwayland.h
@@ -41,4 +41,8 @@ void
meta_xwayland_handle_xwayland_grab (MetaWindow *window,
gboolean allow);
+void
+meta_xwayland_associate_window_with_surface (MetaWindow *window,
+ MetaWaylandSurface *surface);
+
#endif /* META_XWAYLAND_H */