* A fake B_MOUSE_MOVED message is now send on workspace change, and when
a window is closed, too (only happened when a new window was shown before). This is done via the new Desktop::_SendFakeMouseMoved() method. This fixes bug #342. * The MouseFilter now always sets Desktop::fWindowUnderMouse, so that one can differentiate between no window under mouse, and decorator under mouse. * EventDispatcher::SendFakeMouseMoved() now expects a BMessenger instead of an EventTarget as target - this guarantees that it can safely be called with any window now (instead of only the current window). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16953 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4436fae24d
commit
a1a04a4742
@ -218,6 +218,8 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken,
|
||||
if (!fDesktop->LockAllWindows())
|
||||
return B_DISPATCH_MESSAGE;
|
||||
|
||||
int32 viewToken = B_NULL_TOKEN;
|
||||
|
||||
WindowLayer* window = fDesktop->MouseEventWindow();
|
||||
if (window == NULL)
|
||||
window = fDesktop->WindowAt(where);
|
||||
@ -226,30 +228,33 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken,
|
||||
// dispatch event in the window layers
|
||||
switch (message->what) {
|
||||
case B_MOUSE_DOWN:
|
||||
window->MouseDown(message, where, _viewToken);
|
||||
window->MouseDown(message, where, &viewToken);
|
||||
break;
|
||||
|
||||
case B_MOUSE_UP:
|
||||
window->MouseUp(message, where, _viewToken);
|
||||
window->MouseUp(message, where, &viewToken);
|
||||
fDesktop->SetMouseEventWindow(NULL);
|
||||
break;
|
||||
|
||||
case B_MOUSE_MOVED:
|
||||
window->MouseMoved(message, where, _viewToken,
|
||||
window->MouseMoved(message, where, &viewToken,
|
||||
latestMouseMoved == NULL || latestMouseMoved == message);
|
||||
break;
|
||||
}
|
||||
|
||||
if (*_viewToken != B_NULL_TOKEN) {
|
||||
fDesktop->SetViewUnderMouse(window, *_viewToken);
|
||||
if (viewToken != B_NULL_TOKEN) {
|
||||
fDesktop->SetViewUnderMouse(window, viewToken);
|
||||
|
||||
*_viewToken = viewToken;
|
||||
*_target = &window->EventTarget();
|
||||
} else {
|
||||
fDesktop->SetViewUnderMouse(NULL, B_NULL_TOKEN);
|
||||
*_target = NULL;
|
||||
}
|
||||
} else {
|
||||
fDesktop->SetViewUnderMouse(NULL, B_NULL_TOKEN);
|
||||
}
|
||||
|
||||
if (window == NULL || viewToken == B_NULL_TOKEN) {
|
||||
// mouse is not over a window or over a decorator
|
||||
fDesktop->SetViewUnderMouse(window, B_NULL_TOKEN);
|
||||
fDesktop->SetCursor(NULL);
|
||||
|
||||
*_target = NULL;
|
||||
}
|
||||
|
||||
@ -784,6 +789,8 @@ Desktop::SetWorkspace(int32 index)
|
||||
MarkDirty(dirty);
|
||||
|
||||
UnlockAllWindows();
|
||||
|
||||
_SendFakeMouseMoved();
|
||||
}
|
||||
|
||||
|
||||
@ -980,6 +987,51 @@ Desktop::_WindowChanged(WindowLayer* window)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\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.
|
||||
|
||||
Windows must not be locked when calling this method.
|
||||
*/
|
||||
void
|
||||
Desktop::_SendFakeMouseMoved(WindowLayer* window)
|
||||
{
|
||||
BPoint where;
|
||||
int32 buttons;
|
||||
EventDispatcher().GetMouse(where, buttons);
|
||||
|
||||
int32 viewToken = B_NULL_TOKEN;
|
||||
BMessenger target;
|
||||
|
||||
LockAllWindows();
|
||||
|
||||
if (window == NULL)
|
||||
window = MouseEventWindow();
|
||||
if (window == NULL)
|
||||
window = WindowAt(where);
|
||||
|
||||
if (window != NULL) {
|
||||
BMessage message;
|
||||
window->MouseMoved(&message, where, &viewToken, true);
|
||||
}
|
||||
|
||||
if (viewToken != B_NULL_TOKEN)
|
||||
SetViewUnderMouse(window, viewToken);
|
||||
else {
|
||||
SetViewUnderMouse(NULL, B_NULL_TOKEN);
|
||||
SetCursor(NULL);
|
||||
}
|
||||
|
||||
UnlockAllWindows();
|
||||
|
||||
if (viewToken != B_NULL_TOKEN)
|
||||
EventDispatcher().SendFakeMouseMoved(target, viewToken);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Desktop::SetFocusWindow(WindowLayer* focus)
|
||||
{
|
||||
@ -1245,23 +1297,7 @@ Desktop::ShowWindow(WindowLayer* window)
|
||||
// we'll send a fake mouse moved message to the window, so that
|
||||
// it knows the mouse is over it.
|
||||
|
||||
BPoint where;
|
||||
int32 buttons;
|
||||
EventDispatcher().GetMouse(where, buttons);
|
||||
|
||||
int32 viewToken = B_NULL_TOKEN;
|
||||
|
||||
LockAllWindows();
|
||||
|
||||
if (WindowAt(where) == window) {
|
||||
ViewLayer* view = window->ViewAt(where);
|
||||
if (view != NULL)
|
||||
viewToken = view->Token();
|
||||
}
|
||||
UnlockAllWindows();
|
||||
|
||||
if (viewToken != B_NULL_TOKEN)
|
||||
EventDispatcher().SendFakeMouseMoved(window->EventTarget(), viewToken);
|
||||
_SendFakeMouseMoved(window);
|
||||
}
|
||||
|
||||
|
||||
@ -1294,6 +1330,9 @@ Desktop::HideWindow(WindowLayer* window)
|
||||
fWorkspacesLayer = NULL;
|
||||
|
||||
UnlockAllWindows();
|
||||
|
||||
if (window == fWindowUnderMouse)
|
||||
_SendFakeMouseMoved();
|
||||
}
|
||||
|
||||
|
||||
|
@ -184,6 +184,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
void _BringWindowsToFront(WindowList& windows,
|
||||
int32 list, bool wereVisible);
|
||||
status_t _ActivateApp(team_id team);
|
||||
void _SendFakeMouseMoved(WindowLayer* window = NULL);
|
||||
|
||||
void _RebuildClippingForAllWindows(BRegion& stillAvailableOnScreen);
|
||||
void _TriggerWindowRedrawing(BRegion& newDirtyRegion);
|
||||
|
@ -466,7 +466,7 @@ EventDispatcher::GetMouse(BPoint& where, int32& buttons)
|
||||
|
||||
|
||||
void
|
||||
EventDispatcher::SendFakeMouseMoved(EventTarget& target, int32 viewToken)
|
||||
EventDispatcher::SendFakeMouseMoved(BMessenger& target, int32 viewToken)
|
||||
{
|
||||
BAutolock _(this);
|
||||
|
||||
@ -482,7 +482,7 @@ EventDispatcher::SendFakeMouseMoved(EventTarget& target, int32 viewToken)
|
||||
moved.AddMessage("be:drag_message", &fDragMessage);
|
||||
}
|
||||
|
||||
_SendMessage(target.Messenger(), &moved, kMouseTransitImportance);
|
||||
_SendMessage(target, &moved, kMouseTransitImportance);
|
||||
}
|
||||
|
||||
|
||||
|
@ -80,7 +80,7 @@ class EventDispatcher : public BLocker {
|
||||
void SetKeyboardFilter(EventFilter* filter);
|
||||
|
||||
void GetMouse(BPoint& where, int32& buttons);
|
||||
void SendFakeMouseMoved(EventTarget& target, int32 viewToken);
|
||||
void SendFakeMouseMoved(BMessenger& target, int32 viewToken);
|
||||
|
||||
bool HasCursorThread();
|
||||
void SetHWInterface(HWInterface* interface);
|
||||
|
Loading…
Reference in New Issue
Block a user