Now this should nail down bug #762 pretty well: BView::GetMouse() no calls the
private BWindow::_StealMouseMessage() which makes sure only messages for the preferred handler are stolen, and also, that nothing gets lost that shouldn't get lost. Also updates the fLastMouseMoved view in case the message is actually removed due to GetMouse(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@18601 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c944ee6c2d
commit
fa407130aa
@ -310,6 +310,8 @@ private:
|
||||
void _SanitizeMessage(BMessage* message,
|
||||
BHandler* target,
|
||||
bool usePreferred);
|
||||
bool _StealMouseMessage(BMessage* message,
|
||||
bool& deleteMessage);
|
||||
|
||||
bool InUpdate();
|
||||
void _DequeueAll();
|
||||
|
@ -1337,21 +1337,27 @@ BView::GetMouse(BPoint *location, uint32 *buttons, bool checkMessageQueue)
|
||||
|
||||
// Look out for mouse update messages
|
||||
|
||||
BMessage *msg;
|
||||
for (int32 i = 0; (msg = queue->FindMessage(i)) != NULL; i++) {
|
||||
switch (msg->what) {
|
||||
BMessage *message;
|
||||
for (int32 i = 0; (message = queue->FindMessage(i)) != NULL; i++) {
|
||||
switch (message->what) {
|
||||
case B_MOUSE_MOVED:
|
||||
case B_MOUSE_UP:
|
||||
case B_MOUSE_DOWN:
|
||||
case B_MOUSE_MOVED:
|
||||
msg->FindPoint("screen_where", location);
|
||||
msg->FindInt32("buttons", (int32 *)buttons);
|
||||
bool deleteMessage;
|
||||
if (!Window()->_StealMouseMessage(message, deleteMessage))
|
||||
continue;
|
||||
|
||||
message->FindPoint("screen_where", location);
|
||||
message->FindInt32("buttons", (int32 *)buttons);
|
||||
queue->Unlock();
|
||||
// we need to hold the queue lock until here, because
|
||||
// the message might still be used for something else
|
||||
|
||||
ConvertFromScreen(location);
|
||||
|
||||
queue->RemoveMessage(msg);
|
||||
delete msg;
|
||||
if (deleteMessage)
|
||||
delete message;
|
||||
|
||||
queue->Unlock();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -2530,8 +2530,7 @@ BWindow::task_looper()
|
||||
while (_UnpackMessage(cookie, &fLastMessage, &handler, &usePreferred)) {
|
||||
// if there is no target handler, the message is dropped
|
||||
if (handler != NULL) {
|
||||
if (handler != NULL)
|
||||
_SanitizeMessage(fLastMessage, handler, usePreferred);
|
||||
_SanitizeMessage(fLastMessage, handler, usePreferred);
|
||||
|
||||
// Is this a scripting message?
|
||||
if (fLastMessage->HasSpecifiers()) {
|
||||
@ -2802,8 +2801,10 @@ BWindow::_UnpackMessage(unpack_cookie& cookie, BMessage** _message, BHandler** _
|
||||
return false;
|
||||
|
||||
if (cookie.index == 0 && !cookie.tokens_scanned) {
|
||||
// We were called the first time for this message
|
||||
|
||||
if (!*_usePreferred) {
|
||||
// we only consider messages targeted at the preferred handler
|
||||
// only consider messages targeted at the preferred handler
|
||||
cookie.message = NULL;
|
||||
return true;
|
||||
}
|
||||
@ -2964,6 +2965,60 @@ BWindow::_SanitizeMessage(BMessage* message, BHandler* target, bool usePreferred
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
This is called by BView::GetMouse() when a B_MOUSE_MOVED message
|
||||
is removed from the queue.
|
||||
It allows the window to update the last mouse moved view, and
|
||||
let it decide if this message should be kept. It will also remove
|
||||
the message from the queue.
|
||||
You need to hold the message queue lock when calling this method!
|
||||
|
||||
\return true if this message can be used to get the mouse data from,
|
||||
\return false if this is not meant for the public.
|
||||
*/
|
||||
bool
|
||||
BWindow::_StealMouseMessage(BMessage* message, bool& deleteMessage)
|
||||
{
|
||||
BMessage::Private messagePrivate(fLastMessage);
|
||||
if (!messagePrivate.UsePreferredTarget()) {
|
||||
// this message is targeted at a specific handler, so we should
|
||||
// not steal it
|
||||
return false;
|
||||
}
|
||||
|
||||
int32 token;
|
||||
if (message->FindInt32("_token", 0, &token) == B_OK) {
|
||||
// This message has other targets, so we can't remove it;
|
||||
// just prevent it from being sent to the preferred handler
|
||||
// again (if it should have gotten it at all).
|
||||
bool feedFocus;
|
||||
if (message->FindBool("_feed_focus", &feedFocus) == B_OK && feedFocus)
|
||||
return false;
|
||||
|
||||
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
|
||||
BView* viewUnderMouse = NULL;
|
||||
int32 token;
|
||||
if (message->FindInt32("_view_token", &token) == B_OK)
|
||||
viewUnderMouse = _FindView(token);
|
||||
|
||||
fLastMouseMovedView = viewUnderMouse;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
Handles keyboard input before it gets forwarded to the target handler.
|
||||
This includes shortcut evaluation, keyboard navigation, etc.
|
||||
|
Loading…
Reference in New Issue
Block a user