Capturing alt-tab event
-
I want to capture alt-tab event, so that my program will not be switched to other programs, as long as my program is under focus.
to do this, I need to capture the alt-tab event. I'm using nativeEventFilter, but I don't know which native event I need to capture (I'm working on windows, but eventually I need to support linux and mac also).
I tried WM_KEYUP and WM_SYSKEYUP. they won't work.
is there a ALT_TAB event I can capture? or is there any other tricks I can play?
I know that virtual box supports this and its ui seems to be in Qt.
-
so far haven't found how to achieve this on windows.
this link suggests unregistering the default windows hotkey, but this method won't work on win7 and win8
http://www.codeguru.com/cpp/misc/misc/keyboard/article.php/c433/Disabling-the-AltTab-key-combination.htmthis method looks promising, but requires more code change in the client:
http://stackoverflow.com/questions/11352343/how-can-i-disable-specific-windows-hotkeys-from-inside-a-software-using-c -
method mentioned here should work for windows.
http://www.windowsnetworking.com/kbase/WindowsTips/WindowsNT/AdminTips/Miscellaneous/DisableAltTab.htmlbut I don't know how to do this on mac and linux. need to dig more.
-
I have successfully captured cmd+tab on mac by using Quartz event service, but there are two serious problems.
http://brianlipkowitz.tumblr.com/post/4881199383/quartz-event-taps
first, the user must run with root privilege. for users without CS background, this could be a bit difficult.
second, the method monitors the key events sent to the entire system. the implementation has to be careful in order to not to break other apps.
-
ok, I installed virtualbox, and found out that it doesn't seem to require root user to capture alt-tab.
after digging the source code, it seems that they achieved this by disabling default hotkeys.
I need to experiment this myself.
@
/**-
Disables or enabled global hot keys.
-
@param fDisable Pass 'true' to disable the hot keys, pass 'false' to re-enable them.
*/
void DarwinDisableGlobalHotKeys(bool fDisable)
{
static unsigned s_cComplaints = 0;/*
- Lazy connect to the core graphics service.
*/
if (!g_fConnectedToCGS)
{
g_CGSConnection = _CGSDefaultConnection();
g_fConnectedToCGS = true;
}
/*
- Get the current mode.
*/
CGSGlobalHotKeyOperatingMode enmMode = kCGSGlobalHotKeyInvalid;
CGSGetGlobalHotKeyOperatingMode(g_CGSConnection, &enmMode);
if ( enmMode != kCGSGlobalHotKeyEnable
&& enmMode != kCGSGlobalHotKeyDisable
&& enmMode != kCGSGlobalHotKeyDisableExceptUniversalAccess)
{
AssertMsgFailed(("%d\n", enmMode));
if (s_cComplaints++ < 32)
LogRel(("DarwinDisableGlobalHotKeys: Unexpected enmMode=%d\n", enmMode));
return;
}
/*
- Calc the new mode.
*/
if (fDisable)
{
if (enmMode != kCGSGlobalHotKeyEnable)
return;
enmMode = kCGSGlobalHotKeyDisableExceptUniversalAccess;
}
else
{
if (enmMode != kCGSGlobalHotKeyDisableExceptUniversalAccess)
return;
enmMode = kCGSGlobalHotKeyEnable;
}
/*
- Try set it and check the actual result.
/
CGSSetGlobalHotKeyOperatingMode(g_CGSConnection, enmMode);
CGSGlobalHotKeyOperatingMode enmNewMode = kCGSGlobalHotKeyInvalid;
CGSGetGlobalHotKeyOperatingMode(g_CGSConnection, &enmNewMode);
if (enmNewMode != enmMode)
{
/ If the screensaver kicks in we should ignore failure here. */
AssertMsg(enmMode == kCGSGlobalHotKeyEnable, ("enmNewMode=%d enmMode=%d\n", enmNewMode, enmMode));
if (s_cComplaints++ < 32)
LogRel(("DarwinDisableGlobalHotKeys: Failed to change mode; enmNewMode=%d enmMode=%d\n", enmNewMode, enmMode));
}
}
@
- Lazy connect to the core graphics service.
-
-
I verified that the above code could work, but it uses undocumented apis from the coregraphics framework:
it turned out that they disabled the system default hotkeys by using undocumented hidden apis from the coregraphics framework.
extern "C" {
CGSConnection _CGSDefaultConnection(void);
CGError CGSGetGlobalHotKeyOperatingMode(CGSConnection Connection, CGSGlobalHotKeyOperatingMode *enmMode);
CGError CGSSetGlobalHotKeyOperatingMode(CGSConnection Connection, CGSGlobalHotKeyOperatingMode enmMode);
}