~ubuntu-branches/ubuntu/precise/compiz/precise

« back to all changes in this revision

Viewing changes to .pc/fix_gtk_w_d_crash.patch/gtk/window-decorator/events.c

  • Committer: Package Import Robot
  • Author(s): Didier Roche, Łukasz 'sil2100' Zemczak, Didier Roche
  • Date: 2012-03-12 10:22:10 UTC
  • mfrom: (0.168.15)
  • Revision ID: package-import@ubuntu.com-20120312102210-e248pzbccr7r2tdq
Tags: 1:0.9.7.0+bzr3035-0ubuntu1
[ Łukasz 'sil2100' Zemczak ]
* New upstream snapshot:
  - Fix gtk-window-decorator crash upon demaximizing a window (LP: #930071)
  - Fix core keybindings (LP: #930412)
  - Fixes compiz crash with SIGSEGV on shutdown (LP: #931283)
  - Plugins can't tell the difference between a key-tap and modifier
    key-release (LP: #925293)
  - compiz-core r3001 (and 3002) ftbfs (LP: #933226)
  - Semi-maximized windows have no shadow or frame (LP: #924736)
  - Untranslated strings in gtk-window-decorator (LP: #780505)
  - Initialize the _NET_WM_STATE_FOCUSED (LP: #932087)
  - [regression] Customized shortcuts don't work (LP: #931927)
  - Window stacking problem (LP: #936675)
  - Quickly demaximized windows can receive maximized window decorations if 
    they were initially maximized (LP: #936778)
  - Maximized windows do not get shadows at all (LP: #936774)
  - [regression] Launcher, top panel and keyboard un-responsive after using 
    any Super-x shortcut (LP: #934058)
  - No draggable border if mutter isn't installed (LP: #936781)
  - Fix compiz crash with SIGSEGV in XDefineCursor() (LP: #936487)
  - Fixes memory leak at DecorWindow::updateSwitcher() (LP: #940115)
  - Unresolved symbols in plugins cause compiz to exit (LP: #938478)
  - Fix compiz spending about 51% of its CPU time in CompRegion 
    construction/destruction (LP: #940139)
  - Fix Conditional jump or move depends on uninitialised value(s) in 
    decor_match_pixmap (LP: #940066)
  - Fix 'show desktop' behaviour (LP: #871801)
  - Tweak algorithm used to cast shadows on maximized windows (LP: #936784)
  - "Svg" and "Png" should be "SVG and "PNG" (LP: #942890)
  - Fix invalid memory usage after free() in DecorWindow (LP: #943116)
  - Fix alt + F10 (LP: #943223)
* Removed cherry-picked patches
* debian/patches/fix_944631.patch:
  - Always replay the keyboard if something was grabbed and didn't trigger 
    an action and don't trigger actions which aren't added accidentally 
    (LP: #943612) (LP: #944631)
* debian/patches/fix_923683.patch:
  - Backports a patch which prevents the shift race condition

[ Didier Roche ]
* debian/patches/fix_alt_pressing.patch:
  - Patch from ddv to fix all the regressions with the alt key fix and other
    (LP: #943851, #945373)
  - Fix Quicklist are not showing if right-clicking a launcher icon in Expo
    mode if triggered by Super + S (LP: #944979)
* debian/patches/fix_806255.patch:
  - Unity/compiz intercepts keystrokes from grabbed windows (LP: #806255)
* debian/patches/fix_943194.patch:
  - second part for the alt key fix (LP: #943194)
* debian/patches/additional_alt_tapping_fix.patch:
  - again another alt tapping related fix for some regressions from the
    previous branch. Taken from "tapping-panacea" upstream branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright © 2006 Novell, Inc.
3
 
 *
4
 
 * This library is free software; you can redistribute it and/or
5
 
 * modify it under the terms of the GNU Lesser General Public
6
 
 * License as published by the Free Software Foundation; either
7
 
 * version 2 of the License, or (at your option) any later version.
8
 
 *
9
 
 * This library is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12
 
 * Lesser General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU Lesser General Public
15
 
 * License along with this library; if not, write to the
16
 
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17
 
 * Boston, MA 02111-1307, USA.
18
 
 *
19
 
 * Author: David Reveman <davidr@novell.com>
20
 
 *
21
 
 * 2D Mode: Copyright © 2010 Sam Spilsbury <smspillaz@gmail.com>
22
 
 * Frames Management: Copright © 2011 Canonical Ltd.
23
 
 *        Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24
 
 */
25
 
 
26
 
#include "gtk-window-decorator.h" 
27
 
 
28
 
void
29
 
move_resize_window (WnckWindow *win,
30
 
                    int        direction,
31
 
                    decor_event *gtkwd_event)
32
 
{
33
 
    Display    *xdisplay;
34
 
    GdkDisplay *gdkdisplay;
35
 
    GdkScreen  *screen;
36
 
    Window     xroot;
37
 
    XEvent     ev;
38
 
 
39
 
    gdkdisplay = gdk_display_get_default ();
40
 
    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
41
 
    screen     = gdk_display_get_default_screen (gdkdisplay);
42
 
    xroot      = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen));
43
 
 
44
 
    if (action_menu_mapped)
45
 
    {
46
 
        gtk_object_destroy (GTK_OBJECT (action_menu));
47
 
        action_menu_mapped = FALSE;
48
 
        action_menu = NULL;
49
 
        return;
50
 
    }
51
 
 
52
 
    ev.xclient.type    = ClientMessage;
53
 
    ev.xclient.display = xdisplay;
54
 
 
55
 
    ev.xclient.serial     = 0;
56
 
    ev.xclient.send_event = TRUE;
57
 
 
58
 
    ev.xclient.window       = wnck_window_get_xid (win);
59
 
    ev.xclient.message_type = wm_move_resize_atom;
60
 
    ev.xclient.format       = 32;
61
 
 
62
 
    ev.xclient.data.l[0] = gtkwd_event->x_root;
63
 
    ev.xclient.data.l[1] = gtkwd_event->y_root;
64
 
    ev.xclient.data.l[2] = direction;
65
 
    ev.xclient.data.l[3] = gtkwd_event->button;
66
 
    ev.xclient.data.l[4] = 1;
67
 
 
68
 
    XUngrabPointer (xdisplay, gtkwd_event->time);
69
 
    XUngrabKeyboard (xdisplay, gtkwd_event->time);
70
 
 
71
 
    XSendEvent (xdisplay, xroot, FALSE,
72
 
                SubstructureRedirectMask | SubstructureNotifyMask,
73
 
                &ev);
74
 
 
75
 
    XSync (xdisplay, FALSE);
76
 
}
77
 
 
78
 
void
79
 
common_button_event (WnckWindow *win,
80
 
                     decor_event *gtkwd_event,
81
 
                     decor_event_type gtkwd_type,
82
 
                     int        button,
83
 
                     int        max,
84
 
                     char       *tooltip)
85
 
{
86
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
87
 
    guint   state = d->button_states[button];
88
 
 
89
 
    if (settings->use_tooltips)
90
 
        handle_tooltip_event (win, gtkwd_event, gtkwd_type, state, tooltip);
91
 
 
92
 
    if (d->frame_window && gtkwd_type == GEnterNotify)
93
 
    {
94
 
        GdkCursor* cursor;
95
 
        cursor = gdk_cursor_new (GDK_LEFT_PTR);
96
 
        gdk_window_set_cursor (d->frame_window, cursor);
97
 
        gdk_cursor_unref (cursor);
98
 
    }
99
 
 
100
 
    switch (gtkwd_type) {
101
 
    case GButtonPress:
102
 
        if (gtkwd_event->button <= max)
103
 
            d->button_states[button] |= PRESSED_EVENT_WINDOW;
104
 
        break;
105
 
    case GButtonRelease:
106
 
        if (gtkwd_event->button <= max)
107
 
            d->button_states[button] &= ~PRESSED_EVENT_WINDOW;
108
 
        break;
109
 
    case GEnterNotify:
110
 
        d->button_states[button] |= IN_EVENT_WINDOW;
111
 
        break;
112
 
    case GLeaveNotify:
113
 
        d->button_states[button] &= ~IN_EVENT_WINDOW;
114
 
        break;
115
 
    default:
116
 
        break;
117
 
    }
118
 
 
119
 
    if (state != d->button_states[button])
120
 
        queue_decor_draw (d);
121
 
}
122
 
 
123
 
#define BUTTON_EVENT_ACTION_STATE (PRESSED_EVENT_WINDOW | IN_EVENT_WINDOW)
124
 
 
125
 
void
126
 
close_button_event (WnckWindow *win,
127
 
                    decor_event *gtkwd_event,
128
 
                    decor_event_type gtkwd_type)
129
 
{
130
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
131
 
    guint   state = d->button_states[BUTTON_CLOSE];
132
 
 
133
 
    common_button_event (win, gtkwd_event, gtkwd_type,
134
 
                         BUTTON_CLOSE, 1, _("Close Window"));
135
 
 
136
 
    switch (gtkwd_type) {
137
 
    case GButtonRelease:
138
 
        if (gtkwd_event->button == 1)
139
 
            if (state == BUTTON_EVENT_ACTION_STATE)
140
 
                wnck_window_close (win, gtkwd_event->time);
141
 
        break;
142
 
    default:
143
 
        break;
144
 
    }
145
 
}
146
 
 
147
 
void
148
 
max_button_event (WnckWindow *win,
149
 
                  decor_event *gtkwd_event,
150
 
                  decor_event_type gtkwd_type)
151
 
{
152
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
153
 
    guint   state = d->button_states[BUTTON_MAX];
154
 
 
155
 
    if (wnck_window_is_maximized (win))
156
 
        common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
157
 
                             3, _("Unmaximize Window"));
158
 
    else
159
 
        common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
160
 
                             3, _("Maximize Window"));
161
 
 
162
 
    switch (gtkwd_type) {
163
 
    case GButtonRelease:
164
 
        if (gtkwd_event->button <= 3)
165
 
        {
166
 
            if (state == BUTTON_EVENT_ACTION_STATE)
167
 
            {
168
 
                if (gtkwd_event->button == 1)
169
 
                {
170
 
                    if (wnck_window_is_maximized (win))
171
 
                        wnck_window_unmaximize (win);
172
 
                    else if (wnck_window_is_maximized_vertically (win))
173
 
                        wnck_window_unmaximize_vertically (win);
174
 
                    else if (wnck_window_is_maximized_horizontally (win))
175
 
                        wnck_window_unmaximize_horizontally (win);
176
 
                    else
177
 
                        wnck_window_maximize (win);
178
 
                }
179
 
                else if (gtkwd_event->button == 2)
180
 
                {
181
 
                    if (wnck_window_is_maximized_vertically (win))
182
 
                        wnck_window_unmaximize_vertically (win);
183
 
                    else
184
 
                        wnck_window_maximize_vertically (win);
185
 
                }
186
 
                else if (gtkwd_event->button == 3)
187
 
                {
188
 
                    if (wnck_window_is_maximized_horizontally (win))
189
 
                        wnck_window_unmaximize_horizontally (win);
190
 
                    else
191
 
                        wnck_window_maximize_horizontally (win);
192
 
                }
193
 
            }
194
 
        }
195
 
        break;
196
 
    default:
197
 
        break;
198
 
    }
199
 
}
200
 
 
201
 
void
202
 
min_button_event (WnckWindow *win,
203
 
                  decor_event *gtkwd_event,
204
 
                  decor_event_type gtkwd_type)
205
 
{
206
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
207
 
    guint   state = d->button_states[BUTTON_MIN];
208
 
 
209
 
    common_button_event (win, gtkwd_event, gtkwd_type,
210
 
                         BUTTON_MIN, 1, _("Minimize Window"));
211
 
 
212
 
    switch (gtkwd_type) {
213
 
    case GButtonRelease:
214
 
        if (gtkwd_event->button == 1)
215
 
            if (state == BUTTON_EVENT_ACTION_STATE)
216
 
                wnck_window_minimize (win);
217
 
        break;
218
 
    default:
219
 
        break;
220
 
    }
221
 
}
222
 
 
223
 
void
224
 
menu_button_event (WnckWindow *win,
225
 
                   decor_event *gtkwd_event,
226
 
                   decor_event_type gtkwd_type)
227
 
{
228
 
 
229
 
    common_button_event (win, gtkwd_event, gtkwd_type,
230
 
                         BUTTON_MENU, 1, _("Window Menu"));
231
 
 
232
 
    switch (gtkwd_type) {
233
 
    case GButtonPress:
234
 
        if (gtkwd_event->button == 1)
235
 
            action_menu_map (win,
236
 
                             gtkwd_event->button,
237
 
                             gtkwd_event->time);
238
 
        break;
239
 
    default:
240
 
        break;
241
 
    }
242
 
}
243
 
 
244
 
void
245
 
shade_button_event (WnckWindow *win,
246
 
                    decor_event *gtkwd_event,
247
 
                    decor_event_type gtkwd_type)
248
 
{
249
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
250
 
    guint   state = d->button_states[BUTTON_SHADE];
251
 
 
252
 
    common_button_event (win, gtkwd_event, gtkwd_type,
253
 
                         BUTTON_SHADE, 1, _("Shade"));
254
 
 
255
 
    switch (gtkwd_type) {
256
 
    case GButtonRelease:
257
 
        if (gtkwd_event->button == 1)
258
 
        {
259
 
            if (state == BUTTON_EVENT_ACTION_STATE)
260
 
                wnck_window_shade (win);
261
 
        }
262
 
        break;
263
 
    default:
264
 
        break;
265
 
    }
266
 
}
267
 
 
268
 
void
269
 
above_button_event (WnckWindow *win,
270
 
                    decor_event *gtkwd_event,
271
 
                    decor_event_type gtkwd_type)
272
 
{
273
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
274
 
    guint   state = d->button_states[BUTTON_ABOVE];
275
 
 
276
 
    common_button_event (win, gtkwd_event, gtkwd_type,
277
 
                         BUTTON_ABOVE, 1, _("Make Above"));
278
 
 
279
 
    switch (gtkwd_type) {
280
 
    case GButtonRelease:
281
 
        if (gtkwd_event->button == 1)
282
 
            if (state == BUTTON_EVENT_ACTION_STATE)
283
 
#ifdef HAVE_LIBWNCK_2_18_1
284
 
                wnck_window_make_above (win);
285
 
#endif
286
 
        break;
287
 
    default:
288
 
        break;
289
 
    }
290
 
}
291
 
 
292
 
void
293
 
stick_button_event (WnckWindow *win,
294
 
                    decor_event *gtkwd_event,
295
 
                    decor_event_type gtkwd_type)
296
 
{
297
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
298
 
    guint   state = d->button_states[BUTTON_STICK];
299
 
 
300
 
    common_button_event (win, gtkwd_event, gtkwd_type,
301
 
                         BUTTON_STICK, 1, _("Stick"));
302
 
 
303
 
    switch (gtkwd_type) {
304
 
    case GButtonRelease:
305
 
        if (gtkwd_event->button == 1)
306
 
            if (state == BUTTON_EVENT_ACTION_STATE)
307
 
                wnck_window_stick (win);
308
 
        break;
309
 
    default:
310
 
        break;
311
 
    }
312
 
}
313
 
 
314
 
void
315
 
unshade_button_event (WnckWindow *win,
316
 
                      decor_event *gtkwd_event,
317
 
                      decor_event_type gtkwd_type)
318
 
{
319
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
320
 
    guint   state = d->button_states[BUTTON_UNSHADE];
321
 
 
322
 
    common_button_event (win, gtkwd_event, gtkwd_type,
323
 
                         BUTTON_UNSHADE, 1, _("Unshade"));
324
 
 
325
 
    switch (gtkwd_type) {
326
 
    case GButtonRelease:
327
 
        if (gtkwd_event->button == 1)
328
 
            if (state == BUTTON_EVENT_ACTION_STATE)
329
 
                wnck_window_unshade (win);
330
 
        break;
331
 
    default:
332
 
        break;
333
 
    }
334
 
}
335
 
 
336
 
void
337
 
unabove_button_event (WnckWindow *win,
338
 
                      decor_event *gtkwd_event,
339
 
                      decor_event_type gtkwd_type)
340
 
{
341
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
342
 
    guint   state = d->button_states[BUTTON_UNABOVE];
343
 
 
344
 
    common_button_event (win, gtkwd_event, gtkwd_type,
345
 
                         BUTTON_UNABOVE, 1, _("Unmake Above"));
346
 
 
347
 
    switch (gtkwd_type) {
348
 
    case GButtonRelease:
349
 
        if (gtkwd_event->button == 1)
350
 
            if (state == BUTTON_EVENT_ACTION_STATE)
351
 
#ifdef HAVE_LIBWNCK_2_18_1
352
 
                wnck_window_unmake_above (win);
353
 
#endif
354
 
        break;
355
 
    default:
356
 
        break;
357
 
    }
358
 
}
359
 
 
360
 
void
361
 
unstick_button_event (WnckWindow *win,
362
 
                      decor_event *gtkwd_event,
363
 
                      decor_event_type gtkwd_type)
364
 
{
365
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
366
 
    guint   state = d->button_states[BUTTON_UNSTICK];
367
 
 
368
 
    common_button_event (win, gtkwd_event, gtkwd_type,
369
 
                         BUTTON_UNSTICK, 1, _("Unstick"));
370
 
 
371
 
    switch (gtkwd_type) {
372
 
    case GButtonRelease:
373
 
        if (gtkwd_event->button == 1)
374
 
            if (state == BUTTON_EVENT_ACTION_STATE)
375
 
                wnck_window_unstick (win);
376
 
        break;
377
 
    default:
378
 
        break;
379
 
    }
380
 
}
381
 
 
382
 
void
383
 
handle_title_button_event (WnckWindow   *win,
384
 
                           int          action,
385
 
                           decor_event *gtkwd_event)
386
 
{
387
 
    switch (action) {
388
 
    case CLICK_ACTION_SHADE:
389
 
        if (wnck_window_is_shaded (win))
390
 
            wnck_window_unshade (win);
391
 
        else
392
 
            wnck_window_shade (win);
393
 
        break;
394
 
    case CLICK_ACTION_MAXIMIZE:
395
 
        if (wnck_window_is_maximized (win))
396
 
            wnck_window_unmaximize (win);
397
 
        else
398
 
            wnck_window_maximize (win);
399
 
        break;
400
 
    case CLICK_ACTION_MINIMIZE:
401
 
        if (!wnck_window_is_minimized (win))
402
 
            wnck_window_minimize (win);
403
 
        break;
404
 
    case CLICK_ACTION_RAISE:
405
 
        restack_window (win, Above);
406
 
        break;
407
 
    case CLICK_ACTION_LOWER:
408
 
        restack_window (win, Below);
409
 
        break;
410
 
    case CLICK_ACTION_MENU:
411
 
        action_menu_map (win, gtkwd_event->button, gtkwd_event->time);
412
 
        break;
413
 
    }
414
 
}
415
 
 
416
 
void
417
 
handle_mouse_wheel_title_event (WnckWindow   *win,
418
 
                                unsigned int button)
419
 
{
420
 
    switch (settings->wheel_action) {
421
 
    case WHEEL_ACTION_SHADE:
422
 
        if (button == 4)
423
 
        {
424
 
            if (!wnck_window_is_shaded (win))
425
 
                wnck_window_shade (win);
426
 
        }
427
 
        else if (button == 5)
428
 
        {
429
 
            if (wnck_window_is_shaded (win))
430
 
                wnck_window_unshade (win);
431
 
        }
432
 
        break;
433
 
    default:
434
 
        break;
435
 
    }
436
 
}
437
 
 
438
 
void
439
 
title_event (WnckWindow       *win,
440
 
             decor_event      *gtkwd_event,
441
 
             decor_event_type gtkwd_type)
442
 
{
443
 
    static int    last_button_num = 0;
444
 
    static Window last_button_xwindow = None;
445
 
    static Time   last_button_time = 0;
446
 
    static int    last_button_x = 0;
447
 
    static int    last_button_y = 0;
448
 
 
449
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
450
 
 
451
 
    if (d->frame_window && gtkwd_type == GEnterNotify)
452
 
    {
453
 
        GdkCursor* cursor = gdk_cursor_new (GDK_LEFT_PTR);
454
 
        gdk_window_set_cursor (d->frame_window, cursor);
455
 
        gdk_cursor_unref (cursor);
456
 
    }
457
 
 
458
 
    if (gtkwd_type != GButtonPress)
459
 
        return;
460
 
 
461
 
    if (gtkwd_event->button == 1)
462
 
    {
463
 
        if (gtkwd_event->button == last_button_num                      &&
464
 
            gtkwd_event->window == last_button_xwindow                  &&
465
 
            gtkwd_event->time < last_button_time + double_click_timeout &&
466
 
            dist (gtkwd_event->x, gtkwd_event->y,
467
 
                  last_button_x, last_button_y) < DOUBLE_CLICK_DISTANCE)
468
 
        {
469
 
            handle_title_button_event (win, settings->double_click_action,
470
 
                                       gtkwd_event);
471
 
 
472
 
            last_button_num     = 0;
473
 
            last_button_xwindow = None;
474
 
            last_button_time    = 0;
475
 
            last_button_x       = 0;
476
 
            last_button_y       = 0;
477
 
        }
478
 
        else
479
 
        {
480
 
            last_button_num     = gtkwd_event->button;
481
 
            last_button_xwindow = gtkwd_event->window;
482
 
            last_button_time    = gtkwd_event->time;
483
 
            last_button_x       = gtkwd_event->x;
484
 
            last_button_y       = gtkwd_event->y;
485
 
 
486
 
            restack_window (win, Above);
487
 
 
488
 
            move_resize_window (win, WM_MOVERESIZE_MOVE, gtkwd_event);
489
 
        }
490
 
    }
491
 
    else if (gtkwd_event->button == 2)
492
 
    {
493
 
        handle_title_button_event (win, settings->middle_click_action,
494
 
                                   gtkwd_event);
495
 
    }
496
 
    else if (gtkwd_event->button == 3)
497
 
    {
498
 
        handle_title_button_event (win, settings->right_click_action,
499
 
                                   gtkwd_event);
500
 
    }
501
 
    else if (gtkwd_event->button == 4 ||
502
 
             gtkwd_event->button == 5)
503
 
    {
504
 
        handle_mouse_wheel_title_event (win, gtkwd_event->button);
505
 
    }
506
 
}
507
 
 
508
 
void
509
 
frame_common_event (WnckWindow       *win,
510
 
                    int              direction,
511
 
                    decor_event      *gtkwd_event,
512
 
                    decor_event_type gtkwd_type)
513
 
{
514
 
 
515
 
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
516
 
 
517
 
    if (d->frame_window && gtkwd_type == GEnterNotify)
518
 
    {
519
 
        GdkCursor *cursor = NULL;
520
 
 
521
 
        switch (direction)
522
 
        {
523
 
            case WM_MOVERESIZE_SIZE_TOPLEFT:
524
 
                cursor = gdk_cursor_new (GDK_TOP_LEFT_CORNER);
525
 
                break;
526
 
            case WM_MOVERESIZE_SIZE_LEFT:
527
 
                cursor = gdk_cursor_new (GDK_LEFT_SIDE);
528
 
                break;
529
 
            case WM_MOVERESIZE_SIZE_BOTTOMLEFT:
530
 
                cursor = gdk_cursor_new (GDK_BOTTOM_LEFT_CORNER);
531
 
                break;
532
 
            case WM_MOVERESIZE_SIZE_BOTTOM:
533
 
                cursor = gdk_cursor_new (GDK_BOTTOM_SIDE);
534
 
                break;
535
 
            case WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
536
 
                cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER);
537
 
                break;
538
 
            case WM_MOVERESIZE_SIZE_RIGHT:
539
 
                cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
540
 
                break;
541
 
            case WM_MOVERESIZE_SIZE_TOPRIGHT:
542
 
                cursor = gdk_cursor_new (GDK_TOP_RIGHT_CORNER);
543
 
                break;
544
 
            case WM_MOVERESIZE_SIZE_TOP:
545
 
                cursor = gdk_cursor_new (GDK_TOP_SIDE);
546
 
                break;
547
 
            default:
548
 
                break;
549
 
        }
550
 
 
551
 
        if (cursor)
552
 
        {
553
 
            gdk_window_set_cursor (d->frame_window, cursor);
554
 
            gdk_cursor_unref (cursor);
555
 
        }
556
 
    }
557
 
 
558
 
    if (gtkwd_type != GButtonPress)
559
 
        return;
560
 
 
561
 
    switch (gtkwd_event->button) {
562
 
    case 1:
563
 
        move_resize_window (win, direction, gtkwd_event);
564
 
        restack_window (win, Above);
565
 
        break;
566
 
    case 2:
567
 
        handle_title_button_event (win, settings->middle_click_action,
568
 
                                   gtkwd_event);
569
 
        break;
570
 
    case 3:
571
 
        handle_title_button_event (win, settings->right_click_action,
572
 
                                   gtkwd_event);
573
 
        break;
574
 
    }
575
 
}
576
 
 
577
 
void
578
 
top_left_event (WnckWindow       *win,
579
 
                decor_event      *gtkwd_event,
580
 
                decor_event_type gtkwd_type)
581
 
{
582
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_TOPLEFT,
583
 
                        gtkwd_event, gtkwd_type);
584
 
}
585
 
 
586
 
void
587
 
top_event (WnckWindow       *win,
588
 
           decor_event      *gtkwd_event,
589
 
           decor_event_type gtkwd_type)
590
 
{
591
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_TOP,
592
 
                        gtkwd_event, gtkwd_type);
593
 
}
594
 
 
595
 
void
596
 
top_right_event (WnckWindow       *win,
597
 
                 decor_event      *gtkwd_event,
598
 
                 decor_event_type gtkwd_type)
599
 
{
600
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_TOPRIGHT,
601
 
                        gtkwd_event, gtkwd_type);
602
 
}
603
 
 
604
 
void
605
 
left_event (WnckWindow       *win,
606
 
            decor_event      *gtkwd_event,
607
 
            decor_event_type gtkwd_type)
608
 
{
609
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_LEFT,
610
 
                        gtkwd_event, gtkwd_type);
611
 
}
612
 
 
613
 
void
614
 
right_event (WnckWindow       *win,
615
 
             decor_event      *gtkwd_event,
616
 
             decor_event_type gtkwd_type)
617
 
{
618
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_RIGHT,
619
 
                        gtkwd_event, gtkwd_type);
620
 
}
621
 
 
622
 
void
623
 
bottom_left_event (WnckWindow *win,
624
 
                   decor_event *gtkwd_event,
625
 
                   decor_event_type gtkwd_type)
626
 
{
627
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMLEFT,
628
 
                        gtkwd_event, gtkwd_type);
629
 
}
630
 
 
631
 
void
632
 
bottom_event (WnckWindow *win,
633
 
              decor_event *gtkwd_event,
634
 
              decor_event_type gtkwd_type)
635
 
{
636
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOM,
637
 
                        gtkwd_event, gtkwd_type);
638
 
}
639
 
 
640
 
void
641
 
bottom_right_event (WnckWindow *win,
642
 
                    decor_event *gtkwd_event,
643
 
                    decor_event_type gtkwd_type)
644
 
{
645
 
    frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
646
 
                        gtkwd_event, gtkwd_type);
647
 
}
648
 
 
649
 
void
650
 
frame_window_realized (GtkWidget *widget,
651
 
                       gpointer  data)
652
 
{
653
 
    decor_t *d = (decor_t *) data;
654
 
 
655
 
    if (d)
656
 
    {
657
 
        GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
658
 
        gdk_window_reparent (gdk_frame_window, d->frame_window, 0, 0);
659
 
        gdk_window_lower (gdk_frame_window);
660
 
 
661
 
    }
662
 
}
663
 
 
664
 
event_callback
665
 
find_event_callback_for_point (decor_t *d,
666
 
                               int     x,
667
 
                               int     y,
668
 
                               Bool    *enter,
669
 
                               Bool    *leave,
670
 
                               BoxPtr  *entered_box)
671
 
{
672
 
    int    i, j;
673
 
    BoxPtr box;
674
 
 
675
 
    for (i = 0; i < BUTTON_NUM; i++)
676
 
    {
677
 
        box = &d->button_windows[i].pos;
678
 
        if (x >= box->x1 && x <= box->x2 &&
679
 
            y >= box->y1 && y <= box->y2)
680
 
        {
681
 
            if (d->last_pos_entered != box)
682
 
            {
683
 
                if (enter)
684
 
                    *enter = TRUE;
685
 
                if (leave && d->last_pos_entered)
686
 
                    *leave = TRUE;
687
 
                if (entered_box)
688
 
                    *entered_box = box;
689
 
            }
690
 
            return d->button_windows[i].callback;
691
 
        }
692
 
    }
693
 
 
694
 
    for (i = 0; i < 3; i++)
695
 
    {
696
 
        for (j = 0; j < 3; j++)
697
 
        {
698
 
            box = &d->event_windows[i][j].pos;
699
 
            if (x >= box->x1 && x <= box->x2 &&
700
 
                y >= box->y1 && y <= box->y2)
701
 
            {
702
 
                if (d->last_pos_entered != box)
703
 
                {
704
 
                    if (enter)
705
 
                        *enter = TRUE;
706
 
                    if (leave && d->last_pos_entered)
707
 
                        *leave = TRUE;
708
 
                    if (entered_box)
709
 
                        *entered_box = box;
710
 
                }
711
 
                return d->event_windows[i][j].callback;
712
 
            }
713
 
        }
714
 
    }
715
 
 
716
 
    return NULL;
717
 
}
718
 
 
719
 
event_callback
720
 
find_leave_event_callback (decor_t *d)
721
 
{
722
 
    int i, j;
723
 
 
724
 
    for (i = 0; i < BUTTON_NUM; i++)
725
 
    {
726
 
        if (d->last_pos_entered == &d->button_windows[i].pos)
727
 
            return d->button_windows[i].callback;
728
 
    }
729
 
 
730
 
    for (i = 0; i < 3; i++)
731
 
    {
732
 
        for (j = 0; j < 3; j++)
733
 
        {
734
 
            if (d->last_pos_entered == &d->event_windows[i][j].pos)
735
 
                return d->event_windows[i][j].callback;
736
 
        }
737
 
    }
738
 
 
739
 
    return NULL;
740
 
}
741
 
 
742
 
void
743
 
frame_handle_button_press (GtkWidget      *widget,
744
 
                           GdkEventButton *event,
745
 
                           gpointer       user_data)
746
 
{
747
 
    decor_t *d = (decor_t *) user_data;
748
 
 
749
 
    if (d)
750
 
    {
751
 
        /* Check to see where the event happened and fill out an appropriate
752
 
         * struct
753
 
         */
754
 
        event_callback cb;
755
 
 
756
 
        cb = find_event_callback_for_point (d, event->x, event->y,
757
 
                                            NULL, NULL, NULL);
758
 
 
759
 
        if (cb && d->decorated)
760
 
        {
761
 
            decor_event gtkwd_event;
762
 
 
763
 
            gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
764
 
            gtkwd_event.button = event->button;
765
 
            gtkwd_event.x      = event->x;
766
 
            gtkwd_event.y      = event->y;
767
 
            gtkwd_event.x_root = event->x_root;
768
 
            gtkwd_event.y_root = event->y_root;
769
 
            gtkwd_event.time   = event->time;
770
 
 
771
 
            (*cb) (d->win, &gtkwd_event, GButtonPress);
772
 
        }
773
 
    }
774
 
}
775
 
 
776
 
void
777
 
frame_handle_button_release (GtkWidget      *widget,
778
 
                             GdkEventButton *event,
779
 
                             gpointer       user_data)
780
 
{
781
 
    decor_t *d = (decor_t *) user_data;
782
 
 
783
 
    if (d)
784
 
    {
785
 
        event_callback cb;
786
 
 
787
 
        cb = find_event_callback_for_point (d, event->x, event->y,
788
 
                                            NULL, NULL, NULL);
789
 
 
790
 
        if (cb && d->decorated)
791
 
        {
792
 
            decor_event gtkwd_event;
793
 
 
794
 
            gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
795
 
            gtkwd_event.button = event->button;
796
 
            gtkwd_event.x      = event->x;
797
 
            gtkwd_event.y      = event->y;
798
 
            gtkwd_event.x_root = event->x_root;
799
 
            gtkwd_event.y_root = event->y_root;
800
 
            gtkwd_event.time   = event->time;
801
 
 
802
 
            (*cb) (d->win, &gtkwd_event, GButtonRelease);
803
 
        }
804
 
    }
805
 
}
806
 
 
807
 
void
808
 
frame_handle_motion (GtkWidget      *widget,
809
 
                     GdkEventMotion *event,
810
 
                     gpointer       user_data)
811
 
{
812
 
    decor_t *d = (decor_t *) user_data;
813
 
 
814
 
    if (d)
815
 
    {
816
 
        event_callback cb = NULL;
817
 
        Bool           send_enter = FALSE;
818
 
        Bool           send_leave = FALSE;
819
 
        BoxPtr         entered_box;
820
 
 
821
 
        cb = find_event_callback_for_point (d, event->x, event->y,
822
 
                                            &send_enter, &send_leave,
823
 
                                            &entered_box);
824
 
 
825
 
        if (cb && d->decorated)
826
 
        {
827
 
            decor_event gtkwd_event;
828
 
 
829
 
            gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
830
 
            gtkwd_event.x      = event->x;
831
 
            gtkwd_event.y      = event->y;
832
 
            gtkwd_event.x_root = event->x_root;
833
 
            gtkwd_event.y_root = event->y_root;
834
 
            gtkwd_event.time   = event->time;
835
 
 
836
 
            if (send_enter)
837
 
                (*cb) (d->win, &gtkwd_event, GEnterNotify);
838
 
 
839
 
            if (send_leave)
840
 
            {
841
 
                event_callback leave_cb;
842
 
 
843
 
                leave_cb = find_leave_event_callback (d);
844
 
 
845
 
                if (leave_cb)
846
 
                    (*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
847
 
 
848
 
            }
849
 
 
850
 
            if (send_enter)
851
 
                d->last_pos_entered = entered_box;
852
 
        }
853
 
        else if (d->last_pos_entered && d->decorated)
854
 
        {
855
 
            /* We are not in an event / button window but last_pos_entered
856
 
             * is still set, so send a GLeaveNotify to last_pos_entered
857
 
             * and set it to NULL
858
 
             */
859
 
 
860
 
            event_callback leave_cb;
861
 
 
862
 
            leave_cb = find_leave_event_callback (d);
863
 
 
864
 
            if (leave_cb)
865
 
            {
866
 
                decor_event    gtkwd_event;
867
 
 
868
 
                gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
869
 
                gtkwd_event.x      = event->x;
870
 
                gtkwd_event.y      = event->y;
871
 
                gtkwd_event.x_root = event->x_root;
872
 
                gtkwd_event.y_root = event->y_root;
873
 
                gtkwd_event.time   = event->time;
874
 
 
875
 
                (*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
876
 
            }
877
 
 
878
 
            d->last_pos_entered = NULL;
879
 
        }
880
 
    }
881
 
}
882
 
 
883
 
GdkFilterReturn
884
 
event_filter_func (GdkXEvent *gdkxevent,
885
 
                   GdkEvent  *event,
886
 
                   gpointer  data)
887
 
{
888
 
    Display    *xdisplay;
889
 
    GdkDisplay *gdkdisplay;
890
 
    XEvent     *xevent = gdkxevent;
891
 
    gulong     xid = 0;
892
 
    Window     select = 0;
893
 
 
894
 
    gdkdisplay = gdk_display_get_default ();
895
 
    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
896
 
 
897
 
    switch (xevent->type) {
898
 
    case CreateNotify:
899
 
        {
900
 
            if (!wnck_window_get (xevent->xcreatewindow.window))
901
 
            {
902
 
                GdkWindow *toplevel = create_foreign_window (xevent->xcreatewindow.window);
903
 
 
904
 
                if (toplevel)
905
 
                {
906
 
                    gdk_window_set_events (toplevel,
907
 
                                           gdk_window_get_events (toplevel) |
908
 
                                           GDK_PROPERTY_CHANGE_MASK);
909
 
 
910
 
                    /* check if the window is a switcher and update accordingly */
911
 
 
912
 
                    if (get_window_prop (xevent->xcreatewindow.window, select_window_atom, &select))
913
 
                        update_switcher_window (xevent->xcreatewindow.window, select);
914
 
                }
915
 
            }
916
 
        }
917
 
        break;
918
 
    case ButtonPress:
919
 
    case ButtonRelease:
920
 
        xid = (gulong)
921
 
            g_hash_table_lookup (frame_table,
922
 
                                 GINT_TO_POINTER (xevent->xbutton.window));
923
 
        break;
924
 
    case EnterNotify:
925
 
    case LeaveNotify:
926
 
        xid = (gulong)
927
 
            g_hash_table_lookup (frame_table,
928
 
                                 GINT_TO_POINTER (xevent->xcrossing.window));
929
 
        break;
930
 
    case MotionNotify:
931
 
        xid = (gulong)
932
 
            g_hash_table_lookup (frame_table,
933
 
                                 GINT_TO_POINTER (xevent->xmotion.window));
934
 
        break;
935
 
    case PropertyNotify:
936
 
        if (xevent->xproperty.atom == frame_input_window_atom)
937
 
        {
938
 
            WnckWindow *win;
939
 
 
940
 
            xid = xevent->xproperty.window;
941
 
 
942
 
            win = wnck_window_get (xid);
943
 
            if (win)
944
 
            {
945
 
                Window frame;
946
 
 
947
 
                if (!get_window_prop (xid, select_window_atom, &select))
948
 
                {
949
 
                    if (get_window_prop (xid, frame_input_window_atom, &frame))
950
 
                        add_frame_window (win, frame, FALSE);
951
 
                    else
952
 
                        remove_frame_window (win);
953
 
                }
954
 
            }
955
 
        }
956
 
        if (xevent->xproperty.atom == frame_output_window_atom)
957
 
        {
958
 
            WnckWindow *win;
959
 
 
960
 
            xid = xevent->xproperty.window;
961
 
 
962
 
            win = wnck_window_get (xid);
963
 
            if (win)
964
 
            {
965
 
                Window frame;
966
 
 
967
 
                if (!get_window_prop (xid, select_window_atom, &select))
968
 
                {
969
 
                    if (get_window_prop (xid, frame_output_window_atom, &frame))
970
 
                        add_frame_window (win, frame, TRUE);
971
 
                    else
972
 
                        remove_frame_window (win);
973
 
                }
974
 
            }
975
 
        }
976
 
        else if (xevent->xproperty.atom == compiz_shadow_info_atom ||
977
 
                 xevent->xproperty.atom == compiz_shadow_color_atom)
978
 
        {
979
 
            GdkScreen  *g_screen = gdk_display_get_default_screen (gdkdisplay);
980
 
            Window     root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (g_screen));
981
 
            WnckScreen *screen;
982
 
            
983
 
            screen = wnck_screen_get_for_root (root);
984
 
            
985
 
            if (screen)
986
 
            {
987
 
                if (shadow_property_changed (screen))
988
 
                    decorations_changed (screen);
989
 
            }
990
 
        }
991
 
        else if (xevent->xproperty.atom == mwm_hints_atom)
992
 
        {
993
 
            WnckWindow *win;
994
 
 
995
 
            xid = xevent->xproperty.window;
996
 
 
997
 
            win = wnck_window_get (xid);
998
 
            if (win)
999
 
            {
1000
 
                decor_t  *d = g_object_get_data (G_OBJECT (win), "decor");
1001
 
                gboolean decorated = FALSE;
1002
 
 
1003
 
                if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
1004
 
                    decorated = TRUE;
1005
 
 
1006
 
                if (decorated != d->decorated)
1007
 
                {
1008
 
                    d->decorated = decorated;
1009
 
                    if (decorated)
1010
 
                    {
1011
 
                        d->context = NULL;
1012
 
                        d->width = d->height = 0;
1013
 
 
1014
 
                        d->frame = gwd_get_decor_frame (get_frame_type (win));
1015
 
 
1016
 
                        update_window_decoration_size (win);
1017
 
                        update_event_windows (win);
1018
 
                    }
1019
 
                    else
1020
 
                    {
1021
 
                        gwd_decor_frame_unref (d->frame);
1022
 
                        d->frame = NULL;
1023
 
 
1024
 
                        gdk_error_trap_push ();
1025
 
                        XDeleteProperty (xdisplay, xid, win_decor_atom);
1026
 
                        gdk_display_sync (gdk_display_get_default ());
1027
 
                        gdk_error_trap_pop ();
1028
 
                    }
1029
 
                }
1030
 
            }
1031
 
        }
1032
 
        else if (xevent->xproperty.atom == select_window_atom)
1033
 
        {
1034
 
            Window select;
1035
 
 
1036
 
            if (get_window_prop (xevent->xproperty.window, select_window_atom, &select))
1037
 
                update_switcher_window (xevent->xproperty.window, select);
1038
 
        }
1039
 
        break;
1040
 
    case DestroyNotify:
1041
 
        g_hash_table_remove (frame_table,
1042
 
                             GINT_TO_POINTER (xevent->xproperty.window));
1043
 
        break;
1044
 
    case ClientMessage:
1045
 
        if (xevent->xclient.message_type == toolkit_action_atom)
1046
 
        {
1047
 
            long action;
1048
 
 
1049
 
            action = xevent->xclient.data.l[0];
1050
 
            if (action == toolkit_action_window_menu_atom)
1051
 
            {
1052
 
                WnckWindow *win;
1053
 
 
1054
 
                win = wnck_window_get (xevent->xclient.window);
1055
 
                if (win)
1056
 
                {
1057
 
                    action_menu_map (win,
1058
 
                                     xevent->xclient.data.l[2],
1059
 
                                     xevent->xclient.data.l[1]);
1060
 
                }
1061
 
            }
1062
 
            else if (action == toolkit_action_force_quit_dialog_atom)
1063
 
            {
1064
 
                WnckWindow *win;
1065
 
 
1066
 
                win = wnck_window_get (xevent->xclient.window);
1067
 
                if (win)
1068
 
                {
1069
 
                    if (xevent->xclient.data.l[2])
1070
 
                        show_force_quit_dialog (win,
1071
 
                                                xevent->xclient.data.l[1]);
1072
 
                    else
1073
 
                        hide_force_quit_dialog (win);
1074
 
                }
1075
 
            }
1076
 
        }
1077
 
    default:
1078
 
        break;
1079
 
    }
1080
 
 
1081
 
    if (xid)
1082
 
    {
1083
 
        WnckWindow *win;
1084
 
 
1085
 
        win = wnck_window_get (xid);
1086
 
        if (win)
1087
 
        {
1088
 
            decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1089
 
 
1090
 
            if (d->decorated)
1091
 
            {
1092
 
                gint             i, j;
1093
 
                event_callback   cb = NULL;
1094
 
                Window           w = xevent->xany.window;
1095
 
 
1096
 
                for (i = 0; i < 3; i++)
1097
 
                    for (j = 0; j < 3; j++)
1098
 
                        if (d->event_windows[i][j].window == w)
1099
 
                            cb = d->event_windows[i][j].callback;
1100
 
 
1101
 
                if (!cb)
1102
 
                {
1103
 
                    for (i = 0; i < BUTTON_NUM; i++)
1104
 
                        if (d->button_windows[i].window == w)
1105
 
                            cb = d->button_windows[i].callback;
1106
 
                }
1107
 
 
1108
 
                if (cb)
1109
 
                {
1110
 
                    decor_event      gtkwd_event;
1111
 
                    decor_event_type gtkwd_type;
1112
 
 
1113
 
                    gtkwd_event.window = w;
1114
 
 
1115
 
                    switch (xevent->type)
1116
 
                    {
1117
 
                        case ButtonPress:
1118
 
                        case ButtonRelease:
1119
 
                            if (xevent->type == ButtonPress)
1120
 
                                gtkwd_type = GButtonPress;
1121
 
                            else
1122
 
                                gtkwd_type = GButtonRelease;
1123
 
                            gtkwd_event.button = xevent->xbutton.button;
1124
 
                            gtkwd_event.x = xevent->xbutton.x;
1125
 
                            gtkwd_event.y = xevent->xbutton.y;
1126
 
                            gtkwd_event.x_root = xevent->xbutton.x_root;
1127
 
                            gtkwd_event.y_root = xevent->xbutton.y_root;
1128
 
                            gtkwd_event.time = xevent->xbutton.time;
1129
 
                            break;
1130
 
                        case EnterNotify:
1131
 
                        case LeaveNotify:
1132
 
                            if (xevent->type == EnterNotify)
1133
 
                                gtkwd_type = GEnterNotify;
1134
 
                            else
1135
 
                                gtkwd_type = GLeaveNotify;
1136
 
                            gtkwd_event.x = xevent->xcrossing.x;
1137
 
                            gtkwd_event.y = xevent->xcrossing.y;
1138
 
                            gtkwd_event.x_root = xevent->xcrossing.x_root;
1139
 
                            gtkwd_event.y_root = xevent->xcrossing.y_root;
1140
 
                            gtkwd_event.time = xevent->xcrossing.time;
1141
 
                            break;
1142
 
                        default:
1143
 
                            cb = NULL;
1144
 
                            break;
1145
 
                    }
1146
 
                    if (cb)
1147
 
                        (*cb) (win, &gtkwd_event, gtkwd_type);
1148
 
                }
1149
 
            }
1150
 
        }
1151
 
    }
1152
 
 
1153
 
    return GDK_FILTER_CONTINUE;
1154
 
}
1155
 
 
1156
 
GdkFilterReturn
1157
 
selection_event_filter_func (GdkXEvent *gdkxevent,
1158
 
                             GdkEvent  *event,
1159
 
                             gpointer  data)
1160
 
{
1161
 
    Display    *xdisplay;
1162
 
    GdkDisplay *gdkdisplay;
1163
 
    XEvent     *xevent = gdkxevent;
1164
 
    int        status;
1165
 
 
1166
 
    gdkdisplay = gdk_display_get_default ();
1167
 
    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
1168
 
 
1169
 
    switch (xevent->type) {
1170
 
    case SelectionRequest:
1171
 
        decor_handle_selection_request (xdisplay, xevent, dm_sn_timestamp);
1172
 
        break;
1173
 
    case SelectionClear:
1174
 
        status = decor_handle_selection_clear (xdisplay, xevent, 0);
1175
 
        if (status == DECOR_SELECTION_GIVE_UP)
1176
 
            gtk_main_quit ();
1177
 
    default:
1178
 
        break;
1179
 
    }
1180
 
 
1181
 
    return GDK_FILTER_CONTINUE;
1182
 
}