#wayland #event-loop #wlroots #layershell

layershellev

extra shell binding for layershell with winit like eventloop

53 releases (12 breaking)

Uses new Rust 2024

0.13.5 Feb 28, 2025
0.13.2 Jan 20, 2025
0.13.0 Dec 9, 2024
0.11.0-rc3 Nov 29, 2024
0.1.0 Dec 18, 2023

#1016 in GUI

Download history 703/week @ 2024-12-04 154/week @ 2024-12-11 19/week @ 2024-12-18 9/week @ 2024-12-25 7/week @ 2025-01-01 93/week @ 2025-01-08 182/week @ 2025-01-15 47/week @ 2025-01-22 22/week @ 2025-01-29 70/week @ 2025-02-05 274/week @ 2025-02-12 61/week @ 2025-02-19 243/week @ 2025-02-26 34/week @ 2025-03-05 38/week @ 2025-03-12 9/week @ 2025-03-19

329 downloads per month
Used in 5 crates (via iced_layershell)

MIT license

260KB
4.5K SLoC

Layershellev

Layershelleventloop, take lot reference from winit, amin to make a easy way to create layershell window.

you can take ./examples/simplelayer.rs for example

use std::fs::File;
use std::os::fd::AsFd;

use layershellev::reexport::*;
use layershellev::*;

const Q_KEY: u32 = 16;
const W_KEY: u32 = 17;
const E_KEY: u32 = 18;
const A_KEY: u32 = 30;
const S_KEY: u32 = 31;
const D_KEY: u32 = 32;
const Z_KEY: u32 = 44;
const X_KEY: u32 = 45;
const C_KEY: u32 = 46;
const ESC_KEY: u32 = 1;

fn main() {
    let ev: WindowState<()> = WindowState::new("Hello")
        .with_single(false)
        .with_size((0, 400))
        .with_layer(Layer::Top)
        .with_margin((20, 20, 100, 20))
        .with_anchor(Anchor::Bottom | Anchor::Left | Anchor::Right)
        .with_keyboard_interacivity(KeyboardInteractivity::Exclusive)
        .with_exclusize_zone(-1)
        .build()
        .unwrap();

    let mut virtual_keyboard_manager = None;
    ev.running(|event, ev, index| {
        match event {
            // NOTE: this will send when init, you can request bind extra object from here
            LayerEvent::InitRequest => ReturnData::RequestBind,
            LayerEvent::BindProvide(globals, qh) => {
                // NOTE: you can get implied wayland object from here
                virtual_keyboard_manager = Some(
                    globals
                        .bind::<zwp_virtual_keyboard_v1::ZwpVirtualKeyboardManagerV1, _, _>(
                            qh,
                            1..=1,
                            (),
                        )
                        .unwrap(),
                );
                println!("{:?}", virtual_keyboard_manager);
                ReturnData::None
            }
            LayerEvent::XdgInfoChanged(_) => {
                let index = index.unwrap();
                let unit = ev.get_unit(index);
                println!("{:?}", unit.get_xdgoutput_info());
                ReturnData::None
            }
            LayerEvent::RequestBuffer(file, shm, qh, init_w, init_h) => {
                draw(file, (init_w, init_h));
                let pool = shm.create_pool(file.as_fd(), (init_w * init_h * 4) as i32, qh, ());
                ReturnData::WlBuffer(pool.create_buffer(
                    0,
                    init_w as i32,
                    init_h as i32,
                    (init_w * 4) as i32,
                    wl_shm::Format::Argb8888,
                    qh,
                    (),
                ))
            }
            LayerEvent::RequestMessages(DispatchMessage::RequestRefresh { width, height }) => {
                println!("{width}, {height}");
                ReturnData::None
            }
            LayerEvent::RequestMessages(DispatchMessage::MouseButton { .. }) => ReturnData::None,
            LayerEvent::RequestMessages(DispatchMessage::MouseEnter {
                serial, pointer, ..
            }) => ReturnData::RequestSetCursorShape((
                "crosshair".to_owned(),
                pointer.clone(),
                *serial,
            )),
            LayerEvent::RequestMessages(DispatchMessage::MouseMotion {
                time,
                surface_x,
                surface_y,
            }) => {
                println!("{time}, {surface_x}, {surface_y}");
                ReturnData::None
            }
            LayerEvent::RequestMessages(DispatchMessage::KeyBoard { key, .. }) => {
                match index {
                    Some(index) => {
                        let ev_unit = ev.get_unit(index);
                        match *key {
                            Q_KEY => ev_unit.set_anchor(Anchor::Top | Anchor::Left),
                            W_KEY => ev_unit.set_anchor(Anchor::Top),
                            E_KEY => ev_unit.set_anchor(Anchor::Top | Anchor::Right),
                            A_KEY => ev_unit.set_anchor(Anchor::Left),
                            S_KEY => ev_unit.set_anchor(
                                Anchor::Left | Anchor::Right | Anchor::Top | Anchor::Bottom,
                            ),
                            D_KEY => ev_unit.set_anchor(Anchor::Right),
                            Z_KEY => ev_unit.set_anchor(Anchor::Left | Anchor::Bottom),
                            X_KEY => ev_unit.set_anchor(Anchor::Bottom),
                            C_KEY => ev_unit.set_anchor(Anchor::Bottom | Anchor::Right),
                            ESC_KEY => return ReturnData::RequestExist,
                            _ => {}
                        }
                    }
                    None => {
                        for ev_unit in ev.get_unit_iter() {
                            match *key {
                                Q_KEY => ev_unit.set_anchor(Anchor::Top | Anchor::Left),
                                W_KEY => ev_unit.set_anchor(Anchor::Top),
                                E_KEY => ev_unit.set_anchor(Anchor::Top | Anchor::Right),
                                A_KEY => ev_unit.set_anchor(Anchor::Left),
                                S_KEY => ev_unit.set_anchor(
                                    Anchor::Left | Anchor::Right | Anchor::Top | Anchor::Bottom,
                                ),
                                D_KEY => ev_unit.set_anchor(Anchor::Right),
                                Z_KEY => ev_unit.set_anchor(Anchor::Left | Anchor::Bottom),
                                X_KEY => ev_unit.set_anchor(Anchor::Bottom),
                                C_KEY => ev_unit.set_anchor(Anchor::Bottom | Anchor::Right),
                                ESC_KEY => return ReturnData::RequestExist,
                                _ => {}
                            }
                        }
                    }
                };

                ReturnData::None
            }
            _ => ReturnData::None,
        }
    })
    .unwrap();
}

fn draw(tmp: &mut File, (buf_x, buf_y): (u32, u32)) {
    use std::{cmp::min, io::Write};
    let mut buf = std::io::BufWriter::new(tmp);
    for y in 0..buf_y {
        for x in 0..buf_x {
            let a = 0xFF;
            let r = min(((buf_x - x) * 0xFF) / buf_x, ((buf_y - y) * 0xFF) / buf_y);
            let g = min((x * 0xFF) / buf_x, ((buf_y - y) * 0xFF) / buf_y);
            let b = min(((buf_x - x) * 0xFF) / buf_x, (y * 0xFF) / buf_y);

            let color = (a << 24) + (r << 16) + (g << 8) + b;
            buf.write_all(&color.to_ne_bytes()).unwrap();
        }
    }
    buf.flush().unwrap();
}

For more example, please take a look at exwlshelleventloop

Dependencies

~6–16MB
~231K SLoC