From 356eeeebf5545fd54f8e06c24d7e4647563c13e0 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Wed, 10 Jan 2024 16:44:58 -0800 Subject: [PATCH 1/8] v0.4.1 --- CHANGELOG.md | 8 ++++++-- Cargo.toml | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c350ee..3dcd9c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,11 @@ # Unreleased -- On MacOS, Fix double-free of `NSWindow`. -- On Web, add support for more `RawWindowHandle` variants. +- On MacOS, Fix double-free of `NSWindow`. (#180) +- On Web, add support for more `RawWindowHandle` variants. (#188) +- On Wayland, fix buffer age. (#191) +- Update `drm` to 0.11 (#178) + * Fixes build on architectures where drm-rs did not have generated bindings. +- Update x11rb to v0.13 (#183) # 0.4.0 diff --git a/Cargo.toml b/Cargo.toml index 9fd5f0b..1ed404a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "softbuffer" -version = "0.4.0" +version = "0.4.1" edition = "2021" license = "MIT OR Apache-2.0" description = "Cross-platform software buffer" From 832064c012337e2d866a0d9477a7467f13baa570 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Fri, 12 Jan 2024 08:40:02 -0800 Subject: [PATCH 2/8] feat: Add ability to get underlying window handle Adds the `get_ref` and `get_mut` functions, which can be used to get references (mutable or otherwise) to the underlying window handle. cc https://github.com/rust-windowing/raw-window-handle/issues/158#issuecomment-1881376603 Signed-off-by: John Nunley --- src/cg.rs | 10 ++++++++-- src/kms.rs | 10 ++++++++-- src/lib.rs | 30 ++++++++++++++++++++++++++++++ src/orbital.rs | 10 ++++++++-- src/wayland/mod.rs | 10 ++++++++-- src/web.rs | 12 +++++++++--- src/win32.rs | 10 ++++++++-- src/x11.rs | 10 ++++++++-- 8 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/cg.rs b/src/cg.rs index 9f6035a..ef96fb9 100644 --- a/src/cg.rs +++ b/src/cg.rs @@ -30,7 +30,7 @@ pub struct CGImpl { window: id, color_space: CGColorSpace, size: Option<(NonZeroU32, NonZeroU32)>, - _window_source: W, + window_handle: W, _display: PhantomData, } @@ -62,10 +62,16 @@ impl CGImpl { color_space, size: None, _display: PhantomData, - _window_source: window_src, + window_handle: window_src, }) } + /// Get the inner window handle. + #[inline] + pub fn window(&self) -> &W { + &self.window_handle + } + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { self.size = Some((width, height)); Ok(()) diff --git a/src/kms.rs b/src/kms.rs index 6e041e6..2761843 100644 --- a/src/kms.rs +++ b/src/kms.rs @@ -73,7 +73,7 @@ pub(crate) struct KmsImpl { buffer: Option, /// Window handle that we are keeping around. - _window: W, + window_handle: W, } #[derive(Debug)] @@ -200,10 +200,16 @@ impl KmsImpl { connectors, display, buffer: None, - _window: window, + window_handle: window, }) } + /// Get the inner window handle. + #[inline] + pub fn window(&self) -> &W { + &self.window_handle + } + /// Resize the internal buffer to the given size. pub(crate) fn resize( &mut self, diff --git a/src/lib.rs b/src/lib.rs index 6ec267c..14191ca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -86,6 +86,15 @@ macro_rules! make_dispatch { } impl SurfaceDispatch { + fn window(&self) -> &W { + match self { + $( + $(#[$attr])* + Self::$name(inner) => inner.window(), + )* + } + } + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { match self { $( @@ -311,6 +320,11 @@ impl Surface { }) } + /// Get a reference to the underlying window handle. + pub fn window(&self) -> &W { + self.surface_impl.window() + } + /// Set the size of the buffer that will be returned by [`Surface::buffer_mut`]. /// /// If the size of the buffer does not match the size of the window, the buffer is drawn @@ -350,6 +364,22 @@ impl Surface { } } +impl AsRef for Surface { + #[inline] + fn as_ref(&self) -> &W { + self.window() + } +} + +impl HasWindowHandle for Surface { + #[inline] + fn window_handle( + &self, + ) -> Result, raw_window_handle::HandleError> { + self.window().window_handle() + } +} + /// A buffer that can be written to by the CPU and presented to the window. /// /// This derefs to a `[u32]`, which depending on the backend may be a mapping into shared memory diff --git a/src/orbital.rs b/src/orbital.rs index 3495b89..53e2e99 100644 --- a/src/orbital.rs +++ b/src/orbital.rs @@ -59,7 +59,7 @@ pub struct OrbitalImpl { width: u32, height: u32, presented: bool, - _window_source: W, + window_handle: W, _display: PhantomData, } @@ -76,11 +76,17 @@ impl OrbitalImpl { width: 0, height: 0, presented: false, - _window_source: window, + window_handle: window, _display: PhantomData, }) } + /// Get the inner window handle. + #[inline] + pub fn window(&self) -> &W { + &self.window_handle + } + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { let width = width.get(); let height = height.get(); diff --git a/src/wayland/mod.rs b/src/wayland/mod.rs index 8984872..d61a5f1 100644 --- a/src/wayland/mod.rs +++ b/src/wayland/mod.rs @@ -83,7 +83,7 @@ pub struct WaylandImpl { /// /// This has to be dropped *after* the `surface` field, because the `surface` field implicitly /// borrows this. - _window: W, + window_handle: W, } impl WaylandImpl { @@ -109,10 +109,16 @@ impl WaylandImpl { surface: Some(surface), buffers: Default::default(), size: None, - _window: window, + window_handle: window, }) } + /// Get the inner window handle. + #[inline] + pub fn window(&self) -> &W { + &self.window_handle + } + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { self.size = Some( (|| { diff --git a/src/web.rs b/src/web.rs index 7b78fca..595073d 100644 --- a/src/web.rs +++ b/src/web.rs @@ -57,7 +57,7 @@ pub struct WebImpl { size: Option<(NonZeroU32, NonZeroU32)>, /// The underlying window handle. - _window: W, + window_handle: W, /// The underlying display handle. _display: PhantomData, @@ -114,7 +114,7 @@ impl WebImpl { buffer: Vec::new(), buffer_presented: false, size: None, - _window: window, + window_handle: window, _display: PhantomData, }) } @@ -130,11 +130,17 @@ impl WebImpl { buffer: Vec::new(), buffer_presented: false, size: None, - _window: window, + window_handle: window, _display: PhantomData, }) } + /// Get the inner window handle. + #[inline] + pub fn window(&self) -> &W { + &self.window_handle + } + /// De-duplicates the error handling between `HtmlCanvasElement` and `OffscreenCanvas`. fn resolve_ctx( result: Option>, diff --git a/src/win32.rs b/src/win32.rs index 4263d1d..7055b44 100644 --- a/src/win32.rs +++ b/src/win32.rs @@ -142,7 +142,7 @@ pub struct Win32Impl { /// The handle for the window. /// /// This should be kept alive in order to keep `window` valid. - _window: W, + handle: W, /// The display handle. /// @@ -184,11 +184,17 @@ impl Win32Impl { dc, window: hwnd, buffer: None, - _window: window, + handle: window, _display: PhantomData, }) } + /// Get the inner window handle. + #[inline] + pub fn window(&self) -> &W { + &self.handle + } + pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { let (width, height) = (|| { let width = NonZeroI32::new(i32::try_from(width.get()).ok()?)?; diff --git a/src/x11.rs b/src/x11.rs index a5baa82..31b2325 100644 --- a/src/x11.rs +++ b/src/x11.rs @@ -150,7 +150,7 @@ pub struct X11Impl { size: Option<(NonZeroU16, NonZeroU16)>, /// Keep the window alive. - _window_handle: W, + window_handle: W, } /// The buffer that is being drawn to. @@ -292,10 +292,16 @@ impl X11Impl { buffer, buffer_presented: false, size: None, - _window_handle: window_src, + window_handle: window_src, }) } + /// Get the inner window handle. + #[inline] + pub fn window(&self) -> &W { + &self.window_handle + } + /// Resize the internal buffer to the given width and height. pub(crate) fn resize( &mut self, From 34d52bd3509596520d8095ed5bfdb8f9be1d28cd Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 28 Jan 2024 12:29:54 -0800 Subject: [PATCH 3/8] Fix MSRV CI issue by pinning half to v2.2.1 (#198) This commit fixes the MSRV CI failure by pinning the half crate to version 2.2.1 when MSRV CI is active. Signed-off-by: John Nunley --- .github/workflows/ci.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 60f7858..26811d6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,14 +91,17 @@ jobs: shell: bash run: cargo $CMD build --verbose --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES + - name: Pin versions of dev-deps + if: matrix.rust_version == '1.65.0' + run: cargo update -p half --precise 2.2.1 + - name: Build tests shell: bash if: > !((matrix.platform.os == 'ubuntu-latest') && contains(matrix.platform.target, 'i686')) && !contains(matrix.platform.target, 'redox') && !contains(matrix.platform.target, 'freebsd') && - !contains(matrix.platform.target, 'netbsd') && - matrix.rust_version != '1.65.0' + !contains(matrix.platform.target, 'netbsd') run: cargo $CMD test --no-run --verbose --target ${{ matrix.platform.target }} $OPTIONS --features $FEATURES - name: Run tests From e435fc99bce3a35dfa9872799fe1043915337325 Mon Sep 17 00:00:00 2001 From: John Nunley Date: Sun, 28 Jan 2024 12:51:01 -0800 Subject: [PATCH 4/8] ci: Set up an autorelease pipeline This commit adds a pipeline that automatically creates a GitHub Release and a crates.io release when a tag is pushed. Signed-off-by: John Nunley --- .github/workflows/release.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..a3f7c57 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +name: Release + +permissions: + contents: write + +on: + push: + tags: + - v[0-9]+.* + +jobs: + create-release: + if: github.repository_owner == 'rust-windowing' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: taiki-e/create-gh-release-action@v1 + with: + changelog: CHANGELOG.md + branch: master + env: + GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }} + - name: Publish to crates.io + run: cargo publish --token ${{ secrets.CRATES_IO_API_TOKEN }} From 0bb85989353f0d17deb593dedb00ee4392a871e7 Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Wed, 18 Jan 2023 17:17:35 -0500 Subject: [PATCH 5/8] Argb8888 --- src/wayland/buffer.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wayland/buffer.rs b/src/wayland/buffer.rs index 0c8bf86..06abbfc 100644 --- a/src/wayland/buffer.rs +++ b/src/wayland/buffer.rs @@ -98,7 +98,7 @@ impl WaylandBuffer { width, height, width * 4, - wl_shm::Format::Xrgb8888, + wl_shm::Format::Argb8888, qh, released.clone(), ); @@ -138,7 +138,7 @@ impl WaylandBuffer { width, height, width * 4, - wl_shm::Format::Xrgb8888, + wl_shm::Format::Argb8888, &self.qh, self.released.clone(), ); From 6e75b1ad7e98397d37cb187886d05969bc480995 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Fri, 9 Feb 2024 21:03:53 -0700 Subject: [PATCH 6/8] On Orbital, fix window resize. --- CHANGELOG.md | 1 + src/orbital.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dcd9c6..76aab18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ - Update `drm` to 0.11 (#178) * Fixes build on architectures where drm-rs did not have generated bindings. - Update x11rb to v0.13 (#183) +- On Orbital, fix window resize. # 0.4.0 diff --git a/src/orbital.rs b/src/orbital.rs index 53e2e99..50c80d4 100644 --- a/src/orbital.rs +++ b/src/orbital.rs @@ -90,7 +90,7 @@ impl OrbitalImpl { pub fn resize(&mut self, width: NonZeroU32, height: NonZeroU32) -> Result<(), SoftBufferError> { let width = width.get(); let height = height.get(); - if width != self.width && height != self.height { + if width != self.width || height != self.height { self.presented = false; self.width = width; self.height = height; From a3f77e251e7422803f693df6e3fc313c010c4dcb Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 7 Sep 2025 19:06:15 -0600 Subject: [PATCH 7/8] Update redox-syscall to 0.5 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 1ed404a..08ee95d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,7 @@ features = [ ] [target.'cfg(target_os = "redox")'.dependencies] -redox_syscall = "0.4" +redox_syscall = "0.5" [build-dependencies] cfg_aliases = "0.2.0" From ae0f2e3e3f1d92e211e148e9b02ba4e132c17923 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Thu, 16 Apr 2026 02:44:45 +0700 Subject: [PATCH 8/8] Pass damage area to orbital window sync --- src/orbital.rs | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/src/orbital.rs b/src/orbital.rs index 50c80d4..50428ab 100644 --- a/src/orbital.rs +++ b/src/orbital.rs @@ -163,9 +163,6 @@ impl OrbitalImpl { // Window buffer map is dropped here } - - // Tell orbital to show the latest window data - syscall::fsync(self.window_fd()).expect("failed to sync orbital window"); } /// Fetch the buffer from the window. @@ -209,10 +206,13 @@ impl<'a, D: HasDisplayHandle, W: HasWindowHandle> BufferImpl<'a, D, W> { } pub fn present(self) -> Result<(), SoftBufferError> { + self.present_with_damage(&[]) + } + + pub fn present_with_damage(self, damage: &[Rect]) -> Result<(), SoftBufferError> { match self.pixels { Pixels::Mapping(mapping) => { drop(mapping); - syscall::fsync(self.imp.window_fd()).expect("failed to sync orbital window"); self.imp.presented = true; } Pixels::Buffer(buffer) => { @@ -221,10 +221,19 @@ impl<'a, D: HasDisplayHandle, W: HasWindowHandle> BufferImpl<'a, D, W> { } } + // Tell orbital to show the latest window data + if damage.is_empty() { + syscall::fsync(self.imp.window_fd()).expect("failed to sync orbital window"); + } else { + use std::fmt::Write; + let mut damage_buf = "Y".to_string(); + for m in damage { + let _ = write!(damage_buf, ",{},{},{},{}", m.x, m.y, m.width, m.height); + } + syscall::write(self.imp.window_fd(), damage_buf.as_bytes()) + .expect("failed to sync orbital window"); + } + Ok(()) } - - pub fn present_with_damage(self, _damage: &[Rect]) -> Result<(), SoftBufferError> { - self.present() - } }