comparison QuasimodalEventTap.m @ 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
comparison
equal deleted inserted replaced
25:5396bc2158b9 26:284fe09c6e64
12 #define DEBUG_MSG(msg) printf(msg); 12 #define DEBUG_MSG(msg) printf(msg);
13 #else 13 #else
14 #define DEBUG_MSG(msg) 14 #define DEBUG_MSG(msg)
15 #endif 15 #endif
16 16
17 static NSNumber *isPressed(CGEventFlags flags,
18 CGEventFlags filter)
19 {
20 return [NSNumber numberWithBool: ((flags & filter) != 0)];
21 }
22
17 static CGEventRef eventTapCallback(CGEventTapProxy proxy, 23 static CGEventRef eventTapCallback(CGEventTapProxy proxy,
18 CGEventType type, 24 CGEventType type,
19 CGEventRef event, 25 CGEventRef event,
20 void *refcon); 26 void *refcon);
21 27
24 [center postNotificationName: @"NonQuasimodalKeypress" 30 [center postNotificationName: @"NonQuasimodalKeypress"
25 object: name 31 object: name
26 userInfo: nil]; 32 userInfo: nil];
27 } 33 }
28 34
35 - (void)sendQuasimodeEvent:(CGEventRef)event
36 withType:(NSString *)eventType {
37 UniChar strbuf[MAX_STR_LEN];
38 UniCharCount charsCopied;
39
40 CGEventKeyboardGetUnicodeString(event,
41 MAX_STR_LEN,
42 &charsCopied,
43 strbuf);
44
45 NSString *chars = [NSString stringWithCharacters: strbuf
46 length: charsCopied];
47
48 int64_t keycode = CGEventGetIntegerValueField(event,
49 kCGKeyboardEventKeycode);
50
51 NSNumber *keycodeNum = [NSNumber numberWithUnsignedInt: keycode];
52
53 NSArray *keys = [NSArray arrayWithObjects: @"type",
54 @"keyIdentifier",
55 @"keyLocation",
56 @"ctrlKey",
57 @"altKey",
58 @"shiftKey",
59 @"metaKey",
60 nil];
61
62 CGEventFlags flags = CGEventGetFlags(event);
63
64 NSArray *values = [NSArray arrayWithObjects: eventType,
65 chars,
66 keycodeNum,
67 isPressed(flags, kCGEventFlagMaskControl),
68 isPressed(flags, kCGEventFlagMaskAlternate),
69 isPressed(flags, kCGEventFlagMaskShift),
70 isPressed(flags, kCGEventFlagMaskCommand),
71 nil];
72
73 NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
74 forKeys: keys];
75
76 [center postNotificationName: @"QuasimodeEvent"
77 object: name
78 userInfo: dict];
79 }
80
29 - (CGEventRef)processEventWithProxy: (CGEventTapProxy)proxy 81 - (CGEventRef)processEventWithProxy: (CGEventTapProxy)proxy
30 type: (CGEventType)type 82 type: (CGEventType)type
31 event: (CGEventRef)event { 83 event: (CGEventRef)event {
32 BOOL passOnEvent = !inQuasimode; 84 BOOL passOnEvent = !inQuasimode;
85 CGEventFlags flags = CGEventGetFlags(event);
33 86
34 if (type == kCGEventFlagsChanged) { 87 if (type == kCGEventFlagsChanged) {
35 CGEventFlags flags = CGEventGetFlags(event);
36
37 if (inQuasimode) { 88 if (inQuasimode) {
38 if (!(flags & quasimodeKey)) { 89 if (!(flags & quasimodeKey)) {
39 NSArray *keys = [NSArray arrayWithObjects: @"type", nil]; 90 [self sendQuasimodeEvent: event withType: @"quasimodeend"];
40 NSArray *values = [NSArray arrayWithObjects: @"quasimodeend", nil];
41 NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
42 forKeys: keys];
43
44 [center postNotificationName: @"QuasimodeEvent"
45 object: name
46 userInfo: dict];
47 91
48 inQuasimode = NO; 92 inQuasimode = NO;
49 if (numQuasimodalKeyDowns == 1) { 93 if (numQuasimodalKeyDowns == 1) {
50 CGEventRef event[2]; 94 CGEventRef event[2];
51 95
74 } 118 }
75 DEBUG_MSG("Exit quasimode\n"); 119 DEBUG_MSG("Exit quasimode\n");
76 } 120 }
77 } else { 121 } else {
78 if (flags & quasimodeKey) { 122 if (flags & quasimodeKey) {
79 NSArray *keys = [NSArray arrayWithObjects: @"type", nil]; 123 [self sendQuasimodeEvent: event withType: @"quasimodestart"];
80 NSArray *values = [NSArray arrayWithObjects: @"quasimodestart", nil];
81 NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
82 forKeys: keys];
83
84 [center postNotificationName: @"QuasimodeEvent"
85 object: name
86 userInfo: dict];
87 124
88 inQuasimode = YES; 125 inQuasimode = YES;
89 passOnEvent = NO; 126 passOnEvent = NO;
90 numQuasimodalKeyDowns = 0; 127 numQuasimodalKeyDowns = 0;
91 DEBUG_MSG("Enter quasimode\n"); 128 DEBUG_MSG("Enter quasimode\n");
95 } 132 }
96 } else { 133 } else {
97 /* Key up/down event */ 134 /* Key up/down event */
98 135
99 if (inQuasimode) { 136 if (inQuasimode) {
100 UniChar strbuf[MAX_STR_LEN];
101 UniCharCount charsCopied;
102
103 CGEventKeyboardGetUnicodeString(
104 event,
105 MAX_STR_LEN,
106 &charsCopied,
107 strbuf
108 );
109
110 NSString *chars = [NSString stringWithCharacters: strbuf
111 length: charsCopied];
112 NSString *eventType; 137 NSString *eventType;
113
114 int64_t keycode = CGEventGetIntegerValueField( 138 int64_t keycode = CGEventGetIntegerValueField(
115 event, 139 event,
116 kCGKeyboardEventKeycode 140 kCGKeyboardEventKeycode
117 ); 141 );
118 142
122 lastQuasimodalKeyFlags = CGEventGetFlags(event); 146 lastQuasimodalKeyFlags = CGEventGetFlags(event);
123 eventType = @"quasimodekeydown"; 147 eventType = @"quasimodekeydown";
124 } else 148 } else
125 eventType = @"quasimodekeyup"; 149 eventType = @"quasimodekeyup";
126 150
127 NSNumber *keycodeNum = [NSNumber numberWithUnsignedInt: keycode]; 151 [self sendQuasimodeEvent: event withType: eventType];
128
129 NSArray *keys = [NSArray arrayWithObjects: @"type", @"keyIdentifier",
130 @"keyLocation", nil];
131 NSArray *values = [NSArray arrayWithObjects: eventType, chars,
132 keycodeNum, nil];
133 NSDictionary *dict = [NSDictionary dictionaryWithObjects: values
134 forKeys: keys];
135
136 [center postNotificationName: @"QuasimodeEvent"
137 object: name
138 userInfo: dict];
139 } else { 152 } else {
140 [self sendSomeKeyEvent]; 153 [self sendSomeKeyEvent];
141 } 154 }
142 } 155 }
143 156