aboutsummaryrefslogtreecommitdiff
path: root/libLumina/LuminaX11.h
blob: be1ea0696919d3e0af2d1b97dad896c0a3697a21 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
//===========================================
//  Lumina-DE source code
//  Copyright (c) 2014-2015, Ken Moore
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
//  This class governs all the XLib usage and interactions
//  and provides simpler Qt-based functions for use elsewhere
//===========================================
#ifndef _LUMINA_LIBRARY_X11_H
#define _LUMINA_LIBRARY_X11_H

//Qt includes
#include <QList>
#include <QString>
#include <QPixmap>
#include <QImage>
#include <QIcon>
#include <QPixmap>
#include <QX11Info>
#include <QDebug>
#include <QPainter>
#include <QObject>
#include <QFlags>


#include <xcb/xcb_ewmh.h>

//SYSTEM TRAY STANDARD DEFINITIONS
#define _NET_SYSTEM_TRAY_ORIENTATION_HORZ 0
#define _NET_SYSTEM_TRAY_ORIENTATION_VERT 1
#define SYSTEM_TRAY_REQUEST_DOCK 0
#define SYSTEM_TRAY_BEGIN_MESSAGE 1
#define SYSTEM_TRAY_CANCEL_MESSAGE 2

#define URGENCYHINT (1L << 8) //For window urgency detection

//XCB Library replacement for LX11 (Qt5 uses XCB instead of XLib)
class LXCB{
	
public:
	enum WINDOWSTATE {IGNORE, INVISIBLE, VISIBLE, ACTIVE, ATTENTION}; //note that this in order of priority
	enum ICCCM_STATE {WITHDRAWN, NORMAL, ICONIC};
	enum GRAVITY {FORGET=0, NW=1, N=2, NE=3, W=4, CENTER=5, E=6, SW=7, S=8, SE=9, STATIC=10};
	enum STACK_FLAG {ABOVE=0, BELOW=1, TOP_IF=2, BOTTOM_IF=3, OPPOSITE=4};
	//Now enums which can have multiple values at once (Use the plural form for the QFlags)
	enum ICCCM_PROTOCOL {TAKE_FOCUS = 0x0, DELETE_WINDOW = 0x1}; //any combination 
	Q_DECLARE_FLAGS(ICCCM_PROTOCOLS, ICCCM_PROTOCOL);
	enum MOVERESIZE_WINDOW_FLAG { X=0x0, Y=0x1, WIDTH=0x2, HEIGHT=0x3};
	Q_DECLARE_FLAGS(MOVERESIZE_WINDOW_FLAGS, MOVERESIZE_WINDOW_FLAG);
	
	xcb_ewmh_connection_t EWMH; //This is where all the screen info and atoms are located

	LXCB();
	~LXCB();
		
	//== Main Interface functions ==
	// General Information
	QList<WId> WindowList(bool rawlist = false); //list all non-Lumina windows (rawlist -> all workspaces)
	unsigned int CurrentWorkspace();
	unsigned int NumberOfWorkspaces();
	WId ActiveWindow(); //fetch the ID for the currently active window
	
	//Session Modification
	bool CheckDisableXinerama(); //returns true if Xinerama was initially set but now disabled
	void RegisterVirtualRoots(QList<WId> roots);
	void SetCurrentWorkspace(int);

	//Window Information
	QString WindowClass(WId);
	unsigned int WindowWorkspace(WId); //The workspace the window is on
	QRect WindowGeometry(WId win, bool includeFrame = true); //the geometry of the window (frame excluded)
	QList<int> WindowFrameGeometry(WId win); //Returns: [top,bottom,left,right] sizes of the frame
	WINDOWSTATE WindowState(WId win); //Visible state of window
	QString WindowVisibleIconName(WId win); //_NET_WM_VISIBLE_ICON_NAME
	QString WindowIconName(WId win); //_NET_WM_ICON_NAME
	QString WindowVisibleName(WId win); //_NET_WM_VISIBLE_NAME
	QString WindowName(WId win); //_NET_WM_NAME
	QString OldWindowName(WId win); //WM_NAME (old standard)
	QString OldWindowIconName(WId win); //WM_ICON_NAME (old standard)
	bool WindowIsMaximized(WId win);
	int WindowIsFullscreen(WId win); //Returns the screen number if the window is fullscreen (or -1)
	QIcon WindowIcon(WId win); //_NET_WM_ICON
	
	//Window Modification
	// - SubStructure simplifications (not commonly used)
	void SelectInput(WId); //XSelectInput replacement (to see window events)
	uint GenerateDamageID(WId);
	
	// - General Window Modifications
	void SetAsSticky(WId); //Stick to all workspaces
	void SetDisableWMActions(WId); //Disable WM control (shortcuts/automatic functions)
	void SetAsPanel(WId); //Adjust all the window flags for a proper panel (cannot be done through Qt)
	void SetAsDesktop(WId); //Adjust window flags to set as the desktop
	void CloseWindow(WId); //request that the window be closed
	void KillClient(WId); //Force the application that created the window to close
	void MinimizeWindow(WId); //request that the window be unmapped/minimized
	void ActivateWindow(WId); //request that the window become active
	void RestoreWindow(WId); //Re-map/raise the window
	void MaximizeWindow(WId win, bool flagsonly = false); //request that the window become maximized
	void MoveResizeWindow(WId win, QRect geom);
	void ResizeWindow(WId win, int width, int height);
	void ResizeWindow(WId win, QSize sz){ ResizeWindow(win, sz.width(), sz.height()); } //overload for simplicity
	void ReserveLocation(WId win, QRect geom, QString loc);
	
	//Window Embedding/Detaching (for system tray)
	//void SetWindowBackground(QWidget *parent, QRect area, WId client);
	uint EmbedWindow(WId win, WId container); //returns the damage ID (or 0 for an error)
	bool UnembedWindow(WId win);
	QPixmap TrayImage(WId win);
	
	//System Tray Management
	WId startSystemTray(int screen = 0); //Startup the system tray (returns window ID for tray)
	void closeSystemTray(WId); //Close the system tray

	
	//============
	// WM Functions (directly changing properties/settings)
	//  - Using these directly may prevent the WM from seeing the change
	//============
	void WM_CloseWindow(WId win);
	
	// ICCCM Standards (older standards)
	// -- WM_NAME
	QString WM_ICCCM_GetName(WId win);
	void WM_ICCCM_SetName(WId win, QString name);
	// -- WM_ICON_NAME
	QString WM_ICCCM_GetIconName(WId win);
	void WM_ICCCM_SetIconName(WId win, QString name);
	// --- WM_CLIENT_MACHINE
	QString WM_ICCCM_GetClientMachine(WId win);
	void WM_ICCCM_SetClientMachine(WId win, QString name);
	// -- WM_CLASS
	QString WM_ICCCM_GetClass(WId win); //Returns: "<instance name>::::<class name>"
	void WM_ICCCM_SetClass(WId win, QString name);
	// -- WM_TRANSIENT_FOR
	WId WM_ICCCM_GetTransientFor(WId win); //Returns "win" for errors or no transient
	void WM_ICCCM_SetTransientFor(WId win, WId transient);
	// -- WM_SIZE_HINTS
	
	// -- WM_NORMAL_HINTS
	
	// -- WM_HINTS
	
	// -- WM_PROTOCOLS
	ICCCM_PROTOCOLS WM_ICCCM_GetProtocols(WId win);
	void WM_ICCCM_SetProtocols(WId win, ICCCM_PROTOCOLS flags);
	
	//NET_WM Standards (newer standards)
	
	// -- ROOT WINDOW PROPERTIES
	// _NET_SUPPORTED
	void WM_Set_Root_Supported(); //set the atom list of supported features on the root window
	// _NET_CLIENT_LIST
	// Note: client list ordered oldest->newest, stacking list ordered bottom->top
	QList<WId> WM_Get_Client_List(bool stacking = false);
	void WM_Set_Client_List(QList<WId> list, bool stacking=false);
	
	// _NET_NUMBER_OF_DESKTOPS
	// Note: This is the number of virtual workspaces, not monitors
	unsigned int WM_Get_Number_Desktops(); //return value equals 0 for errors
	void WM_SetNumber_Desktops(unsigned int number); //should be at least 1
	
	// _NET_DESKTOP_GEOMETRY
	// Note: This property is the combined size and/or bounding rectangle of all monitors
	//  The definition works well for single-monitors, but gets really fuzzy for multiple monitors
	QSize WM_Get_Desktop_Geometry();
	void WM_Set_Desktop_Geometry(QSize);
	
	// _NET_DESKTOP_VIEWPORT
	// Note: This is the X/Y origin  of the viewport for each monitor 
	//  Thi is normally (0,0) , unless desktop larger than monitor supports
	QList<QPoint> WM_Get_Desktop_Viewport();
	void WM_Set_Desktop_Viewport(QList<QPoint> list);
	
	// _NET_CURRENT_DESKTOP
	// Note: Current workspace number. Range = 0 to (_NET_NUMBER_OF_DESKTOPS - 1)
	int WM_Get_Current_Desktop(); //Returns -1 for errors
	void WM_Set_Current_Desktop(unsigned int num);
	
	// _NET_DESKTOP_NAMES
	QStringList WM_Get_Desktop_Names();
	void WM_Set_Desktop_Names(QStringList list);
	
	// _NET_ACTIVE_WINDOW
	WId WM_Get_Active_Window();
	void WM_Set_Active_Window(WId win);
	
	// _NET_WORKAREA
	// Note: The workarea is the recangle for each monitor where no space is reserved
	//  This accounts for any STRUT's that are set, within the current VIEWPORT
	QList<QRect> WM_Get_Workarea();
	void WM_Set_Workarea(QList<QRect> list);
	
	// _NET_SUPPORTING_WM_CHECK
	// Note: This needs to be set on two windows: root -> child, and child->child
	// So the "set" function will do both at the same time
	// The child window also needs the _NET_WM_NAME set to the window manager name
	WId WM_Get_Supporting_WM(WId win);
	void WM_Set_Supporting_WM(WId child);
	
	// _NET_VIRTUAL_ROOTS
	QList<WId> WM_Get_Virtual_Roots();
	void WM_Set_Virtual_Roots(QList<WId> list);
	
	// _NET_DESKTOP_LAYOUT
	// NOTE: Skip this implementation for now - is supposed to be set by a pager (not the WM)
	//   and the WM can choose to use/ignore it as necessary.
	// (Just use the current XRandR layout instead of this setting/property)
	
	// _NET_SHOWING_DESKTOP
	// Note: This is true/false depending on whether the WM is hiding all windows to show the desktop only
	bool WM_Get_Showing_Desktop();
	void WM_Set_Showing_Desktop(bool show);
	
	// -- ROOT WINDOW MESSAGES/REQUESTS (for non-WM usage)
	// _NET_CLOSE_WINDOW
	void WM_Request_Close_Window(WId win);
	
	// _NET_MOVERESIZE_WINDOW
	// Note: Used for finalized movement/resize operations
	void WM_Request_MoveResize_Window(WId win, QRect geom, bool fromuser = false,  LXCB::GRAVITY grav = LXCB::STATIC, LXCB::MOVERESIZE_WINDOW_FLAGS flags = LXCB::MOVERESIZE_WINDOW_FLAGS(LXCB::X | LXCB::Y | LXCB::WIDTH | LXCB::HEIGHT) );
	
	// _NET_WM_MOVERESIZE 
	// Note: Used for interactive clicks/changes to a window size/position
	// There are known race conditions/issues with this X format - so skip it for now (11/12/15)
	
	// _NET_RESTACK_WINDOW
	// Note: Send a request to re-stack a window (win) with respect to another window (sibling)
	//   based on the flag to determine how the stack order should be changed
	void WM_Request_Restack_Window(WId win, WId sibling, LXCB::STACK_FLAG flag);
	
	// _NET_REQUEST_FRAME_EXTENTS
	// Note: This is used by client windows to get the _NET_FRAME_EXTENTS property pre-set
	//  by the WM before the window is actually mapped (just an estimate of the frame at least)
	void WM_Request_Frame_Extents(WId win);
	
	// -- WINDOW PROPERTIES
	// _NET_SUPPORTED
	void WM_Set_Window_Supported(WId win); //set the atom list of supported features on the given window
	// _NET_WM_NAME
	
	// _NET_WM_VISIBLE_NAME
	
	// _NET_WM_ICON_NAME
	
	// _NET_WM_VISIBLE_ICON_NAME
	
	// _NET_WM_DESKTOP
	
	// _NET_WM_WINDOW_TYPE
	
	// _NET_WM_STATE
	
	// _NET_WM_ALLOWED_ACTIONS
	
	// _NET_WM_STRUT
	
	// _NET_WM_STRUT_PARTIAL
	
	// _NET_WM_ICON_GEOMETRY
	
	// _NET_WM_ICON
	
	// _NET_WM_PID
	
	// _NET_WM_HANDLED_ICONS
	
	// _NET_WM_USER_TIME
	
	// _NET_WM_USER_TIME_WINDOW
	
	// _NET_FRAME_EXTENTS
	
	// _NET_WM_OPAQUE_REGION
	
	// _NET_WM_BYPASS_COMPOSITOR
	
	
private:
	QList<xcb_atom_t> ATOMS;
	QStringList atoms;

	void createWMAtoms(); //fill the private lists above
};
//Now also declare the flags for Qt to use
Q_DECLARE_OPERATORS_FOR_FLAGS(LXCB::ICCCM_PROTOCOLS);
Q_DECLARE_OPERATORS_FOR_FLAGS(LXCB::MOVERESIZE_WINDOW_FLAGS);

#endif
bgstack15