aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--niri-config/src/lib.rs16
-rw-r--r--niri-ipc/src/lib.rs10
-rw-r--r--src/input/mod.rs11
-rw-r--r--src/niri.rs13
-rw-r--r--src/ui/hotkey_overlay.rs25
-rw-r--r--src/ui/screenshot_ui.rs3
-rw-r--r--wiki/Configuration:-Key-Bindings.md23
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>