fix: shutter sound before the window shadow; faster vertical blur

This commit is contained in:
elwrcl committed 2026-10-03 02:50:13 +03:00
1 parent 7a2e7645bf
commit 2531866d22
2 files changed
+35 -15

No files matched your search

+15 -5
View File
@@ -221,7 +221,9 @@ fn capture(mode: Mode, common: Common) -> Result<()> {
// Thumbnails from earlier captures must not end up in this one. // Thumbnails from earlier captures must not end up in this one.
let mut hide = ipc::HideGuard::new(&ipc::socket_path()); let mut hide = ipc::HideGuard::new(&ipc::socket_path());
let (shots, clip, source): Shots = match mode { // Window shots get their (slow) shadow after the shutter sound.
let mut windowed = false;
let (mut shots, clip, source): Shots = match mode {
Mode::Screen { all } => { Mode::Screen { all } => {
let focused = focused_output(&outputs); let focused = focused_output(&outputs);
let source = outputs[focused].geom.name.clone(); let source = outputs[focused].geom.name.clone();
@@ -246,11 +248,15 @@ fn capture(mode: Mode, common: Common) -> Result<()> {
} }
region::Choice::Window => { region::Choice::Window => {
drop(frames); drop(frames);
window_shot(&outputs, cursor, config.capture.window_shadow)? windowed = true;
window_shot(&outputs, cursor)?
} }
} }
} }
Mode::Window => window_shot(&outputs, cursor, config.capture.window_shadow)?, Mode::Window => {
windowed = true;
window_shot(&outputs, cursor)?
}
Mode::Zoom => { Mode::Zoom => {
let focused = focused_output(&outputs); let focused = focused_output(&outputs);
let frame = wl.capture(&outputs[focused..=focused], cursor)?.remove(0); let frame = wl.capture(&outputs[focused..=focused], cursor)?.remove(0);
@@ -267,6 +273,11 @@ fn capture(mode: Mode, common: Common) -> Result<()> {
} }
}; };
sound::play(&config.sound, sound); sound::play(&config.sound, sound);
if windowed && config.capture.window_shadow {
for (image, _) in &mut shots {
*image = shadow::add(image);
}
}
drop(wl); drop(wl);
let target = Target::from_args(common.output, common.clipboard_only); let target = Target::from_args(common.output, common.clipboard_only);
@@ -293,9 +304,8 @@ fn capture(mode: Mode, common: Common) -> Result<()> {
/// A window shot, shaped like the other modes' results. The preview goes to /// A window shot, shaped like the other modes' results. The preview goes to
/// the window's output, or niri's focused one if that is unknown. /// the window's output, or niri's focused one if that is unknown.
fn window_shot(outputs: &[wayland::Output], cursor: bool, shadow: bool) -> Result<Shots> { fn window_shot(outputs: &[wayland::Output], cursor: bool) -> Result<Shots> {
let (image, output) = window::capture(cursor)?; let (image, output) = window::capture(cursor)?;
let image = if shadow { shadow::add(&image) } else { image };
let source = output.unwrap_or_else(|| outputs[focused_output(outputs)].geom.name.clone()); let source = output.unwrap_or_else(|| outputs[focused_output(outputs)].geom.name.clone());
Ok((vec![(image, None)], 0, source)) Ok((vec![(image, None)], 0, source))
} }
+20 -10
View File
@@ -19,7 +19,7 @@ pub fn add(image: &RgbaImage) -> RgbaImage {
alpha[(sy * cw + sx) as usize] = p.0[3] as f32 / 255.0; alpha[(sy * cw + sx) as usize] = p.0[3] as f32 / 255.0;
} }
} }
// Three box blurs approximate a Gaussian of about BLUR / 2 sigma. // Three box blurs approximate a Gaussian (visible extent about BLUR px).
let r = (BLUR / 3).max(1) as usize; let r = (BLUR / 3).max(1) as usize;
for _ in 0..3 { for _ in 0..3 {
alpha = box_blur(&alpha, cw as usize, ch as usize, r); alpha = box_blur(&alpha, cw as usize, ch as usize, r);
@@ -69,17 +69,27 @@ fn box_blur(src: &[f32], w: usize, h: usize, r: usize) -> Vec<f32> {
} }
} }
} }
// Vertically with a running sum per column, walking rows so memory is
// read in order.
let mut out = vec![0f32; src.len()]; let mut out = vec![0f32; src.len()];
for x in 0..w { let mut sums = vec![0f32; w];
let at = |y: usize| tmp[y * w + x]; for y in 0..=r.min(h - 1) {
let mut sum: f32 = (0..=r.min(h - 1)).map(at).sum(); for (sum, v) in sums.iter_mut().zip(&tmp[y * w..(y + 1) * w]) {
for y in 0..h { *sum += v;
out[y * w + x] = sum / n; }
if y + r + 1 < h { }
sum += at(y + r + 1); for y in 0..h {
for (o, sum) in out[y * w..(y + 1) * w].iter_mut().zip(&sums) {
*o = sum / n;
}
if y + r + 1 < h {
for (sum, v) in sums.iter_mut().zip(&tmp[(y + r + 1) * w..(y + r + 2) * w]) {
*sum += v;
} }
if y >= r { }
sum -= at(y - r); if y >= r {
for (sum, v) in sums.iter_mut().zip(&tmp[(y - r) * w..(y - r + 1) * w]) {
*sum -= v;
} }
} }
} }