From 1545556d703fc7f1e1d7f4c3204806b6d9bc6417 Mon Sep 17 00:00:00 2001
From: TheRedDeveloper
Date: Tue, 17 Feb 2026 22:20:36 +0100
Subject: [PATCH 1/3] expose HWND via window::windows_hwnd()
---
src/lib.rs | 9 +++++++++
src/native/windows.rs | 15 ++++++++++++++-
2 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/src/lib.rs b/src/lib.rs
index e7f9d500..a8ab98ce 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -439,6 +439,15 @@ pub mod window {
let d = native_display().lock().unwrap();
d.view_ctrl
}
+
+ /// Get the main window HWND as a raw pointer (`*mut c_void`).
+ ///
+ /// Returns `null_mut()` if the window has not been created yet.
+ /// Only available on Windows.
+ #[cfg(target_os = "windows")]
+ pub fn windows_hwnd() -> *mut std::ffi::c_void {
+ crate::native::windows::get_window_hwnd()
+ }
}
#[derive(Debug, Copy, Clone, PartialEq, Hash, Eq)]
diff --git a/src/native/windows.rs b/src/native/windows.rs
index 01ffe5fa..c7c1b8cf 100644
--- a/src/native/windows.rs
+++ b/src/native/windows.rs
@@ -44,9 +44,19 @@ const WM_KILLFOCUS: UINT = 0x0008;
/// Global flag tracking whether IME has been explicitly disabled by the user.
/// This is controlled via `show_keyboard(bool)` API calls.
-use std::sync::atomic::AtomicBool;
+use std::sync::atomic::{AtomicBool, AtomicPtr};
static IME_USER_DISABLED: AtomicBool = AtomicBool::new(false);
+/// The main window HWND, stored as a raw pointer for cross-crate access.
+static WINDOW_HWND: AtomicPtr = AtomicPtr::new(std::ptr::null_mut());
+
+/// Get the main window HWND as a raw pointer.
+///
+/// Returns `null_mut()` if the window has not been created yet.
+pub fn get_window_hwnd() -> *mut std::ffi::c_void {
+ WINDOW_HWND.load(std::sync::atomic::Ordering::Acquire)
+}
+
// IME composition form constants
const CFS_POINT: DWORD = 0x0002;
const CFS_CANDIDATEPOS: DWORD = 0x0040;
@@ -964,6 +974,9 @@ unsafe fn create_window(
);
assert!(!hwnd.is_null());
+ // Store the HWND globally so external code can access it
+ WINDOW_HWND.store(hwnd as *mut std::ffi::c_void, std::sync::atomic::Ordering::Release);
+
// NOTE: Do not call ShowWindow here!
// Must show window AFTER SetPixelFormat and wglCreateContext
// Otherwise IME will not work correctly.
From 1ebbd8a4dfe450101d84bc570d7ef4a5d61ada5c Mon Sep 17 00:00:00 2001
From: TheRedDeveloper
Date: Wed, 18 Feb 2026 17:02:40 +0100
Subject: [PATCH 2/3] Store HWND in NativeDisplayData, make get_window_hwnd
pub(crate)
---
src/native.rs | 9 +++++++--
src/native/windows.rs | 15 ++++++---------
2 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/src/native.rs b/src/native.rs
index f3820036..089ce5c8 100644
--- a/src/native.rs
+++ b/src/native.rs
@@ -24,6 +24,9 @@ pub(crate) struct NativeDisplayData {
pub dropped_files: DroppedFiles,
pub blocking_event_loop: bool,
+ #[cfg(target_os = "windows")]
+ pub hwnd: *mut std::ffi::c_void,
+
#[cfg(target_vendor = "apple")]
pub view: crate::native::apple::frameworks::ObjcId,
#[cfg(target_os = "ios")]
@@ -31,9 +34,9 @@ pub(crate) struct NativeDisplayData {
#[cfg(target_vendor = "apple")]
pub gfx_api: crate::conf::AppleGfxApi,
}
-#[cfg(target_vendor = "apple")]
+#[cfg(any(target_vendor = "apple", target_os = "windows"))]
unsafe impl Send for NativeDisplayData {}
-#[cfg(target_vendor = "apple")]
+#[cfg(any(target_vendor = "apple", target_os = "windows"))]
unsafe impl Sync for NativeDisplayData {}
impl NativeDisplayData {
@@ -56,6 +59,8 @@ impl NativeDisplayData {
clipboard,
dropped_files: Default::default(),
blocking_event_loop: false,
+ #[cfg(target_os = "windows")]
+ hwnd: std::ptr::null_mut(),
#[cfg(target_vendor = "apple")]
gfx_api: crate::conf::AppleGfxApi::OpenGl,
#[cfg(target_vendor = "apple")]
diff --git a/src/native/windows.rs b/src/native/windows.rs
index c7c1b8cf..371c3dab 100644
--- a/src/native/windows.rs
+++ b/src/native/windows.rs
@@ -44,17 +44,14 @@ const WM_KILLFOCUS: UINT = 0x0008;
/// Global flag tracking whether IME has been explicitly disabled by the user.
/// This is controlled via `show_keyboard(bool)` API calls.
-use std::sync::atomic::{AtomicBool, AtomicPtr};
+use std::sync::atomic::AtomicBool;
static IME_USER_DISABLED: AtomicBool = AtomicBool::new(false);
-/// The main window HWND, stored as a raw pointer for cross-crate access.
-static WINDOW_HWND: AtomicPtr = AtomicPtr::new(std::ptr::null_mut());
-
/// Get the main window HWND as a raw pointer.
///
/// Returns `null_mut()` if the window has not been created yet.
-pub fn get_window_hwnd() -> *mut std::ffi::c_void {
- WINDOW_HWND.load(std::sync::atomic::Ordering::Acquire)
+pub(crate) fn get_window_hwnd() -> *mut std::ffi::c_void {
+ crate::native_display().lock().unwrap().hwnd
}
// IME composition form constants
@@ -974,9 +971,6 @@ unsafe fn create_window(
);
assert!(!hwnd.is_null());
- // Store the HWND globally so external code can access it
- WINDOW_HWND.store(hwnd as *mut std::ffi::c_void, std::sync::atomic::Ordering::Release);
-
// NOTE: Do not call ShowWindow here!
// Must show window AFTER SetPixelFormat and wglCreateContext
// Otherwise IME will not work correctly.
@@ -1219,6 +1213,9 @@ where
..NativeDisplayData::new(conf.window_width, conf.window_height, tx, clipboard)
});
+ // Store the HWND in NativeDisplayData so external code can access it via window::windows_hwnd()
+ crate::native_display().lock().unwrap().hwnd = wnd as *mut std::ffi::c_void;
+
display.update_dimensions(wnd);
let mut wgl = wgl::Wgl::new(&mut display);
From 2b90706d9ba9e69a09009709e7ca3940a5f9a906 Mon Sep 17 00:00:00 2001
From: TheRedDeveloper
Date: Wed, 18 Feb 2026 18:06:33 +0100
Subject: [PATCH 3/3] pass HWND in set_display, remove get_window_hwnd
---
src/lib.rs | 2 +-
src/native/windows.rs | 11 +----------
2 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/src/lib.rs b/src/lib.rs
index a8ab98ce..ba32be01 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -446,7 +446,7 @@ pub mod window {
/// Only available on Windows.
#[cfg(target_os = "windows")]
pub fn windows_hwnd() -> *mut std::ffi::c_void {
- crate::native::windows::get_window_hwnd()
+ crate::native_display().lock().unwrap().hwnd
}
}
diff --git a/src/native/windows.rs b/src/native/windows.rs
index 371c3dab..cf46ed3a 100644
--- a/src/native/windows.rs
+++ b/src/native/windows.rs
@@ -47,13 +47,6 @@ const WM_KILLFOCUS: UINT = 0x0008;
use std::sync::atomic::AtomicBool;
static IME_USER_DISABLED: AtomicBool = AtomicBool::new(false);
-/// Get the main window HWND as a raw pointer.
-///
-/// Returns `null_mut()` if the window has not been created yet.
-pub(crate) fn get_window_hwnd() -> *mut std::ffi::c_void {
- crate::native_display().lock().unwrap().hwnd
-}
-
// IME composition form constants
const CFS_POINT: DWORD = 0x0002;
const CFS_CANDIDATEPOS: DWORD = 0x0040;
@@ -1210,12 +1203,10 @@ where
high_dpi: conf.high_dpi,
dpi_scale: display.window_scale,
blocking_event_loop: conf.platform.blocking_event_loop,
+ hwnd: wnd as *mut std::ffi::c_void,
..NativeDisplayData::new(conf.window_width, conf.window_height, tx, clipboard)
});
- // Store the HWND in NativeDisplayData so external code can access it via window::windows_hwnd()
- crate::native_display().lock().unwrap().hwnd = wnd as *mut std::ffi::c_void;
-
display.update_dimensions(wnd);
let mut wgl = wgl::Wgl::new(&mut display);