summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Ådahl <jadahl@gmail.com>2015-05-18 16:02:45 +0800
committerJonas Ådahl <jadahl@gmail.com>2015-05-20 10:59:47 +0800
commit181e4399f6e2588b462eaa5689bdebd4063d8a6f (patch)
tree2eeb677619b201b2e982e6321b31cb99316754a9
parent688dcadafa6bea6f2f4d685091b3c401cd84acf9 (diff)
downloadgtk+-181e4399f6e2588b462eaa5689bdebd4063d8a6f.tar.gz
wayland: Don't round trip recursively during initialization
Instead use asynchronous round trips that is synchronized in the end of the initialization. This makes it easier to track state, as we won't dispatch arbitrary Wayland messages while processing globals. https://bugzilla.gnome.org/show_bug.cgi?id=719819
-rw-r--r--gdk/wayland/gdkdisplay-wayland.c50
-rw-r--r--gdk/wayland/gdkdisplay-wayland.h2
2 files changed, 48 insertions, 4 deletions
diff --git a/gdk/wayland/gdkdisplay-wayland.c b/gdk/wayland/gdkdisplay-wayland.c
index 6df25cff06..8e23afe96b 100644
--- a/gdk/wayland/gdkdisplay-wayland.c
+++ b/gdk/wayland/gdkdisplay-wayland.c
@@ -74,6 +74,35 @@ static void _gdk_wayland_display_load_cursor_theme (GdkWaylandDisplay *wayland_d
G_DEFINE_TYPE (GdkWaylandDisplay, gdk_wayland_display, GDK_TYPE_DISPLAY)
static void
+async_roundtrip_callback (void *data,
+ struct wl_callback *callback,
+ uint32_t time)
+{
+ GdkWaylandDisplay *display_wayland = data;
+
+ display_wayland->async_roundtrips =
+ g_list_remove (display_wayland->async_roundtrips, callback);
+ wl_callback_destroy (callback);
+}
+
+static const struct wl_callback_listener async_roundrip_listener = {
+ async_roundtrip_callback
+};
+
+static void
+_gdk_wayland_display_async_roundtrip (GdkWaylandDisplay *display_wayland)
+{
+ struct wl_callback *callback;
+
+ callback = wl_display_sync (display_wayland->wl_display);
+ wl_callback_add_listener (callback,
+ &async_roundrip_listener,
+ display_wayland);
+ display_wayland->async_roundtrips =
+ g_list_append (display_wayland->async_roundtrips, callback);
+}
+
+static void
gdk_input_init (GdkDisplay *display)
{
GdkWaylandDisplay *display_wayland;
@@ -193,13 +222,13 @@ gdk_registry_handle_global (void *data,
output =
wl_registry_bind (display_wayland->wl_registry, id, &wl_output_interface, MIN (version, 2));
_gdk_wayland_screen_add_output (display_wayland->screen, id, output, MIN (version, 2));
- wl_display_roundtrip (display_wayland->wl_display);
+ _gdk_wayland_display_async_roundtrip (display_wayland);
}
else if (strcmp (interface, "wl_seat") == 0)
{
seat = wl_registry_bind (display_wayland->wl_registry, id, &wl_seat_interface, MIN (version, 4));
_gdk_wayland_device_manager_add_seat (gdk_display->device_manager, id, seat);
- wl_display_roundtrip (display_wayland->wl_display);
+ _gdk_wayland_display_async_roundtrip (display_wayland);
}
else if (strcmp (interface, "wl_data_device_manager") == 0)
{
@@ -273,8 +302,18 @@ _gdk_wayland_display_open (const gchar *display_name)
display_wayland->wl_registry = wl_display_get_registry (display_wayland->wl_display);
wl_registry_add_listener (display_wayland->wl_registry, &registry_listener, display_wayland);
- /* Wait until the dust has settled during init... */
- wl_display_roundtrip (display_wayland->wl_display);
+ _gdk_wayland_display_async_roundtrip (display_wayland);
+
+ /* Wait for initializing to complete. This means waiting for all
+ * asynchrounous roundtrips that were triggered during initial roundtrip. */
+ while (g_list_length (display_wayland->async_roundtrips) > 0)
+ {
+ if (wl_display_dispatch (display_wayland->wl_display) < 0)
+ {
+ g_object_unref (display);
+ return NULL;
+ }
+ }
gdk_input_init (display);
@@ -308,6 +347,9 @@ gdk_wayland_display_dispose (GObject *object)
display_wayland->selection = NULL;
}
+ g_list_foreach (display_wayland->async_roundtrips,
+ (GFunc) wl_callback_destroy, NULL);
+
G_OBJECT_CLASS (gdk_wayland_display_parent_class)->dispose (object);
}
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index 781be518ef..957a89a774 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -72,6 +72,8 @@ struct _GdkWaylandDisplay
struct wl_data_device_manager *data_device_manager;
struct wl_subcompositor *subcompositor;
+ GList *async_roundtrips;
+
struct wl_cursor_theme *scaled_cursor_themes[GDK_WAYLAND_THEME_SCALES_COUNT];
gchar *cursor_theme_name;
int cursor_theme_size;