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