x11: Manage xserver focus better

dev
Kristian Høgsberg 13 years ago
parent 707e10fa75
commit d6e5525a20
  1. 2
      compositor/compositor.h
  2. 3
      compositor/shell.c
  3. 60
      compositor/xserver-launcher.c

@ -421,5 +421,7 @@ int
wlsc_xserver_init(struct wlsc_compositor *compositor); wlsc_xserver_init(struct wlsc_compositor *compositor);
void void
wlsc_xserver_destroy(struct wlsc_compositor *compositor); wlsc_xserver_destroy(struct wlsc_compositor *compositor);
void
wlsc_xserver_surface_activate(struct wlsc_surface *surface);
#endif #endif

@ -892,6 +892,9 @@ activate(struct wlsc_shell *base, struct wlsc_surface *es,
wlsc_surface_activate(es, device, time); wlsc_surface_activate(es, device, time);
if (compositor->wxs)
wlsc_xserver_surface_activate(es);
if (es == shell->background) { if (es == shell->background) {
wl_list_remove(&es->link); wl_list_remove(&es->link);
wl_list_insert(compositor->surface_list.prev, &es->link); wl_list_insert(compositor->surface_list.prev, &es->link);

@ -92,6 +92,9 @@ struct wlsc_wm_window {
struct wl_listener surface_destroy_listener; struct wl_listener surface_destroy_listener;
}; };
static struct wlsc_wm_window *
get_wm_window(struct wlsc_surface *surface);
static void static void
wlsc_wm_handle_configure_request(struct wlsc_wm *wm, xcb_generic_event_t *event) 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, wlsc_wm_activate(struct wlsc_wm *wm,
struct wlsc_wm_window *window, xcb_timestamp_t time) 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_set_input_focus (wm->conn,
XCB_INPUT_FOCUS_POINTER_ROOT, window->id, time); 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 static void
wlsc_wm_handle_map_request(struct wlsc_wm *wm, xcb_generic_event_t *event) 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 *map_notify =
(xcb_map_notify_event_t *) event; (xcb_map_notify_event_t *) event;
struct wlsc_wm_window *window; struct wlsc_wm_window *window;
xcb_client_message_event_t client_message;
fprintf(stderr, "XCB_MAP_NOTIFY\n"); 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); window = wl_hash_table_lookup(wm->window_hash, map_notify->window);
wlsc_wm_activate(wm, window, XCB_TIME_CURRENT_TIME); 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 static void
@ -591,6 +609,22 @@ surface_destroy(struct wl_listener *listener,
fprintf(stderr, "surface for xid %d destroyed\n", window->id); 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 static void
xserver_set_window_id(struct wl_client *client, struct wl_resource *resource, xserver_set_window_id(struct wl_client *client, struct wl_resource *resource,
struct wl_resource *surface_resource, uint32_t id) struct wl_resource *surface_resource, uint32_t id)

Loading…
Cancel
Save