]> git.sur5r.net Git - i3/i3/blobdiff - src/handlers.c
Added config key for default orientation of containers (new_container_orientation...
[i3/i3] / src / handlers.c
index d8e859b174d8a1aa6cb91c35662c1bf5dd035295..6e6626a9671f275f7a51141b42857fabfb8ced75 100644 (file)
@@ -28,30 +28,6 @@ void add_ignore_event(const int sequence) {
     SLIST_INSERT_HEAD(&ignore_events, event, ignore_events);
 }
 
-/*
- * Unignores the given sequence. Called when unmap events (generated by
- * reparenting) should be ignored and the unmap event actually happens, in
- * order to not ignore too many unmap events (leading to ghost window
- * decorations).
- *
- */
-static void unignore_event(const int sequence) {
-    struct Ignore_Event *event;
-    for (event = SLIST_FIRST(&ignore_events);
-         event != SLIST_END(&ignore_events);
-         event = SLIST_NEXT(event, ignore_events)) {
-        if (event->sequence != sequence)
-            continue;
-
-        DLOG("Unignoring sequence number %d\n", sequence);
-        struct Ignore_Event *save = event;
-        event = SLIST_NEXT(event, ignore_events);
-        SLIST_REMOVE(&ignore_events, save, Ignore_Event, ignore_events);
-        free(save);
-        break;
-    }
-}
-
 /*
  * Checks if the given sequence is ignored and returns true if so.
  *
@@ -126,8 +102,6 @@ int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_
     return 1;
 }
 
-#if 0
-
 /*
  * Called with coordinates of an enter_notify event or motion_notify event
  * to check if the user crossed virtual screen boundaries and adjust the
@@ -135,41 +109,30 @@ int handle_key_press(void *ignored, xcb_connection_t *conn, xcb_key_press_event_
  *
  */
 static void check_crossing_screen_boundary(uint32_t x, uint32_t y) {
-        Output *output;
+    Output *output;
 
-        if ((output = get_output_containing(x, y)) == NULL) {
-                ELOG("ERROR: No such screen\n");
-                return;
-        }
-        if (output == c_ws->output)
-                return;
-
-        c_ws->current_row = current_row;
-        c_ws->current_col = current_col;
-        c_ws = output->current_workspace;
-        current_row = c_ws->current_row;
-        current_col = c_ws->current_col;
-        DLOG("We're now on output %p\n", output);
-
-        /* While usually this function is only called when the user switches
-         * to a different output using his mouse (and thus the output is
-         * empty), it may be that the following race condition occurs:
-         * 1) the user actives a new output (say VGA1).
-         * 2) the cursor is sent to the first pixel of the new VGA1, thus
-         *    generating an enter_notify for the screen (the enter_notify
-         *    is not yet received by i3).
-         * 3) i3 requeries screen configuration and maps a workspace onto the
-         *    new output.
-         * 4) the enter_notify event arrives and c_ws is set to the new
-         *    workspace but the existing windows on the new workspace are not
-         *    focused.
-         *
-         * Therefore, we re-set the focus here to be sure it’s correct. */
-        Client *first_client = SLIST_FIRST(&(c_ws->focus_stack));
-        if (first_client != NULL)
-                set_focus(global_conn, first_client, true);
+    /* If the user disable focus follows mouse, we have nothing to do here */
+    if (config.disable_focus_follows_mouse)
+        return;
+
+    if ((output = get_output_containing(x, y)) == NULL) {
+        ELOG("ERROR: No such screen\n");
+        return;
+    }
+
+    if (output->con == NULL) {
+        ELOG("ERROR: The screen is not recognized by i3 (no container associated)\n");
+        return;
+    }
+
+    /* Focus the output on which the user moved his cursor */
+    Con *old_focused = focused;
+    con_focus(con_descend_focused(output_get_content(output->con)));
+
+    /* If the focus changed, we re-render to get updated decorations */
+    if (old_focused != focused)
+        tree_render();
 }
-#endif
 
 /*
  * When the user moves the mouse pointer onto a window, this callback gets called.
@@ -201,7 +164,12 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn,
     /* 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);
+        check_crossing_screen_boundary(event->root_x, event->root_y);
+        return 1;
+    }
+
+    if (con->parent->type == CT_DOCKAREA) {
+        DLOG("Ignoring, this is a dock client\n");
         return 1;
     }
 
@@ -234,12 +202,9 @@ int handle_enter_notify(void *ignored, xcb_connection_t *conn,
 
     if (config.disable_focus_follows_mouse)
         return 1;
-    Con *next = con;
-    while (!TAILQ_EMPTY(&(next->focus_head)))
-        next = TAILQ_FIRST(&(next->focus_head));
 
-    con_focus(next);
-    x_push_changes(croot);
+    con_focus(con_descend_focused(con));
+    tree_render();
 
     return 1;
 }
@@ -258,8 +223,7 @@ int handle_motion_notify(void *ignored, xcb_connection_t *conn, xcb_motion_notif
 
     Con *con;
     if ((con = con_by_frame_id(event->event)) == NULL) {
-        /* TODO; handle root window: */
-        //check_crossing_screen_boundary(event->root_x, event->root_y);
+        check_crossing_screen_boundary(event->root_x, event->root_y);
         return 1;
     }
 
@@ -287,30 +251,28 @@ int handle_motion_notify(void *ignored, xcb_connection_t *conn, xcb_motion_notif
     return 1;
 }
 
-#if 0
 /*
  * Called when the keyboard mapping changes (for example by using Xmodmap),
  * we need to update our key bindings then (re-translate symbols).
  *
  */
 int handle_mapping_notify(void *ignored, xcb_connection_t *conn, xcb_mapping_notify_event_t *event) {
-        if (event->request != XCB_MAPPING_KEYBOARD &&
-            event->request != XCB_MAPPING_MODIFIER)
-                return 0;
+    if (event->request != XCB_MAPPING_KEYBOARD &&
+        event->request != XCB_MAPPING_MODIFIER)
+        return 0;
 
-        DLOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n");
-        xcb_refresh_keyboard_mapping(keysyms, event);
+    DLOG("Received mapping_notify for keyboard or modifier mapping, re-grabbing keys\n");
+    xcb_refresh_keyboard_mapping(keysyms, event);
 
-        xcb_get_numlock_mask(conn);
+    xcb_get_numlock_mask(conn);
 
-        ungrab_all_keys(conn);
-        translate_keysyms();
-        grab_all_keys(conn, false);
+    ungrab_all_keys(conn);
+    translate_keysyms();
+    grab_all_keys(conn, false);
 
-        return 0;
+    return 0;
 }
 
-#endif
 /*
  * A new window appeared on the screen (=was mapped), so let’s manage it.
  *
@@ -372,8 +334,7 @@ int handle_configure_request(void *prophs, xcb_connection_t *conn, xcb_configure
     DLOG("Configure request!\n");
     if (con_is_floating(con) && con_is_leaf(con)) {
         /* find the height for the decorations */
-        i3Font *font = load_font(conn, config.font);
-        int deco_height = font->height + 5;
+        int deco_height = config.font.height + 5;
         /* we actually need to apply the size/position changes to the *parent*
          * container */
         Rect bsr = con_border_style_rect(con);
@@ -452,6 +413,7 @@ int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_n
 
         return 1;
 }
+#endif
 
 /*
  * Gets triggered upon a RandR screen change event, that is when the user
@@ -460,15 +422,14 @@ int handle_configure_event(void *prophs, xcb_connection_t *conn, xcb_configure_n
  */
 int handle_screen_change(void *prophs, xcb_connection_t *conn,
                          xcb_generic_event_t *e) {
-        DLOG("RandR screen change\n");
+    DLOG("RandR screen change\n");
 
-        randr_query_outputs(conn);
+    randr_query_outputs();
 
-        ipc_send_event("output", I3_IPC_EVENT_OUTPUT, "{\"change\":\"unspecified\"}");
+    ipc_send_event("output", I3_IPC_EVENT_OUTPUT, "{\"change\":\"unspecified\"}");
 
-        return 1;
+    return 1;
 }
-#endif
 
 /*
  * Our window decorations were unmapped. That means, the window will be killed
@@ -643,7 +604,7 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *
         x_draw_decoration(parent);
 
     TAILQ_FOREACH(con, &(parent->nodes_head), nodes) {
-        LOG("expose for con %p / %s\n", con, con->name);
+        DLOG("expose for con %p / %s\n", con, con->name);
         if (con->window)
             x_draw_decoration(con);
     }
@@ -651,49 +612,13 @@ int handle_expose_event(void *data, xcb_connection_t *conn, xcb_expose_event_t *
     /* We also need to render the decorations of other Cons nearby the Con
      * itself to not get overlapping decorations */
     TAILQ_FOREACH(con, &(parent->parent->nodes_head), nodes) {
-        LOG("expose for con %p / %s\n", con, con->name);
+        DLOG("expose for con %p / %s\n", con, con->name);
         if (con->window)
             x_draw_decoration(con);
     }
     xcb_flush(conn);
 
     return 1;
-
-#if 0
-    else {
-            uint32_t background_color;
-            if (client->urgent)
-                    background_color = config.client.urgent.background;
-            /* Distinguish if the window is currently focused… */
-            else if (CUR_CELL != NULL && CUR_CELL->currently_focused == client)
-                    background_color = config.client.focused.background;
-            /* …or if it is the focused window in a not focused container */
-            else background_color = config.client.focused_inactive.background;
-
-            /* Set foreground color to current focused color, line width to 2 */
-            uint32_t values[] = {background_color, 2};
-            xcb_change_gc(conn, client->titlegc, XCB_GC_FOREGROUND | XCB_GC_LINE_WIDTH, values);
-
-            /* Draw the border, the ±1 is for line width = 2 */
-            xcb_point_t points[] = {{1, 0},                                           /* left upper edge */
-                                    {1, client->rect.height-1},                       /* left bottom edge */
-                                    {client->rect.width-1, client->rect.height-1},    /* right bottom edge */
-                                    {client->rect.width-1, 0}};                       /* right upper edge */
-            xcb_poly_line(conn, XCB_COORD_MODE_ORIGIN, client->frame, client->titlegc, 4, points);
-
-            /* Draw a black background */
-            xcb_change_gc_single(conn, client->titlegc, XCB_GC_FOREGROUND, get_colorpixel(conn, "#000000"));
-            if (client->titlebar_position == TITLEBAR_OFF && !client->borderless) {
-                    xcb_rectangle_t crect = {1, 0, client->rect.width - (1 + 1), client->rect.height - 1};
-                    xcb_poly_fill_rectangle(conn, client->frame, client->titlegc, 1, &crect);
-            } else {
-                    xcb_rectangle_t crect = {2, 0, client->rect.width - (2 + 2), client->rect.height - 2};
-                    xcb_poly_fill_rectangle(conn, client->frame, client->titlegc, 1, &crect);
-            }
-    }
-    xcb_flush(conn);
-    return 1;
-#endif
 }
 
 /*
@@ -814,7 +739,6 @@ int handle_normal_hints(void *data, xcb_connection_t *conn, uint8_t state, xcb_w
         con->base_height = base_height;
         DLOG("client's base_height changed to %d\n", base_height);
         DLOG("client's base_width changed to %d\n", base_width);
-        changed = true;
     }
 
     /* If no aspect ratio was set or if it was invalid, we ignore the hints */