aboutsummaryrefslogtreecommitdiff
path: root/sway/input
diff options
context:
space:
mode:
Diffstat (limited to 'sway/input')
-rw-r--r--sway/input/cursor.c93
-rw-r--r--sway/input/input-manager.c22
-rw-r--r--sway/input/seat.c29
3 files changed, 117 insertions, 27 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();
}
diff --git a/sway/input/input-manager.c b/sway/input/input-manager.c
index 055f6752..61087733 100644
--- a/sway/input/input-manager.c
+++ b/sway/input/input-manager.c
@@ -95,6 +95,18 @@ static bool input_has_seat_fallback_configuration(void) {
return false;
}
+void input_manager_verify_fallback_seat(void) {
+ struct sway_seat *seat = NULL;
+ if (!input_has_seat_fallback_configuration()) {
+ wlr_log(WLR_DEBUG, "no fallback seat config - creating default");
+ seat = input_manager_get_default_seat();
+ struct seat_config *sc = new_seat_config(seat->wlr_seat->name);
+ sc->fallback = true;
+ sc = store_seat_config(sc);
+ input_manager_apply_seat_config(sc);
+ }
+}
+
static void input_manager_libinput_config_keyboard(
struct sway_input_device *input_device) {
struct wlr_input_device *wlr_device = input_device->wlr_device;
@@ -296,16 +308,10 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
wl_signal_add(&device->events.destroy, &input_device->device_destroy);
input_device->device_destroy.notify = handle_device_destroy;
- struct sway_seat *seat = NULL;
- if (!input_has_seat_fallback_configuration()) {
- wlr_log(WLR_DEBUG, "no seat config - creating default seat config");
- seat = input_manager_get_default_seat();
- struct seat_config *sc = new_seat_config(seat->wlr_seat->name);
- sc->fallback = true;
- store_seat_config(sc);
- }
+ input_manager_verify_fallback_seat();
bool added = false;
+ struct sway_seat *seat = NULL;
wl_list_for_each(seat, &input->seats, link) {
struct seat_config *seat_config = seat_get_config(seat);
bool has_attachment = seat_config &&
diff --git a/sway/input/seat.c b/sway/input/seat.c
index e0f0db1d..52790039 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -995,6 +995,8 @@ void seat_apply_config(struct sway_seat *seat,
wl_list_for_each(seat_device, &seat->devices, link) {
seat_configure_device(seat, seat_device->input_device);
}
+
+ cursor_handle_activity(seat->cursor);
}
struct seat_config *seat_get_config(struct sway_seat *seat) {
@@ -1009,6 +1011,18 @@ struct seat_config *seat_get_config(struct sway_seat *seat) {
return NULL;
}
+struct seat_config *seat_get_config_by_name(const char *name) {
+ struct seat_config *seat_config = NULL;
+ for (int i = 0; i < config->seat_configs->length; ++i ) {
+ seat_config = config->seat_configs->items[i];
+ if (strcmp(name, seat_config->name) == 0) {
+ return seat_config;
+ }
+ }
+
+ return NULL;
+}
+
void seat_begin_down(struct sway_seat *seat, struct sway_container *con,
uint32_t button, double sx, double sy) {
seat->operation = OP_DOWN;
@@ -1038,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;
@@ -1206,4 +1231,8 @@ void seat_consider_warp_to_focus(struct sway_seat *seat) {
} else {
cursor_warp_to_workspace(seat->cursor, focus->sway_workspace);
}
+ if (seat->cursor->hidden){
+ cursor_unhide(seat->cursor);
+ wl_event_source_timer_update(seat->cursor->hide_source, cursor_get_timeout(seat->cursor));
+ }
}