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_drag_controller.h" | 5 #import "chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.h" |
6 | 6 |
7 #import "base/mac/mac_util.h" | 7 #import "base/mac/mac_util.h" |
8 #include "base/mac/scoped_cftyperef.h" | 8 #include "base/mac/scoped_cftyperef.h" |
9 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" | 9 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" |
10 #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" | 10 #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" |
(...skipping 22 matching lines...) Expand all Loading... |
33 | 33 |
34 const CGFloat kTearDistance = 36.0; | 34 const CGFloat kTearDistance = 36.0; |
35 const NSTimeInterval kTearDuration = 0.333; | 35 const NSTimeInterval kTearDuration = 0.333; |
36 | 36 |
37 @interface TabStripDragController (Private) | 37 @interface TabStripDragController (Private) |
38 - (void)resetDragControllers; | 38 - (void)resetDragControllers; |
39 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController; | 39 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController; |
40 - (void)setWindowBackgroundVisibility:(BOOL)shouldBeVisible; | 40 - (void)setWindowBackgroundVisibility:(BOOL)shouldBeVisible; |
41 - (void)endDrag:(NSEvent*)event; | 41 - (void)endDrag:(NSEvent*)event; |
42 - (void)continueDrag:(NSEvent*)event; | 42 - (void)continueDrag:(NSEvent*)event; |
43 // TODO(davidben): When we stop supporting 10.5, this can be removed. | |
44 - (int)getWorkspaceID:(NSWindow*)window useCache:(BOOL)useCache; | |
45 @end | 43 @end |
46 | 44 |
47 //////////////////////////////////////////////////////////////////////////////// | 45 //////////////////////////////////////////////////////////////////////////////// |
48 | 46 |
49 @implementation TabStripDragController | 47 @implementation TabStripDragController |
50 | 48 |
51 - (id)initWithTabStripController:(TabStripController*)controller { | 49 - (id)initWithTabStripController:(TabStripController*)controller { |
52 if ((self = [super init])) { | 50 if ((self = [super init])) { |
53 tabStrip_ = controller; | 51 tabStrip_ = controller; |
54 } | 52 } |
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 | 433 |
436 // Call to clear out transient weak references we hold during drags. | 434 // Call to clear out transient weak references we hold during drags. |
437 - (void)resetDragControllers { | 435 - (void)resetDragControllers { |
438 draggedTab_ = nil; | 436 draggedTab_ = nil; |
439 draggedController_ = nil; | 437 draggedController_ = nil; |
440 dragWindow_ = nil; | 438 dragWindow_ = nil; |
441 dragOverlay_ = nil; | 439 dragOverlay_ = nil; |
442 sourceController_ = nil; | 440 sourceController_ = nil; |
443 sourceWindow_ = nil; | 441 sourceWindow_ = nil; |
444 targetController_ = nil; | 442 targetController_ = nil; |
445 workspaceIDCache_.clear(); | |
446 } | 443 } |
447 | 444 |
448 // Returns an array of controllers that could be a drop target, ordered front to | 445 // Returns an array of controllers that could be a drop target, ordered front to |
449 // back. It has to be of the appropriate class, and visible (obviously). Note | 446 // back. It has to be of the appropriate class, and visible (obviously). Note |
450 // that the window cannot be a target for itself. | 447 // that the window cannot be a target for itself. |
451 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController { | 448 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController { |
452 NSMutableArray* targets = [NSMutableArray array]; | 449 NSMutableArray* targets = [NSMutableArray array]; |
453 NSWindow* dragWindow = [dragController window]; | 450 NSWindow* dragWindow = [dragController window]; |
454 for (NSWindow* window in [NSApp orderedWindows]) { | 451 for (NSWindow* window in [NSApp orderedWindows]) { |
455 if (window == dragWindow) continue; | 452 if (window == dragWindow) continue; |
456 if (![window isVisible]) continue; | 453 if (![window isVisible]) continue; |
457 // Skip windows on the wrong space. | 454 // Skip windows on the wrong space. |
458 if ([window respondsToSelector:@selector(isOnActiveSpace)]) { | 455 if (![window isOnActiveSpace]) |
459 if (![window performSelector:@selector(isOnActiveSpace)]) | 456 continue; |
460 continue; | |
461 } else { | |
462 // TODO(davidben): When we stop supporting 10.5, this can be | |
463 // removed. | |
464 // | |
465 // We don't cache the workspace of |dragWindow| because it may | |
466 // move around spaces. | |
467 if ([self getWorkspaceID:dragWindow useCache:NO] != | |
468 [self getWorkspaceID:window useCache:YES]) | |
469 continue; | |
470 } | |
471 NSWindowController* controller = [window windowController]; | 457 NSWindowController* controller = [window windowController]; |
472 if ([controller isKindOfClass:[TabWindowController class]]) { | 458 if ([controller isKindOfClass:[TabWindowController class]]) { |
473 TabWindowController* realController = | 459 TabWindowController* realController = |
474 static_cast<TabWindowController*>(controller); | 460 static_cast<TabWindowController*>(controller); |
475 if ([realController canReceiveFrom:dragController]) | 461 if ([realController canReceiveFrom:dragController]) |
476 [targets addObject:controller]; | 462 [targets addObject:controller]; |
477 } | 463 } |
478 } | 464 } |
479 return targets; | 465 return targets; |
480 } | 466 } |
(...skipping 17 matching lines...) Expand all Loading... |
498 [[draggedController_ overlayWindow] setHasShadow:YES]; | 484 [[draggedController_ overlayWindow] setHasShadow:YES]; |
499 [[targetController_ window] makeMainWindow]; | 485 [[targetController_ window] makeMainWindow]; |
500 } else { | 486 } else { |
501 [dragWindow_ setAlphaValue:0.5]; | 487 [dragWindow_ setAlphaValue:0.5]; |
502 [[draggedController_ overlayWindow] setHasShadow:NO]; | 488 [[draggedController_ overlayWindow] setHasShadow:NO]; |
503 [[draggedController_ window] makeMainWindow]; | 489 [[draggedController_ window] makeMainWindow]; |
504 } | 490 } |
505 chromeIsVisible_ = shouldBeVisible; | 491 chromeIsVisible_ = shouldBeVisible; |
506 } | 492 } |
507 | 493 |
508 // Returns the workspace id of |window|. If |useCache|, then lookup | |
509 // and remember the value in |workspaceIDCache_| until the end of the | |
510 // current drag. | |
511 - (int)getWorkspaceID:(NSWindow*)window useCache:(BOOL)useCache { | |
512 CGWindowID windowID = [window windowNumber]; | |
513 if (useCache) { | |
514 std::map<CGWindowID, int>::iterator iter = | |
515 workspaceIDCache_.find(windowID); | |
516 if (iter != workspaceIDCache_.end()) | |
517 return iter->second; | |
518 } | |
519 | |
520 int workspace = -1; | |
521 // It's possible to query in bulk, but probably not necessary. | |
522 base::mac::ScopedCFTypeRef<CFArrayRef> windowIDs(CFArrayCreate( | |
523 NULL, reinterpret_cast<const void **>(&windowID), 1, NULL)); | |
524 base::mac::ScopedCFTypeRef<CFArrayRef> descriptions( | |
525 CGWindowListCreateDescriptionFromArray(windowIDs)); | |
526 DCHECK(CFArrayGetCount(descriptions.get()) <= 1); | |
527 if (CFArrayGetCount(descriptions.get()) > 0) { | |
528 CFDictionaryRef dict = static_cast<CFDictionaryRef>( | |
529 CFArrayGetValueAtIndex(descriptions.get(), 0)); | |
530 DCHECK(CFGetTypeID(dict) == CFDictionaryGetTypeID()); | |
531 | |
532 // Sanity check the ID. | |
533 CFNumberRef otherIDRef = | |
534 base::mac::GetValueFromDictionary<CFNumberRef>(dict, kCGWindowNumber); | |
535 CGWindowID otherID; | |
536 if (otherIDRef && | |
537 CFNumberGetValue(otherIDRef, kCGWindowIDCFNumberType, &otherID) && | |
538 otherID == windowID) { | |
539 // And then get the workspace. | |
540 CFNumberRef workspaceRef = | |
541 base::mac::GetValueFromDictionary<CFNumberRef>(dict, | |
542 kCGWindowWorkspace); | |
543 if (!workspaceRef || | |
544 !CFNumberGetValue(workspaceRef, kCFNumberIntType, &workspace)) { | |
545 workspace = -1; | |
546 } | |
547 } else { | |
548 NOTREACHED(); | |
549 } | |
550 } | |
551 if (useCache) { | |
552 workspaceIDCache_[windowID] = workspace; | |
553 } | |
554 return workspace; | |
555 } | |
556 | |
557 @end | 494 @end |
OLD | NEW |