mirror of
https://github.com/swaywm/sway.git
synced 2024-11-26 18:01:29 +00:00
Refactor dispatch_cursor_button
There was a separate function dispatch_cursor_button_floating which dealt with the resize and move operations, but as resize is not really limited to floating views, it doesn't make as much sense to have this separate. So both functions are now combined into one. Additionally, dispatch_cursor_button now uses a pattern of returning early instead of using else-ifs.
This commit is contained in:
parent
b4a0363d17
commit
f4280e506b
|
@ -175,7 +175,7 @@ static bool edge_is_external(struct sway_container *cont, enum wlr_edges edge) {
|
|||
return true;
|
||||
}
|
||||
|
||||
static enum wlr_edges find_resize_edge(struct sway_container *cont,
|
||||
static enum wlr_edges find_edge(struct sway_container *cont,
|
||||
struct sway_cursor *cursor) {
|
||||
if (cont->type != C_VIEW) {
|
||||
return WLR_EDGE_NONE;
|
||||
|
@ -199,10 +199,19 @@ static enum wlr_edges find_resize_edge(struct sway_container *cont,
|
|||
edge |= WLR_EDGE_BOTTOM;
|
||||
}
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the cursor is over a _resizable_ edge, return the edge.
|
||||
* Edges that can't be resized are edges of the workspace.
|
||||
*/
|
||||
static enum wlr_edges find_resize_edge(struct sway_container *cont,
|
||||
struct sway_cursor *cursor) {
|
||||
enum wlr_edges edge = find_edge(cont, cursor);
|
||||
if (edge && !container_is_floating(cont) && edge_is_external(cont, edge)) {
|
||||
return WLR_EDGE_NONE;
|
||||
}
|
||||
|
||||
return edge;
|
||||
}
|
||||
|
||||
|
@ -500,57 +509,6 @@ static void handle_cursor_motion_absolute(
|
|||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
seat_set_focus(seat, cont);
|
||||
|
||||
// Deny moving or resizing a fullscreen container
|
||||
if (container_is_fullscreen_or_child(cont)) {
|
||||
seat_pointer_notify_button(seat, time_msec, button, state);
|
||||
return;
|
||||
}
|
||||
struct sway_container *floater = cont;
|
||||
while (floater->parent->layout != L_FLOATING) {
|
||||
floater = floater->parent;
|
||||
}
|
||||
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
|
||||
bool mod_pressed = keyboard &&
|
||||
(wlr_keyboard_get_modifiers(keyboard) & config->floating_mod);
|
||||
enum wlr_edges edge = find_resize_edge(floater, cursor);
|
||||
bool over_title = edge == WLR_EDGE_NONE && !surface;
|
||||
|
||||
// Check for beginning move
|
||||
uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
|
||||
if (button == btn_move && state == WLR_BUTTON_PRESSED &&
|
||||
(mod_pressed || over_title)) {
|
||||
seat_begin_move(seat, floater, button);
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for beginning resize
|
||||
bool resizing_via_border = button == BTN_LEFT && edge != WLR_EDGE_NONE;
|
||||
uint32_t btn_resize = config->floating_mod_inverse ? BTN_LEFT : BTN_RIGHT;
|
||||
bool resizing_via_mod = button == btn_resize && mod_pressed;
|
||||
if ((resizing_via_border || resizing_via_mod) &&
|
||||
state == WLR_BUTTON_PRESSED) {
|
||||
if (edge == WLR_EDGE_NONE) {
|
||||
edge |= cursor->cursor->x > floater->x + floater->width / 2 ?
|
||||
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
||||
edge |= cursor->cursor->y > floater->y + floater->height / 2 ?
|
||||
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
||||
}
|
||||
seat_begin_resize_floating(seat, floater, button, edge);
|
||||
return;
|
||||
}
|
||||
|
||||
seat_pointer_notify_button(seat, time_msec, button, state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a button (and duplicates) to the sorted list of currently pressed buttons
|
||||
*/
|
||||
|
@ -630,26 +588,36 @@ static struct sway_binding* get_active_mouse_binding(const struct sway_cursor *c
|
|||
|
||||
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) {
|
||||
seat_end_mouse_operation(cursor->seat);
|
||||
seat_pointer_notify_button(cursor->seat, time_msec, button, state);
|
||||
return;
|
||||
}
|
||||
if (time_msec == 0) {
|
||||
time_msec = get_current_time_msec();
|
||||
}
|
||||
struct sway_seat *seat = cursor->seat;
|
||||
|
||||
// Handle ending seat operation
|
||||
if (cursor->seat->operation != OP_NONE &&
|
||||
button == cursor->seat->op_button && state == WLR_BUTTON_RELEASED) {
|
||||
seat_end_mouse_operation(seat);
|
||||
seat_pointer_notify_button(seat, time_msec, button, state);
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine what's under the cursor
|
||||
struct wlr_surface *surface = NULL;
|
||||
double sx, sy;
|
||||
struct sway_container *cont = container_at_coords(cursor->seat,
|
||||
struct sway_container *cont = container_at_coords(seat,
|
||||
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||
bool is_floating = cont && container_is_floating(cont);
|
||||
bool is_floating_or_child = cont && container_is_floating_or_child(cont);
|
||||
bool is_fullscreen_or_child = cont && container_is_fullscreen_or_child(cont);
|
||||
enum wlr_edges edge = cont ? find_edge(cont, cursor) : WLR_EDGE_NONE;
|
||||
enum wlr_edges resize_edge = edge ?
|
||||
find_resize_edge(cont, cursor) : WLR_EDGE_NONE;
|
||||
bool on_border = edge != WLR_EDGE_NONE;
|
||||
bool on_contents = cont && !on_border && surface;
|
||||
bool on_titlebar = cont && !on_border && !surface;
|
||||
|
||||
// Handle mouse bindings
|
||||
bool on_border = cont && (find_resize_edge(cont, cursor) != WLR_EDGE_NONE);
|
||||
bool on_contents = !on_border && surface;
|
||||
bool on_titlebar = !on_border && !surface;
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
|
||||
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
|
||||
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
||||
|
||||
struct sway_binding *binding = NULL;
|
||||
|
@ -665,51 +633,78 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
|
|||
state_erase_button(cursor, button);
|
||||
}
|
||||
if (binding) {
|
||||
seat_execute_command(cursor->seat, binding);
|
||||
// TODO: do we want to pass on the event?
|
||||
seat_execute_command(seat, binding);
|
||||
return;
|
||||
}
|
||||
|
||||
enum wlr_edges edge = cont ? find_resize_edge(cont, cursor) : WLR_EDGE_NONE;
|
||||
|
||||
// Handle clicking a layer surface
|
||||
if (surface && wlr_surface_is_layer_surface(surface)) {
|
||||
struct wlr_layer_surface *layer =
|
||||
wlr_layer_surface_from_wlr_surface(surface);
|
||||
if (layer->current.keyboard_interactive) {
|
||||
seat_set_focus_layer(cursor->seat, layer);
|
||||
seat_set_focus_layer(seat, layer);
|
||||
}
|
||||
seat_pointer_notify_button(cursor->seat, time_msec, button, state);
|
||||
} else if (edge && button == BTN_LEFT &&
|
||||
!container_is_floating(cont)) {
|
||||
seat_set_focus(cursor->seat, cont);
|
||||
seat_begin_resize_tiling(cursor->seat, cont, BTN_LEFT, edge);
|
||||
} else if (cont && container_is_floating_or_child(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.
|
||||
//
|
||||
// This prevents, for example, losing focus when clicking on swaybar.
|
||||
struct sway_container *new_ws = cont;
|
||||
if (new_ws && new_ws->type != C_WORKSPACE) {
|
||||
new_ws = container_parent(new_ws, C_WORKSPACE);
|
||||
}
|
||||
struct sway_container *old_ws = seat_get_focus(cursor->seat);
|
||||
if (old_ws && old_ws->type != C_WORKSPACE) {
|
||||
old_ws = container_parent(old_ws, C_WORKSPACE);
|
||||
}
|
||||
if (new_ws != old_ws) {
|
||||
seat_set_focus(cursor->seat, cont);
|
||||
}
|
||||
seat_pointer_notify_button(cursor->seat, time_msec, button, state);
|
||||
} else if (cont) {
|
||||
seat_set_focus(cursor->seat, cont);
|
||||
seat_pointer_notify_button(cursor->seat, time_msec, button, state);
|
||||
} else {
|
||||
seat_pointer_notify_button(cursor->seat, time_msec, button, state);
|
||||
seat_pointer_notify_button(seat, time_msec, button, state);
|
||||
return;
|
||||
}
|
||||
|
||||
transaction_commit_dirty();
|
||||
// Handle tiling resize via border
|
||||
if (resize_edge && button == BTN_LEFT && !is_floating) {
|
||||
seat_set_focus(seat, cont);
|
||||
seat_begin_resize_tiling(seat, cont, button, edge);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle beginning floating move
|
||||
bool mod_pressed = keyboard &&
|
||||
(wlr_keyboard_get_modifiers(keyboard) & config->floating_mod);
|
||||
|
||||
if (is_floating_or_child && !is_fullscreen_or_child) {
|
||||
uint32_t btn_move = config->floating_mod_inverse ? BTN_RIGHT : BTN_LEFT;
|
||||
if (button == btn_move && state == WLR_BUTTON_PRESSED &&
|
||||
(mod_pressed || on_titlebar)) {
|
||||
while (cont->parent->layout != L_FLOATING) {
|
||||
cont = cont->parent;
|
||||
}
|
||||
seat_begin_move(seat, cont, button);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle beginning floating resize
|
||||
if (is_floating_or_child && !is_fullscreen_or_child &&
|
||||
state == WLR_BUTTON_PRESSED) {
|
||||
// Via border
|
||||
if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) {
|
||||
seat_begin_resize_floating(seat, cont, button, resize_edge);
|
||||
return;
|
||||
}
|
||||
|
||||
// Via mod+click
|
||||
struct sway_container *floater = cont;
|
||||
while (floater->parent->layout != L_FLOATING) {
|
||||
floater = floater->parent;
|
||||
}
|
||||
uint32_t btn_resize = config->floating_mod_inverse ?
|
||||
BTN_LEFT : BTN_RIGHT;
|
||||
if (button == btn_resize) {
|
||||
edge |= cursor->cursor->x > floater->x + floater->width / 2 ?
|
||||
WLR_EDGE_RIGHT : WLR_EDGE_LEFT;
|
||||
edge |= cursor->cursor->y > floater->y + floater->height / 2 ?
|
||||
WLR_EDGE_BOTTOM : WLR_EDGE_TOP;
|
||||
seat_begin_resize_floating(seat, floater, button, edge);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle clicking a container surface
|
||||
if (cont) {
|
||||
seat_set_focus(seat, cont);
|
||||
seat_pointer_notify_button(seat, time_msec, button, state);
|
||||
return;
|
||||
}
|
||||
|
||||
seat_pointer_notify_button(seat, time_msec, button, state);
|
||||
}
|
||||
|
||||
static void handle_cursor_button(struct wl_listener *listener, void *data) {
|
||||
|
@ -718,6 +713,7 @@ static void handle_cursor_button(struct wl_listener *listener, void *data) {
|
|||
struct wlr_event_pointer_button *event = data;
|
||||
dispatch_cursor_button(cursor,
|
||||
event->time_msec, event->button, event->state);
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
static void handle_cursor_axis(struct wl_listener *listener, void *data) {
|
||||
|
@ -865,6 +861,7 @@ static void handle_tool_tip(struct wl_listener *listener, void *data) {
|
|||
dispatch_cursor_button(cursor, event->time_msec,
|
||||
BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ?
|
||||
WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED);
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
static void handle_tool_button(struct wl_listener *listener, void *data) {
|
||||
|
@ -889,6 +886,7 @@ static void handle_tool_button(struct wl_listener *listener, void *data) {
|
|||
cursor->tool_buttons--;
|
||||
break;
|
||||
}
|
||||
transaction_commit_dirty();
|
||||
}
|
||||
|
||||
static void handle_request_set_cursor(struct wl_listener *listener,
|
||||
|
|
Loading…
Reference in a new issue