a11y: Add magnifier toggle
This commit is contained in:
parent
257784ebc8
commit
2b88f35991
21 changed files with 461 additions and 191 deletions
|
|
@ -2,27 +2,35 @@
|
|||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
use crate::{
|
||||
backend::{self, A11yRequest},
|
||||
backend::{
|
||||
self,
|
||||
dbus::{DBusRequest, DBusUpdate},
|
||||
wayland::{AccessibilityEvent, AccessibilityRequest, WaylandUpdate},
|
||||
},
|
||||
fl,
|
||||
};
|
||||
use cosmic::{
|
||||
applet::{
|
||||
padded_control,
|
||||
menu_button, padded_control,
|
||||
token::subscription::{activation_token_subscription, TokenRequest, TokenUpdate},
|
||||
},
|
||||
cctk::sctk::reexports::calloop,
|
||||
cctk::sctk::reexports::calloop::channel,
|
||||
cosmic_theme::Spacing,
|
||||
iced::{
|
||||
platform_specific::shell::wayland::commands::popup::{destroy_popup, get_popup},
|
||||
window, Length, Subscription,
|
||||
},
|
||||
iced_runtime::core::layout::Limits,
|
||||
widget::container,
|
||||
iced_widget::column,
|
||||
theme,
|
||||
widget::{divider, text},
|
||||
Element, Task,
|
||||
};
|
||||
use cosmic_time::{anim, chain, id, once_cell::sync::Lazy, Instant, Timeline};
|
||||
use tokio::sync::mpsc::UnboundedSender;
|
||||
|
||||
static ENABLED: Lazy<id::Toggler> = Lazy::new(id::Toggler::unique);
|
||||
static READER_TOGGLE: Lazy<id::Toggler> = Lazy::new(id::Toggler::unique);
|
||||
static MAGNIFIER_TOGGLE: Lazy<id::Toggler> = Lazy::new(id::Toggler::unique);
|
||||
|
||||
pub fn run() -> cosmic::iced::Result {
|
||||
cosmic::applet::run::<CosmicA11yApplet>(())
|
||||
|
|
@ -31,24 +39,26 @@ pub fn run() -> cosmic::iced::Result {
|
|||
#[derive(Clone, Default)]
|
||||
struct CosmicA11yApplet {
|
||||
core: cosmic::app::Core,
|
||||
icon_name: String,
|
||||
a11y_enabled: bool,
|
||||
reader_enabled: bool,
|
||||
magnifier_enabled: bool,
|
||||
popup: Option<window::Id>,
|
||||
a11y_sender: Option<UnboundedSender<backend::A11yRequest>>,
|
||||
dbus_sender: Option<UnboundedSender<DBusRequest>>,
|
||||
wayland_sender: Option<channel::SyncSender<AccessibilityRequest>>,
|
||||
timeline: Timeline,
|
||||
token_tx: Option<calloop::channel::Sender<TokenRequest>>,
|
||||
token_tx: Option<channel::Sender<TokenRequest>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
enum Message {
|
||||
TogglePopup,
|
||||
CloseRequested(window::Id),
|
||||
Errored(String),
|
||||
Enabled(chain::Toggler, bool),
|
||||
ScreenReaderEnabled(chain::Toggler, bool),
|
||||
MagnifierEnabled(chain::Toggler, bool),
|
||||
Frame(Instant),
|
||||
Token(TokenUpdate),
|
||||
OpenSettings,
|
||||
Update(backend::Update),
|
||||
DBusUpdate(DBusUpdate),
|
||||
WaylandUpdate(WaylandUpdate),
|
||||
}
|
||||
|
||||
impl cosmic::Application for CosmicA11yApplet {
|
||||
|
|
@ -89,16 +99,23 @@ impl cosmic::Application for CosmicA11yApplet {
|
|||
) -> cosmic::iced::Task<cosmic::app::Message<Self::Message>> {
|
||||
match message {
|
||||
Message::Frame(now) => self.timeline.now(now),
|
||||
Message::Enabled(chain, enabled) => {
|
||||
self.timeline.set_chain(chain).start();
|
||||
self.a11y_enabled = enabled;
|
||||
|
||||
if let Some(tx) = &self.a11y_sender {
|
||||
let _ = tx.send(A11yRequest::Status(enabled));
|
||||
Message::ScreenReaderEnabled(chain, enabled) => {
|
||||
if let Some(tx) = &self.dbus_sender {
|
||||
self.timeline.set_chain(chain).start();
|
||||
self.reader_enabled = enabled;
|
||||
let _ = tx.send(DBusRequest::Status(enabled));
|
||||
} else {
|
||||
self.reader_enabled = false;
|
||||
}
|
||||
}
|
||||
Message::Errored(why) => {
|
||||
tracing::error!("{}", why);
|
||||
Message::MagnifierEnabled(chain, enabled) => {
|
||||
if let Some(tx) = &self.wayland_sender {
|
||||
self.timeline.set_chain(chain).start();
|
||||
self.magnifier_enabled = enabled;
|
||||
let _ = tx.send(AccessibilityRequest::Magnifier(enabled));
|
||||
} else {
|
||||
self.magnifier_enabled = false;
|
||||
}
|
||||
}
|
||||
Message::TogglePopup => {
|
||||
if let Some(p) = self.popup.take() {
|
||||
|
|
@ -131,7 +148,7 @@ impl cosmic::Application for CosmicA11yApplet {
|
|||
}
|
||||
}
|
||||
Message::OpenSettings => {
|
||||
let exec = "cosmic-settings a11y".to_string();
|
||||
let exec = "cosmic-settings accessibility".to_string();
|
||||
if let Some(tx) = self.token_tx.as_ref() {
|
||||
let _ = tx.send(TokenRequest {
|
||||
app_id: Self::APP_ID.to_string(),
|
||||
|
|
@ -150,7 +167,7 @@ impl cosmic::Application for CosmicA11yApplet {
|
|||
}
|
||||
TokenUpdate::ActivationToken { token, .. } => {
|
||||
let mut cmd = std::process::Command::new("cosmic-settings");
|
||||
cmd.arg("a11y");
|
||||
cmd.arg("accessibility");
|
||||
if let Some(token) = token {
|
||||
cmd.env("XDG_ACTIVATION_TOKEN", &token);
|
||||
cmd.env("DESKTOP_STARTUP_ID", &token);
|
||||
|
|
@ -158,16 +175,31 @@ impl cosmic::Application for CosmicA11yApplet {
|
|||
tokio::spawn(cosmic::process::spawn(cmd));
|
||||
}
|
||||
},
|
||||
Message::Update(update) => match update {
|
||||
backend::Update::Error(err) => {
|
||||
Message::DBusUpdate(update) => match update {
|
||||
DBusUpdate::Error(err) => {
|
||||
tracing::error!("{err}");
|
||||
let _ = self.dbus_sender.take();
|
||||
self.reader_enabled = false;
|
||||
}
|
||||
backend::Update::Status(enabled) => {
|
||||
self.a11y_enabled = enabled;
|
||||
DBusUpdate::Status(enabled) => {
|
||||
self.reader_enabled = enabled;
|
||||
}
|
||||
backend::Update::Init(enabled, tx) => {
|
||||
self.a11y_enabled = enabled;
|
||||
self.a11y_sender = Some(tx);
|
||||
DBusUpdate::Init(enabled, tx) => {
|
||||
self.reader_enabled = enabled;
|
||||
self.dbus_sender = Some(tx);
|
||||
}
|
||||
},
|
||||
Message::WaylandUpdate(update) => match update {
|
||||
WaylandUpdate::Errored => {
|
||||
tracing::error!("Wayland error");
|
||||
let _ = self.wayland_sender.take();
|
||||
self.magnifier_enabled = false;
|
||||
}
|
||||
WaylandUpdate::State(AccessibilityEvent::Magnifier(enabled)) => {
|
||||
self.magnifier_enabled = enabled;
|
||||
}
|
||||
WaylandUpdate::Started(tx) => {
|
||||
self.wayland_sender = Some(tx);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
|
@ -183,22 +215,43 @@ impl cosmic::Application for CosmicA11yApplet {
|
|||
}
|
||||
|
||||
fn view_window(&self, _id: window::Id) -> Element<Message> {
|
||||
let toggle = padded_control(
|
||||
let Spacing {
|
||||
space_xxs, space_s, ..
|
||||
} = theme::active().cosmic().spacing;
|
||||
|
||||
let reader_toggle = padded_control(
|
||||
anim!(
|
||||
//toggler
|
||||
ENABLED,
|
||||
READER_TOGGLE,
|
||||
&self.timeline,
|
||||
fl!("accessibility"),
|
||||
self.a11y_enabled,
|
||||
Message::Enabled,
|
||||
fl!("screen-reader"),
|
||||
self.reader_enabled,
|
||||
Message::ScreenReaderEnabled,
|
||||
)
|
||||
.text_size(14)
|
||||
.width(Length::Fill),
|
||||
);
|
||||
let magnifier_toggle = padded_control(
|
||||
anim!(
|
||||
MAGNIFIER_TOGGLE,
|
||||
&self.timeline,
|
||||
fl!("magnifier"),
|
||||
self.magnifier_enabled,
|
||||
Message::MagnifierEnabled,
|
||||
)
|
||||
.text_size(14)
|
||||
.width(Length::Fill),
|
||||
);
|
||||
|
||||
let content_list = column![
|
||||
reader_toggle,
|
||||
magnifier_toggle,
|
||||
padded_control(divider::horizontal::default()).padding([space_xxs, space_s]),
|
||||
menu_button(text::body(fl!("settings"))).on_press(Message::OpenSettings)
|
||||
]
|
||||
.padding([8, 0]);
|
||||
self.core
|
||||
.applet
|
||||
.popup_container(container(toggle).padding([8, 0]))
|
||||
.popup_container(content_list)
|
||||
.max_width(372.)
|
||||
.max_height(600.)
|
||||
.into()
|
||||
|
|
@ -206,7 +259,8 @@ impl cosmic::Application for CosmicA11yApplet {
|
|||
|
||||
fn subscription(&self) -> Subscription<Message> {
|
||||
Subscription::batch(vec![
|
||||
backend::subscription().map(Message::Update),
|
||||
backend::dbus::subscription().map(Message::DBusUpdate),
|
||||
backend::wayland::a11y_subscription().map(Message::WaylandUpdate),
|
||||
self.timeline
|
||||
.as_subscription()
|
||||
.map(|(_, now)| Message::Frame(now)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue