From 70b8b182bde2b5650d0dfe50f5f3df60009e5f9a Mon Sep 17 00:00:00 2001
From: Julian Harnath <github@orangejua.de>
Date: Mon, 7 Oct 2013 12:01:55 +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 | 28 +++++++++++++++++++++++-----
src/servers/app/EventStream.cpp | 23 ++++++++++++++---------
src/servers/app/EventStream.h | 6 ++++--
5 files changed, 43 insertions(+), 29 deletions(-)
diff --git a/headers/os/interface/Window.h b/headers/os/interface/Window.h
index 9853bb5..bc8eb16 100644
a
|
b
|
private:
|
369 | 369 | BView* fTopView; |
370 | 370 | BView* fFocus; |
371 | 371 | BView* fLastMouseMovedView; |
372 | | BMessageRunner* fIdleMouseRunner; |
| 372 | uint32 _unused1; |
373 | 373 | BMenuBar* fKeyMenuBar; |
374 | 374 | BButton* fDefaultButton; |
375 | 375 | BList fShortcuts; |
diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp
index b609353..cfbd4de 100644
a
|
b
|
FrameMoved(origin);
|
1315 | 1315 | message->FindPoint("be:view_where", &where); |
1316 | 1316 | message->FindInt32("buttons", (int32*)&buttons); |
1317 | 1317 | |
1318 | | delete fIdleMouseRunner; |
1319 | | |
1320 | | if (transit != B_EXITED_VIEW && transit != B_OUTSIDE_VIEW) { |
1321 | | // Start new idle runner |
1322 | | BMessage idle(B_MOUSE_IDLE); |
1323 | | idle.AddPoint("be:view_where", where); |
1324 | | fIdleMouseRunner = new BMessageRunner( |
1325 | | BMessenger(NULL, this), &idle, |
1326 | | BToolTipManager::Manager()->ShowDelay(), 1); |
1327 | | } else { |
1328 | | fIdleMouseRunner = NULL; |
| 1318 | if (transit == B_EXITED_VIEW || transit == B_OUTSIDE_VIEW) { |
1329 | 1319 | if (dynamic_cast<BPrivate::ToolTipWindow*>(this) == NULL) |
1330 | 1320 | BToolTipManager::Manager()->HideTip(); |
1331 | 1321 | } |
… |
… |
BWindow::_InitData(BRect frame, const char* title, window_look look,
|
2794 | 2784 | fTopView = NULL; |
2795 | 2785 | fFocus = NULL; |
2796 | 2786 | fLastMouseMovedView = NULL; |
2797 | | fIdleMouseRunner = NULL; |
2798 | 2787 | fKeyMenuBar = NULL; |
2799 | 2788 | fDefaultButton = NULL; |
2800 | 2789 | |
diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp
index 1cddaf6..9492101 100644
a
|
b
|
|
22 | 22 | #include <TokenSpace.h> |
23 | 23 | |
24 | 24 | #include <Autolock.h> |
| 25 | #include <ToolTipManager.h> |
25 | 26 | #include <View.h> |
26 | 27 | |
27 | 28 | #include <new> |
… |
… |
EventDispatcher::_EventLoop()
|
817 | 818 | } |
818 | 819 | case B_MOUSE_DOWN: |
819 | 820 | case B_MOUSE_UP: |
| 821 | case B_MOUSE_IDLE: |
820 | 822 | { |
821 | 823 | #ifdef TRACE_EVENTS |
822 | 824 | if (event->what != B_MOUSE_MOVED) |
… |
… |
void
|
1002 | 1004 | EventDispatcher::_CursorLoop() |
1003 | 1005 | { |
1004 | 1006 | BPoint where; |
1005 | | while (fStream->GetNextCursorPosition(where)) { |
1006 | | BAutolock _(fCursorLock); |
1007 | | |
1008 | | if (fHWInterface != NULL) |
1009 | | fHWInterface->MoveCursorTo(where.x, where.y); |
| 1007 | const bigtime_t toolTipDelay = BToolTipManager::Manager()->ShowDelay(); |
| 1008 | bool mouseIdleSent = true; |
| 1009 | status_t status = B_OK; |
| 1010 | |
| 1011 | while (status != B_ERROR) { |
| 1012 | const bigtime_t timeout = mouseIdleSent ? |
| 1013 | B_INFINITE_TIMEOUT : toolTipDelay; |
| 1014 | status = fStream->GetNextCursorPosition(where, timeout); |
| 1015 | |
| 1016 | if (status == B_OK) { |
| 1017 | mouseIdleSent = false; |
| 1018 | BAutolock _(fCursorLock); |
| 1019 | |
| 1020 | if (fHWInterface != NULL) |
| 1021 | fHWInterface->MoveCursorTo(where.x, where.y); |
| 1022 | } else if (status == B_TIMED_OUT) { |
| 1023 | mouseIdleSent = true; |
| 1024 | BMessage* mouseIdle = new BMessage(B_MOUSE_IDLE); |
| 1025 | mouseIdle->AddPoint("be:view_where", fLastCursorPosition); |
| 1026 | fStream->InsertEvent(mouseIdle); |
| 1027 | } |
1010 | 1028 | } |
1011 | 1029 | |
1012 | 1030 | fCursorThread = -1; |
diff --git a/src/servers/app/EventStream.cpp b/src/servers/app/EventStream.cpp
index 803467b..6eb6352 100644
a
|
b
|
EventStream::SupportsCursorThread() const
|
35 | 35 | } |
36 | 36 | |
37 | 37 | |
38 | | bool |
39 | | EventStream::GetNextCursorPosition(BPoint& where) |
| 38 | status_t |
| 39 | EventStream::GetNextCursorPosition(BPoint& where, bigtime_t timeout) |
40 | 40 | { |
41 | | return false; |
| 41 | return B_ERROR; |
42 | 42 | } |
43 | 43 | |
44 | 44 | |
… |
… |
InputServerStream::GetNextEvent(BMessage** _event)
|
155 | 155 | } |
156 | 156 | |
157 | 157 | |
158 | | bool |
159 | | InputServerStream::GetNextCursorPosition(BPoint &where) |
| 158 | status_t |
| 159 | InputServerStream::GetNextCursorPosition(BPoint &where, bigtime_t timeout) |
160 | 160 | { |
161 | 161 | status_t status; |
| 162 | |
162 | 163 | do { |
163 | | status = acquire_sem(fCursorSemaphore); |
| 164 | status = acquire_sem_etc(fCursorSemaphore, 1, B_RELATIVE_TIMEOUT, |
| 165 | timeout); |
164 | 166 | } while (status == B_INTERRUPTED); |
165 | 167 | |
| 168 | if (status == B_TIMED_OUT) |
| 169 | return status; |
| 170 | |
166 | 171 | if (status == B_BAD_SEM_ID) { |
167 | 172 | // the semaphore is no longer valid - the input_server must have died |
168 | 173 | fCursorSemaphore = -1; |
169 | | return false; |
| 174 | return B_ERROR; |
170 | 175 | } |
171 | 176 | |
172 | 177 | #ifdef HAIKU_TARGET_PLATFORM_HAIKU |
… |
… |
InputServerStream::GetNextCursorPosition(BPoint &where)
|
184 | 189 | |
185 | 190 | if (fQuitting) { |
186 | 191 | fQuitting = false; |
187 | | return false; |
| 192 | return B_ERROR; |
188 | 193 | } |
189 | 194 | |
190 | | return true; |
| 195 | return B_OK; |
191 | 196 | } |
192 | 197 | |
193 | 198 | |
diff --git a/src/servers/app/EventStream.h b/src/servers/app/EventStream.h
index 6063b2c..23a33b9 100644
a
|
b
|
class EventStream {
|
30 | 30 | virtual void UpdateScreenBounds(BRect bounds) = 0; |
31 | 31 | |
32 | 32 | virtual bool GetNextEvent(BMessage** _event) = 0; |
33 | | virtual bool GetNextCursorPosition(BPoint& where); |
| 33 | virtual status_t GetNextCursorPosition(BPoint& where, |
| 34 | bigtime_t timeout = B_INFINITE_TIMEOUT); |
34 | 35 | |
35 | 36 | virtual status_t InsertEvent(BMessage* event) = 0; |
36 | 37 | |
… |
… |
class InputServerStream : public EventStream {
|
55 | 56 | virtual void UpdateScreenBounds(BRect bounds); |
56 | 57 | |
57 | 58 | virtual bool GetNextEvent(BMessage** _event); |
58 | | virtual bool GetNextCursorPosition(BPoint& where); |
| 59 | virtual status_t GetNextCursorPosition(BPoint& where, |
| 60 | bigtime_t timeout = B_INFINITE_TIMEOUT); |
59 | 61 | |
60 | 62 | virtual status_t InsertEvent(BMessage* event); |
61 | 63 | |