1 //===========================================
2 // Lumina-DE source code
3 // Copyright (c) 2015, Ken Moore
4 // Available under the 3-clause BSD license
5 // See the LICENSE file for full details
6 //===========================================
7 #include "LScreenSaver.h"
8 #include <QScreen>
9 #include <QApplication>
10
11 #define DEBUG 0
12
LScreenSaver()13 LScreenSaver::LScreenSaver() : QWidget(0,Qt::BypassWindowManagerHint | Qt::WindowStaysOnTopHint){
14 starttimer = new QTimer(this);
15 starttimer->setSingleShot(true);
16 locktimer = new QTimer(this);
17 locktimer->setSingleShot(true);
18 hidetimer = new QTimer(this);
19 hidetimer->setSingleShot(true);
20 mouseCheckTimer = new QTimer(this);
21 mouseCheckTimer->setInterval(10000); //10 seconds - fallback timer for mouse movement detection
22
23 LOCKER = new LLockScreen(this);
24 LOCKER->hide();
25 SSRunning = SSLocked = updating = false;
26 this->setObjectName("LSCREENSAVERBASE");
27 this->setStyleSheet("LScreenSaver#LSCREENSAVERBASE{ background: grey; }");
28 this->setMouseTracking(true);
29 connect(starttimer, SIGNAL(timeout()), this, SLOT(ShowScreenSaver()) );
30 connect(locktimer, SIGNAL(timeout()), this, SLOT(LockScreen()) );
31 connect(hidetimer, SIGNAL(timeout()), this, SLOT(HideLockScreen()) );
32 connect(mouseCheckTimer, SIGNAL(timeout()), this, SLOT(checkMousePosition()) );
33 connect(LOCKER, SIGNAL(ScreenUnlocked()), this, SLOT(SSFinished()) );
34 connect(LOCKER, SIGNAL(InputDetected()), this, SLOT(newInputEvent()) );
35 }
36
~LScreenSaver()37 LScreenSaver::~LScreenSaver(){
38
39 }
40
isLocked()41 bool LScreenSaver::isLocked(){
42 return SSLocked;
43 }
44
UpdateTimers()45 void LScreenSaver::UpdateTimers(){
46 //This is generally used for programmatic changes
47 if(starttimer->isActive()){ starttimer->stop();}
48 if(locktimer->isActive()){ locktimer->stop(); }
49 if(hidetimer->isActive()){ hidetimer->stop(); }
50
51 if(!SSRunning && !SSLocked && (starttimer->interval() > 1000) ){ starttimer->start(); } //time to SS start
52 else if( SSRunning && !SSLocked && (locktimer->interval() > 1000 ) ){ locktimer->start(); } //time to lock
53 else if( !SSRunning && SSLocked ){ hidetimer->start(); } //time to hide lock screen
54 }
55
56 // ===========
57 // PUBLIC SLOTS
58 // ===========
start()59 void LScreenSaver::start(){
60 reloadSettings(); //setup all the initial time frames
61 starttimer->start();
62 mouseCheckTimer->start();
63 }
64
reloadSettings()65 void LScreenSaver::reloadSettings(){
66 starttimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "timedelaymin",10).toInt() * 60000 );
67 locktimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "lockdelaymin",1).toInt() * 60000 );
68 hidetimer->setInterval( DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "hidesecs",15).toInt() * 1000 );
69 }
70
newInputEvent()71 void LScreenSaver::newInputEvent(){
72 if(updating){ return; } //in the middle of making changes which could cause an event
73 if(DEBUG){ qDebug() << "New Input Event"; }
74 if(SSRunning && SSLocked){
75 //Running and locked
76 // Hide the running setting, and display the lock screen
77 HideScreenSaver();
78 ShowLockScreen();
79 }else if(SSRunning){
80 //Only running, not locked
81 HideScreenSaver();
82 }
83 lastMousePos = QCursor::pos(); //update the internal point
84 UpdateTimers();
85 }
86
LockScreenNow()87 void LScreenSaver::LockScreenNow(){
88 ShowScreenSaver();
89 LockScreen();
90 }
91
92 // ===========
93 // PRIVATE SLOTS
94 // ===========
checkMousePosition()95 void LScreenSaver::checkMousePosition(){
96 QPoint pos = QCursor::pos();
97 if(pos != lastMousePos){
98 newInputEvent(); //this will update the internal position automatically
99 }
100 }
101
ShowScreenSaver()102 void LScreenSaver::ShowScreenSaver(){
103 if(DEBUG){ qDebug() << "Showing Screen Saver:" << QDateTime::currentDateTime().toString(); }
104 //QApplication::setOverrideCursor(QCursor::BlankCursor);
105 SSRunning = true;
106 updating = true;
107 //Now remove any current Base widgets (prevent any lingering painting between sessions)
108 for(int i=0; i<BASES.length(); i++){
109 if(DEBUG){ qDebug() << " - Removing SS Base"; }
110 delete BASES.takeAt(i); i--;
111 }
112 //Now go through and create/show all the various widgets
113 QList<QScreen*> SCREENS = QApplication::screens();
114 QRect bounds;
115 //cBright = LOS::ScreenBrightness();
116 //if(cBright>0){ LOS::setScreenBrightness(cBright/2); } //cut to half while the screensaver is active
117 for(int i=0; i<SCREENS.length(); i++){
118 bounds = bounds.united(SCREENS[i]->geometry());
119 if(DEBUG){ qDebug() << " - New SS Base:" << i; }
120 BASES << new SSBaseWidget(this);
121 connect(BASES[i], SIGNAL(InputDetected()), this, SLOT(newInputEvent()) );
122
123 //Setup the geometry of the base to match the screen
124 BASES[i]->setGeometry(SCREENS[i]->geometry()); //match this screen geometry
125 QString plug = DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "plugin_"+SCREENS[i]->name(), "").toString();
126 if(plug.isEmpty()){ plug = DesktopSettings::instance()->value(DesktopSettings::ScreenSaver, "default_plugin","random").toString(); }
127 BASES[i]->setPlugin(plug);
128 }
129 //Now set the overall parent widget geometry and show everything
130 this->setGeometry(bounds); //overall background widget
131 if(!this->isActiveWindow()){
132 this->raise();
133 this->show();
134 this->activateWindow();
135 }
136 for(int i=0; i<BASES.length(); i++){
137 BASES[i]->show();
138 BASES[i]->startPainting();
139 }
140 updating = false;
141 UpdateTimers();
142 }
143
ShowLockScreen()144 void LScreenSaver::ShowLockScreen(){
145 if(DEBUG){ qDebug() << "Showing Lock Screen:" << QDateTime::currentDateTime().toString(); }
146 LOCKER->aboutToShow();
147 //Move the screen locker to the appropriate spot
148 QPoint ctr = QApplication::desktop()->screenGeometry(QCursor::pos()).center();
149 LOCKER->resize(LOCKER->sizeHint());
150 LOCKER->move(ctr - QPoint(LOCKER->width()/2, LOCKER->height()/2) );
151 LOCKER->show();
152 //Start the timer for hiding the lock screen due to inactivity
153 UpdateTimers();
154 }
155
HideScreenSaver()156 void LScreenSaver::HideScreenSaver(){
157 //QApplication::restoreOverrideCursor();
158 if(DEBUG){ qDebug() << "Hiding Screen Saver:" << QDateTime::currentDateTime().toString(); }
159 SSRunning = false;
160 //if(cBright>0){ LOS::setScreenBrightness(cBright); } //return to current brightness
161 if(!SSLocked){
162 this->hide();
163 emit ClosingScreenSaver();
164 emit LockStatusChanged(false);
165 }
166 if(DEBUG){ qDebug() << "Stop ScreenSavers"; }
167 for(int i=0; i<BASES.length(); i++){
168 BASES[i]->stopPainting();
169 BASES[i]->hide();
170 BASES.takeAt(i)->deleteLater();
171 i--;
172 }
173 UpdateTimers();
174 }
175
HideLockScreen()176 void LScreenSaver::HideLockScreen(){
177 if(DEBUG){ qDebug() << "Hiding Lock Screen:" << QDateTime::currentDateTime().toString(); }
178 //Leave the Locked flag set (still locked, just not visible)
179 LOCKER->aboutToHide();
180 LOCKER->hide();
181 this->repaint();
182 if(SSLocked){ ShowScreenSaver(); }
183 UpdateTimers();
184 }
185
LockScreen()186 void LScreenSaver::LockScreen(){
187 if(SSLocked){ return; }
188 if(DEBUG){ qDebug() << "Locking Screen:" << QDateTime::currentDateTime().toString(); }
189 SSLocked = true;
190 emit LockStatusChanged(true);
191 LOCKER->LoadSystemDetails();
192 UpdateTimers();
193 }
194
SSFinished()195 void LScreenSaver::SSFinished(){
196 if(DEBUG){ qDebug() << "Screensaver Finished:" << QDateTime::currentDateTime().toString(); }
197 SSLocked = false;
198 emit LockStatusChanged(false);
199 HideLockScreen();
200 HideScreenSaver();
201 }
202