diff options
| author | Toby Bridle <foreignspaghettibolognese@gmail.com> | 2025-03-09 20:55:30 +0000 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2025-03-10 22:31:50 -0700 |
| commit | 47dd338340e2c8c17ce210579bcdcf8f320d755e (patch) | |
| tree | 2f0707130f1d9d3b5b2066189d69206c9238be5a | |
| parent | 87b6c1262544a463703a34d8404ef339b7d18536 (diff) | |
| download | niri-47dd338340e2c8c17ce210579bcdcf8f320d755e.tar.gz niri-47dd338340e2c8c17ce210579bcdcf8f320d755e.tar.bz2 niri-47dd338340e2c8c17ce210579bcdcf8f320d755e.zip | |
feat: 🎉 add `show-pointer` for `Screenshot` and `ScreenshotScreen`
| -rw-r--r-- | niri-config/src/lib.rs | 16 | ||||
| -rw-r--r-- | niri-ipc/src/lib.rs | 10 | ||||
| -rw-r--r-- | src/input/mod.rs | 11 | ||||
| -rw-r--r-- | src/niri.rs | 13 | ||||
| -rw-r--r-- | src/ui/hotkey_overlay.rs | 25 | ||||
| -rw-r--r-- | src/ui/screenshot_ui.rs | 3 | ||||
| -rw-r--r-- | wiki/Configuration:-Key-Bindings.md | 23 |
7 files changed, 72 insertions, 29 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 75fc48d1..b95d70cf 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -1454,8 +1454,11 @@ pub enum Action { CancelScreenshot, #[knuffel(skip)] ScreenshotTogglePointer, - Screenshot, - ScreenshotScreen(#[knuffel(property(name = "write-to-disk"), default = true)] bool), + Screenshot(#[knuffel(property(name = "show-pointer"), default = true)] bool), + ScreenshotScreen( + #[knuffel(property(name = "write-to-disk"), default = true)] bool, + #[knuffel(property(name = "show-pointer"), default = true)] bool, + ), ScreenshotWindow(#[knuffel(property(name = "write-to-disk"), default = true)] bool), #[knuffel(skip)] ScreenshotWindowById { @@ -1641,10 +1644,11 @@ impl From<niri_ipc::Action> for Action { niri_ipc::Action::PowerOnMonitors {} => Self::PowerOnMonitors, 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 { write_to_disk } => { - Self::ScreenshotScreen(write_to_disk) - } + niri_ipc::Action::Screenshot { show_pointer } => Self::Screenshot(show_pointer), + niri_ipc::Action::ScreenshotScreen { + write_to_disk, + show_pointer, + } => Self::ScreenshotScreen(write_to_disk, show_pointer), niri_ipc::Action::ScreenshotWindow { id: None, write_to_disk, diff --git a/niri-ipc/src/lib.rs b/niri-ipc/src/lib.rs index 15861293..5d4bee78 100644 --- a/niri-ipc/src/lib.rs +++ b/niri-ipc/src/lib.rs @@ -169,7 +169,11 @@ pub enum Action { delay_ms: Option<u16>, }, /// Open the screenshot UI. - Screenshot {}, + Screenshot { + /// Whether to show the mouse pointer by default in the screenshot UI. + #[cfg_attr(feature = "clap", arg(short = 'p', long, action = clap::ArgAction::Set, default_value_t = true))] + show_pointer: bool, + }, /// Screenshot the focused screen. ScreenshotScreen { /// Write the screenshot to disk in addition to putting it in your clipboard. @@ -177,6 +181,10 @@ pub enum Action { /// 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, + + /// Whether to include the mouse pointer in the screenshot. + #[cfg_attr(feature = "clap", arg(short = 'p', long, action = clap::ArgAction::Set, default_value_t = true))] + show_pointer: bool, }, /// Screenshot a window. #[cfg_attr(feature = "clap", clap(about = "Screenshot the focused window"))] diff --git a/src/input/mod.rs b/src/input/mod.rs index 3930ccf0..55d06c7e 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -565,11 +565,14 @@ impl State { self.niri.do_screen_transition(renderer, delay_ms); }); } - Action::ScreenshotScreen(write_to_disk) => { + Action::ScreenshotScreen(write_to_disk, show_pointer) => { 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, write_to_disk) { + if let Err(err) = + self.niri + .screenshot(renderer, &active, write_to_disk, show_pointer) + { warn!("error taking screenshot: {err:?}"); } }); @@ -615,8 +618,8 @@ impl State { self.niri.screenshot_ui.toggle_pointer(); self.niri.queue_redraw_all(); } - Action::Screenshot => { - self.open_screenshot_ui(); + Action::Screenshot(show_cursor) => { + self.open_screenshot_ui(show_cursor); } Action::ScreenshotWindow(write_to_disk) => { let focus = self.niri.layout.focus_with_output(); diff --git a/src/niri.rs b/src/niri.rs index 08830090..6ce11e59 100644 --- a/src/niri.rs +++ b/src/niri.rs @@ -1538,7 +1538,7 @@ impl State { self.niri.output_management_state.notify_changes(new_config); } - pub fn open_screenshot_ui(&mut self) { + pub fn open_screenshot_ui(&mut self, show_pointer: bool) { if self.niri.is_locked() || self.niri.screenshot_ui.is_open() { return; } @@ -1570,7 +1570,7 @@ impl State { self.backend.with_primary_renderer(|renderer| { self.niri .screenshot_ui - .open(renderer, screenshots, default_output) + .open(renderer, screenshots, default_output, show_pointer) }); self.niri @@ -4701,6 +4701,7 @@ impl Niri { renderer: &mut GlesRenderer, output: &Output, write_to_disk: bool, + include_pointer: bool, ) -> anyhow::Result<()> { let _span = tracy_client::span!("Niri::screenshot"); @@ -4711,8 +4712,12 @@ impl Niri { let size = transform.transform_size(size); let scale = Scale::from(output.current_scale().fractional_scale()); - let elements = - self.render::<GlesRenderer>(renderer, output, true, RenderTarget::ScreenCapture); + let elements = self.render::<GlesRenderer>( + renderer, + output, + include_pointer, + RenderTarget::ScreenCapture, + ); let elements = elements.iter().rev(); let pixels = render_to_vec( renderer, diff --git a/src/ui/hotkey_overlay.rs b/src/ui/hotkey_overlay.rs index c8165ede..29e96e2a 100644 --- a/src/ui/hotkey_overlay.rs +++ b/src/ui/hotkey_overlay.rs @@ -254,8 +254,11 @@ fn render( ]); // Screenshot is not as important, can omit if not bound. - if binds.iter().any(|bind| bind.action == Action::Screenshot) { - actions.push(&Action::Screenshot); + if let Some(bind) = binds + .iter() + .find(|bind| matches!(bind.action, Action::Screenshot(_))) + { + actions.push(&bind.action); } // Add actions with a custom hotkey-overlay-title. @@ -436,7 +439,7 @@ fn action_name(action: &Action) -> String { Action::SwitchFocusBetweenFloatingAndTiling => { String::from("Switch Focus Between Floating and Tiling") } - Action::Screenshot => String::from("Take a Screenshot"), + Action::Screenshot(_) => String::from("Take a Screenshot"), Action::Spawn(args) => format!( "Spawn <span face='monospace' bgcolor='#000000'>{}</span>", args.first().unwrap_or(&String::new()) @@ -545,7 +548,7 @@ mod tests { #[test] fn test_format_bind() { // Not bound. - assert_snapshot!(check("", Action::Screenshot), @" (not bound) : Take a Screenshot"); + assert_snapshot!(check("", Action::Screenshot(true)), @" (not bound) : Take a Screenshot"); // Bound with a default title. assert_snapshot!( @@ -553,7 +556,7 @@ mod tests { r#"binds { Mod+P { screenshot; } }"#, - Action::Screenshot, + Action::Screenshot(true), ), @" Super + P : Take a Screenshot" ); @@ -564,7 +567,7 @@ mod tests { r#"binds { Mod+P hotkey-overlay-title="Hello" { screenshot; } }"#, - Action::Screenshot, + Action::Screenshot(true), ), @" Super + P : Hello" ); @@ -576,7 +579,7 @@ mod tests { Mod+P { screenshot; } Print { screenshot; } }"#, - Action::Screenshot, + Action::Screenshot(true), ), @" Super + P : Take a Screenshot" ); @@ -588,7 +591,7 @@ mod tests { Mod+P { screenshot; } Print hotkey-overlay-title="My Cool Bind" { screenshot; } }"#, - Action::Screenshot, + Action::Screenshot(true), ), @" PrtSc : My Cool Bind" ); @@ -600,7 +603,7 @@ mod tests { Mod+P hotkey-overlay-title="First" { screenshot; } Print hotkey-overlay-title="My Cool Bind" { screenshot; } }"#, - Action::Screenshot, + Action::Screenshot(true), ), @" Super + P : First" ); @@ -612,7 +615,7 @@ mod tests { Mod+P { screenshot; } Print hotkey-overlay-title=null { screenshot; } }"#, - Action::Screenshot, + Action::Screenshot(true), ), @"None" ); @@ -624,7 +627,7 @@ mod tests { Mod+P hotkey-overlay-title="Hello" { screenshot; } Print hotkey-overlay-title=null { screenshot; } }"#, - Action::Screenshot, + Action::Screenshot(true), ), @" Super + P : Hello" ); diff --git a/src/ui/screenshot_ui.rs b/src/ui/screenshot_ui.rs index aa6c38b8..14675f7b 100644 --- a/src/ui/screenshot_ui.rs +++ b/src/ui/screenshot_ui.rs @@ -101,6 +101,7 @@ impl ScreenshotUi { // Output, screencast, screen capture. screenshots: HashMap<Output, [OutputScreenshot; 3]>, default_output: Output, + show_pointer: bool, ) -> bool { if screenshots.is_empty() { return false; @@ -191,7 +192,7 @@ impl ScreenshotUi { selection, output_data, mouse_down: false, - show_pointer: true, + show_pointer, open_anim, clock: clock.clone(), config: config.clone(), diff --git a/wiki/Configuration:-Key-Bindings.md b/wiki/Configuration:-Key-Bindings.md index 24efa839..640f6fd4 100644 --- a/wiki/Configuration:-Key-Bindings.md +++ b/wiki/Configuration:-Key-Bindings.md @@ -306,9 +306,13 @@ binds { } ``` -#### `screenshot-screen`, `screenshot-window` +#### `screenshot`, `screenshot-screen`, `screenshot-window` + +Actions for taking screenshots. + +- `screenshot`: opens the built-in interactive screenshot UI. +- `screenshot-screen`, `screenshow-window`: takes a screenshot of the focused screen or window respectively. -Take a screenshot of the focused screen or window respectively. The screenshot is both stored to the clipboard and saved to disk, according to the [`screenshot-path` option](./Configuration:-Miscellaneous.md). <sup>Since: 25.02</sup> You can disable saving to disk for a specific bind with the `write-to-disk=false` property: @@ -320,6 +324,21 @@ binds { } ``` +In the interactive screenshot UI, pressing <kbd>Ctrl</kbd><kbd>C</kbd> will copy the screenshot to the clipboard without writing it to disk. + +<sup>Since: next release</sup> You can hide the mouse pointer in screenshots with the `show-pointer=false` property: + +```kdl +binds { + // The pointer will be hidden by default + // (you can still show it by pressing P). + Print { screenshot show-pointer=false; } + + // The pointer will be hidden on the screenshot. + Ctrl+Print { screenshot-screen show-pointer=false; } +} +``` + #### `toggle-keyboard-shortcuts-inhibit` <sup>Since: 25.02</sup> |
