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

« back to all changes in this revision

Viewing changes to lisp/sawfish/wm/state/gnome.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
;; gnome.jl -- minimal GNOME compliance
 
2
;; $Id: gnome.jl,v 1.74 2001/12/11 23:05:50 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.state.gnome
 
23
 
 
24
    (export WIN_STATE_STICKY
 
25
            WIN_STATE_MAXIMIZED_VERT
 
26
            WIN_STATE_MAXIMIZED_HORIZ
 
27
            WIN_STATE_HIDDEN
 
28
            WIN_STATE_SHADED
 
29
            WIN_STATE_FIXED_POSITION
 
30
            WIN_LAYER_NORMAL
 
31
            WIN_HINTS_SKIP_FOCUS
 
32
            WIN_HINTS_SKIP_WINLIST
 
33
            WIN_HINTS_SKIP_TASKLIST
 
34
            WIN_HINTS_FOCUS_ON_CLICK
 
35
            WIN_HINTS_DO_NOT_COVER
 
36
            gnome-set-hint
 
37
            gnome-clear-hint
 
38
            gnome-toggle-hint
 
39
            gnome-hint-set-p)
 
40
 
 
41
    (open rep
 
42
          rep.regexp
 
43
          rep.system
 
44
          sawfish.wm.windows
 
45
          sawfish.wm.events
 
46
          sawfish.wm.misc
 
47
          sawfish.wm.menus
 
48
          sawfish.wm.workspace
 
49
          sawfish.wm.viewport
 
50
          sawfish.wm.stacking
 
51
          sawfish.wm.state.maximize
 
52
          sawfish.wm.state.iconify
 
53
          sawfish.wm.state.shading)
 
54
 
 
55
  (define-structure-alias gnome sawfish.wm.state.gnome)
 
56
 
 
57
  (defconst WIN_STATE_STICKY 1)
 
58
  (defconst WIN_STATE_MAXIMIZED_VERT 4)
 
59
  (defconst WIN_STATE_MAXIMIZED_HORIZ 8)
 
60
  (defconst WIN_STATE_HIDDEN 16)
 
61
  (defconst WIN_STATE_SHADED 32)
 
62
  (defconst WIN_STATE_FIXED_POSITION 256)
 
63
 
 
64
  (defconst WIN_LAYER_NORMAL 4)
 
65
 
 
66
  (defconst WIN_HINTS_SKIP_FOCUS 1)
 
67
  (defconst WIN_HINTS_SKIP_WINLIST 2)
 
68
  (defconst WIN_HINTS_SKIP_TASKLIST 4)
 
69
  (defconst WIN_HINTS_FOCUS_ON_CLICK 16)
 
70
  (defconst WIN_HINTS_DO_NOT_COVER 32)
 
71
 
 
72
  (defvar gnome-window-id nil)
 
73
 
 
74
  (defvar gnome-supported-protocols [_WIN_CLIENT_LIST _WIN_WORKSPACE
 
75
                                     _WIN_WORKSPACE_COUNT _WIN_STATE
 
76
                                     _WIN_LAYER])
 
77
 
 
78
  ;; this is needed since the gnome tasklist applet doesn't honour
 
79
  ;; the _WIN_HIDDEN property (?)
 
80
  (defvar gnome-ignored-windows-in-client-list t)
 
81
 
 
82
  (define (gnome-set-client-list)
 
83
    (let (clients vec)
 
84
      (map-windows (lambda (w)
 
85
                     (when (and (windowp w) (window-mapped-p w)
 
86
                                (or gnome-ignored-windows-in-client-list
 
87
                                    (not (window-get w 'ignored))))
 
88
                       (setq clients (cons (window-id w) clients)))))
 
89
      (setq vec (apply vector clients))
 
90
      (set-x-property 'root '_WIN_CLIENT_LIST vec 'CARDINAL 32)))
 
91
 
 
92
  (define (gnome-set-hint w bit)
 
93
    (let ((hints (get-x-property w '_WIN_HINTS)))
 
94
      (if hints
 
95
          (setq hints (aref (nth 2 hints) 0))
 
96
        (setq hints 0))
 
97
      (setq hints (logior bit hints))
 
98
      (set-x-property w '_WIN_HINTS (vector hints) 'CARDINAL 32)))
 
99
 
 
100
  (define (gnome-clear-hint w bit)
 
101
    (let ((hints (get-x-property w '_WIN_HINTS)))
 
102
      (if hints
 
103
          (setq hints (aref (nth 2 hints) 0))
 
104
        (setq hints 0))
 
105
      (setq hints (logand (lognot bit) hints))
 
106
      (set-x-property w '_WIN_HINTS (vector hints) 'CARDINAL 32)))
 
107
 
 
108
  (define (gnome-toggle-hint w bit)
 
109
    (let ((hints (get-x-property w '_WIN_HINTS)))
 
110
      (if hints
 
111
          (setq hints (aref (nth 2 hints) 0))
 
112
        (setq hints 0))
 
113
      (setq hints (logxor bit hints))
 
114
      (set-x-property w '_WIN_HINTS (vector hints) 'CARDINAL 32)))
 
115
 
 
116
  ;; Queries whether a property in _WIN_HINTS is set.  Involves a
 
117
  ;; server roundtrip as it does get-x-property.
 
118
  (define (gnome-hint-set-p w bit)
 
119
    (let ((hints (get-x-property w '_WIN_HINTS)))
 
120
      (if hints
 
121
          (setq hints (aref (nth 2 hints) 0))
 
122
          (setq hints 0))
 
123
      (if (zerop (logand bit hints))
 
124
          nil
 
125
          t)))
 
126
 
 
127
  (define current-workspace-index nil)
 
128
  (define current-workspace-count 0)
 
129
  (define current-workspace-names nil)
 
130
  (define current-area nil)
 
131
  (define current-area-count nil)
 
132
 
 
133
  (define (gnome-set-workspace)
 
134
    (let* ((limits (workspace-limits))
 
135
           (port (screen-viewport))
 
136
           (port-size viewport-dimensions)
 
137
           (total-workspaces (1+ (- (cdr limits) (car limits)))))
 
138
      ;; apparently some pagers don't like it if we place windows
 
139
      ;; on (temporarily) non-existent workspaces
 
140
      (when (< current-workspace-count total-workspaces)
 
141
        (setq current-workspace-count total-workspaces)
 
142
        (set-x-property 'root '_WIN_WORKSPACE_COUNT
 
143
                        (vector current-workspace-count) 'CARDINAL 32))
 
144
      (map-windows
 
145
       (lambda (w)
 
146
         (let
 
147
             ;; XXX the gnome-wm standard sucks..
 
148
             ((space (and (not (window-get w 'sticky))
 
149
                          (window-get w 'swapped-in)))
 
150
              (w-port (and (not (window-get w 'viewport-sticky))
 
151
                           (window-viewport w))))
 
152
           (if space
 
153
               (set-x-property w '_WIN_WORKSPACE
 
154
                               (vector (- space (car limits))) 'CARDINAL 32)
 
155
             (delete-x-property w '_WIN_WORKSPACE))
 
156
           (if w-port
 
157
               (set-x-property w '_WIN_AREA
 
158
                               (vector (car w-port) (cdr w-port))
 
159
                               'CARDINAL 32)
 
160
             (delete-x-property w '_WIN_AREA)))))
 
161
      (unless (equal current-workspace-index
 
162
                     (- current-workspace (car limits)))
 
163
        (setq current-workspace-index (- current-workspace (car limits)))
 
164
        (set-x-property 'root '_WIN_WORKSPACE
 
165
                        (vector current-workspace-index) 'CARDINAL 32))
 
166
      (when (> current-workspace-count total-workspaces)
 
167
        (setq current-workspace-count total-workspaces)
 
168
        (set-x-property 'root '_WIN_WORKSPACE_COUNT
 
169
                        (vector current-workspace-count) 'CARDINAL 32))
 
170
      (unless (equal current-workspace-names workspace-names)
 
171
        (setq current-workspace-names workspace-names)
 
172
        (set-x-text-property 'root '_WIN_WORKSPACE_NAMES
 
173
                             (apply vector workspace-names)))
 
174
      (unless (equal current-area port)
 
175
        (setq current-area port)
 
176
        (set-x-property 'root '_WIN_AREA (vector (car port) (cdr port))
 
177
                        'CARDINAL 32))
 
178
      (unless (equal current-area-count port-size)
 
179
        (setq current-area-count port-size)
 
180
        (set-x-property 'root '_WIN_AREA_COUNT (vector (car port-size)
 
181
                                                       (cdr port-size))
 
182
                        'CARDINAL 32))))
 
183
 
 
184
  (define (gnome-set-client-state w)
 
185
    (let ((state 0))
 
186
      (when (window-get w 'sticky)
 
187
        (setq state (logior state WIN_STATE_STICKY)))
 
188
      (when (window-get w 'shaded)
 
189
        (setq state (logior state WIN_STATE_SHADED)))
 
190
      (when (window-get w 'fixed-position)
 
191
        (setq state (logior state WIN_STATE_FIXED_POSITION)))
 
192
      (when (window-maximized-vertically-p w)
 
193
        (setq state (logior state WIN_STATE_MAXIMIZED_VERT)))
 
194
      (when (window-maximized-horizontally-p w)
 
195
        (setq state (logior state WIN_STATE_MAXIMIZED_HORIZ)))
 
196
      (when (window-get w 'ignored)
 
197
        (setq state (logior state WIN_STATE_HIDDEN)))
 
198
      (set-x-property w '_WIN_STATE (vector state) 'CARDINAL 32)
 
199
      (when (window-get w 'depth)
 
200
        (set-x-property w '_WIN_LAYER
 
201
                        (vector (+ (window-get w 'depth) WIN_LAYER_NORMAL))
 
202
                        'CARDINAL 32))))
 
203
 
 
204
  (define (gnome-set-client-hints w states)
 
205
    (let ((hints (let ((prop (get-x-property w '_WIN_HINTS)))
 
206
                   (if (eq (car prop) 'CARDINAL)
 
207
                       (aref (nth 2 prop) 0)
 
208
                     0))))
 
209
      (mapc (lambda (state)
 
210
              (case state
 
211
                ((window-list-skip)
 
212
                 (setq hints (logior (logand
 
213
                                      hints (lognot WIN_HINTS_SKIP_WINLIST))
 
214
                                     (if (window-get w 'window-list-skip)
 
215
                                         WIN_HINTS_SKIP_WINLIST 0)
 
216
                                     (if (window-get w 'avoid)
 
217
                                         WIN_HINTS_DO_NOT_COVER 0))))))
 
218
            states)
 
219
      (set-x-property w '_WIN_HINTS (vector hints) 'CARDINAL 32)))
 
220
 
 
221
  ;; XXX Ugly hacks to make the GNOME desktop function sanely
 
222
  (define (gnome-window-class-hacks w)
 
223
    (let ((class (get-x-text-property w 'WM_CLASS)))
 
224
      (when (and class (>= (length class) 2))
 
225
        (cond ((and (string= (aref class 1) "Panel")
 
226
                    (string= (aref class 0) "panel_window"))
 
227
               ;; XXX I don't think the GNOME hints specify these things...
 
228
               (window-put w 'focus-click-through t)
 
229
               (window-put w 'no-history t)
 
230
               (window-put w 'never-iconify t)
 
231
               (window-put w 'never-maximize t)
 
232
               ;; XXX the panel is broken, in that it doesn't check
 
233
               ;; XXX that the wm gave it the position that it wanted.
 
234
               ;; XXX (The wm is under no obligation; the panel should
 
235
               ;; XXX move itself to the required position after
 
236
               ;; XXX initially mapping the window, or perhaps it
 
237
               ;; XXX should use the USPosition hints?). The following
 
238
               ;; XXX line prevents panel windows being placed at all
 
239
               (window-put w 'placed t))
 
240
              ((string= (aref class 1) "gmc-desktop-icon")
 
241
               (window-put w 'focus-click-through t)
 
242
               (window-put w 'never-focus t)
 
243
               (window-put w 'never-iconify t)
 
244
               (window-put w 'never-maximize t)
 
245
               ;; XXX same reason as above
 
246
               (window-put w 'placed t))
 
247
              ((and (string= (aref class 1) "Nautilus")
 
248
                    (string= (aref class 0) "desktop_window"))
 
249
               (mark-window-as-desktop w))))))
 
250
 
 
251
  (define (gnome-honour-client-state w)
 
252
    (gnome-window-class-hacks w)
 
253
    (let ((state (get-x-property w '_WIN_STATE))
 
254
          (hints (get-x-property w '_WIN_HINTS))
 
255
          (layer (get-x-property w '_WIN_LAYER))
 
256
          (space (get-x-property w '_WIN_WORKSPACE))
 
257
          bits)
 
258
      (when (eq (car state) 'CARDINAL)
 
259
        (setq bits (aref (nth 2 state) 0))
 
260
        (unless (zerop (logand bits WIN_STATE_STICKY))
 
261
          (window-put w 'sticky t)
 
262
          (window-put w 'sticky-viewport t))
 
263
        (unless (zerop (logand bits WIN_STATE_SHADED))
 
264
          (window-put w 'shaded t))
 
265
        (unless (zerop (logand bits WIN_STATE_FIXED_POSITION))
 
266
          (window-put w 'fixed-position t))
 
267
        (unless (zerop (logand bits WIN_STATE_MAXIMIZED_VERT))
 
268
          (unless (window-maximized-vertically-p w)
 
269
            (window-put w 'queued-vertical-maximize t)))
 
270
        (unless (zerop (logand bits WIN_STATE_MAXIMIZED_HORIZ))
 
271
          (unless (window-maximized-horizontally-p w)
 
272
            (window-put w 'queued-horizontal-maximize t))))
 
273
      (when (eq (car hints) 'CARDINAL)
 
274
        (setq bits (aref (nth 2 hints) 0))
 
275
        (unless (zerop (logand bits WIN_HINTS_SKIP_FOCUS))
 
276
          (window-put w 'cycle-skip t))
 
277
        (unless (zerop (logand bits WIN_HINTS_SKIP_WINLIST))
 
278
          (window-put w 'window-list-skip t))
 
279
        (unless (zerop (logand bits WIN_HINTS_DO_NOT_COVER))
 
280
          (window-put w 'avoid t)))
 
281
      (when layer
 
282
        (setq layer (aref (nth 2 layer) 0))
 
283
        (set-window-depth w (- layer WIN_LAYER_NORMAL)))
 
284
      (when (and space (not (window-workspaces w)))
 
285
        (set-window-workspaces w (list (aref (nth 2 space) 0))))))
 
286
 
 
287
  (define (gnome-client-message-handler w type data)
 
288
    (cond ((eq type '_WIN_WORKSPACE)
 
289
           (let ((limits (workspace-limits)))
 
290
             (select-workspace (+ (aref data 0) (car limits)))
 
291
             t))
 
292
          ((eq type '_WIN_AREA)
 
293
           (set-screen-viewport (aref data 0) (aref data 1)))
 
294
          ((and (eq type '_WIN_STATE) (windowp w))
 
295
           (let ((mask (aref data 0))
 
296
                 (values (aref data 1))
 
297
                 tem)
 
298
             (unless (zerop (logand mask WIN_STATE_STICKY))
 
299
               (if (zerop (logand values WIN_STATE_STICKY))
 
300
                   (make-window-unsticky w)
 
301
                 (make-window-sticky w)))
 
302
             (unless (zerop (logand mask WIN_STATE_SHADED))
 
303
               (if (zerop (logand values WIN_STATE_SHADED))
 
304
                   (unshade-window w)
 
305
                 (shade-window w)))
 
306
             (unless (zerop (logand mask WIN_STATE_FIXED_POSITION))
 
307
               (window-put w 'fixed-position
 
308
                           (/= (logand values WIN_STATE_FIXED_POSITION) 0)))
 
309
             (unless (zerop (logand mask WIN_STATE_MAXIMIZED_VERT))
 
310
               (setq tem (window-maximized-vertically-p w))
 
311
               (if (or (and (not tem) (not (zerop (logand values WIN_STATE_MAXIMIZED_VERT))))
 
312
                       (and tem (zerop (logand values WIN_STATE_MAXIMIZED_VERT))))
 
313
                   (maximize-window-vertically-toggle w)))
 
314
             (unless (zerop (logand mask WIN_STATE_MAXIMIZED_HORIZ))
 
315
               (setq tem (window-maximized-horizontally-p w))
 
316
               (if (or (and (not tem) (not (zerop (logand values WIN_STATE_MAXIMIZED_HORIZ))))
 
317
                       (and tem (zerop (logand values WIN_STATE_MAXIMIZED_HORIZ))))
 
318
                   (maximize-window-horizontally-toggle w))))
 
319
           t)
 
320
          ((and (eq type '_WIN_HINTS) (windowp w))
 
321
           (let ((mask (aref data 0))
 
322
                 (bits (aref data 1)))
 
323
             (unless (zerop (logand mask WIN_HINTS_SKIP_FOCUS))
 
324
               (window-put w 'cycle-skip
 
325
                           (not (zerop (logand bits WIN_HINTS_SKIP_FOCUS)))))
 
326
             (unless (zerop (logand mask WIN_HINTS_SKIP_WINLIST))
 
327
               (window-put w 'window-list-skip
 
328
                           (not (zerop (logand bits WIN_HINTS_SKIP_WINLIST)))))
 
329
             (unless (zerop (logand mask WIN_HINTS_DO_NOT_COVER))
 
330
               (window-put w 'avoid
 
331
                           (not (zerop (logand bits WIN_HINTS_DO_NOT_COVER)))))))
 
332
          ((and (eq type '_WIN_LAYER) (windowp w))
 
333
           (set-window-depth w (- (aref data 0) WIN_LAYER_NORMAL))
 
334
           t)))
 
335
 
 
336
  (define (gnome-property-handler w prop)
 
337
    (when (windowp w)
 
338
      (case prop
 
339
        ((_WIN_WORKSPACE)                       
 
340
          (let ((space (get-x-property w '_WIN_WORKSPACE)))
 
341
            (when (and space (eq (car space) 'CARDINAL)
 
342
                       (= (length (nth 2 space)) 1))
 
343
              (let ((count (aref (nth 2 space) 0)))
 
344
                (unless (window-appears-in-workspace-p
 
345
                         w (workspace-id-from-logical count))
 
346
                  (send-window-to-workspace-from-first w count))))))
 
347
 
 
348
        ((_WIN_AREA)
 
349
         (let ((area (get-x-property w '_WIN_AREA)))
 
350
           (when (and area (eq (car area) 'CARDINAL)
 
351
                      (= (length (nth 2 area)) 2))
 
352
             (let ((x (aref (nth 2 area) 0))
 
353
                   (y (aref (nth 2 area) 1))
 
354
                   (port (window-viewport w)))
 
355
               (unless (and (= (car port) x) (= (cdr port) y))
 
356
                 (set-window-viewport w x y)))))))))
 
357
 
 
358
  (define (gnome-event-proxyer)
 
359
    (when (and (current-event) (eq (current-event-window) 'root))
 
360
      (let ((event (event-name (current-event))))
 
361
        ;; only proxy Click1 or Off events, and only if we don't have
 
362
        ;; a binding for an event that may follow in the same grab
 
363
        (cond ((and (string-match "^(.*)-Click\\d?$" event)
 
364
                    (let ((mirror (lookup-event
 
365
                                   (expand-last-match "\\1-Off"))))
 
366
                      (not (or (search-keymap mirror global-keymap)
 
367
                               (search-keymap mirror root-window-keymap)))))
 
368
               ;; send with SubstructureNotifyMask
 
369
               (proxy-current-event gnome-window-id (lsh 1 19))
 
370
               t)
 
371
              ((and (string-match "^(.*)-Off[123]?$" event)
 
372
                    (let ((mirrors
 
373
                           (mapcar (lambda (x)
 
374
                                     (lookup-event
 
375
                                      (concat (expand-last-match "\\1-") x)))
 
376
                                   '("Click1" "Click2" "Click3" "Move"))))
 
377
                      (catch 'out
 
378
                        (mapc (lambda (ev)
 
379
                                (when (or (search-keymap ev global-keymap)
 
380
                                          (search-keymap ev root-window-keymap))
 
381
                                  (throw 'out nil)))
 
382
                              mirrors)
 
383
                        t)))
 
384
               ;; send with SubstructureNotifyMask
 
385
               (proxy-current-event gnome-window-id (lsh 1 19))
 
386
               t)))))
 
387
 
 
388
 
 
389
;;; initialisation
 
390
 
 
391
  (define (gnome-init)
 
392
    (setq gnome-window-id (create-window 'root -200 -200 5 5))
 
393
 
 
394
    (set-x-property 'root '_WIN_SUPPORTING_WM_CHECK
 
395
                    (vector gnome-window-id) 'CARDINAL 32)
 
396
    (set-x-property gnome-window-id '_WIN_SUPPORTING_WM_CHECK
 
397
                    (vector gnome-window-id) 'CARDINAL 32)
 
398
 
 
399
    (set-x-property 'root '_WIN_DESKTOP_BUTTON_PROXY
 
400
                    (vector gnome-window-id) 'CARDINAL 32)
 
401
    (set-x-property gnome-window-id '_WIN_DESKTOP_BUTTON_PROXY
 
402
                    (vector gnome-window-id) 'CARDINAL 32)
 
403
 
 
404
    (set-x-property 'root '_WIN_PROTOCOLS
 
405
                    gnome-supported-protocols 'ATOM 32)
 
406
 
 
407
    (let ((port (screen-viewport)))
 
408
      (set-x-property 'root '_WIN_AREA
 
409
                      (vector (car port) (cdr port)) 'CARDINAL 32)
 
410
      (set-x-property 'root '_WIN_AREA_COUNT
 
411
                      (vector (car viewport-dimensions)
 
412
                              (cdr viewport-dimensions)) 'CARDINAL 32)
 
413
 
 
414
      ;; XXX I'm using this property to tell desk-guide to move
 
415
      ;; XXX the current area on all desktops at once
 
416
      ;; XXX This is totally non-standard and may change..
 
417
      (set-x-property 'root '_WIN_UNIFIED_AREA (vector 1) 'CARDINAL 32))
 
418
 
 
419
    (delete-x-property 'root '_WIN_WORKSPACE_NAMES)
 
420
 
 
421
    (add-hook 'workspace-state-change-hook gnome-set-workspace)
 
422
    (add-hook 'viewport-resized-hook gnome-set-workspace)
 
423
    (add-hook 'viewport-moved-hook gnome-set-workspace)
 
424
 
 
425
    (add-hook 'add-window-hook gnome-set-client-list)
 
426
    (add-hook 'destroy-notify-hook gnome-set-client-list)
 
427
    (add-hook 'map-notify-hook gnome-set-client-list)
 
428
    (add-hook 'unmap-notify-hook gnome-set-client-list)
 
429
    (add-hook 'workspace-state-change-hook gnome-set-client-list)
 
430
 
 
431
    (add-hook 'before-add-window-hook gnome-honour-client-state)
 
432
    (add-hook 'add-window-hook gnome-set-client-state)
 
433
    (call-after-state-changed '(sticky shaded maximized ignored stacking)
 
434
                              gnome-set-client-state)
 
435
    (call-after-state-changed '(window-list-skip) gnome-set-client-hints)
 
436
 
 
437
    (add-hook 'client-message-hook gnome-client-message-handler)
 
438
    (add-hook 'property-notify-hook gnome-property-handler)
 
439
 
 
440
    (add-hook 'unbound-key-hook gnome-event-proxyer)
 
441
    (add-hook 'before-exit-hook gnome-exit))
 
442
 
 
443
  (define (gnome-exit)
 
444
    (destroy-window gnome-window-id)
 
445
    (delete-x-property 'root '_WIN_SUPPORTING_WM_CHECK)
 
446
    (delete-x-property 'root '_WIN_PROTOCOLS)
 
447
    (delete-x-property 'root '_WIN_AREA)
 
448
    (delete-x-property 'root '_WIN_AREA_COUNT)
 
449
    (delete-x-property 'root '_WIN_UNIFIED_AREA))
 
450
 
 
451
  (unless (or gnome-window-id batch-mode)
 
452
    (gnome-init)
 
453
    (require 'sawfish.wm.gnome.match-window))
 
454
 
 
455
  (add-window-menu-toggle (_ "In GNOME _task list")
 
456
                          'gnome-toggle-skip-tasklist
 
457
                          (lambda (w) (not (gnome-hint-set-p w WIN_HINTS_SKIP_TASKLIST)))))