To avoid deadlocks where the X server is blocked on a roundtrip for information from the compositor, and the compositor is blocked waiting for connection information from the X server in window manager init, wait for a signal from the X server saying that it's now waiting for clients to connect.
Requires a protocol version bump. Signed-off-by: Daniel Stone <[email protected]> --- protocol/xserver.xml | 4 +++- src/xwayland/launcher.c | 9 +++++---- src/xwayland/window-manager.c | 21 ++++++++++++++++++--- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/protocol/xserver.xml b/protocol/xserver.xml index 9e25f5c..2900fef 100644 --- a/protocol/xserver.xml +++ b/protocol/xserver.xml @@ -1,6 +1,6 @@ <protocol name="xserver"> - <interface name="xserver" version="1"> + <interface name="xserver" version="2"> <request name="set_window_id"> <arg name="surface" type="object" interface="wl_surface"/> <arg name="id" type="uint"/> @@ -13,6 +13,8 @@ <event name="listen_socket"> <arg name="fd" type="fd"/> </event> + + <request name="init_complete"/> </interface> </protocol> diff --git a/src/xwayland/launcher.c b/src/xwayland/launcher.c index 00f064e..63986b0 100644 --- a/src/xwayland/launcher.c +++ b/src/xwayland/launcher.c @@ -162,10 +162,11 @@ bind_xserver(struct wl_client *client, wl_client_add_object(client, &xserver_interface, &xserver_implementation, id, wxs); - wxs->wm = weston_wm_create(wxs); - if (wxs->wm == NULL) { - weston_log("failed to create wm\n"); - } + /* init_complete() wasn't added until version 2. Try to do + * our best with v1, even if it does usually mean a + * deadlock. */ + if (version == 1) + wxs->wm = weston_wm_create(wxs); xserver_send_listen_socket(wxs->resource, wxs->abstract_fd); xserver_send_listen_socket(wxs->resource, wxs->unix_fd); diff --git a/src/xwayland/window-manager.c b/src/xwayland/window-manager.c index 57b4e3c..4d44527 100644 --- a/src/xwayland/window-manager.c +++ b/src/xwayland/window-manager.c @@ -811,8 +811,9 @@ weston_wm_handle_property_notify(struct weston_wm *wm, xcb_generic_event_t *even read_and_dump_property(wm, property_notify->window, property_notify->atom); - if (property_notify->atom == wm->atom.net_wm_name || - property_notify->atom == XCB_ATOM_WM_NAME) + if (window && + (property_notify->atom == wm->atom.net_wm_name || + property_notify->atom == XCB_ATOM_WM_NAME)) weston_wm_window_schedule_repaint(window); } @@ -886,6 +887,8 @@ weston_wm_handle_destroy_notify(struct weston_wm *wm, xcb_generic_event_t *event return; window = hash_table_lookup(wm->window_hash, destroy_notify->window); + if (!window) + return; weston_wm_window_destroy(window); } @@ -1686,6 +1689,18 @@ xserver_set_window_id(struct wl_client *client, struct wl_resource *resource, xserver_map_shell_surface(wm, window); } +static void xserver_init_complete(struct wl_client *client, + struct wl_resource *resource) +{ + struct weston_xserver *wxs = resource->data; + + wxs->wm = weston_wm_create(wxs); + if (!wxs->wm) + wl_resource_post_error(resource, WL_DISPLAY_ERROR_NO_MEMORY, + "failed to start window manager\n"); +} + const struct xserver_interface xserver_implementation = { - xserver_set_window_id + xserver_set_window_id, + xserver_init_complete }; -- 1.7.10.4 _______________________________________________ wayland-devel mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/wayland-devel
