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