fix(wayland): protocol error

This commit is contained in:
Nova
2025-08-03 15:43:51 -07:00
parent de045a1c68
commit 24beda4a4a
4 changed files with 60 additions and 23 deletions

View File

@@ -12,7 +12,7 @@ use waynest::{
server::{
Client, Dispatcher, Result,
protocol::stable::linux_dmabuf_v1::zwp_linux_buffer_params_v1::{
Flags, ZwpLinuxBufferParamsV1,
Error, Flags, ZwpLinuxBufferParamsV1,
},
},
wire::ObjectId,
@@ -129,7 +129,7 @@ impl ZwpLinuxBufferParamsV1 for BufferParams {
async fn create_immed(
&self,
client: &mut Client,
_sender_id: ObjectId,
sender_id: ObjectId,
buffer_id: ObjectId,
width: i32,
height: i32,
@@ -138,15 +138,27 @@ impl ZwpLinuxBufferParamsV1 for BufferParams {
) -> Result<()> {
// TODO: terminate client on fail, or send a fail event or something
// Create the buffer with DMA-BUF backing using self as the backing
_ = DmabufBacking::from_params(
match DmabufBacking::from_params(
client.get::<Self>(self.id).unwrap(),
[width as u32, height as u32].into(),
DrmFourcc::try_from(format).unwrap(),
flags,
)
.inspect_err(|e| tracing::error!("Failed to import dmabuf because {e}"))
.map(|backing| Buffer::new(client, buffer_id, BufferBacking::Dmabuf(backing)));
) {
Ok(backing) => {
Buffer::new(client, buffer_id, BufferBacking::Dmabuf(backing));
}
Err(e) => {
client
.protocol_error(
sender_id,
buffer_id,
Error::Incomplete as u32,
format!("Failed to import dmabuf because {e}"),
)
.await?;
tracing::error!("Failed to import dmabuf because {e}");
}
}
Ok(())
}
}

View File

@@ -15,10 +15,7 @@ use vulkano::format::FormatFeatures;
use waynest::{
server::{
Client, Dispatcher, Error, Result,
protocol::{
core::wayland::wl_display::WlDisplay,
stable::linux_dmabuf_v1::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
},
protocol::stable::linux_dmabuf_v1::zwp_linux_dmabuf_v1::ZwpLinuxDmabufV1,
},
wire::ObjectId,
};
@@ -146,9 +143,7 @@ impl ZwpLinuxDmabufV1 for Dmabuf {
) -> Result<()> {
if self.version < 3 {
client
.display()
.error(
client,
.protocol_error(
sender_id,
id,
71,

View File

@@ -110,6 +110,7 @@ pub fn get_free_wayland_socket_path() -> Option<(PathBuf, FlockLock<File>)> {
}
pub enum Message {
Disconnect,
Frame(Arc<Callback>),
ReleaseBuffer(Arc<Buffer>),
CloseToplevel(Arc<Toplevel>),
@@ -200,8 +201,9 @@ impl WaylandClient {
async fn handle_render_message(
client: &mut server::Client,
message: Message,
) -> Result<(), waynest::server::Error> {
) -> Result<bool, waynest::server::Error> {
match message {
Message::Disconnect => return Ok(true),
Message::Frame(callback) => {
let serial = client.next_event_serial();
callback.done(client, callback.0, serial).await?;
@@ -211,25 +213,28 @@ impl WaylandClient {
.delete_id(client, ObjectId::DISPLAY, callback.0.as_raw())
.await?;
client.remove(callback.0);
Ok(())
}
Message::ReleaseBuffer(buffer) => buffer.release(client, buffer.id).await,
Message::CloseToplevel(toplevel) => toplevel.close(client, toplevel.id).await,
Message::ReleaseBuffer(buffer) => {
buffer.release(client, buffer.id).await?;
}
Message::CloseToplevel(toplevel) => {
toplevel.close(client, toplevel.id).await?;
}
Message::ResizeToplevel { toplevel, size } => {
toplevel.set_size(size);
toplevel.reconfigure(client).await
toplevel.reconfigure(client).await?;
}
Message::SetToplevelVisualActive { toplevel, active } => {
toplevel.set_activated(active);
toplevel.reconfigure(client).await
toplevel.reconfigure(client).await?;
}
Message::Seat(seat_message) => {
if let Some(seat) = client.get::<Display>(ObjectId::DISPLAY).unwrap().seat.get() {
seat.handle_message(client, seat_message).await?;
}
Ok(())
}
}
Ok(false)
}
}
impl Drop for WaylandClient {

View File

@@ -1,12 +1,22 @@
#![allow(unused)]
use super::{MessageSink, display::Display};
use super::{Message, MessageSink, display::Display};
use std::{fmt::Debug, sync::Arc};
use waynest::{server::Client, wire::ObjectId};
use waynest::{
server::{Client, Result, protocol::core::wayland::wl_display::WlDisplay},
wire::ObjectId,
};
pub trait ClientExt {
fn message_sink(&self) -> MessageSink;
fn display(&self) -> Arc<Display>;
async fn protocol_error(
&mut self,
sender_id: ObjectId,
object_id: ObjectId,
code: u32,
message: String,
) -> Result<()>;
}
impl ClientExt for Client {
fn message_sink(&self) -> MessageSink {
@@ -19,6 +29,21 @@ impl ClientExt for Client {
fn display(&self) -> Arc<Display> {
self.get::<Display>(ObjectId::DISPLAY).unwrap()
}
async fn protocol_error(
&mut self,
sender_id: ObjectId,
object_id: ObjectId,
code: u32,
message: String,
) -> Result<()> {
self.display()
.error(self, sender_id, object_id, code, message)
.await?;
let _ = self.message_sink().send(Message::Disconnect);
Ok(())
}
}
#[derive(Debug, Default)]