You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Electron迁移至Wry/Tauri后,如何拦截window.resizeTo实现窗口调整?

在Wry/Tauri中拦截并实现window.resizeTo功能

为什么window.resizeTo在Wry/Tauri中无效

Wry/Tauri为了沙箱安全和权限控制,默认禁用了window.resizeTo这类直接操作窗口的DOM API,所以直接调用不会生效。但可以通过前端重写API + 后端IPC调用的方式实现等价功能。

实现步骤

1. 前端拦截window.resizeTo调用

重写全局的window.resizeTo方法,将尺寸参数通过Tauri的IPC发送给Rust后端处理:

import { invoke } from '@tauri-apps/api/tauri';

// 重写window.resizeTo,替换为IPC调用
window.resizeTo = async function (targetWidth, targetHeight) {
  // 可选:添加尺寸合法性校验,避免过小窗口
  const validWidth = Math.max(targetWidth, 300);
  const validHeight = Math.max(targetHeight, 200);
  
  // 调用后端注册的resize命令
  await invoke('resize_window', { width: validWidth, height: validHeight });
};

2. Rust后端实现窗口调整逻辑

在Tauri的主程序中注册resize_window命令,接收前端参数后调用窗口API调整尺寸:

use tauri::{Manager, Window};

// 定义IPC命令
#[tauri::command]
async fn resize_window(window: Window, width: f64, height: f64) -> Result<(), String> {
  // 转换为整数尺寸(窗口尺寸通常以物理像素整数为单位)
  let physical_width = width as u32;
  let physical_height = height as u32;
  
  // 调用Tauri窗口API设置尺寸
  window
    .set_size(tauri::Size::Physical(tauri::PhysicalSize {
      width: physical_width,
      height: physical_height,
    }))
    .map_err(|err| err.to_string())
}

fn main() {
  tauri::Builder::default()
    .invoke_handler(tauri::generate_handler![resize_window])
    .run(tauri::generate_context!())
    .expect("Failed to run Tauri application");
}

纯Wry环境下的实现(不使用Tauri上层框架)

如果是直接使用Wry而非Tauri,需要通过WebView的IPC监听实现:

use wry::{
  application::{window::Window, dpi::PhysicalSize},
  webview::WebViewBuilder,
  serde_json::Value,
};

fn main() -> wry::Result<()> {
  let app = wry::application::Application::new()?;
  let window = app.create_window(
    "Wry Resize Demo",
    wry::application::window::WindowBuilder::new()
      .with_inner_size(PhysicalSize::new(800, 600)),
  )?;

  let _webview = WebViewBuilder::new(window)?
    // 注入JS重写resizeTo
    .with_initialization_script(
      r#"
        window.resizeTo = function(width, height) {
          // 通过IPC发送 resize 消息及参数
          window.ipc.postMessage(JSON.stringify({
            type: 'resize',
            width: width,
            height: height
          }));
        };
      "#,
    )
    // 处理IPC消息
    .with_ipc_handler(|window, message| {
      let msg: Value = serde_json::from_str(&message).unwrap();
      if msg["type"].as_str() == Some("resize") {
        let width = msg["width"].as_f64().unwrap_or(800.0) as u32;
        let height = msg["height"].as_f64().unwrap_or(600.0) as u32;
        // 调整窗口尺寸
        window.set_inner_size(PhysicalSize::new(width, height));
      }
      Ok(())
    })
    .build()?;

  app.run()
}

注意事项

  • 参数校验:建议在前端或后端添加尺寸范围限制,避免窗口被调整到无法操作的大小
  • 多窗口场景:如果应用存在多个窗口,需要在IPC调用时传递窗口标识,后端通过window.get_window("window_label")获取对应窗口实例后调整尺寸
  • DPI适配:如果需要处理高DPI屏幕,可使用Size::Logical替代Physical,并通过Tauri的window.scale_factor()获取缩放比例进行转换

内容的提问来源于stack exchange,提问作者TheGr8_Nik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 13:10:59