Skip to content

Commit

Permalink
#2342 extend stack window sel to support numeric indices
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed Jul 8, 2024
1 parent 09a7b23 commit 84a41c9
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 55 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
### Changed
- Moving windows to other spaces requires SIP to be disabled on macOS Sequoia [#2324](https://github.com/koekeishiya/yabai/issues/2324) [#2331](https://github.com/koekeishiya/yabai/issues/2331)
- Updated scripting-addition mach loader/injection and payload to work for macOS Sequoia Beta 1 and 2 [#2324](https://github.com/koekeishiya/yabai/issues/2324) [#2331](https://github.com/koekeishiya/yabai/issues/2331)
- Extend *stack window selector* to allow numeric indices: `yabai -m window --focus stack.3` [#2342](https://github.com/koekeishiya/yabai/issues/2342)

## [7.1.1] - 2024-05-18
### Changed
Expand Down Expand Up @@ -672,7 +673,7 @@ The *window_destroyed* signal is now triggered for windows that are implicitly d
- Hide power indicator from the status-bar if a battery could not be found [#60](https://github.com/koekeishiya/yabai/issues/60)
- Disable focus follows mouse while the *mouse_modifier* key is held down [#62](https://github.com/koekeishiya/yabai/issues/62)
- Silence meaningless warning reported by the scripting-bridge framework [#55](https://github.com/koekeishiya/yabai/issues/55)
- Extend definition of *WINDOW_SEL* to include *mouse*, targetting the window below the cursor [#66](https://github.com/koekeishiya/yabai/issues/66)
- Extend definition of *WINDOW_SEL* to include *mouse*, targeting the window below the cursor [#66](https://github.com/koekeishiya/yabai/issues/66)
- Allow all *config* (except *status_bar*) settings to be edited at runtime [#69](https://github.com/koekeishiya/yabai/issues/69)
- Window should not be added to the window-tree twice when deminimized on an inactive display [#70](https://github.com/koekeishiya/yabai/issues/70)
- Expose *window_placement* as a config setting to specify if windows become the first or second child [#65](https://github.com/koekeishiya/yabai/issues/65)
Expand Down
104 changes: 50 additions & 54 deletions src/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -242,11 +242,7 @@ extern bool g_verbose;
#define ARGUMENT_COMMON_SEL_WEST "west"
#define ARGUMENT_COMMON_SEL_MOUSE "mouse"
#define ARGUMENT_COMMON_SEL_STACK "stack"
#define ARGUMENT_COMMON_SEL_STACK_PREV "stack.prev"
#define ARGUMENT_COMMON_SEL_STACK_NEXT "stack.next"
#define ARGUMENT_COMMON_SEL_STACK_FIRST "stack.first"
#define ARGUMENT_COMMON_SEL_STACK_LAST "stack.last"
#define ARGUMENT_COMMON_SEL_STACK_RECENT "stack.recent"
#define ARGUMENT_COMMON_SEL_STACK_PREFIX "stack."
/* ----------------------------------------------------------------------------- */

struct token
Expand Down Expand Up @@ -1056,57 +1052,57 @@ static struct selector parse_window_selector(FILE *rsp, char **message, struct w
} else {
daemon_fail(rsp, "could not locate the most recently focused window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_STACK_PREV)) {
} else if (token_prefix(result.token, ARGUMENT_COMMON_SEL_STACK_PREFIX)) {
if (acting_window) {
struct window *prev_window = window_manager_find_prev_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (prev_window) {
result.window = prev_window;
} else {
daemon_fail(rsp, "could not locate the prev stacked window.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_STACK_NEXT)) {
if (acting_window) {
struct window *next_window = window_manager_find_next_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (next_window) {
result.window = next_window;
} else {
daemon_fail(rsp, "could not locate the next stacked window.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_STACK_FIRST)) {
if (acting_window) {
struct window *first_window = window_manager_find_first_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (first_window) {
result.window = first_window;
} else {
daemon_fail(rsp, "could not locate the first stacked window.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_STACK_LAST)) {
if (acting_window) {
struct window *last_window = window_manager_find_last_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (last_window) {
result.window = last_window;
} else {
daemon_fail(rsp, "could not locate the last stacked window.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_STACK_RECENT)) {
if (acting_window) {
struct window *recent_window = window_manager_find_recent_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (recent_window) {
result.window = recent_window;
int index;
result.token.text += strlen(ARGUMENT_COMMON_SEL_STACK_PREFIX);
result.token.length -= strlen(ARGUMENT_COMMON_SEL_STACK_PREFIX);

if (token_equals(result.token, ARGUMENT_COMMON_SEL_PREV)) {
struct window *prev_window = window_manager_find_prev_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (prev_window) {
result.window = prev_window;
} else {
daemon_fail(rsp, "could not locate the prev stacked window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_NEXT)) {
struct window *next_window = window_manager_find_next_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (next_window) {
result.window = next_window;
} else {
daemon_fail(rsp, "could not locate the next stacked window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_FIRST)) {
struct window *first_window = window_manager_find_first_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (first_window) {
result.window = first_window;
} else {
daemon_fail(rsp, "could not locate the first stacked window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_LAST)) {
struct window *last_window = window_manager_find_last_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (last_window) {
result.window = last_window;
} else {
daemon_fail(rsp, "could not locate the last stacked window.\n");
}
} else if (token_equals(result.token, ARGUMENT_COMMON_SEL_RECENT)) {
struct window *recent_window = window_manager_find_recent_window_in_stack(&g_space_manager, &g_window_manager, acting_window);
if (recent_window) {
result.window = recent_window;
} else {
daemon_fail(rsp, "could not locate the recent stacked window.\n");
}
} else if (token_is_valid(result.token) && token_is_positive_integer(result.token, &index) && index > 0) {
struct window *index_window = window_manager_find_window_in_stack(&g_space_manager, &g_window_manager, acting_window, index);
if (index_window) {
result.window = index_window;
} else {
daemon_fail(rsp, "could not locate the stacked window in position %d.\n", index);
}
} else {
daemon_fail(rsp, "could not locate the recent stacked window.\n");
result.did_parse = false;
daemon_fail(rsp, "value '%s%.*s' is not a valid option for WINDOW_SEL\n", ARGUMENT_COMMON_SEL_STACK_PREFIX, result.token.length, result.token.text);
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
Expand Down
11 changes: 11 additions & 0 deletions src/window_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,17 @@ struct window *window_manager_find_recent_window_in_stack(struct space_manager *
return node->window_count > 1 ? window_manager_find_window(wm, node->window_order[1]) : NULL;
}

struct window *window_manager_find_window_in_stack(struct space_manager *sm, struct window_manager *wm, struct window *window, int index)
{
struct view *view = space_manager_find_view(sm, space_manager_active_space());
if (!view) return NULL;

struct window_node *node = view_find_window_node(view, window->id);
if (!node) return NULL;

return node->window_count > 1 && in_range_ii(index, 1, node->window_count) ? window_manager_find_window(wm, node->window_list[index-1]) : NULL;
}

struct window *window_manager_find_largest_managed_window(struct space_manager *sm, struct window_manager *wm)
{
struct view *view = space_manager_find_view(sm, space_manager_active_space());
Expand Down
1 change: 1 addition & 0 deletions src/window_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ struct window *window_manager_find_next_window_in_stack(struct space_manager *sm
struct window *window_manager_find_first_window_in_stack(struct space_manager *sm, struct window_manager *wm, struct window *window);
struct window *window_manager_find_last_window_in_stack(struct space_manager *sm, struct window_manager *wm, struct window *window);
struct window *window_manager_find_recent_window_in_stack(struct space_manager *sm, struct window_manager *wm, struct window *window);
struct window *window_manager_find_window_in_stack(struct space_manager *sm, struct window_manager *wm, struct window *window, int index);
struct window *window_manager_find_largest_managed_window(struct space_manager *sm, struct window_manager *wm);
struct window *window_manager_find_smallest_managed_window(struct space_manager *sm, struct window_manager *wm);
struct window *window_manager_find_sibling_for_managed_window(struct window_manager *wm, struct window *window);
Expand Down

0 comments on commit 84a41c9

Please sign in to comment.