mirror of
https://github.com/pinnacle-comp/pinnacle.git
synced 2025-01-29 20:34:46 +01:00
commit
a80a707cc2
3 changed files with 115 additions and 60 deletions
30
README.md
30
README.md
|
@ -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.
|
||||
|
|
46
src/main.rs
46
src/main.rs
|
@ -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()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
99
src/state.rs
99
src/state.rs
|
@ -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>,
|
||||
|
|
Loading…
Add table
Reference in a new issue