diff --git a/src-tauri/src/properties_window.rs b/src-tauri/src/properties_window.rs
index 38bc44e..0b44a37 100644
--- a/src-tauri/src/properties_window.rs
+++ b/src-tauri/src/properties_window.rs
@@ -455,12 +455,14 @@ pub async fn open_download_properties_window(
// A hidden WebView2 must not request focus during construction. The
// native reveal path focuses it after the window is visible.
.focused(false);
- // Native elevation follows the window shape on macOS. On Windows, Tauri
- // gives an undecorated window the system contour and Windows 11 corners as
- // well as its shadow. Linux does not implement this API, so its guaranteed
- // boundary remains the renderer's theme-aware contour and non-transparent frame.
- #[cfg(any(target_os = "windows", target_os = "macos"))]
+ // Native elevation follows the window shape on macOS. On Windows, Tao enables
+ // an undecorated shadow that leaves an opaque native frame outside the rounded
+ // renderer surface at the corners, so shadow is disabled. Linux does not implement
+ // this API, so its boundary remains the renderer's theme-aware contour.
+ #[cfg(target_os = "macos")]
let builder = builder.transparent(true).shadow(true);
+ #[cfg(target_os = "windows")]
+ let builder = builder.transparent(true).shadow(false);
#[cfg(target_os = "linux")]
let builder = builder.transparent(false).shadow(false);
#[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
diff --git a/src-tauri/tauri.windows.conf.json b/src-tauri/tauri.windows.conf.json
index ee28d6f..ccfdc66 100644
--- a/src-tauri/tauri.windows.conf.json
+++ b/src-tauri/tauri.windows.conf.json
@@ -10,7 +10,7 @@
"minHeight": 640,
"transparent": true,
"decorations": false,
- "shadow": true
+ "shadow": false
}
]
},
diff --git a/src/App.tsx b/src/App.tsx
index 47850e8..edcf200 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1222,7 +1222,7 @@ function App() {
}, [autoAddClipboardLinks, coreReady, showKeychainModal]);
return (
-
{
it('keeps custom controls present while Windows/Linux detection is unresolved', () => {
@@ -20,3 +20,32 @@ describe('shouldUseCustomWindowControls', () => {
expect(shouldUseCustomWindowControls('unknown', 'Mozilla/5.0 (Linux; Android 14; Mobile)')).toBe(false);
});
});
+
+describe('syncPlatformDataset', () => {
+ it('synchronizes known desktop platforms to document dataset', () => {
+ const mockDocument = { documentElement: { dataset: {} as Record
} };
+
+ syncPlatformDataset('macos', mockDocument);
+ expect(mockDocument.documentElement.dataset.platform).toBe('macos');
+
+ syncPlatformDataset('windows', mockDocument);
+ expect(mockDocument.documentElement.dataset.platform).toBe('windows');
+
+ syncPlatformDataset('linux', mockDocument);
+ expect(mockDocument.documentElement.dataset.platform).toBe('linux');
+ });
+
+ it('ignores unknown or unsupported platforms', () => {
+ const mockDocument = { documentElement: { dataset: { platform: 'macos' } } };
+
+ syncPlatformDataset('unknown', mockDocument);
+ expect(mockDocument.documentElement.dataset.platform).toBe('macos');
+
+ syncPlatformDataset('android', mockDocument);
+ expect(mockDocument.documentElement.dataset.platform).toBe('macos');
+ });
+
+ it('safely handles missing document in headless environments', () => {
+ expect(() => syncPlatformDataset('macos', undefined)).not.toThrow();
+ });
+});
diff --git a/src/utils/platform.ts b/src/utils/platform.ts
index d073515..026a2bf 100644
--- a/src/utils/platform.ts
+++ b/src/utils/platform.ts
@@ -22,12 +22,39 @@ export const shouldUseCustomWindowControls = (os: string, userAgent: string): bo
let cached: PlatformInfo | null = null;
let pending: Promise | null = null;
+type TargetDocument = {
+ documentElement: {
+ dataset: Record;
+ };
+};
+
+export const syncPlatformDataset = (
+ os: string,
+ targetDocument: TargetDocument | undefined = typeof document !== 'undefined' ? document : undefined,
+): void => {
+ if (!targetDocument) return;
+ if (os === 'macos' || os === 'windows' || os === 'linux') {
+ targetDocument.documentElement.dataset.platform = os;
+ }
+};
+
+if (typeof document !== 'undefined' && typeof navigator !== 'undefined') {
+ if (/Macintosh|Mac OS X/i.test(navigator.userAgent)) {
+ syncPlatformDataset('macos');
+ } else if (/Windows/i.test(navigator.userAgent)) {
+ syncPlatformDataset('windows');
+ } else if (/Linux/i.test(navigator.userAgent)) {
+ syncPlatformDataset('linux');
+ }
+}
+
export const getPlatformInfo = (): Promise => {
if (cached) return Promise.resolve(cached);
if (!pending) {
pending = invoke('get_platform_info')
.then(info => {
cached = info;
+ syncPlatformDataset(info.os);
return info;
})
.finally(() => {
diff --git a/src/utils/windowConfiguration.test.ts b/src/utils/windowConfiguration.test.ts
index 9ba36c9..7e850ad 100644
--- a/src/utils/windowConfiguration.test.ts
+++ b/src/utils/windowConfiguration.test.ts
@@ -24,22 +24,25 @@ describe('main window configuration', () => {
}
});
- it('uses native elevation where Tauri supports undecorated window shadows', () => {
- for (const [platform, config] of [
- ['macOS', macosConfiguration],
- ['Windows', windowsConfiguration],
- ] as const) {
- expect(config.app.windows[0], platform).toMatchObject({
- transparent: true,
- decorations: false,
- shadow: true,
- });
- }
+ it('uses native elevation on macOS where undecorated window shadows conform to the surface', () => {
+ expect(macosConfiguration.app.windows[0], 'macOS').toMatchObject({
+ transparent: true,
+ decorations: false,
+ shadow: true,
+ });
+ });
+
+ it('keeps Windows transparent without native shadow bleed outside rounded corners', () => {
+ expect(windowsConfiguration.app.windows[0], 'Windows').toMatchObject({
+ transparent: true,
+ decorations: false,
+ shadow: false,
+ });
});
it('keeps Linux on the renderer contour without claiming native shadow support', () => {
const mainWindow = linuxConfiguration.app.windows[0];
- expect(mainWindow).toMatchObject({
+ expect(mainWindow, 'Linux').toMatchObject({
transparent: false,
decorations: false,
shadow: false,