Cycle Near Region, rework to fit better

This commit is contained in:
Droc 2024-06-05 10:15:51 -05:00
parent 1cd9940307
commit 206a72edf8
4 changed files with 70 additions and 0 deletions

View file

@ -99,6 +99,10 @@ Actions are used in menus and keyboard/mouse bindings.
Resize and move active window according to the given region. Resize and move active window according to the given region.
See labwc-config(5) for further information on how to define regions. See labwc-config(5) for further information on how to define regions.
*<action name="CycleNearRegion" region="value" />*
Cycle focus to the next window (mostly) in the given region.
See labwc-config(5) for further information on how to define regions.
*<action name="NextWindow" />* *<action name="NextWindow" />*
Cycle focus to next window. Cycle focus to next window.

View file

@ -454,6 +454,14 @@ enum lab_cycle_dir {
struct view *desktop_cycle_view(struct server *server, struct view *start_view, struct view *desktop_cycle_view(struct server *server, struct view *start_view,
enum lab_cycle_dir dir); enum lab_cycle_dir dir);
/**
* desktop_cycle_view_near_region - return view to 'cycle' to within region
* @active_view: reference point for finding next view to cycle to
* Note: If !active_view, the top-most focusable view is returned
*/
struct view *desktop_cycle_view_near_region(struct server *server,
struct view *active_view, struct region *region);
/** /**
* desktop_focus_topmost_view() - focus the topmost view on the current * desktop_focus_topmost_view() - focus the topmost view on the current
* workspace, skipping views that claim not to want focus (those can * workspace, skipping views that claim not to want focus (those can

View file

@ -100,6 +100,7 @@ enum action_type {
ACTION_TYPE_SEND_TO_DESKTOP, ACTION_TYPE_SEND_TO_DESKTOP,
ACTION_TYPE_GO_TO_DESKTOP, ACTION_TYPE_GO_TO_DESKTOP,
ACTION_TYPE_SNAP_TO_REGION, ACTION_TYPE_SNAP_TO_REGION,
ACTION_TYPE_CYCLE_NEAR_REGION,
ACTION_TYPE_TOGGLE_KEYBINDS, ACTION_TYPE_TOGGLE_KEYBINDS,
ACTION_TYPE_FOCUS_OUTPUT, ACTION_TYPE_FOCUS_OUTPUT,
ACTION_TYPE_MOVE_TO_OUTPUT, ACTION_TYPE_MOVE_TO_OUTPUT,
@ -158,6 +159,7 @@ const char *action_names[] = {
"SendToDesktop", "SendToDesktop",
"GoToDesktop", "GoToDesktop",
"SnapToRegion", "SnapToRegion",
"CycleNearRegion",
"ToggleKeybinds", "ToggleKeybinds",
"FocusOutput", "FocusOutput",
"MoveToOutput", "MoveToOutput",
@ -405,6 +407,12 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
goto cleanup; goto cleanup;
} }
break; break;
case ACTION_TYPE_CYCLE_NEAR_REGION:
if (!strcmp(argument, "region")) {
action_arg_add_str(action, argument, content);
goto cleanup;
}
break;
case ACTION_TYPE_FOCUS_OUTPUT: case ACTION_TYPE_FOCUS_OUTPUT:
if (!strcmp(argument, "output")) { if (!strcmp(argument, "output")) {
action_arg_add_str(action, argument, content); action_arg_add_str(action, argument, content);
@ -545,6 +553,9 @@ action_is_valid(struct action *action)
case ACTION_TYPE_SNAP_TO_REGION: case ACTION_TYPE_SNAP_TO_REGION:
arg_name = "region"; arg_name = "region";
break; break;
case ACTION_TYPE_CYCLE_NEAR_REGION:
arg_name = "region";
break;
case ACTION_TYPE_FOCUS_OUTPUT: case ACTION_TYPE_FOCUS_OUTPUT:
arg_name = "output"; arg_name = "output";
break; break;
@ -1026,6 +1037,26 @@ actions_run(struct view *activator, struct server *server,
wlr_log(WLR_ERROR, "Invalid SnapToRegion id: '%s'", region_name); wlr_log(WLR_ERROR, "Invalid SnapToRegion id: '%s'", region_name);
} }
break; break;
case ACTION_TYPE_CYCLE_NEAR_REGION:
{
if (!view) {
break;
}
struct output *output = view->output;
if (!output_is_usable(output)) {
break;
}
const char *region_name = action_get_str(action, "region", NULL);
struct region *region = regions_from_name(region_name, output);
if (region) {
struct view *new_view = desktop_cycle_view_near_region(
server, view, region);
if (new_view) {
desktop_focus_view(new_view, /*raise*/ true);
}
}
}
break;
case ACTION_TYPE_TOGGLE_KEYBINDS: case ACTION_TYPE_TOGGLE_KEYBINDS:
if (view) { if (view) {
view_toggle_keybinds(view); view_toggle_keybinds(view);

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
#include "config.h" #include "config.h"
#include <assert.h> #include <assert.h>
#include "common/macros.h"
#include "common/scene-helpers.h" #include "common/scene-helpers.h"
#include "common/surface-helpers.h" #include "common/surface-helpers.h"
#include "dnd.h" #include "dnd.h"
@ -139,6 +140,32 @@ desktop_cycle_view(struct server *server, struct view *start_view,
return iter(&server->views, start_view, criteria); return iter(&server->views, start_view, criteria);
} }
struct view *
desktop_cycle_view_near_region(struct server *server, struct view *active_view,
struct region *region)
{
struct view *(*iter)(struct wl_list *head, struct view *view,
enum lab_view_criteria criteria);
enum lab_view_criteria criteria = rc.window_switcher.criteria |
LAB_VIEW_CRITERIA_CURRENT_WORKSPACE;
struct view *cur;
struct wlr_box intersect;
iter = view_prev_no_head_stop;
cur = iter(&server->views, active_view, criteria);
while (cur && cur != active_view) {
wlr_box_intersection(&intersect, &cur->current, &region->geo);
if (!cur->minimized && !wlr_box_empty(&intersect)) {
return cur;
}
cur = iter(&server->views, cur, criteria);
}
/* no matching views found */
return NULL;
}
struct view * struct view *
desktop_topmost_focusable_view(struct server *server) desktop_topmost_focusable_view(struct server *server)
{ {