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