Skip to content
Permalink
Browse files

Move the location-bar's autocomplete into a dedicated window and keep…

… the input control in the shell-window. This improves the effective performance of the location bar. (close #1349)
  • Loading branch information...
pfrazee committed Mar 7, 2019
1 parent b8f51b9 commit 41ca12b5ed2ab4cfcc90b45d142d37f26685ea98
@@ -96,6 +96,9 @@ async function beakerProtocol (request, respond) {
if (requestUrl === 'beaker://shell-window/main.css') {
return cb(200, 'OK', 'text/css; charset=utf-8', path.join(__dirname, 'stylesheets/shell-window.css'))
}
if (requestUrl === 'beaker://location-bar/') {
return cb(200, 'OK', 'text/html; charset=utf-8', path.join(__dirname, 'location-bar.html'))
}
if (requestUrl === 'beaker://shell-menus/') {
return cb(200, 'OK', 'text/html; charset=utf-8', path.join(__dirname, 'shell-menus.html'))
}
@@ -0,0 +1,6 @@
export default {
close: 'promise',
createTab: 'promise',
loadURL: 'promise',
resizeSelf: 'promise'
}
@@ -20,6 +20,9 @@ export default {
hideInpageFind: 'promise',
setInpageFindString: 'promise',
moveInpageFind: 'promise',
showLocationBar: 'promise',
hideLocationBar: 'promise',
runLocationBarCmd: 'promise',
showMenu: 'promise',
toggleMenu: 'promise',
focusShellWindow: 'promise'
@@ -0,0 +1,148 @@
/**
* Location Bar
*
* NOTES
* - There can only ever be one Location Bar window for a given browser window
* - Location Bar windows are created with each browser window and then shown/hidden as needed
* - When unfocused, the Location Bar window is hidden (it's meant to act as a popup menu)
*/
import path from 'path'
import Events from 'events'
import { BrowserWindow } from 'electron'
import * as rpc from 'pauls-electron-rpc'
import locationBarRPCManifest from '../../rpc-manifests/location-bar'
import * as viewManager from '../view-manager'

const WIDTH = 800
const HEIGHT = 310

// globals
// =

var events = new Events()
var windows = {} // map of {[parentWindow.id] => BrowserWindow}

// exported api
// =

export function setup (parentWindow) {
var win = windows[parentWindow.id] = new BrowserWindow({
width: WIDTH,
height: HEIGHT,
parent: parentWindow,
frame: false,
resizable: false,
maximizable: false,
show: false,
fullscreenable: false,
acceptFirstMouse: true,
webPreferences: {
defaultEncoding: 'utf-8',
preload: path.join(__dirname, 'location-bar.build.js')
}
})
win.webContents.on('console-message', (e, level, message) => {
console.log('Location-Bar window says:', message)
})
win.loadURL('beaker://location-bar/')
win.on('blur', () => hide(parentWindow))
}

export function destroy (parentWindow) {
if (get(parentWindow)) {
get(parentWindow).close()
delete windows[parentWindow.id]
}
}

export function get (parentWindow) {
return windows[parentWindow.id]
}

export function reposition (parentWindow) {
var win = get(parentWindow)
if (win) {
var parentBounds = parentWindow.getBounds()
win.setBounds({
x: parentBounds.x + win.boundsOpt.x,
y: parentBounds.y + win.boundsOpt.y,
width: win.boundsOpt.width,
height: 310
})
}
}

export async function show (parentWindow, opts) {
var win = get(parentWindow)
if (win) {
win.boundsOpt = opts && opts.bounds
reposition(parentWindow)
win.webContents.executeJavaScript(`setup()`)
win.showInactive()

// await till hidden
await new Promise(resolve => {
events.once('hide', resolve)
})
}
}

export function hide (parentWindow) {
if (get(parentWindow)) {
get(parentWindow).hide()
}
}

export async function runCmd (parentWindow, cmd, opts) {
var win = get(parentWindow)
if (win) {
if (!win.isVisible()) {
if (cmd === 'set-value') {
// show first
show(parentWindow, opts)
} else {
return
}
}
return win.webContents.executeJavaScript(`command("${cmd}", ${JSON.stringify(opts)})`)
}
}

// rpc api
// =

rpc.exportAPI('background-process-location-bar', locationBarRPCManifest, {
async close () {
hide(getParentWindow(this.sender))
},

async createTab (url) {
var win = getParentWindow(this.sender)
hide(win) // always close the location bar
viewManager.create(win, url, {setActive: true})
},

async loadURL (url) {
var win = getParentWindow(this.sender)
hide(win) // always close the location bar
viewManager.getActive(win).loadURL(url)
win.webContents.send('command', 'unfocus-location') // we have to manually unfocus the location bar
},

async resizeSelf (dimensions) {
var win = BrowserWindow.fromWebContents(this.sender)
if (process.platform === 'win32') {
// on windows, add space for the border
if (dimensions.width) dimensions.width += 2
if (dimensions.height) dimensions.height += 2
}
win.setBounds(dimensions)
}
})

// internal methods
// =

function getParentWindow (sender) {
return BrowserWindow.fromWebContents(sender).getParentWindow()
}
@@ -1,21 +1,28 @@
import {BrowserWindow} from 'electron'
/**
* Status Bar
*
* NOTES
* - There can only ever be one Status Bar window for a given browser window
* - Status Bar windows are created with each browser window and then shown/hidden as needed
*/
import { BrowserWindow } from 'electron'

const WIDTH = 400
const HEIGHT = 24

// globals
// =

var windows = {} // map of {[parent.id] => BrowserWindow}
var windows = {} // map of {[parentWindow.id] => BrowserWindow}

// exported api
// =

export function setup (parent) {
windows[parent.id] = new BrowserWindow({
export function setup (parentWindow) {
windows[parentWindow.id] = new BrowserWindow({
width: WIDTH,
height: HEIGHT,
parent,
parent: parentWindow,
frame: false,
transparent: true,
resizable: false,
@@ -27,50 +34,50 @@ export function setup (parent) {
defaultEncoding: 'utf-8'
}
})
windows[parent.id].loadFile('status-bar.html')
windows[parentWindow.id].loadFile('status-bar.html')
}

export function destroy (parent) {
if (get(parent)) {
get(parent).close()
delete windows[parent.id]
export function destroy (parentWindow) {
if (get(parentWindow)) {
get(parentWindow).close()
delete windows[parentWindow.id]
}
}

export function get (parent) {
return windows[parent.id]
export function get (parentWindow) {
return windows[parentWindow.id]
}

export function reposition (parent) {
var win = get(parent)
export function reposition (parentWindow) {
var win = get(parentWindow)
if (win) {
var {x, y, height} = parent.getBounds()
var {x, y, height} = parentWindow.getBounds()
win.setBounds({x, y: y + height - HEIGHT})
}
}

export function show (parent) {
var win = get(parent)
export function show (parentWindow) {
var win = get(parentWindow)
if (win) {
reposition(parent)
reposition(parentWindow)
win.showInactive()
}
}

export function hide (parent) {
if (get(parent)) {
get(parent).hide()
export function hide (parentWindow) {
if (get(parentWindow)) {
get(parentWindow).hide()
}
}

export function set (parent, value) {
var win = get(parent)
export function set (parentWindow, value) {
var win = get(parentWindow)
if (win) {
if (value) {
show(parent)
show(parentWindow)
win.webContents.executeJavaScript(`set('${value}')`)
} else {
hide(parent)
hide(parentWindow)
}
}
}
@@ -2,7 +2,7 @@ import { app, BrowserView, BrowserWindow, Menu, clipboard } from 'electron'
import * as beakerCore from '@beaker/core'
import errorPage from '@beaker/core/lib/error-page'
import path from 'path'
import {promises as fs} from 'fs'
import { promises as fs } from 'fs'
import Events from 'events'
import _throttle from 'lodash.throttle'
import parseDatURL from 'parse-dat-url'
@@ -14,6 +14,7 @@ import normalizeURL from 'normalize-url'
import viewsRPCManifest from '../rpc-manifests/views'
import * as zoom from './views/zoom'
import * as shellMenus from './subwindows/shell-menus'
import * as locationBar from './subwindows/location-bar'
import * as statusBar from './subwindows/status-bar'
import * as permPrompt from './subwindows/perm-prompt'
import * as modals from './subwindows/modals'
@@ -1049,6 +1050,18 @@ rpc.exportAPI('background-process-views', viewsRPCManifest, {
getByIndex(getWindow(this.sender), index).moveInpageFind(dir)
},

async showLocationBar (opts) {
await locationBar.show(getWindow(this.sender), opts)
},

async hideLocationBar () {
await locationBar.hide(getWindow(this.sender))
},

async runLocationBarCmd (cmd, opts) {
return locationBar.runCmd(getWindow(this.sender), cmd, opts)
},

async showMenu (id, opts) {
await shellMenus.show(getWindow(this.sender), id, opts)
},
@@ -7,22 +7,23 @@ import * as viewManager from './view-manager'
import {
createGlobalKeybindingsHandler,
createKeybindingProtectionsHandler,
registerGlobalKeybinding,
unregisterGlobalKeybinding
registerGlobalKeybinding
} from './keybindings'
import path from 'path'
import * as openURL from '../open-url'
import * as downloads from './downloads'
import * as permissions from './permissions'
import * as statusBarSubwindow from './subwindows/status-bar'
import * as shellMenusSubwindow from './subwindows/shell-menus'
import * as locationBarSubwindow from './subwindows/location-bar'
import * as permPromptSubwindow from './subwindows/perm-prompt'
import * as modalsSubwindow from './subwindows/modals'
const settingsDb = beakerCore.dbs.settings

const IS_WIN = process.platform === 'win32'
const subwindows = {
statusBar: statusBarSubwindow,
locationBar: locationBarSubwindow,
menu: shellMenusSubwindow,
permPrompt: permPromptSubwindow,
modals: modalsSubwindow
@@ -0,0 +1,21 @@
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="beaker://assets/font-awesome.css">
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Ubuntu, Cantarell, "Oxygen Sans", "Helvetica Neue", sans-serif;
margin: 0;
background: #fafafa;
font-size: 12px;
color: rgba(0, 0, 0, 0.8);
}
body.win32 {
border: 1px solid #bbb;
}
</style>
</head>
<body>
<location-bar></location-bar> <!-- this tag will be defined in the preload script -->
</body>
</html>
Oops, something went wrong.

0 comments on commit 41ca12b

Please sign in to comment.
You can’t perform that action at this time.