fix(wallpaper): display preview not set when custom images are yet to be loaded
This commit is contained in:
parent
beaa7bd71e
commit
25b344703c
1 changed files with 70 additions and 63 deletions
|
|
@ -63,6 +63,16 @@ const HOUR_2: usize = 5;
|
||||||
|
|
||||||
pub type Image = ImageBuffer<Rgba<u8>, Vec<u8>>;
|
pub type Image = ImageBuffer<Rgba<u8>, Vec<u8>>;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
struct OutputName(String);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct InitUpdate {
|
||||||
|
service_config: wallpaper::Config,
|
||||||
|
displays: HashMap<String, (String, (u32, u32))>,
|
||||||
|
selection: Context,
|
||||||
|
}
|
||||||
|
|
||||||
/// Messages for the wallpaper view.
|
/// Messages for the wallpaper view.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Message {
|
pub enum Message {
|
||||||
|
|
@ -93,13 +103,7 @@ pub enum Message {
|
||||||
/// Removes a custom image from the wallpaper view.
|
/// Removes a custom image from the wallpaper view.
|
||||||
ImageRemove(DefaultKey),
|
ImageRemove(DefaultKey),
|
||||||
/// Initializes the view.
|
/// Initializes the view.
|
||||||
Init(
|
Init(Box<InitUpdate>),
|
||||||
Box<(
|
|
||||||
wallpaper::Config,
|
|
||||||
HashMap<String, (String, (u32, u32))>,
|
|
||||||
Context,
|
|
||||||
)>,
|
|
||||||
),
|
|
||||||
/// Changes the active output display that is to be configured.
|
/// Changes the active output display that is to be configured.
|
||||||
Output(segmented_button::Entity),
|
Output(segmented_button::Entity),
|
||||||
/// Changes the rotation frequency of wallpaper images in slideshow mode.
|
/// Changes the rotation frequency of wallpaper images in slideshow mode.
|
||||||
|
|
@ -112,6 +116,13 @@ pub enum Message {
|
||||||
Slideshow(bool),
|
Slideshow(bool),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<Message> for crate::app::Message {
|
||||||
|
fn from(message: Message) -> Self {
|
||||||
|
let page_message = crate::pages::Message::DesktopWallpaper(message);
|
||||||
|
crate::app::Message::PageMessage(page_message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Messages defined for the category dropdown menu.
|
/// Messages defined for the category dropdown menu.
|
||||||
#[derive(Clone, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub enum Category {
|
pub enum Category {
|
||||||
|
|
@ -170,6 +181,9 @@ pub struct Page {
|
||||||
|
|
||||||
/// Stores custom colors, custom images, and all image data for every wallpaper.
|
/// Stores custom colors, custom images, and all image data for every wallpaper.
|
||||||
selection: Context,
|
selection: Context,
|
||||||
|
|
||||||
|
/// When set, applys a config update after images are loaded.
|
||||||
|
update_config: Option<(usize, HashMap<String, (String, (u32, u32))>)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl page::Page<crate::pages::Message> for Page {
|
impl page::Page<crate::pages::Message> for Page {
|
||||||
|
|
@ -190,15 +204,15 @@ impl page::Page<crate::pages::Message> for Page {
|
||||||
let current_folder = self.config.current_folder().to_owned();
|
let current_folder = self.config.current_folder().to_owned();
|
||||||
|
|
||||||
command::future(async move {
|
command::future(async move {
|
||||||
let (wallpaper_service_config, outputs) = wallpaper::config().await;
|
let (service_config, displays) = wallpaper::config().await;
|
||||||
|
|
||||||
let update = change_folder(current_folder).await;
|
let selection = change_folder(current_folder).await;
|
||||||
|
|
||||||
crate::pages::Message::DesktopWallpaper(Message::Init(Box::new((
|
crate::pages::Message::DesktopWallpaper(Message::Init(Box::new(InitUpdate {
|
||||||
wallpaper_service_config,
|
service_config,
|
||||||
outputs,
|
displays,
|
||||||
update,
|
selection,
|
||||||
))))
|
})))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -268,6 +282,7 @@ impl Default for Page {
|
||||||
selected_fit: 0,
|
selected_fit: 0,
|
||||||
selected_rotation: 0,
|
selected_rotation: 0,
|
||||||
selection: Context::default(),
|
selection: Context::default(),
|
||||||
|
update_config: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
page.assign_recent_folders();
|
page.assign_recent_folders();
|
||||||
|
|
@ -358,7 +373,10 @@ impl Page {
|
||||||
if self.wallpaper_service_config.same_on_all {
|
if self.wallpaper_service_config.same_on_all {
|
||||||
Some(String::from("all"))
|
Some(String::from("all"))
|
||||||
} else {
|
} else {
|
||||||
self.outputs.active_data::<String>().cloned()
|
self.outputs
|
||||||
|
.active_data::<OutputName>()
|
||||||
|
.cloned()
|
||||||
|
.map(|name| name.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -417,25 +435,18 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates configuration from the wallpaper service.
|
/// Updates configuration from the wallpaper service.
|
||||||
fn wallpaper_service_config_update(
|
fn wallpaper_service_config_update(&mut self, displays: HashMap<String, (String, (u32, u32))>) {
|
||||||
&mut self,
|
|
||||||
wallpaper_service_config: wallpaper::Config,
|
|
||||||
displays: HashMap<String, (String, (u32, u32))>,
|
|
||||||
selection: Context,
|
|
||||||
) {
|
|
||||||
self.wallpaper_service_config = wallpaper_service_config;
|
|
||||||
self.selection = selection;
|
|
||||||
self.outputs.clear();
|
|
||||||
|
|
||||||
let mut first = None;
|
let mut first = None;
|
||||||
for (name, (_model, physical)) in displays {
|
for (name, (_model, physical)) in displays {
|
||||||
|
let is_internal = "eDP-1" == name;
|
||||||
|
|
||||||
let entity = self
|
let entity = self
|
||||||
.outputs
|
.outputs
|
||||||
.insert()
|
.insert()
|
||||||
.text(crate::utils::display_name(&name, physical))
|
.text(crate::utils::display_name(&name, physical))
|
||||||
.data(name);
|
.data(OutputName(name));
|
||||||
|
|
||||||
if first.is_none() {
|
if is_internal || first.is_none() {
|
||||||
first = Some(entity.id());
|
first = Some(entity.id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -449,16 +460,17 @@ impl Page {
|
||||||
{
|
{
|
||||||
let entry = self.wallpaper_service_config.default_background.clone();
|
let entry = self.wallpaper_service_config.default_background.clone();
|
||||||
self.select_wallpaper_entry(&entry);
|
self.select_wallpaper_entry(&entry);
|
||||||
} else if let Some(data) = self.outputs.active_data::<String>() {
|
} else if let Some(OutputName(output)) = self.outputs.active_data() {
|
||||||
let mut wallpapers = Vec::new();
|
let mut wallpapers = Vec::new();
|
||||||
|
|
||||||
std::mem::swap(
|
std::mem::swap(
|
||||||
&mut self.wallpaper_service_config.backgrounds,
|
&mut self.wallpaper_service_config.backgrounds,
|
||||||
&mut wallpapers,
|
&mut wallpapers,
|
||||||
);
|
);
|
||||||
|
|
||||||
for wallpaper in &wallpapers {
|
for wallpaper in &wallpapers {
|
||||||
if &wallpaper.output == data {
|
if wallpaper.output == *output {
|
||||||
self.active_output = Some(data.clone());
|
self.active_output = Some(output.clone());
|
||||||
self.select_wallpaper_entry(wallpaper);
|
self.select_wallpaper_entry(wallpaper);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -675,6 +687,17 @@ impl Page {
|
||||||
selection.into_vec(),
|
selection.into_vec(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If an update was queued, apply it after all custom images have been added.
|
||||||
|
if let Some((mut remaining, displays)) = self.update_config.take() {
|
||||||
|
remaining -= 1;
|
||||||
|
if remaining == 0 {
|
||||||
|
self.wallpaper_service_config_update(displays);
|
||||||
|
self.config_apply();
|
||||||
|
} else {
|
||||||
|
self.update_config = Some((remaining, displays));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::ImageAddDialog => {
|
Message::ImageAddDialog => {
|
||||||
|
|
@ -796,8 +819,9 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::Init(update) => {
|
Message::Init(update) => {
|
||||||
self.wallpaper_service_config_update(update.0, update.1, update.2);
|
self.outputs.clear();
|
||||||
self.config_apply();
|
self.wallpaper_service_config = update.service_config;
|
||||||
|
self.selection = update.selection;
|
||||||
|
|
||||||
// Sync custom colors from config.
|
// Sync custom colors from config.
|
||||||
for color in self.config.custom_colors() {
|
for color in self.config.custom_colors() {
|
||||||
|
|
@ -814,21 +838,21 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load preview images for each custom image stored in the on-disk config.
|
// These will need to be loaded before applying the service config.
|
||||||
return cosmic::command::batch(self.config.custom_images().iter().cloned().map(
|
let custom_images = self.config.custom_images();
|
||||||
|path| {
|
|
||||||
cosmic::command::future(async move {
|
|
||||||
let result =
|
|
||||||
wallpaper::load_image_with_thumbnail(&mut Vec::new(), path).await;
|
|
||||||
|
|
||||||
crate::app::Message::PageMessage(
|
// Make note of how many images are to be loaded, with the display update for the service config.
|
||||||
crate::pages::Message::DesktopWallpaper(Message::ImageAdd(
|
self.update_config = Some((custom_images.len(), update.displays));
|
||||||
result.map(Arc::new),
|
|
||||||
)),
|
// Load preview images concurrently for each custom image stored in the on-disk config.
|
||||||
)
|
return cosmic::command::batch(custom_images.iter().cloned().map(|path| {
|
||||||
})
|
cosmic::command::future(async move {
|
||||||
},
|
let result =
|
||||||
));
|
wallpaper::load_image_with_thumbnail(&mut Vec::new(), path).await;
|
||||||
|
|
||||||
|
Message::ImageAdd(result.map(Arc::new)).into()
|
||||||
|
})
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1183,23 +1207,6 @@ pub fn settings() -> Section<crate::pages::Message> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current wallpaper directory.
|
|
||||||
fn entry_directory(current_folder: &Path, entry: &wallpaper::Entry) -> Option<PathBuf> {
|
|
||||||
Some(match entry.source {
|
|
||||||
wallpaper::Source::Path(ref path) => {
|
|
||||||
if path.is_dir() {
|
|
||||||
path.clone()
|
|
||||||
} else if let Some(path) = path.parent() {
|
|
||||||
path.to_path_buf()
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wallpaper::Source::Color(_) => PathBuf::from(current_folder),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn color_picker_window_settings(window_id: window::Id) -> SctkWindowSettings {
|
fn color_picker_window_settings(window_id: window::Id) -> SctkWindowSettings {
|
||||||
SctkWindowSettings {
|
SctkWindowSettings {
|
||||||
window_id,
|
window_id,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue