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

« back to all changes in this revision

Viewing changes to lisp/sawfish/wm/state/wm-spec.jl

  • Committer: Bazaar Package Importer
  • Author(s): Christian Marillat
  • Date: 2005-02-23 16:16:46 UTC
  • mfrom: (1.2.1 upstream) (2.1.2 hoary)
  • Revision ID: james.westby@ubuntu.com-20050223161646-4id6qyw4h9lkvb0v
Tags: 1:1.3+cvs20050222-1
* New cvs release.
* Add an emacs initialisation script to load sawfish.el (Closes: #295290)
* Updated sawfish.el to 1.32

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
;; wm-spec.jl -- implement the new (GNOME/KDE) wm hints spec
2
2
 
3
 
;; $Id: wm-spec.jl,v 1.27 2001/12/09 22:44:22 jsh Exp $
 
3
;; $Id: wm-spec.jl,v 1.48 2003/11/25 04:01:15 jsh Exp $
4
4
 
5
5
;; Copyright (C) 1999, 2000 John Harper <john@dcs.warwick.ac.uk>
6
6
 
28
28
    (open rep
29
29
          rep.system
30
30
          sawfish.wm.misc
 
31
          sawfish.wm.events
31
32
          sawfish.wm.windows
32
33
          sawfish.wm.workspace
33
34
          sawfish.wm.viewport
34
 
          sawfish.wm.state.maximize
35
 
          sawfish.wm.state.iconify)
 
35
          sawfish.wm.state.iconify
 
36
          sawfish.wm.util.workarea)
36
37
 
37
38
  ;; todo:
38
39
 
39
 
  ;; - _NET_WORKAREA
40
 
  ;; - _NET_WM_NAME             -- needs to be in C code?
41
 
  ;; - _NET_WM_STRUT
42
40
  ;; - _NET_WM_ICON
43
41
 
 
42
  ;; 1.1 additions:
 
43
  ;;  - _NET_WM_ALLOWED_ACTIONS
 
44
  ;;  - _STATE_HIDDEN?
 
45
  ;;  - _NET_WM_MOVERESIZE changes
 
46
  ;;  - _NET_SHOWING_DESKTOP?
 
47
  ;;  - _NET_MOVERESIZE_WINDOW
 
48
 
44
49
  ;; maybe add some state extensions for things the spec doesn't
45
50
  ;; cover but existed in the old GNOME spec; e.g. _GNOME_WM_STATE_FOO
46
51
  ;; for FOO being DO_NOT_COVER, SKIP_FOCUS, ..?
57
62
  (defconst _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT 6)
58
63
  (defconst _NET_WM_MOVERESIZE_SIZE_LEFT 7)
59
64
  (defconst _NET_WM_MOVERESIZE_MOVE 8)
 
65
  (defconst _NET_WM_MOVERESIZE_SIZE_KEYBOARD 9)
 
66
  (defconst _NET_WM_MOVERESIZE_MOVE_KEYBOARD 10)
60
67
 
61
68
  (defconst _NET_WM_STATE_REMOVE 0)
62
69
  (defconst _NET_WM_STATE_ADD 1)
64
71
 
65
72
  (define wm-spec-window-id nil)
66
73
 
67
 
  (define supported-protocols
68
 
    [_NET_CLIENT_LIST _NET_CLIENT_LIST_STACKING _NET_NUMBER_OF_DESKTOPS
69
 
     _NET_DESKTOP_GEOMETRY _NET_DESKTOP_VIEWPORT _NET_CURRENT_DESKTOP
70
 
     _NET_DESKTOP_NAMES _NET_ACTIVE_WINDOW _NET_CLOSE_WINDOW
71
 
     _NET_WM_MOVERESIZE _NET_WM_DESKTOP _NET_WM_WINDOW_TYPE _NET_WM_STATE])
 
74
  (define supported-atoms
 
75
    [_NET_ACTIVE_WINDOW
 
76
     _NET_CLIENT_LIST
 
77
     _NET_CLIENT_LIST_STACKING
 
78
     _NET_CLOSE_WINDOW
 
79
     _NET_CURRENT_DESKTOP
 
80
     _NET_DESKTOP_GEOMETRY
 
81
     _NET_DESKTOP_NAMES
 
82
     _NET_DESKTOP_VIEWPORT
 
83
     _NET_NUMBER_OF_DESKTOPS
 
84
     _NET_PROTOCOLS
 
85
     _NET_SHOWING_DESKTOP
 
86
     _NET_SUPPORTED
 
87
     _NET_SUPPORTING_WM_CHECK
 
88
     _NET_WORKAREA
 
89
     _NET_WM_DESKTOP
 
90
     _NET_WM_ICON_GEOMETRY
 
91
     _NET_WM_MOVERESIZE
 
92
     _NET_WM_MOVERESIZE_MOVE
 
93
     _NET_WM_MOVERESIZE_SIZE_BOTTOM
 
94
     _NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT
 
95
     _NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT
 
96
     _NET_WM_MOVERESIZE_SIZE_LEFT
 
97
     _NET_WM_MOVERESIZE_SIZE_RIGHT
 
98
     _NET_WM_MOVERESIZE_SIZE_TOP
 
99
     _NET_WM_MOVERESIZE_SIZE_TOPLEFT
 
100
     _NET_WM_MOVERESIZE_SIZE_TOPRIGHT
 
101
     _NET_WM_MOVERESIZE_SIZE_KEYBOARD
 
102
     _NET_WM_MOVERESIZE_MOVE_KEYBOARD
 
103
     _NET_WM_PING
 
104
     _NET_WM_STATE
 
105
     _NET_WM_STATE_ABOVE
 
106
     _NET_WM_STATE_ADD
 
107
     _NET_WM_STATE_BELOW
 
108
     _NET_WM_STATE_FULLSCREEN
 
109
     _NET_WM_STATE_MAXIMIZED
 
110
     _NET_WM_STATE_MAXIMIZED_HORZ
 
111
     _NET_WM_STATE_MAXIMIZED_VERT
 
112
     _NET_WM_STATE_REMOVE
 
113
     _NET_WM_STATE_SHADED
 
114
     _NET_WM_STATE_SKIP_PAGER
 
115
     _NET_WM_STATE_SKIP_TASKBAR
 
116
     _NET_WM_STATE_STICKY
 
117
     _NET_WM_STATE_TOGGLE
 
118
     _NET_WM_STRUT
 
119
     _NET_WM_WINDOW_TYPE
 
120
     _NET_WM_WINDOW_TYPE_DESKTOP
 
121
     _NET_WM_WINDOW_TYPE_DIALOG
 
122
     _NET_WM_WINDOW_TYPE_DOCK
 
123
     _NET_WM_WINDOW_TYPE_TOOLBAR
 
124
     _NET_WM_WINDOW_TYPE_MENU
 
125
     _NET_WM_WINDOW_TYPE_UTILITY
 
126
     _NET_WM_WINDOW_TYPE_SPLASH])
72
127
  
73
 
  (defconst desktop-layer -4)
74
 
  (defconst dock-layer +4)
 
128
  (defvar wm-spec-below-depth -2)
 
129
  (defvar wm-spec-above-depth +2)
75
130
 
76
131
  (define supported-states '())
77
132
 
101
156
  (define last-workspace-names nil)
102
157
  (define last-area nil)
103
158
  (define last-area-count nil)
 
159
  (define last-workarea nil)
 
160
  (define last-showing-desktop nil)
 
161
 
 
162
  (define (update-window-workspace-hints w #!key (limits (workspace-limits)))
 
163
    (let ((vec (if (window-sticky-p/workspace w)
 
164
                   (vector #xffffffff)
 
165
                 (let ((space (or (window-get w 'swapped-in)
 
166
                                  (car (window-workspaces w)))))
 
167
                   (and space (vector (- space (car limits))))))))
 
168
      (unless (equal vec (window-get w 'wm-spec/last-workspace))
 
169
        (if vec
 
170
            (set-x-property w '_NET_WM_DESKTOP vec 'CARDINAL 32)
 
171
          (delete-x-property w '_NET_WM_DESTOP))
 
172
        (window-put w 'wm-spec/last-workspace vec))))
104
173
 
105
174
  (define (update-workspace-hints)
106
175
    (let* ((limits (workspace-limits))
107
176
           (port (screen-viewport))
108
177
           (port-size viewport-dimensions)
109
 
           (total-workspaces (1+ (- (cdr limits) (car limits)))))
 
178
           (total-workspaces (1+ (- (cdr limits) (car limits))))
 
179
           (workarea (make-vector (* 4 total-workspaces)))
 
180
           (showing-desktop (showing-desktop-p)))
110
181
 
111
182
      (define (set-ws-hints)
112
183
        ;; _NET_NUMBER_OF_DESKTOPS
119
190
        (unless (equal last-workspace-names workspace-names)
120
191
          (setq last-workspace-names workspace-names)
121
192
          (set-x-text-property 'root '_NET_DESKTOP_NAMES
122
 
                               (apply vector workspace-names)))
 
193
                               (apply vector workspace-names)
 
194
                               'UTF8_STRING))
123
195
 
124
196
        ;; _NET_CURRENT_DESKTOP
125
197
        (unless (equal last-workspace
144
216
                  (set-x-property 'root '_NET_DESKTOP_VIEWPORT
145
217
                                  view 'CARDINAL 32)
146
218
                (aset view (* i 2) (* (car port) (screen-width)))
147
 
                (aset view (1+ (* i 2)) (* (cdr port) (screen-width)))
148
 
                (loop (1+ i)))))))
 
219
                (aset view (1+ (* i 2)) (* (cdr port) (screen-height)))
 
220
                (loop (1+ i))))))
 
221
 
 
222
        ;; _NET_WORKAREA
 
223
        (unless (equal last-workarea workarea)
 
224
          (set-x-property 'root '_NET_WORKAREA workarea 'CARDINAL 32)
 
225
          (setq last-workarea workarea))
 
226
 
 
227
        ;; _NET_SHOWING_DESKTOP
 
228
        (unless (equal showing-desktop last-showing-desktop)
 
229
          (set-x-property 'root '_NET_SHOWING_DESKTOP
 
230
                          (vector (if showing-desktop 1 0)) 'CARDINAL 32)
 
231
          (setq last-showing-desktop showing-desktop)))
149
232
 
150
233
      (define (set-window-hints w)
151
 
        (cond ((window-sticky-p/workspace w)
152
 
               (set-x-property w '_NET_WM_DESKTOP
153
 
                               (vector #xffffffff) 'CARDINAL 32))
154
 
              ((window-get w 'swapped-in)
155
 
               ;; XXX the gnome-wm standard sucks..!
156
 
               (let ((space (window-get w 'swapped-in)))
157
 
                 (set-x-property w '_NET_WM_DESKTOP
158
 
                                 (vector (- space (car limits)))
159
 
                                 'CARDINAL 32)))))
 
234
        (update-window-workspace-hints w #:limits limits))
 
235
 
 
236
      ;; calculate workareas
 
237
      (do ((i 0 (1+ i)))
 
238
          ((= i total-workspaces))
 
239
        (let ((area (calculate-workarea-from-struts
 
240
                     #:workspace (+ i (car limits)))))
 
241
          (aset workarea (+ (* i 4) 0) (nth 0 area))
 
242
          (aset workarea (+ (* i 4) 1) (nth 1 area))
 
243
          (aset workarea (+ (* i 4) 2) (- (nth 2 area) (nth 0 area)))
 
244
          (aset workarea (+ (* i 4) 3) (- (nth 3 area) (nth 1 area)))))
160
245
                 
161
246
      ;; apparently some pagers don't like it if we place windows
162
247
      ;; on (temporarily) non-existent workspaces
184
269
;;; setting the window state hints
185
270
 
186
271
  (define (update-client-state w)
187
 
    (let ((state (filter (lambda (x) (not (supported-state-p x)))
188
 
                         (window-get w 'wm-spec-last-states))))
 
272
    (let ((state '()))
189
273
      (mapc (lambda (x)
190
274
              (when (and (not (pseudo-state-p x))
191
275
                         (call-state-fun w x 'get))
192
276
                (setq state (cons x state))))
193
277
            supported-states)
194
 
      (set-x-property w '_NET_WM_STATE (apply vector state) 'ATOM 32)
195
 
      (window-put w 'wm-spec-last-states state)))
 
278
      (set-x-property w '_NET_WM_STATE (apply vector state) 'ATOM 32)))
196
279
 
197
280
 
198
281
;;; honouring the initially set window state hints
201
284
    (when (>= (length geom) 2)
202
285
      (window-put w 'icon-position (cons (aref geom 0) (aref geom 1)))))
203
286
 
204
 
  (define (wm-class-hacks w)
205
 
    (let ((class (get-x-text-property w 'WM_CLASS)))
206
 
      (when (and class (>= (length class) 2))
207
 
        (cond ((or (and (string= (aref class 1) "Panel")
208
 
                        (string= (aref class 0) "panel_window"))
209
 
                   (and (string= (aref class 1) "kicker")
210
 
                        (string= (aref class 0) "Panel")))
211
 
               (window-put w 'focus-click-through t)
212
 
               (window-put w 'avoid t)
213
 
               (window-put w 'no-history t)
214
 
               (window-put w 'never-iconify t)
215
 
               (window-put w 'never-maximize t)
216
 
               (window-put w 'sticky t)
217
 
               (window-put w 'sticky-viewport t)
218
 
               ;; XXX see gnome.jl for why this is needed..
219
 
               (window-put w 'placed t))
220
 
              ((string= (aref class 1) "gmc-desktop-icon")
221
 
               (window-put w 'never-focus t)
222
 
               (window-put w 'never-iconify t)
223
 
               (window-put w 'never-maximize t))))))
 
287
  (define (update-strut w)
 
288
    (let ((strut (get-x-property w '_NET_WM_STRUT)))
 
289
      (when (and strut (eq (nth 0 strut) 'CARDINAL))
 
290
        (let ((data (nth 2 strut)))
 
291
          (define-window-strut w (aref data 0) (aref data 2)
 
292
                               (aref data 1) (aref data 3))))))
224
293
 
225
294
  (define (honour-client-state w)
226
 
    ;; things the wm-hints doesn't supply
227
 
    (wm-class-hacks w)
228
 
 
229
295
    (let ((space (get-x-property w '_NET_WM_DESKTOP)))
230
296
      (when space
231
297
        (setq space (aref (nth 2 space) 0))
250
316
        (setq state (nth 2 state))
251
317
        (do ((i 0 (1+ i)))
252
318
            ((= i (length state)))
253
 
          (call-state-fun w (aref state i) 'init))
254
 
        (window-put w 'wm-spec-last-states (vector->list state))))
 
319
          (call-state-fun w (aref state i) 'init))))
 
320
 
 
321
    (update-strut w)
255
322
 
256
323
    (let ((geom (get-x-property w '_NET_WM_ICON_GEOMETRY)))
257
324
      (when geom
260
327
 
261
328
;;; helper functions
262
329
 
263
 
  (define (define-wm-spec-window-type x fun) (put x 'wm-spec-type fun))
 
330
  (define (define-wm-spec-window-type x fun)
 
331
    (if (listp x)
 
332
        (mapc (lambda (y) (define-wm-spec-window-type y fun)) x)
 
333
      (put x 'wm-spec-type fun)))
264
334
 
265
335
  (define (define-wm-spec-window-state x fun #!key pseudo)
266
336
    (put x 'wm-spec-state fun)
277
347
      (when fun
278
348
        (fun w mode))))
279
349
 
280
 
  (define-wm-spec-window-type
281
 
   '_NET_WM_WINDOW_TYPE_DESKTOP
282
 
   (lambda (w)
283
 
     (require 'sawfish.wm.stacking)
284
 
     (mark-window-as-desktop w)
285
 
     (window-put w 'fixed-position t)
286
 
     ;; I thought these would be set by the application, but KDE doesn't..
287
 
     (window-put w 'type 'unframed)
288
 
     (window-put w 'sticky t)
289
 
     (window-put w 'sticky-viewport t)
290
 
     (set-window-depth w desktop-layer)))
291
 
 
292
 
  (define-wm-spec-window-type
293
 
   '_NET_WM_WINDOW_TYPE_DOCK
294
 
   (lambda (w)
295
 
     (require 'sawfish.wm.stacking)
296
 
     (set-window-depth w dock-layer)
297
 
     (window-put w 'window-list-skip t)
298
 
     (window-put w 'cycle-skip t)))
299
 
 
300
 
  (define-wm-spec-window-type
301
 
   '_NET_WM_WINDOW_TYPE_DIALOG
302
 
   (lambda (w)
303
 
     (require 'sawfish.wm.frames)
304
 
     (set-window-type w 'transient)))
305
 
 
306
 
  (define-wm-spec-window-state
307
 
   '_NET_WM_STATE_STICKY
 
350
  (define-wm-spec-window-type '_NET_WM_WINDOW_TYPE_DESKTOP
 
351
   (lambda (w)
 
352
     (mark-window-as-desktop w)))
 
353
 
 
354
  (define-wm-spec-window-type '_NET_WM_WINDOW_TYPE_DOCK
 
355
   (lambda (w)
 
356
     (mark-window-as-dock w)))
 
357
 
 
358
  (define-wm-spec-window-type '_NET_WM_WINDOW_TYPE_DIALOG
 
359
   (lambda (w)
 
360
     (mark-window-as-transient w)))
 
361
 
 
362
  (define-wm-spec-window-type '_NET_WM_WINDOW_TYPE_UTILITY
 
363
   (lambda (w)
 
364
     (require 'sawfish.wm.frames)
 
365
     (set-window-type w 'utility)))
 
366
 
 
367
  (define-wm-spec-window-type '_NET_WM_WINDOW_TYPE_TOOLBAR
 
368
   (lambda (w)
 
369
     (require 'sawfish.wm.frames)
 
370
     (set-window-type w 'toolbar)))
 
371
 
 
372
  (define-wm-spec-window-type '_NET_WM_WINDOW_TYPE_MENU
 
373
   (lambda (w)
 
374
     (require 'sawfish.wm.frames)
 
375
     (set-window-type w 'menu)))
 
376
 
 
377
  (define-wm-spec-window-type '_NET_WM_WINDOW_TYPE_SPLASH
 
378
   (lambda (w)
 
379
     (require 'sawfish.wm.frames)
 
380
     (set-window-type w 'splash)
 
381
     (window-put w 'place-mode 'centered)))
 
382
 
 
383
  (define-wm-spec-window-state '_NET_WM_STATE_STICKY
308
384
   (lambda (w mode)
309
385
     (case mode
310
386
       ((init)   (window-put w 'sticky-viewport t))
326
402
        ((remove) (unmaximize-window w direction))
327
403
        ((add)    (maximize-window w direction))
328
404
        ((toggle) (maximize-window-toggle w direction))
329
 
        ((get)    (case direction
330
 
                    ((vertical) (window-maximized-vertically-p w))
331
 
                    ((horizontal) (window-maximized-horizontally-p w))
332
 
                    (t (window-maximized-p w)))))))
 
405
        ((get)    (if (window-maximized-fullscreen-p w)
 
406
                      nil
 
407
                    (case direction
 
408
                      ((vertical) (window-maximized-vertically-p w))
 
409
                      ((horizontal) (window-maximized-horizontally-p w))
 
410
                      (t (window-maximized-p w))))))))
333
411
 
334
412
  (define-wm-spec-window-state '_NET_WM_STATE_MAXIMIZED_VERT
335
413
                               (wm-spec-maximize-handler 'vertical))
339
417
                               (wm-spec-maximize-handler nil)
340
418
                               #:pseudo t)
341
419
 
342
 
  (define-wm-spec-window-state
343
 
   '_NET_WM_STATE_SHADED
 
420
  (define-wm-spec-window-state '_NET_WM_STATE_SHADED
344
421
   (lambda (w mode)
345
422
     (require 'sawfish.wm.state.shading)
346
423
     (case mode
350
427
       ((toggle) (toggle-window-shaded w))
351
428
       ((get)    (window-get w 'shaded)))))
352
429
 
353
 
  (define-wm-spec-window-state
354
 
   '_NET_WM_STATE_SKIP_PAGER
 
430
  (define-wm-spec-window-state '_NET_WM_STATE_SKIP_PAGER
355
431
   (lambda (w mode)
356
432
     (case mode
357
433
       ((init add) (window-put w 'window-list-skip t))
360
436
                               (not (window-get w 'window-list-skip))))
361
437
       ((get)      (window-get w 'window-list-skip)))))
362
438
 
 
439
  (define-wm-spec-window-state '_NET_WM_STATE_SKIP_TASKBAR
 
440
   (lambda (w mode)
 
441
     (case mode
 
442
       ((init add) (window-put w 'task-list-skip t))
 
443
       ((remove)   (window-put w 'task-list-skip nil))
 
444
       ((toggle)   (window-put w 'task-list-skip
 
445
                               (not (window-get w 'task-list-skip))))
 
446
       ((get)      (window-get w 'task-list-skip)))))
 
447
 
 
448
  (define-wm-spec-window-state '_NET_WM_STATE_FULLSCREEN
 
449
   (lambda (w mode)
 
450
     (require 'sawfish.wm.state.maximize)
 
451
     (case mode
 
452
       ((init) (window-put w 'queued-fullscreen-maximize t))
 
453
       ((add remove) (maximize-window-fullscreen w (eq mode 'add)))
 
454
       ((toggle) (maximize-window-fullscreen-toggle w))
 
455
       ((get) (window-maximized-fullscreen-p w)))))
 
456
 
 
457
  (define (above-below-handler depth w mode)
 
458
    (require 'sawfish.wm.stacking)
 
459
    (case mode
 
460
      ((init)
 
461
       (window-put w 'depth depth))
 
462
      ((add remove)
 
463
       (set-window-depth w (if (eq mode 'add) depth 0)))
 
464
      ((toggle)
 
465
       (set-window-depth w (if (= (window-depth w) depth) 0 depth)))
 
466
      ((get)
 
467
       (= (window-depth w) depth))))
 
468
 
 
469
  (define-wm-spec-window-state '_NET_WM_STATE_BELOW
 
470
   (lambda (w mode)
 
471
     (above-below-handler wm-spec-below-depth w mode)))
 
472
 
 
473
  (define-wm-spec-window-state '_NET_WM_STATE_ABOVE
 
474
   (lambda (w mode)
 
475
     (above-below-handler wm-spec-above-depth w mode)))
 
476
 
363
477
 
364
478
;;; client messages
365
479
 
370
484
         (when (windowp w)
371
485
           (delete-window w)))
372
486
 
 
487
        ((_NET_SHOWING_DESKTOP)
 
488
         (if (= (aref data 0) 1)
 
489
             (show-desktop)
 
490
           (hide-desktop)))
 
491
 
373
492
        ((_NET_WM_MOVERESIZE)
374
493
         (when (and (windowp w) (window-mapped-p w))
375
494
           (require 'sawfish.wm.commands.move-resize)
376
495
           (let ((mode (aref data 2)))
377
 
             (if (eq mode _NET_WM_MOVERESIZE_MOVE)
 
496
             ;; don't want grabs failing, sigh
 
497
             (x-server-timestamp t t)
 
498
             (if (or (eq mode _NET_WM_MOVERESIZE_MOVE)
 
499
                     (eq mode _NET_WM_MOVERESIZE_MOVE_KEYBOARD))
378
500
                 (move-window-interactively w)
379
501
               (let ((move-resize-moving-edges
380
502
                      (cond ((eq mode _NET_WM_MOVERESIZE_SIZE_TOPLEFT) '(top left))
387
509
                            ((eq mode _NET_WM_MOVERESIZE_SIZE_RIGHT) '(right)))))
388
510
                 (resize-window-interactively w))))))
389
511
 
390
 
        ((_NET_NUMBER_OF_DESKTOPS _NET_DESKTOP_GEOMETRY)
391
 
         ;; XXX these conflict with user preferences
392
 
         )
 
512
        ((_NET_NUMBER_OF_DESKTOPS)
 
513
         (set-number-of-workspaces (aref data 0)))
 
514
 
 
515
        ((_NET_DESKTOP_GEOMETRY)
 
516
         (set-number-of-viewports (aref data 0) (aref data 1)))
393
517
 
394
518
        ((_NET_DESKTOP_VIEWPORT)
395
519
         (set-viewport (aref data 0) (aref data 1)))
398
522
         (select-workspace (workspace-id-from-logical (aref data 0))))
399
523
 
400
524
        ((_NET_DESKTOP_NAMES)
 
525
         ;; XXX this is kind of broken now we use workspace-names to
 
526
         ;; XXX define the minimum number of workspaces to display?
401
527
         (setq data (aref data 0))
402
528
         (let loop ((i 0)
403
529
                    (out '()))
436
562
                 (make-window-sticky/workspace w)
437
563
               ;; changing the desktop
438
564
               (make-window-unsticky/workspace w)
439
 
               (send-window-to-workspace-from-first w desktop)))))
 
565
               (send-window-to-workspace-from-first w desktop nil)))))
440
566
 
441
567
        (t (setq handled nil)))
442
568
      handled))
450
576
      ((_NET_WM_ICON_GEOMETRY)
451
577
       (let ((geom (get-x-property w '_NET_WM_ICON_GEOMETRY)))
452
578
         (when geom
453
 
           (update-icon-geometry w (nth 2 geom)))))))
 
579
           (update-icon-geometry w (nth 2 geom)))))
 
580
      ((_NET_WM_STRUT)
 
581
       (update-strut w))))
454
582
 
455
583
 
456
584
;;; utilities
470
598
                    (vector wm-spec-window-id) 'WINDOW 32)
471
599
    (set-x-property wm-spec-window-id '_NET_SUPPORTING_WM_CHECK
472
600
                    (vector wm-spec-window-id) 'WINDOW 32)
473
 
    (set-x-property wm-spec-window-id '_NET_WM_NAME "Sawfish" 'STRING 8)
 
601
    (set-x-property wm-spec-window-id '_NET_WM_NAME "Sawfish" 'UTF8_STRING 8)
474
602
 
475
 
    (set-x-property 'root '_NET_SUPPORTED supported-protocols 'ATOM 32)
 
603
    (set-x-property 'root '_NET_SUPPORTED supported-atoms 'ATOM 32)
476
604
 
477
605
    (let ((current-desktop (get-x-property 'root '_NET_CURRENT_DESKTOP)))
478
606
      (when (and current-desktop
490
618
    (add-hook 'workspace-state-change-hook update-workspace-hints)
491
619
    (add-hook 'viewport-resized-hook update-workspace-hints)
492
620
    (add-hook 'viewport-moved-hook update-workspace-hints)
 
621
    (add-hook 'workarea-changed-hook update-workspace-hints)
493
622
 
494
623
    (add-hook 'add-window-hook update-client-list-hints)
495
624
    (add-hook 'destroy-notify-hook update-client-list-hints)
499
628
 
500
629
    (add-hook 'before-add-window-hook honour-client-state)
501
630
    (add-hook 'add-window-hook update-client-state)
502
 
    (call-after-state-changed '(sticky shaded maximized stacking)
 
631
    (call-after-state-changed '(sticky shaded maximized stacking
 
632
                                window-list-skip task-list-skip)
503
633
                              update-client-state)
 
634
    (call-after-state-changed 'sticky update-window-workspace-hints)
504
635
 
505
636
    (add-hook 'focus-in-hook update-focus-state)
506
637
    (add-hook 'focus-out-hook update-focus-state)