mirror of
https://github.com/YaLTeR/niri.git
synced 2024-09-11 12:35:58 +03:00
Implement taking a monitor screenshot
This commit is contained in:
parent
1575753b69
commit
af7b978eb4
211
Cargo.lock
generated
211
Cargo.lock
generated
@ -2,6 +2,12 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.0.4"
|
||||
@ -413,6 +419,12 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b"
|
||||
|
||||
[[package]]
|
||||
name = "color_quant"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
@ -477,6 +489,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.16"
|
||||
@ -496,6 +517,12 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946"
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
@ -517,6 +544,27 @@ dependencies = [
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "directories"
|
||||
version = "5.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35"
|
||||
dependencies = [
|
||||
"dirs-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"option-ext",
|
||||
"redox_users",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dispatch"
|
||||
version = "0.2.0"
|
||||
@ -662,6 +710,25 @@ version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d329bdeac514ee06249dabc27877490f17f5d371ec693360768b838e19f3ae10"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6c98ee8095e9d1dcbf2fcc6d95acccb90d1c81db1e44725c6a984b1dbdfb010"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
@ -831,6 +898,20 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.24.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"color_quant",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "1.9.3"
|
||||
@ -907,6 +988,12 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38"
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
@ -1092,6 +1179,16 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.8"
|
||||
@ -1140,11 +1237,14 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.4.0",
|
||||
"clap",
|
||||
"directories",
|
||||
"image",
|
||||
"keyframe",
|
||||
"profiling",
|
||||
"sd-notify",
|
||||
"smithay",
|
||||
"smithay-drm-extras",
|
||||
"time",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracy-client",
|
||||
@ -1211,6 +1311,27 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.16"
|
||||
@ -1263,6 +1384,15 @@ dependencies = [
|
||||
"syn 2.0.28",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_threads"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "objc-sys"
|
||||
version = "0.2.0-beta.2"
|
||||
@ -1295,13 +1425,19 @@ version = "1.18.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
|
||||
|
||||
[[package]]
|
||||
name = "option-ext"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
|
||||
|
||||
[[package]]
|
||||
name = "orbclient"
|
||||
version = "0.3.46"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8378ac0dfbd4e7895f2d2c1f1345cab3836910baf3a300b000d04250f0c8428f"
|
||||
dependencies = [
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.3.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1350,6 +1486,19 @@ version = "0.3.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "2.8.0"
|
||||
@ -1465,6 +1614,15 @@ version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9"
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.3.5"
|
||||
@ -1474,6 +1632,17 @@ dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_users"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"redox_syscall 0.2.16",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.9.3"
|
||||
@ -1639,6 +1808,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
@ -1791,7 +1966,7 @@ checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand 2.0.0",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.3.5",
|
||||
"rustix 0.38.8",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
@ -1826,6 +2001,36 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
"libc",
|
||||
"num_threads",
|
||||
"serde",
|
||||
"time-core",
|
||||
"time-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572"
|
||||
dependencies = [
|
||||
"time-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.3"
|
||||
@ -2417,7 +2622,7 @@ dependencies = [
|
||||
"orbclient",
|
||||
"percent-encoding",
|
||||
"raw-window-handle",
|
||||
"redox_syscall",
|
||||
"redox_syscall 0.3.5",
|
||||
"smithay-client-toolkit",
|
||||
"wasm-bindgen",
|
||||
"wayland-client",
|
||||
|
@ -10,10 +10,13 @@ edition = "2021"
|
||||
anyhow = { version = "1.0.72" }
|
||||
bitflags = "2.3.3"
|
||||
clap = { version = "4.3.21", features = ["derive"] }
|
||||
directories = "5.0.1"
|
||||
image = { version = "0.24.7", default-features = false, features = ["png"] }
|
||||
keyframe = { version = "1.1.1", default-features = false }
|
||||
profiling = "1.0.9"
|
||||
sd-notify = "0.4.1"
|
||||
smithay-drm-extras = { version = "0.1.0", path = "../smithay/smithay-drm-extras" }
|
||||
time = { version = "0.3.28", features = ["formatting", "local-offset", "macros"] }
|
||||
tracing = "0.1.37"
|
||||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
|
||||
tracy-client = { version = "0.15.2", default-features = false }
|
||||
|
@ -82,6 +82,7 @@ The general system is: if a hotkey switches somewhere, then adding <kbd>Ctrl</kb
|
||||
| <kbd>Mod</kbd><kbd>R</kbd> | Toggle between preset column widths |
|
||||
| <kbd>Mod</kbd><kbd>F</kbd> | Maximize column |
|
||||
| <kbd>Mod</kbd><kbd>Shift</kbd><kbd>F</kbd> | Toggle full-screen on the focused window |
|
||||
| <kbd>Mod</kbd><kbd>PrtSc</kbd> | Save a screenshot to `~/Pictures/Screenshots/` |
|
||||
| <kbd>Mod</kbd><kbd>Shift</kbd><kbd>E</kbd> | Exit niri |
|
||||
|
||||
[PaperWM]: https://github.com/paperwm/PaperWM
|
||||
|
19
src/input.rs
19
src/input.rs
@ -20,6 +20,7 @@ enum Action {
|
||||
Quit,
|
||||
ChangeVt(i32),
|
||||
Spawn(String),
|
||||
Screenshot,
|
||||
CloseWindow,
|
||||
ToggleFullscreen,
|
||||
FocusLeft,
|
||||
@ -48,6 +49,12 @@ enum Action {
|
||||
ToggleFullWidth,
|
||||
}
|
||||
|
||||
pub enum BackendAction {
|
||||
None,
|
||||
ChangeVt(i32),
|
||||
Screenshot,
|
||||
}
|
||||
|
||||
pub enum CompositorMod {
|
||||
Super,
|
||||
Alt,
|
||||
@ -88,6 +95,8 @@ fn action(comp_mod: CompositorMod, keysym: KeysymHandle, mods: ModifiersState) -
|
||||
KEY_t => Action::Spawn("alacritty".to_owned()),
|
||||
KEY_d => Action::Spawn("fuzzel".to_owned()),
|
||||
KEY_n => Action::Spawn("nautilus".to_owned()),
|
||||
// Alt + PrtSc = SysRq
|
||||
KEY_Sys_Req | KEY_Print => Action::Screenshot,
|
||||
KEY_q => Action::CloseWindow,
|
||||
KEY_F => Action::ToggleFullscreen,
|
||||
KEY_comma => Action::ConsumeIntoColumn,
|
||||
@ -126,10 +135,9 @@ fn action(comp_mod: CompositorMod, keysym: KeysymHandle, mods: ModifiersState) -
|
||||
impl Niri {
|
||||
pub fn process_input_event<I: InputBackend>(
|
||||
&mut self,
|
||||
change_vt: &mut dyn FnMut(i32),
|
||||
comp_mod: CompositorMod,
|
||||
event: InputEvent<I>,
|
||||
) {
|
||||
) -> BackendAction {
|
||||
let _span = tracy_client::span!("process_input_event");
|
||||
trace!("process_input_event");
|
||||
|
||||
@ -167,13 +175,16 @@ impl Niri {
|
||||
self.stop_signal.stop()
|
||||
}
|
||||
Action::ChangeVt(vt) => {
|
||||
(*change_vt)(vt);
|
||||
return BackendAction::ChangeVt(vt);
|
||||
}
|
||||
Action::Spawn(command) => {
|
||||
if let Err(err) = Command::new(command).spawn() {
|
||||
warn!("error spawning alacritty: {err}");
|
||||
}
|
||||
}
|
||||
Action::Screenshot => {
|
||||
return BackendAction::Screenshot;
|
||||
}
|
||||
Action::CloseWindow => {
|
||||
if let Some(window) = self.monitor_set.focus() {
|
||||
window.toplevel().send_close();
|
||||
@ -602,6 +613,8 @@ impl Niri {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
BackendAction::None
|
||||
}
|
||||
|
||||
pub fn process_libinput_event(&mut self, event: &mut InputEvent<LibinputInputBackend>) {
|
||||
|
98
src/niri.rs
98
src/niri.rs
@ -2,16 +2,22 @@ use std::collections::HashMap;
|
||||
use std::os::unix::io::AsRawFd;
|
||||
use std::process::Command;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::Context;
|
||||
use directories::UserDirs;
|
||||
use sd_notify::NotifyState;
|
||||
use smithay::backend::allocator::Fourcc;
|
||||
use smithay::backend::renderer::element::surface::{
|
||||
render_elements_from_surface_tree, WaylandSurfaceRenderElement,
|
||||
};
|
||||
use smithay::backend::renderer::element::texture::{TextureBuffer, TextureRenderElement};
|
||||
use smithay::backend::renderer::element::{render_elements, AsRenderElements, RenderElementStates};
|
||||
use smithay::backend::renderer::element::{
|
||||
render_elements, AsRenderElements, Element, RenderElement, RenderElementStates,
|
||||
};
|
||||
use smithay::backend::renderer::gles::{GlesRenderer, GlesTexture};
|
||||
use smithay::backend::renderer::{ImportAll, Renderer};
|
||||
use smithay::backend::renderer::{Bind, ExportMem, Frame, ImportAll, Offscreen, Renderer};
|
||||
use smithay::desktop::utils::{
|
||||
send_frames_surface_tree, surface_presentation_feedback_flags_from_states,
|
||||
take_presentation_feedback_surface_tree, OutputPresentationFeedback,
|
||||
@ -32,7 +38,9 @@ use smithay::reexports::wayland_server::backend::{
|
||||
};
|
||||
use smithay::reexports::wayland_server::protocol::wl_surface::WlSurface;
|
||||
use smithay::reexports::wayland_server::{Display, DisplayHandle};
|
||||
use smithay::utils::{IsAlive, Logical, Physical, Point, Rectangle, Scale, SERIAL_COUNTER};
|
||||
use smithay::utils::{
|
||||
IsAlive, Logical, Physical, Point, Rectangle, Scale, Transform, SERIAL_COUNTER,
|
||||
};
|
||||
use smithay::wayland::compositor::{with_states, CompositorClientState, CompositorState};
|
||||
use smithay::wayland::data_device::DataDeviceState;
|
||||
use smithay::wayland::output::OutputManagerState;
|
||||
@ -42,6 +50,7 @@ use smithay::wayland::shell::xdg::XdgShellState;
|
||||
use smithay::wayland::shm::ShmState;
|
||||
use smithay::wayland::socket::ListeningSocketSource;
|
||||
use smithay::wayland::tablet_manager::TabletManagerState;
|
||||
use time::OffsetDateTime;
|
||||
|
||||
use crate::backend::Backend;
|
||||
use crate::dbus::mutter_service_channel::ServiceChannel;
|
||||
@ -712,6 +721,89 @@ impl Niri {
|
||||
|
||||
feedback
|
||||
}
|
||||
|
||||
pub fn screenshot(
|
||||
&mut self,
|
||||
renderer: &mut GlesRenderer,
|
||||
output: &Output,
|
||||
) -> anyhow::Result<()> {
|
||||
let _span = tracy_client::span!("Niri::screenshot");
|
||||
|
||||
let size = output.current_mode().unwrap().size;
|
||||
let output_rect = Rectangle::from_loc_and_size((0, 0), size);
|
||||
let buffer_size = size.to_logical(1).to_buffer(1, Transform::Normal);
|
||||
let fourcc = Fourcc::Abgr8888;
|
||||
|
||||
let texture: GlesTexture = renderer
|
||||
.create_buffer(fourcc, buffer_size)
|
||||
.context("error creating texture")?;
|
||||
|
||||
let elements = self.render(renderer, output);
|
||||
|
||||
renderer.bind(texture).context("error binding texture")?;
|
||||
let mut frame = renderer
|
||||
.render(size, Transform::Normal)
|
||||
.context("error starting frame")?;
|
||||
|
||||
frame
|
||||
.clear([0.1, 0.1, 0.1, 1.], &[output_rect])
|
||||
.context("error clearing")?;
|
||||
|
||||
for element in elements.into_iter().rev() {
|
||||
let src = element.src();
|
||||
let dst = element.geometry(Scale::from(1.));
|
||||
element
|
||||
.draw(&mut frame, src, dst, &[output_rect])
|
||||
.context("error drawing element")?;
|
||||
}
|
||||
|
||||
let sync_point = frame.finish().context("error finishing frame")?;
|
||||
sync_point.wait();
|
||||
|
||||
let mapping = renderer
|
||||
.copy_framebuffer(Rectangle::from_loc_and_size((0, 0), buffer_size), fourcc)
|
||||
.context("error copying framebuffer")?;
|
||||
let copy = renderer
|
||||
.map_texture(&mapping)
|
||||
.context("error mapping texture")?;
|
||||
let pixels = copy.to_vec();
|
||||
|
||||
let dirs = UserDirs::new().context("error retrieving home directory")?;
|
||||
let mut path = dirs.picture_dir().map(|p| p.to_owned()).unwrap_or_else(|| {
|
||||
let mut dir = dirs.home_dir().to_owned();
|
||||
dir.push("Pictures");
|
||||
dir
|
||||
});
|
||||
path.push("Screenshots");
|
||||
|
||||
unsafe {
|
||||
// are you kidding me
|
||||
time::util::local_offset::set_soundness(time::util::local_offset::Soundness::Unsound);
|
||||
};
|
||||
|
||||
let now = OffsetDateTime::now_local().unwrap_or_else(|_| OffsetDateTime::now_utc());
|
||||
let desc = time::macros::format_description!(
|
||||
"Screenshot from [year]-[month]-[day] [hour]-[minute]-[second].png"
|
||||
);
|
||||
let name = now.format(desc).context("error formatting time")?;
|
||||
path.push(name);
|
||||
|
||||
debug!("saving screenshot to {path:?}");
|
||||
|
||||
thread::spawn(move || {
|
||||
if let Err(err) = image::save_buffer(
|
||||
path,
|
||||
&pixels,
|
||||
size.w as u32,
|
||||
size.h as u32,
|
||||
image::ColorType::Rgba8,
|
||||
) {
|
||||
warn!("error saving screenshot image: {err:?}");
|
||||
}
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
render_elements! {
|
||||
|
21
src/tty.rs
21
src/tty.rs
@ -31,7 +31,7 @@ use smithay_drm_extras::drm_scanner::{DrmScanEvent, DrmScanner};
|
||||
use smithay_drm_extras::edid::EdidInfo;
|
||||
|
||||
use crate::backend::Backend;
|
||||
use crate::input::CompositorMod;
|
||||
use crate::input::{BackendAction, CompositorMod};
|
||||
use crate::niri::OutputRenderElements;
|
||||
use crate::{LoopData, Niri};
|
||||
|
||||
@ -173,10 +173,21 @@ impl Tty {
|
||||
event_loop
|
||||
.insert_source(input_backend, |mut event, _, data| {
|
||||
let tty = data.tty.as_mut().unwrap();
|
||||
let mut change_vt = |vt| tty.change_vt(vt);
|
||||
data.niri.process_libinput_event(&mut event);
|
||||
data.niri
|
||||
.process_input_event(&mut change_vt, CompositorMod::Super, event);
|
||||
let niri = &mut data.niri;
|
||||
|
||||
niri.process_libinput_event(&mut event);
|
||||
match niri.process_input_event(CompositorMod::Super, event) {
|
||||
BackendAction::None => (),
|
||||
BackendAction::ChangeVt(vt) => tty.change_vt(vt),
|
||||
BackendAction::Screenshot => {
|
||||
let active = niri.monitor_set.active_output().cloned();
|
||||
if let Some(active) = active {
|
||||
if let Err(err) = niri.screenshot(tty.renderer(), &active) {
|
||||
warn!("error taking screenshot: {err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
|
16
src/winit.rs
16
src/winit.rs
@ -12,7 +12,7 @@ use smithay::reexports::winit::window::WindowBuilder;
|
||||
use smithay::utils::Transform;
|
||||
|
||||
use crate::backend::Backend;
|
||||
use crate::input::CompositorMod;
|
||||
use crate::input::{BackendAction, CompositorMod};
|
||||
use crate::niri::OutputRenderElements;
|
||||
use crate::utils::get_monotonic_time;
|
||||
use crate::{LoopData, Niri};
|
||||
@ -129,6 +129,7 @@ impl Winit {
|
||||
}
|
||||
|
||||
fn dispatch(&mut self, niri: &mut Niri) {
|
||||
let renderer = self.backend.renderer();
|
||||
let res = self
|
||||
.winit_event_loop
|
||||
.dispatch_new_events(|event| match event {
|
||||
@ -145,7 +146,18 @@ impl Winit {
|
||||
niri.output_resized(self.output.clone());
|
||||
}
|
||||
WinitEvent::Input(event) => {
|
||||
niri.process_input_event(&mut |_| (), CompositorMod::Alt, event)
|
||||
match niri.process_input_event(CompositorMod::Alt, event) {
|
||||
BackendAction::None => (),
|
||||
BackendAction::ChangeVt(_) => (),
|
||||
BackendAction::Screenshot => {
|
||||
let active = niri.monitor_set.active_output().cloned();
|
||||
if let Some(active) = active {
|
||||
if let Err(err) = niri.screenshot(renderer, &active) {
|
||||
warn!("error taking screenshot: {err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
WinitEvent::Focus(_) => (),
|
||||
WinitEvent::Refresh => niri.queue_redraw(self.output.clone()),
|
||||
|
Loading…
Reference in New Issue
Block a user