В настольном приложении (написанном на Electron) я пытаюсь реализовать функцию, которая позволит пользователю открыть приложение в полноэкранном режиме или вернуть его в обратное состояние (изначально приложение не открывается в полноэкранном режиме).
У меня уже есть рабочий функционал.
Что я наделал:
main.ts
ipcMain.handle(IPCChannels.CheckMax, () => {
let result = '';
if (mainWindow.isMaximized()) {
mainWindow.unmaximize();
result = 'unmaximize';
return result;
}
mainWindow.maximize();
result = 'maximize';
return result;
});
TitleBar.tsx
function TitleBar() {
const [checkMax, setCheckMax] = useState('');
function maximize() {
window.electron.ipcRenderer
.invoke(IPCChannels.CheckMax)
.then((res) => setCheckMax(res))
.catch((err) => {
console.error(err);
});
}
return (
<nav>
<div/>
<button onClick = {maximize}>
{checkMax === 'maximize' ? (
<MaxIcon />
) : (
<MinIcon />
)}
</button>
</nav>
);
}
То есть, что происходит из нашего кода: я нажимаю на кнопку изменения размера экрана, экран становится максимальным и иконка меняется. Или наоборот, экран появляется с прежними размерами, а иконка снова меняется.
Однако проблема в том, что переменная результата (и значки соответственно) меняется только тогда, когда я нажимаю на кнопку. Во всех приложениях, и вы можете в этом убедиться, из максимального размера экрана можно выйти, потянув за TitleBar (попробуйте на примере Google Chrome или любого браузера или любого приложения). Подскажите пожалуйста, как мне изменить значение результирующей переменной, в том числе когда я перетягиваю TitleBar





Вы можете добавить прослушиватели окон на события «максимизировать» и «развернуть»:
mainWindow.on("maximize", () => {
mainWindow.webContents.send("maximize");
});
mainWindow.on("unmaximize", () => {
mainWindow.webContents.send("unmaximize");
});
А затем установите прослушиватели IPC на вашем рендерере, чтобы соответствующим образом изменить состояние вашей кнопки, например:
useEffect(() => {
const maximize = () => setCheckMax("maximize"));
window.electron.ipcRenderer.on("maximize", maximize);
const unmaximize = () => setCheckMax("unmaximize");
window.electron.ipcRenderer.on("unmaximize", unmaximize);
return () => {
window.electron.ipcRenderer.removeListener("maximize", maximize);
window.electron.ipcRenderer.removeListener("unmaximize", unmaximize);
};
}, []);
В качестве примера я использовал ваш код, но, пожалуйста, убедитесь, что вы соблюдаете правила безопасности при использовании IPC.
@Paul Объявление вашего окна находится в вашем основном процессе, а слушатели переходят к основному процессу. А я думал у тебя уже есть рабочая кнопка? Просто добавьте useEffect в свой компонент <Titlebar>.
Да, кнопка работает. Но когда я пытаюсь использовать свой код с вашим, он не работает. Видимо я делаю что-то не так
@Paul Что значит «не работает»? Я сделал небольшую опечатку при удалении прослушивателя «unmaximize» (сейчас я это исправил), проверьте, не скопировали ли вы ее, иначе прослушиватель не будет удален правильно. В противном случае просто адаптируйте код к вашей реализации. Ваша проблема заключалась в том, чтобы определить, когда изменяется состояние окна, использование событий решает эту проблему.
Уточню: мне следует добавить в файл main.ts вашу первую часть кода вместо своего кода (который я продемонстрировал в файле main.ts)?
@Paul Это события окна, вы должны поместить их туда, где находится объявление вашего окна, точно так же, как событие «закрытия», чтобы определить, например, закрыто ли ваше окно. Так и должно быть main.ts, поскольку я вижу mainWindow в коде, которым вы поделились.
Извините, но это не работает. Я получаю сообщение об ошибке «Uncaught TypeError: window.electron.ipcRenderer.removeListener не является функцией»
@Пол, Пол, я не знаю, какая у вас реализация IPC, я могу только предоставить пример кода, основанный на том, чем вы поделились. Вам придется адаптировать код, чтобы он работал для вашей реализации. Обновите свой код, чтобы можно было использовать RemoveListener IPC.
Спасибо за помощь и совет. Мне удалось добиться результата, только в моем случае мне нужно написать window.electron.ipcRenderer.on(......) вместо removeListener
@Paul Пока он удаляет прослушиватель, у тебя все будет хорошо. :)
Спасибо, что обратили внимание на мой вопрос! Но так как я только начал изучать электрон, то не совсем понял вашу идею: 1) В какой файл добавить вашу первую часть кода? 2) Как мне повлиять на клик в файле TitleBar.tsx? Возможно, вы сможете интегрировать свой код в мой пример и показать его более подробно?