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 void ColorsChanged(BRegion* updateRegion); 247 248 void SetLook(window_look look, 249 BRegion* updateRegion); 250 void SetFeel(window_feel feel); 251 void SetFlags(uint32 flags, BRegion* updateRegion); 252 253 window_look Look() const { return fLook; } 254 window_feel Feel() const { return fFeel; } 255 uint32 Flags() const { return fFlags; } 256 257 // window manager stuff 258 uint32 Workspaces() const { return fWorkspaces; } 259 void SetWorkspaces(uint32 workspaces) 260 { fWorkspaces = workspaces; } 261 bool InWorkspace(int32 index) const; 262 263 bool SupportsFront(); 264 265 bool IsModal() const; 266 bool IsFloating() const; 267 bool IsNormal() const; 268 269 bool HasModal() const; 270 271 Window* Frontmost(Window* first = NULL, 272 int32 workspace = -1); 273 Window* Backmost(Window* first = NULL, 274 int32 workspace = -1); 275 276 bool AddToSubset(Window* window); 277 void RemoveFromSubset(Window* window); 278 bool HasInSubset(const Window* window) const; 279 bool SameSubset(Window* window); 280 uint32 SubsetWorkspaces() const; 281 bool InSubsetWorkspace(int32 index) const; 282 283 bool HasWorkspacesViews() const 284 { return fWorkspacesViewCount != 0; } 285 void AddWorkspacesView() 286 { fWorkspacesViewCount++; } 287 void RemoveWorkspacesView() 288 { fWorkspacesViewCount--; } 289 void FindWorkspacesViews( 290 BObjectList<WorkspacesView>& list) const; 291 292 static bool IsValidLook(window_look look); 293 static bool IsValidFeel(window_feel feel); 294 static bool IsModalFeel(window_feel feel); 295 static bool IsFloatingFeel(window_feel feel); 296 297 static uint32 ValidWindowFlags(); 298 static uint32 ValidWindowFlags(window_feel feel); 299 300 // Window stack methods. 301 WindowStack* GetWindowStack(); 302 303 bool DetachFromWindowStack( 304 bool ownStackNeeded = true); 305 bool AddWindowToStack(Window* window); 306 Window* StackedWindowAt(const BPoint& where); 307 Window* TopLayerStackWindow(); 308 309 int32 PositionInStack() const; 310 bool MoveToTopStackLayer(); 311 bool MoveToStackPosition(int32 index, 312 bool isMoving); 313 protected: 314 void _ShiftPartOfRegion(BRegion* region, 315 BRegion* regionToShift, int32 xOffset, 316 int32 yOffset); 317 318 // different types of drawing 319 void _TriggerContentRedraw(BRegion& dirty); 320 void _DrawBorder(); 321 322 // handling update sessions 323 void _TransferToUpdateSession( 324 BRegion* contentDirtyRegion); 325 void _SendUpdateMessage(); 326 327 void _UpdateContentRegion(); 328 329 void _ObeySizeLimits(); 330 void _PropagatePosition(); 331 332 BString fTitle; 333 // TODO: no fp rects anywhere 334 BRect fFrame; 335 const ::Screen* fScreen; 336 337 window_anchor fAnchor[kListCount]; 338 339 // the visible region is only recalculated from the 340 // Desktop thread, when using it, Desktop::ReadLockClipping() 341 // has to be called 342 343 BRegion fVisibleRegion; 344 BRegion fVisibleContentRegion; 345 // our part of the "global" dirty region 346 // it is calculated from the desktop thread, 347 // but we can write to it when we read locked 348 // the clipping, since it is local and the desktop 349 // thread is blocked 350 BRegion fDirtyRegion; 351 uint32 fDirtyCause; 352 353 // caching local regions 354 BRegion fContentRegion; 355 BRegion fEffectiveDrawingRegion; 356 357 bool fVisibleContentRegionValid : 1; 358 bool fContentRegionValid : 1; 359 bool fEffectiveDrawingRegionValid : 1; 360 361 ::RegionPool fRegionPool; 362 363 BObjectList<Window> fSubsets; 364 365 WindowBehaviour* fWindowBehaviour; 366 View* fTopView; 367 ::ServerWindow* fWindow; 368 DrawingEngine* fDrawingEngine; 369 ::Desktop* fDesktop; 370 371 // The synchronization, which client drawing commands 372 // belong to the redraw of which dirty region is handled 373 // through an UpdateSession. When the client has 374 // been informed that it should redraw stuff, then 375 // this is the current update session. All new 376 // redraw requests from the Desktop will go 377 // into the pending update session. 378 class UpdateSession { 379 public: 380 UpdateSession(); 381 virtual ~UpdateSession(); 382 383 void Include(BRegion* additionalDirty); 384 void Exclude(BRegion* dirtyInNextSession); 385 386 inline BRegion& DirtyRegion() 387 { return fDirtyRegion; } 388 389 void MoveBy(int32 x, int32 y); 390 391 void SetUsed(bool used); 392 inline bool IsUsed() const 393 { return fInUse; } 394 395 void AddCause(uint8 cause); 396 inline bool IsExpose() const 397 { return fCause & UPDATE_EXPOSE; } 398 inline bool IsRequest() const 399 { return fCause & UPDATE_REQUEST; } 400 401 private: 402 BRegion fDirtyRegion; 403 bool fInUse; 404 uint8 fCause; 405 }; 406 407 UpdateSession fUpdateSessions[2]; 408 UpdateSession* fCurrentUpdateSession; 409 UpdateSession* fPendingUpdateSession; 410 // these two flags are supposed to ensure a sane 411 // and consistent update session 412 bool fUpdateRequested : 1; 413 bool fInUpdate : 1; 414 bool fUpdatesEnabled : 1; 415 416 bool fHidden : 1; 417 int32 fShowLevel; 418 bool fMinimized : 1; 419 bool fIsFocus : 1; 420 421 window_look fLook; 422 window_feel fFeel; 423 uint32 fOriginalFlags; 424 uint32 fFlags; 425 uint32 fWorkspaces; 426 int32 fCurrentWorkspace; 427 428 int32 fMinWidth; 429 int32 fMaxWidth; 430 int32 fMinHeight; 431 int32 fMaxHeight; 432 433 int32 fWorkspacesViewCount; 434 435 friend class DecorManager; 436 437 private: 438 WindowStack* _InitWindowStack(); 439 440 BReference<WindowStack> fCurrentStack; 441 }; 442 443 444 #endif // WINDOW_H 445