Skip to content

Commit

Permalink
Fix Screen Handling on Sonoma
Browse files Browse the repository at this point in the history
On Sonoma, getting the right screen coordiantes was broken (Issue felixhageloh#517).
Somhow the old CG code stopped working, so the fix was to use more modern
APIs.

Getting the screen height correctly on macs with a notch remnained tricky.
Uebersicht has a weird use case where you want 'full screen' for the most part
except for drawing under the top menu bar.

Remaining backwards compatible will be tricky, plus this issue is only present
on macOS 14, so this bumps the minimum requirements to macOS 12.
  • Loading branch information
felixhageloh committed Dec 4, 2023
1 parent 37d8ed3 commit 859a7d7
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 39 deletions.
8 changes: 4 additions & 4 deletions Uebersicht.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -770,7 +770,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 77;
CURRENT_PROJECT_VERSION = 82;
DEVELOPMENT_TEAM = S3P44NRLCW;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
Expand All @@ -783,7 +783,7 @@
INFOPLIST_FILE = "$(SRCROOT)/Uebersicht/Uebersicht-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
"LD_RUNPATH_SEARCH_PATHS[arch=*]" = "@loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.6;
OTHER_CODE_SIGN_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = tracesOf.Uebersicht;
Expand All @@ -805,7 +805,7 @@
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 77;
CURRENT_PROJECT_VERSION = 82;
DEVELOPMENT_TEAM = S3P44NRLCW;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = (
Expand All @@ -818,7 +818,7 @@
INFOPLIST_FILE = "$(SRCROOT)/Uebersicht/Uebersicht-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks";
"LD_RUNPATH_SEARCH_PATHS[arch=*]" = "@loader_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.11;
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.6;
OTHER_CODE_SIGN_FLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = tracesOf.Uebersicht;
Expand Down
6 changes: 3 additions & 3 deletions Uebersicht/UBAppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ - (void)startUp
[[UBWebSocket sharedSocket] open:[self serverUrl:@"ws"]];
[self->widgetsStore reset: [self fetchState]];
// this will trigger a render
[self->screensController syncScreens:self];
[self->screensController syncScreens];

} else if ([output rangeOfString:@"EADDRINUSE"].location != NSNotFound) {
self->portOffset++;
Expand Down Expand Up @@ -320,7 +320,7 @@ - (void)interactionDidChange
{
[windowsController closeAll];
needsRefresh = YES;
[screensController syncScreens:self];
[screensController syncScreens];
}

- (IBAction)showPreferences:(id)sender
Expand All @@ -345,7 +345,7 @@ - (IBAction)visitWidgetGallery:(id)sender
- (IBAction)refreshWidgets:(id)sender
{
needsRefresh = YES;
[screensController syncScreens:self];
[screensController syncScreens];
}

- (IBAction)showDebugConsole:(id)sender
Expand Down
3 changes: 2 additions & 1 deletion Uebersicht/UBScreensController.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
@property NSArray* sortedScreens;

- (id)initWithChangeListener:(id)target;
- (void)syncScreens:(id)sender;
- (void)handleScreenChange:(id)sender;
- (void)syncScreens;

@end
50 changes: 26 additions & 24 deletions Uebersicht/UBScreensController.m
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ - (id)initWithChangeListener:(id<UBScreenChangeListener>)target;

[[NSNotificationCenter defaultCenter]
addObserver: self
selector: @selector(syncScreens:)
selector: @selector(handleScreenChange:)
name: NSApplicationDidChangeScreenParametersNotification
object: nil
];
Expand All @@ -47,29 +47,21 @@ - (void)updateScreens
initWithCapacity:MAX_DISPLAYS
];

CGDirectDisplayID displays[MAX_DISPLAYS];
uint32_t numDisplays;

CGError error = CGGetActiveDisplayList(
MAX_DISPLAYS,
displays,
&numDisplays
);

if (error || numDisplays == 0) {
[self
performSelector: @selector(updateScreens)
withObject: nil
afterDelay: 1
];
return;
}

[screens removeAllObjects];
NSMutableArray *ids = [[NSMutableArray alloc] initWithCapacity:numDisplays];
NSMutableArray *ids = [[NSMutableArray alloc]
initWithCapacity: [NSScreen screens].count
];

for(int i = 0; i < numDisplays; i++) {
name = [self screenNameForDisplay:displays[i]];
int i = 0;
NSNumber* screenId;
for(NSScreen* screen in [NSScreen screens]) {
screenId = [screen deviceDescription][@"NSScreenNumber"];

if (@available(macOS 10.15, *)) {
name = [screen localizedName];
} else {
name = [self screenNameForDisplay: [screenId intValue]];
}
if (!name)
name = [NSString stringWithFormat:@"Display %i", i];

Expand All @@ -83,9 +75,10 @@ - (void)updateScreens
nameList[name] = [NSNumber numberWithInt:1];
}

NSNumber* screenId = @(displays[i]);
screens[screenId] = name;
[ids addObject: screenId];

i++;
}

sortedScreens = ids;
Expand All @@ -96,7 +89,16 @@ - (void)updateScreens
];
}

- (void)syncScreens:(id)sender
- (void)handleScreenChange:(id)sender
{
[self
performSelector:@selector(syncScreens)
withObject:NULL
afterDelay:0
];
}

- (void)syncScreens
{
[self updateScreens];
[listener screensChanged:screens];
Expand Down
1 change: 1 addition & 0 deletions Uebersicht/UBWindowsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)workspaceChanged;
- (void)wallpaperChanged;
- (void)showDebugConsolesForScreen:(NSNumber*)screenId;
- (NSScreen*)getNSScreen:(NSNumber*)screenId;

@end

Expand Down
33 changes: 26 additions & 7 deletions Uebersicht/UBWindowsController.m
Original file line number Diff line number Diff line change
Expand Up @@ -65,16 +65,35 @@ - (void)updateWindows:(NSDictionary*)screens

- (NSRect)screenRect:(NSNumber*)screenId
{
NSRect screenRect = CGDisplayBounds([screenId unsignedIntValue]);
CGRect mainScreenRect = CGDisplayBounds(CGMainDisplayID());
int menuBarHeight = [[NSApp mainMenu] menuBarHeight];
NSScreen* screen = [self getNSScreen:screenId];

CGFloat auxiliaryHeight = screen.auxiliaryTopLeftArea.size.height;
CGFloat windowHeight = screen.visibleFrame.size.height +
(screen.visibleFrame.origin.y - screen.frame.origin.y);

// If the remaining visible height is exactly the auxiliaryHeight, the menu
// bar is hidden. There seems to be no other way to dedect this reliably
if (screen.frame.size.height - windowHeight == auxiliaryHeight) {
windowHeight = windowHeight + auxiliaryHeight;
}

screenRect.origin.y = -1 * (screenRect.origin.y + screenRect.size.height -
mainScreenRect.size.height);
return NSMakeRect(
screen.frame.origin.x,
screen.frame.origin.y,
screen.frame.size.width,
windowHeight
);
}

screenRect.size.height = screenRect.size.height - menuBarHeight;
- (NSScreen*)getNSScreen:(NSNumber*)screenId
{
for (NSScreen* screen in [NSScreen screens]) {
if ([screen deviceDescription][@"NSScreenNumber"] == screenId) {
return screen;
}
};

return screenRect;
return nil;
}

- (void)reloadAll
Expand Down

0 comments on commit 859a7d7

Please sign in to comment.