~compiz-team/compiz-core/oneiric.force_output_detection

« back to all changes in this revision

Viewing changes to gtk/window-decorator/src/events.c

  • Committer: Sam Spilsbury
  • Date: 2011-08-19 18:23:21 UTC
  • Revision ID: sam.spilsbury@canonical.com-20110819182321-iqbupv0eodx3jlyb
Unmerge the new decorator

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
 *        Authored By: Sam Spilsbury <sam.spilsbury@canonical.com>
24
24
 */
25
25
 
26
 
#include "gtk-window-decorator.h"
27
 
 
 
26
#include "gtk-window-decorator.h" 
28
27
void
29
28
move_resize_window (WnckWindow *win,
30
29
                    int        direction,
37
36
    XEvent     ev;
38
37
 
39
38
    gdkdisplay = gdk_display_get_default ();
40
 
    xdisplay   = gdk_x11_display_get_xdisplay (gdkdisplay);
 
39
    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
41
40
    screen     = gdk_display_get_default_screen (gdkdisplay);
42
41
    xroot      = RootWindowOfScreen (gdk_x11_screen_get_xscreen (screen));
43
42
 
83
82
                     int        max,
84
83
                     char       *tooltip)
85
84
{
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];
89
 
 
90
 
    if (gtkwd_type == GEnterNotify)
 
85
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
86
    guint   state = d->button_states[button];
 
87
 
 
88
    handle_tooltip_event (win, gtkwd_event, gtkwd_type, state, tooltip);
 
89
 
 
90
    if (d->frame_window && gtkwd_type == GEnterNotify)
91
91
    {
92
92
        GdkCursor* cursor;
93
 
        GdkWindow* window = create_foreign_window (w->frame_window->xid);
94
 
 
95
 
        if (window)
96
 
        {
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 ())
103
 
                return;
104
 
        }
105
 
        else
106
 
            return;
 
93
        gdk_window_set_cursor (d->frame_window, cursor);
107
94
    }
108
95
 
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;
113
100
        break;
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;
117
104
        break;
118
105
    case GEnterNotify:
119
 
        w->frame_window->button_states[button] |= IN_EVENT_WINDOW;
 
106
        d->button_states[button] |= IN_EVENT_WINDOW;
120
107
        break;
121
108
    case GLeaveNotify:
122
 
        w->frame_window->button_states[button] &= ~IN_EVENT_WINDOW;
 
109
        d->button_states[button] &= ~IN_EVENT_WINDOW;
123
110
        break;
124
111
    default:
125
112
        break;
126
113
    }
127
114
 
128
 
    if (state != w->frame_window->button_states[button]);
 
115
    if (state != d->button_states[button])
129
116
        queue_decor_draw (d);
130
117
}
131
118
 
136
123
                    decor_event *gtkwd_event,
137
124
                    decor_event_type gtkwd_type)
138
125
{
139
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
140
 
    guint   state = w->frame_window->button_states[BUTTON_CLOSE];
 
126
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
127
    guint   state = d->button_states[BUTTON_CLOSE];
141
128
 
142
129
    common_button_event (win, gtkwd_event, gtkwd_type,
143
130
                         BUTTON_CLOSE, 1, _("Close Window"));
158
145
                  decor_event *gtkwd_event,
159
146
                  decor_event_type gtkwd_type)
160
147
{
161
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
162
 
    guint   state = w->frame_window->button_states[BUTTON_MAX];
 
148
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
149
    guint   state = d->button_states[BUTTON_MAX];
163
150
 
164
151
    if (wnck_window_is_maximized (win))
165
152
        common_button_event (win, gtkwd_event, gtkwd_type, BUTTON_MAX,
208
195
                  decor_event *gtkwd_event,
209
196
                  decor_event_type gtkwd_type)
210
197
{
211
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
212
 
    guint   state = w->frame_window->button_states[BUTTON_MIN];
 
198
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
199
    guint   state = d->button_states[BUTTON_MIN];
213
200
 
214
201
    common_button_event (win, gtkwd_event, gtkwd_type,
215
202
                         BUTTON_MIN, 1, _("Minimize Window"));
226
213
}
227
214
 
228
215
void
229
 
menu_button_event (WnckWindow  *win,
 
216
menu_button_event (WnckWindow *win,
230
217
                   decor_event *gtkwd_event,
231
218
                   decor_event_type gtkwd_type)
232
219
{
237
224
    switch (gtkwd_type) {
238
225
    case GButtonPress:
239
226
        if (gtkwd_event->button == 1)
240
 
        {
241
 
            GWDWindow *window = g_object_get_data (G_OBJECT (win), "decor");
242
 
 
243
 
            action_menu_map (window->frame_window->decor,
 
227
            action_menu_map (win,
244
228
                             gtkwd_event->button,
245
229
                             gtkwd_event->time);
246
 
        }
247
230
        break;
248
231
    default:
249
232
        break;
255
238
                    decor_event *gtkwd_event,
256
239
                    decor_event_type gtkwd_type)
257
240
{
258
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
259
 
    guint   state = w->frame_window->button_states[BUTTON_SHADE];
 
241
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
242
    guint   state = d->button_states[BUTTON_SHADE];
260
243
 
261
244
    common_button_event (win, gtkwd_event, gtkwd_type,
262
245
                         BUTTON_SHADE, 1, _("Shade"));
279
262
                    decor_event *gtkwd_event,
280
263
                    decor_event_type gtkwd_type)
281
264
{
282
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
283
 
    guint   state = w->frame_window->button_states[BUTTON_ABOVE];
 
265
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
266
    guint   state = d->button_states[BUTTON_ABOVE];
284
267
 
285
268
    common_button_event (win, gtkwd_event, gtkwd_type,
286
269
                         BUTTON_ABOVE, 1, _("Make Above"));
303
286
                    decor_event *gtkwd_event,
304
287
                    decor_event_type gtkwd_type)
305
288
{
306
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
307
 
    guint   state = w->frame_window->button_states[BUTTON_STICK];
 
289
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
290
    guint   state = d->button_states[BUTTON_STICK];
308
291
 
309
292
    common_button_event (win, gtkwd_event, gtkwd_type,
310
293
                         BUTTON_STICK, 1, _("Stick"));
325
308
                      decor_event *gtkwd_event,
326
309
                      decor_event_type gtkwd_type)
327
310
{
328
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
329
 
    guint   state = w->frame_window->button_states[BUTTON_UNSHADE];
 
311
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
312
    guint   state = d->button_states[BUTTON_UNSHADE];
330
313
 
331
314
    common_button_event (win, gtkwd_event, gtkwd_type,
332
315
                         BUTTON_UNSHADE, 1, _("Unshade"));
347
330
                      decor_event *gtkwd_event,
348
331
                      decor_event_type gtkwd_type)
349
332
{
350
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
351
 
    guint   state = w->frame_window->button_states[BUTTON_UNABOVE];
 
333
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
334
    guint   state = d->button_states[BUTTON_UNABOVE];
352
335
 
353
336
    common_button_event (win, gtkwd_event, gtkwd_type,
354
337
                         BUTTON_UNABOVE, 1, _("Unmake Above"));
371
354
                      decor_event *gtkwd_event,
372
355
                      decor_event_type gtkwd_type)
373
356
{
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];
376
359
 
377
360
    common_button_event (win, gtkwd_event, gtkwd_type,
378
361
                         BUTTON_UNSTICK, 1, _("Unstick"));
379
362
 
380
 
    switch (gtkwd_type)
381
 
    {
 
363
    switch (gtkwd_type) {
382
364
    case GButtonRelease:
383
365
        if (gtkwd_event->button == 1)
384
366
            if (state == BUTTON_EVENT_ACTION_STATE)
417
399
    case CLICK_ACTION_LOWER:
418
400
        restack_window (win, Below);
419
401
        break;
 
402
    case CLICK_ACTION_MENU:
 
403
        action_menu_map (win, gtkwd_event->button, gtkwd_event->time);
 
404
        break;
420
405
    }
421
406
}
422
407
 
453
438
    static int    last_button_x = 0;
454
439
    static int    last_button_y = 0;
455
440
 
456
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
 
441
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
457
442
 
458
 
    if (gtkwd_type == GEnterNotify)
 
443
    if (d->frame_window && gtkwd_type == GEnterNotify)
459
444
    {
460
445
        GdkCursor* cursor = gdk_cursor_new (GDK_LEFT_PTR);
461
 
        GdkWindow* window = create_foreign_window (w->frame_window->xid);
462
 
        if (window)
463
 
        {
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 ())
469
 
                return;
470
 
        }
471
 
        else
472
 
            return;
 
446
        gdk_window_set_cursor (d->frame_window, cursor);
473
447
    }
474
448
 
475
449
    if (gtkwd_type != GButtonPress)
529
503
                    decor_event_type gtkwd_type)
530
504
{
531
505
 
532
 
    GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
 
506
    decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
533
507
 
534
 
    if (gtkwd_type == GEnterNotify)
 
508
    if (d->frame_window && gtkwd_type == GEnterNotify)
535
509
    {
536
510
        GdkCursor *cursor = NULL;
537
511
 
567
541
 
568
542
        if (cursor)
569
543
        {
570
 
            GdkWindow  *window = create_foreign_window (w->frame_window->xid);
571
 
            if (window)
572
 
            {
573
 
                gdk_error_trap_push ();
574
 
                gdk_window_set_cursor (window, cursor);
575
 
                gdk_cursor_unref (cursor);
576
 
                gdk_display_sync (gdk_display_get_default ());
577
 
                if (gdk_error_trap_pop ())
578
 
                    return;
579
 
            }
 
544
            gdk_window_set_cursor (d->frame_window, cursor);
580
545
        }
581
546
    }
582
547
 
645
610
}
646
611
 
647
612
void
648
 
bottom_left_event (WnckWindow  *win,
 
613
bottom_left_event (WnckWindow *win,
649
614
                   decor_event *gtkwd_event,
650
615
                   decor_event_type gtkwd_type)
651
616
{
654
619
}
655
620
 
656
621
void
657
 
bottom_event (WnckWindow  *win,
 
622
bottom_event (WnckWindow *win,
658
623
              decor_event *gtkwd_event,
659
624
              decor_event_type gtkwd_type)
660
625
{
663
628
}
664
629
 
665
630
void
666
 
bottom_right_event (WnckWindow  *win,
 
631
bottom_right_event (WnckWindow *win,
667
632
                    decor_event *gtkwd_event,
668
633
                    decor_event_type gtkwd_type)
669
634
{
671
636
                        gtkwd_event, gtkwd_type);
672
637
}
673
638
 
 
639
void
 
640
frame_window_realized (GtkWidget *widget,
 
641
                       gpointer  data)
 
642
{
 
643
    decor_t *d = (decor_t *) data;
 
644
 
 
645
    if (d)
 
646
    {
 
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);
 
650
 
 
651
    }
 
652
}
 
653
 
674
654
event_callback
675
 
find_event_callback_for_point (GWDWindow    *w,
676
 
                               int           x,
677
 
                               int           y,
678
 
                               Bool          *enter,
679
 
                               Bool          *leave,
680
 
                               event_window  **entered)
 
655
find_event_callback_for_point (decor_t *d,
 
656
                               int     x,
 
657
                               int     y,
 
658
                               Bool    *enter,
 
659
                               Bool    *leave,
 
660
                               BoxPtr  *entered_box)
681
661
{
682
 
    int          i, j;
683
 
    event_window *ew;
 
662
    int    i, j;
 
663
    BoxPtr box;
684
664
 
685
665
    for (i = 0; i < BUTTON_NUM; i++)
686
666
    {
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)
690
670
        {
691
 
            if (w->frame_window->last_entered != ew)
 
671
            if (d->last_pos_entered != box)
692
672
            {
693
673
                if (enter)
694
674
                    *enter = TRUE;
695
 
                if (leave && w->frame_window->last_entered)
 
675
                if (leave && d->last_pos_entered)
696
676
                    *leave = TRUE;
697
 
                if (entered)
698
 
                    *entered = ew;
 
677
                if (entered_box)
 
678
                    *entered_box = box;
699
679
            }
700
 
            return w->frame_window->button_windows[i].callback;
 
680
            return d->button_windows[i].callback;
701
681
        }
702
682
    }
703
683
 
705
685
    {
706
686
        for (j = 0; j < 3; j++)
707
687
        {
708
 
            ew = &w->frame_window->event_windows[i][j];
709
 
            if (x >= ew->pos.x1 && x <= ew->pos.x2 &&
710
 
                y >= ew->pos.y1 && y <= ew->pos.y2)
 
688
            box = &d->event_windows[i][j].pos;
 
689
            if (x >= box->x1 && x <= box->x2 &&
 
690
                y >= box->y1 && y <= box->y2)
711
691
            {
712
 
                if (w->frame_window->last_entered != ew)
 
692
                if (d->last_pos_entered != box)
713
693
                {
714
694
                    if (enter)
715
695
                        *enter = TRUE;
716
 
                    if (leave && w->frame_window->last_entered)
 
696
                    if (leave && d->last_pos_entered)
717
697
                        *leave = TRUE;
718
 
                    if (entered)
719
 
                        *entered = ew;
 
698
                    if (entered_box)
 
699
                        *entered_box = box;
720
700
                }
721
 
                return w->frame_window->event_windows[i][j].callback;
 
701
                return d->event_windows[i][j].callback;
722
702
            }
723
703
        }
724
704
    }
727
707
}
728
708
 
729
709
event_callback
730
 
find_leave_event_callback (GWDWindow *w)
 
710
find_leave_event_callback (decor_t *d)
731
711
{
732
712
    int i, j;
733
713
 
734
714
    for (i = 0; i < BUTTON_NUM; i++)
735
715
    {
736
 
        if (w->frame_window->last_entered == &w->frame_window->button_windows[i])
737
 
            return w->frame_window->button_windows[i].callback;
 
716
        if (d->last_pos_entered == &d->button_windows[i].pos)
 
717
            return d->button_windows[i].callback;
738
718
    }
739
719
 
740
720
    for (i = 0; i < 3; i++)
741
721
    {
742
722
        for (j = 0; j < 3; j++)
743
723
        {
744
 
            if (w->frame_window->last_entered == &w->frame_window->event_windows[i][j])
745
 
                return w->frame_window->event_windows[i][j].callback;
 
724
            if (d->last_pos_entered == &d->event_windows[i][j].pos)
 
725
                return d->event_windows[i][j].callback;
746
726
        }
747
727
    }
748
728
 
750
730
}
751
731
 
752
732
void
753
 
frame_handle_button_press (XButtonEvent   *event,
754
 
                           GWDWindow      *window)
 
733
frame_handle_button_press (GtkWidget      *widget,
 
734
                           GdkEventButton *event,
 
735
                           gpointer       user_data)
755
736
{
756
 
    GWDWindow *w = window;
 
737
    decor_t *d = (decor_t *) user_data;
757
738
 
758
 
    if (w)
 
739
    if (d)
759
740
    {
760
741
        /* Check to see where the event happened and fill out an appropriate
761
742
         * struct
762
743
         */
763
744
        event_callback cb;
764
745
 
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);
767
748
 
768
 
        if (cb)
 
749
        if (cb && d->decorated)
769
750
        {
770
751
            decor_event gtkwd_event;
771
752
 
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;
780
760
 
781
 
            (*cb) (w->win, &gtkwd_event, GButtonPress);
 
761
            (*cb) (d->win, &gtkwd_event, GButtonPress);
782
762
        }
783
763
    }
784
764
}
785
765
 
786
766
void
787
 
frame_handle_button_release (XButtonEvent   *event,
788
 
                             GWDWindow      *window)
 
767
frame_handle_button_release (GtkWidget      *widget,
 
768
                             GdkEventButton *event,
 
769
                             gpointer       user_data)
789
770
{
790
 
    GWDWindow *w = window;
 
771
    decor_t *d = (decor_t *) user_data;
791
772
 
792
 
    if (w)
 
773
    if (d)
793
774
    {
794
775
        event_callback cb;
795
776
 
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);
798
779
 
799
 
        last_clicked_frame = NULL;
800
 
 
801
 
        if (cb && last_clicked_frame)
 
780
        if (cb && d->decorated)
802
781
        {
803
782
            decor_event gtkwd_event;
804
783
 
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;
812
791
 
813
 
            (*cb) (w->win, &gtkwd_event, GButtonRelease);
 
792
            (*cb) (d->win, &gtkwd_event, GButtonRelease);
814
793
        }
815
794
    }
816
795
}
817
796
 
818
797
void
819
 
frame_handle_motion (XMotionEvent   *event,
820
 
                     GWDWindow      *window)
 
798
frame_handle_motion (GtkWidget      *widget,
 
799
                     GdkEventMotion *event,
 
800
                     gpointer       user_data)
821
801
{
822
 
    GWDWindow *w = window;
 
802
    decor_t *d = (decor_t *) user_data;
823
803
 
824
 
    if (w)
 
804
    if (d)
825
805
    {
826
806
        event_callback cb = NULL;
827
807
        Bool           send_enter = FALSE;
828
808
        Bool           send_leave = FALSE;
829
 
        event_window   *entered_window;
 
809
        BoxPtr         entered_box;
830
810
 
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,
833
 
                                            &entered_window);
 
813
                                            &entered_box);
834
814
 
835
 
        if (cb)
 
815
        if (cb && d->decorated)
836
816
        {
837
817
            decor_event gtkwd_event;
838
818
 
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;
845
825
 
846
826
            if (send_enter)
847
 
                (*cb) (w->win, &gtkwd_event, GEnterNotify);
 
827
                (*cb) (d->win, &gtkwd_event, GEnterNotify);
848
828
 
849
829
            if (send_leave)
850
830
            {
851
831
                event_callback leave_cb;
852
832
 
853
 
                leave_cb = find_leave_event_callback (w);
 
833
                leave_cb = find_leave_event_callback (d);
854
834
 
855
835
                if (leave_cb)
856
 
                    (*leave_cb) (w->win, &gtkwd_event, GLeaveNotify);
 
836
                    (*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
857
837
 
858
838
            }
859
839
 
860
840
            if (send_enter)
861
 
                w->frame_window->last_entered = entered_window;
 
841
                d->last_pos_entered = entered_box;
862
842
        }
863
 
        else if (w->frame_window->last_entered)
 
843
        else if (d->last_pos_entered && d->decorated)
864
844
        {
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
869
849
 
870
850
            event_callback leave_cb;
871
851
 
872
 
            leave_cb = find_leave_event_callback (w);
 
852
            leave_cb = find_leave_event_callback (d);
873
853
 
874
854
            if (leave_cb)
875
855
            {
876
856
                decor_event    gtkwd_event;
877
857
 
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;
884
864
 
885
 
                (*leave_cb) (w->win, &gtkwd_event, GLeaveNotify);
 
865
                (*leave_cb) (d->win, &gtkwd_event, GLeaveNotify);
886
866
            }
887
867
 
888
 
            w->frame_window->last_entered = NULL;
 
868
            d->last_pos_entered = NULL;
889
869
        }
890
870
    }
891
871
}
895
875
               GdkEvent    *gevent,
896
876
               gpointer data)
897
877
{
 
878
    Display    *xdisplay;
898
879
    GdkDisplay *gdkdisplay;
899
880
    gulong     xid = 0;
900
881
    Window     select = 0;
901
882
    XEvent     *xevent = (XEvent *) event;
902
883
 
903
884
    gdkdisplay = gdk_display_get_default ();
 
885
    xdisplay   = GDK_DISPLAY_XDISPLAY (gdkdisplay);
904
886
 
905
887
    switch (xevent->type) {
906
888
    case CreateNotify:
907
889
        {
908
 
            if (xevent->xcreatewindow.parent == gdk_x11_get_default_root_xwindow ())
 
890
            if (!wnck_window_get (xevent->xcreatewindow.window))
909
891
            {
910
892
                GdkWindow *toplevel = create_foreign_window (xevent->xcreatewindow.window);
911
893
 
912
894
                if (toplevel)
913
895
                {
914
 
                    if (!wnck_window_get (xevent->xcreatewindow.window))
915
 
                    {
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");
924
 
 
925
 
                        /* check if the window is a switcher and update accordingly */
926
 
 
927
 
                        if (get_window_prop (xevent->xcreatewindow.window, select_window_atom, &select))
928
 
                            update_switcher_window (xevent->xcreatewindow.window, select);
929
 
                    }
 
896
                    gdk_window_set_events (toplevel,
 
897
                                           gdk_window_get_events (toplevel) |
 
898
                                           GDK_PROPERTY_CHANGE_MASK);
930
899
                }
931
900
            }
932
901
        }
933
902
        break;
 
903
    case ButtonPress:
 
904
    case ButtonRelease:
 
905
        xid = (gulong)
 
906
            g_hash_table_lookup (frame_table,
 
907
                                 GINT_TO_POINTER (xevent->xbutton.window));
 
908
        break;
 
909
    case EnterNotify:
 
910
    case LeaveNotify:
 
911
        xid = (gulong)
 
912
            g_hash_table_lookup (frame_table,
 
913
                                 GINT_TO_POINTER (xevent->xcrossing.window));
 
914
        break;
 
915
    case MotionNotify:
 
916
        xid = (gulong)
 
917
            g_hash_table_lookup (frame_table,
 
918
                                 GINT_TO_POINTER (xevent->xmotion.window));
 
919
        break;
934
920
    case PropertyNotify:
935
921
        if (xevent->xproperty.atom == frame_input_window_atom)
936
922
        {
937
923
            WnckWindow *win;
938
 
            GWDWindow  *window;
939
924
 
940
925
            xid = xevent->xproperty.window;
941
926
 
943
928
            if (win)
944
929
            {
945
930
                Window frame;
946
 
                window = (GWDWindow *) g_object_get_data (G_OBJECT (win), "decor");
947
931
 
948
 
                if (window && window != switcher_window)
 
932
                if (!get_window_prop (xid, select_window_atom, &select))
949
933
                {
950
934
                    if (get_window_prop (xid, frame_input_window_atom, &frame))
951
 
                    {
952
 
                        if (window->frame_window)
953
 
                            gwd_frame_window_delete (window->frame_window, FALSE);
954
 
 
955
 
                        window->frame_window = NULL;
956
 
                        window->frame_window = gwd_frame_window_new (window, frame_input_window_atom, frame);
957
 
                    }
958
 
                    else if (window->frame_window)
959
 
                    {
960
 
                        gwd_frame_window_delete (window->frame_window, FALSE);
961
 
                        window->frame_window = NULL;
962
 
                    }
 
935
                        add_frame_window (win, frame, FALSE);
 
936
                    else
 
937
                        remove_frame_window (win);
963
938
                }
964
939
            }
965
940
        }
966
941
        if (xevent->xproperty.atom == frame_output_window_atom)
967
942
        {
968
943
            WnckWindow *win;
969
 
            GWDWindow  *window;
970
944
 
971
945
            xid = xevent->xproperty.window;
972
946
 
974
948
            if (win)
975
949
            {
976
950
                Window frame;
977
 
                window = (GWDWindow *) g_object_get_data (G_OBJECT (win), "decor");
978
951
 
979
 
                if (window && window != switcher_window)
 
952
                if (!get_window_prop (xid, select_window_atom, &select))
980
953
                {
981
954
                    if (get_window_prop (xid, frame_output_window_atom, &frame))
982
 
                    {
983
 
                        if (window->frame_window)
984
 
                            gwd_frame_window_delete (window->frame_window, FALSE);
985
 
 
986
 
                        window->frame_window = NULL;
987
 
                        window->frame_window = gwd_frame_window_new (window, frame_output_window_atom, frame);
988
 
                    }
989
 
                    else if (window->frame_window)
990
 
                    {
991
 
                        gwd_frame_window_delete (window->frame_window, FALSE);
992
 
                        window->frame_window = NULL;
993
 
                    }
994
 
                }
995
 
            }
996
 
        }
997
 
        /* Read in the new mwm hints atom and store the value */
998
 
        else if (xevent->xproperty.atom == mwm_hints_atom)
999
 
        {
1000
 
            WnckWindow *win = wnck_window_get (xevent->xproperty.window);
1001
 
            if (win)
1002
 
            {
1003
 
                GWDWindow  *w = g_object_get_data (G_OBJECT (win), "decor");
1004
 
 
1005
 
                w->mwm_prop = get_mwm_prop (xid);
1006
 
 
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);
1010
 
            }
1011
 
        }
1012
 
        /* Read in the new emwh state hint and store the value */
1013
 
        else if (xevent->xproperty.atom == net_wm_state_atom)
1014
 
        {
1015
 
            WnckWindow    *win = wnck_window_get (xevent->xproperty.window);
1016
 
 
1017
 
            if (win)
1018
 
            {
1019
 
                GWDWindow *w = g_object_get_data (G_OBJECT (win), "decor");
1020
 
                Atom      old;
1021
 
 
1022
 
                if (w)
1023
 
                {
1024
 
                    old = w->net_wm_state_modal_atom;
1025
 
                    w->net_wm_state_modal_atom = get_atom_prop (xevent->xproperty.window,
1026
 
                                                                net_wm_state_atom,
1027
 
                                                                net_wm_state_modal_atom);
1028
 
 
1029
 
                    if (w->net_wm_state_modal_atom != old)
1030
 
                    {
1031
 
                        w->state = populate_frame_state (win);
1032
 
 
1033
 
                        if (w->frame_window)
1034
 
                            update_event_windows (w->frame_window);
1035
 
                    }
 
955
                        add_frame_window (win, frame, TRUE);
 
956
                    else
 
957
                        remove_frame_window (win);
1036
958
                }
1037
959
            }
1038
960
        }
1051
973
                    decorations_changed (screen);
1052
974
            }
1053
975
        }
 
976
        else if (xevent->xproperty.atom == mwm_hints_atom)
 
977
        {
 
978
            WnckWindow *win;
 
979
 
 
980
            xid = xevent->xproperty.window;
 
981
 
 
982
            win = wnck_window_get (xid);
 
983
            if (win)
 
984
            {
 
985
                decor_t  *d = g_object_get_data (G_OBJECT (win), "decor");
 
986
                gboolean decorated = FALSE;
 
987
 
 
988
                if (get_mwm_prop (xid) & (MWM_DECOR_ALL | MWM_DECOR_TITLE))
 
989
                    decorated = TRUE;
 
990
 
 
991
                if (decorated != d->decorated)
 
992
                {
 
993
                    d->decorated = decorated;
 
994
                    if (decorated)
 
995
                    {
 
996
                        d->context = NULL;
 
997
                        d->width = d->height = 0;
 
998
 
 
999
                        d->frame = gwd_get_decor_frame (get_frame_type (win));
 
1000
 
 
1001
                        update_window_decoration_size (win);
 
1002
                        update_event_windows (win);
 
1003
                    }
 
1004
                    else
 
1005
                    {
 
1006
                        gwd_decor_frame_unref (d->frame);
 
1007
                        d->frame = NULL;
 
1008
 
 
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 ();
 
1013
                    }
 
1014
                }
 
1015
            }
 
1016
        }
1054
1017
        else if (xevent->xproperty.atom == select_window_atom)
1055
1018
        {
1056
1019
            Window select;
1059
1022
                update_switcher_window (xevent->xproperty.window, select);
1060
1023
        }
1061
1024
        break;
1062
 
    case FocusIn:
1063
 
    case FocusOut:
1064
 
        if (xevent->xfocus.mode == NotifyUngrab && last_clicked_frame)
1065
 
        {
1066
 
            Window       root, child;
1067
 
            int          x_root, y_root;
1068
 
            int          x, y;
1069
 
            unsigned int mask;
1070
 
            XButtonEvent eb;
1071
 
 
1072
 
            gdk_error_trap_push ();
1073
 
            XQueryPointer (gdk_x11_display_get_xdisplay (gdk_display_get_default ()),
1074
 
                           last_clicked_frame->frame_window->xid,
1075
 
                           &root,
1076
 
                           &child,
1077
 
                           &x_root, &y_root, &x, &y, &mask);
1078
 
            gdk_display_sync (gdk_display_get_default ());
1079
 
            if (!gdk_error_trap_pop ())
1080
 
            {
1081
 
                eb.type = ButtonRelease;
1082
 
                eb.send_event = FALSE;
1083
 
                eb.time = CurrentTime;
1084
 
                eb.x = (double) x;
1085
 
                eb.y = (double) y;
1086
 
                eb.x_root = (double) x_root;
1087
 
                eb.y_root = (double) y_root;
1088
 
                eb.state = 0;
1089
 
                eb.button = 0;
1090
 
 
1091
 
                if (last_clicked_frame)
1092
 
                    frame_handle_button_release (&eb, last_clicked_frame);
1093
 
            }
1094
 
        }
1095
 
    case ButtonPress:
1096
 
    {
1097
 
        GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xbutton.window));
1098
 
 
1099
 
        if (fw)
1100
 
        {
1101
 
            frame_handle_button_press ((XButtonEvent *) xevent, fw->window);
1102
 
        }
1103
 
 
1104
 
        break;
1105
 
    }
1106
 
    case ButtonRelease:
1107
 
    {
1108
 
        GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xbutton.window));
1109
 
 
1110
 
        if (fw)
1111
 
        {
1112
 
            frame_handle_button_release ((XButtonEvent *) xevent, fw->window);
1113
 
        }
1114
 
 
1115
 
        break;
1116
 
    }
1117
 
    case MotionNotify:
1118
 
    {
1119
 
        GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xmotion.window));
1120
 
 
1121
 
        if (fw)
1122
 
        {
1123
 
            frame_handle_motion ((XMotionEvent *) xevent, fw->window);
1124
 
        }
1125
 
 
1126
 
        break;
1127
 
    }
1128
 
    case LeaveNotify:
1129
 
    {
1130
 
        GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xcrossing.window));
1131
 
 
1132
 
        if (fw && xevent->xcrossing.mode == NotifyNormal)
1133
 
        {
1134
 
            guint state[BUTTON_NUM];
1135
 
            memcpy (state, fw->button_states, sizeof (guint) * BUTTON_NUM);
1136
 
 
1137
 
            GWDDecoration *d = gwd_decoration_get (fw->window,
1138
 
                                                   fw->window->type,
1139
 
                                                   fw->window->state,
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);
1143
 
 
1144
 
            fw->last_entered = NULL;
1145
 
 
1146
 
            if (memcmp (state, fw->button_states, sizeof (guint) * BUTTON_NUM))
1147
 
                queue_decor_draw (d);
1148
 
        }
1149
 
        break;
1150
 
    }
1151
1025
    case DestroyNotify:
1152
 
    {
1153
 
        GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xdestroywindow.window));
1154
 
 
1155
 
        /* The parent window went away, we must remove our frame window */
1156
 
        if (fw)
1157
 
        {
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
1160
 
             * hairy here */
1161
 
            gdk_error_trap_push ();
1162
 
            gwd_frame_window_delete (fw, TRUE);
1163
 
            gdk_error_trap_pop ();
1164
 
            fw->window->frame_window = NULL;
1165
 
        }
1166
 
 
1167
 
        break;
1168
 
    }
1169
 
    case ReparentNotify:
1170
 
    {
1171
 
        GWDFrameWindow *fw = g_hash_table_lookup (frame_table, GINT_TO_POINTER (xevent->xreparent.window));
1172
 
 
1173
 
        /* Compiz unreparented the decoration
1174
 
         * so we must remove our frame window
1175
 
         * as well */
1176
 
        if (fw)
1177
 
        {
1178
 
            GdkWindow *backing_window = gtk_widget_get_window (GTK_WIDGET (fw->container));
1179
 
            GdkWindow *compiz_frame_window = create_foreign_window (fw->xid);
1180
 
 
1181
 
            if (xevent->xreparent.parent == gdk_x11_get_default_root_xwindow ())
1182
 
            {
1183
 
                gwd_frame_window_delete (fw, TRUE);
1184
 
            }
1185
 
            else
1186
 
            {
1187
 
                unsigned int i, j;
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 }
1192
 
                };
1193
 
                static event_callback button_callback[BUTTON_NUM] = {
1194
 
                    close_button_event,
1195
 
                    max_button_event,
1196
 
                    min_button_event,
1197
 
                    menu_button_event,
1198
 
                    shade_button_event,
1199
 
                    above_button_event,
1200
 
                    stick_button_event,
1201
 
                    unshade_button_event,
1202
 
                    unabove_button_event,
1203
 
                    unstick_button_event
1204
 
                };
1205
 
 
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 &&
1210
 
                    backing_window &&
1211
 
                    !gdk_window_is_viewable (backing_window))
1212
 
                {
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);
1220
 
 
1221
 
                    gtk_widget_show_all (GTK_WIDGET (fw->container));
1222
 
 
1223
 
                    for (i = 0; i < 3; i++)
1224
 
                        for (j = 0; j < 3; j++)
1225
 
                            fw->event_windows[i][j].callback = callback[i][j];
1226
 
 
1227
 
                    for (i = 0; i < BUTTON_NUM; i++)
1228
 
                        fw->button_windows[i].callback = button_callback[i];
1229
 
 
1230
 
                    update_event_windows (fw);
1231
 
                }
1232
 
            }
1233
 
        }
1234
 
 
1235
 
        break;
1236
 
    }
 
1026
        g_hash_table_remove (frame_table,
 
1027
                             GINT_TO_POINTER (xevent->xproperty.window));
 
1028
        break;
1237
1029
    case ClientMessage:
1238
1030
        if (xevent->xclient.message_type == toolkit_action_atom)
1239
1031
        {
1247
1039
                win = wnck_window_get (xevent->xclient.window);
1248
1040
                if (win)
1249
1041
                {
1250
 
                    GWDWindow *window = (GWDWindow *) g_object_get_data (G_OBJECT (win), "decor");
1251
 
                    GWDDecoration *d = gwd_decoration_get (window, window->type, window->state, window->actions);
1252
 
 
1253
 
                    action_menu_map (d,
 
1042
                    action_menu_map (win,
1254
1043
                                     xevent->xclient.data.l[2],
1255
1044
                                     xevent->xclient.data.l[1]);
1256
1045
                }
1275
1064
        break;
1276
1065
    }
1277
1066
 
 
1067
    if (xid)
 
1068
    {
 
1069
        WnckWindow *win;
 
1070
 
 
1071
        win = wnck_window_get (xid);
 
1072
        if (win)
 
1073
        {
 
1074
            decor_t *d = g_object_get_data (G_OBJECT (win), "decor");
 
1075
 
 
1076
            if (d->decorated)
 
1077
            {
 
1078
                gint             i, j;
 
1079
                event_callback   cb = NULL;
 
1080
                Window           w = xevent->xany.window;
 
1081
 
 
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;
 
1086
 
 
1087
                if (!cb)
 
1088
                {
 
1089
                    for (i = 0; i < BUTTON_NUM; i++)
 
1090
                        if (d->button_windows[i].window == w)
 
1091
                            cb = d->button_windows[i].callback;
 
1092
                }
 
1093
 
 
1094
                if (cb)
 
1095
                {
 
1096
                    decor_event      gtkwd_event;
 
1097
                    decor_event_type gtkwd_type;
 
1098
 
 
1099
                    gtkwd_event.window = w;
 
1100
 
 
1101
                    switch (xevent->type)
 
1102
                    {
 
1103
                        case ButtonPress:
 
1104
                        case ButtonRelease:
 
1105
                            if (xevent->type == ButtonPress)
 
1106
                                gtkwd_type = GButtonPress;
 
1107
                            else
 
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;
 
1115
                            break;
 
1116
                        case EnterNotify:
 
1117
                        case LeaveNotify:
 
1118
                            if (xevent->type == EnterNotify)
 
1119
                                gtkwd_type = GEnterNotify;
 
1120
                            else
 
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;
 
1127
                            break;
 
1128
                        default:
 
1129
                            cb = NULL;
 
1130
                            break;
 
1131
                    }
 
1132
                    if (cb)
 
1133
                        (*cb) (win, &gtkwd_event, gtkwd_type);
 
1134
                }
 
1135
            }
 
1136
        }
 
1137
    }
 
1138
 
1278
1139
    return GDK_FILTER_CONTINUE;
1279
1140
}
1280
1141