Skip to content

Commit 96c0287

Browse files
committed
Release v1.0.25: Fix macOS 26 crash (complete)
1 parent 9bd02c9 commit 96c0287

9 files changed

Lines changed: 61 additions & 9 deletions

File tree

Aegis/Components/MenuBar/Controllers/MenuBarWindowController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ class MenuBarWindowController: ObservableObject {
148148
// MARK: - Custom Window Class
149149

150150
// Custom window that prevents becoming key window (avoids focus stealing)
151-
class MenuBarWindow: NSWindow {
151+
class MenuBarWindow: AegisOverlayWindow {
152152
override var canBecomeKey: Bool {
153153
return false
154154
}

Aegis/Components/Notch/Controllers/NotchHUDController.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class NotchHUDController: ObservableObject {
203203
hostingView.frame = screen.frame
204204

205205
// Create window ONCE at startup
206-
overlayWindow = NSWindow(
206+
overlayWindow = AegisOverlayWindow(
207207
contentRect: screen.frame,
208208
styleMask: [.borderless, .fullSizeContentView],
209209
backing: .buffered,
@@ -271,7 +271,7 @@ class NotchHUDController: ObservableObject {
271271
hostingView.frame = NSRect(origin: .zero, size: windowFrame.size)
272272

273273
// Create main display window (ignores mouse events)
274-
mediaWindow = NSWindow(
274+
mediaWindow = AegisOverlayWindow(
275275
contentRect: windowFrame,
276276
styleMask: [.borderless, .fullSizeContentView],
277277
backing: .buffered,
@@ -328,7 +328,7 @@ class NotchHUDController: ObservableObject {
328328
if #available(macOS 13, *) { hostingView.sceneBridgingOptions = [] }
329329
hostingView.frame = NSRect(origin: .zero, size: windowFrame.size)
330330

331-
deviceWindow = NSWindow(
331+
deviceWindow = AegisOverlayWindow(
332332
contentRect: windowFrame,
333333
styleMask: [.borderless, .fullSizeContentView],
334334
backing: .buffered,
@@ -381,7 +381,7 @@ class NotchHUDController: ObservableObject {
381381
if #available(macOS 13, *) { hostingView.sceneBridgingOptions = [] }
382382
hostingView.frame = NSRect(origin: .zero, size: windowFrame.size)
383383

384-
focusWindow = NSWindow(
384+
focusWindow = AegisOverlayWindow(
385385
contentRect: windowFrame,
386386
styleMask: [.borderless, .fullSizeContentView],
387387
backing: .buffered,

Aegis/Components/Notch/Helpers/Brightness/BrightnessHelper.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,11 @@ extern NSString * _Nonnull const AegisBrightnessChangedNotification;
3030

3131
@end
3232

33+
/// Base NSWindow subclass for all Aegis overlay windows.
34+
/// Overrides postWindowNeedsUpdateConstraints to catch the ObjC exception
35+
/// thrown by macOS 26 for borderless overlay windows.
36+
#import <AppKit/AppKit.h>
37+
@interface AegisOverlayWindow : NSWindow
38+
@end
39+
3340
#endif /* BrightnessHelper_h */

Aegis/Components/Notch/Helpers/Brightness/BrightnessHelper.m

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,24 @@ - (void)dealloc {
116116
}
117117

118118
@end
119+
120+
// Forward-declare the private AppKit category method so the compiler
121+
// knows the selector exists without needing private headers.
122+
@interface NSWindow (NSDisplayCycle_Private)
123+
- (void)postWindowNeedsUpdateConstraints;
124+
@end
125+
126+
@implementation AegisOverlayWindow
127+
128+
- (void)postWindowNeedsUpdateConstraints {
129+
@try {
130+
[super postWindowNeedsUpdateConstraints];
131+
} @catch (NSException *exception) {
132+
// macOS 26 throws in postWindowNeedsUpdateConstraints for borderless
133+
// overlay windows (both invalidateSafeAreaInsets and
134+
// invalidateSafeAreaCornerInsets paths). Safe to suppress —
135+
// NSHostingView will re-request on the next display cycle.
136+
}
137+
}
138+
139+
@end

Aegis/Components/Notch/Views/NotificationHUDHostingView.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import SwiftUI
1313

1414
/// Custom window that can receive mouse events but never becomes key window.
1515
/// This prevents the "makeKeyWindow called but canBecomeKey returned NO" warnings.
16-
class NotificationHUDWindow: NSWindow {
16+
class NotificationHUDWindow: AegisOverlayWindow {
1717
override var canBecomeKey: Bool { false }
1818
override var canBecomeMain: Bool { false }
1919
override func makeKey() { /* Do nothing */ }

Aegis/Info.plist

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
<key>CFBundlePackageType</key>
1616
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
1717
<key>CFBundleShortVersionString</key>
18-
<string>1.0.24</string>
18+
<string>1.0.25</string>
1919
<key>CFBundleVersion</key>
20-
<string>1.0.24</string>
20+
<string>1.0.25</string>
2121
<key>LSMinimumSystemVersion</key>
2222
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
2323
<key>LSUIElement</key>

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [1.0.25] - 2026-04-03
11+
12+
### Fixed
13+
- **Crash on macOS 26 (complete fix)** - Replaced `sceneBridgingOptions = []` workaround with an Objective-C `@try/@catch` override of `NSWindow.postWindowNeedsUpdateConstraints` on all overlay windows. This intercepts the throw at the source regardless of which safe area invalidation path triggers it, fixing both the `invalidateSafeAreaCornerInsets` and `invalidateSafeAreaInsets` paths confirmed in v1.0.24
14+
1015
## [1.0.24] - 2026-04-02
1116

1217
### Added

Distribution/appcast.xml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,25 @@
77
<language>en</language>
88

99
<!-- Latest Release -->
10+
<item>
11+
<title>Version 1.0.25</title>
12+
<sparkle:version>1.0.25</sparkle:version>
13+
<sparkle:shortVersionString>1.0.25</sparkle:shortVersionString>
14+
<sparkle:minimumSystemVersion>14.0</sparkle:minimumSystemVersion>
15+
<pubDate>Thu, 03 Apr 2026 00:00:00 +0000</pubDate>
16+
<description><![CDATA[
17+
<h2>What's New in 1.0.25</h2>
18+
<ul>
19+
<li><strong>Crash Fix (macOS 26) — complete</strong> - Fixed the remaining crash on macOS 26 after granting permissions. The v1.0.24 fix only blocked one of two crash paths; this release adds an Objective-C exception guard directly in the window layer, catching all variants</li>
20+
</ul>
21+
]]></description>
22+
<enclosure
23+
url="https://github.com/CCMurphy-Dev/Aegis/releases/download/v1.0.25/Aegis.app.zip"
24+
length="2804791"
25+
type="application/octet-stream"
26+
sparkle:edSignature="036raPSYZstjVw/yt1DJ7lmcIwCLsBtczDdGKjt1kAoeSmM1I0gIh2P5Tj00yfoFxiYUDleWGH03brmnOumWBg==" />
27+
</item>
28+
1029
<item>
1130
<title>Version 1.0.24</title>
1231
<sparkle:version>1.0.24</sparkle:version>

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.24
1+
1.0.25

0 commit comments

Comments
 (0)