aboutsummaryrefslogtreecommitdiff
path: root/modules/cj-window-geometry-lib.el
diff options
context:
space:
mode:
authorCraig Jennings <c@cjennings.net>2026-06-20 02:46:52 -0400
committerCraig Jennings <c@cjennings.net>2026-06-20 02:46:52 -0400
commit7e8f771408b7051066fb91fa9c68e80fa52405f7 (patch)
tree367b7209af1c725dbfdf11b321ee6948fa4ac096 /modules/cj-window-geometry-lib.el
parent63eff9be3bdb86239ba8d3d5aa916ad08967b238 (diff)
downloaddotemacs-7e8f771408b7051066fb91fa9c68e80fa52405f7.tar.gz
dotemacs-7e8f771408b7051066fb91fa9c68e80fa52405f7.zip
feat(windows): dock companion panels by a shared min-column rule
The F9 agent always docked as a right-side column on a landscape frame. On this 138-column frame that left ~68-column panes, too cramped to read code and the agent side by side. The F12 terminal and F10 playlist hardcoded a bottom split with no width-aware path. I added cj/preferred-dock-direction and the cj/window-dock-min-columns defcustom (default 80) to the window-geometry lib: dock side-by-side only when the narrower pane keeps at least the minimum width, otherwise stack below. All three toggles now route through it. F9 drops its pixel-aspect rule. F12 and F10 gain a right-column width default and become adaptive. F10 keeps width and height size memory in separate vars so a resize on one axis doesn't leak to the other.
Diffstat (limited to 'modules/cj-window-geometry-lib.el')
-rw-r--r--modules/cj-window-geometry-lib.el34
1 files changed, 34 insertions, 0 deletions
diff --git a/modules/cj-window-geometry-lib.el b/modules/cj-window-geometry-lib.el
index 047fe7c45..4c0662124 100644
--- a/modules/cj-window-geometry-lib.el
+++ b/modules/cj-window-geometry-lib.el
@@ -129,5 +129,39 @@ the fraction at toggle-off, replay it on the next toggle-on."
(hi (or max-frac 0.95)))
(max lo (min hi (/ (float window-size) frame-size))))))
+(defcustom cj/window-dock-min-columns 80
+ "Minimum body columns each pane must keep for a side-by-side dock.
+
+`cj/preferred-dock-direction' docks a companion panel as a side-by-side
+column only when both the panel and the main window would stay at least
+this wide; otherwise it stacks the panel below. 80 is the classic
+terminal/code width."
+ :type 'integer
+ :group 'windows)
+
+(defun cj/preferred-dock-direction (frame-cols fraction &optional min-cols)
+ "Return the dock direction for a companion panel beside the main window.
+
+Returns `right' (a side-by-side column) when a split that gives the panel
+FRACTION of FRAME-COLS would leave both panes at least MIN-COLS columns
+wide; otherwise `below' (a stacked panel). FRAME-COLS is the frame's
+total column count; FRACTION is the panel's share of the width, in the
+open interval (0, 1). MIN-COLS defaults to `cj/window-dock-min-columns'.
+
+The narrower of the two resulting panes governs: the panel takes
+round(FRACTION * FRAME-COLS) columns, the main window takes the rest less
+one divider column, and `right' is returned only when the smaller of the
+two clears MIN-COLS. Returns `below' for degenerate input (non-positive
+FRAME-COLS, or FRACTION outside (0, 1)) so a caller always gets a usable
+stacked fallback."
+ (let ((min-cols (or min-cols cj/window-dock-min-columns)))
+ (if (and (numberp frame-cols) (> frame-cols 0)
+ (numberp fraction) (< 0 fraction 1))
+ (let* ((panel (round (* fraction frame-cols)))
+ (main (- frame-cols panel 1))
+ (narrower (min panel main)))
+ (if (>= narrower min-cols) 'right 'below))
+ 'below)))
+
(provide 'cj-window-geometry-lib)
;;; cj-window-geometry-lib.el ends here