diff --git a/src/backend/drm/atomic/surface.rs b/src/backend/drm/atomic/surface.rs index 82bf2da..ce0bb08 100644 --- a/src/backend/drm/atomic/surface.rs +++ b/src/backend/drm/atomic/surface.rs @@ -646,6 +646,15 @@ impl CursorBackend for AtomicDrmSurfaceInternal { Ok(()) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + let mut cursor = self.cursor.lock().unwrap(); + if let Some(fb) = cursor.framebuffer.take() { + let _ = self.destroy_framebuffer(fb); + } + + self.clear_plane(self.planes.cursor) + } } impl AtomicDrmSurfaceInternal { @@ -1022,6 +1031,10 @@ impl CursorBackend for AtomicDrmSurface { ) -> Result<(), Error> { self.0.set_cursor_representation(buffer, hotspot) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + self.0.clear_cursor_representation() + } } impl Surface for AtomicDrmSurface { diff --git a/src/backend/drm/common/fallback.rs b/src/backend/drm/common/fallback.rs index c1ddef7..bfc55d1 100644 --- a/src/backend/drm/common/fallback.rs +++ b/src/backend/drm/common/fallback.rs @@ -552,6 +552,7 @@ where fallback_surface_err_impl!(set_cursor_position, &Self, Result<(), EitherError>, x: u32, y: u32); fallback_surface_err_impl!(set_cursor_representation, &Self, Result<(), EitherError>, buffer: &Self::CursorFormat, hotspot: (u32, u32)); + fallback_surface_err_impl!(clear_cursor_representation, &Self, Result<(), EitherError>,); } #[cfg(feature = "renderer_gl")] diff --git a/src/backend/drm/egl/surface.rs b/src/backend/drm/egl/surface.rs index 4fabceb..2b852fb 100644 --- a/src/backend/drm/egl/surface.rs +++ b/src/backend/drm/egl/surface.rs @@ -92,6 +92,10 @@ where ) -> ::std::result::Result<(), Self::Error> { self.0.surface.set_cursor_representation(buffer, hotspot) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + self.0.surface.clear_cursor_representation() + } } #[cfg(feature = "renderer_gl")] diff --git a/src/backend/drm/eglstream/surface.rs b/src/backend/drm/eglstream/surface.rs index 3d70284..b2ca40c 100644 --- a/src/backend/drm/eglstream/surface.rs +++ b/src/backend/drm/eglstream/surface.rs @@ -190,6 +190,17 @@ impl CursorBackend for EglStreamSurfaceInternal { Ok(()) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + self.crtc.set_cursor(self.crtc.crtc(), Option::<&DumbBuffer>::None) + .compat() + .map_err(|source| DrmError::Access { + errmsg: "Failed to clear cursor", + dev: self.crtc.dev_path(), + source, + }) + .map_err(Error::Underlying) + } } /// egl stream surface for rendering @@ -565,6 +576,10 @@ impl CursorBackend for EglStreamSurface { ) -> Result<(), Self::Error> { self.0.set_cursor_representation(buffer, hotspot) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + self.0.clear_cursor_representation() + } } #[cfg(test)] diff --git a/src/backend/drm/gbm/surface.rs b/src/backend/drm/gbm/surface.rs index c3add63..2bdf3bb 100644 --- a/src/backend/drm/gbm/surface.rs +++ b/src/backend/drm/gbm/surface.rs @@ -305,6 +305,22 @@ where *self.cursor.lock().unwrap() = (cursor, hotspot); Ok(()) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + *self.cursor.lock().unwrap() = (self.dev.lock() + .unwrap() + .create_buffer_object( + 1, + 1, + GbmFormat::ARGB8888, + BufferObjectFlags::CURSOR | BufferObjectFlags::WRITE, + ) + .map_err(Error::BufferCreationFailed)?, + (0, 0) + ); + self.crtc.clear_cursor_representation() + .map_err(Error::Underlying) + } } impl Drop for GbmSurfaceInternal { @@ -415,6 +431,10 @@ where ) -> Result<(), Self::Error> { self.0.set_cursor_representation(buffer, hotspot) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + self.0.clear_cursor_representation() + } } #[cfg(test)] diff --git a/src/backend/drm/legacy/surface.rs b/src/backend/drm/legacy/surface.rs index 383e12e..d54b6a1 100644 --- a/src/backend/drm/legacy/surface.rs +++ b/src/backend/drm/legacy/surface.rs @@ -87,6 +87,16 @@ impl CursorBackend for LegacyDrmSurfaceInternal { Ok(()) } + + fn clear_cursor_representation(&self) -> Result<(), Error> { + self.set_cursor(self.crtc, Option::<&DumbBuffer>::None) + .compat() + .map_err(|source| Error::Access { + errmsg: "Failed to set cursor", + dev: self.dev_path(), + source, + }) + } } impl Surface for LegacyDrmSurfaceInternal { @@ -498,6 +508,10 @@ impl CursorBackend for LegacyDrmSurface { ) -> Result<(), Error> { self.0.set_cursor_representation(buffer, hotspot) } + + fn clear_cursor_representation(&self) -> Result<(), Self::Error> { + self.0.clear_cursor_representation() + } } impl Surface for LegacyDrmSurface { diff --git a/src/backend/graphics/cursor.rs b/src/backend/graphics/cursor.rs index f1ff46c..c0550dc 100644 --- a/src/backend/graphics/cursor.rs +++ b/src/backend/graphics/cursor.rs @@ -34,4 +34,7 @@ pub trait CursorBackend { cursor: &Self::CursorFormat, hotspot: (u32, u32), ) -> Result<(), Self::Error>; + + /// Clear the current cursor image drawn on the [`CursorBackend`]. + fn clear_cursor_representation(&self) -> Result<(), Self::Error>; } diff --git a/src/backend/winit.rs b/src/backend/winit.rs index 239effd..2d90a24 100644 --- a/src/backend/winit.rs +++ b/src/backend/winit.rs @@ -270,6 +270,12 @@ impl CursorBackend for WinitGraphicsBackend { // Cannot log this one, as `CursorFormat` is not `Debug` and should not be debug!(self.logger, "Changing cursor representation"); self.window.window().set_cursor_icon(*cursor); + self.window.window().set_cursor_visible(true); + Ok(()) + } + + fn clear_cursor_representation(&self) -> ::std::result::Result<(), ()> { + self.window.window().set_cursor_visible(false); Ok(()) } }