X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fclick.c;h=58ebbf3d851053330dafe1bab389f36d93d518e5;hb=0eb07dea5c99eb7c2c5a9635bbdef75f0c8631fb;hp=bd2dcb9fdac2bb5a93d8769e42b3749f93234fff;hpb=2bde6f080ecd5d0e2dccb20a1936a5d40af7ff84;p=i3%2Fi3 diff --git a/src/click.c b/src/click.c index bd2dcb9f..58ebbf3d 100644 --- a/src/click.c +++ b/src/click.c @@ -1,5 +1,3 @@ -#undef I3__FILE__ -#define I3__FILE__ "click.c" /* * vim:ts=4:sw=4:expandtab * @@ -46,12 +44,9 @@ static bool tiling_resize_for_border(Con *con, border_t border, xcb_button_press case BORDER_BOTTOM: search_direction = D_DOWN; break; - default: - assert(false); - break; } - bool res = resize_find_tiling_participants(&first, &second, search_direction); + bool res = resize_find_tiling_participants(&first, &second, search_direction, false); if (!res) { LOG("No second container in this direction found.\n"); return false; @@ -180,29 +175,24 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod if (con->parent->type == CT_DOCKAREA) goto done; - const bool is_left_or_right_click = (event->detail == XCB_BUTTON_INDEX_1 || - event->detail == XCB_BUTTON_INDEX_3); + const bool is_left_or_right_click = (event->detail == XCB_BUTTON_CLICK_LEFT || + event->detail == XCB_BUTTON_CLICK_RIGHT); /* if the user has bound an action to this click, it should override the * default behavior. */ if (dest == CLICK_DECORATION || dest == CLICK_INSIDE || dest == CLICK_BORDER) { Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event); - /* clicks over a window decoration will always trigger the binding and - * clicks on the inside of the window will only trigger a binding if - * the --whole-window flag was given for the binding. */ - if (bind && ((dest == CLICK_DECORATION || bind->whole_window) || - (dest == CLICK_BORDER && bind->border))) { + + if (bind != NULL && ((dest == CLICK_DECORATION && !bind->exclude_titlebar) || + (dest == CLICK_INSIDE && bind->whole_window) || + (dest == CLICK_BORDER && bind->border))) { CommandResult *result = run_binding(bind, con); /* ASYNC_POINTER eats the event */ xcb_allow_events(conn, XCB_ALLOW_ASYNC_POINTER, event->time); xcb_flush(conn); - if (result->needs_tree_render) - tree_render(); - command_result_free(result); - return 0; } } @@ -229,46 +219,45 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod /* get the floating con */ Con *floatingcon = con_inside_floating(con); - const bool proportional = (event->state & BIND_SHIFT); + const bool proportional = (event->state & XCB_KEY_BUT_MASK_SHIFT) == XCB_KEY_BUT_MASK_SHIFT; const bool in_stacked = (con->parent->layout == L_STACKED || con->parent->layout == L_TABBED); /* 1: see if the user scrolled on the decoration of a stacked/tabbed con */ if (in_stacked && dest == CLICK_DECORATION && - (event->detail == XCB_BUTTON_INDEX_4 || - event->detail == XCB_BUTTON_INDEX_5)) { + (event->detail == XCB_BUTTON_SCROLL_UP || + event->detail == XCB_BUTTON_SCROLL_DOWN || + event->detail == XCB_BUTTON_SCROLL_LEFT || + event->detail == XCB_BUTTON_SCROLL_RIGHT)) { DLOG("Scrolling on a window decoration\n"); - orientation_t orientation = (con->parent->layout == L_STACKED ? VERT : HORIZ); - /* Focus the currently focused container on the same level that the - * user scrolled on. e.g. the tabbed decoration contains - * "urxvt | i3: V[xterm geeqie] | firefox", - * focus is on the xterm, but the user scrolled on urxvt. - * The splitv container will be focused. */ + orientation_t orientation = con_orientation(con->parent); + /* Use the focused child of the tabbed / stacked container, not the + * container the user scrolled on. */ Con *focused = con->parent; focused = TAILQ_FIRST(&(focused->focus_head)); - con_focus(focused); + con_activate(con_descend_focused(focused)); /* To prevent scrolling from going outside the container (see ticket * #557), we first check if scrolling is possible at all. */ bool scroll_prev_possible = (TAILQ_PREV(focused, nodes_head, nodes) != NULL); bool scroll_next_possible = (TAILQ_NEXT(focused, nodes) != NULL); - if (event->detail == XCB_BUTTON_INDEX_4 && scroll_prev_possible) + if ((event->detail == XCB_BUTTON_SCROLL_UP || event->detail == XCB_BUTTON_SCROLL_LEFT) && scroll_prev_possible) { tree_next('p', orientation); - else if (event->detail == XCB_BUTTON_INDEX_5 && scroll_next_possible) + } else if ((event->detail == XCB_BUTTON_SCROLL_DOWN || event->detail == XCB_BUTTON_SCROLL_RIGHT) && scroll_next_possible) { tree_next('n', orientation); + } + goto done; } /* 2: focus this con. */ - con_focus(con); + con_activate(con); /* 3: For floating containers, we also want to raise them on click. * We will skip handling events on floating cons in fullscreen mode */ - Con *fs = (ws ? con_get_fullscreen_con(ws, CF_OUTPUT) : NULL); + Con *fs = con_get_fullscreen_covering_ws(ws); if (floatingcon != NULL && fs != con) { - floating_raise_con(floatingcon); - /* 4: floating_modifier plus left mouse button drags */ - if (mod_pressed && event->detail == XCB_BUTTON_INDEX_1) { + if (mod_pressed && event->detail == XCB_BUTTON_CLICK_LEFT) { floating_drag_window(floatingcon, event); return 1; } @@ -276,7 +265,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod /* 5: resize (floating) if this was a (left or right) click on the * left/right/bottom border, or a right click on the decoration. * also try resizing (tiling) if it was a click on the top */ - if (mod_pressed && event->detail == XCB_BUTTON_INDEX_3) { + if (mod_pressed && event->detail == XCB_BUTTON_CLICK_RIGHT) { DLOG("floating resize due to floatingmodifier\n"); floating_resize_window(floatingcon, proportional, event); return 1; @@ -290,7 +279,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod goto done; } - if (dest == CLICK_DECORATION && event->detail == XCB_BUTTON_INDEX_3) { + if (dest == CLICK_DECORATION && event->detail == XCB_BUTTON_CLICK_RIGHT) { DLOG("floating resize due to decoration right click\n"); floating_resize_window(floatingcon, proportional, event); return 1; @@ -305,7 +294,7 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod /* 6: dragging, if this was a click on a decoration (which did not lead * to a resize) */ if (!in_stacked && dest == CLICK_DECORATION && - (event->detail == XCB_BUTTON_INDEX_1)) { + (event->detail == XCB_BUTTON_CLICK_LEFT)) { floating_drag_window(floatingcon, event); return 1; } @@ -313,14 +302,8 @@ static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod goto done; } - if (in_stacked) { - /* for stacked/tabbed cons, the resizing applies to the parent - * container */ - con = con->parent; - } - /* 7: floating modifier pressed, initiate a resize */ - if (dest == CLICK_INSIDE && mod_pressed && event->detail == XCB_BUTTON_INDEX_3) { + if (dest == CLICK_INSIDE && mod_pressed && event->detail == XCB_BUTTON_CLICK_RIGHT) { if (floating_mod_on_tiled_client(con, event)) return 1; } @@ -356,13 +339,24 @@ int handle_button_press(xcb_button_press_event_t *event) { last_timestamp = event->time; - const uint32_t mod = config.floating_modifier; + const uint32_t mod = (config.floating_modifier & 0xFFFF); const bool mod_pressed = (mod != 0 && (event->state & mod) == mod); DLOG("floating_mod = %d, detail = %d\n", mod_pressed, event->detail); if ((con = con_by_window_id(event->event))) return route_click(con, event, mod_pressed, CLICK_INSIDE); if (!(con = con_by_frame_id(event->event))) { + /* Run bindings on the root window as well, see #2097. We only run it + * if --whole-window was set as that's the equivalent for a normal + * window. */ + if (event->event == root) { + Binding *bind = get_binding_from_xcb_event((xcb_generic_event_t *)event); + if (bind != NULL && bind->whole_window) { + CommandResult *result = run_binding(bind, NULL); + command_result_free(result); + } + } + /* If the root window is clicked, find the relevant output from the * click coordinates and focus the output's active workspace. */ if (event->event == root && event->response_type == XCB_BUTTON_PRESS) {