moving to electron 14+, jumping through hoops...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2022-01-26 22:19:42 +03:00
parent 0a85322798
commit 6f77e6116b
6 changed files with 2560 additions and 2181 deletions

View File

@ -302,6 +302,16 @@ button:hover {
color: red;
}
.drag-bar {
position: absolute;
-webkit-app-region: drag;
height: 50px;
top: 0px;
left: 0px;
right: 0px;
}
/*
.full-screen-mode .title-bar {
display: none;
@ -313,6 +323,7 @@ button:hover {
display: block;
position: relative;
float: left;
-webkit-app-region: no-drag;
size: 30px;

View File

@ -35,6 +35,7 @@ var VERSION = require('./version').version
var app = electron.app
var BrowserWindow = electron.BrowserWindow
var ipcMain = electron.ipcMain
//
global.ELECTRON_PACKAGED = app.isPackaged
@ -46,15 +47,17 @@ global.START_GUI = false
/*********************************************************************/
// XXX do we need multiwindow support???
// Splash window...
//
// XXX might be nice to show load progress on splash...
var SPLASH
function createSplash(){
// NOTE: this is done here as this does not depend on code loading,
// thus showing the splash significantly faster...
var splash = global.splash = new BrowserWindow({
SPLASH = new BrowserWindow({
// let the window to get ready before we show it to the user...
show: false,
@ -74,31 +77,44 @@ function createSplash(){
autoHideMenuBar: true,
})
splash.loadURL(url.format({
SPLASH.loadURL(url.format({
pathname: path.join(__dirname, 'splash.html'),
protocol: 'file:',
slashes: true
}))
splash.once('ready-to-show', function(){
SPLASH.once('ready-to-show', function(){
this.webContents
// see if the splash screen is disabled...
.executeJavaScript('localStorage.disableSplashScreen')
.then(function(disabled){
// update version...
disabled
|| splash.webContents
.executeJavaScript(
`document.getElementById("version").innerText = "${VERSION}"`)
// show/destroy..
disabled ?
splash.destroy()
: splash.show() }) })
return splash }
.then(function(disabled){
// update version...
disabled
|| SPLASH.webContents
.executeJavaScript(
`document.getElementById("version").innerText = "${VERSION}"`)
// show/destroy..
disabled ?
SPLASH.destroy()
: SPLASH.show() }) })
SPLASH.on('closed',
function(){
SPLASH = null
WIN
&& WIN.webContents.executeJavaScript('document.appSplashScreen = false') })
// handle main window state...
WIN
&& WIN.webContents.executeJavaScript('document.appSplashScreen = true')
return SPLASH }
// Create main window...
//
// XXX get initial settings from config...
// XXX handle maximize corretly...
// ...currently it does not differ visually from fullscreen -- either
// make them the same or keep them separate visually...
var WIN
function createWindow(){
// Create the browser window.
@ -112,6 +128,7 @@ function createWindow(){
// let the window get ready before we show it to the user...
show: false,
frame: false,
backgroundColor: '#333333',
@ -129,18 +146,39 @@ function createWindow(){
protocol: 'file:',
slashes: true,
}))
// XXX HACK: pass this in a formal way... (???)
WIN.once('ready-to-show',
function(){ global.readyToShow = true })
function(){
WIN.webContents.executeJavaScript(`
document.readyToShow = true
// XXX make these a prop...
document.appFullScreen = false
document.appDevTools = false
`)
// splash screen...
WIN.webContents.executeJavaScript(
SPLASH ?
'document.appSplashScreen = true'
: 'document.appSplashScreen = false') })
WIN.on('closed',
function(){ WIN = null })
// devtools...
WIN.on('devtools-opened',
function(){
WIN && WIN.webContents.executeJavaScript('document.appDevTools = true') })
WIN.on('devtools-closed',
function(){
WIN && WIN.webContents.executeJavaScript('document.appDevTools = false') })
// handle env...
// devtools for different windows...
//process.env.IMAGEGRID_ROOT_DEBUG
// && WIN.openDevTools({mode: 'undocked'})
process.env.IMAGEGRID_DEBUG
&& WIN.openDevTools({mode: 'undocked'})
//&& WIN.webContents.openDevTools({mode: 'undocked'})
// Force show window...
process.env.IMAGEGRID_FORCE_SHOW
&& WIN.show()
return WIN }
@ -163,9 +201,9 @@ function start(){
// 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.
// XXX test...
app.on('activate', function(){
WIN === null
&& createWindow() })
WIN || createWindow() })
// Quit when all windows are closed.
// On macOS it is common for applications and their menu bar
@ -176,6 +214,49 @@ app.on('window-all-closed', function(){
//---------------------------------------------------------------------
// Window states...
ipcMain.on('show',
function(){ WIN && WIN.show() })
ipcMain.on('hide',
function(){ WIN && WIN.hide() })
ipcMain.on('minimize',
function(){ WIN && WIN.minimize() })
ipcMain.on('enterFullScreen',
function(){
if(WIN){
WIN.setFullScreen(true)
WIN.webContents.executeJavaScript('document.appFullScreen = true') } })
ipcMain.on('exitFullScreen',
function(){
if(WIN){
WIN.setFullScreen(false)
WIN.webContents.executeJavaScript('document.appFullScreen = false') } })
// Splash screen...
ipcMain.on('openSplashScreen',
function(){ SPLASH || createSplash() })
ipcMain.on('closeSplashScreen',
function(){ SPLASH && SPLASH.destroy() })
// devtools...
// XXX need to focus devtools here...
// see: webContents.getAllWebContents()
ipcMain.on('openDevTools',
function(){
WIN
&& WIN.openDevTools({
mode: 'undocked',
activate: true,
}) })
ipcMain.on('closeDevTools',
function(){ WIN && WIN.closeDevTools() })
//---------------------------------------------------------------------
// start things up...

View File

@ -212,8 +212,7 @@ var NWHostActions = actions.Actions({
function(action){
if(action == '?'){
// XXX get the devtools stage...
return false
}
return false }
nw.Window.get().showDevTools &&
nw.Window.get().showDevTools()
}],
@ -257,46 +256,44 @@ var ElectronHostActions = actions.Actions({
// XXX should this be nested in a .window object???
// XXX should these be props or methods???
get title(){
return electron.remote.getCurrentWindow().getTitle() },
return document.title },
set title(value){
electron.remote.getCurrentWindow().setTitle(value) },
document.title = value },
get size(){
return electron.remote.getCurrentWindow().getSize() },
return [window.outerWidth, window.outerHeight] },
set size(value){
value
&& electron.remote.getCurrentWindow()
.setSize(Math.round(value[0]), Math.round(value[1])) },
&& window.resizeTo(...value) },
get position(){
return electron.remote.getCurrentWindow().getPosition() },
return [window.screenX, window.screenY] },
set position(value){
value
&& electron.remote.getCurrentWindow()
.setPosition(Math.round(value[0]), Math.round(value[1])) },
&& window.moveTo(...value) },
// XXX revise...
// XXX need to handle mazimize correctly -- see e.js...
// XXX do we need .hide(..) here???
show: ['- Window/',
function(){
if(electron.remote.getGlobal('readyToShow')){
electron.remote.getCurrentWindow().show()
} else {
var win = electron.remote.getCurrentWindow()
win.once('ready-to-show', function(){
win.show()
})
}
}],
electron.ipcRenderer.send('show') }],
// if(electron.remote.getGlobal('readyToShow')){
// electron.remote.getCurrentWindow().show()
// } else {
// var win = electron.remote.getCurrentWindow()
// win.once('ready-to-show',
// function(){ win.show() }) } }],
minimize: ['Window/Minimize',
function(){
electron.remote.getCurrentWindow().minimize() }],
electron.ipcRenderer.send('minimize') }],
toggleFullScreen: ['Window/Full screen mode',
toggler.CSSClassToggler(
function(){ return document.body },
'.full-screen-mode',
function(action){
var that = this
var win = electron.remote.getCurrentWindow()
var state = win.isFullScreen() ? 'on' : 'off'
// get current state...
var state = document.appFullScreen ? 'on' : 'off'
// change the state only if the target state is not the same
// as the current state...
@ -306,10 +303,14 @@ var ElectronHostActions = actions.Actions({
// hide the viewer to hide any animation crimes...
this.dom[0].style.visibility = 'hidden'
// XXX async...
// ...this complicates things as we need to do the next
// bit AFTER the resize is done...
win.setFullScreen(action == 'on' ? true : false)
// NOTE: electrons policy that developers can't trust
// their own code making them jump through context
// hoops all of the time instead of in the specific
// contexts that need isolation is crap...
electron.ipcRenderer.send(
state == 'on' ?
'exitFullScreen'
: 'enterFullScreen')
setTimeout(function(){
that
@ -317,32 +318,16 @@ var ElectronHostActions = actions.Actions({
.focusImage()
.ribbons
.restoreTransitions()
that.dom[0].style.visibility = ''
}, 100)
}
// NOTE: we delay this to account for window animation...
setTimeout(function(){
that.storeWindowGeometry()
}, 500)
})],
// show viewer after we are done...
that.dom[0].style.visibility = '' }, 150) } })],
// XXX should this be a toggler???
showDevTools: ['Interface|Development/Show Dev Tools',
{mode: 'advancedBrowseModeAction'},
function(action){
var w = electron.remote.getCurrentWindow()
if(action == '?'){
return w.isDevToolsOpened()
}
w.openDevTools()
// focus the devtools if its window is available...
w.devToolsWebContents
&& w.devToolsWebContents.focus()
}],
return document.appDevTools }
electron.ipcRenderer.send('openDevTools') }],
// XXX make this portable (osx, linux)...
showInFolder: ['File|Image/Show in $folder',
function(image){
@ -363,60 +348,16 @@ var ElectronHostActions = actions.Actions({
toggleSplashScreen: ['Interface/',
{mode: 'advancedBrowseModeAction'},
function(action){
var splash = this.splash = (!this.splash || this.splash.isDestroyed()) ?
electron.remote.getGlobal('splash')
: this.splash
var splash = document.appSplashScreen
if(action == '?'){
return !splash || splash.isDestroyed() ? 'off' : 'on'
}
return !splash ? 'off' : 'on' }
// XXX HACK: use real toggler protocol...
if(action != 'off' && (!splash || splash.isDestroyed())){
var splash = this.splash =
// XXX move this to splash.js and use both here and in e.js...
new electron.remote.BrowserWindow({
// let the window to get ready before we show it to the user...
show: false,
transparent: true,
frame: false,
center: true,
width: 800,
height: 500,
alwaysOnTop: true,
resizable: false,
movable: false,
minimizable: false,
maximizable: false,
fullscreenable: false,
autoHideMenuBar: true,
})
splash.setMenu(null)
// and load the index.html of the app.
splash.loadURL(url.format({
// XXX unify this with index.html
pathname: pathlib.join(__dirname, 'splash.html'),
protocol: 'file:',
slashes: true
}))
splash.once('ready-to-show', function(){
splash.webContents
.executeJavaScript(
`document.getElementById("version").innerText = "${VERSION}"`)
splash.show()
})
if(action != 'off' && !splash){
electron.ipcRenderer.send('openSplashScreen')
} else if(action != 'on' && splash){
splash.destroy()
}
}],
electron.ipcRenderer.send('closeSplashScreen') } }],
// XXX should this support resizing???
copy: ['Image|Edit/Copy image',
@ -669,7 +610,8 @@ var WindowedAppControlActions = actions.Actions({
// is defined...
var cfg = this.config.window = this.config.window || {}
cfg.fullscreen = true
cfg.devtools = this.showDevTools('?')
cfg.devtools = this.showDevTools
&& this.showDevTools('?')
} else {
this.config.window = {
@ -680,18 +622,15 @@ var WindowedAppControlActions = actions.Actions({
y: position[1],
fullscreen: false,
devtools: this.showDevTools('?'),
}
}
}],
devtools: this.showDevTools
&& this.showDevTools('?'),
} } }],
restoreWindowGeometry: ['- Window/Restore window state',
function(){
var that = this
var cfg = this.config.window || {}
var fullscreen = cfg.fullscreen || false
if(fullscreen){
if(cfg.fullscreen){
that.toggleFullScreen('on')
} else {
@ -701,9 +640,7 @@ var WindowedAppControlActions = actions.Actions({
var y = cfg.y || (screen.height - h)/2
this.position = [x, y]
this.size = [w, h]
}
}],
this.size = [w, h] } }],
toggleSplashScreenShowing: ['Interface/Splash screen on start',
{mode: 'advancedBrowseModeAction'},
@ -761,6 +698,9 @@ module.WindowedAppControl = core.ImageGridFeatures.Feature({
// NOTE: this will also set the size to which the OS will
// resize the window in state change...
if(cfg){
cfg.devtools
&& this.showDevTools()
var W = screen.width
var H = screen.height
var w = cfg.width || Math.max(0.8 * W, 600)
@ -769,18 +709,14 @@ module.WindowedAppControl = core.ImageGridFeatures.Feature({
var y = cfg.y || (H - h)/2
this.position = [x, y]
this.size = [w, h]
cfg.devtools
&& this.showDevTools() }
this.size = [w, h] }
// restore actual window state...
this.restoreWindowGeometry()
// declare we are ready when DOM is ready...
$(function(){
that.declareReady('ui-windowed-app-control') })
}],
that.declareReady('ui-windowed-app-control') }) }],
// show window + hide splash screen...
['ready',

View File

@ -63,8 +63,7 @@ if(window.require){
// electron...
} else {
try{
require('electron').remote.getCurrentWindow()
.openDevTools({mode: 'undocked'})
require('electron').ipcRenderer.send('openDevTools')
} catch(err){ } }
}, STARTUP_DEVTOOLS_TIMEOUT) }
</script>
@ -180,7 +179,9 @@ if(typeof(process) == 'undefined'){
<!-- The Viewer block (see: imagegrid/ribbons.js) -->
<div class="viewer gray marks-visible" tabindex="0"></div>
<div class="viewer gray marks-visible" tabindex="0">
<div class="drag-bar"></div>
</div>
<!-- vim:set ts=4 sw=4 spell nowrap : -->

4434
Viewer/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@
"async-json": "0.0.2",
"cli-progress": "^3.9.0",
"colors": "^1.4.0",
"electron": "^9.4.3",
"electron": "*",
"exif-reader": "^1.0.3",
"exifreader": "^2.6.0",
"exiftool": "^0.0.3",
@ -55,7 +55,7 @@
},
"devDependencies": {
"asar": "^3.0.1",
"electron-rebuild": "^1.11.0",
"electron-rebuild": "*",
"less": "^3.13.1",
"rcedit": "^3.0.0"
},