@@ -2,27 +2,76 @@ use windows::core::*;
22use windows:: Win32 :: Foundation :: * ;
33use windows:: Win32 :: System :: LibraryLoader :: * ;
44use windows:: Win32 :: UI :: WindowsAndMessaging :: * ;
5- use windows_registry:: CURRENT_USER ;
65use winit:: event_loop:: EventLoopProxy ;
76
87use crate :: app:: AppMessage ;
9-
10- #[ cfg( debug_assertions) ]
11- const APP_REG_KEY : & str = "SOFTWARE\\ amrbashir\\ komorebi-switcher-debug" ;
12- #[ cfg( not( debug_assertions) ) ]
13- const APP_REG_KEY : & str = "SOFTWARE\\ amrbashir\\ komorebi-switcher" ;
14-
15- const WINDOW_POS_X_KEY : & str = "window-pos-x" ;
16- const WINDOW_POS_Y_KEY : & str = "window-pos-y" ;
8+ use crate :: main_window:: MainWindowView ;
9+ use crate :: window_registry_info:: WindowRegistryInfo ;
1710
1811#[ cfg( debug_assertions) ]
1912const HOST_CLASSNAME : PCWSTR = w ! ( "komorebi-switcher-debug::host" ) ;
2013#[ cfg( not( debug_assertions) ) ]
2114const HOST_CLASSNAME : PCWSTR = w ! ( "komorebi-switcher::host" ) ;
2215
16+ pub unsafe fn create_host (
17+ taskbar_hwnd : HWND ,
18+ proxy : EventLoopProxy < AppMessage > ,
19+ window_info : & WindowRegistryInfo ,
20+ ) -> anyhow:: Result < HWND > {
21+ let hinstance = unsafe { GetModuleHandleW ( None ) } ?;
22+
23+ let mut rect = RECT :: default ( ) ;
24+ GetClientRect ( taskbar_hwnd, & mut rect) ?;
25+
26+ let wc = WNDCLASSW {
27+ hInstance : hinstance. into ( ) ,
28+ lpszClassName : HOST_CLASSNAME ,
29+ style : CS_HREDRAW | CS_VREDRAW ,
30+ lpfnWndProc : Some ( wndproc_host) ,
31+ ..Default :: default ( )
32+ } ;
33+
34+ let atom = RegisterClassW ( & wc) ;
35+ debug_assert ! ( atom != 0 ) ;
36+
37+ let userdata = WndProcUserData { proxy } ;
38+
39+ let height = if window_info. auto_height {
40+ rect. bottom - rect. top
41+ } else {
42+ window_info. height
43+ } ;
44+
45+ let hwnd = CreateWindowExW (
46+ WS_EX_NOACTIVATE | WS_EX_NOREDIRECTIONBITMAP ,
47+ HOST_CLASSNAME ,
48+ PCWSTR :: null ( ) ,
49+ WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS ,
50+ window_info. x ,
51+ window_info. y ,
52+ window_info. width ,
53+ height,
54+ Some ( taskbar_hwnd) ,
55+ None ,
56+ None ,
57+ Some ( Box :: into_raw ( Box :: new ( userdata) ) as _ ) ,
58+ ) ?;
59+
60+ SetWindowPos (
61+ hwnd,
62+ Some ( HWND_TOP ) ,
63+ 0 ,
64+ 0 ,
65+ 0 ,
66+ 0 ,
67+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ,
68+ ) ?;
69+
70+ Ok ( hwnd)
71+ }
72+
2373struct WndProcUserData {
2474 proxy : EventLoopProxy < AppMessage > ,
25- taskbar_hwnd : HWND ,
2675}
2776
2877impl WndProcUserData {
@@ -31,23 +80,6 @@ impl WndProcUserData {
3180 }
3281}
3382
34- unsafe extern "system" fn enum_child_proc ( hwnd : HWND , lparam : LPARAM ) -> BOOL {
35- let children = & mut * ( lparam. 0 as * mut Vec < HWND > ) ;
36- children. push ( hwnd) ;
37- true . into ( )
38- }
39-
40- fn enum_child_windows ( hwnd : HWND ) -> Vec < HWND > {
41- let mut children = Vec :: new ( ) ;
42-
43- let children_ptr = & mut children as * mut Vec < HWND > ;
44- let children_ptr = LPARAM ( children_ptr as _ ) ;
45-
46- let _ = unsafe { EnumChildWindows ( Some ( hwnd) , Some ( enum_child_proc) , children_ptr) } ;
47-
48- children
49- }
50-
5183unsafe extern "system" fn wndproc_host (
5284 hwnd : HWND ,
5385 msg : u32 ,
@@ -70,43 +102,14 @@ unsafe extern "system" fn wndproc_host(
70102 }
71103 }
72104
73- // Disable position changes in y direction
74- // and clamp x direction to stay visible in taskbar
75- WM_WINDOWPOSCHANGING => {
76- let window_pos = & mut * ( lparam. 0 as * mut WINDOWPOS ) ;
77- window_pos. y = 0 ;
78-
79- let userdata = WndProcUserData :: from_hwnd ( hwnd) ;
80-
81- let mut rect = RECT :: default ( ) ;
82- if GetClientRect ( userdata. taskbar_hwnd , & mut rect) . is_ok ( ) {
83- window_pos. x = window_pos. x . max ( 0 ) . min ( rect. right - window_pos. cx ) ;
84- }
85- }
86-
87- // Save host position to be loaded on startup
88- WM_WINDOWPOSCHANGED => {
89- let window_pos = & * ( lparam. 0 as * const WINDOWPOS ) ;
90-
91- let key = CURRENT_USER . create ( APP_REG_KEY ) ;
92- if let Ok ( key) = key {
93- let x = window_pos. x ;
94- let y = window_pos. y ;
95-
96- tracing:: debug!( "Storing window position into registry {x},{y}" ) ;
97-
98- if let Err ( e) = key. set_string ( WINDOW_POS_X_KEY , & x. to_string ( ) ) {
99- tracing:: error!( "Failed to store window pos x into registry: {e}" )
100- }
101-
102- if let Err ( e) = key. set_string ( WINDOW_POS_Y_KEY , & y. to_string ( ) ) {
103- tracing:: error!( "Failed to store window pos y into registry: {e}" )
104- }
105- }
106- }
107-
108105 // Resize children when this host is resized
109106 WM_SIZE => {
107+ // Skip resizing children if this host is in resize mode
108+ let prop = GetPropW ( hwnd, MainWindowView :: IN_RESIZE_PROP ) ;
109+ if prop. 0 as isize != 0 {
110+ return DefWindowProcW ( hwnd, msg, wparam, lparam) ;
111+ }
112+
110113 let mut rect = RECT :: default ( ) ;
111114 if GetClientRect ( hwnd, & mut rect) . is_ok ( ) {
112115 let width = rect. right - rect. left ;
@@ -154,62 +157,19 @@ unsafe extern "system" fn wndproc_host(
154157 DefWindowProcW ( hwnd, msg, wparam, lparam)
155158}
156159
157- pub unsafe fn create_host (
158- taskbar_hwnd : HWND ,
159- proxy : EventLoopProxy < AppMessage > ,
160- ) -> anyhow:: Result < HWND > {
161- let hinstance = unsafe { GetModuleHandleW ( None ) } ?;
162-
163- let mut rect = RECT :: default ( ) ;
164- GetClientRect ( taskbar_hwnd, & mut rect) ?;
165-
166- let wc = WNDCLASSW {
167- hInstance : hinstance. into ( ) ,
168- lpszClassName : HOST_CLASSNAME ,
169- style : CS_HREDRAW | CS_VREDRAW ,
170- lpfnWndProc : Some ( wndproc_host) ,
171- ..Default :: default ( )
172- } ;
173-
174- let atom = RegisterClassW ( & wc) ;
175- debug_assert ! ( atom != 0 ) ;
176-
177- tracing:: debug!( "Loading window position from registry" ) ;
178- let key = CURRENT_USER . create ( APP_REG_KEY ) ?;
179- let window_pos_x = key. get_string ( WINDOW_POS_X_KEY ) . ok ( ) ;
180- let window_pos_y = key. get_string ( WINDOW_POS_Y_KEY ) . ok ( ) ;
181- let window_pos_x = window_pos_x. and_then ( |s| s. parse ( ) . ok ( ) ) ;
182- let window_pos_y = window_pos_y. and_then ( |s| s. parse ( ) . ok ( ) ) ;
160+ unsafe extern "system" fn enum_child_proc ( hwnd : HWND , lparam : LPARAM ) -> BOOL {
161+ let children = & mut * ( lparam. 0 as * mut Vec < HWND > ) ;
162+ children. push ( hwnd) ;
163+ true . into ( )
164+ }
183165
184- let userdata = WndProcUserData {
185- proxy,
186- taskbar_hwnd,
187- } ;
166+ fn enum_child_windows ( hwnd : HWND ) -> Vec < HWND > {
167+ let mut children = Vec :: new ( ) ;
188168
189- let hwnd = CreateWindowExW (
190- WS_EX_NOACTIVATE | WS_EX_NOREDIRECTIONBITMAP ,
191- HOST_CLASSNAME ,
192- PCWSTR :: null ( ) ,
193- WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS ,
194- window_pos_x. unwrap_or ( 16 ) ,
195- window_pos_y. unwrap_or ( 0 ) ,
196- 200 ,
197- rect. bottom - rect. top ,
198- Some ( taskbar_hwnd) ,
199- None ,
200- None ,
201- Some ( Box :: into_raw ( Box :: new ( userdata) ) as _ ) ,
202- ) ?;
169+ let children_ptr = & mut children as * mut Vec < HWND > ;
170+ let children_ptr = LPARAM ( children_ptr as _ ) ;
203171
204- SetWindowPos (
205- hwnd,
206- Some ( HWND_TOP ) ,
207- 0 ,
208- 0 ,
209- 0 ,
210- 0 ,
211- SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE ,
212- ) ?;
172+ let _ = unsafe { EnumChildWindows ( Some ( hwnd) , Some ( enum_child_proc) , children_ptr) } ;
213173
214- Ok ( hwnd )
174+ children
215175}
0 commit comments