* 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

View File

@ -669,24 +669,19 @@ Desktop::_ActivateApp(team_id team)
{
// search for an unhidden window in the current workspace
LockSingleWindow();
AutoWriteLocker locker(fWindowLock);
for (Window* window = _CurrentWindows().LastWindow(); window != NULL;
window = window->PreviousWindow(fCurrentWorkspace)) {
if (!window->IsHidden() && window->IsNormal()
&& window->ServerWindow()->ClientTeam() == team) {
ActivateWindow(window);
UnlockSingleWindow();
return B_OK;
}
}
UnlockSingleWindow();
// search for an unhidden window to give focus to
AutoWriteLocker locker(fWindowLock);
for (Window* window = fAllWindows.FirstWindow(); window != NULL;
window = window->NextWindow(kAllWindowList)) {
// 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;
}
@ -2505,14 +2504,7 @@ Desktop::WriteWindowOrder(int32 workspace, BPrivate::LinkSender& sender)
return;
}
// compute the number of windows
int32 count = 0;
for (Window *window = _Windows(workspace).LastWindow(); window != NULL;
window = window->PreviousWindow(workspace)) {
count++;
}
int32 count = _Windows(workspace).Count();
// write list

View File

@ -128,3 +128,33 @@ WindowList::HasWindow(Window* window) const
|| 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;
}

View File

@ -23,14 +23,18 @@ public:
void SetIndex(int32 index);
int32 Index() const { return fIndex; }
Window* FirstWindow() { return fFirstWindow; }
Window* LastWindow() { return fLastWindow; }
Window* FirstWindow() const { return fFirstWindow; }
Window* LastWindow() const { return fLastWindow; }
void AddWindow(Window* window, Window* before = NULL);
void RemoveWindow(Window* window);
bool HasWindow(Window* window) const;
bool ValidateWindow(Window* window) const;
int32 Count() const;
// O(n)
private:
int32 fIndex;