]> git.sur5r.net Git - i3/i3/commitdiff
re-add focus follows mouse handling
authorMichael Stapelberg <michael@stapelberg.de>
Tue, 13 Apr 2010 16:43:37 +0000 (18:43 +0200)
committerMichael Stapelberg <michael@stapelberg.de>
Tue, 13 Apr 2010 16:43:37 +0000 (18:43 +0200)
include/handlers.h
include/util.h
src/cfgparse.y
src/config.c
src/handlers.c
src/nc.c
src/util.c

index f4aaf58224c9760fe80c418a0a17025cdf3546b7..a691b35a3c69cb12cc1609bbbed2875d9038b428 100644 (file)
@@ -21,7 +21,6 @@
 int handle_key_press(void *ignored, xcb_connection_t *conn,
                      xcb_key_press_event_t *event);
 
-#if 0
 /**
  * When the user moves the mouse pointer onto a window, this callback gets
  * called.
@@ -30,6 +29,7 @@ int handle_key_press(void *ignored, xcb_connection_t *conn,
 int handle_enter_notify(void *ignored, xcb_connection_t *conn,
                         xcb_enter_notify_event_t *event);
 
+#if 0
 /**
  * When the user moves the mouse but does not change the active window
  * (e.g. when having no windows opened but moving mouse on the root screen
index 5d954d39a217a3f7c1bae94fa33c8d1576475b12..cca6985db674fc3192b325041dcf45e5ef1c80cf 100644 (file)
@@ -36,6 +36,7 @@ while (0)
 
 int min(int a, int b);
 int max(int a, int b);
+bool rect_contains(Rect rect, uint32_t x, uint32_t y);
 
 /**
  * Updates *destination with new_value and returns true if it was changed or false
index 19bfaec10f87ae42d36d924f9d7c00536539d315..99367adbd0126d081e5d25fce8042cea0a54a5f0 100644 (file)
@@ -486,6 +486,7 @@ workspace_name:
 assign:
         TOKASSIGN WHITESPACE window_class WHITESPACE optional_arrow assign_target
         {
+#if 0
                 printf("assignment of %s\n", $<string>3);
 
                 struct Assignment *new = $<assignment>6;
@@ -493,29 +494,36 @@ assign:
                 printf("  floating = %d\n", new->floating);
                 new->windowclass_title = $<string>3;
                 TAILQ_INSERT_TAIL(&assignments, new, assignments);
+#endif
         }
         ;
 
 assign_target:
         NUMBER
         {
+#if 0
                 struct Assignment *new = scalloc(sizeof(struct Assignment));
                 new->workspace = $<number>1;
                 new->floating = ASSIGN_FLOATING_NO;
                 $<assignment>$ = new;
+#endif
         }
         | '~'
         {
+#if 0
                 struct Assignment *new = scalloc(sizeof(struct Assignment));
                 new->floating = ASSIGN_FLOATING_ONLY;
                 $<assignment>$ = new;
+#endif
         }
         | '~' NUMBER
         {
+#if 0
                 struct Assignment *new = scalloc(sizeof(struct Assignment));
                 new->workspace = $<number>2;
                 new->floating = ASSIGN_FLOATING;
                 $<assignment>$ = new;
+#endif
         }
         ;
 
index 60c11fe749993ad4b7a858f4d7bdb3413b23f225..2e611e953eae4c4981f93d56ebe585a7a231c8ef 100644 (file)
@@ -305,6 +305,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
                         SLIST_REMOVE(&modes, mode, Mode, modes);
                 }
 
+#if 0
                 struct Assignment *assign;
                 while (!TAILQ_EMPTY(&assignments)) {
                         assign = TAILQ_FIRST(&assignments);
@@ -312,6 +313,7 @@ void load_configuration(xcb_connection_t *conn, const char *override_configpath,
                         TAILQ_REMOVE(&assignments, assign, assignments);
                         FREE(assign);
                 }
+#endif
 
                 /* Clear workspace names */
 #if 0
index b56095409440fdcfc8ef26c885e6877d76de4bea..80f1e66995a5eadbc80769bba1449efe9af103ca 100644 (file)
 static SLIST_HEAD(ignore_head, Ignore_Event) ignore_events;
 
 static void add_ignore_event(const int sequence) {
-        struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
+    struct Ignore_Event *event = smalloc(sizeof(struct Ignore_Event));
 
-        event->sequence = sequence;
-        event->added = time(NULL);
+    event->sequence = sequence;
+    event->added = time(NULL);
 
-        SLIST_INSERT_HEAD(&ignore_events, event, ignore_events);
+    SLIST_INSERT_HEAD(&ignore_events, event, ignore_events);
 }
 
 /*
@@ -33,26 +33,27 @@ static void add_ignore_event(const int sequence) {
  *
  */
 static bool event_is_ignored(const int sequence) {
-        struct Ignore_Event *event;
-        time_t now = time(NULL);
-        for (event = SLIST_FIRST(&ignore_events); event != SLIST_END(&ignore_events);) {
-                if ((now - event->added) > 5) {
-                        struct Ignore_Event *save = event;
-                        event = SLIST_NEXT(event, ignore_events);
-                        SLIST_REMOVE(&ignore_events, save, Ignore_Event, ignore_events);
-                        free(save);
-                } else event = SLIST_NEXT(event, ignore_events);
-        }
-
-        SLIST_FOREACH(event, &ignore_events, ignore_events) {
-                if (event->sequence == sequence) {
-                        SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
-                        free(event);
-                        return true;
-                }
-        }
+    struct Ignore_Event *event;
+    time_t now = time(NULL);
+    for (event = SLIST_FIRST(&ignore_events); event != SLIST_END(&ignore_events);) {
+        if ((now - event->added) > 5) {
+            struct Ignore_Event *save = event;
+            event = SLIST_NEXT(event, ignore_events);
+            SLIST_REMOVE(&ignore_events, save, Ignore_Event, ignore_events);
+            free(save);
+        } else event = SLIST_NEXT(event, ignore_events);
+    }
+
+    SLIST_FOREACH(event, &ignore_events, ignore_events) {
+        if (event->sequence != sequence)
+            continue;
+
+        SLIST_REMOVE(&ignore_events, event, Ignore_Event, ignore_events);
+        free(event);
+        return true;
+    }
 
-        return false;
+    return false;
 }
 
 /*
@@ -140,68 +141,78 @@ static void check_crossing_screen_boundary(uint32_t x, uint32_t y) {
         if (first_client != NULL)
                 set_focus(global_conn, first_client, true);
 }
+#endif
 
 /*
  * When the user moves the mouse pointer onto a window, this callback gets called.
  *
  */
-int handle_enter_notify(void *ignored, xcb_connection_t *conn, xcb_enter_notify_event_t *event) {
-        DLOG("enter_notify for %08x, mode = %d, detail %d, serial %d\n", event->event, event->mode, event->detail, event->sequence);
-        if (event->mode != XCB_NOTIFY_MODE_NORMAL) {
-                DLOG("This was not a normal notify, ignoring\n");
-                return 1;
-        }
-        /* 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))
-                return 1;
+int handle_enter_notify(void *ignored, xcb_connection_t *conn,
+                        xcb_enter_notify_event_t *event) {
+    Con *con;
 
-        /* This was either a focus for a client’s parent (= titlebar)… */
-        Client *client = table_get(&by_parent, event->event);
-        /* …or the client itself */
-        if (client == NULL)
-                client = table_get(&by_child, event->event);
+    DLOG("enter_notify for %08x, mode = %d, detail %d, serial %d\n",
+         event->event, event->mode, event->detail, event->sequence);
+    DLOG("coordinates %x, %x\n", event->event_x, event->event_y);
+    if (event->mode != XCB_NOTIFY_MODE_NORMAL) {
+        DLOG("This was not a normal notify, ignoring\n");
+        return 1;
+    }
+    /* 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))
+        return 1;
 
-        /* Check for stack windows */
-        if (client == NULL) {
-                struct Stack_Window *stack_win;
-                SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
-                        if (stack_win->window == event->event) {
-                                client = stack_win->container->currently_focused;
-                                break;
-                        }
-        }
+    /* Get container by frame or by child window */
+    if ((con = con_by_frame_id(event->event)) == NULL)
+        con = con_by_window_id(event->event);
 
+    /* If not, then the user moved his cursor to the root window. In that case, we adjust c_ws */
+    if (con == NULL) {
+        DLOG("Getting screen at %d x %d\n", event->root_x, event->root_y);
+        //check_crossing_screen_boundary(event->root_x, event->root_y);
+        return 1;
+    }
 
-        /* If not, then the user moved his cursor to the root window. In that case, we adjust c_ws */
-        if (client == NULL) {
-                DLOG("Getting screen at %d x %d\n", event->root_x, event->root_y);
-                check_crossing_screen_boundary(event->root_x, event->root_y);
-                return 1;
-        }
+    /* see if the user entered the window on a certain window decoration */
+    int 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);
+    }
 
-        /* Do plausibility checks: This event may be useless for us if it occurs on a window
-           which is in a stacked container but not the focused one */
-        if (client->container != NULL &&
-            client->container->mode == MODE_STACK &&
-            client->container->currently_focused != client) {
-                DLOG("Plausibility check says: no\n");
-                return 1;
-        }
+#if 0
+    if (client->workspace != c_ws && client->workspace->output == c_ws->output) {
+            /* This can happen when a client gets assigned to a different workspace than
+             * the current one (see src/mainx.c:reparent_window). Shortly after it was created,
+             * an enter_notify will follow. */
+            DLOG("enter_notify for a client on a different workspace but the same screen, ignoring\n");
+            return 1;
+    }
+#endif
 
-        if (client->workspace != c_ws && client->workspace->output == c_ws->output) {
-                /* This can happen when a client gets assigned to a different workspace than
-                 * the current one (see src/mainx.c:reparent_window). Shortly after it was created,
-                 * an enter_notify will follow. */
-                DLOG("enter_notify for a client on a different workspace but the same screen, ignoring\n");
-                return 1;
-        }
+    if (config.disable_focus_follows_mouse)
+        return 1;
+    Con *next = con;
+    while (!TAILQ_EMPTY(&(next->focus_head)))
+        next = TAILQ_FIRST(&(next->focus_head));
 
-        if (!config.disable_focus_follows_mouse)
-                set_focus(conn, client, false);
+    con_focus(next);
+    x_push_changes(croot);
 
-        return 1;
+    return 1;
 }
+#if 0
 
 /*
  * When the user moves the mouse but does not change the active window
index e1b8a409291d318959b39b52b3133bcd485edded..68646c873ad2319dec0eaf33f9fd06633ae6ffc7 100644 (file)
--- a/src/nc.c
+++ b/src/nc.c
@@ -139,7 +139,11 @@ void parse_command(const char *command) {
         tree_next('n', VERT);
     else if (strncasecmp(command, "workspace ", strlen("workspace ")) == 0)
         workspace_show(command + strlen("workspace "));
+    else if (strcasecmp(command, "stack") == 0) {
+        focused->layout = L_STACKED;
+        x_push_changes(croot);
 
+    }
     else if (strcasecmp(command, "move before h") == 0)
         tree_move('p', HORIZ);
     else if (strcasecmp(command, "move before v") == 0)
@@ -312,6 +316,9 @@ int main(int argc, char *argv[]) {
 
     xcb_event_set_expose_handler(&evenths, handle_expose_event, NULL);
 
+    /* Enter window = user moved his mouse over the window */
+    xcb_event_set_enter_notify_handler(&evenths, handle_enter_notify, NULL);
+
 
     /* Setup NetWM atoms */
     #define GET_ATOM(name) \
index cf8f8df69bda9aaf244cf1f70955903492e6b0ba..c8f4ee389492962b8817b8be39737dcbed20362a 100644 (file)
@@ -31,6 +31,13 @@ int max(int a, int b) {
         return (a > b ? a : b);
 }
 
+bool rect_contains(Rect rect, uint32_t x, uint32_t y) {
+        return (x >= rect.x &&
+                x <= (rect.x + rect.width) &&
+                y >= rect.y &&
+                y <= (rect.y + rect.height));
+}
+
 /*
  * Updates *destination with new_value and returns true if it was changed or false
  * if it was the same