[gtk: 6/16] wayland/surface: Add per surface configuration event queues
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk: 6/16] wayland/surface: Add per surface configuration event queues
- Date: Wed, 19 Feb 2020 18:58:33 +0000 (UTC)
commit 7fafa5133b5328c72cf206399647d2ee5dbabb27
Author: Jonas Ã…dahl <jadahl gmail com>
Date: Tue Jan 7 17:13:22 2020 +0100
wayland/surface: Add per surface configuration event queues
Add event queues specifically for surface configuration events
(xdg_surface.configure, xdg_toplevel.configure, xdg_popup.configure etc)
so that a configuration can be completed without having side effects on
other surfaces. This will be used to synchronously configure specific
GdkSurfaces, as is needed by the Gtk layout mechanisms.
gdk/wayland/gdkdisplay-wayland.h | 2 ++
gdk/wayland/gdkeventsource.c | 32 ++++++++++++++++++++++
gdk/wayland/gdksurface-wayland.c | 58 ++++++++++++++++++++++++++++++++++++++--
3 files changed, 90 insertions(+), 2 deletions(-)
---
diff --git a/gdk/wayland/gdkdisplay-wayland.h b/gdk/wayland/gdkdisplay-wayland.h
index 19d4bd5aac..1da3e36fe8 100644
--- a/gdk/wayland/gdkdisplay-wayland.h
+++ b/gdk/wayland/gdkdisplay-wayland.h
@@ -121,6 +121,8 @@ struct _GdkWaylandDisplay
GHashTable *known_globals;
GList *on_has_globals_closures;
+ GList *event_queues;
+
/* Keep a list of orphaned dialogs (i.e. without parent) */
GList *orphan_dialogs;
diff --git a/gdk/wayland/gdkeventsource.c b/gdk/wayland/gdkeventsource.c
index 86c3f86484..be31fb56de 100644
--- a/gdk/wayland/gdkeventsource.c
+++ b/gdk/wayland/gdkeventsource.c
@@ -37,6 +37,7 @@ gdk_event_source_prepare (GSource *base,
{
GdkWaylandEventSource *source = (GdkWaylandEventSource *) base;
GdkWaylandDisplay *display = (GdkWaylandDisplay *) source->display;
+ GList *l;
*timeout = -1;
@@ -60,6 +61,24 @@ gdk_event_source_prepare (GSource *base,
/* if prepare_read() returns non-zero, there are events to be dispatched */
if (wl_display_prepare_read (display->wl_display) != 0)
return TRUE;
+
+ /* We need to check whether there are pending events on the surface queues as well,
+ * but we also need to make sure to only have one active "read" in the end,
+ * or none if we immediately return TRUE, as multiple reads expect reads from
+ * as many threads.
+ */
+ for (l = display->event_queues; l; l = l->next)
+ {
+ struct wl_event_queue *queue = l->data;
+
+ if (wl_display_prepare_read_queue (display->wl_display, queue) != 0)
+ {
+ wl_display_cancel_read (display->wl_display);
+ return TRUE;
+ }
+ wl_display_cancel_read (display->wl_display);
+ }
+
source->reading = TRUE;
if (wl_display_flush (display->wl_display) < 0)
@@ -193,6 +212,7 @@ _gdk_wayland_display_queue_events (GdkDisplay *display)
{
GdkWaylandDisplay *display_wayland;
GdkWaylandEventSource *source;
+ GList *l;
display_wayland = GDK_WAYLAND_DISPLAY (display);
source = (GdkWaylandEventSource *) display_wayland->event_source;
@@ -204,6 +224,18 @@ _gdk_wayland_display_queue_events (GdkDisplay *display)
_exit (1);
}
+ for (l = display_wayland->event_queues; l; l = l->next)
+ {
+ struct wl_event_queue *queue = l->data;
+
+ if (wl_display_dispatch_queue_pending (display_wayland->wl_display, queue) < 0)
+ {
+ g_message ("Error %d (%s) dispatching to Wayland display.",
+ errno, g_strerror (errno));
+ _exit (1);
+ }
+ }
+
if (source->pfd.revents & (G_IO_ERR | G_IO_HUP))
{
g_message ("Lost connection to Wayland compositor.");
diff --git a/gdk/wayland/gdksurface-wayland.c b/gdk/wayland/gdksurface-wayland.c
index 02409da4e7..55134b1409 100644
--- a/gdk/wayland/gdksurface-wayland.c
+++ b/gdk/wayland/gdksurface-wayland.c
@@ -78,6 +78,8 @@ struct _GdkWaylandSurface
struct org_kde_kwin_server_decoration *server_decoration;
} display_server;
+ struct wl_event_queue *event_queue;
+
EGLSurface egl_surface;
EGLSurface dummy_egl_surface;
@@ -450,6 +452,7 @@ gdk_wayland_surface_request_frame (GdkSurface *surface)
clock = gdk_surface_get_frame_clock (surface);
callback = wl_surface_frame (impl->display_server.wl_surface);
+ wl_proxy_set_queue ((struct wl_proxy *) callback, NULL);
wl_callback_add_listener (callback, &frame_listener, surface);
impl->pending_frame_counter = gdk_frame_clock_get_frame_counter (clock);
impl->awaiting_frame = TRUE;
@@ -643,6 +646,44 @@ gdk_wayland_surface_beep (GdkSurface *surface)
return TRUE;
}
+static void
+gdk_wayland_surface_constructed (GObject *object)
+{
+ GdkSurface *surface = GDK_SURFACE (object);
+ GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
+ GdkWaylandDisplay *display_wayland =
+ GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+
+ G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->constructed (object);
+
+ impl->event_queue = wl_display_create_queue (display_wayland->wl_display);
+ display_wayland->event_queues = g_list_prepend (display_wayland->event_queues,
+ impl->event_queue);
+}
+
+static void
+gdk_wayland_surface_dispose (GObject *object)
+{
+ GdkSurface *surface = GDK_SURFACE (object);
+ GdkWaylandSurface *impl;
+
+ g_return_if_fail (GDK_IS_WAYLAND_SURFACE (surface));
+
+ impl = GDK_WAYLAND_SURFACE (surface);
+
+ if (impl->event_queue)
+ {
+ GdkWaylandDisplay *display_wayland =
+ GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+
+ display_wayland->event_queues =
+ g_list_remove (display_wayland->event_queues, surface);
+ g_clear_pointer (&impl->event_queue, wl_event_queue_destroy);
+ }
+
+ G_OBJECT_CLASS (gdk_wayland_surface_parent_class)->dispose (object);
+}
+
static void
gdk_wayland_surface_finalize (GObject *object)
{
@@ -1057,9 +1098,13 @@ gdk_wayland_surface_create_surface (GdkSurface *surface)
{
GdkWaylandSurface *impl = GDK_WAYLAND_SURFACE (surface);
GdkWaylandDisplay *display_wayland = GDK_WAYLAND_DISPLAY (gdk_surface_get_display (surface));
+ struct wl_surface *wl_surface;
+
+ wl_surface = wl_compositor_create_surface (display_wayland->compositor);
+ wl_proxy_set_queue ((struct wl_proxy *) wl_surface, impl->event_queue);
+ wl_surface_add_listener (wl_surface, &surface_listener, surface);
- impl->display_server.wl_surface = wl_compositor_create_surface (display_wayland->compositor);
- wl_surface_add_listener (impl->display_server.wl_surface, &surface_listener, surface);
+ impl->display_server.wl_surface = wl_surface;
}
static void
@@ -1334,6 +1379,8 @@ create_xdg_toplevel_resources (GdkSurface *surface)
impl->display_server.xdg_surface =
xdg_wm_base_get_xdg_surface (display_wayland->xdg_wm_base,
impl->display_server.wl_surface);
+ wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.xdg_surface,
+ impl->event_queue);
xdg_surface_add_listener (impl->display_server.xdg_surface,
&xdg_surface_listener,
surface);
@@ -2183,6 +2230,9 @@ gdk_wayland_surface_create_xdg_popup (GdkSurface *surface,
impl->display_server.xdg_surface =
xdg_wm_base_get_xdg_surface (display->xdg_wm_base,
impl->display_server.wl_surface);
+
+ wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.xdg_surface,
+ impl->event_queue);
xdg_surface_add_listener (impl->display_server.xdg_surface,
&xdg_surface_listener,
surface);
@@ -2987,6 +3037,8 @@ gdk_wayland_surface_init_gtk_surface (GdkSurface *surface)
impl->display_server.gtk_surface =
gtk_shell1_get_gtk_surface (display->gtk_shell,
impl->display_server.wl_surface);
+ wl_proxy_set_queue ((struct wl_proxy *) impl->display_server.gtk_surface,
+ impl->event_queue);
gdk_surface_set_geometry_hints (surface,
&impl->geometry_hints,
impl->geometry_mask);
@@ -3752,6 +3804,8 @@ gdk_wayland_surface_class_init (GdkWaylandSurfaceClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GdkSurfaceClass *impl_class = GDK_SURFACE_CLASS (klass);
+ object_class->constructed = gdk_wayland_surface_constructed;
+ object_class->dispose = gdk_wayland_surface_dispose;
object_class->finalize = gdk_wayland_surface_finalize;
impl_class->show = gdk_wayland_surface_show;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]