From 913b219118b02d0a190047fdfa2659f585130ef0 Mon Sep 17 00:00:00 2001 From: Michael Aaron Murphy Date: Wed, 31 May 2023 02:43:35 +0200 Subject: [PATCH] feat(wallpapers): add function to retrieve displays from sctk --- Cargo.lock | 51 +++++++++++++++--- Cargo.toml | 1 + app/src/pages/desktop/wallpaper.rs | 33 +++++++----- pages/desktop/Cargo.toml | 4 +- pages/desktop/src/lib.rs | 1 + pages/desktop/src/outputs.rs | 84 ++++++++++++++++++++++++++++++ pages/desktop/src/wallpaper.rs | 20 +++++-- 7 files changed, 170 insertions(+), 24 deletions(-) create mode 100644 pages/desktop/src/outputs.rs diff --git a/Cargo.lock b/Cargo.lock index 094c1a7..1f8ee07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -718,7 +718,7 @@ dependencies = [ [[package]] name = "cosmic-bg-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-bg#c9fec966262a9a3572e662b4e98f647f4807ba33" +source = "git+https://github.com/pop-os/cosmic-bg?branch=settings_jammy#23f4a1f80e98d36efc4a83a59ec9e8b13bfca35b" dependencies = [ "cosmic-config", "derive_setters", @@ -754,7 +754,7 @@ dependencies = [ [[package]] name = "cosmic-panel-config" version = "0.1.0" -source = "git+https://github.com/pop-os/cosmic-panel?branch=settings_jammy#a71a4cba13184f22ba8874c910b20e99f60871c0" +source = "git+https://github.com/pop-os/cosmic-panel?branch=settings_jammy#1b8699fb4b23243e425d05174afb8e3275ff3d4a" dependencies = [ "anyhow", "cosmic-config", @@ -804,8 +804,10 @@ dependencies = [ "futures-lite", "image", "rayon", + "smithay-client-toolkit 0.17.0 (git+https://github.com/Smithay/client-toolkit)", "tokio", "tracing", + "wayland-client 0.30.2", ] [[package]] @@ -2076,7 +2078,7 @@ dependencies = [ "instant", "log", "palette", - "smithay-client-toolkit 0.17.0", + "smithay-client-toolkit 0.17.0 (git+https://github.com/pop-os/client-toolkit?tag=themed-pointer)", "thiserror", "twox-hash", ] @@ -2131,7 +2133,7 @@ dependencies = [ "iced_accessibility", "iced_core", "iced_futures", - "smithay-client-toolkit 0.17.0", + "smithay-client-toolkit 0.17.0 (git+https://github.com/pop-os/client-toolkit?tag=themed-pointer)", "thiserror", ] @@ -2150,7 +2152,7 @@ dependencies = [ "itertools", "log", "raw-window-handle 0.5.2", - "smithay-client-toolkit 0.17.0", + "smithay-client-toolkit 0.17.0 (git+https://github.com/pop-os/client-toolkit?tag=themed-pointer)", "smithay-clipboard", "thiserror", "wayland-backend", @@ -2216,7 +2218,7 @@ dependencies = [ "iced_style", "num-traits", "ouroboros 0.13.0", - "smithay-client-toolkit 0.17.0", + "smithay-client-toolkit 0.17.0 (git+https://github.com/pop-os/client-toolkit?tag=themed-pointer)", "thiserror", "unicode-segmentation", ] @@ -2533,7 +2535,7 @@ dependencies = [ "lazy_static", "palette", "slotmap", - "smithay-client-toolkit 0.17.0", + "smithay-client-toolkit 0.17.0 (git+https://github.com/pop-os/client-toolkit?tag=themed-pointer)", "tokio", ] @@ -4006,6 +4008,30 @@ dependencies = [ "xkbcommon", ] +[[package]] +name = "smithay-client-toolkit" +version = "0.17.0" +source = "git+https://github.com/Smithay/client-toolkit#9d0bbc69f33873d5e85864413e12c71f8c458a2d" +dependencies = [ + "bitflags 1.3.2", + "calloop", + "cursor-icon", + "dlib", + "log", + "memmap2", + "nix 0.26.2", + "pkg-config", + "thiserror", + "wayland-backend", + "wayland-client 0.30.2", + "wayland-csd-frame", + "wayland-cursor 0.30.0", + "wayland-protocols 0.30.0", + "wayland-protocols-wlr", + "wayland-scanner 0.30.0", + "xkbcommon", +] + [[package]] name = "smithay-clipboard" version = "0.6.6" @@ -4840,6 +4866,17 @@ dependencies = [ "wayland-sys 0.29.5", ] +[[package]] +name = "wayland-csd-frame" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72191e30290b83491325d32c1327be7f45459c97263d9d48494c81efc9328116" +dependencies = [ + "bitflags 2.3.1", + "cursor-icon", + "wayland-backend", +] + [[package]] name = "wayland-cursor" version = "0.29.5" diff --git a/Cargo.toml b/Cargo.toml index e93a354..90112c5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ git = "https://github.com/pop-os/libcosmic" [workspace.dependencies.cosmic-bg-config] git = "https://github.com/pop-os/cosmic-bg" +branch = "settings_jammy" [workspace.dependencies.cosmic-panel-config] git = "https://github.com/pop-os/cosmic-panel" diff --git a/app/src/pages/desktop/wallpaper.rs b/app/src/pages/desktop/wallpaper.rs index 2d74fa0..48dede1 100644 --- a/app/src/pages/desktop/wallpaper.rs +++ b/app/src/pages/desktop/wallpaper.rs @@ -1,7 +1,7 @@ // Copyright 2023 System76 // SPDX-License-Identifier: GPL-3.0-only -use std::{path::PathBuf, time::Instant}; +use std::{collections::HashMap, path::PathBuf, time::Instant}; use apply::Apply; use cosmic::{ @@ -23,16 +23,17 @@ pub enum Message { SameBackground(bool), Select(DefaultKey), Slideshow(bool), - Update((wallpaper::Config, Context)), + Update((wallpaper::Config, HashMap, Context)), } pub struct Page { pub config: wallpaper::Config, - pub selection: Context, - pub same_background: bool, - pub slideshow: bool, pub fit_options: Vec, + pub outputs: HashMap, + pub same_background: bool, pub selected_fit: u32, + pub selection: Context, + pub slideshow: bool, } const FIT: u32 = 0; @@ -43,11 +44,12 @@ impl Default for Page { fn default() -> Self { Page { config: wallpaper::Config::default(), - selection: Context::default(), - same_background: true, - slideshow: false, fit_options: vec!["Fit to Screen".into(), "Stretch".into(), "Zoom".into()], + outputs: HashMap::new(), + same_background: true, selected_fit: 0, + selection: Context::default(), + slideshow: false, } } } @@ -89,15 +91,22 @@ impl Page { self.apply(); } - Message::SameBackground(value) => self.same_background = value, + + Message::SameBackground(value) => { + self.same_background = value; + } + Message::Select(id) => { self.selection.active = id; self.apply(); } + Message::Slideshow(value) => self.slideshow = value, - Message::Update((config, selection)) => { + + Message::Update((config, outputs, selection)) => { self.config = config; self.selection = selection; + self.outputs = outputs; if let Some(entry) = self .config @@ -138,7 +147,7 @@ impl page::Page for Page { fn load(&self, _page: page::Entity) -> Option> { Some(Box::pin(async move { - let config = wallpaper::config(); + let (config, outputs) = wallpaper::config(); let mut backgrounds = wallpaper::load_each_from_path("/usr/share/backgrounds/pop/".into()); @@ -160,7 +169,7 @@ impl page::Page for Page { Instant::now().duration_since(start) ); - crate::pages::Message::DesktopWallpaper(Message::Update((config, update))) + crate::pages::Message::DesktopWallpaper(Message::Update((config, outputs, update))) })) } } diff --git a/pages/desktop/Cargo.toml b/pages/desktop/Cargo.toml index 40a8f83..38b9fbc 100644 --- a/pages/desktop/Cargo.toml +++ b/pages/desktop/Cargo.toml @@ -14,4 +14,6 @@ futures-lite = "1.13.0" image = "0.24.6" rayon = "1.7.0" tokio = { version = "1.28.0", features = ["sync"] } -tracing = "0.1.37" \ No newline at end of file +tracing = "0.1.37" +sctk = { package = "smithay-client-toolkit", git = "https://github.com/Smithay/client-toolkit" } +wayland-client = "0.30.1" \ No newline at end of file diff --git a/pages/desktop/src/lib.rs b/pages/desktop/src/lib.rs index 5a20f26..888292e 100644 --- a/pages/desktop/src/lib.rs +++ b/pages/desktop/src/lib.rs @@ -1 +1,2 @@ +pub mod outputs; pub mod wallpaper; diff --git a/pages/desktop/src/outputs.rs b/pages/desktop/src/outputs.rs new file mode 100644 index 0000000..5954177 --- /dev/null +++ b/pages/desktop/src/outputs.rs @@ -0,0 +1,84 @@ +//! Test application to list all available outputs. + +use std::error::Error; + +use sctk::{ + delegate_output, delegate_registry, + output::{OutputHandler, OutputInfo, OutputState}, + registry::{ProvidesRegistryState, RegistryState}, + registry_handlers, +}; +use wayland_client::{globals::registry_queue_init, protocol::wl_output, Connection, QueueHandle}; + +pub fn outputs() -> Result, Box> { + let conn = Connection::connect_to_env()?; + + let (globals, mut event_queue) = registry_queue_init(&conn).unwrap(); + let qh = event_queue.handle(); + + let registry_state = RegistryState::new(&globals); + + let output_delegate = OutputState::new(&globals, &qh); + + let mut list_outputs = ListOutputs { + registry_state, + output_state: output_delegate, + }; + + event_queue.roundtrip(&mut list_outputs)?; + + // Now our outputs have been initialized with data, we may access what outputs exist and information about + // said outputs using the output delegate. + Ok(list_outputs + .output_state + .outputs() + .filter_map(move |output| list_outputs.output_state.info(&output))) +} + +struct ListOutputs { + registry_state: RegistryState, + output_state: OutputState, +} + +impl OutputHandler for ListOutputs { + fn output_state(&mut self) -> &mut OutputState { + &mut self.output_state + } + + fn new_output( + &mut self, + _conn: &Connection, + _qh: &QueueHandle, + _output: wl_output::WlOutput, + ) { + } + + fn update_output( + &mut self, + _conn: &Connection, + _qh: &QueueHandle, + _output: wl_output::WlOutput, + ) { + } + + fn output_destroyed( + &mut self, + _conn: &Connection, + _qh: &QueueHandle, + _output: wl_output::WlOutput, + ) { + } +} + +delegate_output!(ListOutputs); +delegate_registry!(ListOutputs); + +impl ProvidesRegistryState for ListOutputs { + fn registry(&mut self) -> &mut RegistryState { + &mut self.registry_state + } + + registry_handlers! { + OutputState + } +} diff --git a/pages/desktop/src/wallpaper.rs b/pages/desktop/src/wallpaper.rs index 1d3eb6c..0fef8f6 100644 --- a/pages/desktop/src/wallpaper.rs +++ b/pages/desktop/src/wallpaper.rs @@ -1,7 +1,7 @@ pub use cosmic_bg_config::{Config, Entry, Output, ScalingMode}; use image::RgbaImage; use std::{ - collections::hash_map::DefaultHasher, + collections::{hash_map::DefaultHasher, HashMap}, fs::DirEntry, hash::{Hash, Hasher}, path::{Path, PathBuf}, @@ -9,16 +9,28 @@ use std::{ }; use tokio::sync::mpsc::{self, Receiver}; -pub fn config() -> Config { +pub fn config() -> (Config, HashMap) { + let mut displays = HashMap::new(); + + if let Ok(outputs) = crate::outputs::outputs() { + for output in outputs { + if let Some(name) = output.name { + displays.insert(name, output.make); + } + } + } + let helper = Config::helper().expect("failed to get helper for cosmic bg config"); - match Config::load(&helper) { + let config = match Config::load(&helper) { Ok(conf) => conf, Err(why) => { tracing::warn!(?why, "Config file error, falling back to defaults"); Config::default() } - } + }; + + (config, displays) } pub fn set(config: &mut Config, entry: Entry) {