From cccd912498ffee682d6a326b248d35d177d737e8 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 2 Dec 2007 15:00:37 +0100 Subject: [PATCH] Nicer looking tabs on Leopard Make the tabs look almost identical to the Leopard Terminal.app tabs (only on Leopard, the Tiger tabs are unchanged). --- src/MacVim/MMVimView.m | 32 ++++++++++ src/MacVim/MMWindowController.m | 95 +++++++++++++++++++++++++---- src/MacVim/MacVim.xcodeproj/project.pbxproj | 14 +---- 3 files changed, 115 insertions(+), 26 deletions(-) diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index dca6f3cd..ae8ff245 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -182,6 +182,38 @@ enum { [super dealloc]; } +- (void)drawRect:(NSRect)rect +{ + // On Leopard, we want to have a textured window background for nice + // looking tabs. However, the textured window background looks really + // weird behind the window resize throbber, so emulate the look of an + // NSScrollView in the bottom right corner. + if (![[self window] showsResizeIndicator] // XXX: make this a flag + || !([[self window] styleMask] & NSTexturedBackgroundWindowMask)) + return; + + int sw = [NSScroller scrollerWidth]; + + // add .5 to the pixel locations to put the lines on a pixel boundary. + // the top and right edges of the rect will be outside of the bounds rect + // and clipped away. + NSRect sizerRect = NSMakeRect([self bounds].size.width - sw + .5, -.5, + sw, sw); + //NSBezierPath* path = [NSBezierPath bezierPath]; + NSBezierPath* path = [NSBezierPath bezierPathWithRect:sizerRect]; + + // On Tiger, we have color #E8E8E8 behind the resize throbber + // (which is windowBackgroundColor on untextured windows or controlColor in + // general). Terminal.app on Leopard has #FFFFFF background and #D9D9D9 as + // stroke. The colors below are #FFFFFF and #D4D4D4, which is close enough + // for me. + [[NSColor controlBackgroundColor] set]; + [path fill]; + + [[NSColor secondarySelectedControlColor] set]; + [path stroke]; +} + - (MMTextView *)textView { return textView; diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index 35b4091b..f11abc2c 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -65,10 +65,14 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) } #endif +@interface NSWindow (NSWindowPrivate) // Note: This hack allows us to set content shadowing separately from // the window shadow. This is apparently what webkit and terminal do. -@interface NSWindow (NSWindowPrivate) // new Tiger private method -- (void)_setContentHasShadow:(BOOL)shadow; +- (void)_setContentHasShadow:(BOOL)shadow; // new Tiger private method + +// This is a private api that makes textured windows not have rounded corners. +// We want this on Leopard. +- (void)setBottomCornerRounded:(BOOL)rounded; @end @@ -76,23 +80,38 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) - (id)initWithVimController:(MMVimController *)controller { - if ((self = [super initWithWindowNibName:@"EmptyWindow"])) { +#ifndef NSAppKitVersionNumber10_4 // needed for non-10.5 sdk +# define NSAppKitVersionNumber10_4 824 +#endif + unsigned styleMask = NSTitledWindowMask | NSClosableWindowMask + | NSMiniaturizableWindowMask | NSResizableWindowMask + | NSUnifiedTitleAndToolbarWindowMask; + + // Use textured background on Leopard or later (uncomment this on Tiger for + // polished metal window). + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_4) + styleMask |= NSTexturedBackgroundWindowMask; + + NSWindow *win = [[NSWindow alloc] + initWithContentRect:NSMakeRect(0,0,480,360) + styleMask:styleMask + backing:NSBackingStoreBuffered + defer:YES]; + + if ((self = [super initWithWindow:win])) { vimController = controller; // Window cascading is handled by MMAppController. [self setShouldCascadeWindows:NO]; - NSWindow *win = [self window]; NSView *contentView = [win contentView]; vimView = [[MMVimView alloc] initWithFrame:[contentView frame] vimController:vimController]; [contentView addSubview:vimView]; - // [vimView translateOriginToPoint: - // NSMakePoint([contentView frame].size.width, 0)]; - // [vimView rotateByAngle:45.f]; // Create the tabline separator (which may be visible when the tabline - // is hidden). + // is hidden). See showTabBar: for circumstances when the separator + // should be hidden. NSRect tabSepRect = [contentView frame]; tabSepRect.origin.y = NSMaxY(tabSepRect)-1; tabSepRect.size.height = 1; @@ -109,6 +128,30 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [win setDelegate:self]; [win setInitialFirstResponder:[vimView textView]]; + if ([win styleMask] & NSTexturedBackgroundWindowMask) { + // On Leopard, we want to have a textured window to have nice + // looking tabs. But the textured window look implies rounded + // corners, which looks really weird -- disable them. This is a + // private api, though. + if ([win respondsToSelector:@selector(setBottomCornerRounded:)]) + [win setBottomCornerRounded:NO]; + +#if NSAppKitVersionNumber > NSAppKitVersionNumber10_4 // Avoid warning on 10.4 + // When the tab bar is toggled, it changes color for the fraction + // of a second, probably because vim sends us events in a strange + // order, confusing appkit's content border heuristic for a short + // while. This can be worked around with these two methods. There + // might be a better way, but it's good enough. + if ([win respondsToSelector:@selector( + setAutorecalculatesContentBorderThickness:forEdge:)]) + [win setAutorecalculatesContentBorderThickness:NO + forEdge:NSMaxYEdge]; + if ([win respondsToSelector: + @selector(setContentBorderThickness:forEdge:)]) + [win setContentBorderThickness:40 forEdge:NSMaxYEdge]; +#endif // NSAppKitVersionNumber > NSAppKitVersionNumber10_4 + } + // Make us safe on pre-tiger OSX if ([win respondsToSelector:@selector(_setContentHasShadow:)]) [win _setContentHasShadow:NO]; @@ -178,7 +221,6 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [self leaveFullscreen]; } - setupDone = NO; vimController = nil; @@ -313,11 +355,29 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) { [[vimView tabBarControl] setHidden:!on]; + // Rules for when to show tabline separator: + // + // Tabline visible & Toolbar visible => Separator visible + // ================================================================ + // NO & NO => NO (Tiger), YES (Leopard) + // NO & YES => YES + // YES & NO => NO + // YES & YES => NO + // + // XXX: This is ignored if called while in fullscreen mode if (!on) { NSToolbar *toolbar = [[self window] toolbar]; - [tablineSeparator setHidden:![toolbar isVisible]]; + if (([[self window] styleMask] & NSTexturedBackgroundWindowMask) == 0) { + [tablineSeparator setHidden:![toolbar isVisible]]; + } else { + [tablineSeparator setHidden:NO]; + } } else { - [tablineSeparator setHidden:on]; + if (([[self window] styleMask] & NSTexturedBackgroundWindowMask) == 0) { + [tablineSeparator setHidden:on]; + } else { + [tablineSeparator setHidden:YES]; + } } //if (setupDone) @@ -333,9 +393,18 @@ NSMutableArray *buildMenuAddress(NSMenu *menu) [toolbar setDisplayMode:mode]; [toolbar setVisible:on]; - if (!on) { - [tablineSeparator setHidden:YES]; + // See showTabBar: for circumstances when the separator should be hidden. + if (([[self window] styleMask] & NSTexturedBackgroundWindowMask) == 0) { + if (!on) { + [tablineSeparator setHidden:YES]; + } else { + [tablineSeparator setHidden:![[vimView tabBarControl] isHidden]]; + } } else { + // Textured windows don't have a line below there title bar, so we + // need the separator in this case as well. In fact, the only case + // where we don't need the separator is when the tab bar control + // is visible (because it brings its own separator). [tablineSeparator setHidden:![[vimView tabBarControl] isHidden]]; } } diff --git a/src/MacVim/MacVim.xcodeproj/project.pbxproj b/src/MacVim/MacVim.xcodeproj/project.pbxproj index df440005..e134dd69 100644 --- a/src/MacVim/MacVim.xcodeproj/project.pbxproj +++ b/src/MacVim/MacVim.xcodeproj/project.pbxproj @@ -41,7 +41,6 @@ 1DD703B90BA9D15D008679E9 /* vim_gloss.icns in Resources */ = {isa = PBXBuildFile; fileRef = 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */; }; 1DD704310BA9F9C2008679E9 /* SpecialKeys.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */; }; 1DD9F5E50C85D60500E8D5A5 /* SystemColors.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */; }; - 1DDBEB6D0C7434150036EEDD /* EmptyWindow.nib in Resources */ = {isa = PBXBuildFile; fileRef = 1DDBEB6B0C7434150036EEDD /* EmptyWindow.nib */; }; 1DE608B40C587FDA0055263D /* runtime in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DE602470C587FD10055263D /* runtime */; }; 1DE8CC620C5E2AAD003F56E3 /* Actions.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1DE8CC610C5E2AAD003F56E3 /* Actions.plist */; }; 1DED78600C6DE43D0079945F /* vimrc in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1DED785F0C6DE43D0079945F /* vimrc */; }; @@ -173,7 +172,6 @@ 1DD703B80BA9D15D008679E9 /* vim_gloss.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = vim_gloss.icns; sourceTree = ""; }; 1DD704300BA9F9C2008679E9 /* SpecialKeys.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = SpecialKeys.plist; sourceTree = ""; }; 1DD9F5E40C85D60500E8D5A5 /* SystemColors.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = SystemColors.plist; sourceTree = ""; }; - 1DDBEB6C0C7434150036EEDD /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/EmptyWindow.nib; sourceTree = ""; }; 1DE602470C587FD10055263D /* runtime */ = {isa = PBXFileReference; lastKnownFileType = folder; name = runtime; path = ../../runtime; sourceTree = SOURCE_ROOT; }; 1DE8CC610C5E2AAD003F56E3 /* Actions.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Actions.plist; sourceTree = ""; }; 1DED785F0C6DE43D0079945F /* vimrc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = vimrc; sourceTree = ""; }; @@ -204,7 +202,7 @@ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 32CA4F630368D1EE00C91783 /* MacVim_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MacVim_Prefix.pch; sourceTree = ""; }; 8D1107310486CEB800E47090 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; - 8D1107320486CEB800E47090 /* MacVim.app */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.application; path = MacVim.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 8D1107320486CEB800E47090 /* MacVim.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MacVim.app; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -380,7 +378,6 @@ 8D1107310486CEB800E47090 /* Info.plist */, 089C165CFE840E0CC02AAC07 /* InfoPlist.strings */, 29B97318FDCFA39411CA2CEA /* MainMenu.nib */, - 1DDBEB6B0C7434150036EEDD /* EmptyWindow.nib */, ); name = Resources; sourceTree = ""; @@ -495,7 +492,6 @@ 1DEE0DB30C4E150B008E82B2 /* Undo.png in Resources */, 1DD04DEC0C529C5E006CDC2B /* Credits.rtf in Resources */, 1DE8CC620C5E2AAD003F56E3 /* Actions.plist in Resources */, - 1DDBEB6D0C7434150036EEDD /* EmptyWindow.nib in Resources */, 1DD9F5E50C85D60500E8D5A5 /* SystemColors.plist in Resources */, 1D3D19110CA690FF0004A0A5 /* DejaVuSansMono-Bold.ttf in Resources */, 1D3D19120CA690FF0004A0A5 /* DejaVuSansMono-BoldOblique.ttf in Resources */, @@ -544,14 +540,6 @@ name = InfoPlist.strings; sourceTree = ""; }; - 1DDBEB6B0C7434150036EEDD /* EmptyWindow.nib */ = { - isa = PBXVariantGroup; - children = ( - 1DDBEB6C0C7434150036EEDD /* English */, - ); - name = EmptyWindow.nib; - sourceTree = ""; - }; 29B97318FDCFA39411CA2CEA /* MainMenu.nib */ = { isa = PBXVariantGroup; children = ( -- 2.11.4.GIT