Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Call for Presentations - Qt World Summit

    Capturing alt-tab event

    General and Desktop
    1
    7
    3195
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B
      billconan last edited by

      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.

      1 Reply Last reply Reply Quote 0
      • B
        billconan last edited by

        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.htm

        this 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

        1 Reply Last reply Reply Quote 0
        • B
          billconan last edited by

          method mentioned here should work for windows.
          http://www.windowsnetworking.com/kbase/WindowsTips/WindowsNT/AdminTips/Miscellaneous/DisableAltTab.html

          but I don't know how to do this on mac and linux. need to dig more.

          1 Reply Last reply Reply Quote 0
          • B
            billconan last edited by

            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.

            1 Reply Last reply Reply Quote 0
            • B
              billconan last edited by

              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));
                  }
                  }
                  @
              1 Reply Last reply Reply Quote 0
              • B
                billconan last edited by

                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);
                }

                1 Reply Last reply Reply Quote 0
                • B
                  billconan last edited by

                  just tested virtual box's solution for linux:

                  XGrabKey(QX11Info::display(), AnyKey, AnyModifier, w.winId(), False, GrabModeAsync, GrabModeAsync);
                  

                  works like a charm

                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post