未验证 提交 03e8f121 编写于 作者: B Benjamin Pasero 提交者: GitHub

follow up title part changes (#91938)

* follow up title part changes

* title - go back to having a part in electron-browser
上级 b31befa9
......@@ -34,7 +34,6 @@ import { Emitter } from 'vs/base/common/event';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { Parts, IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { RunOnceScheduler } from 'vs/base/common/async';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem';
import { IMenuService, IMenu, MenuId } from 'vs/platform/actions/common/actions';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
......@@ -512,5 +511,3 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
`);
}
});
registerSingleton(ITitleService, TitlebarPart);
......@@ -9,7 +9,7 @@ import { createHash } from 'crypto';
import { webFrame } from 'electron';
import { importEntries, mark } from 'vs/base/common/performance';
import { Workbench } from 'vs/workbench/browser/workbench';
import { ElectronWindow } from 'vs/workbench/electron-browser/window';
import { NativeWindow } from 'vs/workbench/electron-browser/window';
import { setZoomLevel, setZoomFactor, setFullscreen } from 'vs/base/browser/browser';
import { domContentLoaded, addDisposableListener, EventType, scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { onUnexpectedError } from 'vs/base/common/errors';
......@@ -126,7 +126,7 @@ class DesktopMain extends Disposable {
const instantiationService = workbench.startup();
// Window
this._register(instantiationService.createInstance(ElectronWindow));
this._register(instantiationService.createInstance(NativeWindow));
// Driver
if (this.environmentService.configuration.driver) {
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as browser from 'vs/base/browser/browser';
import * as DOM from 'vs/base/browser/dom';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { ILabelService } from 'vs/platform/label/common/label';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { isMacintosh, isWindows, isLinux } from 'vs/base/common/platform';
import { IMenuService } from 'vs/platform/actions/common/actions';
import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { IProductService } from 'vs/platform/product/common/productService';
import { IElectronService } from 'vs/platform/electron/node/electron';
import { getTitleBarStyle } from 'vs/platform/windows/common/windows';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
export class NativeTitlebarPart extends TitlebarPart {
private appIcon: HTMLElement | undefined;
private windowControls: HTMLElement | undefined;
private maxRestoreControl: HTMLElement | undefined;
private dragRegion: HTMLElement | undefined;
private resizer: HTMLElement | undefined;
constructor(
@IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService protected readonly configurationService: IConfigurationService,
@IEditorService editorService: IEditorService,
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@ILabelService labelService: ILabelService,
@IStorageService storageService: IStorageService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@IMenuService menuService: IMenuService,
@IContextKeyService contextKeyService: IContextKeyService,
@IHostService hostService: IHostService,
@IProductService productService: IProductService,
@IElectronService private readonly electronService: IElectronService
) {
super(contextMenuService, configurationService, editorService, environmentService, contextService, instantiationService, themeService, labelService, storageService, layoutService, menuService, contextKeyService, hostService, productService);
}
private onUpdateAppIconDragBehavior() {
const setting = this.configurationService.getValue('window.doubleClickIconToClose');
if (setting && this.appIcon) {
(this.appIcon.style as any)['-webkit-app-region'] = 'no-drag';
} else if (this.appIcon) {
(this.appIcon.style as any)['-webkit-app-region'] = 'drag';
}
}
private onDidChangeMaximized(maximized: boolean) {
if (this.maxRestoreControl) {
if (maximized) {
DOM.removeClass(this.maxRestoreControl, 'codicon-chrome-maximize');
DOM.addClass(this.maxRestoreControl, 'codicon-chrome-restore');
} else {
DOM.removeClass(this.maxRestoreControl, 'codicon-chrome-restore');
DOM.addClass(this.maxRestoreControl, 'codicon-chrome-maximize');
}
}
if (this.resizer) {
if (maximized) {
DOM.hide(this.resizer);
} else {
DOM.show(this.resizer);
}
}
this.adjustTitleMarginToCenter();
}
private onMenubarFocusChanged(focused: boolean) {
if ((isWindows || isLinux) && this.currentMenubarVisibility !== 'compact' && this.dragRegion) {
if (focused) {
DOM.hide(this.dragRegion);
} else {
DOM.show(this.dragRegion);
}
}
}
protected onMenubarVisibilityChanged(visible: boolean) {
// Hide title when toggling menu bar
if ((isWindows || isLinux) && this.currentMenubarVisibility === 'toggle' && visible) {
// Hack to fix issue #52522 with layered webkit-app-region elements appearing under cursor
if (this.dragRegion) {
DOM.hide(this.dragRegion);
setTimeout(() => DOM.show(this.dragRegion!), 50);
}
}
super.onMenubarVisibilityChanged(visible);
}
protected onConfigurationChanged(event: IConfigurationChangeEvent): void {
super.onConfigurationChanged(event);
if (event.affectsConfiguration('window.doubleClickIconToClose')) {
if (this.appIcon) {
this.onUpdateAppIconDragBehavior();
}
}
}
protected adjustTitleMarginToCenter(): void {
if (this.customMenubar && this.menubar) {
const leftMarker = (this.appIcon ? this.appIcon.clientWidth : 0) + this.menubar.clientWidth + 10;
const rightMarker = this.element.clientWidth - (this.windowControls ? this.windowControls.clientWidth : 0) - 10;
// Not enough space to center the titlebar within window,
// Center between menu and window controls
if (leftMarker > (this.element.clientWidth - this.title.clientWidth) / 2 ||
rightMarker < (this.element.clientWidth + this.title.clientWidth) / 2) {
this.title.style.position = '';
this.title.style.left = '';
this.title.style.transform = '';
return;
}
}
this.title.style.position = 'absolute';
this.title.style.left = '50%';
this.title.style.transform = 'translate(-50%, 0)';
}
protected installMenubar(): void {
super.installMenubar();
if (this.menubar) {
return;
}
if (this.customMenubar) {
this._register(this.customMenubar.onFocusStateChange(e => this.onMenubarFocusChanged(e)));
}
}
createContentArea(parent: HTMLElement): HTMLElement {
const ret = super.createContentArea(parent);
// App Icon (Native Windows/Linux)
if (!isMacintosh) {
this.appIcon = DOM.prepend(this.element, DOM.$('div.window-appicon'));
this.onUpdateAppIconDragBehavior();
this._register(DOM.addDisposableListener(this.appIcon, DOM.EventType.DBLCLICK, (e => {
this.electronService.closeWindow();
})));
}
// Draggable region that we can manipulate for #52522
this.dragRegion = DOM.prepend(this.element, DOM.$('div.titlebar-drag-region'));
// Window Controls (Native Windows/Linux)
if (!isMacintosh) {
this.windowControls = DOM.append(this.element, DOM.$('div.window-controls-container'));
// Minimize
const minimizeIcon = DOM.append(this.windowControls, DOM.$('div.window-icon.window-minimize.codicon.codicon-chrome-minimize'));
this._register(DOM.addDisposableListener(minimizeIcon, DOM.EventType.CLICK, e => {
this.electronService.minimizeWindow();
}));
// Restore
this.maxRestoreControl = DOM.append(this.windowControls, DOM.$('div.window-icon.window-max-restore.codicon'));
this._register(DOM.addDisposableListener(this.maxRestoreControl, DOM.EventType.CLICK, async e => {
const maximized = await this.electronService.isMaximized();
if (maximized) {
return this.electronService.unmaximizeWindow();
}
return this.electronService.maximizeWindow();
}));
// Close
const closeIcon = DOM.append(this.windowControls, DOM.$('div.window-icon.window-close.codicon.codicon-chrome-close'));
this._register(DOM.addDisposableListener(closeIcon, DOM.EventType.CLICK, e => {
this.electronService.closeWindow();
}));
// Resizer
this.resizer = DOM.append(this.element, DOM.$('div.resizer'));
this._register(this.layoutService.onMaximizeChange(maximized => this.onDidChangeMaximized(maximized)));
this.onDidChangeMaximized(this.layoutService.isWindowMaximized());
}
return ret;
}
updateLayout(dimension: DOM.Dimension): void {
this.lastLayoutDimensions = dimension;
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
// Only prevent zooming behavior on macOS or when the menubar is not visible
if (isMacintosh || this.currentMenubarVisibility === 'hidden') {
this.title.style.zoom = `${1 / browser.getZoomFactor()}`;
if (isWindows || isLinux) {
if (this.appIcon) {
this.appIcon.style.zoom = `${1 / browser.getZoomFactor()}`;
}
if (this.windowControls) {
this.windowControls.style.zoom = `${1 / browser.getZoomFactor()}`;
}
}
} else {
this.title.style.zoom = null;
if (isWindows || isLinux) {
if (this.appIcon) {
this.appIcon.style.zoom = null;
}
if (this.windowControls) {
this.windowControls.style.zoom = null;
}
}
}
DOM.runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter());
if (this.customMenubar) {
const menubarDimension = new DOM.Dimension(0, dimension.height);
this.customMenubar.layout(menubarDimension);
}
}
}
}
......@@ -31,7 +31,7 @@ import { IDisposable, Disposable, DisposableStore } from 'vs/base/common/lifecyc
import { LifecyclePhase, ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
import { IWorkspaceFolderCreationData, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
import { IIntegrityService } from 'vs/workbench/services/integrity/common/integrity';
import { isRootUser, isWindows, isMacintosh, isLinux, isWeb } from 'vs/base/common/platform';
import { isRootUser, isWindows, isMacintosh, isLinux } from 'vs/base/common/platform';
import product from 'vs/platform/product/common/product';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { EditorServiceImpl } from 'vs/workbench/browser/parts/editor/editor';
......@@ -40,7 +40,7 @@ import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { WorkbenchState, IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
import { coalesce } from 'vs/base/common/arrays';
import { IConfigurationService, IConfigurationChangeEvent } from 'vs/platform/configuration/common/configuration';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { isEqual } from 'vs/base/common/resources';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { MenubarControl } from '../browser/parts/titlebar/menubarControl';
......@@ -62,13 +62,8 @@ import { IWorkingCopyService, WorkingCopyCapabilities } from 'vs/workbench/servi
import { AutoSaveMode, IFilesConfigurationService } from 'vs/workbench/services/filesConfiguration/common/filesConfigurationService';
import { Event } from 'vs/base/common/event';
import { INativeWorkbenchEnvironmentService } from 'vs/workbench/services/environment/electron-browser/environmentService';
import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { IProductService } from 'vs/platform/product/common/productService';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
export class ElectronWindow extends Disposable {
export class NativeWindow extends Disposable {
private touchBarMenu: IMenu | undefined;
private readonly touchBarDisposables = this._register(new DisposableStore());
......@@ -883,224 +878,3 @@ class NativeMenubarControl extends MenubarControl {
return undefined;
}
}
export class ElectronTitlebarPart extends TitlebarPart {
private appIcon: HTMLElement | undefined;
private windowControls: HTMLElement | undefined;
private maxRestoreControl: HTMLElement | undefined;
private dragRegion: HTMLElement | undefined;
private resizer: HTMLElement | undefined;
constructor(
@IContextMenuService contextMenuService: IContextMenuService,
@IConfigurationService protected readonly configurationService: IConfigurationService,
@IEditorService editorService: IEditorService,
@IWorkbenchEnvironmentService protected readonly environmentService: IWorkbenchEnvironmentService,
@IWorkspaceContextService contextService: IWorkspaceContextService,
@IInstantiationService instantiationService: IInstantiationService,
@IThemeService themeService: IThemeService,
@ILabelService labelService: ILabelService,
@IStorageService storageService: IStorageService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@IMenuService menuService: IMenuService,
@IContextKeyService contextKeyService: IContextKeyService,
@IHostService hostService: IHostService,
@IProductService productService: IProductService,
@IElectronService private readonly electronService: IElectronService
) {
super(contextMenuService, configurationService, editorService, environmentService, contextService, instantiationService, themeService, labelService, storageService, layoutService, menuService, contextKeyService, hostService, productService);
}
private onUpdateAppIconDragBehavior() {
const setting = this.configurationService.getValue('window.doubleClickIconToClose');
if (setting && this.appIcon) {
(this.appIcon.style as any)['-webkit-app-region'] = 'no-drag';
} else if (this.appIcon) {
(this.appIcon.style as any)['-webkit-app-region'] = 'drag';
}
}
private onDidChangeMaximized(maximized: boolean) {
if (this.maxRestoreControl) {
if (maximized) {
DOM.removeClass(this.maxRestoreControl, 'codicon-chrome-maximize');
DOM.addClass(this.maxRestoreControl, 'codicon-chrome-restore');
} else {
DOM.removeClass(this.maxRestoreControl, 'codicon-chrome-restore');
DOM.addClass(this.maxRestoreControl, 'codicon-chrome-maximize');
}
}
if (this.resizer) {
if (maximized) {
DOM.hide(this.resizer);
} else {
DOM.show(this.resizer);
}
}
this.adjustTitleMarginToCenter();
}
private onMenubarFocusChanged(focused: boolean) {
if (!isWeb && (isWindows || isLinux) && this.currentMenubarVisibility !== 'compact' && this.dragRegion) {
if (focused) {
DOM.hide(this.dragRegion);
} else {
DOM.show(this.dragRegion);
}
}
}
protected onMenubarVisibilityChanged(visible: boolean) {
// Hide title when toggling menu bar
if (!isWeb && (isWindows || isLinux) && this.currentMenubarVisibility === 'toggle' && visible) {
// Hack to fix issue #52522 with layered webkit-app-region elements appearing under cursor
if (this.dragRegion) {
DOM.hide(this.dragRegion);
setTimeout(() => DOM.show(this.dragRegion!), 50);
}
}
super.onMenubarVisibilityChanged(visible);
}
protected onConfigurationChanged(event: IConfigurationChangeEvent): void {
super.onConfigurationChanged(event);
if (event.affectsConfiguration('window.doubleClickIconToClose')) {
if (this.appIcon) {
this.onUpdateAppIconDragBehavior();
}
}
}
protected adjustTitleMarginToCenter(): void {
if (this.customMenubar && this.menubar) {
const leftMarker = (this.appIcon ? this.appIcon.clientWidth : 0) + this.menubar.clientWidth + 10;
const rightMarker = this.element.clientWidth - (this.windowControls ? this.windowControls.clientWidth : 0) - 10;
// Not enough space to center the titlebar within window,
// Center between menu and window controls
if (leftMarker > (this.element.clientWidth - this.title.clientWidth) / 2 ||
rightMarker < (this.element.clientWidth + this.title.clientWidth) / 2) {
this.title.style.position = '';
this.title.style.left = '';
this.title.style.transform = '';
return;
}
}
this.title.style.position = 'absolute';
this.title.style.left = '50%';
this.title.style.transform = 'translate(-50%, 0)';
}
protected installMenubar(): void {
super.installMenubar();
if (this.menubar) {
return;
}
if (this.customMenubar) {
this._register(this.customMenubar.onFocusStateChange(e => this.onMenubarFocusChanged(e)));
}
}
createContentArea(parent: HTMLElement): HTMLElement {
const ret = super.createContentArea(parent);
// App Icon (Native Windows/Linux)
if (!isMacintosh && !isWeb) {
this.appIcon = DOM.prepend(this.element, DOM.$('div.window-appicon'));
this.onUpdateAppIconDragBehavior();
this._register(DOM.addDisposableListener(this.appIcon, DOM.EventType.DBLCLICK, (e => {
this.electronService.closeWindow();
})));
}
// Draggable region that we can manipulate for #52522
if (!isWeb) {
this.dragRegion = DOM.prepend(this.element, DOM.$('div.titlebar-drag-region'));
}
// Window Controls (Native Windows/Linux)
if (!isMacintosh && !isWeb) {
this.windowControls = DOM.append(this.element, DOM.$('div.window-controls-container'));
// Minimize
const minimizeIcon = DOM.append(this.windowControls, DOM.$('div.window-icon.window-minimize.codicon.codicon-chrome-minimize'));
this._register(DOM.addDisposableListener(minimizeIcon, DOM.EventType.CLICK, e => {
this.electronService.minimizeWindow();
}));
// Restore
this.maxRestoreControl = DOM.append(this.windowControls, DOM.$('div.window-icon.window-max-restore.codicon'));
this._register(DOM.addDisposableListener(this.maxRestoreControl, DOM.EventType.CLICK, async e => {
const maximized = await this.electronService.isMaximized();
if (maximized) {
return this.electronService.unmaximizeWindow();
}
return this.electronService.maximizeWindow();
}));
// Close
const closeIcon = DOM.append(this.windowControls, DOM.$('div.window-icon.window-close.codicon.codicon-chrome-close'));
this._register(DOM.addDisposableListener(closeIcon, DOM.EventType.CLICK, e => {
this.electronService.closeWindow();
}));
// Resizer
this.resizer = DOM.append(this.element, DOM.$('div.resizer'));
this._register(this.layoutService.onMaximizeChange(maximized => this.onDidChangeMaximized(maximized)));
this.onDidChangeMaximized(this.layoutService.isWindowMaximized());
}
return ret;
}
updateLayout(dimension: DOM.Dimension): void {
this.lastLayoutDimensions = dimension;
if (getTitleBarStyle(this.configurationService, this.environmentService) === 'custom') {
// Only prevent zooming behavior on macOS or when the menubar is not visible
if ((!isWeb && isMacintosh) || this.currentMenubarVisibility === 'hidden') {
this.title.style.zoom = `${1 / browser.getZoomFactor()}`;
if (!isWeb && (isWindows || isLinux)) {
if (this.appIcon) {
this.appIcon.style.zoom = `${1 / browser.getZoomFactor()}`;
}
if (this.windowControls) {
this.windowControls.style.zoom = `${1 / browser.getZoomFactor()}`;
}
}
} else {
this.title.style.zoom = null;
if (!isWeb && (isWindows || isLinux)) {
if (this.appIcon) {
this.appIcon.style.zoom = null;
}
if (this.windowControls) {
this.windowControls.style.zoom = null;
}
}
}
DOM.runAtThisOrScheduleAtNextAnimationFrame(() => this.adjustTitleMarginToCenter());
if (this.customMenubar) {
const menubarDimension = new DOM.Dimension(0, dimension.height);
this.customMenubar.layout(menubarDimension);
}
}
}
}
registerSingleton(ITitleService, ElectronTitlebarPart);
......@@ -69,8 +69,11 @@ import 'vs/workbench/services/extensionResourceLoader/electron-browser/extension
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService';
import { NativeTitlebarPart } from 'vs/workbench/electron-browser/parts/titlebar/titlebarPart';
import { ITitleService } from 'vs/workbench/services/title/common/titleService';
registerSingleton(ICredentialsService, KeytarCredentialsService, true);
registerSingleton(ITitleService, NativeTitlebarPart);
//#endregion
......
......@@ -25,13 +25,6 @@ import 'vs/workbench/browser/web.main';
//#endregion
//#region --- workbench parts
import 'vs/workbench/browser/parts/titlebar/titlebarPart';
//#endregion
//#region --- workbench services
import 'vs/workbench/services/integrity/browser/integrityService';
import 'vs/workbench/services/textMate/browser/textMateService';
......@@ -78,6 +71,8 @@ import { SettingsSynchroniser } from 'vs/platform/userDataSync/common/settingsSy
import { IAuthenticationTokenService, AuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
import { UserDataAutoSyncService } from 'vs/workbench/contrib/userDataSync/browser/userDataAutoSyncService';
import { AccessibilityService } from 'vs/platform/accessibility/common/accessibilityService';
import { ITitleService } from 'vs/workbench/services/title/common/titleService';
import { TitlebarPart } from 'vs/workbench/browser/parts/titlebar/titlebarPart';
registerSingleton(IExtensionManagementService, ExtensionManagementService);
registerSingleton(IBackupFileService, BackupFileService);
......@@ -92,6 +87,7 @@ registerSingleton(IAuthenticationTokenService, AuthenticationTokenService);
registerSingleton(IUserDataAutoSyncService, UserDataAutoSyncService);
registerSingleton(ISettingsSyncService, SettingsSynchroniser);
registerSingleton(IUserDataSyncService, UserDataSyncService);
registerSingleton(ITitleService, TitlebarPart);
//#endregion
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册