Skip to content

Commit

Permalink
#187 extend the number of window commands that return a non-zero exit…
Browse files Browse the repository at this point in the history
… code upon failure
  • Loading branch information
koekeishiya committed Apr 2, 2020
1 parent 45bb34a commit 5d8dc12
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 50 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
- Fix memory leak that would occur if realloc failed when reading from a socket [#436](https://github.com/koekeishiya/yabai/issues/436)
- Increase number of window commands that return a non-zero exit code upon failure [#187](https://github.com/koekeishiya/yabai/issues/187)

## [2.4.1] - 2020-03-01
### Changed
Expand Down
57 changes: 50 additions & 7 deletions src/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -1509,23 +1509,53 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
} else if (token_equals(command, COMMAND_WINDOW_SWAP)) {
struct selector selector = parse_window_selector(rsp, &message, acting_window);
if (selector.did_parse && selector.window) {
window_manager_swap_window(&g_space_manager, &g_window_manager, acting_window, selector.window);
enum window_op_error result = window_manager_swap_window(&g_space_manager, &g_window_manager, acting_window, selector.window);
if (result == WINDOW_OP_ERROR_INVALID_SRC_VIEW) {
daemon_fail(rsp, "the acting window is not within a bsp space.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_DST_VIEW) {
daemon_fail(rsp, "the selected window is not within a bsp space.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_SRC_NODE) {
daemon_fail(rsp, "the acting window is not managed.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_DST_NODE) {
daemon_fail(rsp, "the selected window is not managed.\n");
} else if (result == WINDOW_OP_ERROR_SAME_WINDOW) {
daemon_fail(rsp, "cannot swap a window with itself.\n");
}
}
} else if (token_equals(command, COMMAND_WINDOW_WARP)) {
struct selector selector = parse_window_selector(rsp, &message, acting_window);
if (selector.did_parse && selector.window) {
window_manager_warp_window(&g_space_manager, &g_window_manager, acting_window, selector.window);
enum window_op_error result = window_manager_warp_window(&g_space_manager, &g_window_manager, acting_window, selector.window);
if (result == WINDOW_OP_ERROR_INVALID_SRC_VIEW) {
daemon_fail(rsp, "the acting window is not within a bsp space.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_DST_VIEW) {
daemon_fail(rsp, "the selected window is not within a bsp space.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_SRC_NODE) {
daemon_fail(rsp, "the acting window is not managed.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_DST_NODE) {
daemon_fail(rsp, "the selected window is not managed.\n");
} else if (result == WINDOW_OP_ERROR_SAME_WINDOW) {
daemon_fail(rsp, "cannot warp a window onto itself.\n");
}
}
} else if (token_equals(command, COMMAND_WINDOW_INSERT)) {
struct selector selector = parse_dir_selector(rsp, &message);
if (selector.did_parse && selector.dir) {
window_manager_set_window_insertion(&g_space_manager, &g_window_manager, acting_window, selector.dir);
enum window_op_error result = window_manager_set_window_insertion(&g_space_manager, &g_window_manager, acting_window, selector.dir);
if (result == WINDOW_OP_ERROR_INVALID_SRC_VIEW) {
daemon_fail(rsp, "the acting window is not within a bsp space.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_SRC_NODE) {
daemon_fail(rsp, "the acting window is not managed.\n");
}
}
} else if (token_equals(command, COMMAND_WINDOW_GRID)) {
unsigned r, c, x, y, w, h;
struct token value = get_token(&message);
if ((sscanf(value.text, ARGUMENT_WINDOW_GRID, &r, &c, &x, &y, &w, &h) == 6)) {
window_manager_apply_grid(&g_space_manager, &g_window_manager, acting_window, r, c, x, y, w, h);
enum window_op_error result = window_manager_apply_grid(&g_space_manager, &g_window_manager, acting_window, r, c, x, y, w, h);
if (result == WINDOW_OP_ERROR_INVALID_SRC_VIEW) {
daemon_fail(rsp, "cannot apply grid layout to a managed window.\n");
}
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.length, value.text, command.length, command.text, domain.length, domain.text);
}
Expand All @@ -1534,7 +1564,10 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
char type[MAXLEN];
struct token value = get_token(&message);
if ((sscanf(value.text, ARGUMENT_WINDOW_MOVE, type, &x, &y) == 3)) {
window_manager_move_window_relative(&g_window_manager, acting_window, parse_value_type(type), x, y);
enum window_op_error result = window_manager_move_window_relative(&g_window_manager, acting_window, parse_value_type(type), x, y);
if (result == WINDOW_OP_ERROR_INVALID_SRC_VIEW) {
daemon_fail(rsp, "cannot move a managed window.\n");
}
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.length, value.text, command.length, command.text, domain.length, domain.text);
}
Expand All @@ -1543,7 +1576,12 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
char handle[MAXLEN];
struct token value = get_token(&message);
if ((sscanf(value.text, ARGUMENT_WINDOW_RESIZE, handle, &w, &h) == 3)) {
window_manager_resize_window_relative(&g_window_manager, acting_window, parse_resize_handle(handle), w, h);
enum window_op_error result = window_manager_resize_window_relative(&g_window_manager, acting_window, parse_resize_handle(handle), w, h);
if (result == WINDOW_OP_ERROR_INVALID_SRC_NODE) {
daemon_fail(rsp, "cannot locate bsp node for the managed window.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_DST_NODE) {
daemon_fail(rsp, "cannot locate a bsp node fence");
}
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.length, value.text, command.length, command.text, domain.length, domain.text);
}
Expand All @@ -1552,7 +1590,12 @@ static void handle_domain_window(FILE *rsp, struct token domain, char *message)
char type[MAXLEN];
struct token value = get_token(&message);
if ((sscanf(value.text, ARGUMENT_WINDOW_RATIO, type, &r) == 2)) {
window_manager_adjust_window_ratio(&g_window_manager, acting_window, parse_value_type(type), r);
enum window_op_error result = window_manager_adjust_window_ratio(&g_window_manager, acting_window, parse_value_type(type), r);
if (result == WINDOW_OP_ERROR_INVALID_SRC_VIEW) {
daemon_fail(rsp, "cannot adjust ratio of a non-managed window.\n");
} else if (result == WINDOW_OP_ERROR_INVALID_SRC_NODE) {
daemon_fail(rsp, "cannot adjust ratio of a root node\n");
}
} else {
daemon_fail(rsp, "unknown value '%.*s' given to command '%.*s' for domain '%.*s'\n", value.length, value.text, command.length, command.text, domain.length, domain.text);
}
Expand Down
90 changes: 54 additions & 36 deletions src/window_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,31 +246,33 @@ void window_manager_add_managed_window(struct window_manager *wm, struct window
window_manager_purify_window(wm, window);
}

void window_manager_adjust_window_ratio(struct window_manager *wm, struct window *window, int type, float ratio)
enum window_op_error window_manager_adjust_window_ratio(struct window_manager *wm, struct window *window, int type, float ratio)
{
struct view *view = window_manager_find_managed_window(wm, window);
if (view) {
struct window_node *node = view_find_window_node(view, window->id);
if (!node || !node->parent) return;

switch (type) {
case TYPE_REL: {
node->parent->ratio = clampf_range(node->parent->ratio + ratio, 0.1f, 0.9f);
} break;
case TYPE_ABS: {
node->parent->ratio = clampf_range(ratio, 0.1f, 0.9f);
} break;
}
if (!view) return WINDOW_OP_ERROR_INVALID_SRC_VIEW;

window_node_update(view, node->parent);
window_node_flush(node->parent);
struct window_node *node = view_find_window_node(view, window->id);
if (!node || !node->parent) return WINDOW_OP_ERROR_INVALID_SRC_NODE;

switch (type) {
case TYPE_REL: {
node->parent->ratio = clampf_range(node->parent->ratio + ratio, 0.1f, 0.9f);
} break;
case TYPE_ABS: {
node->parent->ratio = clampf_range(ratio, 0.1f, 0.9f);
} break;
}

window_node_update(view, node->parent);
window_node_flush(node->parent);

return WINDOW_OP_ERROR_SUCCESS;
}

void window_manager_move_window_relative(struct window_manager *wm, struct window *window, int type, float dx, float dy)
enum window_op_error window_manager_move_window_relative(struct window_manager *wm, struct window *window, int type, float dx, float dy)
{
struct view *view = window_manager_find_managed_window(wm, window);
if (view) return;
if (view) return WINDOW_OP_ERROR_INVALID_SRC_VIEW;

if (type == TYPE_REL) {
CGRect frame = window_frame(window);
Expand All @@ -279,23 +281,25 @@ void window_manager_move_window_relative(struct window_manager *wm, struct windo
}

window_manager_move_window(window, dx, dy);

return WINDOW_OP_ERROR_SUCCESS;
}

void window_manager_resize_window_relative(struct window_manager *wm, struct window *window, int direction, float dx, float dy)
enum window_op_error window_manager_resize_window_relative(struct window_manager *wm, struct window *window, int direction, float dx, float dy)
{
struct view *view = window_manager_find_managed_window(wm, window);
if (view) {
struct window_node *x_fence = NULL;
struct window_node *y_fence = NULL;

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

if (direction & HANDLE_TOP) x_fence = window_node_fence(node, DIR_NORTH);
if (direction & HANDLE_BOTTOM) x_fence = window_node_fence(node, DIR_SOUTH);
if (direction & HANDLE_LEFT) y_fence = window_node_fence(node, DIR_WEST);
if (direction & HANDLE_RIGHT) y_fence = window_node_fence(node, DIR_EAST);
if (!x_fence && !y_fence) return;
if (!x_fence && !y_fence) return WINDOW_OP_ERROR_INVALID_DST_NODE;

if (y_fence) {
float sr = y_fence->ratio + (float) dx / (float) y_fence->area.w;
Expand Down Expand Up @@ -326,6 +330,8 @@ void window_manager_resize_window_relative(struct window_manager *wm, struct win
window_manager_resize_window(window, fw, fh);
}
}

return WINDOW_OP_ERROR_SUCCESS;
}

void window_manager_move_window_cgs(struct window *window, float x, float y)
Expand Down Expand Up @@ -1086,14 +1092,14 @@ void window_manager_add_application_windows(struct space_manager *sm, struct win
free(window_list);
}

void window_manager_set_window_insertion(struct space_manager *sm, struct window_manager *wm, struct window *window, int direction)
enum window_op_error window_manager_set_window_insertion(struct space_manager *sm, struct window_manager *wm, struct window *window, int direction)
{
uint64_t sid = window_space(window);
struct view *view = space_manager_find_view(sm, sid);
if (view->layout != VIEW_BSP) return;
if (view->layout != VIEW_BSP) return WINDOW_OP_ERROR_INVALID_SRC_VIEW;

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

if (view->insertion_point && view->insertion_point != window->id) {
struct window_node *insert_node = view_find_window_node(view, view->insertion_point);
Expand Down Expand Up @@ -1143,23 +1149,27 @@ void window_manager_set_window_insertion(struct space_manager *sm, struct window
}

border_window_refresh(window);

return WINDOW_OP_ERROR_SUCCESS;
}

void window_manager_warp_window(struct space_manager *sm, struct window_manager *wm, struct window *a, struct window *b)
enum window_op_error window_manager_warp_window(struct space_manager *sm, struct window_manager *wm, struct window *a, struct window *b)
{
if (a->id == b->id) return WINDOW_OP_ERROR_SAME_WINDOW;

uint64_t a_sid = window_space(a);
struct view *a_view = space_manager_find_view(sm, a_sid);
if (a_view->layout != VIEW_BSP) return;
if (a_view->layout != VIEW_BSP) return WINDOW_OP_ERROR_INVALID_SRC_VIEW;

uint64_t b_sid = window_space(b);
struct view *b_view = space_manager_find_view(sm, b_sid);
if (b_view->layout != VIEW_BSP) return;
if (b_view->layout != VIEW_BSP) return WINDOW_OP_ERROR_INVALID_DST_VIEW;

struct window_node *a_node = view_find_window_node(a_view, a->id);
if (!a_node) return;
if (!a_node) return WINDOW_OP_ERROR_INVALID_SRC_NODE;

struct window_node *b_node = view_find_window_node(b_view, b->id);
if (!b_node) return;
if (!b_node) return WINDOW_OP_ERROR_INVALID_DST_NODE;

if (a_node->parent == b_node->parent) {
if (b_view->insertion_point == b_node->window_id) {
Expand Down Expand Up @@ -1203,23 +1213,27 @@ void window_manager_warp_window(struct space_manager *sm, struct window_manager

space_manager_tile_window_on_space_with_insertion_point(sm, a, b_view->sid, b->id);
}

return WINDOW_OP_ERROR_SUCCESS;
}

void window_manager_swap_window(struct space_manager *sm, struct window_manager *wm, struct window *a, struct window *b)
enum window_op_error window_manager_swap_window(struct space_manager *sm, struct window_manager *wm, struct window *a, struct window *b)
{
if (a->id == b->id) return WINDOW_OP_ERROR_SAME_WINDOW;

uint64_t a_sid = window_space(a);
struct view *a_view = space_manager_find_view(sm, a_sid);
if (a_view->layout != VIEW_BSP) return;
if (a_view->layout != VIEW_BSP) return WINDOW_OP_ERROR_INVALID_SRC_VIEW;

uint64_t b_sid = window_space(b);
struct view *b_view = space_manager_find_view(sm, b_sid);
if (b_view->layout != VIEW_BSP) return;
if (b_view->layout != VIEW_BSP) return WINDOW_OP_ERROR_INVALID_DST_VIEW;

struct window_node *a_node = view_find_window_node(a_view, a->id);
if (!a_node) return;
if (!a_node) return WINDOW_OP_ERROR_INVALID_SRC_NODE;

struct window_node *b_node = view_find_window_node(b_view, b->id);
if (!b_node) return;
if (!b_node) return WINDOW_OP_ERROR_INVALID_DST_NODE;

a_node->window_id = b->id;
a_node->zoom = NULL;
Expand All @@ -1244,6 +1258,8 @@ void window_manager_swap_window(struct space_manager *sm, struct window_manager

window_node_flush(a_node);
window_node_flush(b_node);

return WINDOW_OP_ERROR_SUCCESS;
}

bool window_manager_close_window(struct window *window)
Expand Down Expand Up @@ -1291,13 +1307,13 @@ void window_manager_send_window_to_space(struct space_manager *sm, struct window
}
}

void window_manager_apply_grid(struct space_manager *sm, struct window_manager *wm, struct window *window, unsigned r, unsigned c, unsigned x, unsigned y, unsigned w, unsigned h)
enum window_op_error window_manager_apply_grid(struct space_manager *sm, struct window_manager *wm, struct window *window, unsigned r, unsigned c, unsigned x, unsigned y, unsigned w, unsigned h)
{
struct view *view = window_manager_find_managed_window(wm, window);
if (view) return;
if (view) return WINDOW_OP_ERROR_INVALID_SRC_VIEW;

uint32_t did = window_display_id(window);
if (!did) return;
if (!did) return WINDOW_OP_ERROR_INVALID_SRC_VIEW;

if (x >= c) x = c - 1;
if (y >= r) y = r - 1;
Expand Down Expand Up @@ -1327,6 +1343,8 @@ void window_manager_apply_grid(struct space_manager *sm, struct window_manager *

window_manager_move_window(window, fx, fy);
window_manager_resize_window(window, fw, fh);

return WINDOW_OP_ERROR_SUCCESS;
}

void window_manager_toggle_window_topmost(struct window *window)
Expand Down
Loading

0 comments on commit 5d8dc12

Please sign in to comment.