time: Calculate period to wait on each iteration (#237)
Computing the delay only once won't work; it has to be be done each time to stay properly in sync. The time widget should now reliably update at the minute. Co-authored-by: Michael Murphy <michael@mmurphy.dev>
This commit is contained in:
parent
43de23e94a
commit
fee7eefe5b
3 changed files with 22 additions and 22 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1035,6 +1035,7 @@ dependencies = [
|
|||
"nix 0.26.4",
|
||||
"once_cell",
|
||||
"rust-embed 6.8.1",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,9 @@ license = "GPL-3.0-or-later"
|
|||
icon-loader = { version = "0.3.6", features = ["gtk"] }
|
||||
libcosmic.workspace = true
|
||||
nix = "0.26.2"
|
||||
chrono = { version = "0.4.23", features = ["clock"] }
|
||||
chrono = { version = "0.4.34", features = ["clock"] }
|
||||
once_cell = "1"
|
||||
tokio = { version = "1.36.0", features = ["time"] }
|
||||
tracing.workspace = true
|
||||
|
||||
# Application i18n
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use cosmic::applet::{menu_button, padded_control};
|
|||
use cosmic::cctk::sctk::reexports::calloop;
|
||||
use cosmic::iced::wayland::popup::{destroy_popup, get_popup};
|
||||
use cosmic::iced::{
|
||||
time,
|
||||
subscription,
|
||||
widget::{column, row, text, vertical_space},
|
||||
window, Alignment, Length, Rectangle, Subscription,
|
||||
};
|
||||
|
|
@ -15,7 +15,7 @@ use cosmic::{
|
|||
Element, Theme,
|
||||
};
|
||||
|
||||
use chrono::{DateTime, Datelike, Local, Months, NaiveDate, Timelike, Weekday};
|
||||
use chrono::{DateTime, Datelike, DurationRound, Local, Months, NaiveDate, Timelike, Weekday};
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::fl;
|
||||
|
|
@ -24,8 +24,8 @@ use cosmic::applet::token::subscription::{
|
|||
activation_token_subscription, TokenRequest, TokenUpdate,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Every {
|
||||
Minute,
|
||||
Second,
|
||||
|
|
@ -94,26 +94,9 @@ impl cosmic::Application for Window {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
const FALLBACK_DELAY: u64 = 500;
|
||||
let update_delay = match self.update_at {
|
||||
Every::Minute => chrono::Duration::minutes(1),
|
||||
Every::Second => chrono::Duration::seconds(1),
|
||||
};
|
||||
|
||||
// Calculate the time until next second/minute so we can sleep the thread until then.
|
||||
let now = Local::now().time();
|
||||
let next = (now + update_delay)
|
||||
.with_second(0)
|
||||
.expect("Setting seconds to 0 should always be possible")
|
||||
.with_nanosecond(0)
|
||||
.expect("Setting nanoseconds to 0 should always be possible.");
|
||||
let wait = 1.max((next - now).num_milliseconds());
|
||||
Subscription::batch(vec![
|
||||
rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)),
|
||||
time::every(Duration::from_millis(
|
||||
wait.try_into().unwrap_or(FALLBACK_DELAY),
|
||||
))
|
||||
.map(|_| Message::Tick),
|
||||
time_subscription(self.update_at).map(|_| Message::Tick),
|
||||
activation_token_subscription(0).map(Message::Token),
|
||||
])
|
||||
}
|
||||
|
|
@ -367,3 +350,18 @@ fn date_button(
|
|||
button
|
||||
}
|
||||
}
|
||||
|
||||
fn time_subscription(update_at: Every) -> Subscription<()> {
|
||||
subscription::unfold("time-sub", (), move |()| async move {
|
||||
let now = Local::now();
|
||||
let update_delay = match update_at {
|
||||
Every::Minute => chrono::TimeDelta::minutes(1),
|
||||
Every::Second => chrono::TimeDelta::seconds(1),
|
||||
};
|
||||
let duration = ((now + update_delay).duration_trunc(update_delay).unwrap() - now)
|
||||
.to_std()
|
||||
.unwrap();
|
||||
tokio::time::sleep(duration).await;
|
||||
((), ())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue