From 2ab5cbaa6c8981f4fb10aa774e6c343f4e89eaf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=97=B0=EC=9A=B0?= Date: Wed, 10 Jun 2026 22:39:41 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EC=98=A4=EB=B2=84=EB=A0=88=EC=9D=B4=20?= =?UTF-8?q?=EC=98=B5=EC=85=98=20=ED=86=A0=EA=B8=80=20=EC=8B=9C=20=EC=B0=BD?= =?UTF-8?q?=EC=9D=B4=20=EC=82=AC=EB=9D=BC=EC=A7=80=EB=8A=94=20=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src-tauri/src/state/app_state.rs | 43 +++++++++----------------------- 1 file changed, 12 insertions(+), 31 deletions(-) diff --git a/src-tauri/src/state/app_state.rs b/src-tauri/src/state/app_state.rs index 49c14fe1..6debae57 100644 --- a/src-tauri/src/state/app_state.rs +++ b/src-tauri/src/state/app_state.rs @@ -1181,6 +1181,8 @@ impl AppState { let window = window_builder .always_on_top(true) .skip_taskbar(false) + // 첫 표시를 SW_SHOWNOACTIVATE로 처리하도록 tao에 지시 (포커스 미탈취) + .focused(false) .visible(snapshot.overlay_visible) .inner_size(bounds.width, bounds.height) .position(bounds.x, bounds.y) @@ -1210,10 +1212,12 @@ impl AppState { } // Windows 오버레이 창 포커스 수신 방지 + // set_focusable(false): tao가 FOCUSABLE 플래그로 WS_EX_NOACTIVATE를 추적 적용 + // (raw SetWindowLongW 적용 시 이후 tao의 스타일 재적용에서 NOACTIVATE가 소실됨) #[cfg(target_os = "windows")] { - if let Err(err) = set_window_no_activate(&window) { - log::warn!("failed to set WS_EX_NOACTIVATE for overlay: {err}"); + if let Err(err) = window.set_focusable(false) { + log::warn!("failed to set overlay non-focusable: {err}"); } // 시스템 컨텍스트 메뉴 비활성화 if let Err(err) = disable_system_context_menu(&window) { @@ -1818,6 +1822,9 @@ fn show_overlay_window(window: &WebviewWindow, _always_on_top: bool) -> Result<( unsafe { let _ = ShowWindow(hwnd, SW_SHOWNOACTIVATE); } + // tao 내부 VISIBLE 플래그 동기화 — raw ShowWindow는 tao 상태를 갱신하지 않아, + // 이후 set_always_on_top/set_ignore_cursor_events 호출 시 tao가 창을 숨겨버림 + window.show()?; Ok(()) } #[cfg(target_os = "macos")] @@ -1837,21 +1844,9 @@ fn show_overlay_window(window: &WebviewWindow, _always_on_top: bool) -> Result<( } fn hide_overlay_window(window: &WebviewWindow) -> Result<()> { - #[cfg(target_os = "windows")] - { - use windows::Win32::UI::WindowsAndMessaging::{ShowWindow, SW_HIDE}; - - let hwnd = window.hwnd()?; - unsafe { - let _ = ShowWindow(hwnd, SW_HIDE); - } - Ok(()) - } - #[cfg(not(target_os = "windows"))] - { - window.hide()?; - Ok(()) - } + // tao API 사용으로 내부 VISIBLE 플래그와 실제 창 상태 일치 유지 + window.hide()?; + Ok(()) } /// macOS 전체화면 Space에서도 오버레이가 보이도록 NSWindow 동작을 보정 @@ -1892,20 +1887,6 @@ fn apply_macos_overlay_fullscreen_behavior_inner(window: &WebviewWindow, always_ } } -#[cfg(target_os = "windows")] -fn set_window_no_activate(window: &WebviewWindow) -> Result<()> { - use windows::Win32::UI::WindowsAndMessaging::{ - GetWindowLongW, SetWindowLongW, GWL_EXSTYLE, WS_EX_NOACTIVATE, - }; - - let hwnd = window.hwnd()?; - unsafe { - let ex_style = GetWindowLongW(hwnd, GWL_EXSTYLE); - SetWindowLongW(hwnd, GWL_EXSTYLE, ex_style | WS_EX_NOACTIVATE.0 as i32); - } - Ok(()) -} - /// 드래그 가능한 영역에서 시스템 컨텍스트 메뉴(이전 크기, 이동, 최소화 등)가 표시되지 않도록 설정 /// WM_INITMENU 메시지를 후킹하여 메뉴가 초기화될 때 창을 비활성화했다 활성화하여 메뉴를 취소시키는 방식 /// (Electron의 hookWindowMessage 방식과 동일)