Some work to get modal/floating windows back:
* B_{FLOATING|MODAL}_ALL_WINDOW_FEEL now works as expected
* reintroduced the concepts of subsets of modal/floating windows - does only
work correctly for subset "all" window feels.
* RootLayer::_SetFront() now deals correctly with modal windows
* renamed RootLayer *WindowLayer() methods to *Window()
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15282 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -626,7 +626,7 @@ Desktop::ShowWindow(WindowLayer* window)
|
||||
return;
|
||||
}
|
||||
|
||||
fRootLayer->ShowWindowLayer(window);
|
||||
fRootLayer->ShowWindow(window);
|
||||
|
||||
// If the mouse cursor is directly over the newly visible window,
|
||||
// we'll send a fake mouse moved message to the window, so that
|
||||
@@ -659,7 +659,7 @@ Desktop::HideWindow(WindowLayer* window)
|
||||
return;
|
||||
}
|
||||
|
||||
fRootLayer->HideWindowLayer(window);
|
||||
fRootLayer->HideWindow(window);
|
||||
}
|
||||
|
||||
|
||||
@@ -692,7 +692,7 @@ Desktop::_ChangeWindowWorkspaces(WindowLayer* window, uint32 oldWorkspaces,
|
||||
// window is on this workspace, is it anymore?
|
||||
if (!workspaces_on_workspace(i, newWorkspaces)) {
|
||||
if (i == CurrentWorkspace())
|
||||
RootLayer()->RemoveWindowLayer(window);
|
||||
RootLayer()->RemoveWindow(window);
|
||||
else
|
||||
fWorkspaces[i].RemoveWindow(window);
|
||||
}
|
||||
@@ -700,7 +700,7 @@ Desktop::_ChangeWindowWorkspaces(WindowLayer* window, uint32 oldWorkspaces,
|
||||
// window was not on this workspace, is it now?
|
||||
if (workspaces_on_workspace(i, newWorkspaces)) {
|
||||
if (i == CurrentWorkspace())
|
||||
RootLayer()->AddWindowLayer(window);
|
||||
RootLayer()->AddWindow(window);
|
||||
else
|
||||
fWorkspaces[i].AddWindow(window);
|
||||
}
|
||||
|
||||
@@ -205,29 +205,73 @@ RootLayer::SetFocus(WindowLayer* focus)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Tries to move the specified window to the front of the screen.
|
||||
|
||||
If there are any modal windows on this screen, it might not actually
|
||||
become the frontmost window, though, as modal windows stay in front
|
||||
of their subset.
|
||||
*/
|
||||
void
|
||||
RootLayer::_SetFront(WindowLayer* windowLayer, BRegion& update)
|
||||
RootLayer::_SetFront(WindowLayer* window, BRegion& update)
|
||||
{
|
||||
if (windowLayer == NULL) {
|
||||
if (window == NULL) {
|
||||
fBack = NULL;
|
||||
fFront = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!windowLayer->SupportsFront() && fFront != NULL)
|
||||
if (!window->SupportsFront() && fFront != NULL)
|
||||
return;
|
||||
|
||||
BRegion previous = windowLayer->FullVisible();
|
||||
BRegion previous = window->FullVisible();
|
||||
WindowLayer* frontmost = window->Frontmost();
|
||||
|
||||
_RemoveChildFromList(windowLayer);
|
||||
_AddChildToList(windowLayer);
|
||||
_RemoveChildFromList(window);
|
||||
|
||||
windowLayer->GetOnScreenRegion(update);
|
||||
if (frontmost != NULL && frontmost->IsModal()) {
|
||||
// all modal windows follow their subsets to the front
|
||||
// (ie. they are staying in front of them, but they are
|
||||
// not supposed to change their order because of that)
|
||||
|
||||
WindowLayer* nextModal;
|
||||
for (WindowLayer* modal = frontmost; modal != NULL ; modal = nextModal) {
|
||||
nextModal = (WindowLayer*)modal->NextLayer();
|
||||
|
||||
if (nextModal == frontmost) {
|
||||
// since we're adding the modal windows to the end of the list
|
||||
// we're traversing, we must stop when we've reached the initial
|
||||
// starting point again
|
||||
nextModal = NULL;
|
||||
} else if (nextModal != NULL
|
||||
&& (!nextModal->IsModal() || !nextModal->HasInSubset(window)))
|
||||
nextModal = NULL;
|
||||
|
||||
previous.Include(&modal->FullVisible());
|
||||
WindowLayer* modalFrontmost = modal->Frontmost();
|
||||
|
||||
_RemoveChildFromList(modal);
|
||||
_AddChildToList(modal, modalFrontmost);
|
||||
|
||||
BRegion modalRegion;
|
||||
modal->GetOnScreenRegion(modalRegion);
|
||||
// TODO: this is not what we want, we'd want the new visible region
|
||||
update.Include(&modalRegion);
|
||||
}
|
||||
}
|
||||
|
||||
_AddChildToList(window, frontmost);
|
||||
|
||||
BRegion windowRegion;
|
||||
window->GetOnScreenRegion(windowRegion);
|
||||
// TODO: this is not what we want, we'd want the new visible region
|
||||
|
||||
update.Include(&windowRegion);
|
||||
update.Exclude(&previous);
|
||||
|
||||
fFront = windowLayer;
|
||||
_UpdateFront();
|
||||
|
||||
if (windowLayer == fBack || fBack == NULL)
|
||||
if (window == fBack || fBack == NULL)
|
||||
_UpdateBack();
|
||||
}
|
||||
|
||||
@@ -280,19 +324,20 @@ RootLayer::_UpdateFronts()
|
||||
|
||||
|
||||
void
|
||||
RootLayer::ActivateWindow(WindowLayer* windowLayer)
|
||||
RootLayer::ActivateWindow(WindowLayer* window)
|
||||
{
|
||||
BAutolock _(fAllRegionsLock);
|
||||
|
||||
BRegion changed;
|
||||
_SetFront(windowLayer, changed);
|
||||
_SetFront(window, changed);
|
||||
|
||||
// TODO: if this window has any floating windows, add them here
|
||||
|
||||
MarkForRebuild(changed);
|
||||
TriggerRebuild();
|
||||
|
||||
_SetFocus(windowLayer, changed);
|
||||
_SetFocus(Front(), changed);
|
||||
|
||||
_WindowsChanged(changed);
|
||||
MarkForRedraw(changed);
|
||||
TriggerRedraw();
|
||||
@@ -336,32 +381,32 @@ RootLayer::SendBehindWindow(WindowLayer* windowLayer, WindowLayer* behindOf)
|
||||
|
||||
|
||||
void
|
||||
RootLayer::AddWindowLayer(WindowLayer* windowLayer)
|
||||
RootLayer::AddWindow(WindowLayer* window)
|
||||
{
|
||||
STRACE(("AddWindowLayer(%p \"%s\")\n", windowLayer, windowLayer->Name()));
|
||||
STRACE(("AddWindowLayer(%p \"%s\")\n", window, window->Name()));
|
||||
|
||||
if (windowLayer->SupportsFront())
|
||||
_AddChildToList(windowLayer);
|
||||
if (window->SupportsFront())
|
||||
_AddChildToList(window, window->Frontmost((WindowLayer*)FirstChild()));
|
||||
else
|
||||
_AddChildToList(windowLayer, Back());
|
||||
_AddChildToList(window, Back());
|
||||
|
||||
windowLayer->SetRootLayer(this);
|
||||
window->SetRootLayer(this);
|
||||
|
||||
if (!windowLayer->IsHidden())
|
||||
ActivateWindow(windowLayer);
|
||||
if (!window->IsHidden())
|
||||
ActivateWindow(window);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RootLayer::RemoveWindowLayer(WindowLayer* windowLayer)
|
||||
RootLayer::RemoveWindow(WindowLayer* window)
|
||||
{
|
||||
if (!windowLayer->IsHidden())
|
||||
HideWindowLayer(windowLayer);
|
||||
if (!window->IsHidden())
|
||||
HideWindow(window);
|
||||
|
||||
_RemoveChildFromList(windowLayer);
|
||||
_RemoveChildFromList(window);
|
||||
|
||||
LayerRemoved(windowLayer);
|
||||
windowLayer->SetRootLayer(NULL);
|
||||
LayerRemoved(window);
|
||||
window->SetRootLayer(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -467,15 +512,15 @@ RootLayer::SetWorkspace(int32 index, Workspace::Private& previousWorkspace,
|
||||
|
||||
|
||||
void
|
||||
RootLayer::HideWindowLayer(WindowLayer* windowLayer)
|
||||
RootLayer::HideWindow(WindowLayer* window)
|
||||
{
|
||||
BAutolock _(fAllRegionsLock);
|
||||
|
||||
BRegion changed = windowLayer->FullVisible();
|
||||
windowLayer->Hide();
|
||||
BRegion changed = window->FullVisible();
|
||||
window->Hide();
|
||||
_UpdateFronts();
|
||||
|
||||
if (dynamic_cast<WorkspacesLayer*>(windowLayer->TopLayer()) != NULL)
|
||||
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
|
||||
fWorkspacesLayer = NULL;
|
||||
|
||||
// TODO: if this window has any floating windows, remove them here
|
||||
@@ -483,7 +528,7 @@ RootLayer::HideWindowLayer(WindowLayer* windowLayer)
|
||||
MarkForRebuild(changed);
|
||||
TriggerRebuild();
|
||||
|
||||
if (windowLayer == Focus())
|
||||
if (window == Focus())
|
||||
_SetFocus(Front(), changed);
|
||||
_WindowsChanged(changed);
|
||||
|
||||
@@ -493,34 +538,34 @@ RootLayer::HideWindowLayer(WindowLayer* windowLayer)
|
||||
|
||||
|
||||
void
|
||||
RootLayer::ShowWindowLayer(WindowLayer* windowLayer, bool toFront)
|
||||
RootLayer::ShowWindow(WindowLayer* window, bool toFront)
|
||||
{
|
||||
STRACE(("ShowWindowLayer(%p)\n", windowLayer));
|
||||
STRACE(("ShowWindowLayer(%p)\n", window));
|
||||
|
||||
if (!windowLayer->IsHidden())
|
||||
if (!window->IsHidden())
|
||||
return;
|
||||
|
||||
BAutolock _(fAllRegionsLock);
|
||||
|
||||
windowLayer->Show();
|
||||
BRegion changed = windowLayer->FullVisible();
|
||||
window->Show();
|
||||
BRegion changed = window->FullVisible();
|
||||
|
||||
if (toFront)
|
||||
_SetFront(windowLayer, changed);
|
||||
_SetFront(window, changed);
|
||||
else
|
||||
_UpdateFront();
|
||||
|
||||
// TODO: if this window has any floating windows, remove them here
|
||||
|
||||
// TODO: support FFM
|
||||
if (Front() == windowLayer || Focus() == NULL)
|
||||
_SetFocus(windowLayer, changed);
|
||||
if (Front() == window || Focus() == NULL)
|
||||
_SetFocus(window, changed);
|
||||
_WindowsChanged(changed);
|
||||
MarkForRedraw(changed);
|
||||
TriggerRedraw();
|
||||
|
||||
if (dynamic_cast<WorkspacesLayer*>(windowLayer->TopLayer()) != NULL)
|
||||
fWorkspacesLayer = windowLayer->TopLayer();
|
||||
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
|
||||
fWorkspacesLayer = window->TopLayer();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -54,8 +54,8 @@ class RootLayer : public Layer {
|
||||
virtual void ScrollBy(float x, float y)
|
||||
{ /* not allowed */ }
|
||||
|
||||
void HideWindowLayer(WindowLayer* windowLayer);
|
||||
void ShowWindowLayer(WindowLayer* windowLayer, bool toFront = true);
|
||||
void HideWindow(WindowLayer* window);
|
||||
void ShowWindow(WindowLayer* window, bool toFront = true);
|
||||
|
||||
void MoveWindowBy(WindowLayer* window, float x, float y);
|
||||
void ResizeWindowBy(WindowLayer* window, float x, float y);
|
||||
@@ -100,8 +100,8 @@ class RootLayer : public Layer {
|
||||
|
||||
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
|
||||
|
||||
void AddWindowLayer(WindowLayer* windowLayer);
|
||||
void RemoveWindowLayer(WindowLayer* windowLayer);
|
||||
void AddWindow(WindowLayer* window);
|
||||
void RemoveWindow(WindowLayer* window);
|
||||
|
||||
private:
|
||||
bool _SetFocus(WindowLayer* focus, BRegion& update);
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Author: DarkWyrm <[email protected]>
|
||||
* Adi Oanca <[email protected]>
|
||||
* Stephan Aßmus <[email protected]>
|
||||
* Axel Dörfler, [email protected]
|
||||
*/
|
||||
|
||||
|
||||
@@ -714,27 +715,6 @@ WindowLayer::SetFeel(window_feel feel)
|
||||
// having modal windows with B_AVOID_FRONT or B_AVOID_FOCUS doesn't
|
||||
// make that much sense, so we filter those flags out on demand
|
||||
fWindowFlags &= ~ValidWindowFlags(fFeel);
|
||||
|
||||
// TODO: this shouldn't be necessary, but we'll see :)
|
||||
|
||||
// floating and modal windows must appear in every workspace where
|
||||
// their main window is present. Thus their fWorkspaces will be set to
|
||||
// '0x0' and they will be made visible when needed.
|
||||
switch (fFeel) {
|
||||
case B_MODAL_APP_WINDOW_FEEL:
|
||||
break;
|
||||
case B_MODAL_SUBSET_WINDOW_FEEL:
|
||||
case B_FLOATING_APP_WINDOW_FEEL:
|
||||
case B_FLOATING_SUBSET_WINDOW_FEEL:
|
||||
fWorkspaces = 0x0UL;
|
||||
break;
|
||||
case B_MODAL_ALL_WINDOW_FEEL:
|
||||
case B_FLOATING_ALL_WINDOW_FEEL:
|
||||
fWorkspaces = 0xffffffffUL;
|
||||
break;
|
||||
case B_NORMAL_WINDOW_FEEL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -768,6 +748,72 @@ WindowLayer::IsFloating() const
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Returns the windows that's in front of the frontmost position
|
||||
this window can get.
|
||||
Returns NULL is this window can be the frontmost window.
|
||||
*/
|
||||
WindowLayer*
|
||||
WindowLayer::Frontmost(WindowLayer* first)
|
||||
{
|
||||
if (fFeel == B_FLOATING_ALL_WINDOW_FEEL)
|
||||
return NULL;
|
||||
|
||||
if (first == NULL)
|
||||
first = (WindowLayer*)NextLayer();
|
||||
|
||||
for (WindowLayer* window = first; window != NULL;
|
||||
window = (WindowLayer*)window->NextLayer()) {
|
||||
if (window->IsHidden())
|
||||
continue;
|
||||
|
||||
// no one can be in front of a floating all window
|
||||
if (window->Feel() == B_FLOATING_ALL_WINDOW_FEEL)
|
||||
return window;
|
||||
|
||||
if (fFeel == B_NORMAL_WINDOW_FEEL
|
||||
&& window->HasInSubset(this))
|
||||
return window;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
WindowLayer::AddToSubset(WindowLayer* window)
|
||||
{
|
||||
if (fFeel == B_FLOATING_ALL_WINDOW_FEEL
|
||||
|| fFeel == B_MODAL_ALL_WINDOW_FEEL)
|
||||
return true;
|
||||
|
||||
return fSubsets.AddItem(window);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WindowLayer::RemoveFromSubset(WindowLayer* window)
|
||||
{
|
||||
if (fFeel == B_FLOATING_ALL_WINDOW_FEEL
|
||||
|| fFeel == B_MODAL_ALL_WINDOW_FEEL)
|
||||
return;
|
||||
|
||||
fSubsets.RemoveItem(window);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WindowLayer::HasInSubset(WindowLayer* window)
|
||||
{
|
||||
if (fFeel == B_FLOATING_ALL_WINDOW_FEEL
|
||||
|| fFeel == B_MODAL_ALL_WINDOW_FEEL)
|
||||
return true;
|
||||
|
||||
return fSubsets.HasItem(window);
|
||||
}
|
||||
|
||||
|
||||
click_type
|
||||
WindowLayer::_ActionFor(const BMessage *msg) const
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
* Author: DarkWyrm <[email protected]>
|
||||
* Adi Oanca <[email protected]>
|
||||
* Stephan Aßmus <[email protected]>
|
||||
* Axel Dörfler, [email protected]
|
||||
*/
|
||||
#ifndef WINDOW_LAYER_H
|
||||
#define WINDOW_LAYER_H
|
||||
@@ -13,6 +14,7 @@
|
||||
#include "Decorator.h"
|
||||
#include "Layer.h"
|
||||
|
||||
#include <ObjectList.h>
|
||||
#include <Rect.h>
|
||||
#include <String.h>
|
||||
|
||||
@@ -113,6 +115,12 @@ class WindowLayer : public Layer {
|
||||
bool IsModal() const;
|
||||
bool IsFloating() const;
|
||||
|
||||
WindowLayer* Frontmost(WindowLayer* first = NULL);
|
||||
|
||||
bool AddToSubset(WindowLayer* window);
|
||||
void RemoveFromSubset(WindowLayer* window);
|
||||
bool HasInSubset(WindowLayer* window);
|
||||
|
||||
void RequestClientRedraw(const BRegion& invalid);
|
||||
|
||||
void SetTopLayer(Layer* layer);
|
||||
@@ -153,6 +161,8 @@ class WindowLayer : public Layer {
|
||||
|
||||
bool fIsFocus;
|
||||
|
||||
BObjectList<WindowLayer> fSubsets;
|
||||
|
||||
bool fIsClosing;
|
||||
bool fIsMinimizing;
|
||||
bool fIsZooming;
|
||||
|
||||
Reference in New Issue
Block a user