haiku/src/servers/app/WindowList.cpp
Axel Dörfler d689f4578d * 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
2008-08-13 09:00:36 +00:00

161 lines
3.1 KiB
C++

/*
* Copyright (c) 2005-2008, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#include "DesktopSettings.h"
#include "Window.h"
const BPoint kInvalidWindowPosition = BPoint(INFINITY, INFINITY);
window_anchor::window_anchor()
:
next(NULL),
previous(NULL),
position(kInvalidWindowPosition)
{
}
// #pragma mark -
WindowList::WindowList(int32 index)
:
fIndex(index),
fFirstWindow(NULL),
fLastWindow(NULL)
{
}
WindowList::~WindowList()
{
}
void
WindowList::SetIndex(int32 index)
{
fIndex = index;
}
/*!
Adds the \a window to the end of the list. If \a before is
given, it will be inserted right before that window.
*/
void
WindowList::AddWindow(Window* window, Window* before)
{
window_anchor& windowAnchor = window->Anchor(fIndex);
if (before != NULL) {
window_anchor& beforeAnchor = before->Anchor(fIndex);
// add view before this one
windowAnchor.next = before;
windowAnchor.previous = beforeAnchor.previous;
if (windowAnchor.previous != NULL)
windowAnchor.previous->Anchor(fIndex).next = window;
beforeAnchor.previous = window;
if (fFirstWindow == before)
fFirstWindow = window;
} else {
// add view to the end of the list
if (fLastWindow != NULL) {
fLastWindow->Anchor(fIndex).next = window;
windowAnchor.previous = fLastWindow;
} else {
fFirstWindow = window;
windowAnchor.previous = NULL;
}
windowAnchor.next = NULL;
fLastWindow = window;
}
if (fIndex < kMaxWorkspaces)
window->SetWorkspaces(window->Workspaces() | (1UL << fIndex));
}
void
WindowList::RemoveWindow(Window* window)
{
window_anchor& windowAnchor = window->Anchor(fIndex);
if (fFirstWindow == window) {
// it's the first child
fFirstWindow = windowAnchor.next;
} else {
// it must have a previous sibling, then
windowAnchor.previous->Anchor(fIndex).next = windowAnchor.next;
}
if (fLastWindow == window) {
// it's the last child
fLastWindow = windowAnchor.previous;
} else {
// then it must have a next sibling
windowAnchor.next->Anchor(fIndex).previous = windowAnchor.previous;
}
if (fIndex < kMaxWorkspaces)
window->SetWorkspaces(window->Workspaces() & ~(1UL << fIndex));
windowAnchor.previous = NULL;
windowAnchor.next = NULL;
}
bool
WindowList::HasWindow(Window* window) const
{
if (window == NULL)
return false;
return window->Anchor(fIndex).next != NULL
|| window->Anchor(fIndex).previous != NULL
|| fFirstWindow == 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;
}