Skycoder42 / QHotkey

A global shortcut/hotkey for Desktop Qt-Applications
BSD 3-Clause "New" or "Revised" License
552 stars 162 forks source link

Cannot override system shortcuts on Windows and OS X #11

Closed ArsenArsen closed 6 years ago

ArsenArsen commented 6 years ago

Hello! I've received complaints from my Windows and OS X users that they cannot override Ctrl+Print and CMD+Shift+4 respectively. The shortcuts get registered but never fire.

Skycoder42 commented 6 years ago

Thats very possible. Special shortcuts that are used by OS cannot be easily overriden. The interesting part is that no errors are beeing reported. I tested ctrl+print on windows right now, and by debugging saw that the windows-os funktion RegisterHotKey returned true!

So apparently, there are hotkeys that can be registered, but are then ignored by windows. And since the OS functions don't report any error, there is no way for me to find that out... I haven't tried on OsX, but I'm pretty sure it's the same situation there.

ArsenArsen commented 6 years ago

ShareX does this though. I'm talking to the dev about it.

Skycoder42 commented 6 years ago

Shure I bet it's possible, but not with the standard Hotkey stuff. There are most likley other APIs like keyboard hooks you need to utilize for that. But that's out of scope for this project.

ArsenArsen commented 6 years ago

https://github.com/ShareX/ShareX/blob/b5cfbc61fc222eeb4ad2f6957dcc09f78c4eb8a5/ShareX.HelpersLib/Input/HotkeyForm.cs#L47 This is the method ShareX uses, and again it's only RegisterHotKey

Skycoder42 commented 6 years ago

Interesting. I tried it out earlier, but nothing was delivered for that specific key combination. It is possible that ctrl+print does not work, because windows needs a different keycode (print was correctly detected as VK_PRINT by QHotkey, but maybe windows assings a special keycode for that combination?).

If you can find out the exact values for keycode and modifiers used by XShare for ctrl+print (this value), you could try to set them as native shortcut (QHotkey::setNativeShortcut) and check if that one does work. If not, I can try to investigate further, but that won't be possible before Friday, as I don't have a windows machine until then.

ArsenArsen commented 6 years ago

https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/Keys.cs,387 Here's the keycodes.

Skycoder42 commented 6 years ago

There we have it (See https://msdn.microsoft.com/de-de/library/windows/desktop/dd375731(v=vs.85).aspx):

So as expected, it is simply translated incorrectly. QKeysequence translates ctrl+print to the ctrl modifier and VK_PRINT. XShare uses Snapshot which corresponds to VK_SNAPSHOT, which is the one you actually need.

There is nothing I can do about that. It seems, there is no Qt::Key_Snapshot - so Qt simply does not know of the existance of such a key (most likely, because it's a windows only virtual key).

Solution: Use the native keycodes directly, by passing VK_SNAPSHOT to QHotkey::setNativeShortcut.

I guess it's a very similar situation for OsX. You need to figure out the virtual key code the corresponds to the "snapshot" key, and set it as native shortcut.

ArsenArsen commented 6 years ago

Maybe translate print to snapshot? I'll look at macos in a bit

Skycoder42 commented 6 years ago

The thing is: print itself is a valid key, so simply translating print to snapshot would not work.

However, it would be possible to add some kind of key mapping. This way you as developer could add such "macros" by yourself, whenever the need arises. In your application code, it would propably look like that:

#ifdef Q_OS_WIN
QHotkey::addGlobalMapping(QKeySequence("ctrl+print"), QHotkey::NativeShortcut(VK_SNAPSHOT);
#endif

Would that be satisfying for you as a solution? This way you can keep "ctrl+print", but still get the correct result.

ArsenArsen commented 6 years ago

The problem is these are by user input, plus it'd make more sense to

#ifdef Q_OS_WIN
QHotkey::addGlobalMapping(Qt::Key_Print, VK_SNAPSHOT);
#endif
Skycoder42 commented 6 years ago

Well, we can't possibly know what a user will enter ;) So adding this function makes it possible for you to add those mappings as reported as missing by your users.

But I don't agree to simply map keys. Doing that for your example would prevent one from using the normal print. So if the user enters just that and registers the hotkey, pressing print will do nothing, as VK_SNAPSHOT seems to be triggered when ctrl+print is pressed. I shortened the expression because of a default parameter. It would actually be:

#ifdef Q_OS_WIN
QHotkey::addGlobalMapping(QKeySequence("ctrl+print"), QHotkey::NativeShortcut(VK_SNAPSHOT, 0);//no modifier
#endif

Of course you have to try that out. Maybe you need VK_SNAPSHOT only or maybe add the modifier as well. I don't know what windows does there.

I will add something like that once I have a windows machine, and use this problem as an example on how to use the mapping.

ArsenArsen commented 6 years ago

Aha, I see. Makes sense. I mean, it makes zero sense to make that a thing, Microsoft Sounds like a viable solution. Thanks

ArsenArsen commented 6 years ago

Any updates on this issue?

Skycoder42 commented 6 years ago

Im sorry, I already have it implemented, but apparently forgot to push... As soon as I get to the machine the commit is on, I will push it (should be in the next 24 hours)