mirror of
				https://github.com/swaywm/sway.git
				synced 2025-11-03 09:01:43 -05:00 
			
		
		
		
	Merge pull request #2709 from BuJo/feature/raise_floating
raise floating
This commit is contained in:
		
						commit
						7fdc557f1e
					
				
					 11 changed files with 64 additions and 34 deletions
				
			
		| 
						 | 
					@ -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;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		*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;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		*surface = NULL;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// Floating (non-focused)
 | 
					 | 
				
			||||||
	if ((c = floating_container_at(lx, ly, surface, sx, sy))) {
 | 
					 | 
				
			||||||
			return c;
 | 
								return c;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							*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;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// 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…
	
	Add table
		Add a link
		
	
		Reference in a new issue