OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #import "chrome/browser/cocoa/browser_window_controller.h" | 5 #import "chrome/browser/cocoa/browser_window_controller.h" |
6 | 6 |
7 #include <Carbon/Carbon.h> | 7 #include <Carbon/Carbon.h> |
8 | 8 |
9 #include "app/l10n_util_mac.h" | 9 #include "app/l10n_util_mac.h" |
10 #include "base/mac_util.h" | 10 #include "base/mac_util.h" |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
358 withObject:nil | 358 withObject:nil |
359 afterDelay:0]; | 359 afterDelay:0]; |
360 } | 360 } |
361 | 361 |
362 // Called when the window meets the criteria to be closed (ie, | 362 // Called when the window meets the criteria to be closed (ie, |
363 // |-windowShouldClose:| returns YES). We must be careful to preserve the | 363 // |-windowShouldClose:| returns YES). We must be careful to preserve the |
364 // semantics of BrowserWindow::Close() and not call the Browser's dtor directly | 364 // semantics of BrowserWindow::Close() and not call the Browser's dtor directly |
365 // from this method. | 365 // from this method. |
366 - (void)windowWillClose:(NSNotification*)notification { | 366 - (void)windowWillClose:(NSNotification*)notification { |
367 DCHECK_EQ([notification object], [self window]); | 367 DCHECK_EQ([notification object], [self window]); |
368 DCHECK(!browser_->tabstrip_model()->count()); | 368 DCHECK(!browser_->tabstrip_model()->HasNonPhantomTabs() || |
| 369 !browser_->tabstrip_model()->count()); |
369 [savedRegularWindow_ close]; | 370 [savedRegularWindow_ close]; |
370 // We delete statusBubble here because we need to kill off the dependency | 371 // We delete statusBubble here because we need to kill off the dependency |
371 // that its window has on our window before our window goes away. | 372 // that its window has on our window before our window goes away. |
372 delete statusBubble_; | 373 delete statusBubble_; |
373 statusBubble_ = NULL; | 374 statusBubble_ = NULL; |
374 // We can't actually use |-autorelease| here because there's an embedded | 375 // We can't actually use |-autorelease| here because there's an embedded |
375 // run loop in the |-performClose:| which contains its own autorelease pool. | 376 // run loop in the |-performClose:| which contains its own autorelease pool. |
376 // Instead call it after a zero-length delay, which gets us back to the main | 377 // Instead call it after a zero-length delay, which gets us back to the main |
377 // event loop. | 378 // event loop. |
378 [self performSelector:@selector(autorelease) | 379 [self performSelector:@selector(autorelease) |
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 // performed. | 1061 // performed. |
1061 NSRect destinationFrame = [view frame]; | 1062 NSRect destinationFrame = [view frame]; |
1062 NSPoint tabOrigin = destinationFrame.origin; | 1063 NSPoint tabOrigin = destinationFrame.origin; |
1063 tabOrigin = [[dragController tabStripView] convertPoint:tabOrigin | 1064 tabOrigin = [[dragController tabStripView] convertPoint:tabOrigin |
1064 toView:nil]; | 1065 toView:nil]; |
1065 tabOrigin = [[view window] convertBaseToScreen:tabOrigin]; | 1066 tabOrigin = [[view window] convertBaseToScreen:tabOrigin]; |
1066 tabOrigin = [[self window] convertScreenToBase:tabOrigin]; | 1067 tabOrigin = [[self window] convertScreenToBase:tabOrigin]; |
1067 tabOrigin = [[self tabStripView] convertPoint:tabOrigin fromView:nil]; | 1068 tabOrigin = [[self tabStripView] convertPoint:tabOrigin fromView:nil]; |
1068 destinationFrame.origin = tabOrigin; | 1069 destinationFrame.origin = tabOrigin; |
1069 | 1070 |
| 1071 // Before the tab is detached from its originating tab strip, store the |
| 1072 // pinned state so that it can be maintained between the windows. |
| 1073 bool isPinned = dragBWC->browser_->tabstrip_model()->IsTabPinned(index); |
| 1074 |
1070 // Now that we have enough information about the tab, we can remove it from | 1075 // Now that we have enough information about the tab, we can remove it from |
1071 // the dragging window. We need to do this *before* we add it to the new | 1076 // the dragging window. We need to do this *before* we add it to the new |
1072 // window as this will remove the TabContents' delegate. | 1077 // window as this will remove the TabContents' delegate. |
1073 [dragController detachTabView:view]; | 1078 [dragController detachTabView:view]; |
1074 | 1079 |
1075 // Deposit it into our model at the appropriate location (it already knows | 1080 // Deposit it into our model at the appropriate location (it already knows |
1076 // where it should go from tracking the drag). Doing this sets the tab's | 1081 // where it should go from tracking the drag). Doing this sets the tab's |
1077 // delegate to be the Browser. | 1082 // delegate to be the Browser. |
1078 [tabStripController_ dropTabContents:contents withFrame:destinationFrame]; | 1083 [tabStripController_ dropTabContents:contents |
| 1084 withFrame:destinationFrame |
| 1085 asPinnedTab:isPinned]; |
1079 } else { | 1086 } else { |
1080 // Moving within a window. | 1087 // Moving within a window. |
1081 int index = [tabStripController_ modelIndexForTabView:view]; | 1088 int index = [tabStripController_ modelIndexForTabView:view]; |
1082 [tabStripController_ moveTabFromIndex:index]; | 1089 [tabStripController_ moveTabFromIndex:index]; |
1083 } | 1090 } |
1084 | 1091 |
1085 // Remove the placeholder since the drag is now complete. | 1092 // Remove the placeholder since the drag is now complete. |
1086 [self removePlaceholder]; | 1093 [self removePlaceholder]; |
1087 } | 1094 } |
1088 | 1095 |
(...skipping 22 matching lines...) Expand all Loading... |
1111 } | 1118 } |
1112 | 1119 |
1113 - (void)layoutTabs { | 1120 - (void)layoutTabs { |
1114 [tabStripController_ layoutTabs]; | 1121 [tabStripController_ layoutTabs]; |
1115 } | 1122 } |
1116 | 1123 |
1117 - (TabWindowController*)detachTabToNewWindow:(TabView*)tabView { | 1124 - (TabWindowController*)detachTabToNewWindow:(TabView*)tabView { |
1118 // Disable screen updates so that this appears as a single visual change. | 1125 // Disable screen updates so that this appears as a single visual change. |
1119 base::ScopedNSDisableScreenUpdates disabler; | 1126 base::ScopedNSDisableScreenUpdates disabler; |
1120 | 1127 |
1121 // Fetch the tab contents for the tab being dragged | 1128 // Fetch the tab contents for the tab being dragged. |
1122 int index = [tabStripController_ modelIndexForTabView:tabView]; | 1129 int index = [tabStripController_ modelIndexForTabView:tabView]; |
1123 TabContents* contents = browser_->tabstrip_model()->GetTabContentsAt(index); | 1130 TabContents* contents = browser_->tabstrip_model()->GetTabContentsAt(index); |
1124 | 1131 |
1125 // Set the window size. Need to do this before we detach the tab so it's | 1132 // Set the window size. Need to do this before we detach the tab so it's |
1126 // still in the window. We have to flip the coordinates as that's what | 1133 // still in the window. We have to flip the coordinates as that's what |
1127 // is expected by the Browser code. | 1134 // is expected by the Browser code. |
1128 NSWindow* sourceWindow = [tabView window]; | 1135 NSWindow* sourceWindow = [tabView window]; |
1129 NSRect windowRect = [sourceWindow frame]; | 1136 NSRect windowRect = [sourceWindow frame]; |
1130 NSScreen* screen = [sourceWindow screen]; | 1137 NSScreen* screen = [sourceWindow screen]; |
1131 windowRect.origin.y = | 1138 windowRect.origin.y = |
1132 [screen frame].size.height - windowRect.size.height - | 1139 [screen frame].size.height - windowRect.size.height - |
1133 windowRect.origin.y; | 1140 windowRect.origin.y; |
1134 gfx::Rect browserRect(windowRect.origin.x, windowRect.origin.y, | 1141 gfx::Rect browserRect(windowRect.origin.x, windowRect.origin.y, |
1135 windowRect.size.width, windowRect.size.height); | 1142 windowRect.size.width, windowRect.size.height); |
1136 | 1143 |
1137 NSRect tabRect = [tabView frame]; | 1144 NSRect tabRect = [tabView frame]; |
1138 | 1145 |
| 1146 // Before detaching the tab, store the pinned state. |
| 1147 bool isPinned = browser_->tabstrip_model()->IsTabPinned(index); |
| 1148 |
1139 // Detach it from the source window, which just updates the model without | 1149 // Detach it from the source window, which just updates the model without |
1140 // deleting the tab contents. This needs to come before creating the new | 1150 // deleting the tab contents. This needs to come before creating the new |
1141 // Browser because it clears the TabContents' delegate, which gets hooked | 1151 // Browser because it clears the TabContents' delegate, which gets hooked |
1142 // up during creation of the new window. | 1152 // up during creation of the new window. |
1143 browser_->tabstrip_model()->DetachTabContentsAt(index); | 1153 browser_->tabstrip_model()->DetachTabContentsAt(index); |
1144 | 1154 |
1145 // Create the new window with a single tab in its model, the one being | 1155 // Create the new window with a single tab in its model, the one being |
1146 // dragged. | 1156 // dragged. |
1147 DockInfo dockInfo; | 1157 DockInfo dockInfo; |
1148 Browser* newBrowser = | 1158 Browser* newBrowser = |
1149 browser_->tabstrip_model()->TearOffTabContents(contents, | 1159 browser_->tabstrip_model()->TearOffTabContents(contents, |
1150 browserRect, | 1160 browserRect, |
1151 dockInfo); | 1161 dockInfo); |
1152 | 1162 |
| 1163 // Propagate the tab pinned state of the new tab (which is the only tab in |
| 1164 // this new window). |
| 1165 newBrowser->tabstrip_model()->SetTabPinned(0, isPinned); |
| 1166 |
1153 // Get the new controller by asking the new window for its delegate. | 1167 // Get the new controller by asking the new window for its delegate. |
1154 BrowserWindowController* controller = | 1168 BrowserWindowController* controller = |
1155 reinterpret_cast<BrowserWindowController*>( | 1169 reinterpret_cast<BrowserWindowController*>( |
1156 [newBrowser->window()->GetNativeHandle() delegate]); | 1170 [newBrowser->window()->GetNativeHandle() delegate]); |
1157 DCHECK(controller && [controller isKindOfClass:[TabWindowController class]]); | 1171 DCHECK(controller && [controller isKindOfClass:[TabWindowController class]]); |
1158 | 1172 |
1159 // Force the added tab to the right size (remove stretching.) | 1173 // Force the added tab to the right size (remove stretching.) |
1160 tabRect.size.height = [TabStripController defaultTabHeight]; | 1174 tabRect.size.height = [TabStripController defaultTabHeight]; |
1161 | 1175 |
1162 // And make sure we use the correct frame in the new view. | 1176 // And make sure we use the correct frame in the new view. |
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1833 | 1847 |
1834 - (BOOL)supportsBookmarkBar { | 1848 - (BOOL)supportsBookmarkBar { |
1835 return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR]; | 1849 return [self supportsWindowFeature:Browser::FEATURE_BOOKMARKBAR]; |
1836 } | 1850 } |
1837 | 1851 |
1838 - (BOOL)isNormalWindow { | 1852 - (BOOL)isNormalWindow { |
1839 return browser_->type() == Browser::TYPE_NORMAL; | 1853 return browser_->type() == Browser::TYPE_NORMAL; |
1840 } | 1854 } |
1841 | 1855 |
1842 @end // @implementation BrowserWindowController(WindowType) | 1856 @end // @implementation BrowserWindowController(WindowType) |
OLD | NEW |