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).
This commit is contained in:
Julian Harnath 2013-10-26 16:11:45 +02:00
parent 7f64b301b1
commit 057c8708f2
5 changed files with 42 additions and 28 deletions

View File

@ -369,7 +369,7 @@ private:
BView* fTopView;
BView* fFocus;
BView* fLastMouseMovedView;
BMessageRunner* fIdleMouseRunner;
uint32 _unused1;
BMenuBar* fKeyMenuBar;
BButton* fDefaultButton;
BList fShortcuts;

View File

@ -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<BPrivate::ToolTipWindow*>(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;

View File

@ -22,6 +22,7 @@
#include <TokenSpace.h>
#include <Autolock.h>
#include <ToolTipManager.h>
#include <View.h>
#include <new>
@ -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;

View File

@ -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;
}

View File

@ -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);