1 //===========================================
2 // Lumina-desktop 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 #include "DesktopManager.h"
8
9 #include "global-objects.h"
10
11 #ifdef USE_WIDGETS
12 #include "src-widgets/NativeWindow.h"
13 #endif
14
15 // === PUBLIC ===
DesktopManager()16 DesktopManager::DesktopManager(){
17
18 }
19
~DesktopManager()20 DesktopManager::~DesktopManager(){
21
22 }
23
start()24 void DesktopManager::start(){
25 connect(DesktopSettings::instance(), SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(settingsChanged(DesktopSettings::File)) );
26 //Perform the initial load of the settings files
27 QTimer::singleShot(0, this, SLOT(updateSessionSettings()) );
28 QTimer::singleShot(0, this, SLOT(updateDesktopSettings()) );
29 QTimer::singleShot(0, this, SLOT(updatePanelSettings()) );
30 QTimer::singleShot(0, this, SLOT(updatePluginSettings()) );
31 QTimer::singleShot(0, this, SLOT(updateMenuSettings()) );
32 QTimer::singleShot(0, this, SLOT(updateAnimationSettings()) );
33 }
34
stop()35 void DesktopManager::stop(){
36 disconnect(DesktopSettings::instance(), SIGNAL(FileModified(DesktopSettings::File)), this, SLOT(settingsChanged(DesktopSettings::File)) );
37 }
38
39 // === PRIVATE ===
updateWallpaper(QString screen_id,int wkspace)40 void DesktopManager::updateWallpaper(QString screen_id, int wkspace){
41 QString current = RootDesktopObject::instance()->CurrentWallpaper(screen_id);
42 if(!current.isEmpty()){ current = QUrl(current).toLocalFile(); } //convert it back to the normal file syntax
43 //First find the list of options from the settings
44 //First look for a list that matches this exact screen/workspace combo
45 QStringList wpaperList = DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id+"_wk_"+QString::number(wkspace), QStringList()).toStringList();
46 //Next look for a list that matches this exact workspace
47 if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default_wk_"+QString::number(wkspace), QStringList()).toStringList(); }
48 wpaperList.removeAll("");
49 //Next look for a list that matches this exact screen
50 if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/"+screen_id, QStringList()).toStringList(); }
51 wpaperList.removeAll("");
52 //Now look for a list that matches any screen/workspace
53 if(wpaperList.isEmpty()){ wpaperList= DesktopSettings::instance()->value(DesktopSettings::Desktop, "wallpapers/default", QStringList()).toStringList(); }
54 wpaperList.removeAll("");
55 //Now use the failover wallpaper directory
56 if(wpaperList.isEmpty()){
57 QString def = LOS::LuminaShare().section("/",0,-3)+"/wallpapers/lumina-nature"; //Note: LuminaShare() ends with an extra "/"
58 //qDebug() << "Default Wallpaper:" << def;
59 if(QFile::exists(def)){ wpaperList << def; }
60 }
61 //qDebug() << "Got wallpaper list:" << screen_id << wkspace << wpaperList;
62 //Wallpaper selection/randomization
63 if(wpaperList.count()==1 && wpaperList.first()==current){ return; } //nothing to do - just the same image
64 QString wpaper;
65 QStringList bgL = wpaperList; //need a copy at the moment - could change the entire list in a second (opening a dir for instance)
66 while(wpaper.isEmpty() || QFileInfo(wpaper).isDir()){
67 QString prefix;
68 if(!wpaper.isEmpty()){
69 //Got a directory - update the list of files and re-randomize the selection
70 QStringList imgs = LUtils::imageExtensions(true);
71 //qDebug() << " - Got Dir: " << imgs;
72 QDir tdir(wpaper);
73 prefix=wpaper+"/";
74 bgL = tdir.entryList(imgs, QDir::Files | QDir::NoDotAndDotDot, QDir::Name);
75 //If directory no longer has any valid images - remove it from list and try again
76 if(bgL.isEmpty()){
77 wpaperList.removeAll(wpaper); //invalid directory - remove it from the list for the moment
78 bgL = wpaperList; //reset the list back to the original list (not within a directory)
79 }
80 }
81 //Verify that there are files in the list - otherwise use the default
82 if(bgL.isEmpty()){ wpaper.clear(); break; }
83 int index = ( qrand() % bgL.length() );
84 if(index== bgL.indexOf(current)){ //if the current wallpaper was selected by the randomization again
85 //Go to the next in the list
86 if(index < 0 || index >= bgL.length()-1){ index = 0; } //if invalid or last item in the list - go to first
87 else{ index++; } //go to next
88 }
89 wpaper = prefix+bgL[index];
90 }
91 //Now go ahead and set the wallpaper in the screen object
92 if(wpaper.isEmpty() || wpaper=="default"){ wpaper = LOS::LuminaShare()+"/desktop-background.jpg"; } //failover image
93 //qDebug() << "Updating Wallpaper:" << screen_id << wpaper;
94 RootDesktopObject::instance()->ChangeWallpaper(screen_id,QUrl::fromLocalFile(wpaper).toString() );
95 }
96
updatePlugins(QString plugin_id)97 void DesktopManager::updatePlugins(QString plugin_id){
98
99 }
100
101 // === PUBLIC SLOTS ===
workspaceChanged(int wknum)102 void DesktopManager::workspaceChanged(int wknum){
103 //qDebug() << "Got Workspace Changed:" << wknum;
104 syncWindowList();
105 }
106
settingsChanged(DesktopSettings::File type)107 void DesktopManager::settingsChanged(DesktopSettings::File type){
108 switch(type){
109 case DesktopSettings::Session:
110 QTimer::singleShot(0, this, SLOT(updateSessionSettings()) );
111 case DesktopSettings::Desktop:
112 QTimer::singleShot(1, this, SLOT(updateDesktopSettings()) );
113 case DesktopSettings::Panels:
114 QTimer::singleShot(2, this, SLOT(updatePanelSettings()) );
115 case DesktopSettings::Plugins:
116 QTimer::singleShot(3, this, SLOT(updatePluginSettings()) );
117 case DesktopSettings::ContextMenu:
118 QTimer::singleShot(4, this, SLOT(updateMenuSettings()) );
119 case DesktopSettings::Animation:
120 QTimer::singleShot(5, this, SLOT(updateAnimationSettings()) );
121 default:
122 break;
123 //Do nothing - not a settings change we care about here
124 }
125 }
126
NewWindowAvailable(NativeWindowObject * win)127 void DesktopManager::NewWindowAvailable(NativeWindowObject* win){
128 //connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(syncWindowList()) );
129 #ifdef USE_WIDGETS
130 qDebug() << "Got New Widget Window:" << win->name();
131 NativeWindow *tmp = new NativeWindow(win);
132 //qDebug() << " - Embed Into frame:" << tmp->relativeOrigin();
133 //Lumina::NWS->RequestReparent(win->id(), win->frameId(), tmp->relativeOrigin());
134 QTimer::singleShot(10, tmp, SLOT(initProperties()) );
135 #endif
136 syncWindowList();
137 }
138
NewTrayWindowAvailable(NativeWindowObject * win)139 void DesktopManager::NewTrayWindowAvailable(NativeWindowObject* win){
140 //connect(win, SIGNAL(WindowClosed(WId)), this, SLOT(syncTrayWindowList()) );
141 syncTrayWindowList();
142 }
143
syncWindowList()144 void DesktopManager::syncWindowList(){
145 QList<NativeWindowObject*> allWins = Lumina::NWS->currentWindows();
146 //Filter out all the windows not in the current workspace
147 QList<NativeWindowObject*> current;
148 QList<NativeWindowObject*> currentStacked;
149 int wkspace = Lumina::NWS->currentWorkspace();
150 for(int i=0; i<allWins.length(); i++){
151 if(allWins[i]->isSticky() || (allWins[i]->workspace() == wkspace)){
152 current << allWins[i];
153 }
154 }
155 //qDebug() << "Synced Window List:" << current.length();
156 RootDesktopObject::instance()->setWindows(current);
157 }
158
syncTrayWindowList()159 void DesktopManager::syncTrayWindowList(){
160 QList<NativeWindowObject*> allWins = Lumina::NWS->currentTrayWindows();
161 //qDebug() << "Synced Tray Window List:" << allWins.length();
162 RootDesktopObject::instance()->setTrayWindows(allWins);
163 }
164
165 // === PRIVATE SLOTS ===
updateSessionSettings()166 void DesktopManager::updateSessionSettings(){
167 //qDebug() << "Update Session Settings...";
168
169 RootDesktopObject::instance()->updateCurrentTimeFormat(DesktopSettings::instance()->value(DesktopSettings::Session, "datetime_format", "").toString());
170 }
171
updateDesktopSettings()172 void DesktopManager::updateDesktopSettings(){
173 //qDebug() << "Update Desktop Settings...";
174 QList<QScreen*> scrns = QGuiApplication::screens();
175 int wkspace = Lumina::NWS->currentWorkspace();
176 for(int i=0; i<scrns.length(); i++){ updateWallpaper(scrns[i]->name(), wkspace); }
177
178 }
179
updatePanelSettings()180 void DesktopManager::updatePanelSettings(){
181 QList<QScreen*> scrns = QGuiApplication::screens();
182 int primary = QApplication::desktop()->primaryScreen();
183 //qDebug() << "Panel Settings Changed:" << primary << scrns.length();
184 QStringList total_ids;
185 for(int i=0; i<scrns.length(); i++){
186 //qDebug() << " - Check Screen Name:" << scrns[i]->name();
187 ScreenObject *sObj = RootDesktopObject::instance()->screen(scrns[i]->name());
188 if(sObj == 0){ continue; } //screen is not managed directly - skip it
189 QStringList ids = DesktopSettings::instance()->value(DesktopSettings::Panels, scrns[i]->name().replace("-","_")+"/active_ids", QStringList()).toStringList();
190 if(ids.isEmpty() && (scrns.length()==1 || i==primary)){
191 //qDebug() << " -- PRIMARY";
192 //Also look for the "default" panel id's for the primary/default screen
193 ids = DesktopSettings::instance()->value(DesktopSettings::Panels, "default/active_ids", QStringList()).toStringList();
194 }
195 ids.removeAll("");
196 //qDebug() << " -- settings:" << ids;
197 for(int j=0; j<ids.length(); j++){
198 total_ids << scrns[i]->name()+"/"+ids[j];
199 }
200 }
201 //Now do the global-session panels
202 QStringList ids = DesktopSettings::instance()->value(DesktopSettings::Panels, "session/active_ids", QStringList()).toStringList();
203 ids.removeAll("");
204 for(int i=0; i<ids.length(); i++){
205 total_ids << "session/"+ids[i];
206 }
207 //qDebug() << "Panel Settings Changed:" << total_ids;
208 RootDesktopObject::instance()->setPanels(total_ids); //put the new ones in place
209 QTimer::singleShot(500, this, SLOT(updatePanelReservations()) );
210 }
211
updatePanelReservations()212 void DesktopManager::updatePanelReservations(){
213 /*QRect raw_session, reserved_session;
214 QList<ScreenObject*> screens = RootDesktopObject::instance()->screenObjects();
215 //Calculate the total session rectangle and session panel reservations
216 QList<PanelObject*> tmp = RootDesktopObject::instance()->panelObjectList();
217 for(int i=0; i<screens.length(); i++){
218 raw_session = raw_session.united(screens[i]->geometry());
219 }
220 for(int i=0; i<tmp.length(); i++){
221 reserved_session =
222 }
223 //Go through all the panels and calculate the current screen reservations
224 */
225
226
227 }
228
updatePluginSettings()229 void DesktopManager::updatePluginSettings(){
230
231 }
232
updateMenuSettings()233 void DesktopManager::updateMenuSettings(){
234
235 }
236
updateAnimationSettings()237 void DesktopManager::updateAnimationSettings(){
238
239 }
240