From 9fbe13b9be18c732b58033a57a22a299af91a170 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Wed, 18 Jul 2018 16:13:28 +1000 Subject: Implement floating_modifier and mouse operations for floating views This implements the following: * `floating_modifier` configuration directive * Drag a floating window by its title bar * Hold mod + drag a floating window from anywhere * Resize a floating view by dragging the border * Resize a floating view by holding mod and right clicking anywhere on the view * Resize a floating view and keep aspect ratio by holding shift while resizing using either method * Mouse cursor turns into resize when hovering floating border or corner --- sway/input/cursor.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 311 insertions(+), 11 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index c76c20b3..6ad214b5 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -5,15 +5,19 @@ #elif __FreeBSD__ #include #endif +#include #include #include #include #include "list.h" #include "log.h" +#include "sway/desktop.h" #include "sway/desktop/transaction.h" #include "sway/input/cursor.h" +#include "sway/input/keyboard.h" #include "sway/layers.h" #include "sway/output.h" +#include "sway/tree/arrange.h" #include "sway/tree/view.h" #include "sway/tree/workspace.h" #include "wlr-layer-shell-unstable-v1-protocol.h" @@ -127,7 +131,7 @@ static struct sway_container *container_at_coords( return ws; } - c = seat_get_focus_inactive(seat, output->swayc); + c = seat_get_active_child(seat, output->swayc); if (c) { return c; } @@ -139,6 +143,173 @@ static struct sway_container *container_at_coords( return output->swayc; } +static enum resize_edge find_resize_edge(struct sway_container *cont, + struct sway_cursor *cursor) { + if (cont->type != C_VIEW) { + return RESIZE_EDGE_NONE; + } + struct sway_view *view = cont->sway_view; + if (view->border == B_NONE || !view->border_thickness || view->using_csd) { + return RESIZE_EDGE_NONE; + } + + enum resize_edge edge = 0; + if (cursor->cursor->x < cont->x + view->border_thickness) { + edge |= RESIZE_EDGE_LEFT; + } + if (cursor->cursor->y < cont->y + view->border_thickness) { + edge |= RESIZE_EDGE_TOP; + } + if (cursor->cursor->x >= cont->x + cont->width - view->border_thickness) { + edge |= RESIZE_EDGE_RIGHT; + } + if (cursor->cursor->y >= cont->y + cont->height - view->border_thickness) { + edge |= RESIZE_EDGE_BOTTOM; + } + return edge; +} + +static void handle_drag_motion(struct sway_seat *seat, + struct sway_cursor *cursor) { + struct sway_container *con = seat->op_container; + desktop_damage_whole_container(con); + container_floating_translate(con, + cursor->cursor->x - cursor->previous.x, + cursor->cursor->y - cursor->previous.y); + desktop_damage_whole_container(con); +} + +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 + *min_width = 0; + } else if (config->floating_minimum_width == 0) { // automatic + *min_width = 75; + } else { + *min_width = config->floating_minimum_width; + } + + if (config->floating_minimum_height == -1) { // no minimum + *min_height = 0; + } else if (config->floating_minimum_height == 0) { // automatic + *min_height = 50; + } else { + *min_height = config->floating_minimum_height; + } + + if (config->floating_maximum_width == -1) { // no maximum + *max_width = INT_MAX; + } else if (config->floating_maximum_width == 0) { // automatic + struct sway_container *ws = container_parent(con, C_WORKSPACE); + *max_width = ws->width; + } else { + *max_width = config->floating_maximum_width; + } + + if (config->floating_maximum_height == -1) { // no maximum + *max_height = INT_MAX; + } else if (config->floating_maximum_height == 0) { // automatic + struct sway_container *ws = container_parent(con, C_WORKSPACE); + *max_height = ws->height; + } else { + *max_height = config->floating_maximum_height; + } +} +static void handle_resize_motion(struct sway_seat *seat, + struct sway_cursor *cursor) { + struct sway_container *con = seat->op_container; + double center_lx = con->x + con->width / 2; + double center_ly = con->y + con->height / 2; + enum resize_edge edge = seat->op_resize_edge; + + // The amount the mouse has moved since the start of the resize operation + // Positive is down/right + double mouse_move_x = cursor->cursor->x - seat->op_ref_lx; + double mouse_move_y = cursor->cursor->y - seat->op_ref_ly; + + if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) { + mouse_move_x = 0; + } + if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) { + mouse_move_y = 0; + } + + double grow_width = seat->op_ref_lx > center_lx ? + mouse_move_x : -mouse_move_x; + double grow_height = seat->op_ref_ly > center_ly ? + mouse_move_y : -mouse_move_y; + + if (seat->op_resize_preserve_ratio) { + double x_multiplier = grow_width / seat->op_ref_width; + double y_multiplier = grow_height / seat->op_ref_height; + double avg_multiplier = (x_multiplier + y_multiplier) / 2; + grow_width = seat->op_ref_width * avg_multiplier; + grow_height = seat->op_ref_height * avg_multiplier; + } + + // If we're resizing from the center (mod + right click), we need to double + // the amount we're growing because we're doing it in both directions. + if (edge == RESIZE_EDGE_NONE) { + grow_width *= 2; + grow_height *= 2; + } + + // Determine new width/height, and accommodate for min/max values + double width = seat->op_ref_width + grow_width; + double height = seat->op_ref_height + grow_height; + int min_width, max_width, min_height, max_height; + calculate_floating_constraints(con, &min_width, &max_width, + &min_height, &max_height); + width = fmax(min_width, fmin(width, max_width)); + height = fmax(min_height, fmin(height, max_height)); + + // Recalculate these, in case we hit a min/max limit + grow_width = width - seat->op_ref_width; + grow_height = height - seat->op_ref_height; + + // Determine grow x/y values - these are relative to the container's x/y at + // the start of the resize operation. + double grow_x = 0, grow_y = 0; + if (edge & RESIZE_EDGE_LEFT) { + grow_x = -grow_width; + } else if (edge & RESIZE_EDGE_RIGHT) { + grow_x = 0; + } else { + grow_x = -grow_width / 2; + } + if (edge & RESIZE_EDGE_TOP) { + grow_y = -grow_height; + } else if (edge & RESIZE_EDGE_BOTTOM) { + grow_y = 0; + } else { + grow_y = -grow_height / 2; + } + + // Determine the amounts we need to bump everything relative to the current + // size. + int relative_grow_width = width - con->width; + int relative_grow_height = height - con->height; + int relative_grow_x = (seat->op_ref_con_lx + grow_x) - con->x; + int relative_grow_y = (seat->op_ref_con_ly + grow_y) - con->y; + + // Actually resize stuff + con->x += relative_grow_x; + con->y += relative_grow_y; + con->width += relative_grow_width; + con->height += relative_grow_height; + + if (con->type == C_VIEW) { + struct sway_view *view = con->sway_view; + view->x += relative_grow_x; + view->y += relative_grow_y; + view->width += relative_grow_width; + view->height += relative_grow_height; + } + + arrange_windows(con); + transaction_commit_dirty(); +} + void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, bool allow_refocusing) { if (time_msec == 0) { @@ -146,6 +317,18 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, } struct sway_seat *seat = cursor->seat; + + if (seat->operation != OP_NONE) { + if (seat->operation == OP_DRAG) { + handle_drag_motion(seat, cursor); + } else { + handle_resize_motion(seat, cursor); + } + cursor->previous.x = cursor->cursor->x; + cursor->previous.y = cursor->cursor->y; + return; + } + struct wlr_seat *wlr_seat = seat->wlr_seat; struct wlr_surface *surface = NULL; double sx, sy; @@ -194,15 +377,54 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, } } - // reset cursor if switching between clients - struct wl_client *client = NULL; - if (surface != NULL) { - client = wl_resource_get_client(surface->resource); - } - if (client != cursor->image_client) { + // Handle cursor image + if (surface) { + // Reset cursor if switching between clients + struct wl_client *client = wl_resource_get_client(surface->resource); + if (client != cursor->image_client) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "left_ptr", cursor->cursor); + cursor->image_client = client; + } + } else if (c && container_is_floating(c)) { + // Try a floating container's resize edge + enum resize_edge edge = find_resize_edge(c, cursor); + if (edge == RESIZE_EDGE_NONE) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "left_ptr", cursor->cursor); + } else if (edge == RESIZE_EDGE_TOP) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "top_side", cursor->cursor); + } else if (edge == RESIZE_EDGE_RIGHT) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "right_side", cursor->cursor); + } else if (edge == RESIZE_EDGE_BOTTOM) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "bottom_side", cursor->cursor); + } else if (edge == RESIZE_EDGE_LEFT) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "left_side", cursor->cursor); + } else if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_LEFT)) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "top_left_corner", cursor->cursor); + } else if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_RIGHT)) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "top_right_corner", cursor->cursor); + } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_LEFT)) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "bottom_left_corner", cursor->cursor); + } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT)) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "bottom_right_corner", cursor->cursor); + } else { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, + "left_ptr", cursor->cursor); + } + cursor->image_client = NULL; + } else { wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "left_ptr", cursor->cursor); - cursor->image_client = client; + "left_ptr", cursor->cursor); + cursor->image_client = NULL; } // send pointer enter/leave @@ -243,8 +465,79 @@ static void handle_cursor_motion_absolute( transaction_commit_dirty(); } +static void handle_end_operation(struct sway_seat *seat) { + if (seat->operation == OP_DRAG) { + // We "move" the container to its own location so it discovers its + // output again. + struct sway_container *con = seat->op_container; + container_floating_move_to(con, con->x, con->y); + seat->operation = OP_NONE; + seat->op_container = NULL; + } else { + // OP_RESIZE + seat->operation = OP_NONE; + seat->op_container = NULL; + } +} + +static void dispatch_cursor_button_floating(struct sway_cursor *cursor, + uint32_t time_msec, uint32_t button, enum wlr_button_state state, + struct wlr_surface *surface, double sx, double sy, + struct sway_container *cont) { + struct sway_seat *seat = cursor->seat; + + // Deny dragging or resizing a fullscreen view + if (cont->type == C_VIEW && cont->sway_view->is_fullscreen) { + wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); + return; + } + + struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); + bool mod_pressed = keyboard && + (keyboard->modifiers.depressed & config->floating_mod); + enum resize_edge edge = find_resize_edge(cont, cursor); + bool over_title = edge == RESIZE_EDGE_NONE && !surface; + + // Check for beginning drag + if (button == BTN_LEFT && state == WLR_BUTTON_PRESSED && + (mod_pressed || over_title)) { + seat->operation = OP_DRAG; + seat->op_container = cont; + seat->op_button = button; + return; + } + + // Check for beginning resize + bool resizing_via_border = button == BTN_LEFT && edge; + bool resizing_via_mod = button == BTN_RIGHT && mod_pressed; + if ((resizing_via_border || resizing_via_mod) && + state == WLR_BUTTON_PRESSED) { + seat->operation = OP_RESIZE; + seat->op_container = cont; + seat->op_resize_preserve_ratio = keyboard && + (keyboard->modifiers.depressed & 1); // Shift + seat->op_resize_edge = edge; + seat->op_button = button; + seat->op_ref_lx = cursor->cursor->x; + seat->op_ref_ly = cursor->cursor->y; + seat->op_ref_con_lx = cont->x; + seat->op_ref_con_ly = cont->y; + seat->op_ref_width = cont->width; + seat->op_ref_height = cont->height; + return; + } + + // Send event to surface + wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); +} + void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec, uint32_t button, enum wlr_button_state state) { + if (cursor->seat->operation != OP_NONE && + button == cursor->seat->op_button && state == WLR_BUTTON_RELEASED) { + handle_end_operation(cursor->seat); + return; + } if (time_msec == 0) { time_msec = get_current_time_msec(); } @@ -259,6 +552,11 @@ void dispatch_cursor_button(struct sway_cursor *cursor, if (layer->current.keyboard_interactive) { seat_set_focus_layer(cursor->seat, layer); } + wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, + time_msec, button, state); + } else if (cont && container_is_floating(cont)) { + dispatch_cursor_button_floating(cursor, time_msec, button, state, + surface, sx, sy, cont); } else if (surface && cont && cont->type != C_VIEW) { // Avoid moving keyboard focus from a surface that accepts it to one // that does not unless the change would move us to a new workspace. @@ -275,12 +573,14 @@ void dispatch_cursor_button(struct sway_cursor *cursor, if (new_ws != old_ws) { seat_set_focus(cursor->seat, cont); } + wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, + time_msec, button, state); } else if (cont) { seat_set_focus(cursor->seat, cont); + wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, + time_msec, button, state); } - wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, - time_msec, button, state); transaction_commit_dirty(); } -- cgit v1.2.3 From 3aadf944ae0ad08439d2651d37eb3c6c686d2709 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Wed, 18 Jul 2018 17:40:53 +1000 Subject: Use WLR_MODIFIER_SHIFT --- sway/input/cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 6ad214b5..3c27a7f6 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -515,7 +515,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, seat->operation = OP_RESIZE; seat->op_container = cont; seat->op_resize_preserve_ratio = keyboard && - (keyboard->modifiers.depressed & 1); // Shift + (keyboard->modifiers.depressed & WLR_MODIFIER_SHIFT); seat->op_resize_edge = edge; seat->op_button = button; seat->op_ref_lx = cursor->cursor->x; -- cgit v1.2.3 From 2c6616050a924a356b9bebbe16c9c7b8661b5d80 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 19 Jul 2018 13:17:20 +1000 Subject: Make mod + resize do it from the top left corner --- sway/input/cursor.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 3c27a7f6..e5631f5b 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -218,8 +218,6 @@ static void calculate_floating_constraints(struct sway_container *con, static void handle_resize_motion(struct sway_seat *seat, struct sway_cursor *cursor) { struct sway_container *con = seat->op_container; - double center_lx = con->x + con->width / 2; - double center_ly = con->y + con->height / 2; enum resize_edge edge = seat->op_resize_edge; // The amount the mouse has moved since the start of the resize operation @@ -234,10 +232,8 @@ static void handle_resize_motion(struct sway_seat *seat, mouse_move_y = 0; } - double grow_width = seat->op_ref_lx > center_lx ? - mouse_move_x : -mouse_move_x; - double grow_height = seat->op_ref_ly > center_ly ? - mouse_move_y : -mouse_move_y; + double grow_width = edge & RESIZE_EDGE_LEFT ? -mouse_move_x : mouse_move_x; + double grow_height = edge & RESIZE_EDGE_TOP ? -mouse_move_y : mouse_move_y; if (seat->op_resize_preserve_ratio) { double x_multiplier = grow_width / seat->op_ref_width; @@ -247,13 +243,6 @@ static void handle_resize_motion(struct sway_seat *seat, grow_height = seat->op_ref_height * avg_multiplier; } - // If we're resizing from the center (mod + right click), we need to double - // the amount we're growing because we're doing it in both directions. - if (edge == RESIZE_EDGE_NONE) { - grow_width *= 2; - grow_height *= 2; - } - // Determine new width/height, and accommodate for min/max values double width = seat->op_ref_width + grow_width; double height = seat->op_ref_height + grow_height; @@ -508,7 +497,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, } // Check for beginning resize - bool resizing_via_border = button == BTN_LEFT && edge; + bool resizing_via_border = button == BTN_LEFT && edge != RESIZE_EDGE_NONE; bool resizing_via_mod = button == BTN_RIGHT && mod_pressed; if ((resizing_via_border || resizing_via_mod) && state == WLR_BUTTON_PRESSED) { @@ -516,7 +505,8 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, seat->op_container = cont; seat->op_resize_preserve_ratio = keyboard && (keyboard->modifiers.depressed & WLR_MODIFIER_SHIFT); - seat->op_resize_edge = edge; + seat->op_resize_edge = resizing_via_mod ? + RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT : edge; seat->op_button = button; seat->op_ref_lx = cursor->cursor->x; seat->op_ref_ly = cursor->cursor->y; -- cgit v1.2.3 From c299b6b5cd72ce186baa9a0a1cc09a4293431d74 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 19 Jul 2018 13:42:43 +1000 Subject: Use max multiplier when resizing while preserving ratio --- sway/input/cursor.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index e5631f5b..a24a7de8 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -238,9 +238,9 @@ static void handle_resize_motion(struct sway_seat *seat, if (seat->op_resize_preserve_ratio) { double x_multiplier = grow_width / seat->op_ref_width; double y_multiplier = grow_height / seat->op_ref_height; - double avg_multiplier = (x_multiplier + y_multiplier) / 2; - grow_width = seat->op_ref_width * avg_multiplier; - grow_height = seat->op_ref_height * avg_multiplier; + double max_multiplier = fmax(x_multiplier, y_multiplier); + grow_width = seat->op_ref_width * max_multiplier; + grow_height = seat->op_ref_height * max_multiplier; } // Determine new width/height, and accommodate for min/max values -- cgit v1.2.3 From 350e9ea9293a4c185734ecda9d77ee2fd13502d2 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 19 Jul 2018 15:20:43 +1000 Subject: Fix clicking xwayland menus --- sway/input/cursor.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index a24a7de8..7a06cf9c 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -569,6 +569,9 @@ void dispatch_cursor_button(struct sway_cursor *cursor, seat_set_focus(cursor->seat, cont); wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, time_msec, button, state); + } else { + wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, + time_msec, button, state); } transaction_commit_dirty(); -- cgit v1.2.3 From dd337127d80ce93ba556691c4a4565a19babba0e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 19 Jul 2018 21:29:21 +1000 Subject: Use separate function for choosing edge cursor --- sway/input/cursor.c | 59 +++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 31 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 7a06cf9c..dfb5603e 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -299,6 +299,31 @@ static void handle_resize_motion(struct sway_seat *seat, transaction_commit_dirty(); } +static const char *edge_to_image_name(enum resize_edge edge) { + switch (edge) { + case RESIZE_EDGE_NONE: + return "left_ptr"; + case RESIZE_EDGE_TOP: + return "top_side"; + case RESIZE_EDGE_RIGHT: + return "right_side"; + case RESIZE_EDGE_BOTTOM: + return "bottom_side"; + case RESIZE_EDGE_LEFT: + return "left_side"; + } + if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_LEFT)) { + return "top_left_corner"; + } else if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_RIGHT)) { + return "top_right_corner"; + } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_LEFT)) { + return "bottom_left_corner"; + } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT)) { + return "bottom_right_corner"; + } + return "left_ptr"; +} + void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, bool allow_refocusing) { if (time_msec == 0) { @@ -378,37 +403,9 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, } else if (c && container_is_floating(c)) { // Try a floating container's resize edge enum resize_edge edge = find_resize_edge(c, cursor); - if (edge == RESIZE_EDGE_NONE) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "left_ptr", cursor->cursor); - } else if (edge == RESIZE_EDGE_TOP) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "top_side", cursor->cursor); - } else if (edge == RESIZE_EDGE_RIGHT) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "right_side", cursor->cursor); - } else if (edge == RESIZE_EDGE_BOTTOM) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "bottom_side", cursor->cursor); - } else if (edge == RESIZE_EDGE_LEFT) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "left_side", cursor->cursor); - } else if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_LEFT)) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "top_left_corner", cursor->cursor); - } else if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_RIGHT)) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "top_right_corner", cursor->cursor); - } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_LEFT)) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "bottom_left_corner", cursor->cursor); - } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT)) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "bottom_right_corner", cursor->cursor); - } else { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "left_ptr", cursor->cursor); - } + const char *image = edge_to_image_name(edge); + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, + cursor->cursor); cursor->image_client = NULL; } else { wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, -- cgit v1.2.3 From 1b3b75a09499972f6fdfb43185f0c9f84c16791e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 19 Jul 2018 21:31:10 +1000 Subject: Use wlr_keyboard_get_modifiers --- sway/input/cursor.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index dfb5603e..8723e2b4 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -480,7 +480,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); bool mod_pressed = keyboard && - (keyboard->modifiers.depressed & config->floating_mod); + (wlr_keyboard_get_modifiers(keyboard) & config->floating_mod); enum resize_edge edge = find_resize_edge(cont, cursor); bool over_title = edge == RESIZE_EDGE_NONE && !surface; @@ -501,7 +501,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, seat->operation = OP_RESIZE; seat->op_container = cont; seat->op_resize_preserve_ratio = keyboard && - (keyboard->modifiers.depressed & WLR_MODIFIER_SHIFT); + (wlr_keyboard_get_modifiers(keyboard) & WLR_MODIFIER_SHIFT); seat->op_resize_edge = resizing_via_mod ? RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT : edge; seat->op_button = button; -- cgit v1.2.3 From ff445cc85597ee6bfae01f03d3c246e2326f3981 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Fri, 20 Jul 2018 09:28:22 +1000 Subject: Implement xdg shell request_move and request_resize events Also does a few other related things: * Now uses enum wlr_edges instead of our own enum resize_edge * Now uses wlr_xcursor_get_resize_name and removes our own find_resize_edge_name * Renames drag to move for consistency --- include/sway/input/seat.h | 13 ++++-- sway/desktop/xdg_shell.c | 33 +++++++++++++++ sway/desktop/xdg_shell_v6.c | 33 +++++++++++++++ sway/input/cursor.c | 100 ++++++++++++++------------------------------ sway/input/seat.c | 38 +++++++++++++++++ 5 files changed, 144 insertions(+), 73 deletions(-) (limited to 'sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index be1f3610..35a965ee 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -3,6 +3,7 @@ #include #include +#include #include "sway/input/input-manager.h" struct sway_seat_device { @@ -34,8 +35,6 @@ struct sway_drag_icon { struct wl_listener destroy; }; -enum resize_edge; - struct sway_seat { struct wlr_seat *wlr_seat; struct sway_cursor *cursor; @@ -57,11 +56,12 @@ struct sway_seat { // Operations (drag and resize) enum { OP_NONE, - OP_DRAG, + OP_MOVE, OP_RESIZE, } operation; + struct sway_container *op_container; - enum resize_edge op_resize_edge; + enum wlr_edges op_resize_edge; uint32_t op_button; bool op_resize_preserve_ratio; double op_ref_lx, op_ref_ly; // cursor's x/y at start of op @@ -150,4 +150,9 @@ bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface); void drag_icon_update_position(struct sway_drag_icon *icon); +void seat_begin_move(struct sway_seat *seat, struct sway_container *con); + +void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, + uint32_t button, enum wlr_edges edge); + #endif diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index 98c16faf..d6c3a9a7 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -1,4 +1,9 @@ #define _POSIX_C_SOURCE 199309L +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include #include @@ -248,6 +253,24 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) transaction_commit_dirty(); } +static void handle_request_move(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_view *xdg_shell_view = + wl_container_of(listener, xdg_shell_view, request_move); + struct sway_view *view = &xdg_shell_view->view; + struct wlr_xdg_toplevel_move_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_move(seat, view->swayc); +} + +static void handle_request_resize(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_view *xdg_shell_view = + wl_container_of(listener, xdg_shell_view, request_resize); + struct sway_view *view = &xdg_shell_view->view; + struct wlr_xdg_toplevel_resize_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); +} + static void handle_unmap(struct wl_listener *listener, void *data) { struct sway_xdg_shell_view *xdg_shell_view = wl_container_of(listener, xdg_shell_view, unmap); @@ -262,6 +285,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&xdg_shell_view->commit.link); wl_list_remove(&xdg_shell_view->new_popup.link); wl_list_remove(&xdg_shell_view->request_fullscreen.link); + wl_list_remove(&xdg_shell_view->request_move.link); + wl_list_remove(&xdg_shell_view->request_resize.link); } static void handle_map(struct wl_listener *listener, void *data) { @@ -299,6 +324,14 @@ static void handle_map(struct wl_listener *listener, void *data) { xdg_shell_view->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &xdg_shell_view->request_fullscreen); + + xdg_shell_view->request_move.notify = handle_request_move; + wl_signal_add(&xdg_surface->toplevel->events.request_move, + &xdg_shell_view->request_move); + + xdg_shell_view->request_resize.notify = handle_request_resize; + wl_signal_add(&xdg_surface->toplevel->events.request_resize, + &xdg_shell_view->request_resize); } static void handle_destroy(struct wl_listener *listener, void *data) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 4d76f0a7..241bd9b0 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -1,4 +1,9 @@ #define _POSIX_C_SOURCE 199309L +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include #include @@ -243,6 +248,24 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) transaction_commit_dirty(); } +static void handle_request_move(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_v6_view *xdg_shell_v6_view = + wl_container_of(listener, xdg_shell_v6_view, request_move); + struct sway_view *view = &xdg_shell_v6_view->view; + struct wlr_xdg_toplevel_v6_move_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_move(seat, view->swayc); +} + +static void handle_request_resize(struct wl_listener *listener, void *data) { + struct sway_xdg_shell_v6_view *xdg_shell_v6_view = + wl_container_of(listener, xdg_shell_v6_view, request_resize); + struct sway_view *view = &xdg_shell_v6_view->view; + struct wlr_xdg_toplevel_v6_resize_event *e = data; + struct sway_seat *seat = e->seat->seat->data; + seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); +} + static void handle_unmap(struct wl_listener *listener, void *data) { struct sway_xdg_shell_v6_view *xdg_shell_v6_view = wl_container_of(listener, xdg_shell_v6_view, unmap); @@ -257,6 +280,8 @@ static void handle_unmap(struct wl_listener *listener, void *data) { wl_list_remove(&xdg_shell_v6_view->commit.link); wl_list_remove(&xdg_shell_v6_view->new_popup.link); wl_list_remove(&xdg_shell_v6_view->request_fullscreen.link); + wl_list_remove(&xdg_shell_v6_view->request_move.link); + wl_list_remove(&xdg_shell_v6_view->request_resize.link); } static void handle_map(struct wl_listener *listener, void *data) { @@ -294,6 +319,14 @@ static void handle_map(struct wl_listener *listener, void *data) { xdg_shell_v6_view->request_fullscreen.notify = handle_request_fullscreen; wl_signal_add(&xdg_surface->toplevel->events.request_fullscreen, &xdg_shell_v6_view->request_fullscreen); + + xdg_shell_v6_view->request_move.notify = handle_request_move; + wl_signal_add(&xdg_surface->toplevel->events.request_move, + &xdg_shell_v6_view->request_move); + + xdg_shell_v6_view->request_resize.notify = handle_request_resize; + wl_signal_add(&xdg_surface->toplevel->events.request_resize, + &xdg_shell_v6_view->request_resize); } static void handle_destroy(struct wl_listener *listener, void *data) { diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 8723e2b4..8b9208c6 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -143,33 +143,33 @@ static struct sway_container *container_at_coords( return output->swayc; } -static enum resize_edge find_resize_edge(struct sway_container *cont, +static enum wlr_edges find_resize_edge(struct sway_container *cont, struct sway_cursor *cursor) { if (cont->type != C_VIEW) { - return RESIZE_EDGE_NONE; + return WLR_EDGE_NONE; } struct sway_view *view = cont->sway_view; if (view->border == B_NONE || !view->border_thickness || view->using_csd) { - return RESIZE_EDGE_NONE; + return WLR_EDGE_NONE; } - enum resize_edge edge = 0; + enum wlr_edges edge = 0; if (cursor->cursor->x < cont->x + view->border_thickness) { - edge |= RESIZE_EDGE_LEFT; + edge |= WLR_EDGE_LEFT; } if (cursor->cursor->y < cont->y + view->border_thickness) { - edge |= RESIZE_EDGE_TOP; + edge |= WLR_EDGE_TOP; } if (cursor->cursor->x >= cont->x + cont->width - view->border_thickness) { - edge |= RESIZE_EDGE_RIGHT; + edge |= WLR_EDGE_RIGHT; } if (cursor->cursor->y >= cont->y + cont->height - view->border_thickness) { - edge |= RESIZE_EDGE_BOTTOM; + edge |= WLR_EDGE_BOTTOM; } return edge; } -static void handle_drag_motion(struct sway_seat *seat, +static void handle_move_motion(struct sway_seat *seat, struct sway_cursor *cursor) { struct sway_container *con = seat->op_container; desktop_damage_whole_container(con); @@ -218,22 +218,22 @@ static void calculate_floating_constraints(struct sway_container *con, static void handle_resize_motion(struct sway_seat *seat, struct sway_cursor *cursor) { struct sway_container *con = seat->op_container; - enum resize_edge edge = seat->op_resize_edge; + enum wlr_edges edge = seat->op_resize_edge; // The amount the mouse has moved since the start of the resize operation // Positive is down/right double mouse_move_x = cursor->cursor->x - seat->op_ref_lx; double mouse_move_y = cursor->cursor->y - seat->op_ref_ly; - if (edge == RESIZE_EDGE_TOP || edge == RESIZE_EDGE_BOTTOM) { + if (edge == WLR_EDGE_TOP || edge == WLR_EDGE_BOTTOM) { mouse_move_x = 0; } - if (edge == RESIZE_EDGE_LEFT || edge == RESIZE_EDGE_RIGHT) { + if (edge == WLR_EDGE_LEFT || edge == WLR_EDGE_RIGHT) { mouse_move_y = 0; } - double grow_width = edge & RESIZE_EDGE_LEFT ? -mouse_move_x : mouse_move_x; - double grow_height = edge & RESIZE_EDGE_TOP ? -mouse_move_y : mouse_move_y; + double grow_width = edge & WLR_EDGE_LEFT ? -mouse_move_x : mouse_move_x; + double grow_height = edge & WLR_EDGE_TOP ? -mouse_move_y : mouse_move_y; if (seat->op_resize_preserve_ratio) { double x_multiplier = grow_width / seat->op_ref_width; @@ -259,16 +259,16 @@ static void handle_resize_motion(struct sway_seat *seat, // Determine grow x/y values - these are relative to the container's x/y at // the start of the resize operation. double grow_x = 0, grow_y = 0; - if (edge & RESIZE_EDGE_LEFT) { + if (edge & WLR_EDGE_LEFT) { grow_x = -grow_width; - } else if (edge & RESIZE_EDGE_RIGHT) { + } else if (edge & WLR_EDGE_RIGHT) { grow_x = 0; } else { grow_x = -grow_width / 2; } - if (edge & RESIZE_EDGE_TOP) { + if (edge & WLR_EDGE_TOP) { grow_y = -grow_height; - } else if (edge & RESIZE_EDGE_BOTTOM) { + } else if (edge & WLR_EDGE_BOTTOM) { grow_y = 0; } else { grow_y = -grow_height / 2; @@ -299,31 +299,6 @@ static void handle_resize_motion(struct sway_seat *seat, transaction_commit_dirty(); } -static const char *edge_to_image_name(enum resize_edge edge) { - switch (edge) { - case RESIZE_EDGE_NONE: - return "left_ptr"; - case RESIZE_EDGE_TOP: - return "top_side"; - case RESIZE_EDGE_RIGHT: - return "right_side"; - case RESIZE_EDGE_BOTTOM: - return "bottom_side"; - case RESIZE_EDGE_LEFT: - return "left_side"; - } - if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_LEFT)) { - return "top_left_corner"; - } else if (edge == (RESIZE_EDGE_TOP | RESIZE_EDGE_RIGHT)) { - return "top_right_corner"; - } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_LEFT)) { - return "bottom_left_corner"; - } else if (edge == (RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT)) { - return "bottom_right_corner"; - } - return "left_ptr"; -} - void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, bool allow_refocusing) { if (time_msec == 0) { @@ -333,8 +308,8 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, struct sway_seat *seat = cursor->seat; if (seat->operation != OP_NONE) { - if (seat->operation == OP_DRAG) { - handle_drag_motion(seat, cursor); + if (seat->operation == OP_MOVE) { + handle_move_motion(seat, cursor); } else { handle_resize_motion(seat, cursor); } @@ -402,8 +377,9 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, } } else if (c && container_is_floating(c)) { // Try a floating container's resize edge - enum resize_edge edge = find_resize_edge(c, cursor); - const char *image = edge_to_image_name(edge); + enum wlr_edges edge = find_resize_edge(c, cursor); + const char *image = edge == WLR_EDGE_NONE ? + "left_ptr" : wlr_xcursor_get_resize_name(edge); wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, cursor->cursor); cursor->image_client = NULL; @@ -452,7 +428,7 @@ static void handle_cursor_motion_absolute( } static void handle_end_operation(struct sway_seat *seat) { - if (seat->operation == OP_DRAG) { + if (seat->operation == OP_MOVE) { // We "move" the container to its own location so it discovers its // output again. struct sway_container *con = seat->op_container; @@ -472,7 +448,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, struct sway_container *cont) { struct sway_seat *seat = cursor->seat; - // Deny dragging or resizing a fullscreen view + // Deny moving or resizing a fullscreen view if (cont->type == C_VIEW && cont->sway_view->is_fullscreen) { wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); return; @@ -481,36 +457,22 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); bool mod_pressed = keyboard && (wlr_keyboard_get_modifiers(keyboard) & config->floating_mod); - enum resize_edge edge = find_resize_edge(cont, cursor); - bool over_title = edge == RESIZE_EDGE_NONE && !surface; + enum wlr_edges edge = find_resize_edge(cont, cursor); + bool over_title = edge == WLR_EDGE_NONE && !surface; - // Check for beginning drag + // Check for beginning move if (button == BTN_LEFT && state == WLR_BUTTON_PRESSED && (mod_pressed || over_title)) { - seat->operation = OP_DRAG; - seat->op_container = cont; - seat->op_button = button; + seat_begin_move(seat, cont); return; } // Check for beginning resize - bool resizing_via_border = button == BTN_LEFT && edge != RESIZE_EDGE_NONE; + bool resizing_via_border = button == BTN_LEFT && edge != WLR_EDGE_NONE; bool resizing_via_mod = button == BTN_RIGHT && mod_pressed; if ((resizing_via_border || resizing_via_mod) && state == WLR_BUTTON_PRESSED) { - seat->operation = OP_RESIZE; - seat->op_container = cont; - seat->op_resize_preserve_ratio = keyboard && - (wlr_keyboard_get_modifiers(keyboard) & WLR_MODIFIER_SHIFT); - seat->op_resize_edge = resizing_via_mod ? - RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT : edge; - seat->op_button = button; - seat->op_ref_lx = cursor->cursor->x; - seat->op_ref_ly = cursor->cursor->y; - seat->op_ref_con_lx = cont->x; - seat->op_ref_con_ly = cont->y; - seat->op_ref_width = cont->width; - seat->op_ref_height = cont->height; + seat_begin_resize(seat, cont, button, edge); return; } diff --git a/sway/input/seat.c b/sway/input/seat.c index e77d88a8..cc5b2e0f 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -1,6 +1,11 @@ #define _XOPEN_SOURCE 700 #define _POSIX_C_SOURCE 199309L #include +#ifdef __linux__ +#include +#elif __FreeBSD__ +#include +#endif #include #include #include @@ -348,6 +353,7 @@ struct sway_seat *seat_create(struct sway_input_manager *input, free(seat); return NULL; } + seat->wlr_seat->data = seat; seat->cursor = sway_cursor_create(seat); if (!seat->cursor) { @@ -894,3 +900,35 @@ struct seat_config *seat_get_config(struct sway_seat *seat) { return NULL; } + +void seat_begin_move(struct sway_seat *seat, struct sway_container *con) { + if (!seat->cursor) { + wlr_log(WLR_DEBUG, "Ignoring move request due to no cursor device"); + return; + } + seat->operation = OP_MOVE; + seat->op_container = con; + seat->op_button = BTN_LEFT; +} + +void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, + uint32_t button, enum wlr_edges edge) { + if (!seat->cursor) { + wlr_log(WLR_DEBUG, "Ignoring resize request due to no cursor device"); + return; + } + struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat); + seat->operation = OP_RESIZE; + seat->op_container = con; + seat->op_resize_preserve_ratio = keyboard && + (wlr_keyboard_get_modifiers(keyboard) & WLR_MODIFIER_SHIFT); + seat->op_resize_edge = edge == WLR_EDGE_NONE ? + RESIZE_EDGE_BOTTOM | RESIZE_EDGE_RIGHT : edge; + seat->op_button = button; + seat->op_ref_lx = seat->cursor->cursor->x; + seat->op_ref_ly = seat->cursor->cursor->y; + seat->op_ref_con_lx = con->x; + seat->op_ref_con_ly = con->y; + seat->op_ref_width = con->width; + seat->op_ref_height = con->height; +} -- cgit v1.2.3 From 0c87bff5d1ce686afdc25d37eee4bdd8f08abdd3 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 21 Jul 2018 10:40:12 +1000 Subject: Replace static handle_end_operation with seat_end_mouse_operation --- include/sway/input/seat.h | 2 ++ sway/input/cursor.c | 17 +---------------- sway/input/seat.c | 19 +++++++++++++++++++ sway/tree/container.c | 3 +-- 4 files changed, 23 insertions(+), 18 deletions(-) (limited to 'sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index 35a965ee..cd36ef5a 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -155,4 +155,6 @@ void seat_begin_move(struct sway_seat *seat, struct sway_container *con); void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, uint32_t button, enum wlr_edges edge); +void seat_end_mouse_operation(struct sway_seat *seat); + #endif diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 8b9208c6..ec83746e 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -427,21 +427,6 @@ static void handle_cursor_motion_absolute( transaction_commit_dirty(); } -static void handle_end_operation(struct sway_seat *seat) { - if (seat->operation == OP_MOVE) { - // We "move" the container to its own location so it discovers its - // output again. - struct sway_container *con = seat->op_container; - container_floating_move_to(con, con->x, con->y); - seat->operation = OP_NONE; - seat->op_container = NULL; - } else { - // OP_RESIZE - seat->operation = OP_NONE; - seat->op_container = NULL; - } -} - static void dispatch_cursor_button_floating(struct sway_cursor *cursor, uint32_t time_msec, uint32_t button, enum wlr_button_state state, struct wlr_surface *surface, double sx, double sy, @@ -484,7 +469,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec, uint32_t button, enum wlr_button_state state) { if (cursor->seat->operation != OP_NONE && button == cursor->seat->op_button && state == WLR_BUTTON_RELEASED) { - handle_end_operation(cursor->seat); + seat_end_mouse_operation(cursor->seat); return; } if (time_msec == 0) { diff --git a/sway/input/seat.c b/sway/input/seat.c index cc5b2e0f..3a3350e1 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -932,3 +932,22 @@ void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, seat->op_ref_width = con->width; seat->op_ref_height = con->height; } + +void seat_end_mouse_operation(struct sway_seat *seat) { + switch (seat->operation) { + case OP_MOVE: + { + // We "move" the container to its own location so it discovers its + // output again. + struct sway_container *con = seat->op_container; + container_floating_move_to(con, con->x, con->y); + } + case OP_RESIZE: + // Don't need to do anything here. + break; + case OP_NONE: + break; + } + seat->operation = OP_NONE; + seat->op_container = NULL; +} diff --git a/sway/tree/container.c b/sway/tree/container.c index ba4af352..42c1d024 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -1114,8 +1114,7 @@ void container_end_mouse_operation(struct sway_container *container) { struct sway_seat *seat; wl_list_for_each(seat, &input_manager->seats, link) { if (seat->op_container == container) { - seat->op_container = NULL; - seat->operation = OP_NONE; + seat_end_mouse_operation(seat); } } } -- cgit v1.2.3 From 6767d8a593723a9b69d018eed13d24a789be9516 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 21 Jul 2018 10:57:14 +1000 Subject: Prevent re-uploading the same cursor image multiple times --- include/sway/input/cursor.h | 4 ++++ sway/input/cursor.c | 22 +++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) (limited to 'sway/input') diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h index 5dd109ca..b0a3a7c5 100644 --- a/include/sway/input/cursor.h +++ b/include/sway/input/cursor.h @@ -11,6 +11,7 @@ struct sway_cursor { } previous; struct wlr_xcursor_manager *xcursor_manager; + const char *image; struct wl_client *image_client; struct wl_listener motion; @@ -37,4 +38,7 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, void dispatch_cursor_button(struct sway_cursor *cursor, uint32_t time_msec, uint32_t button, enum wlr_button_state state); +void cursor_set_image(struct sway_cursor *cursor, const char *image, + struct wl_client *client); + #endif diff --git a/sway/input/cursor.c b/sway/input/cursor.c index ec83746e..43721d28 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -371,22 +371,16 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, // Reset cursor if switching between clients struct wl_client *client = wl_resource_get_client(surface->resource); if (client != cursor->image_client) { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "left_ptr", cursor->cursor); - cursor->image_client = client; + cursor_set_image(cursor, "left_ptr", client); } } else if (c && container_is_floating(c)) { // Try a floating container's resize edge enum wlr_edges edge = find_resize_edge(c, cursor); const char *image = edge == WLR_EDGE_NONE ? "left_ptr" : wlr_xcursor_get_resize_name(edge); - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, - cursor->cursor); - cursor->image_client = NULL; + cursor_set_image(cursor, image, NULL); } else { - wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, - "left_ptr", cursor->cursor); - cursor->image_client = NULL; + cursor_set_image(cursor, "left_ptr", NULL); } // send pointer enter/leave @@ -725,6 +719,16 @@ static void handle_request_set_cursor(struct wl_listener *listener, cursor->image_client = focused_client; } +void cursor_set_image(struct sway_cursor *cursor, const char *image, + struct wl_client *client) { + if (!cursor->image || strcmp(cursor->image, image) != 0) { + wlr_xcursor_manager_set_cursor_image(cursor->xcursor_manager, image, + cursor->cursor); + cursor->image = image; + } + cursor->image_client = client; +} + void sway_cursor_destroy(struct sway_cursor *cursor) { if (!cursor) { return; -- cgit v1.2.3 From 9df660ee3188386c907d8feb999636ce8d61d095 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 21 Jul 2018 11:23:48 +1000 Subject: Store last button and use it when views request to move or resize --- include/sway/input/seat.h | 9 ++++++++- sway/desktop/xdg_shell.c | 13 ++++++------- sway/desktop/xdg_shell_v6.c | 13 ++++++------- sway/input/cursor.c | 18 +++++++----------- sway/input/seat.c | 12 ++++++++++-- 5 files changed, 37 insertions(+), 28 deletions(-) (limited to 'sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index cd36ef5a..ab25788f 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -68,6 +68,9 @@ struct sway_seat { double op_ref_width, op_ref_height; // container's size at start of op double op_ref_con_lx, op_ref_con_ly; // container's x/y at start of op + uint32_t last_button; + uint32_t last_button_serial; + struct wl_listener focus_destroy; struct wl_listener new_container; struct wl_listener new_drag_icon; @@ -150,11 +153,15 @@ bool seat_is_input_allowed(struct sway_seat *seat, struct wlr_surface *surface); void drag_icon_update_position(struct sway_drag_icon *icon); -void seat_begin_move(struct sway_seat *seat, struct sway_container *con); +void seat_begin_move(struct sway_seat *seat, struct sway_container *con, + uint32_t button); void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, uint32_t button, enum wlr_edges edge); void seat_end_mouse_operation(struct sway_seat *seat); +void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, + uint32_t button, enum wlr_button_state state); + #endif diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index d6c3a9a7..c5d53d1d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -1,9 +1,4 @@ #define _POSIX_C_SOURCE 199309L -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#endif #include #include #include @@ -259,7 +254,9 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_view->view; struct wlr_xdg_toplevel_move_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_move(seat, view->swayc); + if (e->serial == seat->last_button_serial) { + seat_begin_move(seat, view->swayc, seat->last_button); + } } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -268,7 +265,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_view->view; struct wlr_xdg_toplevel_resize_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); + if (e->serial == seat->last_button_serial) { + seat_begin_resize(seat, view->swayc, seat->last_button, e->edges); + } } static void handle_unmap(struct wl_listener *listener, void *data) { diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 241bd9b0..4bd6af5e 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -1,9 +1,4 @@ #define _POSIX_C_SOURCE 199309L -#ifdef __linux__ -#include -#elif __FreeBSD__ -#include -#endif #include #include #include @@ -254,7 +249,9 @@ static void handle_request_move(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_v6_view->view; struct wlr_xdg_toplevel_v6_move_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_move(seat, view->swayc); + if (e->serial == seat->last_button_serial) { + seat_begin_move(seat, view->swayc, seat->last_button); + } } static void handle_request_resize(struct wl_listener *listener, void *data) { @@ -263,7 +260,9 @@ static void handle_request_resize(struct wl_listener *listener, void *data) { struct sway_view *view = &xdg_shell_v6_view->view; struct wlr_xdg_toplevel_v6_resize_event *e = data; struct sway_seat *seat = e->seat->seat->data; - seat_begin_resize(seat, view->swayc, BTN_LEFT, e->edges); + if (e->serial == seat->last_button_serial) { + seat_begin_resize(seat, view->swayc, seat->last_button, e->edges); + } } static void handle_unmap(struct wl_listener *listener, void *data) { diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 43721d28..ad0ceb94 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -429,7 +429,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, // Deny moving or resizing a fullscreen view if (cont->type == C_VIEW && cont->sway_view->is_fullscreen) { - wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); + seat_pointer_notify_button(seat, time_msec, button, state); return; } @@ -442,7 +442,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, // Check for beginning move if (button == BTN_LEFT && state == WLR_BUTTON_PRESSED && (mod_pressed || over_title)) { - seat_begin_move(seat, cont); + seat_begin_move(seat, cont, BTN_LEFT); return; } @@ -456,7 +456,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, } // Send event to surface - wlr_seat_pointer_notify_button(seat->wlr_seat, time_msec, button, state); + seat_pointer_notify_button(seat, time_msec, button, state); } void dispatch_cursor_button(struct sway_cursor *cursor, @@ -480,8 +480,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, if (layer->current.keyboard_interactive) { seat_set_focus_layer(cursor->seat, layer); } - wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, - time_msec, button, state); + seat_pointer_notify_button(cursor->seat, time_msec, button, state); } else if (cont && container_is_floating(cont)) { dispatch_cursor_button_floating(cursor, time_msec, button, state, surface, sx, sy, cont); @@ -501,15 +500,12 @@ void dispatch_cursor_button(struct sway_cursor *cursor, if (new_ws != old_ws) { seat_set_focus(cursor->seat, cont); } - wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, - time_msec, button, state); + seat_pointer_notify_button(cursor->seat, time_msec, button, state); } else if (cont) { seat_set_focus(cursor->seat, cont); - wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, - time_msec, button, state); + seat_pointer_notify_button(cursor->seat, time_msec, button, state); } else { - wlr_seat_pointer_notify_button(cursor->seat->wlr_seat, - time_msec, button, state); + seat_pointer_notify_button(cursor->seat, time_msec, button, state); } transaction_commit_dirty(); diff --git a/sway/input/seat.c b/sway/input/seat.c index 3a3350e1..4e803efd 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -901,14 +901,15 @@ struct seat_config *seat_get_config(struct sway_seat *seat) { return NULL; } -void seat_begin_move(struct sway_seat *seat, struct sway_container *con) { +void seat_begin_move(struct sway_seat *seat, struct sway_container *con, + uint32_t button) { if (!seat->cursor) { wlr_log(WLR_DEBUG, "Ignoring move request due to no cursor device"); return; } seat->operation = OP_MOVE; seat->op_container = con; - seat->op_button = BTN_LEFT; + seat->op_button = button; } void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, @@ -951,3 +952,10 @@ void seat_end_mouse_operation(struct sway_seat *seat) { seat->operation = OP_NONE; seat->op_container = NULL; } + +void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, + uint32_t button, enum wlr_button_state state) { + seat->last_button = button; + seat->last_button_serial = wlr_seat_pointer_notify_button(seat->wlr_seat, + time_msec, button, state); +} -- cgit v1.2.3 From 011d1ebfa4219eb666487529a5a5e7189c14fd40 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sat, 21 Jul 2018 12:13:00 +1000 Subject: Consider view's min/max sizes when resizing --- include/sway/tree/view.h | 5 +++++ sway/desktop/xdg_shell.c | 12 ++++++++++++ sway/desktop/xdg_shell_v6.c | 12 ++++++++++++ sway/input/cursor.c | 11 ++++++++++- sway/tree/view.c | 13 +++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) (limited to 'sway/input') diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 068d92c6..1dfb218b 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -26,6 +26,8 @@ enum sway_view_prop { }; struct sway_view_impl { + void (*get_constraints)(struct sway_view *view, double *min_width, + double *max_width, double *min_height, double *max_height); const char *(*get_string_prop)(struct sway_view *view, enum sway_view_prop prop); uint32_t (*get_int_prop)(struct sway_view *view, enum sway_view_prop prop); @@ -215,6 +217,9 @@ uint32_t view_get_window_type(struct sway_view *view); const char *view_get_shell(struct sway_view *view); +void view_get_constraints(struct sway_view *view, double *min_width, + double *max_width, double *min_height, double *max_height); + uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, int height); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index c5d53d1d..76fe72ea 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 199309L +#include #include #include #include @@ -95,6 +96,16 @@ static struct sway_xdg_shell_view *xdg_shell_view_from_view( return (struct sway_xdg_shell_view *)view; } +static void get_constraints(struct sway_view *view, double *min_width, + double *max_width, double *min_height, double *max_height) { + struct wlr_xdg_toplevel_state *state = + &view->wlr_xdg_surface->toplevel->current; + *min_width = state->min_width > 0 ? state->min_width : DBL_MIN; + *max_width = state->max_width > 0 ? state->max_width : DBL_MAX; + *min_height = state->min_height > 0 ? state->min_height : DBL_MIN; + *max_height = state->max_height > 0 ? state->max_height : DBL_MAX; +} + static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { if (xdg_shell_view_from_view(view) == NULL) { return NULL; @@ -188,6 +199,7 @@ static void destroy(struct sway_view *view) { } static const struct sway_view_impl view_impl = { + .get_constraints = get_constraints, .get_string_prop = get_string_prop, .configure = configure, .set_activated = set_activated, diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 4bd6af5e..57b51908 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -1,4 +1,5 @@ #define _POSIX_C_SOURCE 199309L +#include #include #include #include @@ -94,6 +95,16 @@ static struct sway_xdg_shell_v6_view *xdg_shell_v6_view_from_view( return (struct sway_xdg_shell_v6_view *)view; } +static void get_constraints(struct sway_view *view, double *min_width, + double *max_width, double *min_height, double *max_height) { + struct wlr_xdg_toplevel_v6_state *state = + &view->wlr_xdg_surface_v6->toplevel->current; + *min_width = state->min_width > 0 ? state->min_width : DBL_MIN; + *max_width = state->max_width > 0 ? state->max_width : DBL_MAX; + *min_height = state->min_height > 0 ? state->min_height : DBL_MIN; + *max_height = state->max_height > 0 ? state->max_height : DBL_MAX; +} + static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { if (xdg_shell_v6_view_from_view(view) == NULL) { return NULL; @@ -184,6 +195,7 @@ static void destroy(struct sway_view *view) { } static const struct sway_view_impl view_impl = { + .get_constraints = get_constraints, .get_string_prop = get_string_prop, .configure = configure, .set_activated = set_activated, diff --git a/sway/input/cursor.c b/sway/input/cursor.c index ad0ceb94..7deb2b19 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -243,7 +243,7 @@ static void handle_resize_motion(struct sway_seat *seat, grow_height = seat->op_ref_height * max_multiplier; } - // Determine new width/height, and accommodate for min/max values + // Determine new width/height, and accommodate for floating min/max values double width = seat->op_ref_width + grow_width; double height = seat->op_ref_height + grow_height; int min_width, max_width, min_height, max_height; @@ -252,6 +252,15 @@ static void handle_resize_motion(struct sway_seat *seat, width = fmax(min_width, fmin(width, max_width)); height = fmax(min_height, fmin(height, max_height)); + // Apply the view's min/max size + if (con->type == C_VIEW) { + double view_min_width, view_max_width, view_min_height, view_max_height; + view_get_constraints(con->sway_view, &view_min_width, &view_max_width, + &view_min_height, &view_max_height); + width = fmax(view_min_width, fmin(width, view_max_width)); + height = fmax(view_min_height, fmin(height, view_max_height)); + } + // Recalculate these, in case we hit a min/max limit grow_width = width - seat->op_ref_width; grow_height = height - seat->op_ref_height; diff --git a/sway/tree/view.c b/sway/tree/view.c index 24594950..89150a69 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -141,6 +141,19 @@ const char *view_get_shell(struct sway_view *view) { return "unknown"; } +void view_get_constraints(struct sway_view *view, double *min_width, + double *max_width, double *min_height, double *max_height) { + if (view->impl->get_constraints) { + view->impl->get_constraints(view, + min_width, max_width, min_height, max_height); + } else { + *min_width = DBL_MIN; + *max_width = DBL_MAX; + *min_height = DBL_MIN; + *max_height = DBL_MAX; + } +} + uint32_t view_configure(struct sway_view *view, double lx, double ly, int width, int height) { if (view->impl->configure) { -- cgit v1.2.3 From 3faceadffe9c9b334d22cad3a348b82078b542b5 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 21:50:35 +1000 Subject: Fix focus bug with floating containers --- sway/input/cursor.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 7deb2b19..54cd3bf7 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -465,6 +465,7 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, } // Send event to surface + seat_set_focus(seat, cont); seat_pointer_notify_button(seat, time_msec, button, state); } -- cgit v1.2.3 From 5ba2ae9c6a4372cbf6f8867b711bb55ef6937cb4 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 22:14:36 +1000 Subject: Implement request_move and request_resize for xwayland views I discovered we have to send a click event when ending the move or resize operation to make xwayland's requests work correctly. --- sway/desktop/xwayland.c | 41 +++++++++++++++++++++++++++++++++++++++++ sway/input/cursor.c | 1 + 2 files changed, 42 insertions(+) (limited to 'sway/input') diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index bce0a37b..2546168b 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -305,6 +305,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) { wl_list_remove(&xwayland_view->destroy.link); wl_list_remove(&xwayland_view->request_configure.link); wl_list_remove(&xwayland_view->request_fullscreen.link); + wl_list_remove(&xwayland_view->request_move.link); + wl_list_remove(&xwayland_view->request_resize.link); wl_list_remove(&xwayland_view->set_title.link); wl_list_remove(&xwayland_view->set_class.link); wl_list_remove(&xwayland_view->set_window_type.link); @@ -400,6 +402,37 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data) transaction_commit_dirty(); } +static void handle_request_move(struct wl_listener *listener, void *data) { + struct sway_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, request_move); + struct sway_view *view = &xwayland_view->view; + struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; + if (!xsurface->mapped) { + return; + } + if (!container_is_floating(view->swayc)) { + return; + } + struct sway_seat *seat = input_manager_current_seat(input_manager); + seat_begin_move(seat, view->swayc, seat->last_button); +} + +static void handle_request_resize(struct wl_listener *listener, void *data) { + struct sway_xwayland_view *xwayland_view = + wl_container_of(listener, xwayland_view, request_resize); + struct sway_view *view = &xwayland_view->view; + struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface; + if (!xsurface->mapped) { + return; + } + if (!container_is_floating(view->swayc)) { + return; + } + struct wlr_xwayland_resize_event *e = data; + struct sway_seat *seat = input_manager_current_seat(input_manager); + seat_begin_resize(seat, view->swayc, seat->last_button, e->edges); +} + static void handle_set_title(struct wl_listener *listener, void *data) { struct sway_xwayland_view *xwayland_view = wl_container_of(listener, xwayland_view, set_title); @@ -495,6 +528,14 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { &xwayland_view->request_fullscreen); xwayland_view->request_fullscreen.notify = handle_request_fullscreen; + wl_signal_add(&xsurface->events.request_move, + &xwayland_view->request_move); + xwayland_view->request_move.notify = handle_request_move; + + wl_signal_add(&xsurface->events.request_resize, + &xwayland_view->request_resize); + xwayland_view->request_resize.notify = handle_request_resize; + wl_signal_add(&xsurface->events.set_title, &xwayland_view->set_title); xwayland_view->set_title.notify = handle_set_title; diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 54cd3bf7..f9b59fcc 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -474,6 +474,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, if (cursor->seat->operation != OP_NONE && button == cursor->seat->op_button && state == WLR_BUTTON_RELEASED) { seat_end_mouse_operation(cursor->seat); + seat_pointer_notify_button(cursor->seat, time_msec, button, state); return; } if (time_msec == 0) { -- cgit v1.2.3 From 009b42602460076f96073166ce647aa59177b961 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 22:44:09 +1000 Subject: Fix damage when shrinking a floating view using cursor --- sway/input/cursor.c | 1 - 1 file changed, 1 deletion(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index f9b59fcc..ee50dcde 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -305,7 +305,6 @@ static void handle_resize_motion(struct sway_seat *seat, } arrange_windows(con); - transaction_commit_dirty(); } void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec, -- cgit v1.2.3 From d21d4b83a3effc56b177f5d505aedfdf2ddbbbd5 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 22 Jul 2018 23:10:06 +1000 Subject: Set cursor when beginning resize and move operations --- sway/input/cursor.c | 4 ++++ sway/input/seat.c | 6 ++++++ 2 files changed, 10 insertions(+) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index ee50dcde..771ad01d 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -215,6 +215,7 @@ static void calculate_floating_constraints(struct sway_container *con, *max_height = config->floating_maximum_height; } } + static void handle_resize_motion(struct sway_seat *seat, struct sway_cursor *cursor) { struct sway_container *con = seat->op_container; @@ -704,6 +705,9 @@ static void handle_request_set_cursor(struct wl_listener *listener, void *data) { struct sway_cursor *cursor = wl_container_of(listener, cursor, request_set_cursor); + if (cursor->seat->operation != OP_NONE) { + return; + } struct wlr_seat_pointer_request_set_cursor_event *event = data; struct wl_client *focused_client = NULL; diff --git a/sway/input/seat.c b/sway/input/seat.c index 4e803efd..273223db 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -910,6 +910,7 @@ void seat_begin_move(struct sway_seat *seat, struct sway_container *con, seat->operation = OP_MOVE; seat->op_container = con; seat->op_button = button; + cursor_set_image(seat->cursor, "grab", NULL); } void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, @@ -932,6 +933,10 @@ void seat_begin_resize(struct sway_seat *seat, struct sway_container *con, seat->op_ref_con_ly = con->y; seat->op_ref_width = con->width; seat->op_ref_height = con->height; + + const char *image = edge == WLR_EDGE_NONE ? + "se-resize" : wlr_xcursor_get_resize_name(edge); + cursor_set_image(seat->cursor, image, NULL); } void seat_end_mouse_operation(struct sway_seat *seat) { @@ -951,6 +956,7 @@ void seat_end_mouse_operation(struct sway_seat *seat) { } seat->operation = OP_NONE; seat->op_container = NULL; + cursor_set_image(seat->cursor, "left_ptr", NULL); } void seat_pointer_notify_button(struct sway_seat *seat, uint32_t time_msec, -- cgit v1.2.3