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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fRootLayer->ShowWindowLayer(window);
|
fRootLayer->ShowWindow(window);
|
||||||
|
|
||||||
// If the mouse cursor is directly over the newly visible 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
|
// we'll send a fake mouse moved message to the window, so that
|
||||||
@@ -659,7 +659,7 @@ Desktop::HideWindow(WindowLayer* window)
|
|||||||
return;
|
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?
|
// window is on this workspace, is it anymore?
|
||||||
if (!workspaces_on_workspace(i, newWorkspaces)) {
|
if (!workspaces_on_workspace(i, newWorkspaces)) {
|
||||||
if (i == CurrentWorkspace())
|
if (i == CurrentWorkspace())
|
||||||
RootLayer()->RemoveWindowLayer(window);
|
RootLayer()->RemoveWindow(window);
|
||||||
else
|
else
|
||||||
fWorkspaces[i].RemoveWindow(window);
|
fWorkspaces[i].RemoveWindow(window);
|
||||||
}
|
}
|
||||||
@@ -700,7 +700,7 @@ Desktop::_ChangeWindowWorkspaces(WindowLayer* window, uint32 oldWorkspaces,
|
|||||||
// window was not on this workspace, is it now?
|
// window was not on this workspace, is it now?
|
||||||
if (workspaces_on_workspace(i, newWorkspaces)) {
|
if (workspaces_on_workspace(i, newWorkspaces)) {
|
||||||
if (i == CurrentWorkspace())
|
if (i == CurrentWorkspace())
|
||||||
RootLayer()->AddWindowLayer(window);
|
RootLayer()->AddWindow(window);
|
||||||
else
|
else
|
||||||
fWorkspaces[i].AddWindow(window);
|
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
|
void
|
||||||
RootLayer::_SetFront(WindowLayer* windowLayer, BRegion& update)
|
RootLayer::_SetFront(WindowLayer* window, BRegion& update)
|
||||||
{
|
{
|
||||||
if (windowLayer == NULL) {
|
if (window == NULL) {
|
||||||
fBack = NULL;
|
fBack = NULL;
|
||||||
fFront = NULL;
|
fFront = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!windowLayer->SupportsFront() && fFront != NULL)
|
if (!window->SupportsFront() && fFront != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BRegion previous = windowLayer->FullVisible();
|
BRegion previous = window->FullVisible();
|
||||||
|
WindowLayer* frontmost = window->Frontmost();
|
||||||
|
|
||||||
_RemoveChildFromList(windowLayer);
|
_RemoveChildFromList(window);
|
||||||
_AddChildToList(windowLayer);
|
|
||||||
|
|
||||||
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);
|
update.Exclude(&previous);
|
||||||
|
|
||||||
fFront = windowLayer;
|
_UpdateFront();
|
||||||
|
|
||||||
if (windowLayer == fBack || fBack == NULL)
|
if (window == fBack || fBack == NULL)
|
||||||
_UpdateBack();
|
_UpdateBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -280,19 +324,20 @@ RootLayer::_UpdateFronts()
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RootLayer::ActivateWindow(WindowLayer* windowLayer)
|
RootLayer::ActivateWindow(WindowLayer* window)
|
||||||
{
|
{
|
||||||
BAutolock _(fAllRegionsLock);
|
BAutolock _(fAllRegionsLock);
|
||||||
|
|
||||||
BRegion changed;
|
BRegion changed;
|
||||||
_SetFront(windowLayer, changed);
|
_SetFront(window, changed);
|
||||||
|
|
||||||
// TODO: if this window has any floating windows, add them here
|
// TODO: if this window has any floating windows, add them here
|
||||||
|
|
||||||
MarkForRebuild(changed);
|
MarkForRebuild(changed);
|
||||||
TriggerRebuild();
|
TriggerRebuild();
|
||||||
|
|
||||||
_SetFocus(windowLayer, changed);
|
_SetFocus(Front(), changed);
|
||||||
|
|
||||||
_WindowsChanged(changed);
|
_WindowsChanged(changed);
|
||||||
MarkForRedraw(changed);
|
MarkForRedraw(changed);
|
||||||
TriggerRedraw();
|
TriggerRedraw();
|
||||||
@@ -336,32 +381,32 @@ RootLayer::SendBehindWindow(WindowLayer* windowLayer, WindowLayer* behindOf)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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())
|
if (window->SupportsFront())
|
||||||
_AddChildToList(windowLayer);
|
_AddChildToList(window, window->Frontmost((WindowLayer*)FirstChild()));
|
||||||
else
|
else
|
||||||
_AddChildToList(windowLayer, Back());
|
_AddChildToList(window, Back());
|
||||||
|
|
||||||
windowLayer->SetRootLayer(this);
|
window->SetRootLayer(this);
|
||||||
|
|
||||||
if (!windowLayer->IsHidden())
|
if (!window->IsHidden())
|
||||||
ActivateWindow(windowLayer);
|
ActivateWindow(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RootLayer::RemoveWindowLayer(WindowLayer* windowLayer)
|
RootLayer::RemoveWindow(WindowLayer* window)
|
||||||
{
|
{
|
||||||
if (!windowLayer->IsHidden())
|
if (!window->IsHidden())
|
||||||
HideWindowLayer(windowLayer);
|
HideWindow(window);
|
||||||
|
|
||||||
_RemoveChildFromList(windowLayer);
|
_RemoveChildFromList(window);
|
||||||
|
|
||||||
LayerRemoved(windowLayer);
|
LayerRemoved(window);
|
||||||
windowLayer->SetRootLayer(NULL);
|
window->SetRootLayer(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -467,15 +512,15 @@ RootLayer::SetWorkspace(int32 index, Workspace::Private& previousWorkspace,
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
RootLayer::HideWindowLayer(WindowLayer* windowLayer)
|
RootLayer::HideWindow(WindowLayer* window)
|
||||||
{
|
{
|
||||||
BAutolock _(fAllRegionsLock);
|
BAutolock _(fAllRegionsLock);
|
||||||
|
|
||||||
BRegion changed = windowLayer->FullVisible();
|
BRegion changed = window->FullVisible();
|
||||||
windowLayer->Hide();
|
window->Hide();
|
||||||
_UpdateFronts();
|
_UpdateFronts();
|
||||||
|
|
||||||
if (dynamic_cast<WorkspacesLayer*>(windowLayer->TopLayer()) != NULL)
|
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
|
||||||
fWorkspacesLayer = NULL;
|
fWorkspacesLayer = NULL;
|
||||||
|
|
||||||
// TODO: if this window has any floating windows, remove them here
|
// TODO: if this window has any floating windows, remove them here
|
||||||
@@ -483,7 +528,7 @@ RootLayer::HideWindowLayer(WindowLayer* windowLayer)
|
|||||||
MarkForRebuild(changed);
|
MarkForRebuild(changed);
|
||||||
TriggerRebuild();
|
TriggerRebuild();
|
||||||
|
|
||||||
if (windowLayer == Focus())
|
if (window == Focus())
|
||||||
_SetFocus(Front(), changed);
|
_SetFocus(Front(), changed);
|
||||||
_WindowsChanged(changed);
|
_WindowsChanged(changed);
|
||||||
|
|
||||||
@@ -493,34 +538,34 @@ RootLayer::HideWindowLayer(WindowLayer* windowLayer)
|
|||||||
|
|
||||||
|
|
||||||
void
|
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;
|
return;
|
||||||
|
|
||||||
BAutolock _(fAllRegionsLock);
|
BAutolock _(fAllRegionsLock);
|
||||||
|
|
||||||
windowLayer->Show();
|
window->Show();
|
||||||
BRegion changed = windowLayer->FullVisible();
|
BRegion changed = window->FullVisible();
|
||||||
|
|
||||||
if (toFront)
|
if (toFront)
|
||||||
_SetFront(windowLayer, changed);
|
_SetFront(window, changed);
|
||||||
else
|
else
|
||||||
_UpdateFront();
|
_UpdateFront();
|
||||||
|
|
||||||
// TODO: if this window has any floating windows, remove them here
|
// TODO: if this window has any floating windows, remove them here
|
||||||
|
|
||||||
// TODO: support FFM
|
// TODO: support FFM
|
||||||
if (Front() == windowLayer || Focus() == NULL)
|
if (Front() == window || Focus() == NULL)
|
||||||
_SetFocus(windowLayer, changed);
|
_SetFocus(window, changed);
|
||||||
_WindowsChanged(changed);
|
_WindowsChanged(changed);
|
||||||
MarkForRedraw(changed);
|
MarkForRedraw(changed);
|
||||||
TriggerRedraw();
|
TriggerRedraw();
|
||||||
|
|
||||||
if (dynamic_cast<WorkspacesLayer*>(windowLayer->TopLayer()) != NULL)
|
if (dynamic_cast<WorkspacesLayer*>(window->TopLayer()) != NULL)
|
||||||
fWorkspacesLayer = windowLayer->TopLayer();
|
fWorkspacesLayer = window->TopLayer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,8 +54,8 @@ class RootLayer : public Layer {
|
|||||||
virtual void ScrollBy(float x, float y)
|
virtual void ScrollBy(float x, float y)
|
||||||
{ /* not allowed */ }
|
{ /* not allowed */ }
|
||||||
|
|
||||||
void HideWindowLayer(WindowLayer* windowLayer);
|
void HideWindow(WindowLayer* window);
|
||||||
void ShowWindowLayer(WindowLayer* windowLayer, bool toFront = true);
|
void ShowWindow(WindowLayer* window, bool toFront = true);
|
||||||
|
|
||||||
void MoveWindowBy(WindowLayer* window, float x, float y);
|
void MoveWindowBy(WindowLayer* window, float x, float y);
|
||||||
void ResizeWindowBy(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(); }
|
thread_id LockingThread() { return fAllRegionsLock.LockingThread(); }
|
||||||
|
|
||||||
void AddWindowLayer(WindowLayer* windowLayer);
|
void AddWindow(WindowLayer* window);
|
||||||
void RemoveWindowLayer(WindowLayer* windowLayer);
|
void RemoveWindow(WindowLayer* window);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _SetFocus(WindowLayer* focus, BRegion& update);
|
bool _SetFocus(WindowLayer* focus, BRegion& update);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
* Author: DarkWyrm <[email protected]>
|
* Author: DarkWyrm <[email protected]>
|
||||||
* Adi Oanca <[email protected]>
|
* Adi Oanca <[email protected]>
|
||||||
* Stephan Aßmus <[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
|
// 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
|
// make that much sense, so we filter those flags out on demand
|
||||||
fWindowFlags &= ~ValidWindowFlags(fFeel);
|
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
|
click_type
|
||||||
WindowLayer::_ActionFor(const BMessage *msg) const
|
WindowLayer::_ActionFor(const BMessage *msg) const
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
* Author: DarkWyrm <bpmagic@columbus.rr.com>
|
||||||
* Adi Oanca <adioanca@gmail.com>
|
* Adi Oanca <adioanca@gmail.com>
|
||||||
* Stephan Aßmus <superstippi@gmx.de>
|
* Stephan Aßmus <superstippi@gmx.de>
|
||||||
|
* Axel Dörfler, axeld@pinc-software.de
|
||||||
*/
|
*/
|
||||||
#ifndef WINDOW_LAYER_H
|
#ifndef WINDOW_LAYER_H
|
||||||
#define WINDOW_LAYER_H
|
#define WINDOW_LAYER_H
|
||||||
@@ -13,6 +14,7 @@
|
|||||||
#include "Decorator.h"
|
#include "Decorator.h"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
|
|
||||||
|
#include <ObjectList.h>
|
||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
@@ -113,6 +115,12 @@ class WindowLayer : public Layer {
|
|||||||
bool IsModal() const;
|
bool IsModal() const;
|
||||||
bool IsFloating() 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 RequestClientRedraw(const BRegion& invalid);
|
||||||
|
|
||||||
void SetTopLayer(Layer* layer);
|
void SetTopLayer(Layer* layer);
|
||||||
@@ -153,6 +161,8 @@ class WindowLayer : public Layer {
|
|||||||
|
|
||||||
bool fIsFocus;
|
bool fIsFocus;
|
||||||
|
|
||||||
|
BObjectList<WindowLayer> fSubsets;
|
||||||
|
|
||||||
bool fIsClosing;
|
bool fIsClosing;
|
||||||
bool fIsMinimizing;
|
bool fIsMinimizing;
|
||||||
bool fIsZooming;
|
bool fIsZooming;
|
||||||
|
|||||||
Reference in New Issue
Block a user