stumpwm-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [STUMP] [PATCH] Allow *new-window-prefered-frame* callback to return


From: David Hansen
Subject: Re: [STUMP] [PATCH] Allow *new-window-prefered-frame* callback to return a list of preferences.
Date: Fri, 02 May 2008 14:16:49 +0200
User-agent: Gnus/5.110009 (No Gnus v0.9) Emacs/23.0.60 (gnu/linux)

On Sat, 26 Apr 2008 20:28:50 +0200 David Hansen wrote:

> Hello,
>
> this turned out to be useful for me:
>

for the gmail lusers inlined:

diff --git a/primitives.lisp b/primitives.lisp
index ea788db..4637ba0 100644
--- a/primitives.lisp
+++ b/primitives.lisp
@@ -1002,8 +1002,8 @@ Choose any empty frame.
 Choose any unfocused frame.
 @end table
 
-Alternatively, it can be set to a function that takes one argument,
-the new window, and returns the prefered frame.")
+Alternatively, it can be set to a function that takes one argument, the new
+window, and returns the prefered frame or a list of the above preferences.")
 
 (defun backtrace-string ()
   "Similar to print-backtrace, but return the backtrace as a string."
diff --git a/core.lisp b/core.lisp
index 240e2ab..c279a59 100644
--- a/core.lisp
+++ b/core.lisp
@@ -1118,41 +1118,64 @@ than the root window's width and height."
 (defun pick-prefered-frame (window)
   (let* ((group (window-group window))
          (frames (group-frames group))
-         (default (tile-group-current-frame group)))
-    (or
-     (if (or (functionp *new-window-prefered-frame*)
-             (and (symbolp *new-window-prefered-frame*)
-                  (fboundp *new-window-prefered-frame*)))
-         (handler-case
-             (funcall *new-window-prefered-frame* window)
-           (error (c)
-             (message "^1*^BError while calling 
^b^3**new-window-prefered-frame*^1*^B: ^n~a" c)
-             nil))
-         (loop for i in *new-window-prefered-frame*
-               thereis (case i
-                         (:last
-                          ;; last-frame can be stale
-                          (and (> (length frames) 1)
-                               (tile-group-last-frame group)))
-                         (:unfocused
-                          (find-if (lambda (f)
-                                     (not (eq f (tile-group-current-frame 
group))))
-                                   frames))
-                         (:empty
-                          (find-if (lambda (f)
-                                     (null (frame-window f)))
-                                   frames))
-                         (:choice
-                          ;; Transient windows sometimes specify a location
-                          ;; relative to the TRANSIENT_FOR window. Just ignore
-                          ;; these hints.
-                          (unless (find (window-type window) '(:transient 
:dialog))
-                            (let ((hints (window-normal-hints window)))
-                              (when (and hints 
(xlib:wm-size-hints-user-specified-position-p hints))
-                                (find-frame group (window-x window) (window-y 
window))))))
-                         (t             ; :focused
-                          (tile-group-current-frame group)))))
-     default)))
+         (default (tile-group-current-frame group))
+         (prefered-frame
+          ;; If `*new-window-prefered-frame*' is a function use it to get the
+          ;; frame or the methods to determine it.
+          (if (or (functionp *new-window-prefered-frame*)
+                  (and (symbolp *new-window-prefered-frame*)
+                       (fboundp *new-window-prefered-frame*)))
+              (handler-case
+                  (funcall *new-window-prefered-frame* window)
+                (error (c)
+                  (message "^1*^BError while calling 
^b^3**new-window-prefered-frame*^1*^B: ^n~a" c)
+                  default))
+              ;; Otherwise use the methods from `*new-window-prefered-frame*'
+              ;; or the default frame.
+              (or *new-window-prefered-frame*
+                  default))))
+    (cond
+      ;; If we already have a frame, return it.
+      ((frame-p prefered-frame)
+       prefered-frame )
+      ;; If `prefered-frame' is a list of keywords use it to determine the new
+      ;; frame.  The sanity check doesn't cover not recognized keywords.  We
+      ;; simply fall back to the default then.
+      ((and (listp prefered-frame)
+            (every #'keywordp prefered-frame))
+       (loop for i in prefered-frame
+          thereis
+          (case i
+            (:last
+             ;; last-frame can be stale
+             (and (> (length frames) 1)
+                  (tile-group-last-frame group)))
+            (:unfocused
+             (find-if (lambda (f)
+                        (not (eq f (tile-group-current-frame group))))
+                      frames))
+            (:empty
+             (find-if (lambda (f)
+                        (null (frame-window f)))
+                      frames))
+            (:choice
+             ;; Transient windows sometimes specify a location relative to
+             ;; the TRANSIENT_FOR window. Just ignore these hints.
+             (unless (find (window-type window) '(:transient :dialog))
+               (let ((hints (window-normal-hints window)))
+                 (and hints
+                      (xlib:wm-size-hints-user-specified-position-p hints)
+                      (find-frame group
+                                  (window-x window)
+                                  (window-y window))))))
+            (t                          ; :focused, or non recognized keyword
+             (tile-group-current-frame group)))))
+      ;; Not well formed `*new-window-prefered-frame*'.  Message an error and
+      ;; return the default.
+      (t
+       (message "^1*^BInvalid ^b^3**new-window-prefered-frame*^1*^B: ^n~a"
+                prefered-frame)
+       default))))
 
 (defun add-window (screen xwin)
   (screen-add-mapped-window screen xwin)





reply via email to

[Prev in Thread] Current Thread [Next in Thread]