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

Unified Diff: chrome/browser/ui/cocoa/tabs/tab_view.mm

Issue 7080064: [Mac] Refactor the logic of tab dragging out of TabView and into a new helper. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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];

Powered by Google App Engine
This is Rietveld 408576698