1 /* vi:set ts=8 sts=4 sw=4 ft=objc:
3 * VIM - Vi IMproved by Bram Moolenaar
4 * MacVim GUI port by Bjorn Winckler
6 * Do ":help uganda" in Vim to read copying and usage conditions.
7 * Do ":help credits" in Vim to see a list of people who contributed.
8 * See README.txt for an overview of the Vim source code.
11 #import "MMFullscreenWindow.h"
12 #import <PSMTabBarControl.h>
14 #import "MMTextView.h"
15 #import "MMWindowController.h"
16 #import <Carbon/Carbon.h>
20 @implementation MMFullscreenWindow
22 - (MMFullscreenWindow *)initWithWindow:(NSWindow *)t view:(MMVimView *)v
24 NSScreen* screen = [t screen];
26 // XXX: what if screen == nil?
28 // you can't change the style of an existing window in cocoa. create a new
29 // window and move the MMTextView into it.
30 // (another way would be to make the existing window large enough that the
31 // title bar is off screen. but that doesn't work with multiple screens).
32 self = [super initWithContentRect:[screen frame]
33 styleMask:NSBorderlessWindowMask
34 backing:NSBackingStoreBuffered
41 [self setHasShadow:NO];
42 [self setShowsResizeIndicator:NO];
43 [self setBackgroundColor:[NSColor blackColor]];
44 [self setReleasedWhenClosed:NO];
46 target = t; [target retain];
47 view = v; [view retain];
62 NSRect outer = [self frame], inner = [view frame];
63 //NSLog(@"%s %@%@", _cmd, NSStringFromRect(outer), NSStringFromRect(inner));
65 NSPoint origin = NSMakePoint((outer.size.width - inner.size.width)/2,
66 (outer.size.height - inner.size.height)/2);
67 [view setFrameOrigin:origin];
70 - (void)enterFullscreen
72 // hide menu and dock, both appear on demand
73 SetSystemUIMode(kUIModeAllSuppressed, 0); //requires 10.3
76 Boolean didBlend = NO;
77 CGDisplayFadeReservationToken token;
78 if (CGAcquireDisplayFadeReservation(.5, &token) == kCGErrorSuccess) {
79 CGDisplayFade(token, .25, kCGDisplayBlendNormal,
80 kCGDisplayBlendSolidColor, .0, .0, .0, true);
85 id delegate = [target delegate];
86 [target setDelegate:nil];
88 // make target's window controller believe that it's now controlling us
89 [target retain]; // NSWindowController will release target once in the
91 [[target windowController] setWindow:self];
94 oldTabBarStyle = [[view tabBarControl] styleName];
95 [[view tabBarControl] setStyleNamed:@"Unified"];
98 oldPosition = [view frame].origin;
100 [[self contentView] addSubview:view];
101 [self setInitialFirstResponder:[view textView]];
103 [self setTitle:[target title]];
104 [self setOpaque:[target isOpaque]];
106 // make us visible and target invisible
107 [target orderOut:self];
108 [self makeKeyAndOrderFront:self];
110 // don't set this sooner, so we don't get an additional
111 // focus gained message
112 [self setDelegate:delegate];
114 // update bottom right corner scrollbar (no resize handle in fu mode)
115 [[self windowController] placeViews];
117 // the call above moves the text view in the lower left corner, fix that
118 // XXX: still required?
124 CGDisplayFade(token, .25, kCGDisplayBlendSolidColor,
125 kCGDisplayBlendNormal, .0, .0, .0, false);
126 CGReleaseDisplayFadeReservation(token);
130 - (void)leaveFullscreen
133 Boolean didBlend = NO;
134 CGDisplayFadeReservationToken token;
135 if (CGAcquireDisplayFadeReservation(.5, &token) == kCGErrorSuccess) {
136 CGDisplayFade(token, .25, kCGDisplayBlendNormal,
137 kCGDisplayBlendSolidColor, .0, .0, .0, true);
141 // fix up target controller
142 [self retain]; // NSWindowController releases us once
143 [[self windowController] setWindow:target];
146 [[view tabBarControl] setStyleNamed:oldTabBarStyle];
149 id delegate = [self delegate];
150 [self setDelegate:nil];
152 // move text view back to original window, hide fullscreen window,
153 // show original window
154 // do this _after_ resetting delegate and window controller, so the
155 // window controller doesn't get a focus lost message from the fullscreen
157 [[target contentView] addSubview:view];
158 [view setFrameOrigin:oldPosition];
160 [target makeKeyAndOrderFront:self];
162 // ...but we don't want a focus gained message either, so don't set this
164 [target setDelegate:delegate];
167 // update bottom right corner scrollbar (resize handle reappears)
168 // XXX: Doesn't work?
169 [[self windowController] placeViews];
170 [view placeScrollbars];
175 CGDisplayFade(token, .25, kCGDisplayBlendSolidColor,
176 kCGDisplayBlendNormal, .0, .0, .0, false);
177 CGReleaseDisplayFadeReservation(token);
180 // order menu and dock back in
181 SetSystemUIMode(kUIModeNormal, 0);
184 // Title-less windows normally don't receive key presses, override this
185 - (BOOL)canBecomeKeyWindow
190 // Title-less windows normally can't become main which means that another
191 // non-fullscreen window will have the "active" titlebar in expose. Bad, fix it.
192 - (BOOL)canBecomeMainWindow
198 #pragma mark Proxy/Decorator/whatever stuff
200 // the window controller will send us messages that are meant for the original,
201 // non-fullscreen window. forward those, and interpret the messages that are
202 // interesting for us
204 - (void)setTitle:(NSString *)title
206 [target setTitle:title];
207 [super setTitle:title];
210 // HACK: if the T flag in guioptions is changed in fu mode, the toolbar needs
211 // to be changed when nofu is set. MMWindowController gets the toolbar object,
212 // so we need to return a toolbar from this method, even if none is visible for
213 // the fullscreen window. Seems to work, though.
214 - (NSToolbar *)toolbar
216 return [target toolbar];
219 - (void)setFrame:(NSRect)frame display:(BOOL)display
221 // HACK: if the target window would resize, we have to call our own
222 // windowDidResize method so that placeViews in MMWindowController is called
223 if (!NSEqualRects(frame, [target frame]))
225 [target setFrame:frame display:NO];
227 // XXX: send this directly to MMVimView
228 if ([[self delegate] respondsToSelector:@selector(windowDidResize:)])
229 [[self delegate] windowDidResize:nil];
238 return [target frame]; // really? needed by MMWindowController placeViews.
239 // but mucks up display
242 - (NSRect)contentRectForFrameRect:(NSRect)rect
244 //return [target contentRectForFrameRect:rect];
246 // EVIL HACK: this is always called with [[self window] frame] as argument
247 // from MMWindowController. We can't let frame return the frame of target,
248 // so "fix" this here.
249 return [target contentRectForFrameRect:[target frame]];
252 - (NSRect)frameRectForContentRect:(NSRect)contentRect
254 return [target frameRectForContentRect:contentRect];
257 - (NSRect)constrainFrameRect:(NSRect)frameRect toScreen:(NSScreen*)screen
259 return [target constrainFrameRect:frameRect toScreen:screen];
262 - (void)setContentResizeIncrements:(NSSize)size
264 [target setContentResizeIncrements:size];
267 - (void)setOpaque:(BOOL)isOpaque
269 // XXX: Do we want transparency even in fullscreen mode?
270 [super setOpaque:isOpaque];
271 [target setOpaque:isOpaque];