diff --git a/include/sway/commands.h b/include/sway/commands.h index 48228a98f..ab2da1a9c 100644 --- a/include/sway/commands.h +++ b/include/sway/commands.h @@ -95,7 +95,7 @@ struct cmd_results *add_color(const char *name, /** * TODO: Move this function and its dependent functions to container.c. */ -bool container_resize_tiled(struct sway_container *parent, enum wlr_edges edge, +void container_resize_tiled(struct sway_container *parent, enum wlr_edges edge, int amount); sway_cmd cmd_assign; diff --git a/include/sway/config.h b/include/sway/config.h index 549d2677e..bc02c0fd1 100644 --- a/include/sway/config.h +++ b/include/sway/config.h @@ -331,6 +331,12 @@ enum focus_wrapping_mode { WRAP_FORCE }; +enum mouse_warping_mode { + WARP_NO, + WARP_OUTPUT, + WARP_CONTAINER +}; + /** * The configuration struct. The result of loading a config file. */ @@ -372,7 +378,7 @@ struct sway_config { // Flags bool focus_follows_mouse; bool raise_floating; - bool mouse_warping; + enum mouse_warping_mode mouse_warping; enum focus_wrapping_mode focus_wrapping; bool active; bool failed; diff --git a/sway/commands/mouse_warping.c b/sway/commands/mouse_warping.c index eef32ce78..d067bc654 100644 --- a/sway/commands/mouse_warping.c +++ b/sway/commands/mouse_warping.c @@ -6,13 +6,15 @@ struct cmd_results *cmd_mouse_warping(int argc, char **argv) { struct cmd_results *error = NULL; if ((error = checkarg(argc, "mouse_warping", EXPECTED_EQUAL_TO, 1))) { return error; + } else if (strcasecmp(argv[0], "container") == 0) { + config->mouse_warping = WARP_CONTAINER; } else if (strcasecmp(argv[0], "output") == 0) { - config->mouse_warping = true; + config->mouse_warping = WARP_OUTPUT; } else if (strcasecmp(argv[0], "none") == 0) { - config->mouse_warping = false; + config->mouse_warping = WARP_NO; } else { return cmd_results_new(CMD_FAILURE, "mouse_warping", - "Expected 'mouse_warping output|none'"); + "Expected 'mouse_warping output|container|none'"); } return cmd_results_new(CMD_SUCCESS, NULL, NULL); } diff --git a/sway/commands/resize.c b/sway/commands/resize.c index 1343b165a..6de14ca3f 100644 --- a/sway/commands/resize.c +++ b/sway/commands/resize.c @@ -179,11 +179,11 @@ static void container_recursive_resize(struct sway_container *container, } } -static bool resize_tiled(struct sway_container *parent, int amount, +static void resize_tiled(struct sway_container *parent, int amount, enum resize_axis axis) { struct sway_container *focused = parent; if (!parent) { - return false; + return; } enum sway_container_layout parallel_layout = @@ -216,7 +216,7 @@ static bool resize_tiled(struct sway_container *parent, int amount, } if (!parent) { // Can't resize in this direction - return false; + return; } // Implement up/down/left/right direction by zeroing one of the weights, @@ -248,22 +248,22 @@ static bool resize_tiled(struct sway_container *parent, int amount, if (sibling_pos < parent_pos && minor_weight) { double pixels = -amount / minor_weight; if (major_weight && (sibling_size + pixels / 2) < min_sane) { - return false; // Too small + return; // Too small } else if (!major_weight && sibling_size + pixels < min_sane) { - return false; // Too small + return; // Too small } } else if (sibling_pos > parent_pos && major_weight) { double pixels = -amount / major_weight; if (minor_weight && (sibling_size + pixels / 2) < min_sane) { - return false; // Too small + return; // Too small } else if (!minor_weight && sibling_size + pixels < min_sane) { - return false; // Too small + return; // Too small } } } else { double pixels = amount; if (parent_size + pixels < min_sane) { - return false; // Too small + return; // Too small } } } @@ -317,10 +317,9 @@ static bool resize_tiled(struct sway_container *parent, int amount, } else { arrange_workspace(parent->workspace); } - return true; } -bool container_resize_tiled(struct sway_container *parent, +void container_resize_tiled(struct sway_container *parent, enum wlr_edges edge, int amount) { enum resize_axis axis = RESIZE_AXIS_INVALID; switch (edge) { @@ -339,7 +338,7 @@ bool container_resize_tiled(struct sway_container *parent, case WLR_EDGE_NONE: break; } - return resize_tiled(parent, amount, axis); + resize_tiled(parent, amount, axis); } /** @@ -447,7 +446,10 @@ static struct cmd_results *resize_adjust_tiled(enum resize_axis axis, } } - if (!resize_tiled(current, amount->amount, axis)) { + double old_width = current->width; + double old_height = current->height; + resize_tiled(current, amount->amount, axis); + if (current->width == old_width && current->height == old_height) { return cmd_results_new(CMD_INVALID, "resize", "Cannot resize any further"); } diff --git a/sway/config.c b/sway/config.c index 1926bc08e..f239ba1d9 100644 --- a/sway/config.c +++ b/sway/config.c @@ -223,7 +223,7 @@ static void config_defaults(struct sway_config *config) { // Flags config->focus_follows_mouse = true; config->raise_floating = true; - config->mouse_warping = true; + config->mouse_warping = WARP_OUTPUT; config->focus_wrapping = WRAP_YES; config->validating = false; config->reloading = false; diff --git a/sway/input/cursor.c b/sway/input/cursor.c index 6d57c45fc..5c4462997 100644 --- a/sway/input/cursor.c +++ b/sway/input/cursor.c @@ -877,6 +877,7 @@ void dispatch_cursor_button(struct sway_cursor *cursor, while (cont->parent) { cont = cont->parent; } + seat_set_focus_container(seat, cont); seat_begin_move_floating(seat, cont, button); return; } diff --git a/sway/input/seat.c b/sway/input/seat.c index f418785d7..03ed638ed 100644 --- a/sway/input/seat.c +++ b/sway/input/seat.c @@ -772,7 +772,9 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node, } if (last_focus) { - if (config->mouse_warping && warp && new_output != last_output) { + if (config->mouse_warping && warp && + (new_output != last_output || + config->mouse_warping == WARP_CONTAINER)) { double x = 0; double y = 0; if (container) { @@ -782,9 +784,11 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node, x = new_workspace->x + new_workspace->width / 2.0; y = new_workspace->y + new_workspace->height / 2.0; } + if (!wlr_output_layout_contains_point(root->output_layout, new_output->wlr_output, seat->cursor->cursor->x, - seat->cursor->cursor->y)) { + seat->cursor->cursor->y) + || config->mouse_warping == WARP_CONTAINER) { wlr_cursor_warp(seat->cursor->cursor, NULL, x, y); cursor_send_pointer_motion(seat->cursor, 0, true); } @@ -1038,7 +1042,7 @@ void seat_begin_down(struct sway_seat *seat, struct sway_container *con, seat->op_moved = false; // In case the container was not raised by gaining focus, raise on click - if (con && !config->raise_floating) { + if (!config->raise_floating) { container_raise_floating(con); } } @@ -1052,6 +1056,12 @@ void seat_begin_move_floating(struct sway_seat *seat, seat->operation = OP_MOVE_FLOATING; seat->op_container = con; seat->op_button = button; + + // In case the container was not raised by gaining focus, raise on click + if (!config->raise_floating) { + container_raise_floating(con); + } + cursor_set_image(seat->cursor, "grab", NULL); } @@ -1085,6 +1095,11 @@ void seat_begin_resize_floating(struct sway_seat *seat, seat->op_ref_con_ly = con->y; seat->op_ref_width = con->width; seat->op_ref_height = con->height; + // + // In case the container was not raised by gaining focus, raise on click + if (!config->raise_floating) { + container_raise_floating(con); + } const char *image = edge == WLR_EDGE_NONE ? "se-resize" : wlr_xcursor_get_resize_name(edge); diff --git a/sway/sway.5.scd b/sway/sway.5.scd index 28ab15dfd..240e0731b 100644 --- a/sway/sway.5.scd +++ b/sway/sway.5.scd @@ -492,9 +492,10 @@ The default colors are: If _--pango\_markup_ is given, then _mode_ will be interpreted as pango markup. -*mouse\_warping* output|none +*mouse\_warping* output|container|none If _output_ is specified, the mouse will be moved to new outputs as you - move focus between them. Default is _output_. + move focus between them. If _container_ is specified, the mouse will be + moved to the middle of the container on switch. Default is _output_. *no\_focus* Prevents windows matching from being focused automatically when @@ -598,7 +599,7 @@ match any output by using the output name "\*". *workspace* prev\_on\_output|next\_on\_output Switches to the next workspace on the current output. -*workspace* back_and_forth +*workspace* back\_and\_forth Switches to the previously focused workspace. *workspace* gaps inner|outer diff --git a/sway/tree/container.c b/sway/tree/container.c index 1664514ac..f36fe4b07 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -358,7 +358,6 @@ struct sway_container *container_at(struct sway_workspace *workspace, struct wlr_surface **surface, double *sx, double *sy) { struct sway_container *c; - // Focused view's popups struct sway_seat *seat = input_manager_current_seat(input_manager); struct sway_container *focus = seat_get_focused_container(seat); bool is_floating = focus && container_is_floating_or_child(focus); @@ -370,14 +369,11 @@ struct sway_container *container_at(struct sway_workspace *workspace, } *surface = NULL; } - // Cast a ray to handle floating windows - for (int i = workspace->floating->length - 1; i >= 0; --i) { - struct sway_container *cn = workspace->floating->items[i]; - if (cn->view && (c = surface_at_view(cn, lx, ly, surface, sx, sy))) { - return c; - } + // Floating + if ((c = floating_container_at(lx, ly, surface ,sx ,sy))) { + return c; } - // If focused is tiling, focused view's non-popups + // Tiling (focused) if (focus && focus->view && !is_floating) { if ((c = surface_at_view(focus, lx, ly, surface, sx, sy))) { return c; diff --git a/sway/tree/view.c b/sway/tree/view.c index 1f00452dd..e613ac0b0 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -243,10 +243,10 @@ void view_autoconfigure(struct sway_view *view) { // title area. We have to offset the surface y by the height of the title, // bar, and disable any top border because we'll always have the title bar. enum sway_container_layout layout = container_parent_layout(con); - if (layout == L_TABBED) { + if (layout == L_TABBED && !container_is_floating(con)) { y_offset = container_titlebar_height(); view->border_top = false; - } else if (layout == L_STACKED) { + } else if (layout == L_STACKED && !container_is_floating(con)) { list_t *siblings = container_get_siblings(con); y_offset = container_titlebar_height() * siblings->length; view->border_top = false; diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c index b357d83d4..d76505607 100644 --- a/sway/tree/workspace.c +++ b/sway/tree/workspace.c @@ -624,7 +624,10 @@ void workspace_add_gaps(struct sway_workspace *ws) { if (config->smart_gaps) { struct sway_seat *seat = input_manager_get_default_seat(input_manager); struct sway_container *focus = - seat_get_focus_inactive_view(seat, &ws->node); + seat_get_focus_inactive_tiling(seat, ws); + if (focus && !focus->view) { + focus = seat_get_focus_inactive_view(seat, &focus->node); + } if (focus && focus->view && view_is_only_visible(focus->view)) { return; } diff --git a/swaybar/main.c b/swaybar/main.c index d2c579db6..db204f4a8 100644 --- a/swaybar/main.c +++ b/swaybar/main.c @@ -62,7 +62,7 @@ int main(int argc, char **argv) { bar_id = strdup(optarg); break; case 'v': - fprintf(stdout, "sway version " SWAY_VERSION "\n"); + fprintf(stdout, "swaybar version " SWAY_VERSION "\n"); exit(EXIT_SUCCESS); break; case 'd': // Debug diff --git a/swaymsg/main.c b/swaymsg/main.c index 3767daf32..4688737c6 100644 --- a/swaymsg/main.c +++ b/swaymsg/main.c @@ -345,7 +345,7 @@ int main(int argc, char **argv) { cmdtype = strdup(optarg); break; case 'v': - fprintf(stdout, "sway version " SWAY_VERSION "\n"); + fprintf(stdout, "swaymsg version " SWAY_VERSION "\n"); exit(EXIT_SUCCESS); break; default: