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:
Ryan Dwyer 2018-08-10 16:51:24 +10:00
parent b4a0363d17
commit f4280e506b

View File

@ -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,