* Copyright 2001-2020, Haiku, Inc.
* Distributed under the terms of the MIT license.
*
* Authors:
* DarkWyrm, bpmagic@columbus.rr.com
* Adi Oanca, adioanca@gmail.com
* Stephan Aßmus, superstippi@gmx.de
* Axel Dörfler, axeld@pinc-software.de
* Brecht Machiels, brecht@mos6581.org
* Clemens Zeidler, haiku@clemens-zeidler.de
* Tri-Edge AI
* Jacob Secunda, secundja@gmail.com
*/
#ifndef WINDOW_H
#define WINDOW_H
#include "RegionPool.h"
#include "ServerWindow.h"
#include "View.h"
#include "WindowList.h"
#include <AutoDeleter.h>
#include <ObjectList.h>
#include <Referenceable.h>
#include <Region.h>
#include <String.h>
class Window;
typedef BObjectList<Window> StackWindows;
class WindowStack : public BReferenceable {
public:
WindowStack(::Decorator* decorator);
~WindowStack();
void SetDecorator(::Decorator* decorator);
::Decorator* Decorator();
const StackWindows& WindowList() const { return fWindowList; }
const StackWindows& LayerOrder() const { return fWindowLayerOrder; }
Window* TopLayerWindow() const;
int32 CountWindows();
Window* WindowAt(int32 index);
bool AddWindow(Window* window,
int32 position = -1);
bool RemoveWindow(Window* window);
bool MoveToTopLayer(Window* window);
bool Move(int32 from, int32 to);
private:
ObjectDeleter< ::Decorator>
fDecorator;
StackWindows fWindowList;
StackWindows fWindowLayerOrder;
};
namespace BPrivate {
class PortLink;
};
class ClickTarget;
class ClientLooper;
class Decorator;
class Desktop;
class DrawingEngine;
class EventDispatcher;
class Screen;
class WindowBehaviour;
class WorkspacesView;
#define AS_REDRAW 'rdrw'
class Window {
public:
Window(const BRect& frame, const char *name,
window_look look, window_feel feel,
uint32 flags, uint32 workspaces,
::ServerWindow* window,
DrawingEngine* drawingEngine);
virtual ~Window();
status_t InitCheck() const;
BRect Frame() const { return fFrame; }
const char* Title() const { return fTitle.String(); }
window_anchor& Anchor(int32 index);
Window* NextWindow(int32 index) const;
Window* PreviousWindow(int32 index) const;
::Desktop* Desktop() const { return fDesktop; }
::Decorator* Decorator() const;
::ServerWindow* ServerWindow() const { return fWindow; }
::EventTarget& EventTarget() const
{ return fWindow->EventTarget(); }
bool ReloadDecor();
void SetScreen(const ::Screen* screen);
const ::Screen* Screen() const;
void SetClipping(BRegion* stillAvailableOnScreen);
inline BRegion& VisibleRegion() { return fVisibleRegion; }
BRegion& VisibleContentRegion();
void GetFullRegion(BRegion* region);
void GetBorderRegion(BRegion* region);
void GetContentRegion(BRegion* region);
void MoveBy(int32 x, int32 y, bool moveStack = true);
void ResizeBy(int32 x, int32 y,
BRegion* dirtyRegion,
bool resizeStack = true);
void SetOutlinesDelta(BPoint delta,
BRegion* dirtyRegion);
void ScrollViewBy(View* view, int32 dx, int32 dy);
void SetTopView(View* topView);
View* TopView() const { return fTopView.Get(); }
View* ViewAt(const BPoint& where);
virtual bool IsOffscreenWindow() const { return false; }
void GetEffectiveDrawingRegion(View* view,
BRegion& region);
bool DrawingRegionChanged(View* view) const;
void ProcessDirtyRegion(const BRegion& dirtyRegion,
const BRegion& exposeRegion);
void ProcessDirtyRegion(const BRegion& exposeRegion)
{ ProcessDirtyRegion(exposeRegion, exposeRegion); }
void RedrawDirtyRegion();
void MarkDirty(BRegion& regionOnScreen);
void MarkContentDirty(BRegion& dirtyRegion,
BRegion& exposeRegion);
void MarkContentDirtyAsync(BRegion& dirtyRegion);
void InvalidateView(View* view, BRegion& viewRegion);
void DisableUpdateRequests();
void EnableUpdateRequests();
void BeginUpdate(BPrivate::PortLink& link);
void EndUpdate();
bool InUpdate() const
{ return fInUpdate; }
bool NeedsUpdate() const
{ return fUpdateRequested; }
DrawingEngine* GetDrawingEngine() const
{ return fDrawingEngine.Get(); }
::RegionPool* RegionPool()
{ return &fRegionPool; }
inline BRegion* GetRegion()
{ return fRegionPool.GetRegion(); }
inline BRegion* GetRegion(const BRegion& copy)
{ return fRegionPool.GetRegion(copy); }
inline void RecycleRegion(BRegion* region)
{ fRegionPool.Recycle(region); }
void CopyContents(BRegion* region,
int32 xOffset, int32 yOffset);
void MouseDown(BMessage* message, BPoint where,
const ClickTarget& lastClickTarget,
int32& clickCount,
ClickTarget& _clickTarget);
void MouseUp(BMessage* message, BPoint where,
int32* _viewToken);
void MouseMoved(BMessage* message, BPoint where,
int32* _viewToken, bool isLatestMouseMoved,
bool isFake);
void ModifiersChanged(int32 modifiers);
void WorkspaceActivated(int32 index, bool active);
void WorkspacesChanged(uint32 oldWorkspaces,
uint32 newWorkspaces);
void Activated(bool active);
void SetTitle(const char* name, BRegion& dirty);
void SetFocus(bool focus);
bool IsFocus() const { return fIsFocus; }
void SetHidden(bool hidden);
inline bool IsHidden() const { return fHidden; }
void SetShowLevel(int32 showLevel);
inline int32 ShowLevel() const { return fShowLevel; }
void SetMinimized(bool minimized);
inline bool IsMinimized() const { return fMinimized; }
void SetCurrentWorkspace(int32 index)
{ fCurrentWorkspace = index; fPriorWorkspace = index; }
int32 CurrentWorkspace() const
{ return fCurrentWorkspace; }
bool IsVisible() const;
void SetPriorWorkspace(int32 index)
{ fPriorWorkspace = index; }
int32 PriorWorkspace() const
{ return fPriorWorkspace; }
bool IsDragging() const;
bool IsResizing() const;
void SetSizeLimits(int32 minWidth, int32 maxWidth,
int32 minHeight, int32 maxHeight);
void GetSizeLimits(int32* minWidth, int32* maxWidth,
int32* minHeight, int32* maxHeight) const;
bool SetTabLocation(float location, bool isShifting,
BRegion& dirty);
float TabLocation() const;
bool SetDecoratorSettings(const BMessage& settings,
BRegion& dirty);
bool GetDecoratorSettings(BMessage* settings);
void HighlightDecorator(bool active);
void FontsChanged(BRegion* updateRegion);
void ColorsChanged(BRegion* updateRegion);
void SetLook(window_look look,
BRegion* updateRegion);
void SetFeel(window_feel feel);
void SetFlags(uint32 flags, BRegion* updateRegion);
window_look Look() const { return fLook; }
window_feel Feel() const { return fFeel; }
uint32 Flags() const { return fFlags; }
uint32 Workspaces() const { return fWorkspaces; }
void SetWorkspaces(uint32 workspaces)
{ fWorkspaces = workspaces; }
bool InWorkspace(int32 index) const;
bool SupportsFront();
bool IsModal() const;
bool IsFloating() const;
bool IsNormal() const;
bool HasModal() const;
Window* Frontmost(Window* first = NULL,
int32 workspace = -1);
Window* Backmost(Window* first = NULL,
int32 workspace = -1);
bool AddToSubset(Window* window);
void RemoveFromSubset(Window* window);
bool HasInSubset(const Window* window) const;
bool SameSubset(Window* window);
uint32 SubsetWorkspaces() const;
bool InSubsetWorkspace(int32 index) const;
bool HasWorkspacesViews() const
{ return fWorkspacesViewCount != 0; }
void AddWorkspacesView()
{ fWorkspacesViewCount++; }
void RemoveWorkspacesView()
{ fWorkspacesViewCount--; }
void FindWorkspacesViews(
BObjectList<WorkspacesView>& list) const;
static bool IsValidLook(window_look look);
static bool IsValidFeel(window_feel feel);
static bool IsModalFeel(window_feel feel);
static bool IsFloatingFeel(window_feel feel);
static uint32 ValidWindowFlags();
static uint32 ValidWindowFlags(window_feel feel);
WindowStack* GetWindowStack();
bool DetachFromWindowStack(
bool ownStackNeeded = true);
bool AddWindowToStack(Window* window);
Window* StackedWindowAt(const BPoint& where);
Window* TopLayerStackWindow();
int32 PositionInStack() const;
bool MoveToTopStackLayer();
bool MoveToStackPosition(int32 index,
bool isMoving);
protected:
void _ShiftPartOfRegion(BRegion* region,
BRegion* regionToShift, int32 xOffset,
int32 yOffset);
void _TriggerContentRedraw(BRegion& dirty,
const BRegion& expose = BRegion());
void _DrawBorder();
void _TransferToUpdateSession(
BRegion* contentDirtyRegion);
void _SendUpdateMessage();
void _UpdateContentRegion();
void _ObeySizeLimits();
void _PropagatePosition();
BString fTitle;
BRect fFrame;
const ::Screen* fScreen;
window_anchor fAnchor[kListCount];
BRegion fVisibleRegion;
BRegion fVisibleContentRegion;
BRegion fDirtyRegion;
BRegion fExposeRegion;
BRegion fContentRegion;
BRegion fEffectiveDrawingRegion;
bool fVisibleContentRegionValid : 1;
bool fContentRegionValid : 1;
bool fEffectiveDrawingRegionValid : 1;
::RegionPool fRegionPool;
BObjectList<Window> fSubsets;
ObjectDeleter<WindowBehaviour>
fWindowBehaviour;
ObjectDeleter<View> fTopView;
::ServerWindow* fWindow;
ObjectDeleter<DrawingEngine>
fDrawingEngine;
::Desktop* fDesktop;
class UpdateSession {
public:
UpdateSession();
void Include(BRegion* additionalDirty);
void Exclude(BRegion* dirtyInNextSession);
inline BRegion& DirtyRegion()
{ return fDirtyRegion; }
void MoveBy(int32 x, int32 y);
void SetUsed(bool used);
inline bool IsUsed() const
{ return fInUse; }
private:
BRegion fDirtyRegion;
bool fInUse;
};
UpdateSession fUpdateSessions[2];
UpdateSession* fCurrentUpdateSession;
UpdateSession* fPendingUpdateSession;
bool fUpdateRequested : 1;
bool fInUpdate : 1;
bool fUpdatesEnabled : 1;
bool fHidden : 1;
int32 fShowLevel;
bool fMinimized : 1;
bool fIsFocus : 1;
window_look fLook;
window_feel fFeel;
uint32 fOriginalFlags;
uint32 fFlags;
uint32 fWorkspaces;
int32 fCurrentWorkspace;
int32 fPriorWorkspace;
int32 fMinWidth;
int32 fMaxWidth;
int32 fMinHeight;
int32 fMaxHeight;
int32 fWorkspacesViewCount;
friend class DecorManager;
private:
WindowStack* _InitWindowStack();
BReference<WindowStack> fCurrentStack;
};
#endif