Chromium Code Reviews| 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 |