diff --git a/compositor/compositor.h b/compositor/compositor.h index 24c95837..35aaf553 100644 --- a/compositor/compositor.h +++ b/compositor/compositor.h @@ -421,5 +421,7 @@ int wlsc_xserver_init(struct wlsc_compositor *compositor); void wlsc_xserver_destroy(struct wlsc_compositor *compositor); +void +wlsc_xserver_surface_activate(struct wlsc_surface *surface); #endif diff --git a/compositor/shell.c b/compositor/shell.c index 2dfe95b0..05ba7b79 100644 --- a/compositor/shell.c +++ b/compositor/shell.c @@ -892,6 +892,9 @@ activate(struct wlsc_shell *base, struct wlsc_surface *es, wlsc_surface_activate(es, device, time); + if (compositor->wxs) + wlsc_xserver_surface_activate(es); + if (es == shell->background) { wl_list_remove(&es->link); wl_list_insert(compositor->surface_list.prev, &es->link); diff --git a/compositor/xserver-launcher.c b/compositor/xserver-launcher.c index a5362582..6dbf2a5d 100644 --- a/compositor/xserver-launcher.c +++ b/compositor/xserver-launcher.c @@ -92,6 +92,9 @@ struct wlsc_wm_window { struct wl_listener surface_destroy_listener; }; +static struct wlsc_wm_window * +get_wm_window(struct wlsc_surface *surface); + static void wlsc_wm_handle_configure_request(struct wlsc_wm *wm, xcb_generic_event_t *event) { @@ -187,10 +190,38 @@ static void wlsc_wm_activate(struct wlsc_wm *wm, struct wlsc_wm_window *window, xcb_timestamp_t time) { + xcb_client_message_event_t client_message; + + client_message.response_type = XCB_CLIENT_MESSAGE; + client_message.format = 32; + client_message.window = window->id; + client_message.type = wm->atom.wm_protocols; + client_message.data.data32[0] = wm->atom.wm_take_focus; + client_message.data.data32[1] = XCB_TIME_CURRENT_TIME; + + xcb_send_event(wm->conn, 0, window->id, + XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, + (char *) &client_message); + xcb_set_input_focus (wm->conn, XCB_INPUT_FOCUS_POINTER_ROOT, window->id, time); } +WL_EXPORT void +wlsc_xserver_surface_activate(struct wlsc_surface *surface) +{ + struct wlsc_wm_window *window = get_wm_window(surface); + struct wlsc_xserver *wxs = surface->compositor->wxs; + + if (window == NULL && wxs && wxs->wm) + xcb_set_input_focus (wxs->wm->conn, + XCB_INPUT_FOCUS_POINTER_ROOT, + XCB_NONE, + XCB_TIME_CURRENT_TIME); + else + wlsc_wm_activate(wxs->wm, window, XCB_TIME_CURRENT_TIME); +} + static void wlsc_wm_handle_map_request(struct wlsc_wm *wm, xcb_generic_event_t *event) { @@ -214,7 +245,6 @@ wlsc_wm_handle_map_notify(struct wlsc_wm *wm, xcb_generic_event_t *event) xcb_map_notify_event_t *map_notify = (xcb_map_notify_event_t *) event; struct wlsc_wm_window *window; - xcb_client_message_event_t client_message; fprintf(stderr, "XCB_MAP_NOTIFY\n"); @@ -222,18 +252,6 @@ wlsc_wm_handle_map_notify(struct wlsc_wm *wm, xcb_generic_event_t *event) window = wl_hash_table_lookup(wm->window_hash, map_notify->window); wlsc_wm_activate(wm, window, XCB_TIME_CURRENT_TIME); - - client_message.response_type = XCB_CLIENT_MESSAGE; - client_message.format = 32; - client_message.window = window->id; - client_message.type = wm->atom.wm_protocols; - client_message.data.data32[0] = wm->atom.wm_take_focus; - client_message.data.data32[1] = XCB_TIME_CURRENT_TIME; - - xcb_send_event(wm->conn, 0, window->id, - XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT, - (char *) &client_message); - } static void @@ -591,6 +609,22 @@ surface_destroy(struct wl_listener *listener, fprintf(stderr, "surface for xid %d destroyed\n", window->id); } +static struct wlsc_wm_window * +get_wm_window(struct wlsc_surface *surface) +{ + struct wl_resource *resource = &surface->surface.resource; + struct wl_listener *listener; + + wl_list_for_each(listener, &resource->destroy_listener_list, link) { + if (listener->func == surface_destroy) + return container_of(listener, + struct wlsc_wm_window, + surface_destroy_listener); + } + + return NULL; +} + static void xserver_set_window_id(struct wl_client *client, struct wl_resource *resource, struct wl_resource *surface_resource, uint32_t id)