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.
master
Ryan Dwyer 6 years ago
parent b4a0363d17
commit f4280e506b

@ -175,7 +175,7 @@ static bool edge_is_external(struct sway_container *cont, enum wlr_edges edge) {
return true; 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) { struct sway_cursor *cursor) {
if (cont->type != C_VIEW) { if (cont->type != C_VIEW) {
return WLR_EDGE_NONE; return WLR_EDGE_NONE;
@ -199,10 +199,19 @@ static enum wlr_edges find_resize_edge(struct sway_container *cont,
edge |= WLR_EDGE_BOTTOM; 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)) { if (edge && !container_is_floating(cont) && edge_is_external(cont, edge)) {
return WLR_EDGE_NONE; return WLR_EDGE_NONE;
} }
return edge; return edge;
} }
@ -500,57 +509,6 @@ static void handle_cursor_motion_absolute(
transaction_commit_dirty(); 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 * 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, void dispatch_cursor_button(struct sway_cursor *cursor,
uint32_t time_msec, uint32_t button, enum wlr_button_state state) { uint32_t time_msec, uint32_t button, enum wlr_button_state state) {
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 && if (cursor->seat->operation != OP_NONE &&
button == cursor->seat->op_button && state == WLR_BUTTON_RELEASED) { button == cursor->seat->op_button && state == WLR_BUTTON_RELEASED) {
seat_end_mouse_operation(cursor->seat); seat_end_mouse_operation(seat);
seat_pointer_notify_button(cursor->seat, time_msec, button, state); seat_pointer_notify_button(seat, time_msec, button, state);
return; return;
} }
if (time_msec == 0) {
time_msec = get_current_time_msec();
}
// Determine what's under the cursor
struct wlr_surface *surface = NULL; struct wlr_surface *surface = NULL;
double sx, sy; 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); 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 // Handle mouse bindings
bool on_border = cont && (find_resize_edge(cont, cursor) != WLR_EDGE_NONE); struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(seat->wlr_seat);
bool on_contents = !on_border && surface;
bool on_titlebar = !on_border && !surface;
struct wlr_keyboard *keyboard = wlr_seat_get_keyboard(cursor->seat->wlr_seat);
uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0; uint32_t modifiers = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
struct sway_binding *binding = NULL; struct sway_binding *binding = NULL;
@ -665,51 +633,78 @@ void dispatch_cursor_button(struct sway_cursor *cursor,
state_erase_button(cursor, button); state_erase_button(cursor, button);
} }
if (binding) { if (binding) {
seat_execute_command(cursor->seat, binding); seat_execute_command(seat, binding);
// TODO: do we want to pass on the event? 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)) { if (surface && wlr_surface_is_layer_surface(surface)) {
struct wlr_layer_surface *layer = struct wlr_layer_surface *layer =
wlr_layer_surface_from_wlr_surface(surface); wlr_layer_surface_from_wlr_surface(surface);
if (layer->current.keyboard_interactive) { if (layer->current.keyboard_interactive) {
seat_set_focus_layer(cursor->seat, layer); seat_set_focus_layer(seat, layer);
}
seat_pointer_notify_button(seat, time_msec, button, state);
return;
}
// 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;
} }
seat_pointer_notify_button(cursor->seat, time_msec, button, state); }
} else if (edge && button == BTN_LEFT &&
!container_is_floating(cont)) { // Handle beginning floating resize
seat_set_focus(cursor->seat, cont); if (is_floating_or_child && !is_fullscreen_or_child &&
seat_begin_resize_tiling(cursor->seat, cont, BTN_LEFT, edge); state == WLR_BUTTON_PRESSED) {
} else if (cont && container_is_floating_or_child(cont)) { // Via border
dispatch_cursor_button_floating(cursor, time_msec, button, state, if (button == BTN_LEFT && resize_edge != WLR_EDGE_NONE) {
surface, sx, sy, cont); seat_begin_resize_floating(seat, cont, button, resize_edge);
} else if (surface && cont && cont->type != C_VIEW) { return;
// 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) { // Via mod+click
old_ws = container_parent(old_ws, C_WORKSPACE); struct sway_container *floater = cont;
while (floater->parent->layout != L_FLOATING) {
floater = floater->parent;
} }
if (new_ws != old_ws) { uint32_t btn_resize = config->floating_mod_inverse ?
seat_set_focus(cursor->seat, cont); 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;
} }
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);
} }
transaction_commit_dirty(); // 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) { 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; struct wlr_event_pointer_button *event = data;
dispatch_cursor_button(cursor, dispatch_cursor_button(cursor,
event->time_msec, event->button, event->state); event->time_msec, event->button, event->state);
transaction_commit_dirty();
} }
static void handle_cursor_axis(struct wl_listener *listener, void *data) { 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, dispatch_cursor_button(cursor, event->time_msec,
BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ? BTN_LEFT, event->state == WLR_TABLET_TOOL_TIP_DOWN ?
WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED); WLR_BUTTON_PRESSED : WLR_BUTTON_RELEASED);
transaction_commit_dirty();
} }
static void handle_tool_button(struct wl_listener *listener, void *data) { 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--; cursor->tool_buttons--;
break; break;
} }
transaction_commit_dirty();
} }
static void handle_request_set_cursor(struct wl_listener *listener, static void handle_request_set_cursor(struct wl_listener *listener,

Loading…
Cancel
Save