mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-04 07:28:13 +08:00
Desktop: Add window abstraction layer (#3302)
* add bundle for mac os and windows * Fix bundle name This name gets used as the display name of the app on mac os, shorter name looks better and is more consistent. * preserve std out by running bin directly * bundle placeholder on linux * fix linux * window abstraction * fix linux * fix windows * fix fmt * remove windows file that was left * use self
This commit is contained in:
+10
-19
@@ -1,7 +1,6 @@
|
|||||||
use rfd::AsyncFileDialog;
|
use rfd::AsyncFileDialog;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::mpsc::Receiver;
|
use std::sync::mpsc::Receiver;
|
||||||
use std::sync::mpsc::Sender;
|
use std::sync::mpsc::Sender;
|
||||||
use std::sync::mpsc::SyncSender;
|
use std::sync::mpsc::SyncSender;
|
||||||
@@ -12,22 +11,20 @@ use winit::application::ApplicationHandler;
|
|||||||
use winit::event::WindowEvent;
|
use winit::event::WindowEvent;
|
||||||
use winit::event_loop::ActiveEventLoop;
|
use winit::event_loop::ActiveEventLoop;
|
||||||
use winit::event_loop::ControlFlow;
|
use winit::event_loop::ControlFlow;
|
||||||
use winit::window::Window;
|
|
||||||
use winit::window::WindowId;
|
use winit::window::WindowId;
|
||||||
|
|
||||||
use crate::cef;
|
use crate::cef;
|
||||||
use crate::consts::CEF_MESSAGE_LOOP_MAX_ITERATIONS;
|
use crate::consts::CEF_MESSAGE_LOOP_MAX_ITERATIONS;
|
||||||
use crate::event::{AppEvent, AppEventScheduler};
|
use crate::event::{AppEvent, AppEventScheduler};
|
||||||
use crate::native_window;
|
|
||||||
use crate::persist::PersistentData;
|
use crate::persist::PersistentData;
|
||||||
use crate::render::GraphicsState;
|
use crate::render::GraphicsState;
|
||||||
|
use crate::window::Window;
|
||||||
use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Platform};
|
use graphite_desktop_wrapper::messages::{DesktopFrontendMessage, DesktopWrapperMessage, Platform};
|
||||||
use graphite_desktop_wrapper::{DesktopWrapper, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages};
|
use graphite_desktop_wrapper::{DesktopWrapper, NodeGraphExecutionResult, WgpuContext, serialize_frontend_messages};
|
||||||
|
|
||||||
pub(crate) struct App {
|
pub(crate) struct App {
|
||||||
cef_context: Box<dyn cef::CefContext>,
|
cef_context: Box<dyn cef::CefContext>,
|
||||||
window: Option<Arc<dyn Window>>,
|
window: Option<Window>,
|
||||||
native_window: native_window::NativeWindowHandle,
|
|
||||||
cef_schedule: Option<Instant>,
|
cef_schedule: Option<Instant>,
|
||||||
cef_window_size_sender: Sender<cef::WindowSize>,
|
cef_window_size_sender: Sender<cef::WindowSize>,
|
||||||
graphics_state: Option<GraphicsState>,
|
graphics_state: Option<GraphicsState>,
|
||||||
@@ -82,7 +79,6 @@ impl App {
|
|||||||
web_communication_initialized: false,
|
web_communication_initialized: false,
|
||||||
web_communication_startup_buffer: Vec::new(),
|
web_communication_startup_buffer: Vec::new(),
|
||||||
persistent_data,
|
persistent_data,
|
||||||
native_window: Default::default(),
|
|
||||||
launch_documents,
|
launch_documents,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -173,18 +169,17 @@ impl App {
|
|||||||
}
|
}
|
||||||
DesktopFrontendMessage::MinimizeWindow => {
|
DesktopFrontendMessage::MinimizeWindow => {
|
||||||
if let Some(window) = &self.window {
|
if let Some(window) = &self.window {
|
||||||
window.set_minimized(true);
|
window.minimize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DesktopFrontendMessage::MaximizeWindow => {
|
DesktopFrontendMessage::MaximizeWindow => {
|
||||||
if let Some(window) = &self.window {
|
if let Some(window) = &self.window {
|
||||||
let maximized = !window.is_maximized();
|
window.toggle_maximize();
|
||||||
window.set_maximized(maximized);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DesktopFrontendMessage::DragWindow => {
|
DesktopFrontendMessage::DragWindow => {
|
||||||
if let Some(window) = &self.window {
|
if let Some(window) = &self.window {
|
||||||
let _ = window.drag_window();
|
let _ = window.start_drag();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DesktopFrontendMessage::CloseWindow => {
|
DesktopFrontendMessage::CloseWindow => {
|
||||||
@@ -348,15 +343,11 @@ impl App {
|
|||||||
}
|
}
|
||||||
impl ApplicationHandler for App {
|
impl ApplicationHandler for App {
|
||||||
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
fn can_create_surfaces(&mut self, event_loop: &dyn ActiveEventLoop) {
|
||||||
let window_attributes = self.native_window.build(event_loop);
|
let window = Window::new(event_loop);
|
||||||
|
|
||||||
let window: Arc<dyn Window> = Arc::from(event_loop.create_window(window_attributes).unwrap());
|
|
||||||
|
|
||||||
self.native_window.setup(window.as_ref());
|
|
||||||
|
|
||||||
let graphics_state = GraphicsState::new(window.clone(), self.wgpu_context.clone());
|
|
||||||
|
|
||||||
self.window = Some(window);
|
self.window = Some(window);
|
||||||
|
|
||||||
|
let graphics_state = GraphicsState::new(self.window.as_ref().unwrap(), self.wgpu_context.clone());
|
||||||
|
|
||||||
self.graphics_state = Some(graphics_state);
|
self.graphics_state = Some(graphics_state);
|
||||||
|
|
||||||
tracing::info!("Winit window created and ready");
|
tracing::info!("Winit window created and ready");
|
||||||
@@ -397,7 +388,7 @@ impl ApplicationHandler for App {
|
|||||||
let Some(ref mut graphics_state) = self.graphics_state else { return };
|
let Some(ref mut graphics_state) = self.graphics_state else { return };
|
||||||
// Only rerender once we have a new UI texture to display
|
// Only rerender once we have a new UI texture to display
|
||||||
if let Some(window) = &self.window {
|
if let Some(window) = &self.window {
|
||||||
match graphics_state.render(window.as_ref()) {
|
match graphics_state.render(window) {
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
Err(wgpu::SurfaceError::Lost) => {
|
Err(wgpu::SurfaceError::Lost) => {
|
||||||
tracing::warn!("lost surface");
|
tracing::warn!("lost surface");
|
||||||
|
|||||||
+1
-1
@@ -10,9 +10,9 @@ mod cef;
|
|||||||
mod cli;
|
mod cli;
|
||||||
mod dirs;
|
mod dirs;
|
||||||
mod event;
|
mod event;
|
||||||
mod native_window;
|
|
||||||
mod persist;
|
mod persist;
|
||||||
mod render;
|
mod render;
|
||||||
|
mod window;
|
||||||
|
|
||||||
mod gpu_context;
|
mod gpu_context;
|
||||||
|
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
use winit::event_loop::ActiveEventLoop;
|
|
||||||
use winit::window::{Window, WindowAttributes};
|
|
||||||
|
|
||||||
use crate::consts::APP_NAME;
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
mod windows;
|
|
||||||
|
|
||||||
pub(crate) enum NativeWindowHandle {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
#[expect(private_interfaces, dead_code)]
|
|
||||||
Windows(windows::WindowsNativeWindowHandle),
|
|
||||||
None,
|
|
||||||
}
|
|
||||||
impl Default for NativeWindowHandle {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl NativeWindowHandle {
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub(super) fn build(&mut self, event_loop: &dyn ActiveEventLoop) -> WindowAttributes {
|
|
||||||
let mut window = WindowAttributes::default()
|
|
||||||
.with_title(APP_NAME)
|
|
||||||
.with_min_surface_size(winit::dpi::LogicalSize::new(400, 300))
|
|
||||||
.with_surface_size(winit::dpi::LogicalSize::new(1200, 800))
|
|
||||||
.with_resizable(true)
|
|
||||||
.with_theme(Some(winit::window::Theme::Dark));
|
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
|
||||||
{
|
|
||||||
use crate::consts::{APP_ID, APP_NAME};
|
|
||||||
use winit::platform::wayland::ActiveEventLoopExtWayland;
|
|
||||||
use winit::platform::wayland::WindowAttributesWayland;
|
|
||||||
use winit::platform::x11::WindowAttributesX11;
|
|
||||||
window = if event_loop.is_wayland() {
|
|
||||||
let wayland_window = WindowAttributesWayland::default().with_name(APP_ID, "").with_prefer_csd(true);
|
|
||||||
window.with_platform_attributes(Box::new(wayland_window))
|
|
||||||
} else {
|
|
||||||
let x11_window = WindowAttributesX11::default().with_name(APP_ID, APP_NAME);
|
|
||||||
window.with_platform_attributes(Box::new(x11_window))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
{
|
|
||||||
if let Ok(win_icon) = winit::platform::windows::WinIcon::from_resource(1, None) {
|
|
||||||
let icon = winit::icon::Icon(std::sync::Arc::new(win_icon));
|
|
||||||
window = window.with_window_icon(Some(icon));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
|
||||||
{
|
|
||||||
let mac_window = winit::platform::macos::WindowAttributesMacOS::default()
|
|
||||||
.with_titlebar_transparent(true)
|
|
||||||
.with_fullsize_content_view(true)
|
|
||||||
.with_title_hidden(true);
|
|
||||||
window = window.with_platform_attributes(Box::new(mac_window));
|
|
||||||
}
|
|
||||||
|
|
||||||
window
|
|
||||||
}
|
|
||||||
#[allow(unused_variables)]
|
|
||||||
pub(crate) fn setup(&mut self, window: &dyn Window) {
|
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
{
|
|
||||||
*self = NativeWindowHandle::Windows(windows::WindowsNativeWindowHandle::new(window));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
use std::sync::Arc;
|
use crate::window::Window;
|
||||||
use winit::window::Window;
|
|
||||||
|
|
||||||
use graphite_desktop_wrapper::{Color, WgpuContext, WgpuExecutor};
|
use graphite_desktop_wrapper::{Color, WgpuContext, WgpuExecutor};
|
||||||
|
|
||||||
@@ -24,10 +23,9 @@ pub(crate) struct GraphicsState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl GraphicsState {
|
impl GraphicsState {
|
||||||
pub(crate) fn new(window: Arc<dyn Window>, context: WgpuContext) -> Self {
|
pub(crate) fn new(window: &Window, context: WgpuContext) -> Self {
|
||||||
let size = window.surface_size();
|
let size = window.surface_size();
|
||||||
|
let surface = window.create_surface(context.instance.clone());
|
||||||
let surface = context.instance.create_surface(window).unwrap();
|
|
||||||
|
|
||||||
let surface_caps = surface.get_capabilities(&context.adapter);
|
let surface_caps = surface.get_capabilities(&context.adapter);
|
||||||
let surface_format = surface_caps.formats.iter().find(|f| f.is_srgb()).copied().unwrap_or(surface_caps.formats[0]);
|
let surface_format = surface_caps.formats.iter().find(|f| f.is_srgb()).copied().unwrap_or(surface_caps.formats[0]);
|
||||||
@@ -232,7 +230,7 @@ impl GraphicsState {
|
|||||||
self.bind_overlays_texture(texture);
|
self.bind_overlays_texture(texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn render(&mut self, window: &dyn Window) -> Result<(), wgpu::SurfaceError> {
|
pub(crate) fn render(&mut self, window: &Window) -> Result<(), wgpu::SurfaceError> {
|
||||||
if let Some(scene) = self.overlays_scene.take() {
|
if let Some(scene) = self.overlays_scene.take() {
|
||||||
self.render_overlays(scene);
|
self.render_overlays(scene);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use winit::event_loop::ActiveEventLoop;
|
||||||
|
use winit::window::{Window as WinitWindow, WindowAttributes};
|
||||||
|
|
||||||
|
use crate::consts::APP_NAME;
|
||||||
|
|
||||||
|
pub(crate) trait NativeWindow {
|
||||||
|
fn configure(attributes: WindowAttributes, event_loop: &dyn ActiveEventLoop) -> WindowAttributes;
|
||||||
|
fn new(window: &dyn WinitWindow) -> Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
mod linux;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
use linux as native;
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
mod mac;
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
use mac as native;
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
mod win;
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
use win as native;
|
||||||
|
|
||||||
|
pub(crate) struct Window {
|
||||||
|
winit_window: Arc<dyn winit::window::Window>,
|
||||||
|
#[allow(dead_code)]
|
||||||
|
native_handle: native::NativeWindowImpl,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Window {
|
||||||
|
pub(crate) fn new(event_loop: &dyn ActiveEventLoop) -> Self {
|
||||||
|
let mut attributes = WindowAttributes::default()
|
||||||
|
.with_title(APP_NAME)
|
||||||
|
.with_min_surface_size(winit::dpi::LogicalSize::new(400, 300))
|
||||||
|
.with_surface_size(winit::dpi::LogicalSize::new(1200, 800))
|
||||||
|
.with_resizable(true)
|
||||||
|
.with_theme(Some(winit::window::Theme::Dark));
|
||||||
|
|
||||||
|
attributes = native::NativeWindowImpl::configure(attributes, event_loop);
|
||||||
|
|
||||||
|
let winit_window = event_loop.create_window(attributes).unwrap();
|
||||||
|
let native_handle = native::NativeWindowImpl::new(winit_window.as_ref());
|
||||||
|
Self {
|
||||||
|
winit_window: winit_window.into(),
|
||||||
|
native_handle,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn request_redraw(&self) {
|
||||||
|
self.winit_window.request_redraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn create_surface(&self, instance: Arc<wgpu::Instance>) -> wgpu::Surface<'static> {
|
||||||
|
instance.create_surface(self.winit_window.clone()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn pre_present_notify(&self) {
|
||||||
|
self.winit_window.pre_present_notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn surface_size(&self) -> winit::dpi::PhysicalSize<u32> {
|
||||||
|
self.winit_window.surface_size()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn minimize(&self) {
|
||||||
|
self.winit_window.set_minimized(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn toggle_maximize(&self) {
|
||||||
|
self.winit_window.set_maximized(!self.winit_window.is_maximized());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn is_maximized(&self) -> bool {
|
||||||
|
self.winit_window.is_maximized()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn start_drag(&self) {
|
||||||
|
let _ = self.winit_window.drag_window();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn set_cursor(&self, cursor: winit::cursor::Cursor) {
|
||||||
|
self.winit_window.set_cursor(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
use winit::event_loop::ActiveEventLoop;
|
||||||
|
use winit::platform::wayland::ActiveEventLoopExtWayland;
|
||||||
|
use winit::platform::wayland::WindowAttributesWayland;
|
||||||
|
use winit::platform::x11::WindowAttributesX11;
|
||||||
|
use winit::window::{Window, WindowAttributes};
|
||||||
|
|
||||||
|
use crate::consts::{APP_ID, APP_NAME};
|
||||||
|
|
||||||
|
use super::NativeWindow;
|
||||||
|
|
||||||
|
pub(super) struct NativeWindowImpl {}
|
||||||
|
|
||||||
|
impl NativeWindow for NativeWindowImpl {
|
||||||
|
fn configure(attributes: WindowAttributes, event_loop: &dyn ActiveEventLoop) -> WindowAttributes {
|
||||||
|
if event_loop.is_wayland() {
|
||||||
|
let wayland_attributes = WindowAttributesWayland::default().with_name(APP_ID, "").with_prefer_csd(true);
|
||||||
|
attributes.with_platform_attributes(Box::new(wayland_attributes))
|
||||||
|
} else {
|
||||||
|
let x11_attributes = WindowAttributesX11::default().with_name(APP_ID, APP_NAME);
|
||||||
|
attributes.with_platform_attributes(Box::new(x11_attributes))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new(_window: &dyn Window) -> Self {
|
||||||
|
NativeWindowImpl {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
use winit::event_loop::ActiveEventLoop;
|
||||||
|
use winit::window::{Window, WindowAttributes};
|
||||||
|
|
||||||
|
use super::NativeWindow;
|
||||||
|
|
||||||
|
pub(super) struct NativeWindowImpl {}
|
||||||
|
|
||||||
|
impl NativeWindow for NativeWindowImpl {
|
||||||
|
fn configure(attributes: WindowAttributes, _event_loop: &dyn ActiveEventLoop) -> WindowAttributes {
|
||||||
|
let mac_window = winit::platform::macos::WindowAttributesMacOS::default()
|
||||||
|
.with_titlebar_transparent(true)
|
||||||
|
.with_fullsize_content_view(true)
|
||||||
|
.with_title_hidden(true);
|
||||||
|
attributes.with_platform_attributes(Box::new(mac_window))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new(_window: &dyn Window) -> Self {
|
||||||
|
NativeWindowImpl {}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
use winit::event_loop::ActiveEventLoop;
|
||||||
|
use winit::window::{Window, WindowAttributes};
|
||||||
|
|
||||||
|
use super::NativeWindow;
|
||||||
|
|
||||||
|
pub(super) struct NativeWindowImpl {
|
||||||
|
native_handle: native_handle::NativeWindowHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NativeWindow for NativeWindowImpl {
|
||||||
|
fn configure(attributes: WindowAttributes, _event_loop: &dyn ActiveEventLoop) -> WindowAttributes {
|
||||||
|
if let Ok(win_icon) = winit::platform::windows::WinIcon::from_resource(1, None) {
|
||||||
|
let icon = winit::icon::Icon(std::sync::Arc::new(win_icon));
|
||||||
|
attributes.with_window_icon(Some(icon))
|
||||||
|
} else {
|
||||||
|
attributes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new(window: &dyn Window) -> Self {
|
||||||
|
let native_handle = native_handle::NativeWindowHandle::new(window);
|
||||||
|
NativeWindowImpl { native_handle }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for NativeWindowImpl {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.native_handle.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod native_handle;
|
||||||
@@ -21,29 +21,14 @@ use windows::Win32::UI::WindowsAndMessaging::*;
|
|||||||
use windows::core::PCWSTR;
|
use windows::core::PCWSTR;
|
||||||
use winit::window::Window;
|
use winit::window::Window;
|
||||||
|
|
||||||
pub(super) struct WindowsNativeWindowHandle {
|
|
||||||
inner: WindowsNativeWindowHandleInner,
|
|
||||||
}
|
|
||||||
impl WindowsNativeWindowHandle {
|
|
||||||
pub(super) fn new(window: &dyn Window) -> Self {
|
|
||||||
let inner = WindowsNativeWindowHandleInner::new(window);
|
|
||||||
WindowsNativeWindowHandle { inner }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl Drop for WindowsNativeWindowHandle {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.inner.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct WindowsNativeWindowHandleInner {
|
pub(super) struct NativeWindowHandle {
|
||||||
main: HWND,
|
main: HWND,
|
||||||
helper: HWND,
|
helper: HWND,
|
||||||
prev_window_message_handler: isize,
|
prev_window_message_handler: isize,
|
||||||
}
|
}
|
||||||
impl WindowsNativeWindowHandleInner {
|
impl NativeWindowHandle {
|
||||||
fn new(window: &dyn Window) -> WindowsNativeWindowHandleInner {
|
pub(super) fn new(window: &dyn Window) -> NativeWindowHandle {
|
||||||
// Extract Win32 HWND from winit.
|
// Extract Win32 HWND from winit.
|
||||||
let hwnd = match window.window_handle().expect("No window handle").as_raw() {
|
let hwnd = match window.window_handle().expect("No window handle").as_raw() {
|
||||||
RawWindowHandle::Win32(h) => HWND(h.hwnd.get() as *mut std::ffi::c_void),
|
RawWindowHandle::Win32(h) => HWND(h.hwnd.get() as *mut std::ffi::c_void),
|
||||||
@@ -85,7 +70,7 @@ impl WindowsNativeWindowHandleInner {
|
|||||||
panic!("SetWindowLongPtrW failed");
|
panic!("SetWindowLongPtrW failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
let inner = WindowsNativeWindowHandleInner {
|
let inner = NativeWindowHandle {
|
||||||
main: hwnd,
|
main: hwnd,
|
||||||
helper,
|
helper,
|
||||||
prev_window_message_handler,
|
prev_window_message_handler,
|
||||||
@@ -115,7 +100,7 @@ impl WindowsNativeWindowHandleInner {
|
|||||||
inner
|
inner
|
||||||
}
|
}
|
||||||
|
|
||||||
fn destroy(&self) {
|
pub(super) fn destroy(&self) {
|
||||||
registry::remove_by_main(self.main);
|
registry::remove_by_main(self.main);
|
||||||
|
|
||||||
// Undo subclassing and destroy the helper window.
|
// Undo subclassing and destroy the helper window.
|
||||||
@@ -130,13 +115,13 @@ mod registry {
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use windows::Win32::Foundation::HWND;
|
use windows::Win32::Foundation::HWND;
|
||||||
|
|
||||||
use crate::native_window::windows::WindowsNativeWindowHandleInner;
|
use super::NativeWindowHandle;
|
||||||
|
|
||||||
thread_local! {
|
thread_local! {
|
||||||
static STORE: RefCell<Vec<WindowsNativeWindowHandleInner>> = RefCell::new(Vec::new());
|
static STORE: RefCell<Vec<NativeWindowHandle>> = RefCell::new(Vec::new());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn find_by_main(main: HWND) -> Option<WindowsNativeWindowHandleInner> {
|
pub(super) fn find_by_main(main: HWND) -> Option<NativeWindowHandle> {
|
||||||
STORE.with_borrow(|vec| vec.iter().find(|h| h.main == main).cloned())
|
STORE.with_borrow(|vec| vec.iter().find(|h| h.main == main).cloned())
|
||||||
}
|
}
|
||||||
pub(super) fn remove_by_main(main: HWND) {
|
pub(super) fn remove_by_main(main: HWND) {
|
||||||
@@ -144,7 +129,7 @@ mod registry {
|
|||||||
vec.retain(|h| h.main != main);
|
vec.retain(|h| h.main != main);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
pub(super) fn insert(handle: &WindowsNativeWindowHandleInner) {
|
pub(super) fn insert(handle: &NativeWindowHandle) {
|
||||||
STORE.with_borrow_mut(|vec| {
|
STORE.with_borrow_mut(|vec| {
|
||||||
vec.push(handle.clone());
|
vec.push(handle.clone());
|
||||||
});
|
});
|
||||||
Reference in New Issue
Block a user