Update wallpapers when slideshow is used
This commit is contained in:
parent
49ee2c63b7
commit
38d602e71a
2 changed files with 443 additions and 257 deletions
578
Cargo.lock
generated
578
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
122
src/locker.rs
122
src/locker.rs
|
|
@ -17,6 +17,7 @@ use cosmic::{
|
||||||
};
|
};
|
||||||
use cosmic_config::CosmicConfigEntry;
|
use cosmic_config::CosmicConfigEntry;
|
||||||
use std::{
|
use std::{
|
||||||
|
any::TypeId,
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
ffi::{CStr, CString},
|
ffi::{CStr, CString},
|
||||||
fs,
|
fs,
|
||||||
|
|
@ -193,6 +194,7 @@ pub enum Message {
|
||||||
OutputEvent(OutputEvent, WlOutput),
|
OutputEvent(OutputEvent, WlOutput),
|
||||||
SessionLockEvent(SessionLockEvent),
|
SessionLockEvent(SessionLockEvent),
|
||||||
Channel(mpsc::Sender<String>),
|
Channel(mpsc::Sender<String>),
|
||||||
|
BackgroundState(cosmic_bg_config::state::State),
|
||||||
Prompt(String, bool, Option<String>),
|
Prompt(String, bool, Option<String>),
|
||||||
Submit,
|
Submit,
|
||||||
Error(String),
|
Error(String),
|
||||||
|
|
@ -207,12 +209,60 @@ pub struct App {
|
||||||
surface_ids: HashMap<WlOutput, SurfaceId>,
|
surface_ids: HashMap<WlOutput, SurfaceId>,
|
||||||
active_surface_id_opt: Option<SurfaceId>,
|
active_surface_id_opt: Option<SurfaceId>,
|
||||||
surface_images: HashMap<SurfaceId, widget::image::Handle>,
|
surface_images: HashMap<SurfaceId, widget::image::Handle>,
|
||||||
|
surface_names: HashMap<SurfaceId, String>,
|
||||||
value_tx_opt: Option<mpsc::Sender<String>>,
|
value_tx_opt: Option<mpsc::Sender<String>>,
|
||||||
prompt_opt: Option<(String, bool, Option<String>)>,
|
prompt_opt: Option<(String, bool, Option<String>)>,
|
||||||
error_opt: Option<String>,
|
error_opt: Option<String>,
|
||||||
exited: bool,
|
exited: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
//TODO: cache wallpapers by source?
|
||||||
|
fn update_wallpapers(&mut self) {
|
||||||
|
for (output, surface_id) in self.surface_ids.iter() {
|
||||||
|
if self.surface_images.contains_key(surface_id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let output_name = match self.surface_names.get(surface_id) {
|
||||||
|
Some(some) => some,
|
||||||
|
None => continue,
|
||||||
|
};
|
||||||
|
|
||||||
|
log::info!("updating wallpaper for {:?}", output_name);
|
||||||
|
|
||||||
|
for (wallpaper_output_name, wallpaper_source) in self.flags.wallpapers.iter() {
|
||||||
|
if wallpaper_output_name == output_name {
|
||||||
|
match wallpaper_source {
|
||||||
|
cosmic_bg_config::Source::Path(path) => {
|
||||||
|
match fs::read(path) {
|
||||||
|
Ok(bytes) => {
|
||||||
|
let image = widget::image::Handle::from_memory(bytes);
|
||||||
|
self.surface_images.insert(*surface_id, image);
|
||||||
|
//TODO: what to do about duplicates?
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
log::warn!(
|
||||||
|
"output {}: failed to load wallpaper {:?}: {:?}",
|
||||||
|
output.id(),
|
||||||
|
path,
|
||||||
|
err
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cosmic_bg_config::Source::Color(color) => {
|
||||||
|
//TODO: support color sources
|
||||||
|
log::warn!("output {}: unsupported source {:?}", output.id(), color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Implement [`cosmic::Application`] to integrate with COSMIC.
|
/// Implement [`cosmic::Application`] to integrate with COSMIC.
|
||||||
impl cosmic::Application for App {
|
impl cosmic::Application for App {
|
||||||
/// Default async executor to use with the app.
|
/// Default async executor to use with the app.
|
||||||
|
|
@ -252,6 +302,7 @@ impl cosmic::Application for App {
|
||||||
surface_ids: HashMap::new(),
|
surface_ids: HashMap::new(),
|
||||||
active_surface_id_opt: None,
|
active_surface_id_opt: None,
|
||||||
surface_images: HashMap::new(),
|
surface_images: HashMap::new(),
|
||||||
|
surface_names: HashMap::new(),
|
||||||
value_tx_opt: None,
|
value_tx_opt: None,
|
||||||
prompt_opt: None,
|
prompt_opt: None,
|
||||||
error_opt: None,
|
error_opt: None,
|
||||||
|
|
@ -286,45 +337,16 @@ impl cosmic::Application for App {
|
||||||
}
|
}
|
||||||
|
|
||||||
match output_info_opt {
|
match output_info_opt {
|
||||||
Some(output_info) => {
|
Some(output_info) => match output_info.name {
|
||||||
match output_info.name {
|
Some(output_name) => {
|
||||||
Some(output_name) => {
|
self.surface_names.insert(surface_id, output_name.clone());
|
||||||
for (wallpaper_output_name, wallpaper_source) in
|
self.surface_images.remove(&surface_id);
|
||||||
self.flags.wallpapers.iter()
|
self.update_wallpapers();
|
||||||
{
|
|
||||||
if wallpaper_output_name == &output_name {
|
|
||||||
match wallpaper_source {
|
|
||||||
cosmic_bg_config::Source::Path(path) => {
|
|
||||||
match fs::read(path) {
|
|
||||||
Ok(bytes) => {
|
|
||||||
let image = widget::image::Handle::from_memory(bytes);
|
|
||||||
self.surface_images
|
|
||||||
.insert(surface_id, image);
|
|
||||||
//TODO: what to do about duplicates?
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
log::warn!("output {}: failed to load wallpaper {:?}: {:?}", output.id(), path, err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cosmic_bg_config::Source::Color(color) => {
|
|
||||||
//TODO: support color sources
|
|
||||||
log::warn!(
|
|
||||||
"output {}: unsupported source {:?}",
|
|
||||||
output.id(),
|
|
||||||
color
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
log::warn!("output {}: no output name", output.id());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
None => {
|
||||||
|
log::warn!("output {}: no output name", output.id());
|
||||||
|
}
|
||||||
|
},
|
||||||
None => {
|
None => {
|
||||||
log::warn!("output {}: no output info", output.id());
|
log::warn!("output {}: no output info", output.id());
|
||||||
}
|
}
|
||||||
|
|
@ -340,6 +362,7 @@ impl cosmic::Application for App {
|
||||||
match self.surface_ids.remove(&output) {
|
match self.surface_ids.remove(&output) {
|
||||||
Some(surface_id) => {
|
Some(surface_id) => {
|
||||||
self.surface_images.remove(&surface_id);
|
self.surface_images.remove(&surface_id);
|
||||||
|
self.surface_names.remove(&surface_id);
|
||||||
return destroy_lock_surface(surface_id);
|
return destroy_lock_surface(surface_id);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -366,6 +389,11 @@ impl cosmic::Application for App {
|
||||||
Message::Channel(value_tx) => {
|
Message::Channel(value_tx) => {
|
||||||
self.value_tx_opt = Some(value_tx);
|
self.value_tx_opt = Some(value_tx);
|
||||||
}
|
}
|
||||||
|
Message::BackgroundState(background_state) => {
|
||||||
|
self.flags.wallpapers = background_state.wallpapers;
|
||||||
|
self.surface_images.clear();
|
||||||
|
self.update_wallpapers();
|
||||||
|
}
|
||||||
Message::Prompt(prompt, secret, value_opt) => {
|
Message::Prompt(prompt, secret, value_opt) => {
|
||||||
let prompt_was_none = self.prompt_opt.is_none();
|
let prompt_was_none = self.prompt_opt.is_none();
|
||||||
self.prompt_opt = Some((prompt, secret, value_opt));
|
self.prompt_opt = Some((prompt, secret, value_opt));
|
||||||
|
|
@ -400,6 +428,7 @@ impl cosmic::Application for App {
|
||||||
let mut commands = Vec::new();
|
let mut commands = Vec::new();
|
||||||
for (_output, surface_id) in self.surface_ids.drain() {
|
for (_output, surface_id) in self.surface_ids.drain() {
|
||||||
self.surface_images.remove(&surface_id);
|
self.surface_images.remove(&surface_id);
|
||||||
|
self.surface_names.remove(&surface_id);
|
||||||
commands.push(destroy_lock_surface(surface_id));
|
commands.push(destroy_lock_surface(surface_id));
|
||||||
}
|
}
|
||||||
commands.push(unlock());
|
commands.push(unlock());
|
||||||
|
|
@ -594,6 +623,7 @@ impl cosmic::Application for App {
|
||||||
return Subscription::none();
|
return Subscription::none();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BackgroundSubscription;
|
||||||
struct HeartbeatSubscription;
|
struct HeartbeatSubscription;
|
||||||
struct PamSubscription;
|
struct PamSubscription;
|
||||||
|
|
||||||
|
|
@ -612,8 +642,20 @@ impl cosmic::Application for App {
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
}),
|
}),
|
||||||
|
cosmic_config::config_state_subscription(
|
||||||
|
TypeId::of::<BackgroundSubscription>(),
|
||||||
|
cosmic_bg_config::NAME.into(),
|
||||||
|
cosmic_bg_config::state::State::version(),
|
||||||
|
)
|
||||||
|
.map(|(_, res)| match res {
|
||||||
|
Ok(background_state) => Message::BackgroundState(background_state),
|
||||||
|
Err((errs, background_state)) => {
|
||||||
|
log::info!("errors loading background state: {:?}", errs);
|
||||||
|
Message::BackgroundState(background_state)
|
||||||
|
}
|
||||||
|
}),
|
||||||
subscription::channel(
|
subscription::channel(
|
||||||
std::any::TypeId::of::<HeartbeatSubscription>(),
|
TypeId::of::<HeartbeatSubscription>(),
|
||||||
16,
|
16,
|
||||||
|mut msg_tx| async move {
|
|mut msg_tx| async move {
|
||||||
loop {
|
loop {
|
||||||
|
|
@ -625,7 +667,7 @@ impl cosmic::Application for App {
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
subscription::channel(
|
subscription::channel(
|
||||||
std::any::TypeId::of::<PamSubscription>(),
|
TypeId::of::<PamSubscription>(),
|
||||||
16,
|
16,
|
||||||
|mut msg_tx| async move {
|
|mut msg_tx| async move {
|
||||||
loop {
|
loop {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue