🐛 fix(desktop): prevent window resize when onboarding (#10887)

 feat: add window resizing and sizing functionality

* Implemented IPC methods for setting window size and resizability.
* Updated Browser and BrowserManager classes to handle new window settings.
* Integrated window settings in DesktopOnboarding component.
* Added new types for window size and resizability in electron-client-ipc.

Signed-off-by: Innei <tukon479@gmail.com>
This commit is contained in:
Innei
2025-12-22 20:00:19 +08:00
committed by arvinxx
parent 1b0b49cc1a
commit c29c02bb23
8 changed files with 97 additions and 2 deletions

View File

@@ -1,4 +1,9 @@
import { InterceptRouteParams, OpenSettingsWindowOptions } from '@lobechat/electron-client-ipc';
import type {
InterceptRouteParams,
OpenSettingsWindowOptions,
WindowResizableParams,
WindowSizeParams,
} from '@lobechat/electron-client-ipc';
import { findMatchingRoute } from '~common/routes';
import { AppBrowsersIdentifiers, WindowTemplateIdentifiers } from '@/appBrowsers';
@@ -68,6 +73,20 @@ export default class BrowserWindowsCtr extends ControllerModule {
});
}
@IpcMethod()
setWindowSize(params: WindowSizeParams) {
this.withSenderIdentifier((identifier) => {
this.app.browserManager.setWindowSize(identifier, params);
});
}
@IpcMethod()
setWindowResizable(params: WindowResizableParams) {
this.withSenderIdentifier((identifier) => {
this.app.browserManager.setWindowResizable(identifier, params.resizable);
});
}
/**
* Handle route interception requests
* Responsible for handling route interception requests from the renderer process

View File

@@ -473,6 +473,11 @@ export default class Browser {
});
}
setWindowResizable(resizable: boolean) {
logger.debug(`[${this.identifier}] Setting window resizable: ${resizable}`);
this._browserWindow?.setResizable(resizable);
}
broadcast = <T extends MainBroadcastEventKey>(channel: T, data?: MainBroadcastParams<T>) => {
if (this._browserWindow.isDestroyed()) return;

View File

@@ -244,6 +244,16 @@ export class BrowserManager {
}
}
setWindowSize(identifier: string, size: { height?: number; width?: number }) {
const browser = this.browsers.get(identifier);
browser?.setWindowSize(size);
}
setWindowResizable(identifier: string, resizable: boolean) {
const browser = this.browsers.get(identifier);
browser?.setWindowResizable(resizable);
}
getIdentifierByWebContents(webContents: WebContents): string | null {
return this.webContentsMap.get(webContents) || null;
}

View File

@@ -10,3 +10,4 @@ export * from './system';
export * from './tray';
export * from './update';
export * from './upload';
export * from './window';

View File

@@ -0,0 +1,8 @@
export interface WindowSizeParams {
height?: number;
width?: number;
}
export interface WindowResizableParams {
resizable: boolean;
}

View File

@@ -8,14 +8,38 @@ import {
getDesktopOnboardingCompleted,
setDesktopOnboardingCompleted,
} from '@/features/DesktopOnboarding/storage';
import { electronSystemService } from '@/services/electron/system';
import { isDev } from '@/utils/env';
const DesktopOnboarding = () => {
const navigate = useNavigate();
useEffect(() => {
if (isDev) return;
if (getDesktopOnboardingCompleted()) navigate('/', { replace: true });
}, [navigate]);
useEffect(() => {
const fixedSize = { height: 900, width: 1400 };
const applyWindowSettings = async () => {
try {
await electronSystemService.setWindowSize(fixedSize);
await electronSystemService.setWindowResizable({ resizable: false });
} catch (error) {
console.error('[DesktopOnboarding] Failed to apply window settings:', error);
}
};
applyWindowSettings();
return () => {
electronSystemService.setWindowResizable({ resizable: true }).catch((error) => {
console.error('[DesktopOnboarding] Failed to restore window settings:', error);
});
};
}, []);
return (
<OnboardingContainerWithTheme
onComplete={() => {

View File

@@ -5,6 +5,9 @@ import { createStyles } from 'antd-style';
import { AnimatePresence, motion } from 'motion/react';
import React, { useCallback, useEffect, useState } from 'react';
import { TITLE_BAR_HEIGHT } from '@/features/ElectronTitlebar';
import { electronStylish } from '@/styles/electron';
import { Navigation } from './Navigation';
import LightRays from './effects/LightRays';
import { Screen1 } from './screens/Screen1';
@@ -57,6 +60,16 @@ const useStyles = createStyles(({ css }) => ({
width: 100%;
height: 100%;
`,
titleBar: css`
position: fixed;
z-index: 1000;
inset-block-start: 0;
inset-inline: 0 0;
width: 100%;
height: ${TITLE_BAR_HEIGHT}px;
`,
}));
interface OnboardingContainerProps {
@@ -219,6 +232,9 @@ export const OnboardingContainer: React.FC<OnboardingContainerProps> = ({ onComp
return (
<div className={styles.container}>
{/* Title Bar Drag Region */}
<div className={`${styles.titleBar} ${electronStylish.draggable}`} />
{/* LightRays Background Layer */}
{renderBackground()}

View File

@@ -1,4 +1,8 @@
import { ElectronAppState } from '@lobechat/electron-client-ipc';
import type {
ElectronAppState,
WindowResizableParams,
WindowSizeParams,
} from '@lobechat/electron-client-ipc';
import { ensureElectronIpc } from '@/utils/electron/ipc';
@@ -28,6 +32,14 @@ class ElectronSystemService {
return ensureElectronIpc().windows.minimizeWindow();
}
async setWindowResizable(params: WindowResizableParams): Promise<void> {
return ensureElectronIpc().windows.setWindowResizable(params);
}
async setWindowSize(params: WindowSizeParams): Promise<void> {
return ensureElectronIpc().windows.setWindowSize(params);
}
showContextMenu = async (type: string, data?: any) => {
return ensureElectronIpc().menu.showContextMenu({ data, type });
};