Set up legacy window subclass and mouse hook during setForwardMouseMessages.
As opposed to when a legacy window is created/destroyed. This enables forwarding on a per-window basis.
This commit is contained in:
parent
0736de1e8d
commit
60c0bf1636
3 changed files with 39 additions and 39 deletions
|
@ -1064,13 +1064,6 @@ void NativeWindowViews::SetEnabled(bool enable) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(OS_WIN)
|
|
||||||
void NativeWindowViews::SetForwardMouseMessages(bool forward) {
|
|
||||||
forwarding_mouse_messages_ = forward;
|
|
||||||
SetIgnoreMouseEvents(forward);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void NativeWindowViews::OnWidgetActivationChanged(
|
void NativeWindowViews::OnWidgetActivationChanged(
|
||||||
views::Widget* widget, bool active) {
|
views::Widget* widget, bool active) {
|
||||||
if (widget != window_.get())
|
if (widget != window_.get())
|
||||||
|
|
|
@ -267,10 +267,11 @@ class NativeWindowViews : public NativeWindow,
|
||||||
base::win::ScopedHICON window_icon_;
|
base::win::ScopedHICON window_icon_;
|
||||||
base::win::ScopedHICON app_icon_;
|
base::win::ScopedHICON app_icon_;
|
||||||
|
|
||||||
// Handles to legacy windows iterated by the mouse hook
|
// The set of windows currently forwarding mouse messages.
|
||||||
static std::map<HWND, NativeWindowViews*> legacy_window_map_;
|
static std::set<NativeWindowViews*> forwarding_windows_;
|
||||||
static HHOOK mouse_hook_;
|
static HHOOK mouse_hook_;
|
||||||
bool forwarding_mouse_messages_ = false;
|
bool forwarding_mouse_messages_ = false;
|
||||||
|
HWND legacy_window_ = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Handles unhandled keyboard messages coming back from the renderer process.
|
// Handles unhandled keyboard messages coming back from the renderer process.
|
||||||
|
|
|
@ -80,7 +80,7 @@ bool IsScreenReaderActive() {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::map<HWND, NativeWindowViews*> NativeWindowViews::legacy_window_map_;
|
std::set<NativeWindowViews*> NativeWindowViews::forwarding_windows_;
|
||||||
HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
HHOOK NativeWindowViews::mouse_hook_ = NULL;
|
||||||
|
|
||||||
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
bool NativeWindowViews::ExecuteWindowsCommand(int command_id) {
|
||||||
|
@ -160,17 +160,8 @@ bool NativeWindowViews::PreHandleMSG(
|
||||||
if (LOWORD(w_param) == WM_CREATE) {
|
if (LOWORD(w_param) == WM_CREATE) {
|
||||||
// Because of reasons regarding legacy drivers and stuff, a window that
|
// Because of reasons regarding legacy drivers and stuff, a window that
|
||||||
// matches the client area is created and used internally by Chromium.
|
// matches the client area is created and used internally by Chromium.
|
||||||
// This window is subclassed in order to fix some issues when forwarding
|
// This is used when forwarding mouse messages.
|
||||||
// mouse messages; see comments in |SubclassProc|. If by any chance
|
legacy_window_ = reinterpret_cast<HWND>(l_param);
|
||||||
// Chromium removes the legacy window in the future it may be fine to
|
|
||||||
// move the logic to this very switch statement.
|
|
||||||
HWND legacy_window = reinterpret_cast<HWND>(l_param);
|
|
||||||
SetWindowSubclass(
|
|
||||||
legacy_window, SubclassProc, 1, reinterpret_cast<DWORD_PTR>(this));
|
|
||||||
if (legacy_window_map_.size() == 0) {
|
|
||||||
mouse_hook_ = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
|
|
||||||
}
|
|
||||||
legacy_window_map_.insert({ legacy_window, this });
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -229,6 +220,33 @@ void NativeWindowViews::HandleSizeEvent(WPARAM w_param, LPARAM l_param) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NativeWindowViews::SetForwardMouseMessages(bool forward) {
|
||||||
|
forwarding_mouse_messages_ = forward;
|
||||||
|
SetIgnoreMouseEvents(forward);
|
||||||
|
|
||||||
|
if (forward) {
|
||||||
|
forwarding_windows_.insert(this);
|
||||||
|
|
||||||
|
// Subclassing is used to fix some issues when forwarding mouse messages;
|
||||||
|
// see comments in |SubclassProc|.
|
||||||
|
SetWindowSubclass(
|
||||||
|
legacy_window_, SubclassProc, 1, reinterpret_cast<DWORD_PTR>(this));
|
||||||
|
|
||||||
|
if (!mouse_hook_) {
|
||||||
|
mouse_hook_ = SetWindowsHookEx(WH_MOUSE_LL, MouseHookProc, NULL, 0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
forwarding_windows_.erase(this);
|
||||||
|
|
||||||
|
RemoveWindowSubclass(legacy_window_, SubclassProc, 1);
|
||||||
|
|
||||||
|
if (forwarding_windows_.size() == 0) {
|
||||||
|
UnhookWindowsHookEx(mouse_hook_);
|
||||||
|
mouse_hook_ = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LRESULT CALLBACK NativeWindowViews::SubclassProc(
|
LRESULT CALLBACK NativeWindowViews::SubclassProc(
|
||||||
HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, UINT_PTR subclass_id,
|
HWND hwnd, UINT msg, WPARAM w_param, LPARAM l_param, UINT_PTR subclass_id,
|
||||||
DWORD_PTR ref_data) {
|
DWORD_PTR ref_data) {
|
||||||
|
@ -250,14 +268,6 @@ LRESULT CALLBACK NativeWindowViews::SubclassProc(
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WM_DESTROY: {
|
|
||||||
legacy_window_map_.erase(hwnd);
|
|
||||||
if (legacy_window_map_.size() == 0) {
|
|
||||||
UnhookWindowsHookEx(mouse_hook_);
|
|
||||||
mouse_hook_ = NULL;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return DefSubclassProc(hwnd, msg, w_param, l_param);
|
return DefSubclassProc(hwnd, msg, w_param, l_param);
|
||||||
|
@ -270,26 +280,22 @@ LRESULT CALLBACK NativeWindowViews::MouseHookProc(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Post a WM_MOUSEMOVE message for those windows whose client area contains
|
// Post a WM_MOUSEMOVE message for those windows whose client area contains
|
||||||
// the cursor and are set to forward messages since they are in a state where
|
// the cursor since they are in a state where they would otherwise ignore all
|
||||||
// they would otherwise ignore all mouse input.
|
// mouse input.
|
||||||
if (w_param == WM_MOUSEMOVE) {
|
if (w_param == WM_MOUSEMOVE) {
|
||||||
for (auto legacy : legacy_window_map_) {
|
for (auto window : forwarding_windows_) {
|
||||||
if (!legacy.second->forwarding_mouse_messages_) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// At first I considered enumerating windows to check whether the cursor
|
// At first I considered enumerating windows to check whether the cursor
|
||||||
// was directly above the window, but since nothing bad seems to happen
|
// was directly above the window, but since nothing bad seems to happen
|
||||||
// if we post the message even if some other window occludes it I have
|
// if we post the message even if some other window occludes it I have
|
||||||
// just left it as is.
|
// just left it as is.
|
||||||
RECT client_rect;
|
RECT client_rect;
|
||||||
GetClientRect(legacy.first, &client_rect);
|
GetClientRect(window->legacy_window_, &client_rect);
|
||||||
POINT p = reinterpret_cast<MSLLHOOKSTRUCT*>(l_param)->pt;
|
POINT p = reinterpret_cast<MSLLHOOKSTRUCT*>(l_param)->pt;
|
||||||
ScreenToClient(legacy.first, &p);
|
ScreenToClient(window->legacy_window_, &p);
|
||||||
if (PtInRect(&client_rect, p)) {
|
if (PtInRect(&client_rect, p)) {
|
||||||
WPARAM w = 0; // No virtual keys pressed for our purposes
|
WPARAM w = 0; // No virtual keys pressed for our purposes
|
||||||
LPARAM l = MAKELPARAM(p.x, p.y);
|
LPARAM l = MAKELPARAM(p.x, p.y);
|
||||||
PostMessage(legacy.first, WM_MOUSEMOVE, w, l);
|
PostMessage(window->legacy_window_, WM_MOUSEMOVE, w, l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue