diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 808ac9272a..5e45bc975e 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -17,6 +17,7 @@ #include "Desktop.h" + #include #include #include @@ -1051,7 +1052,7 @@ Desktop::ActivateWindow(Window* window) if (window->Workspaces() == 0 && window->IsNormal()) return; - AutoWriteLocker _(fWindowLock); + AutoWriteLocker allWindowLocker(fWindowLock); NotifyWindowActivated(window); @@ -1123,6 +1124,7 @@ Desktop::ActivateWindow(Window* window) WindowList windows(kWorkingList); Window* frontmost = window->Frontmost(); + const Window* lastWindowUnderMouse = fWindowUnderMouse; CurrentWindows().RemoveWindow(window); windows.AddWindow(window); @@ -1152,6 +1154,13 @@ Desktop::ActivateWindow(Window* window) if ((window->Flags() & B_AVOID_FOCUS) == 0) SetFocusWindow(window); + + bool sendFakeMouseMoved = _CheckSendFakeMouseMoved(lastWindowUnderMouse); + + allWindowLocker.Unlock(); + + if (sendFakeMouseMoved) + _SendFakeMouseMoved(); } @@ -1184,6 +1193,7 @@ Desktop::SendWindowBehind(Window* window, Window* behindOf, bool sendStack) BRegion dirty(window->VisibleRegion()); Window* backmost = window->Backmost(behindOf); + const Window* lastWindowUnderMouse = fWindowUnderMouse; CurrentWindows().RemoveWindow(window); CurrentWindows().AddWindow(window, backmost @@ -1206,10 +1216,6 @@ Desktop::SendWindowBehind(Window* window, Window* behindOf, bool sendStack) else if (fSettings->NormalMouse()) SetFocusWindow(NULL); - bool sendFakeMouseMoved = false; - if (FocusWindow() != window) - sendFakeMouseMoved = true; - _WindowChanged(window); if (sendStack && stack != NULL) { @@ -1221,6 +1227,7 @@ Desktop::SendWindowBehind(Window* window, Window* behindOf, bool sendStack) } } + bool sendFakeMouseMoved = _CheckSendFakeMouseMoved(lastWindowUnderMouse); NotifyWindowSentBehind(orgWindow, behindOf); UnlockAllWindows(); @@ -3058,8 +3065,7 @@ Desktop::_ChangeWindowWorkspaces(Window* window, uint32 oldWorkspaces, void -Desktop::_BringWindowsToFront(WindowList& windows, int32 list, - bool wereVisible) +Desktop::_BringWindowsToFront(WindowList& windows, int32 list, bool wereVisible) { // we don't need to redraw what is currently // visible of the window @@ -3118,11 +3124,27 @@ Desktop::_LastFocusSubsetWindow(Window* window) } +/*! \brief Checks whether or not a fake mouse moved message needs to be sent + to the previous mouse window. + + You need to have the all window lock held when calling this method. +*/ +bool +Desktop::_CheckSendFakeMouseMoved(const Window* lastWindowUnderMouse) +{ + Window* window = WindowAt(fLastMousePosition); + return window != lastWindowUnderMouse; +} + + /*! \brief Sends a fake B_MOUSE_MOVED event to the window under the mouse, and also updates the current view under the mouse. - This has only to be done in case the view changed without user interaction, - ie. because of a workspace change or a closing window. + This has only to be done in case the view changed without mouse movement, + ie. because of a workspace change, a closing window, or programmatic window + movement. + + You must not have locked any windows when calling this method. */ void Desktop::_SendFakeMouseMoved(Window* window) @@ -3132,8 +3154,6 @@ Desktop::_SendFakeMouseMoved(Window* window) LockAllWindows(); - if (window == NULL) - window = MouseEventWindow(); if (window == NULL) window = WindowAt(fLastMousePosition); diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index 5c7b565233..c9b8e61959 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2013, Haiku. + * Copyright 2001-2015, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -283,6 +283,8 @@ private: void _BringWindowsToFront(WindowList& windows, int32 list, bool wereVisible); Window* _LastFocusSubsetWindow(Window* window); + bool _CheckSendFakeMouseMoved( + const Window* lastWindowUnderMouse); void _SendFakeMouseMoved(Window* window = NULL); Screen* _DetermineScreenFor(BRect frame);