Skip to content
Open
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
6 changes: 6 additions & 0 deletions src/main/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,12 @@ async function discoverAndBuildCommands(): Promise<CommandInfo[]> {
keywords: ['window', 'management', 'maximize', 'fill', 'fullscreen'],
category: 'system',
},
{
id: 'system-window-management-fill-stage',
title: 'Window: Maximize (Stage Manager)',
keywords: ['window', 'management', 'maximize', 'fill', 'stage manager', 'stage', 'strip', 'respect'],
category: 'system',
},
{
id: 'system-window-management-maximize-width',
title: 'Window: Maximize Width',
Expand Down
14 changes: 14 additions & 0 deletions src/main/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3307,6 +3307,7 @@ const WINDOW_MANAGEMENT_PRESET_COMMAND_IDS = new Set<string>([
'system-window-management-center',
'system-window-management-center-80',
'system-window-management-fill',
'system-window-management-fill-stage',
'system-window-management-maximize-width',
'system-window-management-maximize-height',
'system-window-management-top-left',
Expand Down Expand Up @@ -3372,6 +3373,7 @@ const WINDOW_MANAGEMENT_LAYOUT_COMMAND_IDS = new Set<string>([
'system-window-management-center',
'system-window-management-center-80',
'system-window-management-fill',
'system-window-management-fill-stage',
'system-window-management-maximize-width',
'system-window-management-maximize-height',
'system-window-management-top-left',
Expand Down Expand Up @@ -3939,6 +3941,18 @@ function computeWindowManagementLayoutBounds(
width: area.width,
height: area.height,
};
case 'system-window-management-fill-stage': {
// Maximize while leaving the Stage Manager strip visible: reuse Almost
// Maximize's left inset, extend top/right/bottom to the work-area edges.
const inset = Math.round((area.width - Math.round(area.width * 0.9)) / 2);
const x = area.x + inset;
return {
x,
y: area.y,
width: Math.max(1, areaRight - x),
height: area.height,
};
}
case 'system-window-management-maximize-width': {
// Span the full work-area width, keep the current vertical position/height.
if (!windowBounds) return null;
Expand Down
13 changes: 13 additions & 0 deletions src/native/window-adjust.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ private enum AdjustAction: String {
case center = "center"
case center80 = "center-80"
case fill = "fill"
case fillStage = "fill-stage"
case maximizeWidth = "maximize-width"
case maximizeHeight = "maximize-height"
case topLeft = "top-left"
Expand Down Expand Up @@ -569,6 +570,18 @@ private func adjustedFrame(_ base: WindowFrame, action: AdjustAction, forcedArea
height: max(minHeight, round(area.height))
)
}
case .fillStage:
if let area {
// Maximize while leaving the Stage Manager strip visible: reuse Almost
// Maximize's left inset, extend top/right/bottom to the work-area edges.
let inset = round((area.width - round(area.width * 0.9)) / 2)
next = WindowFrame(
x: area.origin.x + inset,
y: area.origin.y,
width: max(minWidth, round(area.width - inset)),
Comment on lines +579 to +581

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Respect the Stage Manager strip side

When the Dock is positioned on the left, macOS places Stage Manager's recent-apps strip on the right; this preset always offsets the left edge and extends to the right work-area edge, so in that configuration Window: Maximize (Stage Manager) still covers the strip it is meant to preserve. Detect the strip side (or Dock orientation) and apply the inset to the right edge for that case as well.

Useful? React with 👍 / 👎.

height: max(minHeight, round(area.height))
)
}
case .maximizeWidth:
if let area {
// Span the full work-area width, keep the current vertical position/height.
Expand Down
13 changes: 13 additions & 0 deletions src/renderer/src/WindowManagerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ type PresetId =
| 'center'
| 'center-80'
| 'fill'
| 'fill-stage'
| 'maximize-width'
| 'maximize-height'
| 'auto-organize'
Expand Down Expand Up @@ -91,6 +92,7 @@ export const WINDOW_MANAGEMENT_PRESET_COMMANDS: WindowManagementPresetCommand[]
{ commandId: 'system-window-management-center', presetId: 'center' },
{ commandId: 'system-window-management-center-80', presetId: 'center-80' },
{ commandId: 'system-window-management-fill', presetId: 'fill' },
{ commandId: 'system-window-management-fill-stage', presetId: 'fill-stage' },
{ commandId: 'system-window-management-maximize-width', presetId: 'maximize-width' },
{ commandId: 'system-window-management-maximize-height', presetId: 'maximize-height' },
{ commandId: 'system-window-management-top-left', presetId: 'top-left' },
Expand Down Expand Up @@ -147,6 +149,7 @@ const PRESETS: Array<{ id: PresetId; label: string; subtitle: string }> = [
{ id: 'center', label: 'Center', subtitle: 'Current window' },
{ id: 'center-80', label: 'Almost Maximize', subtitle: 'Current window' },
{ id: 'fill', label: 'Maximize', subtitle: 'Current window' },
{ id: 'fill-stage', label: 'Maximize (Stage Manager)', subtitle: 'Current window' },
{ id: 'maximize-width', label: 'Maximize Width', subtitle: 'Current window' },
{ id: 'maximize-height', label: 'Maximize Height', subtitle: 'Current window' },
{ id: 'top-left', label: 'Top Left', subtitle: 'Current window' },
Expand Down Expand Up @@ -309,6 +312,9 @@ function renderPresetIcon(id: PresetId): JSX.Element {
case 'fill':
cells.push({ x: 1, y: 1, w: 18, h: 12 });
break;
case 'fill-stage':
cells.push({ x: 1, y: 3, w: 2, h: 8 }, { x: 4, y: 1, w: 15, h: 12 });
break;
case 'maximize-width':
cells.push({ x: 1, y: 4, w: 18, h: 6 });
break;
Expand Down Expand Up @@ -1032,6 +1038,13 @@ function getPresetRegion(presetId: PresetId, area: ScreenArea): Rect | null {
if (presetId === 'fill') {
return { x: area.left, y: area.top, width: area.width, height: area.height };
}
if (presetId === 'fill-stage') {
// Maximize while leaving the Stage Manager strip visible: reuse Almost
// Maximize's left inset (native path uses 90% width), extend the rest.
const inset = Math.round((area.width - Math.round(area.width * 0.9)) / 2);
const x = area.left + inset;
return { x, y: area.top, width: Math.max(1, area.left + area.width - x), height: area.height };
}
if (presetId === 'center') {
const width = Math.max(1, Math.round(area.width * 0.6));
const height = Math.max(1, Math.round(area.height * 0.6));
Expand Down
5 changes: 5 additions & 0 deletions src/renderer/src/utils/command-helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,7 @@ type WindowManagementGlyphId =
| 'center'
| 'center-80'
| 'fill'
| 'fill-stage'
| 'maximize-width'
| 'maximize-height'
| 'top-left'
Expand Down Expand Up @@ -597,6 +598,7 @@ const WINDOW_MANAGEMENT_GLYPH_SUFFIXES = new Set<WindowManagementGlyphId>([
'center',
'center-80',
'fill',
'fill-stage',
'maximize-width',
'maximize-height',
'top-left',
Expand Down Expand Up @@ -780,6 +782,9 @@ function renderWindowManagementGlyph(glyphId: WindowManagementGlyphId): JSX.Elem
case 'fill':
cells.push({ x: 1, y: 1, w: 18, h: 12 });
break;
case 'fill-stage':
cells.push({ x: 1, y: 3, w: 2, h: 8 }, { x: 4, y: 1, w: 15, h: 12 });
break;
case 'maximize-width':
cells.push({ x: 1, y: 4, w: 18, h: 6 });
break;
Expand Down
Loading