From 057c8708f216514c6874b7c49f6ca170760b3cf0 Mon Sep 17 00:00:00 2001 From: Julian Harnath Date: Sat, 26 Oct 2013 16:11:45 +0200 Subject: [PATCH] Move B_MOUSE_IDLE generation to app_server. * BWindow used to generate the B_MOUSE_IDLE events by sending a delayed message with a one-shot BMessageRunner to itself. Every creation and deletion of BMessageRunners causes synchronous messaging between the application under the mouse cursor and the registrar. This creates large amounts of calls to set_port_owner() in the kernel whenever moving the mouse. * Now, B_MOUSE_IDLE is sent by the cursor loop inside the app_server instead. When the mouse wasn't moved for the tooltip delay time, it inserts a B_MOUSE_IDLE message into the event stream. * The tooltip delay thus becomes a system-wide constant and is not configurable per-application anymore (no code currently in the Haiku repo makes use of that anyhow). --- headers/os/interface/Window.h | 2 +- src/kits/interface/Window.cpp | 13 +------------ src/servers/app/EventDispatcher.cpp | 26 ++++++++++++++++++++++---- src/servers/app/EventStream.cpp | 23 ++++++++++++++--------- src/servers/app/EventStream.h | 6 ++++-- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h index 9853bb5b80..bc8eb16f62 100644 --- a/headers/os/interface/Window.h +++ b/headers/os/interface/Window.h @@ -369,7 +369,7 @@ private: BView* fTopView; BView* fFocus; BView* fLastMouseMovedView; - BMessageRunner* fIdleMouseRunner; + uint32 _unused1; BMenuBar* fKeyMenuBar; BButton* fDefaultButton; BList fShortcuts; diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index 0dd6335a7a..b80530c38f 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -1315,17 +1315,7 @@ FrameMoved(origin); message->FindPoint("be:view_where", &where); message->FindInt32("buttons", (int32*)&buttons); - delete fIdleMouseRunner; - - if (transit != B_EXITED_VIEW && transit != B_OUTSIDE_VIEW) { - // Start new idle runner - BMessage idle(B_MOUSE_IDLE); - idle.AddPoint("be:view_where", where); - fIdleMouseRunner = new BMessageRunner( - BMessenger(NULL, this), &idle, - BToolTipManager::Manager()->ShowDelay(), 1); - } else { - fIdleMouseRunner = NULL; + if (transit == B_EXITED_VIEW || transit == B_OUTSIDE_VIEW) { if (dynamic_cast(this) == NULL) BToolTipManager::Manager()->HideTip(); } @@ -2794,7 +2784,6 @@ BWindow::_InitData(BRect frame, const char* title, window_look look, fTopView = NULL; fFocus = NULL; fLastMouseMovedView = NULL; - fIdleMouseRunner = NULL; fKeyMenuBar = NULL; fDefaultButton = NULL; diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 1cddaf637c..9492101e5a 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -22,6 +22,7 @@ #include #include +#include #include #include @@ -817,6 +818,7 @@ EventDispatcher::_EventLoop() } case B_MOUSE_DOWN: case B_MOUSE_UP: + case B_MOUSE_IDLE: { #ifdef TRACE_EVENTS if (event->what != B_MOUSE_MOVED) @@ -1002,11 +1004,27 @@ void EventDispatcher::_CursorLoop() { BPoint where; - while (fStream->GetNextCursorPosition(where)) { - BAutolock _(fCursorLock); + const bigtime_t toolTipDelay = BToolTipManager::Manager()->ShowDelay(); + bool mouseIdleSent = true; + status_t status = B_OK; + + while (status != B_ERROR) { + const bigtime_t timeout = mouseIdleSent ? + B_INFINITE_TIMEOUT : toolTipDelay; + status = fStream->GetNextCursorPosition(where, timeout); + + if (status == B_OK) { + mouseIdleSent = false; + BAutolock _(fCursorLock); - if (fHWInterface != NULL) - fHWInterface->MoveCursorTo(where.x, where.y); + if (fHWInterface != NULL) + fHWInterface->MoveCursorTo(where.x, where.y); + } else if (status == B_TIMED_OUT) { + mouseIdleSent = true; + BMessage* mouseIdle = new BMessage(B_MOUSE_IDLE); + mouseIdle->AddPoint("be:view_where", fLastCursorPosition); + fStream->InsertEvent(mouseIdle); + } } fCursorThread = -1; diff --git a/src/servers/app/EventStream.cpp b/src/servers/app/EventStream.cpp index 803467b1de..6eb6352b9a 100644 --- a/src/servers/app/EventStream.cpp +++ b/src/servers/app/EventStream.cpp @@ -35,10 +35,10 @@ EventStream::SupportsCursorThread() const } -bool -EventStream::GetNextCursorPosition(BPoint& where) +status_t +EventStream::GetNextCursorPosition(BPoint& where, bigtime_t timeout) { - return false; + return B_ERROR; } @@ -155,18 +155,23 @@ InputServerStream::GetNextEvent(BMessage** _event) } -bool -InputServerStream::GetNextCursorPosition(BPoint &where) +status_t +InputServerStream::GetNextCursorPosition(BPoint &where, bigtime_t timeout) { status_t status; + do { - status = acquire_sem(fCursorSemaphore); + status = acquire_sem_etc(fCursorSemaphore, 1, B_RELATIVE_TIMEOUT, + timeout); } while (status == B_INTERRUPTED); + if (status == B_TIMED_OUT) + return status; + if (status == B_BAD_SEM_ID) { // the semaphore is no longer valid - the input_server must have died fCursorSemaphore = -1; - return false; + return B_ERROR; } #ifdef HAIKU_TARGET_PLATFORM_HAIKU @@ -184,10 +189,10 @@ InputServerStream::GetNextCursorPosition(BPoint &where) if (fQuitting) { fQuitting = false; - return false; + return B_ERROR; } - return true; + return B_OK; } diff --git a/src/servers/app/EventStream.h b/src/servers/app/EventStream.h index 6063b2ce29..23a33b9f96 100644 --- a/src/servers/app/EventStream.h +++ b/src/servers/app/EventStream.h @@ -30,7 +30,8 @@ class EventStream { virtual void UpdateScreenBounds(BRect bounds) = 0; virtual bool GetNextEvent(BMessage** _event) = 0; - virtual bool GetNextCursorPosition(BPoint& where); + virtual status_t GetNextCursorPosition(BPoint& where, + bigtime_t timeout = B_INFINITE_TIMEOUT); virtual status_t InsertEvent(BMessage* event) = 0; @@ -55,7 +56,8 @@ class InputServerStream : public EventStream { virtual void UpdateScreenBounds(BRect bounds); virtual bool GetNextEvent(BMessage** _event); - virtual bool GetNextCursorPosition(BPoint& where); + virtual status_t GetNextCursorPosition(BPoint& where, + bigtime_t timeout = B_INFINITE_TIMEOUT); virtual status_t InsertEvent(BMessage* event);