From 08cfba2192f5770d975c5fe70789a81aaee4dc7e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 26 Jul 2018 18:36:46 +1000 Subject: Allow containers to float Things worth noting: * When a fullscreen view unmaps, the check to unset fullscreen on the workspace has been moved out of view_unmap and into container_destroy, because containers can be fullscreen too * The calls to `container_reap_empty_recursive(workspace)` have been removed from `container_set_floating`. That function reaps upwards so it wouldn't do anything. I'm probably the one who originally added it... * My fix (b14bd1b0b1536039e4f46fe94515c7c44e7afc61) for the tabbed child crash has a side effect where when you close a floating container, focus is not given to the tiled container again. I've removed my fix and removed the call to `send_cursor_motion` from `seat_set_focus_warp`. We should consider calling it from somewhere earlier in the call stack. --- sway/input/cursor.c | 5 ++++- sway/input/seat.c | 5 ----- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index cc0dbe99..d1347198 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -598,7 +598,10 @@ void dispatch_cursor_button(struct sway_cursor *cursor, seat_set_focus_layer(cursor->seat, layer); } seat_pointer_notify_button(cursor->seat, time_msec, button, state); - } else if (cont && container_is_floating(cont)) { + } else if (cont && container_is_floating_or_child(cont)) { + while (cont->parent->layout != L_FLOATING) { + cont = cont->parent; + } dispatch_cursor_button_floating(cursor, time_msec, button, state, surface, sx, sy, cont); } else if (surface && cont && cont->type != C_VIEW) { diff --git a/sway/input/seat.c b/sway/input/seat.c index e7b6e0c5..877a93c6 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -184,7 +184,6 @@ static void handle_seat_container_destroy(struct wl_listener *listener, bool set_focus = focus != NULL && (focus == con || container_has_child(con, focus)) && - con->parent && con->parent->children->length > 1 && con->type != C_WORKSPACE; seat_container_destroy(seat_con); @@ -754,10 +753,6 @@ void seat_set_focus_warp(struct sway_seat *seat, } } - if (last_focus != NULL) { - cursor_send_pointer_motion(seat->cursor, 0, true); - } - seat->has_focus = (container != NULL); update_debug_tree(); -- cgit v1.2.3 From 0b6b6716e28b97213c8f4a3c9e65aeba6409987e Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 26 Jul 2018 19:10:53 +1000 Subject: Fix clicking a floating split container It would focus the split container rather than the child. This commit makes it track the child and the split container separately and send the surface click to the child. --- sway/input/cursor.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'sway/input') diff --git a/sway/input/cursor.c b/sway/input/cursor.c index d1347198..96ac7b33 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -437,18 +437,22 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, 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(cont, cursor); + 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, cont, button); + seat_begin_move(seat, floater, button); return; } @@ -459,12 +463,12 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor, if ((resizing_via_border || resizing_via_mod) && state == WLR_BUTTON_PRESSED) { if (edge == WLR_EDGE_NONE) { - edge |= cursor->cursor->x > cont->x + cont->width / 2 ? + edge |= cursor->cursor->x > floater->x + floater->width / 2 ? WLR_EDGE_RIGHT : WLR_EDGE_LEFT; - edge |= cursor->cursor->y > cont->y + cont->height / 2 ? + edge |= cursor->cursor->y > floater->y + floater->height / 2 ? WLR_EDGE_BOTTOM : WLR_EDGE_TOP; } - seat_begin_resize(seat, cont, button, edge); + seat_begin_resize(seat, floater, button, edge); return; } @@ -599,9 +603,6 @@ void dispatch_cursor_button(struct sway_cursor *cursor, } seat_pointer_notify_button(cursor->seat, time_msec, button, state); } else if (cont && container_is_floating_or_child(cont)) { - while (cont->parent->layout != L_FLOATING) { - cont = cont->parent; - } dispatch_cursor_button_floating(cursor, time_msec, button, state, surface, sx, sy, cont); } else if (surface && cont && cont->type != C_VIEW) { -- cgit v1.2.3 From da2a87f6c71bfe90a4d77542bfc7ed22899f67be Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Thu, 26 Jul 2018 22:58:42 +1000 Subject: When unfloating, return container to previously focused tiled container This introduces seat_get_focus_inactive_tiling and updates `focus mode_toggle` to use it instead, because the previous method wasn't guaranteed to return a tiling view. --- include/sway/input/seat.h | 3 +++ sway/commands/focus.c | 14 ++++++++------ sway/input/seat.c | 23 +++++++++++++++++------ sway/tree/container.c | 5 ++++- 4 files changed, 32 insertions(+), 13 deletions(-) (limited to 'sway/input') diff --git a/include/sway/input/seat.h b/include/sway/input/seat.h index ab25788f..07febe2c 100644 --- a/include/sway/input/seat.h +++ b/include/sway/input/seat.h @@ -124,6 +124,9 @@ struct sway_container *seat_get_focus(struct sway_seat *seat); struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, struct sway_container *container); +struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, + struct sway_container *container); + /** * Descend into the focus stack to find the focus-inactive view. Useful for * container placement when they change position in the tree. diff --git a/sway/commands/focus.c b/sway/commands/focus.c index 9cd8bfae..ce3d032f 100644 --- a/sway/commands/focus.c +++ b/sway/commands/focus.c @@ -35,14 +35,16 @@ static struct cmd_results *focus_mode(struct sway_container *con, struct sway_seat *seat, bool floating) { struct sway_container *ws = con->type == C_WORKSPACE ? con : container_parent(con, C_WORKSPACE); - struct sway_container *new_focus = ws; + struct sway_container *new_focus = NULL; if (floating) { - new_focus = ws->sway_workspace->floating; - if (new_focus->children->length == 0) { - return cmd_results_new(CMD_SUCCESS, NULL, NULL); - } + new_focus = seat_get_focus_inactive(seat, ws->sway_workspace->floating); + } else { + new_focus = seat_get_focus_inactive_tiling(seat, ws); + } + if (!new_focus) { + new_focus = ws; } - seat_set_focus(seat, seat_get_active_child(seat, new_focus)); + seat_set_focus(seat, new_focus); return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/input/seat.c b/sway/input/seat.c index 877a93c6..18d5591d 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -124,12 +124,14 @@ static void seat_send_focus(struct sway_container *con, } static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, - struct sway_container *container, enum sway_container_type type) { + struct sway_container *container, enum sway_container_type type, + bool only_tiling) { if (container->type == C_VIEW) { return container; } - struct sway_container *floating = container->type == C_WORKSPACE ? + struct sway_container *floating = + container->type == C_WORKSPACE && !only_tiling ? container->sway_workspace->floating : NULL; if (container->children->length == 0 && (!floating || floating->children->length == 0)) { @@ -143,6 +145,10 @@ static struct sway_container *seat_get_focus_by_type(struct sway_seat *seat, } if (container_has_child(container, current->container)) { + if (only_tiling && + container_is_floating_or_child(current->container)) { + continue; + } return current->container; } if (floating && container_has_child(floating, current->container)) { @@ -169,7 +175,7 @@ void seat_focus_inactive_children_for_each(struct sway_seat *seat, struct sway_container *seat_get_focus_inactive_view(struct sway_seat *seat, struct sway_container *container) { - return seat_get_focus_by_type(seat, container, C_VIEW); + return seat_get_focus_by_type(seat, container, C_VIEW, false); } static void handle_seat_container_destroy(struct wl_listener *listener, @@ -191,7 +197,7 @@ static void handle_seat_container_destroy(struct wl_listener *listener, if (set_focus) { struct sway_container *next_focus = NULL; while (next_focus == NULL) { - next_focus = seat_get_focus_by_type(seat, parent, C_VIEW); + next_focus = seat_get_focus_by_type(seat, parent, C_VIEW, false); if (next_focus == NULL && parent->type == C_WORKSPACE) { next_focus = parent; @@ -648,7 +654,7 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_container *new_output_last_ws = NULL; if (last_output && new_output && last_output != new_output) { new_output_last_ws = - seat_get_focus_by_type(seat, new_output, C_WORKSPACE); + seat_get_focus_by_type(seat, new_output, C_WORKSPACE, false); } if (container && container->parent) { @@ -853,7 +859,12 @@ void seat_set_exclusive_client(struct sway_seat *seat, struct sway_container *seat_get_focus_inactive(struct sway_seat *seat, struct sway_container *container) { - return seat_get_focus_by_type(seat, container, C_TYPES); + return seat_get_focus_by_type(seat, container, C_TYPES, false); +} + +struct sway_container *seat_get_focus_inactive_tiling(struct sway_seat *seat, + struct sway_container *container) { + return seat_get_focus_by_type(seat, container, C_TYPES, true); } struct sway_container *seat_get_active_child(struct sway_seat *seat, diff --git a/sway/tree/container.c b/sway/tree/container.c index 566432b1..b8ff87e1 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -1015,6 +1015,7 @@ void container_set_floating(struct sway_container *container, bool enable) { return; } + struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *workspace = container_parent(container, C_WORKSPACE); if (enable) { @@ -1029,8 +1030,10 @@ void container_set_floating(struct sway_container *container, bool enable) { if (container->scratchpad) { scratchpad_remove_container(container); } + struct sway_container *sibling = + seat_get_focus_inactive_tiling(seat, workspace); container_remove_child(container); - container_add_child(workspace, container); + container_add_child(sibling, container); container->width = container->parent->width; container->height = container->parent->height; if (container->type == C_VIEW) { -- cgit v1.2.3