Initial commit; mostly a clone of an example from smithay_client_toolkit

This commit is contained in:
TQ Hirsch
2022-05-02 17:46:39 +02:00
commit cbd1283e89
6 changed files with 551 additions and 0 deletions

1
.envrc Normal file
View File

@@ -0,0 +1 @@
eval "$(lorri direnv)"

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
/target
*~
.idea

321
Cargo.lock generated Normal file
View File

@@ -0,0 +1,321 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "anyhow"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "calloop"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf2eec61efe56aa1e813f5126959296933cf0700030e4314786c48779a66ab82"
dependencies = [
"log",
"nix",
]
[[package]]
name = "cc"
version = "1.0.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "dlib"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794"
dependencies = [
"libloading",
]
[[package]]
name = "downcast-rs"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650"
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.125"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b"
[[package]]
name = "libloading"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efbc0f03f9a775e9f6aed295c6a1ba2253c5757a9e03d55c6caa46a681abcddd"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "log"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8"
dependencies = [
"cfg-if",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "memmap2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357"
dependencies = [
"libc",
]
[[package]]
name = "memoffset"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
dependencies = [
"autocfg",
]
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nix"
version = "0.22.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf"
dependencies = [
"bitflags",
"cc",
"cfg-if",
"libc",
"memoffset",
]
[[package]]
name = "nom"
version = "7.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8903e5a29a317527874d0402f867152a3d21c908bb0b933e416c65e301d4c36"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "once_cell"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
[[package]]
name = "pkg-config"
version = "0.3.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae"
[[package]]
name = "proc-macro2"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1"
dependencies = [
"proc-macro2",
]
[[package]]
name = "smallvec"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]]
name = "smithay-client-toolkit"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a28f16a97fa0e8ce563b2774d1e732dd5d4025d2772c5dba0a41a0f90a29da3"
dependencies = [
"bitflags",
"calloop",
"dlib",
"lazy_static",
"log",
"memmap2",
"nix",
"pkg-config",
"wayland-client",
"wayland-cursor",
"wayland-protocols",
]
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "wattbar"
version = "0.1.0"
dependencies = [
"anyhow",
"calloop",
"smithay-client-toolkit",
"wayland-client",
"wayland-protocols",
]
[[package]]
name = "wayland-client"
version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91223460e73257f697d9e23d401279123d36039a3f7a449e983f123292d4458f"
dependencies = [
"bitflags",
"downcast-rs",
"libc",
"nix",
"wayland-commons",
"wayland-scanner",
"wayland-sys",
]
[[package]]
name = "wayland-commons"
version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94f6e5e340d7c13490eca867898c4cec5af56c27a5ffe5c80c6fc4708e22d33e"
dependencies = [
"nix",
"once_cell",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-cursor"
version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c52758f13d5e7861fc83d942d3d99bf270c83269575e52ac29e5b73cb956a6bd"
dependencies = [
"nix",
"wayland-client",
"xcursor",
]
[[package]]
name = "wayland-protocols"
version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60147ae23303402e41fe034f74fb2c35ad0780ee88a1c40ac09a3be1e7465741"
dependencies = [
"bitflags",
"wayland-client",
"wayland-commons",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39a1ed3143f7a143187156a2ab52742e89dac33245ba505c17224df48939f9e0"
dependencies = [
"proc-macro2",
"quote",
"xml-rs",
]
[[package]]
name = "wayland-sys"
version = "0.29.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9341df79a8975679188e37dab3889bfa57c44ac2cb6da166f519a81cbe452d4"
dependencies = [
"pkg-config",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "xcursor"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7"
dependencies = [
"nom",
]
[[package]]
name = "xml-rs"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"

13
Cargo.toml Normal file
View File

@@ -0,0 +1,13 @@
[package]
name = "wattbar"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
wayland-client = "0.29"
wayland-protocols = "0.29"
anyhow = "1"
smithay-client-toolkit = { version = "0.15", default-features = false, features = ["calloop"] }
calloop = "0.9.3"

13
shell.nix Normal file
View File

@@ -0,0 +1,13 @@
{ pkgs ? import <nixpkgs> {} }:
pkgs.mkShell {
buildInputs = with pkgs; [
libxkbcommon
# keep this line if you use bash
bashInteractive
];
nativeBuildInputs = with pkgs; [
pkg-config
];
}

200
src/main.rs Normal file
View File

@@ -0,0 +1,200 @@
use std::{
cell::RefCell,
rc::Rc,
};
use std::cell::Cell;
use wayland_client::{Attached, Main, protocol::{
wl_shm,
wl_surface::WlSurface,
wl_output::WlOutput,
}};
use wayland_protocols::wlr::unstable::layer_shell::v1::client::{
zwlr_layer_surface_v1::{self, ZwlrLayerSurfaceV1},
zwlr_layer_shell_v1::{self, ZwlrLayerShellV1},
};
use smithay_client_toolkit::{
default_environment,
new_default_environment,
environment::SimpleGlobal,
output::OutputInfo,
WaylandSource,
output::with_output_info,
shm::AutoMemPool
};
default_environment!{
MyEnv,
fields = [
layer_shell: SimpleGlobal<ZwlrLayerShellV1>,
],
singles = [
ZwlrLayerShellV1 => layer_shell,
],
}
#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
pub enum RenderEvent {
Closed,
Configure {
width: u32,
height: u32,
}
}
pub struct Surface {
surface: WlSurface,
layer_surface: Main<ZwlrLayerSurfaceV1>,
next_render_event: Rc<Cell<Option<RenderEvent>>>,
pool: AutoMemPool,
dimensions: (u32, u32),
}
impl Surface {
fn new(
output: &WlOutput,
surface: WlSurface,
layer_shell: &Attached<ZwlrLayerShellV1>,
pool: AutoMemPool,
) -> Self {
let layer_surface: Main<ZwlrLayerSurfaceV1> = layer_shell.get_layer_surface(
&surface,
Some(output),
zwlr_layer_shell_v1::Layer::Bottom,
"WattBar".to_owned(),
);
layer_surface.set_size(32, 32);
layer_surface.set_anchor(zwlr_layer_surface_v1::Anchor::Bottom);
layer_surface.set_exclusive_zone(3);
let next_render_event = Rc::new(Cell::new(None));
let nre_handle = Rc::clone(&next_render_event);
layer_surface.quick_assign(move |layer_surface, event, _| {
match (event, nre_handle.get()) {
(zwlr_layer_surface_v1::Event::Closed, _) => {
nre_handle.set(Some(RenderEvent::Closed));
}
(zwlr_layer_surface_v1::Event::Configure {serial, width, height}, next)
if next != Some(RenderEvent::Closed) =>
{
layer_surface.ack_configure(serial);
nre_handle.set(Some(RenderEvent::Configure { width, height }));
}
(_, _) => {}
}
});
surface.commit();
Surface {
surface,
layer_surface,
next_render_event,
pool,
dimensions: (0, 0)
}
}
fn handle_events(&mut self) -> bool {
match self.next_render_event.take() {
Some(RenderEvent::Closed) => true,
Some(RenderEvent::Configure {width, height}) => {
if self.dimensions != (width, height) {
self.dimensions = (width, height);
self.draw();
}
false
}
None => false,
}
}
fn draw(&mut self) {
let stride = 4 * self.dimensions.0 as i32;
let width = self.dimensions.0 as i32;
let height = self.dimensions.1 as i32;
let (canvas, buffer) =
self.pool.buffer(width, height, stride, wl_shm::Format::Argb8888)
.unwrap();
for dst_pixel in canvas.chunks_exact_mut(4) {
let pixel = 0x01_00_8f_00u32.to_ne_bytes();
dst_pixel[0] = pixel[0];
dst_pixel[1] = pixel[1];
dst_pixel[2] = pixel[2];
dst_pixel[3] = pixel[3];
}
self.surface.attach(Some(&buffer), 0, 0);
self.surface.damage_buffer(0, 0, width, height);
self.surface.commit();
}
}
impl Drop for Surface {
fn drop(&mut self) {
self.layer_surface.destroy();
self.surface.destroy();
}
}
fn main() -> anyhow::Result<()> {
let (env, display, queue) = new_default_environment!(
MyEnv,
fields = [
layer_shell: SimpleGlobal::new(),
],
)?;
let env_handle = env.clone();
let layer_shell = env.require_global::<ZwlrLayerShellV1>();
// List surfaces
let surfaces = Rc::new(RefCell::new(Vec::new()));
let surfaces_handle = Rc::clone(&surfaces);
let output_handler = move |output: WlOutput, info: &OutputInfo| {
if info.obsolete {
surfaces_handle.borrow_mut().retain(|(i, _)| *i != info.id);
output.release();
} else {
let surface = env_handle.create_surface().detach();
let pool = env_handle.create_auto_pool().expect("Failed to create a memeory pool!");
surfaces_handle.borrow_mut().push((info.id, Surface::new(&output, surface, &layer_shell.clone(), pool)));
}
};
// Process currently existing outputs
for output in env.get_all_outputs() {
if let Some(info) = with_output_info(&output, Clone::clone) {
output_handler(output, &info);
}
}
let _listener_handle = env.listen_for_outputs(move |output, info, _| output_handler(output, info));
let mut event_loop = calloop::EventLoop::<()>::try_new().expect("Failed to start event loop");
WaylandSource::new(queue).quick_insert(event_loop.handle()).unwrap();
loop {
{
let mut surfaces = surfaces.borrow_mut();
let mut i = 0;
while i != surfaces.len() {
if surfaces[i].1.handle_events() {
surfaces.remove(i);
} else {
i += 1;
}
}
}
display.flush().unwrap();
event_loop.dispatch(None, &mut ()).unwrap();
}
//println!("Registry: {:#?}", env);
}