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:
Axel Dörfler
2006-01-11 12:25:06 +00:00
parent f9f970d98c
commit 92b292f540
7 changed files with 96 additions and 37 deletions
+7 -5
View File
@@ -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;
}
+49 -19
View File
@@ -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;
}
}
+4 -2
View File
@@ -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;
+20 -5
View File
@@ -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)
{
+5
View File
@@ -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 */
+9 -5
View File
@@ -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();
}
+2 -1
View File
@@ -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?