fix(linux): Can't change Chinese IMEs on Debian (#582)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Haze <hazeone@users.noreply.github.com>
This commit is contained in:
Haze
2026-03-19 10:19:44 +08:00
committed by GitHub
Unverified
parent 7aec2febed
commit 1b527d2f49
4 changed files with 65 additions and 7 deletions

View File

@@ -113,6 +113,8 @@ function getAppIcon(): Electron.NativeImage | undefined {
*/
function createWindow(): BrowserWindow {
const isMac = process.platform === 'darwin';
const isWindows = process.platform === 'win32';
const useCustomTitleBar = isWindows;
const win = new BrowserWindow({
width: 1280,
@@ -127,9 +129,9 @@ function createWindow(): BrowserWindow {
sandbox: false,
webviewTag: true, // Enable <webview> for embedding OpenClaw Control UI
},
titleBarStyle: isMac ? 'hiddenInset' : 'hidden',
titleBarStyle: isMac ? 'hiddenInset' : useCustomTitleBar ? 'hidden' : 'default',
trafficLightPosition: isMac ? { x: 16, y: 16 } : undefined,
frame: isMac,
frame: isMac || !useCustomTitleBar,
show: false,
});

View File

@@ -2194,7 +2194,7 @@ function registerUsageHandlers(): void {
});
}
/**
* Window control handlers (for custom title bar on Windows/Linux)
* Window control handlers (for custom title bar on Windows)
*/
function registerWindowHandlers(mainWindow: BrowserWindow): void {
ipcMain.handle('window:minimize', () => {

View File

@@ -1,20 +1,26 @@
/**
* TitleBar Component
* macOS: empty drag region (native traffic lights handled by hiddenInset).
* Windows/Linux: drag region on left, minimize/maximize/close on right.
* Windows: drag region with custom minimize/maximize/close controls.
* Linux: use native window chrome (no custom title bar).
*/
import { useState, useEffect } from 'react';
import { Minus, Square, X, Copy } from 'lucide-react';
import { invokeIpc } from '@/lib/api-client';
const isMac = window.electron?.platform === 'darwin';
export function TitleBar() {
if (isMac) {
const platform = window.electron?.platform;
if (platform === 'darwin') {
// macOS: just a drag region, traffic lights are native
return <div className="drag-region h-10 shrink-0 border-b bg-background" />;
}
// Linux keeps the native frame/title bar for better IME compatibility.
if (platform !== 'win32') {
return null;
}
return <WindowsTitleBar />;
}

View File

@@ -0,0 +1,50 @@
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { render, screen, waitFor } from '@testing-library/react';
import { TitleBar } from '@/components/layout/TitleBar';
const invokeIpcMock = vi.hoisted(() => vi.fn());
vi.mock('@/lib/api-client', () => ({
invokeIpc: (...args: unknown[]) => invokeIpcMock(...args),
}));
describe('TitleBar platform behavior', () => {
beforeEach(() => {
invokeIpcMock.mockReset();
invokeIpcMock.mockResolvedValue(false);
});
it('renders macOS drag region', () => {
window.electron.platform = 'darwin';
const { container } = render(<TitleBar />);
expect(container.querySelector('.drag-region')).toBeInTheDocument();
expect(screen.queryByTitle('Minimize')).not.toBeInTheDocument();
expect(invokeIpcMock).not.toHaveBeenCalled();
});
it('renders custom controls on Windows', async () => {
window.electron.platform = 'win32';
render(<TitleBar />);
expect(screen.getByTitle('Minimize')).toBeInTheDocument();
expect(screen.getByTitle('Maximize')).toBeInTheDocument();
expect(screen.getByTitle('Close')).toBeInTheDocument();
await waitFor(() => {
expect(invokeIpcMock).toHaveBeenCalledWith('window:isMaximized');
});
});
it('renders no custom title bar on Linux', () => {
window.electron.platform = 'linux';
const { container } = render(<TitleBar />);
expect(container.firstChild).toBeNull();
expect(screen.queryByTitle('Minimize')).not.toBeInTheDocument();
expect(invokeIpcMock).not.toHaveBeenCalled();
});
});