fix: shutter sound before the window shadow; faster vertical blur
This commit is contained in:
1 parent
7a2e7645bf
commit
2531866d22
2 files changed
+35
-15
No files matched your search
+15
-5
@@ -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
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user