From d284b910742b934ee60f07d61ca219f4d77ab9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20S=C3=B8borg?= Date: Thu, 4 Jun 2026 10:18:14 +0200 Subject: [PATCH 1/4] feat: show week numbers Controllable by cosmic-settings with this commit: https://github.com/NicolaiSoeborg/cosmic-settings/commit/de3be060c66d5abfe105971ede4145f4144ea31c Disclaimer; I used AI-tools to help me create this commit, but all code has been "verified" by a human (me) before opening this PR. --- cosmic-applet-time/src/window.rs | 34 ++++++++++++++++++++++++++++++- cosmic-applets-config/src/time.rs | 2 ++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index a44d81ee7..be7a4a46d 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -52,6 +52,17 @@ static AUTOSIZE_MAIN_ID: LazyLock = LazyLock::new(|| Id::new("autosize-main" // so those specifiers aren't listed here. This list is non-exhaustive, and it's possible that %X // and other specifiers have to be added depending on locales. const STRFTIME_SECONDS: &[char] = &['S', 'T', '+', 's']; +const WEEK_COLUMN_WIDTH: f32 = 32.0; +const CALENDAR_CELL_SIZE: f32 = 44.0; + +fn week_number_text_style(theme: &theme::Theme) -> cosmic::iced::widget::text::Style { + let mut color = theme.cosmic().background.component.on; + color.alpha *= 0.55; + cosmic::iced::widget::text::Style { + color: Some(color.into()), + ..Default::default() + } +} fn get_system_locale() -> Locale { for var in ["LC_TIME", "LC_ALL", "LANG"] { @@ -149,13 +160,22 @@ impl Window { let prefs = DateTimeFormatterPreferences::from(self.locale.clone()); let weekday = DateTimeFormatter::try_new(prefs, fieldsets::E::short()).unwrap(); + if self.config.show_week_numbers { + calendar = calendar.push( + text::caption("W") + .class(theme::Text::Custom(week_number_text_style)) + .apply(container) + .center_x(Length::Fixed(WEEK_COLUMN_WIDTH)), + ); + } + for i in 0..7 { let date = first_day.checked_add(i.days()).unwrap(); let datetime = self.create_datetime(&date); calendar = calendar.push( text::caption(weekday.format(&datetime).to_string()) .apply(container) - .center_x(Length::Fixed(44.0)), + .center_x(Length::Fixed(CALENDAR_CELL_SIZE)), ); } calendar = calendar.insert_row(); @@ -168,6 +188,18 @@ impl Window { let date = first_day .checked_add(i.days()) .expect("valid date in calendar range"); + + if self.config.show_week_numbers && i % 7 == 0 { + calendar = calendar.push( + text::caption(format!("{}", date.iso_week_date().week())) + .class(theme::Text::Custom(week_number_text_style)) + .apply(container) + .width(Length::Fixed(WEEK_COLUMN_WIDTH)) + .height(Length::Fixed(CALENDAR_CELL_SIZE)) + .center_x(Length::Fixed(WEEK_COLUMN_WIDTH)) + .center_y(Length::Fixed(CALENDAR_CELL_SIZE)), + ); + } let is_month = date.first_of_month() == self.date_selected.first_of_month(); let is_day = date == self.date_selected; let is_today = date == self.date_today; diff --git a/cosmic-applets-config/src/time.rs b/cosmic-applets-config/src/time.rs index 8af390278..a127b81bf 100644 --- a/cosmic-applets-config/src/time.rs +++ b/cosmic-applets-config/src/time.rs @@ -11,6 +11,7 @@ pub struct TimeAppletConfig { pub first_day_of_week: u8, pub show_date_in_top_panel: bool, pub show_weekday: bool, + pub show_week_numbers: bool, #[serde(default, skip_serializing_if = "str::is_empty")] pub format_strftime: String, } @@ -23,6 +24,7 @@ impl Default for TimeAppletConfig { first_day_of_week: 6, show_date_in_top_panel: true, show_weekday: false, + show_week_numbers: true, format_strftime: Default::default(), } } From 455353e80b50f946440f1a7d362abe517a7d409f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolai=20S=C3=B8borg?= Date: Tue, 30 Jun 2026 13:18:33 +0200 Subject: [PATCH 2/4] Fix calendar width when show-week-number column visible --- cosmic-applet-time/src/window.rs | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index be7a4a46d..6df90eec4 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -52,8 +52,10 @@ static AUTOSIZE_MAIN_ID: LazyLock = LazyLock::new(|| Id::new("autosize-main" // so those specifiers aren't listed here. This list is non-exhaustive, and it's possible that %X // and other specifiers have to be added depending on locales. const STRFTIME_SECONDS: &[char] = &['S', 'T', '+', 's']; -const WEEK_COLUMN_WIDTH: f32 = 32.0; +const WEEK_COLUMN_WIDTH: f32 = 28.0; +const CALENDAR_PADDING_WIDTH: f32 = 12.0; const CALENDAR_CELL_SIZE: f32 = 44.0; +const CALENDAR_COLUMN_SPACING: f32 = 4.0; fn week_number_text_style(theme: &theme::Theme) -> cosmic::iced::widget::text::Style { let mut color = theme.cosmic().background.component.on; @@ -140,7 +142,9 @@ impl Window { } fn calendar_grid(&self) -> Grid<'_, Message> { - let mut calendar = grid().width(Length::Fill); + let mut calendar = grid() + .width(Length::Fill) + .column_spacing(CALENDAR_COLUMN_SPACING as u16); let first_day_of_week = match self.config.first_day_of_week { 0 => Weekday::Monday, 1 => Weekday::Tuesday, @@ -771,6 +775,17 @@ impl cosmic::Application for Window { let calendar = self.calendar_grid(); + // Total popup width = 7 day columns + inter-day gaps + padding + // + week column + gap between week and Monday (only when enabled). + let popup_width = (7.0 * CALENDAR_CELL_SIZE + + 6.0 * CALENDAR_COLUMN_SPACING + + 2.0 * CALENDAR_PADDING_WIDTH + + if self.config.show_week_numbers { + WEEK_COLUMN_WIDTH + CALENDAR_COLUMN_SPACING + } else { + 0.0 + }); + let content_list = column![ row![ column![date, day_of_week], @@ -779,16 +794,21 @@ impl cosmic::Application for Window { ] .align_y(Alignment::Center) .padding([12, 20]), - calendar.padding([0, 12].into()), + calendar.padding([0.0, CALENDAR_PADDING_WIDTH].into()), padded_control(divider::horizontal::default()).padding([space_xxs, space_s]), menu_button(text::body(fl!("datetime-settings"))) .on_press(Message::OpenDateTimeSettings), ] - .padding([8, 0]); + .padding([8, 0]) + .width(popup_width); self.core .applet .popup_container(container(content_list)) + .limits( + cosmic::iced::core::layout::Limits::NONE + .min_width(popup_width) + ) .into() } @@ -812,8 +832,8 @@ fn date_button(day: i8, is_month: bool, is_day: bool, is_today: bool) -> Button< .center(Length::Fill), ) .class(style) - .height(Length::Fixed(44.0)) - .width(Length::Fixed(44.0)); + .height(Length::Fixed(CALENDAR_CELL_SIZE)) + .width(Length::Fixed(CALENDAR_CELL_SIZE)); if is_month { button.on_press(Message::SelectDay(day)) From 8f8355afe0d43c19974102b6aa1bfb5cb01c9fff Mon Sep 17 00:00:00 2001 From: Jacob Kauffmann Date: Tue, 30 Jun 2026 11:21:54 -0600 Subject: [PATCH 3/4] chore: cargo fmt --- cosmic-applet-time/src/window.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cosmic-applet-time/src/window.rs b/cosmic-applet-time/src/window.rs index 6df90eec4..6b1f8ba7d 100644 --- a/cosmic-applet-time/src/window.rs +++ b/cosmic-applet-time/src/window.rs @@ -805,10 +805,7 @@ impl cosmic::Application for Window { self.core .applet .popup_container(container(content_list)) - .limits( - cosmic::iced::core::layout::Limits::NONE - .min_width(popup_width) - ) + .limits(cosmic::iced::core::layout::Limits::NONE.min_width(popup_width)) .into() } From 2013bb284fd512c371d8574fe48d0f068ec71eea Mon Sep 17 00:00:00 2001 From: Jacob Kauffmann Date: Tue, 30 Jun 2026 15:37:08 -0600 Subject: [PATCH 4/4] fix: Disable week numbers by default This matches the current default design. --- cosmic-applets-config/src/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cosmic-applets-config/src/time.rs b/cosmic-applets-config/src/time.rs index a127b81bf..e01dec3a8 100644 --- a/cosmic-applets-config/src/time.rs +++ b/cosmic-applets-config/src/time.rs @@ -24,7 +24,7 @@ impl Default for TimeAppletConfig { first_day_of_week: 6, show_date_in_top_panel: true, show_weekday: false, - show_week_numbers: true, + show_week_numbers: false, format_strftime: Default::default(), } }