From 8f80cfb0bb4809df4e1141c70937361bc25a8b65 Mon Sep 17 00:00:00 2001 From: Arthur Beck Date: Fri, 7 Mar 2025 06:58:31 -0600 Subject: [PATCH] Add stuff so can work elsewhere --- src/config.rs | 72 +++++++++++++++++++++++-- src/main.rs | 2 +- src/state.rs | 142 +++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 199 insertions(+), 17 deletions(-) diff --git a/src/config.rs b/src/config.rs index 2e79fa8..fc5809a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,6 +1,6 @@ //! Config parsing. -use std::path::PathBuf; +use std::{ffi::OsString, path::PathBuf}; /// Gets Nuarth's config directory. fn get_config_dir() -> PathBuf { @@ -18,7 +18,73 @@ pub struct TilingConfig { pub tiling_factor: f64 } +/// A keyboard key as represented by the linux kernel. +pub type Key = u32; + +/// A keybind. +pub type Keybind = Vec; + +/// Keybinds. +pub struct Keybinds { + /// The keybind to change the tile selection left by one tile. + pub select_left: Keybind, + /// The keybind to change the tile selection right by one tile. + pub select_right: Keybind, + /// The keybind to change the tile selection up by one tile. + pub select_up: Keybind, + /// The keybind to change the tile selection down by one tile. + pub select_down: Keybind, + + /// The keybind to expand the selected tile left by one tile. + pub expand_left: Keybind, + /// The keybind to expand the selected tile right by one tile. + pub expand_right: Keybind, + /// The keybind to expand the selected tile up by one tile. + pub expand_up: Keybind, + /// The keybind to expand the selected tile down by one tile. + pub expand_down: Keybind, + + /// The keybind to move the selected tile left by one tile. + pub move_left: Keybind, + /// The keybind to move the selected tile right by one tile. + pub move_right: Keybind, + /// The keybind to move the selected tile up by one tile. + pub move_up: Keybind, + /// The keybind to move the selected tile down by one tile. + pub move_down: Keybind, + + /// The keybind to change the workspace selection left by one workspace. + pub select_workspace_left: Keybind, + /// The keybind to change the workspace selection right by one workspace. + pub select_workspace_right: Keybind, + /// The keybind to change the workspace selection up by one workspace. + pub select_workspace_up: Keybind, + /// The keybind to change the workspace selection down by one workspace. + pub select_workspace_down: Keybind, + + /// The keybind to move the selected workspace left by one workspace. + pub move_workspace_left: Keybind, + /// The keybind to move the selected workspace right by one workspace. + pub move_workspace_right: Keybind, + /// The keybind to move the selected workspace up by one workspace. + pub move_workspace_up: Keybind, + /// The keybind to move the selected workspace down by one workspace. + pub move_workspace_down: Keybind, + + /// The keybind to bookmark the current workspace as number N where the keybind is prefix+N. + pub bookmark_workspace_prefix: Keybind, + + /// The keybind to jump to bookmark number N where the keybind is prefix+N. + pub jump_workspace_prefix: Keybind, +} + /// Nuarth configuration. pub struct Config { - pub tiling: TilingConfig -} \ No newline at end of file + /// Configuration for tiling. + pub tiling: TilingConfig, + /// Keybind configuration. + pub keybinds: Keybinds, + /// Environment variables. + pub environment: Vec<(OsString, OsString)> +} + diff --git a/src/main.rs b/src/main.rs index 96525a8..b34f0bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -30,6 +30,6 @@ fn main() { events.clear(); poller.wait(&mut events, None).expect("failed waiting for wayland events"); - display.dispatch_clients(&mut DelegationState { }).expect("failed to dispatch event handlers for clients"); + display.dispatch_clients(&mut DelegationState { surfaces: vec![] }).expect("failed to dispatch event handlers for clients"); } } diff --git a/src/state.rs b/src/state.rs index 31e39b5..5ebf36d 100644 --- a/src/state.rs +++ b/src/state.rs @@ -1,29 +1,145 @@ //! Stuff related to state and dispatch methods. +#![warn(missing_docs, clippy::missing_docs_in_private_items, clippy::unwrap_used)] -use wayland_server::{Dispatch, protocol::*}; +use std::sync::RwLock; + +use wayland_server::{ + protocol::{wl_surface::WlSurface, *}, Dispatch, Resource +}; /// The state of Nuarth. pub struct DelegationState { - + /// Surfaces allocated. + pub surfaces: Vec, } -/// The state of Nuarth for a client. -struct ClientState {} +/// The raw surface data. [Surface] is a thread-safe wrapper around this. +struct RawSurface { + /// The parent of this surface. + parent: Option, + /// The children of this surface. + children: Vec, + /// The buffer used in this surface. + buffer: Option, + /// The offset of the buffer. + buffer_offset: (i32, i32) +} -impl Dispatch for DelegationState { +/// A thread-safe wrapper around [RawSurface]. +struct Surface(RwLock); + +/// The kind of a rectangle in a region +#[derive(Copy, Clone, Debug)] +enum RectangleKind { + /// This rectangle should be added/unioned to the region + Add, + /// This rectangle should be removed/intersected with the region + Remove, +} + +/// A rectangle. +struct Rectangle { + /// The first point(generally top-left) + point1: (Coord, Coord), + /// The second point(generally bottom-right) + point2: (Coord, Coord), + /// The kind of this rectangle + kind: RectangleKind, +} + +/// The raw region data. [Region] is a thread-safe wrapper around this. +struct RawRegion { + /// The shape of the region. + shape: Vec>, +} + +/// A thread-safe wrapper around [RawRegion]. +struct Region(RwLock); + +impl Dispatch for DelegationState { fn request( state: &mut DelegationState, - client: &wayland_server::Client, - resource: &wl_output::WlOutput, - request: ::Request, - data: &ClientState, - dhandle: &wayland_server::DisplayHandle, + _client: &wayland_server::Client, + _resource: &wl_compositor::WlCompositor, + request: ::Request, + _data: &(), + _dhandle: &wayland_server::DisplayHandle, data_init: &mut wayland_server::DataInit<'_, DelegationState>, ) { - if let wl_output::Request::Release = request { + match request { + wl_compositor::Request::CreateSurface { id } => { + println!("[TRACE] Creating new surface"); - } else { - println!("[ERROR] Unknown wl_output request!"); + let surface = data_init.init( + id, + Surface(RwLock::new(RawSurface { + parent: None, + children: vec![], + buffer: None, + buffer_offset: (0, 0) + })), + ); + state.surfaces.push(surface); + } + wl_compositor::Request::CreateRegion { id } => { + println!("[TRACE] Creating new region"); + + data_init.init(id, Region(RwLock::new(RawRegion { shape: vec![] }))); + } + unk => { + println!("[ERROR] Unknown wl_compositor request {}!", unk.opcode()); + } } } } + +impl Dispatch for DelegationState { + fn request( + state: &mut DelegationState, + client: &wayland_server::Client, + surface: &wl_surface::WlSurface, + request: ::Request, + data: &Surface, + dhandle: &wayland_server::DisplayHandle, + data_init: &mut wayland_server::DataInit<'_, DelegationState>, + ) { + match request { + wl_surface::Request::Attach { buffer, x, y } => { + let offset = (x != 0 || y != 0).then_some((x, y)); + + let offset = if surface.version() < 5 { + offset + } else { + surface.post_error( + wl_surface::Error::InvalidOffset, + "Passing non-zero x,y is protocol violation since version 5", + ); + return; + }; + + { + #[allow(clippy::unwrap_used)] // That means the data has been poisoned and we want to panic too + let mut data = data.0.write().unwrap(); + data.buffer = buffer; + data.buffer_offset = offset.unwrap_or((0,0)); + } + } + unk => { + println!("[ERROR] Unknown wl_surface request {}!", unk.opcode()); + } + } + } +} + +impl Dispatch for DelegationState { + fn request( + state: &mut DelegationState, + client: &wayland_server::Client, + resource: &wl_region::WlRegion, + request: ::Request, + data: &Region, + dhandle: &wayland_server::DisplayHandle, + data_init: &mut wayland_server::DataInit<'_, DelegationState>, + ) { + } +}