app_server: reworked SetFocusWindow() logic a bit.
* The normal mouse mode now only uses the window that had focus last if that window is one that does not support to be the front window (such as the desktop). * This should keep the logic of r41264 without the drawbacks (see #7280 for more information). * Added _WindowCanHaveFocus() method. * This should fix #7630.
This commit is contained in:
+42
-28
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2011, Haiku.
|
||||
* Copyright 2001-2013, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -1017,7 +1017,7 @@ Desktop::RemoveWorkspacesView(WorkspacesView* view)
|
||||
void
|
||||
Desktop::SelectWindow(Window* window)
|
||||
{
|
||||
if (fSettings->MouseMode() == B_CLICK_TO_FOCUS_MOUSE) {
|
||||
if (fSettings->ClickToFocusMouse()) {
|
||||
// Only bring the window to front when it is not the window under the
|
||||
// mouse pointer. This should result in sensible behaviour.
|
||||
if (window != fWindowUnderMouse
|
||||
@@ -1201,9 +1201,9 @@ Desktop::SendWindowBehind(Window* window, Window* behindOf, bool sendStack)
|
||||
}
|
||||
|
||||
_UpdateFronts();
|
||||
if (fSettings->MouseMode() == B_FOCUS_FOLLOWS_MOUSE)
|
||||
if (fSettings->FocusFollowsMouse())
|
||||
SetFocusWindow(WindowAt(fLastMousePosition));
|
||||
else if (fSettings->MouseMode() == B_NORMAL_MOUSE)
|
||||
else if (fSettings->NormalMouse())
|
||||
SetFocusWindow(NULL);
|
||||
|
||||
bool sendFakeMouseMoved = false;
|
||||
@@ -1868,24 +1868,24 @@ Desktop::KeyboardEventTarget()
|
||||
is any window at all, that is.
|
||||
*/
|
||||
void
|
||||
Desktop::SetFocusWindow(Window* focus)
|
||||
Desktop::SetFocusWindow(Window* nextFocus)
|
||||
{
|
||||
if (!LockAllWindows())
|
||||
return;
|
||||
|
||||
// test for B_LOCK_WINDOW_FOCUS
|
||||
if (fLockedFocusWindow && focus != fLockedFocusWindow) {
|
||||
if (fLockedFocusWindow && nextFocus != fLockedFocusWindow) {
|
||||
UnlockAllWindows();
|
||||
return;
|
||||
}
|
||||
|
||||
bool hasModal = _WindowHasModal(focus);
|
||||
bool hasModal = _WindowHasModal(nextFocus);
|
||||
bool hasWindowScreen = false;
|
||||
|
||||
if (!hasModal && focus != NULL) {
|
||||
if (!hasModal && nextFocus != NULL) {
|
||||
// Check whether or not a window screen is in front of the window
|
||||
// (if it has a modal, the right thing is done, anyway)
|
||||
Window* window = focus;
|
||||
Window* window = nextFocus;
|
||||
while (true) {
|
||||
window = window->NextWindow(fCurrentWorkspace);
|
||||
if (window == NULL || window->Feel() == kWindowScreenFeel)
|
||||
@@ -1895,35 +1895,36 @@ Desktop::SetFocusWindow(Window* focus)
|
||||
hasWindowScreen = true;
|
||||
}
|
||||
|
||||
if (focus == fFocus && focus != NULL && !focus->IsHidden()
|
||||
&& (focus->Flags() & B_AVOID_FOCUS) == 0
|
||||
if (nextFocus == fFocus && nextFocus != NULL && !nextFocus->IsHidden()
|
||||
&& (nextFocus->Flags() & B_AVOID_FOCUS) == 0
|
||||
&& !hasModal && !hasWindowScreen) {
|
||||
// the window that is supposed to get focus already has focus
|
||||
UnlockAllWindows();
|
||||
return;
|
||||
}
|
||||
|
||||
uint32 list = /*fCurrentWorkspace;
|
||||
if (fSettings->FocusFollowsMouse())
|
||||
list = */kFocusList;
|
||||
uint32 list = fCurrentWorkspace;
|
||||
if (!fSettings->NormalMouse())
|
||||
list = kFocusList;
|
||||
|
||||
if (focus == NULL || hasModal || hasWindowScreen) {
|
||||
/*if (!fSettings->FocusFollowsMouse())
|
||||
focus = CurrentWindows().LastWindow();
|
||||
else*/
|
||||
focus = fFocusList.LastWindow();
|
||||
if (nextFocus == NULL || hasModal || hasWindowScreen) {
|
||||
nextFocus = _Windows(list).LastWindow();
|
||||
|
||||
if (fSettings->NormalMouse()) {
|
||||
// If the last window having focus is a window that cannot make it
|
||||
// to the front, we use that as the next focus
|
||||
Window* lastFocus = fFocusList.LastWindow();
|
||||
if (!lastFocus->SupportsFront() && _WindowCanHaveFocus(lastFocus))
|
||||
nextFocus = lastFocus;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure no window is chosen that doesn't want focus or cannot have it
|
||||
while (focus != NULL
|
||||
&& (!focus->InWorkspace(fCurrentWorkspace)
|
||||
|| (focus->Flags() & B_AVOID_FOCUS) != 0
|
||||
|| _WindowHasModal(focus)
|
||||
|| focus->IsHidden())) {
|
||||
focus = focus->PreviousWindow(list);
|
||||
while (nextFocus != NULL && !_WindowCanHaveFocus(nextFocus)) {
|
||||
nextFocus = nextFocus->PreviousWindow(list);
|
||||
}
|
||||
|
||||
if (fFocus == focus) {
|
||||
if (fFocus == nextFocus) {
|
||||
// turns out the window that is supposed to get focus now already has it
|
||||
UnlockAllWindows();
|
||||
return;
|
||||
@@ -1937,7 +1938,7 @@ Desktop::SetFocusWindow(Window* focus)
|
||||
oldActiveApp = fFocus->ServerWindow()->App()->ClientTeam();
|
||||
}
|
||||
|
||||
fFocus = focus;
|
||||
fFocus = nextFocus;
|
||||
|
||||
if (fFocus != NULL) {
|
||||
fFocus->SetFocus(true);
|
||||
@@ -2811,7 +2812,7 @@ Desktop::_UpdateFronts(bool updateFloating)
|
||||
|
||||
|
||||
bool
|
||||
Desktop::_WindowHasModal(Window* window)
|
||||
Desktop::_WindowHasModal(Window* window) const
|
||||
{
|
||||
if (window == NULL)
|
||||
return false;
|
||||
@@ -2830,6 +2831,19 @@ Desktop::_WindowHasModal(Window* window)
|
||||
}
|
||||
|
||||
|
||||
/*! Determines whether or not the specified \a window can have focus at all.
|
||||
*/
|
||||
bool
|
||||
Desktop::_WindowCanHaveFocus(Window* window) const
|
||||
{
|
||||
return window != NULL
|
||||
&& window->InWorkspace(fCurrentWorkspace)
|
||||
&& (window->Flags() & B_AVOID_FOCUS) == 0
|
||||
&& !_WindowHasModal(window)
|
||||
&& !window->IsHidden();
|
||||
}
|
||||
|
||||
|
||||
/*! You must at least hold a single window lock when calling this method.
|
||||
*/
|
||||
void
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2010, Haiku.
|
||||
* Copyright 2001-2013, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -265,7 +265,8 @@ private:
|
||||
void _UpdateBack();
|
||||
void _UpdateFront(bool updateFloating = true);
|
||||
void _UpdateFronts(bool updateFloating = true);
|
||||
bool _WindowHasModal(Window* window);
|
||||
bool _WindowHasModal(Window* window) const;
|
||||
bool _WindowCanHaveFocus(Window* window) const;
|
||||
|
||||
void _WindowChanged(Window* window);
|
||||
void _WindowRemoved(Window* window);
|
||||
|
||||
Reference in New Issue
Block a user