Vanilla CSS support (#467)

Co-authored-by: ElKowar <5300871+elkowar@users.noreply.github.com>
This commit is contained in:
Ezequiel Ramis 2023-02-25 06:35:35 -03:00 committed by GitHub
parent 59e8e02f15
commit 6b576c02ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 31 additions and 21 deletions

View file

@ -10,6 +10,7 @@ All notable changes to eww will be listed here, starting at changes since versio
- Allow floating-point numbers in percentages for window-geometry - Allow floating-point numbers in percentages for window-geometry
- Add support for safe access with index (`?.[n]`) (By: ModProg) - Add support for safe access with index (`?.[n]`) (By: ModProg)
- Made `and`, `or` and `?:` lazily evaluated in simplexpr (By: ModProg) - Made `and`, `or` and `?:` lazily evaluated in simplexpr (By: ModProg)
- Add Vanilla CSS support (By: Ezequiel Ramis)
## [0.4.0] (04.09.2022) ## [0.4.0] (04.09.2022)

View file

@ -149,7 +149,7 @@ impl App {
if let Err(e) = config_result.and_then(|new_config| self.load_config(new_config)) { if let Err(e) = config_result.and_then(|new_config| self.load_config(new_config)) {
errors.push(e) errors.push(e)
} }
match crate::config::scss::parse_scss_from_file(&self.paths.get_eww_scss_path()) { match crate::config::scss::parse_scss_from_config(&self.paths.get_config_dir()) {
Ok((file_id, css)) => { Ok((file_id, css)) => {
if let Err(e) = self.load_css(file_id, &css) { if let Err(e) = self.load_css(file_id, &css) {
errors.push(anyhow!(e)); errors.push(anyhow!(e));

View file

@ -4,18 +4,31 @@ use anyhow::{anyhow, Context};
use crate::{error_handling_ctx, util::replace_env_var_references}; use crate::{error_handling_ctx, util::replace_env_var_references};
/// read an scss file, replace all environment variable references within it and /// read an (s)css file, replace all environment variable references within it and
/// then parse it into css. /// then parse it into css.
/// Also adds the CSS to the [`crate::file_database::FileDatabase`] /// Also adds the CSS to the [`crate::file_database::FileDatabase`]
pub fn parse_scss_from_file(path: &Path) -> anyhow::Result<(usize, String)> { pub fn parse_scss_from_config(path: &Path) -> anyhow::Result<(usize, String)> {
let config_dir = path.parent().context("Given SCSS file has no parent directory?!")?; let css_file = path.join("eww.css");
let scss_file = path.join("eww.scss");
if css_file.exists() && scss_file.exists() {
return Err(anyhow!("Encountered both an SCSS and CSS file. Only one of these may exist at a time"));
}
let (s_css_path, css) = if css_file.exists() {
let css_file_content = std::fs::read_to_string(&css_file)
.with_context(|| format!("Given CSS file doesn't exist: {}", css_file.display()))?;
let css = replace_env_var_references(css_file_content);
(css_file, css)
} else {
let scss_file_content = let scss_file_content =
std::fs::read_to_string(path).with_context(|| format!("Given SCSS-file doesn't exist! {}", path.display()))?; std::fs::read_to_string(&scss_file).with_context(|| format!("Given SCSS file doesn't exist! {}", path.display()))?;
let file_content = replace_env_var_references(scss_file_content); let file_content = replace_env_var_references(scss_file_content);
let grass_config = grass::Options::default().load_path(config_dir); let grass_config = grass::Options::default().load_path(path);
let css = grass::from_string(file_content, &grass_config).map_err(|err| anyhow!("SCSS parsing error: {}", err))?; let css = grass::from_string(file_content, &grass_config).map_err(|err| anyhow!("SCSS parsing error: {}", err))?;
(scss_file, css)
};
let mut file_db = error_handling_ctx::FILE_DATABASE.write().unwrap(); let mut file_db = error_handling_ctx::FILE_DATABASE.write().unwrap();
let file_id = file_db.insert_string(path.display().to_string(), css.clone())?; let file_id = file_db.insert_string(s_css_path.display().to_string(), css.clone())?;
Ok((file_id, css)) Ok((file_id, css))
} }

View file

@ -32,7 +32,7 @@ struct RawOpt {
#[arg(long = "debug", global = true)] #[arg(long = "debug", global = true)]
log_debug: bool, log_debug: bool,
/// override path to configuration directory (directory that contains eww.yuck and eww.scss) /// override path to configuration directory (directory that contains eww.yuck and eww.(s)css)
#[arg(short, long, global = true)] #[arg(short, long, global = true)]
config: Option<std::path::PathBuf>, config: Option<std::path::PathBuf>,

View file

@ -77,10 +77,6 @@ impl EwwPaths {
pub fn get_yuck_path(&self) -> PathBuf { pub fn get_yuck_path(&self) -> PathBuf {
self.config_dir.join("eww.yuck") self.config_dir.join("eww.yuck")
} }
pub fn get_eww_scss_path(&self) -> PathBuf {
self.config_dir.join("eww.scss")
}
} }
impl std::fmt::Display for EwwPaths { impl std::fmt::Display for EwwPaths {

View file

@ -83,7 +83,7 @@ pub fn initialize_server(paths: EwwPaths, action: Option<DaemonCommand>, should_
gtk::StyleContext::add_provider_for_screen(&screen, &app.css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION); gtk::StyleContext::add_provider_for_screen(&screen, &app.css_provider, gtk::STYLE_PROVIDER_PRIORITY_APPLICATION);
} }
if let Ok((file_id, css)) = config::scss::parse_scss_from_file(&app.paths.get_eww_scss_path()) { if let Ok((file_id, css)) = config::scss::parse_scss_from_config(&app.paths.get_config_dir()) {
if let Err(e) = app.load_css(file_id, &css) { if let Err(e) = app.load_css(file_id, &css) {
error_handling_ctx::print_error(e); error_handling_ctx::print_error(e);
} }
@ -169,7 +169,7 @@ async fn run_filewatch<P: AsRef<Path>>(config_dir: P, evt_send: UnboundedSender<
Ok(notify::Event { kind: notify::EventKind::Modify(_), paths, .. }) => { Ok(notify::Event { kind: notify::EventKind::Modify(_), paths, .. }) => {
let relevant_files_changed = paths.iter().any(|path| { let relevant_files_changed = paths.iter().any(|path| {
let ext = path.extension().unwrap_or_default(); let ext = path.extension().unwrap_or_default();
ext == "yuck" || ext == "scss" ext == "yuck" || ext == "scss" || ext == "css"
}); });
if relevant_files_changed { if relevant_files_changed {
if let Err(err) = tx.send(()) { if let Err(err) = tx.send(()) {

View file

@ -10,13 +10,13 @@ If you're using VSCode, you can get syntax highlighting and formatting from [yuc
It is also recommended to use [parinfer](https://shaunlebron.github.io/parinfer/), It is also recommended to use [parinfer](https://shaunlebron.github.io/parinfer/),
which makes working with S-expressions delightfully easy! which makes working with S-expressions delightfully easy!
Additionally, any styles are defined in SCSS (which is mostly just slightly improved CSS syntax). Additionally, any styles are defined in CSS or SCSS (which is mostly just slightly improved CSS syntax).
While eww supports a significant portion of the CSS you know from the web, While eww supports a significant portion of the CSS you know from the web,
not everything is supported, as eww relies on GTK's own CSS engine. not everything is supported, as eww relies on GTK's own CSS engine.
Notably, some animation features are unsupported, Notably, some animation features are unsupported,
as well as most layout-related CSS properties such as flexbox, `float`, absolute position or `width`/`height`. as well as most layout-related CSS properties such as flexbox, `float`, absolute position or `width`/`height`.
To get started, you'll need to create two files: `eww.yuck` and `eww.scss`. To get started, you'll need to create two files: `eww.yuck` and `eww.scss` (or `eww.css`, if you prefer).
These files must be placed under `$XDG_CONFIG_HOME/eww` (this is most likely `~/.config/eww`). These files must be placed under `$XDG_CONFIG_HOME/eww` (this is most likely `~/.config/eww`).
Now that those files are created, you can start writing your first widget! Now that those files are created, you can start writing your first widget!

View file

@ -14,7 +14,7 @@ Here you will find help if something doesn't work. If the issue isn't listed her
## My configuration is not loaded correctly ## My configuration is not loaded correctly
1. Make sure the `eww.yuck` and `eww.scss` files are in the correct places. 1. Make sure the `eww.yuck` and `eww.(s)css` files are in the correct places.
2. Sometimes, eww might fail to load your configuration as a result of a configuration error. Make sure your configuration is valid. 2. Sometimes, eww might fail to load your configuration as a result of a configuration error. Make sure your configuration is valid.
## Something isn't styled correctly! ## Something isn't styled correctly!

View file

@ -3,7 +3,7 @@
## Gtk-theming ## Gtk-theming
Eww is styled in GTK CSS. Eww is styled in GTK CSS.
To make theming even easier, it makes use of `SCSS` and then compiles that into CSS for you. You can use `Vanilla CSS` or `SCSS` to make theming even easier. The latter is compiled into CSS for you.
If you don't know any way to style something check out the [GTK CSS Overview wiki](https://docs.gtk.org/gtk3/css-overview.html), If you don't know any way to style something check out the [GTK CSS Overview wiki](https://docs.gtk.org/gtk3/css-overview.html),
the [GTK CSS Properties Overview wiki ](https://docs.gtk.org/gtk3/css-properties.html), the [GTK CSS Properties Overview wiki ](https://docs.gtk.org/gtk3/css-properties.html),
or use the [GTK-Debugger](#gtk-debugger). or use the [GTK-Debugger](#gtk-debugger).