Search code examples
reactjselectronresize

Change the maximum screen size icon (and variable) by dragging the TitleBar


In a desktop application (written in Electron), I'm trying to implement a feature that will allow the user to open the application in full screen or return it to the reverse state (initially the application does not open in full screen).

I already have working functionality.

What I've done:

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>
  );
}

That is, what happens from our code: I click on the button to change the screen size, the screen becomes maximum and the icon changes. Or vice versa, the screen appears with the previous sizes, and the icon changes again.

However, the problem is that the result variable (and the icons accordingly) only changes when I click on the button. In all applications, and you can verify this, you can exit the maximum screen size by pulling the TitleBar (try the example of Google Chrome or any browser or any application). Please tell me how I can change the value of the result variable, including when I pull the TitleBar


Solution

  • You can add window listeners on "maximize" and "unmaximize" events:

    mainWindow.on("maximize", () => {
      mainWindow.webContents.send("maximize");
    });
    
    mainWindow.on("unmaximize", () => {
      mainWindow.webContents.send("unmaximize");
    });
    

    And then set IPC listeners on you renderer to change the state of your button accordingly, for example:

    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);
      };
    }, []);
    

    I used your code for the example, but please make sure you follow security guidelines when using IPC.