Compare commits

..

17 Commits

Author SHA1 Message Date
imgurbot12
5fb9aa6863 feat: rustfmt, moved cache to xdg-cache dir 2024-04-02 10:45:51 -07:00
Andrew Scott
64fdbaafc4
Merge pull request #6 from LordGrimmauld/fix_xdg_css
allow searching css independent of config path
2024-04-02 10:35:08 -07:00
018a98d7bc fix missing shell expand 2024-04-02 17:19:42 +02:00
2c71f4ad2b allow searching css independent of config path 2024-04-02 12:26:25 +02:00
imgurbot12
aed276b104 fix: powermenu css updates to fix default css changes 2024-03-31 20:35:14 -07:00
imgurbot12
ecacad55bc chore: upgrade patch version with css update 2024-03-31 13:30:22 -07:00
imgurbot12
9e736ccd07 fix: css boundaries for results updated 2024-03-31 13:21:19 -07:00
imgurbot12
7e2302eb64 chore: license fix 2024-03-29 13:45:48 -07:00
imgurbot12
a18fa25ada chore: license 2024-03-29 12:05:59 -07:00
imgurbot12
ce84787c59 feat: nix support thanks to @LordGrimmauld 2024-03-29 11:53:41 -07:00
Andrew Scott
9236afb93a
Merge pull request #5 from LordGrimmauld/feat/v1.1.0
Add nix tooling and fix XDG path search
2024-03-29 11:47:12 -07:00
179418dece update nix tooling 2024-03-29 14:55:47 +01:00
b6ce0ccb52 fix broken xdg path search 2024-03-29 14:50:42 +01:00
81f612ecbf add basic flake.nix 2024-03-29 10:35:40 +01:00
686328eb71 readd Cargo.lock, ignore nix build result 2024-03-29 10:23:06 +01:00
imgurbot12
188f542ffb feat: support more dynamic configuration via env & xdg 2024-03-28 18:21:41 -07:00
imgurbot12
aa1b2f6db9 fix: remove debug line 2024-03-28 18:08:33 -07:00
17 changed files with 571 additions and 270 deletions

4
.gitignore vendored
View File

@ -1,2 +1,4 @@
target target
Cargo.lock # Cargo.lock
result
.idea

350
Cargo.lock generated

File diff suppressed because it is too large Load Diff

22
LICENSE Normal file
View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2024 Andrew Scott
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,5 +1,4 @@
RMenu ## RMenu
------
<!-- <!--
TODO: improve documentation: TODO: improve documentation:
@ -11,14 +10,25 @@ Another customizable Application-Launcher written in Rust
### Features ### Features
* Blazingly Fast 🔥 - Blazingly Fast 🔥
* Simple and Easy to Use - Simple and Easy to Use
* Customizable (Configuration and CSS-Styling) - Customizable (Configuration and CSS-Styling)
* Plugin Support - Plugin Support
* Dmenu-Like Stdin Menu Generation - Dmenu-Like Stdin Menu Generation
### Installation ### Installation
RMenu now has Nix support thanks to
[@LordGrimmauld](https://github.com/LordGrimmauld)!
Install Dependencies (Ubuntu)
```bash
sudo apt install pkg-config libglib2.0-dev libghc-gi-gdk-dev libsoup-3.0-dev libjavascriptcoregtk-4.1-dev libwebkit2gtk-4.1-dev libnm-dev
```
Compile and Install Binaries/Config-Files
```bash ```bash
$ make install $ make install
``` ```
@ -33,13 +43,13 @@ $ rmenu --help
RMenu Comes with a few default plugins. RMenu Comes with a few default plugins.
| Name | Description | | Name | Description |
| :-------: | ------------------------------------------------------- | | :-------: | ------------------------------------------------------- |
| run | Execute a program in $PATH | | run | Execute a program in $PATH |
| drun | Run a Configured Free-Desktop Application | | drun | Run a Configured Free-Desktop Application |
| audio | Select and Set-Default PulseAudio Sink using `pactl` | | audio | Select and Set-Default PulseAudio Sink using `pactl` |
| network | Wi-Fi Login/Connection Tool using Network-Manager | | network | Wi-Fi Login/Connection Tool using Network-Manager |
| window | Simple Window Switcher (Currently Only Support Sway) | | window | Simple Window Switcher (Currently Only Support Sway) |
| powermenu | Simple Power/Logout Tool (Currently Only Supports Sway) | | powermenu | Simple Power/Logout Tool (Currently Only Supports Sway) |
Run a plugin by passing the `-r` flag like one of the following: Run a plugin by passing the `-r` flag like one of the following:
@ -56,16 +66,16 @@ Or even run plugins in combination if you'd like:
$ rmenu -r run -r drun $ rmenu -r run -r drun
``` ```
Custom Menus can also be passed much like Dmenu by passing items via Custom Menus can also be passed much like Dmenu by passing items via an input.
an input. The schema follows a standard as defined in [rmenu-plugin](./rmenu-plugin) The schema follows a standard as defined in [rmenu-plugin](./rmenu-plugin)
```bash ```bash
$ generate-my-menu.sh > input.json $ generate-my-menu.sh > input.json
$ rmenu -i input.json $ rmenu -i input.json
``` ```
When neither a plugin nor an input are specified, rmenu defaults to When neither a plugin nor an input are specified, rmenu defaults to reading from
reading from stdin. stdin.
```bash ```bash
$ generate-my-menu.sh | rmenu $ generate-my-menu.sh | rmenu
@ -73,20 +83,23 @@ $ generate-my-menu.sh | rmenu
### Configuration ### Configuration
Customize RMenu Behavior and Appearal in a [single config](./rmenu/public/config.yaml) Customize RMenu Behavior and Appearal in a
[single config](./rmenu/public/config.yaml)
Customize the entire app's appearance with CSS. A few [Example Themes](./themes/) Customize the entire app's appearance with CSS. A few
are available as reference. To try them out use: `rmenu --css <my-css-theme>` [Example Themes](./themes/) are available as reference. To try them out use:
or move the css file to `$HOME/.config/rmenu/style.css` `rmenu --css <my-css-theme>` or move the css file to
`$HOME/.config/rmenu/style.css`
### Scripting ### Scripting
RMenu plugins and imports communicate using JSON messages defined in `rmenu-plugin`. RMenu plugins and imports communicate using JSON messages defined in
Writing JSON in shell is painful, so rmenu provides another cli-tool to help build `rmenu-plugin`. Writing JSON in shell is painful, so rmenu provides another
messages quickly and easily while still retaining the flexibility of JSON. cli-tool to help build messages quickly and easily while still retaining the
flexibility of JSON.
After Installing. Use the following command, and look at [other-plugins](./other-plugins) After Installing. Use the following command, and look at
for example uses. [other-plugins](./other-plugins) for example uses.
``` ```
$ rmenu-build --help $ rmenu-build --help
@ -95,16 +108,21 @@ $ rmenu-build --help
### Example Screenshots ### Example Screenshots
#### Launchpad #### Launchpad
![launchpad](./screenshots/launchpad.png) ![launchpad](./screenshots/launchpad.png)
#### Nord #### Nord
![nord](./screenshots/nord.png) ![nord](./screenshots/nord.png)
#### Dark #### Dark
![dark](./screenshots/dark.png) ![dark](./screenshots/dark.png)
#### Solarized #### Solarized
![solzarized](./screenshots/solarized.png) ![solzarized](./screenshots/solarized.png)
#### PowerMenu #### PowerMenu
![powermenu](./screenshots/powermenu.png) ![powermenu](./screenshots/powermenu.png)

26
flake.lock Normal file
View File

@ -0,0 +1,26 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1711655175,
"narHash": "sha256-1xiaYhC3ul4y+i3eicYxeERk8ZkrNjLkrFSb/UW36Zw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "64c81edb4b97a51c5bbc54c191763ac71a6517ee",
"type": "github"
},
"original": {
"id": "nixpkgs",
"ref": "nixpkgs-unstable",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

99
flake.nix Normal file
View File

@ -0,0 +1,99 @@
{
description = "rmenu: Another customizable Application-Launcher written in Rust";
inputs.nixpkgs.url = "nixpkgs/nixpkgs-unstable";
outputs = {
nixpkgs,
self,
...
}: let
systems = [
"x86_64-linux"
"aarch64-linux"
];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f system);
in {
devShells = forAllSystems (system: let
pkgs = nixpkgs.legacyPackages.${system};
overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml));
libPath = with pkgs; lib.makeLibraryPath [
# load external libraries that you need in your rust project here
glib
gtk3
libsoup_3
networkmanager
webkitgtk_4_1
];
in {
default = pkgs.mkShell {
buildInputs = with pkgs; [
llvmPackages.bintools
rustup
];
RUSTC_VERSION = overrides.toolchain.channel;
# https://github.com/rust-lang/rust-bindgen#environment-variables
LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ];
shellHook = ''
export PATH=$PATH:''${CARGO_HOME:-~/.cargo}/bin
export PATH=$PATH:''${RUSTUP_HOME:-~/.rustup}/toolchains/$RUSTC_VERSION-x86_64-unknown-linux-gnu/bin/
'';
# Add precompiled library to rustc search path
RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [
# add libraries here (e.g. pkgs.libvmi)
]);
LD_LIBRARY_PATH = libPath;
# Add glibc, clang, glib, and other headers to bindgen search path
BINDGEN_EXTRA_CLANG_ARGS =
# Includes normal include path
(builtins.map (a: ''-I"${a}/include"'') [
# add dev libraries here (e.g. pkgs.libvmi.dev)
pkgs.glibc.dev
])
# Includes with special directory paths
++ [
''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"''
''-I"${pkgs.glib.dev}/include/glib-2.0"''
''-I${pkgs.glib.out}/lib/glib-2.0/include/''
];
packages = with pkgs; [
# base toolchain
pkg-config
rustup
# runtime deps
glib
gtk3
libsoup_3
networkmanager
webkitgtk_4_1
# nix utils
self.formatter.${pkgs.system}
nil
];
};
});
formatter = forAllSystems (system: let
pkgs = nixpkgs.legacyPackages.${system};
in pkgs.alejandra);
packages = forAllSystems (system: let
pkgs = nixpkgs.legacyPackages.${system};
rmenu-pkg = (pkgs.callPackage ./nix/package.nix {});
in {
rmenu = rmenu-pkg;
default = rmenu-pkg;
});
nixosModules = let
rmenu-module = (import ./nix/rmenu.nix);
in {
rmenu = rmenu-module;
default = rmenu-module;
};
};
}

91
nix/package.nix Normal file
View File

@ -0,0 +1,91 @@
{ cargo
, fetchFromGitHub
, glib
, gnused
, gtk3
, lib
, libsoup_3
, networkmanager
, pkg-config
, rustPlatform
, rustc
, stdenv
, webkitgtk_4_1
, wrapGAppsHook
}:
rustPlatform.buildRustPackage rec {
version = "1.1.0";
pname = "rmenu";
src = lib.cleanSource ../.;
# src = fetchFromGitHub {
# rev = "188f542"; # "v${version}";
# owner = "imgurbot12";
# repo = pname;
# hash = "sha256-IRwYxjyHdP6794pQjyyUmofO8uakMY22pqdFkJZ5Mdo=";
# };
strictDeps = true;
cargoLock = {
lockFile = ../Cargo.lock;
outputHashes = {
"gio-0.19.0" = "sha256-+PAQNJ9sTk8aKAhA/PLQWDCKDT/cQ+ukdbem7g1J+pU=";
"nm-0.4.0" = "sha256-53ipJU10ZhIKIF7PCw5Eo/e/reUK0qpyTyE7uIrCD88=";
};
};
nativeBuildInputs = [
pkg-config
wrapGAppsHook
];
buildInputs = [
glib
gtk3
libsoup_3
networkmanager
webkitgtk_4_1
gnused
];
postInstall = ''
# copy themes and plugins
mkdir $out/themes
mkdir $out/plugins
cp -vfr $src/themes/* $out/themes/.
cp -vfr $src/other-plugins/* $out/plugins/.
mv $out/bin/* $out/plugins # everything is a plugin by default
# rmenu and rmenu-build are actual binaries
mv $out/plugins/rmenu $out/bin/rmenu
mv $out/plugins/rmenu-build $out/bin/rmenu-build
# fix plugin names
# desktop network pactl-audio.sh powermenu.sh run window
mv $out/plugins/run $out/plugins/rmenu-run
mv $out/plugins/desktop $out/plugins/rmenu-desktop
mv $out/plugins/network $out/plugins/rmenu-network
mv $out/plugins/window $out/plugins/rmenu-window
# fix config and theme
mkdir -p $out/etc/xdg/rmenu
cp -vf $src/rmenu/public/config.yaml $out/etc/xdg/rmenu/config.yaml
sed -i "s@~\/\.config\/rmenu\/themes@$out\/themes@g" $out/etc/xdg/rmenu/config.yaml
sed -i "s@~\/\.config\/rmenu@$out\/plugins@g" $out/etc/xdg/rmenu/config.yaml
ln -sf $out/themes/dark.css $out/etc/xdg/rmenu/style.css
'';
doCheck = true;
meta = with lib; {
changelog = "https://github.com/imgurbot12/rmenu/commits/master/";
description = "Another customizable Application-Launcher written in Rust ";
homepage = "https://github.com/imgurbot12/rmenu";
mainProgram = "rmenu";
maintainers = [ maintainers.grimmauld ];
platforms = platforms.linux;
};
}

8
nix/rmenu.nix Normal file
View File

@ -0,0 +1,8 @@
{ lib, pkgs, ... }:
let
rmenu-pkg = pkgs.callPackage ./package.nix {};
in {
config.environment.systemPackages = [ rmenu-pkg ];
meta.maintainers = with lib.maintainers; [ grimmauld ];
}

View File

@ -1,3 +1,6 @@
body {
padding: 0;
}
.navbar { .navbar {
width: 0; width: 0;
@ -9,6 +12,10 @@
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 100vh;
min-height: 100vh;
overflow-y: hidden;
} }
.result { .result {

View File

@ -4,7 +4,6 @@ get_sinks() {
sinks=`pactl list sinks | grep -e 'Sink #' -e 'Name: ' -e 'Description: ' | nl -s '>'` sinks=`pactl list sinks | grep -e 'Sink #' -e 'Name: ' -e 'Description: ' | nl -s '>'`
default=`pactl get-default-sink` default=`pactl get-default-sink`
for i in `seq 1 3 $(echo "$sinks" | wc -l)`; do for i in `seq 1 3 $(echo "$sinks" | wc -l)`; do
echo "$sinks" | grep "$i>"
sink=`echo "$sinks" | grep "$i>" | cut -d '#' -f2` sink=`echo "$sinks" | grep "$i>" | cut -d '#' -f2`
name=`echo "$sinks" | grep "$(expr $i + 1)>" | cut -d ':' -f2 | xargs echo -n` name=`echo "$sinks" | grep "$(expr $i + 1)>" | cut -d ':' -f2 | xargs echo -n`
desc=`echo "$sinks" | grep "$(expr $i + 2)>" | cut -d ':' -f2 | xargs echo -n` desc=`echo "$sinks" | grep "$(expr $i + 2)>" | cut -d ':' -f2 | xargs echo -n`

View File

@ -1,13 +1,13 @@
[package] [package]
name = "rmenu" name = "rmenu"
version = "0.0.1" version = "1.1.1"
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
cached = "0.44.0" cached = "0.44.0"
clap = { version = "4.3.15", features = ["derive"] } clap = { version = "4.3.15", features = ["derive", "env"] }
dioxus = "0.4.3" dioxus = "0.4.3"
dioxus-desktop = "0.4.3" dioxus-desktop = "0.4.3"
dioxus-html = "0.4.3" dioxus-html = "0.4.3"
@ -30,3 +30,4 @@ shellexpand = "3.1.0"
strfmt = "0.2.4" strfmt = "0.2.4"
thiserror = "1.0.43" thiserror = "1.0.43"
which = "4.4.0" which = "4.4.0"
xdg = "2.5.2"

View File

@ -1,19 +1,19 @@
body {
overflow: hidden;
}
body > div {
height: -webkit-fill-available;
overflow: hidden;
}
html, html,
body, body,
.content { .content {
margin: 0; margin: 0;
} }
body {
overflow: hidden;
padding-top: 60px;
}
body>div {
height: -webkit-fill-available;
overflow: hidden;
}
.navbar { .navbar {
top: 0; top: 0;
left: 0; left: 0;
@ -23,9 +23,10 @@ body,
} }
.results { .results {
height: 100vh;
margin-top: 50px;
overflow-y: auto; overflow-y: auto;
height: calc(100vh - 60px);
min-height: calc(100vh - 60px);
scroll-margin-top: 60px;
} }
.selected { .selected {
@ -43,19 +44,21 @@ input {
height: 5vw; height: 5vw;
border: none; border: none;
outline: none; outline: none;
padding: 5px; padding: 5px;
font-size: large; font-size: large;
} }
/* Result CSS */ /* Result CSS */
.result, .action { .result,
.action {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: left; justify-content: left;
} }
.result > div, .action > div { .result>div,
.action>div {
margin: 2px 5px; margin: 2px 5px;
} }

View File

@ -3,15 +3,11 @@ use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::{Duration, SystemTime}; use std::time::{Duration, SystemTime};
use once_cell::sync::Lazy;
use rmenu_plugin::Entry; use rmenu_plugin::Entry;
use thiserror::Error; use thiserror::Error;
use crate::config::{CacheSetting, PluginConfig}; use crate::config::{CacheSetting, PluginConfig};
use crate::CONFIG_DIR; use crate::XDG_PREFIX;
static CONFIG_PATH: Lazy<PathBuf> =
Lazy::new(|| PathBuf::from(shellexpand::tilde(CONFIG_DIR).to_string()));
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum CacheError { pub enum CacheError {
@ -29,7 +25,10 @@ pub enum CacheError {
#[inline] #[inline]
fn cache_file(name: &str) -> PathBuf { fn cache_file(name: &str) -> PathBuf {
CONFIG_PATH.join(format!("{name}.cache")) xdg::BaseDirectories::with_prefix(XDG_PREFIX)
.expect("Failed to read xdg base dirs")
.place_cache_file(format!("{name}.cache"))
.expect("Failed to write xdg cache dirs")
} }
/// Read Entries from Cache (if Valid and Available) /// Read Entries from Cache (if Valid and Available)

View File

@ -1,5 +1,6 @@
use std::fs::File; use std::fs::File;
use std::io::{BufRead, BufReader, Read}; use std::io::{BufRead, BufReader, Read};
use std::path::PathBuf;
use std::process::{Command, ExitStatus, Stdio}; use std::process::{Command, ExitStatus, Stdio};
use std::str::FromStr; use std::str::FromStr;
use std::{fmt::Display, fs::read_to_string}; use std::{fmt::Display, fs::read_to_string};
@ -9,7 +10,7 @@ use rmenu_plugin::{Entry, Message};
use thiserror::Error; use thiserror::Error;
use crate::config::{cfg_replace, Config, Keybind}; use crate::config::{cfg_replace, Config, Keybind};
use crate::{DEFAULT_CONFIG, DEFAULT_CSS}; use crate::{DEFAULT_CONFIG, DEFAULT_THEME, XDG_PREFIX};
/// Allowed Formats for Entry Ingestion /// Allowed Formats for Entry Ingestion
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -52,18 +53,18 @@ pub struct Args {
#[arg(short, long)] #[arg(short, long)]
run: Vec<String>, run: Vec<String>,
/// Override default configuration path /// Override default configuration path
#[arg(short, long)] #[arg(short, long, env = "RMENU_CONFIG")]
config: Option<String>, config: Option<PathBuf>,
/// Override base css theme styling /// Override base css theme styling
#[arg(long, default_value_t=String::from(DEFAULT_CSS))] #[arg(long, env = "RMENU_THEME")]
theme: String, theme: Option<PathBuf>,
/// Include additional css settings /// Include additional css settings
#[arg(long)] #[arg(long, env = "RMENU_CSS")]
css: Option<String>, css: Option<PathBuf>,
// root config settings // root config settings
/// Override terminal command /// Override terminal command
#[arg(long)] #[arg(long, env = "RMENU_TERMINAL")]
terminal: Option<String>, terminal: Option<String>,
/// Number of results to include for each page /// Number of results to include for each page
#[arg(long)] #[arg(long)]
@ -178,23 +179,37 @@ pub enum RMenuError {
pub type Result<T> = std::result::Result<T, RMenuError>; pub type Result<T> = std::result::Result<T, RMenuError>;
impl Args { impl Args {
/// Find a specifically named file across xdg config paths
fn find_xdg_file(&self, name: &str, base: &Option<PathBuf>) -> Option<String> {
return base
.clone()
.or_else(|| {
xdg::BaseDirectories::with_prefix(XDG_PREFIX)
.expect("Failed to read xdg base dirs")
.find_config_file(name)
})
.map(|f| {
let f = f.to_string_lossy().to_string();
shellexpand::tilde(&f).to_string()
});
}
/// Load Configuration File /// Load Configuration File
pub fn get_config(&self) -> Result<Config> { pub fn get_config(&self) -> Result<Config> {
// read configuration let config = self.find_xdg_file(DEFAULT_CONFIG, &self.config);
let path = self
.config if let Some(path) = config {
.as_ref() let config: Config = match read_to_string(path) {
.map(|v| v.as_str()) Ok(content) => serde_yaml::from_str(&content),
.unwrap_or(DEFAULT_CONFIG); Err(err) => {
let path = shellexpand::tilde(path).to_string(); log::error!("Failed to Load Config: {err:?}");
let config: Config = match read_to_string(path) { Ok(Config::default())
Ok(content) => serde_yaml::from_str(&content), }
Err(err) => { }?;
log::error!("Failed to Load Config: {err:?}"); return Ok(config);
Ok(Config::default()) }
} log::error!("Failed to Load Config: no file found in xdg config paths");
}?; Ok(Config::default())
Ok(config)
} }
/// Update Configuration w/ CLI Specified Settings /// Update Configuration w/ CLI Specified Settings
@ -237,22 +252,28 @@ impl Args {
/// Load CSS Theme or Default /// Load CSS Theme or Default
pub fn get_theme(&self) -> String { pub fn get_theme(&self) -> String {
let path = shellexpand::tilde(&self.theme).to_string(); self.find_xdg_file(DEFAULT_THEME, &self.theme)
match read_to_string(&path) { .map(read_to_string)
Ok(css) => css, .map(|f| {
Err(err) => { f.unwrap_or_else(|err| {
log::error!("Failed to load CSS: {err:?}"); log::error!("Failed to load CSS: {err:?}");
String::new() String::new()
} })
} })
.unwrap_or_else(String::new)
} }
/// Load Additional CSS or Default /// Load Additional CSS or Default
pub fn get_css(&self, c: &Config) -> String { pub fn get_css(&self, c: &Config) -> String {
if let Some(css) = self.css.as_ref().or(c.css.as_ref()) { let css = self
let path = shellexpand::tilde(&css).to_string(); .css
.clone()
.map(|s| s.to_string_lossy().to_string())
.or(c.css.clone());
if let Some(path) = css {
let path = shellexpand::tilde(&path).to_string();
match read_to_string(&path) { match read_to_string(&path) {
Ok(theme) => return theme, Ok(css) => return css,
Err(err) => log::error!("Failed to load Theme: {err:?}"), Err(err) => log::error!("Failed to load Theme: {err:?}"),
} }
} }

View File

@ -1,7 +1,4 @@
//! RMENU Configuration Implementations //! RMENU Configuration Implementations
use heck::AsPascalCase;
use rmenu_plugin::Options;
use serde::{de::Error, Deserialize};
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::str::FromStr; use std::str::FromStr;
@ -10,6 +7,9 @@ use dioxus_desktop::tao::{
window::Fullscreen, window::Fullscreen,
}; };
use dioxus_html::input_data::keyboard_types::{Code, Modifiers}; use dioxus_html::input_data::keyboard_types::{Code, Modifiers};
use heck::AsPascalCase;
use rmenu_plugin::Options;
use serde::{de::Error, Deserialize};
// parse supported modifiers from string // parse supported modifiers from string
fn mod_from_str(s: &str) -> Option<Modifiers> { fn mod_from_str(s: &str) -> Option<Modifiers> {

View File

@ -10,9 +10,9 @@ mod state;
use clap::Parser; use clap::Parser;
use rmenu_plugin::{self_exe, Entry}; use rmenu_plugin::{self_exe, Entry};
static CONFIG_DIR: &'static str = "~/.config/rmenu/"; static DEFAULT_THEME: &'static str = "style.css";
static DEFAULT_CSS: &'static str = "~/.config/rmenu/style.css"; static DEFAULT_CONFIG: &'static str = "config.yaml";
static DEFAULT_CONFIG: &'static str = "~/.config/rmenu/config.yaml"; static XDG_PREFIX: &'static str = "rmenu";
static DEFAULT_CSS_CONTENT: &'static str = include_str!("../public/default.css"); static DEFAULT_CSS_CONTENT: &'static str = include_str!("../public/default.css");
/// Application State for GUI /// Application State for GUI
@ -45,8 +45,6 @@ fn main() -> cli::Result<()> {
let mut cli = cli::Args::parse(); let mut cli = cli::Args::parse();
let mut config = cli.get_config()?; let mut config = cli.get_config()?;
let entries = cli.get_entries(&mut config)?; let entries = cli.get_entries(&mut config)?;
let css = cli.get_css(&config);
let theme = cli.get_theme();
// update config based on cli-settings and entries // update config based on cli-settings and entries
config = cli.update_config(config); config = cli.update_config(config);
@ -56,11 +54,8 @@ fn main() -> cli::Result<()> {
.any(|e| e.icon.is_some() || e.icon_alt.is_some()); .any(|e| e.icon.is_some() || e.icon_alt.is_some());
config.use_comments = config.use_comments && entries.iter().any(|e| e.comment.is_some()); config.use_comments = config.use_comments && entries.iter().any(|e| e.comment.is_some());
// change directory to config folder let theme = cli.get_theme();
let cfgdir = shellexpand::tilde(CONFIG_DIR).to_string(); let css = cli.get_css(&config);
if let Err(err) = std::env::set_current_dir(&cfgdir) {
log::error!("failed to change directory: {err:?}");
}
// genrate app context and run gui // genrate app context and run gui
gui::run(App { gui::run(App {

2
rust-toolchain.toml Normal file
View File

@ -0,0 +1,2 @@
[toolchain]
channel = "stable"