mirror of
https://github.com/swaywm/sway.git
synced 2024-11-14 06:24:20 +01:00
Merge pull request #2709 from BuJo/feature/raise_floating
raise floating
This commit is contained in:
commit
7fdc557f1e
@ -125,6 +125,7 @@ sway_cmd cmd_floating_modifier;
|
|||||||
sway_cmd cmd_floating_scroll;
|
sway_cmd cmd_floating_scroll;
|
||||||
sway_cmd cmd_focus;
|
sway_cmd cmd_focus;
|
||||||
sway_cmd cmd_focus_follows_mouse;
|
sway_cmd cmd_focus_follows_mouse;
|
||||||
|
sway_cmd cmd_raise_floating;
|
||||||
sway_cmd cmd_focus_on_window_activation;
|
sway_cmd cmd_focus_on_window_activation;
|
||||||
sway_cmd cmd_focus_wrapping;
|
sway_cmd cmd_focus_wrapping;
|
||||||
sway_cmd cmd_font;
|
sway_cmd cmd_font;
|
||||||
|
@ -359,6 +359,7 @@ struct sway_config {
|
|||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
bool focus_follows_mouse;
|
bool focus_follows_mouse;
|
||||||
|
bool raise_floating;
|
||||||
bool mouse_warping;
|
bool mouse_warping;
|
||||||
enum focus_wrapping_mode focus_wrapping;
|
enum focus_wrapping_mode focus_wrapping;
|
||||||
bool active;
|
bool active;
|
||||||
|
@ -10,6 +10,7 @@ struct sway_cursor {
|
|||||||
struct wlr_cursor *cursor;
|
struct wlr_cursor *cursor;
|
||||||
struct {
|
struct {
|
||||||
double x, y;
|
double x, y;
|
||||||
|
struct sway_node *node;
|
||||||
} previous;
|
} previous;
|
||||||
struct wlr_xcursor_manager *xcursor_manager;
|
struct wlr_xcursor_manager *xcursor_manager;
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ static struct cmd_handler handlers[] = {
|
|||||||
{ "new_window", cmd_default_border },
|
{ "new_window", cmd_default_border },
|
||||||
{ "no_focus", cmd_no_focus },
|
{ "no_focus", cmd_no_focus },
|
||||||
{ "output", cmd_output },
|
{ "output", cmd_output },
|
||||||
|
{ "raise_floating", cmd_raise_floating },
|
||||||
{ "seat", cmd_seat },
|
{ "seat", cmd_seat },
|
||||||
{ "set", cmd_set },
|
{ "set", cmd_set },
|
||||||
{ "show_marks", cmd_show_marks },
|
{ "show_marks", cmd_show_marks },
|
||||||
|
14
sway/commands/raise_floating.c
Normal file
14
sway/commands/raise_floating.c
Normal file
@ -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);
|
||||||
|
}
|
@ -221,6 +221,7 @@ static void config_defaults(struct sway_config *config) {
|
|||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
config->focus_follows_mouse = true;
|
config->focus_follows_mouse = true;
|
||||||
|
config->raise_floating = true;
|
||||||
config->mouse_warping = true;
|
config->mouse_warping = true;
|
||||||
config->focus_wrapping = WRAP_YES;
|
config->focus_wrapping = WRAP_YES;
|
||||||
config->validating = false;
|
config->validating = false;
|
||||||
|
@ -567,15 +567,15 @@ void cursor_send_pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
|
|||||||
struct wlr_surface *surface = NULL;
|
struct wlr_surface *surface = NULL;
|
||||||
double sx, sy;
|
double sx, sy;
|
||||||
|
|
||||||
// Find the node beneath the pointer's previous position
|
struct sway_node *prev_node = cursor->previous.node;
|
||||||
struct sway_node *prev_node = node_at_coords(seat,
|
struct sway_node *node = node_at_coords(seat,
|
||||||
cursor->previous.x, cursor->previous.y, &surface, &sx, &sy);
|
cursor->cursor->x, cursor->cursor->y, &surface, &sx, &sy);
|
||||||
|
|
||||||
// Update the stored previous position
|
// Update the stored previous position
|
||||||
cursor->previous.x = cursor->cursor->x;
|
cursor->previous.x = cursor->cursor->x;
|
||||||
cursor->previous.y = cursor->cursor->y;
|
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) {
|
if (node && config->focus_follows_mouse && allow_refocusing) {
|
||||||
struct sway_node *focus = seat_get_focus(seat);
|
struct sway_node *focus = seat_get_focus(seat);
|
||||||
if (focus && node->type == N_WORKSPACE) {
|
if (focus && node->type == N_WORKSPACE) {
|
||||||
|
@ -606,6 +606,18 @@ static int handle_urgent_timeout(void *data) {
|
|||||||
return 0;
|
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,
|
void seat_set_focus_warp(struct sway_seat *seat, struct sway_node *node,
|
||||||
bool warp, bool notify) {
|
bool warp, bool notify) {
|
||||||
if (seat->focused_layer) {
|
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.
|
// 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 && config->raise_floating) {
|
||||||
if (container) {
|
container_raise_floating(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 (last_focus) {
|
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_lx = sx;
|
||||||
seat->op_ref_con_ly = sy;
|
seat->op_ref_con_ly = sy;
|
||||||
seat->op_moved = false;
|
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,
|
void seat_begin_move_floating(struct sway_seat *seat,
|
||||||
|
@ -48,6 +48,7 @@ sway_sources = files(
|
|||||||
'commands/floating_modifier.c',
|
'commands/floating_modifier.c',
|
||||||
'commands/focus.c',
|
'commands/focus.c',
|
||||||
'commands/focus_follows_mouse.c',
|
'commands/focus_follows_mouse.c',
|
||||||
|
'commands/raise_floating.c',
|
||||||
'commands/focus_on_window_activation.c',
|
'commands/focus_on_window_activation.c',
|
||||||
'commands/focus_wrapping.c',
|
'commands/focus_wrapping.c',
|
||||||
'commands/font.c',
|
'commands/font.c',
|
||||||
|
@ -441,6 +441,11 @@ The default colors are:
|
|||||||
devices. A list of input device names may be obtained via *swaymsg -t
|
devices. A list of input device names may be obtained via *swaymsg -t
|
||||||
get\_inputs*.
|
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...>
|
*seat* <seat> <seat-subcommands...>
|
||||||
For details on seat subcommands, see *sway-input*(5).
|
For details on seat subcommands, see *sway-input*(5).
|
||||||
|
|
||||||
|
@ -151,10 +151,10 @@ struct sway_container *container_find_child(struct sway_container *container,
|
|||||||
return NULL;
|
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) {
|
struct wlr_surface **surface, double *sx, double *sy) {
|
||||||
if (!sway_assert(con->view, "Expected a view")) {
|
if (!sway_assert(con->view, "Expected a view")) {
|
||||||
return;
|
return NULL;
|
||||||
}
|
}
|
||||||
struct sway_view *view = con->view;
|
struct sway_view *view = con->view;
|
||||||
double view_sx = lx - view->x + view->geometry.x;
|
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;
|
*sx = _sx;
|
||||||
*sy = _sy;
|
*sy = _sy;
|
||||||
*surface = _surface;
|
*surface = _surface;
|
||||||
|
return con;
|
||||||
}
|
}
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -355,37 +357,31 @@ struct sway_container *container_at(struct sway_workspace *workspace,
|
|||||||
double lx, double ly,
|
double lx, double ly,
|
||||||
struct wlr_surface **surface, double *sx, double *sy) {
|
struct wlr_surface **surface, double *sx, double *sy) {
|
||||||
struct sway_container *c;
|
struct sway_container *c;
|
||||||
|
|
||||||
// Focused view's popups
|
// Focused view's popups
|
||||||
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||||
struct sway_container *focus = seat_get_focused_container(seat);
|
struct sway_container *focus = seat_get_focused_container(seat);
|
||||||
bool is_floating = focus && container_is_floating_or_child(focus);
|
bool is_floating = focus && container_is_floating_or_child(focus);
|
||||||
// Focused view's popups
|
// Focused view's popups
|
||||||
if (focus && focus->view) {
|
if (focus && focus->view) {
|
||||||
surface_at_view(focus, lx, ly, surface, sx, sy);
|
c = surface_at_view(focus, lx, ly, surface, sx, sy);
|
||||||
if (*surface && surface_is_popup(*surface)) {
|
if (c && surface_is_popup(*surface)) {
|
||||||
return focus;
|
return c;
|
||||||
}
|
}
|
||||||
*surface = NULL;
|
*surface = NULL;
|
||||||
}
|
}
|
||||||
// If focused is floating, focused view's non-popups
|
// Cast a ray to handle floating windows
|
||||||
if (focus && focus->view && is_floating) {
|
for (int i = workspace->floating->length - 1; i >= 0; --i) {
|
||||||
surface_at_view(focus, lx, ly, surface, sx, sy);
|
struct sway_container *cn = workspace->floating->items[i];
|
||||||
if (*surface) {
|
if (cn->view && (c = surface_at_view(cn, lx, ly, surface, sx, sy))) {
|
||||||
return focus;
|
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 focused is tiling, focused view's non-popups
|
||||||
if (focus && focus->view && !is_floating) {
|
if (focus && focus->view && !is_floating) {
|
||||||
surface_at_view(focus, lx, ly, surface, sx, sy);
|
if ((c = surface_at_view(focus, lx, ly, surface, sx, sy))) {
|
||||||
if (*surface) {
|
return c;
|
||||||
return focus;
|
|
||||||
}
|
}
|
||||||
*surface = NULL;
|
|
||||||
}
|
}
|
||||||
// Tiling (non-focused)
|
// Tiling (non-focused)
|
||||||
if ((c = tiling_container_at(&workspace->node, lx, ly, surface, sx, sy))) {
|
if ((c = tiling_container_at(&workspace->node, lx, ly, surface, sx, sy))) {
|
||||||
|
Loading…
Reference in New Issue
Block a user