Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wayland: Surface Transactions #1009

Merged
merged 9 commits into from
May 10, 2023
62 changes: 57 additions & 5 deletions anvil/src/shell/mod.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
use std::cell::RefCell;

#[cfg(feature = "xwayland")]
use smithay::xwayland::X11Wm;
use smithay::xwayland::{X11Wm, XWaylandClientData};
use smithay::{
backend::renderer::utils::on_commit_buffer_handler,
desktop::{
layer_map_for_output, space::SpaceElement, LayerSurface, PopupKind, PopupManager, Space,
WindowSurfaceType,
},
output::Output,
reexports::wayland_server::protocol::{wl_buffer::WlBuffer, wl_output, wl_surface::WlSurface},
reexports::{
calloop::Interest,
wayland_server::{
protocol::{wl_buffer::WlBuffer, wl_output, wl_surface::WlSurface},
Client, Resource,
},
},
utils::{Logical, Point, Rectangle, Size},
wayland::{
buffer::BufferHandler,
compositor::{
get_parent, is_sync_subsurface, with_states, with_surface_tree_upward, CompositorHandler,
CompositorState, TraversalAction,
add_blocker, add_pre_commit_hook, get_parent, is_sync_subsurface, with_states,
with_surface_tree_upward, BufferAssignment, CompositorClientState, CompositorHandler,
CompositorState, SurfaceAttributes, TraversalAction,
},
dmabuf::get_dmabuf,
shell::{
wlr_layer::{
Layer, LayerSurface as WlrLayerSurface, LayerSurfaceData, WlrLayerShellHandler,
Expand All @@ -27,9 +35,12 @@ use smithay::{
},
};

use crate::state::{AnvilState, Backend};
#[cfg(feature = "xwayland")]
use crate::CalloopData;
use crate::{
state::{AnvilState, Backend},
ClientState,
};

mod element;
mod grabs;
Expand Down Expand Up @@ -88,6 +99,47 @@ impl<BackendData: Backend> CompositorHandler for AnvilState<BackendData> {
fn compositor_state(&mut self) -> &mut CompositorState {
&mut self.compositor_state
}
fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
#[cfg(feature = "xwayland")]
if let Some(state) = client.get_data::<XWaylandClientData>() {
return &state.compositor_state;
}
if let Some(state) = client.get_data::<ClientState>() {
return &state.compositor_state;
}
panic!("Unknown client data type")
}

fn new_surface(&mut self, surface: &WlSurface) {
add_pre_commit_hook::<Self, _>(surface, move |state, _dh, surface| {
let maybe_dmabuf = with_states(surface, |surface_data| {
surface_data
.cached_state
.pending::<SurfaceAttributes>()
.buffer
.as_ref()
.and_then(|assignment| match assignment {
BufferAssignment::NewBuffer(buffer) => get_dmabuf(buffer).ok(),
_ => None,
})
});
if let Some(dmabuf) = maybe_dmabuf {
if let Ok((blocker, source)) = dmabuf.generate_blocker(Interest::READ) {
let client = surface.client().unwrap();
let res = state.handle.insert_source(source, move |_, _, data| {
data.state
.client_compositor_state(&client)
.blocker_cleared(&mut data.state, &data.display.handle());
Ok(())
});
if res.is_ok() {
add_blocker(surface, blocker);
}
}
}
})
}

fn commit(&mut self, surface: &WlSurface) {
#[cfg(feature = "xwayland")]
X11Wm::commit_hook::<CalloopData<BackendData>>(surface);
Expand Down
8 changes: 5 additions & 3 deletions anvil/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use smithay::{
},
utils::{Clock, Logical, Monotonic, Point},
wayland::{
compositor::{get_parent, with_states, CompositorState},
compositor::{get_parent, with_states, CompositorClientState, CompositorState},
data_device::{
set_data_device_focus, ClientDndGrabHandler, DataDeviceHandler, DataDeviceState,
ServerDndGrabHandler,
Expand Down Expand Up @@ -87,7 +87,9 @@ pub struct CalloopData<BackendData: Backend + 'static> {
}

#[derive(Debug, Default)]
pub struct ClientState;
pub struct ClientState {
pub compositor_state: CompositorClientState,
}
impl ClientData for ClientState {
/// Notification that a client was initialized
fn initialized(&self, _client_id: ClientId) {}
Expand Down Expand Up @@ -395,7 +397,7 @@ impl<BackendData: Backend + 'static> AnvilState<BackendData> {
if let Err(err) = data
.display
.handle()
.insert_client(client_stream, Arc::new(ClientState))
.insert_client(client_stream, Arc::new(ClientState::default()))
{
warn!("Error adding wayland client: {}", err);
};
Expand Down
15 changes: 11 additions & 4 deletions examples/compositor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ use std::sync::Arc;
use smithay::delegate_compositor;
use smithay::reexports::wayland_server::Display;

use smithay::wayland::compositor::{CompositorHandler, CompositorState};
use smithay::wayland::compositor::{CompositorClientState, CompositorHandler, CompositorState};

use wayland_server::backend::{ClientData, ClientId, DisconnectReason};
use wayland_server::protocol::wl_surface::WlSurface;
use wayland_server::ListeningSocket;
use wayland_server::{Client, ListeningSocket};

struct App {
compositor_state: CompositorState,
Expand All @@ -18,6 +18,10 @@ impl CompositorHandler for App {
&mut self.compositor_state
}

fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
&client.get_data::<ClientState>().unwrap().compositor_state
}

fn commit(&mut self, surface: &WlSurface) {
dbg!("Commit", surface);
}
Expand All @@ -41,7 +45,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

let client = display
.handle()
.insert_client(stream, Arc::new(ClientState))
.insert_client(stream, Arc::new(ClientState::default()))
.unwrap();
clients.push(client);
}
Expand All @@ -51,7 +55,10 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}

struct ClientState;
#[derive(Default)]
struct ClientState {
compositor_state: CompositorClientState,
}
impl ClientData for ClientState {
fn initialized(&self, _client_id: ClientId) {
println!("initialized");
Expand Down
17 changes: 12 additions & 5 deletions examples/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ use smithay::{
wayland::{
buffer::BufferHandler,
compositor::{
with_surface_tree_downward, CompositorHandler, CompositorState, SurfaceAttributes,
TraversalAction,
with_surface_tree_downward, CompositorClientState, CompositorHandler, CompositorState,
SurfaceAttributes, TraversalAction,
},
data_device::{ClientDndGrabHandler, DataDeviceHandler, DataDeviceState, ServerDndGrabHandler},
shell::xdg::{PopupSurface, PositionerState, ToplevelSurface, XdgShellHandler, XdgShellState},
Expand All @@ -33,7 +33,7 @@ use wayland_server::{
wl_buffer,
wl_surface::{self, WlSurface},
},
ListeningSocket,
Client, ListeningSocket,
};

impl BufferHandler for App {
Expand Down Expand Up @@ -77,6 +77,10 @@ impl CompositorHandler for App {
&mut self.compositor_state
}

fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
&client.get_data::<ClientState>().unwrap().compositor_state
}

fn commit(&mut self, surface: &WlSurface) {
on_commit_buffer_handler::<Self>(surface);
}
Expand Down Expand Up @@ -208,7 +212,7 @@ pub fn run_winit() -> Result<(), Box<dyn std::error::Error>> {

let client = display
.handle()
.insert_client(stream, Arc::new(ClientState))
.insert_client(stream, Arc::new(ClientState::default()))
.unwrap();
clients.push(client);
}
Expand Down Expand Up @@ -243,7 +247,10 @@ pub fn send_frames_surface_tree(surface: &wl_surface::WlSurface, time: u32) {
);
}

struct ClientState;
#[derive(Default)]
struct ClientState {
compositor_state: CompositorClientState,
}
impl ClientData for ClientState {
fn initialized(&self, _client_id: ClientId) {
println!("initialized");
Expand Down
15 changes: 12 additions & 3 deletions smallvil/src/handlers/compositor.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
use crate::{grabs::resize_grab, Smallvil};
use crate::{grabs::resize_grab, state::ClientState, Smallvil};
use smithay::{
backend::renderer::utils::on_commit_buffer_handler,
delegate_compositor, delegate_shm,
reexports::wayland_server::protocol::{wl_buffer, wl_surface::WlSurface},
reexports::wayland_server::{
protocol::{wl_buffer, wl_surface::WlSurface},
Client,
},
wayland::{
buffer::BufferHandler,
compositor::{get_parent, is_sync_subsurface, CompositorHandler, CompositorState},
compositor::{
get_parent, is_sync_subsurface, CompositorClientState, CompositorHandler, CompositorState,
},
shm::{ShmHandler, ShmState},
},
};
Expand All @@ -17,6 +22,10 @@ impl CompositorHandler for Smallvil {
&mut self.compositor_state
}

fn client_compositor_state<'a>(&self, client: &'a Client) -> &'a CompositorClientState {
&client.get_data::<ClientState>().unwrap().compositor_state
}

fn commit(&mut self, surface: &WlSurface) {
on_commit_buffer_handler::<Self>(surface);
if !is_sync_subsurface(surface) {
Expand Down
16 changes: 12 additions & 4 deletions smallvil/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ use smithay::{
},
utils::{Logical, Point},
wayland::{
compositor::CompositorState, data_device::DataDeviceState, output::OutputManagerState,
shell::xdg::XdgShellState, shm::ShmState, socket::ListeningSocketSource,
compositor::{CompositorClientState, CompositorState},
data_device::DataDeviceState,
output::OutputManagerState,
shell::xdg::XdgShellState,
shm::ShmState,
socket::ListeningSocketSource,
},
};

Expand Down Expand Up @@ -113,7 +117,7 @@ impl Smallvil {
state
.display
.handle()
.insert_client(client_stream, Arc::new(ClientState))
.insert_client(client_stream, Arc::new(ClientState::default()))
.unwrap();
})
.expect("Failed to init the wayland event source.");
Expand Down Expand Up @@ -149,7 +153,11 @@ impl Smallvil {
}
}

pub struct ClientState;
#[derive(Default)]
pub struct ClientState {
pub compositor_state: CompositorClientState,
}

impl ClientData for ClientState {
fn initialized(&self, _client_id: ClientId) {}
fn disconnected(&self, _client_id: ClientId, _reason: DisconnectReason) {}
Expand Down
Loading