aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-10-03 21:21:25 +0200
committerLibravatar GitHub <noreply@github.com>2018-10-03 21:21:25 +0200
commit7fdc557f1e16f14dea080714b3a261daf8f4634e (patch)
tree2564be2f236c91052227bf2cdf322d620caa18b4
parentMerge pull request #2757 from RyanDwyer/check-focus-stack-empty (diff)
parentReenable popup-handling for determining focus (diff)
downloadsway-7fdc557f1e16f14dea080714b3a261daf8f4634e.tar.gz
sway-7fdc557f1e16f14dea080714b3a261daf8f4634e.tar.zst
sway-7fdc557f1e16f14dea080714b3a261daf8f4634e.zip
Merge pull request #2709 from BuJo/feature/raise_floating
raise floating
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h1
-rw-r--r--include/sway/input/cursor.h1
-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
11 files changed, 64 insertions, 34 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 64f707f4..f7fafb96 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -125,6 +125,7 @@ sway_cmd cmd_floating_modifier;
125sway_cmd cmd_floating_scroll; 125sway_cmd cmd_floating_scroll;
126sway_cmd cmd_focus; 126sway_cmd cmd_focus;
127sway_cmd cmd_focus_follows_mouse; 127sway_cmd cmd_focus_follows_mouse;
128sway_cmd cmd_raise_floating;
128sway_cmd cmd_focus_on_window_activation; 129sway_cmd cmd_focus_on_window_activation;
129sway_cmd cmd_focus_wrapping; 130sway_cmd cmd_focus_wrapping;
130sway_cmd cmd_font; 131sway_cmd cmd_font;
diff --git a/include/sway/config.h b/include/sway/config.h
index 98a18b76..02ace979 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -359,6 +359,7 @@ struct sway_config {
359 359
360 // Flags 360 // Flags
361 bool focus_follows_mouse; 361 bool focus_follows_mouse;
362 bool raise_floating;
362 bool mouse_warping; 363 bool mouse_warping;
363 enum focus_wrapping_mode focus_wrapping; 364 enum focus_wrapping_mode focus_wrapping;
364 bool active; 365 bool active;
diff --git a/include/sway/input/cursor.h b/include/sway/input/cursor.h
index 7ec45120..4d47ab42 100644
--- a/include/sway/input/cursor.h
+++ b/include/sway/input/cursor.h
@@ -10,6 +10,7 @@ struct sway_cursor {
10 struct wlr_cursor *cursor; 10 struct wlr_cursor *cursor;
11 struct { 11 struct {
12 double x, y; 12 double x, y;
13 struct sway_node *node;
13 } previous; 14 } previous;
14 struct wlr_xcursor_manager *xcursor_manager; 15 struct wlr_xcursor_manager *xcursor_manager;
15 16
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[] = {
107 { "new_window", cmd_default_border }, 107 { "new_window", cmd_default_border },
108 { "no_focus", cmd_no_focus }, 108 { "no_focus", cmd_no_focus },
109 { "output", cmd_output }, 109 { "output", cmd_output },
110 { "raise_floating", cmd_raise_floating },
110 { "seat", cmd_seat }, 111 { "seat", cmd_seat },
111 { "set", cmd_set }, 112 { "set", cmd_set },
112 { "show_marks", cmd_show_marks }, 113 { "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 @@
1#include <string.h>
2#include <strings.h>
3#include "sway/commands.h"
4#include "util.h"
5
6struct cmd_results *cmd_raise_floating(int argc, char **argv) {
7 struct cmd_results *error = NULL;
8 if ((error = checkarg(argc, "raise_floating", EXPECTED_EQUAL_TO, 1))) {
9 return error;
10 }
11 config->raise_floating =
12 parse_boolean(argv[0], config->raise_floating);
13 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
14}
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) {
221 221
222 // Flags 222 // Flags
223 config->focus_follows_mouse = true; 223 config->focus_follows_mouse = true;
224 config->raise_floating = true;
224 config->mouse_warping = true; 225 config->mouse_warping = true;
225 config->focus_wrapping = WRAP_YES; 226 config->focus_wrapping = WRAP_YES;
226 config->validating = false; 227 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,
567 struct wlr_surface *surface = NULL; 567 struct wlr_surface *surface = NULL;
568 double sx, sy; 568 double sx, sy;
569 569
570 // Find the node beneath the pointer's previous position 570 struct sway_node *prev_node = cursor->previous.node;
571 struct sway_node *prev_node = node_at_coords(seat, 571 struct sway_node *node = node_at_coords(seat,
572 cursor->previous.x, cursor->previous.y, &surface, &sx, &sy); 572 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
573
573 // Update the stored previous position 574 // Update the stored previous position
574 cursor->previous.x = cursor->cursor->x; 575 cursor->previous.x = cursor->cursor->x;
575 cursor->previous.y = cursor->cursor->y; 576 cursor->previous.y = cursor->cursor->y;
577 cursor->previous.node = node;
576 578
577 struct sway_node *node = node_at_coords(seat,
578 cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
579 if (node && config->focus_follows_mouse && allow_refocusing) { 579 if (node && config->focus_follows_mouse && allow_refocusing) {
580 struct sway_node *focus = seat_get_focus(seat); 580 struct sway_node *focus = seat_get_focus(seat);
581 if (focus && node->type == N_WORKSPACE) { 581 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) {
606 return 0; 606 return 0;
607} 607}
608 608
609static void container_raise_floating(struct sway_container *con) {
610 // Bring container to front by putting it at the end of the floating list.
611 struct sway_container *floater = con;
612 while (floater->parent) {
613 floater = floater->parent;
614 }
615 if (container_is_floating(floater)) {
616 list_move_to_end(floater->workspace->floating, floater);
617 node_set_dirty(&floater->workspace->node);
618 }
619}
620
609void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node, 621void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node,
610 bool warp, bool notify) { 622 bool warp, bool notify) {
611 if (seat->focused_layer) { 623 if (seat->focused_layer) {
@@ -733,16 +745,8 @@ void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node,
733 } 745 }
734 746
735 // If we've focused a floating container, bring it to the front. 747 // If we've focused a floating container, bring it to the front.
736 // We do this by putting it at the end of the floating list. 748 if (container && config->raise_floating) {
737 if (container) { 749 container_raise_floating(container);
738 struct sway_container *floater = container;
739 while (floater->parent) {
740 floater = floater->parent;
741 }
742 if (container_is_floating(floater)) {
743 list_move_to_end(floater->workspace->floating, floater);
744 node_set_dirty(&floater->workspace->node);
745 }
746 } 750 }
747 751
748 if (last_focus) { 752 if (last_focus) {
@@ -1017,6 +1021,11 @@ void seat_begin_down(struct sway_seat *seat, struct sway_container *con,
1017 seat->op_ref_con_lx = sx; 1021 seat->op_ref_con_lx = sx;
1018 seat->op_ref_con_ly = sy; 1022 seat->op_ref_con_ly = sy;
1019 seat->op_moved = false; 1023 seat->op_moved = false;
1024
1025 // In case the container was not raised by gaining focus, raise on click
1026 if (con && !config->raise_floating) {
1027 container_raise_floating(con);
1028 }
1020} 1029}
1021 1030
1022void seat_begin_move_floating(struct sway_seat *seat, 1031void 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(
48 'commands/floating_modifier.c', 48 'commands/floating_modifier.c',
49 'commands/focus.c', 49 'commands/focus.c',
50 'commands/focus_follows_mouse.c', 50 'commands/focus_follows_mouse.c',
51 'commands/raise_floating.c',
51 'commands/focus_on_window_activation.c', 52 'commands/focus_on_window_activation.c',
52 'commands/focus_wrapping.c', 53 'commands/focus_wrapping.c',
53 'commands/font.c', 54 '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:
441 devices. A list of input device names may be obtained via *swaymsg -t 441 devices. A list of input device names may be obtained via *swaymsg -t
442 get\_inputs*. 442 get\_inputs*.
443 443
444*raise\_floating* yes|no
445 Controls the behaviour of floating windows. A _yes_ (the default) will
446 raise windows on gaining focus. A _no_ will only raise floating windows
447 by clicking anywhere in the window.
448
444*seat* <seat> <seat-subcommands...> 449*seat* <seat> <seat-subcommands...>
445 For details on seat subcommands, see *sway-input*(5). 450 For details on seat subcommands, see *sway-input*(5).
446 451
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,
151 return NULL; 151 return NULL;
152} 152}
153 153
154static void surface_at_view(struct sway_container *con, double lx, double ly, 154static struct sway_container *surface_at_view(struct sway_container *con, double lx, double ly,
155 struct wlr_surface **surface, double *sx, double *sy) { 155 struct wlr_surface **surface, double *sx, double *sy) {
156 if (!sway_assert(con->view, "Expected a view")) { 156 if (!sway_assert(con->view, "Expected a view")) {
157 return; 157 return NULL;
158 } 158 }
159 struct sway_view *view = con->view; 159 struct sway_view *view = con->view;
160 double view_sx = lx - view->x + view->geometry.x; 160 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,
184 *sx = _sx; 184 *sx = _sx;
185 *sy = _sy; 185 *sy = _sy;
186 *surface = _surface; 186 *surface = _surface;
187 return con;
187 } 188 }
189 return NULL;
188} 190}
189 191
190/** 192/**
@@ -355,37 +357,31 @@ struct sway_container *container_at(struct sway_workspace *workspace,
355 double lx, double ly, 357 double lx, double ly,
356 struct wlr_surface **surface, double *sx, double *sy) { 358 struct wlr_surface **surface, double *sx, double *sy) {
357 struct sway_container *c; 359 struct sway_container *c;
360
358 // Focused view's popups 361 // Focused view's popups
359 struct sway_seat *seat = input_manager_current_seat(input_manager); 362 struct sway_seat *seat = input_manager_current_seat(input_manager);
360 struct sway_container *focus = seat_get_focused_container(seat); 363 struct sway_container *focus = seat_get_focused_container(seat);
361 bool is_floating = focus && container_is_floating_or_child(focus); 364 bool is_floating = focus && container_is_floating_or_child(focus);
362 // Focused view's popups 365 // Focused view's popups
363 if (focus && focus->view) { 366 if (focus && focus->view) {
364 surface_at_view(focus, lx, ly, surface, sx, sy); 367 c = surface_at_view(focus, lx, ly, surface, sx, sy);
365 if (*surface && surface_is_popup(*surface)) { 368 if (c && surface_is_popup(*surface)) {
366 return focus; 369 return c;
367 } 370 }
368 *surface = NULL; 371 *surface = NULL;
369 } 372 }
370 // If focused is floating, focused view's non-popups 373 // Cast a ray to handle floating windows
371 if (focus && focus->view && is_floating) { 374 for (int i = workspace->floating->length - 1; i >= 0; --i) {
372 surface_at_view(focus, lx, ly, surface, sx, sy); 375 struct sway_container *cn = workspace->floating->items[i];
373 if (*surface) { 376 if (cn->view && (c = surface_at_view(cn, lx, ly, surface, sx, sy))) {
374 return focus; 377 return c;
375 } 378 }
376 *surface = NULL;
377 }
378 // Floating (non-focused)
379 if ((c = floating_container_at(lx, ly, surface, sx, sy))) {
380 return c;
381 } 379 }
382 // If focused is tiling, focused view's non-popups 380 // If focused is tiling, focused view's non-popups
383 if (focus && focus->view && !is_floating) { 381 if (focus && focus->view && !is_floating) {
384 surface_at_view(focus, lx, ly, surface, sx, sy); 382 if ((c = surface_at_view(focus, lx, ly, surface, sx, sy))) {
385 if (*surface) { 383 return c;
386 return focus;
387 } 384 }
388 *surface = NULL;
389 } 385 }
390 // Tiling (non-focused) 386 // Tiling (non-focused)
391 if ((c = tiling_container_at(&workspace->node, lx, ly, surface, sx, sy))) { 387 if ((c = tiling_container_at(&workspace->node, lx, ly, surface, sx, sy))) {