Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Does Global Shortcuts exist ?
Forum Updated to NodeBB v4.3 + New Features

Does Global Shortcuts exist ?

Scheduled Pinned Locked Moved General and Desktop
global key shor
6 Posts 2 Posters 5.8k Views 2 Watching
  • 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.
  • FolcoF Offline
    FolcoF Offline
    Folco
    wrote on last edited by
    #1

    Hi,

    Qxt provided a Global Shortcut class, making shortcuts available even if the app had not the focus : http://libqxt.bitbucket.org/doc/tip/qxtglobalshortcut.html
    Sadly, it's no more maintened.

    Does Qt propose an alternate solution ?

    Thanks in advance.

    1 Reply Last reply
    0
    • FolcoF Offline
      FolcoF Offline
      Folco
      wrote on last edited by
      #2

      I think this class could do the job : http://doc.qt.io/qt-5/qabstractnativeeventfilter.html
      But it's a low level approach, something like QCoreApplication::registerGlobalShortcut(QKeysequence*, &slot) would have been more convenient.

      1 Reply Last reply
      0
      • Chris KawaC Offline
        Chris KawaC Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Qt doesn't expose cross-platform way to do that AFAIK. I haven't actually tested but I don't think an app that doesn't have keyboard focus receives any native events, at least on Windows.

        You would have to first ask for it explicitly by registering a hotkey using native api (e.g. RegisterHotKey and then you could check for the WM_HOTKEY message in the installed native event filter.

        1 Reply Last reply
        1
        • FolcoF Offline
          FolcoF Offline
          Folco
          wrote on last edited by
          #4

          Thanks you for your answer. It's apreciated, because I can't get the thing working.
          I first tried that, and it works :

          #include <QCoreApplication>
          #include "windows.h"
          #include <QDebug>
          
          int main(int argc, char *argv[])
          {
              if (RegisterHotKey(NULL, 1, MOD_ALT | 0x4000, 0x42))  //0x42 is 'b'
              {
                  qDebug() << "Hotkey 'ALT+b' registered, using MOD_NOREPEAT flag";
              }
          
              MSG msg = {0};
              while (GetMessage(&msg, NULL, 0, 0) != 0)
              {
                  if (msg.message == WM_HOTKEY)
                  {
                      qDebug() << "WM_HOTKEY received";
                  }
              }
          
              return 0;
          }
          

          Basically, it's a copy of the example of Microsoft.
          Now I try to use the QCoreApplication::setNativeEventFilter method : just a QCoreApplication, and a derived class with one method rewritten :

          #include <QAbstractNativeEventFilter>
          #include <QCoreApplication>
          #include <QDebug>
          #include "windows.h"
          
          class NativeEventFilter: public QAbstractNativeEventFilter
          {
              public:
                  bool nativeEventFilter(const QByteArray& eventType, void* message, long*)
                  {
                      if (eventType == "windows_dispatcher_MSG")
                      {
                          MSG* msg = static_cast<MSG*>(message);
                          qDebug() << QString("Message: %1").arg(msg->message);
          
                          if (msg->message == WM_HOTKEY)
                          {
                              qDebug() << QString("Event WM_HOTKEY received");
                              return true;
                          }
                      }
                      return false;
                  }
          };
          
          int main(int argc, char *argv[])
          {
              if (RegisterHotKey(NULL, 1, MOD_ALT | 0x4000, 0x42))  //0x42 is 'b'
              {
                  qDebug() << "Hotkey 'ALT+b' registered, using MOD_NOREPEAT flag";
              }
          
              QCoreApplication app(argc, argv);
              NativeEventFilter* nef = new NativeEventFilter;
              app.installNativeEventFilter(nef);
              return app.exec();
          }
          

          I can't see an WM_HOTKEY event anymore...

          Any tip to get something like that working would be greatly apreciated. Perhaps I am totally on the wrong way ?

          1 Reply Last reply
          0
          • Chris KawaC Offline
            Chris KawaC Offline
            Chris Kawa
            Lifetime Qt Champion
            wrote on last edited by
            #5

            Despite of what the docs seem to suggest a hotkey message comes with the eventType set to "windows_generic_MSG" and not "windows_dispatcher_MSG".

            Since any type of Windows message is a MSG struct pointer and that code won't compile on any other platform anyway there's little point to checking that type I think. Something like this works ok:

            bool nativeEventFilter(const QByteArray&, void* message, long*) {
            #ifdef Q_OS_WIN
                MSG* msg = static_cast<MSG*>(message);
                if(msg->message == WM_HOTKEY)
                    qDebug() << "WM_HOTKEY !";
            #endif
                return false;
            }
            

            Btw. I don't see any info on MSDN about what happens to the registered hotkey when your process finishes, so just to be on the safe side you might want to call UnregisterHotKey after you're done with it. Also don't forget to change the second param (the id) of the RegisterHotKeyif you're gonna use several different hotkeys.

            1 Reply Last reply
            1
            • FolcoF Offline
              FolcoF Offline
              Folco
              wrote on last edited by Folco
              #6

              Many, many thanks, you're right, and I have got it work now !

              https://github.com/Folcogh/FMetro/blob/master/NativeEventFilter.hpp
              See this class : https://github.com/Folcogh/FMetro/blob/master/NativeEventFilter.cpp
              (like you said, I should add a call to UnregisterHotKey in the dtor)

              I have removed the type check, and I have read the sources of Qxt : http://libqxt.bitbucket.org/doc/

              The documentation says something about returning 'true' after reading the event, but Qxt doen't act like that.
              So the Qt's documentation seems rather wrong about global hotkeys.

              Also don't forget to change the second param (the id) of the RegisterHotKeyif you're gonna use several different hotkeys.

              Qxt uses the key code to identify the keys, it's a nice idea.

              Now I have to work learn how Windows maps the keyboard, and how Qt does it, to allow me to translate a Windows key into a Qt key.

              Many thanks again, it was a must-have feature to my program. :)

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved