Skip to content

Instantly share code, notes, and snippets.

@kylefeng28
Last active January 3, 2026 19:54
Show Gist options
  • Select an option

  • Save kylefeng28/a9de91976d48e3a47ce45bf2e20bfaa7 to your computer and use it in GitHub Desktop.

Select an option

Save kylefeng28/a9de91976d48e3a47ce45bf2e20bfaa7 to your computer and use it in GitHub Desktop.
no-notch

Starting with the 2021 M1 Pro, MacBook laptops have a camera "notch", which allows the screen to be bigger (e.g., 13.6-inch, 2560 × 1664), but the camera takes up a little notch at the top middle portion of the screen.

The application menus (File, Edit, View, Window, Help, etc) will be displayed to the left of this notch, and the menu bar icons (from applications) and system icons like Bluetooth, Wi-Fi, volume, control center) will be displayed to the right of the notch.

The issue is that if there are too many applications with menu bar icons, this will "overflow" and simply be hidden, as the notch takes up space.

There is an application called Bartender that allows the menu bar icons to be rearranged and displayed in overflow menus. However, the notch still persists and still gets in the way.

There is an application called "Say No to Notch" on the Apple App Store that will resize the screen to be displayed below the notch; therefore sacrificing some vertical real estate space, but allows the screen to behave as if there was no notch.

https://apps.apple.com/us/app/say-no-to-notch/id1639306886?mt=12 https://apple.stackexchange.com/questions/432284/make-macbook-pro-as-if-there-is-no-notch

#!/bin/bash
clang -o NoNotch NoNotch.m -framework Cocoa
echo "Compiled successfully. Run with: ./NoNotch"
#import <Cocoa/Cocoa.h>
#import <CoreGraphics/CoreGraphics.h>
#import <signal.h>
@interface NoNotchApp : NSObject <NSApplicationDelegate>
@property (strong) NSStatusItem *statusItem;
@property (strong) NSWindow *overlayWindow;
@property CGFloat notchHeight;
@property CGDisplayModeRef originalMode;
@end
void signalHandler(int sig);
@implementation NoNotchApp
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
[self setupStatusItem];
[self changeResolution];
[self createNotchOverlay];
[self setupSignalHandlers];
}
- (void)setupSignalHandlers {
signal(SIGINT, signalHandler);
signal(SIGTERM, signalHandler);
}
void signalHandler(int sig) {
NSLog(@"Received signal %d, restoring resolution...", sig);
// Get the app delegate and restore resolution
NoNotchApp *delegate = (NoNotchApp *)[[NSApplication sharedApplication] delegate];
[delegate restoreResolution];
exit(0);
}
- (void)setupStatusItem {
self.statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSVariableStatusItemLength];
self.statusItem.button.title = @"NoNotch";
NSMenu *menu = [[NSMenu alloc] init];
[menu addItemWithTitle:@"Restore & Quit" action:@selector(quit:) keyEquivalent:@"q"];
self.statusItem.menu = menu;
}
- (void)changeResolution {
CGDirectDisplayID displayID = kCGDirectMainDisplay;
NSScreen *screen = [NSScreen mainScreen];
if (!screen) {
NSLog(@"No main screen found");
return;
}
self.notchHeight = screen.safeAreaInsets.top;
NSLog(@"Notch height: %.2f", self.notchHeight);
// Store original mode
self.originalMode = CGDisplayCopyDisplayMode(displayID);
if (!self.originalMode) {
NSLog(@"Could not get original display mode");
return;
}
size_t originalWidth = CGDisplayModeGetWidth(self.originalMode);
size_t originalHeight = CGDisplayModeGetHeight(self.originalMode);
NSLog(@"Original resolution: %zux%zu", originalWidth, originalHeight);
// Calculate new height (subtract notch height)
size_t newHeight = originalHeight - (size_t)self.notchHeight;
NSLog(@"Target height: %zu", newHeight);
// Create dictionary to include HiDPI modes
CFDictionaryRef options = CFDictionaryCreate(NULL,
(const void**)&kCGDisplayShowDuplicateLowResolutionModes,
(const void**)&kCFBooleanTrue, 1,
&kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
// Get all available display modes including HiDPI
CFArrayRef modes = CGDisplayCopyAllDisplayModes(displayID, options);
CFRelease(options);
if (!modes) {
NSLog(@"Could not get display modes");
return;
}
CGDisplayModeRef targetMode = NULL;
CFIndex modeCount = CFArrayGetCount(modes);
NSLog(@"Found %ld display modes (including HiDPI)", modeCount);
// Find a mode with same width but reduced height
for (CFIndex i = 0; i < modeCount; i++) {
CGDisplayModeRef mode = (CGDisplayModeRef)CFArrayGetValueAtIndex(modes, i);
size_t modeWidth = CGDisplayModeGetWidth(mode);
size_t modeHeight = CGDisplayModeGetHeight(mode);
NSLog(@"Mode %ld: %zux%zu", i, modeWidth, modeHeight);
// Look for exact match or closest smaller height with same width
if (modeWidth == originalWidth && modeHeight == newHeight) {
NSLog(@"Found exact target mode: %zux%zu", modeWidth, modeHeight);
targetMode = mode;
break;
} else if (modeWidth == originalWidth && modeHeight < originalHeight && modeHeight >= newHeight - 50) {
NSLog(@"Found close target mode: %zux%zu", modeWidth, modeHeight);
targetMode = mode;
}
}
// Apply the new resolution
if (targetMode) {
NSLog(@"Applying new resolution...");
CGDisplayConfigRef config;
CGError error = CGBeginDisplayConfiguration(&config);
if (error != kCGErrorSuccess) {
NSLog(@"Failed to begin display configuration: %d", error);
CFRelease(modes);
return;
}
error = CGConfigureDisplayWithDisplayMode(config, displayID, targetMode, NULL);
if (error != kCGErrorSuccess) {
NSLog(@"Failed to configure display mode: %d", error);
CGCancelDisplayConfiguration(config);
CFRelease(modes);
return;
}
error = CGCompleteDisplayConfiguration(config, kCGConfigureForSession);
if (error != kCGErrorSuccess) {
NSLog(@"Failed to complete display configuration: %d", error);
} else {
NSLog(@"Successfully changed resolution");
}
} else {
NSLog(@"No suitable display mode found");
}
CFRelease(modes);
}
- (void)createNotchOverlay {
// Create overlay at the top of the physical screen
NSScreen *screen = [NSScreen mainScreen];
if (!screen) return;
// The overlay should cover the area above the new resolution
NSRect overlayFrame = NSMakeRect(0,
screen.frame.size.height,
screen.frame.size.width,
self.notchHeight);
self.overlayWindow = [[NSWindow alloc] initWithContentRect:overlayFrame
styleMask:NSWindowStyleMaskBorderless
backing:NSBackingStoreBuffered
defer:NO];
self.overlayWindow.backgroundColor = [NSColor blackColor];
self.overlayWindow.level = kCGMaximumWindowLevel;
self.overlayWindow.ignoresMouseEvents = NO;
[self.overlayWindow makeKeyAndOrderFront:nil];
}
- (void)restoreResolution {
if (self.originalMode) {
CGDirectDisplayID displayID = kCGDirectMainDisplay;
CGDisplayConfigRef config;
CGBeginDisplayConfiguration(&config);
CGConfigureDisplayWithDisplayMode(config, displayID, self.originalMode, NULL);
CGCompleteDisplayConfiguration(config, kCGConfigureForSession);
CGDisplayModeRelease(self.originalMode);
}
}
- (void)quit:(id)sender {
[self restoreResolution];
[NSApplication.sharedApplication terminate:nil];
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSApplication *app = [NSApplication sharedApplication];
NoNotchApp *delegate = [[NoNotchApp alloc] init];
app.delegate = delegate;
[app setActivationPolicy:NSApplicationActivationPolicyAccessory];
[app run];
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment