New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mouseleave event isn't fired when moving the mouse outside the window (Windows) #611
Comments
I just tested on Windows 8.1 and Atom-Shell 0.15.7 and your example seems to work fine for me on both a framed and unframed browser window. I cannot reproduce the behavior I see on your video. |
The video above was made on Windows 7. Sorry for the confusion. But I just tested it again on another computer (this time Windows 8.1 and atomshell 0.15.9), same behavior. |
Yes, I tested both framed and non-framed windows. I'll test on another On Wed, Aug 27, 2014 at 4:53 PM, Martin Mädler notifications@github.com
|
I have access to a few machines and one is working fine but the other exhibits the behavior you are talking about. Both Windows 8.1. That is crazy! I'd have expected it would be consistent. |
There is dragging border in frameless window, and it is causing the window to loose mouse events. Possibly related: #741. |
Okay, I have created an app window that is frameless with a custom titlebar and drag region. I am definitely seeing the loss of mouse events. I have custom hover effects on the various minimize, maximize, close buttons and if the mouse pointer leaves the main window immediately after it triggered a hover on one of these buttons the hover effect is not removed to return the button to it's original state. |
On Windows, I think it's necessary to track the mouse events by calling the TrackMouseEvent function in order to be able to receive the I don't fully comprehend how and where Anyhow, this is basically how chromium (Google Chrome) seems to do it in their if (message == WM_MOUSEMOVE || message == WM_NCMOUSEMOVE)
{
// Windows only fires WM_MOUSELEAVE events if the application begins
// "tracking" mouse events for a given HWND during WM_MOUSEMOVE events.
// We need to call |TrackMouseEvents| to listen for WM_MOUSELEAVE.
TrackMouseEvents((message == WM_NCMOUSEMOVE) ? TME_NONCLIENT | TME_LEAVE : TME_LEAVE);
}
else if (message == WM_MOUSELEAVE || message == WM_NCMOUSELEAVE)
{
// Reset our tracking flags so future mouse movement over this
// window results in a new tracking session.
active_mouse_tracking_flags_ = 0;
} void HWNDMessageHandler::TrackMouseEvents(DWORD mouse_tracking_flags) {
// Begin tracking mouse events for this HWND so that we get WM_MOUSELEAVE
// when the user moves the mouse outside this HWND's bounds.
if (active_mouse_tracking_flags_ == 0 || mouse_tracking_flags & TME_CANCEL)
{
if (mouse_tracking_flags & TME_CANCEL)
{
// We're about to cancel active mouse tracking, so empty out the stored
// state.
active_mouse_tracking_flags_ = 0;
}
else
{
active_mouse_tracking_flags_ = mouse_tracking_flags;
}
TRACKMOUSEEVENT tme;
tme.cbSize = sizeof(tme);
tme.dwFlags = mouse_tracking_flags;
tme.hwndTrack = hwnd();
tme.dwHoverTime = 0;
TrackMouseEvent(&tme);
}
else if (mouse_tracking_flags != active_mouse_tracking_flags_)
{
TrackMouseEvents(active_mouse_tracking_flags_ | TME_CANCEL);
TrackMouseEvents(mouse_tracking_flags);
}
}
|
This also happens when moving your mouse from an item with a hover style to an item with the |
Does anyway found solutions for this bug? |
I'm afraid this is related to Chromium, so we can't really make something |
This seems to happen in both frameless and non-frameless windows, with and without 'webkit-app-region'. It doesn't seem to happen in Atom IDE or Chrome. It does happen in Visual Studio code though and my test apps. Anyone have insight into it? |
Reproduce in my app too :( |
Tried a bunch different things to get it working, but it happens in every version of Chromium, including frameless Chrome apps. We submitted an issue to Chromium but they upgraded to VS2015 that same day, so I imagine they got flooded with more important bugs. |
Does anyone have a work around for this problem? I'm getting the same issue. |
I wrote a workaround for this, not ideal but it's enough for my use case. See how the window mouseleave is detected, even when leaving the app-region top bar: The code is here: https://gist.github.com/louisameline/1213bb112c6cb12a98b2ab525dfb8b07 |
Nice one! Perhaps you could prevent the events triggering while a window is overlaying it by checking for focus? |
I thought about that but then a blurred window wouldn't react to mouse hovering, even if there were no windows on top of it. That's not the usual behavior and I'm not sure it would be better. |
When I say the window wouldn't react, I'm actually thinking about my app-region titlebar, which wouldn't reappear because it can't catch mouse moves and needs coordinates calculations instead. But you're probably right, with appropriate modifications on this bar it may work as expected. |
I have enabled the check for the focused window by default, but you can disable it by setting I thought it would be smart to apply a |
Given that there exist workarounds, this is something that isn't on our current roadmap and which I am thus goin to tag as |
Appeal to reopen this issue! |
I don't think they will fix it, even their Github Desktop app exhibits this unfortunate behavior. Minimize the app and then hover over the taskbar icon in Windows and you'll notice that they cannot react to the minimize state and the minimize icon is still highlighted in the preview. Here is a screenshot showing (yeah it's hard to see but it's there) |
I just found a hacky solution, which works for me, use |
mouseleave event doesn't fire with the below window properties set but if resizable is set to true then it works. Using windows 10 with electron 7.3.1. Any way to work around this? alwaysOnTop: true, |
same problem |
I add a fix for this bug, see #29721 |
我英文不太好,尝试解释一下 bug 产生的细节: 经研究发现:
当 resizable 设置为 false 时,鼠标经过窗口边缘时(窗口边缘设置为5个像素[kResizeInsideBoundsSize]), 调用 这会导致 Windows 误以为鼠标离开了窗口区域,从而向窗口发送了一个 WM_MOUSELEAVE 事件,实际上鼠标依然在窗口内。 chromium 在 LRESULT LegacyRenderWidgetHostHWND::OnMouseLeave(UINT message,
WPARAM w_param,
LPARAM l_param) {
mouse_tracking_enabled_ = false;
LRESULT ret = 0;
HWND capture_window = ::GetCapture();
if ((capture_window != GetParent()) && GetWindowEventTarget(GetParent())) {
// We should send a WM_MOUSELEAVE to the parent window only if the mouse
// has moved outside the bounds of the parent.
POINT cursor_pos;
::GetCursorPos(&cursor_pos);
// WindowFromPoint returns the top-most HWND. As hwnd() may not
// respond with HTTRANSPARENT to a WM_NCHITTEST message,
// it may be returned.
HWND window_from_point = ::WindowFromPoint(cursor_pos);
if (window_from_point != GetParent() &&
(capture_window || window_from_point != hwnd())) {
bool msg_handled = false;
ret = GetWindowEventTarget(GetParent())->HandleMouseMessage(
message, w_param, l_param, &msg_handled);
SetMsgHandled(msg_handled);
}
}
return ret;
} 此时因为 WM_NCHITTEST 返回了 HTBORDER,因此虽然触发了 WM_MOUSELEAVE,但是鼠标仍然在窗口内部。 所以会导致 所以当 BrowserWindow 的 resizable 属性设置为 false 时,NCHitTest 应该返回 HTCLIENT,这样才能让 Windows 在鼠标真正离开窗口时触发 WM_MOUSELEAVE,解决 hover 状态清除不掉的问题。 |
…resizable (electron#611) (electron#29721)" This reverts commit e54667e. Around allows interactions within the non-client region so that the floating window allows dragging. This also affects modals which are not resizable.
I have a simple
div
with a css hover effect changing the background color. When I move the mouse outside of the window area, thediv
keeps its hover style. It should actually go back to its normal style. Presumable the mouseleave event was "swallowed".For a demonstration video see here: https://www.screenr.com/4M0N
It happens using the frameless view and using the windows frame view. Even though the latter is more difficult to reproduce (move the mouse faster).
You can reproduce it with this sample code:
My setup:
Windows
8.17atom-shell 0.15.7
The text was updated successfully, but these errors were encountered: