README: update for Snowcap, kill Pinnacle if Snowcap dies

This commit is contained in:
Ottatop 2024-06-16 18:51:34 -05:00
parent a67ec57e3c
commit 1f0e5e8e57
5 changed files with 104 additions and 55 deletions

128
README.md
View file

@ -35,6 +35,14 @@ Pinnacle is a Wayland compositor built in Rust using [Smithay](https://github.co
It's my attempt at creating something like [AwesomeWM](https://github.com/awesomeWM/awesome) It's my attempt at creating something like [AwesomeWM](https://github.com/awesomeWM/awesome)
for Wayland. for Wayland.
### What is Snowcap?
You will see references to Snowcap throughout this README. [Snowcap](https://github.com/pinnacle-comp/snowcap) is the
very, *very* WIP widget system for Pinnacle. Currently it's only being used for the builtin quit prompt and keybind overlay.
In the future, Snowcap will be used for everything Awesome uses its widget system for: a taskbar, system tray, etc.
> [!NOTE]
> Only the Rust API has implemented Snowcap integration currently. Lua support soon™
### Features ### Features
- Tag system - Tag system
- Customizable layouts, including most of the ones from Awesome - Customizable layouts, including most of the ones from Awesome
@ -42,6 +50,7 @@ for Wayland.
- wlr-layer-shell support - wlr-layer-shell support
- Configurable in Lua or Rust - Configurable in Lua or Rust
- wlr-screencopy support - wlr-screencopy support
- A really *really* WIP widget system
- Is very cool :thumbsup: - Is very cool :thumbsup:
### Roadmap ### Roadmap
@ -51,57 +60,63 @@ for Wayland.
You will need: You will need:
- [Rust](https://www.rust-lang.org/) 1.75 or newer - [Rust](https://www.rust-lang.org/) 1.75 or newer
- Packages for [Smithay](https://github.com/Smithay/smithay): - The following external dependencies:
`libwayland libxkbcommon libudev libinput libgdm libseat`, as well as `xwayland` - `libwayland`
- Arch: - `libxkbcommon`
```sh - `libudev`
sudo pacman -S wayland wayland-protocols libxkbcommon systemd-libs libinput mesa seatd xorg-xwayland - `libinput`
``` - `libgbm`
- Debian/Ubuntu: - `libseat`
```sh - `libEGL`
sudo apt install libwayland-dev libxkbcommon-dev libudev-dev libinput-dev libgdm-dev libseat-dev xwayland - `libsystemd`
``` - `libdisplay-info` for monitor display information
- NixOS: There is flake [`flake.nix`](flake.nix) with a devShell. It also - `xwayland` for Xwayland support
- [`protoc`](https://grpc.io/docs/protoc-installation/) for the API
The following are optional dependencies:
- [`just`](https://github.com/casey/just) to automate installation of libraries and files
- The following are required to use the Lua API:
- `just` as mentioned above
- [`lua`](https://www.lua.org/) 5.2 or newer
- [`luarocks`](https://luarocks.org/) for API installation
- You must run `eval $(luarocks path --lua-version <your-lua-version>)` so that your config can find the API
library files. It is recommended to place this command in your shell's startup script.
- Arch and derivatives:
```sh
sudo pacman -S wayland libxkbcommon libinput mesa seatd systemd-libs libdisplay-info xorg-xwayland protobuf
# And optionally
sudo pacman -S just lua luarocks
```
- Debian and derivatives:
```sh
sudo apt install libwayland-dev libxkbcommon-dev libudev-dev libinput-dev libgbm-dev libseat-dev libsystemd-dev protobuf-compiler xwayland libegl-dev libdisplay-info-dev
# And optionally
sudo apt install just lua5.4 luarocks
```
- Note: `just` is only available in apt from Debian 13.
- Nix and NixOS:
- Use the provided [`flake.nix`](flake.nix) with a devShell. It also
includes the other tools needed for the build and sets up the includes the other tools needed for the build and sets up the
`LD_LIBRARY_PATH` so the dynamically loaded libraries are found. `LD_LIBRARY_PATH` so the dynamically loaded libraries are found.
> Luarocks currently doesn't install the Lua library and its dependencies due to openssh directory > Luarocks currently doesn't install the Lua library and its dependencies due to openssh directory
> shenanigans. Fix soon, hopefully. In the meantime you can use the Rust API. > shenanigans. Fix soon, hopefully. In the meantime you can use the Rust API.
- `libdisplay-info`, for monitor display information
- [protoc](https://grpc.io/docs/protoc-installation/), the Protocol Buffer Compiler, for configuration
- Arch:
```sh
sudo pacman -S protobuf
```
- Debian/Ubuntu:
```sh
sudo apt install protobuf-compiler
```
- [just](https://github.com/casey/just), to automate installation of libraries and files
- You don't *need* this but without installation you will not be able to run `cargo run -- config gen` or
use the Lua API (it requires the protobuf definitions at runtime)
- Arch:
```sh
sudo pacman -S just
```
If you would like to use the Lua API, you will additionally need:
- [Lua](https://www.lua.org/) 5.2 or newer
- [LuaRocks](https://luarocks.org/), the Lua package manager
- Arch:
```sh
sudo pacman -S luarocks
```
- Debian/Ubuntu:
```sh
sudo apt install luarocks
```
- You must run `eval $(luarocks path --lua-version <your-lua-version>)` so that your config can find the API
library files. It is recommended to place this command in your shell's startup script.
TODO: other distros TODO: other distros
# Building # Building
Clone this repository and, if building with Snowcap integration, update the `snowcap` submodule:
```sh
git clone https://github.com/pinnacle-comp/pinnacle
git submodule update --init
```
> [!NOTE]
> For all following `cargo`/`just` commands, if you would like to build without Snowcap integration,
> run with `--no-default-features`.
Build the project with: Build the project with:
```sh ```sh
cargo build [--release] cargo build [--release]
@ -126,6 +141,16 @@ After building, run the executable located in either:
./target/release/pinnacle # with --release ./target/release/pinnacle # with --release
``` ```
> [!IMPORTANT]
> When compiling with Snowcap integration, if you do not have Vulkan set up properly,
> Pinnacle will crash on startup.
>
> For those using Nix outside of NixOS, you will need to run the built binary
> with [nixGL](https://github.com/nix-community/nixGL) using *both* GL and Vulkan wrappers, nested inside one another:
> ```
> nix run --impure github:nix-community/nixGL -- nix run --impure github:nix-community/nixGL#nixVulkanIntel -- ./target/debug/pinnacle
> ```
Or, run the project directly with Or, run the project directly with
```sh ```sh
cargo run [--release] cargo run [--release]
@ -145,12 +170,16 @@ the Lua or Rust default configs standalone, run one of the following in the crat
```sh ```sh
# For a Lua configuration # For a Lua configuration
cargo run -- -c "./api/lua/examples/default"
just install run -- -c "./api/lua/examples/default" just install run -- -c "./api/lua/examples/default"
# For a Rust configuration # For a Rust configuration
cargo run -- -c "./api/rust/examples/default_config" cargo run -- -c "./api/rust/examples/default_config"
just install run -- -c "./api/rust/examples/default_config" ```
When running the default Rust config standalone without compiled Snowcap integration,
run the one in the following directory:
```sh
cargo run -- -c "./api/rust/examples/default_config_no_snowcap"
``` ```
## Custom configuration ## Custom configuration
@ -161,15 +190,9 @@ just install run -- -c "./api/rust/examples/default_config"
### Generating a config ### Generating a config
> [!NOTE]
> The default configs must be installed for them to be copied:
> ```sh
> just install-configs # Or alternatively, `just install` which installs everything
> ```
Run the following command to open up the interactive config generator: Run the following command to open up the interactive config generator:
```sh ```sh
cargo run -- config gen just install-configs run -- config gen
``` ```
This will prompt you to choose a language (Lua or Rust) and directory to put the config in. This will prompt you to choose a language (Lua or Rust) and directory to put the config in.
@ -232,6 +255,7 @@ Rust: https://pinnacle-comp.github.io/rust-reference/main.</b>
The following are the default controls in the [`default_config`](api/rust/examples/default_config/main.rs). The following are the default controls in the [`default_config`](api/rust/examples/default_config/main.rs).
| Binding | Action | | Binding | Action |
|----------------------------------------------|------------------------------------| |----------------------------------------------|------------------------------------|
| <kbd>Ctrl</kbd> + <kbd>s</kbd> | Show the keybind overlay |
| <kbd>Ctrl</kbd> + <kbd>Mouse left drag</kbd> | Move window | | <kbd>Ctrl</kbd> + <kbd>Mouse left drag</kbd> | Move window |
| <kbd>Ctrl</kbd> + <kbd>Mouse right drag</kbd>| Resize window | | <kbd>Ctrl</kbd> + <kbd>Mouse right drag</kbd>| Resize window |
| <kbd>Ctrl</kbd><kbd>Alt</kbd> + <kbd>q</kbd> | Quit Pinnacle | | <kbd>Ctrl</kbd><kbd>Alt</kbd> + <kbd>q</kbd> | Quit Pinnacle |

View file

@ -50,6 +50,7 @@
libinput libinput
mesa mesa
xwayland xwayland
libdisplay-info
# winit on x11 # winit on x11
xorg.libXcursor xorg.libXcursor

@ -1 +1 @@
Subproject commit d2f44f2ee5755d694822593d0219b9d9304109ab Subproject commit 3e79a16e1065f07001b08fabdc763bb274cac394

View file

@ -186,14 +186,21 @@ async fn main() -> anyhow::Result<()> {
let (ping, source) = calloop::ping::make_ping()?; let (ping, source) = calloop::ping::make_ping()?;
let ready_flag = Arc::new(AtomicBool::new(false)); let ready_flag = Arc::new(AtomicBool::new(false));
let ready_clone = ready_flag.clone(); let ready_clone = ready_flag.clone();
tokio::task::spawn_blocking(move || { let join_handle = tokio::task::spawn_blocking(move || {
let _span = tracing::error_span!("snowcap");
let _span = _span.enter();
snowcap::start(Some(source), ready_clone); snowcap::start(Some(source), ready_clone);
}); });
while !ready_flag.load(Ordering::SeqCst) { while !ready_flag.load(Ordering::SeqCst) {
event_loop.dispatch(None, &mut state)?; if join_handle.is_finished() {
panic!("snowcap failed to start");
}
event_loop.dispatch(Duration::from_secs(1), &mut state)?;
state.on_event_loop_cycle_completion(); state.on_event_loop_cycle_completion();
} }
state.pinnacle.snowcap_shutdown_ping = Some(ping); state.pinnacle.snowcap_shutdown_ping = Some(ping);
state.pinnacle.snowcap_join_handle = Some(join_handle);
} }
if !metaconfig.no_xwayland { if !metaconfig.no_xwayland {

View file

@ -158,6 +158,8 @@ pub struct Pinnacle {
#[cfg(feature = "snowcap")] #[cfg(feature = "snowcap")]
pub snowcap_shutdown_ping: Option<smithay::reexports::calloop::ping::Ping>, pub snowcap_shutdown_ping: Option<smithay::reexports::calloop::ping::Ping>,
#[cfg(feature = "snowcap")]
pub snowcap_join_handle: Option<tokio::task::JoinHandle<()>>,
} }
impl State { impl State {
@ -173,6 +175,19 @@ impl State {
winit.render_if_scheduled(&mut self.pinnacle); winit.render_if_scheduled(&mut self.pinnacle);
} }
#[cfg(feature = "snowcap")]
if self
.pinnacle
.snowcap_join_handle
.as_ref()
.is_some_and(|handle| handle.is_finished())
{
// If Snowcap is dead, the config has most likely crashed or will crash if it's used.
// The embedded config will also fail to start.
// We'll panic here just so people aren't stuck in the compositor.
panic!("snowcap has exited");
}
// FIXME: Don't poll this every cycle // FIXME: Don't poll this every cycle
for output in self.pinnacle.space.outputs().cloned().collect::<Vec<_>>() { for output in self.pinnacle.space.outputs().cloned().collect::<Vec<_>>() {
output.with_state_mut(|state| { output.with_state_mut(|state| {
@ -361,6 +376,8 @@ impl Pinnacle {
#[cfg(feature = "snowcap")] #[cfg(feature = "snowcap")]
snowcap_shutdown_ping: None, snowcap_shutdown_ping: None,
#[cfg(feature = "snowcap")]
snowcap_join_handle: None,
}; };
Ok(pinnacle) Ok(pinnacle)