[PATCH weston] xwm: don't let X windows steal the focus
Giulio Camuffo
giuliocamuffo at gmail.com
Sun Mar 29 04:18:18 PDT 2015
When we get a focus in event from an X window which is not the one
we last set as the active window, reset the focus.
---
xwayland/window-manager.c | 44 +++++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 1e4abbb..e8f94f7 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -694,18 +694,11 @@ weston_wm_create_surface(struct wl_listener *listener, void *data)
}
static void
-weston_wm_window_activate(struct wl_listener *listener, void *data)
+weston_wm_send_focus_window(struct weston_wm *wm,
+ struct weston_wm_window *window)
{
- struct weston_surface *surface = data;
- struct weston_wm_window *window = NULL;
- struct weston_wm *wm =
- container_of(listener, struct weston_wm, activate_listener);
xcb_client_message_event_t client_message;
- if (surface) {
- window = get_wm_window(surface);
- }
-
if (window) {
if (window->override_redirect)
return;
@@ -717,7 +710,7 @@ weston_wm_window_activate(struct wl_listener *listener, void *data)
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_send_event(wm->conn, 0, window->id,
XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT,
(char *) &client_message);
@@ -729,6 +722,21 @@ weston_wm_window_activate(struct wl_listener *listener, void *data)
XCB_NONE,
XCB_TIME_CURRENT_TIME);
}
+}
+
+static void
+weston_wm_window_activate(struct wl_listener *listener, void *data)
+{
+ struct weston_surface *surface = data;
+ struct weston_wm_window *window = NULL;
+ struct weston_wm *wm =
+ container_of(listener, struct weston_wm, activate_listener);
+
+ if (surface) {
+ window = get_wm_window(surface);
+ }
+
+ weston_wm_send_focus_window(wm, window);
if (wm->focus_window) {
if (wm->focus_window->frame)
@@ -1139,7 +1147,8 @@ weston_wm_window_create(struct weston_wm *wm,
geometry_cookie = xcb_get_geometry(wm->conn, id);
- values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE;
+ values[0] = XCB_EVENT_MASK_PROPERTY_CHANGE |
+ XCB_EVENT_MASK_FOCUS_CHANGE;
xcb_change_window_attributes(wm->conn, id, XCB_CW_EVENT_MASK, values);
window->wm = wm;
@@ -1827,6 +1836,16 @@ weston_wm_handle_leave(struct weston_wm *wm, xcb_generic_event_t *event)
weston_wm_window_set_cursor(wm, window->frame_id, XWM_CURSOR_LEFT_PTR);
}
+static void
+weston_wm_handle_focus_in(struct weston_wm *wm, xcb_generic_event_t *event)
+{
+ xcb_focus_in_event_t *focus = (xcb_focus_in_event_t *) event;
+ /* Do not let X clients change the focus behind the compositor's
+ * back. Reset the focus to the old one if it changed. */
+ if (focus->event != (wm->focus_window ? wm->focus_window->id : 0))
+ weston_wm_send_focus_window(wm, wm->focus_window);
+}
+
static int
weston_wm_handle_event(int fd, uint32_t mask, void *data)
{
@@ -1894,6 +1913,9 @@ weston_wm_handle_event(int fd, uint32_t mask, void *data)
case XCB_CLIENT_MESSAGE:
weston_wm_handle_client_message(wm, event);
break;
+ case XCB_FOCUS_IN:
+ weston_wm_handle_focus_in(wm, event);
+ break;
}
free(event);
--
2.3.4
More information about the wayland-devel
mailing list