Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Sergio10

macrumors regular
Original poster
Oct 3, 2007
137
0
Hi,

I've developed application as agent which placed in status bar(near clock).

1. Is it possible to handle hot keys(e.g. when user press: Mac + G) out of application?
2. Is it possible to handle text selecting in some text editor etc. when my app is running?

Thanks
 
It may be possible with a kernel extension. You would have to over-write the HID driver or wrap something around an existing one.
 
Could you please provide me some url with more detailed info?

Thank you.
 
I'm pretty sure you can do this without writing a kernel extension, by making use of the "Enable access for assistive devices" in Univeral Access.

Several applications tell you to check that off, then allow you to map key combos to applications that are not the first responder.
 
jared_kipe, it's very interesting.
I've turned on "Enable access for assistive devices" option but when run my application and press hot key combination nothing heppens.

Could you please explain how to fix it or provide some simple example?

Thank you very much.
 
Its not magic, you can't just check off the box and expect it to start working in your application. Otherwise... every application would suddenly get key commands when they are not the first responder and it would get really confusing really fast.

I'm not going to "explain how to fix it" because you need to look into it yourself. I don't know how to do it, and I'm not going to learn how to just so I can "provide some simple example."

I would suspect that there is something like the NSNotification that you can register to receive these special key combos on, probably has something to do with the checkbox I described earlier.
 
Guys,

According to the guide I've developed a simple application which should track all keyboard events: http://slil.ru/29371847
But it doesn't work:confused:
Could you please help with fixing the issue?

Here is a code:
PHP:
@implementation MyApplication


static OSStatus MonitorHandler(EventHandlerCallRef nextHandler, EventRef theEvent, void * inRefcon)
{
	// Useless on 10.4 for keyboard events. If you requested to watch other events
	// (mouse or tablet events for example) they would into funnel to here.
	
	NSLog(@"it's working!!!!\n");
	
	return CallNextEventHandler(nextHandler, theEvent);
}

- (void)installMonitorHandler;
{
	OSStatus error = noErr;
	EventTypeSpec	kEvents[] =
	{
		{ kEventClassKeyboard, kEventRawKeyDown },
		{ kEventClassKeyboard, kEventRawKeyUp }
	};
	
	// the magic happens here with the call to GetEventMonitorTarget as described in CarbonEvents.h
	// The event monitor target is a special event target used to monitor user input events across all processes.
	// When the monitor target detects a matching event, then MonitorHandler is called.
	error = InstallEventHandler( GetEventMonitorTarget(), MonitorHandler, GetEventTypeCount( kEvents ),
								kEvents, NULL, &mMonitorHandlerRef );
	if (error != noErr) {
		NSBeep();
		NSLog(@"InstallEventHandler error %d", error);
	}
}


- (void)uninstallMonitorHandler;
{
	if (mMonitorHandlerRef) {
		RemoveEventHandler(mMonitorHandlerRef);
		mMonitorHandlerRef = NULL;
	}
}


- (void)sendEvent:(NSEvent *)event;
{
	NSEventType eventType = [event type];
	
	// Catch keyboard events destined for other apps when recording
	if (![self isActive] && (eventType == NSKeyDown || eventType == NSKeyUp || eventType == NSFlagsChanged)) {
		NSLog(@"sendEvent: interior");
		return;
	}
	
    [super sendEvent:event];
}
PHP:
@implementation MyApplicationAppDelegate

@synthesize window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
	
	// Insert code here to initialize your application 	
	MyApplication *app = [[MyApplication alloc] init];
	[app installMonitorHandler];
}

@end

Thank you very much
 
The comment "// Useless on 10.4 for keyboard events." would seem to suggest it won't work for keyboard events (depending on whether they mean "10.4 and later" or "10.4 and earlier". ;)

Some time ago, I used the following page which describes a Carbon solution. It might not be recommended (or work at all) on recent OS releases, but it might help you.

Global hotkeys
 
Also I've tried this code sample you provided. But it doesn't work as well:confused:

Here is my project: http://slil.ru/29376587
My app is as agent.

PHP:
- (void)activateStatusMenu
{
    NSStatusBar *statusBar = [NSStatusBar systemStatusBar];
	
    NSStatusItem *dictItem = [statusBar statusItemWithLength:NSVariableStatusItemLength];
	[dictItem retain];
	
    [dictItem setTitle: NSLocalizedString(@"Dictionary",@"")];
    [dictItem setHighlightMode:YES];
    [dictItem setMenu:menu];
	
}

- (IBAction)onAutostartup:(id)sender {

	exit(0);
}

OSStatus MyHotKeyHandler(EventHandlerCallRef nextHandler,EventRef theEvent, void *userData)
{
	NSLog(@"it works...\n");
	
	//Do something once the key is pressed
	return noErr;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

	//Register the Hotkeys
	EventHotKeyRef gMyHotKeyRef;
	EventHotKeyID gMyHotKeyID;
	EventTypeSpec eventType;
	eventType.eventClass=kEventClassKeyboard;
	eventType.eventKind=kEventHotKeyPressed;

	InstallApplicationEventHandler(&MyHotKeyHandler,1,&eventType,NULL,NULL);
	
	gMyHotKeyID.signature='htk1';
	gMyHotKeyID.id=1;
	RegisterEventHotKey(49, cmdKey+optionKey, gMyHotKeyID, GetApplicationEventTarget(), 0, &gMyHotKeyRef);		
	
	// Insert code here to initialize your application
	[self activateStatusMenu];
}

Please help with this issue.

Thank you.
 
Yes, I've researched this point but didn't found an example.(

Could you please help me with the code I've already developed?
 
Update:

I've fixed the code. Now it's working. But have a few questions:

1. I'm hooking command + "C" (copy to clipboard). It works just fine but it is not coping data to the buffer after my hooking(( Even I send noErr in MyHotKeyHandler() function. How to fix this problem?
According to this topic(http://groups.jonzu.com/z_apple_how-can-i-not-block-hotkey-from-other-apps.html) I do it in next way:
PHP:
OSStatus MyHotKeyHandler(EventHandlerCallRef nextHandler,EventRef theEvent, void *userData)
{
	NSLog(@"it works...\n");
	UnregisterEventHotKey(gMyHotKeyRef);
	SendEventToEventTarget(theEvent, eventTargetRef);
	return noErr;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

	//Register the Hotkey
	EventHotKeyID gMyHotKeyID;
	EventTypeSpec eventType;
	eventType.eventClass = kEventClassKeyboard;
	eventType.eventKind = kEventHotKeyPressed;

	InstallApplicationEventHandler(&MyHotKeyHandler,1,&eventType,NULL,NULL);
	
	gMyHotKeyID.signature = 'htk1';
	gMyHotKeyID.id = 1;
	
	eventTargetRef = GetApplicationEventTarget();
	RegisterEventHotKey(8, cmdKey, gMyHotKeyID, eventTargetRef, 0, &gMyHotKeyRef);	
	
	// Insert code here to initialize your application
	[self activateStatusMenu];
}

2. Also I need to hook double click. Current code doesn't do it:
PHP:
	EventTypeSpec eventType;
	eventType.eventClass = kEventClassMouse;
	eventType.eventKind = kEventMouseDown;
	
	InstallApplicationEventHandler(&MyHotKeyHandler,1,&eventType,NULL,NULL);
Where is the problem?

Thanks.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.