diff --git a/app/brave_app_management.grdp b/app/brave_app_management.grdp
new file mode 100644
index 00000000000..a676ad568d5
--- /dev/null
+++ b/app/brave_app_management.grdp
@@ -0,0 +1,13 @@
+
+
+
+
+ Open mode
+
+
+ Open as tabbed window
+
+
+ Open in browser
+
+
diff --git a/app/brave_generated_resources.grd b/app/brave_generated_resources.grd
index e9f992af78d..b89184f3161 100644
--- a/app/brave_generated_resources.grd
+++ b/app/brave_generated_resources.grd
@@ -172,6 +172,9 @@
+
+
+
diff --git a/app/feature_defaults_unittest.cc b/app/feature_defaults_unittest.cc
index 3f895ae7e2e..4094a1d46b9 100644
--- a/app/feature_defaults_unittest.cc
+++ b/app/feature_defaults_unittest.cc
@@ -266,6 +266,7 @@ TEST(FeatureDefaultsTest, EnabledFeatures) {
&blink::features::kReduceUserAgentMinorVersion,
&blink::features::kUACHOverrideBlank,
&features::kCertificateTransparencyAskBeforeEnabling,
+ &features::kDesktopPWAsTabStripSettings,
#if !BUILDFLAG(IS_ANDROID)
&features::kLocationProviderManager,
#endif
diff --git a/chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts
new file mode 100644
index 00000000000..752a2456dcd
--- /dev/null
+++ b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts
@@ -0,0 +1,23 @@
+// Copyright (c) 2025 The Brave Authors. All rights reserved.
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import { mangle } from 'lit_mangler';
+
+mangle((element) => {
+ const toggleRow = element.querySelector('app-management-toggle-row')
+ if (!toggleRow) {
+ throw new Error('[Brave App Settings] Could not find app-management-toggle-row. Maybe upstream has changed to a radio button?')
+ }
+ toggleRow.outerHTML = `
+
+
+ \${this.windowModes.map(mode => html\`
+ \${mode.label}
+ \`)}
+
+
`
+}, t => t.text.includes('id="toggle-row"'))
diff --git a/chromium_src/chrome/browser/resources/app_settings/window_mode_item.ts b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.ts
new file mode 100644
index 00000000000..3c1ea440e5c
--- /dev/null
+++ b/chromium_src/chrome/browser/resources/app_settings/window_mode_item.ts
@@ -0,0 +1,83 @@
+// Copyright (c) 2025 The Brave Authors. All rights reserved.
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+import type { App } from '//resources/cr_components/app_management/app_management.mojom-webui.js';
+import { CrLitElement, css } from '//resources/lit/v3_0/lit.rollup.js';
+
+import { getCss } from './app_management_shared_style.css.js';
+import { createDummyApp } from './web_app_settings_utils.js';
+import { getHtml } from './window_mode_item.html.js';
+import { loadTimeData } from '//resources/js/load_time_data.js';
+import { BrowserProxy } from '//resources/cr_components/app_management/browser_proxy.js';
+import { WindowMode } from '//resources/cr_components/app_management/constants.js';
+
+export class WindowModeItemElement extends CrLitElement {
+ static get is() {
+ return 'app-management-window-mode-item';
+ }
+
+ static override get styles() {
+ return [
+ getCss(),
+ css`
+ :host > div {
+ width: 100%;
+ }
+
+ leo-radiobutton {
+ display: flex;
+ }
+ `
+ ];
+ }
+
+ override render() {
+ return getHtml.bind(this)();
+ }
+
+ static override get properties() {
+ return {
+ windowModeLabel: { type: String },
+
+ app: { type: Object },
+ };
+ }
+
+ get tabStripSettingsEnabled_(): boolean {
+ return loadTimeData.getBoolean('isPWAsTabStripSettingsEnabled');
+ }
+
+ get windowModes() {
+ return [
+ {
+ label: loadTimeData.getString('appManagementWindowModeLabel'),
+ value: WindowMode.kWindow,
+ },
+ {
+ label: loadTimeData.getString('appManagementBrowserModeLabel'),
+ value: WindowMode.kBrowser,
+ },
+ ...this.tabStripSettingsEnabled_ ? [{
+ label: loadTimeData.getString('appManagementTabbedWindowModeLabel'),
+ value: WindowMode.kTabbedWindow,
+ }] : [],
+ ]
+ }
+
+ accessor windowModeLabel: string = '';
+ accessor app: App = createDummyApp();
+
+ onChange(e: { value: string }) {
+ BrowserProxy.getInstance().handler.setWindowMode(this.app.id, parseInt(e.value) as WindowMode);
+ }
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'app-management-window-mode-item': WindowModeItemElement;
+ }
+}
+
+customElements.define(WindowModeItemElement.is, WindowModeItemElement);
diff --git a/chromium_src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc b/chromium_src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc
new file mode 100644
index 00000000000..0d3f0d796ab
--- /dev/null
+++ b/chromium_src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc
@@ -0,0 +1,31 @@
+// Copyright (c) 2025 The Brave Authors. All rights reserved.
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this file,
+// You can obtain one at https://mozilla.org/MPL/2.0/.
+
+#include "chrome/browser/ui/webui/app_settings/web_app_settings_ui.h"
+
+#include "base/feature_list.h"
+#include "chrome/common/chrome_features.h"
+#include "content/public/browser/web_ui_data_source.h"
+#include "ui/webui/webui_util.h"
+
+#define SetupWebUIDataSource(...) \
+ SetupWebUIDataSource(__VA_ARGS__); \
+ html_source->AddBoolean( \
+ "isPWAsTabStripSettingsEnabled", \
+ base::FeatureList::IsEnabled(features::kDesktopPWAsTabStripSettings))
+
+#define AddLocalizedStrings(...) \
+ AddLocalizedStrings(__VA_ARGS__); \
+ html_source->AddLocalizedString("appManagementTabbedWindowModeLabel", \
+ IDS_APP_MANAGEMENT_TABBED_WINDOW); \
+ html_source->AddLocalizedString("appManagementBrowserModeLabel", \
+ IDS_APP_MANAGEMENT_BROWSER); \
+ html_source->AddLocalizedString("appManagementOpenModeLabel", \
+ IDS_APP_MANAGEMENT_OPEN_MODE)
+
+#include "src/chrome/browser/ui/webui/app_settings/web_app_settings_ui.cc"
+
+#undef AddLocalizedStrings
+#undef SetupWebUIDataSource
diff --git a/chromium_src/chrome/common/chrome_features.cc b/chromium_src/chrome/common/chrome_features.cc
index 146609c457d..be842e71b65 100644
--- a/chromium_src/chrome/common/chrome_features.cc
+++ b/chromium_src/chrome/common/chrome_features.cc
@@ -13,6 +13,7 @@ namespace features {
OVERRIDE_FEATURE_DEFAULT_STATES({{
{kChromeStructuredMetrics, base::FEATURE_DISABLED_BY_DEFAULT},
+ {kDesktopPWAsTabStripSettings, base::FEATURE_ENABLED_BY_DEFAULT},
{kHttpsFirstBalancedMode, base::FEATURE_DISABLED_BY_DEFAULT},
{kKAnonymityService, base::FEATURE_DISABLED_BY_DEFAULT},
{kKAnonymityServiceOHTTPRequests, base::FEATURE_DISABLED_BY_DEFAULT},
diff --git a/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap b/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap
index 31d68f63483..c1fd81daa18 100644
--- a/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap
+++ b/tools/chromium_src/lit_mangler/__snapshots__/mangle.test.ts.snap
@@ -1,5 +1,34 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
+exports[`mangled files should have up to date snapshots ./chromium_src/chrome/browser/resources/app_settings/window_mode_item.html.ts.lit_mangler.ts should match snapshot 1`] = `
+"===================================================================
+--- ../chrome/browser/resources/app_settings/window_mode_item.html.ts
++++ gen/chrome/browser/resources/app_settings/preprocessed/window_mode_item.html.ts
+@@ -3,11 +3,16 @@
+ import type {WindowModeItemElement} from './window_mode_item.js';
+
+ export function getHtml(this: WindowModeItemElement) {
+ return html\`
+-
+-
++
++
++
++ \${this.windowModes.map(mode => html\`
++ \${mode.label}
++ \`)}
++
++
+ \`;
+ }
+"
+`;
+
exports[`mangled files should have up to date snapshots ./chromium_src/chrome/browser/resources/extensions/detail_view.html.ts.lit_mangler.ts should match snapshot 1`] = `
"===================================================================
--- ../chrome/browser/resources/extensions/detail_view.html.ts
diff --git a/ui/webui/resources/leo/web_components.ts b/ui/webui/resources/leo/web_components.ts
index a775cc9aaad..720c4afbaf2 100644
--- a/ui/webui/resources/leo/web_components.ts
+++ b/ui/webui/resources/leo/web_components.ts
@@ -16,6 +16,7 @@ import '@brave/leo/web-components/progressRing'
import '@brave/leo/web-components/textarea'
import '@brave/leo/web-components/toggle'
import '@brave/leo/web-components/tooltip'
+import '@brave/leo/web-components/radioButton'
import { setIconBasePath } from '@brave/leo/web-components/icon'
import iconsMeta from '@brave/leo/icons/meta'