Merge pull request #194 from pop-os/wallpapers

Wallpaper settings improvements
This commit is contained in:
Jeremy Soller 2024-03-12 11:04:49 -06:00 committed by GitHub
commit 37e5bcc402
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 151 additions and 121 deletions

84
Cargo.lock generated
View file

@ -157,9 +157,9 @@ dependencies = [
[[package]]
name = "anyhow"
version = "1.0.80"
version = "1.0.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
checksum = "0952808a6c2afd1aa8947271f3a60f1a6763c7b912d210184c5149b5cf147247"
[[package]]
name = "apply"
@ -318,9 +318,9 @@ dependencies = [
[[package]]
name = "async-io"
version = "2.3.1"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65"
checksum = "dcccb0f599cfa2f8ace422d3555572f47424da5648a4382a9dd0310ff8210884"
dependencies = [
"async-lock 3.3.0",
"cfg-if",
@ -389,7 +389,7 @@ version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5"
dependencies = [
"async-io 2.3.1",
"async-io 2.3.2",
"async-lock 2.8.0",
"atomic-waker",
"cfg-if",
@ -674,9 +674,9 @@ dependencies = [
[[package]]
name = "bytemuck_derive"
version = "1.5.0"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1"
checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60"
dependencies = [
"proc-macro2",
"quote",
@ -1076,7 +1076,7 @@ dependencies = [
[[package]]
name = "cosmic-comp-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-comp#9cb1adb37cc7e0dab9b5e7076aee292e244c421b"
source = "git+https://github.com/pop-os/cosmic-comp#c685440155063dae2d09ebc70e2a41f88180b2c2"
dependencies = [
"cosmic-config",
"input",
@ -1086,7 +1086,7 @@ dependencies = [
[[package]]
name = "cosmic-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"atomicwrites",
"calloop",
@ -1104,7 +1104,7 @@ dependencies = [
[[package]]
name = "cosmic-config-derive"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"quote",
"syn 1.0.109",
@ -1113,7 +1113,7 @@ dependencies = [
[[package]]
name = "cosmic-panel-config"
version = "0.1.0"
source = "git+https://github.com/pop-os/cosmic-panel#e51be500fc0e62afe5a9002fd11f230f9fcbae41"
source = "git+https://github.com/pop-os/cosmic-panel#07fcaee64f80d9aa498be53d40077bc0a510437b"
dependencies = [
"anyhow",
"cosmic-config",
@ -1241,9 +1241,9 @@ dependencies = [
"dirs 5.0.1",
"freedesktop-icons",
"futures-lite 2.2.0",
"futures-util",
"image",
"infer",
"rayon",
"tokio",
"tracing",
]
@ -1251,7 +1251,7 @@ dependencies = [
[[package]]
name = "cosmic-text"
version = "0.11.2"
source = "git+https://github.com/pop-os/cosmic-text.git#a53a0b3a8c085143470a9d26ac2c2911cc479033"
source = "git+https://github.com/pop-os/cosmic-text.git#18c3d2acec5e7f64a670c6643ee3ab220bc92a89"
dependencies = [
"bitflags 2.4.2",
"fontdb",
@ -1273,7 +1273,7 @@ dependencies = [
[[package]]
name = "cosmic-theme"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"almost",
"cosmic-config",
@ -1972,9 +1972,9 @@ dependencies = [
[[package]]
name = "freedesktop-desktop-entry"
version = "0.5.0"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45157175a725e81f3f594382430b6b78af5f8f72db9bd51b94f0785f80fc6d29"
checksum = "287f89b1a3d88dd04d2b65dfec39f3c381efbcded7b736456039c4ee49d54b17"
dependencies = [
"dirs 3.0.2",
"gettext-rs",
@ -2496,7 +2496,7 @@ dependencies = [
"serde",
"serde_derive",
"thiserror",
"toml 0.8.10",
"toml 0.8.11",
"unic-langid",
]
@ -2559,7 +2559,7 @@ dependencies = [
[[package]]
name = "iced"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"iced_accessibility",
"iced_core",
@ -2574,7 +2574,7 @@ dependencies = [
[[package]]
name = "iced_accessibility"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"accesskit",
"accesskit_unix",
@ -2583,7 +2583,7 @@ dependencies = [
[[package]]
name = "iced_core"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"bitflags 1.3.2",
"iced_accessibility",
@ -2602,7 +2602,7 @@ dependencies = [
[[package]]
name = "iced_futures"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"futures",
"iced_core",
@ -2615,7 +2615,7 @@ dependencies = [
[[package]]
name = "iced_graphics"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
@ -2639,7 +2639,7 @@ dependencies = [
[[package]]
name = "iced_renderer"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"iced_graphics",
"iced_tiny_skia",
@ -2651,7 +2651,7 @@ dependencies = [
[[package]]
name = "iced_runtime"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"iced_accessibility",
"iced_core",
@ -2663,7 +2663,7 @@ dependencies = [
[[package]]
name = "iced_sctk"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"enum-repr",
"float-cmp",
@ -2689,7 +2689,7 @@ dependencies = [
[[package]]
name = "iced_style"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"iced_core",
"once_cell",
@ -2699,7 +2699,7 @@ dependencies = [
[[package]]
name = "iced_tiny_skia"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"bytemuck",
"cosmic-text",
@ -2716,7 +2716,7 @@ dependencies = [
[[package]]
name = "iced_wgpu"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"bitflags 1.3.2",
"bytemuck",
@ -2735,7 +2735,7 @@ dependencies = [
[[package]]
name = "iced_widget"
version = "0.12.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"iced_renderer",
"iced_runtime",
@ -3132,7 +3132,7 @@ checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "libcosmic"
version = "0.1.0"
source = "git+https://github.com/pop-os/libcosmic#52491e08ee83254e64d1c3730fed221a40696a85"
source = "git+https://github.com/pop-os/libcosmic#64ecb0ea48f262e13b1036757211b70432fd42e5"
dependencies = [
"apply",
"ashpd 0.7.0",
@ -4013,9 +4013,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.78"
version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae"
checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e"
dependencies = [
"unicode-ident",
]
@ -4956,7 +4956,7 @@ dependencies = [
"cfg-expr",
"heck",
"pkg-config",
"toml 0.8.10",
"toml 0.8.11",
"version-compare",
]
@ -5012,18 +5012,18 @@ dependencies = [
[[package]]
name = "thiserror"
version = "1.0.57"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.57"
version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
@ -5161,14 +5161,14 @@ dependencies = [
[[package]]
name = "toml"
version = "0.8.10"
version = "0.8.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290"
checksum = "af06656561d28735e9c1cd63dfd57132c8155426aa6af24f36a00a351f88c48e"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit 0.22.6",
"toml_edit 0.22.7",
]
[[package]]
@ -5204,9 +5204,9 @@ dependencies = [
[[package]]
name = "toml_edit"
version = "0.22.6"
version = "0.22.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c1b5fd4128cc8d3e0cb74d4ed9a9cc7c7284becd4df68f5f940e1ad123606f6"
checksum = "18769cd1cec395d70860ceb4d932812a0b4d06b1a4bb336745a4d21b9496e992"
dependencies = [
"indexmap",
"serde",

View file

@ -12,7 +12,7 @@ use crate::pages::desktop::{
},
};
use crate::pages::input::{self, keyboard};
use crate::pages::{display, sound, system, time};
use crate::pages::{self, display, sound, system, time};
use crate::subscription::desktop_files;
use crate::widget::{page_title, search_header};
use crate::PageCommands;
@ -21,7 +21,7 @@ use cosmic::iced::Subscription;
use cosmic::widget::{button, row, text_input};
use cosmic::{
app::{Command, Core},
cosmic_config::config_subscription,
cosmic_config::{config_state_subscription, config_subscription},
iced::{
self,
event::{self, wayland, PlatformSpecific},
@ -228,6 +228,11 @@ impl cosmic::Application for SettingsApp {
Message::PanelConfig(update.config)
}),
config_state_subscription(0, cosmic_bg_config::NAME.into(), 1).map(|update| {
Message::PageMessage(pages::Message::DesktopWallpaper(
pages::desktop::wallpaper::Message::UpdateState(update.config),
))
}),
])
}

View file

@ -259,7 +259,7 @@ impl Page {
button(text(fl!("add")))
.style(button::Style::Custom {
active: Box::new(|focused, theme| {
let mut style = theme.active(focused, &button::Style::Text);
let mut style = theme.active(focused, false, &button::Style::Text);
style.text_color = Some(theme.cosmic().accent_color().into());
style
}),
@ -271,12 +271,12 @@ impl Page {
style
}),
hovered: Box::new(|focused, theme| {
let mut style = theme.hovered(focused, &theme::Button::Text);
let mut style = theme.hovered(focused, false, &theme::Button::Text);
style.text_color = Some(theme.cosmic().accent_color().into());
style
}),
pressed: Box::new(|focused, theme| {
let mut style = theme.pressed(focused, &theme::Button::Text);
let mut style = theme.pressed(focused, false, &theme::Button::Text);
style.text_color = Some(theme.cosmic().accent_color().into());
style
}),

View file

@ -5,6 +5,7 @@ mod config;
pub mod widgets;
pub use config::Config;
use futures::StreamExt;
use url::Url;
use std::{
@ -114,6 +115,8 @@ pub enum Message {
Select(DefaultKey),
/// Changes the slideshow parameter.
Slideshow(bool),
/// State change from cosmic-bg
UpdateState(cosmic_bg_config::state::State),
}
impl From<Message> for crate::app::Message {
@ -138,6 +141,9 @@ pub enum Category {
/// The page struct for the wallpaper view.
pub struct Page {
/// Whether to show the tab_bar or not.
show_tab_bar: bool,
/// The display that is currently being configured.
///
/// If set to `None`, all displays will have the same wallpaper.
@ -203,10 +209,12 @@ impl page::Page<crate::pages::Message> for Page {
fn reload(&mut self, _page: page::Entity) -> Command<crate::pages::Message> {
let current_folder = self.config.current_folder().to_owned();
let recurse = self.categories.selected == Some(Category::Wallpapers);
command::future(async move {
let (service_config, displays) = wallpaper::config().await;
let selection = change_folder(current_folder).await;
let selection = change_folder(current_folder, recurse).await;
crate::pages::Message::DesktopWallpaper(Message::Init(Box::new(InitUpdate {
service_config,
@ -222,6 +230,7 @@ impl page::AutoBind<crate::pages::Message> for Page {}
impl Default for Page {
fn default() -> Self {
let mut page = Page {
show_tab_bar: false,
active_output: None,
cached_display_handle: None,
categories: {
@ -507,7 +516,7 @@ impl Page {
if self.config.current_folder.is_some() {
let _ = self.config.set_current_folder(None);
command = cosmic::command::future(async move {
let folder = change_folder(Config::default_folder().to_owned()).await;
let folder = change_folder(Config::default_folder().to_owned(), true).await;
Message::ChangeFolder(folder).into()
});
} else {
@ -527,7 +536,7 @@ impl Page {
}
command = cosmic::command::future(async move {
Message::ChangeFolder(change_folder(path).await).into()
Message::ChangeFolder(change_folder(path, false).await).into()
});
}
}
@ -608,6 +617,12 @@ impl Page {
#[allow(clippy::too_many_lines)]
pub fn update(&mut self, message: Message) -> Command<crate::app::Message> {
match message {
Message::UpdateState(_state) => {
if let Choice::Slideshow = self.selection.active {
self.cache_display_image();
}
}
Message::DragColorDialog => {
return cosmic::iced_sctk::commands::window::start_drag_window(self.color_dialog)
}
@ -819,9 +834,12 @@ 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.
return cosmic::command::future(async move {
let message = Message::ChangeFolder(change_folder(path).await);
let message = Message::ChangeFolder(change_folder(path, recurse).await);
let page_message = crate::pages::Message::DesktopWallpaper(message);
crate::Message::PageMessage(page_message)
});
@ -842,8 +860,7 @@ impl Page {
// Loads a single custom image and its thumbnail for display in the backgrounds view.
return cosmic::command::future(async move {
let result =
wallpaper::load_image_with_thumbnail(&mut Vec::new(), path).await;
let result = wallpaper::load_image_with_thumbnail(path);
let message = Message::ImageAdd(result.map(Arc::new));
let page_message = crate::pages::Message::DesktopWallpaper(message);
@ -856,6 +873,7 @@ impl Page {
self.outputs.clear();
self.wallpaper_service_config = update.service_config;
self.selection = update.selection;
self.show_tab_bar = update.displays.len() > 1;
// Sync custom colors from config.
for color in self.config.custom_colors() {
@ -881,8 +899,7 @@ impl Page {
// 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;
let result = wallpaper::load_image_with_thumbnail(path);
Message::ImageAdd(result.map(Arc::new)).into()
})
@ -1042,11 +1059,11 @@ impl Context {
}
}
pub async fn change_folder(current_folder: PathBuf) -> Context {
pub async fn change_folder(current_folder: PathBuf, recurse: bool) -> Context {
let mut update = Context::default();
let mut wallpapers = wallpaper::load_each_from_path(current_folder);
let mut wallpapers = wallpaper::load_each_from_path(current_folder, recurse).await;
while let Some((path, display_image, selection_image)) = wallpapers.recv().await {
while let Some((path, display_image, selection_image)) = wallpapers.next().await {
let id = update.paths.insert(path);
update.display_images.insert(id, display_image);
@ -1109,8 +1126,8 @@ pub fn settings() -> Section<crate::pages::Message> {
},
));
children.push(if page.wallpaper_service_config.same_on_all {
text(fl!("all-displays"))
if page.wallpaper_service_config.same_on_all {
let element = text(fl!("all-displays"))
.font(cosmic::font::FONT_SEMIBOLD)
.horizontal_alignment(alignment::Horizontal::Center)
.vertical_alignment(alignment::Vertical::Center)
@ -1118,13 +1135,16 @@ pub fn settings() -> Section<crate::pages::Message> {
.height(Length::Fill)
.apply(cosmic::widget::container)
.width(Length::Fill)
.height(Length::Fixed(32.0))
.into()
} else {
tab_bar::horizontal(&page.outputs)
.on_activate(Message::Output)
.into()
});
.height(Length::Fixed(32.0));
children.push(element.into());
} else if page.show_tab_bar {
let element = tab_bar::horizontal(&page.outputs)
.button_alignment(Alignment::Center)
.on_activate(Message::Output);
children.push(element.into());
}
let wallpaper_fit =
cosmic::widget::dropdown(&page.fit_options, Some(page.selected_fit), Message::Fit);

View file

@ -8,7 +8,7 @@ pub mod text;
use crate::{app, pages};
use apply::Apply;
use arrangement::Arrangement;
use cosmic::iced::Length;
use cosmic::iced::{Alignment, Length};
use cosmic::iced_widget::scrollable::{Direction, Properties, RelativeOffset};
use cosmic::widget::{
column, container, dropdown, list_column, segmented_button, tab_bar, toggler,
@ -459,8 +459,9 @@ impl Page {
let mut content = column().spacing(theme.cosmic().space_m());
if self.list.outputs.len() > 1 {
let display_switcher =
tab_bar::horizontal(&self.display_tabs).on_activate(Message::Display);
let display_switcher = tab_bar::horizontal(&self.display_tabs)
.button_alignment(Alignment::Center)
.on_activate(Message::Display);
let display_enable = list_column().add(cosmic::widget::settings::item(
&*text::DISPLAY_ENABLE,

View file

@ -12,8 +12,8 @@ cosmic-randr-shell = { workspace = true }
dirs = "5.0.1"
freedesktop-icons = "0.2.5"
futures-lite = "2.2.0"
futures-util = "0.3.30"
image = "0.24.8"
infer = "0.15.0"
rayon = "1.8.1"
tokio = { version = "1.35.1", features = ["sync"] }
tracing = "0.1.40"

View file

@ -1,5 +1,6 @@
pub use cosmic_bg_config::{Color, Config, Entry, Gradient, ScalingMode, Source};
use futures_lite::Stream;
use image::{DynamicImage, ImageBuffer, Rgba, RgbaImage};
use std::{
borrow::Cow,
@ -7,8 +8,8 @@ use std::{
hash::{Hash, Hasher},
io::Read,
path::{Path, PathBuf},
pin::Pin,
};
use tokio::sync::mpsc::{self, Receiver};
pub const DEFAULT_COLORS: &[Color] = &[
Color::Single([0.580, 0.922, 0.922]),
@ -87,12 +88,11 @@ pub fn cache_dir() -> Option<PathBuf> {
/// Loads wallpapers in parallel by spawning tasks with a rayon thread pool.
#[must_use]
pub fn load_each_from_path(path: PathBuf) -> Receiver<(PathBuf, RgbaImage, RgbaImage)> {
let (tx, rx) = mpsc::channel(1);
tokio::task::spawn(async move {
// Scratch space for storing images into.
let mut buffer = Vec::new();
pub async fn load_each_from_path(
path: PathBuf,
recurse: bool,
) -> Pin<Box<dyn Send + Stream<Item = (PathBuf, RgbaImage, RgbaImage)>>> {
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.
@ -108,7 +108,7 @@ pub fn load_each_from_path(path: PathBuf) -> Receiver<(PathBuf, RgbaImage, RgbaI
let path = entry.path();
// Recursively search directories, while storing only image files.
if file_type.is_dir() {
if recurse && file_type.is_dir() {
paths.push(path);
} else if file_type.is_file() {
let Ok(Some(kind)) = infer::get_from_path(&path) else {
@ -117,24 +117,34 @@ pub fn load_each_from_path(path: PathBuf) -> Receiver<(PathBuf, RgbaImage, RgbaI
if infer::MatcherType::Image == kind.matcher_type() {
wallpapers.insert(path);
if wallpapers.len() > 99 {
break;
}
}
}
}
}
}
for path in wallpapers {
if let Some(value) = load_image_with_thumbnail(&mut buffer, path).await {
let _res = tx.send(value).await;
}
}
wallpapers
});
rx
if let Ok(wallpapers) = wallpapers.await {
use futures_util::StreamExt;
let future = futures_util::stream::iter(wallpapers)
.map(|path| tokio::task::spawn_blocking(|| load_image_with_thumbnail(path)))
.buffered(4)
.filter_map(|value| async { value.ok()? });
Box::pin(future)
} else {
Box::pin(futures_lite::stream::empty())
}
}
pub async fn load_image_with_thumbnail(
buffer: &mut Vec<u8>,
#[must_use]
pub fn load_image_with_thumbnail(
path: PathBuf,
) -> Option<(
PathBuf,
@ -142,54 +152,48 @@ pub async fn load_image_with_thumbnail(
ImageBuffer<Rgba<u8>, Vec<u8>>,
)> {
let cache_dir = cache_dir();
let image_operation = load_thumbnail(buffer, cache_dir.as_deref(), &path);
let (tx, rx) = tokio::sync::oneshot::channel();
let image_operation = load_thumbnail(&mut Vec::new(), cache_dir.as_deref(), &path);
if let Some(image_operation) = image_operation {
let tokio_handle = tokio::runtime::Handle::current();
rayon::spawn_fifo(move || {
let display_thumbnail = match image_operation {
ImageOperation::Cached(thumbnail) => thumbnail.to_rgba8(),
let display_thumbnail = match image_operation {
ImageOperation::Cached(thumbnail) => thumbnail.to_rgba8(),
ImageOperation::GenerateThumbnail { path, image } => {
let image = image.thumbnail(300, 169).to_rgba8();
ImageOperation::GenerateThumbnail { path, image } => {
let image = image.thumbnail(300, 169).to_rgba8();
if let Some(path) = path {
// Save thumbnail to disk without blocking.
tokio_handle.spawn_blocking({
let image = image.clone();
move || {
if let Err(why) = image.save(&path) {
tracing::error!(?path, ?why, "failed to save image thumbnail");
if let Some(path) = path {
// Save thumbnail to disk without blocking.
tokio_handle.spawn_blocking({
let image = image.clone();
move || {
if let Err(why) = image.save(&path) {
tracing::error!(?path, ?why, "failed to save image thumbnail");
let _res = std::fs::remove_file(&path);
}
let _res = std::fs::remove_file(&path);
}
});
}
image
}
});
}
};
let mut selection_thumbnail = image::imageops::resize(
&display_thumbnail,
158,
105,
image::imageops::FilterType::Lanczos3,
);
image
}
};
round(&mut selection_thumbnail, [8, 8, 8, 8]);
let mut selection_thumbnail = image::imageops::resize(
&display_thumbnail,
158,
105,
image::imageops::FilterType::Lanczos3,
);
let _res = tx.send(Some((path, display_thumbnail, selection_thumbnail)));
});
round(&mut selection_thumbnail, [8, 8, 8, 8]);
Some((path, display_thumbnail, selection_thumbnail))
} else {
let _res = tx.send(None);
None
}
rx.await.unwrap_or(None)
}
enum ImageOperation {