diff options
| author | Craig Jennings <c@cjennings.net> | 2026-05-13 13:27:25 -0500 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-05-13 13:27:25 -0500 |
| commit | 97f0f8e67fa5aecf3161ce5b45d2bb17d075111e (patch) | |
| tree | 61a1c293b4a3b57867368cb65d24136e0df9caed /modules | |
| parent | 8e579508a1e23e66513d2e8f97844d0eab2156d7 (diff) | |
| download | dotemacs-97f0f8e67fa5aecf3161ce5b45d2bb17d075111e.tar.gz dotemacs-97f0f8e67fa5aecf3161ce5b45d2bb17d075111e.zip | |
fix(ui-navigation): clear dedicated before toggling window split
toggle-window-split swapped buffers between two windows via two set-window-buffer calls. If either window was strongly dedicated (e.g. *Org Agenda* via the display-buffer-alist rule), the dedicated window rejected the second swap. Both panes ended up showing the dedicated buffer. The non-dedicated buffer never made it across.
The fix clears dedicated on both windows before the swap. The user explicitly invoked a layout change, so preserving per-window dedicated through the operation would just re-trigger the same wedge on the next toggle.
Tests in tests/test-ui-navigation--toggle-window-split.el cover the no-dedicated baseline, the bug-trigger (dedicated selected window), the post-toggle cleared state, and the one-window / three-window no-op boundaries.
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/ui-navigation.el | 54 |
1 files changed, 32 insertions, 22 deletions
diff --git a/modules/ui-navigation.el b/modules/ui-navigation.el index 23e38c0a..09100799 100644 --- a/modules/ui-navigation.el +++ b/modules/ui-navigation.el @@ -100,30 +100,40 @@ nudging until any other key. Bound to `C-; b <left>/<right>/<up>/<down>'." If the window is split horizontally, change the split to vertical. If it's vertical, change the split to horizontal. +Clears dedicated state on both windows so the toggle still works when +one is strongly dedicated (e.g. =*Org Agenda*=). Without this, the +internal `set-window-buffer' call refuses to place a non-matching +buffer in a dedicated window and both panes end up showing the +dedicated buffer. This function won't work with more than one split window." (interactive) - (if (= (count-windows) 2) - (let* ((this-win-buffer (window-buffer)) - (next-win-buffer (window-buffer (next-window))) - (this-win-edges (window-edges (selected-window))) - (next-win-edges (window-edges (next-window))) - (this-win-2nd (not (and (<= (car this-win-edges) - (car next-win-edges)) - (<= (cadr this-win-edges) - (cadr next-win-edges))))) - (splitter - (if (= (car this-win-edges) - (car (window-edges (next-window)))) - 'split-window-horizontally - 'split-window-vertically))) - (delete-other-windows) - (let ((first-win (selected-window))) - (funcall splitter) - (if this-win-2nd (other-window 1)) - (set-window-buffer (selected-window) this-win-buffer) - (set-window-buffer (next-window) next-win-buffer) - (select-window first-win) - (if this-win-2nd (other-window 1)))))) + (when (= (count-windows) 2) + ;; Clear dedicated up front: `set-window-buffer' rejects buffer swaps + ;; on strongly-dedicated windows. The user explicitly invoked a + ;; layout change, so don't try to preserve dedicated through it. + (set-window-dedicated-p (selected-window) nil) + (set-window-dedicated-p (next-window) nil) + (let* ((this-win-buffer (window-buffer)) + (next-win-buffer (window-buffer (next-window))) + (this-win-edges (window-edges (selected-window))) + (next-win-edges (window-edges (next-window))) + (this-win-2nd (not (and (<= (car this-win-edges) + (car next-win-edges)) + (<= (cadr this-win-edges) + (cadr next-win-edges))))) + (splitter + (if (= (car this-win-edges) + (car (window-edges (next-window)))) + 'split-window-horizontally + 'split-window-vertically))) + (delete-other-windows) + (let ((first-win (selected-window))) + (funcall splitter) + (if this-win-2nd (other-window 1)) + (set-window-buffer (selected-window) this-win-buffer) + (set-window-buffer (next-window) next-win-buffer) + (select-window first-win) + (if this-win-2nd (other-window 1)))))) (keymap-global-set "M-S-t" #'toggle-window-split) ;; was M-T, overrides transpose-words ;; ---------------------------- Buffer Manipulation ---------------------------- |
