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/cursor.c | |
parent | Fix fullscreen view rendering crash (diff) | |
download | sway-5bf4daf2634929e7c94a6c7e56eda66d4667ca2f.tar.gz sway-5bf4daf2634929e7c94a6c7e56eda66d4667ca2f.tar.zst sway-5bf4daf2634929e7c94a6c7e56eda66d4667ca2f.zip |
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/cursor.c')
-rw-r--r-- | sway/input/cursor.c | 41 |
1 files changed, 39 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, | |||
384 | desktop_damage_box(&seat->op_drop_box); | 384 | desktop_damage_box(&seat->op_drop_box); |
385 | } | 385 | } |
386 | 386 | ||
387 | static void handle_move_tiling_threshold_motion(struct sway_seat *seat, | ||
388 | struct sway_cursor *cursor) { | ||
389 | double cx = seat->cursor->cursor->x; | ||
390 | double cy = seat->cursor->cursor->y; | ||
391 | double sx = seat->op_ref_lx; | ||
392 | double sy = seat->op_ref_ly; | ||
393 | |||
394 | // Get the scaled threshold for the output. Even if the operation goes | ||
395 | // across multiple outputs of varying scales, just use the scale for the | ||
396 | // output that the cursor is currently on for simplicity. | ||
397 | struct wlr_output *wlr_output = wlr_output_layout_output_at( | ||
398 | root->output_layout, cx, cy); | ||
399 | double output_scale = wlr_output ? wlr_output->scale : 1; | ||
400 | double threshold = config->tiling_drag_threshold * output_scale; | ||
401 | threshold *= threshold; | ||
402 | |||
403 | // If the threshold has been exceeded, start the actual drag | ||
404 | if ((cx - sx) * (cx - sx) + (cy - sy) * (cy - sy) > threshold) { | ||
405 | seat->operation = OP_MOVE_TILING; | ||
406 | cursor_set_image(cursor, "grab", NULL); | ||
407 | handle_move_tiling_motion(seat, cursor); | ||
408 | } | ||
409 | } | ||
410 | |||
387 | static void calculate_floating_constraints(struct sway_container *con, | 411 | static void calculate_floating_constraints(struct sway_container *con, |
388 | int *min_width, int *max_width, int *min_height, int *max_height) { | 412 | int *min_width, int *max_width, int *min_height, int *max_height) { |
389 | if (config->floating_minimum_width == -1) { // no minimum | 413 | if (config->floating_minimum_width == -1) { // no minimum |
@@ -640,6 +664,9 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, | |||
640 | case OP_MOVE_FLOATING: | 664 | case OP_MOVE_FLOATING: |
641 | handle_move_floating_motion(seat, cursor); | 665 | handle_move_floating_motion(seat, cursor); |
642 | break; | 666 | break; |
667 | case OP_MOVE_TILING_THRESHOLD: | ||
668 | handle_move_tiling_threshold_motion(seat, cursor); | ||
669 | break; | ||
643 | case OP_MOVE_TILING: | 670 | case OP_MOVE_TILING: |
644 | handle_move_tiling_motion(seat, cursor); | 671 | handle_move_tiling_motion(seat, cursor); |
645 | break; | 672 | break; |
@@ -984,12 +1011,22 @@ void dispatch_cursor_button(struct sway_cursor *cursor, | |||
984 | if (config->tiling_drag && (mod_pressed || on_titlebar) && | 1011 | if (config->tiling_drag && (mod_pressed || on_titlebar) && |
985 | state == WLR_BUTTON_PRESSED && !is_floating_or_child && | 1012 | state == WLR_BUTTON_PRESSED && !is_floating_or_child && |
986 | cont && !cont->is_fullscreen) { | 1013 | cont && !cont->is_fullscreen) { |
987 | if (on_titlebar) { | 1014 | struct sway_container *focus = seat_get_focused_container(seat); |
1015 | bool focused = focus == cont || container_has_ancestor(focus, cont); | ||
1016 | if (on_titlebar && !focused) { | ||
988 | node = seat_get_focus_inactive(seat, &cont->node); | 1017 | node = seat_get_focus_inactive(seat, &cont->node); |
989 | seat_set_focus(seat, node); | 1018 | seat_set_focus(seat, node); |
990 | } | 1019 | } |
1020 | |||
991 | seat_pointer_notify_button(seat, time_msec, button, state); | 1021 | seat_pointer_notify_button(seat, time_msec, button, state); |
992 | seat_begin_move_tiling(seat, cont, button); | 1022 | |
1023 | // If moving a previously unfocused container by it's title bar, use a | ||
1024 | // threshold for the drag. | ||
1025 | if (!mod_pressed && !focused && config->tiling_drag_threshold > 0) { | ||
1026 | seat_begin_move_tiling_threshold(seat, cont, button); | ||
1027 | } else { | ||
1028 | seat_begin_move_tiling(seat, cont, button); | ||
1029 | } | ||
993 | return; | 1030 | return; |
994 | } | 1031 | } |
995 | 1032 | ||