Implement lock on demand
This commit is contained in:
parent
349c009321
commit
eb3ba78e57
2 changed files with 161 additions and 91 deletions
32
Cargo.lock
generated
32
Cargo.lock
generated
|
|
@ -905,7 +905,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"atomicwrites",
|
||||
"calloop",
|
||||
|
|
@ -923,7 +923,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-config-derive"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
|
|
@ -1026,7 +1026,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "cosmic-theme"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"almost",
|
||||
"cosmic-config",
|
||||
|
|
@ -2247,7 +2247,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"dnd",
|
||||
"iced_accessibility",
|
||||
|
|
@ -2265,7 +2265,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_accessibility"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"accesskit",
|
||||
"accesskit_unix",
|
||||
|
|
@ -2274,7 +2274,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_core"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"dnd",
|
||||
|
|
@ -2296,7 +2296,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_futures"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"futures",
|
||||
"iced_core",
|
||||
|
|
@ -2309,7 +2309,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_graphics"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
|
|
@ -2333,7 +2333,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_renderer"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"iced_graphics",
|
||||
"iced_tiny_skia",
|
||||
|
|
@ -2345,7 +2345,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_runtime"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"dnd",
|
||||
"iced_accessibility",
|
||||
|
|
@ -2359,7 +2359,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_sctk"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"enum-repr",
|
||||
"float-cmp",
|
||||
|
|
@ -2385,7 +2385,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_style"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"iced_core",
|
||||
"once_cell",
|
||||
|
|
@ -2395,7 +2395,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_tiny_skia"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"cosmic-text",
|
||||
|
|
@ -2412,7 +2412,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_wgpu"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"bytemuck",
|
||||
|
|
@ -2431,7 +2431,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "iced_widget"
|
||||
version = "0.12.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"dnd",
|
||||
"iced_renderer",
|
||||
|
|
@ -2676,7 +2676,7 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
|||
[[package]]
|
||||
name = "libcosmic"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/pop-os/libcosmic#6b7fa3d4767bbf21b39d07b3bdba4a49e6375dd1"
|
||||
source = "git+https://github.com/pop-os/libcosmic#0dca2e046887922563236f0b22b55313efc80319"
|
||||
dependencies = [
|
||||
"apply",
|
||||
"ashpd 0.7.0",
|
||||
|
|
|
|||
220
src/locker.rs
220
src/locker.rs
|
|
@ -195,20 +195,29 @@ pub enum Message {
|
|||
SessionLockEvent(SessionLockEvent),
|
||||
Channel(mpsc::Sender<String>),
|
||||
BackgroundState(cosmic_bg_config::state::State),
|
||||
LogindLock,
|
||||
NetworkIcon(Option<&'static str>),
|
||||
PowerInfo(Option<(String, f64)>),
|
||||
Prompt(String, bool, Option<String>),
|
||||
Submit,
|
||||
Suspend,
|
||||
Error(String),
|
||||
Lock,
|
||||
Unlock,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
enum State {
|
||||
Locking,
|
||||
Locked,
|
||||
Unlocking,
|
||||
Unlocked,
|
||||
}
|
||||
|
||||
/// The [`App`] stores application-specific state.
|
||||
pub struct App {
|
||||
core: Core,
|
||||
flags: Flags,
|
||||
state: State,
|
||||
surface_ids: HashMap<WlOutput, SurfaceId>,
|
||||
active_surface_id_opt: Option<SurfaceId>,
|
||||
surface_images: HashMap<SurfaceId, widget::image::Handle>,
|
||||
|
|
@ -303,6 +312,7 @@ impl cosmic::Application for App {
|
|||
App {
|
||||
core,
|
||||
flags,
|
||||
state: State::Unlocked,
|
||||
surface_ids: HashMap::new(),
|
||||
active_surface_id_opt: None,
|
||||
surface_images: HashMap::new(),
|
||||
|
|
@ -314,7 +324,13 @@ impl cosmic::Application for App {
|
|||
prompt_opt: None,
|
||||
error_opt: None,
|
||||
},
|
||||
lock(),
|
||||
if cfg!(feature = "logind") {
|
||||
// When logind feature is used, wait for lock signal
|
||||
Command::none()
|
||||
} else {
|
||||
// When logind feature not used, lock immediately
|
||||
lock()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -360,10 +376,12 @@ impl cosmic::Application for App {
|
|||
self.text_input_ids
|
||||
.insert(surface_id, text_input_id.clone());
|
||||
|
||||
return Command::batch([
|
||||
get_lock_surface(surface_id, output),
|
||||
widget::text_input::focus(text_input_id),
|
||||
]);
|
||||
if matches!(self.state, State::Locked) {
|
||||
return Command::batch([
|
||||
get_lock_surface(surface_id, output),
|
||||
widget::text_input::focus(text_input_id),
|
||||
]);
|
||||
}
|
||||
}
|
||||
OutputEvent::Removed => {
|
||||
log::info!("output {}: removed", output.id());
|
||||
|
|
@ -372,15 +390,17 @@ impl cosmic::Application for App {
|
|||
self.surface_images.remove(&surface_id);
|
||||
self.surface_names.remove(&surface_id);
|
||||
self.text_input_ids.remove(&surface_id);
|
||||
return destroy_lock_surface(surface_id);
|
||||
if matches!(self.state, State::Locked) {
|
||||
return destroy_lock_surface(surface_id);
|
||||
}
|
||||
}
|
||||
None => {
|
||||
log::warn!("output {}: no surface found", output.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
OutputEvent::InfoUpdate(output_info) => {
|
||||
log::info!("output {}: info update {:#?}", output.id(), output_info);
|
||||
OutputEvent::InfoUpdate(_output_info) => {
|
||||
log::info!("output {}: info update", output.id());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -392,10 +412,27 @@ impl cosmic::Application for App {
|
|||
return widget::text_input::focus(text_input_id.clone());
|
||||
}
|
||||
}
|
||||
SessionLockEvent::Unlocked => {
|
||||
//TODO: cleaner method to exit?
|
||||
process::exit(0);
|
||||
SessionLockEvent::Locked => {
|
||||
log::info!("session locked");
|
||||
self.state = State::Locked;
|
||||
let mut commands = Vec::with_capacity(self.surface_ids.len());
|
||||
for (output, surface_id) in self.surface_ids.iter() {
|
||||
commands.push(get_lock_surface(*surface_id, output.clone()));
|
||||
}
|
||||
return Command::batch(commands);
|
||||
}
|
||||
SessionLockEvent::Unlocked => {
|
||||
log::info!("session unlocked");
|
||||
self.state = State::Unlocked;
|
||||
if cfg!(feature = "logind") {
|
||||
// When using logind feature, stick around for more lock signals
|
||||
} else {
|
||||
// When not using logind feature, exit immediately after unlocking
|
||||
//TODO: cleaner method to exit?
|
||||
process::exit(0);
|
||||
}
|
||||
}
|
||||
//TODO: handle finished signal
|
||||
_ => {}
|
||||
},
|
||||
Message::Channel(value_tx) => {
|
||||
|
|
@ -406,9 +443,6 @@ impl cosmic::Application for App {
|
|||
self.surface_images.clear();
|
||||
self.update_wallpapers();
|
||||
}
|
||||
Message::LogindLock => {
|
||||
log::warn!("TODO: LogindLock");
|
||||
}
|
||||
Message::NetworkIcon(network_icon_opt) => {
|
||||
self.network_icon_opt = network_icon_opt;
|
||||
}
|
||||
|
|
@ -430,6 +464,8 @@ impl cosmic::Application for App {
|
|||
Some((_prompt, _secret, value_opt)) => match value_opt {
|
||||
Some(value) => match self.value_tx_opt.take() {
|
||||
Some(value_tx) => {
|
||||
// Clear errors
|
||||
self.error_opt = None;
|
||||
return Command::perform(
|
||||
async move {
|
||||
value_tx.send(value).await.unwrap();
|
||||
|
|
@ -462,17 +498,47 @@ impl cosmic::Application for App {
|
|||
Message::Error(error) => {
|
||||
self.error_opt = Some(error);
|
||||
}
|
||||
Message::Unlock => {
|
||||
let mut commands = Vec::new();
|
||||
for (_output, surface_id) in self.surface_ids.drain() {
|
||||
self.surface_images.remove(&surface_id);
|
||||
self.surface_names.remove(&surface_id);
|
||||
self.text_input_ids.remove(&surface_id);
|
||||
commands.push(destroy_lock_surface(surface_id));
|
||||
Message::Lock => match self.state {
|
||||
State::Unlocked => {
|
||||
log::info!("session locking");
|
||||
self.state = State::Locking;
|
||||
// Clear errors
|
||||
self.error_opt = None;
|
||||
// Clear value_tx
|
||||
self.value_tx_opt = None;
|
||||
return lock();
|
||||
}
|
||||
State::Unlocking => {
|
||||
log::info!("session still unlocking");
|
||||
}
|
||||
State::Locking | State::Locked => {
|
||||
log::info!("session already locking or locked");
|
||||
}
|
||||
},
|
||||
Message::Unlock => {
|
||||
match self.state {
|
||||
State::Locked => {
|
||||
log::info!("sessing unlocking");
|
||||
self.state = State::Unlocking;
|
||||
// Clear errors
|
||||
self.error_opt = None;
|
||||
// Clear value_tx
|
||||
self.value_tx_opt = None;
|
||||
let mut commands = Vec::with_capacity(self.surface_ids.len() + 1);
|
||||
for (_output, surface_id) in self.surface_ids.iter() {
|
||||
commands.push(destroy_lock_surface(*surface_id));
|
||||
}
|
||||
commands.push(unlock());
|
||||
// Wait to exit until `Unlocked` event, when server has processed unlock
|
||||
return Command::batch(commands);
|
||||
}
|
||||
State::Locking => {
|
||||
log::info!("session still locking");
|
||||
}
|
||||
State::Unlocking | State::Unlocked => {
|
||||
log::info!("session already unlocking or unlocked");
|
||||
}
|
||||
}
|
||||
commands.push(unlock());
|
||||
// Wait to exit until `Unlocked` event, when server has processed unlock
|
||||
return Command::batch(commands);
|
||||
}
|
||||
}
|
||||
Command::none()
|
||||
|
|
@ -659,53 +725,23 @@ impl cosmic::Application for App {
|
|||
}
|
||||
|
||||
fn subscription(&self) -> Subscription<Self::Message> {
|
||||
struct BackgroundSubscription;
|
||||
struct HeartbeatSubscription;
|
||||
struct PamSubscription;
|
||||
let mut subscriptions = Vec::with_capacity(7);
|
||||
|
||||
//TODO: just use one vec for all subscriptions
|
||||
let mut extra_subscriptions = Vec::with_capacity(3);
|
||||
|
||||
#[cfg(feature = "logind")]
|
||||
{
|
||||
extra_subscriptions.push(crate::logind::subscription().map(|lock| {
|
||||
if lock {
|
||||
Message::LogindLock
|
||||
} else {
|
||||
Message::Unlock
|
||||
subscriptions.push(event::listen_with(|event, _| match event {
|
||||
iced::Event::PlatformSpecific(iced::event::PlatformSpecific::Wayland(
|
||||
wayland_event,
|
||||
)) => match wayland_event {
|
||||
WaylandEvent::Output(output_event, output) => {
|
||||
Some(Message::OutputEvent(output_event, output))
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(feature = "networkmanager")]
|
||||
{
|
||||
extra_subscriptions.push(
|
||||
crate::networkmanager::subscription()
|
||||
.map(|icon_opt| Message::NetworkIcon(icon_opt)),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "upower")]
|
||||
{
|
||||
extra_subscriptions
|
||||
.push(crate::upower::subscription().map(|info_opt| Message::PowerInfo(info_opt)));
|
||||
}
|
||||
|
||||
//TODO: how to avoid cloning this on every time subscription is called?
|
||||
let username = self.flags.current_user.name.clone();
|
||||
Subscription::batch([
|
||||
event::listen_with(|event, _| match event {
|
||||
iced::Event::PlatformSpecific(iced::event::PlatformSpecific::Wayland(
|
||||
wayland_event,
|
||||
)) => match wayland_event {
|
||||
WaylandEvent::Output(output_event, output) => {
|
||||
Some(Message::OutputEvent(output_event, output))
|
||||
}
|
||||
WaylandEvent::SessionLock(evt) => Some(Message::SessionLockEvent(evt)),
|
||||
_ => None,
|
||||
},
|
||||
WaylandEvent::SessionLock(evt) => Some(Message::SessionLockEvent(evt)),
|
||||
_ => None,
|
||||
}),
|
||||
},
|
||||
_ => None,
|
||||
}));
|
||||
|
||||
struct BackgroundSubscription;
|
||||
subscriptions.push(
|
||||
cosmic_config::config_state_subscription(
|
||||
TypeId::of::<BackgroundSubscription>(),
|
||||
cosmic_bg_config::NAME.into(),
|
||||
|
|
@ -717,7 +753,11 @@ impl cosmic::Application for App {
|
|||
}
|
||||
Message::BackgroundState(res.config)
|
||||
}),
|
||||
subscription::channel(
|
||||
);
|
||||
|
||||
if matches!(self.state, State::Locked) {
|
||||
struct HeartbeatSubscription;
|
||||
subscriptions.push(subscription::channel(
|
||||
TypeId::of::<HeartbeatSubscription>(),
|
||||
16,
|
||||
|mut msg_tx| async move {
|
||||
|
|
@ -728,8 +768,12 @@ impl cosmic::Application for App {
|
|||
time::sleep(time::Duration::new(1, 0)).await;
|
||||
}
|
||||
},
|
||||
),
|
||||
subscription::channel(
|
||||
));
|
||||
|
||||
struct PamSubscription;
|
||||
//TODO: how to avoid cloning this on every time subscription is called?
|
||||
let username = self.flags.current_user.name.clone();
|
||||
subscriptions.push(subscription::channel(
|
||||
TypeId::of::<PamSubscription>(),
|
||||
16,
|
||||
|mut msg_tx| async move {
|
||||
|
|
@ -764,8 +808,34 @@ impl cosmic::Application for App {
|
|||
time::sleep(time::Duration::new(60, 0)).await;
|
||||
}
|
||||
},
|
||||
),
|
||||
Subscription::batch(extra_subscriptions),
|
||||
])
|
||||
));
|
||||
}
|
||||
|
||||
#[cfg(feature = "logind")]
|
||||
{
|
||||
subscriptions.push(crate::logind::subscription().map(|lock| {
|
||||
if lock {
|
||||
Message::Lock
|
||||
} else {
|
||||
Message::Unlock
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
#[cfg(feature = "networkmanager")]
|
||||
{
|
||||
subscriptions.push(
|
||||
crate::networkmanager::subscription()
|
||||
.map(|icon_opt| Message::NetworkIcon(icon_opt)),
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(feature = "upower")]
|
||||
{
|
||||
subscriptions
|
||||
.push(crate::upower::subscription().map(|info_opt| Message::PowerInfo(info_opt)));
|
||||
}
|
||||
|
||||
Subscription::batch(subscriptions)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue