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.
This commit is contained in:
parent
b12c92e206
commit
8df2a1452c
@ -72,6 +72,8 @@ struct _MetaWaylandCompositor
|
||||
|
||||
MetaWaylandSeat *seat;
|
||||
MetaWaylandTabletManager *tablet_manager;
|
||||
|
||||
GHashTable *scheduled_surface_associations;
|
||||
};
|
||||
|
||||
#endif /* META_WAYLAND_PRIVATE_H */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -60,8 +60,8 @@ G_DEFINE_TYPE (MetaWaylandSurfaceRoleXWayland,
|
||||
meta_wayland_surface_role_xwayland,
|
||||
META_TYPE_WAYLAND_ACTOR_SURFACE)
|
||||
|
||||
static void
|
||||
associate_window_with_surface (MetaWindow *window,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user