Merge pull request #52 from Ottatop/improve_cmd

Improve run command
This commit is contained in:
Ottatop 2023-08-08 14:21:52 -05:00 committed by GitHub
commit a80a707cc2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 115 additions and 60 deletions

View file

@ -85,20 +85,25 @@ It *should* work, but if it doesn't, please raise an issue. <sup>flake soon:tm:<
## Running
After building, run the executable located in either:
```sh
./target/debug/pinnacle --<backend> # without --release
./target/release/pinnacle --<backend> # with --release
./target/debug/pinnacle # without --release
./target/release/pinnacle # with --release
```
Or, run the project directly with
```sh
cargo run [--release] -- --<backend>
cargo run [--release]
```
There is an additional flag you can pass in: `--<backend>`. You most likely do not need to use it.
`backend` can be one of two values:
- `winit`: run Pinnacle as a window in your graphical environment
- `udev`: run Pinnacle in a tty. NOTE: I tried running udev in Awesome and some things broke so uh, don't do that
If you try to run either in environments where you shouldn't be, you will get a warning requiring you to
pass in the `--force` flag to continue. *You probably shouldn't be doing that.*
> :information_source: When running in debug mode, the compositor will drastically slow down
> if there are too many windows on screen. If you don't want this to happen, use release mode.
@ -106,17 +111,15 @@ cargo run [--release] -- --<backend>
> If you successfully enter the `udev` backend but none of the controls work, this means either Pinnacle
failed to find your config, or the config process crashed.
>
> I have not yet implemented VT switching, so to enable you to exit the compositor if this happens,
> ```
> Ctrl + Alt + Shift + Escape
> ```
> has been hardcoded in to kill the compositor.
> You can either switch ttys or press
> `Ctrl + Alt + Shift + Escape`,
> which has been hardcoded in to kill the compositor.
> #### :information_source: Pinnacle will open a socket in the `/tmp` directory.
> If for whatever reason you need the socket to be in a different place, run Pinnacle with
> the `SOCKET_DIR` environment variable:
> ```sh
> SOCKET_DIR=/path/to/new/dir/ cargo run -- --<backend>
> SOCKET_DIR=/path/to/new/dir/ cargo run
> ```
> #### :warning: Don't run Pinnacle as root.
@ -128,19 +131,20 @@ Please note: this is WIP and has few options.
Pinnacle supports configuration through Lua (and hopefully more languages if it's not too unwieldy :crab:).
Run Pinnacle with the `PINNACLE_CONFIG` environment variable set to the path of your config file. If not specified, Pinnacle will look for the following:
Run Pinnacle with the `PINNACLE_CONFIG` environment variable set to the path of your config file.
If not specified, Pinnacle will look for the following:
```sh
$XDG_CONFIG_HOME/pinnacle/init.lua
~/.config/pinnacle/init.lua # if XDG_CONFIG_HOME isn't set
```
The following will use the example config file in [`api/lua`](api/lua):
```sh
PINNACLE_CONFIG="./api/lua/example_config.lua" cargo run -- --<backend>
PINNACLE_CONFIG="./api/lua/example_config.lua" cargo run
```
> #### :information_source: The config is an external process.
> If it crashes for whatever reason, all of your keybinds will stop working.
> Again, you can exit the compositor with `Ctrl + Alt + Shift + Escape`.
> Again, you can switch ttys or exit the compositor with `Ctrl + Alt + Shift + Escape`.
>
> Config reloading soon:tm:
@ -151,7 +155,7 @@ as well as any function overloads, but these should be autocompleted through the
Documentation for other branches can be reached at `https://ottatop.github.io/pinnacle/<branch name>`.
### Autocomplete and that cool stuff
### :information_source: Using the Lua Language Server :information_source:
It is *highly* recommended to use the [Lua language server](https://github.com/LuaLS/lua-language-server)
and set it up to have the [`api/lua`](api/lua) directory as a library, as I'll be using
its doc comments to provide documentation, autocomplete, and error checking.

View file

@ -41,21 +41,53 @@ fn main() -> Result<(), Box<dyn Error>> {
}
}
let in_graphical_env =
std::env::var("WAYLAND_DISPLAY").is_ok() || std::env::var("DISPLAY").is_ok();
let mut args = std::env::args().skip(1);
match args.next().as_deref() {
Some("--winit") => {
tracing::info!("Starting winit backend");
crate::backend::winit::run_winit()?;
if !in_graphical_env {
if let Some("--force") = args.next().as_deref() {
tracing::info!("Starting winit backend with no detected graphical environment");
crate::backend::winit::run_winit()?;
} else {
println!("Both WAYLAND_DISPLAY and DISPLAY were not set.");
println!("If you are trying to run the winit backend in a tty, it won't work.");
println!("If you really want to, additionally pass in the --force flag.");
}
} else {
tracing::info!("Starting winit backend");
crate::backend::winit::run_winit()?;
}
}
Some("--udev") => {
tracing::info!("Starting udev backend");
crate::backend::udev::run_udev()?;
if in_graphical_env {
if let Some("--force") = args.next().as_deref() {
tracing::info!("Starting udev backend with a detected graphical environment");
crate::backend::udev::run_udev()?;
} else {
println!("WAYLAND_DISPLAY and/or DISPLAY were set.");
println!(
"If you are trying to run the udev backend in a graphical environment,"
);
println!("it won't work and may mess some things up.");
println!("If you really want to, additionally pass in the --force flag.");
}
} else {
tracing::info!("Starting udev backend");
crate::backend::udev::run_udev()?;
}
}
Some(arg) => tracing::error!("Unknown argument {}", arg),
None => {
println!(
"Specify a backend:\n\t--udev to launch Pinnacle in a tty, or\n\t--winit to launch Pinnacle as a window in your graphical environment."
);
if in_graphical_env {
tracing::info!("Starting winit backend");
crate::backend::winit::run_winit()?;
} else {
tracing::info!("Starting udev backend");
crate::backend::udev::run_udev()?;
}
}
}

View file

@ -5,7 +5,7 @@ use std::{
error::Error,
ffi::OsString,
os::{fd::AsRawFd, unix::net::UnixStream},
path::Path,
path::PathBuf,
process::Stdio,
sync::{Arc, Mutex},
time::Duration,
@ -845,45 +845,7 @@ impl<B: Backend> State<B> {
calloop::futures::executor::<()>().expect("Couldn't create executor");
loop_handle.insert_source(executor, |_, _, _| {})?;
// TODO: move all this into the lua api
let config_path = std::env::var("PINNACLE_CONFIG").unwrap_or_else(|_| {
let mut default_path =
std::env::var("XDG_CONFIG_HOME").unwrap_or("~/.config".to_string());
default_path.push_str("/pinnacle/init.lua");
default_path
});
if Path::new(&config_path).exists() {
let lua_path = std::env::var("LUA_PATH").unwrap_or_else(|_| {
tracing::info!("LUA_PATH was not set, using empty string");
"".to_string()
});
let mut local_lua_path = std::env::current_dir()
.expect("Couldn't get current dir")
.to_string_lossy()
.to_string();
local_lua_path.push_str("/api/lua"); // TODO: get from crate root and do dynamically
let new_lua_path =
format!("{local_lua_path}/?.lua;{local_lua_path}/?/init.lua;{local_lua_path}/lib/?.lua;{local_lua_path}/lib/?/init.lua;{lua_path}");
let lua_cpath = std::env::var("LUA_CPATH").unwrap_or_else(|_| {
tracing::info!("LUA_CPATH was not set, using empty string");
"".to_string()
});
let new_lua_cpath = format!("{local_lua_path}/lib/?.so;{lua_cpath}");
if let Err(err) = std::process::Command::new("lua")
.arg(config_path)
.env("LUA_PATH", new_lua_path)
.env("LUA_CPATH", new_lua_cpath)
.spawn()
{
tracing::error!("Failed to start Lua: {err}");
return Err(err)?;
}
} else {
tracing::error!("Could not find {}", config_path);
}
start_lua_config()?;
let display_handle = display.handle();
let mut seat_state = SeatState::new();
@ -991,6 +953,63 @@ impl<B: Backend> State<B> {
}
}
fn start_lua_config() -> Result<(), Box<dyn std::error::Error>> {
// TODO: move all this into the lua api
let config_path = std::env::var("PINNACLE_CONFIG")
.map(PathBuf::from)
.unwrap_or_else(|_| {
let default_path = std::env::var("XDG_CONFIG_HOME").unwrap_or("~/.config".to_string());
let mut default_path = PathBuf::from(default_path);
default_path.push("pinnacle/init.lua");
default_path
});
let config_path = {
let path = shellexpand::tilde(&config_path.to_string_lossy().to_string()).to_string();
PathBuf::from(path)
};
if config_path.exists() {
let lua_path = std::env::var("LUA_PATH").unwrap_or_else(|_| {
tracing::info!("LUA_PATH was not set, using empty string");
"".to_string()
});
let mut local_lua_path = std::env::current_dir()
.expect("Couldn't get current dir")
.to_string_lossy()
.to_string();
local_lua_path.push_str("/api/lua"); // TODO: get from crate root and do dynamically
let new_lua_path =
format!("{local_lua_path}/?.lua;{local_lua_path}/?/init.lua;{local_lua_path}/lib/?.lua;{local_lua_path}/lib/?/init.lua;{lua_path}");
let lua_cpath = std::env::var("LUA_CPATH").unwrap_or_else(|_| {
tracing::info!("LUA_CPATH was not set, using empty string");
"".to_string()
});
let new_lua_cpath = format!("{local_lua_path}/lib/?.so;{lua_cpath}");
if let Err(err) = std::process::Command::new("lua")
.arg(config_path)
.env("LUA_PATH", new_lua_path)
.env("LUA_CPATH", new_lua_cpath)
.spawn()
{
tracing::error!("Failed to start Lua: {err}");
return Err(err)?;
}
Ok(())
} else {
tracing::error!("Could not find config {:?}", config_path);
if std::env::var("PINNACLE_CONFIG").is_err() {
tracing::error!("Help: Run Pinnacle with PINNACLE_CONFIG set to a valid config file, or copy the provided example_config.lua to the path mentioned above.");
}
Err(std::io::Error::new(
std::io::ErrorKind::Other,
"No config found",
))?
}
}
pub struct CalloopData<B: Backend> {
pub display: Display<State<B>>,
pub state: State<B>,