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

« back to all changes in this revision

Viewing changes to lisp/sawfish/wm/viewport.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
;; viewport.jl -- virtual desktops
 
2
;; $Id: viewport.jl,v 1.42 2001/12/05 01:04:52 federico Exp $
 
3
 
 
4
;; Copyright (C) 1999 John Harper <john@dcs.warwick.ac.uk>
 
5
 
 
6
;; This file is part of sawmill.
 
7
 
 
8
;; sawmill is free software; you can redistribute it and/or modify it
 
9
;; under the terms of the GNU General Public License as published by
 
10
;; the Free Software Foundation; either version 2, or (at your option)
 
11
;; any later version.
 
12
 
 
13
;; sawmill is distributed in the hope that it will be useful, but
 
14
;; WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
;; GNU General Public License for more details.
 
17
 
 
18
;; You should have received a copy of the GNU General Public License
 
19
;; along with sawmill; see the file COPYING.  If not, write to
 
20
;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
21
 
 
22
(define-structure sawfish.wm.viewport
 
23
 
 
24
    (export set-viewport
 
25
            screen-viewport
 
26
            set-screen-viewport
 
27
            select-workspace-and-viewport
 
28
            move-viewport
 
29
            move-viewport-to-window
 
30
            window-outside-workspace-p
 
31
            window-outside-viewport-p
 
32
            move-window-to-current-viewport
 
33
            set-window-viewport
 
34
            move-window-viewport
 
35
            window-viewport
 
36
            window-absolute-position)
 
37
 
 
38
    (open rep
 
39
          rep.system
 
40
          sawfish.wm.windows
 
41
          sawfish.wm.misc
 
42
          sawfish.wm.events
 
43
          sawfish.wm.commands
 
44
          sawfish.wm.workspace
 
45
          sawfish.wm.custom
 
46
          sawfish.wm.session.init)
 
47
 
 
48
  ;; Virtual workspaces are implemented by moving windows in and out of
 
49
  ;; the screen dimensions. E.g. moving to the left moves all windows one
 
50
  ;; screen-width to the right. 
 
51
 
 
52
  (defvar viewport-dimensions '(1 . 1)
 
53
    "Size of each virtual workspace.")
 
54
 
 
55
  (defcustom uniconify-to-current-viewport t
 
56
    "Windows uniconify to the current viewport."
 
57
    :type boolean
 
58
    :group (min-max iconify))
 
59
 
 
60
 
 
61
;;; raw viewport handling
 
62
 
 
63
  (defvar viewport-x-offset 0)
 
64
  (defvar viewport-y-offset 0)
 
65
 
 
66
  (define (set-viewport x y)
 
67
    ;; move W to its new position
 
68
    (define (move-window w)
 
69
      (unless (window-get w 'sticky-viewport)
 
70
        (let ((pos (window-position w)))
 
71
          (move-window-to w (- (+ (car pos) viewport-x-offset) x)
 
72
                          (- (+ (cdr pos) viewport-y-offset) y)))))
 
73
 
 
74
    (unless (and (= viewport-x-offset x) (= viewport-y-offset y))
 
75
      (let loop ((rest (stacking-order))
 
76
                 (inside '())
 
77
                 (outside '()))
 
78
        (cond ((null rest)
 
79
               (with-server-grabbed
 
80
                ;; First move all windows not on the old viewport, and
 
81
                ;; move in top-to-bottom order..
 
82
                (mapc move-window (nreverse outside))
 
83
                ;; ..then move away the windows on the old viewport,
 
84
                ;; in bottom-to-top order
 
85
                (mapc move-window inside)))
 
86
 
 
87
              ((window-outside-viewport-p (car rest))
 
88
               (loop (cdr rest) inside (cons (car rest) outside)))
 
89
 
 
90
              (t (loop (cdr rest) (cons (car rest) inside) outside))))
 
91
 
 
92
      (setq viewport-x-offset x)
 
93
      (setq viewport-y-offset y)
 
94
      (call-hook 'viewport-moved-hook)))
 
95
 
 
96
  (define (viewport-before-exiting)
 
97
    (set-screen-viewport 0 0))
 
98
 
 
99
  (add-hook 'before-exit-hook viewport-before-exiting t)
 
100
 
 
101
 
 
102
;; screen sized viewport handling
 
103
 
 
104
  (define (screen-viewport)
 
105
    (cons (quotient viewport-x-offset (screen-width))
 
106
          (quotient viewport-y-offset (screen-height))))
 
107
 
 
108
  ;; returns t if it actually moved the viewport
 
109
  (define (set-screen-viewport col row)
 
110
    (when (and (>= col 0) (< col (car viewport-dimensions))
 
111
               (>= row 0) (< row (cdr viewport-dimensions)))
 
112
      (set-viewport (* col (screen-width))
 
113
                    (* row (screen-height)))
 
114
      t))
 
115
 
 
116
  (define (select-workspace-and-viewport space col row)
 
117
    (select-workspace space nil (lambda ()
 
118
                                  (set-screen-viewport col row))))
 
119
  
 
120
  ;; returns t if it actually moved the viewport
 
121
  (define (move-viewport right down)
 
122
    (let ((port (screen-viewport)))
 
123
      (set-screen-viewport (+ (car port) right)
 
124
                           (+ (cdr port) down))))
 
125
 
 
126
  (define (move-viewport-to-window window)
 
127
    (when (window-outside-viewport-p window)
 
128
      (let ((pos (window-position window)))
 
129
        (rplaca pos (+ (car pos) viewport-x-offset))
 
130
        (rplacd pos (+ (cdr pos) viewport-y-offset))
 
131
        (set-screen-viewport (quotient (car pos) (screen-width))
 
132
                             (quotient (cdr pos) (screen-height))))))
 
133
 
 
134
  (define (window-outside-workspace-p window)
 
135
    (let ((pos (window-position window))
 
136
          (dims (window-frame-dimensions window))
 
137
          (left (- viewport-x-offset))
 
138
          (right (- (* (car viewport-dimensions) (screen-width))
 
139
                    viewport-x-offset))
 
140
          (top (- viewport-y-offset))
 
141
          (bottom (- (* (cdr viewport-dimensions) (screen-height))
 
142
                     viewport-y-offset)))
 
143
      (or (>= (car pos) right)
 
144
          (>= (cdr pos) bottom)
 
145
          (<= (+ (car pos) (car dims)) left)
 
146
          (<= (+ (cdr pos) (cdr dims)) top))))
 
147
 
 
148
  (define (window-outside-viewport-p window)
 
149
    (let ((pos (window-position window))
 
150
          (dims (window-frame-dimensions window)))
 
151
      (or (<= (+ (car pos) (car dims)) 0)
 
152
          (<= (+ (cdr pos) (cdr dims)) 0)
 
153
          (>= (car pos) (screen-width))
 
154
          (>= (cdr pos) (screen-height)))))
 
155
 
 
156
  (define (move-window-to-current-viewport window)
 
157
    (when (and (window-outside-viewport-p window)
 
158
               (not (window-get window 'sticky-viewport)))
 
159
      (let ((pos (window-position window)))
 
160
        (move-window-to window (mod (car pos) (screen-width))
 
161
                        (mod (cdr pos) (screen-height))))))
 
162
 
 
163
  (define (set-window-viewport window col row)
 
164
    (unless (window-get window 'sticky-viewport)
 
165
      (let ((pos (window-position window)))
 
166
        (setq col (max 0 (min (1- (car viewport-dimensions)) col)))
 
167
        (setq row (max 0 (min (1- (cdr viewport-dimensions)) row)))
 
168
        (setq col (+ (* col (screen-width)) (mod (car pos) (screen-width))))
 
169
        (setq row (+ (* row (screen-height)) (mod (cdr pos) (screen-height))))
 
170
        (move-window-to
 
171
         window (- col viewport-x-offset) (- row viewport-y-offset)))))
 
172
 
 
173
  (define (move-window-viewport window col row)
 
174
    (let ((pos (window-position window)))
 
175
      (set-window-viewport window
 
176
                           (+ (quotient (+ (car pos) viewport-x-offset)
 
177
                                        (screen-width)) col)
 
178
                           (+ (quotient (+ (cdr pos) viewport-y-offset)
 
179
                                        (screen-height)) row))))
 
180
 
 
181
  (define (window-viewport w)
 
182
    (let ((position (window-position w)))
 
183
      (cons (quotient (+ (car position) viewport-x-offset) (screen-width))
 
184
            (quotient (+ (cdr position) viewport-y-offset) (screen-height)))))
 
185
 
 
186
  (define (window-absolute-position w)
 
187
    (let ((position (window-position w)))
 
188
      (if (window-outside-viewport-p w)
 
189
          (cons (mod (+ (car position) viewport-x-offset) (screen-width))
 
190
                (mod (+ (cdr position) viewport-y-offset) (screen-height)))
 
191
        position)))
 
192
 
 
193
  (define (viewport-size-changed)
 
194
    (let ((port (screen-viewport)))
 
195
      (set-screen-viewport (min (car port) (1- (car viewport-dimensions)))
 
196
                           (min (cdr port) (1- (cdr viewport-dimensions))))
 
197
      (map-windows (lambda (w)
 
198
                     (when (window-outside-workspace-p w)
 
199
                       (move-window-to-current-viewport w))))
 
200
      (call-hook 'viewport-resized-hook)))
 
201
 
 
202
 
 
203
;; commands
 
204
 
 
205
  (define (activate-viewport x y)
 
206
    "Select the specified viewport."
 
207
    (set-screen-viewport (1- x) (1- y)))
 
208
 
 
209
  (define-command 'activate-viewport activate-viewport
 
210
    #:spec "NX:\nNY:"
 
211
    #:type `(and (labelled ,(_ "Column:") (number 1))
 
212
                 (labelled ,(_ "Row:") (number 1))))
 
213
 
 
214
  (define (activate-viewport-column x)
 
215
    "Select the specified viewport column."
 
216
    (set-screen-viewport (1- x) (cdr (screen-viewport))))
 
217
 
 
218
  (define-command 'activate-viewport-column activate-viewport-column
 
219
    #:spec "NX:"
 
220
    #:type `(and (labelled ,(_ "Column:") (number 1))))
 
221
 
 
222
  (define (activate-viewport-row y)
 
223
    "Select the specified viewport row."
 
224
    (set-screen-viewport (car (screen-viewport)) (1- y)))
 
225
 
 
226
  (define-command 'activate-viewport-row activate-viewport-row
 
227
    #:spec "NY:"
 
228
    #:type `(and (labelled ,(_ "Row:") (number 1))))
 
229
 
 
230
  (define (move-window-to-viewport x y)
 
231
    "Move the current window to the specified viewport."
 
232
    (move-window-viewport (current-event-window) (1- x) (1- y)))
 
233
 
 
234
  (define-command 'move-window-to-viewport move-window-to-viewport
 
235
    #:spec "NX:\nNY:"
 
236
    #:type '(and (labelled "X:" (number 1)) (labelled "Y:" (number 1))))
 
237
 
 
238
  (define (move-viewport-right)
 
239
    "Move the viewport one screen to the right."
 
240
    (move-viewport 1 0))
 
241
 
 
242
  (define (move-viewport-left)
 
243
    "Move the viewport one screen to the left."
 
244
    (move-viewport -1 0))
 
245
 
 
246
  (define (move-viewport-down)
 
247
    "Move the viewport one screen down."
 
248
    (move-viewport 0 1))
 
249
 
 
250
  (define (move-viewport-up)
 
251
    "Move the viewport one screen up."
 
252
    (move-viewport 0 -1))
 
253
 
 
254
  ;; Moves the window by the specified offsets and then flips to the
 
255
  ;; viewport that is relative those offsets to the current viewport.
 
256
  (define (move-window-to-viewport-and-move-viewport window col row)
 
257
    (require 'sawfish.wm.util.stacking)
 
258
    (let ((sticky-viewport (window-get window 'sticky-viewport)))
 
259
      (window-put window 'sticky-viewport t)
 
260
      (with-server-grabbed
 
261
       (raise-window* window)
 
262
       (move-viewport col row))
 
263
      (unless sticky-viewport
 
264
        (window-put window 'sticky-viewport nil))))
 
265
 
 
266
  (define (move-window-left w)
 
267
    "Move the window to the viewport on the left, and switch to that viewport."
 
268
    (move-window-to-viewport-and-move-viewport w -1 0))
 
269
 
 
270
  (define (move-window-right w)
 
271
    "Move the window to the viewport on the right, and switch to that viewport."
 
272
    (move-window-to-viewport-and-move-viewport w 1 0))
 
273
 
 
274
  (define (move-window-down w)
 
275
    "Move the window to the viewport below, and switch to that viewport."
 
276
    (move-window-to-viewport-and-move-viewport w 0 1))
 
277
 
 
278
  (define (move-window-up w)
 
279
    "Move the window to the viewport above, and switch to that viewport."
 
280
    (move-window-to-viewport-and-move-viewport w 0 -1))
 
281
 
 
282
  (define-command 'move-viewport-right move-viewport-right)
 
283
  (define-command 'move-viewport-left move-viewport-left)
 
284
  (define-command 'move-viewport-up move-viewport-up)
 
285
  (define-command 'move-viewport-down move-viewport-down)
 
286
  (define-command 'move-window-right move-window-right #:spec "%W")
 
287
  (define-command 'move-window-left move-window-left #:spec "%W")
 
288
  (define-command 'move-window-up move-window-up #:spec "%W")
 
289
  (define-command 'move-window-down move-window-down #:spec "%W")
 
290
 
 
291
 
 
292
;;; session management, config
 
293
 
 
294
  (define (viewport-saved-state w)
 
295
    (let ((position (window-position w)))
 
296
      (when (window-get w 'sticky-viewport)
 
297
        (rplaca position (mod (car position) (screen-width)))
 
298
        (rplacd position (mod (cdr position) (screen-height))))
 
299
      `((position . ,(window-absolute-position w))
 
300
        (viewport . ,(window-viewport w)))))
 
301
 
 
302
  (define (viewport-load-state w alist)
 
303
    (let ((position (cdr (assq 'position alist)))
 
304
          (viewport (cdr (assq 'viewport alist))))
 
305
      (when position
 
306
        (if (or (not viewport) (window-get w 'sticky-viewport))
 
307
            (move-window-to w (car position) (cdr position))
 
308
          (move-window-to w (+ (* (car viewport) (screen-width))
 
309
                               (car position))
 
310
                          (+ (* (cdr viewport) (screen-height))
 
311
                             (cdr position)))
 
312
          (when (window-outside-workspace-p w)
 
313
            (move-window-to-current-viewport w)))
 
314
        (window-put w 'placed t))))
 
315
                             
 
316
  (sm-add-saved-properties 'sticky-viewport)
 
317
  (add-hook 'sm-window-save-functions viewport-saved-state)
 
318
  (add-hook 'sm-restore-window-hook viewport-load-state)
 
319
 
 
320
  (define (viewport-window-uniconified w)
 
321
    (when uniconify-to-current-viewport
 
322
      (move-window-to-current-viewport w)))
 
323
 
 
324
  (add-hook 'workspace-geometry-changed
 
325
            (lambda ()
 
326
              (setq viewport-dimensions (cdr workspace-geometry))
 
327
              (viewport-size-changed)))
 
328
 
 
329
  (add-hook 'uniconify-window-hook viewport-window-uniconified))