Skip to content

Commit

Permalink
feat(time): Option to show seconds on clock
Browse files Browse the repository at this point in the history
Closes: #496
  • Loading branch information
joshuamegnauth54 committed Aug 20, 2024
1 parent 2f89e49 commit 1266956
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 11 deletions.
2 changes: 2 additions & 0 deletions cosmic-applet-time/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use cosmic::cosmic_config::{self, cosmic_config_derive::CosmicConfigEntry, Cosmi
#[version = 1]
pub struct TimeAppletConfig {
pub military_time: bool,
pub show_seconds: bool,
pub first_day_of_week: u8,
pub show_date_in_top_panel: bool,
pub show_weekday: bool,
Expand All @@ -16,6 +17,7 @@ impl Default for TimeAppletConfig {
fn default() -> Self {
Self {
military_time: false,
show_seconds: false,
first_day_of_week: 6,
show_date_in_top_panel: true,
show_weekday: false,
Expand Down
79 changes: 68 additions & 11 deletions cosmic-applet-time/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use cosmic::{
Command, Element, Theme,
};
use timedate_zbus::TimeDateProxy;
use tokio::{sync::watch, time};

use icu::{
calendar::DateTime,
Expand Down Expand Up @@ -56,6 +57,8 @@ pub struct Window {
rectangle: Rectangle,
token_tx: Option<calloop::channel::Sender<TokenRequest>>,
config: TimeAppletConfig,
show_seconds_rx: watch::Receiver<bool>,
show_seconds_tx: watch::Sender<bool>,
locale: Locale,
}

Expand Down Expand Up @@ -136,6 +139,9 @@ impl cosmic::Application for Window {
// timezone is ever externally changed
let now: chrono::DateTime<chrono::FixedOffset> = chrono::Local::now().fixed_offset();

// Synch `show_seconds` from the config within the time subscription
let (show_seconds_tx, show_seconds_rx) = watch::channel(false);

(
Self {
core,
Expand All @@ -147,6 +153,8 @@ impl cosmic::Application for Window {
rectangle: Rectangle::default(),
token_tx: None,
config: TimeAppletConfig::default(),
show_seconds_tx,
show_seconds_rx,
locale,
},
Command::none(),
Expand All @@ -166,16 +174,53 @@ impl cosmic::Application for Window {
}

fn subscription(&self) -> Subscription<Message> {
fn time_subscription() -> Subscription<()> {
subscription::unfold("time-sub", (), move |()| async move {
let now = chrono::Local::now();
let update_delay = chrono::TimeDelta::minutes(1);

let duration = ((now + update_delay).duration_trunc(update_delay).unwrap() - now)
.to_std()
.unwrap();
tokio::time::sleep(duration).await;
((), ())
fn time_subscription(mut show_seconds: watch::Receiver<bool>) -> Subscription<()> {
subscription::channel("time-sub", 1, |mut output| async move {
let mut period = if *show_seconds.borrow_and_update() {
1
} else {
60
};
let mut timer = time::interval(time::Duration::from_secs(period));
timer.set_missed_tick_behavior(time::MissedTickBehavior::Skip);

loop {
tokio::select! {
_ = timer.tick() => {
#[cfg(debug_assertions)]
if let Err(err) = output.send(()).await {
tracing::error!(?err, "Failed sending tick request to applet");
}
#[cfg(not(debug_assertions))]
let _ = output.send(()).await;

// Calculate a delta if we're ticking per minute to keep ticks stable
// Based on i3status-rust
let current = chrono::Local::now().second() as u64 % period;
if current != 0 {
timer.reset_after(time::Duration::from_secs(period - current));
}
},
// Update timer if the user toggles show_seconds
Ok(()) = show_seconds.changed() => {
let seconds = *show_seconds.borrow_and_update();
if seconds {
period = 1;
timer = time::interval(time::Duration::from_secs(period));
} else {
period = 60;
let delta = time::Duration::from_secs(period - chrono::Local::now().second() as u64 % period);
let now = time::Instant::now();
// Start ticking from the next minute to update the time properly
let start = now + delta;
let period = time::Duration::from_secs(period);
timer = time::interval_at(start, period);
}

timer.set_missed_tick_behavior(time::MissedTickBehavior::Skip);
}
}
}
})
}

Expand Down Expand Up @@ -221,7 +266,7 @@ impl cosmic::Application for Window {

Subscription::batch(vec![
rectangle_tracker_subscription(0).map(|e| Message::Rectangle(e.1)),
time_subscription().map(|_| Message::Tick),
time_subscription(self.show_seconds_rx.clone()).map(|_| Message::Tick),
activation_token_subscription(0).map(Message::Token),
timezone_subscription(),
self.core.watch_config(Self::APP_ID).map(|u| {
Expand Down Expand Up @@ -356,6 +401,14 @@ impl cosmic::Application for Window {
Command::none()
}
Message::ConfigChanged(c) => {
self.show_seconds_tx.send_if_modified(|show_seconds| {
if *show_seconds == c.show_seconds {
false
} else {
*show_seconds = c.show_seconds;
true
}
});
self.config = c;
Command::none()
}
Expand Down Expand Up @@ -396,6 +449,10 @@ impl cosmic::Application for Window {

time_bag.hour = Some(components::Numeric::Numeric);
time_bag.minute = Some(components::Numeric::Numeric);
time_bag.second = self
.config
.show_seconds
.then_some(components::Numeric::Numeric);

let hour_cycle = if self.config.military_time {
preferences::HourCycle::H23
Expand Down

0 comments on commit 1266956

Please sign in to comment.