| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/cocoa/tabs/tab_strip_controller.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" |
| 6 | 6 |
| 7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #include <cmath> | 9 #include <cmath> |
| 10 #include <limits> | 10 #include <limits> |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 bool animate_; | 143 bool animate_; |
| 144 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); | 144 DISALLOW_COPY_AND_ASSIGN(ScopedNSAnimationContextGroup); |
| 145 }; | 145 }; |
| 146 | 146 |
| 147 } // namespace | 147 } // namespace |
| 148 | 148 |
| 149 @interface TabStripController (Private) | 149 @interface TabStripController (Private) |
| 150 - (void)addSubviewToPermanentList:(NSView*)aView; | 150 - (void)addSubviewToPermanentList:(NSView*)aView; |
| 151 - (void)regenerateSubviewList; | 151 - (void)regenerateSubviewList; |
| 152 - (NSInteger)indexForContentsView:(NSView*)view; | 152 - (NSInteger)indexForContentsView:(NSView*)view; |
| 153 - (void)updateFaviconForContents:(TabContents*)contents | 153 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents; |
| 154 - (void)updateFaviconForContents:(content::WebContents*)contents |
| 154 atIndex:(NSInteger)modelIndex; | 155 atIndex:(NSInteger)modelIndex; |
| 155 - (void)layoutTabsWithAnimation:(BOOL)animate | 156 - (void)layoutTabsWithAnimation:(BOOL)animate |
| 156 regenerateSubviews:(BOOL)doUpdate; | 157 regenerateSubviews:(BOOL)doUpdate; |
| 157 - (void)animationDidStopForController:(TabController*)controller | 158 - (void)animationDidStopForController:(TabController*)controller |
| 158 finished:(BOOL)finished; | 159 finished:(BOOL)finished; |
| 159 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 160 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
| 160 - (void)clickNewTabButton:(id)sender; | 161 - (void)clickNewTabButton:(id)sender; |
| 161 - (NSInteger)numberOfOpenTabs; | 162 - (NSInteger)numberOfOpenTabs; |
| 162 - (NSInteger)numberOfOpenMiniTabs; | 163 - (NSInteger)numberOfOpenMiniTabs; |
| 163 - (NSInteger)numberOfOpenNonMiniTabs; | 164 - (NSInteger)numberOfOpenNonMiniTabs; |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 453 // Set accessibility descriptions. http://openradar.appspot.com/7496255 | 454 // Set accessibility descriptions. http://openradar.appspot.com/7496255 |
| 454 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); | 455 NSString* description = l10n_util::GetNSStringWithFixup(IDS_ACCNAME_NEWTAB); |
| 455 [[newTabButton_ cell] | 456 [[newTabButton_ cell] |
| 456 accessibilitySetOverrideValue:description | 457 accessibilitySetOverrideValue:description |
| 457 forAttribute:NSAccessibilityDescriptionAttribute]; | 458 forAttribute:NSAccessibilityDescriptionAttribute]; |
| 458 | 459 |
| 459 // Controller may have been (re-)created by switching layout modes, which | 460 // Controller may have been (re-)created by switching layout modes, which |
| 460 // means the tab model is already fully formed with tabs. Need to walk the | 461 // means the tab model is already fully formed with tabs. Need to walk the |
| 461 // list and create the UI for each. | 462 // list and create the UI for each. |
| 462 const int existingTabCount = tabStripModel_->count(); | 463 const int existingTabCount = tabStripModel_->count(); |
| 463 const TabContents* selection = tabStripModel_->GetActiveTabContents(); | 464 const content::WebContents* selection = |
| 465 tabStripModel_->GetActiveWebContents(); |
| 464 for (int i = 0; i < existingTabCount; ++i) { | 466 for (int i = 0; i < existingTabCount; ++i) { |
| 465 TabContents* currentContents = tabStripModel_->GetTabContentsAt(i); | 467 content::WebContents* currentContents = |
| 468 tabStripModel_->GetWebContentsAt(i); |
| 466 [self insertTabWithContents:currentContents | 469 [self insertTabWithContents:currentContents |
| 467 atIndex:i | 470 atIndex:i |
| 468 inForeground:NO]; | 471 inForeground:NO]; |
| 469 if (selection == currentContents) { | 472 if (selection == currentContents) { |
| 470 // Must manually force a selection since the model won't send | 473 // Must manually force a selection since the model won't send |
| 471 // selection messages in this scenario. | 474 // selection messages in this scenario. |
| 472 [self activateTabWithContents:currentContents | 475 [self activateTabWithContents:currentContents |
| 473 previousContents:NULL | 476 previousContents:NULL |
| 474 atIndex:i | 477 atIndex:i |
| 475 userGesture:NO]; | 478 userGesture:NO]; |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 if (contents) | 1163 if (contents) |
| 1161 titleString = base::SysUTF16ToNSString(contents->GetTitle()); | 1164 titleString = base::SysUTF16ToNSString(contents->GetTitle()); |
| 1162 if (![titleString length]) { | 1165 if (![titleString length]) { |
| 1163 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); | 1166 titleString = l10n_util::GetNSString(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); |
| 1164 } | 1167 } |
| 1165 [tab setTitle:titleString]; | 1168 [tab setTitle:titleString]; |
| 1166 } | 1169 } |
| 1167 | 1170 |
| 1168 // Called when a notification is received from the model to insert a new tab | 1171 // Called when a notification is received from the model to insert a new tab |
| 1169 // at |modelIndex|. | 1172 // at |modelIndex|. |
| 1170 - (void)insertTabWithContents:(TabContents*)contents | 1173 - (void)insertTabWithContents:(content::WebContents*)contents |
| 1171 atIndex:(NSInteger)modelIndex | 1174 atIndex:(NSInteger)modelIndex |
| 1172 inForeground:(bool)inForeground { | 1175 inForeground:(bool)inForeground { |
| 1173 DCHECK(contents); | 1176 DCHECK(contents); |
| 1174 DCHECK(modelIndex == TabStripModel::kNoTab || | 1177 DCHECK(modelIndex == TabStripModel::kNoTab || |
| 1175 tabStripModel_->ContainsIndex(modelIndex)); | 1178 tabStripModel_->ContainsIndex(modelIndex)); |
| 1176 | 1179 |
| 1177 // Cancel any pending tab transition. | 1180 // Cancel any pending tab transition. |
| 1178 hoverTabSelector_->CancelTabTransition(); | 1181 hoverTabSelector_->CancelTabTransition(); |
| 1179 | 1182 |
| 1180 // Take closing tabs into account. | 1183 // Take closing tabs into account. |
| 1181 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1184 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1182 | 1185 |
| 1183 // Make a new tab. Load the contents of this tab from the nib and associate | 1186 // Make a new tab. Load the contents of this tab from the nib and associate |
| 1184 // the new controller with |contents| so it can be looked up later. | 1187 // the new controller with |contents| so it can be looked up later. |
| 1185 scoped_nsobject<TabContentsController> contentsController( | 1188 scoped_nsobject<TabContentsController> contentsController( |
| 1186 [[TabContentsController alloc] | 1189 [[TabContentsController alloc] initWithContents:contents]); |
| 1187 initWithContents:contents->web_contents()]); | |
| 1188 [tabContentsArray_ insertObject:contentsController atIndex:index]; | 1190 [tabContentsArray_ insertObject:contentsController atIndex:index]; |
| 1189 | 1191 |
| 1190 // Make a new tab and add it to the strip. Keep track of its controller. | 1192 // Make a new tab and add it to the strip. Keep track of its controller. |
| 1191 TabController* newController = [self newTab]; | 1193 TabController* newController = [self newTab]; |
| 1192 [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1194 [newController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
| 1193 [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1195 [newController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
| 1194 [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1196 [newController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
| 1195 [newController setUrl:contents->web_contents()->GetURL()]; | 1197 [newController setUrl:contents->GetURL()]; |
| 1196 [tabArray_ insertObject:newController atIndex:index]; | 1198 [tabArray_ insertObject:newController atIndex:index]; |
| 1197 NSView* newView = [newController view]; | 1199 NSView* newView = [newController view]; |
| 1198 | 1200 |
| 1199 // Set the originating frame to just below the strip so that it animates | 1201 // Set the originating frame to just below the strip so that it animates |
| 1200 // upwards as it's being initially layed out. Oddly, this works while doing | 1202 // upwards as it's being initially layed out. Oddly, this works while doing |
| 1201 // something similar in |-layoutTabs| confuses the window server. | 1203 // something similar in |-layoutTabs| confuses the window server. |
| 1202 [newView setFrame:NSOffsetRect([newView frame], | 1204 [newView setFrame:NSOffsetRect([newView frame], |
| 1203 0, -[[self class] defaultTabHeight])]; | 1205 0, -[[self class] defaultTabHeight])]; |
| 1204 | 1206 |
| 1205 [self setTabTitle:newController withContents:contents->web_contents()]; | 1207 [self setTabTitle:newController withContents:contents]; |
| 1206 | 1208 |
| 1207 // If a tab is being inserted, we can again use the entire tab strip width | 1209 // If a tab is being inserted, we can again use the entire tab strip width |
| 1208 // for layout. | 1210 // for layout. |
| 1209 availableResizeWidth_ = kUseFullAvailableWidth; | 1211 availableResizeWidth_ = kUseFullAvailableWidth; |
| 1210 | 1212 |
| 1211 [delegate_ onInsertTabWithContents:contents->web_contents()]; | 1213 [delegate_ onInsertTabWithContents:contents]; |
| 1212 | 1214 |
| 1213 // We don't need to call |-layoutTabs| if the tab will be in the foreground | 1215 // We don't need to call |-layoutTabs| if the tab will be in the foreground |
| 1214 // because it will get called when the new tab is selected by the tab model. | 1216 // because it will get called when the new tab is selected by the tab model. |
| 1215 // Whenever |-layoutTabs| is called, it'll also add the new subview. | 1217 // Whenever |-layoutTabs| is called, it'll also add the new subview. |
| 1216 if (!inForeground) { | 1218 if (!inForeground) { |
| 1217 [self layoutTabs]; | 1219 [self layoutTabs]; |
| 1218 } | 1220 } |
| 1219 | 1221 |
| 1220 // During normal loading, we won't yet have a favicon and we'll get | 1222 // During normal loading, we won't yet have a favicon and we'll get |
| 1221 // subsequent state change notifications to show the throbber, but when we're | 1223 // subsequent state change notifications to show the throbber, but when we're |
| 1222 // dragging a tab out into a new window, we have to put the tab's favicon | 1224 // dragging a tab out into a new window, we have to put the tab's favicon |
| 1223 // into the right state up front as we won't be told to do it from anywhere | 1225 // into the right state up front as we won't be told to do it from anywhere |
| 1224 // else. | 1226 // else. |
| 1225 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1227 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1226 } | 1228 } |
| 1227 | 1229 |
| 1228 // Called when a notification is received from the model to select a particular | 1230 // Called when a notification is received from the model to select a particular |
| 1229 // tab. Swaps in the toolbar and content area associated with |newContents|. | 1231 // tab. Swaps in the toolbar and content area associated with |newContents|. |
| 1230 - (void)activateTabWithContents:(TabContents*)newContents | 1232 - (void)activateTabWithContents:(content::WebContents*)newContents |
| 1231 previousContents:(TabContents*)oldContents | 1233 previousContents:(content::WebContents*)oldContents |
| 1232 atIndex:(NSInteger)modelIndex | 1234 atIndex:(NSInteger)modelIndex |
| 1233 userGesture:(bool)wasUserGesture { | 1235 userGesture:(bool)wasUserGesture { |
| 1234 // Take closing tabs into account. | 1236 // Take closing tabs into account. |
| 1235 NSInteger activeIndex = [self indexFromModelIndex:modelIndex]; | 1237 NSInteger activeIndex = [self indexFromModelIndex:modelIndex]; |
| 1236 | 1238 |
| 1237 if (oldContents) { | 1239 if (oldContents) { |
| 1238 int oldModelIndex = | 1240 int oldModelIndex = chrome::GetIndexOfTab(browser_, oldContents); |
| 1239 chrome::GetIndexOfTab(browser_, oldContents->web_contents()); | |
| 1240 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone. | 1241 if (oldModelIndex != -1) { // When closing a tab, the old tab may be gone. |
| 1241 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; | 1242 NSInteger oldIndex = [self indexFromModelIndex:oldModelIndex]; |
| 1242 TabContentsController* oldController = | 1243 TabContentsController* oldController = |
| 1243 [tabContentsArray_ objectAtIndex:oldIndex]; | 1244 [tabContentsArray_ objectAtIndex:oldIndex]; |
| 1244 [oldController willBecomeUnselectedTab]; | 1245 [oldController willBecomeUnselectedTab]; |
| 1245 oldContents->web_contents()->GetView()->StoreFocus(); | 1246 oldContents->GetView()->StoreFocus(); |
| 1246 oldContents->web_contents()->WasHidden(); | 1247 oldContents->WasHidden(); |
| 1247 } | 1248 } |
| 1248 } | 1249 } |
| 1249 | 1250 |
| 1250 // First get the vector of indices, which is allays sorted in ascending order. | 1251 // First get the vector of indices, which is allays sorted in ascending order. |
| 1251 TabStripSelectionModel::SelectedIndices selection( | 1252 TabStripSelectionModel::SelectedIndices selection( |
| 1252 tabStripModel_->selection_model().selected_indices()); | 1253 tabStripModel_->selection_model().selected_indices()); |
| 1253 // Iterate through all of the tabs, selecting each as necessary. | 1254 // Iterate through all of the tabs, selecting each as necessary. |
| 1254 TabStripSelectionModel::SelectedIndices::iterator iter = selection.begin(); | 1255 TabStripSelectionModel::SelectedIndices::iterator iter = selection.begin(); |
| 1255 int i = 0; | 1256 int i = 0; |
| 1256 for (TabController* current in tabArray_.get()) { | 1257 for (TabController* current in tabArray_.get()) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1271 | 1272 |
| 1272 // Relayout for new tabs and to let the selected tab grow to be larger in | 1273 // Relayout for new tabs and to let the selected tab grow to be larger in |
| 1273 // size than surrounding tabs if the user has many. This also raises the | 1274 // size than surrounding tabs if the user has many. This also raises the |
| 1274 // selected tab to the top. | 1275 // selected tab to the top. |
| 1275 [self layoutTabs]; | 1276 [self layoutTabs]; |
| 1276 | 1277 |
| 1277 // Swap in the contents for the new tab. | 1278 // Swap in the contents for the new tab. |
| 1278 [self swapInTabAtIndex:modelIndex]; | 1279 [self swapInTabAtIndex:modelIndex]; |
| 1279 | 1280 |
| 1280 if (newContents) { | 1281 if (newContents) { |
| 1281 newContents->web_contents()->WasShown(); | 1282 newContents->WasShown(); |
| 1282 newContents->web_contents()->GetView()->RestoreFocus(); | 1283 newContents->GetView()->RestoreFocus(); |
| 1283 | 1284 |
| 1284 FindTabHelper* findTabHelper = | 1285 FindTabHelper* findTabHelper = FindTabHelper::FromWebContents(newContents); |
| 1285 FindTabHelper::FromWebContents(newContents->web_contents()); | |
| 1286 if (findTabHelper->find_ui_active()) | 1286 if (findTabHelper->find_ui_active()) |
| 1287 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); | 1287 browser_->GetFindBarController()->find_bar()->SetFocusAndSelection(); |
| 1288 } | 1288 } |
| 1289 } | 1289 } |
| 1290 | 1290 |
| 1291 - (void)tabReplacedWithContents:(TabContents*)newContents | 1291 - (void)tabReplacedWithContents:(content::WebContents*)newContents |
| 1292 previousContents:(TabContents*)oldContents | 1292 previousContents:(content::WebContents*)oldContents |
| 1293 atIndex:(NSInteger)modelIndex { | 1293 atIndex:(NSInteger)modelIndex { |
| 1294 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1294 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1295 TabContentsController* oldController = | 1295 TabContentsController* oldController = |
| 1296 [tabContentsArray_ objectAtIndex:index]; | 1296 [tabContentsArray_ objectAtIndex:index]; |
| 1297 DCHECK_EQ(oldContents->web_contents(), [oldController webContents]); | 1297 DCHECK_EQ(oldContents, [oldController webContents]); |
| 1298 | 1298 |
| 1299 // Simply create a new TabContentsController for |newContents| and place it | 1299 // Simply create a new TabContentsController for |newContents| and place it |
| 1300 // into the array, replacing |oldContents|. A ActiveTabChanged notification | 1300 // into the array, replacing |oldContents|. A ActiveTabChanged notification |
| 1301 // will follow, at which point we will install the new view. | 1301 // will follow, at which point we will install the new view. |
| 1302 scoped_nsobject<TabContentsController> newController( | 1302 scoped_nsobject<TabContentsController> newController( |
| 1303 [[TabContentsController alloc] | 1303 [[TabContentsController alloc] initWithContents:newContents]); |
| 1304 initWithContents:newContents->web_contents()]); | |
| 1305 | 1304 |
| 1306 // Bye bye, |oldController|. | 1305 // Bye bye, |oldController|. |
| 1307 [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; | 1306 [tabContentsArray_ replaceObjectAtIndex:index withObject:newController]; |
| 1308 | 1307 |
| 1309 [delegate_ onReplaceTabWithContents:newContents->web_contents()]; | 1308 [delegate_ onReplaceTabWithContents:newContents]; |
| 1310 | 1309 |
| 1311 // Fake a tab changed notification to force tab titles and favicons to update. | 1310 // Fake a tab changed notification to force tab titles and favicons to update. |
| 1312 [self tabChangedWithContents:newContents | 1311 [self tabChangedWithContents:newContents |
| 1313 atIndex:modelIndex | 1312 atIndex:modelIndex |
| 1314 changeType:TabStripModelObserver::ALL]; | 1313 changeType:TabStripModelObserver::ALL]; |
| 1315 } | 1314 } |
| 1316 | 1315 |
| 1317 // Remove all knowledge about this tab and its associated controller, and remove | 1316 // Remove all knowledge about this tab and its associated controller, and remove |
| 1318 // the view from the strip. | 1317 // the view from the strip. |
| 1319 - (void)removeTab:(TabController*)controller { | 1318 - (void)removeTab:(TabController*)controller { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1396 NSRect newFrame = [tabView frame]; | 1395 NSRect newFrame = [tabView frame]; |
| 1397 newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); | 1396 newFrame = NSOffsetRect(newFrame, 0, -newFrame.size.height); |
| 1398 ScopedNSAnimationContextGroup animationGroup(true); | 1397 ScopedNSAnimationContextGroup animationGroup(true); |
| 1399 animationGroup.SetCurrentContextDuration(kAnimationDuration); | 1398 animationGroup.SetCurrentContextDuration(kAnimationDuration); |
| 1400 [[tabView animator] setFrame:newFrame]; | 1399 [[tabView animator] setFrame:newFrame]; |
| 1401 } | 1400 } |
| 1402 | 1401 |
| 1403 // Called when a notification is received from the model that the given tab | 1402 // Called when a notification is received from the model that the given tab |
| 1404 // has gone away. Start an animation then force a layout to put everything | 1403 // has gone away. Start an animation then force a layout to put everything |
| 1405 // in motion. | 1404 // in motion. |
| 1406 - (void)tabDetachedWithContents:(TabContents*)contents | 1405 - (void)tabDetachedWithContents:(content::WebContents*)contents |
| 1407 atIndex:(NSInteger)modelIndex { | 1406 atIndex:(NSInteger)modelIndex { |
| 1408 // Take closing tabs into account. | 1407 // Take closing tabs into account. |
| 1409 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1408 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1410 | 1409 |
| 1411 // Cancel any pending tab transition. | 1410 // Cancel any pending tab transition. |
| 1412 hoverTabSelector_->CancelTabTransition(); | 1411 hoverTabSelector_->CancelTabTransition(); |
| 1413 | 1412 |
| 1414 TabController* tab = [tabArray_ objectAtIndex:index]; | 1413 TabController* tab = [tabArray_ objectAtIndex:index]; |
| 1415 if (tabStripModel_->count() > 0) { | 1414 if (tabStripModel_->count() > 0) { |
| 1416 [self startClosingTabWithAnimation:tab]; | 1415 [self startClosingTabWithAnimation:tab]; |
| 1417 [self layoutTabs]; | 1416 [self layoutTabs]; |
| 1418 } else { | 1417 } else { |
| 1419 [self removeTab:tab]; | 1418 [self removeTab:tab]; |
| 1420 } | 1419 } |
| 1421 | 1420 |
| 1422 [delegate_ onTabDetachedWithContents:contents->web_contents()]; | 1421 [delegate_ onTabDetachedWithContents:contents]; |
| 1423 } | 1422 } |
| 1424 | 1423 |
| 1425 // A helper routine for creating an NSImageView to hold the favicon or app icon | 1424 // A helper routine for creating an NSImageView to hold the favicon or app icon |
| 1426 // for |contents|. | 1425 // for |contents|. |
| 1427 - (NSImageView*)iconImageViewForContents:(TabContents*)contents { | 1426 - (NSImageView*)iconImageViewForContents:(content::WebContents*)contents { |
| 1428 extensions::TabHelper* extensions_tab_helper = | 1427 extensions::TabHelper* extensions_tab_helper = |
| 1429 extensions::TabHelper::FromWebContents(contents->web_contents()); | 1428 extensions::TabHelper::FromWebContents(contents); |
| 1430 BOOL isApp = extensions_tab_helper->is_app(); | 1429 BOOL isApp = extensions_tab_helper->is_app(); |
| 1431 NSImage* image = nil; | 1430 NSImage* image = nil; |
| 1432 // Favicons come from the renderer, and the renderer draws everything in the | 1431 // Favicons come from the renderer, and the renderer draws everything in the |
| 1433 // system color space. | 1432 // system color space. |
| 1434 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); | 1433 CGColorSpaceRef colorSpace = base::mac::GetSystemColorSpace(); |
| 1435 if (isApp) { | 1434 if (isApp) { |
| 1436 SkBitmap* icon = extensions_tab_helper->GetExtensionAppIcon(); | 1435 SkBitmap* icon = extensions_tab_helper->GetExtensionAppIcon(); |
| 1437 if (icon) | 1436 if (icon) |
| 1438 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); | 1437 image = gfx::SkBitmapToNSImageWithColorSpace(*icon, colorSpace); |
| 1439 } else { | 1438 } else { |
| 1440 image = mac::FaviconForTabContents(contents); | 1439 image = mac::FaviconForWebContents(contents); |
| 1441 } | 1440 } |
| 1442 | 1441 |
| 1443 // Either we don't have a valid favicon or there was some issue converting it | 1442 // Either we don't have a valid favicon or there was some issue converting it |
| 1444 // from an SkBitmap. Either way, just show the default. | 1443 // from an SkBitmap. Either way, just show the default. |
| 1445 if (!image) | 1444 if (!image) |
| 1446 image = defaultFavicon_.get(); | 1445 image = defaultFavicon_.get(); |
| 1447 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); | 1446 NSRect frame = NSMakeRect(0, 0, kIconWidthAndHeight, kIconWidthAndHeight); |
| 1448 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; | 1447 NSImageView* view = [[[NSImageView alloc] initWithFrame:frame] autorelease]; |
| 1449 [view setImage:image]; | 1448 [view setImage:image]; |
| 1450 return view; | 1449 return view; |
| 1451 } | 1450 } |
| 1452 | 1451 |
| 1453 // Updates the current loading state, replacing the icon view with a favicon, | 1452 // Updates the current loading state, replacing the icon view with a favicon, |
| 1454 // a throbber, the default icon, or nothing at all. | 1453 // a throbber, the default icon, or nothing at all. |
| 1455 - (void)updateFaviconForContents:(TabContents*)contents | 1454 - (void)updateFaviconForContents:(content::WebContents*)contents |
| 1456 atIndex:(NSInteger)modelIndex { | 1455 atIndex:(NSInteger)modelIndex { |
| 1457 if (!contents) | 1456 if (!contents) |
| 1458 return; | 1457 return; |
| 1459 | 1458 |
| 1460 static NSImage* throbberWaitingImage = | 1459 static NSImage* throbberWaitingImage = |
| 1461 ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1460 ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1462 IDR_THROBBER_WAITING).CopyNSImage(); | 1461 IDR_THROBBER_WAITING).CopyNSImage(); |
| 1463 static NSImage* throbberLoadingImage = | 1462 static NSImage* throbberLoadingImage = |
| 1464 ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1463 ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1465 IDR_THROBBER).CopyNSImage(); | 1464 IDR_THROBBER).CopyNSImage(); |
| 1466 static NSImage* sadFaviconImage = | 1465 static NSImage* sadFaviconImage = |
| 1467 ResourceBundle::GetSharedInstance().GetNativeImageNamed( | 1466 ResourceBundle::GetSharedInstance().GetNativeImageNamed( |
| 1468 IDR_SAD_FAVICON).CopyNSImage(); | 1467 IDR_SAD_FAVICON).CopyNSImage(); |
| 1469 | 1468 |
| 1470 // Take closing tabs into account. | 1469 // Take closing tabs into account. |
| 1471 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1470 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1472 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1471 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1473 | 1472 |
| 1474 FaviconTabHelper* favicon_tab_helper = | 1473 FaviconTabHelper* favicon_tab_helper = |
| 1475 FaviconTabHelper::FromWebContents(contents->web_contents()); | 1474 FaviconTabHelper::FromWebContents(contents); |
| 1476 bool oldHasIcon = [tabController iconView] != nil; | 1475 bool oldHasIcon = [tabController iconView] != nil; |
| 1477 bool newHasIcon = favicon_tab_helper->ShouldDisplayFavicon() || | 1476 bool newHasIcon = favicon_tab_helper->ShouldDisplayFavicon() || |
| 1478 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. | 1477 tabStripModel_->IsMiniTab(modelIndex); // Always show icon if mini. |
| 1479 | 1478 |
| 1480 TabLoadingState oldState = [tabController loadingState]; | 1479 TabLoadingState oldState = [tabController loadingState]; |
| 1481 TabLoadingState newState = kTabDone; | 1480 TabLoadingState newState = kTabDone; |
| 1482 NSImage* throbberImage = nil; | 1481 NSImage* throbberImage = nil; |
| 1483 if (contents->web_contents()->IsCrashed()) { | 1482 if (contents->IsCrashed()) { |
| 1484 newState = kTabCrashed; | 1483 newState = kTabCrashed; |
| 1485 newHasIcon = true; | 1484 newHasIcon = true; |
| 1486 } else if (contents->web_contents()->IsWaitingForResponse()) { | 1485 } else if (contents->IsWaitingForResponse()) { |
| 1487 newState = kTabWaiting; | 1486 newState = kTabWaiting; |
| 1488 throbberImage = throbberWaitingImage; | 1487 throbberImage = throbberWaitingImage; |
| 1489 } else if (contents->web_contents()->IsLoading()) { | 1488 } else if (contents->IsLoading()) { |
| 1490 newState = kTabLoading; | 1489 newState = kTabLoading; |
| 1491 throbberImage = throbberLoadingImage; | 1490 throbberImage = throbberLoadingImage; |
| 1492 } | 1491 } |
| 1493 | 1492 |
| 1494 if (oldState != newState) | 1493 if (oldState != newState) |
| 1495 [tabController setLoadingState:newState]; | 1494 [tabController setLoadingState:newState]; |
| 1496 | 1495 |
| 1497 // While loading, this function is called repeatedly with the same state. | 1496 // While loading, this function is called repeatedly with the same state. |
| 1498 // To avoid expensive unnecessary view manipulation, only make changes when | 1497 // To avoid expensive unnecessary view manipulation, only make changes when |
| 1499 // the state is actually changing. When loading is complete (kTabDone), | 1498 // the state is actually changing. When loading is complete (kTabDone), |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1527 // some tests. | 1526 // some tests. |
| 1528 //DCHECK_LE(NSMaxX([iconView frame]), | 1527 //DCHECK_LE(NSMaxX([iconView frame]), |
| 1529 // NSWidth([[tabController view] frame]) - kTabOverlap); | 1528 // NSWidth([[tabController view] frame]) - kTabOverlap); |
| 1530 } | 1529 } |
| 1531 } | 1530 } |
| 1532 } | 1531 } |
| 1533 | 1532 |
| 1534 // Called when a notification is received from the model that the given tab | 1533 // Called when a notification is received from the model that the given tab |
| 1535 // has been updated. |loading| will be YES when we only want to update the | 1534 // has been updated. |loading| will be YES when we only want to update the |
| 1536 // throbber state, not anything else about the (partially) loading tab. | 1535 // throbber state, not anything else about the (partially) loading tab. |
| 1537 - (void)tabChangedWithContents:(TabContents*)contents | 1536 - (void)tabChangedWithContents:(content::WebContents*)contents |
| 1538 atIndex:(NSInteger)modelIndex | 1537 atIndex:(NSInteger)modelIndex |
| 1539 changeType:(TabStripModelObserver::TabChangeType)change { | 1538 changeType:(TabStripModelObserver::TabChangeType)change { |
| 1540 // Take closing tabs into account. | 1539 // Take closing tabs into account. |
| 1541 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1540 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1542 | 1541 |
| 1543 if (modelIndex == tabStripModel_->active_index()) | 1542 if (modelIndex == tabStripModel_->active_index()) |
| 1544 [delegate_ onTabChanged:change withContents:contents->web_contents()]; | 1543 [delegate_ onTabChanged:change withContents:contents]; |
| 1545 | 1544 |
| 1546 if (change == TabStripModelObserver::TITLE_NOT_LOADING) { | 1545 if (change == TabStripModelObserver::TITLE_NOT_LOADING) { |
| 1547 // TODO(sky): make this work. | 1546 // TODO(sky): make this work. |
| 1548 // We'll receive another notification of the change asynchronously. | 1547 // We'll receive another notification of the change asynchronously. |
| 1549 return; | 1548 return; |
| 1550 } | 1549 } |
| 1551 | 1550 |
| 1552 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1551 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1553 | 1552 |
| 1554 if (change != TabStripModelObserver::LOADING_ONLY) | 1553 if (change != TabStripModelObserver::LOADING_ONLY) |
| 1555 [self setTabTitle:tabController withContents:contents->web_contents()]; | 1554 [self setTabTitle:tabController withContents:contents]; |
| 1556 | 1555 |
| 1557 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1556 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1558 | 1557 |
| 1559 TabContentsController* updatedController = | 1558 TabContentsController* updatedController = |
| 1560 [tabContentsArray_ objectAtIndex:index]; | 1559 [tabContentsArray_ objectAtIndex:index]; |
| 1561 [updatedController tabDidChange:contents->web_contents()]; | 1560 [updatedController tabDidChange:contents]; |
| 1562 } | 1561 } |
| 1563 | 1562 |
| 1564 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays | 1563 // Called when a tab is moved (usually by drag&drop). Keep our parallel arrays |
| 1565 // in sync with the tab strip model. It can also be pinned/unpinned | 1564 // in sync with the tab strip model. It can also be pinned/unpinned |
| 1566 // simultaneously, so we need to take care of that. | 1565 // simultaneously, so we need to take care of that. |
| 1567 - (void)tabMovedWithContents:(TabContents*)contents | 1566 - (void)tabMovedWithContents:(content::WebContents*)contents |
| 1568 fromIndex:(NSInteger)modelFrom | 1567 fromIndex:(NSInteger)modelFrom |
| 1569 toIndex:(NSInteger)modelTo { | 1568 toIndex:(NSInteger)modelTo { |
| 1570 // Take closing tabs into account. | 1569 // Take closing tabs into account. |
| 1571 NSInteger from = [self indexFromModelIndex:modelFrom]; | 1570 NSInteger from = [self indexFromModelIndex:modelFrom]; |
| 1572 NSInteger to = [self indexFromModelIndex:modelTo]; | 1571 NSInteger to = [self indexFromModelIndex:modelTo]; |
| 1573 | 1572 |
| 1574 // Cancel any pending tab transition. | 1573 // Cancel any pending tab transition. |
| 1575 hoverTabSelector_->CancelTabTransition(); | 1574 hoverTabSelector_->CancelTabTransition(); |
| 1576 | 1575 |
| 1577 scoped_nsobject<TabContentsController> movedTabContentsController( | 1576 scoped_nsobject<TabContentsController> movedTabContentsController( |
| 1578 [[tabContentsArray_ objectAtIndex:from] retain]); | 1577 [[tabContentsArray_ objectAtIndex:from] retain]); |
| 1579 [tabContentsArray_ removeObjectAtIndex:from]; | 1578 [tabContentsArray_ removeObjectAtIndex:from]; |
| 1580 [tabContentsArray_ insertObject:movedTabContentsController.get() | 1579 [tabContentsArray_ insertObject:movedTabContentsController.get() |
| 1581 atIndex:to]; | 1580 atIndex:to]; |
| 1582 scoped_nsobject<TabController> movedTabController( | 1581 scoped_nsobject<TabController> movedTabController( |
| 1583 [[tabArray_ objectAtIndex:from] retain]); | 1582 [[tabArray_ objectAtIndex:from] retain]); |
| 1584 DCHECK([movedTabController isKindOfClass:[TabController class]]); | 1583 DCHECK([movedTabController isKindOfClass:[TabController class]]); |
| 1585 [tabArray_ removeObjectAtIndex:from]; | 1584 [tabArray_ removeObjectAtIndex:from]; |
| 1586 [tabArray_ insertObject:movedTabController.get() atIndex:to]; | 1585 [tabArray_ insertObject:movedTabController.get() atIndex:to]; |
| 1587 | 1586 |
| 1588 // The tab moved, which means that the mini-tab state may have changed. | 1587 // The tab moved, which means that the mini-tab state may have changed. |
| 1589 if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) | 1588 if (tabStripModel_->IsMiniTab(modelTo) != [movedTabController mini]) |
| 1590 [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; | 1589 [self tabMiniStateChangedWithContents:contents atIndex:modelTo]; |
| 1591 | 1590 |
| 1592 [self layoutTabs]; | 1591 [self layoutTabs]; |
| 1593 } | 1592 } |
| 1594 | 1593 |
| 1595 // Called when a tab is pinned or unpinned without moving. | 1594 // Called when a tab is pinned or unpinned without moving. |
| 1596 - (void)tabMiniStateChangedWithContents:(TabContents*)contents | 1595 - (void)tabMiniStateChangedWithContents:(content::WebContents*)contents |
| 1597 atIndex:(NSInteger)modelIndex { | 1596 atIndex:(NSInteger)modelIndex { |
| 1598 // Take closing tabs into account. | 1597 // Take closing tabs into account. |
| 1599 NSInteger index = [self indexFromModelIndex:modelIndex]; | 1598 NSInteger index = [self indexFromModelIndex:modelIndex]; |
| 1600 | 1599 |
| 1601 TabController* tabController = [tabArray_ objectAtIndex:index]; | 1600 TabController* tabController = [tabArray_ objectAtIndex:index]; |
| 1602 DCHECK([tabController isKindOfClass:[TabController class]]); | 1601 DCHECK([tabController isKindOfClass:[TabController class]]); |
| 1603 | 1602 |
| 1604 // Don't do anything if the change was already picked up by the move event. | 1603 // Don't do anything if the change was already picked up by the move event. |
| 1605 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) | 1604 if (tabStripModel_->IsMiniTab(modelIndex) == [tabController mini]) |
| 1606 return; | 1605 return; |
| 1607 | 1606 |
| 1608 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; | 1607 [tabController setMini:tabStripModel_->IsMiniTab(modelIndex)]; |
| 1609 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; | 1608 [tabController setPinned:tabStripModel_->IsTabPinned(modelIndex)]; |
| 1610 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; | 1609 [tabController setApp:tabStripModel_->IsAppTab(modelIndex)]; |
| 1611 [tabController setUrl:contents->web_contents()->GetURL()]; | 1610 [tabController setUrl:contents->GetURL()]; |
| 1612 [self updateFaviconForContents:contents atIndex:modelIndex]; | 1611 [self updateFaviconForContents:contents atIndex:modelIndex]; |
| 1613 // If the tab is being restored and it's pinned, the mini state is set after | 1612 // If the tab is being restored and it's pinned, the mini state is set after |
| 1614 // the tab has already been rendered, so re-layout the tabstrip. In all other | 1613 // the tab has already been rendered, so re-layout the tabstrip. In all other |
| 1615 // cases, the state is set before the tab is rendered so this isn't needed. | 1614 // cases, the state is set before the tab is rendered so this isn't needed. |
| 1616 [self layoutTabs]; | 1615 [self layoutTabs]; |
| 1617 } | 1616 } |
| 1618 | 1617 |
| 1619 - (void)setFrameOfActiveTab:(NSRect)frame { | 1618 - (void)setFrameOfActiveTab:(NSRect)frame { |
| 1620 NSView* view = [self activeTabView]; | 1619 NSView* view = [self activeTabView]; |
| 1621 NSValue* identifier = [NSValue valueWithPointer:view]; | 1620 NSValue* identifier = [NSValue valueWithPointer:view]; |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2111 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) { | 2110 NSView* GetSheetParentViewForWebContents(WebContents* web_contents) { |
| 2112 // View hierarchy of the contents view: | 2111 // View hierarchy of the contents view: |
| 2113 // NSView -- switchView, same for all tabs | 2112 // NSView -- switchView, same for all tabs |
| 2114 // +- NSView -- TabContentsController's view | 2113 // +- NSView -- TabContentsController's view |
| 2115 // +- TabContentsViewCocoa | 2114 // +- TabContentsViewCocoa |
| 2116 // | 2115 // |
| 2117 // Changing it? Do not forget to modify | 2116 // Changing it? Do not forget to modify |
| 2118 // -[TabStripController swapInTabAtIndex:] too. | 2117 // -[TabStripController swapInTabAtIndex:] too. |
| 2119 return [web_contents->GetNativeView() superview]; | 2118 return [web_contents->GetNativeView() superview]; |
| 2120 } | 2119 } |
| OLD | NEW |