Add FocusOutput action

Fixes #806

Suggested-by: @EysseW
Tested-by: @EysseW
This commit is contained in:
Consolatis 2023-03-05 17:16:23 +01:00 committed by Johan Malm
parent 037dace5bc
commit a0b5a80ce1
5 changed files with 76 additions and 0 deletions

View file

@ -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;

View file

@ -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)
{

View file

@ -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)
{