* Fixed a possible deadlock in Desktop::_ActivateApp(): since ActivateWindow()

will need to write lock the window lock, we cannot call it with the read
  lock held.
* Added a TODO comment in _ActivateApp() on how we could handle minimized
  windows.
* Added a WindowList::Count() method.
* Added a WindowList::ValidateWindow() that you can use to validate a window
  pointer in case you had to unlock the list.
* Made FirstWindow()/LastWindow() const.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26957 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2008-08-13 09:00:36 +00:00
parent c91868ae1d
commit d689f4578d
3 changed files with 45 additions and 19 deletions
+6 -14
View File
@@ -669,24 +669,19 @@ Desktop::_ActivateApp(team_id team)
{ {
// search for an unhidden window in the current workspace // search for an unhidden window in the current workspace
LockSingleWindow(); AutoWriteLocker locker(fWindowLock);
for (Window* window = _CurrentWindows().LastWindow(); window != NULL; for (Window* window = _CurrentWindows().LastWindow(); window != NULL;
window = window->PreviousWindow(fCurrentWorkspace)) { window = window->PreviousWindow(fCurrentWorkspace)) {
if (!window->IsHidden() && window->IsNormal() if (!window->IsHidden() && window->IsNormal()
&& window->ServerWindow()->ClientTeam() == team) { && window->ServerWindow()->ClientTeam() == team) {
ActivateWindow(window); ActivateWindow(window);
UnlockSingleWindow();
return B_OK; return B_OK;
} }
} }
UnlockSingleWindow();
// search for an unhidden window to give focus to // search for an unhidden window to give focus to
AutoWriteLocker locker(fWindowLock);
for (Window* window = fAllWindows.FirstWindow(); window != NULL; for (Window* 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,
@@ -698,6 +693,10 @@ Desktop::_ActivateApp(team_id team)
} }
} }
// TODO: we cannot maximize minimized windows here (with the window lock
// write locked). To work-around this, we could forward the request to
// the ServerApp of this team - it maintains its own window list, and can
// therefore call ActivateWindow() without holding the window lock.
return B_BAD_VALUE; return B_BAD_VALUE;
} }
@@ -2505,14 +2504,7 @@ Desktop::WriteWindowOrder(int32 workspace, BPrivate::LinkSender& sender)
return; return;
} }
// compute the number of windows int32 count = _Windows(workspace).Count();
int32 count = 0;
for (Window *window = _Windows(workspace).LastWindow(); window != NULL;
window = window->PreviousWindow(workspace)) {
count++;
}
// write list // write list
+30
View File
@@ -128,3 +128,33 @@ WindowList::HasWindow(Window* window) const
|| fLastWindow == window; || fLastWindow == window;
} }
/*! Unlike HasWindow(), this will not reference the window pointer. You
can use this method to check whether or not a window is still part
of a list (when it's possible that the window is already gone).
*/
bool
WindowList::ValidateWindow(Window* validateWindow) const
{
for (Window *window = FirstWindow(); window != NULL;
window = window->NextWindow(fIndex)) {
if (window == validateWindow)
return true;
}
return false;
}
int32
WindowList::Count() const
{
int32 count = 0;
for (Window *window = FirstWindow(); window != NULL;
window = window->NextWindow(fIndex)) {
count++;
}
return count;
}
+6 -2
View File
@@ -24,13 +24,17 @@ public:
void SetIndex(int32 index); void SetIndex(int32 index);
int32 Index() const { return fIndex; } int32 Index() const { return fIndex; }
Window* FirstWindow() { return fFirstWindow; } Window* FirstWindow() const { return fFirstWindow; }
Window* LastWindow() { return fLastWindow; } Window* LastWindow() const { return fLastWindow; }
void AddWindow(Window* window, Window* before = NULL); void AddWindow(Window* window, Window* before = NULL);
void RemoveWindow(Window* window); void RemoveWindow(Window* window);
bool HasWindow(Window* window) const; bool HasWindow(Window* window) const;
bool ValidateWindow(Window* window) const;
int32 Count() const;
// O(n)
private: private:
int32 fIndex; int32 fIndex;