diff --git a/src/client/dialogs/appSettingsDialog.tsx b/src/client/dialogs/appSettingsDialog.tsx index 9a4db63f1..8cfd0e86d 100644 --- a/src/client/dialogs/appSettingsDialog.tsx +++ b/src/client/dialogs/appSettingsDialog.tsx @@ -111,7 +111,8 @@ export class AppSettingsDialog extends React.Component<{}, {}> { browseForNgrokPath = () => { const dir = path.dirname(this.ngrokPathInputRef.value); - remote.dialog.showOpenDialog({ + remote.dialog.showOpenDialog( + remote.getCurrentWindow(), { title: 'Browse for ngrok', defaultPath: dir, properties: ['openFile'] diff --git a/src/client/index.tsx b/src/client/index.tsx index 3737b35a8..491463e44 100644 --- a/src/client/index.tsx +++ b/src/client/index.tsx @@ -74,7 +74,79 @@ window.open = (url: string): any => { navigate(url); } +// Right-click context menu for edit boxes + +const remote = require('electron').remote; +const Menu = remote.Menu; + +const ContextMenuRW = Menu.buildFromTemplate([{ + label: 'Undo', + role: 'undo', + }, { + label: 'Redo', + role: 'redo', + }, { + type: 'separator', + }, { + label: 'Cut', + role: 'cut', + }, { + label: 'Copy', + role: 'copy', + }, { + label: 'Paste', + role: 'paste', + } +]); + +const ContextMenuRO = Menu.buildFromTemplate([{ + label: 'Undo', + role: 'undo', + enabled: false + }, { + label: 'Redo', + role: 'redo', + enabled: false + }, { + type: 'separator', + }, { + label: 'Cut', + role: 'cut', + enabled: false + }, { + label: 'Copy', + role: 'copy', + enabled: false + }, { + label: 'Paste', + role: 'paste', + enabled: false + } +]); + +document.body.addEventListener('contextmenu', (e) => { + e.preventDefault(); + e.stopPropagation(); + + let node: any = e.target; + + while (node) { + if (node.nodeName.match(/^(input|textarea)$/i) || node.isContentEditable) { + if (node.readOnly) { + ContextMenuRO.popup(remote.getCurrentWindow()); + } else { + ContextMenuRW.popup(remote.getCurrentWindow()); + } + break; + } + node = node.parentNode; + } +}); + +// Load settings Settings.startup(); +// Load main control + ReactDOM.render(, document.getElementById('mainview')); diff --git a/src/server/main.ts b/src/server/main.ts index e9314af25..4b1b05b4d 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -32,6 +32,7 @@ // import * as Electron from 'electron'; +import { Menu } from 'electron'; import { Emulator } from './emulator'; import { getSettings, dispatch } from './settings'; import { WindowStateAction } from './reducers/windowStateReducer'; @@ -54,18 +55,18 @@ const createMainWindow = () => { // TODO: Make a better/safer window state restoration module // (handles change in display dimensions, maximized state, etc) const safeLowerBound = (val: any, lowerBound: number) => { - if (typeof(val) === 'number') { + if (typeof (val) === 'number') { return Math.max(lowerBound, val); } } const settings = getSettings(); mainWindow = new Electron.BrowserWindow( - { - width: safeLowerBound(settings.windowState.width, 0), - height: safeLowerBound(settings.windowState.height, 0), - x: safeLowerBound(settings.windowState.left, 0), - y: safeLowerBound(settings.windowState.top, 0) - }); + { + width: safeLowerBound(settings.windowState.width, 0), + height: safeLowerBound(settings.windowState.height, 0), + x: safeLowerBound(settings.windowState.left, 0), + y: safeLowerBound(settings.windowState.top, 0) + }); //mainWindow.webContents.openDevTools(); mainWindow.setTitle(`Microsoft Bot Framework Emulator (v${pjson.version})`); @@ -104,15 +105,15 @@ const createMainWindow = () => { mainWindow.webContents.once('did-finish-load', () => { let page = url.format({ - protocol:'file', - slashes : true, + protocol: 'file', + slashes: true, pathname: path.join(__dirname, '../client/index.html') }); mainWindow.loadURL(page); }); let splash = url.format({ - protocol:'file', - slashes : true, + protocol: 'file', + slashes: true, pathname: path.join(__dirname, '../client/splash.html') }); mainWindow.loadURL(splash);