~bratsche/ubuntu/maverick/gtk+2.0/menu-activation-fix

« back to all changes in this revision

Viewing changes to gdk/quartz/gdkevents-quartz.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-06-13 10:00:13 UTC
  • mto: (72.2.1 lenny) (1.5.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 44.
  • Revision ID: james.westby@ubuntu.com-20070613100013-qstao3cwpm6xdlxc
Tags: upstream-2.11.2
ImportĀ upstreamĀ versionĀ 2.11.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 *
3
3
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4
4
 * Copyright (C) 1998-2002 Tor Lillqvist
5
 
 * Copyright (C) 2005-2006 Imendio AB
 
5
 * Copyright (C) 2005-2007 Imendio AB
6
6
 *
7
7
 * This library is free software; you can redistribute it and/or
8
8
 * modify it under the terms of the GNU Lesser General Public
30
30
 
31
31
#include "gdkscreen.h"
32
32
#include "gdkkeysyms.h"
33
 
 
34
33
#include "gdkprivate-quartz.h"
35
34
 
36
 
static GPollFD event_poll_fd;
37
 
static NSEvent *current_event;
38
 
 
39
35
/* This is the window the mouse is currently over */
40
 
static GdkWindow *current_mouse_window;
 
36
static GdkWindow   *current_mouse_window;
41
37
 
42
38
/* This is the window corresponding to the key window */
43
 
static GdkWindow *current_keyboard_window;
 
39
static GdkWindow   *current_keyboard_window;
44
40
 
45
41
/* This is the pointer grab window */
46
 
GdkWindow *_gdk_quartz_pointer_grab_window;
47
 
static gboolean pointer_grab_owner_events;
 
42
GdkWindow          *_gdk_quartz_pointer_grab_window;
 
43
static gboolean     pointer_grab_owner_events;
48
44
static GdkEventMask pointer_grab_event_mask;
49
 
static gboolean pointer_grab_implicit;
 
45
static gboolean     pointer_grab_implicit;
50
46
 
51
47
/* This is the keyboard grab window */
52
 
GdkWindow *_gdk_quartz_keyboard_grab_window;
53
 
static gboolean keyboard_grab_owner_events;
54
 
 
55
 
static void append_event (GdkEvent *event);
56
 
 
57
 
static gboolean
58
 
gdk_event_prepare (GSource *source,
59
 
                   gint    *timeout)
60
 
{
61
 
  NSEvent *event;
62
 
  gboolean retval;
63
 
  
64
 
  GDK_QUARTZ_ALLOC_POOL;
65
 
 
66
 
  *timeout = -1;
67
 
 
68
 
  event = [NSApp nextEventMatchingMask: NSAnyEventMask
69
 
                             untilDate: [NSDate distantPast]
70
 
                                inMode: NSDefaultRunLoopMode
71
 
                               dequeue: NO];
72
 
 
73
 
  retval = (_gdk_event_queue_find_first (_gdk_display) != NULL ||
74
 
            event != NULL);
75
 
 
76
 
  GDK_QUARTZ_RELEASE_POOL;
77
 
 
78
 
  return retval;
79
 
}
80
 
 
81
 
static gboolean
82
 
gdk_event_check (GSource *source)
83
 
{
84
 
  if (_gdk_event_queue_find_first (_gdk_display) != NULL ||
85
 
      current_event)
86
 
    return TRUE;
87
 
 
88
 
  /* FIXME: We should maybe try to fetch an event again here */
89
 
 
90
 
  return FALSE;
91
 
}
92
 
 
93
 
static gboolean
94
 
gdk_event_dispatch (GSource     *source,
95
 
                    GSourceFunc  callback,
96
 
                    gpointer     user_data)
97
 
{
98
 
  GdkEvent *event;
99
 
 
100
 
  GDK_QUARTZ_ALLOC_POOL;
101
 
 
102
 
  _gdk_events_queue (_gdk_display);
103
 
 
104
 
  event = _gdk_event_unqueue (_gdk_display);
105
 
 
106
 
  if (event)
107
 
    {
108
 
      if (_gdk_event_func)
109
 
        (*_gdk_event_func) (event, _gdk_event_data);
110
 
 
111
 
      gdk_event_free (event);
112
 
    }
113
 
 
114
 
  GDK_QUARTZ_RELEASE_POOL;
115
 
 
116
 
  return TRUE;
117
 
}
118
 
 
119
 
static GSourceFuncs event_funcs = {
120
 
  gdk_event_prepare,
121
 
  gdk_event_check,
122
 
  gdk_event_dispatch,
123
 
  NULL
124
 
};
125
 
 
126
 
static GPollFunc old_poll_func;
127
 
 
128
 
static pthread_t select_thread = 0;
129
 
static int wakeup_pipe[2];
130
 
static pthread_mutex_t pollfd_mutex = PTHREAD_MUTEX_INITIALIZER;
131
 
static pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;
132
 
static GPollFD *pollfds;
133
 
static GPollFD *pipe_pollfd;
134
 
static guint n_pollfds;
135
 
static CFRunLoopSourceRef select_main_thread_source;
136
 
static CFRunLoopRef main_thread_run_loop;
137
 
 
138
 
static void *
139
 
select_thread_func (void *arg)
140
 
{
141
 
  int n_active_fds;
142
 
 
143
 
  while (1)
144
 
    {
145
 
      pthread_mutex_lock (&pollfd_mutex);
146
 
      pthread_cond_wait (&ready_cond, &pollfd_mutex);
147
 
 
148
 
      n_active_fds = old_poll_func (pollfds, n_pollfds, -1);
149
 
      if (pipe_pollfd->revents)
150
 
        {
151
 
          char c;
152
 
          int n;
153
 
 
154
 
          n = read (pipe_pollfd->fd, &c, 1);
155
 
 
156
 
          g_assert (n == 1);
157
 
          g_assert (c == 'A');
158
 
 
159
 
          n_active_fds --;
160
 
        }
161
 
      pthread_mutex_unlock (&pollfd_mutex);
162
 
 
163
 
      if (n_active_fds)
164
 
        {
165
 
          /* We have active fds, signal the main thread */
166
 
          CFRunLoopSourceSignal (select_main_thread_source);
167
 
          if (CFRunLoopIsWaiting (main_thread_run_loop))
168
 
            CFRunLoopWakeUp (main_thread_run_loop);
169
 
        }
170
 
    }
171
 
}
172
 
 
173
 
static void 
174
 
got_fd_activity (void *info)
175
 
{
176
 
  NSEvent *event;
177
 
 
178
 
  /* Post a message so we'll break out of the message loop */
179
 
  event = [NSEvent otherEventWithType: NSApplicationDefined
180
 
                             location: NSZeroPoint
181
 
                        modifierFlags: 0
182
 
                            timestamp: 0
183
 
                         windowNumber: 0
184
 
                              context: nil
185
 
                              subtype: 0
186
 
                                data1: 0 
187
 
                                data2: 0];
188
 
 
189
 
  [NSApp postEvent:event atStart:YES];
190
 
}
191
 
 
192
 
static gint
193
 
poll_func (GPollFD *ufds, guint nfds, gint timeout_)
194
 
{
195
 
  NSEvent *event;
196
 
  NSDate *limit_date;
197
 
  int n_active = 0;
198
 
  int i;
199
 
 
200
 
  GDK_QUARTZ_ALLOC_POOL;
201
 
 
202
 
  if (nfds > 1)
203
 
    {
204
 
      if (!select_thread) {
205
 
        /* Create source used for signalling the main thread */
206
 
        main_thread_run_loop = CFRunLoopGetCurrent ();
207
 
        CFRunLoopSourceContext source_context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, got_fd_activity };
208
 
        select_main_thread_source = CFRunLoopSourceCreate (NULL, 0, &source_context);
209
 
        CFRunLoopAddSource (main_thread_run_loop, select_main_thread_source, kCFRunLoopDefaultMode);
210
 
 
211
 
        pipe (wakeup_pipe);
212
 
        pthread_create (&select_thread, NULL, select_thread_func, NULL);
213
 
      }
214
 
 
215
 
      pthread_mutex_lock (&pollfd_mutex);
216
 
      n_pollfds = nfds;
217
 
      g_free (pollfds);
218
 
      pollfds = g_memdup (ufds, sizeof (GPollFD) * nfds);
219
 
 
220
 
      /* We cheat and use the fake fd for our pipe */
221
 
      for (i = 0; i < nfds; i++)
222
 
        {
223
 
          if (pollfds[i].fd == -1)
224
 
            {
225
 
              pipe_pollfd = &pollfds[i];
226
 
              pollfds[i].fd = wakeup_pipe[0];
227
 
              pollfds[i].events = G_IO_IN;
228
 
            }
229
 
        }
230
 
      
231
 
      pthread_mutex_unlock (&pollfd_mutex);
232
 
 
233
 
      /* Start our thread */
234
 
      pthread_cond_signal (&ready_cond);
235
 
    }
236
 
 
237
 
  if (timeout_ == -1)
238
 
    limit_date = [NSDate distantFuture];
239
 
  else if (timeout_ == 0)
240
 
    limit_date = [NSDate distantPast];
241
 
  else
242
 
    limit_date = [NSDate dateWithTimeIntervalSinceNow:timeout_/1000.0];
243
 
 
244
 
  event = [NSApp nextEventMatchingMask: NSAnyEventMask
245
 
                             untilDate: limit_date
246
 
                                inMode: NSDefaultRunLoopMode
247
 
                               dequeue: YES];
248
 
  
249
 
  if (event)
250
 
    {
251
 
      if ([event type] == NSApplicationDefined)
252
 
        {
253
 
          pthread_mutex_lock (&pollfd_mutex);
254
 
 
255
 
          for (i = 0; i < n_pollfds; i++)
256
 
            {
257
 
              if (ufds[i].fd == -1)
258
 
                continue;
259
 
 
260
 
              g_assert (ufds[i].fd == pollfds[i].fd);
261
 
              g_assert (ufds[i].events == pollfds[i].events);
262
 
              
263
 
              if (pollfds[i].revents)
264
 
                {
265
 
                  ufds[i].revents = pollfds[i].revents;
266
 
                  n_active ++;
267
 
                }
268
 
            }
269
 
 
270
 
          pthread_mutex_unlock (&pollfd_mutex);
271
 
 
272
 
          event = [NSApp nextEventMatchingMask: NSAnyEventMask
273
 
                                     untilDate: [NSDate distantPast]
274
 
                                        inMode: NSDefaultRunLoopMode
275
 
                                       dequeue: YES];
276
 
 
277
 
        }
278
 
    }
279
 
 
280
 
  /* There were no active fds, break out of the other thread's poll() */
281
 
  if (n_active == 0 && wakeup_pipe[1])
282
 
    {
283
 
      char c = 'A';
284
 
 
285
 
      write (wakeup_pipe[1], &c, 1);
286
 
    }
287
 
 
288
 
  if (event) 
289
 
    {
290
 
      ufds[0].revents = G_IO_IN;
291
 
 
292
 
      /* FIXME: We can't assert here, but we might need to have a
293
 
       * queue for events instead.
294
 
       */
295
 
      /*g_assert (current_event == NULL);*/
296
 
 
297
 
      current_event = [event retain];
298
 
 
299
 
      n_active ++;
300
 
    }
301
 
 
302
 
  GDK_QUARTZ_RELEASE_POOL;
303
 
 
304
 
  return n_active;
305
 
}
 
48
GdkWindow *         _gdk_quartz_keyboard_grab_window;
 
49
static gboolean     keyboard_grab_owner_events;
 
50
 
 
51
static void get_child_coordinates_from_ancestor (GdkWindow *ancestor_window,
 
52
                                                 gint       ancestor_x,
 
53
                                                 gint       ancestor_y,
 
54
                                                 GdkWindow *child_window, 
 
55
                                                 gint      *child_x, 
 
56
                                                 gint      *child_y);
 
57
static void get_ancestor_coordinates_from_child (GdkWindow *child_window,
 
58
                                                 gint       child_x,
 
59
                                                 gint       child_y,
 
60
                                                 GdkWindow *ancestor_window, 
 
61
                                                 gint      *ancestor_x, 
 
62
                                                 gint      *ancestor_y);
 
63
static void get_converted_window_coordinates    (GdkWindow *in_window,
 
64
                                                 gint       in_x,
 
65
                                                 gint       in_y,
 
66
                                                 GdkWindow *out_window, 
 
67
                                                 gint      *out_x, 
 
68
                                                 gint      *out_y);
 
69
static void append_event                        (GdkEvent  *event);
306
70
 
307
71
void 
308
72
_gdk_events_init (void)
309
73
{
310
 
  GSource *source;
311
 
 
312
 
  event_poll_fd.events = G_IO_IN;
313
 
  event_poll_fd.fd = -1;
314
 
 
315
 
  source = g_source_new (&event_funcs, sizeof (GSource));
316
 
  g_source_add_poll (source, &event_poll_fd);
317
 
  g_source_set_priority (source, GDK_PRIORITY_EVENTS);
318
 
  g_source_set_can_recurse (source, TRUE);
319
 
  g_source_attach (source, NULL);
320
 
 
321
 
  old_poll_func = g_main_context_get_poll_func (NULL);
322
 
  g_main_context_set_poll_func (NULL, poll_func);  
 
74
  _gdk_quartz_event_loop_init ();
323
75
 
324
76
  current_mouse_window = g_object_ref (_gdk_root);
325
77
  current_keyboard_window = g_object_ref (_gdk_root);
329
81
gdk_events_pending (void)
330
82
{
331
83
  return (_gdk_event_queue_find_first (_gdk_display) ||
332
 
          (current_event != NULL));
 
84
          (_gdk_quartz_event_loop_get_current () != NULL));
333
85
}
334
86
 
335
87
GdkEvent*
421
173
  g_object_unref (_gdk_quartz_pointer_grab_window);
422
174
  _gdk_quartz_pointer_grab_window = NULL;
423
175
 
 
176
  pointer_grab_owner_events = FALSE;
 
177
  pointer_grab_event_mask = 0;
 
178
  pointer_grab_implicit = FALSE;
 
179
 
424
180
  /* FIXME: Send crossing events */
425
181
}
426
182
 
427
183
gboolean
428
184
gdk_display_pointer_is_grabbed (GdkDisplay *display)
429
185
{
430
 
  return _gdk_quartz_pointer_grab_window != NULL;
 
186
  return (_gdk_quartz_pointer_grab_window != NULL && 
 
187
          !pointer_grab_implicit);
431
188
}
432
189
 
433
190
gboolean
485
242
 
486
243
  if (_gdk_quartz_pointer_grab_window)
487
244
    {
488
 
      if (_gdk_quartz_pointer_grab_window == window && !pointer_grab_implicit)
489
 
        return GDK_GRAB_ALREADY_GRABBED;
490
 
      else
491
 
        {
492
 
          if (_gdk_quartz_pointer_grab_window != window)
493
 
            generate_grab_broken_event (_gdk_quartz_pointer_grab_window,
494
 
                                        FALSE, pointer_grab_implicit, window);
495
 
          pointer_ungrab_internal (TRUE);
496
 
        }
 
245
      if (_gdk_quartz_pointer_grab_window != window)
 
246
        generate_grab_broken_event (_gdk_quartz_pointer_grab_window,
 
247
                                    FALSE, pointer_grab_implicit, window);
 
248
 
 
249
      pointer_ungrab_internal (FALSE);
497
250
    }
498
251
 
499
252
  return pointer_grab_internal (window, owner_events, event_mask, 
565
318
  return result;
566
319
}
567
320
 
568
 
/* This function checks if the passed in window is interested in the
569
 
 * event mask. If so, it's returned. If not, the event can be propagated
570
 
 * to its parent.
 
321
/* Checks if the passed in window is interested in the event mask, and
 
322
 * if so, it's returned. If not, the event can be propagated through
 
323
 * its ancestors until one with the right event mask is found, up to
 
324
 * the nearest toplevel.
571
325
 */
572
326
static GdkWindow *
573
 
find_window_interested_in_event_mask (GdkWindow   *window, 
574
 
                                      GdkEventMask event_mask,
575
 
                                      gboolean     propagate)
 
327
find_window_interested_in_event_mask (GdkWindow    *window, 
 
328
                                      GdkEventMask  event_mask,
 
329
                                      gboolean      propagate)
576
330
{
577
 
  while (window)
 
331
  GdkWindowObject *private;
 
332
 
 
333
  private = GDK_WINDOW_OBJECT (window);
 
334
  while (private)
578
335
    {
579
 
      GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
580
 
 
581
336
      if (private->event_mask & event_mask)
582
 
        return window;
 
337
        return (GdkWindow *)private;
583
338
 
584
339
      if (!propagate)
585
340
        return NULL;
586
 
      else
587
 
        window = GDK_WINDOW (private->parent);
 
341
 
 
342
      /* Don't traverse beyond toplevels. */
 
343
      if (GDK_WINDOW_TYPE (private) != GDK_WINDOW_CHILD)
 
344
        break;
 
345
 
 
346
      private = private->parent;
588
347
    }
589
348
 
590
349
  return NULL;
591
350
}
592
351
 
593
352
static guint32
594
 
get_event_time (NSEvent *event)
 
353
get_time_from_ns_event (NSEvent *event)
595
354
{
596
355
  double time = [event timestamp];
597
356
  
599
358
}
600
359
 
601
360
static int
602
 
convert_mouse_button_number (int button)
 
361
get_mouse_button_from_ns_event (NSEvent *event)
603
362
{
 
363
  int button;
 
364
 
 
365
  button = [event buttonNumber];
 
366
 
604
367
  switch (button)
605
368
    {
606
369
    case 0:
614
377
    }
615
378
}
616
379
 
 
380
static GdkModifierType
 
381
get_keyboard_modifiers_from_ns_event (NSEvent *nsevent)
 
382
{
 
383
  GdkModifierType modifiers = 0;
 
384
  int nsflags;
 
385
 
 
386
  nsflags = [nsevent modifierFlags];
 
387
  
 
388
  if (nsflags & NSAlphaShiftKeyMask)
 
389
    modifiers |= GDK_LOCK_MASK;
 
390
  if (nsflags & NSShiftKeyMask)
 
391
    modifiers |= GDK_SHIFT_MASK;
 
392
  if (nsflags & NSControlKeyMask)
 
393
    modifiers |= GDK_CONTROL_MASK;
 
394
  if (nsflags & NSCommandKeyMask)
 
395
    modifiers |= GDK_MOD1_MASK;
 
396
 
 
397
  /* FIXME: Support GDK_BUTTON_MASK */
 
398
 
 
399
  return modifiers;
 
400
}
 
401
 
617
402
/* Return an event mask from an NSEvent */
618
403
static GdkEventMask
619
404
get_event_mask_from_ns_event (NSEvent *nsevent)
652
437
                GDK_POINTER_MOTION_HINT_MASK |
653
438
                GDK_BUTTON_MOTION_MASK);
654
439
 
655
 
        if (convert_mouse_button_number ([nsevent buttonNumber]) == 2)
 
440
        if (get_mouse_button_from_ns_event (nsevent) == 2)
656
441
          mask |= (GDK_BUTTON2_MOTION_MASK | GDK_BUTTON2_MOTION_MASK | 
657
442
                   GDK_BUTTON2_MASK);
658
443
 
662
447
    case NSKeyUp:
663
448
    case NSFlagsChanged:
664
449
      {
665
 
        switch (_gdk_quartz_key_event_type (nsevent))
 
450
        switch (_gdk_quartz_keys_event_type (nsevent))
666
451
          {
667
452
          case GDK_KEY_PRESS:
668
453
            return GDK_KEY_PRESS_MASK;
696
481
 
697
482
/* Note: Used to both set a new focus window and to unset the old one. */
698
483
void
699
 
_gdk_quartz_update_focus_window (GdkWindow *window,
700
 
                                 gboolean   got_focus)
 
484
_gdk_quartz_events_update_focus_window (GdkWindow *window,
 
485
                                        gboolean   got_focus)
701
486
{
702
487
  GdkEvent *event;
703
488
 
710
495
  
711
496
  if (!got_focus && window == current_keyboard_window)
712
497
    {
713
 
          event = create_focus_event (current_keyboard_window, FALSE);
714
 
          append_event (event);
715
 
          g_object_unref (current_keyboard_window);
716
 
          current_keyboard_window = NULL;
 
498
      event = create_focus_event (current_keyboard_window, FALSE);
 
499
      append_event (event);
 
500
      g_object_unref (current_keyboard_window);
 
501
      current_keyboard_window = NULL;
717
502
    }
718
503
 
719
504
  if (got_focus)
743
528
          gdk_window_is_ancestor (ancestor, gdk_window_get_parent (window)));
744
529
}
745
530
 
746
 
static GdkModifierType
747
 
get_keyboard_modifiers_from_nsevent (NSEvent *nsevent)
748
 
{
749
 
  GdkModifierType modifiers = 0;
750
 
  int nsflags;
751
 
 
752
 
  nsflags = [nsevent modifierFlags];
753
 
  
754
 
  if (nsflags & NSAlphaShiftKeyMask)
755
 
    modifiers |= GDK_LOCK_MASK;
756
 
  if (nsflags & NSShiftKeyMask)
757
 
    modifiers |= GDK_SHIFT_MASK;
758
 
  if (nsflags & NSControlKeyMask)
759
 
    modifiers |= GDK_CONTROL_MASK;
760
 
  if (nsflags & NSCommandKeyMask)
761
 
    modifiers |= GDK_MOD1_MASK;
762
 
 
763
 
  /* FIXME: Support GDK_BUTTON_MASK */
764
 
 
765
 
  return modifiers;
766
 
}
767
 
 
768
531
static void
769
532
convert_window_coordinates_to_root (GdkWindow *window,
770
533
                                    gdouble    x,
784
547
    }
785
548
}
786
549
 
 
550
/* FIXME: Refactor and share with scroll event. */
787
551
static GdkEvent *
788
552
create_crossing_event (GdkWindow      *window, 
789
553
                       NSEvent        *nsevent, 
792
556
                       GdkNotifyType   detail)
793
557
{
794
558
  GdkEvent *event;
795
 
  NSPoint point;
 
559
  gint x_tmp, y_tmp;
796
560
 
797
561
  event = gdk_event_new (event_type);
798
 
  
 
562
 
799
563
  event->crossing.window = window;
800
564
  event->crossing.subwindow = NULL; /* FIXME */
801
 
  event->crossing.time = get_event_time (nsevent);
802
 
 
803
 
  point = [nsevent locationInWindow];
804
 
  event->crossing.x = point.x;
805
 
  event->crossing.y = point.y;
806
 
  convert_window_coordinates_to_root (window, event->crossing.x, event->crossing.y, 
 
565
  event->crossing.time = get_time_from_ns_event (nsevent);
 
566
 
 
567
  /* Split out this block: */
 
568
  {
 
569
    NSWindow *nswindow;
 
570
    GdkWindow *toplevel;
 
571
    NSPoint point;
 
572
 
 
573
    nswindow = [nsevent window];
 
574
    point = [nsevent locationInWindow];
 
575
 
 
576
    toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
 
577
 
 
578
    x_tmp = point.x;
 
579
 
 
580
    /* Flip the y coordinate. */
 
581
    if (toplevel == _gdk_root)
 
582
      y_tmp = _gdk_quartz_window_get_inverted_screen_y (point.y);
 
583
    else
 
584
      {
 
585
        GdkWindowImplQuartz *impl;
 
586
 
 
587
        impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
 
588
        y_tmp = impl->height - point.y;
 
589
      }
 
590
 
 
591
    get_converted_window_coordinates (toplevel,
 
592
                                      x_tmp, y_tmp,
 
593
                                      window,
 
594
                                      &x_tmp, &y_tmp);
 
595
    }
 
596
 
 
597
  event->crossing.x = x_tmp;
 
598
  event->crossing.y = y_tmp;
 
599
 
 
600
  convert_window_coordinates_to_root (window, 
 
601
                                      event->crossing.x, 
 
602
                                      event->crossing.y, 
807
603
                                      &event->crossing.x_root,
808
604
                                      &event->crossing.y_root);
809
605
 
810
606
  event->crossing.mode = mode;
811
607
  event->crossing.detail = detail;
812
 
  /* FIXME: focus */
813
 
  /* FIXME: state, (button state too) */
 
608
  event->crossing.state = get_keyboard_modifiers_from_ns_event (nsevent);
 
609
 
 
610
  /* FIXME: focus and button state */
814
611
 
815
612
  return event;
816
613
}
958
755
    }
959
756
  else
960
757
    {
961
 
      /* This means we have not current_mouse_window. FIXME: Should
962
 
       * we make sure to always set the root window instead of NULL?
 
758
      /* This means we have no current_mouse_window, which probably
 
759
       * means that there is a bug somewhere, we should always have
 
760
       * the root in we don't have another window. Does this ever
 
761
       * happen?
963
762
       */
964
 
 
965
 
      /* FIXME: Figure out why this is being called with window being
966
 
       * NULL. The check works around a crash for now.
967
 
       */ 
968
 
      if (window)
969
 
        synthesize_enter_event (window, nsevent, mode, GDK_NOTIFY_UNKNOWN);
 
763
      g_warning ("Trying to create crossing event when current_mouse_window is NULL");
970
764
    }
971
765
  
972
 
  _gdk_quartz_update_mouse_window (window);
 
766
  _gdk_quartz_events_update_mouse_window (window);
973
767
}
974
768
 
975
769
void 
976
 
_gdk_quartz_send_map_events (GdkWindow *window)
 
770
_gdk_quartz_events_send_map_events (GdkWindow *window)
977
771
{
978
772
  GList *list;
979
773
  GdkWindow *interested_window;
991
785
    }
992
786
 
993
787
  for (list = private->children; list != NULL; list = list->next)
994
 
    _gdk_quartz_send_map_events ((GdkWindow *)list->data);
 
788
    _gdk_quartz_events_send_map_events ((GdkWindow *)list->data);
995
789
}
996
790
 
997
791
/* Get current mouse window */
998
792
GdkWindow *
999
 
_gdk_quartz_get_mouse_window (void)
 
793
_gdk_quartz_events_get_mouse_window (void)
1000
794
{
1001
795
  if (_gdk_quartz_pointer_grab_window && !pointer_grab_owner_events)
1002
796
    return _gdk_quartz_pointer_grab_window;
1006
800
 
1007
801
/* Update mouse window */
1008
802
void 
1009
 
_gdk_quartz_update_mouse_window (GdkWindow *window)
 
803
_gdk_quartz_events_update_mouse_window (GdkWindow *window)
1010
804
{
 
805
  if (window == current_mouse_window)
 
806
    return;
 
807
 
1011
808
  if (window)
1012
809
    g_object_ref (window);
1013
810
  if (current_mouse_window)
1018
815
 
1019
816
/* Update current cursor */
1020
817
void
1021
 
_gdk_quartz_update_cursor (GdkWindow *window)
 
818
_gdk_quartz_events_update_cursor (GdkWindow *window)
1022
819
{
1023
820
  GdkWindowObject *private = GDK_WINDOW_OBJECT (window);
1024
821
  NSCursor *nscursor = nil;
1040
837
    [nscursor set];
1041
838
}
1042
839
 
1043
 
/* This function finds the correct window to send an event to,
1044
 
 * taking into account grabs (FIXME: not done yet), event propagation,
1045
 
 * and event masks.
1046
 
 */
1047
 
static GdkWindow *
1048
 
find_window_for_event (NSEvent *nsevent, gint *x, gint *y)
 
840
/* Translates coordinates from an ancestor window + coords, to
 
841
 * coordinates that are relative the child window.
 
842
 */
 
843
static void
 
844
get_child_coordinates_from_ancestor (GdkWindow *ancestor_window,
 
845
                                     gint       ancestor_x,
 
846
                                     gint       ancestor_y,
 
847
                                     GdkWindow *child_window, 
 
848
                                     gint      *child_x, 
 
849
                                     gint      *child_y)
 
850
{
 
851
  GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
 
852
  GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
 
853
 
 
854
  while (child_private != ancestor_private)
 
855
    {
 
856
      ancestor_x -= child_private->x;
 
857
      ancestor_y -= child_private->y;
 
858
 
 
859
      child_private = child_private->parent;
 
860
    }
 
861
 
 
862
  *child_x = ancestor_x;
 
863
  *child_y = ancestor_y;
 
864
}
 
865
 
 
866
/* Translates coordinates from a child window + coords, to
 
867
 * coordinates that are relative the ancestor window.
 
868
 */
 
869
static void
 
870
get_ancestor_coordinates_from_child (GdkWindow *child_window,
 
871
                                     gint       child_x,
 
872
                                     gint       child_y,
 
873
                                     GdkWindow *ancestor_window, 
 
874
                                     gint      *ancestor_x, 
 
875
                                     gint      *ancestor_y)
 
876
{
 
877
  GdkWindowObject *child_private = GDK_WINDOW_OBJECT (child_window);
 
878
  GdkWindowObject *ancestor_private = GDK_WINDOW_OBJECT (ancestor_window);
 
879
 
 
880
  while (child_private != ancestor_private)
 
881
    {
 
882
      child_x += child_private->x;
 
883
      child_y += child_private->y;
 
884
 
 
885
      child_private = child_private->parent;
 
886
    }
 
887
 
 
888
  *ancestor_x = child_x;
 
889
  *ancestor_y = child_y;
 
890
}
 
891
 
 
892
/* Translates coordinates relative to one window (in_window) into
 
893
 * coordinates relative to another window (out_window).
 
894
 */
 
895
static void
 
896
get_converted_window_coordinates (GdkWindow *in_window,
 
897
                                  gint       in_x,
 
898
                                  gint       in_y,
 
899
                                  GdkWindow *out_window, 
 
900
                                  gint      *out_x, 
 
901
                                  gint      *out_y)
 
902
{
 
903
  GdkWindow *in_toplevel;
 
904
  GdkWindow *out_toplevel;
 
905
  int in_origin_x, in_origin_y;
 
906
  int out_origin_x, out_origin_y;
 
907
 
 
908
  /* First translate to "in" toplevel coordinates, then on to "out"
 
909
   * toplevel coordinates, and finally to "out" child (the passed in
 
910
   * window) coordinates.
 
911
   */
 
912
 
 
913
  in_toplevel = gdk_window_get_toplevel (in_window);
 
914
  out_toplevel  = gdk_window_get_toplevel (out_window);
 
915
 
 
916
  /* Translate in_x, in_y to "in" toplevel coordinates. */
 
917
  get_ancestor_coordinates_from_child (in_window, in_x, in_y,
 
918
                                       in_toplevel, &in_x, &in_y);
 
919
 
 
920
  gdk_window_get_origin (in_toplevel, &in_origin_x, &in_origin_y);
 
921
  gdk_window_get_origin (out_toplevel, &out_origin_x, &out_origin_y);
 
922
 
 
923
  /* Translate in_x, in_y to "out" toplevel coordinates. */
 
924
  in_x -= out_origin_x - in_origin_x;
 
925
  in_y -= out_origin_y - in_origin_y;
 
926
 
 
927
  get_child_coordinates_from_ancestor (out_toplevel, 
 
928
                                       in_x, in_y,
 
929
                                       out_window,
 
930
                                       out_x, out_y);
 
931
}
 
932
 
 
933
/* Given a mouse NSEvent, returns the window in which the pointer
 
934
 * position from the event is. The returned coordinates are relative
 
935
 * to the found window, and normal GDK coordinates, not Quartz.
 
936
 */
 
937
static GdkWindow *
 
938
find_window_for_mouse_ns_event (NSEvent *nsevent,
 
939
                                gint    *x_ret,
 
940
                                gint    *y_ret)
 
941
{
 
942
  NSWindow *nswindow;
 
943
  GdkWindow *toplevel;
 
944
  NSPoint point;
 
945
  gint x_tmp, y_tmp;
 
946
  GdkWindow *found_window;
 
947
 
 
948
  nswindow = [nsevent window];
 
949
  toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
 
950
 
 
951
  point = [nsevent locationInWindow];
 
952
 
 
953
  x_tmp = point.x;
 
954
 
 
955
  /* Flip the y coordinate. */
 
956
  if (toplevel == _gdk_root)
 
957
    y_tmp = _gdk_quartz_window_get_inverted_screen_y (point.y);
 
958
  else
 
959
    {
 
960
      GdkWindowImplQuartz *impl;
 
961
 
 
962
      impl = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (toplevel)->impl);
 
963
      y_tmp = impl->height - point.y;
 
964
    }
 
965
 
 
966
  found_window = _gdk_quartz_window_find_child (toplevel, x_tmp, y_tmp);
 
967
 
 
968
  /* Translate the coordinates so they are relative to the found
 
969
   * window.
 
970
   */
 
971
  if (found_window)
 
972
    get_child_coordinates_from_ancestor (toplevel,
 
973
                                         x_tmp, y_tmp,
 
974
                                         found_window,
 
975
                                         &x_tmp, &y_tmp);
 
976
 
 
977
  *x_ret = x_tmp;
 
978
  *y_ret = y_tmp;
 
979
 
 
980
  return found_window;
 
981
}
 
982
 
 
983
/* This function finds the correct window to send an event to, taking
 
984
 * into account grabs, event propagation, and event masks.
 
985
 */
 
986
static GdkWindow *
 
987
find_window_for_ns_event (NSEvent *nsevent, 
 
988
                          gint    *x, 
 
989
                          gint    *y)
1049
990
{
1050
991
  NSWindow *nswindow = [nsevent window];
1051
992
  NSEventType event_type = [nsevent type];
1053
994
  if (!nswindow)
1054
995
    return NULL;
1055
996
 
 
997
  /* Window was not created by GDK so the event should be handled by Quartz. */
 
998
  if (![[nswindow contentView] isKindOfClass:[GdkQuartzView class]]) 
 
999
    return NULL;
 
1000
 
 
1001
  /* Synthesize crossing events when moving between child
 
1002
   * windows. Toplevels are handled with NSMouseEntered and
 
1003
   * NSMouseExited in the switch below.
 
1004
   */
1056
1005
  if (event_type == NSMouseMoved ||
1057
1006
      event_type == NSLeftMouseDragged ||
1058
1007
      event_type == NSRightMouseDragged ||
1059
1008
      event_type == NSOtherMouseDragged)
1060
1009
    {
1061
 
      GdkWindow *toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
1062
 
      NSPoint point = [nsevent locationInWindow];
1063
1010
      GdkWindow *mouse_window;
1064
1011
 
1065
 
      mouse_window = _gdk_quartz_find_child_window_by_point (toplevel, point.x, point.y, x, y);
 
1012
      mouse_window = find_window_for_mouse_ns_event (nsevent, x, y);
1066
1013
 
1067
1014
      if (!mouse_window)
1068
1015
        mouse_window = _gdk_root;
1077
1024
          if (current_mouse_window != mouse_window)
1078
1025
            {
1079
1026
              synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, *x, *y);
1080
 
              
1081
 
              _gdk_quartz_update_cursor (mouse_window);
 
1027
              _gdk_quartz_events_update_cursor (mouse_window);
1082
1028
            }
1083
1029
        }
1084
1030
    }
1097
1043
    case NSRightMouseDragged:
1098
1044
    case NSOtherMouseDragged:
1099
1045
      {
1100
 
        GdkWindow *toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
1101
 
        NSPoint point = [nsevent locationInWindow];
1102
1046
        GdkWindow *mouse_window;
1103
1047
        GdkEventMask event_mask;
1104
1048
        GdkWindow *real_window;
1105
1049
 
1106
 
        if (_gdk_quartz_pointer_grab_window && !pointer_grab_owner_events)
 
1050
        /* From the docs for XGrabPointer:
 
1051
         *
 
1052
         * If owner_events is True and if a generated pointer event
 
1053
         * would normally be reported to this client, it is reported
 
1054
         * as usual. Otherwise, the event is reported with respect to
 
1055
         * the grab_window and is reported only if selected by
 
1056
         * event_mask. For either value of owner_events, unreported
 
1057
         * events are discarded.
 
1058
         *
 
1059
         * This means we first try the owner, then the grab window,
 
1060
         * then give up.
 
1061
         */
 
1062
        if (_gdk_quartz_pointer_grab_window)
1107
1063
          {
 
1064
            if (pointer_grab_owner_events)
 
1065
              {
 
1066
                mouse_window = find_window_for_mouse_ns_event (nsevent, x, y);
 
1067
                event_mask = get_event_mask_from_ns_event (nsevent);
 
1068
                real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
 
1069
                
 
1070
                if (mouse_window && real_window && mouse_window != real_window)
 
1071
                  get_ancestor_coordinates_from_child (mouse_window,
 
1072
                                                       *x, *y,
 
1073
                                                       real_window,
 
1074
                                                       x, y);
 
1075
 
 
1076
                if (real_window)
 
1077
                  return real_window;
 
1078
              }
 
1079
 
 
1080
            /* FIXME: This part needs some fixing, it doesn't return
 
1081
             * the right coordinates if the nsevent happens for a
 
1082
             * different window than the grab window.
 
1083
             */
1108
1084
            if (pointer_grab_event_mask & get_event_mask_from_ns_event (nsevent))
1109
1085
              {
1110
 
                int tempx, tempy;
1111
 
                GdkWindowObject *w;
1112
 
                GdkWindowObject *grab_toplevel;
1113
 
 
1114
 
                w = GDK_WINDOW_OBJECT (_gdk_quartz_pointer_grab_window);
1115
 
                grab_toplevel = GDK_WINDOW_OBJECT (gdk_window_get_toplevel (_gdk_quartz_pointer_grab_window));
1116
 
 
1117
 
                tempx = point.x;
1118
 
                tempy = GDK_WINDOW_IMPL_QUARTZ (grab_toplevel->impl)->height -
1119
 
                  point.y;
1120
 
 
1121
 
                while (w != grab_toplevel)
1122
 
                  {
1123
 
                    tempx -= w->x;
1124
 
                    tempy -= w->y;
1125
 
 
1126
 
                    w = w->parent;
1127
 
                  }
1128
 
 
1129
 
                *x = tempx;
1130
 
                *y = tempy;
 
1086
                GdkWindow *grab_toplevel;
 
1087
                NSPoint point;
 
1088
                int x_tmp, y_tmp;
 
1089
 
 
1090
                grab_toplevel = gdk_window_get_toplevel (_gdk_quartz_pointer_grab_window);
 
1091
                point = [nsevent locationInWindow];
 
1092
 
 
1093
                x_tmp = point.x;
 
1094
                y_tmp = GDK_WINDOW_IMPL_QUARTZ (GDK_WINDOW_OBJECT (grab_toplevel)->impl)->height - point.y;
 
1095
 
 
1096
                get_child_coordinates_from_ancestor (grab_toplevel,
 
1097
                                                     x_tmp, y_tmp, 
 
1098
                                                     _gdk_quartz_pointer_grab_window,
 
1099
                                                     x, y);
1131
1100
 
1132
1101
                return _gdk_quartz_pointer_grab_window;
1133
1102
              }
1134
 
            else
1135
 
              {
1136
 
                return NULL;
1137
 
              }
1138
 
          }
1139
 
 
1140
 
        if (!nswindow)
1141
 
          {
1142
 
            mouse_window = _gdk_root;
1143
 
          }
1144
 
        else
1145
 
          {
1146
 
            mouse_window = _gdk_quartz_find_child_window_by_point (toplevel, point.x, point.y, x, y);
1147
 
          }
1148
 
 
1149
 
        event_mask = get_event_mask_from_ns_event (nsevent);
1150
 
        real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
1151
 
        
1152
 
        return real_window;
 
1103
 
 
1104
            return NULL;
 
1105
          }
 
1106
        else 
 
1107
          {
 
1108
            /* The non-grabbed case. */
 
1109
            mouse_window = find_window_for_mouse_ns_event (nsevent, x, y);
 
1110
            event_mask = get_event_mask_from_ns_event (nsevent);
 
1111
            real_window = find_window_interested_in_event_mask (mouse_window, event_mask, TRUE);
 
1112
            
 
1113
            /* We have to translate the coordinates if the actual
 
1114
             * window is different from the mouse window.
 
1115
             */
 
1116
            if (mouse_window && real_window && mouse_window != real_window)
 
1117
              get_ancestor_coordinates_from_child (mouse_window,
 
1118
                                                   *x, *y,
 
1119
                                                   real_window,
 
1120
                                                   x, y);
 
1121
 
 
1122
            return real_window;
 
1123
          }
1153
1124
      }
1154
1125
      break;
1155
1126
      
1156
1127
    case NSMouseEntered:
1157
1128
      {
1158
 
        NSPoint point;
1159
 
        GdkWindow *toplevel;
1160
1129
        GdkWindow *mouse_window;
1161
1130
 
1162
 
        point = [nsevent locationInWindow];
1163
 
 
1164
 
        toplevel = [(GdkQuartzView *)[nswindow contentView] gdkWindow];
1165
 
 
1166
 
        mouse_window = _gdk_quartz_find_child_window_by_point (toplevel, point.x, point.y, x, y);
1167
 
        
 
1131
        mouse_window = find_window_for_mouse_ns_event (nsevent, x, y);
1168
1132
        synthesize_crossing_events (mouse_window, GDK_CROSSING_NORMAL, nsevent, *x, *y);
1169
1133
      }
1170
1134
      break;
1191
1155
    case NSSystemDefined:
1192
1156
      /* We ignore these events */
1193
1157
      break;
 
1158
 
1194
1159
    default:
1195
1160
      NSLog(@"Unhandled event %@", nsevent);
1196
1161
    }
1199
1164
}
1200
1165
 
1201
1166
static GdkEvent *
1202
 
create_button_event (GdkWindow *window, NSEvent *nsevent,
1203
 
                     gint x, gint y)
 
1167
create_button_event (GdkWindow *window, 
 
1168
                     NSEvent   *nsevent,
 
1169
                     gint       x,
 
1170
                     gint       y)
1204
1171
{
1205
1172
  GdkEvent *event;
1206
1173
  GdkEventType type;
1222
1189
      g_assert_not_reached ();
1223
1190
    }
1224
1191
  
1225
 
  button = convert_mouse_button_number ([nsevent buttonNumber]);
 
1192
  button = get_mouse_button_from_ns_event (nsevent);
1226
1193
 
1227
1194
  event = gdk_event_new (type);
1228
1195
  event->button.window = window;
1229
 
  event->button.time = get_event_time (nsevent);
 
1196
  event->button.time = get_time_from_ns_event (nsevent);
1230
1197
  event->button.x = x;
1231
1198
  event->button.y = y;
1232
1199
  /* FIXME event->axes */
1233
 
  event->button.state = get_keyboard_modifiers_from_nsevent (nsevent);
 
1200
  event->button.state = get_keyboard_modifiers_from_ns_event (nsevent);
1234
1201
  event->button.button = button;
1235
1202
  event->button.device = _gdk_display->core_pointer;
1236
1203
  convert_window_coordinates_to_root (window, x, y, 
1241
1208
}
1242
1209
 
1243
1210
static GdkEvent *
1244
 
create_motion_event (GdkWindow *window, NSEvent *nsevent, gint x, gint y)
 
1211
create_motion_event (GdkWindow *window, 
 
1212
                     NSEvent   *nsevent, 
 
1213
                     gint       x, 
 
1214
                     gint       y)
1245
1215
{
1246
1216
  GdkEvent *event;
1247
1217
  GdkEventType type;
1253
1223
    case NSLeftMouseDragged:
1254
1224
    case NSRightMouseDragged:
1255
1225
    case NSOtherMouseDragged:
1256
 
      button = convert_mouse_button_number ([nsevent buttonNumber]);
 
1226
      button = get_mouse_button_from_ns_event (nsevent);
1257
1227
      /* Fall through */
1258
1228
    case NSMouseMoved:
1259
1229
      type = GDK_MOTION_NOTIFY;
1266
1236
  if (button >= 1 && button <= 5)
1267
1237
    state = (1 << (button + 7));
1268
1238
  
1269
 
  state |= get_keyboard_modifiers_from_nsevent (nsevent);
 
1239
  state |= get_keyboard_modifiers_from_ns_event (nsevent);
1270
1240
 
1271
1241
  event = gdk_event_new (type);
1272
1242
  event->motion.window = window;
1273
 
  event->motion.time = get_event_time (nsevent);
 
1243
  event->motion.time = get_time_from_ns_event (nsevent);
1274
1244
  event->motion.x = x;
1275
1245
  event->motion.y = y;
1276
1246
  /* FIXME event->axes */
1284
1254
}
1285
1255
 
1286
1256
static GdkEvent *
1287
 
create_scroll_event (GdkWindow *window, NSEvent *nsevent, GdkScrollDirection direction)
 
1257
create_scroll_event (GdkWindow          *window, 
 
1258
                     NSEvent            *nsevent, 
 
1259
                     GdkScrollDirection  direction)
1288
1260
{
1289
1261
  GdkEvent *event;
1290
1262
  NSPoint point;
1291
1263
  
1292
1264
  event = gdk_event_new (GDK_SCROLL);
1293
1265
  event->scroll.window = window;
1294
 
  event->scroll.time = get_event_time (nsevent);
 
1266
  event->scroll.time = get_time_from_ns_event (nsevent);
1295
1267
 
1296
1268
  point = [nsevent locationInWindow];
1297
1269
  event->scroll.x = point.x;
1307
1279
}
1308
1280
 
1309
1281
static GdkEvent *
1310
 
create_key_event (GdkWindow *window, NSEvent *nsevent, GdkEventType type)
 
1282
create_key_event (GdkWindow    *window, 
 
1283
                  NSEvent      *nsevent, 
 
1284
                  GdkEventType  type)
1311
1285
{
1312
1286
  GdkEvent *event;
1313
1287
  gchar buf[7];
1315
1289
 
1316
1290
  event = gdk_event_new (type);
1317
1291
  event->key.window = window;
1318
 
  event->key.time = get_event_time (nsevent);
1319
 
  event->key.state = get_keyboard_modifiers_from_nsevent (nsevent);
 
1292
  event->key.time = get_time_from_ns_event (nsevent);
 
1293
  event->key.state = get_keyboard_modifiers_from_ns_event (nsevent);
1320
1294
  event->key.hardware_keycode = [nsevent keyCode];
1321
1295
  event->key.group = ([nsevent modifierFlags] & NSAlternateKeyMask) ? 1 : 0;
1322
1296
 
1329
1303
                                       &event->key.keyval,
1330
1304
                                       NULL, NULL, NULL);
1331
1305
 
1332
 
  event->key.is_modifier = _gdk_quartz_key_is_modifier (event->key.hardware_keycode);
 
1306
  event->key.is_modifier = _gdk_quartz_keys_is_modifier (event->key.hardware_keycode);
1333
1307
 
1334
1308
  event->key.string = NULL;
1335
1309
 
1379
1353
}
1380
1354
 
1381
1355
static GdkEventMask current_mask = 0;
1382
 
GdkEventMask _gdk_quartz_get_current_event_mask (void)
 
1356
GdkEventMask 
 
1357
_gdk_quartz_events_get_current_event_mask (void)
1383
1358
{
1384
1359
  return current_mask;
1385
1360
}
1397
1372
      /* Apply global filters */
1398
1373
 
1399
1374
      GdkFilterReturn result = apply_filters (NULL, nsevent, _gdk_default_filters);
1400
 
      
 
1375
 
1401
1376
      /* If result is GDK_FILTER_CONTINUE, we continue as if nothing
1402
1377
       * happened. If it is GDK_FILTER_REMOVE,
1403
1378
       * we return TRUE and won't send the message to Quartz.
1425
1400
              generate_grab_broken_event (_gdk_quartz_pointer_grab_window,
1426
1401
                                          FALSE, pointer_grab_implicit,
1427
1402
                                          NULL);
1428
 
              g_object_unref (_gdk_quartz_pointer_grab_window);
1429
 
              _gdk_quartz_pointer_grab_window = NULL;
 
1403
              pointer_ungrab_internal (FALSE);
1430
1404
            }
1431
1405
        }
1432
1406
    }
1433
1407
 
1434
 
  window = find_window_for_event (nsevent, &x, &y);
 
1408
  window = find_window_for_ns_event (nsevent, &x, &y);
1435
1409
 
1436
 
  /* FIXME: During owner_event grabs, we don't find a window when there is a
1437
 
   * click on a no-window widget, which makes popups etc still stay up. Need
1438
 
   * to figure out why that is.
1439
 
   */
1440
 
  
1441
1410
  if (!window)
1442
1411
    return FALSE;
1443
1412
 
1457
1426
        GdkEventMask event_mask;
1458
1427
 
1459
1428
        /* Emulate implicit grab, when the window has both PRESS and RELEASE
1460
 
         * in its mask, like X (and make it owner_events since that's what
1461
 
         * implicit grabs are like).
 
1429
         * in its mask, like X.
1462
1430
         */
1463
 
        event_mask = (GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK);
 
1431
        event_mask = (GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
1464
1432
        if (!_gdk_quartz_pointer_grab_window &&
1465
1433
            (GDK_WINDOW_OBJECT (window)->event_mask & event_mask) == event_mask)
1466
1434
          {
1467
 
            pointer_grab_internal (window, TRUE,
 
1435
            pointer_grab_internal (window, FALSE,
1468
1436
                                   GDK_WINDOW_OBJECT (window)->event_mask,
1469
1437
                                   NULL, NULL, TRUE);
1470
1438
          }
1483
1451
      append_event (event);
1484
1452
      
1485
1453
      /* Ungrab implicit grab */
1486
 
      if (_gdk_quartz_pointer_grab_window &&
1487
 
          pointer_grab_implicit)
 
1454
      if (_gdk_quartz_pointer_grab_window && pointer_grab_implicit)
1488
1455
        pointer_ungrab_internal (TRUE);
1489
1456
      break;
1490
1457
 
1546
1513
      {
1547
1514
        GdkEventType type;
1548
1515
 
1549
 
        type = _gdk_quartz_key_event_type (nsevent);
 
1516
        type = _gdk_quartz_keys_event_type (nsevent);
1550
1517
        if (type == GDK_NOTHING)
1551
1518
          return FALSE;
1552
1519
        
1565
1532
void
1566
1533
_gdk_events_queue (GdkDisplay *display)
1567
1534
{  
 
1535
  NSEvent *current_event = _gdk_quartz_event_loop_get_current ();
 
1536
 
1568
1537
  if (current_event)
1569
1538
    {
1570
 
      if (!gdk_event_translate (current_event))
 
1539
      if (!gdk_event_translate (current_event)) 
1571
1540
        [NSApp sendEvent:current_event];
1572
 
      
1573
 
      [current_event release];
1574
 
      current_event = NULL;
 
1541
                
 
1542
      _gdk_quartz_event_loop_release_current ();
1575
1543
    }
1576
1544
}
1577
1545
 
1581
1549
  /* Not supported. */
1582
1550
}
1583
1551
 
 
1552
void 
 
1553
gdk_display_add_client_message_filter (GdkDisplay   *display,
 
1554
                                       GdkAtom       message_type,
 
1555
                                       GdkFilterFunc func,
 
1556
                                       gpointer      data)
 
1557
{
 
1558
  /* Not supported. */
 
1559
}
 
1560
 
 
1561
void 
 
1562
gdk_add_client_message_filter (GdkAtom       message_type,
 
1563
                               GdkFilterFunc func,
 
1564
                               gpointer      data)
 
1565
{
 
1566
  /* Not supported. */
 
1567
}
 
1568
 
1584
1569
void
1585
1570
gdk_display_sync (GdkDisplay *display)
1586
1571
{
1614
1599
                        const gchar *name,
1615
1600
                        GValue      *value)
1616
1601
{
1617
 
  /* FIXME: This should be fetched from the correct preference value. See:
1618
 
     http://developer.apple.com/documentation/UserExperience/\
1619
 
     Conceptual/OSXHIGuidelines/XHIGText/chapter_13_section_2.html
1620
 
  */
1621
 
  if (strcmp (name, "gtk-font-name") == 0)
1622
 
    {
1623
 
      g_value_set_string (value, "Lucida Grande 12");
1624
 
      return TRUE;
1625
 
    }
1626
 
  else if (strcmp (name, "gtk-double-click-time") == 0)
 
1602
  if (strcmp (name, "gtk-double-click-time") == 0)
1627
1603
    {
1628
1604
      NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
1629
1605
      float t;