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),
|
||||
#[error("Missing config directory")]
|
||||
MissingConfigDir,
|
||||
#[error("Missing data directory")]
|
||||
MissingDataDir,
|
||||
#[error("Serde Error: {0}")]
|
||||
Serde(#[from] serde_json::Error),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ impl Theme {
|
|||
#[cold]
|
||||
/// 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/
|
||||
pub fn as_qt_color_scheme(&self) -> String {
|
||||
pub fn as_qt(&self) -> 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
|
||||
|
|
@ -179,10 +179,136 @@ inactiveForeground=161,169,177
|
|||
|
||||
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`
|
||||
pub fn to_rgb(c: Srgba) -> String {
|
||||
fn to_rgb(c: Srgba) -> String {
|
||||
let c_u8: Rgba<palette::encoding::Srgb, u8> = c.into_format();
|
||||
format!("{},{},{}", c_u8.red, c_u8.green, c_u8.blue)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue