forked from quickshell/quickshell
		
	core/clock: fix behavior with odd time changes
This commit is contained in:
		
							parent
							
								
									815867c178
								
							
						
					
					
						commit
						1d2bf5d7b4
					
				
					 2 changed files with 29 additions and 25 deletions
				
			
		| 
						 | 
					@ -31,20 +31,25 @@ void SystemClock::setPrecision(SystemClock::Enum precision) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SystemClock::onTimeout() {
 | 
					void SystemClock::onTimeout() {
 | 
				
			||||||
	this->setTime(this->nextTime);
 | 
						this->setTime(this->targetTime);
 | 
				
			||||||
	this->schedule(this->nextTime);
 | 
						this->schedule(this->targetTime);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SystemClock::update() {
 | 
					void SystemClock::update() {
 | 
				
			||||||
	if (this->mEnabled) {
 | 
						if (this->mEnabled) {
 | 
				
			||||||
		this->setTime(QTime::currentTime());
 | 
							this->setTime(QDateTime::fromMSecsSinceEpoch(0));
 | 
				
			||||||
		this->schedule(QTime::currentTime());
 | 
							this->schedule(QDateTime::fromMSecsSinceEpoch(0));
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		this->timer.stop();
 | 
							this->timer.stop();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SystemClock::setTime(QTime time) {
 | 
					void SystemClock::setTime(const QDateTime& targetTime) {
 | 
				
			||||||
 | 
						auto currentTime = QDateTime::currentDateTime();
 | 
				
			||||||
 | 
						auto offset = currentTime.msecsTo(targetTime);
 | 
				
			||||||
 | 
						auto dtime = offset > -500 && offset < 500 ? targetTime : currentTime;
 | 
				
			||||||
 | 
						auto time = dtime.time();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto secondPrecision = this->mPrecision >= SystemClock::Seconds;
 | 
						auto secondPrecision = this->mPrecision >= SystemClock::Seconds;
 | 
				
			||||||
	auto secondChanged = this->setSeconds(secondPrecision ? time.second() : 0);
 | 
						auto secondChanged = this->setSeconds(secondPrecision ? time.second() : 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,34 +62,33 @@ void SystemClock::setTime(QTime time) {
 | 
				
			||||||
	DropEmitter::call(secondChanged, minuteChanged, hourChanged);
 | 
						DropEmitter::call(secondChanged, minuteChanged, hourChanged);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SystemClock::schedule(QTime floor) {
 | 
					void SystemClock::schedule(const QDateTime& targetTime) {
 | 
				
			||||||
	auto secondPrecision = this->mPrecision >= SystemClock::Seconds;
 | 
						auto secondPrecision = this->mPrecision >= SystemClock::Seconds;
 | 
				
			||||||
	auto minutePrecision = this->mPrecision >= SystemClock::Minutes;
 | 
						auto minutePrecision = this->mPrecision >= SystemClock::Minutes;
 | 
				
			||||||
	auto hourPrecision = this->mPrecision >= SystemClock::Hours;
 | 
						auto hourPrecision = this->mPrecision >= SystemClock::Hours;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
setnext:
 | 
						auto currentTime = QDateTime::currentDateTime();
 | 
				
			||||||
	auto nextTime = QTime(
 | 
					
 | 
				
			||||||
	    hourPrecision ? floor.hour() : 0,
 | 
						auto offset = currentTime.msecsTo(targetTime);
 | 
				
			||||||
	    minutePrecision ? floor.minute() : 0,
 | 
					
 | 
				
			||||||
	    secondPrecision ? floor.second() : 0
 | 
						// timer skew
 | 
				
			||||||
 | 
						auto nextTime = offset > 0 && offset < 500 ? targetTime : currentTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto baseTimeT = nextTime.time();
 | 
				
			||||||
 | 
						nextTime.setTime(
 | 
				
			||||||
 | 
						    {hourPrecision ? baseTimeT.hour() : 0,
 | 
				
			||||||
 | 
						     minutePrecision ? baseTimeT.minute() : 0,
 | 
				
			||||||
 | 
						     secondPrecision ? baseTimeT.second() : 0}
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (secondPrecision) nextTime = nextTime.addSecs(1);
 | 
						if (secondPrecision) nextTime = nextTime.addSecs(1);
 | 
				
			||||||
	else if (minutePrecision) nextTime = nextTime.addSecs(60);
 | 
						else if (minutePrecision) nextTime = nextTime.addSecs(60);
 | 
				
			||||||
	else if (hourPrecision) nextTime = nextTime.addSecs(3600);
 | 
						else if (hourPrecision) nextTime = nextTime.addSecs(3600);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto delay = QTime::currentTime().msecsTo(nextTime);
 | 
						auto delay = currentTime.msecsTo(nextTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// If off by more than 2 hours we likely wrapped around midnight.
 | 
						this->timer.start(static_cast<qint32>(delay));
 | 
				
			||||||
	if (delay < -7200000) delay += 86400000;
 | 
						this->targetTime = nextTime;
 | 
				
			||||||
	else if (delay < 0) {
 | 
					 | 
				
			||||||
		// Otherwise its just the timer being unstable.
 | 
					 | 
				
			||||||
		floor = QTime::currentTime();
 | 
					 | 
				
			||||||
		goto setnext;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	this->timer.start(delay);
 | 
					 | 
				
			||||||
	this->nextTime = nextTime;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEFINE_MEMBER_GETSET(SystemClock, hours, setHours);
 | 
					DEFINE_MEMBER_GETSET(SystemClock, hours, setHours);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,11 +59,11 @@ private:
 | 
				
			||||||
	quint32 mMinutes = 0;
 | 
						quint32 mMinutes = 0;
 | 
				
			||||||
	quint32 mSeconds = 0;
 | 
						quint32 mSeconds = 0;
 | 
				
			||||||
	QTimer timer;
 | 
						QTimer timer;
 | 
				
			||||||
	QTime nextTime;
 | 
						QDateTime targetTime;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void update();
 | 
						void update();
 | 
				
			||||||
	void setTime(QTime time);
 | 
						void setTime(const QDateTime& targetTime);
 | 
				
			||||||
	void schedule(QTime floor);
 | 
						void schedule(const QDateTime& targetTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DECLARE_PRIVATE_MEMBER(SystemClock, hours, setHours, mHours, hoursChanged);
 | 
						DECLARE_PRIVATE_MEMBER(SystemClock, hours, setHours, mHours, hoursChanged);
 | 
				
			||||||
	DECLARE_PRIVATE_MEMBER(SystemClock, minutes, setMinutes, mMinutes, minutesChanged);
 | 
						DECLARE_PRIVATE_MEMBER(SystemClock, minutes, setMinutes, mMinutes, minutesChanged);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue