mirror of
https://github.com/labwc/labwc.git
synced 2025-10-29 05:40:24 -04:00
feat: add left-occupied and right-occupied to workspaces_find
This commit is contained in:
parent
5cf4aa83e2
commit
614c008bea
2 changed files with 79 additions and 4 deletions
|
|
@ -281,8 +281,8 @@ Actions are used in menus and keyboard/mouse bindings.
|
|||
Switch to workspace.
|
||||
|
||||
*to* The workspace to switch to. Supported values are "current", "last",
|
||||
"left", "right" or the full name of a workspace or its index (starting
|
||||
at 1) as configured in rc.xml.
|
||||
"left", "right", "left-occupied", "right-occupied" or the full name of a
|
||||
workspace or its index (starting at 1) as configured in rc.xml.
|
||||
|
||||
*wrap* [yes|no] Wrap around from last desktop to first, and vice
|
||||
versa. Default yes.
|
||||
|
|
@ -469,8 +469,10 @@ Actions that execute other actions. Used in keyboard/mouse bindings.
|
|||
*desktop*
|
||||
The desktop the client is currently on. This can be the
|
||||
number or name of a desktop, or special relative values
|
||||
"current", "other", "left", "right" or "last". The
|
||||
"left" and "right" directions will not wrap.
|
||||
"current", "other", "left", "right", "left-occupied",
|
||||
"right-occupied" or "last".
|
||||
The "left" , "right", "left-occupied" and
|
||||
"right-occupied" directions will not wrap.
|
||||
|
||||
*tiled* [up|right|down|left|center]
|
||||
Whether the client is tiled (snapped) along the the
|
||||
|
|
|
|||
|
|
@ -269,6 +269,75 @@ get_next(struct workspace *current, struct wl_list *workspaces, bool wrap)
|
|||
return wl_container_of(target_link, current, link);
|
||||
}
|
||||
|
||||
static bool
|
||||
workspace_has_views(struct workspace *workspace, struct server *server)
|
||||
{
|
||||
struct view *view;
|
||||
|
||||
for_each_view(view, &server->views, LAB_VIEW_CRITERIA_NO_OMNIPRESENT) {
|
||||
if (view->workspace == workspace) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct workspace *
|
||||
get_adjacent_occupied(struct workspace *current, struct wl_list *workspaces,
|
||||
bool wrap, bool reverse)
|
||||
{
|
||||
struct server *server = current->server;
|
||||
struct wl_list *start = ¤t->link;
|
||||
struct wl_list *link = reverse ? start->prev : start->next;
|
||||
bool has_wrapped = false;
|
||||
|
||||
while (true) {
|
||||
/* Handle list boundaries */
|
||||
if (link == workspaces) {
|
||||
if (!wrap) {
|
||||
break; /* No wrapping allowed - stop searching */
|
||||
}
|
||||
if (has_wrapped) {
|
||||
break; /* Already wrapped once - stop to prevent infinite loop */
|
||||
}
|
||||
/* Wrap around */
|
||||
link = reverse ? workspaces->prev : workspaces->next;
|
||||
has_wrapped = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the workspace */
|
||||
struct workspace *target = wl_container_of(link, target, link);
|
||||
|
||||
/* Check if we've come full circle */
|
||||
if (link == start) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check if it's occupied (and not current) */
|
||||
if (target != current && workspace_has_views(target, server)) {
|
||||
return target;
|
||||
}
|
||||
|
||||
/* Move to next/prev */
|
||||
link = reverse ? link->prev : link->next;
|
||||
}
|
||||
|
||||
return NULL; /* No occupied workspace found */
|
||||
}
|
||||
|
||||
static struct workspace *
|
||||
get_prev_occupied(struct workspace *current, struct wl_list *workspaces, bool wrap)
|
||||
{
|
||||
return get_adjacent_occupied(current, workspaces, wrap, true);
|
||||
}
|
||||
|
||||
static struct workspace *
|
||||
get_next_occupied(struct workspace *current, struct wl_list *workspaces, bool wrap)
|
||||
{
|
||||
return get_adjacent_occupied(current, workspaces, wrap, false);
|
||||
}
|
||||
|
||||
static int
|
||||
_osd_handle_timeout(void *data)
|
||||
{
|
||||
|
|
@ -453,6 +522,10 @@ workspaces_find(struct workspace *anchor, const char *name, bool wrap)
|
|||
return get_prev(anchor, workspaces, wrap);
|
||||
} else if (!strcasecmp(name, "right")) {
|
||||
return get_next(anchor, workspaces, wrap);
|
||||
} else if (!strcasecmp(name, "left-occupied")) {
|
||||
return get_prev_occupied(anchor, workspaces, wrap);
|
||||
} else if (!strcasecmp(name, "right-occupied")) {
|
||||
return get_next_occupied(anchor, workspaces, wrap);
|
||||
} else {
|
||||
wl_list_for_each(target, workspaces, link) {
|
||||
if (!strcasecmp(target->name, name)) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue