feat(tauri): 맥에서도 빌드되게 Win32 모듈을 cfg(windows) 로 분리
windows crate 를 Windows 타깃 전용 의존성으로 옮기고, paste/capture 는 다른 OS 에서 같은 API 의 껍데기(_stub)로 컴파일. hwnd 접근은 window::native_handle 하나로. Windows 동작은 그대로. 맥에선 붙여넣기·영역 캡처가 'Windows 에서만 됨'으로 응답. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
Generated
-15
@@ -100,9 +100,6 @@
|
|||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "Apache-2.0 OR MIT",
|
"license": "Apache-2.0 OR MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -120,9 +117,6 @@
|
|||||||
"arm64"
|
"arm64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "Apache-2.0 OR MIT",
|
"license": "Apache-2.0 OR MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -140,9 +134,6 @@
|
|||||||
"riscv64"
|
"riscv64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "Apache-2.0 OR MIT",
|
"license": "Apache-2.0 OR MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -160,9 +151,6 @@
|
|||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"glibc"
|
|
||||||
],
|
|
||||||
"license": "Apache-2.0 OR MIT",
|
"license": "Apache-2.0 OR MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
@@ -180,9 +168,6 @@
|
|||||||
"x64"
|
"x64"
|
||||||
],
|
],
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"libc": [
|
|
||||||
"musl"
|
|
||||||
],
|
|
||||||
"license": "Apache-2.0 OR MIT",
|
"license": "Apache-2.0 OR MIT",
|
||||||
"optional": true,
|
"optional": true,
|
||||||
"os": [
|
"os": [
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ serde_json = "1"
|
|||||||
rusqlite = { version = "0.32.1", features = ["bundled"] }
|
rusqlite = { version = "0.32.1", features = ["bundled"] }
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
png = "0.17"
|
png = "0.17"
|
||||||
|
|
||||||
|
# Win32 (붙여넣기·영역 캡처) — Windows 빌드에서만. 맥/리눅스는 shell/*_stub.rs 껍데기.
|
||||||
|
[target.'cfg(windows)'.dependencies]
|
||||||
windows = { version = "0.61.3", features = [
|
windows = { version = "0.61.3", features = [
|
||||||
"Win32_Foundation",
|
"Win32_Foundation",
|
||||||
"Win32_Graphics_Gdi",
|
"Win32_Graphics_Gdi",
|
||||||
|
|||||||
@@ -116,10 +116,7 @@ pub async fn paste_code(
|
|||||||
.lock()
|
.lock()
|
||||||
.map(|target| target.clone())
|
.map(|target| target.clone())
|
||||||
.map_err(|_| "붙여넣기 대상 상태를 읽지 못함".to_string());
|
.map_err(|_| "붙여넣기 대상 상태를 읽지 못함".to_string());
|
||||||
let palette_hwnd = window::main_window(&app)
|
let palette_hwnd = window::native_handle(&app).unwrap_or_default();
|
||||||
.and_then(|window| window.hwnd().ok())
|
|
||||||
.map(|hwnd| hwnd.0 as isize)
|
|
||||||
.unwrap_or_default();
|
|
||||||
let worker_app = app.clone();
|
let worker_app = app.clone();
|
||||||
let result = tauri::async_runtime::spawn_blocking(move || {
|
let result = tauri::async_runtime::spawn_blocking(move || {
|
||||||
let _paste_guard = paste_guard;
|
let _paste_guard = paste_guard;
|
||||||
|
|||||||
@@ -125,9 +125,7 @@ fn chat_toggle_target(visible: bool, current: &str, last_snap: &str) -> Option<S
|
|||||||
|
|
||||||
/// 팔레트를 띄우기 직전에 대상 창 값을 복사해 둔다. 대상이 닫혀도 배지 문자열은 유지됨.
|
/// 팔레트를 띄우기 직전에 대상 창 값을 복사해 둔다. 대상이 닫혀도 배지 문자열은 유지됨.
|
||||||
fn show_palette(app: &AppHandle) -> tauri::Result<()> {
|
fn show_palette(app: &AppHandle) -> tauri::Result<()> {
|
||||||
let own_hwnd = window::main_window(app)
|
let own_hwnd = window::native_handle(app);
|
||||||
.and_then(|window| window.hwnd().ok())
|
|
||||||
.map(|hwnd| hwnd.0 as isize);
|
|
||||||
let captured = paste::capture_foreground(own_hwnd);
|
let captured = paste::capture_foreground(own_hwnd);
|
||||||
let state = app.state::<paste::PasteState>();
|
let state = app.state::<paste::PasteState>();
|
||||||
let target = match state.lock() {
|
let target = match state.lock() {
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
//! `capture.rs` 의 Windows 외 껍데기 — 영역 캡처 오버레이는 GDI 전용이라 맥/리눅스에선 아무것도 안 함.
|
||||||
|
|
||||||
|
use tauri::AppHandle;
|
||||||
|
|
||||||
|
pub fn start<F>(_app: AppHandle, _on_captured: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(AppHandle, String) + Send + 'static,
|
||||||
|
{
|
||||||
|
eprintln!("[capture] 영역 캡처는 Windows 에서만 됨");
|
||||||
|
}
|
||||||
@@ -7,8 +7,17 @@
|
|||||||
//! 일부러 `init(ShellConfig)` 같은 통합 진입점을 안 만들었다 — 세 모듈이 서로 독립이고
|
//! 일부러 `init(ShellConfig)` 같은 통합 진입점을 안 만들었다 — 세 모듈이 서로 독립이고
|
||||||
//! 콜백도 각자 달라서, 감싸봐야 그냥 넘겨주기만 하는 껍데기가 하나 더 생길 뿐임.
|
//! 콜백도 각자 달라서, 감싸봐야 그냥 넘겨주기만 하는 껍데기가 하나 더 생길 뿐임.
|
||||||
|
|
||||||
|
// capture·paste 는 Win32 전용. 다른 OS 는 같은 API 의 껍데기(_stub)로 컴파일만 되게 함 — 맥에서 개발용.
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub mod capture;
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[path = "capture_stub.rs"]
|
||||||
pub mod capture;
|
pub mod capture;
|
||||||
pub mod hotkey;
|
pub mod hotkey;
|
||||||
|
#[cfg(windows)]
|
||||||
|
pub mod paste;
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
#[path = "paste_stub.rs"]
|
||||||
pub mod paste;
|
pub mod paste;
|
||||||
pub mod tray;
|
pub mod tray;
|
||||||
pub mod window;
|
pub mod window;
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
//! `paste.rs` 의 Windows 외 껍데기 — 직전 앱 기억·키 입력 붙여넣기는 Win32 전용이라
|
||||||
|
//! 맥/리눅스에선 "대상 없음"으로만 동작함. 공개 API(타입·함수 시그니처)는 paste.rs 와 같아야 함.
|
||||||
|
|
||||||
|
use std::sync::Mutex;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
pub const DEFAULT_PASTE_DELAY: Duration = Duration::from_millis(80);
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default)]
|
||||||
|
pub struct PasteTarget {
|
||||||
|
pub name: String,
|
||||||
|
pub app: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type PasteState = Mutex<PasteTarget>;
|
||||||
|
|
||||||
|
pub fn capture_foreground(_excluded_hwnd: Option<isize>) -> Option<PasteTarget> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn paste(
|
||||||
|
text: &str,
|
||||||
|
_target: &PasteTarget,
|
||||||
|
_palette_hwnd: isize,
|
||||||
|
_delay: Duration,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
if text.is_empty() {
|
||||||
|
return Err("붙여넣을 코드가 비었음".to_string());
|
||||||
|
}
|
||||||
|
Err("직전 앱 붙여넣기는 Windows 에서만 됨".to_string())
|
||||||
|
}
|
||||||
@@ -20,6 +20,22 @@ pub fn main_window(app: &AppHandle) -> Option<WebviewWindow> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 창 표시 + 포커스. (핫키/트레이 소환용)
|
/// 창 표시 + 포커스. (핫키/트레이 소환용)
|
||||||
|
/// 붙여넣기 대상에서 우리 창을 빼거나 포커스 비교할 때 쓰는 네이티브 창 핸들(HWND).
|
||||||
|
/// Windows 에서만 값이 있고 다른 OS 는 None — 호출부가 알아서 "대상 없음"으로 처리함.
|
||||||
|
pub fn native_handle(app: &AppHandle) -> Option<isize> {
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
main_window(app)
|
||||||
|
.and_then(|window| window.hwnd().ok())
|
||||||
|
.map(|hwnd| hwnd.0 as isize)
|
||||||
|
}
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
{
|
||||||
|
let _ = app;
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn show(app: &AppHandle) -> tauri::Result<()> {
|
pub fn show(app: &AppHandle) -> tauri::Result<()> {
|
||||||
if let Some(w) = main_window(app) {
|
if let Some(w) = main_window(app) {
|
||||||
w.show()?;
|
w.show()?;
|
||||||
|
|||||||
Reference in New Issue
Block a user