Skip to content

Commit

Permalink
#105 extend definition of window_sel to include smallest and largest
Browse files Browse the repository at this point in the history
  • Loading branch information
koekeishiya committed Jul 8, 2019
1 parent 04941bd commit 77de2e0
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased]
### Changed
- No longer necessary to depend on the scripting-addition to focus a window [#102](https://github.com/koekeishiya/yabai/issues/102)
- Extend definition of *WINDOW_SEL* to include *smallest* and *largest* [#105](https://github.com/koekeishiya/yabai/issues/105)

## [1.0.5] - 2019-07-07
### Changed
Expand Down
2 changes: 1 addition & 1 deletion doc/yabai.1
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ Loads the scripting\-addition into Dock.app.
.nf
DIR_SEL := north | east | south | west

WINDOW_SEL := prev | next | first | last | recent | mouse | DIR_SEL
WINDOW_SEL := prev | next | first | last | recent | mouse | largest | smallest | DIR_SEL

DISPLAY_SEL := prev | next | first | last | recent | arrangement index (1\-based)

Expand Down
2 changes: 1 addition & 1 deletion doc/yabai.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Definitions
----
DIR_SEL := north | east | south | west
WINDOW_SEL := prev | next | first | last | recent | mouse | DIR_SEL
WINDOW_SEL := prev | next | first | last | recent | mouse | largest | smallest | DIR_SEL
DISPLAY_SEL := prev | next | first | last | recent | arrangement index (1-based)
Expand Down
62 changes: 60 additions & 2 deletions src/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ extern struct window_manager g_window_manager;
extern struct mouse_state g_mouse_state;
extern struct bar g_bar;

static const char *bool_str[] = { "off", "on" };

#define DOMAIN_CONFIG "config"
#define DOMAIN_DISPLAY "display"
#define DOMAIN_SPACE "space"
Expand Down Expand Up @@ -119,6 +117,8 @@ static const char *bool_str[] = { "off", "on" };
#define ARGUMENT_WINDOW_DIR_SOUTH "south"
#define ARGUMENT_WINDOW_DIR_WEST "west"
#define ARGUMENT_WINDOW_SEL_MOUSE "mouse"
#define ARGUMENT_WINDOW_SEL_LARGEST "largest"
#define ARGUMENT_WINDOW_SEL_SMALLEST "smallest"
#define ARGUMENT_WINDOW_GRID "%d:%d:%d:%d:%d:%d"
#define ARGUMENT_WINDOW_MOVE "%255[^:]:%f:%f"
#define ARGUMENT_WINDOW_RESIZE "%255[^:]:%f:%f"
Expand Down Expand Up @@ -1056,6 +1056,20 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
} else {
daemon_fail(rsp, "could not locate a window below the cursor.\n");
}
} else if (token_equals(value, ARGUMENT_WINDOW_SEL_LARGEST)) {
struct window *area_window = window_manager_find_largest_managed_window(&g_space_manager, &g_window_manager);
if (area_window) {
window_manager_focus_window_with_raise(&area_window->application->psn, area_window->id, area_window->ref);
} else {
daemon_fail(rsp, "could not locate window with the largest area.\n");
}
} else if (token_equals(value, ARGUMENT_WINDOW_SEL_SMALLEST)) {
struct window *area_window = window_manager_find_smallest_managed_window(&g_space_manager, &g_window_manager);
if (area_window) {
window_manager_focus_window_with_raise(&area_window->application->psn, area_window->id, area_window->ref);
} else {
daemon_fail(rsp, "could not locate window with the smallest area.\n");
}
} else if (token_equals(value, ARGUMENT_COMMON_SEL_PREV)) {
if (window) {
struct window *prev_window = window_manager_find_prev_managed_window(&g_space_manager, &g_window_manager, window);
Expand Down Expand Up @@ -1167,6 +1181,28 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(value, ARGUMENT_WINDOW_SEL_LARGEST)) {
if (window) {
struct window *area_window = window_manager_find_largest_managed_window(&g_space_manager, &g_window_manager);
if (area_window) {
window_manager_swap_window(&g_space_manager, &g_window_manager, window, area_window);
} else {
daemon_fail(rsp, "could not locate window with the largest area.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(value, ARGUMENT_WINDOW_SEL_SMALLEST)) {
if (window) {
struct window *area_window = window_manager_find_smallest_managed_window(&g_space_manager, &g_window_manager);
if (area_window) {
window_manager_swap_window(&g_space_manager, &g_window_manager, window, area_window);
} else {
daemon_fail(rsp, "could not locate window with the smallest area.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(value, ARGUMENT_COMMON_SEL_PREV)) {
if (window) {
struct window *prev_window = window_manager_find_prev_managed_window(&g_space_manager, &g_window_manager, window);
Expand Down Expand Up @@ -1282,6 +1318,28 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(value, ARGUMENT_WINDOW_SEL_LARGEST)) {
if (window) {
struct window *area_window = window_manager_find_largest_managed_window(&g_space_manager, &g_window_manager);
if (area_window) {
window_manager_warp_window(&g_space_manager, window, area_window);
} else {
daemon_fail(rsp, "could not locate window with the largest area.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(value, ARGUMENT_WINDOW_SEL_SMALLEST)) {
if (window) {
struct window *area_window = window_manager_find_smallest_managed_window(&g_space_manager, &g_window_manager);
if (area_window) {
window_manager_warp_window(&g_space_manager, window, area_window);
} else {
daemon_fail(rsp, "could not locate window with the smallest area.\n");
}
} else {
daemon_fail(rsp, "could not locate the selected window.\n");
}
} else if (token_equals(value, ARGUMENT_COMMON_SEL_PREV)) {
if (window) {
struct window *prev_window = window_manager_find_prev_managed_window(&g_space_manager, &g_window_manager, window);
Expand Down
2 changes: 2 additions & 0 deletions src/misc/helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

extern AXError _AXUIElementGetWindow(AXUIElementRef ref, uint32_t *wid);

static const char *bool_str[] = { "off", "on" };

struct rgba_color
{
bool is_valid;
Expand Down
5 changes: 1 addition & 4 deletions src/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -416,10 +416,7 @@ uint32_t *view_find_window_list(struct view *view)

struct window_node *node = window_node_find_first_leaf(view->root);
while (node) {
if (window_node_is_leaf(node)) {
buf_push(window_list, node->window_id);
}

buf_push(window_list, node->window_id);
node = window_node_find_next_leaf(node);
}

Expand Down
38 changes: 38 additions & 0 deletions src/window_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,44 @@ struct window *window_manager_find_recent_managed_window(struct space_manager *s
return window_manager_find_window(wm, node->window_id);
}

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());
if (!view) return NULL;

uint32_t best_id = 0;
uint32_t best_area = 0;

for (struct window_node *node = window_node_find_first_leaf(view->root); node != NULL; node = window_node_find_next_leaf(node)) {
uint32_t area = node->area.w * node->area.h;
if (area > best_area) {
best_id = node->window_id;
best_area = area;
}
}

return best_id ? window_manager_find_window(wm, best_id) : NULL;
}

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

uint32_t best_id = 0;
uint32_t best_area = UINT32_MAX;

for (struct window_node *node = window_node_find_first_leaf(view->root); node != NULL; node = window_node_find_next_leaf(node)) {
uint32_t area = node->area.w * node->area.h;
if (area <= best_area) {
best_id = node->window_id;
best_area = area;
}
}

return best_id ? window_manager_find_window(wm, best_id) : NULL;
}

static void window_manager_defer_window_raise(ProcessSerialNumber *window_psn, uint32_t window_id)
{
uint8_t bytes[0xf8] = {
Expand Down
2 changes: 2 additions & 0 deletions src/window_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ struct window *window_manager_find_next_managed_window(struct space_manager *sm,
struct window *window_manager_find_first_managed_window(struct space_manager *sm, struct window_manager *wm);
struct window *window_manager_find_last_managed_window(struct space_manager *sm, struct window_manager *wm);
struct window *window_manager_find_recent_managed_window(struct space_manager *sm, struct window_manager *wm);
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);
void window_manager_focus_window_without_raise(ProcessSerialNumber *window_psn, uint32_t window_id);
void window_manager_focus_window_with_raise(ProcessSerialNumber *window_psn, uint32_t window_id, AXUIElementRef window_ref);
struct window *window_manager_focused_window(struct window_manager *wm);
Expand Down

0 comments on commit 77de2e0

Please sign in to comment.