mirror of
https://github.com/YaLTeR/niri.git
synced 2024-09-17 15:27:54 +03:00
Add screenshot-window action
This commit is contained in:
parent
cb73bcfb32
commit
c8105ae1a6
@ -208,6 +208,8 @@ binds {
|
||||
Mod+Equal { set-column-width "+10%"; }
|
||||
|
||||
Print { screenshot; }
|
||||
Alt+Print { screenshot-window; }
|
||||
|
||||
Mod+Shift+E { quit; }
|
||||
Mod+Shift+P { power-off-monitors; }
|
||||
|
||||
|
@ -239,6 +239,7 @@ pub enum Action {
|
||||
ToggleDebugTint,
|
||||
Spawn(#[knuffel(arguments)] Vec<String>),
|
||||
Screenshot,
|
||||
ScreenshotWindow,
|
||||
CloseWindow,
|
||||
FullscreenWindow,
|
||||
FocusColumnLeft,
|
||||
|
12
src/input.rs
12
src/input.rs
@ -167,6 +167,18 @@ impl State {
|
||||
}
|
||||
}
|
||||
}
|
||||
Action::ScreenshotWindow => {
|
||||
let active = self.niri.layout.active_window();
|
||||
if let Some((window, output)) = active {
|
||||
if let Some(renderer) = self.backend.renderer() {
|
||||
if let Err(err) =
|
||||
self.niri.screenshot_window(renderer, &output, &window)
|
||||
{
|
||||
warn!("error taking screenshot: {err:?}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Action::CloseWindow => {
|
||||
if let Some(window) = self.niri.layout.focus() {
|
||||
window.toplevel().send_close();
|
||||
|
@ -751,6 +751,30 @@ impl<W: LayoutElement> Layout<W> {
|
||||
Some(&mon.workspaces[mon.active_workspace_idx])
|
||||
}
|
||||
|
||||
pub fn active_window(&self) -> Option<(W, Output)> {
|
||||
let MonitorSet::Normal {
|
||||
monitors,
|
||||
active_monitor_idx,
|
||||
..
|
||||
} = &self.monitor_set
|
||||
else {
|
||||
return None;
|
||||
};
|
||||
|
||||
let mon = &monitors[*active_monitor_idx];
|
||||
let ws = &mon.workspaces[mon.active_workspace_idx];
|
||||
|
||||
if ws.columns.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let col = &ws.columns[ws.active_column_idx];
|
||||
Some((
|
||||
col.windows[col.active_window_idx].clone(),
|
||||
mon.output.clone(),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn workspace_for_output(&self, output: &Output) -> Option<&Workspace<W>> {
|
||||
let MonitorSet::Normal { monitors, .. } = &self.monitor_set else {
|
||||
return None;
|
||||
|
34
src/niri.rs
34
src/niri.rs
@ -1510,6 +1510,40 @@ impl Niri {
|
||||
let elements = self.render(renderer, output, true);
|
||||
let pixels = render_to_vec(renderer, size, scale, &elements)?;
|
||||
|
||||
self.save_screenshot(size, pixels)
|
||||
.context("error saving screenshot")
|
||||
}
|
||||
|
||||
pub fn screenshot_window(
|
||||
&mut self,
|
||||
renderer: &mut GlesRenderer,
|
||||
output: &Output,
|
||||
window: &Window,
|
||||
) -> anyhow::Result<()> {
|
||||
let _span = tracy_client::span!("Niri::screenshot_window");
|
||||
|
||||
let scale = Scale::from(output.current_scale().fractional_scale());
|
||||
let bbox = window.bbox_with_popups();
|
||||
let size = bbox.size.to_physical_precise_ceil(scale);
|
||||
let buf_pos = Point::from((0, 0)) - bbox.loc;
|
||||
// FIXME: pointer.
|
||||
let elements = window.render_elements::<WaylandSurfaceRenderElement<GlesRenderer>>(
|
||||
renderer,
|
||||
buf_pos.to_physical_precise_ceil(scale),
|
||||
scale,
|
||||
1.,
|
||||
);
|
||||
let pixels = render_to_vec(renderer, size, scale, &elements)?;
|
||||
|
||||
self.save_screenshot(size, pixels)
|
||||
.context("error saving screenshot")
|
||||
}
|
||||
|
||||
fn save_screenshot(
|
||||
&mut self,
|
||||
size: Size<i32, Physical>,
|
||||
pixels: Vec<u8>,
|
||||
) -> anyhow::Result<()> {
|
||||
let path = make_screenshot_path().context("error making screenshot path")?;
|
||||
debug!("saving screenshot to {path:?}");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user