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
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,
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);
ACTION_TYPE_SEND_TO_DESKTOP,
ACTION_TYPE_SNAP_TO_REGION,
ACTION_TYPE_TOGGLE_KEYBINDS,
+ ACTION_TYPE_FOCUS_OUTPUT,
};
const char *action_names[] = {
"SendToDesktop",
"SnapToRegion",
"ToggleKeybinds",
+ "FocusOutput",
NULL
};
} 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);
}
}
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;
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)
{
#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>
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)
{