Bind wlr layer shell global and get layer surface

This commit is contained in:
2025-04-24 22:38:25 -07:00
parent 1e7676ddb7
commit 970c59edee
6 changed files with 92 additions and 37 deletions

31
src/layer_shell.rs Normal file
View File

@@ -0,0 +1,31 @@
use std::{error::Error, io::Write};
use crate::{surface::UnsetErr, vec_utils::WlMessage, WlClient};
const NAMESPACE: &str = "chlorostart";
const OVERLAY: u32 = 3;
impl WlClient {
pub fn layer_shell_get_layer_surface(&mut self) -> Result<(), Box<dyn Error>> {
let object: u32 = self.layer_shell_id.unwrap();
const OPCODE: u16 = 0;
let msg_size: u16 = 28 + (NAMESPACE.len()+1).next_multiple_of(4) as u16;
let mut request = vec![0u8; msg_size as usize];
let mut offset: usize = 0;
let output: u32 = 0;
request.write_u32(&object, &mut offset);
request.write_u16(&OPCODE, &mut offset);
request.write_u16(&msg_size, &mut offset);
self.current_id += 1;
request.write_u32(&self.current_id, &mut offset);
request.write_u32(&self.surface_id.unwrap(), &mut offset);
request.write_u32(&output, &mut offset);
request.write_u32(&OVERLAY, &mut offset);
request.write_string(&NAMESPACE.to_string(), &mut offset);
self.socket.write(&request)?;
Ok(())
}
}

View File

@@ -7,6 +7,7 @@ mod wl_shm;
mod vec_utils;
mod shm;
mod surface;
mod layer_shell;
use wl_client::WlClient;
fn main() -> Result<(), Box<dyn Error>> {

View File

@@ -2,20 +2,22 @@ use std::{error::Error, io::Write};
use crate::{vec_utils::WlMessage, WlClient};
use std::fmt;
#[derive(Debug)]
pub struct UnsetErr (String);
pub struct UnsetErr (pub String);
impl Error for UnsetErr {}
impl std::fmt::Display for UnsetErr {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{} not set!", self.0)
impl fmt::Display for UnsetErr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} is not set!", self.0)
}
}
impl WlClient {
pub fn wl_compositor_create_surface(&mut self) -> Result<(), Box<dyn Error>> {
if self.compositor_id.is_none() {
return Err(Box::new(UnsetErr("compositor_id".to_string())));
return Err(UnsetErr("compositor_id".to_string()).into());
}
let object = self.compositor_id.unwrap();

View File

@@ -28,6 +28,7 @@ impl WlMessage for Vec<u8> {
}
fn write_string(&mut self, str: &String, offset: &mut usize) {
// TODO: Don't clone str, use &str instead of &String
let mut str = str.clone();
str.push('\0');
let rounded_len: u32 = (str.len()+3) as u32 & (u32::MAX-3);

View File

@@ -18,6 +18,7 @@ pub struct WlClient {
pub compositor_id: Option<u32>,
pub surface_id: Option<u32>,
pub xdg_wm_base_id: Option<u32>,
pub layer_shell_id: Option<u32>,
}
impl WlClient {
@@ -38,6 +39,7 @@ impl WlClient {
compositor_id: None,
surface_id: None,
xdg_wm_base_id: None,
layer_shell_id: None,
};
Ok(res)

View File

@@ -1,15 +1,27 @@
use crate::{WlClient, vec_utils::WlMessage};
use crate::{surface::UnsetErr, vec_utils::WlMessage, WlClient};
use std::{io::Write, error::Error};
impl WlClient {
fn init_toplevel(&mut self) -> Result<(), Box<dyn Error>> {
println!("----> shm and compositor found!");
if self.shm_id.is_none() {
return Err(Box::new(UnsetErr("shm_id".to_string())));
}
if self.compositor_id.is_none() {
return Err(Box::new(UnsetErr("compositor_id".to_string())));
}
if self.xdg_wm_base_id.is_none() {
return Err(Box::new(UnsetErr("xdg_wm_base_id".to_string())));
}
if self.layer_shell_id.is_none() {
return Err(UnsetErr("layer_shell_id".to_string()).into());
}
println!("Initializing toplevel!");
self.wl_compositor_create_surface()?;
self.layer_shell_get_layer_surface()?;
self.wl_shm_create_pool()?;
self.wl_shm_pool_create_buffer(0, 200, 200)?;
self.wl_compositor_create_surface()?;
self.wl_surface_attach()?;
Ok(())
}
@@ -49,6 +61,8 @@ impl WlClient {
version,
);
// TODO: Collapse these into one line (probably using a macro)
if interface == "wl_shm" {
self.current_id += 1;
self.wl_registry_bind(
@@ -58,9 +72,7 @@ impl WlClient {
&self.current_id.clone()
)?;
self.shm_id = Some(self.current_id);
if self.compositor_id.is_some() && self.xdg_wm_base_id.is_some() {
self.init_toplevel()?;
}
self.init_toplevel().unwrap_or_else(|err| {eprintln!("{}", err)});
}
if interface == "wl_compositor" {
@@ -72,10 +84,7 @@ impl WlClient {
&self.current_id.clone()
)?;
self.compositor_id = Some(self.current_id);
if self.shm_id.is_some() && self.xdg_wm_base_id.is_some() {
self.init_toplevel()?;
}
self.init_toplevel().unwrap_or_else(|err| {eprintln!("{}", err)});
}
if interface == "xdg_wm_base" {
@@ -87,10 +96,19 @@ impl WlClient {
&self.current_id.clone()
)?;
self.xdg_wm_base_id = Some(self.current_id);
if self.shm_id.is_some() && self.compositor_id.is_some() {
self.init_toplevel()?;
self.init_toplevel().unwrap_or_else(|err| {eprintln!("{}", err)});
}
if interface == "zwlr_layer_shell_v1" {
self.current_id += 1;
self.wl_registry_bind(
&name,
&interface,
&version,
&self.current_id.clone()
)?;
self.layer_shell_id = Some(self.current_id);
self.init_toplevel().unwrap_or_else(|err| {eprintln!("{}", err)});
}
Ok(())