Add screenshot-window action

This commit is contained in:
Ivan Molodetskikh
2023-10-10 12:42:24 +04:00
parent cb73bcfb32
commit c8105ae1a6
5 changed files with 73 additions and 0 deletions
+2
View File
@@ -208,6 +208,8 @@ binds {
Mod+Equal { set-column-width "+10%"; } Mod+Equal { set-column-width "+10%"; }
Print { screenshot; } Print { screenshot; }
Alt+Print { screenshot-window; }
Mod+Shift+E { quit; } Mod+Shift+E { quit; }
Mod+Shift+P { power-off-monitors; } Mod+Shift+P { power-off-monitors; }
+1
View File
@@ -239,6 +239,7 @@ pub enum Action {
ToggleDebugTint, ToggleDebugTint,
Spawn(#[knuffel(arguments)] Vec<String>), Spawn(#[knuffel(arguments)] Vec<String>),
Screenshot, Screenshot,
ScreenshotWindow,
CloseWindow, CloseWindow,
FullscreenWindow, FullscreenWindow,
FocusColumnLeft, FocusColumnLeft,
+12
View File
@@ -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 => { Action::CloseWindow => {
if let Some(window) = self.niri.layout.focus() { if let Some(window) = self.niri.layout.focus() {
window.toplevel().send_close(); window.toplevel().send_close();
+24
View File
@@ -751,6 +751,30 @@ impl<W: LayoutElement> Layout<W> {
Some(&mon.workspaces[mon.active_workspace_idx]) 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>> { pub fn workspace_for_output(&self, output: &Output) -> Option<&Workspace<W>> {
let MonitorSet::Normal { monitors, .. } = &self.monitor_set else { let MonitorSet::Normal { monitors, .. } = &self.monitor_set else {
return None; return None;
+34
View File
@@ -1510,6 +1510,40 @@ impl Niri {
let elements = self.render(renderer, output, true); let elements = self.render(renderer, output, true);
let pixels = render_to_vec(renderer, size, scale, &elements)?; 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")?; let path = make_screenshot_path().context("error making screenshot path")?;
debug!("saving screenshot to {path:?}"); debug!("saving screenshot to {path:?}");