haiku/src/servers/app/WindowList.cpp
Axel Dörfler 150e5ed532 * When the current focus window was closed or invisible, we used to
chose the front window as our next focus window - but this proved
  to be problematic with B_AVOID_FRONT windows. Therefore, we now
  simply chose the top-most window as the next focus window.
  This fixes bug #281, and potentially also fixes bug #181.
* This also revealed another bug in SetFocusWindow(): when the window
  to have focus already had focus, but were hidden before, the focus
  did not change; if that window was subsequently removed, the app_server
  would have crashed.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16811 a95241bf-73f2-0310-859d-f6bbb57e9c96
2006-03-15 21:33:12 +00:00

131 lines
2.5 KiB
C++

/*
* Copyright (c) 2005-2006, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* Axel Dörfler, axeld@pinc-software.de
*/
#include "DesktopSettings.h"
#include "WindowLayer.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(WindowLayer* window, WindowLayer* 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(WindowLayer* 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(WindowLayer* window) const
{
if (window == NULL)
return false;
return window->Anchor(fIndex).next != NULL
|| window->Anchor(fIndex).previous != NULL
|| fFirstWindow == window
|| fLastWindow == window;
}