diff --git a/app/renderer/components/menubar.js b/app/renderer/components/menubar.js index 3ef73fcfaab..8ecf7302c71 100644 --- a/app/renderer/components/menubar.js +++ b/app/renderer/components/menubar.js @@ -12,13 +12,21 @@ class MenubarItem extends ImmutableComponent { constructor () { super() this.onClick = this.onClick.bind(this) + this.onMouseOver = this.onMouseOver.bind(this) } onClick (e) { if (e && e.stopPropagation) { e.stopPropagation() } - + // If clicking on an already selected item, deselect it + const selected = this.props.menubar.state.selectedLabel + if (selected && selected === this.props.label) { + this.props.menubar.setState({selectedLabel: null}) + return + } + // Otherwise, mark item as selected and show its context menu + this.props.menubar.setState({selectedLabel: this.props.label}) const rect = e.target.getBoundingClientRect() windowActions.setContextMenuDetail(Immutable.fromJS({ left: rect.left, @@ -35,10 +43,18 @@ class MenubarItem extends ImmutableComponent { })) } + onMouseOver (e) { + const selected = this.props.menubar.state.selectedLabel + if (selected && selected !== this.props.label) { + this.onClick(e) + } + } + render () { return + className={'menubarItem' + (this.props.selected ? ' selected' : '')} + onClick={this.onClick} + onMouseOver={this.onMouseOver}> { this.props.label } } @@ -50,11 +66,34 @@ class MenubarItem extends ImmutableComponent { * NOTE: the system menu is still created and used in order to keep the accelerators working. */ class Menubar extends ImmutableComponent { + constructor () { + super() + this.state = { + selectedLabel: null + } + } + + shouldComponentUpdate (nextProps, nextState) { + return this.state.selectedLabel !== nextState.selectedLabel + } + + // TODO: this needs to clear its state every time a context menu is closed + // selected label would need to be in windowState for this to work + render () { return
{ - this.props.template.map((menubarItem) => - ) + this.props.template.map((menubarItem) => { + let props = { + label: menubarItem.get('label'), + submenu: menubarItem.get('submenu').toJS(), + menubar: this + } + if (props.label === this.state.selectedLabel) { + props.selected = true + } + return + }) }
} diff --git a/js/stores/appStore.js b/js/stores/appStore.js index 9996a3518c7..cb7322f059a 100644 --- a/js/stores/appStore.js +++ b/js/stores/appStore.js @@ -674,6 +674,7 @@ const handleAppAction = (action) => { break case ExtensionConstants.EXTENSION_DISABLED: appState = extensionState.extensionDisabled(appState, action) + break case AppConstants.APP_SET_MENUBAR_TEMPLATE: appState = appState.setIn(['menu', 'template'], action.menubarTemplate) break diff --git a/js/stores/windowStore.js b/js/stores/windowStore.js index e7d7b134c68..157a2bdb5d7 100644 --- a/js/stores/windowStore.js +++ b/js/stores/windowStore.js @@ -774,8 +774,11 @@ const doAction = (action) => { } break case WindowConstants.WINDOW_TOGGLE_MENUBAR_VISIBLE: + // Close existing context menus + windowState = windowState.delete('contextMenuDetail') + // Use value if provided; if not, toggle to opposite. if (getSetting(settings.AUTO_HIDE_MENU)) { - if (typeof action.isVisible === 'boolean'){ + if (typeof action.isVisible === 'boolean') { windowState = windowState.setIn(['ui', 'menubar', 'isVisible'], action.isVisible) } else { const currentStatus = windowState.getIn(['ui', 'menubar', 'isVisible']) diff --git a/less/navigationBar.less b/less/navigationBar.less index 4331f0abf1a..4c51b18e7f2 100644 --- a/less/navigationBar.less +++ b/less/navigationBar.less @@ -405,6 +405,7 @@ -webkit-user-select: none; -webkit-app-region: drag; height: 29px; + display: inline-block; .menubar { display: inline-block; @@ -425,6 +426,11 @@ border: 1px solid #cce8ff; } } + + .selected { + background-color: #cce8ff !important; + border: 1px solid #99d1ff !important; + } } }