Skip to content

Commit

Permalink
Merge branch 'master' into serialize-webview-copy
Browse files Browse the repository at this point in the history
Signed-off-by: Vitaliy Gulyy <vgulyy@redhat.com>
  • Loading branch information
vitaliy-guliy committed Oct 29, 2020
2 parents 579f971 + 6fe570d commit a7bf3ba
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 42 deletions.
12 changes: 11 additions & 1 deletion packages/core/src/browser/core-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,22 @@ export const corePreferenceSchema: PreferenceSchema = {
enum: ['onHover', 'none', 'always'],
default: 'onHover',
description: 'Controls whether the tree should render indent guides.'
}
},
'keyboard.dispatch': {
type: 'string',
enum: [
'code',
'keyCode',
],
default: 'code',
description: 'Whether to interpret keypresses by the `code` of the physical key, or by the `keyCode` provided by the OS.'
},
}
};

export interface CoreConfiguration {
'application.confirmExit': 'never' | 'ifRequired' | 'always';
'keyboard.dispatch': 'code' | 'keyCode';
'workbench.list.openMode': 'singleClick' | 'doubleClick';
'workbench.commandPalette.history': number;
'workbench.editor.highlightModifiedTabs': boolean;
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/browser/keybinding.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { MockLogger } from '../common/test/mock-logger';
import { StatusBar, StatusBarImpl } from './status-bar/status-bar';
import { FrontendApplicationStateService } from './frontend-application-state';
import { ContextKeyService } from './context-key-service';
import { CorePreferences } from './core-preferences';
import * as os from '../common/os';
import * as chai from 'chai';
import * as sinon from 'sinon';
Expand Down Expand Up @@ -85,6 +86,7 @@ before(async () => {
bind(LabelParser).toSelf().inSingletonScope();
bind(ContextKeyService).toSelf().inSingletonScope();
bind(FrontendApplicationStateService).toSelf().inSingletonScope();
bind(CorePreferences).toConstantValue(<CorePreferences>{});
});

testContainer.load(module);
Expand Down
7 changes: 6 additions & 1 deletion packages/core/src/browser/keybinding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { ContributionProvider } from '../common/contribution-provider';
import { ILogger } from '../common/logger';
import { StatusBarAlignment, StatusBar } from './status-bar/status-bar';
import { ContextKeyService } from './context-key-service';
import { CorePreferences } from './core-preferences';
import * as common from '../common/keybinding';

export enum KeybindingScope {
Expand Down Expand Up @@ -101,6 +102,9 @@ export class KeybindingRegistry {
protected readonly contexts: { [id: string]: KeybindingContext } = {};
protected readonly keymaps: ScopedKeybinding[][] = [...Array(KeybindingScope.length)].map(() => []);

@inject(CorePreferences)
protected readonly corePreferences: CorePreferences;

@inject(KeyboardLayoutService)
protected readonly keyboardLayoutService: KeyboardLayoutService;

Expand Down Expand Up @@ -513,7 +517,8 @@ export class KeybindingRegistry {
return;
}

const keyCode = KeyCode.createKeyCode(event);
const eventDispatch = this.corePreferences['keyboard.dispatch'];
const keyCode = KeyCode.createKeyCode(event, eventDispatch);
/* Keycode is only a modifier, next keycode will be modifier + key.
Ignore this one. */
if (keyCode.isModifierOnly()) {
Expand Down
9 changes: 9 additions & 0 deletions packages/core/src/browser/keyboard/keys.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,15 @@ describe('keys api', () => {
stub.restore();
});

it('should properly handle eventDispatch', () => {
const event = new KeyboardEvent('keydown', {
code: Key.CAPS_LOCK.code,
});
Object.defineProperty(event, 'keyCode', { get: () => Key.ESCAPE.keyCode });
expect(KeyCode.createKeyCode(event, 'code').toString()).to.be.equal(Key.CAPS_LOCK.easyString);
expect(KeyCode.createKeyCode(event, 'keyCode').toString()).to.be.equal(Key.ESCAPE.easyString);
});

it('should serialize a keycode properly with a + M4', () => {
const stub = sinon.stub(os, 'isOSX').value(true);
const keyCode = KeyCode.createKeyCode({ first: Key.KEY_A, modifiers: [KeyModifier.MacCtrl] });
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/browser/keyboard/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ export class KeyCode {
/**
* Create a KeyCode from one of several input types.
*/
public static createKeyCode(input: KeyboardEvent | Keystroke | KeyCodeSchema | string): KeyCode {
public static createKeyCode(input: KeyboardEvent | Keystroke | KeyCodeSchema | string, eventDispatch: 'code' | 'keyCode' = 'code'): KeyCode {
if (typeof input === 'string') {
const parts = input.split('+');
if (!KeyCode.isModifierString(parts[0])) {
Expand All @@ -188,7 +188,7 @@ export class KeyCode {
}
return KeyCode.createKeyCode({ modifiers: parts as KeyModifier[] });
} else if (KeyCode.isKeyboardEvent(input)) {
const key = KeyCode.toKey(input);
const key = KeyCode.toKey(input, eventDispatch);
return new KeyCode({
key: Key.isModifier(key.code) ? undefined : key,
meta: isOSX && input.metaKey,
Expand Down Expand Up @@ -344,9 +344,9 @@ export namespace KeyCode {
* `keyIdentifier` is used to access this deprecated field:
* https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyIdentifier
*/
export function toKey(event: KeyboardEvent): Key {
export function toKey(event: KeyboardEvent, dispatch: 'code' | 'keyCode' = 'code'): Key {
const code = event.code;
if (code) {
if (code && dispatch === 'code') {
if (isOSX) {
// https://github.com/eclipse-theia/theia/issues/4986
const char = event.key;
Expand Down
47 changes: 26 additions & 21 deletions packages/debug/src/browser/debug-session.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,27 +85,9 @@ export class DebugSession implements CompositeTreeElement {
this.connection,
this.on('initialized', () => this.configure()),
this.on('breakpoint', ({ body }) => this.updateBreakpoint(body)),
this.on('continued', ({ body: { allThreadsContinued, threadId } }) => {
if (allThreadsContinued !== false) {
this.clearThreads();
} else {
this.clearThread(threadId);
}
}),
this.on('stopped', async ({ body }) => {
// Update thread list
await this.updateThreads(body);

// Update current thread's frames immediately
await this.updateFrames();
}),
this.on('thread', ({ body: { reason, threadId } }) => {
if (reason === 'started') {
this.scheduleUpdateThreads();
} else if (reason === 'exited') {
this.clearThread(threadId);
}
}),
this.on('continued', e => this.handleContinued(e)),
this.on('stopped', e => this.handleStopped(e)),
this.on('thread', e => this.handleThread(e)),
this.on('terminated', () => this.terminated = true),
this.on('capabilities', event => this.updateCapabilities(event.body.capabilities)),
this.breakpoints.onDidChangeMarkers(uri => this.updateBreakpoints({ uri, sourceModified: true }))
Expand Down Expand Up @@ -759,4 +741,27 @@ export class DebugSession implements CompositeTreeElement {
return this.threads;
}

protected async handleContinued({ body: { allThreadsContinued, threadId } }: DebugProtocol.ContinuedEvent): Promise<void> {
if (allThreadsContinued !== false) {
this.clearThreads();
} else {
this.clearThread(threadId);
}
};

protected async handleStopped({ body }: DebugProtocol.StoppedEvent): Promise<void> {
// Update thread list
await this.updateThreads(body);

// Update current thread's frames immediately
await this.updateFrames();
};

protected async handleThread({ body: { reason, threadId } }: DebugProtocol.ThreadEvent): Promise<void> {
if (reason === 'started') {
this.scheduleUpdateThreads();
} else if (reason === 'exited') {
this.clearThread(threadId);
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import { ApplicationShellMouseTracker } from '@theia/core/lib/browser/shell/appl
import { CommandService } from '@theia/core/lib/common/command';
import TheiaURI from '@theia/core/lib/common/uri';
import { EditorManager } from '@theia/editor/lib/browser';
import { CodeEditorWidget } from '@theia/plugin-ext/lib/main/browser/menus/menus-contribution-handler';
import {
CodeEditorWidgetUtil
} from '@theia/plugin-ext/lib/main/browser/menus/menus-contribution-handler';
import {
TextDocumentShowOptions,
Location,
Expand Down Expand Up @@ -102,6 +104,8 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
protected readonly quickOpenWorkspace: QuickOpenWorkspace;
@inject(TerminalService)
protected readonly terminalService: TerminalService;
@inject(CodeEditorWidgetUtil)
protected readonly codeEditorWidgetUtil: CodeEditorWidgetUtil;

registerCommands(commands: CommandRegistry): void {
commands.registerCommand(VscodeCommands.OPEN, {
Expand Down Expand Up @@ -233,7 +237,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
return (resourceUri && resourceUri.toString()) === uriString;
});
}
if (CodeEditorWidget.is(widget)) {
if (this.codeEditorWidgetUtil.is(widget)) {
await this.shell.closeWidget(widget.id);
}
}
Expand All @@ -249,7 +253,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
});
}
for (const widget of this.shell.widgets) {
if (CodeEditorWidget.is(widget) && widget !== editor) {
if (this.codeEditorWidgetUtil.is(widget) && widget !== editor) {
await this.shell.closeWidget(widget.id);
}
}
Expand All @@ -269,7 +273,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
const tabBar = this.shell.getTabBarFor(editor);
if (tabBar) {
this.shell.closeTabs(tabBar,
({ owner }) => CodeEditorWidget.is(owner)
({ owner }) => this.codeEditorWidgetUtil.is(owner)
);
}
}
Expand All @@ -283,7 +287,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
for (const tabBar of this.shell.allTabBars) {
if (tabBar !== editorTabBar) {
this.shell.closeTabs(tabBar,
({ owner }) => CodeEditorWidget.is(owner)
({ owner }) => this.codeEditorWidgetUtil.is(owner)
);
}
}
Expand All @@ -303,7 +307,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
left = false;
return false;
}
return left && CodeEditorWidget.is(owner);
return left && this.codeEditorWidgetUtil.is(owner);
}
);
}
Expand All @@ -323,7 +327,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
left = false;
return false;
}
return !left && CodeEditorWidget.is(owner);
return !left && this.codeEditorWidgetUtil.is(owner);
}
);
}
Expand All @@ -334,7 +338,7 @@ export class PluginVscodeCommandsContribution implements CommandContribution {
execute: async () => {
const promises = [];
for (const widget of this.shell.widgets) {
if (CodeEditorWidget.is(widget)) {
if (this.codeEditorWidgetUtil.is(widget)) {
promises.push(this.shell.closeWidget(widget.id));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ import { TIMELINE_ITEM_CONTEXT_MENU } from '@theia/timeline/lib/browser/timeline
import { TimelineItem } from '@theia/timeline/lib/common/timeline-model';

type CodeEditorWidget = EditorWidget | WebviewWidget;
export namespace CodeEditorWidget {
export function is(arg: any): arg is CodeEditorWidget {
@injectable()
export class CodeEditorWidgetUtil {
is(arg: any): arg is CodeEditorWidget {
return arg instanceof EditorWidget || arg instanceof WebviewWidget;
}
export function getResourceUri(editor: CodeEditorWidget): CodeUri | undefined {
getResourceUri(editor: CodeEditorWidget): CodeUri | undefined {
const resourceUri = Navigatable.is(editor) && editor.getResourceUri();
return resourceUri ? resourceUri['codeUri'] : undefined;
}
Expand Down Expand Up @@ -88,6 +89,9 @@ export class MenusContributionPointHandler {
@inject(ContextKeyService)
protected readonly contextKeyService: ContextKeyService;

@inject(CodeEditorWidgetUtil)
protected readonly codeEditorWidgetUtil: CodeEditorWidgetUtil;

handle(plugin: DeployedPlugin): Disposable {
const allMenus = plugin.contributes && plugin.contributes.menus;
if (!allMenus) {
Expand All @@ -104,9 +108,9 @@ export class MenusContributionPointHandler {
} else if (location === 'editor/title') {
for (const action of allMenus[location]) {
toDispose.push(this.registerTitleAction(location, action, {
execute: widget => CodeEditorWidget.is(widget) && this.commands.executeCommand(action.command, CodeEditorWidget.getResourceUri(widget)),
isEnabled: widget => CodeEditorWidget.is(widget) && this.commands.isEnabled(action.command, CodeEditorWidget.getResourceUri(widget)),
isVisible: widget => CodeEditorWidget.is(widget) && this.commands.isVisible(action.command, CodeEditorWidget.getResourceUri(widget))
execute: widget => this.codeEditorWidgetUtil.is(widget) && this.commands.executeCommand(action.command, this.codeEditorWidgetUtil.getResourceUri(widget)),
isEnabled: widget => this.codeEditorWidgetUtil.is(widget) && this.commands.isEnabled(action.command, this.codeEditorWidgetUtil.getResourceUri(widget)),
isVisible: widget => this.codeEditorWidgetUtil.is(widget) && this.commands.isVisible(action.command, this.codeEditorWidgetUtil.getResourceUri(widget))
}));
}
} else if (location === 'view/title') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { PluginFrontendViewContribution } from './plugin-frontend-view-contribut
import { PluginExtDeployCommandService } from './plugin-ext-deploy-command';
import { EditorModelService } from './text-editor-model-service';
import { UntitledResourceResolver } from './editor/untitled-resource';
import { MenusContributionPointHandler } from './menus/menus-contribution-handler';
import { CodeEditorWidgetUtil, MenusContributionPointHandler } from './menus/menus-contribution-handler';
import { PluginContributionHandler } from './plugin-contribution-handler';
import { PluginViewRegistry, PLUGIN_VIEW_CONTAINER_FACTORY_ID, PLUGIN_VIEW_FACTORY_ID, PLUGIN_VIEW_DATA_FACTORY_ID } from './view/plugin-view-registry';
import { TextContentResourceResolver } from './workspace-main';
Expand Down Expand Up @@ -185,6 +185,7 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {
bind(LabelProviderContribution).toService(PluginIconThemeService);

bind(MenusContributionPointHandler).toSelf().inSingletonScope();
bind(CodeEditorWidgetUtil).toSelf().inSingletonScope();
bind(KeybindingsContributionPointHandler).toSelf().inSingletonScope();
bind(PluginContributionHandler).toSelf().inSingletonScope();

Expand Down

0 comments on commit a7bf3ba

Please sign in to comment.