aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/raise_floating.c14
-rw-r--r--sway/config.c1
-rw-r--r--sway/input/cursor.c10
-rw-r--r--sway/input/seat.c29
-rw-r--r--sway/meson.build1
-rw-r--r--sway/sway.5.scd5
-rw-r--r--sway/tree/container.c34
8 files changed, 61 insertions, 34 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 72db8ab9..5dd27f7e 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -107,6 +107,7 @@ static struct cmd_handler handlers[] = {
{ "new_window", cmd_default_border },
{ "no_focus", cmd_no_focus },
{ "output", cmd_output },
+ { "raise_floating", cmd_raise_floating },
{ "seat", cmd_seat },
{ "set", cmd_set },
{ "show_marks", cmd_show_marks },
diff --git a/sway/commands/raise_floating.c b/sway/commands/raise_floating.c
new file mode 100644
index 00000000..930299a1
--- /dev/null
+++ b/sway/commands/raise_floating.c
@@ -0,0 +1,14 @@
+#include <string.h>
+#include <strings.h>
+#include "sway/commands.h"
+#include "util.h"
+
+struct cmd_results *cmd_raise_floating(int argc, char **argv) {
+ struct cmd_results *error = NULL;
+ if ((error = checkarg(argc, "raise_floating", EXPECTED_EQUAL_TO, 1))) {
+ return error;
+ }
+ config->raise_floating =
+ parse_boolean(argv[0], config->raise_floating);
+ return cmd_results_new(CMD_SUCCESS, NULL, NULL);
+}
diff --git a/sway/config.c b/sway/config.c
index 048b57de..b56c4f71 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -221,6 +221,7 @@ static void config_defaults(struct sway_config *config) {
// Flags
config->focus_follows_mouse = true;
+ config->raise_floating = true;
config->mouse_warping = true;
config->focus_wrapping = WRAP_YES;
config->validating = false;
diff --git a/sway/input/cursor.c b/sway/input/cursor.c
index afad6f6f..3c62acb9 100644
--- a/sway/input/cursor.c
+++ b/sway/input/cursor.c
@@ -567,15 +567,15 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
struct wlr_surface *surface = NULL;
double sx, sy;
- // Find the node beneath the pointer's previous position
- struct sway_node *prev_node = node_at_coords(seat,
- cursor->previous.x, cursor->previous.y, &surface, &sx, &sy);
+ struct sway_node *prev_node = cursor->previous.node;
+ struct sway_node *node = node_at_coords(seat,
+ cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
+
// Update the stored previous position
cursor->previous.x = cursor->cursor->x;
cursor->previous.y = cursor->cursor->y;
+ cursor->previous.node = node;
- struct sway_node *node = node_at_coords(seat,
- cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
if (node && config->focus_follows_mouse && allow_refocusing) {
struct sway_node *focus = seat_get_focus(seat);
if (focus && node->type == N_WORKSPACE) {
diff --git a/sway/input/seat.c b/sway/input/seat.c
index 69bee47e..15c56a43 100644
--- a/sway/input/seat.c
+++ b/sway/input/seat.c
@@ -606,6 +606,18 @@ static int handle_urgent_timeout(void *data) {
return 0;
}
+static void container_raise_floating(struct sway_container *con) {
+ // Bring container to front by putting it at the end of the floating list.
+ struct sway_container *floater = con;
+ while (floater->parent) {
+ floater = floater->parent;
+ }
+ if (container_is_floating(floater)) {
+ list_move_to_end(floater->workspace->floating, floater);
+ node_set_dirty(&floater->workspace->node);
+ }
+}
+
void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node,
bool warp, bool notify) {
if (seat->focused_layer) {
@@ -733,16 +745,8 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node,
}
// If we've focused a floating container, bring it to the front.
- // We do this by putting it at the end of the floating list.
- if (container) {
- struct sway_container *floater = container;
- while (floater->parent) {
- floater = floater->parent;
- }
- if (container_is_floating(floater)) {
- list_move_to_end(floater->workspace->floating, floater);
- node_set_dirty(&floater->workspace->node);
- }
+ if (container && config->raise_floating) {
+ container_raise_floating(container);
}
if (last_focus) {
@@ -1017,6 +1021,11 @@ void seat_begin_down(struct sway_seat *seat, struct sway_container *con,
seat->op_ref_con_lx = sx;
seat->op_ref_con_ly = sy;
seat->op_moved = false;
+
+ // In case the container was not raised by gaining focus, raise on click
+ if (con && !config->raise_floating) {
+ container_raise_floating(con);
+ }
}
void seat_begin_move_floating(struct sway_seat *seat,
diff --git a/sway/meson.build b/sway/meson.build
index 00ebcb40..8ab28869 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -48,6 +48,7 @@ sway_sources = files(
'commands/floating_modifier.c',
'commands/focus.c',
'commands/focus_follows_mouse.c',
+ 'commands/raise_floating.c',
'commands/focus_on_window_activation.c',
'commands/focus_wrapping.c',
'commands/font.c',
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index 3202d517..3fda6cef 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -441,6 +441,11 @@ The default colors are:
devices. A list of input device names may be obtained via *swaymsg -t
get\_inputs*.
+*raise\_floating* yes|no
+ Controls the behaviour of floating windows. A _yes_ (the default) will
+ raise windows on gaining focus. A _no_ will only raise floating windows
+ by clicking anywhere in the window.
+
*seat* <seat> <seat-subcommands...>
For details on seat subcommands, see *sway-input*(5).
diff --git a/sway/tree/container.c b/sway/tree/container.c
index a069b177..9db7aed1 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -151,10 +151,10 @@ struct sway_container *container_find_child(struct sway_container *container,
return NULL;
}
-static void surface_at_view(struct sway_container *con, double lx, double ly,
+static struct sway_container *surface_at_view(struct sway_container *con, double lx, double ly,
struct wlr_surface **surface, double *sx, double *sy) {
if (!sway_assert(con->view, "Expected a view")) {
- return;
+ return NULL;
}
struct sway_view *view = con->view;
double view_sx = lx - view->x + view->geometry.x;
@@ -184,7 +184,9 @@ static void surface_at_view(struct sway_container *con, double lx, double ly,
*sx = _sx;
*sy = _sy;
*surface = _surface;
+ return con;
}
+ return NULL;
}
/**
@@ -355,37 +357,31 @@ struct sway_container *container_at(struct sway_workspace *workspace,
double lx, double ly,
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);
// Focused view's popups
if (focus && focus->view) {
- surface_at_view(focus, lx, ly, surface, sx, sy);
- if (*surface && surface_is_popup(*surface)) {
- return focus;
+ c = surface_at_view(focus, lx, ly, surface, sx, sy);
+ if (c && surface_is_popup(*surface)) {
+ return c;
}
*surface = NULL;
}
- // If focused is floating, focused view's non-popups
- if (focus && focus->view && is_floating) {
- surface_at_view(focus, lx, ly, surface, sx, sy);
- if (*surface) {
- return focus;
+ // 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;
}
- *surface = NULL;
- }
- // Floating (non-focused)
- if ((c = floating_container_at(lx, ly, surface, sx, sy))) {
- return c;
}
// If focused is tiling, focused view's non-popups
if (focus && focus->view && !is_floating) {
- surface_at_view(focus, lx, ly, surface, sx, sy);
- if (*surface) {
- return focus;
+ if ((c = surface_at_view(focus, lx, ly, surface, sx, sy))) {
+ return c;
}
- *surface = NULL;
}
// Tiling (non-focused)
if ((c = tiling_container_at(&workspace->node, lx, ly, surface, sx, sy))) {