]> git.sur5r.net Git - i3/i3/blobdiff - src/handlers.c
Bugfix: Fix focus follows mouse for non-default layout cons (Thanks phnom)
[i3/i3] / src / handlers.c
index f1c6128b750aa42cffc2bb91978c5cd17403b479..c63f236c1c8510571d82dd824c257f578ac6fa1f 100644 (file)
@@ -21,10 +21,11 @@ int randr_base = -1;
    changing workspaces */
 static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events;
 
-void add_ignore_event(const int sequence) {
+void add_ignore_event(const int sequence, const int response_type) {
     struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
 
     event->sequence = sequence;
+    event->response_type = response_type;
     event->added = time(NULL);
 
     SLIST_INSERT_HEAD(&ignore_events, event, ignore_events);
@@ -34,7 +35,7 @@ void add_ignore_event(const int sequence) {
  * Checks if the given sequence is ignored and returns true if so.
  *
  */
-static bool event_is_ignored(const int sequence) {
+static bool event_is_ignored(const int sequence, const int response_type) {
     struct Ignore_Event *event;
     time_t now = time(NULL);
     for (event = SLIST_FIRST(&ignore_events); event != SLIST_END(&ignore_events);) {
@@ -50,6 +51,10 @@ static bool event_is_ignored(const int sequence) {
         if (event->sequence != sequence)
             continue;
 
+        if (event->response_type != 0 &&
+            event->response_type != response_type)
+            continue;
+
         /* instead of removing a sequence number we better wait until it gets
          * garbage collected. it may generate multiple events (there are multiple
          * enter_notifies for one configure_request, for example). */
@@ -153,8 +158,10 @@ static int handle_enter_notify(xcb_enter_notify_event_t *event) {
     }
     /* Some events are not interesting, because they were not generated
      * actively by the user, but by reconfiguration of windows */
-    if (event_is_ignored(event->sequence))
+    if (event_is_ignored(event->sequence, XCB_ENTER_NOTIFY)) {
+        DLOG("Event ignored\n");
         return 1;
+    }
 
     bool enter_child = false;
     /* Get container by frame or by child window */
@@ -177,19 +184,14 @@ static int handle_enter_notify(xcb_enter_notify_event_t *event) {
 
     /* see if the user entered the window on a certain window decoration */
     int layout = (enter_child ? con->parent->layout : con->layout);
-    Con *child;
-    TAILQ_FOREACH(child, &(con->nodes_head), nodes)
-        if (rect_contains(child->deco_rect, event->event_x, event->event_y)) {
-            LOG("using child %p / %s instead!\n", child, child->name);
-            con = child;
-            break;
-        }
-
-    /* for stacked/tabbed layout we do not want to change focus when the user
-     * enters the window at the decoration of any child window. */
-    if (layout == L_STACKED || layout == L_TABBED) {
-        con = TAILQ_FIRST(&(con->parent->focus_head));
-        LOG("using focused %p / %s instead\n", con, con->name);
+    if (layout == L_DEFAULT) {
+        Con *child;
+        TAILQ_FOREACH(child, &(con->nodes_head), nodes)
+            if (rect_contains(child->deco_rect, event->event_x, event->event_y)) {
+                LOG("using child %p / %s instead!\n", child, child->name);
+                con = child;
+                break;
+            }
     }
 
 #if 0
@@ -285,7 +287,7 @@ static int handle_map_request(xcb_map_request_event_t *event) {
     cookie = xcb_get_window_attributes_unchecked(conn, event->window);
 
     DLOG("window = 0x%08x, serial is %d.\n", event->window, event->sequence);
-    add_ignore_event(event->sequence);
+    add_ignore_event(event->sequence, 0);
 
     manage_window(event->window, cookie, false);
     x_push_changes(croot);
@@ -438,12 +440,9 @@ static int handle_screen_change(xcb_generic_event_t *e) {
  *
  */
 static int handle_unmap_notify_event(xcb_unmap_notify_event_t *event) {
-
-    /* FIXME: we cannot ignore this sequence because more UnmapNotifys with the same sequence
-     * numbers but different window IDs may follow */
     /* we need to ignore EnterNotify events which will be generated because a
      * different window is visible now */
-    //add_ignore_event(event->sequence);
+    add_ignore_event(event->sequence, XCB_ENTER_NOTIFY);
 
     DLOG("UnmapNotify for 0x%08x (received from 0x%08x), serial %d\n", event->window, event->event, event->sequence);
     Con *con = con_by_window_id(event->window);
@@ -809,7 +808,13 @@ static int handle_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_w
     //CLIENT_LOG(con);
     LOG("Urgency flag changed to %d\n", con->urgent);
 
-    workspace_update_urgent_flag(con_get_workspace(con));
+    Con *ws;
+    /* Set the urgency flag on the workspace, if a workspace could be found
+     * (for dock clients, that is not the case). */
+    if ((ws = con_get_workspace(con)) != NULL)
+        workspace_update_urgent_flag(ws);
+
+    tree_render();
 
 #if 0
     /* If the workspace this client is on is not visible, we need to redraw
@@ -896,6 +901,12 @@ static int handle_focus_in(xcb_focus_in_event_t *event) {
         return 1;
     DLOG("That is con %p / %s\n", con, con->name);
 
+    if (event->mode == XCB_NOTIFY_MODE_GRAB ||
+        event->mode == XCB_NOTIFY_MODE_UNGRAB) {
+        DLOG("FocusIn event for grab/ungrab, ignoring\n");
+        return 1;
+    }
+
     if (event->detail == XCB_NOTIFY_DETAIL_POINTER) {
         DLOG("notify detail is pointer, ignoring this event\n");
         return 1;