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