Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions lang/index.json
Original file line number Diff line number Diff line change
Expand Up @@ -3894,5 +3894,53 @@
"ru": "",
"en": "",
"fr": ""
},
"70wovq6": {
"zh-cn": "窗口默认尺寸",
"ja": "",
"ko": "",
"ru": "",
"en": "",
"fr": ""
},
"j6rndol": {
"zh-cn": "设置 Milkup 启动时的窗口宽度和高度",
"ja": "",
"ko": "",
"ru": "",
"en": "",
"fr": ""
},
"hdojy66": {
"zh-cn": "宽度(PX)",
"ja": "",
"ko": "",
"ru": "",
"en": "",
"fr": ""
},
"c2mhr16": {
"zh-cn": "最小 400",
"ja": "",
"ko": "",
"ru": "",
"en": "",
"fr": ""
},
"va60g76": {
"zh-cn": "高度(PX)",
"ja": "",
"ko": "",
"ru": "",
"en": "",
"fr": ""
},
"c2mihq6": {
"zh-cn": "最小 300",
"ja": "",
"ko": "",
"ru": "",
"en": "",
"fr": ""
}
}
28 changes: 26 additions & 2 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@ async function createWindow() {
win = new BrowserWindow({
width: 1200,
height: 800,
minWidth: 800,
minHeight: 600,
minWidth: 400,
minHeight: 300,
show: false,
frame: false,
titleBarStyle: "hidden", // ✅ macOS 专属
icon: path.join(__dirname, "../assets/icons/milkup.ico"),
Expand Down Expand Up @@ -258,6 +259,20 @@ app.whenReady().then(async () => {
}
});

let startupSizeTimeout: ReturnType<typeof setTimeout> | null = null;
ipcMain.on("window:apply-startup-size", (event, width: number, height: number) => {
const senderWin = BrowserWindow.fromWebContents(event.sender);
if (senderWin !== win) return;
if (!win || win.isDestroyed()) return;
if (startupSizeTimeout) {
clearTimeout(startupSizeTimeout);
startupSizeTimeout = null;
}
win.setSize(width, height);
win.center();
win.show();
});

// 监听渲染进程就绪事件 (Moved up to avoid race condition)
ipcMain.on("renderer-ready", () => {
isRendererReady = true;
Expand All @@ -269,6 +284,15 @@ app.whenReady().then(async () => {

await createWindow();

if (win && !win.isDestroyed()) {
startupSizeTimeout = setTimeout(() => {
if (win && !win.isDestroyed() && !win.isVisible()) {
win.center();
win.show();
}
}, 2000);
}

sendLaunchFileIfExists();
});

Expand Down
5 changes: 4 additions & 1 deletion src/main/ipcBridge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,10 @@ export function registerGlobalIpcHandlers() {
): Promise<boolean> => {
try {
const sourceWin = BrowserWindow.fromWebContents(event.sender);
startDragFollow(tabData, screenX, screenY, offsetX, offsetY, sourceWin);
const bounds = sourceWin?.getBounds();
const width = bounds?.width ?? 1000;
const height = bounds?.height ?? 700;
startDragFollow(tabData, screenX, screenY, offsetX, offsetY, sourceWin, width, height);
return true;
} catch (error) {
console.error("[tab:tear-off-start] 创建窗口失败:", error);
Expand Down
10 changes: 7 additions & 3 deletions src/main/windowManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,8 @@ export async function createEditorWindow(
const winOptions: Electron.BrowserWindowConstructorOptions = {
width,
height,
minWidth: 800,
minHeight: 600,
minWidth: 400,
minHeight: 300,
frame: false,
titleBarStyle: "hidden",
show: !fastCreate, // 拖拽跟随窗口初始不显示,避免抢夺焦点
Expand Down Expand Up @@ -416,7 +416,9 @@ export function startDragFollow(
screenY: number,
offsetX: number,
offsetY: number,
sourceWin: BrowserWindow | null
sourceWin: BrowserWindow | null,
width: number,
height: number
): void {
cleanupDragFollow();

Expand All @@ -429,6 +431,8 @@ export function startDragFollow(
const win = await createEditorWindow({
x: initX,
y: initY,
width,
height,
tabData,
fastCreate: true,
center: false,
Expand Down
2 changes: 2 additions & 0 deletions src/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ contextBridge.exposeInMainWorld("electronAPI", {
saveCustomTheme: (theme: any) => ipcRenderer.send("save-custom-theme", theme),
platform: process.platform,
rendererReady: () => ipcRenderer.send("renderer-ready"),
applyStartupSize: (width: number, height: number) =>
ipcRenderer.send("window:apply-startup-size", width, height),

// Tab 拖拽分离
tearOffTabStart: (
Expand Down
8 changes: 5 additions & 3 deletions src/renderer/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ function onOutlineTransitionEnd(e: TransitionEvent) {
}

onMounted(() => {
const { windowDefaultWidth = 1200, windowDefaultHeight = 800 } = config.value.other ?? {};
window.electronAPI.applyStartupSize(windowDefaultWidth, windowDefaultHeight);
initTheme();
initFont();
initOtherConfig();
Expand Down Expand Up @@ -275,7 +277,7 @@ const handleInstall = async () => {
position: absolute;
left: 0;
top: 0;
width: 25%;
width: max(25%, 150px);
height: 100%;
z-index: 10;
transform: translateX(-100%);
Expand All @@ -300,7 +302,7 @@ const handleInstall = async () => {
pointer-events: auto;
}
.editorBox {
transform: translateX(25%);
transform: translateX(max(25%, 150px));
}
}

Expand Down Expand Up @@ -332,7 +334,7 @@ const handleInstall = async () => {
}
.editorBox {
width: 100%;
transform: translateX(25%);
transform: translateX(max(25%, 150px));
transition: none;
}
}
Expand Down
28 changes: 27 additions & 1 deletion src/renderer/components/menu/MenuBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ checkUpdate().then((updateInfo) => {
@click="option.action"
>
<AppIcon :name="option.icon" class="menu-option-icon" />
{{ option.label }}
<span class="menu-option-label">{{ option.label }}</span>
</button>
</div>
<div class="detailContainer">
Expand Down Expand Up @@ -118,6 +118,7 @@ checkUpdate().then((updateInfo) => {
gap: 4px;
-webkit-app-region: drag;
background: var(--background-color);
transition: width 0.25s ease;

.menu-option {
cursor: pointer;
Expand All @@ -132,12 +133,21 @@ checkUpdate().then((updateInfo) => {
background: transparent;
text-align: left;
color: var(--text-color);
transition: padding 0.25s ease;

.menu-option-icon {
font-size: 18px;
flex-shrink: 0;
}

.menu-option-label {
white-space: nowrap;
overflow: hidden;
transition:
opacity 0.25s ease,
max-width 0.25s ease;
}

&:hover {
background: var(--hover-color);
}
Expand All @@ -148,5 +158,21 @@ checkUpdate().then((updateInfo) => {
}
}
}

@media (max-width: 600px) {
.optionsContainer {
width: 56px;

.menu-option {
padding: 16px 19px;
gap: 0;

.menu-option-label {
opacity: 0;
max-width: 0;
}
}
}
}
}
</style>
76 changes: 76 additions & 0 deletions src/renderer/components/settings/OtherSetting.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { config } = useConfig();

const paddingSettingsExpanded = ref(false);
const mermaidSettingsExpanded = ref(false);
const windowSizeExpanded = ref(false);

// 从完整值中提取数字部分用于显示(如 "20px" -> "20")
const displayPaddingValue = computed(() => {
Expand Down Expand Up @@ -45,6 +46,32 @@ function setMermaidMode(mode: string) {
mermaid: { ...config.value.mermaid, defaultDisplayMode: mode as "code" | "mixed" | "diagram" },
};
}

function toggleWindowSize() {
windowSizeExpanded.value = !windowSizeExpanded.value;
}

const currentWindowWidth = computed(() => String(config.value.other?.windowDefaultWidth ?? 1200));
const currentWindowHeight = computed(() => String(config.value.other?.windowDefaultHeight ?? 800));

const WINDOW_MIN_WIDTH = 400;
const WINDOW_MIN_HEIGHT = 300;

function handleWindowWidthChange(value: string) {
const num = Math.max(WINDOW_MIN_WIDTH, parseInt(value) || WINDOW_MIN_WIDTH);
config.value = {
...config.value,
other: { ...config.value.other, windowDefaultWidth: num },
};
}

function handleWindowHeightChange(value: string) {
const num = Math.max(WINDOW_MIN_HEIGHT, parseInt(value) || WINDOW_MIN_HEIGHT);
config.value = {
...config.value,
other: { ...config.value.other, windowDefaultHeight: num },
};
}
</script>

<template>
Expand Down Expand Up @@ -84,6 +111,50 @@ function setMermaidMode(mode: string) {
</div>
</div>

<!-- 窗口默认尺寸设置折叠抽屉 -->
<div class="collapsible-section">
<div class="section-header" @click="toggleWindowSize">
<div class="section-content-wrapper">
<h2 class="section-title">
<span class="title-icon accent-window">
<AppIcon name="max" />
</span>
<span class="title-text">窗口默认尺寸</span>
</h2>
<p class="section-desc">设置 Milkup 启动时的窗口宽度和高度</p>
</div>
<AppIcon name="arrow-right" class="section-arrow" :class="{ active: windowSizeExpanded }" />
</div>
<div class="section-content" :class="{ expanded: windowSizeExpanded }">
<div class="setting-list">
<div class="setting-item">
<label class="setting-label">宽度(PX)</label>
<div class="setting-input-wrapper">
<Input
type="number"
:model-value="currentWindowWidth"
placeholder="最小 400"
:min="WINDOW_MIN_WIDTH"
@update:model-value="handleWindowWidthChange"
/>
</div>
</div>
<div class="setting-item">
<label class="setting-label">高度(PX)</label>
<div class="setting-input-wrapper">
<Input
type="number"
:model-value="currentWindowHeight"
placeholder="最小 300"
:min="WINDOW_MIN_HEIGHT"
@update:model-value="handleWindowHeightChange"
/>
</div>
</div>
</div>
</div>
</div>

<!-- Mermaid 设置折叠抽屉 -->
<div class="collapsible-section">
<div class="section-header" @click="toggleMermaidSettings">
Expand Down Expand Up @@ -187,6 +258,11 @@ function setMermaidMode(mode: string) {
background: color-mix(in srgb, #14b8a6 14%, transparent);
color: #14b8a6;
}

&.accent-window {
background: color-mix(in srgb, #f59e0b 14%, transparent);
color: #f59e0b;
}
}
}

Expand Down
Loading