Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add write-to-disk argument to screenshot actions #975

Merged
merged 1 commit into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 20 additions & 7 deletions niri-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1185,16 +1185,21 @@ pub enum Action {
Spawn(#[knuffel(arguments)] Vec<String>),
DoScreenTransition(#[knuffel(property(name = "delay-ms"))] Option<u16>),
#[knuffel(skip)]
ConfirmScreenshot,
ConfirmScreenshot {
write_to_disk: bool,
},
#[knuffel(skip)]
CancelScreenshot,
#[knuffel(skip)]
ScreenshotTogglePointer,
Screenshot,
ScreenshotScreen,
ScreenshotWindow,
ScreenshotScreen(#[knuffel(property(name = "write-to-disk"), default = true)] bool),
ScreenshotWindow(#[knuffel(property(name = "write-to-disk"), default = true)] bool),
#[knuffel(skip)]
ScreenshotWindowById(u64),
ScreenshotWindowById {
id: u64,
write_to_disk: bool,
},
CloseWindow,
#[knuffel(skip)]
CloseWindowById(u64),
Expand Down Expand Up @@ -1351,9 +1356,17 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::Spawn { command } => Self::Spawn(command),
niri_ipc::Action::DoScreenTransition { delay_ms } => Self::DoScreenTransition(delay_ms),
niri_ipc::Action::Screenshot {} => Self::Screenshot,
niri_ipc::Action::ScreenshotScreen {} => Self::ScreenshotScreen,
niri_ipc::Action::ScreenshotWindow { id: None } => Self::ScreenshotWindow,
niri_ipc::Action::ScreenshotWindow { id: Some(id) } => Self::ScreenshotWindowById(id),
niri_ipc::Action::ScreenshotScreen { write_to_disk } => {
Self::ScreenshotScreen(write_to_disk)
}
niri_ipc::Action::ScreenshotWindow {
id: None,
write_to_disk,
} => Self::ScreenshotWindow(write_to_disk),
niri_ipc::Action::ScreenshotWindow {
id: Some(id),
write_to_disk,
} => Self::ScreenshotWindowById { id, write_to_disk },
niri_ipc::Action::CloseWindow { id: None } => Self::CloseWindow,
niri_ipc::Action::CloseWindow { id: Some(id) } => Self::CloseWindowById(id),
niri_ipc::Action::FullscreenWindow { id: None } => Self::FullscreenWindow,
Expand Down
13 changes: 12 additions & 1 deletion niri-ipc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,13 @@ pub enum Action {
/// Open the screenshot UI.
Screenshot {},
/// Screenshot the focused screen.
ScreenshotScreen {},
ScreenshotScreen {
/// Write the screenshot to disk in addition to putting it in your clipboard.
///
/// The screenshot is saved according to the `screenshot-path` config setting.
#[cfg_attr(feature = "clap", arg(short = 'd', long, action = clap::ArgAction::Set, default_value_t = true))]
write_to_disk: bool,
},
/// Screenshot a window.
#[cfg_attr(feature = "clap", clap(about = "Screenshot the focused window"))]
ScreenshotWindow {
Expand All @@ -176,6 +182,11 @@ pub enum Action {
/// If `None`, uses the focused window.
#[cfg_attr(feature = "clap", arg(long))]
id: Option<u64>,
/// Write the screenshot to disk in addition to putting it in your clipboard.
///
/// The screenshot is saved according to the `screenshot-path` config setting.
#[cfg_attr(feature = "clap", arg(short = 'd', long, action = clap::ArgAction::Set, default_value_t = true))]
write_to_disk: bool,
},
/// Close a window.
#[cfg_attr(feature = "clap", clap(about = "Close the focused window"))]
Expand Down
23 changes: 15 additions & 8 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,25 +529,26 @@ impl State {
self.niri.do_screen_transition(renderer, delay_ms);
});
}
Action::ScreenshotScreen => {
Action::ScreenshotScreen(write_to_disk) => {
let active = self.niri.layout.active_output().cloned();
if let Some(active) = active {
self.backend.with_primary_renderer(|renderer| {
if let Err(err) = self.niri.screenshot(renderer, &active) {
if let Err(err) = self.niri.screenshot(renderer, &active, write_to_disk) {
warn!("error taking screenshot: {err:?}");
}
});
}
}
Action::ConfirmScreenshot => {
Action::ConfirmScreenshot { write_to_disk } => {
if !self.niri.screenshot_ui.is_open() {
return;
}

self.backend.with_primary_renderer(|renderer| {
match self.niri.screenshot_ui.capture(renderer) {
Ok((size, pixels)) => {
if let Err(err) = self.niri.save_screenshot(size, pixels) {
if let Err(err) = self.niri.save_screenshot(size, pixels, write_to_disk)
{
warn!("error saving screenshot: {err:?}");
}
}
Expand Down Expand Up @@ -581,23 +582,29 @@ impl State {
Action::Screenshot => {
self.open_screenshot_ui();
}
Action::ScreenshotWindow => {
Action::ScreenshotWindow(write_to_disk) => {
let focus = self.niri.layout.focus_with_output();
if let Some((mapped, output)) = focus {
self.backend.with_primary_renderer(|renderer| {
if let Err(err) = self.niri.screenshot_window(renderer, output, mapped) {
if let Err(err) =
self.niri
.screenshot_window(renderer, output, mapped, write_to_disk)
{
warn!("error taking screenshot: {err:?}");
}
});
}
}
Action::ScreenshotWindowById(id) => {
Action::ScreenshotWindowById { id, write_to_disk } => {
let mut windows = self.niri.layout.windows();
let window = windows.find(|(_, m)| m.id().get() == id);
if let Some((Some(monitor), mapped)) = window {
let output = monitor.output();
self.backend.with_primary_renderer(|renderer| {
if let Err(err) = self.niri.screenshot_window(renderer, output, mapped) {
if let Err(err) =
self.niri
.screenshot_window(renderer, output, mapped, write_to_disk)
{
warn!("error taking screenshot: {err:?}");
}
});
Expand Down
23 changes: 14 additions & 9 deletions src/niri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4519,6 +4519,7 @@ impl Niri {
&mut self,
renderer: &mut GlesRenderer,
output: &Output,
write_to_disk: bool,
) -> anyhow::Result<()> {
let _span = tracy_client::span!("Niri::screenshot");

Expand All @@ -4541,7 +4542,7 @@ impl Niri {
elements,
)?;

self.save_screenshot(size, pixels)
self.save_screenshot(size, pixels, write_to_disk)
.context("error saving screenshot")
}

Expand All @@ -4550,6 +4551,7 @@ impl Niri {
renderer: &mut GlesRenderer,
output: &Output,
mapped: &Mapped,
write_to_disk: bool,
) -> anyhow::Result<()> {
let _span = tracy_client::span!("Niri::screenshot_window");

Expand Down Expand Up @@ -4585,22 +4587,25 @@ impl Niri {
elements,
)?;

self.save_screenshot(geo.size, pixels)
self.save_screenshot(geo.size, pixels, write_to_disk)
.context("error saving screenshot")
}

pub fn save_screenshot(
&self,
size: Size<i32, Physical>,
pixels: Vec<u8>,
write_to_disk: bool,
) -> anyhow::Result<()> {
let path = match make_screenshot_path(&self.config.borrow()) {
Ok(path) => path,
Err(err) => {
warn!("error making screenshot path: {err:?}");
None
}
};
let path = write_to_disk
.then(|| match make_screenshot_path(&self.config.borrow()) {
Ok(path) => path,
Err(err) => {
warn!("error making screenshot path: {err:?}");
None
}
})
.flatten();

// Prepare to set the encoded image as our clipboard selection. This must be done from the
// main thread.
Expand Down
13 changes: 9 additions & 4 deletions src/ui/screenshot_ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -629,10 +629,15 @@ fn action(raw: Keysym, mods: ModifiersState) -> Option<Action> {
return None;
}

if (mods.ctrl && raw == Keysym::c)
|| (!mods.ctrl && (raw == Keysym::space || raw == Keysym::Return))
{
return Some(Action::ConfirmScreenshot);
if !mods.ctrl && (raw == Keysym::space || raw == Keysym::Return) {
return Some(Action::ConfirmScreenshot {
write_to_disk: true,
});
}
if mods.ctrl && raw == Keysym::c {
return Some(Action::ConfirmScreenshot {
write_to_disk: false,
});
}

if !mods.ctrl && raw == Keysym::p {
Expand Down