From df94ce05a297c1e62ff1eaa1f8354fcf2193126c Mon Sep 17 00:00:00 2001 From: koekeishiya Date: Wed, 14 Jun 2023 19:03:48 +0200 Subject: [PATCH] #960 allow window swap command to swap windows inside the same stack --- CHANGELOG.md | 2 ++ src/window_manager.c | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5859f779..df2049b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,8 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +### Changed +- Allow window swap commands to work on windows that are in the same stack, using the stack window selectors [#960](https://github.com/koekeishiya/yabai/issues/960) ## [5.0.6] - 2023-05-27 ### Changed diff --git a/src/window_manager.c b/src/window_manager.c index 3d7fabaf..c14309cf 100644 --- a/src/window_manager.c +++ b/src/window_manager.c @@ -1758,7 +1758,41 @@ enum window_op_error window_manager_swap_window(struct space_manager *sm, struct struct window_node *b_node = view_find_window_node(b_view, b->id); if (!b_node) return WINDOW_OP_ERROR_INVALID_DST_NODE; - if (a_node == b_node) return WINDOW_OP_ERROR_SAME_STACK; + if (a_node == b_node) { + int a_list_index = 0; + int a_order_index = 0; + + int b_list_index = 0; + int b_order_index = 0; + + for (int i = 0; i < a_node->window_count; ++i) { + if (a_node->window_list[i] == a->id) { + a_list_index = i; + } else if (a_node->window_list[i] == b->id) { + b_list_index = i; + } + + if (a_node->window_order[i] == a->id) { + a_order_index = i; + } else if (a_node->window_order[i] == b->id) { + b_order_index = i; + } + } + + a_node->window_list[a_list_index] = b->id; + a_node->window_order[a_order_index] = b->id; + + a_node->window_list[b_list_index] = a->id; + a_node->window_order[b_order_index] = a->id; + + if (a->id == wm->focused_window_id) { + window_manager_focus_window_with_raise(&b->application->psn, b->id, b->ref); + } else if (b->id == wm->focused_window_id) { + window_manager_focus_window_with_raise(&a->application->psn, a->id, a->ref); + } + + return WINDOW_OP_ERROR_SUCCESS; + } if (window_node_contains_window(a_node, a_view->insertion_point)) { a_view->insertion_point = b->id;