+/*
+ * Being called by handle_button_press, this function calls the appropriate
+ * functions for resizing/dragging.
+ *
+ */
+static int route_click(Con *con, xcb_button_press_event_t *event, const bool mod_pressed, const click_destination_t dest) {
+ DLOG("--> click properties: mod = %d, destination = %d\n", mod_pressed, dest);
+ DLOG("--> OUTCOME = %p\n", con);
+ DLOG("type = %d, name = %s\n", con->type, con->name);
+
+ /* Any click in a workspace should focus that workspace. If the
+ * workspace is on another output we need to do a workspace_show in
+ * order for i3bar (and others) to notice the change in workspace. */
+ Con *ws = con_get_workspace(con);
+ Con *focused_workspace = con_get_workspace(focused);
+
+ if (!ws) {
+ ws = TAILQ_FIRST(&(output_get_content(con_get_output(con))->focus_head));
+ if (!ws)
+ goto done;
+ }
+
+ if (ws != focused_workspace)
+ workspace_show(ws);
+ focused_id = XCB_NONE;
+
+ /* don’t handle dockarea cons, they must not be focused */
+ if (con->parent->type == CT_DOCKAREA)
+ goto done;
+
+ /* get the floating con */
+ Con *floatingcon = con_inside_floating(con);
+ const bool proportional = (event->state & BIND_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)) {
+ DLOG("Scrolling on a window decoration\n");
+ orientation_t orientation = (con->parent->layout == L_STACKED ? VERT : HORIZ);
+ /* To prevent scrolling from going outside the container (see ticket
+ * #557), we first check if scrolling is possible at all. */
+ Con *focused = con_descend_focused(con->parent);
+ 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)
+ tree_next('p', orientation);
+ else if (event->detail == XCB_BUTTON_INDEX_5 && scroll_next_possible)
+ tree_next('n', orientation);
+ goto done;
+ }
+
+ /* 2: focus this con. */
+ con_focus(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);
+ 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) {
+ floating_drag_window(floatingcon, event);
+ return 1;