app_server: Fixed some send fake mouse event issues.

* Activating a window never send a faked mouse message. This was
  noticeable when switching windows using the keyboard; if you then
  scrolled with the mouse wheel you could scroll in the previous window
  still.
* Also, using MouseEventWindow() in _SendFakeMouseMoved() doesn't work
  when you click the window to send it to behind: it's moved on button
  press, but the mouse event window is only released on button release,
  ie. too late.
* This is fixed by always using the current window under the mouse as
  target for the fake event.
This commit is contained in:
Axel Dörfler 2015-05-22 00:25:08 +02:00
parent e711e6e42f
commit fa6fca91e6
2 changed files with 35 additions and 13 deletions

View File

@ -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 <stdio.h>
#include <string.h>
#include <syslog.h>
@ -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);

View File

@ -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);