changeset 26:284fe09c6e64

quasimode events now come with complete modifier key information.
author Atul Varma <avarma@mozilla.com>
date Mon, 12 Apr 2010 10:08:28 -0700
parents 5396bc2158b9
children 5b881055e83d
files QuasimodalEventTap.m Quasimode.m
diffstat 2 files changed, 64 insertions(+), 54 deletions(-) [+]
line wrap: on
line diff
--- a/QuasimodalEventTap.m	Mon Apr 12 06:57:47 2010 -0700
+++ b/QuasimodalEventTap.m	Mon Apr 12 10:08:28 2010 -0700
@@ -14,6 +14,12 @@
 #define DEBUG_MSG(msg)
 #endif
 
+static NSNumber *isPressed(CGEventFlags flags,
+                           CGEventFlags filter)
+{
+  return [NSNumber numberWithBool: ((flags & filter) != 0)];
+}
+
 static CGEventRef eventTapCallback(CGEventTapProxy proxy,
                                    CGEventType type,
                                    CGEventRef event,
@@ -26,24 +32,62 @@
           userInfo: nil];
 }
 
+- (void)sendQuasimodeEvent:(CGEventRef)event
+                  withType:(NSString *)eventType {
+  UniChar strbuf[MAX_STR_LEN];
+  UniCharCount charsCopied;
+
+  CGEventKeyboardGetUnicodeString(event,
+                                  MAX_STR_LEN,
+                                  &charsCopied,
+                                  strbuf);
+
+  NSString *chars = [NSString stringWithCharacters: strbuf
+                              length: charsCopied];
+
+  int64_t keycode = CGEventGetIntegerValueField(event,
+                                                kCGKeyboardEventKeycode);
+
+  NSNumber *keycodeNum = [NSNumber numberWithUnsignedInt: keycode];
+
+  NSArray *keys = [NSArray arrayWithObjects: @"type",
+                           @"keyIdentifier",
+                           @"keyLocation",
+                           @"ctrlKey",
+                           @"altKey",
+                           @"shiftKey",
+                           @"metaKey",
+                           nil];
+
+  CGEventFlags flags = CGEventGetFlags(event);
+
+  NSArray *values = [NSArray arrayWithObjects: eventType,
+                             chars,
+                             keycodeNum,
+                             isPressed(flags, kCGEventFlagMaskControl),
+                             isPressed(flags, kCGEventFlagMaskAlternate),
+                             isPressed(flags, kCGEventFlagMaskShift),
+                             isPressed(flags, kCGEventFlagMaskCommand),
+                             nil];
+
+  NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
+                                     forKeys: keys];
+
+  [center postNotificationName: @"QuasimodeEvent"
+          object: name
+          userInfo: dict];
+}
+
 - (CGEventRef)processEventWithProxy: (CGEventTapProxy)proxy
                                type: (CGEventType)type
                               event: (CGEventRef)event {
   BOOL passOnEvent = !inQuasimode;
+  CGEventFlags flags = CGEventGetFlags(event);
 
   if (type == kCGEventFlagsChanged) {
-    CGEventFlags flags = CGEventGetFlags(event);
-
     if (inQuasimode) {
       if (!(flags & quasimodeKey)) {
-        NSArray *keys = [NSArray arrayWithObjects: @"type", nil];
-        NSArray *values = [NSArray arrayWithObjects: @"quasimodeend", nil];
-        NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
-                                           forKeys: keys];
-
-        [center postNotificationName: @"QuasimodeEvent"
-                object: name
-                userInfo: dict];
+        [self sendQuasimodeEvent: event withType: @"quasimodeend"];
 
         inQuasimode = NO;
         if (numQuasimodalKeyDowns == 1) {
@@ -76,14 +120,7 @@
       }
     } else {
       if (flags & quasimodeKey) {
-        NSArray *keys = [NSArray arrayWithObjects: @"type", nil];
-        NSArray *values = [NSArray arrayWithObjects: @"quasimodestart", nil];
-        NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
-                                           forKeys: keys];
-
-        [center postNotificationName: @"QuasimodeEvent"
-                object: name
-                userInfo: dict];
+        [self sendQuasimodeEvent: event withType: @"quasimodestart"];
 
         inQuasimode = YES;
         passOnEvent = NO;
@@ -97,20 +134,7 @@
     /* Key up/down event */
 
     if (inQuasimode) {
-      UniChar strbuf[MAX_STR_LEN];
-      UniCharCount charsCopied;
-
-      CGEventKeyboardGetUnicodeString(
-        event,
-        MAX_STR_LEN,
-        &charsCopied,
-        strbuf
-      );
-
-      NSString *chars = [NSString stringWithCharacters: strbuf
-                                  length: charsCopied];
       NSString *eventType;
-
       int64_t keycode = CGEventGetIntegerValueField(
         event,
         kCGKeyboardEventKeycode
@@ -124,18 +148,7 @@
       } else
         eventType = @"quasimodekeyup";
 
-      NSNumber *keycodeNum = [NSNumber numberWithUnsignedInt: keycode];
-
-      NSArray *keys = [NSArray arrayWithObjects: @"type", @"keyIdentifier",
-                               @"keyLocation", nil];
-      NSArray *values = [NSArray arrayWithObjects: eventType, chars,
-                                 keycodeNum, nil];
-      NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
-                                         forKeys: keys];
-
-      [center postNotificationName: @"QuasimodeEvent"
-              object: name
-              userInfo: dict];
+      [self sendQuasimodeEvent: event withType: eventType];
     } else {
       [self sendSomeKeyEvent];
     }
--- a/Quasimode.m	Mon Apr 12 06:57:47 2010 -0700
+++ b/Quasimode.m	Mon Apr 12 10:08:28 2010 -0700
@@ -14,23 +14,20 @@
 @implementation Quasimode
 - onEvent:(NSNotification *)notification {
   NSDictionary *info = [notification userInfo];
-  NSString *type = [info valueForKey: @"type"];
-  NSString *keyIdentifier = [info valueForKey: @"keyIdentifier"];
-  NSNumber *keyLocation = [info valueForKey: @"keyLocation"];
   DOMDocument *document = [[view mainFrame] DOMDocument];
   DOMEvent *event = [document createEvent: @"KeyboardEvent"];
   DOMKeyboardEvent *keyEvent = (DOMKeyboardEvent *) event;
-  [keyEvent initKeyboardEvent: type
+  [keyEvent initKeyboardEvent: [info valueForKey: @"type"]
             canBubble: NO
             cancelable: NO
             view: [document defaultView]
-            keyIdentifier: keyIdentifier
-            keyLocation: [keyLocation unsignedIntValue]
-            ctrlKey: NO
-            altKey: NO
-            shiftKey: NO
-            metaKey: YES
-            altGraphKey: NO];
+            keyIdentifier: [info valueForKey: @"keyIdentifier"]
+            keyLocation: [[info valueForKey: @"keyLocation"]
+                           unsignedIntValue]
+            ctrlKey: [[info valueForKey: @"ctrlKey"] boolValue]
+            altKey: [[info valueForKey: @"altKey"] boolValue]
+            shiftKey: [[info valueForKey: @"shiftKey"] boolValue]
+            metaKey: [[info valueForKey: @"metaKey"] boolValue]];
   [document dispatchEvent: event];
 }