summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid <171410+dmb2@users.noreply.github.com>2022-05-23 11:02:31 -0400
committerGitHub <noreply@github.com>2022-05-23 11:02:31 -0400
commit09685fcddc32befcf7a0fbe38df9b0613fc4539b (patch)
treeca89d2c6d387f546925fb8718334379653b70eec
parente79564517f4a67aeee580e2f88a6f1d349fc2e27 (diff)
parent783ee26c6cd68b6e1d713861a13a7eb75e494b50 (diff)
Merge pull request #974 from szos/in-frame-fullscreen22.05
Add in frame fullscreen functionality
-rw-r--r--primitives.lisp40
-rw-r--r--stumpwm.texi.in8
-rw-r--r--tile-window.lisp21
3 files changed, 64 insertions, 5 deletions
diff --git a/primitives.lisp b/primitives.lisp
index dbdd0cd..7772c92 100644
--- a/primitives.lisp
+++ b/primitives.lisp
@@ -1179,6 +1179,46 @@ Must be an unquoted symbol to be looked up at runtime.
"Clear all window placement rules."
(setf *window-placement-rules* nil))
+(defvar *fullscreen-in-frame-p-window-functions* nil
+ "A alist of predicate functions for determining if a window should be
+fullscreen in frame.")
+
+(defun fullscreen-in-frame-p (win)
+ (some (lambda (r)
+ (let ((res (funcall (cdr r) win)))
+ (when res
+ (dformat 3 "Fullscreen in frame selector ~A matches window ~A"
+ (car r) win))
+ res))
+ *fullscreen-in-frame-p-window-functions*))
+
+(defun add-fullscreen-in-frame-rule (name function &key shadow)
+ "Add a function to the fullscreen-in-frame window rules alist. If @var{NAME}
+already exists as a key in the alist and @var{SHADOW} is nil, then
+@var{FUNCTION} replaces the existing value. Otherwise @var{NAME} and
+@var{FUNCTION} are pushed onto the alist."
+ (let ((present (assoc name *fullscreen-in-frame-p-window-functions*)))
+ (if (and present (not shadow))
+ (setf (cdr present) function)
+ (push (cons name function) *fullscreen-in-frame-p-window-functions*))))
+
+(defun remove-fullscreen-in-frame-rule (name &key count)
+ "Remove rules named @var{NAME} from the fullscreen-in-frame window rules alist.
+If @var{COUNT} is NIL then all matching rules are removed, otherwise only the
+first @var{COUNT} rules are removed."
+ (setf *fullscreen-in-frame-p-window-functions*
+ (remove name *fullscreen-in-frame-p-window-functions*
+ :key #'car :count count)))
+
+(defmacro define-fullscreen-in-frame-rule (name (window-argument) &body body)
+ "Define a rule for a window to be fullscreened within the frame. Each rule is a
+function which will be called when a window is made fullscreen. If the rule
+returns NIL then the fullscreen window takes up the entire head, otherwise it
+takes up only its frame. Within the body of the rule @var{WINDOW-ARGUMENT} is
+bound to the window being processed."
+ `(flet ((,name (,window-argument) ,@body))
+ (add-fullscreen-in-frame-rule ',name #',name)))
+
(defvar *mouse-focus-policy* :ignore
"The mouse focus policy decides how the mouse affects input
focus. Possible values are :ignore, :sloppy, and :click. :ignore means
diff --git a/stumpwm.texi.in b/stumpwm.texi.in
index ca6dc12..dac8c62 100644
--- a/stumpwm.texi.in
+++ b/stumpwm.texi.in
@@ -1706,6 +1706,14 @@ An input function takes 2 arguments: the input structure and the key pressed.
### *hidden-window-color*
### *honor-window-moves*
+
+
+%%% define-fullscreen-in-frame-rule
+@@@ add-fullscreen-in-frame-rule
+@@@ remove-fullscreen-in-frame-rule
+### *fullscreen-in-frame-p-window-functions*
+
+
@menu
* Window Marks::
* Customizing Window Appearance::
diff --git a/tile-window.lisp b/tile-window.lisp
index e2b88f2..b183570 100644
--- a/tile-window.lisp
+++ b/tile-window.lisp
@@ -114,11 +114,22 @@ than the root window's width and height."
;; handle specially fullscreen windows.
((window-fullscreen win)
(let* ((win-group (window-group win))
- (head (frame-head win-group f)))
- (setf x (frame-x head)
- y (frame-y head)
- width (frame-width head)
- height (frame-height head)))
+ (fs-in-frame (fullscreen-in-frame-p win))
+ (head (frame-head win-group f))
+ (frame-to-fill (if fs-in-frame f head))
+ (ml (head-mode-line head))
+ (adjust-by (if (and fs-in-frame
+ (or (eq :stump (mode-line-mode ml))
+ (eq :visible (mode-line-mode ml))))
+ (mode-line-height ml)
+ 0)))
+ ;; determine if the window should be fullscreened in the frame or the
+ ;; head. When fullscreen-in-frame-p returns true, use the current frame
+ ;; and adjust for mode line size.
+ (setf x (frame-x frame-to-fill)
+ y (+ (frame-y frame-to-fill) adjust-by)
+ width (frame-width frame-to-fill)
+ height (- (frame-height frame-to-fill) adjust-by)))
(return-from geometry-hints (values x y 0 0 width height 0 t)))
;; Adjust the defaults if the window is a transient_for window.
((find (window-type win) '(:transient :dialog))