~ubuntu-branches/ubuntu/lucid/sawfish/lucid-updates

« back to all changes in this revision

Viewing changes to lisp/sawfish/wm/commands/grow-pack.jl

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2002-01-20 17:42:28 UTC
  • Revision ID: james.westby@ubuntu.com-20020120174228-4q1ydztbkvfq1ht2
Tags: upstream-1.0.1.20020116
ImportĀ upstreamĀ versionĀ 1.0.1.20020116

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
;; grow-pack.jl -- window resize and movement
 
2
;; $Id: grow-pack.jl,v 1.12 2001/03/09 20:06:05 jsh Exp $
 
3
;; Id: grow-pack.jl,v 1.9 2000/08/04 16:42:43 grossjoh Exp 
 
4
 
 
5
;; Copyright (C) 2000 Kai Grossjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE>
 
6
 
 
7
;; This file is free software; you can redistribute it and/or modify it
 
8
;; under the terms of the GNU General Public License as published by
 
9
;; the Free Software Foundation; either version 2, or (at your option)
 
10
;; any later version.
 
11
 
 
12
;; sawmill is distributed in the hope that it will be useful, but
 
13
;; WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
;; GNU General Public License for more details.
 
16
 
 
17
;; You should have received a copy of the GNU General Public License
 
18
;; along with sawmill; see the file COPYING.  If not, write to
 
19
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
20
 
 
21
;;; Commentary:
 
22
 
 
23
;; This package provides functions to `grow' or `pack' a window in
 
24
;; four directions.  `Growing' means to grow the window in the
 
25
;; indicated direction until it `bumps into' another window.
 
26
;; `Packing' means to move the window in the indicated direction until
 
27
;; it `bumps into' another window.
 
28
 
 
29
;; Copy this file into a directory which is on your load-path, then
 
30
;; use it.  I installed this package by placing the following into my
 
31
;; ~/.sawmillrc:
 
32
;;
 
33
;; (require 'grow-pack)
 
34
;; (require 'menus)
 
35
;; (setq window-ops-menu
 
36
;;       (append window-ops-menu
 
37
;;               (list (cons "Grow/pack" grow-pack-menu))))
 
38
 
 
39
(define-structure sawfish.wm.commands.grow-pack ()
 
40
 
 
41
    (open rep
 
42
          sawfish.wm.windows
 
43
          sawfish.wm.events
 
44
          sawfish.wm.misc
 
45
          sawfish.wm.util.rects
 
46
          sawfish.wm.state.maximize
 
47
          sawfish.wm.state.iconify
 
48
          sawfish.wm.custom
 
49
          sawfish.wm.commands
 
50
          sawfish.wm.workspace
 
51
          sawfish.wm.util.stacking)
 
52
 
 
53
  (define-structure-alias grow-pack sawfish.wm.commands.grow-pack)
 
54
 
 
55
;;; Code:
 
56
 
 
57
  (defcustom grow-window-repeat t
 
58
    "Whether growing an already grown window grows it again."
 
59
    :type boolean
 
60
    :group (min-max maximize))
 
61
 
 
62
  (defcustom grow-is-maximize t
 
63
    "Whether growing is considered to be maximization.  When you turn
 
64
this on, you can use `unmaximize-window' or something similar to get
 
65
back to the original size."
 
66
    :type boolean
 
67
    :group (min-max maximize))
 
68
 
 
69
  (defcustom pack-warp-pointer 'maybe
 
70
    "Whether and how to move the pointer when packing windows.
 
71
 
 
72
`maybe' means that the pointer is moved along with the window, if the
 
73
pointer was within the window area before packing.
 
74
 
 
75
`always' warps the pointer to the center of the window if it isn't
 
76
already in the window, then does like `maybe'.
 
77
 
 
78
`never' means not to warp the pointer."
 
79
    :type (choice maybe always never)
 
80
    :group (move))
 
81
 
 
82
  ;; Entry points.
 
83
 
 
84
  (defun grow-window-left (w)
 
85
    "Grows window to the left until it `bumps into' another window."
 
86
    (grow-window w 'left))
 
87
 
 
88
  (defun grow-window-right (w)
 
89
    "Grows window to the right until it `bumps into' another window."
 
90
    (grow-window w 'right))
 
91
 
 
92
  (defun grow-window-up (w)
 
93
    "Grows window upwards until it `bumps into' another window."
 
94
    (grow-window w 'up))
 
95
 
 
96
  (defun grow-window-down (w)
 
97
    "Grows window downwards until it `bumps into' another window."
 
98
    (grow-window w 'down))
 
99
 
 
100
  (defun pack-window-left (w)
 
101
    "Moves window to the left until it `bumps into' another window."
 
102
    (pack-window w 'left))
 
103
 
 
104
  (defun pack-window-right (w)
 
105
    "Moves window to the right until it `bumps into' another window."
 
106
    (pack-window w 'right))
 
107
 
 
108
  (defun pack-window-up (w)
 
109
    "Moves window upwards until it `bumps into' another window."
 
110
    (pack-window w 'up))
 
111
 
 
112
  (defun pack-window-down (w)
 
113
    "Moves window downwards until it `bumps into' another window."
 
114
    (pack-window w 'down))
 
115
 
 
116
  ;; Command defs
 
117
 
 
118
  ;;###autoload
 
119
  (define-command 'grow-window-left grow-window-left #:spec "%W")
 
120
  (define-command 'grow-window-right grow-window-right #:spec "%W")
 
121
  (define-command 'grow-window-up grow-window-up #:spec "%W")
 
122
  (define-command 'grow-window-down grow-window-down #:spec "%W")
 
123
  (define-command 'pack-window-left pack-window-left #:spec "%W")
 
124
  (define-command 'pack-window-right pack-window-right #:spec "%W")
 
125
  (define-command 'pack-window-up pack-window-up #:spec "%W")
 
126
  (define-command 'pack-window-down pack-window-down #:spec "%W")
 
127
 
 
128
  ;; Convenience variable.
 
129
 
 
130
  (defvar grow-pack-menu
 
131
    '(("Grow left" grow-window-left)
 
132
      ("Grow right" grow-window-right)
 
133
      ("Grow up" grow-window-up)
 
134
      ("Grow down" grow-window-down)
 
135
      ("Pack left" pack-window-left)
 
136
      ("Pack right" pack-window-right)
 
137
      ("Pack up" pack-window-up)
 
138
      ("Pack down" pack-window-down))
 
139
    "Menu of grow and pack operations.")
 
140
 
 
141
  ;; Implementation part.
 
142
 
 
143
  (defun gp-avoid-windows (w direction)
 
144
    "Returns list of windows to avoid when growing/filling window W in DIRECTION."
 
145
    (let* ((wpos    (window-position w))
 
146
           (wdim    (window-frame-dimensions w))
 
147
           (wleft   (car wpos))
 
148
           (wtop    (cdr wpos))
 
149
           (wright  (+ wleft (car wdim)))
 
150
           (wbottom (+ wtop (cdr wdim)))
 
151
           (nleft   wleft)
 
152
           (ntop    wtop)
 
153
           (nright  wright)
 
154
           (nbottom wbottom)
 
155
           (szhints (window-size-hints w))
 
156
           (winc    (or (cdr (assq 'width-inc szhints)) 1))
 
157
           (hinc    (or (cdr (assq 'height-inc szhints)) 1)))
 
158
      (when (eq direction 'left)
 
159
        (setq nleft 0)
 
160
        (when grow-window-repeat
 
161
          (setq wleft (max (- wleft winc) 0))))
 
162
      (when (eq direction 'right)
 
163
        (setq nright (screen-width))
 
164
        (when grow-window-repeat
 
165
          (setq wright (min (+ wright winc) (screen-width)))))
 
166
      (when (eq direction 'up)
 
167
        (setq ntop 0)
 
168
        (when grow-window-repeat
 
169
          (setq wtop (max (- wtop hinc) 0))))
 
170
      (when (eq direction 'down)
 
171
        (setq nbottom (screen-height))
 
172
        (when grow-window-repeat
 
173
          (setq wbottom (min (+ wbottom hinc) (screen-height)))))
 
174
      (filter-windows
 
175
       (lambda (x)
 
176
         (let* ((xpos (window-position x))
 
177
                (xdim (window-frame-dimensions x))
 
178
                (xleft (car xpos))
 
179
                (xtop (cdr xpos))
 
180
                (xright (+ xleft (car xdim)))
 
181
                (xbottom (+ xtop (cdr xdim))))
 
182
           ;; If window does not overlap W but does overlap the
 
183
           ;; larger W, then we need to avoid this window.
 
184
           (and (window-mapped-p x)
 
185
                (not (window-iconified-p x))
 
186
                (window-appears-in-workspace-p x current-workspace)
 
187
                (<= (rect-2d-overlap* (list xleft xtop xright xbottom)
 
188
                                      (list wleft wtop wright wbottom)) 0)
 
189
                (> (rect-2d-overlap* (list xleft xtop xright xbottom)
 
190
                                     (list nleft ntop nright nbottom)) 0)))))))
 
191
 
 
192
  (defun gp-surrounding-rect (wlist)
 
193
    "Returns the rectangle surrounding all given windows."
 
194
    (if wlist
 
195
        (let* ((w (car wlist))
 
196
               (wrest (cdr wlist))
 
197
               (wpos (window-position w))
 
198
               (wdim (window-frame-dimensions w))
 
199
               (rleft (car wpos))
 
200
               (rtop  (cdr wpos))
 
201
               (rright (+ rleft (car wdim)))
 
202
               (rbottom (+ rtop (cdr wdim))))
 
203
          (mapcar
 
204
           (lambda (x)
 
205
             (let* ((xpos (window-position x))
 
206
                    (xdim (window-frame-dimensions x))
 
207
                    (xleft (car xpos))
 
208
                    (xtop  (cdr xpos))
 
209
                    (xright (+ xleft (car xdim)))
 
210
                    (xbottom (+ xtop (cdr xdim))))
 
211
               (when (< xleft rleft) (setq rleft xleft))
 
212
               (when (< xtop  rtop) (setq rtop xtop))
 
213
               (when (> xright rright) (setq rright xright))
 
214
               (when (> xbottom rbottom) (setq rbottom xbottom))))
 
215
           wrest)
 
216
          (list rleft rtop rright rbottom))
 
217
      (list (screen-width) (screen-height) 0 0)))
 
218
 
 
219
  (defun grow-window (w direction)
 
220
    "Grows window W in DIRECTION."
 
221
    (let* ((avoid-wins (gp-avoid-windows w direction))
 
222
           (surround   (gp-surrounding-rect avoid-wins))
 
223
           (wpos       (window-position w))
 
224
           (wdim       (window-dimensions w))
 
225
           (fdim       (window-frame-dimensions w))
 
226
           (wleft      (car wpos))
 
227
           (wtop       (cdr wpos))
 
228
           (wwidth     (car wdim))
 
229
           (wheight    (cdr wdim))
 
230
           (nwidth     wwidth)
 
231
           (nheight    wheight)
 
232
           (sleft      (nth 0 surround))
 
233
           (stop       (nth 1 surround))
 
234
           (sright     (nth 2 surround))
 
235
           (sbottom    (nth 3 surround)))
 
236
      (when (eq direction 'left)
 
237
        (setq nwidth (- (+ wleft wwidth) sright)))
 
238
      (when (eq direction 'up)
 
239
        (setq nheight (- (+ wtop wheight) sbottom)))
 
240
      (when (eq direction 'right)
 
241
        (setq nwidth (- sleft wleft (- (car fdim) wwidth))))
 
242
      (when (eq direction 'down)
 
243
        (setq nheight (- stop wtop (- (cdr fdim) wheight))))
 
244
      (let
 
245
          ((tem (cons nwidth nheight)))
 
246
        (maximize-truncate-dims w tem)  ;truncate to column/row increments
 
247
        (setq nwidth (car tem))
 
248
        (setq nheight (cdr tem)))
 
249
      (when (eq direction 'left)
 
250
        (setq wleft (- wleft (- nwidth wwidth))))
 
251
      (when (eq direction 'up)
 
252
        (setq wtop (- wtop (- nheight wheight))))
 
253
      (when grow-is-maximize
 
254
        (unless (window-get w 'unmaximized-geometry)
 
255
          (window-put w 'unmaximized-geometry (list (car wpos) (cdr wpos)
 
256
                                                    (car wdim) (cdr wdim))))
 
257
        (if (memq direction '(left right))
 
258
            (window-put w 'maximized-horizontally t)
 
259
          (window-put w 'maximzed-vertically t)))
 
260
      (move-resize-window-to w wleft wtop nwidth nheight)
 
261
      (when maximize-raises (raise-window* w))
 
262
      (when grow-is-maximize
 
263
        (call-window-hook 'window-maximized-hook w
 
264
                          (list (if (member direction '(left right))
 
265
                                    'horizontal 'vertical)))
 
266
        (call-window-hook 'window-state-change-hook w (list '(maximized))))))
 
267
 
 
268
  (defun pack-window (w direction)
 
269
    (let* ((avoid-wins (gp-avoid-windows w direction))
 
270
           (surround   (gp-surrounding-rect avoid-wins))
 
271
           (wpos       (window-position w))
 
272
           (wdim       (window-frame-dimensions w))
 
273
           (wleft      (car wpos))
 
274
           (wtop       (cdr wpos))
 
275
           (wwidth     (car wdim))
 
276
           (wheight    (cdr wdim))
 
277
           (sleft      (nth 0 surround))
 
278
           (stop       (nth 1 surround))
 
279
           (sright     (nth 2 surround))
 
280
           (sbottom    (nth 3 surround))
 
281
           (wpointer   (query-pointer-window))
 
282
           (xpointer   (car (query-pointer)))
 
283
           (ypointer   (cdr (query-pointer)))
 
284
           (xoffset    (- xpointer wleft))
 
285
           (yoffset    (- ypointer wtop)))
 
286
      (when (eq direction 'left) (setq wleft sright))
 
287
      (when (eq direction 'up) (setq wtop sbottom))
 
288
      (when (eq direction 'right) (setq wleft (- sleft wwidth)))
 
289
      (when (eq direction 'down) (setq wtop (- stop wheight)))
 
290
      (move-window-to w wleft wtop)
 
291
      (cond ((eq pack-warp-pointer 'always)
 
292
             (warp-cursor-to-window w))
 
293
            ((eq pack-warp-pointer 'maybe)
 
294
             (when (equal wpointer w)
 
295
               (warp-cursor (+ wleft xoffset) (+ wtop yoffset)))))
 
296
      (call-window-hook 'after-move-hook w
 
297
                        (list (list (if (memq direction '(left right))
 
298
                                        'horizontal 'vertical)))))))
 
299
;; grow-pack.jl ends here.