better syncing
This commit is contained in:
parent
9c1306d8c7
commit
9a72c09fed
6 changed files with 144 additions and 45 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
|
@ -1308,6 +1308,7 @@ name = "cosmic-settings-daemon-config"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"cosmic-config",
|
||||
"cosmic-theme",
|
||||
"ron 0.8.1",
|
||||
"serde",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ use std::{
|
|||
pub use cosmic_applets_config::time::TimeAppletConfig;
|
||||
pub use cosmic_bg_config::{state::State as BgState, Color, Source as BgSource};
|
||||
pub use cosmic_comp_config::{CosmicCompConfig, XkbConfig};
|
||||
pub use cosmic_theme::Theme;
|
||||
pub use cosmic_theme::{Theme, ThemeBuilder};
|
||||
|
||||
#[derive(Clone, Debug, Default, serde::Deserialize, serde::Serialize)]
|
||||
pub struct UserData {
|
||||
|
|
@ -17,6 +17,7 @@ pub struct UserData {
|
|||
pub full_name: String,
|
||||
pub icon_opt: Option<Vec<u8>>,
|
||||
pub theme_opt: Option<Theme>,
|
||||
pub theme_builder_opt: Option<ThemeBuilder>,
|
||||
pub bg_state: BgState,
|
||||
pub bg_path_data: BTreeMap<PathBuf, Vec<u8>>,
|
||||
pub xkb_config_opt: Option<XkbConfig>,
|
||||
|
|
@ -59,6 +60,7 @@ impl UserData {
|
|||
pub fn load_config_as_user(&mut self) {
|
||||
self.icon_opt = None;
|
||||
self.theme_opt = None;
|
||||
self.theme_builder_opt = None;
|
||||
self.bg_state = Default::default();
|
||||
self.xkb_config_opt = None;
|
||||
self.time_applet_config = Default::default();
|
||||
|
|
@ -114,6 +116,28 @@ impl UserData {
|
|||
}
|
||||
}
|
||||
|
||||
match if is_dark {
|
||||
cosmic_theme::ThemeBuilder::dark_config()
|
||||
} else {
|
||||
cosmic_theme::ThemeBuilder::light_config()
|
||||
} {
|
||||
Ok(helper) => match cosmic_theme::ThemeBuilder::get_entry(&helper) {
|
||||
Ok(theme) => {
|
||||
self.theme_builder_opt = Some(theme);
|
||||
}
|
||||
Err((errs, theme)) => {
|
||||
log::error!("failed to load cosmic-theme builder config: {:?}", errs);
|
||||
self.theme_builder_opt = Some(theme);
|
||||
}
|
||||
},
|
||||
Err(err) => {
|
||||
log::error!(
|
||||
"failed to create cosmic-theme builder config helper: {:?}",
|
||||
err
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: fallback to background config if background state is not set?
|
||||
match cosmic_bg_config::state::State::state() {
|
||||
Ok(helper) => match cosmic_bg_config::state::State::get_entry(&helper) {
|
||||
|
|
|
|||
3
debian/cosmic-greeter.tmpfiles
vendored
3
debian/cosmic-greeter.tmpfiles
vendored
|
|
@ -1,2 +1,3 @@
|
|||
# Home directory of cosmic-greeter
|
||||
d /var/lib/cosmic-greeter 0750 cosmic-greeter cosmic-greeter
|
||||
d /var/lib/cosmic-greeter 0750 cosmic-greeter cosmic-greeter
|
||||
d /run/cosmic-greeter 0755 cosmic-greeter cosmic-greeter -
|
||||
|
|
|
|||
149
src/greeter.rs
149
src/greeter.rs
|
|
@ -9,7 +9,6 @@ use cosmic::app::{Core, Settings, Task};
|
|||
use cosmic::cctk::wayland_protocols::xdg::shell::client::xdg_positioner::Gravity;
|
||||
use cosmic::iced::{Point, Size};
|
||||
use cosmic::iced_runtime::platform_specific::wayland::subsurface::SctkSubsurfaceSettings;
|
||||
use cosmic::surface;
|
||||
use cosmic::widget::text;
|
||||
use cosmic::{
|
||||
Element,
|
||||
|
|
@ -29,11 +28,13 @@ use cosmic::{
|
|||
iced_runtime::core::window::Id as SurfaceId,
|
||||
theme, widget,
|
||||
};
|
||||
use cosmic::{cosmic_theme::{self, CosmicPalette}, surface};
|
||||
use cosmic_config::CosmicConfigEntry;
|
||||
use cosmic_greeter_config::Config as CosmicGreeterConfig;
|
||||
use cosmic_greeter_daemon::UserData;
|
||||
use cosmic_settings_subscriptions::{
|
||||
accessibility::{self, DBusRequest, DBusUpdate},
|
||||
cosmic_a11y_manager::{AccessibilityEvent, AccessibilityRequest, ColorFilter},
|
||||
use cosmic_settings_daemon_config::greeter::GreeterAccessibilityState;
|
||||
use cosmic_settings_subscriptions::cosmic_a11y_manager::{
|
||||
AccessibilityEvent, AccessibilityRequest,
|
||||
};
|
||||
use greetd_ipc::Request;
|
||||
use std::sync::LazyLock;
|
||||
|
|
@ -47,7 +48,8 @@ use std::{
|
|||
sync::Arc,
|
||||
time::{Duration, Instant},
|
||||
};
|
||||
use tokio::{sync::mpsc::UnboundedSender, time};
|
||||
use tokio::process::Child;
|
||||
use tokio::time;
|
||||
use wayland_client::{Proxy, protocol::wl_output::WlOutput};
|
||||
use zbus::{Connection, proxy};
|
||||
|
||||
|
|
@ -339,7 +341,6 @@ struct NameIndexPair {
|
|||
#[derive(Clone, Debug)]
|
||||
pub enum Message {
|
||||
Common(common::Message),
|
||||
DBusUpdate(DBusUpdate),
|
||||
OutputEvent(OutputEvent, WlOutput),
|
||||
Auth(Option<String>),
|
||||
ConfigUpdateUser,
|
||||
|
|
@ -354,6 +355,7 @@ pub enum Message {
|
|||
KeyboardLayout(usize),
|
||||
Login,
|
||||
Reconnect,
|
||||
Reload(cosmic::Theme),
|
||||
Restart,
|
||||
Session(String),
|
||||
Shutdown,
|
||||
|
|
@ -389,20 +391,20 @@ pub struct App {
|
|||
dropdown_opt: Option<Dropdown>,
|
||||
heartbeat_handle: Option<cosmic::iced::task::Handle>,
|
||||
entering_name: bool,
|
||||
theme_builder: cosmic_theme::ThemeBuilder,
|
||||
|
||||
accessibility: Accessibility,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Accessibility {
|
||||
pub dbus_sender: Option<UnboundedSender<DBusRequest>>,
|
||||
pub wayland_sender: Option<calloop::channel::Sender<AccessibilityRequest>>,
|
||||
pub wayland_protocol_version: Option<u32>,
|
||||
|
||||
pub state: cosmic_settings_daemon_config::greeter::GreeterAccessibilityState,
|
||||
pub helper: Option<cosmic::cosmic_config::Config>,
|
||||
|
||||
pub screen_reader: bool,
|
||||
pub screen_reader: Option<Child>,
|
||||
pub magnifier: bool,
|
||||
pub high_contrast: bool,
|
||||
pub invert_colors: bool,
|
||||
|
|
@ -592,8 +594,8 @@ impl App {
|
|||
let mut items = Vec::new();
|
||||
items.push(menu_checklist(
|
||||
fl!("accessibility", "screen-reader"),
|
||||
self.accessibility.screen_reader,
|
||||
Message::ScreenReader(!self.accessibility.screen_reader),
|
||||
self.accessibility.screen_reader.is_some(),
|
||||
Message::ScreenReader(!self.accessibility.screen_reader.is_some()),
|
||||
));
|
||||
items.push(menu_checklist(
|
||||
fl!("accessibility", "magnifier"),
|
||||
|
|
@ -907,8 +909,13 @@ impl App {
|
|||
// Ensure that user's xkb config is used
|
||||
self.common.set_xkb_config(&user_data);
|
||||
|
||||
if let Some(builder) = &user_data.theme_builder_opt {
|
||||
self.theme_builder = builder.clone();
|
||||
}
|
||||
|
||||
match &user_data.theme_opt {
|
||||
Some(theme) => {
|
||||
self.accessibility.high_contrast = theme.is_high_contrast;
|
||||
cosmic::command::set_theme(cosmic::Theme::custom(Arc::new(theme.clone())))
|
||||
}
|
||||
None => Task::none(),
|
||||
|
|
@ -940,10 +947,6 @@ impl cosmic::Application for App {
|
|||
|
||||
/// Creates the application, and optionally emits command on initialize.
|
||||
fn init(core: Core, flags: Self::Flags) -> (Self, Task<Message>) {
|
||||
// init state that is communicated to cosmic session
|
||||
if let Err(err) = crate::state::init() {
|
||||
log::error!("{err:?}");
|
||||
}
|
||||
let (mut common, common_task) = Common::init(core);
|
||||
common.on_output_event = Some(Box::new(|output_event, output| {
|
||||
Message::OutputEvent(output_event, output)
|
||||
|
|
@ -993,6 +996,10 @@ impl cosmic::Application for App {
|
|||
let mut accessibility = Accessibility::default();
|
||||
accessibility.helper =
|
||||
cosmic_settings_daemon_config::greeter::GreeterAccessibilityState::config().ok();
|
||||
// Reset the state so that only new changes are applied.
|
||||
if let Some(helper) = accessibility.helper.as_ref() {
|
||||
_ = GreeterAccessibilityState::write_entry(&Default::default(), helper);
|
||||
}
|
||||
|
||||
let app = App {
|
||||
common,
|
||||
|
|
@ -1008,6 +1015,7 @@ impl cosmic::Application for App {
|
|||
heartbeat_handle: None,
|
||||
entering_name: false,
|
||||
accessibility,
|
||||
theme_builder: Default::default(),
|
||||
};
|
||||
(app, common_task)
|
||||
}
|
||||
|
|
@ -1018,20 +1026,7 @@ impl cosmic::Application for App {
|
|||
Message::Common(common_message) => {
|
||||
return self.common.update(common_message);
|
||||
}
|
||||
Message::DBusUpdate(update) => match update {
|
||||
DBusUpdate::Error(err) => {
|
||||
log::error!("{err}");
|
||||
let _ = self.accessibility.dbus_sender.take();
|
||||
self.accessibility.screen_reader = false;
|
||||
}
|
||||
DBusUpdate::Status(enabled) => {
|
||||
self.accessibility.screen_reader = enabled;
|
||||
}
|
||||
DBusUpdate::Init(enabled, tx) => {
|
||||
self.accessibility.screen_reader = enabled;
|
||||
self.accessibility.dbus_sender = Some(tx);
|
||||
}
|
||||
},
|
||||
|
||||
Message::OutputEvent(output_event, output) => {
|
||||
match output_event {
|
||||
OutputEvent::Created(output_info_opt) => {
|
||||
|
|
@ -1176,6 +1171,12 @@ impl cosmic::Application for App {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
Message::Reload(new) => {
|
||||
|
||||
return cosmic::command::set_theme(
|
||||
new.clone(),
|
||||
);
|
||||
}
|
||||
Message::Session(selected_session) => {
|
||||
self.selected_session = selected_session;
|
||||
if self.dropdown_opt == Some(Dropdown::Session) {
|
||||
|
|
@ -1458,23 +1459,78 @@ impl cosmic::Application for App {
|
|||
));
|
||||
}
|
||||
Message::ScreenReader(enabled) => {
|
||||
if let Some(tx) = &self.accessibility.dbus_sender.as_ref() {
|
||||
self.accessibility.screen_reader = enabled;
|
||||
let _ = tx.send(DBusRequest::Status(enabled));
|
||||
if enabled
|
||||
&& self
|
||||
.accessibility
|
||||
.screen_reader
|
||||
.as_mut()
|
||||
.is_none_or(|c| c.try_wait().is_ok())
|
||||
{
|
||||
self.accessibility.screen_reader =
|
||||
tokio::process::Command::new("/usr/bin/orca").spawn().ok();
|
||||
} else {
|
||||
self.accessibility.screen_reader = false;
|
||||
if let Some(mut c) = self.accessibility.screen_reader.take() {
|
||||
return cosmic::task::future::<(), ()>(async move {
|
||||
if let Err(err) = c.kill().await {
|
||||
log::error!("Failed to stop screen reader: {err:?}");
|
||||
}
|
||||
})
|
||||
.discard();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(helper) = self.accessibility.helper.as_ref() {
|
||||
_ = self
|
||||
.accessibility
|
||||
.state
|
||||
.set_screen_reader(&helper, Some(enabled));
|
||||
}
|
||||
}
|
||||
Message::Magnifier(enabled) => {
|
||||
if let Some(tx) = &self.accessibility.wayland_sender {
|
||||
self.accessibility.magnifier = enabled;
|
||||
let _ = tx.send(AccessibilityRequest::Magnifier(enabled));
|
||||
if let Some(helper) = self.accessibility.helper.as_ref() {
|
||||
_ = self
|
||||
.accessibility
|
||||
.state
|
||||
.set_magnifier(&helper, Some(enabled));
|
||||
}
|
||||
} else {
|
||||
self.accessibility.magnifier = false;
|
||||
}
|
||||
}
|
||||
Message::HighContrast(enabled) => {
|
||||
self.accessibility.high_contrast = enabled;
|
||||
|
||||
if let Some(helper) = self.accessibility.helper.as_ref() {
|
||||
_ = self
|
||||
.accessibility
|
||||
.state
|
||||
.set_high_contrast(&helper, Some(enabled));
|
||||
}
|
||||
let builder = self.theme_builder.clone();
|
||||
|
||||
return cosmic::task::future::<_, _>(async move {
|
||||
let builder = builder.clone();
|
||||
let (tx, rx) = tokio::sync::oneshot::channel();
|
||||
std::thread::spawn(move || {
|
||||
match apply_hc_theme(builder, enabled) {
|
||||
Ok(t) => {
|
||||
_ = tx.send(Some(t));
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!("{err:?}");
|
||||
_ = tx.send(None);
|
||||
}
|
||||
}
|
||||
});
|
||||
if let Ok(Some(theme)) = rx.await {
|
||||
cosmic::Action::App(Message::Reload(cosmic::Theme::custom(std::sync::Arc::new(theme))))
|
||||
} else {
|
||||
cosmic::Action::None
|
||||
}
|
||||
});
|
||||
}
|
||||
Message::InvertColors(enabled) => {
|
||||
if let Some(tx) = &self.accessibility.wayland_sender {
|
||||
|
|
@ -1483,6 +1539,12 @@ impl cosmic::Application for App {
|
|||
inverted: enabled,
|
||||
filter: None,
|
||||
});
|
||||
if let Some(helper) = self.accessibility.helper.as_ref() {
|
||||
_ = self
|
||||
.accessibility
|
||||
.state
|
||||
.set_invert_colors(&helper, Some(enabled));
|
||||
}
|
||||
} else {
|
||||
self.accessibility.invert_colors = false;
|
||||
}
|
||||
|
|
@ -1539,7 +1601,28 @@ impl cosmic::Application for App {
|
|||
self.common.subscription().map(Message::from),
|
||||
ipc::subscription(),
|
||||
wayland::a11y_subscription().map(Message::WaylandUpdate),
|
||||
accessibility::subscription().map(Message::DBusUpdate),
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn apply_hc_theme(builder: cosmic_theme::ThemeBuilder, enabled: bool) -> Result<cosmic_theme::Theme, cosmic_config::Error> {
|
||||
let is_dark = builder.palette.is_dark();
|
||||
let mut builder = builder.clone();
|
||||
|
||||
builder.palette = if is_dark {
|
||||
if enabled {
|
||||
CosmicPalette::HighContrastDark(builder.palette.inner())
|
||||
} else {
|
||||
CosmicPalette::Dark(builder.palette.inner())
|
||||
}
|
||||
} else if enabled {
|
||||
CosmicPalette::HighContrastLight(builder.palette.inner())
|
||||
} else {
|
||||
CosmicPalette::Light(builder.palette.inner())
|
||||
};
|
||||
|
||||
let new_theme = builder.build();
|
||||
|
||||
Ok(new_theme)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,4 @@ mod networkmanager;
|
|||
#[cfg(feature = "upower")]
|
||||
mod upower;
|
||||
|
||||
mod state;
|
||||
|
||||
mod time;
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
use std::os::unix::fs::PermissionsExt as _;
|
||||
|
||||
pub fn init() -> anyhow::Result<()> {
|
||||
let path = cosmic_settings_daemon_config::greeter::GreeterAccessibilityState::path();
|
||||
std::fs::create_dir_all(&path)?;
|
||||
std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o755))?;
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue