]> git.sur5r.net Git - i3/i3/commitdiff
Only send WM_TAKE_FOCUS when the client supports it in the protocols atom
authorMichael Stapelberg <michael@stapelberg.de>
Fri, 18 Mar 2011 16:07:56 +0000 (17:07 +0100)
committerMichael Stapelberg <michael@stapelberg.de>
Fri, 18 Mar 2011 16:07:56 +0000 (17:07 +0100)
Fixes opening xterm, for example

include/data.h
include/x.h
include/xcb.h
src/manage.c
src/x.c
src/xcb.c

index 8beb91ab5f7f73a8d020afb55f8ac25d73f0b454..088561c416c54246ee0706682bdc2493d51762ed 100644 (file)
@@ -246,6 +246,9 @@ struct Window {
     /** Whether the application used _NET_WM_NAME */
     bool uses_net_wm_name;
 
+    /** Whether the application needs to receive WM_TAKE_FOCUS */
+    bool needs_take_focus;
+
     /** Whether the window says it is a dock window */
     enum { W_NODOCK = 0, W_DOCK_TOP = 1, W_DOCK_BOTTOM = 2 } dock;
 
index 43b0814b14d4e6384f4dccfbfad6133ecb8a33b4..da4147cc64abe3e41bab28dd609b6f9c58f18ea0 100644 (file)
@@ -39,6 +39,12 @@ void x_reinit(Con *con);
  */
 void x_con_kill(Con *con);
 
+/**
+ * Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
+ *
+ */
+bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom);
+
 /**
  * Kills the given X11 window using WM_DELETE_WINDOW (if supported).
  *
index bec06b06269e88821729095947733634477e2b7d..4a09766fe478aeb4bd49e842489de15f8de3fcc4 100644 (file)
@@ -116,6 +116,12 @@ void fake_configure_notify(xcb_connection_t *conn, Rect r, xcb_window_t window);
  */
 void fake_absolute_configure_notify(Con *con);
 
+/**
+ * Sends the WM_TAKE_FOCUS ClientMessage to the given window
+ *
+ */
+void send_take_focus(xcb_window_t window);
+
 /**
  * Finds out which modifier mask is the one for numlock, as the user may
  * change this.
index 4821e28f76451e393b925adb8cab6cca6b634913..ac199468d339221ecd3bddb1a9694f3061be45d1 100644 (file)
@@ -156,6 +156,9 @@ void manage_window(xcb_window_t window, xcb_get_window_attributes_cookie_t cooki
     window_update_transient_for(cwindow, xcb_get_property_reply(conn, transient_cookie, NULL));
     window_update_strut_partial(cwindow, xcb_get_property_reply(conn, strut_cookie, NULL));
 
+    /* check if the window needs WM_TAKE_FOCUS */
+    cwindow->needs_take_focus = window_supports_protocol(cwindow->id, A_WM_TAKE_FOCUS);
+
     /* Where to start searching for a container that swallows the new one? */
     Con *search_at = croot;
 
diff --git a/src/x.c b/src/x.c
index 374fd1626ca12073d0f191d014c71a9f563e46d6..21e9b14e15c419b3a54b652843533c963ab784bf 100644 (file)
--- a/src/x.c
+++ b/src/x.c
@@ -178,7 +178,7 @@ void x_con_kill(Con *con) {
  * Returns true if the client supports the given protocol atom (like WM_DELETE_WINDOW)
  *
  */
-static bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom) {
+bool window_supports_protocol(xcb_window_t window, xcb_atom_t atom) {
     xcb_get_property_cookie_t cookie;
     xcb_icccm_get_wm_protocols_reply_t protocols;
     bool result = false;
@@ -618,19 +618,10 @@ void x_push_changes(Con *con) {
             xcb_set_input_focus(conn, XCB_INPUT_FOCUS_POINTER_ROOT, to_focus, XCB_CURRENT_TIME);
 
             /* TODO: check if that client acccepts WM_TAKE_FOCUS at all */
-            xcb_client_message_event_t ev;
-
-            memset(&ev, 0, sizeof(xcb_client_message_event_t));
-
-            ev.response_type = XCB_CLIENT_MESSAGE;
-            ev.window = to_focus;
-            ev.type = A_WM_PROTOCOLS;
-            ev.format = 32;
-            ev.data.data32[0] = A_WM_TAKE_FOCUS;
-            ev.data.data32[1] = XCB_CURRENT_TIME;
-
-            DLOG("Sending WM_TAKE_FOCUS to the client\n");
-            xcb_send_event(conn, false, to_focus, XCB_EVENT_MASK_NO_EVENT, (char*)&ev);
+            if (focused->window != NULL &&
+                focused->window->needs_take_focus) {
+                send_take_focus(to_focus);
+            }
 
             ewmh_update_active_window(to_focus);
             focused_id = to_focus;
index aaad590d97a871fc33a0fafced0722496d8d1a89..7382cc615efe91f718890c812e2b9e38e91a86f3 100644 (file)
--- a/src/xcb.c
+++ b/src/xcb.c
@@ -206,6 +206,26 @@ void fake_absolute_configure_notify(Con *con) {
     fake_configure_notify(conn, absolute, con->window->id);
 }
 
+/*
+ * Sends the WM_TAKE_FOCUS ClientMessage to the given window
+ *
+ */
+void send_take_focus(xcb_window_t window) {
+    xcb_client_message_event_t ev;
+
+    memset(&ev, 0, sizeof(xcb_client_message_event_t));
+
+    ev.response_type = XCB_CLIENT_MESSAGE;
+    ev.window = window;
+    ev.type = A_WM_PROTOCOLS;
+    ev.format = 32;
+    ev.data.data32[0] = A_WM_TAKE_FOCUS;
+    ev.data.data32[1] = XCB_CURRENT_TIME;
+
+    DLOG("Sending WM_TAKE_FOCUS to the client\n");
+    xcb_send_event(conn, false, window, XCB_EVENT_MASK_NO_EVENT, (char*)&ev);
+}
+
 /*
  * Finds out which modifier mask is the one for numlock, as the user may change this.
  *