perf(wallpaper): avoid recursion for system wallpapers
This commit is contained in:
parent
7576ad1af7
commit
0bf63a0d91
3 changed files with 46 additions and 50 deletions
|
|
@ -221,12 +221,10 @@ 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();
|
||||||
|
|
||||||
let recurse = self.categories.selected == Some(Category::Wallpapers);
|
|
||||||
|
|
||||||
let (task, on_enter_handle) = Task::future(async move {
|
let (task, on_enter_handle) = Task::future(async move {
|
||||||
let (service_config, displays) = wallpaper::config().await;
|
let (service_config, displays) = wallpaper::config().await;
|
||||||
|
|
||||||
let mut selection = change_folder(current_folder, recurse).await;
|
let mut selection = change_folder(current_folder).await;
|
||||||
|
|
||||||
// `selection.active` is usually empty because `change_folder` creates a fresh context.
|
// `selection.active` is usually empty because `change_folder` creates a fresh context.
|
||||||
// This leads to blank previews in certain conditions when the program is restarted.
|
// This leads to blank previews in certain conditions when the program is restarted.
|
||||||
|
|
@ -578,7 +576,7 @@ impl Page {
|
||||||
if self.config.current_folder.is_some() {
|
if self.config.current_folder.is_some() {
|
||||||
let _ = self.config.set_current_folder(None);
|
let _ = self.config.set_current_folder(None);
|
||||||
task = cosmic::task::future(async move {
|
task = cosmic::task::future(async move {
|
||||||
let folder = change_folder(Config::default_folder().to_owned(), true).await;
|
let folder = change_folder(Config::default_folder().to_owned()).await;
|
||||||
Message::ChangeFolder(folder)
|
Message::ChangeFolder(folder)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -598,7 +596,7 @@ impl Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
task = cosmic::task::future(async move {
|
task = cosmic::task::future(async move {
|
||||||
Message::ChangeFolder(change_folder(path, false).await)
|
Message::ChangeFolder(change_folder(path).await)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -903,12 +901,9 @@ impl Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Avoid walking user-selected folders.
|
|
||||||
let recurse = self.categories.selected == Some(Category::Wallpapers);
|
|
||||||
|
|
||||||
// Load the wallpapers from the selected folder into the view.
|
// Load the wallpapers from the selected folder into the view.
|
||||||
return cosmic::Task::future(async move {
|
return cosmic::Task::future(async move {
|
||||||
let message = Message::ChangeFolder(change_folder(path, recurse).await);
|
let message = Message::ChangeFolder(change_folder(path).await);
|
||||||
let page_message = crate::pages::Message::DesktopWallpaper(message);
|
let page_message = crate::pages::Message::DesktopWallpaper(message);
|
||||||
crate::Message::PageMessage(page_message)
|
crate::Message::PageMessage(page_message)
|
||||||
});
|
});
|
||||||
|
|
@ -1138,22 +1133,31 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn change_folder(current_folder: PathBuf, recurse: bool) -> Context {
|
pub async fn change_folder(current_folder: PathBuf) -> Context {
|
||||||
let mut update = Context::default();
|
let mut update = Context::default();
|
||||||
let mut wallpapers = wallpaper::load_each_from_path(current_folder, recurse).await;
|
let mut streams = Vec::with_capacity(2);
|
||||||
|
|
||||||
while let Some((path, display_image, selection_image)) = wallpapers.next().await {
|
// Include the cosmic background folder when loading the system wallpapers.
|
||||||
let id = update.paths.insert(path);
|
if current_folder == Config::default_folder() {
|
||||||
|
streams.push(wallpaper::load_each_from_path(Config::default_folder().join("cosmic")).await);
|
||||||
|
}
|
||||||
|
|
||||||
update.display_images.insert(id, display_image);
|
streams.push(wallpaper::load_each_from_path(current_folder).await);
|
||||||
|
|
||||||
let selection_handle = ImageHandle::from_rgba(
|
for mut wallpapers in streams {
|
||||||
selection_image.width(),
|
while let Some((path, display_image, selection_image)) = wallpapers.next().await {
|
||||||
selection_image.height(),
|
let id = update.paths.insert(path);
|
||||||
selection_image.into_vec(),
|
|
||||||
);
|
|
||||||
|
|
||||||
update.selection_handles.insert(id, selection_handle);
|
update.display_images.insert(id, display_image);
|
||||||
|
|
||||||
|
let selection_handle = ImageHandle::from_rgba(
|
||||||
|
selection_image.width(),
|
||||||
|
selection_image.height(),
|
||||||
|
selection_image.into_vec(),
|
||||||
|
);
|
||||||
|
|
||||||
|
update.selection_handles.insert(id, selection_handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
update
|
update
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ use slab::Slab;
|
||||||
use slotmap::{Key, SecondaryMap, SlotMap};
|
use slotmap::{Key, SecondaryMap, SlotMap};
|
||||||
use std::{collections::BTreeMap, process::ExitStatus, sync::Arc};
|
use std::{collections::BTreeMap, process::ExitStatus, sync::Arc};
|
||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tokio::task::JoinHandle;
|
|
||||||
use tracing::error;
|
use tracing::error;
|
||||||
|
|
||||||
static DPI_SCALES: &[u32] = &[50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300];
|
static DPI_SCALES: &[u32] = &[50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300];
|
||||||
|
|
@ -30,6 +29,7 @@ static DPI_SCALE_LABELS: Lazy<Vec<String>> =
|
||||||
Lazy::new(|| DPI_SCALES.iter().map(|scale| format!("{scale}%")).collect());
|
Lazy::new(|| DPI_SCALES.iter().map(|scale| format!("{scale}%")).collect());
|
||||||
|
|
||||||
/// Display color depth options
|
/// Display color depth options
|
||||||
|
#[allow(dead_code)]
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub struct ColorDepth(usize);
|
pub struct ColorDepth(usize);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,44 +97,36 @@ pub fn cache_dir() -> Option<PathBuf> {
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub async fn load_each_from_path(
|
pub async fn load_each_from_path(
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
recurse: bool,
|
|
||||||
) -> Pin<Box<dyn Send + Stream<Item = (PathBuf, RgbaImage, RgbaImage)>>> {
|
) -> Pin<Box<dyn Send + Stream<Item = (PathBuf, RgbaImage, RgbaImage)>>> {
|
||||||
let wallpapers = tokio::task::spawn_blocking(move || {
|
let wallpapers = tokio::task::spawn_blocking(move || {
|
||||||
// Directories to search recursively.
|
|
||||||
let mut paths = vec![path];
|
|
||||||
// Discovered image files that will be loaded as wallpapers.
|
// Discovered image files that will be loaded as wallpapers.
|
||||||
let mut wallpapers = BTreeSet::new();
|
let mut wallpapers = BTreeSet::new();
|
||||||
|
|
||||||
while let Some(path) = paths.pop() {
|
if let Ok(dir) = path.read_dir() {
|
||||||
if let Ok(dir) = path.read_dir() {
|
for entry in dir.filter_map(Result::ok) {
|
||||||
for entry in dir.filter_map(Result::ok) {
|
let Ok(file_type) = entry.file_type() else {
|
||||||
let Ok(file_type) = entry.file_type() else {
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = entry.path();
|
||||||
|
|
||||||
|
if file_type.is_file() {
|
||||||
|
let path = if path.extension().map_or(false, |ext| ext == "jxl") {
|
||||||
|
path
|
||||||
|
} else if let Ok(Some(kind)) = infer::get_from_path(&path) {
|
||||||
|
if infer::MatcherType::Image == kind.matcher_type() {
|
||||||
|
path
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
let path = entry.path();
|
wallpapers.insert(path);
|
||||||
|
|
||||||
// Recursively search directories, while storing only image files.
|
if wallpapers.len() > 99 {
|
||||||
if recurse && file_type.is_dir() {
|
break;
|
||||||
paths.push(path);
|
|
||||||
} else if file_type.is_file() {
|
|
||||||
let path = if path.extension().map_or(false, |ext| ext == "jxl") {
|
|
||||||
path
|
|
||||||
} else if let Ok(Some(kind)) = infer::get_from_path(&path) {
|
|
||||||
if infer::MatcherType::Image == kind.matcher_type() {
|
|
||||||
path
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
wallpapers.insert(path);
|
|
||||||
|
|
||||||
if wallpapers.len() > 99 {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue