Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ clap.workspace = true
# configuration file
xdg = "^3.0"
toml = "0.9.11"
serde = "1.0"
serde.workspace = true
serde_derive = "1.0"
hex_color = {version = "3", features = ["serde"]}
chrono = "0.4.42"
Expand Down Expand Up @@ -76,3 +76,4 @@ license = "MPL-2.0"
[workspace.dependencies]
clap = { version = "4.5.54", features = ["derive"] }
satty_cli = { path = "cli" }
serde = { version = "1.0", features = ["derive"] }
20 changes: 17 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ Default single-key shortcuts:
[general]
# Start Satty in fullscreen mode
fullscreen = true
#fullscreen = false
# since NEXTRELEASE, this can be written like below. Current is just the current screen, all is all screens. This may depend on the compositor.
#fullscreen = "all"
#fullscreen = "current-screen"
# resize initially (NEXTRELEASE)
#resize = { mode="smart" }
resize = { mode = "size", width=2000, height=800 }
# try to have the window float (NEXTRELEASE). This may depend on the compositor.
floating-hack = true
# Exit directly after copy/save action. NEXTRELEASE: Does not apply to save as
early-exit = true
# Exit directly after save as (NEXTRELEASE)
Expand Down Expand Up @@ -149,6 +158,7 @@ zoom-factor = 1.1
text-move-length = 50.0
# experimental feature (NEXTRELEASE): Scale factor on the input image when it was taken (e.g. DPI scale on the monitor it was recorded from).
# This may be more useful to set via the command line.
# Note, this is ignored with explicit resize.
input-scale = 2.0

# Tool selection keyboard shortcuts (since 0.20.0)
Expand Down Expand Up @@ -221,8 +231,12 @@ Options:
Path to the config file. Otherwise will be read from XDG_CONFIG_DIR/satty/config.toml
-f, --filename <FILENAME>
Path to input image or '-' to read from stdin
--fullscreen
Start Satty in fullscreen mode
--fullscreen [<FULLSCREEN>]
Start Satty in fullscreen mode. Since NEXTRELEASE, takes optional parameter. --fullscreen without parameter is equivalent to --fullscreen current. Mileage may vary depending on compositor [possible values: all, current-screen]
--resize [<MODE|WIDTHxHEIGHT>]
Resize to coordinates or use smart mode (NEXTRELEASE). --resize without parameter is equivalent to --resize smart [possible values: smart, WxH.]
--floating-hack
Try to enforce floating (NEXTRELEASE). Mileage may vary depending on compositor
-o, --output-filename <OUTPUT_FILENAME>
Filename to use for saving action or '-' to print to stdout. Omit to disable saving to file. Might contain format specifiers: <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>. Since 0.20.0, can contain tilde (~) for home dir
--early-exit
Expand Down Expand Up @@ -272,7 +286,7 @@ Options:
--text-move-length <TEXT_MOVE_LENGTH>
Experimental feature (NEXTRELEASE): The length to move the text when using the arrow keys. defaults to 50.0
--input-scale <INPUT_SCALE>
Experimental feature (NEXTRELEASE): Scale the default window size to fit different displays
Experimental feature (NEXTRELEASE): Scale the default window size to fit different displays. Note that this is ignored with explicit resize
--right-click-copy
Right click to copy. Preferably use the `action_on_right_click` option instead
--action-on-enter <ACTION_ON_ENTER>
Expand Down
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ repository.workspace = true

[dependencies]
clap.workspace = true
serde.workspace = true
55 changes: 52 additions & 3 deletions cli/src/command_line.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use clap::{Parser, ValueEnum};
use serde::Deserialize;
use std::str::FromStr;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
Expand All @@ -11,9 +13,22 @@ pub struct CommandLine {
#[arg(short, long)]
pub filename: String,

/// Start Satty in fullscreen mode
/// Start Satty in fullscreen mode. Since NEXTRELEASE, takes optional parameter.
/// --fullscreen without parameter is equivalent to --fullscreen current.
/// Mileage may vary depending on compositor.
#[arg(long, num_args = 0..=1, default_missing_value = "current-screen", value_enum)]
pub fullscreen: Option<Fullscreen>,

/// Resize to coordinates or use smart mode (NEXTRELEASE).
/// --resize without parameter is equivalent to --resize smart
/// [possible values: smart, WxH.]
#[arg(long, num_args=0..=1, value_name="MODE|WIDTHxHEIGHT", default_missing_value = "smart", value_parser = Resize::from_str)]
pub resize: Option<Resize>,

/// Try to enforce floating (NEXTRELEASE).
/// Mileage may vary depending on compositor.
#[arg(long)]
pub fullscreen: bool,
pub floating_hack: bool,

/// Filename to use for saving action or '-' to print to stdout. Omit to disable saving to file. Might contain format
/// specifiers: <https://docs.rs/chrono/latest/chrono/format/strftime/index.html>.
Expand Down Expand Up @@ -124,7 +139,7 @@ pub struct CommandLine {
#[arg(long)]
pub text_move_length: Option<f32>,

/// Experimental feature (NEXTRELEASE): Scale the default window size to fit different displays.
/// Experimental feature (NEXTRELEASE): Scale the default window size to fit different displays. Note that this is ignored with explicit resize.
#[arg(long)]
pub input_scale: Option<f32>,

Expand All @@ -140,6 +155,40 @@ pub struct CommandLine {
// ---
}

#[derive(Debug, Deserialize, Clone, Copy, ValueEnum, PartialEq)]
#[value(rename_all = "kebab-case")]
#[serde(rename_all = "kebab-case")]
pub enum Fullscreen {
All,
CurrentScreen,
}

#[derive(Debug, Deserialize, Clone, Copy, PartialEq)]
#[serde(rename_all = "kebab-case", tag = "mode")]
pub enum Resize {
Size { width: i32, height: i32 },
Smart,
}

impl FromStr for Resize {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.trim().to_lowercase();
match s.as_str() {
"smart" => Ok(Resize::Smart),
_ => {
let (w, h) = s.split_once('x').ok_or("Expected size=WxH")?;
let w: i32 = w.parse().map_err(|_| "Invalid width".to_string())?;
let h: i32 = h.parse().map_err(|_| "Invalid height".to_string())?;
Ok(Resize::Size {
width: w,
height: h,
})
}
}
}
}

#[derive(Debug, Clone, Copy, Default, ValueEnum)]
pub enum Tools {
#[default]
Expand Down
67 changes: 58 additions & 9 deletions src/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use std::{
use clap::Parser;
use hex_color::HexColor;
use relm4::SharedState;
use serde_derive::Deserialize;

use serde::de::Deserializer;
use serde::Deserialize;
use thiserror::Error;
use xdg::{BaseDirectories, BaseDirectoriesError};

Expand All @@ -17,7 +19,7 @@ use crate::{
tools::{Highlighters, Tools},
};

use satty_cli::command_line::{Action as CommandLineAction, CommandLine};
use satty_cli::command_line::{Action as CommandLineAction, CommandLine, Fullscreen, Resize};

pub static APP_CONFIG: SharedState<Configuration> = SharedState::new();

Expand All @@ -36,7 +38,9 @@ enum ConfigurationFileError {
pub struct Configuration {
input_filename: String,
output_filename: Option<String>,
fullscreen: bool,
fullscreen: Option<Fullscreen>,
resize: Option<Resize>,
floating_hack: bool,
early_exit: bool,
early_exit_save_as: bool,
corner_roundness: f32,
Expand Down Expand Up @@ -192,6 +196,26 @@ impl ColorPalette {
}
}

// remain compatible with old config with fullscreen=true/false
#[derive(Deserialize)]
#[serde(untagged)]
#[serde(rename_all = "kebab-case")]
enum FullscreenCompat {
Bool(bool),
Mode(Fullscreen),
}

fn de_fullscreen_mode<'de, D>(d: D) -> Result<Option<Fullscreen>, D::Error>
where
D: Deserializer<'de>,
{
match FullscreenCompat::deserialize(d)? {
FullscreenCompat::Bool(true) => Ok(Some(Fullscreen::CurrentScreen)),
FullscreenCompat::Bool(false) => Ok(None),
FullscreenCompat::Mode(m) => Ok(Some(m)),
}
}

#[derive(Debug, Clone, Copy, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub enum Action {
Expand Down Expand Up @@ -245,7 +269,13 @@ impl Configuration {
}
fn merge_general(&mut self, general: ConfigurationFileGeneral) {
if let Some(v) = general.fullscreen {
self.fullscreen = v;
self.fullscreen = Some(v);
}
if let Some(v) = general.resize {
self.resize = Some(v);
}
if let Some(v) = general.floating_hack {
self.floating_hack = v;
}
if let Some(v) = general.early_exit {
self.early_exit = v;
Expand Down Expand Up @@ -350,8 +380,14 @@ impl Configuration {
}

// overwrite with all specified values from command line
if command_line.fullscreen {
self.fullscreen = command_line.fullscreen;
if let Some(v) = command_line.fullscreen {
self.fullscreen = Some(v);
}
if let Some(v) = command_line.resize {
self.resize = Some(v);
}
if command_line.floating_hack {
self.floating_hack = command_line.floating_hack;
}
if command_line.early_exit {
self.early_exit = command_line.early_exit;
Expand Down Expand Up @@ -464,10 +500,18 @@ impl Configuration {
self.copy_command.as_ref()
}

pub fn fullscreen(&self) -> bool {
pub fn fullscreen(&self) -> Option<Fullscreen> {
self.fullscreen
}

pub fn resize(&self) -> Option<Resize> {
self.resize
}

pub fn floating_hack(&self) -> bool {
self.floating_hack
}

pub fn output_filename(&self) -> Option<&String> {
self.output_filename.as_ref()
}
Expand Down Expand Up @@ -561,7 +605,9 @@ impl Default for Configuration {
Self {
input_filename: String::new(),
output_filename: None,
fullscreen: false,
fullscreen: None,
resize: None,
floating_hack: false,
early_exit: false,
early_exit_save_as: false,
corner_roundness: 12.0,
Expand Down Expand Up @@ -642,7 +688,10 @@ struct FontFile {
#[derive(Deserialize)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
struct ConfigurationFileGeneral {
fullscreen: Option<bool>,
#[serde(deserialize_with = "de_fullscreen_mode", default)]
fullscreen: Option<Fullscreen>,
resize: Option<Resize>,
floating_hack: Option<bool>,
early_exit: Option<bool>,
early_exit_save_as: Option<bool>,
corner_roundness: Option<f32>,
Expand Down
Loading