VSCode源码分析 - 主要窗口

目录

主要窗口

workbench.ts中startup里面Workbench负责创建主界面 src/vs/workbench/browser/workbench.ts

  1. startup(): IInstantiationService {
  2. try {
  3. ...
  4. instantiationService.invokeFunction(async accessor => {
  5. // 渲染主工作界面
  6. this.renderWorkbench(instantiationService, accessor.get(INotificationService) as NotificationService, storageService, configurationService);
  7. // 界面布局
  8. this.createWorkbenchLayout(instantiationService);
  9. // Layout
  10. this.layout();
  11. // Restore
  12. try {
  13. await this.restoreWorkbench(accessor.get(IEditorService), accessor.get(IEditorGroupsService), accessor.get(IViewletService), accessor.get(IPanelService), accessor.get(ILogService), lifecycleService);
  14. } catch (error) {
  15. onUnexpectedError(error);
  16. }
  17. });
  18. return instantiationService;
  19. } catch (error) {
  20. onUnexpectedError(error);
  21. throw error; // rethrow because this is a critical issue we cannot handle properly here
  22. }
  23. }

渲染主工作台,渲染完之后加入到container中,container加入到parent, parent就是body了。

this.parent.appendChild(this.container);

  1. private renderWorkbench(instantiationService: IInstantiationService, notificationService: NotificationService, storageService: IStorageService, configurationService: IConfigurationService): void {
  2. ...
  3. //TITLEBAR_PART 顶部操作栏
  4. //ACTIVITYBAR_PART 最左侧菜单选项卡
  5. //SIDEBAR_PART 左侧边栏,显示文件,结果展示等
  6. //EDITOR_PART 右侧窗口,代码编写,欢迎界面等
  7. //STATUSBAR_PART 底部状态栏
  8. [
  9. { id: Parts.TITLEBAR_PART, role: 'contentinfo', classes: ['titlebar'] },
  10. { id: Parts.ACTIVITYBAR_PART, role: 'navigation', classes: ['activitybar', this.state.sideBar.position === Position.LEFT ? 'left' : 'right'] },
  11. { id: Parts.SIDEBAR_PART, role: 'complementary', classes: ['sidebar', this.state.sideBar.position === Position.LEFT ? 'left' : 'right'] },
  12. { id: Parts.EDITOR_PART, role: 'main', classes: ['editor'], options: { restorePreviousState: this.state.editor.restoreEditors } },
  13. { id: Parts.PANEL_PART, role: 'complementary', classes: ['panel', this.state.panel.position === Position.BOTTOM ? 'bottom' : 'right'] },
  14. { id: Parts.STATUSBAR_PART, role: 'contentinfo', classes: ['statusbar'] }
  15. ].forEach(({ id, role, classes, options }) => {
  16. const partContainer = this.createPart(id, role, classes);
  17. if (!configurationService.getValue('workbench.useExperimentalGridLayout')) {
  18. // TODO@Ben cleanup once moved to grid
  19. // Insert all workbench parts at the beginning. Issue #52531
  20. // This is primarily for the title bar to allow overriding -webkit-app-region
  21. this.container.insertBefore(partContainer, this.container.lastChild);
  22. }
  23. this.getPart(id).create(partContainer, options);
  24. });
  25. // 将工作台添加至container dom渲染
  26. this.parent.appendChild(this.container);
  27. }

workbench最后调用this.layout()方法,将窗口占据整个界面,渲染完成

  1. layout(options?: ILayoutOptions): void {
  2. if (!this.disposed) {
  3. this._dimension = getClientArea(this.parent);
  4. if (this.workbenchGrid instanceof Grid) {
  5. position(this.container, 0, 0, 0, 0, 'relative');
  6. size(this.container, this._dimension.width, this._dimension.height);
  7. // Layout the grid widget
  8. this.workbenchGrid.layout(this._dimension.width, this._dimension.height);
  9. } else {
  10. this.workbenchGrid.layout(options);
  11. }
  12. // Emit as event
  13. this._onLayout.fire(this._dimension);
  14. }
  15. }