mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
fix: preserve mouse hook handle when UnhookWindowsHookEx fails (#51098)
* fix: preserve mouse hook handle when UnhookWindowsHookEx fails NativeWindowViews::SetForwardMouseMessages() installs a low-level mouse hook when mouse forwarding begins and unhooks it once no window needs forwarding. The previous code reset the shared `mouse_hook_` handle to `nullptr` unconditionally after calling UnhookWindowsHookEx, even when the unhook call failed. When unhooking fails, the hook is still installed in the system. Because `mouse_hook_` is nulled out anyway, the next call to SetForwardMouseMessages(true) evaluates `if (!mouse_hook_)` as true and installs a second, duplicate hook via SetWindowsHookEx, so every mouse message is processed by MouseHookProc multiple times. Check the return value of UnhookWindowsHookEx and only null the handle on success. When the call fails, leave `mouse_hook_` pointing at the existing hook so the next activation reuses it rather than stacking a new one on top, and log the failure via PLOG to surface the underlying Windows error. Fixes: #51064 Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> * fix: clear invalid mouse hook handles Signed-off-by: Asish Kumar <officialasishkumar@gmail.com> --------- Signed-off-by: Asish Kumar <officialasishkumar@gmail.com>
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include <shellapi.h>
|
||||
#include <wrl/client.h>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/win/atl.h" // Must be before UIAutomationCore.h
|
||||
#include "base/win/registry.h"
|
||||
#include "base/win/scoped_handle.h"
|
||||
@@ -677,8 +678,21 @@ void NativeWindowViews::SetForwardMouseMessages(bool forward) {
|
||||
RemoveWindowSubclass(legacy_window_, SubclassProc, 1);
|
||||
|
||||
if (forwarding_windows_->empty()) {
|
||||
UnhookWindowsHookEx(mouse_hook_);
|
||||
mouse_hook_ = nullptr;
|
||||
// If UnhookWindowsHookEx fails, the hook is still installed in the
|
||||
// system. Leave |mouse_hook_| pointing at the existing hook so that a
|
||||
// subsequent SetForwardMouseMessages(true) reuses it instead of
|
||||
// installing a duplicate hook.
|
||||
if (UnhookWindowsHookEx(mouse_hook_)) {
|
||||
mouse_hook_ = nullptr;
|
||||
} else {
|
||||
const DWORD error = ::GetLastError();
|
||||
if (error == ERROR_INVALID_HOOK_HANDLE) {
|
||||
mouse_hook_ = nullptr;
|
||||
} else {
|
||||
LOG(WARNING) << "Failed to unhook low-level mouse hook: "
|
||||
<< logging::SystemErrorCodeToString(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user