summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiulio Camuffo <giuliocamuffo@gmail.com>2015-03-29 14:20:23 +0300
committerDaniel Stone <daniels@collabora.com>2015-08-06 16:39:42 +0100
commitb18f788e2e7476840eac54b0e7ac30a0244e4528 (patch)
tree8bd7a253c589f914b5bd1448a52751edbce86dd6
parent75ead05dd2aa917c34bfe312f7e3c1a7944cda9a (diff)
xwm: don't let X windows steal the focus
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. Reviewed-by: Bryce Harrington <bryce@osg.samsung.com> Reviewed-by: Daniel Stone <daniels@collabora.com>
-rw-r--r--xwayland/window-manager.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/xwayland/window-manager.c b/xwayland/window-manager.c
index 03adaa6c..5062cc9b 100644
--- a/xwayland/window-manager.c
+++ b/xwayland/window-manager.c
@@ -734,18 +734,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) {
uint32_t values[1];
@@ -775,6 +768,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)
@@ -1185,7 +1193,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;
@@ -1884,6 +1893,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 (!wm->focus_window || focus->event != wm->focus_window->id)
+ weston_wm_send_focus_window(wm, wm->focus_window);
+}
+
static int
weston_wm_handle_event(int fd, uint32_t mask, void *data)
{
@@ -1951,6 +1970,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);