1 ;;; --------------------------------------------------------------------------
2 ;;; CLFSWM - FullScreen Window Manager
4 ;;; --------------------------------------------------------------------------
5 ;;; Documentation: Expose functions - An expose like.
6 ;;; --------------------------------------------------------------------------
8 ;;; (C) 2010 Philippe Brochard <hocwp@free.fr>
10 ;;; This program is free software; you can redistribute it and/or modify
11 ;;; it under the terms of the GNU General Public License as published by
12 ;;; the Free Software Foundation; either version 3 of the License, or
13 ;;; (at your option) any later version.
15 ;;; This program is distributed in the hope that it will be useful,
16 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;;; GNU General Public License for more details.
20 ;;; You should have received a copy of the GNU General Public License
21 ;;; along with this program; if not, write to the Free Software
22 ;;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 ;;; --------------------------------------------------------------------------
28 (defparameter *expose-font
* nil
)
29 (defparameter *expose-windows-list
* nil
)
31 (defun leave-expose-mode ()
32 "Leave the expose mode"
33 (throw 'exit-expose-loop nil
))
35 (defun valid-expose-mode ()
36 "Valid the expose mode"
37 (throw 'exit-expose-loop t
))
39 (defun mouse-leave-expose-mode (window root-x root-y
)
40 "Leave the expose mode"
41 (declare (ignore window root-x root-y
))
42 (throw 'exit-expose-loop nil
))
44 (defun mouse-valid-expose-mode (window root-x root-y
)
45 "Valid the expose mode"
46 (declare (ignore window root-x root-y
))
47 (throw 'exit-expose-loop t
))
50 (define-handler expose-mode
:key-press
(code state
)
51 (funcall-key-from-code *expose-keys
* code state
))
53 (define-handler expose-mode
:button-press
(code state window root-x root-y
)
54 (funcall-button-from-code *expose-mouse
* code state window root-x root-y
*fun-press
*))
56 (define-handler expose-mode
:exposure
()
60 (add-hook *binding-hook
* 'set-default-expose-keys
)
62 (defun set-default-expose-keys ()
63 (define-expose-key ("Escape") 'leave-expose-mode
)
64 (define-expose-key ("g" :control
) 'leave-expose-mode
)
65 (define-expose-key ("Escape" :alt
) 'leave-expose-mode
)
66 (define-expose-key ("g" :control
:alt
) 'leave-expose-mode
)
67 (define-expose-key ("Return") 'valid-expose-mode
)
68 (define-expose-key ("space") 'valid-expose-mode
)
69 (define-expose-key ("Tab") 'valid-expose-mode
)
70 (define-expose-key ("Right") 'speed-mouse-right
)
71 (define-expose-key ("Left") 'speed-mouse-left
)
72 (define-expose-key ("Down") 'speed-mouse-down
)
73 (define-expose-key ("Up") 'speed-mouse-up
)
74 (define-expose-key ("Left" :control
) 'speed-mouse-undo
)
75 (define-expose-key ("Up" :control
) 'speed-mouse-first-history
)
76 (define-expose-key ("Down" :control
) 'speed-mouse-reset
)
77 (define-expose-mouse (1) 'mouse-valid-expose-mode
)
78 (define-expose-mouse (2) 'mouse-leave-expose-mode
)
79 (define-expose-mouse (3) 'mouse-leave-expose-mode
))
81 (defmacro define-expose-letter-keys
()
82 (labels ((produce-name (n)
83 (symb "%" "expose-fun-key-" n
"%")))
85 ,@(loop for n from
0 to
25
87 (defun ,(produce-name n
) ()
88 ,(format nil
"Select child '~A' (~A)" (number->char n
) n
)
89 (let ((child (nth ,n
*expose-windows-list
*)))
91 (xlib:warp-pointer
*root
* (xlib:drawable-x
(first child
)) (xlib:drawable-y
(first child
)))
92 (when *expose-valid-on-key
*
93 (valid-expose-mode)))))
94 (define-expose-key (,(number->char n
)) ',(produce-name n
)))))))
96 (define-expose-letter-keys)
99 (defun expose-draw-letter ()
100 (loop for lwin in
*expose-windows-list
* do
101 (xlib:draw-glyphs
(first lwin
) (second lwin
)
102 (xlib:max-char-width
*expose-font
*)
103 (+ (xlib:font-ascent
*expose-font
*) (xlib:font-descent
*expose-font
*))
106 (defun expose-create-window (child n
)
107 (let* ((*current-child
* child
)
108 (string (format nil
"~A~A" (number->char n
)
109 (if *expose-show-window-title
*
110 (format nil
" - ~A" (ensure-printable (child-fullname child
)))
112 (width (if *expose-show-window-title
*
113 (min (* (xlib:max-char-width
*expose-font
*) (+ (length string
) 2))
114 (- (child-width child
) 4))
115 (* (xlib:max-char-width
*expose-font
*) 3)))
116 (height (* (xlib:font-ascent
*expose-font
*) 2)))
117 (with-placement (*expose-mode-placement
* x y width height
)
118 (let* ((window (xlib:create-window
:parent
*root
*
120 :width width
:height height
121 :background
(get-color *expose-background
*)
123 :border
(get-color *expose-border
*)
124 :colormap
(xlib:screen-default-colormap
*screen
*)
125 :event-mask
'(:exposure
:key-press
)))
126 (gc (xlib:create-gcontext
:drawable window
127 :foreground
(get-color *expose-foreground
*)
128 :background
(get-color *expose-background
*)
130 :line-style
:solid
)))
132 (push (list window gc string
) *expose-windows-list
*)))))
136 (defun expose-mode-display-accel-windows ()
138 (with-all-children-reversed (*current-root
* child
)
140 (expose-create-window child
(incf n
)))))
141 (setf *expose-windows-list
* (nreverse *expose-windows-list
*))
142 (expose-draw-letter))
145 (defun expose-windows-generic (first-restore-frame &optional body body-escape
)
146 (setf *expose-font
* (xlib:open-font
*display
* *expose-font-string
*)
147 *expose-windows-list
* nil
)
148 (xlib:warp-pointer
*root
* (truncate (/ (xlib:screen-width
*screen
*) 2))
149 (truncate (/ (xlib:screen-height
*screen
*) 2)))
150 (with-all-frames (first-restore-frame frame
)
151 (setf (frame-data-slot frame
:old-layout
) (frame-layout frame
)
152 (frame-layout frame
) #'tile-space-layout
))
153 (show-all-children *current-root
*)
154 (expose-mode-display-accel-windows)
155 (let ((grab-keyboard-p (xgrab-keyboard-p))
156 (grab-pointer-p (xgrab-pointer-p)))
157 (xgrab-pointer *root
* 92 93)
158 (unless grab-keyboard-p
160 (xgrab-keyboard *root
*))
161 (if (generic-mode 'expose-mode
'exit-expose-loop
162 :original-mode
'(main-mode))
163 (multiple-value-bind (x y
) (xlib:query-pointer
*root
*)
164 (let* ((child (find-child-under-mouse x y
))
165 (parent (find-parent-frame child
*root-frame
*)))
166 (when (and child parent
)
167 (pfuncall body parent
)
168 (focus-all-children child parent
))))
169 (pfuncall body-escape
))
170 (dolist (lwin *expose-windows-list
*)
172 (xlib:destroy-window it
))
174 (xlib:free-gcontext it
)))
176 (xlib:close-font
*expose-font
*))
177 (setf *expose-windows-list
* nil
)
178 (with-all-frames (first-restore-frame frame
)
179 (setf (frame-layout frame
) (frame-data-slot frame
:old-layout
)
180 (frame-data-slot frame
:old-layout
) nil
))
181 (show-all-children *current-root
*)
182 (unless grab-keyboard-p
186 (xgrab-pointer *root
* 66 67)
191 (defun expose-windows-mode ()
192 "Present all windows in the current frame (An expose like)"
194 (expose-windows-generic *current-root
*))
196 (defun expose-all-windows-mode ()
197 "Present all windows in all frames (An expose like)"
199 (let ((orig-root *current-root
*))
200 (switch-to-root-frame :show-later t
)
201 (expose-windows-generic *root-frame
*
203 (hide-all-children *root-frame
*)
204 (setf *current-root
* parent
))
206 (hide-all-children *current-root
*)
207 (setf *current-root
* orig-root
)))))