1
0
Fork 0
forked from wry/wry

Merge pull request #74 from mahkoh/jorth/wlc6

wayland: implement wl_surface v6
This commit is contained in:
mahkoh 2024-02-06 10:50:16 +01:00 committed by GitHub
commit 8bac01ca70
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 53 additions and 14 deletions

View file

@ -20,7 +20,7 @@ pub struct WlCompositorGlobal {
pub struct WlCompositor { pub struct WlCompositor {
id: WlCompositorId, id: WlCompositorId,
client: Rc<Client>, client: Rc<Client>,
_version: u32, version: u32,
pub tracker: Tracker<Self>, pub tracker: Tracker<Self>,
} }
@ -38,7 +38,7 @@ impl WlCompositorGlobal {
let obj = Rc::new(WlCompositor { let obj = Rc::new(WlCompositor {
id, id,
client: client.clone(), client: client.clone(),
_version: version, version,
tracker: Default::default(), tracker: Default::default(),
}); });
track!(client, obj); track!(client, obj);
@ -50,7 +50,7 @@ impl WlCompositorGlobal {
impl WlCompositor { impl WlCompositor {
fn create_surface(&self, parser: MsgParser<'_, '_>) -> Result<(), WlCompositorError> { fn create_surface(&self, parser: MsgParser<'_, '_>) -> Result<(), WlCompositorError> {
let surface: CreateSurface = self.client.parse(self, parser)?; let surface: CreateSurface = self.client.parse(self, parser)?;
let surface = Rc::new(WlSurface::new(surface.id, &self.client)); let surface = Rc::new(WlSurface::new(surface.id, &self.client, self.version));
track!(self.client, surface); track!(self.client, surface);
self.client.add_client_obj(&surface)?; self.client.add_client_obj(&surface)?;
if self.client.is_xwayland { if self.client.is_xwayland {
@ -80,7 +80,7 @@ impl Global for WlCompositorGlobal {
} }
fn version(&self) -> u32 { fn version(&self) -> u32 {
4 6
} }
} }

View file

@ -75,6 +75,9 @@ const INVALID_TRANSFORM: u32 = 1;
#[allow(dead_code)] #[allow(dead_code)]
const INVALID_SIZE: u32 = 2; const INVALID_SIZE: u32 = 2;
const OFFSET_SINCE: u32 = 5;
const BUFFER_SCALE_SINCE: u32 = 6;
#[derive(Copy, Clone, Debug, PartialEq)] #[derive(Copy, Clone, Debug, PartialEq)]
enum Transform { enum Transform {
Normal, Normal,
@ -209,7 +212,7 @@ impl SurfaceRole {
pub struct SurfaceSendPreferredScaleVisitor; pub struct SurfaceSendPreferredScaleVisitor;
impl NodeVisitorBase for SurfaceSendPreferredScaleVisitor { impl NodeVisitorBase for SurfaceSendPreferredScaleVisitor {
fn visit_surface(&mut self, node: &Rc<WlSurface>) { fn visit_surface(&mut self, node: &Rc<WlSurface>) {
node.send_preferred_scale(); node.on_scale_change();
node.node_visit_children(self); node.node_visit_children(self);
} }
} }
@ -252,6 +255,7 @@ pub struct WlSurface {
xwayland_serial: Cell<Option<u64>>, xwayland_serial: Cell<Option<u64>>,
tearing_control: CloneCell<Option<Rc<WpTearingControlV1>>>, tearing_control: CloneCell<Option<Rc<WpTearingControlV1>>>,
tearing: Cell<bool>, tearing: Cell<bool>,
version: u32,
} }
impl Debug for WlSurface { impl Debug for WlSurface {
@ -333,7 +337,8 @@ impl SurfaceExt for NoneSurfaceExt {
#[derive(Default)] #[derive(Default)]
struct PendingState { struct PendingState {
buffer: Cell<Option<Option<(i32, i32, Rc<WlBuffer>)>>>, buffer: Cell<Option<Option<Rc<WlBuffer>>>>,
offset: Cell<(i32, i32)>,
opaque_region: Cell<Option<Option<Rc<Region>>>>, opaque_region: Cell<Option<Option<Rc<Region>>>>,
input_region: Cell<Option<Option<Rc<Region>>>>, input_region: Cell<Option<Option<Rc<Region>>>>,
frame_request: RefCell<Vec<Rc<WlCallback>>>, frame_request: RefCell<Vec<Rc<WlCallback>>>,
@ -360,7 +365,7 @@ pub struct StackElement {
} }
impl WlSurface { impl WlSurface {
pub fn new(id: WlSurfaceId, client: &Rc<Client>) -> Self { pub fn new(id: WlSurfaceId, client: &Rc<Client>, version: u32) -> Self {
Self { Self {
id, id,
node_id: client.state.node_ids.next(), node_id: client.state.node_ids.next(),
@ -399,6 +404,7 @@ impl WlSurface {
xwayland_serial: Default::default(), xwayland_serial: Default::default(),
tearing_control: Default::default(), tearing_control: Default::default(),
tearing: Cell::new(false), tearing: Cell::new(false),
version,
} }
} }
@ -427,9 +433,7 @@ impl WlSurface {
output.global.send_enter(self); output.global.send_enter(self);
old.global.send_leave(self); old.global.send_leave(self);
if old.preferred_scale.get() != output.preferred_scale.get() { if old.preferred_scale.get() != output.preferred_scale.get() {
if let Some(fs) = self.fractional_scale.get() { self.on_scale_change();
fs.send_preferred_scale();
}
} }
let children = self.children.borrow_mut(); let children = self.children.borrow_mut();
if let Some(children) = &*children { if let Some(children) = &*children {
@ -439,10 +443,11 @@ impl WlSurface {
} }
} }
pub fn send_preferred_scale(&self) { fn on_scale_change(&self) {
if let Some(fs) = self.fractional_scale.get() { if let Some(fs) = self.fractional_scale.get() {
fs.send_preferred_scale(); fs.send_preferred_scale();
} }
self.send_preferred_buffer_scale();
} }
pub fn get_toplevel(&self) -> Option<Rc<dyn ToplevelNode>> { pub fn get_toplevel(&self) -> Option<Rc<dyn ToplevelNode>> {
@ -513,6 +518,15 @@ impl WlSurface {
}) })
} }
pub fn send_preferred_buffer_scale(&self) {
if self.version >= BUFFER_SCALE_SINCE {
self.client.event(PreferredBufferScale {
self_id: self.id,
factor: self.output.get().global.legacy_scale.get() as _,
});
}
}
fn set_toplevel(&self, tl: Option<Rc<dyn ToplevelNode>>) { fn set_toplevel(&self, tl: Option<Rc<dyn ToplevelNode>>) {
let ch = self.children.borrow(); let ch = self.children.borrow();
if let Some(ch) = &*ch { if let Some(ch) = &*ch {
@ -640,8 +654,15 @@ impl WlSurface {
fn attach(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> { fn attach(self: &Rc<Self>, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> {
let req: Attach = self.parse(parser)?; let req: Attach = self.parse(parser)?;
if self.version >= OFFSET_SINCE {
if req.x != 0 || req.y != 0 {
return Err(WlSurfaceError::OffsetInAttach);
}
} else {
self.pending.offset.set((req.x, req.y));
}
let buf = if req.buffer.is_some() { let buf = if req.buffer.is_some() {
Some((req.x, req.y, self.client.lookup(req.buffer)?)) Some(self.client.lookup(req.buffer)?)
} else { } else {
None None
}; };
@ -729,6 +750,7 @@ impl WlSurface {
} }
let mut buffer_changed = false; let mut buffer_changed = false;
let mut old_raw_size = None; let mut old_raw_size = None;
let (dx, dy) = self.pending.offset.take();
if let Some(buffer_change) = self.pending.buffer.take() { if let Some(buffer_change) = self.pending.buffer.take() {
buffer_changed = true; buffer_changed = true;
if let Some(buffer) = self.buffer.take() { if let Some(buffer) = self.buffer.take() {
@ -737,7 +759,7 @@ impl WlSurface {
buffer.send_release(); buffer.send_release();
} }
} }
if let Some((dx, dy, buffer)) = buffer_change { if let Some(buffer) = buffer_change {
let _ = buffer.update_texture(); let _ = buffer.update_texture();
self.buffer.set(Some(buffer)); self.buffer.set(Some(buffer));
self.buf_x.fetch_add(dx); self.buf_x.fetch_add(dx);
@ -909,6 +931,12 @@ impl WlSurface {
Ok(()) Ok(())
} }
fn offset(&self, parser: MsgParser<'_, '_>) -> Result<(), WlSurfaceError> {
let req: Offset = self.parse(parser)?;
self.pending.offset.set((req.x, req.y));
Ok(())
}
fn find_surface_at(self: &Rc<Self>, x: i32, y: i32) -> Option<(Rc<Self>, i32, i32)> { fn find_surface_at(self: &Rc<Self>, x: i32, y: i32) -> Option<(Rc<Self>, i32, i32)> {
let rect = self.buffer_abs_pos.get().at_point(0, 0); let rect = self.buffer_abs_pos.get().at_point(0, 0);
let children = self.children.borrow(); let children = self.children.borrow();
@ -1033,11 +1061,12 @@ object_base! {
SET_BUFFER_TRANSFORM => set_buffer_transform, SET_BUFFER_TRANSFORM => set_buffer_transform,
SET_BUFFER_SCALE => set_buffer_scale, SET_BUFFER_SCALE => set_buffer_scale,
DAMAGE_BUFFER => damage_buffer, DAMAGE_BUFFER => damage_buffer,
OFFSET => offset,
} }
impl Object for WlSurface { impl Object for WlSurface {
fn num_requests(&self) -> u32 { fn num_requests(&self) -> u32 {
DAMAGE_BUFFER + 1 OFFSET + 1
} }
fn break_loops(&self) { fn break_loops(&self) {
@ -1227,6 +1256,8 @@ pub enum WlSurfaceError {
NonIntegerViewportSize, NonIntegerViewportSize,
#[error("Viewport source is not contained in the attached buffer")] #[error("Viewport source is not contained in the attached buffer")]
ViewportOutsideBuffer, ViewportOutsideBuffer,
#[error("attach request must not contain offset")]
OffsetInAttach,
} }
efrom!(WlSurfaceError, ClientError); efrom!(WlSurfaceError, ClientError);
efrom!(WlSurfaceError, XdgSurfaceError); efrom!(WlSurfaceError, XdgSurfaceError);

View file

@ -60,3 +60,11 @@ msg enter = 0 {
msg leave = 1 { msg leave = 1 {
output: id(wl_output), output: id(wl_output),
} }
msg preferred_buffer_scale = 2 {
factor: i32,
}
msg preferred_buffer_transform = 3 {
transform: u32,
}