keepassxreboot / keepassxc

KeePassXC is a cross-platform community-driven port of the Windows application “Keepass Password Safe”.
https://keepassxc.org/
Other
21.48k stars 1.48k forks source link

Auto-Type shortcut doesn't work right after Windows restarts #11151

Open mih-kopylov opened 3 months ago

mih-kopylov commented 3 months ago

Overview

When my Windows 10 computer restarts, it starts KeePassXC automatically because of the option "Automatically launch KeePassXC at system starup" enabled. But the Auto-Type hotkey doens't work. I have to close and reopen KeePassXC one or several times until hotkey starts working eventually.

When I open Application Settings "Auto-Type" tab, I see "Global Auto-Type shortcut" option is colored with red. Just like in https://github.com/keepassxreboot/keepassxc/issues/9463#issuecomment-1557326005 image

Another way to workaround the bug is to open Application Settings and re-configure the shortcut, even to the same combination.

It seems like KeePassXC tries to register the shortcut, but fails with no reason. That's not quite clear to me why, but after some time after system starts KeePassXC succeeds with registering the shortcut

When I close and reopen KeePassXC in regular work, not after system restart, it always registers the hotkey properly, and it works.

Steps to Reproduce

  1. Enable "Automatically launch KeePassXC at system starup" option
  2. Restart the system
  3. Press the shortcut

Expected Behavior

Auto-Type window is open

Actual Behavior

Auto-Type window doesn't open

KeePassXC - Version 2.7.9 Revision: 8f6dd13

Qt 5.15.11 Debugging mode is disabled.

Operating system: Windows 10 Version 2009 CPU architecture: x86_64 Kernel: winnt 10.0.19045

Enabled extensions:

Cryptographic libraries:

NOTE: Operating System: Windows 10

droidmonkey commented 3 months ago

Your shortcut choice is likely being used by some other program. Hover over the field highlighted red to see the error message. There isn't much we can do about this since it works nearly 100% of the time everywhere else, most likely explanation is a conflict.

mih-kopylov commented 3 months ago

Hey @droidmonkey , thanks for the response.

When I hover of the field, it doesn't show any message.

image

Even though it looks like a conflict, there's no proof about any:

It definitely seems like the app fails to register the shortcut. But why - that's the question.

Is there any log file that application writes that could contain any hints about the reason why it fails to register a global shortcut?

mih-kopylov commented 3 months ago

I've tried to change the shortcut combination to multiple others - the behaviour is the same. It fails to register the shortcut after the system startup.

So it doesn't seem like a conflict.

@droidmonkey could you please reopen the ticket?

droidmonkey commented 3 months ago

Check the windows event logs, maybe. There isn't anything we can do if we can't replicate the behavior. Check taskmanager to be certain that two KeePassXC instances aren't started.

mih-kopylov commented 3 months ago

The KeePassXC settings have a checkbox to start the only instance of the app. The task manager shows the only process.

The bug is reproduced not only when the app is started by Windows, but also when I start it manually right after system start. So it seems like it fails to register the shortcut several first times, but succeeds then.

Are there any KeePassXC logs that could help to diagnose what's happening with it? And you mentioned earlier that it should show some message when hovering over the field, but it doesn't. Why?

droidmonkey commented 3 months ago

You could try running a snapshot build, I made edits to this code tha hasn't landed in a release yet.

https://snapshot.keepassxc.org

mih-kopylov commented 3 months ago

Thanks, @droidmonkey!

I've installed the snapshot build, but it looks it behaves the same. It looks like RegisterHotKey windows function is either not called or fails with some error. Unfortunately I didn't find any error codes or messages :(

I've also found and tried Hotkey Screener app to detect all the hotkeys registered by RegisterHotKey function and when they are registered. I've proven that Ctrl + Alt + Q shortcut is not registered at all in the system, neither before the KeePassXC start, nor later. I've pressed "Update" button to reload registered shortcuts every 2-3 seconds until KeePassXC started and a couple minutes later, and the configured shortcut didn't appear at all. image

I've waited for several minutes, but the shortcut still wasn't registered. The KeePassXC options form shows the Auto-Type shortcut field in red. When I open KeePassXC options and then just press "OK" green button, the shortcut gets registered at once.

The experiment was run multiple times, every time the app behaves the same.

Another experiment I've made is to change the shortcut combination. The tested options were:

droidmonkey commented 3 months ago

Maybe you need to reset your settings for KeePassXC, shooting in the dark here. You can reset at the bottom of the application settings.

mih-kopylov commented 3 months ago

Done, but didn't help. :(

I know it sounds bad, but is there any chance to make the app try to register the shortcut multiple times later if the first failed?

Or at least to show some user alert about the registration failed? In RegisterHotKey docs they say:

If the function fails, the return value is zero. To get extended error information, call GetLastError.

I haven't found GetLastError call in sources that call RegisterHotKey. Hopefully, it could give some additional information?

droidmonkey commented 3 months ago

If you can compile the code yourself, replace the code in src/gui/osutils/winutils/WinUtils.cpp lines 174-177 with:

if (!::RegisterHotKey(nullptr, gs->id, gs->nativeModifiers | MOD_NOREPEAT, gs->nativeKeyCode)) {
    if (error) {
        auto winErrorId = GetLastError();
        LPSTR messageBuffer = nullptr;
        FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
                       nullptr,
                       winErrorId,
                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                       messageBuffer,
                       0,
                       nullptr);
        auto msg = tr("Could not register global shortcut: %1").arg(messageBuffer);
        qWarning(qPrintable(msg));
        *error = msg;
        LocalFree(messageBuffer);
    }
    return false;
}

I can provide a compiled portable version if necessary

mih-kopylov commented 3 months ago

Unfortunately I can't compile it myself :( Could you please make a snapshot binary?

mih-kopylov commented 3 months ago

@droidmonkey 🙏

droidmonkey commented 3 months ago

Sorry about that, got distracted, here you go: https://keepassxc.dmapps.us/KeePassXC-2.7.10-snapshot-Win64.zip

mih-kopylov commented 3 months ago

Hey @droidmonkey

Thanks for the build!

I've tried it and where's what I found.

With the earlier snapshot the behaviour was like this: once the application started it failed to register the shortcut. I've opened the settings window multiple times: opened, noticed the red shortcut field, then closed with Esc, and opened again. Some attempts later I noticed it stopped being red and became normal color, and the shortcut worked.

Once I tried the last snapshot, the behaviour changed. It also fails to register the shortcut once the app starts (does it try at all?), but when I open the settings window, I see the shortcut field with normal color at once, not red.

Note, that I just open the settings window, and don't change anything there, or don't click "Ok" button to close it. If I don't open the settings window - the shortcut doesn't work. Once I open it - it starts working even with not closing. Does it try to register a shortcut when the settings window is opened?

Is there any logfile, btw? I haven't found any.

Is there a chance to make the app try to register the shortcut multiple times once the app starts with some retry strategy?

droidmonkey commented 3 months ago

Run the provided snapshot from command prompt to see the error message output from the shortcut registration, if there is any.

mih-kopylov commented 3 months ago

@droidmonkey when I do

> .\Downloads\KeePassXC-2.7.10-snapshot-Win64\KeePassXC.exe

it just opens the app, as usual, it doens't print anything to the console.

After the app is open, the shortcut field is colored in red some first times I open the settings window (~1-3 times), then it's shown with regular color and the shortcut is registered.

droidmonkey commented 3 months ago

Honestly there is really nothing we can do about this. Your behavior indicates something really strange with your computer. This is not experienced by anyone else at the moment. No print out to the console indicates there is no error thrown by windows when attempting to register the shortcut. The shortcut is registered as soon as KeePassXC is opened and also when the settings are shown.

alparo commented 3 months ago

Hi @droidmonkey , let me support @mih-kopylov on this matter. I still have the same issue as him. Initially reported in #9463 .

I have latest Windows 11. When I just start and unlock the app it won't react on auto-type hotkey. But if I open the settings and then press cancel it starts to react. I've just checked with Hotkey Screener - my hotkey for auto-type - ctrl+alt+E - isn't registered before I start KeePassXC and isn't after I start it and unlock. After I click on the settings button the hotkey gets immediately registered. I doubt that it is connected with some hotkey conflict between applications.

droidmonkey commented 3 months ago

This could possibly be fixed by slightly delaying the hotkey registration on startup

droidmonkey commented 3 months ago

@alparo @mih-kopylov I updated my snapshot build to include a delay to registering the auto-type shortcut during application startup: https://keepassxc.dmapps.us/KeePassXC-2.7.10-snapshot-Win64.zip

if (globalAutoTypeKey > 0 && globalAutoTypeModifiers > 0) {
    // Register the global auto-type shortcut after the application has settled
    QTimer::singleShot(
        100, this, [=] { autoType()->registerGlobalShortcut(globalAutoTypeKey, globalAutoTypeModifiers); });
}
mih-kopylov commented 3 months ago

@droidmonkey Thanks!

It works more stable now, bit still looks like the root cause is not caught.

I don't see red background on the shortcut field in the settings screen.

But it definitely looks like it registers the shortcut right after I open the settings window. I've tried the new snapshot multiple times, and sometimes the shortkey starts working at once, but other times it starts working only after I open the settings window.

droidmonkey commented 3 months ago

Needs more delay than

@mih-kopylov I upped the delay to 500 ms: https://keepassxc.dmapps.us/KeePassXC-2.7.10-snapshot-Win64.zip

mih-kopylov commented 2 months ago

@droidmonkey Thanks!

Generally it behaves the same.

The behaviour is constant and looks like this:

Do you have any ideas why?

=== UPD

At the same time, I've got some other apps that register gobal shortcuts on startup:

=== UPD2

Magic. When I launch KeePass with PowerToys Run utility, the former registers the shortcut from the first try. When I launch the same KeePass binary but manually, it doesn't. Tested dozens of times. Constant behaviour and difference. And with the latest release (not snapshot) as well.

droidmonkey commented 2 months ago

You must have something that wipes the registered shortcuts on startup. That is my only explanation. KeePassXC starts, registers it's shortcut, then something else starts and resets everything. This may be avoided with the power tools run because it delays that startup of keepassxc until after that other thing wipes shortcuts.

Do a thorough scrub of everything starting up on your system.

Note: the other apps may be unaffected because they might register their shortcut over and over or detect when the registration changes and re-register. We don't do that, but that is certainly another fix option.

mih-kopylov commented 2 months ago

Does the KeePass try to register shortcut when the settings window opened?

I can't explain the behaviour when the shortcut starts working once I open the settings window.

And what conditions make the red shortcut field backgroud appear in the settings window?

droidmonkey commented 2 months ago

Yes the shortcut is registered again when settings are closed

mih-kopylov commented 2 months ago

That's weird. It gets working when the settings window is open, not closed. @alparo describes the same in https://github.com/keepassxreboot/keepassxc/issues/11151#issuecomment-2322923799 :

After I click on the settings button the hotkey gets immediately registered.

In general, the delay doesn't really help. Probably, if the app can detect that the shortcut is unregistered and retry, that could help.

@droidmonkey, what do you think about adding such a feature to the app?

droidmonkey commented 2 months ago

I looked into this, and I don't have a good answer. Windows doesn't offer an API to detect if a key is registered. I'm really not sure what to do in your case without more data on why it fails in the first place.

The key is registered when you open the application settings because the shortcut widget is populated with your desired key settings and it triggers the registration of the key.