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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Programa is a fork of [cmux](https://github.com/manaflow-ai/cmux); for history p
- The library-validation and unsigned-executable-memory entitlements.

### Fixed
- The Window menu's Fill, Center, Move & Resize, Full Screen Tile and Move to Display items, and their shortcuts, work again. The main window had been marked not movable, which makes macOS disable all of them.
- Port chips in the sidebar now show up again for terminals restored after relaunching Programa. The restored terminals kept their running shell, but port scanning never learned about them.
- A window closed with the red button no longer comes back on the next launch. Since 0.5.0 a closed window was kept alive for Dock reopen and then saved and restored like a visible one, so every restart opened an extra window of stale workspaces. Closed windows now stay closed across a relaunch and their shells are ended at startup.
- The agent status badge in a sidebar row stays readable in a narrow sidebar; the tab title is cut short instead. While the badge shows, a spinner character at the start of a program-set title (such as Claude Code's "◐" or "✳") is hidden, since the badge already shows the state.
Expand Down
18 changes: 10 additions & 8 deletions Sources/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4757,8 +4757,12 @@ final class AppDelegate: NSObject, NSApplicationDelegate, @preconcurrency UNUser
window.title = ""
window.titleVisibility = .hidden
window.titlebarAppearsTransparent = true
// Keep the window movable: AppKit validates Window > Fill / Center /
// Move & Resize / Move to Display (and their shortcuts) against
// `isMovable`. Native titlebar drag stays off because
// MainWindowHostingView returns false from `mouseDownCanMoveWindow`;
// explicit drag surfaces use `performDrag` instead.
window.isMovableByWindowBackground = false
window.isMovable = false
let restoredFrame = resolvedWindowFrame(from: sessionWindowSnapshot)
if let restoredFrame {
window.setFrame(restoredFrame, display: false)
Expand Down Expand Up @@ -8135,16 +8139,14 @@ final class AppDelegate: NSObject, NSApplicationDelegate, @preconcurrency UNUser
if !window.titlebarAppearsTransparent {
window.titlebarAppearsTransparent = true
}
// Keep window immovable; the sidebar's WindowDragHandleView handles
// drag-to-move via performDrag with temporary movable override.
// isMovableByWindowBackground=true breaks tab reordering, and
// isMovable=true blocks clicks on sidebar buttons in minimal mode.
// isMovableByWindowBackground=true breaks sidebar tab reordering, so
// drag-to-move goes through WindowDragHandleView's performDrag. The
// window itself stays movable (see createMainWindow) so the Window menu
// tiling items validate; MainWindowHostingView's mouseDownCanMoveWindow
// override keeps clicks on sidebar buttons from becoming native drags.
if window.isMovableByWindowBackground {
window.isMovableByWindowBackground = false
}
if window.isMovable {
window.isMovable = false
}
if !window.styleMask.contains(.fullSizeContentView) {
window.styleMask.insert(.fullSizeContentView)
}
Expand Down
6 changes: 6 additions & 0 deletions Sources/MainWindowHostingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ final class MainWindowHostingView<Content: View>: NSHostingView<Content>, MainWi
override var safeAreaRect: NSRect { bounds }
override var safeAreaLayoutGuide: NSLayoutGuide { zeroSafeAreaLayoutGuide }

/// The window stays `isMovable` so AppKit enables the Window menu tiling
/// items, but SwiftUI content under the transparent titlebar must not turn
/// a click into a native window drag (sidebar buttons in minimal mode).
/// Explicit drag surfaces call `performDrag` themselves.
override var mouseDownCanMoveWindow: Bool { false }

required init(rootView: Content) {
super.init(rootView: rootView)
// Tell SwiftUI to ignore safe areas outright, rather than relying only on
Expand Down
Loading