Skip to main content

dear_imgui_rs/context/
clipboard.rs

1use crate::clipboard::{ClipboardBackend, ClipboardContext};
2use crate::sys;
3
4use super::Context;
5use super::binding::{CTX_MUTEX, with_bound_context};
6
7impl Context {
8    /// Returns the current clipboard text, if available.
9    ///
10    /// This calls Dear ImGui's clipboard callbacks (configured via
11    /// [`Context::set_clipboard_backend`]). When no backend is installed, this returns `None`.
12    ///
13    /// Note: returned data is copied into a new `String`.
14    #[doc(alias = "GetClipboardText")]
15    pub fn clipboard_text(&self) -> Option<String> {
16        let _guard = CTX_MUTEX.lock();
17        unsafe {
18            with_bound_context(self.raw, || {
19                let ptr = sys::igGetClipboardText();
20                if ptr.is_null() {
21                    return None;
22                }
23                Some(std::ffi::CStr::from_ptr(ptr).to_string_lossy().into_owned())
24            })
25        }
26    }
27
28    /// Sets the clipboard text.
29    ///
30    /// This calls Dear ImGui's clipboard callbacks (configured via
31    /// [`Context::set_clipboard_backend`]). If no backend is installed, this is a no-op.
32    ///
33    /// Interior NUL bytes are sanitized to `?` to match other scratch-string helpers.
34    #[doc(alias = "SetClipboardText")]
35    pub fn set_clipboard_text(&self, text: impl AsRef<str>) {
36        let _guard = CTX_MUTEX.lock();
37        unsafe {
38            with_bound_context(self.raw, || {
39                sys::igSetClipboardText(self.ui.scratch_txt(text.as_ref()));
40            });
41        }
42    }
43
44    /// Sets the clipboard backend used for clipboard operations
45    pub fn set_clipboard_backend<T: ClipboardBackend>(&mut self, backend: T) {
46        let _guard = CTX_MUTEX.lock();
47
48        let clipboard_ctx = Box::new(ClipboardContext::new(backend));
49
50        // On native/desktop targets, register clipboard callbacks in ImGui PlatformIO
51        // so ImGui can call back into Rust for copy/paste.
52        //
53        // On wasm32 (import-style build), function pointers cannot safely cross the
54        // module boundary between the Rust main module and the cimgui provider. We
55        // therefore keep the backend alive on the Rust side but do not hook it into
56        // ImGui's PlatformIO yet; clipboard integration for web will need a dedicated
57        // design using JS bindings.
58        #[cfg(not(target_arch = "wasm32"))]
59        unsafe {
60            let platform_io = sys::igGetPlatformIO_ContextPtr(self.raw);
61            if platform_io.is_null() {
62                panic!("Context::set_clipboard_backend() requires a valid ImGui context");
63            }
64            (*platform_io).Platform_SetClipboardTextFn = Some(crate::clipboard::set_clipboard_text);
65            (*platform_io).Platform_GetClipboardTextFn = Some(crate::clipboard::get_clipboard_text);
66            (*platform_io).Platform_ClipboardUserData =
67                clipboard_ctx.as_ref() as *const ClipboardContext as *mut _;
68        }
69
70        self.clipboard_ctx = clipboard_ctx;
71    }
72}