1 /* 2 * Copyright 2001-2020, Haiku, Inc. 3 * Distributed under the terms of the MIT license. 4 * 5 * Authors: 6 * DarkWyrm, bpmagic@columbus.rr.com 7 * Adi Oanca, adioanca@gmail.com 8 * Stephan Aßmus, superstippi@gmx.de 9 * Axel Dörfler, axeld@pinc-software.de 10 * Brecht Machiels, brecht@mos6581.org 11 * Clemens Zeidler, haiku@clemens-zeidler.de 12 * Tri-Edge AI 13 * Jacob Secunda, secundja@gmail.com 14 */ 15 #ifndef WINDOW_H 16 #define WINDOW_H 17 18 19 #include "RegionPool.h" 20 #include "ServerWindow.h" 21 #include "View.h" 22 #include "WindowList.h" 23 24 #include <AutoDeleter.h> 25 #include <ObjectList.h> 26 #include <Referenceable.h> 27 #include <Region.h> 28 #include <String.h> 29 30 31 class Window; 32 33 34 typedef BObjectList<Window> StackWindows; 35 36 37 class WindowStack : public BReferenceable { 38 public: 39 WindowStack(::Decorator* decorator); 40 ~WindowStack(); 41 42 void SetDecorator(::Decorator* decorator); 43 ::Decorator* Decorator(); 44 45 const StackWindows& WindowList() const { return fWindowList; } 46 const StackWindows& LayerOrder() const { return fWindowLayerOrder; } 47 48 Window* TopLayerWindow() const; 49 50 int32 CountWindows(); 51 Window* WindowAt(int32 index); 52 bool AddWindow(Window* window, 53 int32 position = -1); 54 bool RemoveWindow(Window* window); 55 56 bool MoveToTopLayer(Window* window); 57 bool Move(int32 from, int32 to); 58 private: 59 ObjectDeleter< ::Decorator> 60 fDecorator; 61 62 StackWindows fWindowList; 63 StackWindows fWindowLayerOrder; 64 }; 65 66 67 namespace BPrivate { 68 class PortLink; 69 }; 70 71 class ClickTarget; 72 class ClientLooper; 73 class Decorator; 74 class Desktop; 75 class DrawingEngine; 76 class EventDispatcher; 77 class Screen; 78 class WindowBehaviour; 79 class WorkspacesView; 80 81 // TODO: move this into a proper place 82 #define AS_REDRAW 'rdrw' 83 84 enum { 85 UPDATE_REQUEST = 0x01, 86 UPDATE_EXPOSE = 0x02, 87 }; 88 89 90 class Window { 91 public: 92 Window(const BRect& frame, const char *name, 93 window_look look, window_feel feel, 94 uint32 flags, uint32 workspaces, 95 ::ServerWindow* window, 96 DrawingEngine* drawingEngine); 97 virtual ~Window(); 98 99 status_t InitCheck() const; 100 101 BRect Frame() const { return fFrame; } 102 const char* Title() const { return fTitle.String(); } 103 104 window_anchor& Anchor(int32 index); 105 Window* NextWindow(int32 index) const; 106 Window* PreviousWindow(int32 index) const; 107 108 ::Desktop* Desktop() const { return fDesktop; } 109 ::Decorator* Decorator() const; 110 ::ServerWindow* ServerWindow() const { return fWindow; } 111 ::EventTarget& EventTarget() const 112 { return fWindow->EventTarget(); } 113 114 bool ReloadDecor(); 115 116 void SetScreen(const ::Screen* screen); 117 const ::Screen* Screen() const; 118 119 // setting and getting the "hard" clipping, you need to have 120 // WriteLock()ed the clipping! 121 void SetClipping(BRegion* stillAvailableOnScreen); 122 // you need to have ReadLock()ed the clipping! 123 inline BRegion& VisibleRegion() { return fVisibleRegion; } 124 BRegion& VisibleContentRegion(); 125 126 // TODO: not protected by a lock, but noone should need this anyways 127 // make private? when used inside Window, it has the ReadLock() 128 void GetFullRegion(BRegion* region); 129 void GetBorderRegion(BRegion* region); 130 void GetContentRegion(BRegion* region); 131 132 void MoveBy(int32 x, int32 y, bool moveStack = true); 133 void ResizeBy(int32 x, int32 y, 134 BRegion* dirtyRegion, 135 bool resizeStack = true); 136 void SetOutlinesDelta(BPoint delta, 137 BRegion* dirtyRegion); 138 139 void ScrollViewBy(View* view, int32 dx, int32 dy); 140 141 void SetTopView(View* topView); 142 View* TopView() const { return fTopView.Get(); } 143 View* ViewAt(const BPoint& where); 144 145 virtual bool IsOffscreenWindow() const { return false; } 146 147 void GetEffectiveDrawingRegion(View* view, 148 BRegion& region); 149 bool DrawingRegionChanged(View* view) const; 150 151 // generic version, used by the Desktop 152 void ProcessDirtyRegion(BRegion& regionOnScreen); 153 void RedrawDirtyRegion(); 154 155 // can be used from inside classes that don't 156 // need to know about Desktop (first version uses Desktop) 157 void MarkDirty(BRegion& regionOnScreen); 158 // these versions do not use the Desktop 159 void MarkContentDirty(BRegion& regionOnScreen); 160 void MarkContentDirtyAsync(BRegion& regionOnScreen); 161 // shortcut for invalidating just one view 162 void InvalidateView(View* view, BRegion& viewRegion); 163 164 void DisableUpdateRequests(); 165 void EnableUpdateRequests(); 166 167 void BeginUpdate(BPrivate::PortLink& link); 168 void EndUpdate(); 169 bool InUpdate() const 170 { return fInUpdate; } 171 172 bool NeedsUpdate() const 173 { return fUpdateRequested; } 174 175 DrawingEngine* GetDrawingEngine() const 176 { return fDrawingEngine.Get(); } 177 178 // managing a region pool 179 ::RegionPool* RegionPool() 180 { return &fRegionPool; } 181 inline BRegion* GetRegion() 182 { return fRegionPool.GetRegion(); } 183 inline BRegion* GetRegion(const BRegion& copy) 184 { return fRegionPool.GetRegion(copy); } 185 inline void RecycleRegion(BRegion* region) 186 { fRegionPool.Recycle(region); } 187 188 void CopyContents(BRegion* region, 189 int32 xOffset, int32 yOffset); 190 191 void MouseDown(BMessage* message, BPoint where, 192 const ClickTarget& lastClickTarget, 193 int32& clickCount, 194 ClickTarget& _clickTarget); 195 void MouseUp(BMessage* message, BPoint where, 196 int32* _viewToken); 197 void MouseMoved(BMessage* message, BPoint where, 198 int32* _viewToken, bool isLatestMouseMoved, 199 bool isFake); 200 201 void ModifiersChanged(int32 modifiers); 202 203 // some hooks to inform the client window 204 // TODO: move this to ServerWindow maybe? 205 void WorkspaceActivated(int32 index, bool active); 206 void WorkspacesChanged(uint32 oldWorkspaces, 207 uint32 newWorkspaces); 208 void Activated(bool active); 209 210 // changing some properties 211 void SetTitle(const char* name, BRegion& dirty); 212 213 void SetFocus(bool focus); 214 bool IsFocus() const { return fIsFocus; } 215 216 void SetHidden(bool hidden); 217 inline bool IsHidden() const { return fHidden; } 218 219 void SetShowLevel(int32 showLevel); 220 inline int32 ShowLevel() const { return fShowLevel; } 221 222 void SetMinimized(bool minimized); 223 inline bool IsMinimized() const { return fMinimized; } 224 225 void SetCurrentWorkspace(int32 index) 226 { fCurrentWorkspace = index; } 227 int32 CurrentWorkspace() const 228 { return fCurrentWorkspace; } 229 bool IsVisible() const; 230 231 bool IsDragging() const; 232 bool IsResizing() const; 233 234 void SetSizeLimits(int32 minWidth, int32 maxWidth, 235 int32 minHeight, int32 maxHeight); 236 237 void GetSizeLimits(int32* minWidth, int32* maxWidth, 238 int32* minHeight, int32* maxHeight) const; 239 240 // 0.0 -> left .... 1.0 -> right 241 bool SetTabLocation(float location, bool isShifting, 242 BRegion& dirty); 243 float TabLocation() const; 244 245 bool SetDecoratorSettings(const BMessage& settings, 246 BRegion& dirty); 247 bool GetDecoratorSettings(BMessage* settings); 248 249 void HighlightDecorator(bool active); 250 251 void FontsChanged(BRegion* updateRegion); 252 void ColorsChanged(BRegion* updateRegion); 253 254 void SetLook(window_look look, 255 BRegion* updateRegion); 256 void SetFeel(window_feel feel); 257 void SetFlags(uint32 flags, BRegion* updateRegion); 258 259 window_look Look() const { return fLook; } 260 window_feel Feel() const { return fFeel; } 261 uint32 Flags() const { return fFlags; } 262 263 // window manager stuff 264 uint32 Workspaces() const { return fWorkspaces; } 265 void SetWorkspaces(uint32 workspaces) 266 { fWorkspaces = workspaces; } 267 bool InWorkspace(int32 index) const; 268 269 bool SupportsFront(); 270 271 bool IsModal() const; 272 bool IsFloating() const; 273 bool IsNormal() const; 274 275 bool HasModal() const; 276 277 Window* Frontmost(Window* first = NULL, 278 int32 workspace = -1); 279 Window* Backmost(Window* first = NULL, 280 int32 workspace = -1); 281 282 bool AddToSubset(Window* window); 283 void RemoveFromSubset(Window* window); 284 bool HasInSubset(const Window* window) const; 285 bool SameSubset(Window* window); 286 uint32 SubsetWorkspaces() const; 287 bool InSubsetWorkspace(int32 index) const; 288 289 bool HasWorkspacesViews() const 290 { return fWorkspacesViewCount != 0; } 291 void AddWorkspacesView() 292 { fWorkspacesViewCount++; } 293 void RemoveWorkspacesView() 294 { fWorkspacesViewCount--; } 295 void FindWorkspacesViews( 296 BObjectList<WorkspacesView>& list) const; 297 298 static bool IsValidLook(window_look look); 299 static bool IsValidFeel(window_feel feel); 300 static bool IsModalFeel(window_feel feel); 301 static bool IsFloatingFeel(window_feel feel); 302 303 static uint32 ValidWindowFlags(); 304 static uint32 ValidWindowFlags(window_feel feel); 305 306 // Window stack methods. 307 WindowStack* GetWindowStack(); 308 309 bool DetachFromWindowStack( 310 bool ownStackNeeded = true); 311 bool AddWindowToStack(Window* window); 312 Window* StackedWindowAt(const BPoint& where); 313 Window* TopLayerStackWindow(); 314 315 int32 PositionInStack() const; 316 bool MoveToTopStackLayer(); 317 bool MoveToStackPosition(int32 index, 318 bool isMoving); 319 protected: 320 void _ShiftPartOfRegion(BRegion* region, 321 BRegion* regionToShift, int32 xOffset, 322 int32 yOffset); 323 324 // different types of drawing 325 void _TriggerContentRedraw(BRegion& dirty); 326 void _DrawBorder(); 327 328 // handling update sessions 329 void _TransferToUpdateSession( 330 BRegion* contentDirtyRegion); 331 void _SendUpdateMessage(); 332 333 void _UpdateContentRegion(); 334 335 void _ObeySizeLimits(); 336 void _PropagatePosition(); 337 338 BString fTitle; 339 // TODO: no fp rects anywhere 340 BRect fFrame; 341 const ::Screen* fScreen; 342 343 window_anchor fAnchor[kListCount]; 344 345 // the visible region is only recalculated from the 346 // Desktop thread, when using it, Desktop::ReadLockClipping() 347 // has to be called 348 349 BRegion fVisibleRegion; 350 BRegion fVisibleContentRegion; 351 // our part of the "global" dirty region 352 // it is calculated from the desktop thread, 353 // but we can write to it when we read locked 354 // the clipping, since it is local and the desktop 355 // thread is blocked 356 BRegion fDirtyRegion; 357 uint32 fDirtyCause; 358 359 // caching local regions 360 BRegion fContentRegion; 361 BRegion fEffectiveDrawingRegion; 362 363 bool fVisibleContentRegionValid : 1; 364 bool fContentRegionValid : 1; 365 bool fEffectiveDrawingRegionValid : 1; 366 367 ::RegionPool fRegionPool; 368 369 BObjectList<Window> fSubsets; 370 371 ObjectDeleter<WindowBehaviour> 372 fWindowBehaviour; 373 ObjectDeleter<View> fTopView; 374 ::ServerWindow* fWindow; 375 ObjectDeleter<DrawingEngine> 376 fDrawingEngine; 377 ::Desktop* fDesktop; 378 379 // The synchronization, which client drawing commands 380 // belong to the redraw of which dirty region is handled 381 // through an UpdateSession. When the client has 382 // been informed that it should redraw stuff, then 383 // this is the current update session. All new 384 // redraw requests from the Desktop will go 385 // into the pending update session. 386 class UpdateSession { 387 public: 388 UpdateSession(); 389 virtual ~UpdateSession(); 390 391 void Include(BRegion* additionalDirty); 392 void Exclude(BRegion* dirtyInNextSession); 393 394 inline BRegion& DirtyRegion() 395 { return fDirtyRegion; } 396 397 void MoveBy(int32 x, int32 y); 398 399 void SetUsed(bool used); 400 inline bool IsUsed() const 401 { return fInUse; } 402 403 void AddCause(uint8 cause); 404 inline bool IsExpose() const 405 { return fCause & UPDATE_EXPOSE; } 406 inline bool IsRequest() const 407 { return fCause & UPDATE_REQUEST; } 408 409 private: 410 BRegion fDirtyRegion; 411 bool fInUse; 412 uint8 fCause; 413 }; 414 415 UpdateSession fUpdateSessions[2]; 416 UpdateSession* fCurrentUpdateSession; 417 UpdateSession* fPendingUpdateSession; 418 // these two flags are supposed to ensure a sane 419 // and consistent update session 420 bool fUpdateRequested : 1; 421 bool fInUpdate : 1; 422 bool fUpdatesEnabled : 1; 423 424 bool fHidden : 1; 425 int32 fShowLevel; 426 bool fMinimized : 1; 427 bool fIsFocus : 1; 428 429 window_look fLook; 430 window_feel fFeel; 431 uint32 fOriginalFlags; 432 uint32 fFlags; 433 uint32 fWorkspaces; 434 int32 fCurrentWorkspace; 435 436 int32 fMinWidth; 437 int32 fMaxWidth; 438 int32 fMinHeight; 439 int32 fMaxHeight; 440 441 int32 fWorkspacesViewCount; 442 443 friend class DecorManager; 444 445 private: 446 WindowStack* _InitWindowStack(); 447 448 BReference<WindowStack> fCurrentStack; 449 }; 450 451 452 #endif // WINDOW_H 453