Skip to content

Commit

Permalink
rfct: Move clock to sep. component
Browse files Browse the repository at this point in the history
- Separate the clock from the Greeter component
- Replace chrono with jiff
- Add TOML config options for the clock widget
- Update the README with config options
- Minor misc. improvements
  • Loading branch information
max-ishere committed Dec 29, 2024
1 parent 6625ea7 commit a90a7ce
Show file tree
Hide file tree
Showing 11 changed files with 541 additions and 356 deletions.
596 changes: 296 additions & 300 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ license = "GPL-3.0-or-later"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
chrono = { version = "0.4.22", default-features = false }
clap = { version = "4.5", features = ["derive"] }
const_format = { version = "0.2.33", features = ["rust_1_64"] }
educe = "0.6"
file-rotate = "0.7"
glob = "0.3"
greetd_ipc = { version = "0.10", features = ["tokio-codec"] }
gtk4 = "0.9"
humantime-serde = "1.1.1"
jiff = "0.1.14"
lazy_static = "1.5.0"
lru = "0.12"
pwd = "1.4.0"
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ These screenshots use the [Canta GTK theme](https://github.com/vinceliuice/Canta
* Allows setting environment variables for created sessions
* Supports customizing:
- Background image
- Clock
- GTK theme
- Dark mode
- Icon theme
Expand Down Expand Up @@ -190,6 +191,7 @@ Currently, the following can be configured:
* How the background image fits the screen (needs GTK 4.8+ support compiled)
* Environment variables for created sessions
* Greeting message
* Clock
* GTK theme
* Dark mode
* Icon theme
Expand Down
21 changes: 19 additions & 2 deletions regreet.sample.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,31 @@ theme_name = "Adwaita"

[commands]
# The command used to reboot the system
reboot = [ "systemctl", "reboot" ]
reboot = ["systemctl", "reboot"]

# The command used to shut down the system
poweroff = [ "systemctl", "poweroff" ]
poweroff = ["systemctl", "poweroff"]

# The command prefix for X11 sessions to start the X server
x11_prefix = [ "startx", "/usr/bin/env" ]

[appearance]
# The message that initially displays on startup
greeting_msg = "Welcome back!"


[widget.clock]
# strftime format argument
# See https://docs.rs/jiff/0.1.14/jiff/fmt/strtime/index.html#conversion-specifications
format = "%a %H:%M"

# How often to update the text
resolution = "500ms"

# Override system timezone (IANA Time Zone Database name, aka /etc/zoneinfo path)
# Remove to use the system time zone.
timezone = "America/Chicago"

# Ask GTK to make the label at least this wide. This helps keeps the parent element layout and width consistent.
# Experiment with different widths, the interpretation of this value is entirely up to GTK.
label_width = 150
20 changes: 17 additions & 3 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use std::path::Path;
use serde::{Deserialize, Serialize};

use crate::constants::{GREETING_MSG, POWEROFF_CMD, REBOOT_CMD, X11_CMD_PREFIX};
use crate::gui::widget::clock::ClockConfig;
use crate::tomlutils::load_toml;

#[derive(Deserialize, Serialize)]
Expand Down Expand Up @@ -98,18 +99,31 @@ fn default_greeting_msg() -> String {
}

/// The configuration struct
#[derive(Default, Deserialize, Serialize)]
#[derive(Default, Deserialize)]
pub struct Config {
#[serde(default)]
appearance: AppearanceSettings,

#[serde(default)]
env: HashMap<String, String>,

#[serde(default)]
background: Background,

#[serde(default, rename = "GTK")]
gtk: Option<GtkSettings>,

#[serde(default)]
commands: SystemCommands,

#[serde(default)]
pub(crate) widget: WidgetConfig,
}

#[derive(Deserialize, Default)]
pub struct WidgetConfig {
#[serde(default)]
pub(crate) clock: ClockConfig,
}

impl Config {
Expand All @@ -121,8 +135,8 @@ impl Config {
&self.env
}

pub fn get_background(&self) -> &Option<String> {
&self.background.path
pub fn get_background(&self) -> Option<&str> {
self.background.path.as_deref()
}

#[cfg(feature = "gtk4_8")]
Expand Down
50 changes: 10 additions & 40 deletions src/gui/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,14 @@
//! Setup for using the greeter as a Relm4 component
use std::path::PathBuf;
use std::time::Duration;

use chrono::Local;

use gtk::prelude::*;
use relm4::{
component::{AsyncComponent, AsyncComponentParts, AsyncComponentSender},
gtk,
component::{AsyncComponent, AsyncComponentParts},
gtk::prelude::*,
prelude::*,
AsyncComponentSender,
};
use tokio::time::sleep;
use tracing::{debug, info, warn};

#[cfg(feature = "gtk4_8")]
use crate::config::BgFit;
Expand All @@ -23,9 +21,6 @@ use super::messages::{CommandMsg, InputMsg, UserSessInfo};
use super::model::{Greeter, InputMode, Updates};
use super::templates::Ui;

const DATETIME_FMT: &str = "%a %R";
const DATETIME_UPDATE_DELAY: u64 = 500;

/// Load GTK settings from the greeter config.
fn setup_settings(model: &Greeter, root: &gtk::ApplicationWindow) {
let settings = root.settings();
Expand Down Expand Up @@ -101,25 +96,6 @@ fn setup_users_sessions(model: &Greeter, widgets: &GreeterWidgets) {
}
}

/// Set up auto updation for the datetime label.
fn setup_datetime_display(sender: &AsyncComponentSender<Greeter>) {
// Set a timer in a separate thread that signals the main thread to update the time, so as to
// not block the GUI.
sender.command(|sender, shutdown| {
shutdown
.register(async move {
// Run it infinitely, since the clock always needs to stay updated.
loop {
if sender.send(CommandMsg::UpdateTime).is_err() {
warn!("Couldn't update datetime");
};
sleep(Duration::from_millis(DATETIME_UPDATE_DELAY)).await;
}
})
.drop_on_shutdown()
});
}

/// The info required to initialize the greeter
pub struct GreeterInit {
pub config_path: PathBuf,
Expand All @@ -145,11 +121,11 @@ impl AsyncComponent for Greeter {
#[template]
Ui {
#[template_child]
background { set_filename: model.config.get_background().clone() },
background { set_filename: model.config.get_background() },

#[template_child]
datetime_label {
#[track(model.updates.changed(Updates::time()))]
set_label: &model.updates.time
clock_frame {
model.clock.widget(),
},

#[template_child]
Expand Down Expand Up @@ -392,7 +368,6 @@ impl AsyncComponent for Greeter {
// full-screening.
setup_settings(&model, &root);
setup_users_sessions(&model, &widgets);
setup_datetime_display(&sender);

if input.css_path.exists() {
debug!("Loading custom CSS from file: {}", input.css_path.display());
Expand Down Expand Up @@ -450,17 +425,12 @@ impl AsyncComponent for Greeter {
sender: AsyncComponentSender<Self>,
_root: &Self::Root,
) {
if !matches!(msg, Self::CommandOutput::UpdateTime) {
debug!("Got command message: {msg:?}");
}
debug!("Got command message: {msg:?}");

// Reset the tracker for update changes.
self.updates.reset();

match msg {
Self::CommandOutput::UpdateTime => self
.updates
.set_time(Local::now().format(DATETIME_FMT).to_string()),
Self::CommandOutput::ClearErr => self.updates.set_error(None),
Self::CommandOutput::HandleGreetdResponse(response) => {
self.handle_greetd_response(&sender, response).await
Expand Down
2 changes: 0 additions & 2 deletions src/gui/messages.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,6 @@ pub enum InputMsg {
#[derive(Debug)]
/// The messages sent to the sender to run tasks in the background
pub enum CommandMsg {
/// Update the clock.
UpdateTime,
/// Clear the error message.
ClearErr,
/// Handle a response received from greetd
Expand Down
3 changes: 3 additions & 0 deletions src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ mod component;
mod messages;
mod model;
mod templates;
pub(crate) mod widget {
pub mod clock;
}

pub use component::GreeterInit;
pub use model::Greeter;
15 changes: 13 additions & 2 deletions src/gui/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use relm4::{
gdk::{Display, Monitor},
prelude::*,
},
AsyncComponentSender,
AsyncComponentSender, Component, Controller,
};
use tokio::{sync::Mutex, time::sleep};

Expand All @@ -28,7 +28,10 @@ use crate::client::{AuthStatus, GreetdClient};
use crate::config::Config;
use crate::sysutil::{SessionInfo, SessionType, SysUtil};

use super::messages::{CommandMsg, UserSessInfo};
use super::{
messages::{CommandMsg, UserSessInfo},
widget::clock::Clock,
};

const ERROR_MSG_CLEAR_DELAY: u64 = 5;

Expand Down Expand Up @@ -91,6 +94,8 @@ pub struct Greeter {
pub(super) updates: Updates,
/// Is it run as demo
pub(super) demo: bool,

pub(super) clock: Controller<Clock>,
}

impl Greeter {
Expand All @@ -115,6 +120,11 @@ impl Greeter {
.await
.expect("Couldn't initialize greetd client"),
));

let clock = Clock::builder()
.launch(config.widget.clock.clone())
.detach();

Self {
greetd_client,
sys_util: SysUtil::new(&config).expect("Couldn't read available users and sessions"),
Expand All @@ -123,6 +133,7 @@ impl Greeter {
config,
updates,
demo,
clock,
}
}

Expand Down
11 changes: 5 additions & 6 deletions src/gui/templates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ impl WidgetTemplate for Ui {
add_overlay = &gtk::Frame {
set_halign: gtk::Align::Center,
set_valign: gtk::Align::Center,
inline_css: "background-color: @theme_bg_color",
add_css_class: "background",

gtk::Grid {
set_column_spacing: 15,
Expand Down Expand Up @@ -154,20 +154,19 @@ impl WidgetTemplate for Ui {
},

/// Clock widget
#[name = "clock_frame"]
add_overlay = &gtk::Frame {
set_halign: gtk::Align::Center,
set_valign: gtk::Align::Start,

add_css_class: "background",

// Make it fit cleanly onto the top edge of the screen.
inline_css: "
border-top-right-radius: 0px;
border-top-left-radius: 0px;
border-top-width: 0px;
background-color: @theme_bg_color;
",

/// Label displaying the current date & time
#[name = "datetime_label"]
gtk::Label { set_width_request: 150 },
},

/// Collection of widgets appearing at the bottom
Expand Down
Loading

0 comments on commit a90a7ce

Please sign in to comment.