Electron Vue: Настраиваемая панель заголовка -> Получение правильного развернутого/восстановленного состояния окна из компонента

#javascript #vue.js #electron #vue-component

Вопрос:

Я разрабатываю бескаркасное приложение с пользовательской панелью заголовка (Electron Vue Vuex, используя шаблон electron-vue). До сих пор мне удавалось переключать кнопки «Развернуть/восстановить» при нажатии на них.

Проблема заключается в том, что состояние Windows контролируется другими событиями, такими как двойной щелчок в строке заголовка для разворачивания или значок на панели задач (Windows) для сворачивания/восстановления.

Есть ли способ добавить своего рода прослушиватель событий для реагирования на изменения Windows изнутри компонента (.vue), чтобы отобразить правильную кнопку «Развернуть/восстановить»?

Комментарии:

1. Я думаю ipcRenderer , и ipcMain , возможно, это то, что вы ищете

2. Я знаю, как излучать из ipcMain, но не знаю, как прослушивать из одного файлового компонента в Vue. Куда мне его положить ipcRenderer.on ? В методах, в вычисленном значении,…? Спасибо за помощь

3. Это сильно зависит от того, для чего предназначен ipcRender.on, однако я бы поместил его в мутацию и обновил конкретное состояние на основе ответа

4. Сначала я хотел бы даже иметь возможность сделать что-то такое простое, как тест «пинг-понг». Проблема в том, что мой ipcRender не слушает «понг». (Я знаю, что ipcMain работает, потому что я могу закрыть приложение с помощью кнопки компонента vue)

Ответ №1:

Ну, через некоторое время, до сих пор вот как мне это удавалось:

в electron-main.js

     mainWindow.on("move", () => {
        //_ console.log("electron move");
        mainWindow.webContents.send("winState", "normal");
    });
    mainWindow.on("minimize", () => {
        //_ console.log("electron minimize");
        mainWindow.webContents.send("winState", "minimized");
    });
    mainWindow.on("maximize", () => {
        //_ console.log("electron maximize");
        mainWindow.webContents.send("winState", "maximized");
    });
    mainWindow.on("unmaximize", () => {
        //_ console.log("electron unmaximize");
        mainWindow.webContents.send("winState", "normal");
    });
    mainWindow.on("restore", () => {
        //_ console.log("electron restore");
        mainWindow.webContents.send("winState", "normal");
    });
 

в electron-preload.js

 import { contextBridge, ipcRenderer } from "electron";
import { BrowserWindow } from "@electron/remote";

contextBridge.exposeInMainWorld("csxAPI", {
    envMode: process.env.MODE,
    minimize() {
        BrowserWindow.getFocusedWindow().minimize();
    },
    maximize() {
        BrowserWindow.getFocusedWindow().maximize();
    },
    restore() {
        BrowserWindow.getFocusedWindow().unmaximize();
    },
    close() {
        BrowserWindow.getFocusedWindow().close();
        BrowserWindow.getFocusedWindow().destroy();
    },
});

const validChannels = ["winState"];
contextBridge.exposeInMainWorld("ipc", {
    send: (channel, data) => {
        if (validChannels.includes(channel)) {
            ipcRenderer.send(channel, data);
        }
    },
    on: (channel, func) => {
        if (validChannels.includes(channel)) {
            // Strip event as it includes `sender` and is a security risk
            //_ ipcRenderer.on(channel, (event, ...args) => func(...args));
            ipcRenderer.on(channel, (...args) => func(...args));
        }
    },
});
 

в заголовке.vue

 //...
data: function () {
        return {
            status: "normal",
        };
    },

//...
mounted() {
        window.ipc.on("winState", (event, msg) => {
            this.status = msg;
        });

//...
methods: {
        winMinimize() {
            if (window.csxAPI.envMode === "electron") {
                window.csxAPI.minimize();
            }
        },
        winMaximize() {
            if (window.csxAPI.envMode === "electron") {
                window.csxAPI.maximize();
            }
        },
        winRestore() {
            if (window.csxAPI.envMode === "electron") {
                window.csxAPI.restore();
            }
        },
        winClose() {
            if (window.csxAPI.envMode === "electron") {
                window.csxAPI.close();
            }
        },
    },

 

Не знаю, оптимизировано ли это или даже правильно ли это, но у меня это сработало.

Спасибо тем, кто пытался помочь