Having read through various posts and threads that lead me nowhere I need your help.
I do have a Qt Application for Mac OS X that at some point of use will be in the background and not active. When this is the case I want to add a global hotkey so that the user can easily turn certain features on or off by clicking pre-defined hotkeys. The following isn't working while the app is in the background and not focused.
QShortcut *shortcut = new QShortcut(QKeySequence(Qt::Key_F12), parent);
shortcut->setContext(Qt::ApplicationShortcut);
So far I found Qxt
which happens to be outdated for Qt 5.5.
Then there is DDHotkey which requires a certain compiler which we can not use for various reasons.
Lastly, I found the solution of adding a global AppleScript
which registers an event, again, not what I am looking for.
tell application "System Events" to tell process "myApp"
click menu item "myButton" of menu 1 of menu bar item "Menu" of menu bar 1
end tell
Is there a way to use objective-c
or cocoa
to accomplish exactly what I am looking for?
Please lead me in the right direction if I may have missed something.
Thanks in advance!
To those who seek a more Qt way, check the following repository: https://github.com/ddqd/qxtglobalshortcut5
It makes use of the outdated qxt
library but gets it working again.
The person tested it until Qt 5.4, we use it successfully under Qt 5.5.
This might be what you're looking for https://github.com/jaz303/JFHotkeyManager
You could also look at this example from Apple, using the RegisterEventHotKey API call which I think will point you in the right direction. https://developer.apple.com/library/prerelease/mac/samplecode/FunkyOverlayWindow/Listings/FunkyOverlayWindow_OverlayWindow_m.html#//apple_ref/doc/uid/DTS10000391-FunkyOverlayWindow_OverlayWindow_m-DontLinkElementID_8
Or you could try this code
#import <Carbon/Carbon.h>
EventHandlerUPP hotKeyFunction;
pascal OSStatus hotKeyHandler(EventHandlerCallRef nextHandler,EventRef theEvent, void *userData)
{
Notify *obj = userData;
[obj foo];
return noErr;
}
@implementation Notify
- (id)init
{
self = [super init];
if (self) {
//handler
hotKeyFunction = NewEventHandlerUPP(hotKeyHandler);
EventTypeSpec eventType;
eventType.eventClass = kEventClassKeyboard;
eventType.eventKind = kEventHotKeyReleased;
InstallApplicationEventHandler(hotKeyFunction,1,&eventType,self,NULL);
//hotkey
UInt32 keyCode = 80; //F19
EventHotKeyRef theRef = NULL;
EventHotKeyID keyID;
keyID.signature = 'FOO '; //arbitrary string
keyID.id = 1;
RegisterEventHotKey(keyCode,0,keyID,GetApplicationEventTarget(),0,&theRef);
}
return self;
}
- (void)foo
{
}
@end
And the header
#include "notify.mm"
@interface Notify
- (id)init;
- (void)foo;
@end
Simply this is just a object with a method and a constructor, in objective-c this is called init, or initialize, and variants. Calling it should be straight forward with "new".
E.x
#include "notify.h"
int main(){
Notify* object = new Notify();
}
However, some basic understanding of Objective-C is needed. It's mostly syntax differences in my opinion. But I'm no Objective-C expert myself. Anyway, there is a lot of ways to solve it, this might not be the best idea. You can also call Objective-C code from inside of a C++ class of yours. Take a look at the links bellow for a great example of how that's done.
https://el-tramo.be/blog/mixing-cocoa-and-qt/
https://github.com/remko/mixing-cocoa-and-qt/
http://philjordan.eu/article/mixing-objective-c-c++-and-objective-c++
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With