Apply qt theme
This commit is contained in:
parent
4fb4542d69
commit
3712406972
2 changed files with 130 additions and 2 deletions
|
|
@ -17,6 +17,8 @@ pub enum OutputError {
|
||||||
Io(std::io::Error),
|
Io(std::io::Error),
|
||||||
#[error("Missing config directory")]
|
#[error("Missing config directory")]
|
||||||
MissingConfigDir,
|
MissingConfigDir,
|
||||||
|
#[error("Missing data directory")]
|
||||||
|
MissingDataDir,
|
||||||
#[error("Serde Error: {0}")]
|
#[error("Serde Error: {0}")]
|
||||||
Serde(#[from] serde_json::Error),
|
Serde(#[from] serde_json::Error),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ impl Theme {
|
||||||
#[cold]
|
#[cold]
|
||||||
/// Some high-level documentation for this file can be found at:
|
/// Some high-level documentation for this file can be found at:
|
||||||
/// https://web.archive.org/web/20250402234329/https://docs.kde.org/stable5/en/plasma-workspace/kcontrol/colors/
|
/// https://web.archive.org/web/20250402234329/https://docs.kde.org/stable5/en/plasma-workspace/kcontrol/colors/
|
||||||
pub fn as_qt_color_scheme(&self) -> String {
|
pub fn as_qt(&self) -> String {
|
||||||
let mut output = "# GENERATED BY COSMIC\n".to_string();
|
let mut output = "# GENERATED BY COSMIC\n".to_string();
|
||||||
|
|
||||||
// Usually, disabled elements will have strongly reduced contrast and are often notably darker or lighter
|
// Usually, disabled elements will have strongly reduced contrast and are often notably darker or lighter
|
||||||
|
|
@ -179,10 +179,136 @@ inactiveForeground=161,169,177
|
||||||
|
|
||||||
output
|
output
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Write the color scheme to the appropriate directory.
|
||||||
|
/// Should be written in `~/.local/share/color-schemes/`.
|
||||||
|
///
|
||||||
|
/// See the docs: https://develop.kde.org/docs/plasma/#color-scheme
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an `OutputError` if there is an error writing the colors file.
|
||||||
|
#[cold]
|
||||||
|
pub fn write_qt(&self) -> Result<(), OutputError> {
|
||||||
|
let colors = self.as_qt();
|
||||||
|
let Some(mut data_dir) = dirs::data_dir() else {
|
||||||
|
return Err(OutputError::MissingDataDir);
|
||||||
|
};
|
||||||
|
|
||||||
|
let file_name = if self.is_dark {
|
||||||
|
"CosmicDark.colors"
|
||||||
|
} else {
|
||||||
|
"CosmicLight.colors"
|
||||||
|
};
|
||||||
|
|
||||||
|
data_dir.push("color-schemes");
|
||||||
|
if !data_dir.exists() {
|
||||||
|
std::fs::create_dir_all(&data_dir).map_err(OutputError::Io)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut file = File::create(data_dir.join(file_name)).map_err(OutputError::Io)?;
|
||||||
|
file.write_all(colors.as_bytes()).map_err(OutputError::Io)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Apply the color scheme by copying it to `~/.config/kdeglobals`.
|
||||||
|
///
|
||||||
|
/// See the docs: https://develop.kde.org/docs/plasma/#color-scheme
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an `OutputError` if there is an error applying the color scheme.
|
||||||
|
#[cold]
|
||||||
|
pub fn apply_qt(is_dark: bool) -> Result<(), OutputError> {
|
||||||
|
let Some(config_dir) = dirs::config_dir() else {
|
||||||
|
return Err(OutputError::MissingConfigDir);
|
||||||
|
};
|
||||||
|
let Some(mut data_dir) = dirs::data_dir() else {
|
||||||
|
return Err(OutputError::MissingDataDir);
|
||||||
|
};
|
||||||
|
data_dir.push("color-schemes");
|
||||||
|
|
||||||
|
let src_file = data_dir.join(if is_dark {
|
||||||
|
"CosmicDark.colors"
|
||||||
|
} else {
|
||||||
|
"CosmicLight.colors"
|
||||||
|
});
|
||||||
|
|
||||||
|
let dest_file = config_dir.join("kdeglobals");
|
||||||
|
|
||||||
|
#[cfg(target_family = "unix")]
|
||||||
|
{
|
||||||
|
use std::os::unix::fs::symlink;
|
||||||
|
Self::backup_non_cosmic_kdeglobals(&dest_file).map_err(OutputError::Io)?;
|
||||||
|
|
||||||
|
if dest_file.exists() {
|
||||||
|
// Currently we overwrite the file with our symlink.
|
||||||
|
// Maybe in the future we could merge kdeglobals with our color scheme ini?
|
||||||
|
fs::remove_file(&dest_file).map_err(OutputError::Io)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
symlink(src_file, dest_file).map_err(OutputError::Io)?
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reset the applied qt colors by deleting the `~/.config/kdeglobals` file.
|
||||||
|
///
|
||||||
|
/// This does not restore the backed up kdeglobals file.
|
||||||
|
///
|
||||||
|
/// # Errors
|
||||||
|
///
|
||||||
|
/// Returns an `OutputError` if there is an error resetting the CSS file.
|
||||||
|
#[cold]
|
||||||
|
pub fn reset_qt() -> Result<(), OutputError> {
|
||||||
|
let Some(config_dir) = dirs::config_dir() else {
|
||||||
|
return Err(OutputError::MissingConfigDir);
|
||||||
|
};
|
||||||
|
let dest_file = config_dir.join("kdeglobals");
|
||||||
|
|
||||||
|
if Self::is_cosmic_kdeglobals(&dest_file).map_err(OutputError::Io)?.unwrap_or_default() {
|
||||||
|
fs::remove_file(dest_file).map_err(OutputError::Io)?
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
fn backup_non_cosmic_kdeglobals(path: &Path) -> io::Result<()> {
|
||||||
|
if !Self::is_cosmic_kdeglobals(path)?.unwrap_or(true) {
|
||||||
|
let backup_path = path.with_extension("bak");
|
||||||
|
fs::rename(path, &backup_path)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cold]
|
||||||
|
fn is_cosmic_kdeglobals(path: &Path) -> io::Result<Option<bool>> {
|
||||||
|
if !path.exists() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(metadata) = fs::symlink_metadata(path) {
|
||||||
|
if !metadata.file_type().is_symlink() {
|
||||||
|
return Ok(Some(false));
|
||||||
|
}
|
||||||
|
let Ok(target) = fs::read_link(path) else {
|
||||||
|
return Ok(Some(false));
|
||||||
|
};
|
||||||
|
let Some(target_filename) = target.file_name() else {
|
||||||
|
return Ok(Some(false));
|
||||||
|
};
|
||||||
|
return Ok(Some(
|
||||||
|
target_filename == "CosmicDark.colors" || target_filename == "CosmicLight.colors",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(Some(false))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Formats a color in the form `r,g,b` e.g. `255,255,255`
|
/// Formats a color in the form `r,g,b` e.g. `255,255,255`
|
||||||
pub fn to_rgb(c: Srgba) -> String {
|
fn to_rgb(c: Srgba) -> String {
|
||||||
let c_u8: Rgba<palette::encoding::Srgb, u8> = c.into_format();
|
let c_u8: Rgba<palette::encoding::Srgb, u8> = c.into_format();
|
||||||
format!("{},{},{}", c_u8.red, c_u8.green, c_u8.blue)
|
format!("{},{},{}", c_u8.red, c_u8.green, c_u8.blue)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue