mirror of
https://github.com/marcoallegretti/WEFT_OS.git
synced 2026-03-27 01:13:09 +00:00
feat(compositor): render pointer cursor from CursorImageStatus::Surface
When a Wayland client calls wl_pointer.set_cursor, render the cursor surface at pointer_location using render_elements_from_surface_tree. Changes in render_output: - Collect output_geo, pointer_location, cursor_status before the inner rendering block (avoids borrow conflict with space+drm destructure) - Build cursor elements as Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>> via render_elements_from_surface_tree with Kind::Cursor; hotspot is read from CursorImageSurfaceData on the cursor wl_surface - Cursor elements prepend space elements (highest z-index first, matching render_elements_for_output sort order descending by z_index) - CursorImageStatus::Hidden / Named: no cursor element emitted New imports: SpaceRenderElements, CursorImageStatus, CursorImageSurfaceData, render_elements_from_surface_tree, Kind, Scale, with_states Hardware cursor plane deferred requires DRM cursor plane API audit.
This commit is contained in:
parent
fc5ada2079
commit
43269c9be1
1 changed files with 42 additions and 6 deletions
|
|
@ -33,13 +33,18 @@ use smithay::{
|
||||||
input::InputEvent,
|
input::InputEvent,
|
||||||
libinput::{LibinputInputBackend, LibinputSessionInterface},
|
libinput::{LibinputInputBackend, LibinputSessionInterface},
|
||||||
renderer::{
|
renderer::{
|
||||||
element::surface::WaylandSurfaceRenderElement,
|
element::{
|
||||||
|
Kind,
|
||||||
|
surface::{WaylandSurfaceRenderElement, render_elements_from_surface_tree},
|
||||||
|
},
|
||||||
gles::GlesRenderer,
|
gles::GlesRenderer,
|
||||||
multigpu::{GpuManager, MultiRenderer, gbm::GbmGlesBackend},
|
multigpu::{GpuManager, MultiRenderer, gbm::GbmGlesBackend},
|
||||||
},
|
},
|
||||||
session::{Event as SessionEvent, Session, libseat::LibSeatSession},
|
session::{Event as SessionEvent, Session, libseat::LibSeatSession},
|
||||||
udev::{UdevBackend, UdevEvent, all_gpus, primary_gpu},
|
udev::{UdevBackend, UdevEvent, all_gpus, primary_gpu},
|
||||||
},
|
},
|
||||||
|
desktop::space::SpaceRenderElements,
|
||||||
|
input::pointer::{CursorImageStatus, CursorImageSurfaceData},
|
||||||
output::{Mode as WlMode, Output, PhysicalProperties, Subpixel},
|
output::{Mode as WlMode, Output, PhysicalProperties, Subpixel},
|
||||||
reexports::{
|
reexports::{
|
||||||
calloop::{EventLoop, Interest, Mode, PostAction, generic::Generic},
|
calloop::{EventLoop, Interest, Mode, PostAction, generic::Generic},
|
||||||
|
|
@ -48,8 +53,8 @@ use smithay::{
|
||||||
rustix::fs::OFlags,
|
rustix::fs::OFlags,
|
||||||
wayland_server::Display,
|
wayland_server::Display,
|
||||||
},
|
},
|
||||||
utils::{DeviceFd, Transform},
|
utils::{DeviceFd, Scale, Transform},
|
||||||
wayland::socket::ListeningSocketSource,
|
wayland::{compositor::with_states, socket::ListeningSocketSource},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
|
|
@ -594,6 +599,10 @@ fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Han
|
||||||
.map(|d| d.start_time.elapsed())
|
.map(|d| d.start_time.elapsed())
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
|
let output_geo = state.space.output_geometry(&output).unwrap_or_default();
|
||||||
|
let pointer_location = state.pointer_location;
|
||||||
|
let cursor_status = state.cursor_image_status.clone();
|
||||||
|
|
||||||
{
|
{
|
||||||
let WeftCompositorState {
|
let WeftCompositorState {
|
||||||
ref mut drm,
|
ref mut drm,
|
||||||
|
|
@ -629,9 +638,36 @@ fn render_output(state: &mut WeftCompositorState, node: DrmNode, crtc: crtc::Han
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let elements = space
|
let output_scale = output.current_scale().fractional_scale();
|
||||||
|
|
||||||
|
let mut elements: Vec<SpaceRenderElements<_, WaylandSurfaceRenderElement<_>>> =
|
||||||
|
if let CursorImageStatus::Surface(ref cursor_surface) = cursor_status {
|
||||||
|
let hotspot = with_states(cursor_surface, |states| {
|
||||||
|
states
|
||||||
|
.data_map
|
||||||
|
.get::<CursorImageSurfaceData>()
|
||||||
|
.and_then(|d| d.lock().ok().map(|g| g.hotspot))
|
||||||
|
.unwrap_or_default()
|
||||||
|
});
|
||||||
|
let cursor_pos = (pointer_location - output_geo.loc.to_f64() - hotspot.to_f64())
|
||||||
|
.to_physical_precise_round(output_scale);
|
||||||
|
render_elements_from_surface_tree(
|
||||||
|
&mut renderer,
|
||||||
|
cursor_surface,
|
||||||
|
cursor_pos,
|
||||||
|
Scale::from(output_scale),
|
||||||
|
1.0,
|
||||||
|
Kind::Cursor,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
|
elements.extend(
|
||||||
|
space
|
||||||
.render_elements_for_output(&mut renderer, &output, 1.0)
|
.render_elements_for_output(&mut renderer, &output, 1.0)
|
||||||
.unwrap_or_default();
|
.unwrap_or_default(),
|
||||||
|
);
|
||||||
|
|
||||||
match surface.drm_output.render_frame(
|
match surface.drm_output.render_frame(
|
||||||
&mut renderer,
|
&mut renderer,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue