Giter Site home page Giter Site logo

skycoder42 / qhotkey Goto Github PK

View Code? Open in Web Editor NEW
539.0 22.0 160.0 198 KB

A global shortcut/hotkey for Desktop Qt-Applications

License: BSD 3-Clause "New" or "Revised" License

C++ 92.13% CMake 7.87%
qt hotkeys cross-platform global-shortcuts native-shortcuts qpm

qhotkey's Introduction

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

  • Works on Windows, Mac and X11
  • Easy to use, can use QKeySequence for easy shortcut input
  • Supports almost all common keys (Depends on OS & Keyboard-Layout)
  • Allows direct input of Key/Modifier-Combinations
  • Supports multiple QHotkey-instances for the same shortcut (with optimisations)
  • Thread-Safe - Can be used on all threads (See section Thread safety)
  • Allows usage of native keycodes and modifiers, if needed

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 Ctrl+Alt+Q (++Q 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:

  • Playground: You can enter some sequences here and try it out with different key combinations.
  • Testings: A list of selected hotkeys. Activate it and try out which ones work for you (Hint: Depending on OS and keyboard layout, it's very possible that a few don't work).
  • Threading: Activate the checkbox to move 2 Hotkeys of the playground to separate threads. It should work without a difference.
  • Native Shortcut: Allows you to try out the direct usage of native shortcuts

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

  • Explicit support is only given down to the latest Qt LTS, but may work with earlier versions, too
  • At least the QtGui-Module (a QGuiApplication). Hotkeys on console based applications are not supported (By the operating systems). You can however create a gui application without any visible window.
  • C++11

Known Limitations

  • Only single key/modifier combinations are possible. If using QKeySequence, only the first key+modifier of the sequence will be used.
  • Qt::Key makes no difference between normal numbers and the Numpad numbers. Most keyboards however require this. Thus, you can't register shortcuts for the numpad, unless you use a native shortcut.
  • Supports not all keys, but most of the common ones. There are differences between platforms and it depends on the Keyboard-Layout. "Delete", for example, works on windows and mac, but not on X11 (At least on my test machines). I tried to use OS-Functions where possible, but since the Qt::Key values need to be converted into native keys, there are some limitations. I can use need such a key, try using the native shortcut.
  • The registered keys will be "taken" by QHotkey. This means after a hotkey was cosumend by your application, it will not be sent to the active application. This is done this way by the operating systems and cannot be changed.
  • If you get a QHotkey: Failed to register hotkey. Error: BadAccess (attempt to access private resource denied) error on X11, this means you are trying to register a hotkey that is private to X11. Those keys simply cannot be registered using the normal API

qhotkey's People

Contributors

aknobloch avatar alexandrvicente avatar arsenarsen avatar cuperino avatar dbermond avatar dualthrust avatar fredbill1 avatar kolcha avatar luzpaz avatar mujx avatar olegantonyan avatar pbek avatar sandsmark avatar semanser avatar shatur avatar skycoder42 avatar waneon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qhotkey's Issues

Infinite loop (ending in a segmentation fault) upon BadAccess

When a BadAccess failure occurs during registering shortcuts QHotkey will go into an infinite loop, spamming the console each iteration.

WARN: Failed to unregister hotkey. Error: BadAccess (attempt to access private resource denied)

This time I tested it seems to have crashed. Segmentation fault @ qhotkey_x11.cpp:133 (The XSync line).

Tried again, the SIGSEGV is reproducable.

warning during compilation on Linux

Ubuntu 16.04, GCC 5.4.0
RedHat 6.9, GCC 5.3.1
RedHat 6.9, GCC 6.3.1

../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp: In static member function ‘static int QHotkeyPrivateX11::HotkeyErrorHandler::handleError(Display*, XErrorEvent*)’:
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp:176:24: warning: unknown option after ‘#pragma GCC diagnostic’ kind [-Wpragmas]
 QT_WARNING_DISABLE_GCC("-Wimplicit-fallthrough")
                        ^

I think, you added this to prevent/disable warning produced by GCC 7. If so, see
https://stackoverflow.com/questions/45129741/gcc-7-wimplicit-fallthrough-warnings-and-portable-way-to-clear-them
for other (and more portable) ways to do this.

I commented macro which produces this warning on GCC 5 and 6, compiled with GCC 7 and got warning exact you disabled.
I tested suggested solution (added comment before default) with GCC 7.2.1 on RedHat 6.9 and it really works. No warning produced even without macro (macro is commented).
I think this will be a better solution, because this produces no warning for wide range of compilers (GCC 5, 6, and 7)

Failed to build, error at /lib/QHotkey/CMakeLists.txt (find_package) (i just need some help)

Void Linux
Qt 6.4.2

So i have been trying to build albert and it requires QHotkey, trying to build albert there is an error when i run the first cmake, shows this:

[void@VOID albert]$ cmake -B build -S . -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug
CMake Error at lib/QHotkey/CMakeLists.txt:16 (find_package):
By not providing "FindQt6.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "Qt6", but
CMake did not find one.

Could not find a package configuration file provided by "Qt6" (requested
version 6.2.0) with any of the following names:

Qt6Config.cmake
qt6-config.cmake

Add the installation prefix of "Qt6" to CMAKE_PREFIX_PATH or set "Qt6_DIR"
to a directory containing one of the above files. If "Qt6" provides a
separate development package or SDK, be sure it has been installed.

-- Configuring incomplete, errors occurred!
See also "/home/void/albert/build/CMakeFiles/CMakeOutput.log".

From now on i don't really know what to do, i asked on the albert discord and they suggested me that i should talk here for more info, this is just a post looking for help for a noob.

CMake not working with FetchContent

CMakeLists.txt:

cmake_minimum_required(VERSION 3.14)
project(qhotkey_test)

set(CMAKE_CXX_STANDARD 14)

include(FetchContent)
FetchContent_Declare(
        qhotkey
        GIT_REPOSITORY https://github.com/Skycoder42/QHotkey.git
        GIT_TAG        master
)


add_executable(qhotkey_test main.cpp)

FetchContent_MakeAvailable(qhotkey)

main.cpp:

#include <iostream>

#include <QHotkey>


int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

When making this test project, I get fatal error: 'QHotkey' file not found. Maybe @mujx knows more?

SIGSEGV on Fedora (Wayland)

I'm using QHotKey in my project (https://github.com/olegantonyan/mpz/) and trying to make it work on most popular Linux distros. So far it works fine on openSUSE (my workstation) and Ubuntu. But on Fedora I got SIGSEGV upon initialization. Here's a screenshot from QTCreator under Fedora 32: https://yadi.sk/i/GLekPj-yX7i0LA

The rest of the app works fine if I remove QHotKey initialization. Any ideas how to fix this?

QHotKey 1.4.1, same problem was with 1.2.2

UPDATE
Switching off wayland seems to work. But How to check if wayland is active at runtime so I can skip qhotkey initialization?

Issue with "qpm install de.skycoder42.qhotkey"

When I tried installing using the command "qpm install de.skycoder42.qhotkey", I got the following issue:

QPM: 2017/06/09 06:36:44 ERROR: GetFileAttributesEx
\app2\vendor\Skycoder42-QHotkey-a0678c4\doc\qpm.json: The system cannot find the file specified.

So, I checked for the file and its missing in the repository too.

Cannot register CapsLock

Cannot use QHotkey hotkey(Qt::Key_CapsLock, Qt::NoModifier, true);

Application Output:
QHotkey: Failed to register hotkey. Error: BadAccess (attempt to access private resource denied)
QHotkey: Failed to unregister hotkey. Error: BadAccess (attempt to access private resource denied)

Could we use CapsLock as a hotkey, please?

New release

Could you draft a new release with the latest changes?

CMake support

Are there any plans to add cmake support for the library?

If yes, I could make a PR.

About QKeySequence

Great repo, thanks!

Only single key/modifier combinations are possible. If using QKeySequence, only the first key+modifier of the sequence will be used.

Is there any chance that QKeySequence would be supported? I really need this function.

Thanks!

Common base library?

Hi @Skycoder42, I'm a new user of your library. I implemented native hotkeys for albertlauncher before. I know how hard it is to get things right. There are dozens of hotkey libs around but none of them does the job well. Probably because of lacking manpower. Especially when it comes to Wayland. This is extremely frustrating for users (devs) and end users of the apps.

This is an issue I want to address with the idea of a common library with a C interface (implementation would have to be C/C++/ObjC anyway). A generalized libhotkey so to say. Language/Framework (e.g. C++ (exceptions!)/Python/Qt) bindings can be built on top of it.

We could work together and there are standalone app devs who would join for sure (already talked with zeal and copyq devs about this idea). In the end we hopefully can get things right and make our lives a ton easier.

Let me know what you think about it.

[!] Looking for a Maintainer

As things stand right now, I personally do not have the time anymore to maintain this repository. I will still answer to issue and review and accept PRs though.

Since Qt 6 was released, according to #49, some major changes will have to be done to the code base, which I cannot provide. Thus, I am currently looking for someone to take over the repository and maintain it. If anyone is interested, please contact me here and state your preferred communication channel for further steps.

Thanks to everyone who has contributed so far!

Listen keyboard

Hi,

I'm trying to develop a keylogger with QHotkey for all platforms. So, I want to listen keyboard without signal/slot (connect). How can I use your code to listen system-wide keyboard?

Release a new version in qpm

I have recently installed QHotkey from qpm, but looks like qpm use the outdated version of package and it should be updated.
Also not sure why on Github the latest version is 1.1.3, but on qpm - 1.2.1.

Failed to register hotkey on Ubuntu

Hello! When I am try to run library on ubuntu I have got:

$ sudo ./myapp
libEGL warning: DRI2: failed to authenticate
QHotkey: Failed to register hotkey. Error: BadAccess (attempt to access private resource denied)
...

and of cource hotkeys do not work after that. Maybe youalready have faced with that and can recommend what to do? Thanks! Great library by the way!

Qml example

Hi, first of all, thank you very much for this package.

I see there is QWidget example with .ui file. Can you provide an example of how to use it with .qml components? What to register in main.cpp and in what way (qmlRegisterType/setContextProperty/qmlRegisterUncreatableType) to use it in .qml files? I was wondering if that would be similar usage like Shortcuts qml components.

Thank you

EDIT: or just say in what way I can use it with Qml components (some snippet) and I can provide the same example in qml like you did in .ui in PR

SIGSEGV: x11Interface is null

Ubuntu 22.10
Qt 6.4

file: qhotkey_x11.cpp

line 134:
const QNativeInterface::QX11Application *x11Interface = qGuiApp->nativeInterface<QNativeInterface::QX11Application>();

x11Interface is null

screenshot

Can't register shortcut on windows

I used this code from readme:

QHotkey hotkey(QKeySequence("ctrl+alt+Q"), true);//The hotkey will be automatically registered
            qDebug() << "Is Registered: " << hotkey.isRegistered();

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

And got the following:

QHotkey: Unable to map shortcut to native keys. Key: Qt::Key(Key_Q) Modifiers: QFlags<Qt::KeyboardModifiers>(ControlModifier|AltModifier)
Is Registered:  false

Any other key sequence don't work too.

I also tried HotkeyTest and got this errors on start:

QHotkey: Unable to map shortcut to native keys. Key: Qt::Key(Key_F) Modifiers: QFlags<Qt::KeyboardModifiers>(NoModifier)
QHotkey: Unable to map shortcut to native keys. Key: Qt::Key(Key_K) Modifiers: QFlags<Qt::KeyboardModifiers>(ShiftModifier|AltModifier)
QHotkey: Unable to map shortcut to native keys. Key: Qt::Key(Key_K) Modifiers: QFlags<Qt::KeyboardModifiers>(ShiftModifier|AltModifier)

But when I assign key sequence in app menu - it works.
Is this bug or I doing something wrong?

Windows 10 x64
Qt 5.10
MinGW 5.3.0 32bit

P.S. On ArchLinux the same code works properly.

Please add cmake subdir instructions to README

I tried to use qhotkey as a git submodule using

add_subdirectory(QHotKey)
target_link_libraries(${PROJECT_NAME} PRIVATE qhotkey)

However I get errors considering windows.h and QX11Extras although I am on Macos. I guess I am doing it wrong. How are we intended to use QHotkey when qpm is not an option?

"Escape" button hotkey does not work on X11

Impossible to use Escape button because QKeySequence gives wrong symbol text to XStringToKeysym, QKeySequence("Escape").toString(QKeySequence::NativeText) = "Esc", should return "Escape" because the key symbol is called XK_Escape.

Actualy this looks more like a Qt issue. Maybe use another way to translate a Qt key to KeySym?

Bug: the `released` signal will not be properly emitted when pressing multiple hotkeys at the same time on windows

Steps to reproduce

I'm using Qt6.4.3 on windows 11. Here is a minimum demo code for reproducing the bug:

#include <QApplication>
#include <QDebug>
#include <QHotkey>
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);
    QHotkey key_a(QKeySequence(Qt::Key_A), true);
    QHotkey key_b(QKeySequence(Qt::Key_B), true);
    QObject::connect(&key_a, &QHotkey::activated, [&]() { qDebug() << "A pressed"; });
    QObject::connect(&key_b, &QHotkey::activated, [&]() { qDebug() << "B pressed"; });
    QObject::connect(&key_a, &QHotkey::released, [&]() { qDebug() << "A released"; });
    QObject::connect(&key_b, &QHotkey::released, [&]() { qDebug() << "B released"; });
    return app.exec();
}

Run the code in a debugger, and press the keys as the following sequence: press A-> press B -> release A -> release B.

The expected console output would be:

A pressed
B pressed
A released
B released

But the actual output is:

A pressed
B pressed
B released

Where A released is missing. Further more, when pressing multiple hotkeys at the same time, only the last hotkey would emit the released signal.

Cause of the bug

The QHotkeyPrivateWin class only polls the release of the last hotkey being pressed, and the previous hotkeys are replaced by the new pressed hotkey. The link to the related code is here.

bool QHotkeyPrivateWin::nativeEventFilter(const QByteArray &eventType, void *message, _NATIVE_EVENT_RESULT *result)
{
	Q_UNUSED(eventType)
	Q_UNUSED(result)

	MSG* msg = static_cast<MSG*>(message);
	if(msg->message == WM_HOTKEY) {
		QHotkey::NativeShortcut shortcut = {HIWORD(msg->lParam), LOWORD(msg->lParam)};
		this->activateShortcut(shortcut);
		this->polledShortcut = shortcut;  //! previous pressed hotkeys being replaced
		this->pollTimer.start();
	}

	return false;
}

void QHotkeyPrivateWin::pollForHotkeyRelease()
{
	//! only polls the last pressed hotkey
	bool pressed = (GetAsyncKeyState(this->polledShortcut.key) & (1 << 15)) != 0;
	if(!pressed) {
		this->pollTimer.stop();
		this->releaseShortcut(this->polledShortcut);
	}
}

Possible solution

Use a container like QList<QHotkey::NativeShortcut> to maintain all the keys being pressed but not yet released, and use std::remove_if to emit the released signal and remove the corresponding NativeShortcut from the container.

Can't register shortcut for non-English active keyboard on Windows

Hi. Looks like current implementation does not support different keyboard languages.

For example if I register shortcut with English keyboard, everything working good (even after language change). But when I register shortcut with non-English active keyboard (Ukrainian for example), shortcut doesn't get registered.

After some debug, I found that the reason of the problem is in the VkKeyScan function:

if(keycode <= 0xFFFF) {//Try to obtain the key from it's "character"
const SHORT vKey = VkKeyScanW(keycode);
if(vKey > -1)
return LOBYTE(vKey);
}

This function always return -1 if current active keyboard is non-English.

As documentation said:

Translates a character to the corresponding virtual-key code and shift state for the current keyboard.

If the function finds no key that translates to the passed character code, both the low-order and high-order bytes contain –1.

So this function is dependends on the current active keyboard and should be replaced with to something else.

Hotkey not working when instantiated from another class

Hey, sorry if this is not a valid concern, I'm new to C++ as well as Qt so a bit over my head here. The example code given in the README works perfectly in the main, but placing it in a class method and invoking that from the main method fails. I thought this was odd, since the shortcut still reports as being successfully registered via the isRegistered() method.

If that's not clear, let me know and I can put up some actual code. Otherwise, this library is a godsend, since I couldn't seem to get X11 to play nice for me.

Can't map media buttons (like "Launch mail" button) to global shortcuts

I have a multimedia keyboard with separate keys, that are recognized in Crow's key sequence input as: "Launch (1)", "Home page", "Launch mail", and I even can accept the shortcut.

But as result, all of them are not working. Other combinations like default "Ctrl+Alt+C" work well.

Also, when I apply the changes, I see an error in console output:

QHotkey: Unable to map shortcut to native keys. Key: Qt::Key_HomePage Modifiers: QFlags<Qt::KeyboardModifier>(NoModifier)

OS - Ubuntu Linux 22.04, application - Crow Translate.

Is it possible to fix?

Initial issue is here: crow-translate/crow-translate#511

How to use numpad keys ?

Hello,

Thanks for this nice library !

I need to use the 'Plus', 'Minus', and almost all other keys of the numpad.
The 'Qt::KeypadModifier' doesn't work in QKeySequence.

So what's the solution ?

Thx again

All other keys are masked while shotcut key is held under X11

I'm using Qt 5.12.8, on Ubuntu 20.04 under X.

Using the HotkeyTest app, if I register a hotkey, e.g. a I understand that that key will be consumed, but it seems that all other keys are consumed as well between when a is pressed and when it's released.

Repro steps:

  1. Bind a as Hotkey 1 in the test app, activate the hotkey
  2. In another windows, hold a, then type sdf
  3. Release a, then type g.

Observed behaviour:

  1. QHotkey::activated is fired.
  2. QHotkey::released is fired.
  3. g is entered into the underlying application.

Can this be avoided? This seems quite intrusive for e.g. games where a user might want to hold a push to talk button and keep entering other keys at the same time.

I've done a bit of investigation and

  1. If I immediately return false in QHotkeyPrivateX11::nativeEventFilter, the behaviour doesn't change. Returning false there looks correct to avoid eating the key per Qt docs: https://doc.qt.io/qt-5/qabstractnativeeventfilter.html#nativeEventFilter

    In your reimplementation of this function, if you want to filter the message out, i.e. stop it being handled further, return true; otherwise return false.

  2. XGrabKey's registration uses True, which from docs

    Specifies a Boolean value that indicates whether the keyboard events are to be reported as usual.

So I don't understand why the keys are being masked at all. Based on docs it seems like not even the shortcut key should be masked? But I'm more interested if still getting the non-shortcut keys while the shortcut is held.

multiple registered-hotkeys-with-the-same-character are activated at the same time with one hotkey

Hello, thank you so much for creating this library I loved using it to develop an open source program that can register up to to a hundred hotkeys and more, I found that when one of multiple registered hotkeys with the same character is pressed all of them fire/activate.

also, modifierleess/character-only hotkeys cause the same issue.
I'd love to keep using this awesome library to keep developing my program, which I'd will release on all platforms, because I think it could help popularize a new way (which is RSI and hacker friendly) to interact with computers, with the rise of high DPI displays. so please, could you help make this issue not block that goal?

I'm developing and testing only on X11 for now, I uSe ArCh LiNuX BtW, (too) :D

Draft a new release

Hello! Could you draft a new small release with the latest changes?
Sorry to write here, but I did not find your email address.

building with cmake build for a Debug Config automatically if you don't precise it in the "--build" step

Hi, I've tried to build the project in windows, but I noticed that when I do cmake --install build cmake couldn't find the .lib file because cmake was building for a Debug config while it the last command asked for a Release config

Please add to the documentation that people should use
cmake --build build --config release instead of just saying cmake --build build

Just wanted to help others that would've struggled :)

Why doesn't QHotkey work on the widget?

Hello! I can't get QHotkey to work on the widget.
If I use the example code from ReadMe in EntryPoint.cpp, the hotkey works but if I use the same code in WMain.cpp it hotkey no longer works.

EntryPoint.cpp --> WORKS

int main(int argc, char* argv[])
{
	QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
	qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
	qputenv("QT_FONT_DPI", "96");

	QApplication qApplication(argc, argv);

	QHotkey hotkey(QKeySequence("Ctrl+Q"), true, &qApplication);
	QObject::connect(&hotkey, &QHotkey::activated, qApp, [&]() { qApp->quit(); });

	WMain wMain;
	wMain.show();

	return qApplication.exec();
}

WMain.cpp --> DOESNT WORK

WMain::WMain(QWidget* parent) : QMainWindow(parent, Qt::FramelessWindowHint)
{
	this->UI_WMain.setupUi(this);

	this->setAttribute(Qt::WA_TranslucentBackground);
	
	this->qGraphicsDropShadowEffect->setBlurRadius(10);
	this->qGraphicsDropShadowEffect->setColor(QColor(0, 0, 0));
	this->qGraphicsDropShadowEffect->setOffset(0);
	this->UI_WMain.widgetMainFrameless->setGraphicsEffect(this->qGraphicsDropShadowEffect);

	QHotkey hotkey(QKeySequence("Ctrl+Q"), true, this);
	QObject::connect(&hotkey, &QHotkey::activated, qApp, [&]() { qApp->quit(); });
}

What am I doing wrong?

Add the ability to check if the platform is supported

Thanks for your awesome library!
I have a suggestion. Since hotkeys for Linux work only for X11, then could you add a function that checks if the platform is supported? This can be convenient if I want to show the user in the UI that hotkeys cannot be registered.
This can be implemented by adding a function that returns true for Windows and Mac, and QX11Info::isPlatformX11() on Linux.
I can make a PR if you approve my suggestion.

Odd implementation question.

Hi, I am looking to register multiple hotkeys to a single callback. But pass through the qkeysequence and bool pressed to that callback. How would I go about setting that up?

Binding to media keys on GNOME-based systems (Fedora, Ubuntu, etc) is flaky

Spent the better part of an afternoon debugging this one! Binding to media keys on GNOME-based systems (Fedora, Ubuntu, etc) is flaky - either the bindings will fail completely, or they will seemingly randomly and intermittently stop working, instead greeting the user with this pop-up when pressing the media keys:

Media App Not Registered

The gnome-settings-daemon intercepts X11 media keys and translates them to a MPRIS D-Bus call. We should be able to register and respond to these via the QtDBUS module, and bind as outlined in the MPRIS specification linked above.

In the meantime, effected GNOME users can disable the gnome-settings-daemon bindings to X11 media keys as outlined below:

  1. Install dconf-editor
  2. Open dconf-editor and navigate to org.gnome.settings-daemon.plugins.media-keys.
  3. Remove the previous-static binding by changing the value to nothing (['']).
  4. Repeat the above for pause-static, play-static, stop-static and next-static.
  5. If problems persist, look through the settings in step two and validate nothing is bound to suspicious XF86Audio*keys.

Registering before creating the first window does not work

Hello!
Using a hotkey before showing a MainWindow makes the QHotkey signals not trigger. Current workaround I've found is

    QApplication a(argc, argv);

    QCommandLineParser parser;
    parser.addHelpOption();

    QCommandLineOption h({ "b", "background" }, "Does not show the main window, starts in tray.");
    parser.addOption(h);
    parser.process(a);

    MainWindow w;
    w.show();
    QTimer::singleShot(0, [&] {
        if (parser.isSet(h)) w.hide();
    });
    return a.exec();

Which flashes the window for one event loop iteration (too short to be visible).

I assume this is a singleton not being set up issue.

The hotkeys are registered at the end of the MainWindow constructor.

Thanks for creating QHotkey! :)

BadAccess when try to register Meida keys in linux

Hi,

I develop a simple audio player with Qt, now I have handle mediakeys like play/pause , next , previous and others but when try to register hotkeys a badaccess exception occur in code.
Is it a library bug ?

error message : QHotkey: Failed to register hotkey. Error: BadAccess (attempt to access private resource denied)

Cannot install on Windows via qpm

Hey, I get next error when try to install this package via qpm:

INFO: Package de.skycoder42.qhotkey has a different license (BSD_3_CLAUSE) than it's dependant (NONE).
Installing [email protected]
QPM: 2018/04/11 15:00:50 ERROR: GetFileAttributesEx D:\Andriy\Programing\VT\visualtranslator\src\vendor\Skycoder42-QHotkey-547cf7a\doc\qpm.json: The system cannot find the file specified.

fails to build on Linux

Ubuntu 18.04 (bionic), amd64, build on Travis CI

../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp: In member function ‘virtual bool QHotkeyPrivateX11::nativeEventFilter(const QByteArray&, void*, long int*)’:
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp:88:9: error: ‘class QHotkeyPrivateX11’ has no member named ‘releaseTimer’; did you mean ‘deleteLater’?
   this->releaseTimer = timer;
         ^~~~~~~~~~~~
         deleteLater
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp: In constructor ‘QHotkeyPrivateX11::HotkeyErrorHandler::HotkeyErrorHandler()’:
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp:220:2: error: invalid use of non-static data member ‘QHotkeyPrivateX11::prevHandler’
  prevHandler = XSetErrorHandler(&HotkeyErrorHandler::handleError);
  ^~~~~~~~~~~
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp:32:16: note: declared here
  XErrorHandler prevHandler;
                ^~~~~~~~~~~
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp: In destructor ‘QHotkeyPrivateX11::HotkeyErrorHandler::~HotkeyErrorHandler()’:
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp:225:19: error: invalid use of non-static data member ‘QHotkeyPrivateX11::prevHandler’
  XSetErrorHandler(prevHandler);
                   ^~~~~~~~~~~
../../../3rdparty/QHotkey/QHotkey/qhotkey_x11.cpp:32:16: note: declared here
  XErrorHandler prevHandler;
                ^~~~~~~~~~~
Makefile:583: recipe for target 'qhotkey_x11.o' failed
make[2]: *** [qhotkey_x11.o] Error 1

library is a part of app, qhotkey.pri is included
full build output can be found here, it has some highlight, so it is easier to read

Port it to Qt6

It would be great if it is ported to Qt6 since x11extras module has been deprecated and is no longer part of Qt.
The functionality of the module has been incorporated into other parts of Qt, or in some cases removed due to being obsolete or better suited as cross platform APIs.

For more details, see QTBUG-93633 in the Qt issue tracker.

Print hook not working

This is the code I use for creating the hotkey:

d_hotkey = new QHotkey(Qt::Key_Print, Qt::NoModifier, true, this);
qDebug() << "Is registered:" << d_hotkey->isRegistered();

It is printing true, but however many ways I try to connect the signal to a slot, it just doesn't work.
It either prints:

qt.core.qobject.connect: QObject::connect: signal not found in QHotkey

or straight up doesn't do anything.

I'm on a Windows system.

Any ideas why this could be?

Windows: linking client to shared library fails when QHotkey is compiled with CMake and MSVC

When building QHotkey as a shared library on Windows with CMake and MSVC 2019 (-DBUILD_SHARED_LIBS=ON), compiling a client application leads to the following error:

main.obj : error LNK2019: unresolved external symbol "public: static struct QMetaObject const QHotkey::staticMetaObject" (?staticMetaObject@QHotkey@@2UQMetaObject@@B) referenced in function main

First of all, QHotkeys's CMakeLists.txt needs a fix to correctly build the shared library on Windows under MSVC. It lacks the QHOTKEY_LIB and QHOTKEY_LIB_BUILD definitions (referenced here), and in this way it will not produce the qhotkey.lib file, but only the qhotkey.dll one. Without this, a client application will not even pass the CMake step, telling that the imported qhotkey target references the file qhotkey.lib, and that it was not found.

So, we need to add something like add_definitions(-DQHOTKEY_LIB=1 -DQHOTKEY_LIB_BUILD=1) to QHotkeys's CMakeLists.txt in order to MSVC to correctly generate the qhotkey.lib. I've not sent any pull request because it's not sufficient to fix the issue.

After this, compiling a client application fails with the link error above. Like the simple application example from the README file.

On Windows, I'm using the classic CMake build steps like on the README, with cmake <args>, cmake --build and cmake --install. No fancy compiler flags.

This is the CMakeLists.txt that I'm using for the client application:

cmake_minimum_required(VERSION 3.1)
project(qhotkey_example VERSION 1.0.0 LANGUAGES CXX)
find_package(Qt5 COMPONENTS Core Widgets REQUIRED)
find_package(QHotkey REQUIRED)
add_executable(qhotkey_example main.cpp)
target_link_libraries(qhotkey_example PRIVATE Qt5::Core Qt5::Widgets qhotkey)

Linking from a static library compiled with CMake and MSVC 2019 works fine.

Not a Windows guy here, and maybe I'm doing something wrong, but that's what I could gather about this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.