diff --git a/src/web-ui/src/app/components/NavPanel/components/PersistentFooterActions.tsx b/src/web-ui/src/app/components/NavPanel/components/PersistentFooterActions.tsx
index ca23356f3a..11f99bb607 100644
--- a/src/web-ui/src/app/components/NavPanel/components/PersistentFooterActions.tsx
+++ b/src/web-ui/src/app/components/NavPanel/components/PersistentFooterActions.tsx
@@ -25,7 +25,6 @@ import { useToolbarModeContext } from '@/flow_chat/components/toolbar-mode/Toolb
import { useNotification } from '@/shared/notification-system';
import { useAccountLoginState } from '@/infrastructure/account/useAccountLoginState';
import NotificationButton from '../../TitleBar/NotificationButton';
-import GithubStarButton from './GithubStarButton';
import { usePrivacy } from '../../Privacy/PrivacyContext';
import {
hasActionableUnreadReply,
@@ -425,7 +424,6 @@ const PersistentFooterActions: React.FC = () => {
-
diff --git a/src/web-ui/src/app/components/SceneBar/SceneBar.tsx b/src/web-ui/src/app/components/SceneBar/SceneBar.tsx
index af1ff374fb..fb43165e76 100644
--- a/src/web-ui/src/app/components/SceneBar/SceneBar.tsx
+++ b/src/web-ui/src/app/components/SceneBar/SceneBar.tsx
@@ -27,6 +27,7 @@ interface SceneBarProps {
onMaximize?: () => void;
onClose?: () => void;
isMaximized?: boolean;
+ reserveNativeWindowControls?: boolean;
}
const SceneBar: React.FC = ({
@@ -35,12 +36,14 @@ const SceneBar: React.FC = ({
onMaximize,
onClose,
isMaximized = false,
+ reserveNativeWindowControls = false,
}) => {
const { openTabs, activeTabId, tabDefs, activateScene, closeScene } = useSceneManager();
const sessionTitle = useCurrentSessionTitle();
const settingsTabTitle = useCurrentSettingsTabTitle();
const { t } = useI18n('common');
const hasWindowControls = !!(onMinimize && onMaximize && onClose);
+ const showWindowControls = hasWindowControls || reserveNativeWindowControls;
const sceneBarClassName = `bitfun-scene-bar ${!hasWindowControls ? 'bitfun-scene-bar--no-controls' : ''} ${className}`.trim();
const isSingleTab = openTabs.length <= 1;
const tabCount = Math.max(openTabs.length, 1);
@@ -108,13 +111,14 @@ const SceneBar: React.FC = ({
})}
- {hasWindowControls && (
+ {showWindowControls && (
)}
diff --git a/src/web-ui/src/app/layout/AppLayout.tsx b/src/web-ui/src/app/layout/AppLayout.tsx
index ded1494b3d..e0698c1bc1 100644
--- a/src/web-ui/src/app/layout/AppLayout.tsx
+++ b/src/web-ui/src/app/layout/AppLayout.tsx
@@ -34,7 +34,7 @@ import { WorkspaceKind } from '@/shared/types';
import { SSHContext } from '@/features/ssh-remote/SSHRemoteContext';
import { shortcutManager, parseStoredKeybindings } from '@/infrastructure/services/ShortcutManager';
import { useSessionModeStore } from '../stores/sessionModeStore';
-import { isMacOSDesktopRuntime } from '@/infrastructure/runtime';
+import { isMacOSDesktopRuntime, isOpenHarmonyRuntime } from '@/infrastructure/runtime';
import { flowChatSessionConfigForWorkspace } from '../utils/projectSessionWorkspace';
import { notificationService } from '@/shared/notification-system';
import { AppearanceBackgroundMediaLayer, appearanceRuntime, useAppearance } from '@/infrastructure/appearance';
@@ -83,6 +83,7 @@ const AppLayout: React.FC = ({ className = '' }) => {
const { t: tCommon } = useI18n('common');
const currentAppearance = useAppearance().current;
const backgroundMedia = currentAppearance?.backgroundMedia;
+ const isOpenHarmony = isOpenHarmonyRuntime();
usePermissionRequestNotify();
const {
currentWorkspace,
@@ -757,10 +758,11 @@ const AppLayout: React.FC = ({ className = '' }) => {
{/* Main content — always render WorkspaceBody; WelcomeScene in viewport handles no-workspace state */}
diff --git a/src/web-ui/src/app/layout/WorkspaceBody.tsx b/src/web-ui/src/app/layout/WorkspaceBody.tsx
index 2dc9fa092b..1482abb023 100644
--- a/src/web-ui/src/app/layout/WorkspaceBody.tsx
+++ b/src/web-ui/src/app/layout/WorkspaceBody.tsx
@@ -32,6 +32,7 @@ interface WorkspaceBodyProps {
onMaximize?: () => void;
onClose?: () => void;
isMaximized?: boolean;
+ reserveNativeWindowControls?: boolean;
sceneOverlay?: React.ReactNode;
}
@@ -43,6 +44,7 @@ const WorkspaceBody: React.FC = ({
onMaximize,
onClose,
isMaximized = false,
+ reserveNativeWindowControls = false,
sceneOverlay,
}) => {
const { workspace: currentWorkspace } = useCurrentWorkspace();
@@ -177,6 +179,7 @@ const WorkspaceBody: React.FC = ({
onMaximize={onMaximize}
onClose={onClose}
isMaximized={isMaximized}
+ reserveNativeWindowControls={reserveNativeWindowControls}
/>
= ({
'data-testid-minimize': testIdMinimize,
'data-testid-maximize': testIdMaximize,
'data-testid-close': testIdClose,
+ nativePlaceholder = false,
...props
}) => {
const { t } = useTranslation('common');
+
+ if (nativePlaceholder) {
+ return ;
+ }
+
const defaultMinimizeIcon = (