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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user