| 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 #import "chrome/browser/cocoa/tab_strip_controller.h" | 5 #import "chrome/browser/cocoa/tab_strip_controller.h" |
| 6 | 6 |
| 7 #import <QuartzCore/QuartzCore.h> | 7 #import <QuartzCore/QuartzCore.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <string> |
| 10 | 11 |
| 11 #include "app/l10n_util.h" | 12 #include "app/l10n_util.h" |
| 12 #include "app/resource_bundle.h" | 13 #include "app/resource_bundle.h" |
| 13 #include "base/mac_util.h" | 14 #include "base/mac_util.h" |
| 14 #include "base/nsimage_cache_mac.h" | 15 #include "base/nsimage_cache_mac.h" |
| 15 #include "base/sys_string_conversions.h" | 16 #include "base/sys_string_conversions.h" |
| 16 #include "chrome/app/chrome_dll_resource.h" | 17 #include "chrome/app/chrome_dll_resource.h" |
| 17 #include "chrome/browser/browser.h" | 18 #include "chrome/browser/browser.h" |
| 18 #include "chrome/browser/find_bar.h" | 19 #include "chrome/browser/find_bar.h" |
| 19 #include "chrome/browser/find_bar_controller.h" | 20 #include "chrome/browser/find_bar_controller.h" |
| 20 #include "chrome/browser/metrics/user_metrics.h" | 21 #include "chrome/browser/metrics/user_metrics.h" |
| 21 #include "chrome/browser/profile.h" | 22 #include "chrome/browser/profile.h" |
| 22 #import "chrome/browser/cocoa/browser_window_controller.h" | 23 #import "chrome/browser/cocoa/browser_window_controller.h" |
| 23 #import "chrome/browser/cocoa/constrained_window_mac.h" | 24 #import "chrome/browser/cocoa/constrained_window_mac.h" |
| 24 #import "chrome/browser/cocoa/tab_strip_view.h" | 25 #import "chrome/browser/cocoa/tab_strip_view.h" |
| 25 #import "chrome/browser/cocoa/tab_contents_controller.h" | 26 #import "chrome/browser/cocoa/tab_contents_controller.h" |
| 26 #import "chrome/browser/cocoa/tab_controller.h" | 27 #import "chrome/browser/cocoa/tab_controller.h" |
| 27 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" | 28 #import "chrome/browser/cocoa/tab_strip_model_observer_bridge.h" |
| 28 #import "chrome/browser/cocoa/tab_view.h" | 29 #import "chrome/browser/cocoa/tab_view.h" |
| 29 #import "chrome/browser/cocoa/throbber_view.h" | 30 #import "chrome/browser/cocoa/throbber_view.h" |
| 31 #include "chrome/browser/net/url_fixer_upper.h" |
| 30 #include "chrome/browser/tab_contents/navigation_controller.h" | 32 #include "chrome/browser/tab_contents/navigation_controller.h" |
| 31 #include "chrome/browser/tab_contents/navigation_entry.h" | 33 #include "chrome/browser/tab_contents/navigation_entry.h" |
| 32 #include "chrome/browser/tab_contents/tab_contents.h" | 34 #include "chrome/browser/tab_contents/tab_contents.h" |
| 33 #include "chrome/browser/tab_contents/tab_contents_view.h" | 35 #include "chrome/browser/tab_contents/tab_contents_view.h" |
| 34 #include "chrome/browser/tabs/tab_strip_model.h" | 36 #include "chrome/browser/tabs/tab_strip_model.h" |
| 35 #include "grit/app_resources.h" | 37 #include "grit/app_resources.h" |
| 36 #include "grit/generated_resources.h" | 38 #include "grit/generated_resources.h" |
| 37 #include "grit/theme_resources.h" | 39 #include "grit/theme_resources.h" |
| 38 #include "skia/ext/skia_utils_mac.h" | 40 #include "skia/ext/skia_utils_mac.h" |
| 39 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" | 41 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" |
| 40 | 42 |
| 41 NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged"; | 43 NSString* const kTabStripNumberOfTabsChanged = @"kTabStripNumberOfTabsChanged"; |
| 42 | 44 |
| 45 namespace { |
| 46 |
| 43 // A value to indicate tab layout should use the full available width of the | 47 // A value to indicate tab layout should use the full available width of the |
| 44 // view. | 48 // view. |
| 45 static const CGFloat kUseFullAvailableWidth = -1.0; | 49 const CGFloat kUseFullAvailableWidth = -1.0; |
| 46 | 50 |
| 47 // Left-side indent for tab layout so tabs don't overlap with the window | 51 // Left-side indent for tab layout so tabs don't overlap with the window |
| 48 // controls. | 52 // controls. |
| 49 static const CGFloat kIndentLeavingSpaceForControls = 64.0; | 53 const CGFloat kIndentLeavingSpaceForControls = 64.0; |
| 54 |
| 55 // The amount by which tabs overlap. |
| 56 const CGFloat kTabOverlap = 20.0; |
| 57 |
| 58 // The amount by which the new tab button is offset (from the tabs). |
| 59 const CGFloat kNewTabButtonOffset = 8.0; |
| 50 | 60 |
| 51 // Time (in seconds) in which tabs animate to their final position. | 61 // Time (in seconds) in which tabs animate to their final position. |
| 52 static const NSTimeInterval kAnimationDuration = 0.2; | 62 const NSTimeInterval kAnimationDuration = 0.2; |
| 53 | |
| 54 namespace { | |
| 55 | 63 |
| 56 // Helper class for doing NSAnimationContext calls that takes a bool to disable | 64 // Helper class for doing NSAnimationContext calls that takes a bool to disable |
| 57 // all the work. Useful for code that wants to conditionally animate. | 65 // all the work. Useful for code that wants to conditionally animate. |
| 58 class ScopedNSAnimationContextGroup { | 66 class ScopedNSAnimationContextGroup { |
| 59 public: | 67 public: |
| 60 explicit ScopedNSAnimationContextGroup(bool animate) | 68 explicit ScopedNSAnimationContextGroup(bool animate) |
| 61 : animate_(animate) { | 69 : animate_(animate) { |
| 62 if (animate_) { | 70 if (animate_) { |
| 63 [NSAnimationContext beginGrouping]; | 71 [NSAnimationContext beginGrouping]; |
| 64 } | 72 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 - (void)layoutTabsWithAnimation:(BOOL)animate | 113 - (void)layoutTabsWithAnimation:(BOOL)animate |
| 106 regenerateSubviews:(BOOL)doUpdate; | 114 regenerateSubviews:(BOOL)doUpdate; |
| 107 - (void)animationDidStopForController:(TabController*)controller | 115 - (void)animationDidStopForController:(TabController*)controller |
| 108 finished:(BOOL)finished; | 116 finished:(BOOL)finished; |
| 109 - (NSInteger)indexFromModelIndex:(NSInteger)index; | 117 - (NSInteger)indexFromModelIndex:(NSInteger)index; |
| 110 - (NSInteger)numberOfOpenTabs; | 118 - (NSInteger)numberOfOpenTabs; |
| 111 - (NSInteger)numberOfOpenPinnedTabs; | 119 - (NSInteger)numberOfOpenPinnedTabs; |
| 112 - (NSInteger)numberOfOpenUnpinnedTabs; | 120 - (NSInteger)numberOfOpenUnpinnedTabs; |
| 113 - (void)mouseMoved:(NSEvent*)event; | 121 - (void)mouseMoved:(NSEvent*)event; |
| 114 - (void)setTabTrackingAreasEnabled:(BOOL)enabled; | 122 - (void)setTabTrackingAreasEnabled:(BOOL)enabled; |
| 123 - (void)droppingURLsAt:(NSPoint)location |
| 124 givesIndex:(NSInteger*)index |
| 125 disposition:(WindowOpenDisposition*)disposition; |
| 115 @end | 126 @end |
| 116 | 127 |
| 117 // A simple view class that prevents the Window Server from dragging the area | 128 // A simple view class that prevents the Window Server from dragging the area |
| 118 // behind tabs. Sometimes core animation confuses it. Unfortunately, it can also | 129 // behind tabs. Sometimes core animation confuses it. Unfortunately, it can also |
| 119 // falsely pick up clicks during rapid tab closure, so we have to account for | 130 // falsely pick up clicks during rapid tab closure, so we have to account for |
| 120 // that. | 131 // that. |
| 121 @interface TabStripControllerDragBlockingView : NSView { | 132 @interface TabStripControllerDragBlockingView : NSView { |
| 122 TabStripController* controller_; // weak; owns us | 133 TabStripController* controller_; // weak; owns us |
| 123 } | 134 } |
| 124 | 135 |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 [newTabButton_ setAction:@selector(commandDispatch:)]; | 293 [newTabButton_ setAction:@selector(commandDispatch:)]; |
| 283 [newTabButton_ setTag:IDC_NEW_TAB]; | 294 [newTabButton_ setTag:IDC_NEW_TAB]; |
| 284 newTabTrackingArea_.reset( | 295 newTabTrackingArea_.reset( |
| 285 [[NSTrackingArea alloc] initWithRect:[newTabButton_ bounds] | 296 [[NSTrackingArea alloc] initWithRect:[newTabButton_ bounds] |
| 286 options:(NSTrackingMouseEnteredAndExited | | 297 options:(NSTrackingMouseEnteredAndExited | |
| 287 NSTrackingActiveAlways) | 298 NSTrackingActiveAlways) |
| 288 owner:self | 299 owner:self |
| 289 userInfo:nil]); | 300 userInfo:nil]); |
| 290 [newTabButton_ addTrackingArea:newTabTrackingArea_.get()]; | 301 [newTabButton_ addTrackingArea:newTabTrackingArea_.get()]; |
| 291 targetFrames_.reset([[NSMutableDictionary alloc] init]); | 302 targetFrames_.reset([[NSMutableDictionary alloc] init]); |
| 303 |
| 292 dragBlockingView_.reset( | 304 dragBlockingView_.reset( |
| 293 [[TabStripControllerDragBlockingView alloc] initWithFrame:NSZeroRect | 305 [[TabStripControllerDragBlockingView alloc] initWithFrame:NSZeroRect |
| 294 controller:self]); | 306 controller:self]); |
| 295 [self addSubviewToPermanentList:dragBlockingView_]; | 307 [self addSubviewToPermanentList:dragBlockingView_]; |
| 308 |
| 296 newTabTargetFrame_ = NSMakeRect(0, 0, 0, 0); | 309 newTabTargetFrame_ = NSMakeRect(0, 0, 0, 0); |
| 297 availableResizeWidth_ = kUseFullAvailableWidth; | 310 availableResizeWidth_ = kUseFullAvailableWidth; |
| 298 | 311 |
| 299 closingControllers_.reset([[NSMutableSet alloc] init]); | 312 closingControllers_.reset([[NSMutableSet alloc] init]); |
| 300 | 313 |
| 301 // Install the permanent subviews. | 314 // Install the permanent subviews. |
| 302 [self regenerateSubviewList]; | 315 [self regenerateSubviewList]; |
| 303 | 316 |
| 304 // Watch for notifications that the tab strip view has changed size so | 317 // Watch for notifications that the tab strip view has changed size so |
| 305 // we can tell it to layout for the new size. | 318 // we can tell it to layout for the new size. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 318 owner:self | 331 owner:self |
| 319 userInfo:nil]); | 332 userInfo:nil]); |
| 320 [tabView_ addTrackingArea:trackingArea_.get()]; | 333 [tabView_ addTrackingArea:trackingArea_.get()]; |
| 321 } | 334 } |
| 322 return self; | 335 return self; |
| 323 } | 336 } |
| 324 | 337 |
| 325 - (void)dealloc { | 338 - (void)dealloc { |
| 326 if (trackingArea_.get()) | 339 if (trackingArea_.get()) |
| 327 [tabView_ removeTrackingArea:trackingArea_.get()]; | 340 [tabView_ removeTrackingArea:trackingArea_.get()]; |
| 341 |
| 328 [newTabButton_ removeTrackingArea:newTabTrackingArea_.get()]; | 342 [newTabButton_ removeTrackingArea:newTabTrackingArea_.get()]; |
| 329 // Invalidate all closing animations so they don't call back to us after | 343 // Invalidate all closing animations so they don't call back to us after |
| 330 // we're gone. | 344 // we're gone. |
| 331 for (TabController* controller in closingControllers_.get()) { | 345 for (TabController* controller in closingControllers_.get()) { |
| 332 NSView* view = [controller view]; | 346 NSView* view = [controller view]; |
| 333 [[[view animationForKey:@"frameOrigin"] delegate] invalidate]; | 347 [[[view animationForKey:@"frameOrigin"] delegate] invalidate]; |
| 334 } | 348 } |
| 335 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 349 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 336 [super dealloc]; | 350 [super dealloc]; |
| 337 } | 351 } |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 593 // subclass of TabContentsController with everything stubbed out or by | 607 // subclass of TabContentsController with everything stubbed out or by |
| 594 // abstracting a base class interface. | 608 // abstracting a base class interface. |
| 595 // TODO(pinkerton): Note this doesn't do too well when the number of min-sized | 609 // TODO(pinkerton): Note this doesn't do too well when the number of min-sized |
| 596 // tabs would cause an overflow. | 610 // tabs would cause an overflow. |
| 597 - (void)layoutTabsWithAnimation:(BOOL)animate | 611 - (void)layoutTabsWithAnimation:(BOOL)animate |
| 598 regenerateSubviews:(BOOL)doUpdate { | 612 regenerateSubviews:(BOOL)doUpdate { |
| 599 DCHECK([NSThread isMainThread]); | 613 DCHECK([NSThread isMainThread]); |
| 600 if (![tabArray_ count]) | 614 if (![tabArray_ count]) |
| 601 return; | 615 return; |
| 602 | 616 |
| 603 const CGFloat kTabOverlap = 20.0; | |
| 604 const CGFloat kNewTabButtonOffset = 8.0; | |
| 605 const CGFloat kMaxTabWidth = [TabController maxTabWidth]; | 617 const CGFloat kMaxTabWidth = [TabController maxTabWidth]; |
| 606 const CGFloat kMinTabWidth = [TabController minTabWidth]; | 618 const CGFloat kMinTabWidth = [TabController minTabWidth]; |
| 607 const CGFloat kMinSelectedTabWidth = [TabController minSelectedTabWidth]; | 619 const CGFloat kMinSelectedTabWidth = [TabController minSelectedTabWidth]; |
| 608 const CGFloat kPinnedTabWidth = [TabController pinnedTabWidth]; | 620 const CGFloat kPinnedTabWidth = [TabController pinnedTabWidth]; |
| 609 | 621 |
| 610 NSRect enclosingRect = NSZeroRect; | 622 NSRect enclosingRect = NSZeroRect; |
| 611 ScopedNSAnimationContextGroup mainAnimationGroup(animate); | 623 ScopedNSAnimationContextGroup mainAnimationGroup(animate); |
| 612 mainAnimationGroup.SetCurrentContextDuration(kAnimationDuration); | 624 mainAnimationGroup.SetCurrentContextDuration(kAnimationDuration); |
| 613 | 625 |
| 614 // Update the current subviews and their z-order if requested. | 626 // Update the current subviews and their z-order if requested. |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1394 [subviews addObject:tabView]; | 1406 [subviews addObject:tabView]; |
| 1395 } | 1407 } |
| 1396 } | 1408 } |
| 1397 if (selectedTabView) { | 1409 if (selectedTabView) { |
| 1398 [subviews addObject:selectedTabView]; | 1410 [subviews addObject:selectedTabView]; |
| 1399 } | 1411 } |
| 1400 [tabView_ setSubviews:subviews]; | 1412 [tabView_ setSubviews:subviews]; |
| 1401 [self setTabTrackingAreasEnabled:mouseInside_]; | 1413 [self setTabTrackingAreasEnabled:mouseInside_]; |
| 1402 } | 1414 } |
| 1403 | 1415 |
| 1416 // Get the index and disposition for a potential URL(s) drop given a location |
| 1417 // (in window base coordinates). It considers x coordinate of the given |
| 1418 // location. If it's in the "middle" of a tab, it drops on that tab. If it's to |
| 1419 // the left, it inserts to the left, and similarly for the right. |
| 1420 - (void)droppingURLsAt:(NSPoint)location |
| 1421 givesIndex:(NSInteger*)index |
| 1422 disposition:(WindowOpenDisposition*)disposition { |
| 1423 // Proportion of the tab which is considered the "middle" (and causes things |
| 1424 // to drop on that tab). |
| 1425 const double kMiddleProportion = 0.5; |
| 1426 const double kLRProportion = (1.0 - kMiddleProportion) / 2.0; |
| 1427 |
| 1428 DCHECK(index && disposition); |
| 1429 NSInteger i = 0; |
| 1430 for (TabController* tab in tabArray_.get()) { |
| 1431 NSView* view = [tab view]; |
| 1432 DCHECK([view isKindOfClass:[TabView class]]); |
| 1433 |
| 1434 // Recall that |-[NSView frame]| is in its superview's coordinates, so a |
| 1435 // |TabView|'s frame is in the coordinates of the |TabStripView| (which is |
| 1436 // confusingly called |tabView_|). |
| 1437 NSRect frame = [tabView_ convertRectToBase:[view frame]]; |
| 1438 |
| 1439 // Modify the frame to make it "unoverlapped". |
| 1440 frame.origin.x += kTabOverlap / 2.0; |
| 1441 frame.size.width -= kTabOverlap; |
| 1442 if (frame.size.width < 1.0) |
| 1443 frame.size.width = 1.0; // try to avoid complete failure |
| 1444 |
| 1445 // Drop in a new tab to the left of tab |i|? |
| 1446 if (location.x < (frame.origin.x + kLRProportion * frame.size.width)) { |
| 1447 *index = i; |
| 1448 *disposition = NEW_FOREGROUND_TAB; |
| 1449 return; |
| 1450 } |
| 1451 |
| 1452 // Drop on tab |i|? |
| 1453 if (location.x <= (frame.origin.x + |
| 1454 (1.0 - kLRProportion) * frame.size.width)) { |
| 1455 *index = i; |
| 1456 *disposition = CURRENT_TAB; |
| 1457 return; |
| 1458 } |
| 1459 |
| 1460 // (Dropping in a new tab to the right of tab |i| will be taken care of in |
| 1461 // the next iteration.) |
| 1462 i++; |
| 1463 } |
| 1464 |
| 1465 // If we've made it here, we want to append a new tab to the end. |
| 1466 *index = -1; |
| 1467 *disposition = NEW_FOREGROUND_TAB; |
| 1468 } |
| 1469 |
| 1470 // Drop URLs at the given location. |
| 1471 - (void)dropURLs:(NSArray*)urls at:(NSPoint)location { |
| 1472 if ([urls count] < 1) { |
| 1473 NOTREACHED(); |
| 1474 return; |
| 1475 } |
| 1476 |
| 1477 //TODO(viettrungluu): dropping multiple URLs. |
| 1478 if ([urls count] > 1) |
| 1479 NOTIMPLEMENTED(); |
| 1480 |
| 1481 // Get the first URL and fix it up. |
| 1482 GURL url(URLFixerUpper::FixupURL( |
| 1483 base::SysNSStringToUTF8([urls objectAtIndex:0]), std::string())); |
| 1484 |
| 1485 // Get the index and disposition. |
| 1486 NSInteger index; |
| 1487 WindowOpenDisposition disposition; |
| 1488 [self droppingURLsAt:location |
| 1489 givesIndex:&index |
| 1490 disposition:&disposition]; |
| 1491 |
| 1492 // Either insert a new tab or open in a current tab. |
| 1493 switch (disposition) { |
| 1494 case NEW_FOREGROUND_TAB: |
| 1495 browser_->AddTabWithURL(url, GURL(), PageTransition::TYPED, true, index, |
| 1496 true, NULL); |
| 1497 break; |
| 1498 case CURRENT_TAB: |
| 1499 tabModel_->GetTabContentsAt(index)->OpenURL(url, GURL(), CURRENT_TAB, |
| 1500 PageTransition::TYPED); |
| 1501 tabModel_->SelectTabContentsAt(index, true); |
| 1502 break; |
| 1503 default: |
| 1504 NOTIMPLEMENTED(); |
| 1505 } |
| 1506 } |
| 1507 |
| 1508 // Update (possibly showing) the indicator which indicates where an URL drop |
| 1509 // would happen. |
| 1510 - (void)indicateDropURLsAt:(NSPoint)location { |
| 1511 // TODO(viettrungluu): Make the tabs move around, show an indicator, etc. This |
| 1512 // requires a re-work of the tabs code.... |
| 1513 #if 0 |
| 1514 NSInteger index; |
| 1515 WindowOpenDisposition disposition; |
| 1516 [self droppingURLsAt:location |
| 1517 givesIndex:&index |
| 1518 disposition:&disposition]; |
| 1519 |
| 1520 if (index == -1) { |
| 1521 // Append a tab at the end. |
| 1522 DCHECK(disposition == NEW_FOREGROUND_TAB); |
| 1523 // TODO(viettrungluu): ... |
| 1524 } else { |
| 1525 NSRect overRect = [[[tabArray_ objectAtIndex:index] view] frame]; |
| 1526 switch (disposition) { |
| 1527 case NEW_FOREGROUND_TAB: |
| 1528 // Insert tab (to the left of the given tab). |
| 1529 // TODO(viettrungluu): ... |
| 1530 break; |
| 1531 case CURRENT_TAB: |
| 1532 // Overwrite the given tab. |
| 1533 // TODO(viettrungluu): ... |
| 1534 break; |
| 1535 default: |
| 1536 NOTREACHED(); |
| 1537 } |
| 1538 } |
| 1539 |
| 1540 // TODO(viettrungluu): ... |
| 1541 #endif |
| 1542 } |
| 1543 |
| 1544 // Hide the indicator which indicates where an URL drop would happen. |
| 1545 - (void)hideDropURLsIndicator { |
| 1546 // TODO(viettrungluu): See TODO in |-indicateDropURLsAt:| above. |
| 1547 } |
| 1548 |
| 1404 - (GTMWindowSheetController*)sheetController { | 1549 - (GTMWindowSheetController*)sheetController { |
| 1405 if (!sheetController_.get()) | 1550 if (!sheetController_.get()) |
| 1406 sheetController_.reset([[GTMWindowSheetController alloc] | 1551 sheetController_.reset([[GTMWindowSheetController alloc] |
| 1407 initWithWindow:[switchView_ window] delegate:self]); | 1552 initWithWindow:[switchView_ window] delegate:self]); |
| 1408 return sheetController_.get(); | 1553 return sheetController_.get(); |
| 1409 } | 1554 } |
| 1410 | 1555 |
| 1411 - (void)gtm_systemRequestsVisibilityForView:(NSView*)view { | 1556 - (void)gtm_systemRequestsVisibilityForView:(NSView*)view { |
| 1412 // This implementation is required by GTMWindowSheetController. | 1557 // This implementation is required by GTMWindowSheetController. |
| 1413 | 1558 |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1496 // Show next sheet | 1641 // Show next sheet |
| 1497 NSWindowController* controller = [[tab window] windowController]; | 1642 NSWindowController* controller = [[tab window] windowController]; |
| 1498 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); | 1643 DCHECK([controller isKindOfClass:[BrowserWindowController class]]); |
| 1499 windows.front()->Realize( | 1644 windows.front()->Realize( |
| 1500 static_cast<BrowserWindowController*>(controller)); | 1645 static_cast<BrowserWindowController*>(controller)); |
| 1501 } | 1646 } |
| 1502 } | 1647 } |
| 1503 } | 1648 } |
| 1504 | 1649 |
| 1505 @end | 1650 @end |
| OLD | NEW |