Implemented respecting B_LOCK_WINDOW_FOCUS that a view can set using

SetMouseEventMask() from within it's mouse hooks. Among other things,
scroll bars won't stop scrolling in FFM mode now if you accidentally
leave the window with the mouse, something which is very likely.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28481 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus
2008-11-03 19:34:13 +00:00
parent 6198dc0e17
commit 21b40edd75
3 changed files with 38 additions and 5 deletions
+33 -4
View File
@@ -262,7 +262,7 @@ MouseFilter::Filter(BMessage* message, EventTarget** _target, int32* _viewToken,
*_target = NULL;
}
fDesktop->SetLastMouseState(where, buttons);
fDesktop->SetLastMouseState(where, buttons, window);
fDesktop->UnlockAllWindows();
@@ -311,6 +311,7 @@ Desktop::Desktop(uid_t userID)
fMouseEventWindow(NULL),
fWindowUnderMouse(NULL),
fLockedFocusWindow(NULL),
fViewUnderMouse(B_NULL_TOKEN),
fLastMousePosition(B_ORIGIN),
fLastMouseButtons(0),
@@ -750,10 +751,17 @@ Desktop::Cursor() const
void
Desktop::SetLastMouseState(const BPoint& position, int32 buttons)
Desktop::SetLastMouseState(const BPoint& position, int32 buttons,
Window* windowUnderMouse)
{
// The all-window-lock is write-locked.
fLastMousePosition = position;
fLastMouseButtons = buttons;
if (fLastMouseButtons == 0 && fLockedFocusWindow) {
fLockedFocusWindow = NULL;
SetFocusWindow(windowUnderMouse);
}
}
@@ -1375,9 +1383,13 @@ Desktop::SetFocusWindow(Window* focus)
if (!LockAllWindows())
return;
bool hasModal = _WindowHasModal(focus);
// test for B_LOCK_WINDOW_FOCUS
if (fLockedFocusWindow && focus != fLockedFocusWindow) {
UnlockAllWindows();
return;
}
// TODO: test for B_LOCK_WINDOW_FOCUS
bool hasModal = _WindowHasModal(focus);
if (focus == fFocus && focus != NULL && !focus->IsHidden()
&& (focus->Flags() & B_AVOID_FOCUS) == 0 && !hasModal) {
@@ -1461,6 +1473,23 @@ Desktop::SetFocusWindow(Window* focus)
}
void
Desktop::SetFocusLocked(const Window* window)
{
AutoWriteLocker _(fWindowLock);
if (window != NULL) {
// Don't allow this to be set when no mouse buttons
// are pressed. (BView::SetMouseEventMask() should only be called
// from mouse hooks.)
if (fLastMouseButtons == 0)
return;
}
fLockedFocusWindow = window;
}
void
Desktop::_BringWindowsToFront(WindowList& windows, int32 list,
bool wereVisible)
+3 -1
View File
@@ -82,7 +82,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
void SetCursor(ServerCursor* cursor);
ServerCursorReference Cursor() const;
void SetLastMouseState(const BPoint& position,
int32 buttons);
int32 buttons, Window* windowUnderMouse);
// for use by the mouse filter only
// both mouse position calls require
// the Desktop object to be locked
@@ -164,6 +164,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
void SetFocusWindow(Window* window = NULL);
EventTarget* KeyboardEventTarget();
void SetFocusLocked(const Window* window);
Window* FindWindowByClientToken(int32 token,
team_id teamID);
@@ -303,6 +304,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
Window* fMouseEventWindow;
const Window* fWindowUnderMouse;
const Window* fLockedFocusWindow;
int32 fViewUnderMouse;
BPoint fLastMousePosition;
int32 fLastMouseButtons;
+2
View File
@@ -1343,6 +1343,8 @@ fDesktop->LockSingleWindow();
fDesktop->UnlockSingleWindow();
// TODO: possible deadlock
if (eventMask != 0 || options != 0) {
if (options & B_LOCK_WINDOW_FOCUS)
fDesktop->SetFocusLocked(fWindow);
fDesktop->EventDispatcher().AddTemporaryListener(EventTarget(),
fCurrentView->Token(), eventMask, options);
} else {