Skip to content

Commit 4024152

Browse files
authored
feat(wayland): support image capture on wlroot wayland (#207)
* feat: support image capture on `wlroot` wayland * fix: use correct method * refactor: inline variables * chore: descriptive error message --------- Co-authored-by: Nikita Revenco <[email protected]>
1 parent a65e361 commit 4024152

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ dbus = "0.9"
5757
lazy_static = "1.5"
5858
percent-encoding = "2.3"
5959
xcb = { version = "1.5", features = ["randr"] }
60+
libwayshot = "0.3"
6061

6162
[dev-dependencies]
6263
fs_extra = "1.3"

src/error.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ pub enum XCapError {
3030
#[cfg(target_os = "linux")]
3131
#[error(transparent)]
3232
StdTimeSystemTimeError(#[from] std::time::SystemTimeError),
33+
#[cfg(target_os = "linux")]
34+
#[error(transparent)]
35+
LibwayshotError(#[from] libwayshot::Error),
3336

3437
#[cfg(target_os = "macos")]
3538
#[error("Objc2CoreGraphicsCGError {:?}", 0)]

src/linux/wayland_capture.rs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,40 @@ fn org_freedesktop_portal_screenshot(
172172

173173
static DBUS_LOCK: Mutex<()> = Mutex::new(());
174174

175+
fn wlroots_screenshot(
176+
x_coordinate: i32,
177+
y_coordinate: i32,
178+
width: i32,
179+
height: i32,
180+
) -> XCapResult<RgbaImage> {
181+
let wayshot_connection = libwayshot::WayshotConnection::new()?;
182+
let capture_region = libwayshot::CaptureRegion {
183+
x_coordinate,
184+
y_coordinate,
185+
width,
186+
height,
187+
};
188+
let rgba_image = wayshot_connection.screenshot(capture_region, false)?;
189+
190+
// libwayshot returns image 0.24 RgbaImage
191+
// we need image 0.25 RgbaImage
192+
let image = image::RgbaImage::from_raw(
193+
rgba_image.width(),
194+
rgba_image.height(),
195+
rgba_image.into_raw(),
196+
)
197+
.expect("Conversion of PNG -> Raw -> PNG does not fail");
198+
199+
Ok(image)
200+
}
201+
175202
pub fn wayland_capture(x: i32, y: i32, width: i32, height: i32) -> XCapResult<RgbaImage> {
176203
let lock = DBUS_LOCK.lock();
177204

178205
let conn = Connection::new_session()?;
179206
let res = org_gnome_shell_screenshot(&conn, x, y, width, height)
180-
.or_else(|_| org_freedesktop_portal_screenshot(&conn, x, y, width, height));
207+
.or_else(|_| org_freedesktop_portal_screenshot(&conn, x, y, width, height))
208+
.or_else(|_| wlroots_screenshot(x, y, width, height));
181209

182210
drop(lock);
183211

0 commit comments

Comments
 (0)