Generate a grab broken event when appropriate. Fixes bug #346603, patch

2006-07-07  Richard Hult  <richard@imendio.com>

	* gdk/quartz/gdkevents-quartz.c: Generate a grab broken event when
	appropriate. Fixes bug #346603, patch from Dave Vasilevsky.

	* gdk/quartz/gdkevents-quartz.c:
	* gdk/quartz/gdkkeys-quartz.c:
	* gdk/quartz/gdkprivate-quartz.c: Another patch from Dave Vasilevsky,
	fixes bug #346605. Makes modifier key events being sent properly.
This commit is contained in:
Richard Hult 2006-07-07 20:19:22 +00:00 committed by Richard Hult
parent ca752b0f85
commit 2fbe2ebc9a
5 changed files with 152 additions and 49 deletions

View File

@ -1,3 +1,13 @@
2006-07-07 Richard Hult <richard@imendio.com>
* gdk/quartz/gdkevents-quartz.c: Generate a grab broken event when
appropriate. Fixes bug #346603, patch from Dave Vasilevsky.
* gdk/quartz/gdkevents-quartz.c:
* gdk/quartz/gdkkeys-quartz.c:
* gdk/quartz/gdkprivate-quartz.c: Another patch from Dave Vasilevsky,
fixes bug #346605. Makes modifier key events being sent properly.
2006-07-07 Michael Natterer <mitch@imendio.com>
* gtk/gtkrc.c

View File

@ -1,3 +1,13 @@
2006-07-07 Richard Hult <richard@imendio.com>
* gdk/quartz/gdkevents-quartz.c: Generate a grab broken event when
appropriate. Fixes bug #346603, patch from Dave Vasilevsky.
* gdk/quartz/gdkevents-quartz.c:
* gdk/quartz/gdkkeys-quartz.c:
* gdk/quartz/gdkprivate-quartz.c: Another patch from Dave Vasilevsky,
fixes bug #346605. Makes modifier key events being sent properly.
2006-07-07 Michael Natterer <mitch@imendio.com>
* gtk/gtkrc.c

View File

@ -333,6 +333,28 @@ gdk_event_get_graphics_expose (GdkWindow *window)
return NULL;
}
static void
generate_grab_broken_event (GdkWindow *window,
gboolean keyboard,
gboolean implicit,
GdkWindow *grab_window)
{
if (!GDK_WINDOW_DESTROYED (window))
{
GdkEvent event;
event.type = GDK_GRAB_BROKEN;
event.grab_broken.window = window;
event.grab_broken.send_event = 0;
event.grab_broken.keyboard = keyboard;
event.grab_broken.implicit = implicit;
event.grab_broken.grab_window = grab_window;
gdk_event_put (&event);
}
}
GdkGrabStatus
gdk_keyboard_grab (GdkWindow *window,
gint owner_events,
@ -342,7 +364,11 @@ gdk_keyboard_grab (GdkWindow *window,
g_return_val_if_fail (GDK_IS_WINDOW (window), 0);
if (_gdk_quartz_keyboard_grab_window)
gdk_keyboard_ungrab (time);
{
generate_grab_broken_event (_gdk_quartz_keyboard_grab_window,
TRUE, FALSE, window);
g_object_unref (_gdk_quartz_keyboard_grab_window);
}
_gdk_quartz_keyboard_grab_window = g_object_ref (window);
keyboard_grab_owner_events = owner_events;
@ -454,10 +480,15 @@ gdk_pointer_grab (GdkWindow *window,
if (_gdk_quartz_pointer_grab_window)
{
if (!pointer_grab_implicit)
return GDK_GRAB_ALREADY_GRABBED;
if (_gdk_quartz_pointer_grab_window == window && !pointer_grab_implicit)
return GDK_GRAB_ALREADY_GRABBED;
else
pointer_ungrab_internal (TRUE);
{
if (_gdk_quartz_pointer_grab_window != window)
generate_grab_broken_event (_gdk_quartz_pointer_grab_window,
FALSE, pointer_grab_implicit, window);
pointer_ungrab_internal (TRUE);
}
}
return pointer_grab_internal (window, owner_events, event_mask,
@ -680,9 +711,18 @@ get_event_mask_from_ns_event (NSEvent *nsevent)
return mask;
}
case NSKeyDown:
return GDK_KEY_PRESS_MASK;
case NSKeyUp:
return GDK_KEY_RELEASE_MASK;
case NSFlagsChanged:
{
GdkEventType type = _gdk_quartz_key_event_type (nsevent);
switch (type)
{
case GDK_KEY_PRESS: return GDK_KEY_PRESS_MASK;
case GDK_KEY_RELEASE: return GDK_KEY_RELEASE_MASK;
case GDK_NOTHING: return 0;
default: g_assert_not_reached ();
}
}
default:
g_assert_not_reached ();
}
@ -1137,6 +1177,7 @@ find_window_for_event (NSEvent *nsevent, gint *x, gint *y)
case NSKeyDown:
case NSKeyUp:
case NSFlagsChanged:
{
GdkWindow *keyboard_window;
GdkEventMask event_mask;
@ -1274,24 +1315,11 @@ create_scroll_event (GdkWindow *window, NSEvent *nsevent, GdkScrollDirection dir
}
static GdkEvent *
create_key_event (GdkWindow *window, NSEvent *nsevent)
create_key_event (GdkWindow *window, NSEvent *nsevent, GdkEventType type)
{
GdkEventType event_type;
GdkEvent *event;
switch ([nsevent type])
{
case NSKeyDown:
event_type = GDK_KEY_PRESS;
break;
case NSKeyUp:
event_type = GDK_KEY_RELEASE;
break;
default:
g_assert_not_reached ();
}
event = gdk_event_new (event_type);
event = gdk_event_new (type);
event->key.window = window;
event->key.time = get_event_time (nsevent);
event->key.state = get_keyboard_modifiers_from_nsevent (nsevent);
@ -1305,6 +1333,12 @@ create_key_event (GdkWindow *window, NSEvent *nsevent)
&event->key.keyval,
NULL, NULL, NULL);
GDK_NOTE(EVENTS,
g_message ("key %s:\t\twindow: %p key: %12s %d",
type == GDK_KEY_PRESS ? "press" : "release",
event->key.window,
event->key.keyval ? gdk_keyval_name (event->key.keyval) : "(none)",
event->key.keyval));
return event;
}
@ -1425,11 +1459,17 @@ gdk_event_translate (NSEvent *nsevent)
}
case NSKeyDown:
case NSKeyUp:
event = create_key_event (window, nsevent);
append_event (event);
return TRUE;
break;
case NSFlagsChanged:
{
GdkEventType type = _gdk_quartz_key_event_type (nsevent);
if (type == GDK_NOTHING)
return FALSE;
event = create_key_event (window, nsevent, type);
append_event (event);
return TRUE;
break;
}
default:
NSLog(@"Untranslated: %@", nsevent);
}

View File

@ -52,6 +52,7 @@
#include <config.h>
#include <Carbon/Carbon.h>
#include <AppKit/NSEvent.h>
#include "gdk.h"
#include "gdkkeysyms.h"
@ -102,30 +103,32 @@ macroman2ucs (unsigned char c)
const static struct {
guint keycode;
guint keyval;
unsigned int modmask; /* So we can tell when a mod key is pressed/released */
} known_keys[] = {
{ 55, GDK_Meta_L },
{ 56, GDK_Shift_L },
{ 57, GDK_Caps_Lock },
{ 58, GDK_Alt_L },
{ 59, GDK_Control_L },
{ 60, GDK_Shift_R },
{ 61, GDK_Alt_R },
{ 62, GDK_Control_R },
{ 122, GDK_F1 },
{ 120, GDK_F2 },
{ 99, GDK_F3 },
{ 118, GDK_F4 },
{ 96, GDK_F5 },
{ 97, GDK_F6 },
{ 98, GDK_F7 },
{ 100, GDK_F8 },
{ 101, GDK_F9 },
{ 109, GDK_F10 },
{ 103, GDK_F11 },
{ 111, GDK_F12 },
{ 105, GDK_F13 },
{ 107, GDK_F14 },
{ 113, GDK_F15 },
{ 54, GDK_Meta_R, NSCommandKeyMask },
{ 55, GDK_Meta_L, NSCommandKeyMask },
{ 56, GDK_Shift_L, NSShiftKeyMask },
{ 57, GDK_Caps_Lock, NSAlphaShiftKeyMask },
{ 58, GDK_Alt_L, NSAlternateKeyMask },
{ 59, GDK_Control_L, NSControlKeyMask },
{ 60, GDK_Shift_R, NSShiftKeyMask },
{ 61, GDK_Alt_R, NSAlternateKeyMask },
{ 62, GDK_Control_R, NSControlKeyMask },
{ 122, GDK_F1, 0 },
{ 120, GDK_F2, 0 },
{ 99, GDK_F3, 0 },
{ 118, GDK_F4, 0 },
{ 96, GDK_F5, 0 },
{ 97, GDK_F6, 0 },
{ 98, GDK_F7, 0 },
{ 100, GDK_F8, 0 },
{ 101, GDK_F9, 0 },
{ 109, GDK_F10, 0 },
{ 103, GDK_F11, 0 },
{ 111, GDK_F12, 0 },
{ 105, GDK_F13, 0 },
{ 107, GDK_F14, 0 },
{ 113, GDK_F15, 0 },
};
const static struct {
@ -574,3 +577,41 @@ gdk_keymap_translate_keyboard_state (GdkKeymap *keymap,
return TRUE;
}
/* What sort of key event is this? Returns one of
* GDK_KEY_PRESS, GDK_KEY_RELEASE, GDK_NOTHING (should be ignored)
*/
GdkEventType _gdk_quartz_key_event_type (NSEvent *event)
{
unsigned short keycode;
unsigned int flags;
int i;
switch ([event type])
{
case NSKeyDown: return GDK_KEY_PRESS;
case NSKeyUp: return GDK_KEY_RELEASE;
case NSFlagsChanged: break; /* Continue... */
default: g_assert_not_reached ();
}
/* For flags-changed events, we have to find the special key that caused the
* event, and see if it's in the modifier mask. */
keycode = [event keyCode];
flags = [event modifierFlags];
for (i = 0; i < G_N_ELEMENTS (known_keys); i++)
{
if (known_keys[i].keycode == keycode)
{
if (flags & known_keys[i].modmask)
return GDK_KEY_PRESS;
else
return GDK_KEY_RELEASE;
}
}
/* Some keypresses (eg: Expose' activations) seem to trigger flags-changed
* events for no good reason. Ignore them! */
return GDK_NOTHING;
}

View File

@ -122,6 +122,8 @@ GdkImage *_gdk_quartz_copy_to_image (GdkDrawable *drawable,
void _gdk_quartz_send_map_events (GdkWindow *window);
GdkEventType _gdk_quartz_flags_changed_is_press (NSEvent *event);
extern GdkWindow *_gdk_quartz_keyboard_grab_window;
extern GdkWindow *_gdk_quartz_pointer_grab_window;