Thanks to visit codestin.com
Credit goes to github.com

Skip to content
This repository was archived by the owner on Oct 31, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ image = { version = "0.25", default-features = false, features = [
"tiff",
"webp",
] }
jzon = { version = "0.12", default-features = false }
resvg = { version = "0.45" }
rustix = { version = "1.1", default-features = false, features = [ "fs" ] }
fast_image_resize = "5.3"
Expand Down
4 changes: 4 additions & 0 deletions client/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ pub struct Query {
#[arg(short, long, default_value = "false")]
pub all: bool,

/// Print the information in `json` format
#[arg(short, long, default_value = "false")]
pub json: bool,

/// The daemon's namespace.
///
/// The resulting namespace will be 'swww-daemon' appended to what you pass in this argument.
Expand Down
68 changes: 57 additions & 11 deletions client/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::{str::FromStr, time::Duration};

use clap::Parser;
use common::cache;
use common::ipc::{self, Answer, Client, IpcSocket, RequestSend};
use common::ipc::{self, Answer, BgInfo, Client, IpcSocket, RequestSend};
use common::mmap::Mmap;

mod imgproc;
Expand Down Expand Up @@ -42,8 +42,9 @@ fn main() -> Result<(), String> {
}
};

for namespace in namespaces {
let socket = IpcSocket::connect(&namespace).map_err(|err| err.to_string())?;
let mut infos = Vec::new();
for namespace in &namespaces {
let socket = IpcSocket::connect(namespace).map_err(|err| err.to_string())?;
loop {
RequestSend::Ping.send(&socket)?;
let bytes = socket.recv().map_err(|err| err.to_string())?;
Expand All @@ -58,22 +59,66 @@ fn main() -> Result<(), String> {
std::thread::sleep(Duration::from_millis(1));
}

process_swww_args(&swww, &namespace)?;
if let Some(info) = process_swww_args(&swww, namespace)? {
infos.push(info);
}
}

if !infos.is_empty() {
if let Swww::Query(query) = swww
&& query.json
{
use jzon::{JsonValue, object, stringify_pretty};
let mut buf = String::new();
for (namespace, infos) in namespaces.iter().zip(infos) {
let mut arr = JsonValue::new_array();
for info in infos {
let displaying = match info.img {
ipc::BgImg::Color(color) => {
object! { color: format!("#{:x}", u32::from_ne_bytes(color)) }
}
ipc::BgImg::Img(img) => {
object! { image: img.as_ref() }
}
};
_ = arr.push(object! {
name: info.name.as_ref(),
width: info.dim.0,
height: info.dim.1,
scale: info.scale_factor.to_f32(),
displaying: displaying
});
}
buf = format!("{buf}\n\"{namespace}\": {},", stringify_pretty(arr, 4));
}
buf.pop(); // delete trailing comma
println!("{{{buf}\n}}");
} else {
for (namespace, infos) in namespaces.iter().zip(infos) {
for info in infos {
println!("{namespace}: {info}");
}
}
}
}
Ok(())
}

fn process_swww_args(args: &Swww, namespace: &str) -> Result<(), String> {
fn process_swww_args(args: &Swww, namespace: &str) -> Result<Option<Box<[BgInfo]>>, String> {
let request = match make_request(args, namespace)? {
Some(request) => request,
None => return Ok(()),
None => return Ok(None),
};
let socket = IpcSocket::connect(namespace).map_err(|err| err.to_string())?;
request.send(&socket)?;
let bytes = socket.recv().map_err(|err| err.to_string())?;
drop(socket);
match Answer::receive(bytes) {
Answer::Info(info) => info.iter().for_each(|i| println!("{namespace}: {i}")),
Answer::Info(infos) => {
if let Swww::Query(_) = args {
return Ok(Some(infos));
}
}
Answer::Ok => {
if let Swww::Kill(_) = args {
#[cfg(debug_assertions)]
Expand All @@ -83,7 +128,7 @@ fn process_swww_args(args: &Swww, namespace: &str) -> Result<(), String> {
let path = IpcSocket::<Client>::path(namespace);
for _ in 0..tries {
if rustix::fs::access(&path, rustix::fs::Access::EXISTS).is_err() {
return Ok(());
return Ok(None);
}
std::thread::sleep(Duration::from_millis(100));
}
Expand All @@ -94,10 +139,10 @@ fn process_swww_args(args: &Swww, namespace: &str) -> Result<(), String> {
}
}
Answer::Ping(_) => {
return Ok(());
return Ok(None);
}
}
Ok(())
Ok(None)
}

fn make_request(args: &Swww, namespace: &str) -> Result<Option<RequestSend>, String> {
Expand Down Expand Up @@ -405,5 +450,6 @@ fn restore_output(output: &str, namespace: &str) -> Result<(), String> {
transition_wave: (0.0, 0.0),
}),
namespace,
)
)?;
Ok(())
}
17 changes: 9 additions & 8 deletions common/src/ipc/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,14 @@ impl Scale {
}
}
}

#[must_use]
pub fn to_f32(&self) -> f32 {
match self {
Scale::Output(i) | Scale::Preferred(i) => i.get() as f32,
Scale::Fractional(f) => f.get() as f32 / 120.0,
}
}
}

impl PartialEq for Scale {
Expand All @@ -193,14 +201,7 @@ impl PartialEq for Scale {

impl fmt::Display for Scale {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
Scale::Output(i) | Scale::Preferred(i) => i.get() as f32,
Scale::Fractional(f) => f.get() as f32 / 120.0,
}
)
write!(f, "{}", self.to_f32())
}
}

Expand Down
3 changes: 3 additions & 0 deletions doc/swww-query.1.scd
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ swww-query
*-a*,*--all*
Send this command to all active *swww-daemon* namespaces.

*-j*,*--j*
Print the information in *json* format.

*-n*,*--namespace* <namespace>
Which wayland namespace to send this command to.

Expand Down
Loading