diff --git a/src/vs/base/browser/ui/actionbar/actionbar.ts b/src/vs/base/browser/ui/actionbar/actionbar.ts index b7b4120c57d7fd5f7e4e4c54a9bb78fdcd7ac9cd..d8e0875177b74f78fb4331663164c46ae7f077fc 100644 --- a/src/vs/base/browser/ui/actionbar/actionbar.ts +++ b/src/vs/base/browser/ui/actionbar/actionbar.ts @@ -10,6 +10,7 @@ import nls = require('vs/nls'); import lifecycle = require('vs/base/common/lifecycle'); import {Promise} from 'vs/base/common/winjs.base'; import {Builder, $} from 'vs/base/browser/builder'; +import platform = require('vs/base/common/platform'); import {IAction, IActionRunner, Action, ActionRunner} from 'vs/base/common/actions'; import DOM = require('vs/base/browser/dom'); import {EventType as CommonEventType} from 'vs/base/common/events'; @@ -115,6 +116,10 @@ export class BaseActionItem extends EventEmitter implements IActionItem { this.builder.on(DOM.EventType.CLICK, (event: Event) => { this.onClick(event); }); this.builder.on(EventType.Tap, e => { this.onClick(e); }); + if (platform.isMacintosh) { + this.builder.on(DOM.EventType.CONTEXT_MENU, (event: Event) => { this.onClick(event); }); // https://github.com/Microsoft/vscode/issues/1011 + } + this.builder.on('mousedown', (e: MouseEvent) => { if (e.button === 0 && this._action.enabled) { this.builder.addClass('active'); diff --git a/src/vs/base/browser/ui/messagelist/messageList.ts b/src/vs/base/browser/ui/messagelist/messageList.ts index 192b11d8ccfb226f9d1a5cd66cb3cd5babcb93d7..f305ef485cfba7332510e813c617ff80705370ea 100644 --- a/src/vs/base/browser/ui/messagelist/messageList.ts +++ b/src/vs/base/browser/ui/messagelist/messageList.ts @@ -15,6 +15,8 @@ import types = require('vs/base/common/types'); import Event, {Emitter} from 'vs/base/common/event'; import {Action} from 'vs/base/common/actions'; import htmlRenderer = require('vs/base/browser/htmlContentRenderer'); +import {StandardKeyboardEvent} from 'vs/base/browser/keyboardEvent'; +import {CommonKeybindings} from 'vs/base/common/keyCodes'; export enum Severity { Info, @@ -197,7 +199,14 @@ export class MessageList { messageActions.forEach((action) => { let clazz = (total > 1 || delta < 0) ? 'message-right-side multiple' : 'message-right-side'; li.div({ class: clazz }, (div) => { - div.a({ class: 'action-button' }).text(action.label).on('click', (e) => { + div.a({ class: 'action-button', tabindex: '0' }).text(action.label).on([DOM.EventType.CLICK, DOM.EventType.KEY_DOWN], (e) => { + if (e instanceof KeyboardEvent) { + let event = new StandardKeyboardEvent(e); + if (!event.equals(CommonKeybindings.ENTER) && !event.equals(CommonKeybindings.SPACE)) { + return; // Only handle Enter/Escape for keyboard access + } + } + DOM.EventHelper.stop(e, true); if (this.usageLogger) { diff --git a/src/vs/workbench/browser/parts/activitybar/media/activityaction.css b/src/vs/workbench/browser/parts/activitybar/media/activityaction.css index 5c91ac95da421104b84060e26c3baea4c14550e2..9916c32ac74fb65306b416c86304ee5825c55b2b 100644 --- a/src/vs/workbench/browser/parts/activitybar/media/activityaction.css +++ b/src/vs/workbench/browser/parts/activitybar/media/activityaction.css @@ -79,14 +79,6 @@ text-decoration: none; } -.monaco-workbench > .activitybar > .content .monaco-action-bar .action-item.active { - -ms-transform: none; - -webkit-transform: none; - -moz-transform: none; - -o-transform: none; - transform: none; -} - .monaco-workbench > .activitybar > .content .monaco-action-bar .badge { position: absolute; top: 0; @@ -115,54 +107,6 @@ opacity: 1; } -.monaco-workbench.vs > .activitybar.left > .content > .monaco-action-bar.position-top .action-label.active:after { - content: ''; - position: absolute; - top: 15px; - right: 0; - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-right: 5px solid #F6F6F6; -} - -.monaco-workbench.vs-dark > .activitybar.left > .content > .monaco-action-bar.position-top .action-label.active:after { - content: ''; - position: absolute; - top: 15px; - right: 0; - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-right: 5px solid #252526; -} - -.monaco-workbench.vs > .activitybar.right > .content > .monaco-action-bar.position-top .action-label.active:before { - content: ''; - position: absolute; - top: 15px; - left: 0; - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid #F6F6F6; -} - -.monaco-workbench.vs-dark > .activitybar.right > .content > .monaco-action-bar.position-top .action-label.active:before { - content: ''; - position: absolute; - top: 15px; - left: 0; - width: 0; - height: 0; - border-top: 5px solid transparent; - border-bottom: 5px solid transparent; - border-left: 5px solid #252526; -} - /* Right aligned */ .monaco-workbench > .activitybar.right > .content .monaco-action-bar .action-label { diff --git a/src/vs/workbench/browser/viewlet.ts b/src/vs/workbench/browser/viewlet.ts index 41784402d0eeadbcb8d2a72b0dbde0f4ecaaf223..285dc0599959093ccaf5965773d8d92e7b7dd1ff 100644 --- a/src/vs/workbench/browser/viewlet.ts +++ b/src/vs/workbench/browser/viewlet.ts @@ -334,7 +334,7 @@ export class AdaptiveCollapsibleViewletView extends FixedCollapsibleView impleme } protected changeState(state: CollapsibleState): void { - changeState(state, this.tree); + updateTreeVisibility(this.tree, state === CollapsibleState.EXPANDED, true /* focus if expanded */); super.changeState(state); } @@ -354,11 +354,7 @@ export class AdaptiveCollapsibleViewletView extends FixedCollapsibleView impleme public setVisible(visible: boolean): TPromise { this.isVisible = visible; - if (visible) { - this.tree.onVisible(); - } else { - this.tree.onHidden(); - } + updateTreeVisibility(this.tree, this.state === CollapsibleState.EXPANDED); return Promise.as(null); } @@ -441,7 +437,7 @@ export class CollapsibleViewletView extends CollapsibleView implements IViewletV } protected changeState(state: CollapsibleState): void { - changeState(state, this.tree); + updateTreeVisibility(this.tree, state === CollapsibleState.EXPANDED, true /* focus if expanded */); super.changeState(state); } @@ -483,11 +479,7 @@ export class CollapsibleViewletView extends CollapsibleView implements IViewletV public setVisible(visible: boolean): TPromise { this.isVisible = visible; - if (visible) { - this.tree.onVisible(); - } else { - this.tree.onHidden(); - } + updateTreeVisibility(this.tree, this.state === CollapsibleState.EXPANDED); return Promise.as(null); } @@ -550,17 +542,26 @@ function renderViewTree(container: HTMLElement): HTMLElement { return treeContainer; } -function changeState(state: CollapsibleState, tree: ITree): void { +function updateTreeVisibility(tree: ITree, isVisible: boolean, focusIfVisible?: boolean): void { if (!tree) { return; } - if (state == CollapsibleState.EXPANDED) { + if (isVisible) { $(tree.getHTMLElement()).show(); - tree.DOMFocus(); // make the tree have focus once a view gets expanded } else { $(tree.getHTMLElement()).hide(); // make sure the tree goes out of the tabindex world by hiding it } + + if (focusIfVisible && isVisible) { + tree.DOMFocus(); + } + + if (isVisible) { + tree.onVisible(); + } else { + tree.onHidden(); + } } function focus(tree: ITree): void { diff --git a/src/vs/workbench/electron-browser/media/shell.css b/src/vs/workbench/electron-browser/media/shell.css index 2d3b49836f53f6cac7eebb885f43fb6025e1e1a8..fbc14c349bf9db45d5006bd87b0b37efd0b35bc3 100644 --- a/src/vs/workbench/electron-browser/media/shell.css +++ b/src/vs/workbench/electron-browser/media/shell.css @@ -78,28 +78,24 @@ outline-offset: -2px; } -.monaco-shell.vs .monaco-tree.focused .monaco-tree-rows:empty, -.monaco-shell.vs .monaco-tree.focused.no-item-focus .monaco-tree-rows { +.monaco-shell.vs .monaco-tree.focused:focus .monaco-tree-rows:empty, +.monaco-shell.vs .monaco-tree.focused:focus.no-item-focus .monaco-tree-rows { outline: 1px auto #1E8AE5; /* we still need to handle the empty tree or no focus item case */ - outline-offset: -3px; + outline-offset: -2px; } -.monaco-shell.vs-dark .monaco-tree.focused .monaco-tree-rows:empty, -.monaco-shell.vs-dark .monaco-tree.focused.no-item-focus .monaco-tree-rows { +.monaco-shell.vs-dark .monaco-tree.focused:focus .monaco-tree-rows:empty, +.monaco-shell.vs-dark .monaco-tree.focused.no-item-focus:focus .monaco-tree-rows { outline: 1px auto #1E8AE5; /* we still need to handle the empty tree or no focus item case */ - outline-offset: -3px; + outline-offset: -2px; } -.monaco-shell.hc-black .monaco-tree.focused .monaco-tree-rows:empty, -.monaco-shell.hc-black .monaco-tree.focused.no-item-focus .monaco-tree-rows { +.monaco-shell.hc-black .monaco-tree.focused:focus .monaco-tree-rows:empty, +.monaco-shell.hc-black .monaco-tree.focused.no-item-focus:focus .monaco-tree-rows { outline: 2px auto #DF740C; /* we still need to handle the empty tree or no focus item case */ outline-offset: -2px; } -.monaco-shell .quick-open-widget .quick-open-tree .monaco-tree-rows { - outline: 0 !important; /* quick open is special because focus is always in the input field */ -} - .monaco-shell input[type="text"], .monaco-shell textarea { outline: 0; /* do not show outline in input fields and textarea */ } @@ -109,7 +105,11 @@ } .monaco-shell .activitybar [tabindex="0"]:focus { - outline: 0 !important; /* activity bar indicates focus customly */ + outline: 0; /* activity bar indicates focus custom */ +} + +.monaco-shell .part.editor .binary-container:focus { + outline: 0; /* binary container indicates focus custom */ } /* END Keyboard Focus Indication Styles */ diff --git a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts index fcdda7eac8e3acf9296a159d0da738f94d6ba5a2..a16aa8c0cdfa34f31cbefc2469ac8808b9e90c3c 100644 --- a/src/vs/workbench/parts/files/browser/views/explorerViewer.ts +++ b/src/vs/workbench/parts/files/browser/views/explorerViewer.ts @@ -317,7 +317,7 @@ export class FileRenderer extends ActionsRenderer implements Tree.IRenderer { var toDispose = [ inputBox, - DOM.addStandardDisposableListener(inputBox.inputElement, 'keydown', (e: DOM.IKeyboardEvent) => { + DOM.addStandardDisposableListener(inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: DOM.IKeyboardEvent) => { if (e.equals(CommonKeybindings.ENTER)) { if (inputBox.validate() && !disposed) { commit(); diff --git a/src/vs/workbench/parts/git/browser/views/changes/changesView.ts b/src/vs/workbench/parts/git/browser/views/changes/changesView.ts index 9dfef0a964a514b5261139204b943c5fb341cc8a..5affc748b5063b680e893c0fee7c69d46b2fb061 100644 --- a/src/vs/workbench/parts/git/browser/views/changes/changesView.ts +++ b/src/vs/workbench/parts/git/browser/views/changes/changesView.ts @@ -200,7 +200,7 @@ export class ChangesView extends EventEmitter.EventEmitter implements GitView.IV this.currentDimension = dimension; this.commitInputBox.layout(); - var statusViewHeight = dimension.height - (this.commitInputBox.height + 10 /* margin */); + var statusViewHeight = dimension.height - (this.commitInputBox.height + 12 /* margin */); this.$statusView.size(dimension.width, statusViewHeight); this.tree.layout(statusViewHeight);