From 892b3f46f916e7ebff8a93c78f26dcd3f0811940 Mon Sep 17 00:00:00 2001 From: Ian Douglas Scott Date: Fri, 3 Jan 2025 15:00:11 -0800 Subject: [PATCH] Add an `offset` to `IconSurface`, so icon can be offset from custor --- core/src/clipboard.rs | 9 ++++++--- winit/src/platform_specific/mod.rs | 6 +++--- winit/src/platform_specific/wayland/mod.rs | 6 +++--- winit/src/platform_specific/wayland/subsurface_widget.rs | 5 +++-- winit/src/program.rs | 2 +- 5 files changed, 16 insertions(+), 12 deletions(-) diff --git a/core/src/clipboard.rs b/core/src/clipboard.rs index 160ca46f07..4dc64c5842 100644 --- a/core/src/clipboard.rs +++ b/core/src/clipboard.rs @@ -5,25 +5,27 @@ use std::any::Any; use dnd::{DndAction, DndDestinationRectangle, DndSurface}; use mime::{self, AllowedMimeTypes, AsMimeTypes, ClipboardStoreData}; -use crate::{widget::tree::State, window, Element}; +use crate::{widget::tree::State, window, Element, Vector}; #[derive(Debug)] pub struct IconSurface { pub element: E, pub state: State, + pub offset: Vector, } pub type DynIconSurface = IconSurface>; impl IconSurface> { - pub fn new(element: Element<'static, (), T, R>, state: State) -> Self { - Self { element, state } + pub fn new(element: Element<'static, (), T, R>, state: State, offset: Vector) -> Self { + Self { element, state, offset } } fn upcast(self) -> DynIconSurface { IconSurface { element: Box::new(self.element), state: self.state, + offset: self.offset, } } } @@ -36,6 +38,7 @@ impl DynIconSurface { IconSurface { element: *self.element.downcast().expect("drag-and-drop icon surface has invalid element type"), state: self.state, + offset: self.offset, } } } diff --git a/winit/src/platform_specific/mod.rs b/winit/src/platform_specific/mod.rs index 5490bfac77..b3f516c3bd 100644 --- a/winit/src/platform_specific/mod.rs +++ b/winit/src/platform_specific/mod.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use iced_graphics::Compositor; -use iced_runtime::{core::window, user_interface, Debug}; +use iced_runtime::{core::{window, Vector}, user_interface, Debug}; use raw_window_handle::HasWindowHandle; #[cfg(all(feature = "wayland", target_os = "linux"))] @@ -128,10 +128,10 @@ impl PlatformSpecific { None } - pub(crate) fn update_surface_shm(&mut self, surface: &dyn HasWindowHandle, width: u32, height: u32, data: &[u8]) { + pub(crate) fn update_surface_shm(&mut self, surface: &dyn HasWindowHandle, width: u32, height: u32, data: &[u8], offset: Vector) { #[cfg(all(feature = "wayland", target_os = "linux"))] { - return self.wayland.update_surface_shm(surface, width, height, data); + return self.wayland.update_surface_shm(surface, width, height, data, offset); } } } diff --git a/winit/src/platform_specific/wayland/mod.rs b/winit/src/platform_specific/wayland/mod.rs index 1b3b8cf5b8..267e501a71 100644 --- a/winit/src/platform_specific/wayland/mod.rs +++ b/winit/src/platform_specific/wayland/mod.rs @@ -15,7 +15,7 @@ use cctk::sctk::reexports::client::protocol::wl_surface::WlSurface; use cctk::sctk::seat::keyboard::Modifiers; use iced_futures::futures::channel::mpsc; use iced_graphics::Compositor; -use iced_runtime::core::window; +use iced_runtime::core::{window, Vector}; use iced_runtime::Debug; use raw_window_handle::{DisplayHandle, HasDisplayHandle, HasWindowHandle}; use raw_window_handle::{HasRawDisplayHandle, RawWindowHandle}; @@ -239,12 +239,12 @@ impl WaylandSpecific { } } - pub(crate) fn update_surface_shm(&mut self, window: &dyn HasWindowHandle, width: u32, height: u32, data: &[u8]) { + pub(crate) fn update_surface_shm(&mut self, window: &dyn HasWindowHandle, width: u32, height: u32, data: &[u8], offset: Vector) { if let Some(subsurface_state) = self.subsurface_state.as_mut() { if let RawWindowHandle::Wayland(window) = window.window_handle().unwrap().as_raw() { let id = unsafe { ObjectId::from_ptr(WlSurface::interface(), window.surface.as_ptr().cast()).unwrap() }; let surface = WlSurface::from_id(self.conn.as_ref().unwrap(), id).unwrap(); - subsurface_state.update_surface_shm(&surface, width, height, data); + subsurface_state.update_surface_shm(&surface, width, height, data, offset); } } } diff --git a/winit/src/platform_specific/wayland/subsurface_widget.rs b/winit/src/platform_specific/wayland/subsurface_widget.rs index 5cde0e96bb..18730bce58 100644 --- a/winit/src/platform_specific/wayland/subsurface_widget.rs +++ b/winit/src/platform_specific/wayland/subsurface_widget.rs @@ -4,7 +4,7 @@ use crate::core::{ layout::{self, Layout}, mouse, renderer, widget::{self, Widget}, - ContentFit, Element, Length, Rectangle, Size, + ContentFit, Element, Length, Rectangle, Size, Vector, }; use std::{ cell::RefCell, @@ -377,13 +377,14 @@ impl SubsurfaceState { .create_surface(&self.qh, SurfaceData::new(None, 1)) } - pub fn update_surface_shm(&self, surface: &WlSurface, width: u32, height: u32, data: &[u8]) { + pub fn update_surface_shm(&self, surface: &WlSurface, width: u32, height: u32, data: &[u8], offset: Vector) { let shm = ShmGlobal(&self.wl_shm); let mut pool = SlotPool::new(width as usize * height as usize * 4, &shm).unwrap(); let (buffer, canvas) = pool.create_buffer(width as i32, height as i32, width as i32 * 4, wl_shm::Format::Argb8888).unwrap(); canvas[0..width as usize * height as usize * 4].copy_from_slice(data); surface.damage_buffer(0, 0, width as i32, height as i32); buffer.attach_to(&surface); + surface.offset(offset.x as i32, offset.y as i32); surface.commit(); } diff --git a/winit/src/program.rs b/winit/src/program.rs index c9de2e2bd5..148906af12 100644 --- a/winit/src/program.rs +++ b/winit/src/program.rs @@ -956,7 +956,7 @@ async fn run_instance<'a, P, C>( let id = window::Id::unique(); platform_specific_handler .update_subsurfaces(id, &surface); - platform_specific_handler.update_surface_shm(&surface, viewport.physical_width(), viewport.physical_height(), &bytes); + platform_specific_handler.update_surface_shm(&surface, viewport.physical_width(), viewport.physical_height(), &bytes, icon_surface.offset); let surface = Arc::new(surface); dnd_surface = Some(surface.clone()); Icon::Surface(dnd::DndSurface(surface))