diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..738a316 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "JRSwizzle"] + path = JRSwizzle + url = git://github.com/rentzsch/jrswizzle.git diff --git a/Info.plist b/Info.plist new file mode 100644 index 0000000..bc15baa --- /dev/null +++ b/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + noTitleBar-Terminal + CFBundleIdentifier + me.choco.noTitleBarTerminal + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + noTitleBar-Terminal + CFBundlePackageType + BNDL + CFBundleSignature + ???? + CFBundleVersion + 0.1 + NSPrincipalClass + noTitleBarTerminal + SIMBLTargetApplications + + + BundleIdentifier + com.apple.Terminal + + + + diff --git a/JRSwizzle b/JRSwizzle new file mode 160000 index 0000000..6627afc --- /dev/null +++ b/JRSwizzle @@ -0,0 +1 @@ +Subproject commit 6627afc464d7a0ae4ee6f8221fdbea7d89313061 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c762a6a --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +CC=clang +LD=$(CC) + +ARCH= +ARCHES=$(foreach arch,$(ARCH),-arch $(arch)) +OSXVER=10.5 +OSXVER64=10.5 +ifneq ($(OSXVER),$(OSXVER64)) +ARCHES+=-Xarch_x86_64 -mmacosx-version-min=$(OSXVER64) +endif + +OPTLEVEL=2 +CFLAGS+=-std=c99 -O$(OPTLEVEL) -Wall -mmacosx-version-min=$(OSXVER) $(ARCHES) +LDFLAGS+=-bundle -framework Cocoa +OBJS=noTitleBar-Terminal.m JRSwizzle/JRSwizzle.o +NAME=noTitleBar-Terminal +BUNDLE=$(NAME).bundle +TARGET=$(BUNDLE)/Contents/MacOS/$(NAME) +SIMBLDIR=$(HOME)/Library/Application\ Support/SIMBL/Plugins + +default: all +%.o: %.m + $(CC) -c $(CFLAGS) $< -o $@ + +$(TARGET): $(OBJS) + mkdir -p $(BUNDLE)/Contents/MacOS + $(LD) $(CFLAGS) $(LDFLAGS) -o $@ $^ + cp Info.plist $(BUNDLE)/Contents + +all: $(TARGET) + +clean: + rm -f *.o + rm -f JRSwizzle/*.o + rm -rf $(BUNDLE) $(NAME) + +install: $(TARGET) uninstall + mkdir -p $(SIMBLDIR) + cp -R $(BUNDLE) $(SIMBLDIR) + +uninstall: + rm -rf $(SIMBLDIR)/$(BUNDLE) diff --git a/README.md b/README.md new file mode 100644 index 0000000..fa707d1 --- /dev/null +++ b/README.md @@ -0,0 +1,36 @@ +「 noTitleBar Terminal.app 」 +================================= + +Simple SIMBL plugin that removes the Titlebar (and Toolbar) from Terminal.app. + +Why and how +----------- + +I've always envied Linux for the great window managers that the community +produces. Some nice tools to mimic that behaviour are finally surfacing on OS X +like [Hammerspoon][1] and [Kwm][2]. Many setups you see around use iTerm without +the title bar, and since I thought it was pretty cool I decided to add the same +option in Terminal.app +The basic change is removing the NSTitledWindowMask during the window creation, +the other hooked functions are needed to keep all Terminal features working. + +Download +-------- + +An already compiled bundle is available: + +[https://github.com/cHoco/noTitleBar-Terminal/releases] +(https://github.com/cHoco/noTitleBar-Terminal/releases) + +Development +----------- + +Download the development repository using Git: + + git clone --recursive git://github.com/cHoco/noTitleBar-Terminal.git + +Run `make` to compile the plugin, and `make install` to install it into your +home directory's SIMBL plugins folder. + +[1]: http://www.hammerspoon.org +[2]: https://github.com/koekeishiya/kwm diff --git a/noTitleBar-Terminal.h b/noTitleBar-Terminal.h new file mode 100644 index 0000000..33c5ec3 --- /dev/null +++ b/noTitleBar-Terminal.h @@ -0,0 +1,13 @@ +// +// noTitleBar-Terminal.h +// noTitleBar-Terminal +// +// Created by Enrico "cHoco" Ghirardi on 23/12/15. +// Copyright (c) 2015 cHoco. All rights reserved. +// + +#import + +@interface noTitleBarTerminal : NSObject + +@end diff --git a/noTitleBar-Terminal.m b/noTitleBar-Terminal.m new file mode 100644 index 0000000..0190504 --- /dev/null +++ b/noTitleBar-Terminal.m @@ -0,0 +1,103 @@ +// +// noTitleBar-Terminal.m +// noTitleBar-Terminal +// +// Created by Enrico "cHoco" Ghirardi on 23/12/15. +// Copyright (c) 2015 cHoco. All rights reserved. +// + +#import "noTitleBar-Terminal.h" +#import "JRSwizzle/JRSwizzle.h" +#import + +@implementation noTitleBarTerminal + ++ (void)load { + [NSClassFromString(@"TTWindow") + jr_swizzleMethod:@selector(initWithContentRect:styleMask:backing:defer:) + withMethod:@selector(noTitleBar_initWithContentRect:styleMask:backing:defer:) + error:NULL]; + [NSClassFromString(@"TTWindow") + jr_swizzleMethod:@selector(canBecomeKeyWindow) + withMethod:@selector(noTitleBar_canBecomeKeyWindow) + error:NULL]; + [NSClassFromString(@"TTWindow") + jr_swizzleMethod:@selector(canBecomeMainWindow) + withMethod:@selector(noTitleBar_canBecomeMainWindow) + error:NULL]; + [NSClassFromString(@"TTWindow") + jr_swizzleMethod:@selector(performClose:) + withMethod:@selector(noTitleBar_performClose:) + error:NULL]; + [self updateWindows]; +} + +/* + * Remove the titlebars of already created windows, since our bundle will + * probably be loaded after the first window is created (SIMBL limitation) + */ ++ (void)updateWindows { + Class windowMetaClass = NSClassFromString(@"TTWindow"); + Class applicationMetaClass = NSClassFromString(@"TTApplication"); + id currentApp = [applicationMetaClass sharedApplication]; + NSArray *windows = [currentApp windows]; + for (id possibleWindow in windows) { + if ([possibleWindow isKindOfClass:windowMetaClass]) { + // This was a nightmare to debug... for some reason changing the + // styleMask of a window also changes the firstResponder, losing + // keyboard focus. We just save and restore it! + id savedResponder = [possibleWindow firstResponder]; + [possibleWindow setStyleMask:(NSClosableWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask | + NSTexturedBackgroundWindowMask)]; + [possibleWindow makeFirstResponder:savedResponder]; + } + } +} + +@end + +@implementation NSWindow(TTWindow) + +/* + * The 3 following methods must be added because Cocoa doesn't give focus and + * main window status if the window doesn't have a title bar. + * The first two are well documented around the web but the third one is + * necessary to keep Command-W shortucut to close a window since it's disabled + * without a titlebar + */ +- (BOOL)noTitleBar_canBecomeKeyWindow { + return YES; +} + +- (BOOL)noTitleBar_canBecomeMainWindow { + return YES; +} + +- (void)noTitleBar_performClose:(id)sender { + BOOL shouldClose = YES; + + if ([[self delegate] respondsToSelector:@selector(windowShouldClose:)]) { + shouldClose = [(id)[self delegate] windowShouldClose:sender]; + } + if (shouldClose) { + [self close]; + } +} + +- (id)noTitleBar_initWithContentRect:(CGRect)rect + styleMask:(unsigned long long)style + backing:(unsigned long long)backing + defer:(char)defer +{ + return [self noTitleBar_initWithContentRect:rect + styleMask:(NSClosableWindowMask | + NSMiniaturizableWindowMask | + NSResizableWindowMask | + NSTexturedBackgroundWindowMask) + backing:backing + defer:defer]; +} + +@end