* Refactored a method for getting the transit from a mouse moved message.

* In _StealMouseMessage(), don't maintain fLastMouseMovedView, instead,
  prevent B_MOUSE_MOVED message from being stolen that are important for
  detecting transit changes. The point is that some apps (like Tracker) are
  shooting themselves in the foot because they steal mouse messages via
  GetMouse() in one place, but then rely on sane transit values in another
  place. The way it works now, the view in question may get notified of the
  same mouse moved coordinate twice, once via GetMouse() and once via
  MouseMoved().


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28002 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2008-10-12 19:30:59 +00:00
parent e1ca73e1f1
commit 71ea6c9229
2 changed files with 38 additions and 22 deletions

View File

@ -301,6 +301,8 @@ private:
BHandler* target, bool usePreferred);
bool _StealMouseMessage(BMessage* message,
bool& deleteMessage);
uint32 _TransitForMouseMoved(BView* view,
BView* viewUnderMouse) const;
bool InUpdate();
void _DequeueAll();

View File

@ -3006,8 +3006,8 @@ BWindow::_DetermineTarget(BMessage *message, BHandler *target)
Returns \c true in case the message should still be dispatched
*/
bool
BWindow::_UnpackMessage(unpack_cookie& cookie, BMessage** _message, BHandler** _target,
bool* _usePreferred)
BWindow::_UnpackMessage(unpack_cookie& cookie, BMessage** _message,
BHandler** _target, bool* _usePreferred)
{
if (cookie.message == NULL)
return false;
@ -3140,21 +3140,7 @@ BWindow::_SanitizeMessage(BMessage* message, BHandler* target, bool usePreferred
viewUnderMouse = _FindView(token);
// add transit information
int32 transit;
if (viewUnderMouse == view) {
// the mouse is over the target view
if (fLastMouseMovedView != view)
transit = B_ENTERED_VIEW;
else
transit = B_INSIDE_VIEW;
} else {
// the mouse is not over the target view
if (view == fLastMouseMovedView)
transit = B_EXITED_VIEW;
else
transit = B_OUTSIDE_VIEW;
}
uint32 transit = _TransitForMouseMoved(view, viewUnderMouse);;
message->AddInt32("be:transit", transit);
if (usePreferred || viewUnderMouse == NULL)
@ -3210,20 +3196,27 @@ BWindow::_StealMouseMessage(BMessage* message, bool& deleteMessage)
message->RemoveName("_feed_focus");
deleteMessage = false;
} else {
// The message is only thought for the preferred handler, so we
// can just remove it.
MessageQueue()->RemoveMessage(message);
deleteMessage = true;
if (message->what == B_MOUSE_MOVED) {
// We need to update the last mouse moved view, as this message
// won't make it to _SanitizeMessage() anymore
// won't make it to _SanitizeMessage() anymore.
BView* viewUnderMouse = NULL;
int32 token;
if (message->FindInt32("_view_token", &token) == B_OK)
viewUnderMouse = _FindView(token);
fLastMouseMovedView = viewUnderMouse;
// Don't remove important transit messages!
uint32 transit = _TransitForMouseMoved(fLastMouseMovedView,
viewUnderMouse);
if (transit == B_ENTERED_VIEW || transit == B_EXITED_VIEW)
deleteMessage = false;
}
if (deleteMessage) {
// The message is only thought for the preferred handler, so we
// can just remove it.
MessageQueue()->RemoveMessage(message);
}
}
@ -3231,6 +3224,27 @@ BWindow::_StealMouseMessage(BMessage* message, bool& deleteMessage)
}
uint32
BWindow::_TransitForMouseMoved(BView* view, BView* viewUnderMouse) const
{
uint32 transit;
if (viewUnderMouse == view) {
// the mouse is over the target view
if (fLastMouseMovedView != view)
transit = B_ENTERED_VIEW;
else
transit = B_INSIDE_VIEW;
} else {
// the mouse is not over the target view
if (view == fLastMouseMovedView)
transit = B_EXITED_VIEW;
else
transit = B_OUTSIDE_VIEW;
}
return transit;
}
/*!
Handles keyboard input before it gets forwarded to the target handler.
This includes shortcut evaluation, keyboard navigation, etc.