86
GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
87
GWDDecoration *d = gwd_decoration_get (w, w->type, w->state, w->actions);
88
guint state = w->frame_window->button_states[button];
90
if (gtkwd_type == GEnterNotify)
85
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
86
guint state = d->button_states[button];
88
handle_tooltip_event (win, gtkwd_event, gtkwd_type, state, tooltip);
90
if (d->frame_window && gtkwd_type == GEnterNotify)
93
GdkWindow* window = create_foreign_window (w->frame_window->xid);
97
cursor = gdk_cursor_new (GDK_LEFT_PTR);
98
gdk_error_trap_push ();
99
gdk_window_set_cursor (window, cursor);
100
gdk_cursor_unref (cursor);
101
gdk_display_sync (gdk_display_get_default ());
102
if (gdk_error_trap_pop ())
93
gdk_window_set_cursor (d->frame_window, cursor);
109
96
switch (gtkwd_type) {
110
97
case GButtonPress:
111
98
if (gtkwd_event->button <= max)
112
w->frame_window->button_states[button] |= PRESSED_EVENT_WINDOW;
99
d->button_states[button] |= PRESSED_EVENT_WINDOW;
114
101
case GButtonRelease:
115
102
if (gtkwd_event->button <= max)
116
w->frame_window->button_states[button] &= ~PRESSED_EVENT_WINDOW;
103
d->button_states[button] &= ~PRESSED_EVENT_WINDOW;
118
105
case GEnterNotify:
119
w->frame_window->button_states[button] |= IN_EVENT_WINDOW;
106
d->button_states[button] |= IN_EVENT_WINDOW;
121
108
case GLeaveNotify:
122
w->frame_window->button_states[button] &= ~IN_EVENT_WINDOW;
109
d->button_states[button] &= ~IN_EVENT_WINDOW;
128
if (state != w->frame_window->button_states[button]);
115
if (state != d->button_states[button])
129
116
queue_decor_draw (d);
371
354
decor_event *gtkwd_event,
372
355
decor_event_type gtkwd_type)
374
GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
375
guint state = w->frame_window->button_states[BUTTON_UNSTICK];
357
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
358
guint state = d->button_states[BUTTON_UNSTICK];
377
360
common_button_event (win, gtkwd_event, gtkwd_type,
378
361
BUTTON_UNSTICK, 1, _("Unstick"));
363
switch (gtkwd_type) {
382
364
case GButtonRelease:
383
365
if (gtkwd_event->button == 1)
384
366
if (state == BUTTON_EVENT_ACTION_STATE)
453
438
static int last_button_x = 0;
454
439
static int last_button_y = 0;
456
GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
441
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
458
if (gtkwd_type == GEnterNotify)
443
if (d->frame_window && gtkwd_type == GEnterNotify)
460
445
GdkCursor* cursor = gdk_cursor_new (GDK_LEFT_PTR);
461
GdkWindow* window = create_foreign_window (w->frame_window->xid);
464
gdk_error_trap_push ();
465
gdk_window_set_cursor (window, cursor);
466
gdk_cursor_unref (cursor);
467
gdk_display_sync (gdk_display_get_default ());
468
if (gdk_error_trap_pop ())
446
gdk_window_set_cursor (d->frame_window, cursor);
475
449
if (gtkwd_type != GButtonPress)
671
636
gtkwd_event, gtkwd_type);
640
frame_window_realized (GtkWidget *widget,
643
decor_t *d = (decor_t *) data;
647
GdkWindow *gdk_frame_window = gtk_widget_get_window (d->decor_window);
648
gdk_window_reparent (gdk_frame_window, d->frame_window, 0, 0);
649
gdk_window_lower (gdk_frame_window);
675
find_event_callback_for_point (GWDWindow *w,
680
event_window **entered)
655
find_event_callback_for_point (decor_t *d,
685
665
for (i = 0; i < BUTTON_NUM; i++)
687
ew = &w->frame_window->button_windows[i];
688
if (x >= ew->pos.x1 && x <= ew->pos.x2 &&
689
y >= ew->pos.y1 && y <= ew->pos.y2)
667
box = &d->button_windows[i].pos;
668
if (x >= box->x1 && x <= box->x2 &&
669
y >= box->y1 && y <= box->y2)
691
if (w->frame_window->last_entered != ew)
671
if (d->last_pos_entered != box)
695
if (leave && w->frame_window->last_entered)
675
if (leave && d->last_pos_entered)
700
return w->frame_window->button_windows[i].callback;
680
return d->button_windows[i].callback;
753
frame_handle_button_press (XButtonEvent *event,
733
frame_handle_button_press (GtkWidget *widget,
734
GdkEventButton *event,
756
GWDWindow *w = window;
737
decor_t *d = (decor_t *) user_data;
760
741
/* Check to see where the event happened and fill out an appropriate
763
744
event_callback cb;
765
cb = find_event_callback_for_point (w, event->x, event->y,
746
cb = find_event_callback_for_point (d, event->x, event->y,
766
747
NULL, NULL, NULL);
749
if (cb && d->decorated)
770
751
decor_event gtkwd_event;
772
last_clicked_frame = w;
773
gtkwd_event.window = w->frame_window->xid;
753
gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
774
754
gtkwd_event.button = event->button;
775
755
gtkwd_event.x = event->x;
776
756
gtkwd_event.y = event->y;
778
758
gtkwd_event.y_root = event->y_root;
779
759
gtkwd_event.time = event->time;
781
(*cb) (w->win, >kwd_event, GButtonPress);
761
(*cb) (d->win, >kwd_event, GButtonPress);
787
frame_handle_button_release (XButtonEvent *event,
767
frame_handle_button_release (GtkWidget *widget,
768
GdkEventButton *event,
790
GWDWindow *w = window;
771
decor_t *d = (decor_t *) user_data;
794
775
event_callback cb;
796
cb = find_event_callback_for_point (w, event->x, event->y,
777
cb = find_event_callback_for_point (d, event->x, event->y,
797
778
NULL, NULL, NULL);
799
last_clicked_frame = NULL;
801
if (cb && last_clicked_frame)
780
if (cb && d->decorated)
803
782
decor_event gtkwd_event;
805
gtkwd_event.window = w->frame_window->xid;
784
gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
806
785
gtkwd_event.button = event->button;
807
786
gtkwd_event.x = event->x;
808
787
gtkwd_event.y = event->y;
810
789
gtkwd_event.y_root = event->y_root;
811
790
gtkwd_event.time = event->time;
813
(*cb) (w->win, >kwd_event, GButtonRelease);
792
(*cb) (d->win, >kwd_event, GButtonRelease);
819
frame_handle_motion (XMotionEvent *event,
798
frame_handle_motion (GtkWidget *widget,
799
GdkEventMotion *event,
822
GWDWindow *w = window;
802
decor_t *d = (decor_t *) user_data;
826
806
event_callback cb = NULL;
827
807
Bool send_enter = FALSE;
828
808
Bool send_leave = FALSE;
829
event_window *entered_window;
831
cb = find_event_callback_for_point (w, event->x, event->y,
811
cb = find_event_callback_for_point (d, event->x, event->y,
832
812
&send_enter, &send_leave,
815
if (cb && d->decorated)
837
817
decor_event gtkwd_event;
839
gtkwd_event.window = w->frame_window->xid;
819
gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
840
820
gtkwd_event.x = event->x;
841
821
gtkwd_event.y = event->y;
842
822
gtkwd_event.x_root = event->x_root;
844
824
gtkwd_event.time = event->time;
847
(*cb) (w->win, >kwd_event, GEnterNotify);
827
(*cb) (d->win, >kwd_event, GEnterNotify);
851
831
event_callback leave_cb;
853
leave_cb = find_leave_event_callback (w);
833
leave_cb = find_leave_event_callback (d);
856
(*leave_cb) (w->win, >kwd_event, GLeaveNotify);
836
(*leave_cb) (d->win, >kwd_event, GLeaveNotify);
861
w->frame_window->last_entered = entered_window;
841
d->last_pos_entered = entered_box;
863
else if (w->frame_window->last_entered)
843
else if (d->last_pos_entered && d->decorated)
865
845
/* We are not in an event / button window but last_pos_entered
866
846
* is still set, so send a GLeaveNotify to last_pos_entered
870
850
event_callback leave_cb;
872
leave_cb = find_leave_event_callback (w);
852
leave_cb = find_leave_event_callback (d);
876
856
decor_event gtkwd_event;
878
gtkwd_event.window = w->frame_window->xid;
858
gtkwd_event.window = GDK_WINDOW_XID (d->frame_window);
879
859
gtkwd_event.x = event->x;
880
860
gtkwd_event.y = event->y;
881
861
gtkwd_event.x_root = event->x_root;
882
862
gtkwd_event.y_root = event->y_root;
883
863
gtkwd_event.time = event->time;
885
(*leave_cb) (w->win, >kwd_event, GLeaveNotify);
865
(*leave_cb) (d->win, >kwd_event, GLeaveNotify);
888
w->frame_window->last_entered = NULL;
868
d->last_pos_entered = NULL;
895
875
GdkEvent *gevent,
898
879
GdkDisplay *gdkdisplay;
900
881
Window select = 0;
901
882
XEvent *xevent = (XEvent *) event;
903
884
gdkdisplay = gdk_display_get_default ();
885
xdisplay = GDK_DISPLAY_XDISPLAY (gdkdisplay);
905
887
switch (xevent->type) {
906
888
case CreateNotify:
908
if (xevent->xcreatewindow.parent == gdk_x11_get_default_root_xwindow ())
890
if (!wnck_window_get (xevent->xcreatewindow.window))
910
892
GdkWindow *toplevel = create_foreign_window (xevent->xcreatewindow.window);
914
if (!wnck_window_get (xevent->xcreatewindow.window))
916
gdk_error_trap_push ();
917
gdk_window_set_events (toplevel,
918
gdk_window_get_events (toplevel) |
919
GDK_PROPERTY_CHANGE_MASK |
920
GDK_FOCUS_CHANGE_MASK);
921
gdk_display_sync (gdk_display_get_default ());
922
if (gdk_error_trap_pop ())
923
g_warning ("X Error while trying to set window events");
925
/* check if the window is a switcher and update accordingly */
927
if (get_window_prop (xevent->xcreatewindow.window, select_window_atom, &select))
928
update_switcher_window (xevent->xcreatewindow.window, select);
896
gdk_window_set_events (toplevel,
897
gdk_window_get_events (toplevel) |
898
GDK_PROPERTY_CHANGE_MASK);
906
g_hash_table_lookup (frame_table,
907
GINT_TO_POINTER (xevent->xbutton.window));
912
g_hash_table_lookup (frame_table,
913
GINT_TO_POINTER (xevent->xcrossing.window));
917
g_hash_table_lookup (frame_table,
918
GINT_TO_POINTER (xevent->xmotion.window));
934
920
case PropertyNotify:
935
921
if (xevent->xproperty.atom == frame_input_window_atom)
940
925
xid = xevent->xproperty.window;
946
window = (GWDWindow *) g_object_get_data (G_OBJECT (win), "decor");
948
if (window && window != switcher_window)
932
if (!get_window_prop (xid, select_window_atom, &select))
950
934
if (get_window_prop (xid, frame_input_window_atom, &frame))
952
if (window->frame_window)
953
gwd_frame_window_delete (window->frame_window, FALSE);
955
window->frame_window = NULL;
956
window->frame_window = gwd_frame_window_new (window, frame_input_window_atom, frame);
958
else if (window->frame_window)
960
gwd_frame_window_delete (window->frame_window, FALSE);
961
window->frame_window = NULL;
935
add_frame_window (win, frame, FALSE);
937
remove_frame_window (win);
966
941
if (xevent->xproperty.atom == frame_output_window_atom)
971
945
xid = xevent->xproperty.window;
977
window = (GWDWindow *) g_object_get_data (G_OBJECT (win), "decor");
979
if (window && window != switcher_window)
952
if (!get_window_prop (xid, select_window_atom, &select))
981
954
if (get_window_prop (xid, frame_output_window_atom, &frame))
983
if (window->frame_window)
984
gwd_frame_window_delete (window->frame_window, FALSE);
986
window->frame_window = NULL;
987
window->frame_window = gwd_frame_window_new (window, frame_output_window_atom, frame);
989
else if (window->frame_window)
991
gwd_frame_window_delete (window->frame_window, FALSE);
992
window->frame_window = NULL;
997
/* Read in the new mwm hints atom and store the value */
998
else if (xevent->xproperty.atom == mwm_hints_atom)
1000
WnckWindow *win = wnck_window_get (xevent->xproperty.window);
1003
GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
1005
w->mwm_prop = get_mwm_prop (xid);
1007
/* This window was decorated, ensure it has a decoration */
1008
if (w->mwm_prop & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
1009
gwd_decoration_get (w, w->type, w->state, w->actions);
1012
/* Read in the new emwh state hint and store the value */
1013
else if (xevent->xproperty.atom == net_wm_state_atom)
1015
WnckWindow *win = wnck_window_get (xevent->xproperty.window);
1019
GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
1024
old = w->net_wm_state_modal_atom;
1025
w->net_wm_state_modal_atom = get_atom_prop (xevent->xproperty.window,
1027
net_wm_state_modal_atom);
1029
if (w->net_wm_state_modal_atom != old)
1031
w->state = populate_frame_state (win);
1033
if (w->frame_window)
1034
update_event_windows (w->frame_window);
955
add_frame_window (win, frame, TRUE);
957
remove_frame_window (win);
1051
973
decorations_changed (screen);
976
else if (xevent->xproperty.atom == mwm_hints_atom)
980
xid = xevent->xproperty.window;
982
win = wnck_window_get (xid);
985
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
986
gboolean decorated = FALSE;
988
if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
991
if (decorated != d->decorated)
993
d->decorated = decorated;
997
d->width = d->height = 0;
999
d->frame = gwd_get_decor_frame (get_frame_type (win));
1001
update_window_decoration_size (win);
1002
update_event_windows (win);
1006
gwd_decor_frame_unref (d->frame);
1009
gdk_error_trap_push ();
1010
XDeleteProperty (xdisplay, xid, win_decor_atom);
1011
gdk_display_sync (gdk_display_get_default ());
1012
gdk_error_trap_pop ();
1054
1017
else if (xevent->xproperty.atom == select_window_atom)
1059
1022
update_switcher_window (xevent->xproperty.window, select);
1064
if (xevent->xfocus.mode == NotifyUngrab && last_clicked_frame)
1072
gdk_error_trap_push ();
1073
XQueryPointer (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
1074
last_clicked_frame->frame_window->xid,
1077
&x_root, &y_root, &x, &y, &mask);
1078
gdk_display_sync (gdk_display_get_default ());
1079
if (!gdk_error_trap_pop ())
1081
eb.type = ButtonRelease;
1082
eb.send_event = FALSE;
1083
eb.time = CurrentTime;
1086
eb.x_root = (double) x_root;
1087
eb.y_root = (double) y_root;
1091
if (last_clicked_frame)
1092
frame_handle_button_release (&eb, last_clicked_frame);
1097
GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xbutton.window));
1101
frame_handle_button_press ((XButtonEvent *) xevent, fw->window);
1108
GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xbutton.window));
1112
frame_handle_button_release ((XButtonEvent *) xevent, fw->window);
1119
GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xmotion.window));
1123
frame_handle_motion ((XMotionEvent *) xevent, fw->window);
1130
GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xcrossing.window));
1132
if (fw && xevent->xcrossing.mode == NotifyNormal)
1134
guint state[BUTTON_NUM];
1135
memcpy (state, fw->button_states, sizeof (guint) * BUTTON_NUM);
1137
GWDDecoration *d = gwd_decoration_get (fw->window,
1140
fw->window->actions);
1141
/* Reset button states as we are no longer in this frame window */
1142
memset (&fw->button_states, 0, sizeof (guint) * BUTTON_NUM);
1144
fw->last_entered = NULL;
1146
if (memcmp (state, fw->button_states, sizeof (guint) * BUTTON_NUM))
1147
queue_decor_draw (d);
1151
1025
case DestroyNotify:
1153
GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xdestroywindow.window));
1155
/* The parent window went away, we must remove our frame window */
1158
/* The reality is that we're racing with gtk to get rid of
1159
* the window before it dies server side, things could get
1161
gdk_error_trap_push ();
1162
gwd_frame_window_delete (fw, TRUE);
1163
gdk_error_trap_pop ();
1164
fw->window->frame_window = NULL;
1169
case ReparentNotify:
1171
GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xreparent.window));
1173
/* Compiz unreparented the decoration
1174
* so we must remove our frame window
1178
GdkWindow *backing_window = gtk_widget_get_window (GTK_WIDGET (fw->container));
1179
GdkWindow *compiz_frame_window = create_foreign_window (fw->xid);
1181
if (xevent->xreparent.parent == gdk_x11_get_default_root_xwindow ())
1183
gwd_frame_window_delete (fw, TRUE);
1188
static event_callback callback[3][3] = {
1189
{ top_left_event, top_event, top_right_event },
1190
{ left_event, title_event, right_event },
1191
{ bottom_left_event, bottom_event, bottom_right_event }
1193
static event_callback button_callback[BUTTON_NUM] = {
1201
unshade_button_event,
1202
unabove_button_event,
1203
unstick_button_event
1206
/* Checking if the window is mapped
1207
* seems to help in the case where
1208
* GDK sends the same event multiple times */
1209
if (compiz_frame_window &&
1211
!gdk_window_is_viewable (backing_window))
1213
gdk_window_set_events (compiz_frame_window,
1214
GDK_STRUCTURE_MASK |
1215
GDK_SUBSTRUCTURE_MASK);
1216
gdk_window_set_events (backing_window, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
1217
GDK_BUTTON_PRESS_MASK |
1218
GDK_BUTTON_RELEASE_MASK |
1219
GDK_LEAVE_NOTIFY_MASK);
1221
gtk_widget_show_all (GTK_WIDGET (fw->container));
1223
for (i = 0; i < 3; i++)
1224
for (j = 0; j < 3; j++)
1225
fw->event_windows[i][j].callback = callback[i][j];
1227
for (i = 0; i < BUTTON_NUM; i++)
1228
fw->button_windows[i].callback = button_callback[i];
1230
update_event_windows (fw);
1026
g_hash_table_remove (frame_table,
1027
GINT_TO_POINTER (xevent->xproperty.window));
1237
1029
case ClientMessage:
1238
1030
if (xevent->xclient.message_type == toolkit_action_atom)
1071
win = wnck_window_get (xid);
1074
decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
1079
event_callback cb = NULL;
1080
Window w = xevent->xany.window;
1082
for (i = 0; i < 3; i++)
1083
for (j = 0; j < 3; j++)
1084
if (d->event_windows[i][j].window == w)
1085
cb = d->event_windows[i][j].callback;
1089
for (i = 0; i < BUTTON_NUM; i++)
1090
if (d->button_windows[i].window == w)
1091
cb = d->button_windows[i].callback;
1096
decor_event gtkwd_event;
1097
decor_event_type gtkwd_type;
1099
gtkwd_event.window = w;
1101
switch (xevent->type)
1105
if (xevent->type == ButtonPress)
1106
gtkwd_type = GButtonPress;
1108
gtkwd_type = GButtonRelease;
1109
gtkwd_event.button = xevent->xbutton.button;
1110
gtkwd_event.x = xevent->xbutton.x;
1111
gtkwd_event.y = xevent->xbutton.y;
1112
gtkwd_event.x_root = xevent->xbutton.x_root;
1113
gtkwd_event.y_root = xevent->xbutton.y_root;
1114
gtkwd_event.time = xevent->xbutton.time;
1118
if (xevent->type == EnterNotify)
1119
gtkwd_type = GEnterNotify;
1121
gtkwd_type = GLeaveNotify;
1122
gtkwd_event.x = xevent->xcrossing.x;
1123
gtkwd_event.y = xevent->xcrossing.y;
1124
gtkwd_event.x_root = xevent->xcrossing.x_root;
1125
gtkwd_event.y_root = xevent->xcrossing.y_root;
1126
gtkwd_event.time = xevent->xcrossing.time;
1133
(*cb) (win, >kwd_event, gtkwd_type);
1278
1139
return GDK_FILTER_CONTINUE;