File size: 2,460 Bytes
a5ca9aa
07eb768
 
 
 
a5ca9aa
 
07eb768
 
a5ca9aa
 
 
 
 
 
07eb768
 
a5ca9aa
 
 
 
 
 
 
 
07eb768
 
 
 
a5ca9aa
 
 
07eb768
 
 
 
 
 
a5ca9aa
 
07eb768
 
 
a5ca9aa
 
 
07eb768
 
 
 
 
 
 
 
 
 
a5ca9aa
 
 
07eb768
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use tauri::{AppHandle, LogicalPosition, LogicalSize, Manager};

use super::tab_manager::{tab_label, ViewportLayout};
use crate::state::AppState;

const OFFSCREEN_X: f64 = -32000.0;
const OFFSCREEN_Y: f64 = -32000.0;

pub fn bounds(layout: &ViewportLayout) -> (f64, f64, f64, f64) {
    (
        layout.x.max(0.0),
        layout.y.max(0.0),
        layout.width.max(1.0),
        layout.height.max(1.0),
    )
}

/// Child webviews added with `window.add_child` are positioned in the parent
/// window client-area logical coordinate space. DOM getBoundingClientRect()
/// from the main webview also reports CSS/logical pixels relative to that same
/// client area (because our main webview fills the undecorated window).
///
/// So: use LogicalPosition/LogicalSize directly. Do NOT multiply by DPI here.
/// Passing PhysicalPosition can push the child webview out of the intended
/// panel on scaled displays and was the main reason it appeared invisible.
pub fn show_tab(app: &AppHandle, tab_id: &str, layout: &ViewportLayout) -> Result<(), String> {
    let label = tab_label(app, tab_id)?;
    let (x, y, w, h) = bounds(layout);
    if let Some(webview) = app.get_webview(&label) {
        // Bounds first, then visible/focus. Idempotent and cross-platform.
        webview.set_position(LogicalPosition::new(x, y)).map_err(|e| e.to_string())?;
        webview.set_size(LogicalSize::new(w, h)).map_err(|e| e.to_string())?;
        let _ = webview.show();
        let _ = webview.set_focus();
    }
    Ok(())
}

/// Park offscreen instead of relying on hide/show lifecycle. This keeps WebView2
/// initialized and avoids stale rendering after panel close/open.
pub fn hide_tab(app: &AppHandle, tab_id: &str) -> Result<(), String> {
    let label = tab_label(app, tab_id)?;
    if let Some(webview) = app.get_webview(&label) {
        webview.set_position(LogicalPosition::new(OFFSCREEN_X, OFFSCREEN_Y)).map_err(|e| e.to_string())?;
        webview.set_size(LogicalSize::new(1.0, 1.0)).map_err(|e| e.to_string())?;
        // Do not call hide(); parking is more reliable with child WebView2.
    }
    Ok(())
}

pub fn resize_active(app: &AppHandle, layout: &ViewportLayout) -> Result<(), String> {
    let active = {
        let state = app.state::<AppState>();
        let tabs = state.tabs.lock().map_err(|_| "lock")?;
        tabs.active.clone()
    };
    if let Some(active_id) = active {
        show_tab(app, &active_id, layout)?;
    }
    Ok(())
}