Skip to content
This repository was archived by the owner on Oct 31, 2025. It is now read-only.
/ swww Public archive

Commit 53e6bed

Browse files
committed
swww-query: support json printing
1 parent 1333015 commit 53e6bed

File tree

6 files changed

+81
-19
lines changed

6 files changed

+81
-19
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ image = { version = "0.25", default-features = false, features = [
2929
"tiff",
3030
"webp",
3131
] }
32+
jzon = { version = "0.12", default-features = false }
3233
resvg = { version = "0.45" }
3334
rustix = { version = "1.1", default-features = false, features = [ "fs" ] }
3435
fast_image_resize = "5.3"

client/src/cli.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ pub struct Query {
265265
#[arg(short, long, default_value = "false")]
266266
pub all: bool,
267267

268+
/// Print the information in `json` format
269+
#[arg(short, long, default_value = "false")]
270+
pub json: bool,
271+
268272
/// The daemon's namespace.
269273
///
270274
/// The resulting namespace will be 'swww-daemon' appended to what you pass in this argument.

client/src/main.rs

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::{str::FromStr, time::Duration};
22

33
use clap::Parser;
44
use common::cache;
5-
use common::ipc::{self, Answer, Client, IpcSocket, RequestSend};
5+
use common::ipc::{self, Answer, BgInfo, Client, IpcSocket, RequestSend};
66
use common::mmap::Mmap;
77

88
mod imgproc;
@@ -42,8 +42,9 @@ fn main() -> Result<(), String> {
4242
}
4343
};
4444

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

61-
process_swww_args(&swww, &namespace)?;
62+
if let Some(info) = process_swww_args(&swww, namespace)? {
63+
infos.push(info);
64+
}
65+
}
66+
67+
if !infos.is_empty() {
68+
if let Swww::Query(query) = swww
69+
&& query.json
70+
{
71+
use jzon::{JsonValue, object, stringify_pretty};
72+
let mut buf = String::new();
73+
for (namespace, infos) in namespaces.iter().zip(infos) {
74+
let mut arr = JsonValue::new_array();
75+
for info in infos {
76+
let displaying = match info.img {
77+
ipc::BgImg::Color(color) => {
78+
object! { color: format!("#{:x}", u32::from_ne_bytes(color)) }
79+
}
80+
ipc::BgImg::Img(img) => {
81+
object! { image: img.as_ref() }
82+
}
83+
};
84+
_ = arr.push(object! {
85+
name: info.name.as_ref(),
86+
width: info.dim.0,
87+
height: info.dim.1,
88+
scale: info.scale_factor.to_f32(),
89+
displaying: displaying
90+
});
91+
}
92+
buf = format!("{buf}\n\"{namespace}\": {},", stringify_pretty(arr, 4));
93+
}
94+
buf.pop(); // delete trailing comma
95+
println!("{{{buf}\n}}");
96+
} else {
97+
for (namespace, infos) in namespaces.iter().zip(infos) {
98+
for info in infos {
99+
println!("{namespace}: {info}");
100+
}
101+
}
102+
}
62103
}
63104
Ok(())
64105
}
65106

66-
fn process_swww_args(args: &Swww, namespace: &str) -> Result<(), String> {
107+
fn process_swww_args(args: &Swww, namespace: &str) -> Result<Option<Box<[BgInfo]>>, String> {
67108
let request = match make_request(args, namespace)? {
68109
Some(request) => request,
69-
None => return Ok(()),
110+
None => return Ok(None),
70111
};
71112
let socket = IpcSocket::connect(namespace).map_err(|err| err.to_string())?;
72113
request.send(&socket)?;
73114
let bytes = socket.recv().map_err(|err| err.to_string())?;
74115
drop(socket);
75116
match Answer::receive(bytes) {
76-
Answer::Info(info) => info.iter().for_each(|i| println!("{namespace}: {i}")),
117+
Answer::Info(infos) => {
118+
if let Swww::Query(_) = args {
119+
return Ok(Some(infos));
120+
}
121+
}
77122
Answer::Ok => {
78123
if let Swww::Kill(_) = args {
79124
#[cfg(debug_assertions)]
@@ -83,7 +128,7 @@ fn process_swww_args(args: &Swww, namespace: &str) -> Result<(), String> {
83128
let path = IpcSocket::<Client>::path(namespace);
84129
for _ in 0..tries {
85130
if rustix::fs::access(&path, rustix::fs::Access::EXISTS).is_err() {
86-
return Ok(());
131+
return Ok(None);
87132
}
88133
std::thread::sleep(Duration::from_millis(100));
89134
}
@@ -94,10 +139,10 @@ fn process_swww_args(args: &Swww, namespace: &str) -> Result<(), String> {
94139
}
95140
}
96141
Answer::Ping(_) => {
97-
return Ok(());
142+
return Ok(None);
98143
}
99144
}
100-
Ok(())
145+
Ok(None)
101146
}
102147

103148
fn make_request(args: &Swww, namespace: &str) -> Result<Option<RequestSend>, String> {
@@ -405,5 +450,6 @@ fn restore_output(output: &str, namespace: &str) -> Result<(), String> {
405450
transition_wave: (0.0, 0.0),
406451
}),
407452
namespace,
408-
)
453+
)?;
454+
Ok(())
409455
}

common/src/ipc/types.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,14 @@ impl Scale {
177177
}
178178
}
179179
}
180+
181+
#[must_use]
182+
pub fn to_f32(&self) -> f32 {
183+
match self {
184+
Scale::Output(i) | Scale::Preferred(i) => i.get() as f32,
185+
Scale::Fractional(f) => f.get() as f32 / 120.0,
186+
}
187+
}
180188
}
181189

182190
impl PartialEq for Scale {
@@ -193,14 +201,7 @@ impl PartialEq for Scale {
193201

194202
impl fmt::Display for Scale {
195203
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196-
write!(
197-
f,
198-
"{}",
199-
match self {
200-
Scale::Output(i) | Scale::Preferred(i) => i.get() as f32,
201-
Scale::Fractional(f) => f.get() as f32 / 120.0,
202-
}
203-
)
204+
write!(f, "{}", self.to_f32())
204205
}
205206
}
206207

doc/swww-query.1.scd

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ swww-query
1111
*-a*,*--all*
1212
Send this command to all active *swww-daemon* namespaces.
1313

14+
*-j*,*--j*
15+
Print the information in *json* format.
16+
1417
*-n*,*--namespace* <namespace>
1518
Which wayland namespace to send this command to.
1619

0 commit comments

Comments
 (0)