自定义electron的最大化和还原

479 阅读2分钟

在开发electron应用时,通常需要重新开发最大化和还原,因为设计师门往往不会用原来的ui.

设计思路

  1. 首先最大化和还原,用原生的api maximize()和restore
  2. 然后是监听考虑用window.addEventlistenner("resize",xx) 或者 BrowserWindow.on("resized",xxx);
  3. 存储窗口大小用于初始化还原:考虑localStorage或者其它方式

写代码

主线程: 监听对应操作和resized,这里的resized只会监听拉的动作

   mainWindow.on("resized", () => {
    const [w, h] = mainWindow.getSize();
    mainWindow.webContents.send("resized", [w, h], false);
  });
  ipcMain.on("setSize",(event, [w,h]) => {
    mainWindow.setSize(w,h)
  })
  ipcMain.on("opt", (event, type) => {
    switch (type) {
      case "min":
        {
          mainWindow.minimize();
          const [w, h] = mainWindow.getSize();
          mainWindow.webContents.send("resized", [w, h], false);
        }
        break;
      case "max":
        {
          mainWindow.maximize();
          const [w, h] = mainWindow.getSize();
          mainWindow.webContents.send("resized", [w, h], true);
        }
        break;
      case "restore":
        {
          mainWindow.restore();
          const [w, h] = mainWindow.getSize();
          mainWindow.webContents.send("resized", [w, h], false);
        }
        break;
      case "close":
        mainWindow.close();
    }
  });

渲染进程,注册点击事件,监听resized 然后存储localStorage,初始化读取localStorage 还原之前的大小

 const wh = localStorage.getItem("wh");
      setTimeout( () => {
        if (wh) {
          const { w, h, isMax } = JSON.parse(wh);
          if (isMax) {
            ipcRenderer.send("opt", "max");
          } else {
            ipcRenderer.send("setSize", [w, h]);
          }
        }
      });

      const { ipcRenderer } = require("electron");
      function opt(type) {
        ipcRenderer.send("opt", type);
      }
      ipcRenderer.on("resized", (event, [w, h], isMax) => {
        localStorage.setItem("wh", JSON.stringify({ w, h, isMax }));
      });

测试

跑跑看,基本没什么问题,~~~ 设置透明属性看看

发现 restore 还原完成全失效

看了不能用restore,设置一个之前的宽高才行

优化

加多一个参数判断是否是监听

   mainWindow.on("resized", () => {
    const [w, h] = mainWindow.getSize();
    mainWindow.webContents.send("resized", [w, h], false, true);
  });

function opt(type) {
        if (type=='restore') {
          const wh=localStorage.getItem("lastWh");
          const [w,h] = JSON.parse(wh);
          ipcRenderer.send("setSize", [w, h]);
        } else {
          ipcRenderer.send("opt", type);
        }
      }
ipcRenderer.on("resized", (event, [w, h], isMax,isResized) => {
        localStorage.setItem("wh", JSON.stringify({ w, h, isMax }));
        if (isResized) {
          localStorage.setItem("lastWh",JSON.stringify([w,h]));
        }
      });

最后发现,忘记记录当前的位置,加加

    ...
    const [x,y] = mainWindow.getPosition();
    mainWindow.webContents.send("resized", [w, h],[x,y] ,false, true);
    ...
      ipcMain.on("setSize",(event, [w,h],[x,y]) => {
        mainWindow.setSize(w,h);
        mainWindow.setPosition(x,y)
  })

总结

自定义electron的最大化和还原,还是有一点坑的,设计思路大概是没什么问题,就是有些设置不支持,要通过变通来实现

后续

笑死了发现使用

titleBarStyle: "hidden", titleBarOverlay: { color:"#fff" },

可以去掉标题,然后自定义颜色