OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <Carbon/Carbon.h> | 5 #include <Carbon/Carbon.h> |
6 | 6 |
7 #include "base/mac_util.h" | 7 #include "base/mac_util.h" |
8 #include "base/scoped_nsdisable_screen_updates.h" | 8 #include "base/scoped_nsdisable_screen_updates.h" |
9 #import "base/scoped_nsobject.h" | 9 #import "base/scoped_nsobject.h" |
10 #include "base/sys_string_conversions.h" | 10 #include "base/sys_string_conversions.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 | 53 |
54 @interface GTMTheme (BrowserThemeProviderInitialization) | 54 @interface GTMTheme (BrowserThemeProviderInitialization) |
55 + (GTMTheme*)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider | 55 + (GTMTheme*)themeWithBrowserThemeProvider:(BrowserThemeProvider*)provider |
56 isOffTheRecord:(BOOL)offTheRecord; | 56 isOffTheRecord:(BOOL)offTheRecord; |
57 @end | 57 @end |
58 | 58 |
59 @interface NSWindow (NSPrivateApis) | 59 @interface NSWindow (NSPrivateApis) |
60 // Note: These functions are private, use -[NSObject respondsToSelector:] | 60 // Note: These functions are private, use -[NSObject respondsToSelector:] |
61 // before calling them. | 61 // before calling them. |
62 | 62 |
63 - (void)setAutorecalculatesContentBorderThickness:(BOOL)b | |
64 forEdge:(NSRectEdge)e; | |
65 - (void)setContentBorderThickness:(CGFloat)b forEdge:(NSRectEdge)e; | |
66 | |
67 - (void)setBottomCornerRounded:(BOOL)rounded; | 63 - (void)setBottomCornerRounded:(BOOL)rounded; |
68 | 64 |
69 - (NSRect)_growBoxRect; | 65 - (NSRect)_growBoxRect; |
70 | 66 |
71 @end | 67 @end |
72 | 68 |
73 | 69 |
74 @interface BrowserWindowController(Private) | 70 @interface BrowserWindowController(Private) |
75 | 71 |
76 // Saves the window's position in the local state preferences. | 72 // Saves the window's position in the local state preferences. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
109 // can override it in a unit test. | 105 // can override it in a unit test. |
110 NSString* nibpath = [mac_util::MainAppBundle() | 106 NSString* nibpath = [mac_util::MainAppBundle() |
111 pathForResource:@"BrowserWindow" | 107 pathForResource:@"BrowserWindow" |
112 ofType:@"nib"]; | 108 ofType:@"nib"]; |
113 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { | 109 if ((self = [super initWithWindowNibPath:nibpath owner:self])) { |
114 DCHECK(browser); | 110 DCHECK(browser); |
115 browser_.reset(browser); | 111 browser_.reset(browser); |
116 ownsBrowser_ = ownIt; | 112 ownsBrowser_ = ownIt; |
117 tabObserver_.reset( | 113 tabObserver_.reset( |
118 new TabStripModelObserverBridge(browser->tabstrip_model(), self)); | 114 new TabStripModelObserverBridge(browser->tabstrip_model(), self)); |
119 windowShim_.reset(new BrowserWindowCocoa(browser, self, [self window])); | 115 NSWindow* window = [self window]; |
116 windowShim_.reset(new BrowserWindowCocoa(browser, self, window)); | |
120 | 117 |
121 // The window is now fully realized and |-windowDidLoad:| has been | |
122 // called. We shouldn't do much in wDL because |windowShim_| won't yet | |
123 // be initialized (as it's called in response to |[self window]| above). | |
124 // Retain it per the comment in the header. | |
125 window_.reset([[self window] retain]); | |
126 | 118 |
127 // Sets the window to not have rounded corners, which prevents | 119 // Sets the window to not have rounded corners, which prevents |
128 // the resize control from being inset slightly and looking ugly. | 120 // the resize control from being inset slightly and looking ugly. |
129 if ([window_ respondsToSelector:@selector(setBottomCornerRounded:)]) | 121 if ([window respondsToSelector:@selector(setBottomCornerRounded:)]) |
130 [window_ setBottomCornerRounded:NO]; | 122 [window setBottomCornerRounded:NO]; |
131 | 123 |
132 [self setTheme]; | 124 [self setTheme]; |
133 | 125 |
134 // Get the most appropriate size for the window, then enforce the | 126 // Get the most appropriate size for the window, then enforce the |
135 // minimum width and height. The window shim will handle flipping | 127 // minimum width and height. The window shim will handle flipping |
136 // the coordinates for us so we can use it to save some code. | 128 // the coordinates for us so we can use it to save some code. |
137 // Note that this may leave a significant portion of the window | 129 // Note that this may leave a significant portion of the window |
138 // offscreen, but there will always be enough window onscreen to | 130 // offscreen, but there will always be enough window onscreen to |
139 // drag the whole window back into view. | 131 // drag the whole window back into view. |
140 NSSize minSize = [[self window] minSize]; | 132 NSSize minSize = [[self window] minSize]; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
215 initWithBrowser:browser_.get() | 207 initWithBrowser:browser_.get() |
216 resizeDelegate:self]); | 208 resizeDelegate:self]); |
217 [[[self window] contentView] addSubview:[extensionShelfController_ view]]; | 209 [[[self window] contentView] addSubview:[extensionShelfController_ view]]; |
218 [extensionShelfController_ wasInsertedIntoWindow]; | 210 [extensionShelfController_ wasInsertedIntoWindow]; |
219 } | 211 } |
220 | 212 |
221 // Force a relayout of all the various bars. | 213 // Force a relayout of all the various bars. |
222 [self layoutSubviews]; | 214 [self layoutSubviews]; |
223 | 215 |
224 // Create the bridge for the status bubble. | 216 // Create the bridge for the status bubble. |
225 statusBubble_.reset(new StatusBubbleMac([self window], self)); | 217 statusBubble_ = new StatusBubbleMac([self window], self); |
226 } | 218 } |
227 return self; | 219 return self; |
228 } | 220 } |
229 | 221 |
230 - (void)dealloc { | 222 - (void)dealloc { |
231 browser_->CloseAllTabs(); | 223 browser_->CloseAllTabs(); |
232 [downloadShelfController_ exiting]; | 224 [downloadShelfController_ exiting]; |
233 | 225 |
234 // Under certain testing configurations we may not actually own the browser. | 226 // Under certain testing configurations we may not actually own the browser. |
235 if (ownsBrowser_ == NO) | 227 if (ownsBrowser_ == NO) |
236 browser_.release(); | 228 browser_.release(); |
237 // Since |window_| outlives our obj-c shutdown sequence, clear out the | |
238 // delegate so nothing tries to call us back in the meantime as part of | |
239 // window destruction. | |
240 [window_ setDelegate:nil]; | |
241 | 229 |
242 [super dealloc]; | 230 [super dealloc]; |
243 } | 231 } |
244 | 232 |
245 // Access the C++ bridge between the NSWindow and the rest of Chromium | 233 // Access the C++ bridge between the NSWindow and the rest of Chromium |
246 - (BrowserWindow*)browserWindow { | 234 - (BrowserWindow*)browserWindow { |
247 return windowShim_.get(); | 235 return windowShim_.get(); |
248 } | 236 } |
249 | 237 |
250 - (void)destroyBrowser { | 238 - (void)destroyBrowser { |
251 [NSApp removeWindowsItem:[self window]]; | 239 [NSApp removeWindowsItem:[self window]]; |
252 | 240 |
253 // We need the window to go away now. | 241 // We need the window to go away now. |
254 [self autorelease]; | 242 // We can't actually use |-autorelease| here because there's an embedded |
243 // run loop in the |-performClose:| which contains its own autorelease pool. | |
244 // Instead we use call it after a zero-length delay, which gets us back | |
245 // to the main event loop. | |
246 [self performSelector:@selector(autorelease) | |
247 withObject:nil | |
248 afterDelay:0]; | |
255 } | 249 } |
256 | 250 |
257 // Called when the window meets the criteria to be closed (ie, | 251 // Called when the window meets the criteria to be closed (ie, |
258 // |-windowShouldClose:| returns YES). We must be careful to preserve the | 252 // |-windowShouldClose:| returns YES). We must be careful to preserve the |
259 // semantics of BrowserWindow::Close() and not call the Browser's dtor directly | 253 // semantics of BrowserWindow::Close() and not call the Browser's dtor directly |
260 // from this method. | 254 // from this method. |
261 - (void)windowWillClose:(NSNotification*)notification { | 255 - (void)windowWillClose:(NSNotification*)notification { |
262 // Don't update the window any longer. | 256 DCHECK_EQ([notification object], [self window]); |
263 // TODO(shess,dmaclach): This is a work-around for some cases where | |
264 // the window's views were living longer than this controller, and | |
265 // were then being re-displayed. Better would be to have it live | |
266 // the appropriate amount of time, at which point we can remove | |
267 // this. [And perhaps the funky -autorelease below can be fixed.] | |
268 [window_ setAutodisplay:NO]; | |
269 | |
270 DCHECK(!browser_->tabstrip_model()->count()); | 257 DCHECK(!browser_->tabstrip_model()->count()); |
271 | 258 [savedRegularWindow_ close]; |
259 [bookmarkBubbleController_ close]; | |
260 // We delete statusBubble here because we need to kill off the dependency | |
261 // that its window has on our window before our window goes away. | |
262 delete statusBubble_; | |
263 statusBubble_ = NULL; | |
272 // We can't actually use |-autorelease| here because there's an embedded | 264 // We can't actually use |-autorelease| here because there's an embedded |
273 // run loop in the |-performClose:| which contains its own autorelease pool. | 265 // run loop in the |-performClose:| which contains its own autorelease pool. |
274 // Instead we use call it after a zero-length delay, which gets us back | 266 // Instead we use call it after a zero-length delay, which gets us back |
275 // to the main event loop. | 267 // to the main event loop. |
276 [self performSelector:@selector(autorelease) | 268 [self performSelector:@selector(autorelease) |
277 withObject:nil | 269 withObject:nil |
278 afterDelay:0]; | 270 afterDelay:0]; |
279 } | 271 } |
280 | 272 |
281 - (void)attachConstrainedWindow:(ConstrainedWindowMac*)window { | 273 - (void)attachConstrainedWindow:(ConstrainedWindowMac*)window { |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 rwhv->SetActive(true); | 335 rwhv->SetActive(true); |
344 } | 336 } |
345 } | 337 } |
346 | 338 |
347 // Called when we are deactivated (when we lose focus). | 339 // Called when we are deactivated (when we lose focus). |
348 - (void)windowDidResignKey:(NSNotification*)notification { | 340 - (void)windowDidResignKey:(NSNotification*)notification { |
349 // If our app is still active and we're still the key window, ignore this | 341 // If our app is still active and we're still the key window, ignore this |
350 // message, since it just means that a menu extra (on the "system status bar") | 342 // message, since it just means that a menu extra (on the "system status bar") |
351 // was activated; we'll get another |-windowDidResignKey| if we ever really | 343 // was activated; we'll get another |-windowDidResignKey| if we ever really |
352 // lose key window status. | 344 // lose key window status. |
353 if ([NSApp isActive] && | 345 if ([NSApp isActive] && ([NSApp keyWindow] == [self window])) |
354 ([NSApp keyWindow] == static_cast<NSWindow*>(window_))) | |
355 return; | 346 return; |
356 | 347 |
357 // We need to deactivate the controls (in the "WebView"). To do this, get the | 348 // We need to deactivate the controls (in the "WebView"). To do this, get the |
358 // selected TabContents's RenderWidgetHostView and tell it to deactivate. | 349 // selected TabContents's RenderWidgetHostView and tell it to deactivate. |
359 if (TabContents* contents = browser_->GetSelectedTabContents()) { | 350 if (TabContents* contents = browser_->GetSelectedTabContents()) { |
360 if (RenderWidgetHostView* rwhv = contents->render_widget_host_view()) | 351 if (RenderWidgetHostView* rwhv = contents->render_widget_host_view()) |
361 rwhv->SetActive(false); | 352 rwhv->SetActive(false); |
362 } | 353 } |
363 } | 354 } |
364 | 355 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 frame.origin.x = frame.origin.x + frame.size.width - zoomedWidth; | 408 frame.origin.x = frame.origin.x + frame.size.width - zoomedWidth; |
418 else | 409 else |
419 frame.origin.x = currentFrame.origin.x; | 410 frame.origin.x = currentFrame.origin.x; |
420 | 411 |
421 // Set the width. Don't touch y or height. | 412 // Set the width. Don't touch y or height. |
422 frame.size.width = zoomedWidth; | 413 frame.size.width = zoomedWidth; |
423 | 414 |
424 return frame; | 415 return frame; |
425 } | 416 } |
426 | 417 |
418 - (void)activate { | |
419 [[self window] makeKeyAndOrderFront:self]; | |
420 } | |
421 | |
427 // Determine whether we should let a window zoom/unzoom to the given |newFrame|. | 422 // Determine whether we should let a window zoom/unzoom to the given |newFrame|. |
428 // We avoid letting unzoom move windows between screens, because it's really | 423 // We avoid letting unzoom move windows between screens, because it's really |
429 // strange and unintuitive. | 424 // strange and unintuitive. |
430 - (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame { | 425 - (BOOL)windowShouldZoom:(NSWindow*)window toFrame:(NSRect)newFrame { |
431 // Figure out which screen |newFrame| is on. | 426 // Figure out which screen |newFrame| is on. |
432 NSScreen* newScreen = nil; | 427 NSScreen* newScreen = nil; |
433 CGFloat newScreenOverlapArea = 0.0; | 428 CGFloat newScreenOverlapArea = 0.0; |
434 for (NSScreen* screen in [NSScreen screens]) { | 429 for (NSScreen* screen in [NSScreen screens]) { |
435 NSRect overlap = NSIntersectionRect(newFrame, [screen frame]); | 430 NSRect overlap = NSIntersectionRect(newFrame, [screen frame]); |
436 CGFloat overlapArea = overlap.size.width * overlap.size.height; | 431 CGFloat overlapArea = overlap.size.width * overlap.size.height; |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
630 | 625 |
631 - (GTMWindowSheetController*)sheetController { | 626 - (GTMWindowSheetController*)sheetController { |
632 return [tabStripController_ sheetController]; | 627 return [tabStripController_ sheetController]; |
633 } | 628 } |
634 | 629 |
635 - (LocationBar*)locationBar { | 630 - (LocationBar*)locationBar { |
636 return [toolbarController_ locationBar]; | 631 return [toolbarController_ locationBar]; |
637 } | 632 } |
638 | 633 |
639 - (StatusBubbleMac*)statusBubble { | 634 - (StatusBubbleMac*)statusBubble { |
640 return statusBubble_.get(); | 635 return statusBubble_; |
641 } | 636 } |
642 | 637 |
643 - (void)updateToolbarWithContents:(TabContents*)tab | 638 - (void)updateToolbarWithContents:(TabContents*)tab |
644 shouldRestoreState:(BOOL)shouldRestore { | 639 shouldRestoreState:(BOOL)shouldRestore { |
645 [toolbarController_ updateToolbarWithContents:tab | 640 [toolbarController_ updateToolbarWithContents:tab |
646 shouldRestoreState:shouldRestore]; | 641 shouldRestoreState:shouldRestore]; |
647 } | 642 } |
648 | 643 |
649 - (void)setStarredState:(BOOL)isStarred { | 644 - (void)setStarredState:(BOOL)isStarred { |
650 [toolbarController_ setStarredState:isStarred]; | 645 [toolbarController_ setStarredState:isStarred]; |
651 } | 646 } |
652 | 647 |
653 // Return the rect, in WebKit coordinates (flipped), of the window's grow box | 648 // Return the rect, in WebKit coordinates (flipped), of the window's grow box |
654 // in the coordinate system of the content area of the currently selected tab. | 649 // in the coordinate system of the content area of the currently selected tab. |
655 // |windowGrowBox| needs to be in the window's coordinate system. | 650 // |windowGrowBox| needs to be in the window's coordinate system. |
656 - (NSRect)selectedTabGrowBoxRect { | 651 - (NSRect)selectedTabGrowBoxRect { |
657 if (![window_ respondsToSelector:@selector(_growBoxRect)]) | 652 NSWindow* window = [self window]; |
653 if (![window respondsToSelector:@selector(_growBoxRect)]) | |
658 return NSZeroRect; | 654 return NSZeroRect; |
659 | 655 |
660 // Before we return a rect, we need to convert it from window coordinates | 656 // Before we return a rect, we need to convert it from window coordinates |
661 // to tab content area coordinates and flip the coordinate system. | 657 // to tab content area coordinates and flip the coordinate system. |
662 NSRect growBoxRect = | 658 NSRect growBoxRect = |
663 [[self tabContentArea] convertRect:[window_ _growBoxRect] fromView:nil]; | 659 [[self tabContentArea] convertRect:[window _growBoxRect] fromView:nil]; |
664 growBoxRect.origin.y = | 660 growBoxRect.origin.y = |
665 [[self tabContentArea] frame].size.height - growBoxRect.size.height - | 661 [[self tabContentArea] frame].size.height - growBoxRect.size.height - |
666 growBoxRect.origin.y; | 662 growBoxRect.origin.y; |
667 return growBoxRect; | 663 return growBoxRect; |
668 } | 664 } |
669 | 665 |
670 // Accept tabs from a BrowserWindowController with the same Profile. | 666 // Accept tabs from a BrowserWindowController with the same Profile. |
671 - (BOOL)canReceiveFrom:(TabWindowController*)source { | 667 - (BOOL)canReceiveFrom:(TabWindowController*)source { |
672 if (![source isKindOfClass:[BrowserWindowController class]]) { | 668 if (![source isKindOfClass:[BrowserWindowController class]]) { |
673 return NO; | 669 return NO; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
756 } | 752 } |
757 | 753 |
758 - (TabStripController*)tabStripController { | 754 - (TabStripController*)tabStripController { |
759 return tabStripController_; | 755 return tabStripController_; |
760 } | 756 } |
761 | 757 |
762 - (void)setIsLoading:(BOOL)isLoading { | 758 - (void)setIsLoading:(BOOL)isLoading { |
763 [toolbarController_ setIsLoading:isLoading]; | 759 [toolbarController_ setIsLoading:isLoading]; |
764 } | 760 } |
765 | 761 |
766 - (void)activate { | |
767 // TODO(rohitrao): Figure out the proper activation behavior for fullscreen | |
768 // windows. When there is only one window open, this code makes sense, but | |
769 // what should we do if we need to activate a non-fullscreen background window | |
770 // while a fullscreen window has focus? http://crbug.com/24893 | |
771 if (fullscreen_) | |
772 [fullscreen_window_ makeKeyAndOrderFront:self]; | |
773 else | |
774 [window_ makeKeyAndOrderFront:self]; | |
775 } | |
776 | |
777 // Make the location bar the first responder, if possible. | 762 // Make the location bar the first responder, if possible. |
778 - (void)focusLocationBar { | 763 - (void)focusLocationBar { |
779 [toolbarController_ focusLocationBar]; | 764 [toolbarController_ focusLocationBar]; |
780 } | 765 } |
781 | 766 |
782 - (void)layoutTabs { | 767 - (void)layoutTabs { |
783 [tabStripController_ layoutTabs]; | 768 [tabStripController_ layoutTabs]; |
784 } | 769 } |
785 | 770 |
786 - (TabWindowController*)detachTabToNewWindow:(TabView*)tabView { | 771 - (TabWindowController*)detachTabToNewWindow:(TabView*)tabView { |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
921 | 906 |
922 - (NSWindow*)fullscreenWindow { | 907 - (NSWindow*)fullscreenWindow { |
923 return [[[FullscreenWindow alloc] initForScreen:[[self window] screen]] | 908 return [[[FullscreenWindow alloc] initForScreen:[[self window] screen]] |
924 autorelease]; | 909 autorelease]; |
925 } | 910 } |
926 | 911 |
927 - (void)setFullscreen:(BOOL)fullscreen { | 912 - (void)setFullscreen:(BOOL)fullscreen { |
928 if (![self supportsFullscreen]) | 913 if (![self supportsFullscreen]) |
929 return; | 914 return; |
930 | 915 |
931 fullscreen_ = fullscreen; | 916 NSWindow* window = [self window]; |
917 | |
918 // Retain the contentView while we remove it from its superview. | |
919 scoped_nsobject<NSView> content([[window contentView] retain]); | |
920 | |
921 // Disable autoresizing of subviews while we move views around. This | |
922 // prevents spurious renderer resizes. | |
923 [content setAutoresizesSubviews:NO]; | |
924 [content removeFromSuperview]; | |
925 | |
926 NSWindow* dstWindow = nil; | |
932 if (fullscreen) { | 927 if (fullscreen) { |
933 // Move content to a new fullscreen window | 928 DCHECK(!savedRegularWindow_); |
934 NSView* content = [[self window] contentView]; | 929 savedRegularWindow_ = [window retain]; |
935 // Disable autoresizing of subviews while we move views around. This | 930 dstWindow = [self fullscreenWindow]; |
936 // prevents spurious renderer resizes. | 931 } else { |
937 [content setAutoresizesSubviews:NO]; | 932 DCHECK(savedRegularWindow_); |
938 fullscreen_window_.reset([[self fullscreenWindow] retain]); | 933 dstWindow = [savedRegularWindow_ autorelease]; |
939 [content removeFromSuperview]; | 934 savedRegularWindow_ = nil; |
940 [fullscreen_window_ setContentView:content]; | 935 } |
941 [self setWindow:fullscreen_window_.get()]; | |
942 [window_ setWindowController:nil]; | |
943 [window_ setDelegate:nil]; | |
944 // Required for proper event dispatch. | |
945 [fullscreen_window_ setWindowController:self]; | |
946 [fullscreen_window_ setDelegate:self]; | |
947 | 936 |
948 // Minimize our UI. This call triggers a relayout, so it needs to come | 937 // With this call, valgrind yells at me about "Conditional jump or |
949 // after we move the contentview to the new window. | 938 // move depends on uninitialised value(s)". The error happens in |
950 [self adjustUIForFullscreen:fullscreen]; | 939 // -[NSThemeFrame drawOverlayRect:]. I'm pretty convinced this is |
951 // Show one window, hide the other. | 940 // an Apple bug, but there is no visual impact. I have been |
952 [fullscreen_window_ makeKeyAndOrderFront:self]; | 941 // unable to tickle it away with other window or view manipulation |
953 [content setAutoresizesSubviews:YES]; | 942 // Cocoa calls. Stack added to suppressions_mac.txt. |
Scott Hess - ex-Googler
2009/10/26 19:45:21
Just checking - does this comment now apply to -se
| |
954 [content setNeedsDisplay:YES]; | 943 [content setAutoresizesSubviews:YES]; |
Scott Hess - ex-Googler
2009/10/26 19:45:21
Previously this line was way down the list. The c
| |
955 [window_ orderOut:self]; | 944 [dstWindow setContentView:content]; |
956 } else { | 945 [window setWindowController:nil]; |
957 NSView* content = [fullscreen_window_ contentView]; | 946 [window setDelegate:nil]; |
958 // Disable autoresizing of subviews while we move views around. This | 947 [self setWindow:dstWindow]; |
959 // prevents spurious renderer resizes. | 948 [dstWindow setWindowController:self]; |
960 [content setAutoresizesSubviews:NO]; | 949 [dstWindow setDelegate:self]; |
961 [content removeFromSuperview]; | 950 [self adjustUIForFullscreen:fullscreen]; |
962 [window_ setContentView:content]; | 951 [dstWindow makeKeyAndOrderFront:self]; |
963 [fullscreen_window_ setDelegate:nil]; | |
964 [fullscreen_window_ setWindowController:nil]; | |
965 [window_ setWindowController:self]; | |
966 [window_ setDelegate:self]; | |
967 [self setWindow:window_.get()]; | |
968 // This call triggers a relayout, so it needs to come after we move the | |
969 // contentview to the new window. | |
970 [self adjustUIForFullscreen:fullscreen]; | |
971 [content setAutoresizesSubviews:YES]; | |
972 [content setNeedsDisplay:YES]; | |
973 | 952 |
974 // With this call, valgrind yells at me about "Conditional jump or | 953 [window orderOut:self]; |
975 // move depends on uninitialised value(s)". The error happens in | |
976 // -[NSThemeFrame drawOverlayRect:]. I'm pretty convinced this is | |
977 // an Apple bug, but there is no visual impact. I have been | |
978 // unable to tickle it away with other window or view manipulation | |
979 // Cocoa calls. Stack added to suppressions_mac.txt. | |
980 [window_ makeKeyAndOrderFront:self]; | |
981 | |
982 [fullscreen_window_ close]; | |
983 fullscreen_window_.reset(nil); | |
984 } | |
985 } | 954 } |
986 | 955 |
987 - (BOOL)isFullscreen { | 956 - (BOOL)isFullscreen { |
988 return fullscreen_; | 957 return savedRegularWindow_ != nil; |
989 } | 958 } |
990 | 959 |
991 // Called by the bookmark bar to open a URL. | 960 // Called by the bookmark bar to open a URL. |
992 - (void)openBookmarkURL:(const GURL&)url | 961 - (void)openBookmarkURL:(const GURL&)url |
993 disposition:(WindowOpenDisposition)disposition { | 962 disposition:(WindowOpenDisposition)disposition { |
994 browser_->OpenURL(url, GURL(), disposition, PageTransition::AUTO_BOOKMARK); | 963 browser_->OpenURL(url, GURL(), disposition, PageTransition::AUTO_BOOKMARK); |
995 } | 964 } |
996 | 965 |
997 - (NSInteger)numberOfTabs { | 966 - (NSInteger)numberOfTabs { |
998 return browser_->tabstrip_model()->count(); | 967 return browser_->tabstrip_model()->count(); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1081 // Adjust top-left based on our knowledge of how the view looks. | 1050 // Adjust top-left based on our knowledge of how the view looks. |
1082 p.x -= 2; | 1051 p.x -= 2; |
1083 p.y += 7; | 1052 p.y += 7; |
1084 | 1053 |
1085 return p; | 1054 return p; |
1086 } | 1055 } |
1087 | 1056 |
1088 // Show the bookmark bubble (e.g. user just clicked on the STAR). | 1057 // Show the bookmark bubble (e.g. user just clicked on the STAR). |
1089 - (void)showBookmarkBubbleForURL:(const GURL&)url | 1058 - (void)showBookmarkBubbleForURL:(const GURL&)url |
1090 alreadyBookmarked:(BOOL)alreadyBookmarked { | 1059 alreadyBookmarked:(BOOL)alreadyBookmarked { |
1091 BookmarkModel* model = browser_->profile()->GetBookmarkModel(); | 1060 if (!bookmarkBubbleController_) { |
1092 const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url); | 1061 BookmarkModel* model = browser_->profile()->GetBookmarkModel(); |
1062 const BookmarkNode* node = model->GetMostRecentlyAddedNodeForURL(url); | |
1063 NSPoint topLeft = [self topLeftForBubble]; | |
1064 bookmarkBubbleController_ = | |
1065 [[BookmarkBubbleController alloc] initWithDelegate:self | |
1066 parentWindow:[self window] | |
1067 topLeftForBubble:topLeft | |
1068 model:model | |
1069 node:node | |
1070 alreadyBookmarked:alreadyBookmarked]; | |
1071 NSWindow* bookmarkBubbleWindow = [bookmarkBubbleController_ window]; | |
1072 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; | |
1073 [nc addObserver:self | |
1074 selector:@selector(bubbleWindowWillClose:) | |
1075 name:NSWindowWillCloseNotification | |
1076 object:bookmarkBubbleWindow]; | |
1077 [bookmarkBubbleController_ showWindow:self]; | |
1078 } | |
1079 } | |
1093 | 1080 |
1094 // Bring up the bubble. But clicking on STAR while the bubble is | 1081 // Notification sent when our bubble window is closed. |
1095 // open should make it go away. | 1082 - (void)bubbleWindowWillClose:(NSNotification*)notification { |
1096 if (bookmarkBubbleController_.get()) { | 1083 DCHECK([[notification object] windowController] == bookmarkBubbleController_); |
1097 [self doneWithBubbleController:bookmarkBubbleController_.get()]; | 1084 NSNotificationCenter* nc = [NSNotificationCenter defaultCenter]; |
1098 } else { | 1085 [nc removeObserver:self |
1099 bookmarkBubbleController_.reset([[BookmarkBubbleController alloc] | 1086 name:NSWindowWillCloseNotification |
1100 initWithDelegate:self | 1087 object:[bookmarkBubbleController_ window]]; |
1101 parentWindow:[self window] | 1088 bookmarkBubbleController_ = nil; |
1102 topLeftForBubble:[self topLeftForBubble] | |
1103 model:model | |
1104 node:node | |
1105 alreadyBookmarked:alreadyBookmarked]); | |
1106 [bookmarkBubbleController_ showWindow]; | |
1107 } | |
1108 } | 1089 } |
1109 | 1090 |
1110 // Implement BookmarkBubbleControllerDelegate | 1091 // Implement BookmarkBubbleControllerDelegate |
1111 - (void)editBookmarkNode:(const BookmarkNode*)node { | 1092 - (void)editBookmarkNode:(const BookmarkNode*)node { |
1112 // A BookmarkEditorController is a sheet that owns itself, and | 1093 // A BookmarkEditorController is a sheet that owns itself, and |
1113 // deallocates itself when closed. | 1094 // deallocates itself when closed. |
1114 [[[BookmarkEditorController alloc] | 1095 [[[BookmarkEditorController alloc] |
1115 initWithParentWindow:[self window] | 1096 initWithParentWindow:[self window] |
1116 profile:browser_->profile() | 1097 profile:browser_->profile() |
1117 parent:node->GetParent() | 1098 parent:node->GetParent() |
1118 node:node | 1099 node:node |
1119 configuration:BookmarkEditor::SHOW_TREE | 1100 configuration:BookmarkEditor::SHOW_TREE |
1120 handler:NULL] | 1101 handler:NULL] |
1121 runAsModalSheet]; | 1102 runAsModalSheet]; |
1122 } | 1103 } |
1123 | 1104 |
1124 // Implement BookmarkBubbleControllerDelegate | |
1125 - (void)doneWithBubbleController:(BookmarkBubbleController*)controller { | |
1126 bookmarkBubbleController_.reset(nil); | |
1127 } | |
1128 | 1105 |
1129 // Delegate method called when window is resized. | 1106 // Delegate method called when window is resized. |
1130 - (void)windowDidResize:(NSNotification*)notification { | 1107 - (void)windowDidResize:(NSNotification*)notification { |
1131 // Resize (and possibly move) the status bubble. Note that we may get called | 1108 // Resize (and possibly move) the status bubble. Note that we may get called |
1132 // when the status bubble does not exist. | 1109 // when the status bubble does not exist. |
1133 if (statusBubble_.get()) | 1110 if (statusBubble_) { |
1134 statusBubble_->UpdateSizeAndPosition(); | 1111 statusBubble_->UpdateSizeAndPosition(); |
1112 } | |
1135 } | 1113 } |
1136 | 1114 |
1137 @end | 1115 @end |
1138 | 1116 |
1139 @implementation BrowserWindowController (Private) | 1117 @implementation BrowserWindowController (Private) |
1140 | 1118 |
1141 // If the browser is in incognito mode, install the image view to decorate | 1119 // If the browser is in incognito mode, install the image view to decorate |
1142 // the window at the upper right. Use the same base y coordinate as the | 1120 // the window at the upper right. Use the same base y coordinate as the |
1143 // tab strip. | 1121 // tab strip. |
1144 - (void)installIncognitoBadge { | 1122 - (void)installIncognitoBadge { |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1269 } | 1247 } |
1270 | 1248 |
1271 // Private method to layout browser window subviews. Positions the toolbar and | 1249 // Private method to layout browser window subviews. Positions the toolbar and |
1272 // the infobar above the tab content area. Positions the download shelf below | 1250 // the infobar above the tab content area. Positions the download shelf below |
1273 // the tab content area. If the toolbar is not a child of the contentview, this | 1251 // the tab content area. If the toolbar is not a child of the contentview, this |
1274 // method will not leave room for it. If we are currently running in fullscreen | 1252 // method will not leave room for it. If we are currently running in fullscreen |
1275 // mode, or if the tabstrip is not a descendant of the window, this method fills | 1253 // mode, or if the tabstrip is not a descendant of the window, this method fills |
1276 // the entire content area. Otherwise, this method places the topmost view | 1254 // the entire content area. Otherwise, this method places the topmost view |
1277 // directly beneath the tabstrip. | 1255 // directly beneath the tabstrip. |
1278 - (void)layoutSubviews { | 1256 - (void)layoutSubviews { |
1279 NSView* contentView = fullscreen_ ? [fullscreen_window_ contentView] | 1257 NSWindow* window = [self window]; |
1280 : [[self window] contentView]; | 1258 NSView* contentView = [window contentView]; |
1281 NSRect contentFrame = [contentView frame]; | 1259 NSRect contentFrame = [contentView frame]; |
1282 int maxY = NSMaxY(contentFrame); | 1260 int maxY = NSMaxY(contentFrame); |
1283 int minY = NSMinY(contentFrame); | 1261 int minY = NSMinY(contentFrame); |
1284 if (!fullscreen_ && [self isNormalWindow]) { | 1262 if (![self isFullscreen] && [self isNormalWindow]) { |
1285 maxY = NSMinY([[self tabStripView] frame]); | 1263 maxY = NSMinY([[self tabStripView] frame]); |
1286 } | 1264 } |
1287 DCHECK_GE(maxY, minY); | 1265 DCHECK_GE(maxY, minY); |
1288 | 1266 |
1289 // Suppress title drawing for normal windows (popups use normal | 1267 // Suppress title drawing for normal windows (popups use normal |
1290 // window title bars). | 1268 // window title bars). |
1291 [window_ setShouldHideTitle:[self isNormalWindow]]; | 1269 if ([window respondsToSelector:@selector(setShouldHideTitle:)]) { |
1270 [(id)window setShouldHideTitle:[self isNormalWindow]]; | |
1271 } | |
1292 | 1272 |
1293 // Place the toolbar at the top of the reserved area, but only if we're not in | 1273 // Place the toolbar at the top of the reserved area, but only if we're not in |
1294 // fullscreen mode. | 1274 // fullscreen mode. |
1295 NSView* toolbarView = [toolbarController_ view]; | 1275 NSView* toolbarView = [toolbarController_ view]; |
1296 NSRect toolbarFrame = [toolbarView frame]; | 1276 NSRect toolbarFrame = [toolbarView frame]; |
1297 if (!fullscreen_) { | 1277 if (![self isFullscreen]) { |
1298 // The toolbar is present in the window, so we make room for it. | 1278 // The toolbar is present in the window, so we make room for it. |
1299 toolbarFrame.origin.x = 0; | 1279 toolbarFrame.origin.x = 0; |
1300 toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame); | 1280 toolbarFrame.origin.y = maxY - NSHeight(toolbarFrame); |
1301 toolbarFrame.size.width = NSWidth(contentFrame); | 1281 toolbarFrame.size.width = NSWidth(contentFrame); |
1302 maxY -= NSHeight(toolbarFrame); | 1282 maxY -= NSHeight(toolbarFrame); |
1303 } | 1283 } |
1304 [toolbarView setFrame:toolbarFrame]; | 1284 [toolbarView setFrame:toolbarFrame]; |
1305 | 1285 |
1306 if ([bookmarkBarController_ isAlwaysVisible]) { | 1286 if ([bookmarkBarController_ isAlwaysVisible]) { |
1307 NSView* bookmarkBarView = [bookmarkBarController_ view]; | 1287 NSView* bookmarkBarView = [bookmarkBarController_ view]; |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1531 if (frameOverlayInactiveImage) { | 1511 if (frameOverlayInactiveImage) { |
1532 [theme setValue:frameOverlayInactiveImage | 1512 [theme setValue:frameOverlayInactiveImage |
1533 forAttribute:@"overlay" | 1513 forAttribute:@"overlay" |
1534 style:GTMThemeStyleWindow | 1514 style:GTMThemeStyleWindow |
1535 state:GTMThemeStateInactiveWindow]; | 1515 state:GTMThemeStateInactiveWindow]; |
1536 } | 1516 } |
1537 | 1517 |
1538 return theme; | 1518 return theme; |
1539 } | 1519 } |
1540 @end | 1520 @end |
OLD | NEW |