Измените значок максимального размера экрана (и переменную), перетащив строку заголовка

В настольном приложении (написанном на 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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете добавить прослушиватели окон на события «максимизировать» и «развернуть»:

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.

Спасибо, что обратили внимание на мой вопрос! Но так как я только начал изучать электрон, то не совсем понял вашу идею: 1) В какой файл добавить вашу первую часть кода? 2) Как мне повлиять на клик в файле TitleBar.tsx? Возможно, вы сможете интегрировать свой код в мой пример и показать его более подробно?

Paul 31.03.2024 12:01

@Paul Объявление вашего окна находится в вашем основном процессе, а слушатели переходят к основному процессу. А я думал у тебя уже есть рабочая кнопка? Просто добавьте useEffect в свой компонент <Titlebar>.

Arkellys 31.03.2024 12:13

Да, кнопка работает. Но когда я пытаюсь использовать свой код с вашим, он не работает. Видимо я делаю что-то не так

Paul 31.03.2024 12:17

@Paul Что значит «не работает»? Я сделал небольшую опечатку при удалении прослушивателя «unmaximize» (сейчас я это исправил), проверьте, не скопировали ли вы ее, иначе прослушиватель не будет удален правильно. В противном случае просто адаптируйте код к вашей реализации. Ваша проблема заключалась в том, чтобы определить, когда изменяется состояние окна, использование событий решает эту проблему.

Arkellys 31.03.2024 12:21

Уточню: мне следует добавить в файл main.ts вашу первую часть кода вместо своего кода (который я продемонстрировал в файле main.ts)?

Paul 31.03.2024 12:25

@Paul Это события окна, вы должны поместить их туда, где находится объявление вашего окна, точно так же, как событие «закрытия», чтобы определить, например, закрыто ли ваше окно. Так и должно быть main.ts, поскольку я вижу mainWindow в коде, которым вы поделились.

Arkellys 31.03.2024 12:27

Извините, но это не работает. Я получаю сообщение об ошибке «Uncaught TypeError: window.electron.ipcRenderer.removeListener не является функцией»

Paul 31.03.2024 12:43

@Пол, Пол, я не знаю, какая у вас реализация IPC, я могу только предоставить пример кода, основанный на том, чем вы поделились. Вам придется адаптировать код, чтобы он работал для вашей реализации. Обновите свой код, чтобы можно было использовать RemoveListener IPC.

Arkellys 31.03.2024 12:45

Спасибо за помощь и совет. Мне удалось добиться результата, только в моем случае мне нужно написать window.electron.ipcRenderer.on(......) вместо removeListener

Paul 31.03.2024 16:15

@Paul Пока он удаляет прослушиватель, у тебя все будет хорошо. :)

Arkellys 31.03.2024 16:17

Другие вопросы по теме

Похожие вопросы

Синтаксическая ошибка: неожиданный токен '<', "<!doctype"... недопустимый JSON. как решить эту ошибку
Почему при развертывании серверной части отображается сообщение об ошибке 404 при развертывании проекта на Vercel?
Автозаполнение MUI с кнопки
Почему этот дочерний компонент `<Suspense>` теряет свое состояние, а не отображается после разрешения приостановочного обещания?
Действия Github для развертывания проекта flask подкаталога в веб-приложении Azure
Работа с нулевыми значениями в ответе API GraphQL
Каталог приложений Next.js — обновление клиентского компонента после завершения асинхронной функции. Компонент обновляется только при обновлении страницы
Свойство default не объявлено настраиваемым при издевательстве над компонентом React
Безопасно ли изменять объект состояния непосредственно в useEffect? (Реакция и неизменность)
Что вызывает эту ошибку типа Next.js при сборке?