wayland: Roundtrip until we've receive initial input and output configuration
We use a ref-count mechanism to track whether parts of the init sequence still needs round trips to receive remaining initial state. Typically we need a couple of roundtrips total to get the global list, then the input and output configurations, but with the ref-count we avoid making global assumptions like that. https://bugzilla.gnome.org/show_bug.cgi?id=696340
This commit is contained in:
parent
b1aa23f4bd
commit
a9e980e578
@ -1106,6 +1106,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
GdkWaylandDeviceData *device = data;
|
||||
GdkWaylandDeviceManager *device_manager =
|
||||
GDK_WAYLAND_DEVICE_MANAGER(device->device_manager);
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (device->display);
|
||||
|
||||
if ((caps & WL_SEAT_CAPABILITY_POINTER) && !device->wl_pointer)
|
||||
{
|
||||
@ -1178,6 +1179,10 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
|
||||
_gdk_device_set_associated_device (device->pointer, device->keyboard);
|
||||
_gdk_device_set_associated_device (device->keyboard, device->pointer);
|
||||
}
|
||||
|
||||
/* Once we have the capabilities event we know we have all events
|
||||
* from the wl_seat and need no further init roundtrips. */
|
||||
display->init_ref_count--;
|
||||
}
|
||||
|
||||
static const struct wl_seat_listener seat_listener = {
|
||||
|
@ -100,6 +100,7 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
|
||||
if (strcmp(interface, "wl_compositor") == 0) {
|
||||
display_wayland->compositor =
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_compositor_interface, 1);
|
||||
display_wayland->init_ref_count--;
|
||||
} else if (strcmp(interface, "wl_shm") == 0) {
|
||||
display_wayland->shm =
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_shm_interface, 1);
|
||||
@ -113,10 +114,18 @@ gdk_registry_handle_global(void *data, struct wl_registry *registry, uint32_t id
|
||||
output =
|
||||
wl_registry_bind(display_wayland->wl_registry, id, &wl_output_interface, 1);
|
||||
_gdk_wayland_screen_add_output(display_wayland->screen, output);
|
||||
/* We need to roundtrip until we've received the modes and
|
||||
* geometry events for the output, which gives us the physical
|
||||
* properties and available modes on the output. */
|
||||
display_wayland->init_ref_count++;
|
||||
} else if (strcmp(interface, "wl_seat") == 0) {
|
||||
seat = wl_registry_bind(display_wayland->wl_registry, id, &wl_seat_interface, 1);
|
||||
_gdk_wayland_device_manager_add_device (gdk_display->device_manager,
|
||||
seat);
|
||||
/* We need to roundtrip until we've received the wl_seat
|
||||
* capabilities event which informs us of available input devices
|
||||
* on this seat. */
|
||||
display_wayland->init_ref_count++;
|
||||
} else if (strcmp(interface, "wl_data_device_manager") == 0) {
|
||||
display_wayland->data_device_manager =
|
||||
wl_registry_bind(display_wayland->wl_registry, id,
|
||||
@ -164,7 +173,11 @@ _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, ®istry_listener, display_wayland);
|
||||
|
||||
wl_display_dispatch(display_wayland->wl_display);
|
||||
/* We use init_ref_count to track whether some part of our
|
||||
* initialization still needs a roundtrip to complete. */
|
||||
display_wayland->init_ref_count = 1;
|
||||
while (display_wayland->init_ref_count > 0)
|
||||
wl_display_roundtrip(display_wayland->wl_display);
|
||||
|
||||
display_wayland->event_source =
|
||||
_gdk_wayland_display_event_source_new (display);
|
||||
|
@ -66,6 +66,8 @@ struct _GdkWaylandDisplay
|
||||
|
||||
GSource *event_source;
|
||||
|
||||
int init_ref_count;
|
||||
|
||||
struct xkb_context *xkb_context;
|
||||
};
|
||||
|
||||
|
@ -79,6 +79,7 @@ struct _GdkWaylandScreenClass
|
||||
|
||||
struct _GdkWaylandMonitor
|
||||
{
|
||||
GdkWaylandScreen *screen;
|
||||
struct wl_output *output;
|
||||
GdkRectangle geometry;
|
||||
int width_mm;
|
||||
@ -859,6 +860,7 @@ output_handle_geometry(void *data,
|
||||
int32_t transform)
|
||||
{
|
||||
GdkWaylandMonitor *monitor = (GdkWaylandMonitor *)data;
|
||||
GdkWaylandDisplay *display = GDK_WAYLAND_DISPLAY (monitor->screen->display);
|
||||
|
||||
monitor->geometry.x = x;
|
||||
monitor->geometry.y = y;
|
||||
@ -868,6 +870,10 @@ output_handle_geometry(void *data,
|
||||
|
||||
monitor->manufacturer = g_strdup (make);
|
||||
monitor->output_name = g_strdup (model);
|
||||
|
||||
/* Once we have the geometry event we know we have all events
|
||||
* from the wl_output and need no further init roundtrips. */
|
||||
display->init_ref_count--;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -901,6 +907,7 @@ _gdk_wayland_screen_add_output (GdkScreen *screen,
|
||||
GdkWaylandMonitor *monitor = g_new0(GdkWaylandMonitor, 1);
|
||||
|
||||
monitor->output = output;
|
||||
monitor->screen = screen_wayland;
|
||||
g_ptr_array_add(screen_wayland->monitors, monitor);
|
||||
|
||||
wl_output_add_listener(output, &output_listener, monitor);
|
||||
|
Loading…
Reference in New Issue
Block a user