Skip to content

Commit 0469431

Browse files
committed
[update] replace xdg-output-handler with wl_output
* Update some dependencies. * Rewrite output.rs to use wl_output version 4 instead of xdg-output-handler * Sent patch to smithay to update wl_output least supported version Smithay/client-toolkit#259.
1 parent fc90d64 commit 0469431

File tree

6 files changed

+75
-103
lines changed

6 files changed

+75
-103
lines changed

Cargo.lock

+2-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ keywords = ["screenshot", "wayland", "wlroots"]
88
license = "BSD-2-Clause"
99
name = "wayshot"
1010
repository = "https://git.sr.ht/~shinyzenith/wayshot"
11-
version = "1.1.5"
11+
version = "1.1.7"
1212
exclude = [
1313
"CODE_OF_CONDUCT.md",
1414
"CONTRIBUTING.md",

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ uninstall:
2222
check:
2323
@cargo fmt
2424
@cargo check
25+
@cargo clippy
2526

2627
clean:
2728
@cargo clean

src/backend.rs

+7-13
Original file line numberDiff line numberDiff line change
@@ -116,22 +116,19 @@ pub fn capture_output_frame(
116116
}
117117
};
118118

119-
// Instantiating the image frame.
120-
let frame: Main<ZwlrScreencopyFrameV1>;
121-
122119
// Capture output.
123-
if let Some(region) = capture_region {
124-
frame = screencopy_manager.capture_output_region(
120+
let frame: Main<ZwlrScreencopyFrameV1> = if let Some(region) = capture_region {
121+
screencopy_manager.capture_output_region(
125122
cursor_overlay,
126123
&output,
127124
region.x_coordinate,
128125
region.y_coordinate,
129126
region.width,
130127
region.height,
131-
);
128+
)
132129
} else {
133-
frame = screencopy_manager.capture_output(cursor_overlay, &output);
134-
}
130+
screencopy_manager.capture_output(cursor_overlay, &output)
131+
};
135132

136133
// Assign callback to frame.
137134
frame.quick_assign({
@@ -197,13 +194,12 @@ pub fn capture_output_frame(
197194
let frame_format = frame_formats
198195
.borrow()
199196
.iter()
200-
.filter(|frame| {
197+
.find(|frame| {
201198
matches!(
202199
frame.format,
203200
wl_shm::Format::Argb8888 | wl_shm::Format::Xrgb8888 | wl_shm::Format::Xbgr8888
204201
)
205202
})
206-
.nth(0)
207203
.copied();
208204
log::debug!("Selected frame buffer format: {:#?}", frame_format);
209205

@@ -257,9 +253,7 @@ pub fn capture_output_frame(
257253
wl_shm::Format::Argb8888 | wl_shm::Format::Xrgb8888 => {
258254
// Swap out b with r as these formats are in little endian notation.
259255
for chunk in data.chunks_exact_mut(4) {
260-
let alpha = chunk[0];
261-
chunk[0] = chunk[2];
262-
chunk[2] = alpha;
256+
chunk.swap(0, 2);
263257
}
264258
Rgba8
265259
}

src/output.rs

+42-43
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,53 @@
1-
use smithay_client_toolkit::{
2-
environment,
3-
environment::Environment,
4-
output::{with_output_info, OutputHandler, OutputInfo, XdgOutputHandler},
5-
reexports::{
6-
client::{protocol::wl_output::WlOutput, Display},
7-
protocols::unstable::xdg_output::v1::client::zxdg_output_manager_v1::ZxdgOutputManagerV1,
8-
},
1+
use smithay_client_toolkit::reexports::client::{
2+
protocol::wl_output, protocol::wl_output::WlOutput, Display, GlobalManager,
93
};
4+
use std::{cell::RefCell, process::exit, rc::Rc};
105

11-
struct App {
12-
outputs: OutputHandler,
13-
xdg_output: XdgOutputHandler,
6+
#[derive(Debug, Clone)]
7+
pub struct OutputInfo {
8+
pub wl_output: *mut WlOutput,
9+
pub name: String,
1410
}
1511

16-
environment! {App,
17-
singles = [
18-
ZxdgOutputManagerV1 => xdg_output,
19-
],
20-
multis = [
21-
WlOutput => outputs,
22-
]
23-
}
24-
25-
pub fn get_valid_outputs(display: Display) -> Vec<(WlOutput, OutputInfo)> {
26-
let mut queue = display.create_event_queue();
27-
let attached_display = display.attach(queue.token());
28-
29-
let (outputs, xdg_output) = XdgOutputHandler::new_output_handlers();
30-
let mut valid_outputs: Vec<(WlOutput, OutputInfo)> = Vec::new();
12+
pub fn get_all_outputs(display: Display) -> Vec<OutputInfo> {
13+
// Connecting to wayland environment.
14+
let mut event_queue = display.create_event_queue();
15+
let attached_display = (*display).clone().attach(event_queue.token());
3116

32-
let env = Environment::new(
33-
&attached_display,
34-
&mut &mut queue,
35-
App {
36-
outputs,
37-
xdg_output,
38-
},
39-
)
40-
.unwrap();
17+
let outputs: Rc<RefCell<Vec<OutputInfo>>> = Rc::new(RefCell::new(Vec::new()));
4118

42-
queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
19+
// Instantiating the global manager.
20+
let globals = GlobalManager::new(&attached_display);
21+
event_queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
4322

44-
for output in env.get_all_outputs() {
45-
with_output_info(&output, |info| {
46-
if info.obsolete == false {
47-
valid_outputs.push((output.clone(), info.clone()));
48-
} else {
49-
output.release();
23+
globals
24+
.instantiate_exact::<WlOutput>(4)
25+
.expect("Failed to bind to wl_output global.")
26+
.quick_assign({
27+
let outputs = outputs.clone();
28+
move |output, event, _| {
29+
if let wl_output::Event::Name { name } = event {
30+
outputs.borrow_mut().push(OutputInfo {
31+
wl_output: &mut output.detach(),
32+
name,
33+
});
34+
}
5035
}
5136
});
37+
event_queue.sync_roundtrip(&mut (), |_, _, _| {}).unwrap();
38+
let x = outputs.borrow().to_vec();
39+
x
40+
}
41+
42+
/// Get a wl_output object from the output name.
43+
pub fn get_wloutput(name: String, outputs: Vec<OutputInfo>) -> &'static WlOutput {
44+
for output in outputs {
45+
if output.name == name {
46+
unsafe {
47+
return &*output.wl_output;
48+
}
49+
}
5250
}
53-
valid_outputs
51+
log::error!("Error: No output of name \"{}\" was found", name);
52+
exit(1);
5453
}

src/wayshot.rs

+22-43
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,7 @@ use std::{
77
time::{SystemTime, UNIX_EPOCH},
88
};
99

10-
use smithay_client_toolkit::{
11-
output::OutputInfo,
12-
reexports::client::{protocol::wl_output::WlOutput, Display},
13-
};
10+
use smithay_client_toolkit::reexports::client::{protocol::wl_output::WlOutput, Display};
1411

1512
mod backend;
1613
mod clap;
@@ -35,65 +32,61 @@ fn main() -> Result<(), Box<dyn Error>> {
3532

3633
let display = Display::connect_to_env()?;
3734
let mut extension = backend::EncodingFormat::Png;
38-
let frame_copy: backend::FrameCopy;
39-
let output: WlOutput;
35+
let output: &WlOutput;
4036

4137
let mut cursor_overlay: i32 = 0;
4238
if args.is_present("cursor") {
4339
cursor_overlay = 1;
4440
}
4541

4642
if args.is_present("listoutputs") {
47-
let valid_outputs = output::get_valid_outputs(display);
43+
let valid_outputs = output::get_all_outputs(display);
4844
for output in valid_outputs {
49-
let (_, info) = output;
50-
log::info!("{:#?}", info.name);
45+
log::info!("{:#?}", output.name);
5146
}
5247
exit(1);
5348
}
5449

5550
if args.is_present("output") {
56-
output = get_wloutput(
51+
output = &*output::get_wloutput(
5752
args.value_of("output").unwrap().trim().to_string(),
58-
output::get_valid_outputs(display.clone()),
53+
output::get_all_outputs(display.clone()),
5954
)
6055
} else {
61-
(output, _) = output::get_valid_outputs(display.clone())
62-
.first()
63-
.unwrap()
64-
.clone();
56+
unsafe {
57+
output = &*output::get_all_outputs(display.clone())
58+
.first()
59+
.unwrap()
60+
.wl_output;
61+
}
6562
}
6663

67-
if args.is_present("slurp") {
64+
let frame_copy: backend::FrameCopy = if args.is_present("slurp") {
6865
if args.value_of("slurp").unwrap() == "" {
6966
log::error!("Failed to recieve geometry.");
7067
exit(1);
7168
}
72-
let slurp: Vec<_> = args.value_of("slurp").unwrap().trim().split(" ").collect();
69+
let slurp: Vec<_> = args.value_of("slurp").unwrap().trim().split(' ').collect();
7370
let slurp: Vec<i32> = slurp.iter().map(|i| i.parse::<i32>().unwrap()).collect();
7471
let x_coordinate = slurp[0];
7572
let y_coordinate = slurp[1];
7673
let width = slurp[2];
7774
let height = slurp[3];
7875

79-
//let out = output::get_valid_outputs(display.clone());
80-
//println!("{:#?}", out);
81-
//exit(1);
82-
83-
frame_copy = backend::capture_output_frame(
84-
display.clone(),
76+
backend::capture_output_frame(
77+
display,
8578
cursor_overlay,
86-
output,
79+
output.clone(),
8780
Some(backend::CaptureRegion {
8881
x_coordinate,
8982
y_coordinate,
9083
width,
9184
height,
9285
}),
93-
)?;
86+
)?
9487
} else {
95-
frame_copy = backend::capture_output_frame(display.clone(), cursor_overlay, output, None)?;
96-
}
88+
backend::capture_output_frame(display, cursor_overlay, output.clone(), None)?
89+
};
9790

9891
if args.is_present("stdout") {
9992
let stdout = stdout();
@@ -126,28 +119,14 @@ fn main() -> Result<(), Box<dyn Error>> {
126119
}
127120
}
128121
}
129-
path = (time
122+
path = time
130123
+ match extension {
131124
backend::EncodingFormat::Png => "-wayshot.png",
132125
backend::EncodingFormat::Jpg => "-wayshot.jpg",
133-
})
134-
.to_string();
126+
};
135127
}
136128

137129
backend::write_to_file(File::create(path)?, extension, frame_copy)?;
138130
}
139131
Ok(())
140132
}
141-
142-
//TODO: This should be a part of output.rs which inturn should be merged into backend.rs
143-
/// Get a wl_output object from the output name.
144-
fn get_wloutput(name: String, valid_outputs: Vec<(WlOutput, OutputInfo)>) -> WlOutput {
145-
for device in valid_outputs.clone() {
146-
let (output_device, info) = device;
147-
if info.name == name {
148-
return output_device;
149-
}
150-
}
151-
println!("Error: No output of name \"{}\" was found", name);
152-
exit(1);
153-
}

0 commit comments

Comments
 (0)