diff --git a/imgui/src/context.rs b/imgui/src/context.rs index 22e0d63..3b6a071 100644 --- a/imgui/src/context.rs +++ b/imgui/src/context.rs @@ -683,12 +683,11 @@ impl Context { /// Installs a [`PlatformViewportBackend`](crate::PlatformViewportBackend) that is used to /// create platform windows on demand if a window is dragged outside of the main viewport. pub fn set_platform_backend(&mut self, backend: T) { - let ctx = Box::new(UnsafeCell::new(crate::PlatformViewportContext { + let ctx = crate::PlatformViewportContext { backend: Box::new(backend), - })); + }; - let io = self.io_mut(); - io.backend_platform_user_data = ctx.get() as *mut _; + *crate::PLATFORM_VIEWPORT_BACKEND.lock().unwrap() = Some(ctx); let pio = self.platform_io_mut(); pio.platform_create_window = Some(docking_utils::platform_create_window); @@ -719,18 +718,15 @@ impl Context { pio.platform_render_window = Some(docking_utils::platform_render_window); pio.platform_swap_buffers = Some(docking_utils::platform_swap_buffers); pio.platform_create_vk_surface = Some(docking_utils::platform_create_vk_surface); - - self.platform_viewport_ctx = ctx; } /// Installs a [`RendererViewportBackend`](crate::RendererViewportBackend) that is used to /// render extra viewports created by ImGui. pub fn set_renderer_backend(&mut self, backend: T) { - let ctx = Box::new(UnsafeCell::new(crate::RendererViewportContext { + let ctx = crate::RendererViewportContext { backend: Box::new(backend), - })); + }; - let io = self.io_mut(); - io.backend_renderer_user_data = ctx.get() as *mut _; + *crate::RENDERER_VIEWPORT_BACKEND.lock().unwrap() = Some(ctx); let pio = self.platform_io_mut(); pio.renderer_create_window = Some(docking_utils::renderer_create_window); @@ -738,8 +734,6 @@ impl Context { pio.renderer_set_window_size = Some(docking_utils::renderer_set_window_size); pio.renderer_render_window = Some(docking_utils::renderer_render_window); pio.renderer_swap_buffers = Some(docking_utils::renderer_swap_buffers); - - self.renderer_viewport_ctx = ctx; } /// Updates the extra Viewports created by ImGui. /// Has to be called every frame if Viewports are enabled. diff --git a/imgui/src/docking_utils.rs b/imgui/src/docking_utils.rs index c66818f..c3047cc 100644 --- a/imgui/src/docking_utils.rs +++ b/imgui/src/docking_utils.rs @@ -1,9 +1,17 @@ use std::{ + cell::UnsafeCell, ffi::{c_void, CStr}, os::raw::{c_char, c_int}, + sync::{Mutex, MutexGuard}, }; -use crate::{Io, PlatformIo, Viewport}; +use crate::{PlatformIo, Viewport}; + +pub(crate) static PLATFORM_VIEWPORT_BACKEND: Mutex> = + Mutex::new(None); + +pub(crate) static RENDERER_VIEWPORT_BACKEND: Mutex> = + Mutex::new(None); /// Trait holding functions needed when the platform integration supports viewports. /// @@ -67,20 +75,14 @@ pub trait PlatformViewportBackend: 'static { /// Used to get the current Contexts [`PlatformViewportContext`]. fn get_platform_ctx() -> &'static mut PlatformViewportContext { - unsafe { - // should be safe as it is impossible to call any imgui function on a non-active context. - &mut *((*(sys::igGetIO() as *const Io)).backend_platform_user_data - as *mut PlatformViewportContext) - } + let a = UnsafeCell::new(PLATFORM_VIEWPORT_BACKEND.lock().unwrap()).get(); + unsafe { (*a).as_mut().unwrap() } } /// Used to get the current Contexts [`RendererViewportContext`]. fn get_renderer_ctx() -> &'static mut RendererViewportContext { - unsafe { - // should be safe as it is impossible to call any imgui function on a non-active context. - &mut *((*(sys::igGetIO() as *const Io)).backend_renderer_user_data - as *mut RendererViewportContext) - } + let a = UnsafeCell::new(RENDERER_VIEWPORT_BACKEND.lock().unwrap()).get(); + unsafe { (*a).as_mut().unwrap() } } pub(crate) extern "C" fn platform_create_window(viewport: *mut Viewport) { @@ -259,6 +261,8 @@ impl PlatformViewportContext { } } +unsafe impl Send for PlatformViewportContext {} + /// Trait that holds optional functions for a rendering backend to support multiple viewports. /// /// It is completely fine to not use this Backend at all, as all functions are optional. @@ -332,6 +336,8 @@ impl RendererViewportContext { } } +unsafe impl Send for RendererViewportContext {} + /// Describes a monitor that can be used by ImGui. #[repr(C)] pub struct PlatformMonitor {