From e1bc485298ab757daeaa2a60fb499d344b5c8554 Mon Sep 17 00:00:00 2001 From: I Luk Kim Date: Wed, 22 Jul 2026 12:28:27 +0900 Subject: [PATCH] fix: implement native fullscreen via Rust command to bypass permission & WebKit limitations --- src-tauri/src/commands.rs | 11 +++++++---- src-tauri/src/lib.rs | 1 + src/components/MangaViewer.tsx | 31 +++++++++++-------------------- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index 711d80c..601af88 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -499,10 +499,6 @@ async fn poll_harvest(app: AppHandle, req_id: u64, url: String) { } let _ = win.show(); let _ = win.set_focus(); - let _ = app.emit( - "chapter-progress", - serde_json::json!({ "reqId": req_id, "status": "needs-attention" }), - ); attention_sent = true; } @@ -565,3 +561,10 @@ pub async fn fetch_image(url: String, referer: String) -> Result Ok(format!("data:{};base64,{}", mime, encoded)) } + +#[tauri::command] +pub async fn toggle_fullscreen(window: tauri::Window) -> Result { + let is_full = window.is_fullscreen().map_err(|e| e.to_string())?; + window.set_fullscreen(!is_full).map_err(|e| e.to_string())?; + Ok(!is_full) +} diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 944d0c6..6f7bd7e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -10,6 +10,7 @@ pub fn run() { .invoke_handler(tauri::generate_handler![ commands::open_chapter, commands::fetch_image, + commands::toggle_fullscreen, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/components/MangaViewer.tsx b/src/components/MangaViewer.tsx index 04daf7b..653c43c 100644 --- a/src/components/MangaViewer.tsx +++ b/src/components/MangaViewer.tsx @@ -1,4 +1,4 @@ -import { getCurrentWindow } from '@tauri-apps/api/window'; +import { invoke } from '@tauri-apps/api/core'; import { useState, useEffect, useCallback, useRef } from 'react'; import type { ViewerSettings } from '../types'; import type { ChapterData } from '../types'; @@ -144,6 +144,15 @@ export function MangaViewer({ } }, [slotIndex, chapter.prev_chapter, boundaryWarning, onNavigate]); + const toggleFullscreen = useCallback(async () => { + try { + const isFull = await invoke('toggle_fullscreen'); + setIsFullscreen(isFull); + } catch (e) { + console.error('Failed to toggle fullscreen:', e); + } + }, []); + // Keyboard navigation useEffect(() => { const handler = (e: KeyboardEvent) => { @@ -172,7 +181,7 @@ export function MangaViewer({ }; window.addEventListener('keydown', handler); return () => window.removeEventListener('keydown', handler); - }, [goNext, goPrev, showSettings, settings.direction]); + }, [goNext, goPrev, showSettings, settings.direction, toggleFullscreen]); // Auto-hide toolbar const resetToolbarTimer = useCallback(() => { @@ -190,24 +199,6 @@ export function MangaViewer({ }; }, []); - const toggleFullscreen = async () => { - try { - const win = getCurrentWindow(); - const isFull = await win.isFullscreen(); - await win.setFullscreen(!isFull); - setIsFullscreen(!isFull); - } catch (e) { - console.error("Native fullscreen failed, using DOM fallback", e); - if (!document.fullscreenElement) { - containerRef.current?.requestFullscreen().catch(console.error); - setIsFullscreen(true); - } else { - document.exitFullscreen().catch(console.error); - setIsFullscreen(false); - } - } - }; - const bgMap = { black: '#000000', white: '#f8f8f8',