Index: chrome/browser/ui/cocoa/tabs/tab_view.mm |
diff --git a/chrome/browser/ui/cocoa/tabs/tab_view.mm b/chrome/browser/ui/cocoa/tabs/tab_view.mm |
index 15d1fdbbb446b9164509ba0a55e6440501a0fa47..4cb230ccf80e75f247e7093a32ce514dbd9093a6 100644 |
--- a/chrome/browser/ui/cocoa/tabs/tab_view.mm |
+++ b/chrome/browser/ui/cocoa/tabs/tab_view.mm |
@@ -5,8 +5,6 @@ |
#import "chrome/browser/ui/cocoa/tabs/tab_view.h" |
#include "base/logging.h" |
-#import "base/mac/mac_util.h" |
-#include "base/mac/scoped_cftyperef.h" |
#include "chrome/browser/themes/theme_service.h" |
#import "chrome/browser/ui/cocoa/nsview_additions.h" |
#import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
@@ -39,9 +37,6 @@ const NSTimeInterval kAlertHideDuration = 0.4; |
// increasing/decreasing). |
const NSTimeInterval kGlowUpdateInterval = 0.025; |
-const CGFloat kTearDistance = 36.0; |
-const NSTimeInterval kTearDuration = 0.333; |
- |
// This is used to judge whether the mouse has moved during rapid closure; if it |
// has moved less than the threshold, we want to close the tab. |
const CGFloat kRapidCloseDist = 2.5; |
@@ -53,8 +48,6 @@ const CGFloat kRapidCloseDist = 2.5; |
- (void)resetLastGlowUpdateTime; |
- (NSTimeInterval)timeElapsedSinceLastGlowUpdate; |
- (void)adjustGlowValue; |
-// TODO(davidben): When we stop supporting 10.5, this can be removed. |
-- (int)getWorkspaceID:(NSWindow*)window useCache:(BOOL)useCache; |
- (NSBezierPath*)bezierPathForRect:(NSRect)rect; |
@end // TabView(Private) |
@@ -153,86 +146,7 @@ const CGFloat kRapidCloseDist = 2.5; |
// Returns |YES| if this tab can be torn away into a new window. |
- (BOOL)canBeDragged { |
- if ([self isClosing]) |
- return NO; |
- NSWindowController* controller = [sourceWindow_ windowController]; |
- if ([controller isKindOfClass:[TabWindowController class]]) { |
- TabWindowController* realController = |
- static_cast<TabWindowController*>(controller); |
- return [realController isTabDraggable:self]; |
- } |
- return YES; |
-} |
- |
-// Returns an array of controllers that could be a drop target, ordered front to |
-// back. It has to be of the appropriate class, and visible (obviously). Note |
-// that the window cannot be a target for itself. |
-- (NSArray*)dropTargetsForController:(TabWindowController*)dragController { |
- NSMutableArray* targets = [NSMutableArray array]; |
- NSWindow* dragWindow = [dragController window]; |
- for (NSWindow* window in [NSApp orderedWindows]) { |
- if (window == dragWindow) continue; |
- if (![window isVisible]) continue; |
- // Skip windows on the wrong space. |
- if ([window respondsToSelector:@selector(isOnActiveSpace)]) { |
- if (![window performSelector:@selector(isOnActiveSpace)]) |
- continue; |
- } else { |
- // TODO(davidben): When we stop supporting 10.5, this can be |
- // removed. |
- // |
- // We don't cache the workspace of |dragWindow| because it may |
- // move around spaces. |
- if ([self getWorkspaceID:dragWindow useCache:NO] != |
- [self getWorkspaceID:window useCache:YES]) |
- continue; |
- } |
- NSWindowController* controller = [window windowController]; |
- if ([controller isKindOfClass:[TabWindowController class]]) { |
- TabWindowController* realController = |
- static_cast<TabWindowController*>(controller); |
- if ([realController canReceiveFrom:dragController]) |
- [targets addObject:controller]; |
- } |
- } |
- return targets; |
-} |
- |
-// Call to clear out transient weak references we hold during drags. |
-- (void)resetDragControllers { |
- draggedController_ = nil; |
- dragWindow_ = nil; |
- dragOverlay_ = nil; |
- sourceController_ = nil; |
- sourceWindow_ = nil; |
- targetController_ = nil; |
- workspaceIDCache_.clear(); |
-} |
- |
-// Sets whether the window background should be visible or invisible when |
-// dragging a tab. The background should be invisible when the mouse is over a |
-// potential drop target for the tab (the tab strip). It should be visible when |
-// there's no drop target so the window looks more fully realized and ready to |
-// become a stand-alone window. |
-- (void)setWindowBackgroundVisibility:(BOOL)shouldBeVisible { |
- if (chromeIsVisible_ == shouldBeVisible) |
- return; |
- |
- // There appears to be a race-condition in CoreAnimation where if we use |
- // animators to set the alpha values, we can't guarantee that we cancel them. |
- // This has the side effect of sometimes leaving the dragged window |
- // translucent or invisible. As a result, don't animate the alpha change. |
- [[draggedController_ overlayWindow] setAlphaValue:1.0]; |
- if (targetController_) { |
- [dragWindow_ setAlphaValue:0.0]; |
- [[draggedController_ overlayWindow] setHasShadow:YES]; |
- [[targetController_ window] makeMainWindow]; |
- } else { |
- [dragWindow_ setAlphaValue:0.5]; |
- [[draggedController_ overlayWindow] setHasShadow:NO]; |
- [[draggedController_ window] makeMainWindow]; |
- } |
- chromeIsVisible_ = shouldBeVisible; |
+ return [controller_ tabCanBeDragged:controller_]; |
} |
// Handle clicks and drags in this button. We get here because we have |
@@ -241,18 +155,20 @@ const CGFloat kRapidCloseDist = 2.5; |
if ([self isClosing]) |
return; |
- NSPoint downLocation = [theEvent locationInWindow]; |
+ // Record the point at which this event happened. This is used by other mouse |
+ // events that are dispatched from |-maybeStartDrag::|. |
+ mouseDownPoint_ = [theEvent locationInWindow]; |
// Record the state of the close button here, because selecting the tab will |
// unhide it. |
- BOOL closeButtonActive = [closeButton_ isHidden] ? NO : YES; |
+ BOOL closeButtonActive = ![closeButton_ isHidden]; |
// During the tab closure animation (in particular, during rapid tab closure), |
// we may get incorrectly hit with a mouse down. If it should have gone to the |
// close button, we send it there -- it should then track the mouse, so we |
// don't have to worry about mouse ups. |
if (closeButtonActive && [controller_ inRapidClosureMode]) { |
- NSPoint hitLocation = [[self superview] convertPoint:downLocation |
+ NSPoint hitLocation = [[self superview] convertPoint:mouseDownPoint_ |
fromView:nil]; |
if ([self hitTest:hitLocation] == closeButton_) { |
[closeButton_ mouseDown:theEvent]; |
@@ -260,376 +176,57 @@ const CGFloat kRapidCloseDist = 2.5; |
} |
} |
- [self resetDragControllers]; |
- |
- // Resolve overlay back to original window. |
- sourceWindow_ = [self window]; |
- if ([sourceWindow_ isKindOfClass:[NSPanel class]]) { |
- sourceWindow_ = [sourceWindow_ parentWindow]; |
- } |
- |
- sourceWindowFrame_ = [sourceWindow_ frame]; |
- sourceTabFrame_ = [self frame]; |
- sourceController_ = [sourceWindow_ windowController]; |
- tabWasDragged_ = NO; |
- tearTime_ = 0.0; |
- draggingWithinTabStrip_ = YES; |
- chromeIsVisible_ = NO; |
- |
- // If there's more than one potential window to be a drop target, we want to |
- // treat a drag of a tab just like dragging around a tab that's already |
- // detached. Note that unit tests might have |-numberOfTabs| reporting zero |
- // since the model won't be fully hooked up. We need to be prepared for that |
- // and not send them into the "magnetic" codepath. |
- NSArray* targets = [self dropTargetsForController:sourceController_]; |
- moveWindowOnDrag_ = |
- ([sourceController_ numberOfTabs] < 2 && ![targets count]) || |
- ![self canBeDragged] || |
- ![sourceController_ tabDraggingAllowed]; |
- // If we are dragging a tab, a window with a single tab should immediately |
- // snap off and not drag within the tab strip. |
- if (!moveWindowOnDrag_) |
- draggingWithinTabStrip_ = [sourceController_ numberOfTabs] > 1; |
- |
- dragOrigin_ = [NSEvent mouseLocation]; |
- |
// If the tab gets torn off, the tab controller will be removed from the tab |
// strip and then deallocated. This will also result in *us* being |
// deallocated. Both these are bad, so we prevent this by retaining the |
// controller. |
scoped_nsobject<TabController> controller([controller_ retain]); |
- // Because we move views between windows, we need to handle the event loop |
- // ourselves. Ideally we should use the standard event loop. |
- while (1) { |
- const NSUInteger mask = |
- NSLeftMouseUpMask | NSLeftMouseDraggedMask | NSKeyUpMask; |
- theEvent = |
- [NSApp nextEventMatchingMask:mask |
- untilDate:[NSDate distantFuture] |
- inMode:NSDefaultRunLoopMode dequeue:YES]; |
- NSEventType type = [theEvent type]; |
- if (type == NSKeyUp) { |
- if ([theEvent keyCode] == kVK_Escape) { |
- // Cancel the drag and restore the previous state. |
- if (draggingWithinTabStrip_) { |
- // Simply pretend the tab wasn't dragged (far enough). |
- tabWasDragged_ = NO; |
- } else { |
- [targetController_ removePlaceholder]; |
- if ([sourceController_ numberOfTabs] < 2) { |
- // Revert to a single-tab window. |
- targetController_ = nil; |
- } else { |
- // Change the target to the source controller. |
- targetController_ = sourceController_; |
- [targetController_ insertPlaceholderForTab:self |
- frame:sourceTabFrame_ |
- yStretchiness:0]; |
- } |
- } |
- // Call the |mouseUp:| code to end the drag. |
- [self mouseUp:theEvent]; |
- break; |
- } |
- } else if (type == NSLeftMouseDragged) { |
- [self mouseDragged:theEvent]; |
- } else if (type == NSLeftMouseUp) { |
- NSPoint upLocation = [theEvent locationInWindow]; |
- CGFloat dx = upLocation.x - downLocation.x; |
- CGFloat dy = upLocation.y - downLocation.y; |
- |
- // During rapid tab closure (mashing tab close buttons), we may get hit |
- // with a mouse down. As long as the mouse up is over the close button, |
- // and the mouse hasn't moved too much, we close the tab. |
- if (closeButtonActive && |
- (dx*dx + dy*dy) <= kRapidCloseDist*kRapidCloseDist && |
- [controller inRapidClosureMode]) { |
- NSPoint hitLocation = |
- [[self superview] convertPoint:[theEvent locationInWindow] |
- fromView:nil]; |
- if ([self hitTest:hitLocation] == closeButton_) { |
- [controller closeTab:self]; |
- break; |
- } |
- } |
+ // Try to initiate a drag. This will spin a custom event loop and may |
+ // dispatch other mouse events. |
+ [controller_ maybeStartDrag:theEvent forTab:controller]; |
- [self mouseUp:theEvent]; |
- break; |
- } else { |
- // TODO(viettrungluu): [crbug.com/23830] We can receive right-mouse-ups |
- // (and maybe even others?) for reasons I don't understand. So we |
- // explicitly check for both events we're expecting, and log others. We |
- // should figure out what's going on. |
- LOG(WARNING) << "Spurious event received of type " << type << "."; |
- } |
- } |
+ // The custom loop has ended, so clear the point. |
+ mouseDownPoint_ = NSZeroPoint; |
} |
- (void)mouseDragged:(NSEvent*)theEvent { |
- // Special-case this to keep the logic below simpler. |
- if (moveWindowOnDrag_) { |
- if ([sourceController_ windowMovementAllowed]) { |
- NSPoint thisPoint = [NSEvent mouseLocation]; |
- NSPoint origin = sourceWindowFrame_.origin; |
- origin.x += (thisPoint.x - dragOrigin_.x); |
- origin.y += (thisPoint.y - dragOrigin_.y); |
- [sourceWindow_ setFrameOrigin:NSMakePoint(origin.x, origin.y)]; |
- } // else do nothing. |
- return; |
- } |
- |
- // First, go through the magnetic drag cycle. We break out of this if |
- // "stretchiness" ever exceeds a set amount. |
- tabWasDragged_ = YES; |
- |
- if (draggingWithinTabStrip_) { |
- NSPoint thisPoint = [NSEvent mouseLocation]; |
- CGFloat stretchiness = thisPoint.y - dragOrigin_.y; |
- stretchiness = copysign(sqrtf(fabs(stretchiness))/sqrtf(kTearDistance), |
- stretchiness) / 2.0; |
- CGFloat offset = thisPoint.x - dragOrigin_.x; |
- if (fabsf(offset) > 100) stretchiness = 0; |
- [sourceController_ insertPlaceholderForTab:self |
- frame:NSOffsetRect(sourceTabFrame_, |
- offset, 0) |
- yStretchiness:stretchiness]; |
- // Check that we haven't pulled the tab too far to start a drag. This |
- // can include either pulling it too far down, or off the side of the tab |
- // strip that would cause it to no longer be fully visible. |
- BOOL stillVisible = [sourceController_ isTabFullyVisible:self]; |
- CGFloat tearForce = fabs(thisPoint.y - dragOrigin_.y); |
- if ([sourceController_ tabTearingAllowed] && |
- (tearForce > kTearDistance || !stillVisible)) { |
- draggingWithinTabStrip_ = NO; |
- // When you finally leave the strip, we treat that as the origin. |
- dragOrigin_.x = thisPoint.x; |
- } else { |
- // Still dragging within the tab strip, wait for the next drag event. |
- return; |
- } |
- } |
- |
- // Do not start dragging until the user has "torn" the tab off by |
- // moving more than 3 pixels. |
- NSDate* targetDwellDate = nil; // The date this target was first chosen. |
- |
- NSPoint thisPoint = [NSEvent mouseLocation]; |
- |
- // Iterate over possible targets checking for the one the mouse is in. |
- // If the tab is just in the frame, bring the window forward to make it |
- // easier to drop something there. If it's in the tab strip, set the new |
- // target so that it pops into that window. We can't cache this because we |
- // need the z-order to be correct. |
- NSArray* targets = [self dropTargetsForController:draggedController_]; |
- TabWindowController* newTarget = nil; |
- for (TabWindowController* target in targets) { |
- NSRect windowFrame = [[target window] frame]; |
- if (NSPointInRect(thisPoint, windowFrame)) { |
- [[target window] orderFront:self]; |
- NSRect tabStripFrame = [[target tabStripView] frame]; |
- tabStripFrame.origin = [[target window] |
- convertBaseToScreen:tabStripFrame.origin]; |
- if (NSPointInRect(thisPoint, tabStripFrame)) { |
- newTarget = target; |
- } |
- break; |
- } |
- } |
- |
- // If we're now targeting a new window, re-layout the tabs in the old |
- // target and reset how long we've been hovering over this new one. |
- if (targetController_ != newTarget) { |
- targetDwellDate = [NSDate date]; |
- [targetController_ removePlaceholder]; |
- targetController_ = newTarget; |
- if (!newTarget) { |
- tearTime_ = [NSDate timeIntervalSinceReferenceDate]; |
- tearOrigin_ = [dragWindow_ frame].origin; |
- } |
- } |
- |
- // Create or identify the dragged controller. |
- if (!draggedController_) { |
- // Get rid of any placeholder remaining in the original source window. |
- [sourceController_ removePlaceholder]; |
- |
- // Detach from the current window and put it in a new window. If there are |
- // no more tabs remaining after detaching, the source window is about to |
- // go away (it's been autoreleased) so we need to ensure we don't reference |
- // it any more. In that case the new controller becomes our source |
- // controller. |
- draggedController_ = [sourceController_ detachTabToNewWindow:self]; |
- dragWindow_ = [draggedController_ window]; |
- [dragWindow_ setAlphaValue:0.0]; |
- if (![sourceController_ hasLiveTabs]) { |
- sourceController_ = draggedController_; |
- sourceWindow_ = dragWindow_; |
- } |
- |
- // If dragging the tab only moves the current window, do not show overlay |
- // so that sheets stay on top of the window. |
- // Bring the target window to the front and make sure it has a border. |
- [dragWindow_ setLevel:NSFloatingWindowLevel]; |
- [dragWindow_ setHasShadow:YES]; |
- [dragWindow_ orderFront:nil]; |
- [dragWindow_ makeMainWindow]; |
- [draggedController_ showOverlay]; |
- dragOverlay_ = [draggedController_ overlayWindow]; |
- // Force the new tab button to be hidden. We'll reset it on mouse up. |
- [draggedController_ showNewTabButton:NO]; |
- tearTime_ = [NSDate timeIntervalSinceReferenceDate]; |
- tearOrigin_ = sourceWindowFrame_.origin; |
- } |
- |
- // TODO(pinkerton): http://crbug.com/25682 demonstrates a way to get here by |
- // some weird circumstance that doesn't first go through mouseDown:. We |
- // really shouldn't go any farther. |
- if (!draggedController_ || !sourceController_) |
- return; |
- |
- // When the user first tears off the window, we want slide the window to |
- // the current mouse location (to reduce the jarring appearance). We do this |
- // by calling ourselves back with additional mouseDragged calls (not actual |
- // events). |tearProgress| is a normalized measure of how far through this |
- // tear "animation" (of length kTearDuration) we are and has values [0..1]. |
- // We use sqrt() so the animation is non-linear (slow down near the end |
- // point). |
- NSTimeInterval tearProgress = |
- [NSDate timeIntervalSinceReferenceDate] - tearTime_; |
- tearProgress /= kTearDuration; // Normalize. |
- tearProgress = sqrtf(MAX(MIN(tearProgress, 1.0), 0.0)); |
- |
- // Move the dragged window to the right place on the screen. |
- NSPoint origin = sourceWindowFrame_.origin; |
- origin.x += (thisPoint.x - dragOrigin_.x); |
- origin.y += (thisPoint.y - dragOrigin_.y); |
- |
- if (tearProgress < 1) { |
- // If the tear animation is not complete, call back to ourself with the |
- // same event to animate even if the mouse isn't moving. We need to make |
- // sure these get cancelled in mouseUp:. |
- [NSObject cancelPreviousPerformRequestsWithTarget:self]; |
- [self performSelector:@selector(mouseDragged:) |
- withObject:theEvent |
- afterDelay:1.0f/30.0f]; |
- |
- // Set the current window origin based on how far we've progressed through |
- // the tear animation. |
- origin.x = (1 - tearProgress) * tearOrigin_.x + tearProgress * origin.x; |
- origin.y = (1 - tearProgress) * tearOrigin_.y + tearProgress * origin.y; |
- } |
- |
- if (targetController_) { |
- // In order to "snap" two windows of different sizes together at their |
- // toolbar, we can't just use the origin of the target frame. We also have |
- // to take into consideration the difference in height. |
- NSRect targetFrame = [[targetController_ window] frame]; |
- NSRect sourceFrame = [dragWindow_ frame]; |
- origin.y = NSMinY(targetFrame) + |
- (NSHeight(targetFrame) - NSHeight(sourceFrame)); |
- } |
- [dragWindow_ setFrameOrigin:NSMakePoint(origin.x, origin.y)]; |
- |
- // If we're not hovering over any window, make the window fully |
- // opaque. Otherwise, find where the tab might be dropped and insert |
- // a placeholder so it appears like it's part of that window. |
- if (targetController_) { |
- if (![[targetController_ window] isKeyWindow]) { |
- // && ([targetDwellDate timeIntervalSinceNow] < -REQUIRED_DWELL)) { |
- [[targetController_ window] orderFront:nil]; |
- targetDwellDate = nil; |
- } |
- |
- // Compute where placeholder should go and insert it into the |
- // destination tab strip. |
- TabView* draggedTabView = (TabView*)[draggedController_ activeTabView]; |
- NSRect tabFrame = [draggedTabView frame]; |
- tabFrame.origin = [dragWindow_ convertBaseToScreen:tabFrame.origin]; |
- tabFrame.origin = [[targetController_ window] |
- convertScreenToBase:tabFrame.origin]; |
- tabFrame = [[targetController_ tabStripView] |
- convertRect:tabFrame fromView:nil]; |
- [targetController_ insertPlaceholderForTab:self |
- frame:tabFrame |
- yStretchiness:0]; |
- [targetController_ layoutTabs]; |
- } else { |
- [dragWindow_ makeKeyAndOrderFront:nil]; |
- } |
- |
- // Adjust the visibility of the window background. If there is a drop target, |
- // we want to hide the window background so the tab stands out for |
- // positioning. If not, we want to show it so it looks like a new window will |
- // be realized. |
- BOOL chromeShouldBeVisible = targetController_ == nil; |
- [self setWindowBackgroundVisibility:chromeShouldBeVisible]; |
+ [controller_ continueDrag:theEvent]; |
} |
- (void)mouseUp:(NSEvent*)theEvent { |
- // The drag/click is done. If the user dragged the mouse, finalize the drag |
- // and clean up. |
- |
// Fire the action to select the tab. |
if ([[controller_ target] respondsToSelector:[controller_ action]]) |
[[controller_ target] performSelector:[controller_ action] |
withObject:self]; |
- // Special-case this to keep the logic below simpler. |
- if (moveWindowOnDrag_) |
- return; |
- |
- // Cancel any delayed -mouseDragged: requests that may still be pending. |
- [NSObject cancelPreviousPerformRequestsWithTarget:self]; |
- |
- // TODO(pinkerton): http://crbug.com/25682 demonstrates a way to get here by |
- // some weird circumstance that doesn't first go through mouseDown:. We |
- // really shouldn't go any farther. |
- if (!sourceController_) |
- return; |
- |
- // We are now free to re-display the new tab button in the window we're |
- // dragging. It will show when the next call to -layoutTabs (which happens |
- // indrectly by several of the calls below, such as removing the placeholder). |
- [draggedController_ showNewTabButton:YES]; |
- |
- if (draggingWithinTabStrip_) { |
- if (tabWasDragged_) { |
- // Move tab to new location. |
- DCHECK([sourceController_ numberOfTabs]); |
- TabWindowController* dropController = sourceController_; |
- [dropController moveTabView:[dropController activeTabView] |
- fromController:nil]; |
- } |
- } else if (targetController_) { |
- // Move between windows. If |targetController_| is nil, we're not dropping |
- // into any existing window. |
- NSView* draggedTabView = [draggedController_ activeTabView]; |
- [targetController_ moveTabView:draggedTabView |
- fromController:draggedController_]; |
- // Force redraw to avoid flashes of old content before returning to event |
- // loop. |
- [[targetController_ window] display]; |
- [targetController_ showWindow:nil]; |
- [draggedController_ removeOverlay]; |
- } else { |
- // Only move the window around on screen. Make sure it's set back to |
- // normal state (fully opaque, has shadow, has key, etc). |
- [draggedController_ removeOverlay]; |
- // Don't want to re-show the window if it was closed during the drag. |
- if ([dragWindow_ isVisible]) { |
- [dragWindow_ setAlphaValue:1.0]; |
- [dragOverlay_ setHasShadow:NO]; |
- [dragWindow_ setHasShadow:YES]; |
- [dragWindow_ makeKeyAndOrderFront:nil]; |
+ // Check for rapid tab closure. |
+ if ([theEvent type] == NSLeftMouseUp) { |
+ NSPoint upLocation = [theEvent locationInWindow]; |
+ CGFloat dx = upLocation.x - mouseDownPoint_.x; |
+ CGFloat dy = upLocation.y - mouseDownPoint_.y; |
+ |
+ // During rapid tab closure (mashing tab close buttons), we may get hit |
+ // with a mouse down. As long as the mouse up is over the close button, |
+ // and the mouse hasn't moved too much, we close the tab. |
+ if (![closeButton_ isHidden] && |
+ (dx*dx + dy*dy) <= kRapidCloseDist*kRapidCloseDist && |
+ [controller_ inRapidClosureMode]) { |
+ NSPoint hitLocation = |
+ [[self superview] convertPoint:[theEvent locationInWindow] |
+ fromView:nil]; |
+ if ([self hitTest:hitLocation] == closeButton_) { |
+ [controller_ closeTab:self]; |
+ } |
} |
- [[draggedController_ window] setLevel:NSNormalWindowLevel]; |
- [draggedController_ removePlaceholder]; |
} |
- [sourceController_ removePlaceholder]; |
- chromeIsVisible_ = YES; |
- [self resetDragControllers]; |
+ // Messaging the drag controller with |-endDrag:| would seem like the right |
+ // thing to do here. But, when a tab has been detached, the controller's |
+ // target is nil until the drag is finalized. Since |-mouseUp:| gets called |
+ // via the manual event loop inside -[TabStripDragController |
+ // maybeStartDrag:forTab:], the drag controller can end the dragging session |
+ // itself directly after calling this. |
} |
- (void)otherMouseUp:(NSEvent*)theEvent { |
@@ -972,54 +569,6 @@ const CGFloat kRapidCloseDist = 2.5; |
[self setNeedsDisplay:YES]; |
} |
-// Returns the workspace id of |window|. If |useCache|, then lookup |
-// and remember the value in |workspaceIDCache_| until the end of the |
-// current drag. |
-- (int)getWorkspaceID:(NSWindow*)window useCache:(BOOL)useCache { |
- CGWindowID windowID = [window windowNumber]; |
- if (useCache) { |
- std::map<CGWindowID, int>::iterator iter = |
- workspaceIDCache_.find(windowID); |
- if (iter != workspaceIDCache_.end()) |
- return iter->second; |
- } |
- |
- int workspace = -1; |
- // It's possible to query in bulk, but probably not necessary. |
- base::mac::ScopedCFTypeRef<CFArrayRef> windowIDs(CFArrayCreate( |
- NULL, reinterpret_cast<const void **>(&windowID), 1, NULL)); |
- base::mac::ScopedCFTypeRef<CFArrayRef> descriptions( |
- CGWindowListCreateDescriptionFromArray(windowIDs)); |
- DCHECK(CFArrayGetCount(descriptions.get()) <= 1); |
- if (CFArrayGetCount(descriptions.get()) > 0) { |
- CFDictionaryRef dict = static_cast<CFDictionaryRef>( |
- CFArrayGetValueAtIndex(descriptions.get(), 0)); |
- DCHECK(CFGetTypeID(dict) == CFDictionaryGetTypeID()); |
- |
- // Sanity check the ID. |
- CFNumberRef otherIDRef = (CFNumberRef)base::mac::GetValueFromDictionary( |
- dict, kCGWindowNumber, CFNumberGetTypeID()); |
- CGWindowID otherID; |
- if (otherIDRef && |
- CFNumberGetValue(otherIDRef, kCGWindowIDCFNumberType, &otherID) && |
- otherID == windowID) { |
- // And then get the workspace. |
- CFNumberRef workspaceRef = (CFNumberRef)base::mac::GetValueFromDictionary( |
- dict, kCGWindowWorkspace, CFNumberGetTypeID()); |
- if (!workspaceRef || |
- !CFNumberGetValue(workspaceRef, kCFNumberIntType, &workspace)) { |
- workspace = -1; |
- } |
- } else { |
- NOTREACHED(); |
- } |
- } |
- if (useCache) { |
- workspaceIDCache_[windowID] = workspace; |
- } |
- return workspace; |
-} |
- |
// Returns the bezier path used to draw the tab given the bounds to draw it in. |
- (NSBezierPath*)bezierPathForRect:(NSRect)rect { |
const CGFloat lineWidth = [self cr_lineWidth]; |