2
* Copyright © 2006 Novell, Inc.
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.
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.
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.
19
* Author: David Reveman <davidr@novell.com>
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>
26
#include "gtk-window-decorator.h"
29
move_resize_window (WnckWindow *win,
31
decor_event *gtkwd_event)
34
GdkDisplay *gdkdisplay;
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));
44
if (action_menu_mapped)
46
gtk_object_destroy (GTK_OBJECT (action_menu));
47
action_menu_mapped = FALSE;
52
ev.xclient.type = ClientMessage;
53
ev.xclient.display = xdisplay;
55
ev.xclient.serial = 0;
56
ev.xclient.send_event = TRUE;
58
ev.xclient.window = wnck_window_get_xid (win);
59
ev.xclient.message_type = wm_move_resize_atom;
60
ev.xclient.format = 32;
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;
68
XUngrabPointer (xdisplay, gtkwd_event->time);
69
XUngrabKeyboard (xdisplay, gtkwd_event->time);
71
XSendEvent (xdisplay, xroot, FALSE,
72
SubstructureRedirectMask | SubstructureNotifyMask,
75
XSync (xdisplay, FALSE);
79
common_button_event (WnckWindow *win,
80
decor_event *gtkwd_event,
81
decor_event_type gtkwd_type,
86
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
87
guint state = d->button_states[button];
89
if (settings->use_tooltips)
90
handle_tooltip_event (win, gtkwd_event, gtkwd_type, state, tooltip);
92
if (d->frame_window && gtkwd_type == GEnterNotify)
95
cursor = gdk_cursor_new (GDK_LEFT_PTR);
96
gdk_window_set_cursor (d->frame_window, cursor);
97
gdk_cursor_unref (cursor);
100
switch (gtkwd_type) {
102
if (gtkwd_event->button <= max)
103
d->button_states[button] |= PRESSED_EVENT_WINDOW;
106
if (gtkwd_event->button <= max)
107
d->button_states[button] &= ~PRESSED_EVENT_WINDOW;
110
d->button_states[button] |= IN_EVENT_WINDOW;
113
d->button_states[button] &= ~IN_EVENT_WINDOW;
119
if (state != d->button_states[button])
120
queue_decor_draw (d);
123
#define BUTTON_EVENT_ACTION_STATE (PRESSED_EVENT_WINDOW | IN_EVENT_WINDOW)
126
close_button_event (WnckWindow *win,
127
decor_event *gtkwd_event,
128
decor_event_type gtkwd_type)
130
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
131
guint state = d->button_states[BUTTON_CLOSE];
133
common_button_event (win, gtkwd_event, gtkwd_type,
134
BUTTON_CLOSE, 1, _("Close Window"));
136
switch (gtkwd_type) {
138
if (gtkwd_event->button == 1)
139
if (state == BUTTON_EVENT_ACTION_STATE)
140
wnck_window_close (win, gtkwd_event->time);
148
max_button_event (WnckWindow *win,
149
decor_event *gtkwd_event,
150
decor_event_type gtkwd_type)
152
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
153
guint state = d->button_states[BUTTON_MAX];
155
if (wnck_window_is_maximized (win))
156
common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
157
3, _("Unmaximize Window"));
159
common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
160
3, _("Maximize Window"));
162
switch (gtkwd_type) {
164
if (gtkwd_event->button <= 3)
166
if (state == BUTTON_EVENT_ACTION_STATE)
168
if (gtkwd_event->button == 1)
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);
177
wnck_window_maximize (win);
179
else if (gtkwd_event->button == 2)
181
if (wnck_window_is_maximized_vertically (win))
182
wnck_window_unmaximize_vertically (win);
184
wnck_window_maximize_vertically (win);
186
else if (gtkwd_event->button == 3)
188
if (wnck_window_is_maximized_horizontally (win))
189
wnck_window_unmaximize_horizontally (win);
191
wnck_window_maximize_horizontally (win);
202
min_button_event (WnckWindow *win,
203
decor_event *gtkwd_event,
204
decor_event_type gtkwd_type)
206
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
207
guint state = d->button_states[BUTTON_MIN];
209
common_button_event (win, gtkwd_event, gtkwd_type,
210
BUTTON_MIN, 1, _("Minimize Window"));
212
switch (gtkwd_type) {
214
if (gtkwd_event->button == 1)
215
if (state == BUTTON_EVENT_ACTION_STATE)
216
wnck_window_minimize (win);
224
menu_button_event (WnckWindow *win,
225
decor_event *gtkwd_event,
226
decor_event_type gtkwd_type)
229
common_button_event (win, gtkwd_event, gtkwd_type,
230
BUTTON_MENU, 1, _("Window Menu"));
232
switch (gtkwd_type) {
234
if (gtkwd_event->button == 1)
235
action_menu_map (win,
245
shade_button_event (WnckWindow *win,
246
decor_event *gtkwd_event,
247
decor_event_type gtkwd_type)
249
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
250
guint state = d->button_states[BUTTON_SHADE];
252
common_button_event (win, gtkwd_event, gtkwd_type,
253
BUTTON_SHADE, 1, _("Shade"));
255
switch (gtkwd_type) {
257
if (gtkwd_event->button == 1)
259
if (state == BUTTON_EVENT_ACTION_STATE)
260
wnck_window_shade (win);
269
above_button_event (WnckWindow *win,
270
decor_event *gtkwd_event,
271
decor_event_type gtkwd_type)
273
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
274
guint state = d->button_states[BUTTON_ABOVE];
276
common_button_event (win, gtkwd_event, gtkwd_type,
277
BUTTON_ABOVE, 1, _("Make Above"));
279
switch (gtkwd_type) {
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);
293
stick_button_event (WnckWindow *win,
294
decor_event *gtkwd_event,
295
decor_event_type gtkwd_type)
297
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
298
guint state = d->button_states[BUTTON_STICK];
300
common_button_event (win, gtkwd_event, gtkwd_type,
301
BUTTON_STICK, 1, _("Stick"));
303
switch (gtkwd_type) {
305
if (gtkwd_event->button == 1)
306
if (state == BUTTON_EVENT_ACTION_STATE)
307
wnck_window_stick (win);
315
unshade_button_event (WnckWindow *win,
316
decor_event *gtkwd_event,
317
decor_event_type gtkwd_type)
319
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
320
guint state = d->button_states[BUTTON_UNSHADE];
322
common_button_event (win, gtkwd_event, gtkwd_type,
323
BUTTON_UNSHADE, 1, _("Unshade"));
325
switch (gtkwd_type) {
327
if (gtkwd_event->button == 1)
328
if (state == BUTTON_EVENT_ACTION_STATE)
329
wnck_window_unshade (win);
337
unabove_button_event (WnckWindow *win,
338
decor_event *gtkwd_event,
339
decor_event_type gtkwd_type)
341
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
342
guint state = d->button_states[BUTTON_UNABOVE];
344
common_button_event (win, gtkwd_event, gtkwd_type,
345
BUTTON_UNABOVE, 1, _("Unmake Above"));
347
switch (gtkwd_type) {
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);
361
unstick_button_event (WnckWindow *win,
362
decor_event *gtkwd_event,
363
decor_event_type gtkwd_type)
365
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
366
guint state = d->button_states[BUTTON_UNSTICK];
368
common_button_event (win, gtkwd_event, gtkwd_type,
369
BUTTON_UNSTICK, 1, _("Unstick"));
371
switch (gtkwd_type) {
373
if (gtkwd_event->button == 1)
374
if (state == BUTTON_EVENT_ACTION_STATE)
375
wnck_window_unstick (win);
383
handle_title_button_event (WnckWindow *win,
385
decor_event *gtkwd_event)
388
case CLICK_ACTION_SHADE:
389
if (wnck_window_is_shaded (win))
390
wnck_window_unshade (win);
392
wnck_window_shade (win);
394
case CLICK_ACTION_MAXIMIZE:
395
if (wnck_window_is_maximized (win))
396
wnck_window_unmaximize (win);
398
wnck_window_maximize (win);
400
case CLICK_ACTION_MINIMIZE:
401
if (!wnck_window_is_minimized (win))
402
wnck_window_minimize (win);
404
case CLICK_ACTION_RAISE:
405
restack_window (win, Above);
407
case CLICK_ACTION_LOWER:
408
restack_window (win, Below);
410
case CLICK_ACTION_MENU:
411
action_menu_map (win, gtkwd_event->button, gtkwd_event->time);
417
handle_mouse_wheel_title_event (WnckWindow *win,
420
switch (settings->wheel_action) {
421
case WHEEL_ACTION_SHADE:
424
if (!wnck_window_is_shaded (win))
425
wnck_window_shade (win);
427
else if (button == 5)
429
if (wnck_window_is_shaded (win))
430
wnck_window_unshade (win);
439
title_event (WnckWindow *win,
440
decor_event *gtkwd_event,
441
decor_event_type gtkwd_type)
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;
449
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
451
if (d->frame_window && gtkwd_type == GEnterNotify)
453
GdkCursor* cursor = gdk_cursor_new (GDK_LEFT_PTR);
454
gdk_window_set_cursor (d->frame_window, cursor);
455
gdk_cursor_unref (cursor);
458
if (gtkwd_type != GButtonPress)
461
if (gtkwd_event->button == 1)
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)
469
handle_title_button_event (win, settings->double_click_action,
473
last_button_xwindow = None;
474
last_button_time = 0;
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;
486
restack_window (win, Above);
488
move_resize_window (win, WM_MOVERESIZE_MOVE, gtkwd_event);
491
else if (gtkwd_event->button == 2)
493
handle_title_button_event (win, settings->middle_click_action,
496
else if (gtkwd_event->button == 3)
498
handle_title_button_event (win, settings->right_click_action,
501
else if (gtkwd_event->button == 4 ||
502
gtkwd_event->button == 5)
504
handle_mouse_wheel_title_event (win, gtkwd_event->button);
509
frame_common_event (WnckWindow *win,
511
decor_event *gtkwd_event,
512
decor_event_type gtkwd_type)
515
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
517
if (d->frame_window && gtkwd_type == GEnterNotify)
519
GdkCursor *cursor = NULL;
523
case WM_MOVERESIZE_SIZE_TOPLEFT:
524
cursor = gdk_cursor_new (GDK_TOP_LEFT_CORNER);
526
case WM_MOVERESIZE_SIZE_LEFT:
527
cursor = gdk_cursor_new (GDK_LEFT_SIDE);
529
case WM_MOVERESIZE_SIZE_BOTTOMLEFT:
530
cursor = gdk_cursor_new (GDK_BOTTOM_LEFT_CORNER);
532
case WM_MOVERESIZE_SIZE_BOTTOM:
533
cursor = gdk_cursor_new (GDK_BOTTOM_SIDE);
535
case WM_MOVERESIZE_SIZE_BOTTOMRIGHT:
536
cursor = gdk_cursor_new (GDK_BOTTOM_RIGHT_CORNER);
538
case WM_MOVERESIZE_SIZE_RIGHT:
539
cursor = gdk_cursor_new (GDK_RIGHT_SIDE);
541
case WM_MOVERESIZE_SIZE_TOPRIGHT:
542
cursor = gdk_cursor_new (GDK_TOP_RIGHT_CORNER);
544
case WM_MOVERESIZE_SIZE_TOP:
545
cursor = gdk_cursor_new (GDK_TOP_SIDE);
553
gdk_window_set_cursor (d->frame_window, cursor);
554
gdk_cursor_unref (cursor);
558
if (gtkwd_type != GButtonPress)
561
switch (gtkwd_event->button) {
563
move_resize_window (win, direction, gtkwd_event);
564
restack_window (win, Above);
567
handle_title_button_event (win, settings->middle_click_action,
571
handle_title_button_event (win, settings->right_click_action,
578
top_left_event (WnckWindow *win,
579
decor_event *gtkwd_event,
580
decor_event_type gtkwd_type)
582
frame_common_event (win, WM_MOVERESIZE_SIZE_TOPLEFT,
583
gtkwd_event, gtkwd_type);
587
top_event (WnckWindow *win,
588
decor_event *gtkwd_event,
589
decor_event_type gtkwd_type)
591
frame_common_event (win, WM_MOVERESIZE_SIZE_TOP,
592
gtkwd_event, gtkwd_type);
596
top_right_event (WnckWindow *win,
597
decor_event *gtkwd_event,
598
decor_event_type gtkwd_type)
600
frame_common_event (win, WM_MOVERESIZE_SIZE_TOPRIGHT,
601
gtkwd_event, gtkwd_type);
605
left_event (WnckWindow *win,
606
decor_event *gtkwd_event,
607
decor_event_type gtkwd_type)
609
frame_common_event (win, WM_MOVERESIZE_SIZE_LEFT,
610
gtkwd_event, gtkwd_type);
614
right_event (WnckWindow *win,
615
decor_event *gtkwd_event,
616
decor_event_type gtkwd_type)
618
frame_common_event (win, WM_MOVERESIZE_SIZE_RIGHT,
619
gtkwd_event, gtkwd_type);
623
bottom_left_event (WnckWindow *win,
624
decor_event *gtkwd_event,
625
decor_event_type gtkwd_type)
627
frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMLEFT,
628
gtkwd_event, gtkwd_type);
632
bottom_event (WnckWindow *win,
633
decor_event *gtkwd_event,
634
decor_event_type gtkwd_type)
636
frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOM,
637
gtkwd_event, gtkwd_type);
641
bottom_right_event (WnckWindow *win,
642
decor_event *gtkwd_event,
643
decor_event_type gtkwd_type)
645
frame_common_event (win, WM_MOVERESIZE_SIZE_BOTTOMRIGHT,
646
gtkwd_event, gtkwd_type);
650
frame_window_realized (GtkWidget *widget,
653
decor_t *d = (decor_t *) data;
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);
665
find_event_callback_for_point (decor_t *d,
675
for (i = 0; i < BUTTON_NUM; i++)
677
box = &d->button_windows[i].pos;
678
if (x >= box->x1 && x <= box->x2 &&
679
y >= box->y1 && y <= box->y2)
681
if (d->last_pos_entered != box)
685
if (leave && d->last_pos_entered)
690
return d->button_windows[i].callback;
694
for (i = 0; i < 3; i++)
696
for (j = 0; j < 3; j++)
698
box = &d->event_windows[i][j].pos;
699
if (x >= box->x1 && x <= box->x2 &&
700
y >= box->y1 && y <= box->y2)
702
if (d->last_pos_entered != box)
706
if (leave && d->last_pos_entered)
711
return d->event_windows[i][j].callback;
720
find_leave_event_callback (decor_t *d)
724
for (i = 0; i < BUTTON_NUM; i++)
726
if (d->last_pos_entered == &d->button_windows[i].pos)
727
return d->button_windows[i].callback;
730
for (i = 0; i < 3; i++)
732
for (j = 0; j < 3; j++)
734
if (d->last_pos_entered == &d->event_windows[i][j].pos)
735
return d->event_windows[i][j].callback;
743
frame_handle_button_press (GtkWidget *widget,
744
GdkEventButton *event,
747
decor_t *d = (decor_t *) user_data;
751
/* Check to see where the event happened and fill out an appropriate
756
cb = find_event_callback_for_point (d, event->x, event->y,
759
if (cb && d->decorated)
761
decor_event gtkwd_event;
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;
771
(*cb) (d->win, >kwd_event, GButtonPress);
777
frame_handle_button_release (GtkWidget *widget,
778
GdkEventButton *event,
781
decor_t *d = (decor_t *) user_data;
787
cb = find_event_callback_for_point (d, event->x, event->y,
790
if (cb && d->decorated)
792
decor_event gtkwd_event;
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;
802
(*cb) (d->win, >kwd_event, GButtonRelease);
808
frame_handle_motion (GtkWidget *widget,
809
GdkEventMotion *event,
812
decor_t *d = (decor_t *) user_data;
816
event_callback cb = NULL;
817
Bool send_enter = FALSE;
818
Bool send_leave = FALSE;
821
cb = find_event_callback_for_point (d, event->x, event->y,
822
&send_enter, &send_leave,
825
if (cb && d->decorated)
827
decor_event gtkwd_event;
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;
837
(*cb) (d->win, >kwd_event, GEnterNotify);
841
event_callback leave_cb;
843
leave_cb = find_leave_event_callback (d);
846
(*leave_cb) (d->win, >kwd_event, GLeaveNotify);
851
d->last_pos_entered = entered_box;
853
else if (d->last_pos_entered && d->decorated)
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
860
event_callback leave_cb;
862
leave_cb = find_leave_event_callback (d);
866
decor_event gtkwd_event;
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;
875
(*leave_cb) (d->win, >kwd_event, GLeaveNotify);
878
d->last_pos_entered = NULL;
884
event_filter_func (GdkXEvent *gdkxevent,
889
GdkDisplay *gdkdisplay;
890
XEvent *xevent = gdkxevent;
894
gdkdisplay = gdk_display_get_default ();
895
xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
897
switch (xevent->type) {
900
if (!wnck_window_get (xevent->xcreatewindow.window))
902
GdkWindow *toplevel = create_foreign_window (xevent->xcreatewindow.window);
906
gdk_window_set_events (toplevel,
907
gdk_window_get_events (toplevel) |
908
GDK_PROPERTY_CHANGE_MASK);
910
/* check if the window is a switcher and update accordingly */
912
if (get_window_prop (xevent->xcreatewindow.window, select_window_atom, &select))
913
update_switcher_window (xevent->xcreatewindow.window, select);
921
g_hash_table_lookup (frame_table,
922
GINT_TO_POINTER (xevent->xbutton.window));
927
g_hash_table_lookup (frame_table,
928
GINT_TO_POINTER (xevent->xcrossing.window));
932
g_hash_table_lookup (frame_table,
933
GINT_TO_POINTER (xevent->xmotion.window));
936
if (xevent->xproperty.atom == frame_input_window_atom)
940
xid = xevent->xproperty.window;
942
win = wnck_window_get (xid);
947
if (!get_window_prop (xid, select_window_atom, &select))
949
if (get_window_prop (xid, frame_input_window_atom, &frame))
950
add_frame_window (win, frame, FALSE);
952
remove_frame_window (win);
956
if (xevent->xproperty.atom == frame_output_window_atom)
960
xid = xevent->xproperty.window;
962
win = wnck_window_get (xid);
967
if (!get_window_prop (xid, select_window_atom, &select))
969
if (get_window_prop (xid, frame_output_window_atom, &frame))
970
add_frame_window (win, frame, TRUE);
972
remove_frame_window (win);
976
else if (xevent->xproperty.atom == compiz_shadow_info_atom ||
977
xevent->xproperty.atom == compiz_shadow_color_atom)
979
GdkScreen *g_screen = gdk_display_get_default_screen (gdkdisplay);
980
Window root = GDK_WINDOW_XWINDOW (gdk_screen_get_root_window (g_screen));
983
screen = wnck_screen_get_for_root (root);
987
if (shadow_property_changed (screen))
988
decorations_changed (screen);
991
else if (xevent->xproperty.atom == mwm_hints_atom)
995
xid = xevent->xproperty.window;
997
win = wnck_window_get (xid);
1000
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1001
gboolean decorated = FALSE;
1003
if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
1006
if (decorated != d->decorated)
1008
d->decorated = decorated;
1012
d->width = d->height = 0;
1014
d->frame = gwd_get_decor_frame (get_frame_type (win));
1016
update_window_decoration_size (win);
1017
update_event_windows (win);
1021
gwd_decor_frame_unref (d->frame);
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 ();
1032
else if (xevent->xproperty.atom == select_window_atom)
1036
if (get_window_prop (xevent->xproperty.window, select_window_atom, &select))
1037
update_switcher_window (xevent->xproperty.window, select);
1041
g_hash_table_remove (frame_table,
1042
GINT_TO_POINTER (xevent->xproperty.window));
1045
if (xevent->xclient.message_type == toolkit_action_atom)
1049
action = xevent->xclient.data.l[0];
1050
if (action == toolkit_action_window_menu_atom)
1054
win = wnck_window_get (xevent->xclient.window);
1057
action_menu_map (win,
1058
xevent->xclient.data.l[2],
1059
xevent->xclient.data.l[1]);
1062
else if (action == toolkit_action_force_quit_dialog_atom)
1066
win = wnck_window_get (xevent->xclient.window);
1069
if (xevent->xclient.data.l[2])
1070
show_force_quit_dialog (win,
1071
xevent->xclient.data.l[1]);
1073
hide_force_quit_dialog (win);
1085
win = wnck_window_get (xid);
1088
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1093
event_callback cb = NULL;
1094
Window w = xevent->xany.window;
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;
1103
for (i = 0; i < BUTTON_NUM; i++)
1104
if (d->button_windows[i].window == w)
1105
cb = d->button_windows[i].callback;
1110
decor_event gtkwd_event;
1111
decor_event_type gtkwd_type;
1113
gtkwd_event.window = w;
1115
switch (xevent->type)
1119
if (xevent->type == ButtonPress)
1120
gtkwd_type = GButtonPress;
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;
1132
if (xevent->type == EnterNotify)
1133
gtkwd_type = GEnterNotify;
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;
1147
(*cb) (win, >kwd_event, gtkwd_type);
1153
return GDK_FILTER_CONTINUE;
1157
selection_event_filter_func (GdkXEvent *gdkxevent,
1162
GdkDisplay *gdkdisplay;
1163
XEvent *xevent = gdkxevent;
1166
gdkdisplay = gdk_display_get_default ();
1167
xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
1169
switch (xevent->type) {
1170
case SelectionRequest:
1171
decor_handle_selection_request (xdisplay, xevent, dm_sn_timestamp);
1173
case SelectionClear:
1174
status = decor_handle_selection_clear (xdisplay, xevent, 0);
1175
if (status == DECOR_SELECTION_GIVE_UP)
1181
return GDK_FILTER_CONTINUE;