diff --git a/komorebi/src/border_manager/border.rs b/komorebi/src/border_manager/border.rs index 839b4e40..17ee8887 100644 --- a/komorebi/src/border_manager/border.rs +++ b/komorebi/src/border_manager/border.rs @@ -3,6 +3,7 @@ use crate::border_manager::WindowKind; use crate::border_manager::BORDER_OFFSET; use crate::border_manager::BORDER_WIDTH; use crate::border_manager::FOCUS_STATE; +use crate::border_manager::RENDER_TARGETS; use crate::border_manager::STYLE; use crate::border_manager::Z_ORDER; use crate::core::BorderStyle; @@ -130,9 +131,37 @@ impl Border { Ok(()) }); - Ok(Self { - hwnd: hwnd_receiver.recv()?, - }) + let hwnd = hwnd_receiver.recv()?; + + let hwnd_render_target_properties = D2D1_HWND_RENDER_TARGET_PROPERTIES { + hwnd: HWND(windows_api::as_ptr!(hwnd)), + pixelSize: Default::default(), + presentOptions: D2D1_PRESENT_OPTIONS_IMMEDIATELY, + }; + + let render_target_properties = D2D1_RENDER_TARGET_PROPERTIES { + r#type: D2D1_RENDER_TARGET_TYPE_DEFAULT, + pixelFormat: D2D1_PIXEL_FORMAT { + format: DXGI_FORMAT_UNKNOWN, + alphaMode: D2D1_ALPHA_MODE_PREMULTIPLIED, + }, + dpiX: 96.0, + dpiY: 96.0, + ..Default::default() + }; + + match unsafe { + RENDER_FACTORY + .CreateHwndRenderTarget(&render_target_properties, &hwnd_render_target_properties) + } { + Ok(render_target) => unsafe { + render_target.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); + let mut render_targets = RENDER_TARGETS.lock(); + render_targets.insert(hwnd, render_target); + Ok(Self { hwnd }) + }, + Err(error) => Err(error.into()), + } } pub fn destroy(&self) -> color_eyre::Result<()> { @@ -173,29 +202,8 @@ impl Border { match message { WM_PAINT => { if let Ok(rect) = WindowsApi::window_rect(window.0 as isize) { - let hwnd_render_target_properties = D2D1_HWND_RENDER_TARGET_PROPERTIES { - hwnd: window, - pixelSize: Default::default(), - presentOptions: D2D1_PRESENT_OPTIONS_IMMEDIATELY, - }; - - let render_target_properties = D2D1_RENDER_TARGET_PROPERTIES { - r#type: D2D1_RENDER_TARGET_TYPE_DEFAULT, - pixelFormat: D2D1_PIXEL_FORMAT { - format: DXGI_FORMAT_UNKNOWN, - alphaMode: D2D1_ALPHA_MODE_PREMULTIPLIED, - }, - dpiX: 96.0, - dpiY: 96.0, - ..Default::default() - }; - - if let Ok(render_target) = RENDER_FACTORY.CreateHwndRenderTarget( - &render_target_properties, - &hwnd_render_target_properties, - ) { - render_target.SetAntialiasMode(D2D1_ANTIALIAS_MODE_PER_PRIMITIVE); - + let render_targets = RENDER_TARGETS.lock(); + if let Some(render_target) = render_targets.get(&(window.0 as isize)) { let brush_properties = D2D1_BRUSH_PROPERTIES { opacity: 1.0, transform: Matrix3x2::identity(), diff --git a/komorebi/src/border_manager/mod.rs b/komorebi/src/border_manager/mod.rs index 48271b5f..0e64a6c8 100644 --- a/komorebi/src/border_manager/mod.rs +++ b/komorebi/src/border_manager/mod.rs @@ -1,7 +1,6 @@ #![deny(clippy::unwrap_used, clippy::expect_used)] mod border; - use crate::core::BorderImplementation; use crate::core::BorderStyle; use crate::core::WindowKind; @@ -30,6 +29,7 @@ use std::sync::atomic::AtomicU32; use std::sync::atomic::Ordering; use std::sync::Arc; use std::sync::OnceLock; +use windows::Win32::Graphics::Direct2D::ID2D1HwndRenderTarget; pub static BORDER_WIDTH: AtomicI32 = AtomicI32::new(8); pub static BORDER_OFFSET: AtomicI32 = AtomicI32::new(-1); @@ -57,6 +57,8 @@ lazy_static! { static ref BORDERS_MONITORS: Mutex> = Mutex::new(HashMap::new()); static ref BORDER_STATE: Mutex> = Mutex::new(HashMap::new()); static ref FOCUS_STATE: Mutex> = Mutex::new(HashMap::new()); + static ref RENDER_TARGETS: Mutex> = + Mutex::new(HashMap::new()); } pub struct Notification(pub Option);