Implemented B_NO_POINTER_HISTORY. Window moving/resizing uses this mechanism
as well now, and makes quite a difference in Qemu. Not tested for standard BViews, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15907 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -53,7 +53,7 @@ class KeyboardFilter : public EventFilter {
|
||||
KeyboardFilter(Desktop* desktop);
|
||||
|
||||
virtual filter_result Filter(BMessage* message, EventTarget** _target,
|
||||
int32* _viewToken);
|
||||
int32* _viewToken, BMessage* latestMouseMoved);
|
||||
|
||||
private:
|
||||
Desktop* fDesktop;
|
||||
@@ -66,7 +66,7 @@ class MouseFilter : public EventFilter {
|
||||
MouseFilter(Desktop* desktop);
|
||||
|
||||
virtual filter_result Filter(BMessage* message, EventTarget** _target,
|
||||
int32* _viewToken);
|
||||
int32* _viewToken, BMessage* latestMouseMoved);
|
||||
|
||||
private:
|
||||
Desktop* fDesktop;
|
||||
@@ -87,7 +87,7 @@ KeyboardFilter::KeyboardFilter(Desktop* desktop)
|
||||
|
||||
filter_result
|
||||
KeyboardFilter::Filter(BMessage* message, EventTarget** _target,
|
||||
int32* /*_viewToken*/)
|
||||
int32* /*_viewToken*/, BMessage* /*latestMouseMoved*/)
|
||||
{
|
||||
int32 key;
|
||||
int32 modifiers;
|
||||
@@ -190,7 +190,8 @@ MouseFilter::MouseFilter(Desktop* desktop)
|
||||
|
||||
|
||||
filter_result
|
||||
MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken)
|
||||
MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken,
|
||||
BMessage* latestMouseMoved)
|
||||
{
|
||||
BPoint where;
|
||||
if (message->FindPoint("where", &where) != B_OK)
|
||||
@@ -216,7 +217,8 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken)
|
||||
break;
|
||||
|
||||
case B_MOUSE_MOVED:
|
||||
window->MouseMoved(message, where, _viewToken);
|
||||
window->MouseMoved(message, where, _viewToken,
|
||||
latestMouseMoved == NULL || latestMouseMoved == message);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ struct event_listener {
|
||||
uint32 temporary_options;
|
||||
|
||||
uint32 EffectiveEventMask() const { return event_mask | temporary_event_mask; }
|
||||
uint32 EffectiveOptions() const { return options | temporary_options; }
|
||||
};
|
||||
|
||||
static const char* kTokenName = "_token";
|
||||
@@ -220,6 +221,7 @@ EventDispatcher::EventDispatcher()
|
||||
fMouseFilter(NULL),
|
||||
fKeyboardFilter(NULL),
|
||||
fTargets(10),
|
||||
fNextLatestMouseMoved(NULL),
|
||||
fCursorLock("cursor loop lock"),
|
||||
fHWInterface(NULL)
|
||||
{
|
||||
@@ -550,25 +552,36 @@ EventDispatcher::_SendMessage(BMessenger& messenger, BMessage* message,
|
||||
|
||||
|
||||
bool
|
||||
EventDispatcher::_AddTokens(BMessage* message, EventTarget* target, uint32 eventMask)
|
||||
EventDispatcher::_AddTokens(BMessage* message, EventTarget* target,
|
||||
uint32 eventMask, BMessage* nextMouseMoved, int32* _viewToken)
|
||||
{
|
||||
_RemoveTokens(message);
|
||||
|
||||
int32 count = target->CountListeners();
|
||||
for (int32 i = count; i-- > 0;) {
|
||||
int32 added = 0;
|
||||
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
event_listener* listener = target->ListenerAt(i);
|
||||
if ((listener->EffectiveEventMask() & eventMask) == 0) {
|
||||
count--;
|
||||
if ((listener->EffectiveEventMask() & eventMask) == 0)
|
||||
continue;
|
||||
|
||||
if (nextMouseMoved != NULL
|
||||
&& (listener->EffectiveOptions() & B_NO_POINTER_HISTORY) != 0
|
||||
&& message != nextMouseMoved) {
|
||||
if (listener->token == *_viewToken) {
|
||||
// focus view doesn't want to get pointer history
|
||||
*_viewToken = B_NULL_TOKEN;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ETRACE((" add token %ld\n", listener->token));
|
||||
|
||||
if (message->AddInt32(kTokenName, listener->token) != B_OK)
|
||||
count--;
|
||||
if (message->AddInt32(kTokenName, listener->token) == B_OK)
|
||||
added++;
|
||||
}
|
||||
|
||||
return count != 0;
|
||||
return added != 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -664,14 +677,17 @@ EventDispatcher::_EventLoop()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: this drops older mouse events, but should probably work
|
||||
// a bit different (ie. don't drop the last event)
|
||||
bigtime_t eventTime;
|
||||
if (event->FindInt64("when", &eventTime) == B_OK) {
|
||||
if (system_time() - eventTime > 25000) {
|
||||
// the server itself lags behind too much
|
||||
// -> drop the event
|
||||
break;
|
||||
// This is for B_NO_POINTER_HISTORY - we always want the
|
||||
// latest mouse moved event in the queue only
|
||||
if (fNextLatestMouseMoved == NULL)
|
||||
fNextLatestMouseMoved = fStream->PeekLatestMouseMoved();
|
||||
else if (fNextLatestMouseMoved != event) {
|
||||
// Drop older mouse moved messages if the server is lagging too
|
||||
// much (if the message is older than 100 msecs)
|
||||
bigtime_t eventTime;
|
||||
if (event->FindInt64("when", &eventTime) == B_OK) {
|
||||
if (system_time() - eventTime > 100000)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -691,7 +707,8 @@ EventDispatcher::_EventLoop()
|
||||
|
||||
EventTarget* mouseTarget = fPreviousMouseTarget;
|
||||
int32 viewToken = B_NULL_TOKEN;
|
||||
if (fMouseFilter->Filter(event, &mouseTarget, &viewToken) == B_SKIP_MESSAGE) {
|
||||
if (fMouseFilter->Filter(event, &mouseTarget, &viewToken,
|
||||
fNextLatestMouseMoved) == B_SKIP_MESSAGE) {
|
||||
// this is a work-around if the wrong B_MOUSE_UP
|
||||
// event is filtered out
|
||||
if (event->what == B_MOUSE_UP) {
|
||||
@@ -728,11 +745,21 @@ EventDispatcher::_EventLoop()
|
||||
current = fPreviousMouseTarget = mouseTarget;
|
||||
|
||||
if (current != NULL) {
|
||||
addedTokens |= _AddTokens(event, current, B_POINTER_EVENTS);
|
||||
int32 focusView = viewToken;
|
||||
addedTokens |= _AddTokens(event, current, B_POINTER_EVENTS,
|
||||
fNextLatestMouseMoved, &focusView);
|
||||
|
||||
bool noPointerHistoryFocus = focusView != viewToken;
|
||||
|
||||
if (viewToken != B_NULL_TOKEN)
|
||||
event->AddInt32("_view_token", viewToken);
|
||||
if (addedTokens)
|
||||
|
||||
if (addedTokens && !noPointerHistoryFocus)
|
||||
_SetFeedFocus(event);
|
||||
else if (noPointerHistoryFocus) {
|
||||
// no tokens were added or the focus shouldn't get a mouse moved
|
||||
break;
|
||||
}
|
||||
|
||||
_SendMessage(current->Messenger(), event, event->what == B_MOUSE_MOVED
|
||||
? kMouseMovedImportance : kStandardImportance);
|
||||
@@ -801,7 +828,8 @@ EventDispatcher::_EventLoop()
|
||||
|
||||
// don't send the message if there are no tokens for this event
|
||||
if (!_AddTokens(event, target,
|
||||
keyboardEvent ? B_KEYBOARD_EVENTS : B_POINTER_EVENTS))
|
||||
keyboardEvent ? B_KEYBOARD_EVENTS : B_POINTER_EVENTS,
|
||||
event->what == B_MOUSE_MOVED ? fNextLatestMouseMoved : NULL))
|
||||
continue;
|
||||
|
||||
if (!_SendMessage(target->Messenger(), event, event->what == B_MOUSE_MOVED
|
||||
@@ -819,6 +847,8 @@ EventDispatcher::_EventLoop()
|
||||
}
|
||||
}
|
||||
|
||||
if (fNextLatestMouseMoved == event)
|
||||
fNextLatestMouseMoved = NULL;
|
||||
delete event;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ class EventTarget {
|
||||
class EventFilter {
|
||||
public:
|
||||
virtual filter_result Filter(BMessage* event, EventTarget** _target,
|
||||
int32* _viewToken = NULL) = 0;
|
||||
int32* _viewToken = NULL, BMessage* latestMouseMoved = NULL) = 0;
|
||||
};
|
||||
|
||||
class EventDispatcher : public BLocker {
|
||||
@@ -96,7 +96,8 @@ class EventDispatcher : public BLocker {
|
||||
|
||||
bool _SendMessage(BMessenger& messenger, BMessage* message, float importance);
|
||||
|
||||
bool _AddTokens(BMessage* message, EventTarget* target, uint32 eventMask);
|
||||
bool _AddTokens(BMessage* message, EventTarget* target, uint32 eventMask,
|
||||
BMessage* nextMouseMoved = NULL, int32* _viewToken = NULL);
|
||||
void _RemoveTokens(BMessage* message);
|
||||
void _SetFeedFocus(BMessage* message);
|
||||
void _UnsetFeedFocus(BMessage* message);
|
||||
@@ -130,6 +131,7 @@ class EventDispatcher : public BLocker {
|
||||
|
||||
BObjectList<EventTarget> fTargets;
|
||||
|
||||
BMessage* fNextLatestMouseMoved;
|
||||
BPoint fLastCursorPosition;
|
||||
int32 fLastButtons;
|
||||
|
||||
|
||||
@@ -49,7 +49,8 @@ InputServerStream::InputServerStream(BMessenger& messenger)
|
||||
:
|
||||
fInputServer(messenger),
|
||||
fPort(-1),
|
||||
fQuitting(false)
|
||||
fQuitting(false),
|
||||
fLatestMouseMoved(NULL)
|
||||
{
|
||||
BMessage message(IS_ACQUIRE_INPUT);
|
||||
fCursorArea = create_area("shared cursor", (void **)&fCursorBuffer, B_ANY_ADDRESS,
|
||||
@@ -72,7 +73,8 @@ InputServerStream::InputServerStream(BMessenger& messenger)
|
||||
InputServerStream::InputServerStream()
|
||||
:
|
||||
fQuitting(false),
|
||||
fCursorSemaphore(-1)
|
||||
fCursorSemaphore(-1),
|
||||
fLatestMouseMoved(NULL)
|
||||
{
|
||||
fPort = find_port(SERVER_INPUT_PORT);
|
||||
}
|
||||
@@ -122,9 +124,12 @@ InputServerStream::GetNextEvent(BMessage** _event)
|
||||
// wait for new events
|
||||
BMessage* event;
|
||||
status_t status = _MessageFromPort(&event);
|
||||
if (status == B_OK)
|
||||
if (status == B_OK) {
|
||||
if (event->what == B_MOUSE_MOVED)
|
||||
fLatestMouseMoved = event;
|
||||
|
||||
fEvents.AddMessage(event);
|
||||
else if (status == B_BAD_PORT_ID) {
|
||||
} else if (status == B_BAD_PORT_ID) {
|
||||
// our port got deleted - the input_server must have died
|
||||
fPort = -1;
|
||||
return false;
|
||||
@@ -134,8 +139,11 @@ InputServerStream::GetNextEvent(BMessage** _event)
|
||||
if (count > 0) {
|
||||
// empty port queue completely while we're at it
|
||||
for (int32 i = 0; i < count; i++) {
|
||||
if (_MessageFromPort(&event, 0) == B_OK)
|
||||
if (_MessageFromPort(&event, 0) == B_OK) {
|
||||
if (event->what == B_MOUSE_MOVED)
|
||||
fLatestMouseMoved = event;
|
||||
fEvents.AddMessage(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,6 +191,13 @@ InputServerStream::GetNextCursorPosition(BPoint &where)
|
||||
}
|
||||
|
||||
|
||||
BMessage*
|
||||
InputServerStream::PeekLatestMouseMoved()
|
||||
{
|
||||
return fLatestMouseMoved;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
InputServerStream::_MessageFromPort(BMessage** _message, bigtime_t timeout)
|
||||
{
|
||||
|
||||
@@ -31,6 +31,8 @@ class EventStream {
|
||||
|
||||
virtual bool GetNextEvent(BMessage** _event) = 0;
|
||||
virtual bool GetNextCursorPosition(BPoint& where);
|
||||
|
||||
virtual BMessage* PeekLatestMouseMoved() = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -53,6 +55,8 @@ class InputServerStream : public EventStream {
|
||||
virtual bool GetNextEvent(BMessage** _event);
|
||||
virtual bool GetNextCursorPosition(BPoint& where);
|
||||
|
||||
virtual BMessage* PeekLatestMouseMoved();
|
||||
|
||||
private:
|
||||
status_t _MessageFromPort(BMessage** _message,
|
||||
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||
@@ -64,6 +68,7 @@ class InputServerStream : public EventStream {
|
||||
sem_id fCursorSemaphore;
|
||||
area_id fCursorArea;
|
||||
shared_cursor* fCursorBuffer;
|
||||
BMessage* fLatestMouseMoved;
|
||||
};
|
||||
|
||||
#endif /* EVENT_STREAM_H */
|
||||
|
||||
@@ -905,10 +905,17 @@ WindowLayer::MouseUp(BMessage* msg, BPoint where, int32* _viewToken)
|
||||
|
||||
|
||||
void
|
||||
WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken)
|
||||
WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken,
|
||||
bool isLatestMouseMoved)
|
||||
{
|
||||
if (fDecorator) {
|
||||
if (ViewLayer* view = ViewAt(where))
|
||||
*_viewToken = view->Token();
|
||||
|
||||
// ignore pointer history
|
||||
if (!isLatestMouseMoved)
|
||||
return;
|
||||
|
||||
if (fDecorator) {
|
||||
BRegion visibleBorder;
|
||||
GetBorderRegion(&visibleBorder);
|
||||
visibleBorder.IntersectWith(&VisibleRegion());
|
||||
@@ -971,9 +978,6 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken)
|
||||
|
||||
if (desktopSettings.MouseMode() != B_NORMAL_MOUSE && !IsFocus())
|
||||
fDesktop->SetFocusWindow(this);
|
||||
|
||||
if (ViewLayer* view = ViewAt(where))
|
||||
*_viewToken = view->Token();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -118,7 +118,8 @@ class WindowLayer {
|
||||
|
||||
void MouseDown(BMessage* message, BPoint where, int32* _viewToken);
|
||||
void MouseUp(BMessage* message, BPoint where, int32* _viewToken);
|
||||
void MouseMoved(BMessage* message, BPoint where, int32* _viewToken);
|
||||
void MouseMoved(BMessage* message, BPoint where, int32* _viewToken,
|
||||
bool isLatestMouseMoved);
|
||||
|
||||
// some hooks to inform the client window
|
||||
// TODO: move this to ServerWindow maybe?
|
||||
|
||||
Reference in New Issue
Block a user