xref: /haiku/src/servers/app/Window.h (revision 97dfeb96704e5dbc5bec32ad7b21379d0125e031)
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