Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(29)

Side by Side Diff: chrome/browser/cocoa/browser_window_controller.mm

Issue 159780: Add support for constrained windows on os x, based on Avi's GTMWindowSheetController. (Closed)
Patch Set: Merge with ToT Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 // Note: These functions are private, use -[NSObject respondsToSelector:] 55 // Note: These functions are private, use -[NSObject respondsToSelector:]
56 // before calling them. 56 // before calling them.
57 57
58 - (void)setAutorecalculatesContentBorderThickness:(BOOL)b 58 - (void)setAutorecalculatesContentBorderThickness:(BOOL)b
59 forEdge:(NSRectEdge)e; 59 forEdge:(NSRectEdge)e;
60 - (void)setContentBorderThickness:(CGFloat)b forEdge:(NSRectEdge)e; 60 - (void)setContentBorderThickness:(CGFloat)b forEdge:(NSRectEdge)e;
61 61
62 - (void)setBottomCornerRounded:(BOOL)rounded; 62 - (void)setBottomCornerRounded:(BOOL)rounded;
63 63
64 - (NSRect)_growBoxRect; 64 - (NSRect)_growBoxRect;
65
65 @end 66 @end
66 67
67 68
68 @interface BrowserWindowController(Private) 69 @interface BrowserWindowController(Private)
69 70
70 // Leopard's gradient heuristic gets confused by our tabs and makes the title 71 // Leopard's gradient heuristic gets confused by our tabs and makes the title
71 // gradient jump when creating a tab that is less than a tab width from the 72 // gradient jump when creating a tab that is less than a tab width from the
72 // right side of the screen. This function disables Leopard's gradient 73 // right side of the screen. This function disables Leopard's gradient
73 // heuristic. 74 // heuristic.
74 - (void)fixWindowGradient; 75 - (void)fixWindowGradient;
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 } 232 }
232 233
233 - (void)destroyBrowser { 234 - (void)destroyBrowser {
234 [NSApp removeWindowsItem:[self window]]; 235 [NSApp removeWindowsItem:[self window]];
235 236
236 // We need the window to go away now. 237 // We need the window to go away now.
237 [self autorelease]; 238 [self autorelease];
238 } 239 }
239 240
240 // Called when the window meets the criteria to be closed (ie, 241 // Called when the window meets the criteria to be closed (ie,
241 // |-windowShoudlClose:| returns YES). We must be careful to preserve the 242 // |-windowShouldClose:| returns YES). We must be careful to preserve the
242 // semantics of BrowserWindow::Close() and not call the Browser's dtor directly 243 // semantics of BrowserWindow::Close() and not call the Browser's dtor directly
243 // from this method. 244 // from this method.
244 - (void)windowWillClose:(NSNotification*)notification { 245 - (void)windowWillClose:(NSNotification*)notification {
245 DCHECK(!browser_->tabstrip_model()->count()); 246 DCHECK(!browser_->tabstrip_model()->count());
246 247
247 // We can't actually use |-autorelease| here because there's an embedded 248 // We can't actually use |-autorelease| here because there's an embedded
248 // run loop in the |-performClose:| which contains its own autorelease pool. 249 // run loop in the |-performClose:| which contains its own autorelease pool.
249 // Instead we use call it after a zero-length delay, which gets us back 250 // Instead we use call it after a zero-length delay, which gets us back
250 // to the main event loop. 251 // to the main event loop.
251 [self performSelector:@selector(autorelease) 252 [self performSelector:@selector(autorelease)
252 withObject:nil 253 withObject:nil
253 afterDelay:0]; 254 afterDelay:0];
254 } 255 }
255 256
257 // Checks if there are any tabs with sheets open, and if so, raises one of
258 // the tabs with a sheet and returns NO.
259 - (BOOL)shouldCloseWithOpenPerTabSheets {
260 // This is O(n_open_sheets * n_tabs), i.e. O(n**2). Since people probably
261 // won't have 100 tabs open, and not every tab will have a sheet, this is ok.
262 for (NSView* view in
263 [[tabStripController_ sheetController] viewsWithAttachedSheets]) {
264 [tabStripController_ gtm_systemRequestsVisibilityForView:view];
265 return NO;
266 }
267
268 return YES;
269 }
270
271 - (void)attachConstrainedWindow:(ConstrainedWindowMac*)window {
272 [tabStripController_ attachConstrainedWindow:window];
273 }
274
275 - (void)removeConstrainedWindow:(ConstrainedWindowMac*)window {
276 [tabStripController_ removeConstrainedWindow:window];
277 }
278
256 // Called when the user wants to close a window or from the shutdown process. 279 // Called when the user wants to close a window or from the shutdown process.
257 // The Browser object is in control of whether or not we're allowed to close. It 280 // The Browser object is in control of whether or not we're allowed to close. It
258 // may defer closing due to several states, such as onUnload handlers needing to 281 // may defer closing due to several states, such as onUnload handlers needing to
259 // be fired. If closing is deferred, the Browser will handle the processing 282 // be fired. If closing is deferred, the Browser will handle the processing
260 // required to get us to the closing state and (by watching for all the tabs 283 // required to get us to the closing state and (by watching for all the tabs
261 // going away) will again call to close the window when it's finally ready. 284 // going away) will again call to close the window when it's finally ready.
262 - (BOOL)windowShouldClose:(id)sender { 285 - (BOOL)windowShouldClose:(id)sender {
286 // Do not close a window with open sheets, as required by
287 // GTMWindowSheetController.
288 if (![self shouldCloseWithOpenPerTabSheets])
289 return NO;
290
263 // Disable updates while closing all tabs to avoid flickering. 291 // Disable updates while closing all tabs to avoid flickering.
264 base::ScopedNSDisableScreenUpdates disabler; 292 base::ScopedNSDisableScreenUpdates disabler;
265 // Give beforeunload handlers the chance to cancel the close before we hide 293 // Give beforeunload handlers the chance to cancel the close before we hide
266 // the window below. 294 // the window below.
267 if (!browser_->ShouldCloseWindow()) 295 if (!browser_->ShouldCloseWindow())
268 return NO; 296 return NO;
269 297
270 // saveWindowPositionIfNeeded: only works if we are the last active 298 // saveWindowPositionIfNeeded: only works if we are the last active
271 // window, but orderOut: ends up activating another window, so we 299 // window, but orderOut: ends up activating another window, so we
272 // have to save the window position before we call orderOut:. 300 // have to save the window position before we call orderOut:.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 return; 441 return;
414 } 442 }
415 const std::wstring encoding = current_tab->encoding(); 443 const std::wstring encoding = current_tab->encoding();
416 444
417 bool toggled = encoding_controller.IsItemChecked(profile, encoding, tag); 445 bool toggled = encoding_controller.IsItemChecked(profile, encoding, tag);
418 NSInteger oldState = [item state]; 446 NSInteger oldState = [item state];
419 NSInteger newState = toggled ? NSOnState : NSOffState; 447 NSInteger newState = toggled ? NSOnState : NSOffState;
420 if (oldState != newState) 448 if (oldState != newState)
421 [item setState:newState]; 449 [item setState:newState];
422 } 450 }
451 }
423 452
453 - (BOOL)supportsFullscreen {
454 // TODO(avi, thakis): GTMWindowSheetController has no api to move
455 // tabsheets between windows. Until then, we have to prevent having to
456 // move a tabsheet between windows, e.g. no fullscreen toggling
457 NSArray* a = [[tabStripController_ sheetController] viewsWithAttachedSheets];
458 return [a count] == 0;
424 } 459 }
425 460
426 // Called to validate menu and toolbar items when this window is key. All the 461 // Called to validate menu and toolbar items when this window is key. All the
427 // items we care about have been set with the |commandDispatch:| action and 462 // items we care about have been set with the |commandDispatch:| action and
428 // a target of FirstResponder in IB. If it's not one of those, let it 463 // a target of FirstResponder in IB. If it's not one of those, let it
429 // continue up the responder chain to be handled elsewhere. We pull out the 464 // continue up the responder chain to be handled elsewhere. We pull out the
430 // tag as the cross-platform constant to differentiate and dispatch the 465 // tag as the cross-platform constant to differentiate and dispatch the
431 // various commands. 466 // various commands.
432 // NOTE: we might have to handle state for app-wide menu items, 467 // NOTE: we might have to handle state for app-wide menu items,
433 // although we could cheat and directly ask the app controller if our 468 // although we could cheat and directly ask the app controller if our
(...skipping 11 matching lines...) Expand all
445 case IDC_CLOSE_TAB: 480 case IDC_CLOSE_TAB:
446 // Disable "close tab" if we're not the key window or if there's only 481 // Disable "close tab" if we're not the key window or if there's only
447 // one tab. 482 // one tab.
448 enable &= [self numberOfTabs] > 1 && [[self window] isKeyWindow]; 483 enable &= [self numberOfTabs] > 1 && [[self window] isKeyWindow];
449 break; 484 break;
450 case IDC_RESTORE_TAB: 485 case IDC_RESTORE_TAB:
451 // We have to ask the Browser manually if we can restore. The 486 // We have to ask the Browser manually if we can restore. The
452 // command updater doesn't know. 487 // command updater doesn't know.
453 enable &= browser_->CanRestoreTab(); 488 enable &= browser_->CanRestoreTab();
454 break; 489 break;
490 case IDC_FULLSCREEN:
491 enable &= [self supportsFullscreen];
492 break;
455 } 493 }
456 494
457 // If the item is toggleable, find its toggle state and 495 // If the item is toggleable, find its toggle state and
458 // try to update it. This is a little awkward, but the alternative is 496 // try to update it. This is a little awkward, but the alternative is
459 // to check after a commandDispatch, which seems worse. 497 // to check after a commandDispatch, which seems worse.
460 [self updateToggleStateWithTag:tag forItem:item]; 498 [self updateToggleStateWithTag:tag forItem:item];
461 } 499 }
462 } 500 }
463 return enable; 501 return enable;
464 } 502 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 - (float)verticalOffsetForStatusBubble { 538 - (float)verticalOffsetForStatusBubble {
501 float offset = 0.0; 539 float offset = 0.0;
502 540
503 // Don't create a download shelf if there isn't one. 541 // Don't create a download shelf if there isn't one.
504 if (downloadShelfController_.get() && [[self downloadShelf] isVisible]) 542 if (downloadShelfController_.get() && [[self downloadShelf] isVisible])
505 offset += [[self downloadShelf] height]; 543 offset += [[self downloadShelf] height];
506 544
507 return offset; 545 return offset;
508 } 546 }
509 547
548 - (GTMWindowSheetController*)sheetController {
549 return [tabStripController_ sheetController];
550 }
551
510 - (LocationBar*)locationBar { 552 - (LocationBar*)locationBar {
511 return [toolbarController_ locationBar]; 553 return [toolbarController_ locationBar];
512 } 554 }
513 555
514 - (StatusBubble*)statusBubble { 556 - (StatusBubble*)statusBubble {
515 return statusBubble_.get(); 557 return statusBubble_.get();
516 } 558 }
517 559
518 - (void)updateToolbarWithContents:(TabContents*)tab 560 - (void)updateToolbarWithContents:(TabContents*)tab
519 shouldRestoreState:(BOOL)shouldRestore { 561 shouldRestoreState:(BOOL)shouldRestore {
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
777 // Force a relayout. 819 // Force a relayout.
778 [self layoutSubviews]; 820 [self layoutSubviews];
779 } 821 }
780 822
781 - (NSWindow*)fullscreenWindow { 823 - (NSWindow*)fullscreenWindow {
782 return [[[FullscreenWindow alloc] initForScreen:[[self window] screen]] 824 return [[[FullscreenWindow alloc] initForScreen:[[self window] screen]]
783 autorelease]; 825 autorelease];
784 } 826 }
785 827
786 - (void)setFullscreen:(BOOL)fullscreen { 828 - (void)setFullscreen:(BOOL)fullscreen {
829 if (![self supportsFullscreen])
830 return;
831
787 fullscreen_ = fullscreen; 832 fullscreen_ = fullscreen;
788 if (fullscreen) { 833 if (fullscreen) {
789 // Move content to a new fullscreen window 834 // Move content to a new fullscreen window
790 NSView* content = [[self window] contentView]; 835 NSView* content = [[self window] contentView];
791 fullscreen_window_.reset([[self fullscreenWindow] retain]); 836 fullscreen_window_.reset([[self fullscreenWindow] retain]);
792 [content removeFromSuperview]; 837 [content removeFromSuperview];
793 [fullscreen_window_ setContentView:content]; 838 [fullscreen_window_ setContentView:content];
794 [self setWindow:fullscreen_window_.get()]; 839 [self setWindow:fullscreen_window_.get()];
795 // Minimize our UI. This call triggers a relayout, so it needs to come 840 // Minimize our UI. This call triggers a relayout, so it needs to come
796 // after we move the contentview to the new window. 841 // after we move the contentview to the new window.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 - (void)selectTabWithContents:(TabContents*)newContents 899 - (void)selectTabWithContents:(TabContents*)newContents
855 previousContents:(TabContents*)oldContents 900 previousContents:(TabContents*)oldContents
856 atIndex:(NSInteger)index 901 atIndex:(NSInteger)index
857 userGesture:(bool)wasUserGesture { 902 userGesture:(bool)wasUserGesture {
858 DCHECK(oldContents != newContents); 903 DCHECK(oldContents != newContents);
859 904
860 // Update various elements that are interested in knowing the current 905 // Update various elements that are interested in knowing the current
861 // TabContents. 906 // TabContents.
862 #if 0 907 #if 0
863 // TODO(pinkerton):Update as more things become window-specific 908 // TODO(pinkerton):Update as more things become window-specific
864 contents_container_->SetTabContents(new_contents); 909 contents_container_->SetTabContents(newContents);
865 #endif 910 #endif
866 911
867 // Update all the UI bits. 912 // Update all the UI bits.
868 windowShim_->UpdateTitleBar(); 913 windowShim_->UpdateTitleBar();
869 #if 0 914 #if 0
870 // TODO(pinkerton):Update as more things become window-specific 915 // TODO(pinkerton):Update as more things become window-specific
871 toolbar_->SetProfile(new_contents->profile()); 916 toolbar_->SetProfile(newContents->profile());
872 UpdateToolbar(new_contents, true); 917 UpdateToolbar(newContents, true);
873 UpdateUIForContents(new_contents); 918 UpdateUIForContents(newContents);
874 #endif 919 #endif
875 } 920 }
876 921
877 - (void)tabChangedWithContents:(TabContents*)contents 922 - (void)tabChangedWithContents:(TabContents*)contents
878 atIndex:(NSInteger)index 923 atIndex:(NSInteger)index
879 loadingOnly:(BOOL)loading { 924 loadingOnly:(BOOL)loading {
880 // Update titles if this is the currently selected tab. 925 if (index == browser_->tabstrip_model()->selected_index()) {
881 if (index == browser_->tabstrip_model()->selected_index()) 926 // Update titles if this is the currently selected tab.
882 windowShim_->UpdateTitleBar(); 927 windowShim_->UpdateTitleBar();
928 }
883 } 929 }
884 930
885 - (void)userChangedTheme { 931 - (void)userChangedTheme {
886 [self setTheme]; 932 [self setTheme];
887 [self applyTheme]; 933 [self applyTheme];
888 934
889 [tabStripController_ userChangedTheme]; 935 [tabStripController_ userChangedTheme];
890 } 936 }
891 937
892 - (GTMTheme *)gtm_themeForWindow:(NSWindow*)window { 938 - (GTMTheme *)gtm_themeForWindow:(NSWindow*)window {
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 NSColor* toolbarButtonBorderColor = toolbarButtonIconColor; 1237 NSColor* toolbarButtonBorderColor = toolbarButtonIconColor;
1192 [theme setValue:toolbarButtonBorderColor 1238 [theme setValue:toolbarButtonBorderColor
1193 forAttribute:@"borderColor" 1239 forAttribute:@"borderColor"
1194 style:GTMThemeStyleToolBar 1240 style:GTMThemeStyleToolBar
1195 state:YES]; 1241 state:YES];
1196 1242
1197 return theme; 1243 return theme;
1198 } 1244 }
1199 @end 1245 @end
1200 1246
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698