Skip to content

Commit

Permalink
Add wayland interface check binary
Browse files Browse the repository at this point in the history
This will let us write a script that ensures the necessary wayland interfaces exist and otherwise fall back to x11.
  • Loading branch information
Alex Saveau committed Nov 20, 2024
1 parent b931b23 commit cabaae4
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/cid.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ jobs:
cargo publish --package clipboard-history-server
cargo publish --package clipboard-history
cargo publish --package clipboard-history-x11
cargo publish --package wayland-interface-check
cargo publish --package clipboard-history-egui
cargo publish --package clipboard-history-tui
Expand Down Expand Up @@ -126,6 +127,13 @@ jobs:
file: target/${{ matrix.target }}/release/ringboard-x11
asset_name: ${{ matrix.target }}-ringboard-x11
tag: ${{ github.ref }}
- name: Upload binary
uses: svenstaro/upload-release-action@v2
with:
repo_token: ${{ secrets.GITHUB_TOKEN }}
file: target/${{ matrix.target }}/release/wayland-interface-check
asset_name: ${{ matrix.target }}-wayland-interface-check
tag: ${{ github.ref }}
- name: Upload binary
uses: svenstaro/upload-release-action@v2
with:
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"egui",
"server",
"tui",
"wayland-interface-check",
"x11",
]

Expand Down
14 changes: 14 additions & 0 deletions wayland-interface-check/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[package]
name = "wayland-interface-check"
version = "0.1.0"
authors.workspace = true
edition.workspace = true
description = "Binary to answer the question, \"Is this Wayland interface available?\""
repository.workspace = true
keywords = ["tools", "wayland", "cli"]
categories = ["command-line-utilities", "development-tools"]
license.workspace = true

[dependencies]
rustc-hash = "2.0.0"
wayland-client = "0.31.7"
1 change: 1 addition & 0 deletions wayland-interface-check/LICENSE
13 changes: 13 additions & 0 deletions wayland-interface-check/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Wayland interface check

<a href="https://crates.io/crates/wayland-interface-check">![Crates.io Version](https://img.shields.io/crates/v/wayland-interface-check)</a>

This simple binary answers the question, "Is this Wayland interface available?" For example,

```sh
$ wayland-interface-check zwlr_data_control_manager_v1
$ echo $?
0
```

means the interface is available.
68 changes: 68 additions & 0 deletions wayland-interface-check/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#![feature(exitcode_exit_method)]

use std::{
collections::HashSet, env, ffi::OsString, hash::BuildHasherDefault, os::unix::ffi::OsStringExt,
process::ExitCode,
};

use rustc_hash::FxHasher;
use wayland_client::{
Connection, Dispatch, QueueHandle,
protocol::{wl_registry, wl_registry::WlRegistry},
};

fn main() -> ExitCode {
let interfaces = env::args_os()
.skip(1)
.map(OsString::into_vec)
.collect::<HashSet<_, _>>();
if interfaces.is_empty() {
return ExitCode::SUCCESS;
}

let Ok(conn) = Connection::connect_to_env() else {
return ExitCode::FAILURE;
};
let display = conn.display();

let mut event_queue = conn.new_event_queue();
let qh = event_queue.handle();

let mut state = State(interfaces);

display.get_registry(&qh, ());
let Ok(_) = event_queue.roundtrip(&mut state) else {
return ExitCode::FAILURE;
};

if state.0.is_empty() {
ExitCode::SUCCESS
} else {
ExitCode::FAILURE
}
}

struct State(HashSet<Vec<u8>, BuildHasherDefault<FxHasher>>);

impl Dispatch<WlRegistry, ()> for State {
fn event(
this: &mut Self,
_: &WlRegistry,
event: wl_registry::Event,
(): &(),
_: &Connection,
_: &QueueHandle<Self>,
) {
if let wl_registry::Event::Global {
name: _,
interface,
version: _,
} = event
{
this.0.remove(interface.as_bytes());
if this.0.is_empty() {
ExitCode::SUCCESS.exit_process()
}
}
}
}

0 comments on commit cabaae4

Please sign in to comment.