merge: epoch-1.9.0 d'upstream

# Conflicts:
#	Cargo.lock
#	Cargo.toml
This commit is contained in:
Lionel DARNIS 2026-09-24 20:48:01 +02:00
commit d5c5fd72f1
52 changed files with 1176 additions and 1370 deletions

View file

@ -1,6 +1,6 @@
[package]
name = "cosmic-settings"
version = "1.7.0"
version = "1.9.0"
edition = "2024"
license = "GPL-3.0-only"
publish = false
@ -22,6 +22,7 @@ cosmic-bg-config.workspace = true
cosmic-comp-config = { workspace = true, optional = true }
cosmic-config.workspace = true
cosmic-idle-config.workspace = true
cosmic-osk-config = { git = "https://github.com/pop-os/cosmic-osk", features = ["subscription"] }
cosmic-panel-config = { workspace = true, optional = true }
cosmic-protocols = { git = "https://github.com/pop-os/cosmic-protocols", optional = true }
cosmic-randr-shell.workspace = true
@ -59,7 +60,7 @@ openlogi-core = { path = "../../OpenLogi/crates/openlogi-core" }
openlogi-ipc = { path = "../../OpenLogi/crates/openlogi-ipc" }
tarpc = { version = "0.38", features = ["serde1", "tokio1"] }
notify = "8.2.0"
nmrs = { version = "3.5.2", optional = true }
nmrs = { version = "3.5.3", optional = true }
regex = "1.13.1"
ron = "0.12"
rust-embed = "8.12.0"

View file

@ -80,6 +80,8 @@ impl SettingsApp {
PageCommands::AccessibilityMagnifier => {
self.pages.page_id::<accessibility::magnifier::Page>()
}
#[cfg(feature = "page-accessibility")]
PageCommands::AccessibilityOsk => self.pages.page_id::<accessibility::osk::Page>(),
#[cfg(feature = "page-about")]
PageCommands::About => self.pages.page_id::<system::about::Page>(),
PageCommands::Appearance { command: _ } => {
@ -178,7 +180,7 @@ pub enum Message {
SearchSubmit,
SetTheme(cosmic::theme::Theme),
SetWindowTitle,
Surface(surface::Action),
Surface(surface::Action<Message>),
}
impl cosmic::Application for SettingsApp {
@ -425,6 +427,12 @@ impl cosmic::Application for SettingsApp {
return page.update(self.active_page, message).map(Into::into);
}
}
#[cfg(feature = "page-accessibility")]
crate::pages::Message::AccessibilityOsk(message) => {
if let Some(page) = self.pages.page_mut::<accessibility::osk::Page>() {
return page.update(self.active_page, message).map(Into::into);
}
}
#[cfg(feature = "page-input")]
crate::pages::Message::AccessibilityShortcuts(message) => {
if let Some(page) = self
@ -880,9 +888,7 @@ impl cosmic::Application for SettingsApp {
tracing::error!(error, "error occurred");
}
Message::Surface(a) => {
return cosmic::task::message(cosmic::Action::Cosmic(
cosmic::app::Action::Surface(a),
));
return cosmic::task::message(cosmic::Action::Surface(a));
}
}

View file

@ -68,6 +68,9 @@ pub enum PageCommands {
/// Accessibility Magnifier settings page
#[cfg(feature = "page-accessibility")]
AccessibilityMagnifier,
/// Accessibility OSK settings page
#[cfg(feature = "page-accessibility")]
AccessibilityOsk,
/// About settings page
#[cfg(feature = "page-about")]
About,

View file

@ -42,7 +42,7 @@ pub enum Message {
SetIncrement(usize),
SetSignin(bool),
SetMovement(ZoomMovement),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl Default for Page {

View file

@ -17,6 +17,8 @@ use num_traits::FromPrimitive;
use slotmap::SlotMap;
pub mod magnifier;
pub mod osk;
pub use cosmic_a11y_manager::{AccessibilityEvent, AccessibilityRequest, ColorFilter};
use tokio::sync::mpsc::UnboundedSender;
@ -95,7 +97,7 @@ pub enum Message {
SetScreenFilterSelection(ColorFilter),
SetScreenInverted(bool),
SetSoundMono(bool),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
SystemTheme(Box<cosmic::cosmic_theme::Theme>),
}
@ -128,7 +130,11 @@ impl page::Page<crate::pages::Message> for Page {
&self,
sections: &mut SlotMap<section::Entity, page::Section<crate::pages::Message>>,
) -> Option<page::Content> {
Some(vec![sections.insert(vision()), sections.insert(hearing())])
Some(vec![
sections.insert(vision()),
sections.insert(hearing()),
sections.insert(mobility()),
])
}
fn on_enter(&mut self) -> cosmic::Task<crate::pages::Message> {
@ -185,7 +191,7 @@ impl page::Page<crate::pages::Message> for Page {
impl page::AutoBind<crate::pages::Message> for Page {
fn sub_pages(page: Insert<crate::pages::Message>) -> Insert<crate::pages::Message> {
page.sub_page::<magnifier::Page>()
page.sub_page::<magnifier::Page>().sub_page::<osk::Page>()
}
}
@ -326,6 +332,34 @@ pub fn hearing() -> section::Section<crate::pages::Message> {
})
}
pub fn mobility() -> section::Section<crate::pages::Message> {
crate::slab!(descriptions {
mobility = fl!("mobility");
on_screen_keyboard = fl!("on-screen-keyboard");
});
Section::default()
.title(&descriptions[mobility])
.descriptions(descriptions)
.view::<Page>(move |binder, _, section| {
let descriptions = &section.descriptions;
let (osk_entity, _osk_info) = binder
.info
.iter()
.find(|(_, v)| v.id == "accessibility_osk")
.expect("osk page not found");
settings::section()
.title(&section.title)
.add(crate::widget::go_next_item(
&descriptions[on_screen_keyboard],
crate::pages::Message::Page(osk_entity),
))
.into()
})
}
impl Page {
pub fn update(&mut self, message: Message) -> cosmic::iced::Task<crate::app::Message> {
match message {

View file

@ -0,0 +1,146 @@
use cosmic::Apply;
use cosmic::iced::Element;
use cosmic::widget::settings;
use cosmic_config::CosmicConfigEntry;
use cosmic_osk_config::Config;
use cosmic_settings_page::section::{self, Section};
use cosmic_settings_page::{self as page, Entity};
use slotmap::SlotMap;
#[derive(Debug)]
pub struct Page {
entity: Entity,
config: Config,
config_handler: cosmic_config::Config,
}
#[derive(Debug, Clone)]
pub enum Message {
AlwaysShow(bool),
Config(Config),
GamepadShortcut(bool),
ImeActivation(bool),
}
impl Default for Page {
fn default() -> Self {
let (config_handler, config) = match Config::handler() {
Ok(config_handler) => {
let config = Config::get_entry(&config_handler).unwrap_or_else(|(errs, config)| {
tracing::warn!("errors loading OSK config: {:?}", errs);
config
});
(config_handler, config)
}
Err(err) => {
panic!("failed to create OSK config handler: {}", err);
}
};
Page {
entity: Entity::default(),
config,
config_handler,
}
}
}
impl page::Page<crate::pages::Message> for Page {
fn set_id(&mut self, entity: Entity) {
self.entity = entity;
}
fn info(&self) -> page::Info {
page::Info::new("accessibility_osk", "preferences-desktop-accessibility")
.title(fl!("on-screen-keyboard"))
}
fn content(
&self,
sections: &mut SlotMap<section::Entity, page::Section<crate::pages::Message>>,
) -> Option<page::Content> {
Some(vec![sections.insert(osk())])
}
fn subscription(
&self,
_core: &cosmic::Core,
) -> cosmic::iced::Subscription<crate::pages::Message> {
Config::subscription().map(|update| {
if !update.errors.is_empty() {
tracing::warn!("failed to parse OSK config update: {:?}", update.errors);
}
crate::pages::Message::AccessibilityOsk(Message::Config(update.config))
})
}
}
impl page::AutoBind<crate::pages::Message> for Page {}
pub fn osk() -> section::Section<crate::pages::Message> {
crate::slab!(descriptions {
on_screen_keyboard = fl!("on-screen-keyboard");
always_show = fl!("on-screen-keyboard", "always-show");
//TODO: icon_on_panel = fl!("on-screen-keyboard", "icon-on-panel");
show_on_gamepad_shortcut = fl!("on-screen-keyboard", "show-on-gamepad-shortcut");
show_on_text_input = fl!("on-screen-keyboard", "show-on-text-input");
});
Section::default()
.title(&descriptions[on_screen_keyboard])
.descriptions(descriptions)
.view::<Page>(move |_binder, page, section| {
let descriptions = &section.descriptions;
settings::section()
.add(
settings::item::builder(&descriptions[always_show])
.toggler(page.config.always_shown, Message::AlwaysShow),
)
.add(
settings::item::builder(&descriptions[show_on_gamepad_shortcut])
.toggler(page.config.gamepad_shortcut, Message::GamepadShortcut),
)
.add(
settings::item::builder(&descriptions[show_on_text_input])
.toggler(page.config.ime_activation, Message::ImeActivation),
)
.apply(Element::from)
.map(crate::pages::Message::AccessibilityOsk)
})
}
impl Page {
pub fn update(
&mut self,
_: page::Entity,
message: Message,
) -> cosmic::iced::Task<crate::app::Message> {
match message {
Message::AlwaysShow(value) => {
if let Err(err) = self.config.set_always_shown(&self.config_handler, value) {
tracing::error!("failed to set OSK config: {}", err);
}
}
Message::Config(config) => {
self.config = config;
}
Message::GamepadShortcut(value) => {
if let Err(err) = self
.config
.set_gamepad_shortcut(&self.config_handler, value)
{
tracing::error!("failed to set OSK config: {}", err);
}
}
Message::ImeActivation(value) => {
if let Err(err) = self.config.set_ime_activation(&self.config_handler, value) {
tracing::error!("failed to set OSK config: {}", err);
}
}
}
cosmic::iced::Task::none()
}
}

View file

@ -48,7 +48,7 @@ pub enum Category {
pub enum Message {
SetDefault(Category, usize),
Update(Arc<CachedMimeApps>),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl From<Message> for crate::app::Message {

View file

@ -25,7 +25,7 @@ pub enum Message {
SetXwaylandKeyboardMode(EavesdroppingKeyboardMode),
SetXwaylandMouseButtonMode(bool),
SetXwaylandPrimaryOutput(usize),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl From<Message> for crate::pages::Message {

View file

@ -431,7 +431,7 @@ pub enum Message {
PanelConfig(Box<CosmicPanelConfig>),
ResetPanel,
FullReset,
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl PageInner {

View file

@ -102,7 +102,7 @@ pub enum Message {
Slideshow(bool),
/// State change from cosmic-bg
UpdateState(cosmic_bg_config::state::State),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl From<Message> for crate::app::Message {

View file

@ -25,7 +25,7 @@ pub enum Message {
ShowMinimizeButton(bool),
WindowControlsPositionStart(bool),
SetEdgeSnapThreshold(u32),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
pub struct Page {

View file

@ -19,7 +19,7 @@ pub enum Message {
SetWorkspaceWraparound(bool),
SetShowName(bool),
SetShowNumber(bool),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
pub struct Page {

View file

@ -108,7 +108,7 @@ pub enum Message {
/// Available outputs from cosmic-randr.
randr: Arc<Result<List, cosmic_randr_shell::Error>>,
},
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl From<Message> for app::Message {

View file

@ -33,6 +33,8 @@ pub enum Message {
Accessibility(accessibility::Message),
#[cfg(feature = "page-accessibility")]
AccessibilityMagnifier(accessibility::magnifier::Message),
#[cfg(feature = "page-accessibility")]
AccessibilityOsk(accessibility::osk::Message),
#[cfg(feature = "page-input")]
AccessibilityShortcuts(input::keyboard::shortcuts::ShortcutMessage),
#[cfg(feature = "page-about")]

View file

@ -312,7 +312,7 @@ pub enum Message {
SuspendOnBatteryTimeChange(Option<Duration>),
BackendAvailabilityCheck(Option<backend::PowerBackendEnum>),
CurrentPowerProfileUpdate(PowerProfile),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl From<Message> for crate::app::Message {

View file

@ -28,7 +28,7 @@ pub enum Message {
SetMute(u32, bool),
SetSink(u32, usize),
SetVolume(u32, u32),
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
ToggleExpanded(u32),
}

View file

@ -19,7 +19,7 @@ pub enum Message {
/// Set the profile of a sound device.
SetProfile(u32, u32),
/// Surface Action
Surface(cosmic::surface::Action),
Surface(cosmic::surface::Action<crate::app::Message>),
}
impl From<Message> for crate::pages::Message {

View file

@ -39,7 +39,7 @@ pub enum Message {
/// Request to change the input volume.
SetSourceVolume(u32),
/// Surface Action
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
/// Toggle the mute status of the output.
ToggleSinkMute,
/// Toggle the mute status of the input output.

View file

@ -10,16 +10,16 @@ use std::process::Command;
#[must_use]
#[derive(Clone, Debug, Default)]
pub struct Info {
pub desktop_environment: String,
pub device_name: String,
pub disk_capacity: String,
pub graphics: Vec<String>,
pub hardware_model: String,
pub memory: String,
pub processor: String,
pub graphics: Vec<String>,
pub disk_capacity: String,
pub operating_system: String,
pub os_architecture: String,
pub kernel_version: String,
pub processor: String,
pub desktop_environment: String,
pub windowing_system: String,
}
@ -144,11 +144,11 @@ impl Info {
pub async fn load() -> Info {
let mut info = Info {
hardware_model: hardware_model(),
processor: processor_name(),
operating_system: operating_system(),
os_architecture: architecture(),
kernel_version: kernel_version(),
hardware_model: hardware_model(),
operating_system: operating_system(),
processor: processor_name(),
..Default::default()
};
@ -189,7 +189,11 @@ impl Info {
if let Some(first) = session.get_mut(0..1) {
first.make_ascii_uppercase();
}
info.desktop_environment = session;
info.desktop_environment = if session.eq_ignore_ascii_case("COSMIC") {
format!("COSMIC {}", env!("CARGO_PKG_VERSION"))
} else {
session
};
}
#[cfg(feature = "wgpu")]

View file

@ -21,7 +21,9 @@ use tracing::error;
crate::cache_dynamic_lazy! {
static WEEKDAYS: [String; 4] = [fl!("time-format", "friday"), fl!("time-format", "saturday"), fl!("time-format", "sunday"), fl!("time-format", "monday")];
}
static SHOW_WEEKDAY: String = fl!("time-format", "show-weekday");
static SHOW_SECONDS: String = fl!("time-format", "show-seconds");
static SHOW_DATE: String = fl!("time-format", "date");}
#[derive(Debug, Clone)]
pub struct Info {
@ -36,9 +38,11 @@ pub struct Page {
first_day_of_week: usize,
military_time: bool,
show_seconds: bool,
show_weekday: bool,
ntp_enabled: bool,
show_date_in_top_panel: bool,
timezone_context: bool,
date_time_applet_context: bool,
local_time: Option<DateTime<Gregorian>>,
timezone: Option<usize>,
timezone_list: Vec<String>,
@ -73,6 +77,16 @@ impl Default for Page {
false
});
let show_weekday = cosmic_applet_config
.get("show_weekday")
.unwrap_or_else(|err| {
if err.is_err() {
error!(?err, "Failed to read config 'show_weekday'");
}
false
});
let first_day_of_week = cosmic_applet_config
.get("first_day_of_week")
.unwrap_or_else(|err| {
@ -103,10 +117,12 @@ impl Default for Page {
local_time: None,
military_time,
show_seconds,
show_weekday,
ntp_enabled: false,
show_date_in_top_panel,
timezone: None,
timezone_context: false,
date_time_applet_context: false,
timezone_list: Vec::new(),
timezone_search: String::new(),
}
@ -183,6 +199,15 @@ impl page::Page<crate::pages::Message> for Page {
.title(fl!("time-zone"))
.header(search),
);
} else if self.date_time_applet_context {
return Some(
cosmic::app::context_drawer(
self.date_time_applet_view()
.map(crate::pages::Message::from),
crate::pages::Message::CloseContextDrawer,
)
.title(fl!("date-time-applet-settings-title")),
);
}
None
@ -216,6 +241,15 @@ impl Page {
}
}
Message::ShowWeekday(enable) => {
self.show_weekday = enable;
self.update_local_time();
if let Err(err) = self.cosmic_applet_config.set("show_weekday", enable) {
error!(?err, "Failed to set config 'show_weekday'");
}
}
Message::FirstDayOfWeek(weekday) => {
self.first_day_of_week = weekday;
@ -224,6 +258,11 @@ impl Page {
}
}
Message::DateAndTimeContext => {
self.date_time_applet_context = true;
return cosmic::task::message(crate::app::Message::OpenContextDrawer(self.entity));
}
Message::ShowDate(enable) => {
self.show_date_in_top_panel = enable;
@ -342,6 +381,25 @@ impl Page {
.map(crate::pages::Message::DateAndTime)
}
fn date_time_applet_view(&self) -> Element<'_, crate::pages::Message> {
let mut list = widget::list_column();
list = list.add(
settings::item::builder(&*SHOW_DATE)
.toggler(self.show_date_in_top_panel, Message::ShowDate)
)
.add(
settings::item::builder(&*SHOW_WEEKDAY)
.toggler(self.show_weekday, Message::ShowWeekday),
)
.add(
settings::item::builder(&*SHOW_SECONDS)
.toggler(self.show_seconds, Message::ShowSeconds));
list.apply(Element::from)
.map(crate::pages::Message::DateAndTime)
}
fn update_local_time(&mut self) {
self.local_time = Some(update_local_time());
@ -357,15 +415,17 @@ pub enum Message {
Error(String),
MilitaryTime(bool),
ShowSeconds(bool),
ShowWeekday(bool),
None,
FirstDayOfWeek(usize),
Refresh(Info),
ShowDate(bool),
Timezone(usize),
TimezoneContext,
DateAndTimeContext,
TimezoneSearch(String),
UpdateTime,
Surface(surface::Action),
Surface(surface::Action<crate::app::Message>),
}
impl page::AutoBind<crate::pages::Message> for Page {}
@ -394,9 +454,8 @@ fn date() -> Section<crate::pages::Message> {
fn format() -> Section<crate::pages::Message> {
crate::slab!(descriptions {
military = fl!("time-format", "twenty-four");
show_seconds = fl!("time-format", "show-seconds");
first = fl!("time-format", "first");
show_date = fl!("time-format", "show-date");
date_time_applet_settings_label = fl!("date-time-applet-settings-label");
});
Section::default()
@ -410,11 +469,6 @@ fn format() -> Section<crate::pages::Message> {
settings::item::builder(&section.descriptions[military])
.toggler(page.military_time, Message::MilitaryTime),
)
// Show seconds in time format
.add(
settings::item::builder(&section.descriptions[show_seconds])
.toggler(page.show_seconds, Message::ShowSeconds),
)
// First day of week
.add(
settings::item::builder(&section.descriptions[first]).control(
@ -444,11 +498,13 @@ fn format() -> Section<crate::pages::Message> {
),
),
)
// Date on top panel toggle
// Show a Context Drawer which contains settings for how the Date and Time applet displays the date.
.add(
settings::item::builder(&section.descriptions[show_date])
.toggler(page.show_date_in_top_panel, Message::ShowDate),
)
crate::widget::go_next_with_item(
&section.descriptions[date_time_applet_settings_label],
"",
Message::DateAndTimeContext,
))
.apply(cosmic::Element::from)
.map(crate::pages::Message::DateAndTime)
})