mirror of
https://github.com/niri-wm/niri.git
synced 2026-06-22 02:01:55 +07:00
Make screenshot path configurable
This commit is contained in:
@@ -110,6 +110,13 @@ preset-column-widths {
|
|||||||
// Set gaps around windows in logical pixels.
|
// Set gaps around windows in logical pixels.
|
||||||
gaps 16
|
gaps 16
|
||||||
|
|
||||||
|
// You can change the path where screenshots are saved.
|
||||||
|
// A ~ at the front will be expanded to the home directory.
|
||||||
|
screenshot-path "~/Pictures/Screenshots"
|
||||||
|
|
||||||
|
// You can also set this to null to disable saving screenshots to disk.
|
||||||
|
// screenshot-path null
|
||||||
|
|
||||||
binds {
|
binds {
|
||||||
// Keys consist of modifiers separated by + signs, followed by an XKB key name
|
// Keys consist of modifiers separated by + signs, followed by an XKB key name
|
||||||
// in the end. To find an XKB name for a particular key, you may use a program
|
// in the end. To find an XKB name for a particular key, you may use a program
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ pub struct Config {
|
|||||||
pub preset_column_widths: Vec<PresetWidth>,
|
pub preset_column_widths: Vec<PresetWidth>,
|
||||||
#[knuffel(child, unwrap(argument), default = 16)]
|
#[knuffel(child, unwrap(argument), default = 16)]
|
||||||
pub gaps: u16,
|
pub gaps: u16,
|
||||||
|
#[knuffel(child, unwrap(argument), default = Some(PathBuf::from("~/Pictures/Screenshots")))]
|
||||||
|
pub screenshot_path: Option<PathBuf>,
|
||||||
#[knuffel(child, default)]
|
#[knuffel(child, default)]
|
||||||
pub binds: Binds,
|
pub binds: Binds,
|
||||||
#[knuffel(child, default)]
|
#[knuffel(child, default)]
|
||||||
@@ -539,6 +541,8 @@ mod tests {
|
|||||||
|
|
||||||
gaps 8
|
gaps 8
|
||||||
|
|
||||||
|
screenshot-path "~/Screenshots"
|
||||||
|
|
||||||
binds {
|
binds {
|
||||||
Mod+T { spawn "alacritty"; }
|
Mod+T { spawn "alacritty"; }
|
||||||
Mod+Q { close-window; }
|
Mod+Q { close-window; }
|
||||||
@@ -613,6 +617,7 @@ mod tests {
|
|||||||
PresetWidth::Fixed(1280),
|
PresetWidth::Fixed(1280),
|
||||||
],
|
],
|
||||||
gaps: 8,
|
gaps: 8,
|
||||||
|
screenshot_path: Some(PathBuf::from("~/Screenshots")),
|
||||||
binds: Binds(vec![
|
binds: Binds(vec![
|
||||||
Bind {
|
Bind {
|
||||||
key: Key {
|
key: Key {
|
||||||
|
|||||||
+26
-5
@@ -2009,8 +2009,13 @@ impl Niri {
|
|||||||
size: Size<i32, Physical>,
|
size: Size<i32, Physical>,
|
||||||
pixels: Vec<u8>,
|
pixels: Vec<u8>,
|
||||||
) -> anyhow::Result<()> {
|
) -> anyhow::Result<()> {
|
||||||
let path = make_screenshot_path().context("error making screenshot path")?;
|
let path = match make_screenshot_path(&self.config.borrow()) {
|
||||||
debug!("saving screenshot to {path:?}");
|
Ok(path) => path,
|
||||||
|
Err(err) => {
|
||||||
|
warn!("error making screenshot path: {err:?}");
|
||||||
|
None
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Prepare to set the encoded image as our clipboard selection. This must be done from the
|
// Prepare to set the encoded image as our clipboard selection. This must be done from the
|
||||||
// main thread.
|
// main thread.
|
||||||
@@ -2048,8 +2053,13 @@ impl Niri {
|
|||||||
let buf: Arc<[u8]> = Arc::from(buf.into_boxed_slice());
|
let buf: Arc<[u8]> = Arc::from(buf.into_boxed_slice());
|
||||||
let _ = tx.send(buf.clone());
|
let _ = tx.send(buf.clone());
|
||||||
|
|
||||||
if let Err(err) = std::fs::write(path, buf) {
|
if let Some(path) = path {
|
||||||
warn!("error saving screenshot image: {err:?}");
|
debug!("saving screenshot to {path:?}");
|
||||||
|
if let Err(err) = std::fs::write(path, buf) {
|
||||||
|
warn!("error saving screenshot image: {err:?}");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
debug!("not saving screenshot to disk");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2067,6 +2077,8 @@ impl Niri {
|
|||||||
|
|
||||||
use smithay::backend::renderer::element::utils::{Relocate, RelocateRenderElement};
|
use smithay::backend::renderer::element::utils::{Relocate, RelocateRenderElement};
|
||||||
|
|
||||||
|
use crate::utils::add_screenshot_filename;
|
||||||
|
|
||||||
let _span = tracy_client::span!("Niri::screenshot_all_outputs");
|
let _span = tracy_client::span!("Niri::screenshot_all_outputs");
|
||||||
|
|
||||||
let mut elements = vec![];
|
let mut elements = vec![];
|
||||||
@@ -2090,7 +2102,16 @@ impl Niri {
|
|||||||
// FIXME: scale.
|
// FIXME: scale.
|
||||||
let pixels = render_to_vec(renderer, size, Scale::from(1.), Fourcc::Abgr8888, &elements)?;
|
let pixels = render_to_vec(renderer, size, Scale::from(1.), Fourcc::Abgr8888, &elements)?;
|
||||||
|
|
||||||
let path = make_screenshot_path().context("error making screenshot path")?;
|
let path = make_screenshot_path(&self.config.borrow())
|
||||||
|
.and_then(|path| match path {
|
||||||
|
Some(path) => Ok(path),
|
||||||
|
None => {
|
||||||
|
let mut path = env::temp_dir();
|
||||||
|
add_screenshot_filename(&mut path)?;
|
||||||
|
Ok(path)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.context("error making screenshot path")?;
|
||||||
debug!("saving screenshot to {path:?}");
|
debug!("saving screenshot to {path:?}");
|
||||||
|
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
|
|||||||
+18
-9
@@ -12,6 +12,8 @@ use directories::UserDirs;
|
|||||||
use smithay::reexports::rustix::time::{clock_gettime, ClockId};
|
use smithay::reexports::rustix::time::{clock_gettime, ClockId};
|
||||||
use smithay::utils::{Logical, Point, Rectangle};
|
use smithay::utils::{Logical, Point, Rectangle};
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
|
|
||||||
pub fn get_monotonic_time() -> Duration {
|
pub fn get_monotonic_time() -> Duration {
|
||||||
let ts = clock_gettime(ClockId::Monotonic);
|
let ts = clock_gettime(ClockId::Monotonic);
|
||||||
Duration::new(ts.tv_sec as u64, ts.tv_nsec as u32)
|
Duration::new(ts.tv_sec as u64, ts.tv_nsec as u32)
|
||||||
@@ -21,15 +23,22 @@ pub fn center(rect: Rectangle<i32, Logical>) -> Point<i32, Logical> {
|
|||||||
rect.loc + rect.size.downscale(2).to_point()
|
rect.loc + rect.size.downscale(2).to_point()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_screenshot_path() -> anyhow::Result<PathBuf> {
|
pub fn make_screenshot_path(config: &Config) -> anyhow::Result<Option<PathBuf>> {
|
||||||
let dirs = UserDirs::new().context("error retrieving home directory")?;
|
let Some(mut path) = config.screenshot_path.clone() else {
|
||||||
let mut path = dirs.picture_dir().map(|p| p.to_owned()).unwrap_or_else(|| {
|
return Ok(None);
|
||||||
let mut dir = dirs.home_dir().to_owned();
|
};
|
||||||
dir.push("Pictures");
|
|
||||||
dir
|
|
||||||
});
|
|
||||||
path.push("Screenshots");
|
|
||||||
|
|
||||||
|
if let Ok(rest) = path.strip_prefix("~") {
|
||||||
|
let dirs = UserDirs::new().context("error retrieving home directory")?;
|
||||||
|
path = [dirs.home_dir(), rest].iter().collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
add_screenshot_filename(&mut path)?;
|
||||||
|
|
||||||
|
Ok(Some(path))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_screenshot_filename(path: &mut PathBuf) -> anyhow::Result<()> {
|
||||||
let mut buf = [0u8; 256];
|
let mut buf = [0u8; 256];
|
||||||
let name;
|
let name;
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -53,7 +62,7 @@ pub fn make_screenshot_path() -> anyhow::Result<PathBuf> {
|
|||||||
|
|
||||||
path.push(name);
|
path.push(name);
|
||||||
|
|
||||||
Ok(path)
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawns the command to run independently of the compositor.
|
/// Spawns the command to run independently of the compositor.
|
||||||
|
|||||||
Reference in New Issue
Block a user