diff options
Diffstat (limited to 'sway/input/cursor.c')
-rw-r--r-- | sway/input/cursor.c | 93 |
1 files changed, 74 insertions, 19 deletions
diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 22c5b075..510030ae 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 @@ -597,21 +621,40 @@ static int hide_notify(void *data) { return 1; } -static void handle_activity(struct sway_cursor *cursor) { - wl_event_source_timer_update(cursor->hide_source, - config->hide_cursor_timeout); +int cursor_get_timeout(struct sway_cursor *cursor){ + struct seat_config *sc = seat_get_config(cursor->seat); + if (!sc) { + sc = seat_get_config_by_name("*"); + } + int timeout = sc ? sc->hide_cursor_timeout : 0; + if (timeout < 0) { + timeout = 0; + } + return timeout; +} + +void cursor_handle_activity(struct sway_cursor *cursor) { + wl_event_source_timer_update( + cursor->hide_source, cursor_get_timeout(cursor)); + wlr_idle_notify_activity(server.idle, cursor->seat->wlr_seat); if (cursor->hidden) { - cursor->hidden = false; - if (cursor->image_surface) { - cursor_set_image_surface(cursor, cursor->image_surface, - cursor->hotspot_x, cursor->hotspot_y, - cursor->image_client); - } else { - const char *image = cursor->image; - cursor->image = NULL; - cursor_set_image(cursor, image, cursor->image_client); - } + cursor_unhide(cursor); + } +} + +void cursor_unhide(struct sway_cursor *cursor) { + cursor->hidden = false; + if (cursor->image_surface) { + cursor_set_image_surface(cursor, + cursor->image_surface, + cursor->hotspot_x, + cursor->hotspot_y, + cursor->image_client); + } else { + const char *image = cursor->image; + cursor->image = NULL; + cursor_set_image(cursor, image, cursor->image_client); } } @@ -632,6 +675,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; @@ -709,7 +755,7 @@ static void handle_cursor_motion(struct wl_listener *listener, void *data) { wlr_cursor_move(cursor->cursor, event->device, event->delta_x, event->delta_y); cursor_send_pointer_motion(cursor, event->time_msec); - handle_activity(cursor); + cursor_handle_activity(cursor); transaction_commit_dirty(); } @@ -720,7 +766,7 @@ static void handle_cursor_motion_absolute( struct wlr_event_pointer_motion_absolute *event = data; wlr_cursor_warp_absolute(cursor->cursor, event->device, event->x, event->y); cursor_send_pointer_motion(cursor, event->time_msec); - handle_activity(cursor); + cursor_handle_activity(cursor); transaction_commit_dirty(); } @@ -976,12 +1022,21 @@ 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 container by it's title bar, use a threshold for the drag + if (!mod_pressed && config->tiling_drag_threshold > 0) { + seat_begin_move_tiling_threshold(seat, cont, button); + } else { + seat_begin_move_tiling(seat, cont, button); + } return; } @@ -1009,7 +1064,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) { struct wlr_event_pointer_button *event = data; dispatch_cursor_button(cursor, event->device, event->time_msec, event->button, event->state); - handle_activity(cursor); + cursor_handle_activity(cursor); transaction_commit_dirty(); } @@ -1119,7 +1174,7 @@ static void handle_cursor_axis(struct wl_listener *listener, void *data) { struct sway_cursor *cursor = wl_container_of(listener, cursor, axis); struct wlr_event_pointer_axis *event = data; dispatch_cursor_axis(cursor, event); - handle_activity(cursor); + cursor_handle_activity(cursor); transaction_commit_dirty(); } |