mirror of
				https://github.com/labwc/labwc.git
				synced 2025-11-03 09:01:51 -05:00 
			
		
		
		
	Add FocusOutput action
Fixes #806 Suggested-by: @EysseW Tested-by: @EysseW
This commit is contained in:
		
							parent
							
								
									037dace5bc
								
							
						
					
					
						commit
						a0b5a80ce1
					
				
					 5 changed files with 76 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -80,6 +80,11 @@ Actions are used in menus and keyboard/mouse bindings.
 | 
			
		|||
	to Virtual Machines, VNC clients or nested compositors.
 | 
			
		||||
	A second call will restore all original keybinds.
 | 
			
		||||
 | 
			
		||||
*<action name="FocusOutput" output="HDMI-A-1" />*
 | 
			
		||||
	Give focus to topmost window on given output and warp the cursor
 | 
			
		||||
	to the center of the window. If the given output does not contain
 | 
			
		||||
	any windows, the cursor is centered on the given output.
 | 
			
		||||
 | 
			
		||||
*<action name="GoToDesktop" to="value" />*
 | 
			
		||||
	Switch to workspace. Supported values are "last", "left", "right" or the
 | 
			
		||||
	full name of a workspace or its index (starting at 1) as configured in
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -372,6 +372,7 @@ void desktop_move_to_front(struct view *view);
 | 
			
		|||
void desktop_move_to_back(struct view *view);
 | 
			
		||||
void desktop_focus_and_activate_view(struct seat *seat, struct view *view);
 | 
			
		||||
void desktop_arrange_all_views(struct server *server);
 | 
			
		||||
void desktop_focus_output(struct output *output);
 | 
			
		||||
 | 
			
		||||
enum lab_cycle_dir {
 | 
			
		||||
	LAB_CYCLE_DIR_NONE,
 | 
			
		||||
| 
						 | 
				
			
			@ -418,6 +419,7 @@ void output_init(struct server *server);
 | 
			
		|||
void output_manager_init(struct server *server);
 | 
			
		||||
struct output *output_from_wlr_output(struct server *server,
 | 
			
		||||
	struct wlr_output *wlr_output);
 | 
			
		||||
struct output *output_from_name(struct server *server, const char *name);
 | 
			
		||||
struct output *output_nearest_to(struct server *server, int lx, int ly);
 | 
			
		||||
struct output *output_nearest_to_cursor(struct server *server);
 | 
			
		||||
bool output_is_usable(struct output *output);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										13
									
								
								src/action.c
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								src/action.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -61,6 +61,7 @@ enum action_type {
 | 
			
		|||
	ACTION_TYPE_SEND_TO_DESKTOP,
 | 
			
		||||
	ACTION_TYPE_SNAP_TO_REGION,
 | 
			
		||||
	ACTION_TYPE_TOGGLE_KEYBINDS,
 | 
			
		||||
	ACTION_TYPE_FOCUS_OUTPUT,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char *action_names[] = {
 | 
			
		||||
| 
						 | 
				
			
			@ -90,6 +91,7 @@ const char *action_names[] = {
 | 
			
		|||
	"SendToDesktop",
 | 
			
		||||
	"SnapToRegion",
 | 
			
		||||
	"ToggleKeybinds",
 | 
			
		||||
	"FocusOutput",
 | 
			
		||||
	NULL
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -119,6 +121,9 @@ action_arg_from_xml_node(struct action *action, char *nodename, char *content)
 | 
			
		|||
	} else if (!strcmp(nodename, "region.action")) {
 | 
			
		||||
		/* SnapToRegion */
 | 
			
		||||
		action_arg_add_str(action, NULL, content);
 | 
			
		||||
	} else if (!strcmp(nodename, "output.action")) {
 | 
			
		||||
		/* FocusOutput */
 | 
			
		||||
		action_arg_add_str(action, NULL, content);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -470,6 +475,14 @@ actions_run(struct view *activator, struct server *server,
 | 
			
		|||
			wlr_log(WLR_DEBUG, "%s keybinds",
 | 
			
		||||
				server->seat.inhibit_keybinds ? "Disabled" : "Enabled");
 | 
			
		||||
			break;
 | 
			
		||||
		case ACTION_TYPE_FOCUS_OUTPUT:
 | 
			
		||||
			if (!arg) {
 | 
			
		||||
				wlr_log(WLR_ERROR, "Missing argument for FocusOutput");
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			const char *output_name = action_str_from_arg(arg);
 | 
			
		||||
			desktop_focus_output(output_from_name(server, output_name));
 | 
			
		||||
			break;
 | 
			
		||||
		case ACTION_TYPE_INVALID:
 | 
			
		||||
			wlr_log(WLR_ERROR, "Not executing unknown action");
 | 
			
		||||
			break;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -268,6 +268,46 @@ desktop_focus_topmost_mapped_view(struct server *server)
 | 
			
		|||
	desktop_move_to_front(view);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
desktop_focus_output(struct output *output)
 | 
			
		||||
{
 | 
			
		||||
	if (!output_is_usable(output) || output->server->input_mode
 | 
			
		||||
			!= LAB_INPUT_STATE_PASSTHROUGH) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
	struct view *view;
 | 
			
		||||
	struct wlr_scene_node *node;
 | 
			
		||||
	struct wlr_output_layout *layout = output->server->output_layout;
 | 
			
		||||
	struct wl_list *list_head =
 | 
			
		||||
		&output->server->workspace_current->tree->children;
 | 
			
		||||
	wl_list_for_each_reverse(node, list_head, link) {
 | 
			
		||||
		if (!node->data) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		view = node_view_from_node(node);
 | 
			
		||||
		if (!isfocusable(view)) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (wlr_output_layout_intersects(layout,
 | 
			
		||||
				output->wlr_output, &view->current)) {
 | 
			
		||||
			desktop_focus_and_activate_view(&output->server->seat, view);
 | 
			
		||||
			wlr_cursor_warp(output->server->seat.cursor, NULL,
 | 
			
		||||
				view->current.x + view->current.width / 2,
 | 
			
		||||
				view->current.y + view->current.height / 2);
 | 
			
		||||
			cursor_update_focus(output->server);
 | 
			
		||||
			return;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	/* No view found on desired output */
 | 
			
		||||
	struct wlr_box layout_box;
 | 
			
		||||
	wlr_output_layout_get_box(output->server->output_layout,
 | 
			
		||||
		output->wlr_output, &layout_box);
 | 
			
		||||
	wlr_cursor_warp(output->server->seat.cursor, NULL,
 | 
			
		||||
		layout_box.x + output->usable_area.x + output->usable_area.width / 2,
 | 
			
		||||
		layout_box.y + output->usable_area.y + output->usable_area.height / 2);
 | 
			
		||||
	cursor_update_focus(output->server);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static struct wlr_surface *
 | 
			
		||||
get_surface_from_layer_node(struct wlr_scene_node *node)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										16
									
								
								src/output.c
									
										
									
									
									
								
							
							
						
						
									
										16
									
								
								src/output.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
 | 
			
		||||
#define _POSIX_C_SOURCE 200809L
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
#include <strings.h>
 | 
			
		||||
#include <wlr/types/wlr_buffer.h>
 | 
			
		||||
#include <wlr/types/wlr_drm_lease_v1.h>
 | 
			
		||||
#include <wlr/types/wlr_output.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -458,6 +459,21 @@ output_from_wlr_output(struct server *server, struct wlr_output *wlr_output)
 | 
			
		|||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct output *
 | 
			
		||||
output_from_name(struct server *server, const char *name)
 | 
			
		||||
{
 | 
			
		||||
	struct output *output;
 | 
			
		||||
	wl_list_for_each(output, &server->outputs, link) {
 | 
			
		||||
		if (!output_is_usable(output) || !output->wlr_output->name) {
 | 
			
		||||
			continue;
 | 
			
		||||
		}
 | 
			
		||||
		if (!strcasecmp(name, output->wlr_output->name)) {
 | 
			
		||||
			return output;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct output *
 | 
			
		||||
output_nearest_to(struct server *server, int lx, int ly)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue