resize the electron app to match the content. Might be used for web-based Asterisk BLI-Pages or other unobstrusive notifications.
Window is always on top on Ubuntu/Windows
resize the electron app to match the content. Might be used for web-based Asterisk BLI-Pages or other unobstrusive notifications.
Window is always on top on Ubuntu/Windows
| <!DOCTYPE html> | |
| <html> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <title>Electron Window expand/shrink Demo!</title> | |
| </head> | |
| <body> | |
| <h1>Hello World!</h1> | |
| We are using Node.js <span id="node-version"></span>, | |
| Chromium <span id="chrome-version"></span>, | |
| and Electron <span id="electron-version"></span>. | |
| <p>This Window will expand/shrink in height only. It will keep the width the user sets</p> | |
| <p id="content"> Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> | |
| <input type="button" id="addContent" value="Add Content" /> | |
| <input type="button" id="resetter" value="Reset" /> | |
| <!-- You can also require other files to run in this process --> | |
| <script src="./renderer.js"></script> | |
| </body> | |
| </html> |
| // Modules to control application life and create native browser window | |
| const { app, BrowserWindow } = require('electron') | |
| const path = require('path') | |
| let mainWindow; | |
| function createWindow() { | |
| mainWindow = new BrowserWindow({ | |
| width: 400, | |
| height: 600, | |
| alwaysOnTop: true, | |
| autoHideMenuBar: true, | |
| useContentSize: true, | |
| backgroundColor: '#f9f9fa', | |
| webPreferences: { | |
| preload: path.join(__dirname, 'preload.js') | |
| } | |
| }) | |
| // and load the index.html of the app. | |
| mainWindow.loadFile('index.html') | |
| // Open the DevTools. | |
| // mainWindow.webContents.openDevTools() | |
| } | |
| moveNotification = function (event) { | |
| cancelMoveNotification() | |
| } | |
| const { ipcMain } = require('electron') | |
| let suspected_y = -1, previous_y = -1; | |
| cancelMoveNotification = function () { // workaround to register potentially moved windows | |
| mainWindow.removeListener('move', moveNotification) | |
| const after = mainWindow.getBounds(); | |
| if (after.y < previous_y) { | |
| // suspect that window moved upwards | |
| if (suspected_y < 0) | |
| suspected_y = previous_y; | |
| } | |
| } | |
| ipcMain.on('resize-window-content-height', (event, arg) => { | |
| const before = mainWindow.getContentBounds(); | |
| const width = mainWindow.getContentSize()[0] | |
| mainWindow.on('move', moveNotification) | |
| mainWindow.setContentBounds({x:before.x, y:before.y, width:before.width,height:arg + 30}, true); // +30 because not everything is shown -.- | |
| const after = mainWindow.getContentBounds(); // this does not reflect potentially moved window | |
| if (before.height < after.height) { | |
| // it expanded | |
| previous_y = after.y | |
| } else { | |
| //it shrank | |
| if (suspected_y > 0) { | |
| //mainWindow.setContentBounds({y: suspected_y}) // does not work | |
| mainWindow.setContentBounds({x:after.x, y: suspected_y, width:after.width, height:after.height }) | |
| } | |
| suspected_y = -1; | |
| } | |
| setTimeout(cancelMoveNotification, 200) | |
| }) | |
| // This method will be called when Electron has finished | |
| // initialization and is ready to create browser windows. | |
| // Some APIs can only be used after this event occurs. | |
| app.whenReady().then(() => { | |
| createWindow() | |
| app.on('activate', function () { | |
| // On macOS it's common to re-create a window in the app when the | |
| // dock icon is clicked and there are no other windows open. | |
| if (BrowserWindow.getAllWindows().length === 0) createWindow() | |
| }) | |
| }) | |
| // Quit when all windows are closed, except on macOS. There, it's common | |
| // for applications and their menu bar to stay active until the user quits | |
| // explicitly with Cmd + Q. | |
| app.on('window-all-closed', function () { | |
| if (process.platform !== 'darwin') app.quit() | |
| }) | |
| // In this file you can include the rest of your app's specific main process | |
| // code. You can also put them in separate files and require them here. |
| { | |
| "name": "lonely-floor-use-n68x5", | |
| "productName": "lonely-floor-use-n68x5", | |
| "description": "My Electron application description", | |
| "keywords": [], | |
| "main": "./main.js", | |
| "version": "1.0.0", | |
| "author": "max", | |
| "scripts": { | |
| "start": "electron ." | |
| }, | |
| "dependencies": {}, | |
| "devDependencies": { | |
| "electron": "13.1.9" | |
| } | |
| } |
| // All of the Node.js APIs are available in the preload process. | |
| // It has the same sandbox as a Chrome extension. | |
| window.addEventListener('DOMContentLoaded', () => { | |
| const replaceText = (selector, text) => { | |
| const element = document.getElementById(selector) | |
| if (element) element.innerText = text | |
| } | |
| for (const type of ['chrome', 'node', 'electron']) { | |
| replaceText(`${type}-version`, process.versions[type]) | |
| } | |
| }) | |
| const { contextBridge, ipcRenderer } = require('electron') | |
| contextBridge.exposeInMainWorld( | |
| 'electron', | |
| { | |
| resizerContent: (height) => ipcRenderer.send('resize-window-content-height', height) | |
| } | |
| ) | |
| // This file is required by the index.html file and will | |
| // be executed in the renderer process for that window. | |
| // No Node.js APIs are available in this process because | |
| // `nodeIntegration` is turned off. Use `preload.js` to | |
| // selectively enable features needed in the rendering | |
| // process. | |
| document.getElementById('addContent').addEventListener('click', (e) => { | |
| document.getElementById('content').innerHTML = document.getElementById('content').innerHTML + document.getElementById('content').innerHTML; | |
| }); | |
| document.getElementById('resetter').addEventListener('click', (e) => { | |
| document.getElementById('content').innerText = 'this is text.'; | |
| }); | |
| // automatically resize on content change | |
| var observer = new MutationObserver(function (mutations) { | |
| window.electron.resizerContent(document.body.scrollHeight) | |
| }); | |
| var container = document.documentElement || document.body; | |
| var config = { subtree: true, attributes: false, childList: true, characterData: false }; | |
| observer.observe(container, config); |
| /* Empty */ |