Home

Awesome

QHotkey

A global shortcut/hotkey for Desktop Qt-Applications.

The QHotkey is a class that can be used to create hotkeys/global shortcuts, aka shortcuts that work everywhere, independent of the application state. This means your application can be active, inactive, minimized or not visible at all and still receive the shortcuts.

Features

Note: For now Wayland is not supported, as it is simply not possible to register a global shortcut with wayland. For more details, or possible Ideas on how to get Hotkeys working on wayland, see Issue #14.

Building

QHotkey supports both Qt6 and Qt5. When using Qt6, version 6.2.0 or later required. It can be built using the CMake building system.

CMake

The CMake QT_DEFAULT_MAJOR_VERSION variable controls which major version of Qt is used for building, and defaults to 5. For example, use the CMake command line option -DQT_DEFAULT_MAJOR_VERSION=6 for building with Qt6. To build the testing application QHotkeyTest, specify -DQHOTKEY_EXAMPLES=ON. CMake example usage:

$ cd QHotkey
$ cmake -B build -S . -DQT_DEFAULT_MAJOR_VERSION=6
$ cmake --build build
# cmake --install build

Installation

The package is providet as qpm package, de.skycoder42.qhotkey. You can install it either via qpmx (preferred) or directly via qpm.

Via qpmx

qpmx is a frontend for qpm (and other tools) with additional features, and is the preferred way to install packages. To use it:

  1. Install qpmx (See GitHub - Installation)
  2. Install qpm (See GitHub - Installing, for windows see below)
  3. In your projects root directory, run qpmx install de.skycoder42.qhotkey

Via qpm

  1. Install qpm (See GitHub - Installing, for windows see below)
  2. In your projects root directory, run qpm install de.skycoder42.qhotkey
  3. Include qpm to your project by adding include(vendor/vendor.pri) to your .pro file

Check their GitHub - Usage for App Developers to learn more about qpm.

Important for Windows users: QPM Version 0.10.0 (the one you can download on the website) is currently broken on windows! It's already fixed in master, but not released yet. Until a newer versions gets released, you can download the latest dev build from here:

Usage

The general usage is to create QHotkey instances for specific hotkeys, register them and then simply connect to the signal emitted once the hotkey is pressed.

Example

The following example shows a simple application that will run without a window in the background until you press the key-combination <kbd>Ctrl</kbd>+<kbd>Alt</kbd>+<kbd>Q</kbd> (<kbd></kbd>+<kbd></kbd>+<kbd>Q</kbd> on Mac). This will quit the application. The debug output will tell if the hotkey was successfully registered and that it was pressed.

#include <QHotkey>
#include <QApplication>
#include <QDebug>

int main(int argc, char *argv[])
{
	QApplication app(argc, argv);

	QHotkey hotkey(QKeySequence("Ctrl+Alt+Q"), true, &app); //The hotkey will be automatically registered
	qDebug() << "Is segistered:" << hotkey.isRegistered();

	QObject::connect(&hotkey, &QHotkey::activated, qApp, [&](){
		qDebug() << "Hotkey Activated - the application will quit now";
		qApp->quit();
	});

	return app.exec();
}

Note: You need the .pri include for this to work.

Testing

By running the example in ./HotkeyTest you can test out the QHotkey class. There are 4 sections:

Logging

By default, QHotkey prints some warning messages if something goes wrong (For example, a key that cannot be translated). All messages of QHotkey are grouped into the QLoggingCategory "QHotkey". If you want to simply disable the logging, call the following function somewhere in your code:

QLoggingCategory::setFilterRules(QStringLiteral("QHotkey.warning=false"));

This will turn all warnings of QHotkey of (It only uses warnings for now, that's why this is enough). For more information about all the things you can do with the logging categories, check the Qt-Documentation

Thread safety

The QHotkey class itself is reentrant - which means you can create as many instances as required on any thread. This allows you to use the QHotkey on all threads. But you should never use the QHotkey instance on a thread that is different from the one the instance belongs to! Internally the system uses a singleton instance that handles the hotkey events and distributes them to the QHotkey instances. This internal class is completely threadsafe.

However, this singleton instance only runs on the main thread. (One reason is that some of the OS-Functions are not thread safe). To make threaded hotkeys possible, the critical functions (registering/unregistering hotkeys and keytranslation) are all run on the mainthread too. The QHotkey instances on other threads use QMetaObject::invokeMethod with a Qt::BlockingQueuedConnection.

For you this means: QHotkey instances on other threads than the main thread may take a little longer to register/unregister/translate hotkeys, because they have to wait for the main thread to do this for them. Important: there is however, one additional limitation that comes with that feature: QHotkey instances on other threads but the main thread must be unregistered or destroyed before the main eventloop ends. Otherwise, your application will hangup on destruction of the hotkey. This limitation does not apply for instances on the main thread. Furthermore, the same happens if you change the shortcut or register/unregister before the loop started, until it actually starts.

Documentation

The documentation is available as release and on github pages.

The documentation was created using doxygen. It includes an HTML-documentation and Qt-Help files that can be included into QtCreator (QtAssistant) to show F1-Help (See Adding External Documentation for more details).

Technical

Requirements

Known Limitations