diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2019-01-01 08:45:21 -0500 |
---|---|---|
committer | emersion <contact@emersion.fr> | 2019-01-02 23:33:33 +0100 |
commit | 5bf4daf2634929e7c94a6c7e56eda66d4667ca2f (patch) | |
tree | 1a5b0c1300c056cdd48f9d819e960e1336c46602 /sway/input | |
parent | a96e86744ffd19d9ed8a7fc8e5468bb8b274b228 (diff) |
Implement tiling_drag_threshold
Implements `tiling_drag_threshold <threshold>` to prevent accidental
dragging of tiling containers. If a container (and all of its
descendants) are unfocused and the tile bar is pressed, a threshold
will be used before actually starting the drag. Once the threshold has
been exceeded, the cursor will change to the grab icon and the operation
will switch from `OP_MOVE_TILING_THRESHOLD` to `OP_MOVE_TILING`.
Diffstat (limited to 'sway/input')
-rw-r--r-- | sway/input/cursor.c | 41 | ||||
-rw-r--r-- | sway/input/seat.c | 11 |
2 files changed, 50 insertions, 2 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index f8302ddf..516251f7 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -384,6 +384,30 @@ static void handle_move_tiling_motion(struct sway_seat *seat, desktop_damage_box(&seat->op_drop_box); } +static void handle_move_tiling_threshold_motion(struct sway_seat *seat, + struct sway_cursor *cursor) { + double cx = seat->cursor->cursor->x; + double cy = seat->cursor->cursor->y; + double sx = seat->op_ref_lx; + double sy = seat->op_ref_ly; + + // Get the scaled threshold for the output. Even if the operation goes + // across multiple outputs of varying scales, just use the scale for the + // output that the cursor is currently on for simplicity. + struct wlr_output *wlr_output = wlr_output_layout_output_at( + root->output_layout, cx, cy); + double output_scale = wlr_output ? wlr_output->scale : 1; + double threshold = config->tiling_drag_threshold * output_scale; + threshold *= threshold; + + // If the threshold has been exceeded, start the actual drag + if ((cx - sx) * (cx - sx) + (cy - sy) * (cy - sy) > threshold) { + seat->operation = OP_MOVE_TILING; + cursor_set_image(cursor, "grab", NULL); + handle_move_tiling_motion(seat, cursor); + } +} + static void calculate_floating_constraints(struct sway_container *con, int *min_width, int *max_width, int *min_height, int *max_height) { if (config->floating_minimum_width == -1) { // no minimum @@ -640,6 +664,9 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, case OP_MOVE_FLOATING: handle_move_floating_motion(seat, cursor); break; + case OP_MOVE_TILING_THRESHOLD: + handle_move_tiling_threshold_motion(seat, cursor); + break; case OP_MOVE_TILING: handle_move_tiling_motion(seat, cursor); break; @@ -984,12 +1011,22 @@ void dispatch_cursor_button(struct sway_cursor *cursor, if (config->tiling_drag && (mod_pressed || on_titlebar) && state == WLR_BUTTON_PRESSED && !is_floating_or_child && cont && !cont->is_fullscreen) { - if (on_titlebar) { + struct sway_container *focus = seat_get_focused_container(seat); + bool focused = focus == cont || container_has_ancestor(focus, cont); + if (on_titlebar && !focused) { node = seat_get_focus_inactive(seat, &cont->node); seat_set_focus(seat, node); } + seat_pointer_notify_button(seat, time_msec, button, state); - seat_begin_move_tiling(seat, cont, button); + + // If moving a previously unfocused container by it's title bar, use a + // threshold for the drag. + if (!mod_pressed && !focused && config->tiling_drag_threshold > 0) { + seat_begin_move_tiling_threshold(seat, cont, button); + } else { + seat_begin_move_tiling(seat, cont, button); + } return; } diff --git a/sway/input/seat.c b/sway/input/seat.c index fa82c9ce..9422713d 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -1052,6 +1052,17 @@ void seat_begin_move_floating(struct sway_seat *seat, cursor_set_image(seat->cursor, "grab", NULL); } +void seat_begin_move_tiling_threshold(struct sway_seat *seat, + struct sway_container *con, uint32_t button) { + seat->operation = OP_MOVE_TILING_THRESHOLD; + seat->op_container = con; + seat->op_button = button; + seat->op_target_node = NULL; + seat->op_target_edge = 0; + seat->op_ref_lx = seat->cursor->cursor->x; + seat->op_ref_ly = seat->cursor->cursor->y; +} + void seat_begin_move_tiling(struct sway_seat *seat, struct sway_container *con, uint32_t button) { seat->operation = OP_MOVE_TILING; |