diff --git a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css index fcda99efffd..ff98427909f 100644 --- a/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css +++ b/src/vs/workbench/contrib/preferences/browser/media/settingsEditor2.css @@ -388,15 +388,20 @@ -webkit-user-select: text; } -.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-trust-description { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-untrusted > .setting-item-contents .setting-item-trust-description { display: flex; + font-weight: 600; margin: 6px 0 12px 0; } -.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-trust-description > span { +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-untrusted > .setting-item-contents .setting-item-trust-description > span { padding-right: 5px; } +.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-untrusted > .setting-item-contents .setting-item-trust-description > span.codicon.codicon-workspace-untrusted { + color: var(--workspace-trust-state-untrusted-color) !important; +} + .settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-validation-message { display: none; } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts index 2b35defd7ce..ac02b175756 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsEditor2.ts @@ -25,7 +25,7 @@ import { URI } from 'vs/base/common/uri'; import 'vs/css!./media/settingsEditor2'; import { localize } from 'vs/nls'; import { ICommandService } from 'vs/platform/commands/common/commands'; -import { ConfigurationTarget, IConfigurationOverrides, IConfigurationService } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationOverrides } from 'vs/platform/configuration/common/configuration'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; @@ -41,7 +41,7 @@ import { IEditorMemento, IEditorOpenContext, IEditorPane } from 'vs/workbench/co import { attachSuggestEnabledInputBoxStyler, SuggestEnabledInput } from 'vs/workbench/contrib/codeEditor/browser/suggestEnabledInput/suggestEnabledInput'; import { SettingsTarget, SettingsTargetsWidget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets'; import { commonlyUsedData, tocData } from 'vs/workbench/contrib/preferences/browser/settingsLayout'; -import { AbstractSettingRenderer, ISettingLinkClickEvent, ISettingOverrideClickEvent, resolveExtensionsSettings, resolveSettingsTree, SettingsTree, SettingTreeRenderers } from 'vs/workbench/contrib/preferences/browser/settingsTree'; +import { AbstractSettingRenderer, ISettingLinkClickEvent, ISettingOverrideClickEvent, resolveConfiguredUntrustedSettings, resolveExtensionsSettings, resolveSettingsTree, SettingsTree, SettingTreeRenderers } from 'vs/workbench/contrib/preferences/browser/settingsTree'; import { ISettingsEditorViewState, parseQuery, SearchResultIdx, SearchResultModel, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeModel, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels'; import { settingsTextInputBorder } from 'vs/workbench/contrib/preferences/browser/settingsWidgets'; import { createTOCIterator, TOCTree, TOCTreeModel } from 'vs/workbench/contrib/preferences/browser/tocTree'; @@ -53,6 +53,7 @@ import { Settings2EditorModel } from 'vs/workbench/services/preferences/common/p import { IUserDataSyncWorkbenchService } from 'vs/workbench/services/userDataSync/common/userDataSync'; import { preferencesClearInputIcon } from 'vs/workbench/contrib/preferences/browser/preferencesIcons'; import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; export const enum SettingsFocusContext { Search, @@ -164,7 +165,7 @@ export class SettingsEditor2 extends EditorPane { constructor( @ITelemetryService telemetryService: ITelemetryService, - @IConfigurationService private readonly configurationService: IConfigurationService, + @IWorkbenchConfigurationService private readonly configurationService: IWorkbenchConfigurationService, @IThemeService themeService: IThemeService, @IPreferencesService private readonly preferencesService: IPreferencesService, @IInstantiationService private readonly instantiationService: IInstantiationService, @@ -997,6 +998,17 @@ export class SettingsEditor2 extends EditorPane { resolvedSettingsRoot.children!.push(resolveExtensionsSettings(dividedGroups.extension || [])); + if (!this.workspaceTrustManagementService.isWorkpaceTrusted() && (this.viewState.settingsTarget instanceof URI || this.viewState.settingsTarget === ConfigurationTarget.WORKSPACE)) { + const configuredUntrustedWorkspaceSettings = resolveConfiguredUntrustedSettings(groups, this.viewState.settingsTarget, this.configurationService); + if (configuredUntrustedWorkspaceSettings.length) { + resolvedSettingsRoot.children!.unshift({ + id: 'workspaceTrust', + label: localize('settings require trust', "Workspace Trust"), + settings: configuredUntrustedWorkspaceSettings + }); + } + } + if (this.searchResultModel) { this.searchResultModel.updateChildren(); } diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts index e42e7f1330a..ea25d0469f2 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTree.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTree.ts @@ -38,11 +38,11 @@ import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent'; import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding'; import { IOpenerService } from 'vs/platform/opener/common/opener'; import { editorBackground, errorForeground, focusBorder, foreground, inputValidationErrorBackground, inputValidationErrorBorder, inputValidationErrorForeground } from 'vs/platform/theme/common/colorRegistry'; -import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler } from 'vs/platform/theme/common/styler'; +import { attachButtonStyler, attachInputBoxStyler, attachSelectBoxStyler, attachStyler, attachStylerCallback } from 'vs/platform/theme/common/styler'; import { ICssStyleCollector, IColorTheme, IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { getIgnoredSettings } from 'vs/platform/userDataSync/common/settingsMerge'; import { ITOCEntry } from 'vs/workbench/contrib/preferences/browser/settingsLayout'; -import { ISettingsEditorViewState, settingKeyToDisplayFormat, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels'; +import { inspectSetting, ISettingsEditorViewState, settingKeyToDisplayFormat, SettingsTreeElement, SettingsTreeGroupChild, SettingsTreeGroupElement, SettingsTreeNewExtensionsElement, SettingsTreeSettingElement } from 'vs/workbench/contrib/preferences/browser/settingsTreeModels'; import { ExcludeSettingWidget, ISettingListChangeEvent, IListDataItem, ListSettingWidget, settingsNumberInputBackground, settingsNumberInputBorder, settingsNumberInputForeground, settingsSelectBackground, settingsSelectBorder, settingsSelectForeground, settingsSelectListBorder, settingsTextInputBackground, settingsTextInputBorder, settingsTextInputForeground, ObjectSettingWidget, IObjectDataItem, IObjectEnumOption, ObjectValue, IObjectValueSuggester, IObjectKeySuggester, focusedRowBackground, focusedRowBorder, settingsHeaderForeground, rowHoverBackground } from 'vs/workbench/contrib/preferences/browser/settingsWidgets'; import { SETTINGS_EDITOR_COMMAND_SHOW_CONTEXT_MENU } from 'vs/workbench/contrib/preferences/common/preferences'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; @@ -58,6 +58,9 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility'; import { ILogService } from 'vs/platform/log/common/log'; import { settingsMoreActionIcon } from 'vs/workbench/contrib/preferences/browser/preferencesIcons'; +import { IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; +import { SettingsTarget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets'; +import { untrustedForegroundColor } from 'vs/workbench/contrib/workspace/browser/workspaceTrustColors'; const $ = DOM.$; @@ -280,6 +283,11 @@ export function resolveSettingsTree(tocData: ITOCEntry, coreSettingsGrou }; } +export function resolveConfiguredUntrustedSettings(groups: ISettingsGroup[], target: SettingsTarget, configurationService: IWorkbenchConfigurationService): ISetting[] { + const allSettings = getFlatSettings(groups); + return [...allSettings].filter(setting => setting.requireTrust && inspectSetting(setting.key, target, configurationService).isConfigured); +} + export function resolveExtensionsSettings(groups: ISettingsGroup[]): ITOCEntry { const settingsGroupToEntry = (group: ISettingsGroup) => { const flatSettings = arrays.flatten( @@ -1528,22 +1536,25 @@ export class SettingUntrustedRenderer extends AbstractSettingRenderer implements const manageWorkspaceTrustLabel = localize('manageWorkspaceTrust', "Manage Workspace Trust"); const trustLabelElement = $('.setting-item-trust-description'); - DOM.append(trustLabelElement, $('span.codicon.codicon-workspace-untrusted')); + const untrustedWorkspaceIcon = DOM.append(trustLabelElement, $('span.codicon.codicon-workspace-untrusted')); + template.toDispose.add(attachStylerCallback(this._themeService, { untrustedForegroundColor }, colors => { + untrustedWorkspaceIcon.style.setProperty('--workspace-trust-state-untrusted-color', colors.untrustedForegroundColor?.toString() || ''); + })); const element = DOM.append(trustLabelElement, $('span')); element.textContent = localize('trustLabel', "This setting can be applied only in the trusted workspace."); const linkElement: HTMLAnchorElement = DOM.append(trustLabelElement, $('a')); linkElement.textContent = manageWorkspaceTrustLabel; linkElement.setAttribute('tabindex', '0'); linkElement.href = '#'; - DOM.addStandardDisposableListener(linkElement, DOM.EventType.CLICK, () => { + template.toDispose.add(DOM.addStandardDisposableListener(linkElement, DOM.EventType.CLICK, () => { this._commandService.executeCommand('workbench.trust.manage'); - }); - DOM.addStandardDisposableListener(linkElement, DOM.EventType.KEY_DOWN, (e: IKeyboardEvent) => { + })); + template.toDispose.add(DOM.addStandardDisposableListener(linkElement, DOM.EventType.KEY_DOWN, (e: IKeyboardEvent) => { if (e.equals(KeyCode.Enter) || e.equals(KeyCode.Space)) { this._commandService.executeCommand('workbench.trust.manage'); e.stopPropagation(); } - }); + })); template.containerElement.insertBefore(trustLabelElement, template.descriptionElement); @@ -1951,6 +1962,9 @@ export class SettingsTree extends WorkbenchObjectTree { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-description { color: ${fgWithOpacity}; }`); collector.addRule(`.settings-editor > .settings-body .settings-toc-container .monaco-list-row:not(.selected) { color: ${fgWithOpacity}; }`); + const disabledfgColor = new Color(new RGBA(foregroundColor.rgba.r, foregroundColor.rgba.g, foregroundColor.rgba.b, 0.6)); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-untrusted > .setting-item-contents .setting-item-description { color: ${disabledfgColor}; }`); + // Hack for subpixel antialiasing collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-overrides, .settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-title .setting-item-ignored { color: ${fgWithOpacity}; }`); diff --git a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts index c81447a943d..7c6b0eeaca0 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsTreeModels.ts @@ -8,13 +8,13 @@ import { escapeRegExpCharacters, isFalsyOrWhitespace } from 'vs/base/common/stri import { isArray, withUndefinedAsNull, isUndefinedOrNull } from 'vs/base/common/types'; import { URI } from 'vs/base/common/uri'; import { localize } from 'vs/nls'; -import { ConfigurationTarget, IConfigurationService, IConfigurationValue } from 'vs/platform/configuration/common/configuration'; +import { ConfigurationTarget, IConfigurationValue } from 'vs/platform/configuration/common/configuration'; import { SettingsTarget } from 'vs/workbench/contrib/preferences/browser/preferencesWidgets'; import { ITOCEntry, knownAcronyms, knownTermMappings, tocData } from 'vs/workbench/contrib/preferences/browser/settingsLayout'; import { MODIFIED_SETTING_TAG, REQUIRE_TRUSTED_WORKSPACE_SETTING_TAG } from 'vs/workbench/contrib/preferences/common/preferences'; import { IExtensionSetting, ISearchResult, ISetting, SettingValueType } from 'vs/workbench/services/preferences/common/preferences'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; -import { FOLDER_SCOPES, WORKSPACE_SCOPES, REMOTE_MACHINE_SCOPES, LOCAL_MACHINE_SCOPES } from 'vs/workbench/services/configuration/common/configuration'; +import { FOLDER_SCOPES, WORKSPACE_SCOPES, REMOTE_MACHINE_SCOPES, LOCAL_MACHINE_SCOPES, IWorkbenchConfigurationService } from 'vs/workbench/services/configuration/common/configuration'; import { IJSONSchema } from 'vs/base/common/jsonSchema'; import { Disposable } from 'vs/base/common/lifecycle'; import { Emitter } from 'vs/base/common/event'; @@ -353,7 +353,7 @@ export class SettingsTreeModel { constructor( protected _viewState: ISettingsEditorViewState, private _isWorkspaceTrusted: boolean, - @IConfigurationService private readonly _configurationService: IConfigurationService, + @IWorkbenchConfigurationService private readonly _configurationService: IWorkbenchConfigurationService, ) { } @@ -466,14 +466,25 @@ interface IInspectResult { targetSelector: 'userLocalValue' | 'userRemoteValue' | 'workspaceValue' | 'workspaceFolderValue'; } -function inspectSetting(key: string, target: SettingsTarget, configurationService: IConfigurationService): IInspectResult { +export function inspectSetting(key: string, target: SettingsTarget, configurationService: IWorkbenchConfigurationService): IInspectResult { const inspectOverrides = URI.isUri(target) ? { resource: target } : undefined; const inspected = configurationService.inspect(key, inspectOverrides); const targetSelector = target === ConfigurationTarget.USER_LOCAL ? 'userLocalValue' : target === ConfigurationTarget.USER_REMOTE ? 'userRemoteValue' : target === ConfigurationTarget.WORKSPACE ? 'workspaceValue' : 'workspaceFolderValue'; - const isConfigured = typeof inspected[targetSelector] !== 'undefined'; + let isConfigured = typeof inspected[targetSelector] !== 'undefined'; + if (!isConfigured) { + if (target === ConfigurationTarget.USER_LOCAL) { + isConfigured = !!configurationService.unTrustedSettings.userLocal?.includes(key); + } else if (target === ConfigurationTarget.USER_REMOTE) { + isConfigured = !!configurationService.unTrustedSettings.userRemote?.includes(key); + } else if (target === ConfigurationTarget.WORKSPACE) { + isConfigured = !!configurationService.unTrustedSettings.workspace?.includes(key); + } else if (target instanceof URI) { + isConfigured = !!configurationService.unTrustedSettings.workspaceFolder?.get(target)?.includes(key); + } + } return { isConfigured, inspected, targetSelector }; } @@ -622,7 +633,7 @@ export class SearchResultModel extends SettingsTreeModel { constructor( viewState: ISettingsEditorViewState, isWorkspaceTrusted: boolean, - @IConfigurationService configurationService: IConfigurationService, + @IWorkbenchConfigurationService configurationService: IWorkbenchConfigurationService, @IWorkbenchEnvironmentService private environmentService: IWorkbenchEnvironmentService, ) { super(viewState, isWorkspaceTrusted, configurationService); diff --git a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts index 39a1b8c9c00..e296f566505 100644 --- a/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/settingsWidgets.ts @@ -97,6 +97,9 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) = collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item-contents .setting-item-markdown a > code { color: ${link}; }`); collector.addRule(`.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown a { color: ${link}; }`); collector.addRule(`.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown a > code { color: ${link}; }`); + + const disabledfgColor = new Color(new RGBA(link.rgba.r, link.rgba.g, link.rgba.b, 0.6)); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-untrusted > .setting-item-contents .setting-item-markdown a { color: ${disabledfgColor}; }`); } const activeLink = theme.getColor(textLinkActiveForeground); @@ -154,7 +157,8 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) = if (codeTextForegroundColor) { collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item .setting-item-markdown code { color: ${codeTextForegroundColor} }`); collector.addRule(`.monaco-select-box-dropdown-container > .select-box-details-pane > .select-box-description-markdown code { color: ${codeTextForegroundColor} }`); - + const disabledfgColor = new Color(new RGBA(codeTextForegroundColor.rgba.r, codeTextForegroundColor.rgba.g, codeTextForegroundColor.rgba.b, 0.6)); + collector.addRule(`.settings-editor > .settings-body > .settings-tree-container .setting-item.setting-item-untrusted > .setting-item-contents .setting-item-description .setting-item-markdown code { color: ${disabledfgColor} }`); } const modifiedItemIndicatorColor = theme.getColor(modifiedItemIndicator);