* 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:
parent
c91868ae1d
commit
d689f4578d
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user