branch: externals/exwm
commit d1be727e1e96621478a209b48f7cf293a8fb4344
Author: Steven Allen <[email protected]>
Commit: Steven Allen <[email protected]>
Set floating mode-lines using window parameters
Rather than mess with the global mode-line each time a window is made
floating/tiling:
1. Set the buffer-local `mode-line-format' variable to customize the
tiling mode-line.
2. Set the floating window's `mode-line-format' window-parameter to
customize the floating mode-line.
This brings us a step closer to being able to have X windows appear in
multiple windows at the same time.
Additionally, apply all the same logic to the header line.
Unfortunately, this did make `exwm-layout-toggle-mode-line'
significantly more complex as it now has to handle window-specific
versus global mode-lines.
* exwm-core.el (exwm--saved-mode-line-format): Rename to make it clear
that this is a backup variable.
* exwm-floating.el (exwm-floating--set-floating): Apply floating window
decoration (mode/header-line) customizations via window parameters.
(exwm-floating-toggle-floating): We no longer need to restore
header/mode-line settings when switching from floating to tiling mode
because they're attached to the window, not the buffer.
* exwm-manage.el (exwm-manage--manage-window): Configure the tiling
mode-line on manage because we no longer do this from
`exwm-floating--unset-floating'.
* exwm-layout.el (exwm-layout-show-mode-line):
(exwm-layout-hide-mode-line): Replace body with calls to
`exwm-layout-toggle-mode-line'.
(exwm-layout--toggle-mode-line-1): A new macro to abstract over
configuring window-specific versus global mode-lines.
(exwm-layout--window-specific-mode-line):
(exwm-layout--mode-line): New helper functions.
(exwm-layout-toggle-mode-line): Refactor to hide/show the
window-specific (via window parameters) mode-line or the buffer-local
mode-line, depending on whether or not the window has a window-specific
mode-line format.
---
exwm-core.el | 2 +-
exwm-floating.el | 40 +++++--------------
exwm-layout.el | 119 +++++++++++++++++++++++++++++++++++++++----------------
exwm-manage.el | 5 +++
4 files changed, 101 insertions(+), 65 deletions(-)
diff --git a/exwm-core.el b/exwm-core.el
index 4e0e518576..627db1468c 100644
--- a/exwm-core.el
+++ b/exwm-core.el
@@ -273,7 +273,7 @@ If CONN is non-nil, use it instead of the value of the
variable
(defvar-local exwm--configurations nil) ;initial configurations.
(defvar-local exwm--frame nil) ;workspace frame
(defvar-local exwm--floating-frame nil) ;floating frame
-(defvar-local exwm--mode-line-format nil) ;save mode-line-format
+(defvar-local exwm--saved-mode-line-format nil) ;save mode-line-format
(defvar-local exwm--floating-frame-geometry nil) ;set when hidden.
(defvar-local exwm--fixed-size nil) ;fixed size
(defvar-local exwm--selected-input-mode 'line-mode
diff --git a/exwm-floating.el b/exwm-floating.el
index 05a3166673..302a8d75a1 100644
--- a/exwm-floating.el
+++ b/exwm-floating.el
@@ -212,24 +212,15 @@ configured dimension is invalid."
exwm--floating-frame frame)
;; Adjust the header & mode line before calculating sizes.
- (if-let* ((floating-mode-line (plist-get exwm--configurations
- 'floating-mode-line)))
- (setq exwm--mode-line-format (or exwm--mode-line-format
- mode-line-format)
- mode-line-format floating-mode-line)
- (if (and (not (plist-member exwm--configurations 'floating-mode-line))
- exwm--mwm-hints-decorations)
- (when exwm--mode-line-format
- (setq mode-line-format exwm--mode-line-format))
- ;; The mode-line need to be hidden in floating mode.
- (setq exwm--mode-line-format (or exwm--mode-line-format
- mode-line-format)
- mode-line-format nil)))
- (if-let* ((floating-header-line (plist-get exwm--configurations
- 'floating-header-line)))
- (setq header-line-format floating-header-line)
- ;; The header-line need to be hidden in floating mode.
- (setq header-line-format nil))
+ (pcase-dolist (`(,prop . ,setting) '((mode-line-format .
floating-mode-line)
+ (header-line-format .
floating-header-line)))
+ (cond
+ ((plist-member exwm--configurations setting)
+ (set-window-parameter
+ window prop
+ (or (plist-get exwm--configurations setting) 'none)))
+ ((not exwm--mwm-hints-decorations)
+ (set-window-parameter window prop 'none))))
;; We MUST redisplay with the frame visible here in order to correctly
calculate the sizes.
(redisplay)
@@ -413,18 +404,7 @@ configured dimension is invalid."
(delete-frame exwm--floating-frame))))
(with-current-buffer buffer
(setq window-size-fixed nil
- exwm--floating-frame nil)
- (if (not (plist-member exwm--configurations 'tiling-mode-line))
- (when exwm--mode-line-format
- (setq mode-line-format exwm--mode-line-format))
- (setq exwm--mode-line-format (or exwm--mode-line-format
- mode-line-format)
- mode-line-format (plist-get exwm--configurations
- 'tiling-mode-line)))
- (if (not (plist-member exwm--configurations 'tiling-header-line))
- (setq header-line-format nil)
- (setq header-line-format (plist-get exwm--configurations
- 'tiling-header-line))))
+ exwm--floating-frame nil))
;; Only show X windows in normal state.
(unless (exwm-layout--iconic-state-p)
(pop-to-buffer-same-window buffer)))
diff --git a/exwm-layout.el b/exwm-layout.el
index de5294989d..229d80147e 100644
--- a/exwm-layout.el
+++ b/exwm-layout.el
@@ -542,47 +542,98 @@ See also `exwm-layout-enlarge-window'."
(elt (exwm--window-inside-pixel-edges ) 3)))
(defun exwm-layout-hide-mode-line ()
- "Hide mode-line."
+ "Hide the mode-line.
+See `exwm-layout-toggle-mode-line' for more details."
(interactive)
(exwm--log)
- (when (and (derived-mode-p 'exwm-mode) mode-line-format)
- (if exwm--floating-frame
- (let* ((window (frame-first-window exwm--floating-frame))
- (old-bottom-offset (exwm-layout--window-bottom-offset window)))
- (setq exwm--mode-line-format mode-line-format
- mode-line-format nil)
- (exwm-layout-enlarge-window
- (- (exwm-layout--window-bottom-offset window) old-bottom-offset)))
- (setq exwm--mode-line-format mode-line-format
- mode-line-format nil)
- (exwm-layout--show exwm--id))))
+ (exwm-layout-toggle-mode-line -1))
(defun exwm-layout-show-mode-line ()
- "Show mode-line."
+ "Show the mode-line.
+See `exwm-layout-toggle-mode-line' for more details."
(interactive)
(exwm--log)
- (when (and (derived-mode-p 'exwm-mode) (not mode-line-format))
- (if exwm--floating-frame
- (let* ((window (frame-first-window exwm--floating-frame))
- (old-bottom-offset (exwm-layout--window-bottom-offset window)))
- (setq mode-line-format exwm--mode-line-format
- exwm--mode-line-format nil)
- (exwm-layout-enlarge-window
- (- (exwm-layout--window-bottom-offset window) old-bottom-offset))
- (call-interactively #'exwm-input-grab-keyboard))
- (setq mode-line-format exwm--mode-line-format
- exwm--mode-line-format nil)
- (exwm-layout--show exwm--id))
- (force-mode-line-update)))
-
-(defun exwm-layout-toggle-mode-line ()
- "Toggle the display of mode-line."
- (interactive)
+ (exwm-layout-toggle-mode-line 1))
+
+;; You can do this with by let-binding places with `gv-ref' and
+;; `gv-deref' instead of a macro, but the macro is cleaner.
+(defmacro exwm-layout--toggle-mode-line-1
+ (hide active-place saved-place none)
+ "Macro implementing the core logic behind mode-line toggling.
+
+If HIDE, the modeline is hidden. Otherwise, it is shown.
+
+ACTIVE-PLACE is the generalized variable where the active mode-line
+is stored.
+
+SAVED-PLACE is the generalized variable where the saved mode-line is
+stored when hidden.
+
+NONE is the symbol stored in ACTIVE-PLACE to hide the mode-line."
+ `(if ,hide
+ (ignore (cl-shiftf ,saved-place ,active-place ',none))
+ (setf ,active-place (or (cl-shiftf ,saved-place nil)
+ mode-line-format
+ (default-value 'mode-line-format)
+ (error "No sane mode-line to show")))))
+
+(defsubst exwm-layout--window-specific-mode-line (window)
+ "Return non-nil if WINDOW has a WINDOW-specific mode-line."
+ (or (window-parameter window 'mode-line-format)
+ (window-parameter window 'exwm--saved-mode-line-format)))
+
+(defsubst exwm-layout--mode-line (&optional window)
+ "Return the effective mode-line for WINDOW or the current buffer.
+Return nil if the buffer/window has no mode-line."
+ (pcase (and window (window-parameter window 'mode-line-format))
+ ('none nil)
+ ('nil mode-line-format)
+ (wml wml)))
+
+(defun exwm-layout-toggle-mode-line (&optional arg)
+ "Toggle the display of mode-line.
+
+If ARG is a positive number, show the mode-line.
+If ARG is a negative number, hide the mode-line.
+Otherwise, toggle the mode-line.
+
+If the mode-line format is specific to the current window (e.g., an
+undecorated floating window), the mode-line is toggled in that window
+only. Otherwise, it's toggled globally."
+ (interactive (list (and current-prefix-arg
+ (prefix-numeric-value current-prefix-arg))))
(exwm--log)
- (when (derived-mode-p 'exwm-mode)
- (if mode-line-format
- (exwm-layout-hide-mode-line)
- (exwm-layout-show-mode-line))))
+ (let* ((target-window
+ (cond (exwm--floating-frame
+ (frame-first-window exwm--floating-frame))
+ ((eq (window-buffer) (current-buffer))
+ (selected-window))))
+ (is-visible
+ (not (null (exwm-layout--mode-line target-window)))))
+ (when (or (not (numberp arg)) (eq (< arg 0) is-visible))
+ (let ((old-bottom-offset
+ (and exwm--floating-frame
+ target-window
+ (exwm-layout--window-bottom-offset target-window))))
+ (if (and target-window
+ (exwm-layout--window-specific-mode-line target-window))
+ (exwm-layout--toggle-mode-line-1
+ is-visible
+ (window-parameter target-window
+ 'mode-line-format)
+ (window-parameter target-window
+ 'exwm--saved-mode-line-format)
+ none)
+ (exwm-layout--toggle-mode-line-1
+ is-visible
+ mode-line-format
+ exwm--saved-mode-line-format
+ nil))
+ (when old-bottom-offset
+ (exwm-layout-enlarge-window
+ (- (exwm-layout--window-bottom-offset target-window)
+ old-bottom-offset))))
+ (force-mode-line-update))))
(defun exwm-layout--init ()
"Initialize layout module."
diff --git a/exwm-manage.el b/exwm-manage.el
index cccf9fedaf..674fc4f5c3 100644
--- a/exwm-manage.el
+++ b/exwm-manage.el
@@ -343,6 +343,11 @@ This only works when procfs is mounted, which may not be
the case on some BSDs."
;; UnmapNotify/DestroyNotify event of the dock.
(exwm--get-client-event-mask)
xcb:EventMask:NoEvent)))
+ ;; Configure the tiling mode-line & header-line
+ (pcase-dolist (`(,var . ,setting) '((mode-line-format .
tiling-mode-line)
+ (header-line-format .
tiling-header-line)))
+ (when (plist-member exwm--configurations setting)
+ (set var (plist-get exwm--configurations setting))))
;; The window needs to be mapped
(xcb:+request exwm--connection
(make-instance 'xcb:MapWindow :window id))