Allow dragging tiled windows with the mouse. (#3085)

Fixes #2643

Inner drop region behaves like move to mark.
The outer region is close to the edge (currently 30px from the edge).
This will place the container as a sibling in the given direction within
the parent container. If the move direction goes against the orientation
of the parent container, tree_move() is called.

Contributors:
Co-authored-by: Orestis Floros <orestisflo@gmail.com>
See #3085
- Inner drop region behaves like move to mark
- Handle workspaces
- Fix crash when target closes
- Initiate tiling drag from titlebar
- Hide indicator until container is dragged outside of original position
- Calculate outer_threshold using percentages instead of fixed pixel
values
- Emit 'move' event properly
- Don't focus previously unfocused containers
- Use tree_split() on different orientation
- Fix redundant split containers
- DT_PARENT
- Readability & optimizations
- Limit parent threshold by render_deco_height()
- Tests
- Fullscreen container handling
- Initiate drag from title bar
- Fix issue of EnterNotify events still triggering after drag_callback
  is called
- Include decorations for drop target calculation

Co-authored-by: Michael Forster <email@michael-forster.de>
See #2178
- Original implementation of tiling drag + indicator window
> A container can be dragged by the title bar to one of the four sides
> of another container. That container will then be split either
> horizontally or vertically.

Co-authored-by: Tony Crisci <tony@dubstepdish.com>
See #2653
- Original implementation of outer/inner drop region indicator:
> There are two drop regions per direction.
>
> The inner region is closer to the center of the window. Dropping on
> this region will split the target container and put the container
> within the split at the given direction beside the target container.
>
> The outer region is close to the edge (currently 30px from the edge).
> This will place the container as a sibling in the given direction within
> the parent container.
>
> Dropping into the outer region moves the con beside the target. If the
> move direction goes against the orientation of the parent container, the
> con moves out of the row.
- Fix crash: Ignore containers without a managed window (eg i3bar)
This commit is contained in:
Orestis Floros
2022-07-28 12:03:16 +02:00
committed by GitHub
parent 807e972330
commit ebcd1d43ea
13 changed files with 849 additions and 23 deletions

View File

@ -188,9 +188,6 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
goto done;
}
if (ws != focused_workspace)
workspace_show(ws);
/* get the floating con */
Con *floatingcon = con_inside_floating(con);
const bool proportional = (event->state & XCB_KEY_BUT_MASK_SHIFT) == XCB_KEY_BUT_MASK_SHIFT;
@ -218,7 +215,13 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
goto done;
}
/* 2: focus this con or one of its children. */
/* 2: floating modifier pressed, initiate a drag */
if (mod_pressed && event->detail == XCB_BUTTON_INDEX_1 && !floatingcon) {
tiling_drag(con, event);
goto done;
}
/* 3: focus this con or one of its children. */
Con *con_to_focus = con;
if (in_stacked && dest == CLICK_DECORATION) {
/* If the container is a tab/stacked container and the click happened
@ -231,19 +234,22 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
}
}
}
if (ws != focused_workspace) {
workspace_show(ws);
}
con_activate(con_to_focus);
/* 3: For floating containers, we also want to raise them on click.
/* 4: For floating containers, we also want to raise them on click.
* We will skip handling events on floating cons in fullscreen mode */
Con *fs = con_get_fullscreen_covering_ws(ws);
if (floatingcon != NULL && fs != con) {
/* 4: floating_modifier plus left mouse button drags */
/* 5: floating_modifier plus left mouse button drags */
if (mod_pressed && is_left_click) {
floating_drag_window(floatingcon, event, false);
return;
}
/* 5: resize (floating) if this was a (left or right) click on the
/* 6: 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 possible */
if (mod_pressed && is_right_click) {
@ -272,7 +278,7 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
return;
}
/* 6: dragging, if this was a click on a decoration (which did not lead
/* 7: dragging, if this was a click on a decoration (which did not lead
* to a resize) */
if (dest == CLICK_DECORATION && is_left_click) {
floating_drag_window(floatingcon, event, !was_focused);
@ -282,7 +288,13 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
goto done;
}
/* 7: floating modifier pressed, initiate a resize */
/* 8: floating modifier pressed, initiate a drag */
if ((mod_pressed || dest == CLICK_DECORATION) && event->detail == XCB_BUTTON_INDEX_1) {
tiling_drag(con, event);
goto done;
}
/* 9: floating modifier pressed, initiate a resize */
if (dest == CLICK_INSIDE && mod_pressed && is_right_click) {
if (floating_mod_on_tiled_client(con, event)) {
return;
@ -293,7 +305,7 @@ static void route_click(Con *con, xcb_button_press_event_t *event, const bool mo
xcb_flush(conn);
return;
}
/* 8: otherwise, check for border/decoration clicks and resize */
/* 10: otherwise, check for border/decoration clicks and resize */
if ((dest == CLICK_BORDER || dest == CLICK_DECORATION) &&
is_left_or_right_click) {
DLOG("Trying to resize (tiling)\n");