* Added a separate focus list that will contain all windows in the order

of the last focus.
* When choosing a new focus window, this list is now used to find the
  new focus window instead of just choosing the next window in the
  workspace list.
* With the normal mode mouse, this shouldn't change anything, but with
  focus follows mouse turned on, this will behave much better if you 
  don't actually move the mouse - and it also fixes bug #1886.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24234 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-03-04 12:47:34 +00:00
parent 017fb2f082
commit d01879e5a6
3 changed files with 30 additions and 25 deletions
+25 -22
View File
@@ -316,6 +316,7 @@ Desktop::Desktop(uid_t userID)
fCurrentWorkspace(0), fCurrentWorkspace(0),
fAllWindows(kAllWindowList), fAllWindows(kAllWindowList),
fSubsetWindows(kSubsetList), fSubsetWindows(kSubsetList),
fFocusList(kFocusList),
fWorkspacesLayer(NULL), fWorkspacesLayer(NULL),
fActiveScreen(NULL), fActiveScreen(NULL),
@@ -670,7 +671,7 @@ Desktop::_ActivateApp(team_id team)
for (WindowLayer* window = fAllWindows.FirstWindow(); window != NULL; for (WindowLayer* window = fAllWindows.FirstWindow(); window != NULL;
window = window->NextWindow(kAllWindowList)) { window = window->NextWindow(kAllWindowList)) {
// if window is a normal window of the team, and not hidden, // if window is a normal window of the team, and not hidden,
// we've found our target // we've found our target
if (!window->IsHidden() && window->IsNormal() if (!window->IsHidden() && window->IsNormal()
&& window->ServerWindow()->ClientTeam() == team) { && window->ServerWindow()->ClientTeam() == team) {
@@ -685,8 +686,8 @@ Desktop::_ActivateApp(team_id team)
/*! /*!
\brief Send a quick (no attachments) message to all applications \brief Send a quick (no attachments) message to all applications
Quite useful for notification for things like server shutdown, system Quite useful for notification for things like server shutdown, system
color changes, etc. color changes, etc.
*/ */
void void
@@ -1020,7 +1021,7 @@ Desktop::_SetWorkspace(int32 index)
if (!_Windows(index).HasWindow(FocusWindow()) || !FocusWindow()->IsFloating()) if (!_Windows(index).HasWindow(FocusWindow()) || !FocusWindow()->IsFloating())
SetFocusWindow(FrontWindow()); SetFocusWindow(FrontWindow());
_WindowChanged(NULL); _WindowChanged(NULL);
MarkDirty(dirty); MarkDirty(dirty);
#if 0 #if 0
@@ -1147,7 +1148,7 @@ Desktop::_UpdateFloating(int32 previousWorkspace, int32 nextWorkspace,
_HideWindow(floating); _HideWindow(floating);
if (FocusWindow() == floating) if (FocusWindow() == floating)
SetFocusWindow(_CurrentWindows().LastWindow()); SetFocusWindow();
} }
} }
} }
@@ -1324,21 +1325,16 @@ Desktop::SetFocusWindow(WindowLayer* focus)
return; return;
} }
if (focus == NULL || hasModal) { if (focus == NULL || hasModal)
focus = FrontWindow(); focus = fFocusList.LastWindow();
if (focus == NULL) {
// there might be no front window in case of only a single
// window with B_FLOATING_ALL_WINDOW_FEEL
focus = _CurrentWindows().LastWindow();
}
}
// make sure no window is chosen that doesn't want focus or cannot have it // make sure no window is chosen that doesn't want focus or cannot have it
while (focus != NULL while (focus != NULL
&& ((focus->Flags() & B_AVOID_FOCUS) != 0 && (!focus->InWorkspace(fCurrentWorkspace)
|| (focus->Flags() & B_AVOID_FOCUS) != 0
|| _WindowHasModal(focus) || _WindowHasModal(focus)
|| focus->IsHidden())) { || focus->IsHidden())) {
focus = focus->PreviousWindow(fCurrentWorkspace); focus = focus->PreviousWindow(kFocusList);
} }
if (fFocus == focus) { if (fFocus == focus) {
@@ -1360,6 +1356,10 @@ Desktop::SetFocusWindow(WindowLayer* focus)
if (fFocus != NULL) { if (fFocus != NULL) {
fFocus->SetFocus(true); fFocus->SetFocus(true);
newActiveApp = fFocus->ServerWindow()->App()->ClientTeam(); newActiveApp = fFocus->ServerWindow()->App()->ClientTeam();
// move current focus to the end of the focus list
fFocusList.RemoveWindow(fFocus);
fFocusList.AddWindow(fFocus);
} }
if (newActiveApp == -1) { if (newActiveApp == -1) {
@@ -1571,7 +1571,7 @@ Desktop::SendWindowBehind(WindowLayer* window, WindowLayer* behindOf)
MarkDirty(dirty); MarkDirty(dirty);
_UpdateFronts(); _UpdateFronts();
SetFocusWindow(_CurrentWindows().LastWindow()); SetFocusWindow();
_WindowChanged(window); _WindowChanged(window);
UnlockAllWindows(); UnlockAllWindows();
@@ -1587,6 +1587,7 @@ Desktop::ShowWindow(WindowLayer* window)
LockAllWindows(); LockAllWindows();
window->SetHidden(false); window->SetHidden(false);
fFocusList.AddWindow(window);
if (window->InWorkspace(fCurrentWorkspace)) { if (window->InWorkspace(fCurrentWorkspace)) {
_ShowWindow(window, true); _ShowWindow(window, true);
@@ -1625,6 +1626,8 @@ Desktop::HideWindow(WindowLayer* window)
return; return;
window->SetHidden(true); window->SetHidden(true);
fFocusList.RemoveWindow(window);
if (fMouseEventWindow == window) if (fMouseEventWindow == window)
fMouseEventWindow = NULL; fMouseEventWindow = NULL;
@@ -1634,7 +1637,7 @@ Desktop::HideWindow(WindowLayer* window)
_UpdateFronts(); _UpdateFronts();
if (FocusWindow() == window) if (FocusWindow() == window)
SetFocusWindow(_CurrentWindows().LastWindow()); SetFocusWindow();
} else } else
_WindowChanged(window); _WindowChanged(window);
@@ -1785,7 +1788,7 @@ Desktop::ResizeWindowBy(WindowLayer* window, float x, float y)
// track the dirty region outside the window in case // track the dirty region outside the window in case
// it is shrunk in "previouslyOccupiedRegion" // it is shrunk in "previouslyOccupiedRegion"
BRegion previouslyOccupiedRegion(window->VisibleRegion()); BRegion previouslyOccupiedRegion(window->VisibleRegion());
window->ResizeBy(x, y, &newDirtyRegion); window->ResizeBy(x, y, &newDirtyRegion);
BRegion background; BRegion background;
@@ -1848,7 +1851,7 @@ Desktop::SetWindowDecoratorSettings(WindowLayer* window,
BRegion stillAvailableOnScreen; BRegion stillAvailableOnScreen;
_RebuildClippingForAllWindows(stillAvailableOnScreen); _RebuildClippingForAllWindows(stillAvailableOnScreen);
_SetBackground(stillAvailableOnScreen); _SetBackground(stillAvailableOnScreen);
_TriggerWindowRedrawing(dirty); _TriggerWindowRedrawing(dirty);
} }
@@ -2157,7 +2160,7 @@ Desktop::SetWindowFeel(WindowLayer *window, window_feel newFeel)
_UpdateFronts(); _UpdateFronts();
if (window == FocusWindow() && !window->IsVisible()) if (window == FocusWindow() && !window->IsVisible())
SetFocusWindow(_CurrentWindows().LastWindow()); SetFocusWindow();
UnlockAllWindows(); UnlockAllWindows();
} }
@@ -2201,7 +2204,7 @@ Desktop::SetWindowTitle(WindowLayer *window, const char* title)
BRegion stillAvailableOnScreen; BRegion stillAvailableOnScreen;
_RebuildClippingForAllWindows(stillAvailableOnScreen); _RebuildClippingForAllWindows(stillAvailableOnScreen);
_SetBackground(stillAvailableOnScreen); _SetBackground(stillAvailableOnScreen);
_TriggerWindowRedrawing(dirty); _TriggerWindowRedrawing(dirty);
} }
@@ -2448,7 +2451,7 @@ Desktop::_SetBackground(BRegion& background)
// moving windows // moving windows
// remember the region not covered by any windows // remember the region not covered by any windows
// and redraw the dirty background // and redraw the dirty background
BRegion dirtyBackground(background); BRegion dirtyBackground(background);
dirtyBackground.Exclude(&fBackgroundRegion); dirtyBackground.Exclude(&fBackgroundRegion);
dirtyBackground.IntersectWith(&background); dirtyBackground.IntersectWith(&background);
+3 -2
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2006, Haiku. * Copyright 2001-2008, Haiku.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
@@ -153,7 +153,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
void SetViewUnderMouse(const WindowLayer* window, int32 viewToken); void SetViewUnderMouse(const WindowLayer* window, int32 viewToken);
int32 ViewUnderMouse(const WindowLayer* window); int32 ViewUnderMouse(const WindowLayer* window);
void SetFocusWindow(WindowLayer* window); void SetFocusWindow(WindowLayer* window = NULL);
EventTarget* KeyboardEventTarget(); EventTarget* KeyboardEventTarget();
WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID); WindowLayer* FindWindowLayerByClientToken(int32 token, team_id teamID);
@@ -253,6 +253,7 @@ class Desktop : public MessageLooper, public ScreenOwner {
WindowList fAllWindows; WindowList fAllWindows;
WindowList fSubsetWindows; WindowList fSubsetWindows;
WindowList fFocusList;
WorkspacesLayer* fWorkspacesLayer; WorkspacesLayer* fWorkspacesLayer;
Screen* fActiveScreen; Screen* fActiveScreen;
+2 -1
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, Haiku, Inc. * Copyright (c) 2005-2008, Haiku, Inc.
* Distributed under the terms of the MIT license. * Distributed under the terms of the MIT license.
* *
* Authors: * Authors:
@@ -41,6 +41,7 @@ class WindowList {
enum window_lists { enum window_lists {
kAllWindowList = 32, kAllWindowList = 32,
kSubsetList, kSubsetList,
kFocusList,
kWorkingList, kWorkingList,
kListCount kListCount