From 60c68a2f2bb893a2fde1c095b0157ba26f976d53 Mon Sep 17 00:00:00 2001 From: jbm Date: Fri, 9 Oct 2026 08:42:43 -0600 Subject: [PATCH 1/3] =?UTF-8?q?Add=20"Open=20in=20New=20Tab=E2=80=A6"=20al?= =?UTF-8?q?ternate=20to=20the=20File=20menu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Holding Option in the File menu now turns "Open…" into "Open in New Tab…" (⌥⌘O) when a repository window is already open, and the selected repositories are opened as tabs of that window, using the same code path as `gitup -t`. When no repository window is open the alternate is hidden so Option keeps showing "Open…", and if the last repository window is closed while the open panel is up, the repositories are opened in new windows instead. Co-Authored-By: Claude Opus 5.5 --- GitUp/Application/AppDelegate.m | 15 +++++++++++++++ GitUp/Application/Base.lproj/MainMenu.xib | 6 ++++++ 2 files changed, 21 insertions(+) diff --git a/GitUp/Application/AppDelegate.m b/GitUp/Application/AppDelegate.m index fa98bf0f4..418c553e9 100644 --- a/GitUp/Application/AppDelegate.m +++ b/GitUp/Application/AppDelegate.m @@ -372,6 +372,11 @@ - (BOOL)validateMenuItem:(NSMenuItem*)menuItem { if (menuItem.action == @selector(checkForUpdates:)) { return _updaterController.updater.canCheckForUpdates; } + if (menuItem.action == @selector(openDocumentInNewTab:)) { + // Hiding the alternate makes AppKit keep showing "Open…" when Option is pressed + menuItem.hidden = ([[NSDocumentController sharedDocumentController] documents].count == 0); + return YES; + } return YES; } @@ -381,6 +386,16 @@ - (IBAction)openDocument:(id)sender { [[NSDocumentController sharedDocumentController] openDocument:sender]; } +- (IBAction)openDocumentInNewTab:(id)sender { + NSDocumentController* controller = [NSDocumentController sharedDocumentController]; + [controller beginOpenPanelWithCompletionHandler:^(NSArray* urls) { + BOOL inTab = (controller.documents.count > 0); // Fall back to a new window if the last repository window was closed in the meantime + for (NSURL* url in urls) { + [self _openRepositoryWithURL:url inTab:inTab withCloneMode:kCloneMode_None windowModeID:NSNotFound]; + } + }]; +} + - (IBAction)viewWiki:(id)sender { [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:kURL_Wiki]]; } diff --git a/GitUp/Application/Base.lproj/MainMenu.xib b/GitUp/Application/Base.lproj/MainMenu.xib index 3630edc0c..6cdb9c79e 100644 --- a/GitUp/Application/Base.lproj/MainMenu.xib +++ b/GitUp/Application/Base.lproj/MainMenu.xib @@ -102,6 +102,12 @@ + + + + + + From 4e20cfb00021aca6aa952a3e64ca0384f30d6a32 Mon Sep 17 00:00:00 2001 From: jbm Date: Fri, 9 Oct 2026 08:42:43 -0600 Subject: [PATCH 2/3] Fix overlay banner hidden by the window tab bar The overlay banner shown by GIWindowController was given a fixed frame computed from the window content layout rect at the moment it appeared. When the window gained a tab bar afterwards (for example when another repository is added as a tab, or when the window itself is merged into a tab group), the banner stayed in place and ended up hidden underneath the tab bar. The overlay is now positioned with Auto Layout and pinned to the top of the content view safe area, the same way the help banner in the repository window is, so it follows the titlebar as the tab bar appears or disappears. Co-Authored-By: Claude Opus 5.5 --- GitUpKit/Utilities/GIWindowController.m | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/GitUpKit/Utilities/GIWindowController.m b/GitUpKit/Utilities/GIWindowController.m index 6481b9818..68938433e 100644 --- a/GitUpKit/Utilities/GIWindowController.m +++ b/GitUpKit/Utilities/GIWindowController.m @@ -179,6 +179,8 @@ - (instancetype)initWithWindow:(NSWindow*)window { if ((self = [super initWithWindow:window])) { [[NSBundle bundleForClass:[GIWindowController class]] loadNibNamed:@"GIWindowController" owner:self topLevelObjects:NULL]; XLOG_DEBUG_CHECK(_overlayView); + _overlayView.translatesAutoresizingMaskIntoConstraints = NO; + [_overlayView.heightAnchor constraintEqualToConstant:_overlayView.frame.size.height].active = YES; _area = [[NSTrackingArea alloc] initWithRect:NSZeroRect options:(NSTrackingInVisibleRect | NSTrackingActiveAlways | NSTrackingMouseEnteredAndExited) owner:self userInfo:nil]; [_overlayView addTrackingArea:_area]; @@ -230,11 +232,15 @@ - (void)showOverlayWithStyle:(GIOverlayStyle)style message:(NSString*)message { } if (_overlayView.superview == nil) { - NSRect bounds = self.window.contentLayoutRect; - NSRect frame = _overlayView.frame; - _overlayView.frame = NSMakeRect(0, bounds.size.height - frame.size.height, bounds.size.width, frame.size.height); + NSView* contentView = self.window.contentView; _overlayView.alphaValue = 0; - [self.window.contentView addSubview:_overlayView]; // Must be above everything else + [contentView addSubview:_overlayView]; // Must be above everything else + [NSLayoutConstraint activateConstraints:@[ + [_overlayView.topAnchor constraintEqualToAnchor:contentView.safeAreaLayoutGuide.topAnchor], // Follows the titlebar as the tab bar appears or disappears + [_overlayView.leadingAnchor constraintEqualToAnchor:contentView.leadingAnchor], + [_overlayView.trailingAnchor constraintEqualToAnchor:contentView.trailingAnchor] + ]]; + [contentView layoutSubtreeIfNeeded]; [CATransaction flush]; _overlayTextField.stringValue = message; From 16e6f080e2552c8e9101bec5da556ad80a345b27 Mon Sep 17 00:00:00 2001 From: jbm Date: Fri, 9 Oct 2026 09:50:19 -0600 Subject: [PATCH 3/3] =?UTF-8?q?Keep=20"Open=E2=80=A6"=20when=20pressing=20?= =?UTF-8?q?Option=20without=20a=20repository=20window?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "Open in New Tab…" was hidden from -validateMenuItem: when no repository window was open, but AppKit had already swapped in the alternate by then, and it swaps in hidden alternates anyway. With only the welcome window open, pressing Option therefore still turned "Open…" into "Open in New Tab…". The item is now updated whenever the number of open documents changes: without a repository window it is hidden and no longer an alternate, so pressing Option keeps showing "Open…". It is restored as the visible Option alternate as soon as a repository window opens. Co-Authored-By: Claude Opus 5.5 --- GitUp/Application/AppDelegate.m | 12 +++++++----- GitUp/Application/Base.lproj/MainMenu.xib | 6 +++++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/GitUp/Application/AppDelegate.m b/GitUp/Application/AppDelegate.m index 418c553e9..a6138f7b2 100644 --- a/GitUp/Application/AppDelegate.m +++ b/GitUp/Application/AppDelegate.m @@ -47,6 +47,7 @@ @interface AppDelegate ()