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

Side by Side Diff: chrome/browser/ui/cocoa/tabs/tab_strip_drag_controller.mm

Issue 199663004: Mac: Fix crash when dragging tabs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: A better fix Created 6 years, 9 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "base/mac/sdk_forward_declarations.h" 9 #import "base/mac/sdk_forward_declarations.h"
10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h" 10 #import "chrome/browser/ui/cocoa/tabs/tab_controller.h"
11 #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h" 11 #import "chrome/browser/ui/cocoa/tabs/tab_controller_target.h"
12 #import "chrome/browser/ui/cocoa/tabs/tab_strip_view.h"
12 #import "chrome/browser/ui/cocoa/tabs/tab_view.h" 13 #import "chrome/browser/ui/cocoa/tabs/tab_view.h"
13 #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h" 14 #import "chrome/browser/ui/cocoa/tabs/tab_window_controller.h"
14 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h" 15 #import "chrome/browser/ui/cocoa/tabs/tab_strip_controller.h"
15 16
16 const CGFloat kTearDistance = 36.0; 17 const CGFloat kTearDistance = 36.0;
17 const NSTimeInterval kTearDuration = 0.333; 18 const NSTimeInterval kTearDuration = 0.333;
18 19
20 // Returns whether |screenPoint| is inside the bounds of |view|.
21 static BOOL PointIsInsideView(NSPoint screenPoint, NSView* view) {
22 if ([view window] == nil)
23 return NO;
24 NSPoint windowPoint = [[view window] convertScreenToBase:screenPoint];
25 NSPoint viewPoint = [view convertPoint:windowPoint fromView:nil];
26 return [view mouse:viewPoint inRect:[view bounds]];
27 }
28
19 @interface TabStripDragController (Private) 29 @interface TabStripDragController (Private)
20 - (void)resetDragControllers; 30 - (void)resetDragControllers;
21 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController; 31 - (NSArray*)dropTargetsForController:(TabWindowController*)dragController;
22 - (void)setWindowBackgroundVisibility:(BOOL)shouldBeVisible; 32 - (void)setWindowBackgroundVisibility:(BOOL)shouldBeVisible;
23 - (void)endDrag:(NSEvent*)event; 33 - (void)endDrag:(NSEvent*)event;
24 - (void)continueDrag:(NSEvent*)event; 34 - (void)continueDrag:(NSEvent*)event;
25 @end 35 @end
26 36
27 //////////////////////////////////////////////////////////////////////////////// 37 ////////////////////////////////////////////////////////////////////////////////
28 38
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 (tearForce > kTearDistance || !stillVisible)) { 190 (tearForce > kTearDistance || !stillVisible)) {
181 draggingWithinTabStrip_ = NO; 191 draggingWithinTabStrip_ = NO;
182 // When you finally leave the strip, we treat that as the origin. 192 // When you finally leave the strip, we treat that as the origin.
183 dragOrigin_.x = thisPoint.x; 193 dragOrigin_.x = thisPoint.x;
184 } else { 194 } else {
185 // Still dragging within the tab strip, wait for the next drag event. 195 // Still dragging within the tab strip, wait for the next drag event.
186 return; 196 return;
187 } 197 }
188 } 198 }
189 199
190 // Do not start dragging until the user has "torn" the tab off by
191 // moving more than 3 pixels.
Andre 2014/03/26 01:29:31 I think this comment is outdated. The distance is
192 NSPoint thisPoint = [NSEvent mouseLocation]; 200 NSPoint thisPoint = [NSEvent mouseLocation];
193 201
194 // Iterate over possible targets checking for the one the mouse is in. 202 // Iterate over possible targets checking for the one the mouse is in.
195 // If the tab is just in the frame, bring the window forward to make it 203 // If the tab is just in the frame, bring the window forward to make it
196 // easier to drop something there. If it's in the tab strip, set the new 204 // easier to drop something there. If it's in the tab strip, set the new
197 // target so that it pops into that window. We can't cache this because we 205 // target so that it pops into that window. We can't cache this because we
198 // need the z-order to be correct. 206 // need the z-order to be correct.
199 NSArray* targets = [self dropTargetsForController:draggedController_]; 207 NSArray* targets = [self dropTargetsForController:draggedController_];
200 TabWindowController* newTarget = nil; 208 TabWindowController* newTarget = nil;
201 for (TabWindowController* target in targets) { 209 for (TabWindowController* target in targets) {
202 NSRect windowFrame = [[target window] frame]; 210 NSRect windowFrame = [[target window] frame];
203 if (NSPointInRect(thisPoint, windowFrame)) { 211 if (NSPointInRect(thisPoint, windowFrame)) {
204 [[target window] orderFront:self]; 212 [[target window] orderFront:self];
205 NSRect tabStripFrame = [[target tabStripView] frame]; 213 if (PointIsInsideView(thisPoint, [target tabStripView])) {
206 tabStripFrame.origin = [[target window]
207 convertBaseToScreen:tabStripFrame.origin];
208 if (NSPointInRect(thisPoint, tabStripFrame)) {
209 newTarget = target; 214 newTarget = target;
210 } 215 }
211 break; 216 break;
212 } 217 }
213 } 218 }
214 219
215 // If we're now targeting a new window, re-layout the tabs in the old 220 // If we're now targeting a new window, re-layout the tabs in the old
216 // target and reset how long we've been hovering over this new one. 221 // target and reset how long we've been hovering over this new one.
217 if (targetController_ != newTarget) { 222 if (targetController_ != newTarget) {
218 [targetController_ removePlaceholder]; 223 [targetController_ removePlaceholder];
219 targetController_ = newTarget; 224 targetController_ = newTarget;
220 if (!newTarget) { 225 if (!newTarget) {
221 tearTime_ = [NSDate timeIntervalSinceReferenceDate]; 226 tearTime_ = [NSDate timeIntervalSinceReferenceDate];
222 tearOrigin_ = [dragWindow_ frame].origin; 227 tearOrigin_ = [dragWindow_ frame].origin;
223 } 228 }
224 } 229 }
225 230
226 // Create or identify the dragged controller. 231 // Create or identify the dragged controller.
227 if (!draggedController_) { 232 if (!draggedController_) {
228 // We don't want to remove the source window's placeholder here because the
229 // new tab button may briefly flash in and out if we remove and add back the
230 // placeholder.
231 // Instead, we will remove the placeholder later when the target window
232 // actually changes.
233 targetController_ = sourceController_;
234
235 // Detach from the current window and put it in a new window. If there are 233 // Detach from the current window and put it in a new window. If there are
236 // no more tabs remaining after detaching, the source window is about to 234 // no more tabs remaining after detaching, the source window is about to
237 // go away (it's been autoreleased) so we need to ensure we don't reference 235 // go away (it's been autoreleased) so we need to ensure we don't reference
238 // it any more. In that case the new controller becomes our source 236 // it any more. In that case the new controller becomes our source
239 // controller. 237 // controller.
240 NSArray* tabs = [draggedTab_ selected] ? [tabStrip_ selectedViews] 238 NSArray* tabs = [draggedTab_ selected] ? [tabStrip_ selectedViews]
241 : @[ [draggedTab_ tabView] ]; 239 : @[ [draggedTab_ tabView] ];
242 draggedController_ = 240 draggedController_ =
243 [sourceController_ detachTabsToNewWindow:tabs 241 [sourceController_ detachTabsToNewWindow:tabs
244 draggedTab:[draggedTab_ tabView]]; 242 draggedTab:[draggedTab_ tabView]];
245 243
246 dragWindow_ = [draggedController_ window]; 244 dragWindow_ = [draggedController_ window];
247 [dragWindow_ setAlphaValue:0.0]; 245 [dragWindow_ setAlphaValue:0.0];
248 if (![sourceController_ hasLiveTabs]) { 246 if ([sourceController_ hasLiveTabs]) {
247 if (PointIsInsideView(thisPoint, [sourceController_ tabStripView])) {
248 // We don't want to remove the source window's placeholder here because
249 // the new tab button may briefly flash in and out if we remove and add
250 // back the placeholder.
251 // Instead, we will remove the placeholder later when the target window
252 // actually changes.
253 targetController_ = sourceController_;
254 } else {
255 [sourceController_ removePlaceholder];
256 }
257 } else {
258 [sourceController_ removePlaceholder];
249 sourceController_ = draggedController_; 259 sourceController_ = draggedController_;
250 sourceWindow_ = dragWindow_; 260 sourceWindow_ = dragWindow_;
251 } 261 }
252 262
253 // Disable window animation before calling |orderFront:| when detaching 263 // Disable window animation before calling |orderFront:| when detaching
254 // to a new window. 264 // to a new window.
255 NSWindowAnimationBehavior savedAnimationBehavior = 265 NSWindowAnimationBehavior savedAnimationBehavior =
256 NSWindowAnimationBehaviorDefault; 266 NSWindowAnimationBehaviorDefault;
257 bool didSaveAnimationBehavior = false; 267 bool didSaveAnimationBehavior = false;
258 if ([dragWindow_ respondsToSelector:@selector(animationBehavior)] && 268 if ([dragWindow_ respondsToSelector:@selector(animationBehavior)] &&
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 [[targetController_ window] makeMainWindow]; 490 [[targetController_ window] makeMainWindow];
481 } else { 491 } else {
482 [dragWindow_ setAlphaValue:0.5]; 492 [dragWindow_ setAlphaValue:0.5];
483 [[draggedController_ overlayWindow] setHasShadow:NO]; 493 [[draggedController_ overlayWindow] setHasShadow:NO];
484 [[draggedController_ window] makeMainWindow]; 494 [[draggedController_ window] makeMainWindow];
485 } 495 }
486 chromeIsVisible_ = shouldBeVisible; 496 chromeIsVisible_ = shouldBeVisible;
487 } 497 }
488 498
489 @end 499 @end
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698