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.
*
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
*
*/
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.
/* 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;
}
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;
}
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;
}
+ if (config.disable_focus_follows_mouse)
+ return 1;
+
+ if (con->layout != L_DEFAULT)
+ return 1;
+
/* see over which rect the user is */
Con *current;
TAILQ_FOREACH(current, &(con->nodes_head), nodes) {
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.
*
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);
- if (con->border_style == BS_NORMAL)
+ if (con->border_style == BS_NORMAL) {
+ bsr.y += deco_height;
bsr.height -= deco_height;
+ }
con = con->parent;
DLOG("Container is a floating leaf node, will do that.\n");
if (event->value_mask & XCB_CONFIG_WINDOW_X) {
return 1;
}
+#endif
/*
* Gets triggered upon a RandR screen change event, that is when the user
*/
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
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);
}
/* 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
}
/*
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 */