1 //===========================================
2 //  Lumina-DE source code
3 //  Copyright (c) 2017-2018, Ken Moore
4 //  Available under the 3-clause BSD license
5 //  See the LICENSE file for full details
6 //===========================================
7 //  This is a Qt5/Lumina wrapper around native graphics system calls
8 //  It is primarily designed around the creation/modification of instances of
9 //   the "NativeWindowObject" class for passing information around
10 //===========================================
11 #ifndef _LUMINA_DESKTOP_NATIVE_WINDOW_SYSTEM_H
12 #define _LUMINA_DESKTOP_NATIVE_WINDOW_SYSTEM_H
13 
14 #include <NativeWindowObject.h>
15 #include <QObject>
16 #include <QHash>
17 #include <QTimer>
18 
19 
20 class NativeWindowSystem : public QObject{
21 	Q_OBJECT
22 private:
23 	QList<NativeWindowObject*> NWindows;
24 	QList<NativeWindowObject*> TWindows;
25 
26 	//Now define a simple private_objects class so that each implementation
27 	//  has a storage container for defining/placing private objects as needed
28 	class p_objects;
29 	p_objects* obj;
30 
31 	//Internal timers/variables for managing pings
32 	QTimer *pingTimer;
33 	QHash<WId, QDateTime> waitingForPong;
34 
checkPings()35 	void checkPings(){
36 	  QDateTime cur = QDateTime::currentDateTime();
37 	  QList<WId> waiting = waitingForPong.keys();
38 	  for(int i=0; i<waiting.length(); i++){
39 	    if(waitingForPong.value(waiting[i]) < cur){
40 	      waitingForPong.remove(waiting[i]); //Timeout on this window
41 	      if(waitingForPong.isEmpty() && pingTimer!=0){ pingTimer->stop(); }
42 	      NativeWindowObject *win = findWindow(waiting[i]);
43 	      if(win==0){ win = findTrayWindow(waiting[i]); }
44 	      if(win!=0){ win->emit WindowNotResponding(waiting[i]); }
45 	    }
46 	  }
47 	}
48 
49 	//Generic private variables
50 	bool screenLocked;
51 
52 public:
53 	//enum Property{ None, CurrentWorkspace, Workspaces, VirtualRoots, WorkAreas };
54 	enum MouseButton{NoButton, LeftButton, RightButton, MidButton, BackButton, ForwardButton, TaskButton, WheelUp, WheelDown, WheelLeft, WheelRight};
55 
56 	//Simplifications to find an already-created window object
57 	NativeWindowObject* findWindow(WId id, bool checkRelated = true);
58 
59 	NativeWindowObject* findTrayWindow(WId id);
60 	// Since some properties may be easier to update in bulk
61 	//   let the native system interaction do them in whatever logical groups are best
62 	void UpdateWindowProperties(NativeWindowObject* win, QList< NativeWindowObject::Property > props);
63 	void ChangeWindowProperties(NativeWindowObject* win, QList< NativeWindowObject::Property > props, QList<QVariant> vals);
64 
65 	void SetupNewWindow(NativeWindowObject *win);
66 	QImage GetWindowImage(NativeWindowObject *win);
67 	QPixmap GetTrayWindowImage(NativeWindowObject *win);
68 
69 	NativeWindowSystem();
70 	~NativeWindowSystem();
71 
72 	//Overarching start/stop functions
73 	bool start();
74 	void stop();
75 
76 	//General-purpose listing functions
currentWindows()77 	QList<NativeWindowObject*> currentWindows(){ return NWindows; }
currentTrayWindows()78 	QList<NativeWindowObject*> currentTrayWindows(){ return TWindows; }
79 
80 	//Small simplification functions
81 	static Qt::Key KeycodeToQt(int keycode);
82 	static NativeWindowSystem::MouseButton MouseToQt(int button);
83 	void RegisterEventShortcut(Qt::Key key, bool set);
84 	void RegisterEventShortcut(int keycode, bool set);
85 
86 	void raiseWindow(NativeWindowObject *win);
87 	void lowerWindow(NativeWindowObject *win);
88 
89 public slots:
90 	//These are the slots which are typically only used by the desktop system itself or the NativeWindowEventFilter
91 
92 	//This is called by the lock screen to keep the NWS aware of the current status
93 	// it is **NOT** the function to call for the user to actually lock the session (that is in the screensaver/lockscreen class)
ScreenLockChanged(bool lock)94 	 void ScreenLockChanged(bool lock){
95 	  screenLocked = lock;
96 	}
97 
98 	//Root Window property registrations
99 	void RegisterVirtualRoot(WId);
100 	void setRoot_supportedActions();
101 	void setRoot_numberOfWorkspaces(QStringList names);
102 	void setRoot_currentWorkspace(int);
103 	void setRoot_clientList(QList<WId>, bool stackorder = false);
104 	void setRoot_desktopGeometry(QRect);
105 	void setRoot_desktopWorkarea(QList<QRect>);
106 	void setRoot_activeWindow(WId);
107 
108 	//  - Workspaces
109 	int currentWorkspace();
110 	//void GoToWorkspace(int);
111 
112 
113 	//NativeWindowEventFilter interactions
114 	void NewWindowDetected(WId); //will automatically create the new NativeWindow object
115 	void NewTrayWindowDetected(WId); //will automatically create the new NativeWindow object
116 	void WindowCloseDetected(WId); //will update the lists and make changes if needed
117 	void WindowPropertyChanged(WId, NativeWindowObject::Property); //will rescan the window and update the object as needed
118 	void WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>);
119 	void WindowPropertyChanged(WId, NativeWindowObject::Property, QVariant); //will save that property/value to the right object
120 	void WindowPropertiesChanged(WId, QList<NativeWindowObject::Property>, QList<QVariant>);
121 	void RequestPropertyChange(WId, NativeWindowObject::Property, QVariant);
122 	void RequestPropertiesChange(WId, QList<NativeWindowObject::Property>, QList<QVariant>);
123 	void GotPong(WId);
124 
125 	void NewKeyPress(int keycode, WId win = 0);
126 	void NewKeyRelease(int keycode, WId win = 0);
127 	void NewMousePress(int buttoncode, WId win = 0);
128 	void NewMouseRelease(int buttoncode, WId win = 0);
129 	void CheckDamageID(WId);
130 
131 	void RequestReparent(WId, WId, QPoint); //client, parent, relative origin point in parent
132 
133 
134 private slots:
135 	//Internal Admin functions
136 	void verifyWindowExistance();
137 
138 	//These are the slots which are built-in and automatically connected when a new NativeWindow is created
139 	void RequestClose(WId);
140 	void RequestKill(WId);
141 	void RequestPing(WId);
142 
143 	//Window-mgmt functions (see Window-mgmt.cpp for details)
144 	void ArrangeWindows(WId primary, QString type);
145 	void TileWindows(WId primary, QString type);
146 	void CheckWindowPosition(WId id, bool newwindow = false);
147 	void CheckWindowPosition(NativeWindowObject *win, bool newwindow = false);
148 	void arrangeWindows(NativeWindowObject *primary, QString type, bool primaryonly = false);
149 
150 signals:
151 	void NewWindowAvailable(NativeWindowObject*);
152 	void WindowClosed();
153 	void NewTrayWindowAvailable(NativeWindowObject*);
154 	void TrayWindowClosed();
155 	void NewInputEvent(); //a mouse or keypress was detected (lock-state independent);
156 	void KeyPressDetected(WId, Qt::Key); //only emitted if lockstate = false
157 	void KeyReleaseDetected(WId, Qt::Key); //only emitted if lockstate = false
158 	void MousePressDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false
159 	void MouseReleaseDetected(WId, NativeWindowSystem::MouseButton); //only emitted if lockstate = false
160 
161 };
162 
163 #endif
164