aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2010-09-21 17:35:45 +0000
committerGravatar gtm.daemon <gtm.daemon@7dc7ac4e-7543-0410-b95c-c1676fc8e2a3>2010-09-21 17:35:45 +0000
commit28ef947c2b07cb24cef5c3ae14c0e1974e60bf92 (patch)
tree79f7f3b995f17535b502dc84f91a46f70651e2e8
parent13d6b8a9e2d515de9d6b77064f69848a46a4cdeb (diff)
[Author: dmaclach]
Clean up GTMCarbonEvent hotkey stuff to make it more usable. R=thomasvl DELTA=138 (59 added, 13 deleted, 66 changed)
-rw-r--r--AppKit/GTMCarbonEvent.h86
-rw-r--r--AppKit/GTMCarbonEvent.m189
-rw-r--r--AppKit/GTMCarbonEventTest.m111
3 files changed, 216 insertions, 170 deletions
diff --git a/AppKit/GTMCarbonEvent.h b/AppKit/GTMCarbonEvent.h
index 93ad949..a234532 100644
--- a/AppKit/GTMCarbonEvent.h
+++ b/AppKit/GTMCarbonEvent.h
@@ -6,9 +6,9 @@
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -22,6 +22,7 @@
#import "GTMDefines.h"
@class GTMCarbonEventHandler;
+@class GTMCarbonHotKey;
// Objective C wrapper for a Carbon Event
@interface GTMCarbonEvent : NSObject <NSCopying> {
@@ -109,9 +110,9 @@
// size - the size of the data that |data| points to.
// data - pointer to the data you want to set the parameter to.
//
-- (void)setParameterNamed:(EventParamName)name
- type:(EventParamType)type
- size:(ByteCount)size
+- (void)setParameterNamed:(EventParamName)name
+ type:(EventParamType)type
+ size:(ByteCount)size
data:(const void *)data;
@@ -127,12 +128,12 @@
// Returns:
// YES is parameter is retrieved successfully. NO if parameter doesn't exist.
//
-- (BOOL)getParameterNamed:(EventParamName)name
- type:(EventParamType)type
- size:(ByteCount)size
+- (BOOL)getParameterNamed:(EventParamName)name
+ type:(EventParamType)type
+ size:(ByteCount)size
data:(void *)data;
-// Gets a the size of a parameter from an event.
+// Gets a the size of a parameter from an event.
//
// Arguments:
// name - the parameter name.
@@ -155,7 +156,7 @@
// Returns:
// OSStatus value.
//
-- (OSStatus)sendToTarget:(GTMCarbonEventHandler *)target
+- (OSStatus)sendToTarget:(GTMCarbonEventHandler *)target
options:(OptionBits)options;
// Post event to an event queue.
@@ -211,7 +212,7 @@ GTM_PARAM_TEMPLATE_DECL(EventHotKeyID)
// Utility function for converting between modifier types
// Arguments:
-// inCocoaModifiers - keyboard modifiers in carbon form
+// inCocoaModifiers - keyboard modifiers in carbon form
// (NSCommandKeyMask etc)
// Returns:
// Carbon modifiers equivalent to |inCocoaModifiers| (cmdKey etc)
@@ -224,20 +225,20 @@ GTM_EXTERN UInt32 GTMCocoaToCarbonKeyModifiers(NSUInteger inCocoaModifiers);
// cocoa modifiers equivalent to |inCocoaModifiers| (NSCommandKeyMask etc)
GTM_EXTERN NSUInteger GTMCarbonToCocoaKeyModifiers(UInt32 inCarbonModifiers);
-// An "abstract" superclass for objects that handle events such as
-// menus, HIObjects, etc.
+// An "abstract" superclass for objects that handle events such as
+// menus, HIObjects, etc.
//
// Subclasses are expected to override the eventTarget and
// handleEvent:handler: methods to customize them.
@interface GTMCarbonEventHandler : NSObject {
@private
- // handler we are wrapping
+ // handler we are wrapping
// lazily created in the eventHandler method
- EventHandlerRef eventHandler_;
+ EventHandlerRef eventHandler_;
__weak id delegate_; // Our delegate
// Does our delegate respond to the gtm_eventHandler:receivedEvent:handler:
// selector? Cached for performance reasons.
- BOOL delegateRespondsToHandleEvent_;
+ BOOL delegateRespondsToHandleEvent_;
}
// Registers the event handler to listen for |events|.
@@ -256,7 +257,7 @@ GTM_EXTERN NSUInteger GTMCarbonToCocoaKeyModifiers(UInt32 inCarbonModifiers);
//
- (void)unregisterForEvents:(const EventTypeSpec *)events count:(size_t)count;
-// To be overridden by subclasses to respond to events.
+// To be overridden by subclasses to respond to events.
//
// All subclasses should call [super handleEvent:handler:] if they
// don't handle the event themselves.
@@ -268,7 +269,7 @@ GTM_EXTERN NSUInteger GTMCarbonToCocoaKeyModifiers(UInt32 inCarbonModifiers);
// Returns:
// OSStatus - usually either noErr or eventNotHandledErr
//
-- (OSStatus)handleEvent:(GTMCarbonEvent *)event
+- (OSStatus)handleEvent:(GTMCarbonEvent *)event
handler:(EventHandlerCallRef)handler;
// To be overridden by subclasses to return the event target for the class.
@@ -300,12 +301,12 @@ GTM_EXTERN NSUInteger GTMCarbonToCocoaKeyModifiers(UInt32 inCarbonModifiers);
@end
-// Category for methods that a delegate of GTMCarbonEventHandlerDelegate may
+// Category for methods that a delegate of GTMCarbonEventHandlerDelegate may
// want to implement.
-@interface NSObject (GTMCarbonEventHandlerDelegate)
+@interface NSObject (GTMCarbonEventHandlerDelegate)
// If a delegate implements this method it gets called before every event
-// that the handler gets sent. If it returns anything but eventNotHandledErr,
+// that the handler gets sent. If it returns anything but eventNotHandledErr,
// the handlers handlerEvent:handler: method will not be called, and
// the return value returned by the delegate will be returned back to the
// carbon event dispatch system. This allows you to override any method
@@ -314,8 +315,8 @@ GTM_EXTERN NSUInteger GTMCarbonToCocoaKeyModifiers(UInt32 inCarbonModifiers);
// Arguments:
// delegate - the delegate to set to
//
-- (OSStatus)gtm_eventHandler:(GTMCarbonEventHandler *)sender
- receivedEvent:(GTMCarbonEvent *)event
+- (OSStatus)gtm_eventHandler:(GTMCarbonEventHandler *)sender
+ receivedEvent:(GTMCarbonEvent *)event
handler:(EventHandlerCallRef)handler;
@end
@@ -355,7 +356,7 @@ GTM_EXTERN const OSType kGTMCarbonFrameworkSignature;
// event handlers directly on the dispatcher if necessary.
@interface GTMCarbonEventDispatcherHandler : GTMCarbonEventHandler {
@private
- NSMutableDictionary *hotkeys_; // Collection of registered hotkeys
+ NSMutableArray *hotkeys_; // Collection of registered hotkeys
}
// Accessor to get the GTMCarbonEventDispatcherHandler singleton.
@@ -372,21 +373,40 @@ GTM_EXTERN const OSType kGTMCarbonFrameworkSignature;
// that these are cocoa modifiers, so NSCommandKeyMask etc.
// target - instance that will get |action| called when the hotkey fires
// action - the method to call on |target| when the hotkey fires
+// userInfo - storage for callers use
// onPress - is YES, the hotkey fires on the keydown (usual) otherwise
// it fires on the key up.
// Returns:
-// a EventHotKeyRef that you can use with other Carbon functions, or for
-// unregistering the hotkey. Note that all hotkeys are unregistered
-// automatically when an app quits. Will be NULL on failure.
-- (EventHotKeyRef)registerHotKey:(NSUInteger)keyCode
- modifiers:(NSUInteger)cocoaModifiers
- target:(id)target
- action:(SEL)action
- whenPressed:(BOOL)onPress;
+// a GTMCarbonHotKey. Note that all hotkeys are unregistered
+// automatically when an app quits. Will be nil on failure.
+- (GTMCarbonHotKey *)registerHotKey:(NSUInteger)keyCode
+ modifiers:(NSUInteger)cocoaModifiers
+ target:(id)target
+ action:(SEL)action
+ userInfo:(id)userInfo
+ whenPressed:(BOOL)onPress;
// Unregisters a hotkey previously registered with registerHotKey.
// Arguments:
// keyRef - the EventHotKeyRef to unregister
-- (void)unregisterHotKey:(EventHotKeyRef)keyRef;
+- (void)unregisterHotKey:(GTMCarbonHotKey *)keyRef;
+
+@end
+
+// Wrapper for all the info we need about a hotkey that we can store in a
+// Foundation storage class. We expecct selector to have this signature:
+// - (void)hitHotKey:(GTMCarbonHotKey *)key;
+@interface GTMCarbonHotKey : NSObject {
+ @private
+ EventHotKeyID id_; // EventHotKeyID for this hotkey.
+ EventHotKeyRef hotKeyRef_;
+ id target_; // Object we are going to call when the hotkey is hit
+ SEL selector_; // Selector we are going to call on target_
+ BOOL onKeyDown_; // Do we do it on key down or on key up?
+ id userInfo_;
+}
+- (id)userInfo;
+- (EventHotKeyRef)hotKeyRef;
+- (BOOL)onKeyDown;
@end
diff --git a/AppKit/GTMCarbonEvent.m b/AppKit/GTMCarbonEvent.m
index 28bfdb9..7753f1b 100644
--- a/AppKit/GTMCarbonEvent.m
+++ b/AppKit/GTMCarbonEvent.m
@@ -6,9 +6,9 @@
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -23,27 +23,22 @@
#import "GTMTypeCasting.h"
// Wrapper for all the info we need about a hotkey that we can store in a
-// Foundation storage class. We expecct selector to have this signature:
-// - (void)hitHotKey:sender;
-@interface GTMCarbonHotKey : NSObject {
- @private
- EventHotKeyID id_; // EventHotKeyID for this hotkey.
- id target_; // Object we are going to call when the hotkey is hit
- SEL selector_; // Selector we are going to call on target_
- BOOL onKeyDown_; // Do we do it on key down or on key up?
-}
+// Foundation storage class.
+@interface GTMCarbonHotKey (GTMCarbonHotKeyPrivate)
// Create a HotKey record
// Arguments:
// keyID - id of the hotkey
// target - object we are going to call when the hotkey is hit
// action - selector we are going to call on target
+// userInfo - user storage
// whenPressed - do we do it on key down or key up?
// Returns:
// a hotkey record, or nil on failure
-- (id)initWithHotKey:(EventHotKeyID)keyID
- target:(id)target
- action:(SEL)selector
+- (id)initWithHotKey:(EventHotKeyID)keyID
+ target:(id)target
+ action:(SEL)selector
+ userInfo:(id)userInfo
whenPressed:(BOOL)onKeyDown;
// Does this record match key |keyID|
@@ -56,13 +51,9 @@
// Make target perform selector
// Returns:
// Yes if handled
-- (BOOL)sendAction:(id)sender;
-
-// Do we do it on key down or key up?
-// Returns:
-// Yes if on keydown
-- (BOOL)onKeyDown;
+- (BOOL)sendAction;
+- (void)setHotKeyRef:(EventHotKeyRef)ref;
@end
@implementation GTMCarbonEvent
@@ -104,7 +95,7 @@
//
- (id)initWithClass:(UInt32)inClass kind:(UInt32)kind {
if ((self = [super init])) {
- verify_noerr(CreateEvent(kCFAllocatorDefault, inClass, kind,
+ verify_noerr(CreateEvent(kCFAllocatorDefault, inClass, kind,
0, kEventAttributeNone, &event_));
}
return self;
@@ -168,7 +159,7 @@
- (NSString *)description {
char cls[5];
UInt32 kind;
-
+
// Need everything bigendian if we are printing out the class as a "string"
*((UInt32 *)cls) = CFSwapInt32HostToBig([self eventClass]);
kind = [self eventKind];
@@ -237,9 +228,9 @@
// Returns:
// OSStatus value.
//
-- (OSStatus)sendToTarget:(GTMCarbonEventHandler *)target
+- (OSStatus)sendToTarget:(GTMCarbonEventHandler *)target
options:(OptionBits)options {
- return SendEventToEventTargetWithOptions(event_,
+ return SendEventToEventTargetWithOptions(event_,
[target eventTarget], options);
}
@@ -260,7 +251,7 @@
// Post event to current queue with standard priority.
//
- (void)postToCurrentQueue {
- verify_noerr([self postToQueue:GetCurrentEventQueue()
+ verify_noerr([self postToQueue:GetCurrentEventQueue()
priority:kEventPriorityStandard]);
}
@@ -268,7 +259,7 @@
// Post event to main queue with standard priority.
//
- (void)postToMainQueue {
- verify_noerr([self postToQueue:GetMainEventQueue()
+ verify_noerr([self postToQueue:GetMainEventQueue()
priority:kEventPriorityStandard]);
}
@@ -282,9 +273,9 @@
// size - the size of the data that |data| points to.
// data - pointer to the data you want to set the parameter to.
//
-- (void)setParameterNamed:(EventParamName)name
- type:(EventParamType)type
- size:(ByteCount)size
+- (void)setParameterNamed:(EventParamName)name
+ type:(EventParamType)type
+ size:(ByteCount)size
data:(const void *)data {
verify_noerr(SetEventParameter(event_, name, type, size, data));
}
@@ -302,17 +293,17 @@
// Returns:
// YES is parameter is retrieved successfully. NO if parameter doesn't exist.
//
-- (BOOL)getParameterNamed:(EventParamName)name
- type:(EventParamType)type
- size:(ByteCount)size
+- (BOOL)getParameterNamed:(EventParamName)name
+ type:(EventParamType)type
+ size:(ByteCount)size
data:(void *)data {
- OSStatus status = GetEventParameter(event_, name, type,
+ OSStatus status = GetEventParameter(event_, name, type,
NULL, size, NULL, data);
return status == noErr;
}
-// Gets a the size of a parameter from an event.
+// Gets a the size of a parameter from an event.
//
// Arguments:
// name - the parameter name.
@@ -398,7 +389,7 @@ const OSType kGTMCarbonFrameworkSignature = 'GTM ';
// Returns:
// OSStatus - usually either noErr or eventNotHandledErr
//
-- (OSStatus)handleEvent:(GTMCarbonEvent *)event
+- (OSStatus)handleEvent:(GTMCarbonEvent *)event
handler:(EventHandlerCallRef)handler {
OSStatus status = eventNotHandledErr;
require(event, CantUseParams);
@@ -436,14 +427,14 @@ static OSStatus EventHandler(EventHandlerCallRef inHandler,
GTMCarbonEvent *event = [GTMCarbonEvent eventWithEvent:inEvent];
GTMCarbonEventHandler *handler
= GTM_STATIC_CAST(GTMCarbonEventHandler, inUserData);
-
+
// First check to see if our delegate cares about this event. If the delegate
// handles it (i.e responds to it and does not return eventNotHandledErr) we
// do not pass it on to default handling.
OSStatus status = eventNotHandledErr;
if ([handler delegateRespondsToHandleEvent]) {
- status = [[handler delegate] gtm_eventHandler:handler
- receivedEvent:event
+ status = [[handler delegate] gtm_eventHandler:handler
+ receivedEvent:event
handler:inHandler];
}
if (status == eventNotHandledErr) {
@@ -463,8 +454,8 @@ static OSStatus EventHandler(EventHandlerCallRef inHandler,
if ( sHandlerProc == NULL ) {
sHandlerProc = NewEventHandlerUPP(EventHandler);
}
- verify_noerr(InstallEventHandler([self eventTarget],
- sHandlerProc, 0,
+ verify_noerr(InstallEventHandler([self eventTarget],
+ sHandlerProc, 0,
NULL, self, &eventHandler_));
}
return eventHandler_;
@@ -493,7 +484,7 @@ static OSStatus EventHandler(EventHandlerCallRef inHandler,
@implementation GTMCarbonEventMonitorHandler
-GTMOBJECT_SINGLETON_BOILERPLATE(GTMCarbonEventMonitorHandler,
+GTMOBJECT_SINGLETON_BOILERPLATE(GTMCarbonEventMonitorHandler,
sharedEventMonitorHandler);
- (EventTargetRef)eventTarget {
@@ -521,7 +512,7 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMCarbonEventApplicationEventHandler,
@implementation GTMCarbonEventDispatcherHandler
-GTMOBJECT_SINGLETON_BOILERPLATE(GTMCarbonEventDispatcherHandler,
+GTMOBJECT_SINGLETON_BOILERPLATE(GTMCarbonEventDispatcherHandler,
sharedEventDispatcherHandler);
// Register for the events we handle, and set up the dictionaries we need
@@ -535,7 +526,7 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMCarbonEventDispatcherHandler,
{ kEventClassKeyboard, kEventHotKeyReleased },
};
[self registerForEvents:events count:GetEventTypeCount(events)];
- hotkeys_ = [[NSMutableDictionary alloc] initWithCapacity:0];
+ hotkeys_ = [[NSMutableArray alloc] initWithCapacity:0];
}
return self;
}
@@ -560,51 +551,56 @@ GTMOBJECT_SINGLETON_BOILERPLATE(GTMCarbonEventDispatcherHandler,
// that these are cocoa modifiers, so NSCommandKeyMask etc.
// target - instance that will get |action| called when the hotkey fires
// action - the method to call on |target| when the hotkey fires
+// action should have the signature - (void)handler:(GTMCarbonEventDispatcherHandler *)handler
+// userInfo - user storage
// onKeyDown - is YES, the hotkey fires on the keydown (usual) otherwise
// it fires on the key up.
// Returns:
// a EventHotKeyRef that you can use with other Carbon functions, or for
// unregistering the hotkey. Note that all hotkeys are unregistered
// automatically when an app quits. Will be NULL on failure.
-- (EventHotKeyRef)registerHotKey:(NSUInteger)keyCode
- modifiers:(NSUInteger)cocoaModifiers
- target:(id)target
- action:(SEL)selector
- whenPressed:(BOOL)onKeyDown {
+- (GTMCarbonHotKey *)registerHotKey:(NSUInteger)keyCode
+ modifiers:(NSUInteger)cocoaModifiers
+ target:(id)target
+ action:(SEL)selector
+ userInfo:(id)userInfo
+ whenPressed:(BOOL)onKeyDown {
static UInt32 sCurrentID = 0;
-
+
+ GTMCarbonHotKey *newKey = nil;
EventHotKeyRef theRef = NULL;
EventHotKeyID keyID;
keyID.signature = kGTMCarbonFrameworkSignature;
keyID.id = ++sCurrentID;
- GTMCarbonHotKey *newKey = [[[GTMCarbonHotKey alloc] initWithHotKey:keyID
- target:target
- action:selector
- whenPressed:onKeyDown]
- autorelease];
+ newKey = [[[GTMCarbonHotKey alloc] initWithHotKey:keyID
+ target:target
+ action:selector
+ userInfo:userInfo
+ whenPressed:onKeyDown] autorelease];
require(newKey, CantCreateKey);
- require_noerr(RegisterEventHotKey((UInt32)keyCode,
- GTMCocoaToCarbonKeyModifiers(cocoaModifiers),
- keyID,
- [self eventTarget],
- 0,
- &theRef), CantRegisterHotkey);
-
-
- [hotkeys_ setObject:newKey forKey:[NSValue valueWithPointer:theRef]];
+ if (RegisterEventHotKey((UInt32)keyCode,
+ GTMCocoaToCarbonKeyModifiers(cocoaModifiers),
+ keyID,
+ [self eventTarget],
+ 0,
+ &theRef) == noErr) {
+ [newKey setHotKeyRef:theRef];
+ [hotkeys_ addObject:newKey];
+ } else {
+ newKey = nil;
+ }
CantCreateKey:
-CantRegisterHotkey:
- return theRef;
+ return newKey;
}
// Unregisters a hotkey previously registered with registerHotKey.
// Arguments:
// keyRef - the EventHotKeyRef to unregister
-- (void)unregisterHotKey:(EventHotKeyRef)keyRef {
- NSValue *key = [NSValue valueWithPointer:keyRef];
- check([hotkeys_ objectForKey:key] != nil);
- [hotkeys_ removeObjectForKey:key];
- verify_noerr(UnregisterEventHotKey(keyRef));
+- (void)unregisterHotKey:(GTMCarbonHotKey *)keyRef {
+ check([hotkeys_ containsObject:keyRef]);
+ [[keyRef retain] autorelease];
+ [hotkeys_ removeObject:keyRef];
+ verify_noerr(UnregisterEventHotKey([keyRef hotKeyRef]));
}
// A hotkey has been hit. See if it is one of ours, and if so fire it.
@@ -614,17 +610,17 @@ CantRegisterHotkey:
// Yes if handled.
- (BOOL)handleHotKeyEvent:(GTMCarbonEvent *)event {
EventHotKeyID keyID;
- BOOL handled = [event getEventHotKeyIDParameterNamed:kEventParamDirectObject
+ BOOL handled = [event getEventHotKeyIDParameterNamed:kEventParamDirectObject
data:&keyID];
if (handled) {
GTMCarbonHotKey *hotkey;
- GTM_FOREACH_OBJECT(hotkey, [hotkeys_ allValues]) {
+ GTM_FOREACH_OBJECT(hotkey, hotkeys_) {
if ([hotkey matchesHotKeyID:keyID]) {
EventKind kind = [event eventKind];
BOOL onKeyDown = [hotkey onKeyDown];
- if ((kind == kEventHotKeyPressed && onKeyDown) ||
+ if ((kind == kEventHotKeyPressed && onKeyDown) ||
(kind == kEventHotKeyReleased && !onKeyDown)) {
- handled = [hotkey sendAction:self];
+ handled = [hotkey sendAction];
}
break;
}
@@ -641,7 +637,7 @@ CantRegisterHotkey:
// handler - the handler call ref
// Returns:
// OSStatus
-- (OSStatus)handleEvent:(GTMCarbonEvent *)event
+- (OSStatus)handleEvent:(GTMCarbonEvent *)event
handler:(EventHandlerCallRef)handler {
OSStatus theStatus = eventNotHandledErr;
if ([event eventClass] == kEventClassKeyboard) {
@@ -665,14 +661,17 @@ CantRegisterHotkey:
// passed matches what we expect. (
// Arguments:
// keyID - id of the hotkey
+// reference - hotkey reference
// target - object we are going to call when the hotkey is hit
// action - selector we are going to call on target
+// userinfo - info for user
// whenPressed - do we do it on key down or key up?
// Returns:
// a hotkey record, or nil on failure
-- (id)initWithHotKey:(EventHotKeyID)keyID
- target:(id)target
- action:(SEL)selector
+- (id)initWithHotKey:(EventHotKeyID)keyID
+ target:(id)target
+ action:(SEL)selector
+ userInfo:(id)userInfo
whenPressed:(BOOL)onKeyDown {
if ((self = [super init])) {
if(!target || !selector) {
@@ -681,22 +680,33 @@ CantRegisterHotkey:
}
id_ = keyID;
target_ = [target retain];
+ userInfo_ = [userInfo retain];
selector_ = selector;
onKeyDown_ = onKeyDown;
- GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(target,
- selector,
- @encode(void),
+ GTMAssertSelectorNilOrImplementedWithReturnTypeAndArguments(target,
+ selector,
+ @encode(void),
@encode(id),
- NULL);
+ NULL);
}
return self;
}
- (void)dealloc {
[target_ release];
+ [userInfo_ release];
[super dealloc];
}
+- (NSUInteger)hash {
+ return (NSUInteger)hotKeyRef_;
+}
+
+- (BOOL)isEqual:(id)object {
+ return [object isMemberOfClass:[self class]]
+ && (hotKeyRef_ = [object hotKeyRef]);
+}
+
// Does this record match key |keyID|
// Arguments:
// keyID - the id to match against
@@ -706,10 +716,10 @@ CantRegisterHotkey:
return (id_.signature == keyID.signature) && (id_.id == keyID.id);
}
-- (BOOL)sendAction:(id)sender {
+- (BOOL)sendAction {
BOOL handled = NO;
@try {
- [target_ performSelector:selector_ withObject:sender];
+ [target_ performSelector:selector_ withObject:self];
handled = YES;
}
@catch (NSException * e) {
@@ -723,6 +733,17 @@ CantRegisterHotkey:
return onKeyDown_;
}
+- (id)userInfo {
+ return userInfo_;
+}
+
+- (EventHotKeyRef)hotKeyRef {
+ return hotKeyRef_;
+}
+
+- (void)setHotKeyRef:(EventHotKeyRef)ref {
+ hotKeyRef_ = ref;
+}
@end
diff --git a/AppKit/GTMCarbonEventTest.m b/AppKit/GTMCarbonEventTest.m
index 4cc039c..6a3d007 100644
--- a/AppKit/GTMCarbonEventTest.m
+++ b/AppKit/GTMCarbonEventTest.m
@@ -6,9 +6,9 @@
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the License at
-//
+//
// http://www.apache.org/licenses/LICENSE-2.0
-//
+//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
@@ -33,7 +33,7 @@
}
@end
-@interface GTMCarbonEventMonitorHandlerTest : GTMTestCase
+@interface GTMCarbonEventMonitorHandlerTest : GTMTestCase
@end
@interface GTMCarbonEventApplicationEventHandlerTest : GTMTestCase
@@ -60,7 +60,7 @@ static const UInt32 kTestParameterValue = 'bam ';
[event_ release];
}
-- (void)testCopy {
+- (void)testCopy {
GTMCarbonEvent *event2 = [[event_ copy] autorelease];
STAssertNotNil(event2, nil);
}
@@ -83,7 +83,7 @@ static const UInt32 kTestParameterValue = 'bam ';
- (void)testEventClass {
[self testEventWithClassAndKind];
-}
+}
- (void)testEventKind {
[self testEventWithClassAndKind];
@@ -112,10 +112,10 @@ static const UInt32 kTestParameterValue = 'bam ';
UInt32 theData = kTestParameterValue;
[event_ setUInt32ParameterNamed:kTestParameterName data:&theData];
theData = 0;
- STAssertEquals([event_ sizeOfParameterNamed:kTestParameterName
- type:typeUInt32],
+ STAssertEquals([event_ sizeOfParameterNamed:kTestParameterName
+ type:typeUInt32],
sizeof(UInt32), nil);
- STAssertTrue([event_ getUInt32ParameterNamed:kTestParameterName
+ STAssertTrue([event_ getUInt32ParameterNamed:kTestParameterName
data:&theData], nil);
STAssertEquals(theData, kTestParameterValue, nil);
}
@@ -123,11 +123,11 @@ static const UInt32 kTestParameterValue = 'bam ';
- (void)testGetParameterNamed {
[self testSetParameterNamed];
UInt32 theData = kTestParameterValue;
- STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
+ STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
data:&theData], nil);
- STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
+ STAssertFalse([event_ getUInt32ParameterNamed:kTestBadParameterName
data:NULL], nil);
-
+
}
- (void)testSizeOfParameterNamed {
@@ -138,8 +138,8 @@ static const UInt32 kTestParameterValue = 'bam ';
[self testSetParameterNamed];
}
-- (OSStatus)gtm_eventHandler:(GTMCarbonEventHandler *)sender
- receivedEvent:(GTMCarbonEvent *)event
+- (OSStatus)gtm_eventHandler:(GTMCarbonEventHandler *)sender
+ receivedEvent:(GTMCarbonEvent *)event
handler:(EventHandlerCallRef)handler {
OSStatus status = eventNotHandledErr;
if ([event eventClass] == kTestClass && [event eventKind] == kTestKind) {
@@ -150,8 +150,8 @@ static const UInt32 kTestParameterValue = 'bam ';
- (void)testSendToTarget {
EventTypeSpec types = { kTestClass, kTestKind };
- GTMCarbonEventDispatcherHandler *handler
- = [[GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler]
+ GTMCarbonEventDispatcherHandler *handler
+ = [[GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler]
autorelease];
[handler registerForEvents:&types count:1];
OSStatus status = [event_ sendToTarget:handler options:0];
@@ -165,13 +165,13 @@ static const UInt32 kTestParameterValue = 'bam ';
- (void)testPostToQueue {
EventQueueRef eventQueue = GetMainEventQueue();
[event_ postToMainQueue];
- OSStatus status = [event_ postToQueue:eventQueue
+ OSStatus status = [event_ postToQueue:eventQueue
priority:kEventPriorityStandard];
STAssertErr(status, eventAlreadyPostedErr, @"status: %ld", status);
EventTypeSpec types = { kTestClass, kTestKind };
status = FlushEventsMatchingListFromQueue(eventQueue, 1, &types);
STAssertNoErr(status, @"status: %ld", status);
-
+
eventQueue = GetCurrentEventQueue();
[event_ postToCurrentQueue];
status = [event_ postToQueue:eventQueue priority:kEventPriorityStandard];
@@ -190,9 +190,9 @@ static const UInt32 kTestParameterValue = 'bam ';
}
- (void)testDescription {
- NSString *descString
+ NSString *descString
= [NSString stringWithFormat:@"GTMCarbonEvent 'foo ' %d", kTestKind];
- STAssertEqualObjects([event_ description], descString, nil);
+ STAssertEqualObjects([event_ description], descString, nil);
}
@end
@@ -224,7 +224,7 @@ static const UInt32 kTestParameterValue = 'bam ';
}
-- (void)testSetDelegate {
+- (void)testSetDelegate {
[self testDelegate];
}
@@ -233,7 +233,7 @@ static const UInt32 kTestParameterValue = 'bam ';
@implementation GTMCarbonEventMonitorHandlerTest
- (void)testEventHandler {
- GTMCarbonEventMonitorHandler *monitor
+ GTMCarbonEventMonitorHandler *monitor
= [GTMCarbonEventMonitorHandler sharedEventMonitorHandler];
STAssertEquals([monitor eventTarget], GetEventMonitorTarget(), nil);
}
@@ -268,73 +268,78 @@ extern EventTargetRef GetApplicationEventTarget(void);
}
- (void)testEventHandler {
- GTMCarbonEventDispatcherHandler *dispatcher
+ GTMCarbonEventDispatcherHandler *dispatcher
= [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
STAssertEquals([dispatcher eventTarget], GetEventDispatcherTarget(), nil);
}
-- (void)hitHotKey:(id)sender {
+- (void)hitHotKey:(GTMCarbonHotKey *)key {
+ STAssertEqualObjects([key userInfo], self, nil);
[hotKeyHit_ setShouldStop:YES];
}
-- (void)hitExceptionalHotKey:(id)sender {
+- (void)hitExceptionalHotKey:(GTMCarbonHotKey *)key {
+ STAssertEqualObjects([key userInfo], self, nil);
[hotKeyHit_ setShouldStop:YES];
[NSException raise:@"foo" format:@"bar"];
}
- (void)testRegisterHotKeyModifiersTargetActionWhenPressed {
-
+
// This test can't be run if the screen saver is active because the security
// agent blocks us from sending events via remote operations
if (![GTMAppKitUnitTestingUtilities isScreenSaverActive]) {
- GTMCarbonEventDispatcherHandler *dispatcher
+ GTMCarbonEventDispatcherHandler *dispatcher
= [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
STAssertNotNil(dispatcher, @"Unable to acquire singleton");
- UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
+ UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
| NSAlternateKeyMask | NSCommandKeyMask);
- EventHotKeyRef hotKey;
[GTMUnitTestDevLogDebug expectPattern:@"DebugAssert: GoogleToolboxForMac: "
@"newKey CantCreateKey .*"];
- STAssertNULL([dispatcher registerHotKey:0x5
- modifiers:keyMods
- target:nil
- action:nil
- whenPressed:YES],
+ STAssertNil([dispatcher registerHotKey:0x5
+ modifiers:keyMods
+ target:nil
+ action:nil
+ userInfo:nil
+ whenPressed:YES],
@"Shouldn't have created hotkey");
- hotKey = [dispatcher registerHotKey:0x5
- modifiers:keyMods
- target:self
- action:@selector(hitHotKey:)
- whenPressed:YES];
- STAssertNotNULL(hotKey, @"Unable to create hotkey");
-
+ GTMCarbonHotKey *hotKey = [dispatcher registerHotKey:0x5
+ modifiers:keyMods
+ target:self
+ action:@selector(hitHotKey:)
+ userInfo:self
+ whenPressed:YES];
+ STAssertNotNil(hotKey, @"Unable to create hotkey");
+
// Post the hotkey combo to the event queue. If everything is working
// correctly hitHotKey: should get called, and hotKeyHit_ will be set for
// us. We run the event loop for a set amount of time waiting for this to
// happen.
[GTMAppKitUnitTestingUtilities postTypeCharacterEvent:'g' modifiers:keyMods];
STAssertTrue([NSApp gtm_runUpToSixtySecondsWithContext:hotKeyHit_], nil);
- [dispatcher unregisterHotKey:hotKey];
+ [dispatcher unregisterHotKey:hotKey];
}
}
- (void)testRegisterHotKeyModifiersTargetActionWhenPressedException {
-
+
// This test can't be run if the screen saver is active because the security
// agent blocks us from sending events via remote operations
if (![GTMAppKitUnitTestingUtilities isScreenSaverActive]) {
- GTMCarbonEventDispatcherHandler *dispatcher
+ GTMCarbonEventDispatcherHandler *dispatcher
= [GTMCarbonEventDispatcherHandler sharedEventDispatcherHandler];
STAssertNotNil(dispatcher, @"Unable to acquire singleton");
- UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
+ UInt32 keyMods = (NSShiftKeyMask | NSControlKeyMask
| NSAlternateKeyMask | NSCommandKeyMask);
- EventHotKeyRef hotKey = [dispatcher registerHotKey:0x5
- modifiers:keyMods
- target:self
- action:@selector(hitExceptionalHotKey:)
- whenPressed:YES];
- STAssertTrue(hotKey != nil, @"Unable to create hotkey");
-
+ GTMCarbonHotKey *hotKey
+ = [dispatcher registerHotKey:0x5
+ modifiers:keyMods
+ target:self
+ action:@selector(hitExceptionalHotKey:)
+ userInfo:self
+ whenPressed:YES];
+ STAssertNotNil(hotKey, @"Unable to create hotkey");
+
// Post the hotkey combo to the event queue. If everything is working
// correctly hitHotKey: should get called, and hotKeyHit_ will be set for
// us. We run the event loop for a set amount of time waiting for this to
@@ -342,7 +347,7 @@ extern EventTargetRef GetApplicationEventTarget(void);
[GTMAppKitUnitTestingUtilities postTypeCharacterEvent:'g' modifiers:keyMods];
[GTMUnitTestDevLog expectString:@"Exception fired in hotkey: foo (bar)"];
STAssertTrue([NSApp gtm_runUpToSixtySecondsWithContext:hotKeyHit_], nil);
- [dispatcher unregisterHotKey:hotKey];
+ [dispatcher unregisterHotKey:hotKey];
}
}
@@ -371,7 +376,7 @@ extern EventTargetRef GetApplicationEventTarget(void);
STAssertEquals(GTMCarbonToCocoaKeyModifiers(carbonMods), cocoaMods, nil);
}
}
-
+
@end