Nurul Alam Ador
Nurul Alam Ador

Reputation: 387

Electron Remote (Close, Minimize etc) not work (Cannot read property 'getCurrentWindow' of undefined)

I am trying to add close and minimize button on frameless window in Electron JS app. But its not working in anyhow. It's alwasy show "Cannot read property 'getCurrentWindow' of undefined" error. Here is my code:

const {remote} = require('electron');

document.getElementById('minimize').onclick = function() {
    var window = remote.getCurrentWindow();
    window.minimize();
}

document.getElementById('close').onclick = function() {
    var window = remote.getCurrentWindow();
    window.close();
}

I also add webPreferences: {nodeIntegration: true} in main.js.

win = new BrowserWindow({width: 990, height: 660, title: "Okkhor52 Tools", show: false, resizable: false, frame: false, webPreferences: {nodeIntegration: true}});

Please give me a sollution, I try to found this problem sollution in many place but i didn't get exact sollution.

Upvotes: 4

Views: 12030

Answers (4)

Mihail Serikov
Mihail Serikov

Reputation: 51

According to this article we shouldn't use "remote" at all. The better way is to communicate with the renderer through Sending Messages.

First of all, you'll need WindowNodeHandlers class to invoke BrowserWindow maximize/unmaximize actions and update isMaximized flag:

class WindowNodeHandlers {
  ipcMain.on('maximize', () => {
    BrowserWindow.getFocusedWindow()?.maximize();
  });

  ipcMain.on('unmaximize', () => {
    BrowserWindow.getFocusedWindow()?.unmaximize();
  });

  ipcMain.on('isMaximized', (event) => {
    event.returnValue = BrowserWindow.getFocusedWindow()?.isMaximized();
  });
}

Then create ElectronWindowApi class to communicate between renderer and main processes:

class ElectronWindowApi implements MainWindowApi {
  maximize(): void {
   ipcRenderer.send('maximize');
  }

  unmaximize(): void {
   ipcRenderer.send('unmaximize');
  }

  isMaximized(): boolean {
   return ipcRenderer.sendSync('isMaximized') as boolean;
  }
 }

After that in your createWindow function create WindowNodeHandlers instance and add listeners for these events which will send messages back to renderer process:

const createWindow = async () => {
 ...
 new WindowNodeHandlers();

 mainWindow.on('maximize', () =>
   mainWindow?.webContents.send('window-maximized')
 );

 mainWindow.on('unmaximize', () =>
   mainWindow?.webContents.send('window-unmaximized')
 );
}

And the last thing you should do - it's to add handlers for these messages and use ElectronWindowApi to call maximize/unmaximize actions on the renderer side:

...
const windowApi = new ElectronWindowApi();
const [isMaximized, setIsMaximized] = useState(windowApi.isMaximized());
const onMaximized = () => setIsMaximized(true);
const onRestore = () => setIsMaximized(false);

const toggleMaximize = () => {
  isMaximized ? windowApi.unmaximize() : windowApi.maximize();
};

useEffect(() => {
  ipcRenderer.on('window-maximized', onMaximized);
  ipcRenderer.on('window-unmaximized', onRestore);
}, []);

return (
   <IconButton
      aria-label={isMaximized ? 'minimize' : 'maximize'}
      onClick={toggleMaximize}
    >
      {isMaximized ? (
        <SvgIcon
          component={MinimizeWindowIcon}
        />
      ) : (
        <SvgIcon
          component={MaximizeWindowIcon}
        />
      )}
    </IconButton>
)
...

Upvotes: 3

avisk
avisk

Reputation: 390

If you already have enableRemoteModule set to true and are still having this problem, it could very well be that you are requiring the remote module, or requiring a file that requires it inside the main process, at least this was the case for me. The remote module is not necessary inside the main process and is only for the renderer process.

If you require or require another javascript file that uses require("electron").remote.getCurrentWindow() inside the main process then you will get this error.

Solve this simply by not including that code in any way inside the main process.

Upvotes: 3

Jenny
Jenny

Reputation: 111

Actually, from a safety perspective,I suggest that you should use :

win = new BrowserWindow({
width: 990, 
height: 660,
title: "Okkhor52 Tools", 
resizable: false, 
frame: false, 
webPreferences: {
    nodeIntegration: false, //default 
    enableRemoteModule: true,
    preload: path.join(__dirname, 'preload.js')
}

}); And put you js code into 'preload.js'.

According to the official doc Disable the Node.js integration in all renderers that display remote content, nodeIntergration: true is very dangerous.

Upvotes: 1

Nurul Alam Ador
Nurul Alam Ador

Reputation: 387

Sollution is very easy. Just add webPreferences: {enableRemoteModule: true} in your BrowserWindow in main.js.

win = new BrowserWindow({
    width: 990, 
    height: 660,
    title: "Okkhor52 Tools", 
    resizable: false, 
    frame: false, 
    webPreferences: {
        nodeIntegration: true, 
        enableRemoteModule: true
    }
}); 

Beside enableRemoteModule: true you will need to add nodeIntegration: true in webPreference, otherwise if you call electron from other's javascript (Like this const {remote} = require('electron'); ) it will be not work.

Upvotes: 17

Related Questions