1 //
2 // PWinObj.hh for pekwm
3 // Copyright (C) 2003-2020 Claes Nästen <pekdon@gmail.com>
4 //
5 // This program is licensed under the GNU GPL.
6 // See the LICENSE file for more information.
7 //
8 
9 #ifndef _PEKWM_PWINOBJ_HH_
10 #define _PEKWM_PWINOBJ_HH_
11 
12 #include "config.h"
13 
14 #include <algorithm>
15 #include <map>
16 
17 #include "pekwm.hh"
18 #include "X11.hh"
19 #include "Action.hh"
20 #include "Observable.hh"
21 
22 //! @brief X11 Window wrapper class.
23 class PWinObj : public Observable
24 {
25 public:
26 	/**
27 	 * Observation sent when a PWinObj is destructed.
28 	 */
29 	class PWinObjDeleted : public Observation {
30 	};
31 
32 	//! @brief PWinObj inherited types.
33 	enum Type {
34 		WO_FRAME = (1<<1), //!< Frame type.
35 		WO_CLIENT = (1<<2), //!< Client type.
36 		WO_MENU = (1<<3), //!< PMenu type.
37 		WO_DOCKAPP = (1<<4), //!< DockApp type.
38 		WO_SCREEN_EDGE = (1<<5), //!< ScreenEdge type.
39 		WO_SCREEN_ROOT = (1<<6), //!< PWinObj type for root Window.
40 		WO_CMD_DIALOG = (1<<7), //!< CmdDialog type.
41 		WO_STATUS = (1<<8), //!< StatusWindow type.
42 		WO_WORKSPACE_INDICATOR = (1<<9), //!< WorkspaceIndicator type.
43 		WO_SCREEN_HINT = (1<<10), /**< Invisible hint window. */
44 		WO_SEARCH_DIALOG = (1<<11), //!< SearchDialog type
45 		WO_NO_TYPE = 0 //!< No type.
46 	};
47 
48 	PWinObj(bool keyboard_input);
49 	virtual ~PWinObj(void);
50 
51 	//! @brief Returns the focused PWinObj.
getFocusedPWinObj(void)52 	static inline PWinObj *getFocusedPWinObj(void) { return _focused_wo; }
53 	//! @brief Returns the PWinObj representing the root Window.
getRootPWinObj(void)54 	static inline PWinObj *getRootPWinObj(void) { return _root_wo; }
55 	//! @brief Sets the focused PWinObj.
setFocusedPWinObj(PWinObj * wo)56 	static inline void setFocusedPWinObj(PWinObj *wo) { _focused_wo = wo; }
57 	//! @brief Sets the PWinObj representing the root Window.
setRootPWinObj(PWinObj * wo)58 	static inline void setRootPWinObj(PWinObj *wo) { _root_wo = wo; }
59 	//! @brief Checks if focused window is of type
isFocusedPWinObj(Type type)60 	static inline bool isFocusedPWinObj(Type type) {
61 		return _focused_wo ? _focused_wo->getType() == type : false;
62 	}
63 
64 	//! @brief Searches for the PWinObj matching Window win.
65 	//! @param win Window to match PWinObjs against.
66 	//! @return PWinObj pointer on match, else 0.
findPWinObj(Window win)67 	static inline PWinObj *findPWinObj(Window win) {
68 		std::map<Window, PWinObj*>::iterator it(_wo_map.find(win));
69 		return (it != _wo_map.end()) ? it->second : 0;
70 	}
71 
72 	//! @brief Searches in PWinObj list if PWinObj wo exists.
73 	//! @param wo PWinObj to search for.
74 	//! @return true if found, else false.
windowObjectExists(PWinObj * wo)75 	static inline bool windowObjectExists(PWinObj *wo) {
76 		std::vector<PWinObj*>::iterator it =
77 			std::find(_wo_list.begin(), _wo_list.end(), wo);
78 		if (it != _wo_list.end()) {
79 			return true;
80 		}
81 		return false;
82 	}
83 
isSkipEnterAfter(Window win)84 	static bool isSkipEnterAfter(Window win) {
85 		return (win == _win_skip_enter_after
86 			|| (_skip_enter_after != nullptr && *_skip_enter_after == win));
87 	}
88 
setSkipEnterAfter(PWinObj * wo)89 	static void setSkipEnterAfter(PWinObj *wo) {
90 		_win_skip_enter_after = None;
91 		_skip_enter_after = wo;
92 	}
93 
94 	//! @brief Return Window this PWinObj represents.
getWindow(void) const95 	inline Window getWindow(void) const { return _window; }
96 	//! @brief Sets Window this PWinObj represents.
setWindow(Window window)97 	inline void setWindow(Window window) { _window = window; }
98 	//! @brief Returns parent PWinObj.
getParent(void) const99 	inline PWinObj *getParent(void) const { return _parent; }
100 	//! @brief Sets parent PWinObj.
setParent(PWinObj * wo)101 	inline void setParent(PWinObj *wo) { _parent = wo; }
102 	//! @brief Returns type of PWinObj.
getType(void) const103 	inline Type getType(void) const { return _type; }
104 	//! @brief Returns the last activity time for this window
getLastActivity(void) const105 	inline Time getLastActivity(void) const { return _lastActivity; }
106 	//! @brief Sets the last activity time for this window.
setLastActivity(Time lastActivity)107 	inline void setLastActivity(Time lastActivity) {
108 		_lastActivity = lastActivity;
109 	}
110 
addChildWindow(Window win)111 	inline void addChildWindow(Window win) { _wo_map[win] = this; }
removeChildWindow(Window win)112 	inline void removeChildWindow(Window win) { _wo_map.erase(win); }
113 
114 	//! @brief Returns x coordinate of PWinObj.
getX(void) const115 	inline int getX(void) const { return _gm.x; }
116 	//! @brief Returns y coordinate of PWinObj.
getY(void) const117 	inline int getY(void) const { return _gm.y; }
118 	//! @brief Returns right edge x coordinate of PWinObj.
getRX(void) const119 	inline int getRX(void) const { return _gm.x + _gm.width; }
120 	//! @brief Returns bottom edge y coordinate of PWinObj.
getBY(void) const121 	inline int getBY(void) const { return _gm.y + _gm.height; }
122 
123 	//! @brief Returns width of PWinObj.
getWidth(void) const124 	inline uint getWidth(void) const { return _gm.width; }
125 	//! @brief Returns height of PWinObj:
getHeight(void) const126 	inline uint getHeight(void) const { return _gm.height; }
127 
128 	//! @brief Sets gm to geometry of window.
getGeometry(Geometry & gm) const129 	inline void getGeometry(Geometry &gm) const { gm = _gm; }
130 
131 	uint getHead(void);
132 	//! @brief Returns workspace PWinObj is on.
getWorkspace(void) const133 	inline uint getWorkspace(void) const { return _workspace; }
134 	/** @brief Returns layer PWinObj is in. */
getLayer(void) const135 	inline Layer getLayer(void) const { return _layer; }
136 
137 	//! @brief Returns mapped state of PWinObj.
isMapped(void) const138 	inline bool isMapped(void) const { return _mapped; }
139 	//! @brief Returns iconofied state of PWinObj.
isIconified(void) const140 	inline bool isIconified(void) const { return _iconified; }
141 	//! @brief Returns hidden state of PWinObj.
isHidden(void) const142 	inline bool isHidden(void) const { return _hidden; }
143 	//! @brief Returns focused state of PWinObj.
isFocused(void) const144 	inline bool isFocused(void) const { return _focused; }
145 	//! @brief Returns sticky state of PWinObj.
isSticky(void) const146 	inline bool isSticky(void) const { return _sticky; }
147 	//! @brief Returns Focusable state of PWinObj.
isFocusable(void) const148 	inline bool isFocusable(void) const { return _focusable; }
149 	//! @brief Returns true if the PWinObj is interested in keyboard input
isKeyboardInput(void) const150 	inline bool isKeyboardInput(void) const { return _keyboard_input; }
isFullscreen(void) const151 	virtual bool isFullscreen(void) const { return false; }
152 
153 	//! @brief Returns transparency state of PWinObj
isOpaque(void) const154 	inline bool isOpaque(void) const { return _opaque; }
155 	void setOpacity(uint focused, uint unfocused, bool enabled=true);
setOpacity(uint value)156 	inline void setOpacity(uint value) { setOpacity(value, value); }
setOpacity(PWinObj * child)157 	inline void setOpacity(PWinObj *child) {
158 		setOpacity(child->_opacity.focused,
159 			   child->_opacity.unfocused,
160 			   !child->_opaque);
161 	}
162 	void updateOpacity(void);
163 	void setOpaque(bool opaque);
164 
hasShapeRegion(void) const165 	bool hasShapeRegion(void) const { return _shape_bounding; }
166 
167 	// interface
168 	virtual void mapWindow(void);
169 	virtual void mapWindowRaised(void);
170 	virtual void unmapWindow(void);
171 	virtual void iconify(void);
172 	virtual void stick(void);
173 
174 	virtual void move(int x, int y);
175 	virtual void resize(uint width, uint height);
176 	virtual void moveResize(int x, int y, uint width, uint height);
177 
178 	//! @brief Raises PWinObj without respect of layer.
raise(void)179 	virtual void raise(void) { X11::raiseWindow(_window); }
180 	//! @brief Lowers PWinObj without respect of layer.
lower(void)181 	virtual void lower(void) { X11::lowerWindow(_window); }
182 
183 	virtual void setWorkspace(uint workspace);
184 	virtual void setLayer(Layer layer);
185 	virtual void setFocused(bool focused);
186 	virtual void setSticky(bool sticky);
187 
188 	/** Set focusable flag. */
setFocusable(bool focusable)189 	virtual void setFocusable(bool focusable) { _focusable = focusable; }
190 	virtual void setHidden(bool hidden);
191 
192 	virtual void giveInputFocus(void);
193 	virtual void reparent(PWinObj *parent, int x, int y);
194 
195 	virtual bool getSizeRequest(Geometry &request);
196 
197 	// event interface
198 
handleButtonPress(XButtonEvent *)199 	virtual ActionEvent *handleButtonPress(XButtonEvent*) { return nullptr; }
handleButtonRelease(XButtonEvent *)200 	virtual ActionEvent *handleButtonRelease(XButtonEvent*) { return nullptr; }
handleKeyPress(XKeyEvent *)201 	virtual ActionEvent *handleKeyPress(XKeyEvent*) { return nullptr; }
handleKeyRelease(XKeyEvent *)202 	virtual ActionEvent *handleKeyRelease(XKeyEvent*) { return nullptr; }
handleMotionEvent(XMotionEvent *)203 	virtual ActionEvent *handleMotionEvent(XMotionEvent*) { return nullptr; }
handleEnterEvent(XCrossingEvent *)204 	virtual ActionEvent *handleEnterEvent(XCrossingEvent*) { return nullptr; }
handleLeaveEvent(XCrossingEvent *)205 	virtual ActionEvent *handleLeaveEvent(XCrossingEvent*) { return nullptr; }
handleExposeEvent(XExposeEvent *)206 	virtual ActionEvent *handleExposeEvent(XExposeEvent*) { return nullptr; }
handleMapRequest(XMapRequestEvent *)207 	virtual ActionEvent *handleMapRequest(XMapRequestEvent*) { return nullptr; }
handleUnmapEvent(XUnmapEvent *)208 	virtual ActionEvent *handleUnmapEvent(XUnmapEvent*) { return nullptr; }
209 
210 	// operators
211 
212 	//! @brief Operator matching against Window PWinObj represents..
operator ==(const Window & window)213 	virtual bool operator == (const Window &window) {
214 		return (_window == window);
215 	}
216 	//! @brief Operator matching against Window PWinObj represents.
operator !=(const Window & window)217 	virtual bool operator != (const Window &window) {
218 		return (_window != window);
219 	}
220 
221 	// other window commands
222 
223 public:
224 	static PWinObjDeleted pwin_obj_deleted;
225 
226 protected:
227 	static void woListAdd(PWinObj *wo);
228 	static void woListRemove(PWinObj *wo);
229 
230 protected:
231 	Window _window; //!< Window PWinObj represents.
232 	PWinObj *_parent; //!< Parent PWinObj.
233 
234 	Type _type; //!< Type of PWinObj.
235 	Time _lastActivity; //!< Last time PWinObj received input.
236 
237 	// Opacity information
238 	class Opacity {
239 	public:
Opacity(void)240 		Opacity(void)
241 			: current(EWMH_OPAQUE_WINDOW),
242 			  focused(EWMH_OPAQUE_WINDOW),
243 			  unfocused(EWMH_OPAQUE_WINDOW) { }
244 		Cardinal current;
245 		Cardinal focused;
246 		Cardinal unfocused;
247 	} _opacity;
248 	bool _opaque; //!< Opaque set state of PWinObj
249 
250 	Geometry _gm; //!< Geometry of PWinObj (always in absolute coordinates).
251 	uint _workspace; //!< Workspace PWinObj is on.
252 	Layer _layer; //!< Layer PWinObj is in.
253 	bool _mapped:1; //!< Mapped state of PWinObj.
254 	bool _iconified:1; //!< Iconified state of PWinObj.
255 	bool _hidden:1; //!< Hidden state of PWinObj.
256 	bool _focused:1; //!< Focused state of PWinObj.
257 	bool _sticky:1; //!< Sticky state of PWinObj.
258 	bool _focusable:1; //!< Focusable state of PWinObj.
259 	bool _shape_bounding:1; //!< _window has a custom bounding region (shape)
260 	bool _keyboard_input:1; //!< PWinObj is consuming keyboard input.
261 
262 	/**
263 	 * Window to skip (instead of PWinObj), set on PWinObj destructor
264 	 * to preserve skip functionality when PWinObj goes away.
265 	 */
266 	static Window _win_skip_enter_after;
267 	static PWinObj *_skip_enter_after;
268 
269 	static PWinObj *_root_wo; //!< Static root PWinObj pointer.
270 	static PWinObj *_focused_wo; //!< Static focused PWinObj pointer.
271 	static std::vector<PWinObj*> _wo_list; //!< List of PWinObjs.
272 	static std::map<Window, PWinObj*> _wo_map; //!< Mapping of Window to PWinObj
273 };
274 
275 #endif // _PEKWM_PWINOBJ_HH_
276