| 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/download/download_shelf_controller.h" | 5 #import "chrome/browser/ui/cocoa/download/download_shelf_controller.h" |
| 6 | 6 |
| 7 #include "base/mac/bundle_locations.h" | 7 #include "base/mac/bundle_locations.h" |
| 8 #include "base/mac/mac_util.h" | 8 #include "base/mac/mac_util.h" |
| 9 #include "base/strings/sys_string_conversions.h" | 9 #include "base/strings/sys_string_conversions.h" |
| 10 #include "chrome/browser/download/download_util.h" | 10 #include "chrome/browser/download/download_util.h" |
| (...skipping 13 matching lines...) Expand all Loading... |
| 24 #include "content/public/browser/download_manager.h" | 24 #include "content/public/browser/download_manager.h" |
| 25 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" | 25 #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" |
| 26 #import "ui/base/cocoa/hover_button.h" | 26 #import "ui/base/cocoa/hover_button.h" |
| 27 #include "ui/base/l10n/l10n_util.h" | 27 #include "ui/base/l10n/l10n_util.h" |
| 28 | 28 |
| 29 using content::DownloadItem; | 29 using content::DownloadItem; |
| 30 | 30 |
| 31 // Download shelf autoclose behavior: | 31 // Download shelf autoclose behavior: |
| 32 // | 32 // |
| 33 // The download shelf autocloses if all of this is true: | 33 // The download shelf autocloses if all of this is true: |
| 34 // 1) An item on the shelf has just been opened. | 34 // 1) An item on the shelf has just been opened or removed. |
| 35 // 2) All remaining items on the shelf have been opened in the past. | 35 // 2) All remaining items on the shelf have been opened in the past. |
| 36 // 3) The mouse leaves the shelf and remains off the shelf for 5 seconds. | 36 // 3) The mouse leaves the shelf and remains off the shelf for 5 seconds. |
| 37 // | 37 // |
| 38 // If the mouse re-enters the shelf within the 5 second grace period, the | 38 // If the mouse re-enters the shelf within the 5 second grace period, the |
| 39 // autoclose is canceled. An autoclose can only be scheduled in response to a | 39 // autoclose is canceled. An autoclose can only be scheduled in response to a |
| 40 // shelf item being opened or removed. If an item is opened and then the | 40 // shelf item being opened or removed. If an item is opened and then the |
| 41 // resulting autoclose is canceled, subsequent mouse exited events will NOT | 41 // resulting autoclose is canceled, subsequent mouse exited events will NOT |
| 42 // trigger an autoclose. | 42 // trigger an autoclose. |
| 43 // | 43 // |
| 44 // If the shelf is manually closed while a download is still in progress, that | 44 // If the shelf is manually closed while a download is still in progress, that |
| (...skipping 19 matching lines...) Expand all Loading... |
| 64 // Amount of time between when the mouse is moved off the shelf and the shelf is | 64 // Amount of time between when the mouse is moved off the shelf and the shelf is |
| 65 // autoclosed, in seconds. | 65 // autoclosed, in seconds. |
| 66 const NSTimeInterval kAutoCloseDelaySeconds = 5; | 66 const NSTimeInterval kAutoCloseDelaySeconds = 5; |
| 67 | 67 |
| 68 // The size of the x button by default. | 68 // The size of the x button by default. |
| 69 const NSSize kHoverCloseButtonDefaultSize = { 18, 18 }; | 69 const NSSize kHoverCloseButtonDefaultSize = { 18, 18 }; |
| 70 | 70 |
| 71 } // namespace | 71 } // namespace |
| 72 | 72 |
| 73 @interface DownloadShelfController(Private) | 73 @interface DownloadShelfController(Private) |
| 74 - (void)removeDownload:(DownloadItemController*)download |
| 75 isShelfClosing:(BOOL)isShelfClosing; |
| 74 - (void)layoutItems:(BOOL)skipFirst; | 76 - (void)layoutItems:(BOOL)skipFirst; |
| 75 - (void)closed; | 77 - (void)closed; |
| 76 - (void)maybeAutoCloseAfterDelay; | 78 - (void)maybeAutoCloseAfterDelay; |
| 79 - (void)scheduleAutoClose; |
| 80 - (void)cancelAutoClose; |
| 77 - (void)autoClose; | 81 - (void)autoClose; |
| 78 - (void)viewFrameDidChange:(NSNotification*)notification; | 82 - (void)viewFrameDidChange:(NSNotification*)notification; |
| 79 - (void)installTrackingArea; | 83 - (void)installTrackingArea; |
| 80 - (void)cancelAutoCloseAndRemoveTrackingArea; | 84 - (void)removeTrackingArea; |
| 81 - (void)willEnterFullscreen; | 85 - (void)willEnterFullscreen; |
| 82 - (void)willLeaveFullscreen; | 86 - (void)willLeaveFullscreen; |
| 83 - (void)updateCloseButton; | 87 - (void)updateCloseButton; |
| 84 @end | 88 @end |
| 85 | 89 |
| 86 | 90 |
| 87 @implementation DownloadShelfController | 91 @implementation DownloadShelfController |
| 88 | 92 |
| 89 - (id)initWithBrowser:(Browser*)browser | 93 - (id)initWithBrowser:(Browser*)browser |
| 90 resizeDelegate:(id<ViewResizer>)resizeDelegate { | 94 resizeDelegate:(id<ViewResizer>)resizeDelegate { |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 129 // These notifications are declared in fullscreen_controller, and are posted | 133 // These notifications are declared in fullscreen_controller, and are posted |
| 130 // without objects. | 134 // without objects. |
| 131 [defaultCenter addObserver:self | 135 [defaultCenter addObserver:self |
| 132 selector:@selector(willEnterFullscreen) | 136 selector:@selector(willEnterFullscreen) |
| 133 name:kWillEnterFullscreenNotification | 137 name:kWillEnterFullscreenNotification |
| 134 object:nil]; | 138 object:nil]; |
| 135 [defaultCenter addObserver:self | 139 [defaultCenter addObserver:self |
| 136 selector:@selector(willLeaveFullscreen) | 140 selector:@selector(willLeaveFullscreen) |
| 137 name:kWillLeaveFullscreenNotification | 141 name:kWillLeaveFullscreenNotification |
| 138 object:nil]; | 142 object:nil]; |
| 143 [self installTrackingArea]; |
| 139 } | 144 } |
| 140 | 145 |
| 141 - (void)dealloc { | 146 - (void)dealloc { |
| 142 [[NSNotificationCenter defaultCenter] removeObserver:self]; | 147 [[NSNotificationCenter defaultCenter] removeObserver:self]; |
| 143 [self cancelAutoCloseAndRemoveTrackingArea]; | 148 [self removeTrackingArea]; |
| 144 | 149 |
| 145 // The controllers will unregister themselves as observers when they are | 150 // The controllers will unregister themselves as observers when they are |
| 146 // deallocated. No need to do that here. | 151 // deallocated. No need to do that here. |
| 147 [super dealloc]; | 152 [super dealloc]; |
| 148 } | 153 } |
| 149 | 154 |
| 150 // Called after the frame's rect has changed; usually when the height is | 155 // Called after the frame's rect has changed; usually when the height is |
| 151 // animated. | 156 // animated. |
| 152 - (void)viewFrameDidChange:(NSNotification*)notification { | 157 - (void)viewFrameDidChange:(NSNotification*)notification { |
| 153 // Anchor subviews at the top of |view|, so that it looks like the shelf | 158 // Anchor subviews at the top of |view|, so that it looks like the shelf |
| (...skipping 16 matching lines...) Expand all Loading... |
| 170 | 175 |
| 171 - (IBAction)showDownloadsTab:(id)sender { | 176 - (IBAction)showDownloadsTab:(id)sender { |
| 172 chrome::ShowDownloads(bridge_->browser()); | 177 chrome::ShowDownloads(bridge_->browser()); |
| 173 } | 178 } |
| 174 | 179 |
| 175 - (IBAction)handleClose:(id)sender { | 180 - (IBAction)handleClose:(id)sender { |
| 176 bridge_->Close(DownloadShelf::USER_ACTION); | 181 bridge_->Close(DownloadShelf::USER_ACTION); |
| 177 } | 182 } |
| 178 | 183 |
| 179 - (void)remove:(DownloadItemController*)download { | 184 - (void)remove:(DownloadItemController*)download { |
| 185 [self removeDownload:download |
| 186 isShelfClosing:NO]; |
| 187 } |
| 188 |
| 189 - (void)removeDownload:(DownloadItemController*)download |
| 190 isShelfClosing:(BOOL)isShelfClosing { |
| 180 // Look for the download in our controller array and remove it. This will | 191 // Look for the download in our controller array and remove it. This will |
| 181 // explicity release it so that it removes itself as an Observer of the | 192 // explicity release it so that it removes itself as an Observer of the |
| 182 // DownloadItem. We don't want to wait for autorelease since the DownloadItem | 193 // DownloadItem. We don't want to wait for autorelease since the DownloadItem |
| 183 // we are observing will likely be gone by then. | 194 // we are observing will likely be gone by then. |
| 184 [[NSNotificationCenter defaultCenter] removeObserver:download]; | 195 [[NSNotificationCenter defaultCenter] removeObserver:download]; |
| 185 | 196 |
| 186 // TODO(dmaclach): Remove -- http://crbug.com/25845 | 197 // TODO(dmaclach): Remove -- http://crbug.com/25845 |
| 187 [[download view] removeFromSuperview]; | 198 [[download view] removeFromSuperview]; |
| 188 | 199 |
| 189 [downloadItemControllers_ removeObject:download]; | 200 [downloadItemControllers_ removeObject:download]; |
| 190 [self layoutItems]; | |
| 191 | 201 |
| 192 // If there are no more downloads or if all the remaining downloads have been | 202 if (!isShelfClosing) { |
| 193 // opened, we can close the shelf. | 203 [self layoutItems]; |
| 194 [self maybeAutoCloseAfterDelay]; | 204 |
| 205 // If there are no more downloads or if all the remaining downloads have |
| 206 // been opened, we can close the shelf. |
| 207 [self maybeAutoCloseAfterDelay]; |
| 208 } |
| 195 } | 209 } |
| 196 | 210 |
| 197 - (void)downloadWasOpened:(DownloadItemController*)item_controller { | 211 - (void)downloadWasOpened:(DownloadItemController*)item_controller { |
| 198 // This should only be called on the main thead. | 212 // This should only be called on the main thead. |
| 199 DCHECK([NSThread isMainThread]); | 213 DCHECK([NSThread isMainThread]); |
| 200 [self maybeAutoCloseAfterDelay]; | 214 [self maybeAutoCloseAfterDelay]; |
| 201 } | 215 } |
| 202 | 216 |
| 203 // We need to explicitly release our download controllers here since they need | 217 // We need to explicitly release our download controllers here since they need |
| 204 // to remove themselves as observers before the remaining shutdown happens. | 218 // to remove themselves as observers before the remaining shutdown happens. |
| 205 - (void)exiting { | 219 - (void)exiting { |
| 206 [[self animatableView] stopAnimation]; | 220 [[self animatableView] stopAnimation]; |
| 207 [self cancelAutoCloseAndRemoveTrackingArea]; | 221 [self removeTrackingArea]; |
| 222 while ([downloadItemControllers_ count] > 0) { |
| 223 [self removeDownload:[downloadItemControllers_ lastObject] |
| 224 isShelfClosing:YES]; |
| 225 } |
| 208 downloadItemControllers_.reset(); | 226 downloadItemControllers_.reset(); |
| 209 } | 227 } |
| 210 | 228 |
| 211 - (void)showDownloadShelf:(BOOL)show | 229 - (void)showDownloadShelf:(BOOL)show |
| 212 isUserAction:(BOOL)isUserAction { | 230 isUserAction:(BOOL)isUserAction { |
| 231 shouldCloseOnMouseExit_ = NO; |
| 232 |
| 213 if ([self isVisible] == show) | 233 if ([self isVisible] == show) |
| 214 return; | 234 return; |
| 215 | 235 |
| 216 if (!show) { | 236 if (!show) { |
| 217 [self cancelAutoCloseAndRemoveTrackingArea]; | |
| 218 int numInProgress = 0; | 237 int numInProgress = 0; |
| 219 for (NSUInteger i = 0; i < [downloadItemControllers_ count]; ++i) { | 238 for (NSUInteger i = 0; i < [downloadItemControllers_ count]; ++i) { |
| 220 if ([[downloadItemControllers_ objectAtIndex:i]download]->IsInProgress()) | 239 if ([[downloadItemControllers_ objectAtIndex:i]download]->IsInProgress()) |
| 221 ++numInProgress; | 240 ++numInProgress; |
| 222 } | 241 } |
| 223 download_util::RecordShelfClose( | 242 download_util::RecordShelfClose( |
| 224 [downloadItemControllers_ count], numInProgress, !isUserAction); | 243 [downloadItemControllers_ count], numInProgress, !isUserAction); |
| 225 } | 244 } |
| 226 | 245 |
| 227 // Animate the shelf out, but not in. | 246 // Animate the shelf out, but not in. |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 skipFirst = NO; | 289 skipFirst = NO; |
| 271 } | 290 } |
| 272 } | 291 } |
| 273 | 292 |
| 274 - (void)layoutItems { | 293 - (void)layoutItems { |
| 275 [self layoutItems:NO]; | 294 [self layoutItems:NO]; |
| 276 } | 295 } |
| 277 | 296 |
| 278 - (void)addDownloadItem:(DownloadItem*)downloadItem { | 297 - (void)addDownloadItem:(DownloadItem*)downloadItem { |
| 279 DCHECK([NSThread isMainThread]); | 298 DCHECK([NSThread isMainThread]); |
| 280 [self cancelAutoCloseAndRemoveTrackingArea]; | |
| 281 | |
| 282 // Insert new item at the left. | |
| 283 scoped_nsobject<DownloadItemController> controller( | 299 scoped_nsobject<DownloadItemController> controller( |
| 284 [[DownloadItemController alloc] initWithDownload:downloadItem | 300 [[DownloadItemController alloc] initWithDownload:downloadItem |
| 285 shelf:self | 301 shelf:self |
| 286 navigator:navigator_]); | 302 navigator:navigator_]); |
| 303 [self add:controller.get()]; |
| 304 } |
| 287 | 305 |
| 306 - (void)add:(DownloadItemController*)controller { |
| 307 DCHECK([NSThread isMainThread]); |
| 308 shouldCloseOnMouseExit_ = NO; |
| 309 |
| 310 // Insert new item at the left. |
| 288 // Adding at index 0 in NSMutableArrays is O(1). | 311 // Adding at index 0 in NSMutableArrays is O(1). |
| 289 [downloadItemControllers_ insertObject:controller.get() atIndex:0]; | 312 [downloadItemControllers_ insertObject:controller atIndex:0]; |
| 290 | 313 |
| 291 [itemContainerView_ addSubview:[controller view]]; | 314 [itemContainerView_ addSubview:[controller view]]; |
| 292 | 315 |
| 293 // The controller is in charge of removing itself as an observer in its | 316 // The controller is in charge of removing itself as an observer in its |
| 294 // dealloc. | 317 // dealloc. |
| 295 [[NSNotificationCenter defaultCenter] | 318 [[NSNotificationCenter defaultCenter] |
| 296 addObserver:controller | 319 addObserver:controller |
| 297 selector:@selector(updateVisibility:) | 320 selector:@selector(updateVisibility:) |
| 298 name:NSViewFrameDidChangeNotification | 321 name:NSViewFrameDidChangeNotification |
| 299 object:[controller view]]; | 322 object:[controller view]]; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 317 [[[controller view] animator] setFrame:frame]; | 340 [[[controller view] animator] setFrame:frame]; |
| 318 [NSAnimationContext endGrouping]; | 341 [NSAnimationContext endGrouping]; |
| 319 | 342 |
| 320 // Keep only a limited number of items in the shelf. | 343 // Keep only a limited number of items in the shelf. |
| 321 if ([downloadItemControllers_ count] > kMaxDownloadItemCount) { | 344 if ([downloadItemControllers_ count] > kMaxDownloadItemCount) { |
| 322 DCHECK(kMaxDownloadItemCount > 0); | 345 DCHECK(kMaxDownloadItemCount > 0); |
| 323 | 346 |
| 324 // Since no user will ever see the item being removed (needs a horizontal | 347 // Since no user will ever see the item being removed (needs a horizontal |
| 325 // screen resolution greater than 3200 at 16 items at 200 pixels each), | 348 // screen resolution greater than 3200 at 16 items at 200 pixels each), |
| 326 // there's no point in animating the removal. | 349 // there's no point in animating the removal. |
| 327 [self remove:[downloadItemControllers_ lastObject]]; | 350 [self removeDownload:[downloadItemControllers_ lastObject] |
| 351 isShelfClosing:NO]; |
| 328 } | 352 } |
| 329 | 353 |
| 330 // Finally, move the remaining items to the right. Skip the first item when | 354 // Finally, move the remaining items to the right. Skip the first item when |
| 331 // laying out the items, so that the longer animation duration we set up above | 355 // laying out the items, so that the longer animation duration we set up above |
| 332 // is not overwritten. | 356 // is not overwritten. |
| 333 [self layoutItems:YES]; | 357 [self layoutItems:YES]; |
| 334 } | 358 } |
| 335 | 359 |
| 336 - (void)closed { | 360 - (void)closed { |
| 337 // Don't remove completed downloads if the shelf is just being auto-hidden | 361 // Don't remove completed downloads if the shelf is just being auto-hidden |
| 338 // rather than explicitly closed by the user. | 362 // rather than explicitly closed by the user. |
| 339 if (bridge_->is_hidden()) | 363 if (bridge_->is_hidden()) |
| 340 return; | 364 return; |
| 341 NSUInteger i = 0; | 365 NSUInteger i = 0; |
| 342 while (i < [downloadItemControllers_ count]) { | 366 while (i < [downloadItemControllers_ count]) { |
| 343 DownloadItemController* itemController = | 367 DownloadItemController* itemController = |
| 344 [downloadItemControllers_ objectAtIndex:i]; | 368 [downloadItemControllers_ objectAtIndex:i]; |
| 345 DownloadItem* download = [itemController download]; | 369 DownloadItem* download = [itemController download]; |
| 346 bool isTransferDone = download->IsComplete() || | 370 bool isTransferDone = download->IsComplete() || |
| 347 download->IsCancelled() || | 371 download->IsCancelled() || |
| 348 download->IsInterrupted(); | 372 download->IsInterrupted(); |
| 349 if (isTransferDone && !download->IsDangerous()) { | 373 if (isTransferDone && !download->IsDangerous()) { |
| 350 [self remove:itemController]; | 374 [self removeDownload:itemController |
| 375 isShelfClosing:YES]; |
| 351 } else { | 376 } else { |
| 352 // Treat the item as opened when we close. This way if we get shown again | 377 // Treat the item as opened when we close. This way if we get shown again |
| 353 // the user need not open this item for the shelf to auto-close. | 378 // the user need not open this item for the shelf to auto-close. |
| 354 download->SetOpened(true); | 379 download->SetOpened(true); |
| 355 ++i; | 380 ++i; |
| 356 } | 381 } |
| 357 } | 382 } |
| 358 } | 383 } |
| 359 | 384 |
| 360 - (void)mouseEntered:(NSEvent*)event { | 385 - (void)mouseEntered:(NSEvent*)event { |
| 386 isMouseInsideView_ = YES; |
| 361 // If the mouse re-enters the download shelf, cancel the auto-close. Further | 387 // If the mouse re-enters the download shelf, cancel the auto-close. Further |
| 362 // mouse exits should not trigger autoclose, so also remove the tracking area. | 388 // mouse exits should not trigger autoclose. |
| 363 [self cancelAutoCloseAndRemoveTrackingArea]; | 389 if (shouldCloseOnMouseExit_) { |
| 390 [self cancelAutoClose]; |
| 391 shouldCloseOnMouseExit_ = NO; |
| 392 } |
| 364 } | 393 } |
| 365 | 394 |
| 366 - (void)mouseExited:(NSEvent*)event { | 395 - (void)mouseExited:(NSEvent*)event { |
| 396 isMouseInsideView_ = NO; |
| 397 if (shouldCloseOnMouseExit_) |
| 398 [self scheduleAutoClose]; |
| 399 } |
| 400 |
| 401 - (void)scheduleAutoClose { |
| 367 // Cancel any previous hide requests, just to be safe. | 402 // Cancel any previous hide requests, just to be safe. |
| 368 [NSObject cancelPreviousPerformRequestsWithTarget:self | 403 [self cancelAutoClose]; |
| 369 selector:@selector(autoClose) | |
| 370 object:nil]; | |
| 371 | 404 |
| 372 // Schedule an autoclose after a delay. If the mouse is moved back into the | 405 // Schedule an autoclose after a delay. If the mouse is moved back into the |
| 373 // view, or if an item is added to the shelf, the timer will be canceled. | 406 // view, or if an item is added to the shelf, the timer will be canceled. |
| 374 [self performSelector:@selector(autoClose) | 407 [self performSelector:@selector(autoClose) |
| 375 withObject:nil | 408 withObject:nil |
| 376 afterDelay:kAutoCloseDelaySeconds]; | 409 afterDelay:kAutoCloseDelaySeconds]; |
| 377 } | 410 } |
| 378 | 411 |
| 412 - (void)cancelAutoClose { |
| 413 [NSObject cancelPreviousPerformRequestsWithTarget:self |
| 414 selector:@selector(autoClose) |
| 415 object:nil]; |
| 416 } |
| 417 |
| 379 - (void)maybeAutoCloseAfterDelay { | 418 - (void)maybeAutoCloseAfterDelay { |
| 380 // We can close the shelf automatically if all the downloads on the shelf have | 419 // We can close the shelf automatically if all the downloads on the shelf have |
| 381 // been opened. | 420 // been opened. |
| 382 for (NSUInteger i = 0; i < [downloadItemControllers_ count]; ++i) { | 421 for (NSUInteger i = 0; i < [downloadItemControllers_ count]; ++i) { |
| 383 DownloadItemController* itemController = | 422 DownloadItemController* itemController = |
| 384 [downloadItemControllers_ objectAtIndex:i]; | 423 [downloadItemControllers_ objectAtIndex:i]; |
| 385 if (![itemController download]->GetOpened()) | 424 if (![itemController download]->GetOpened()) |
| 386 return; | 425 return; |
| 387 } | 426 } |
| 388 | 427 |
| 389 if ([self isVisible] && [downloadItemControllers_ count] > 0) { | 428 if ([self isVisible] && [downloadItemControllers_ count] > 0 && |
| 390 // If the shelf is visible and has download items remaining on it, close the | 429 isMouseInsideView_) { |
| 391 // shelf after the user moves the mouse out of the download shelf. Note that | 430 // If there are download items on the shelf and the user is potentially stil |
| 392 // the mouse might not be over the shelf. In this case, the shelf will not | 431 // interacting with them, schedule an auto close after the user moves the |
| 393 // auto close. | 432 // mouse off the shelf. |
| 394 // TODO(asanka): Don't install a tracking area if the mouse isn't over the | 433 shouldCloseOnMouseExit_ = YES; |
| 395 // shelf. Autoclose instead. | |
| 396 [self installTrackingArea]; | |
| 397 } else { | 434 } else { |
| 398 // We notify the DownloadShelf of our intention to close even if the shelf | 435 // We notify the DownloadShelf of our intention to close even if the shelf |
| 399 // is currently hidden. If the shelf was temporarily hidden (e.g. because | 436 // is currently hidden. If the shelf was temporarily hidden (e.g. because |
| 400 // the browser window entered fullscreen mode), then this prevents the shelf | 437 // the browser window entered fullscreen mode), then this prevents the shelf |
| 401 // from being shown again when the browser exits fullscreen mode. | 438 // from being shown again when the browser exits fullscreen mode. |
| 402 [self autoClose]; | 439 [self autoClose]; |
| 403 } | 440 } |
| 404 } | 441 } |
| 405 | 442 |
| 406 - (void)autoClose { | 443 - (void)autoClose { |
| 407 bridge_->Close(DownloadShelf::AUTOMATIC); | 444 bridge_->Close(DownloadShelf::AUTOMATIC); |
| 408 } | 445 } |
| 409 | 446 |
| 410 - (void)installTrackingArea { | 447 - (void)installTrackingArea { |
| 411 // Install the tracking area to listen for mouseExited messages and trigger | 448 // Install the tracking area to listen for mouseEntered and mouseExited |
| 412 // the shelf autoclose. | 449 // messages. |
| 413 if (trackingArea_.get()) | 450 DCHECK(!trackingArea_.get()); |
| 414 return; | |
| 415 | 451 |
| 416 trackingArea_.reset([[NSTrackingArea alloc] | 452 trackingArea_.reset([[CrTrackingArea alloc] |
| 417 initWithRect:[[self view] bounds] | 453 initWithRect:[[self view] bounds] |
| 418 options:NSTrackingMouseEnteredAndExited | | 454 options:NSTrackingMouseEnteredAndExited | |
| 419 NSTrackingActiveAlways | | 455 NSTrackingActiveAlways | |
| 420 NSTrackingInVisibleRect | 456 NSTrackingInVisibleRect |
| 421 owner:self | 457 owner:self |
| 422 userInfo:nil]); | 458 userInfo:nil]); |
| 423 [[self view] addTrackingArea:trackingArea_]; | 459 [[self view] addTrackingArea:trackingArea_.get()]; |
| 424 } | 460 } |
| 425 | 461 |
| 426 - (void)cancelAutoCloseAndRemoveTrackingArea { | 462 - (void)removeTrackingArea { |
| 427 [NSObject cancelPreviousPerformRequestsWithTarget:self | |
| 428 selector:@selector(autoClose) | |
| 429 object:nil]; | |
| 430 | |
| 431 if (trackingArea_.get()) { | 463 if (trackingArea_.get()) { |
| 432 [[self view] removeTrackingArea:trackingArea_]; | 464 [[self view] removeTrackingArea:trackingArea_.get()]; |
| 433 trackingArea_.reset(nil); | 465 trackingArea_.reset(nil); |
| 434 } | 466 } |
| 435 } | 467 } |
| 436 | 468 |
| 437 - (void)willEnterFullscreen { | 469 - (void)willEnterFullscreen { |
| 438 isFullscreen_ = YES; | 470 isFullscreen_ = YES; |
| 439 [self updateCloseButton]; | 471 [self updateCloseButton]; |
| 440 } | 472 } |
| 441 | 473 |
| 442 - (void)willLeaveFullscreen { | 474 - (void)willLeaveFullscreen { |
| (...skipping 21 matching lines...) Expand all Loading... |
| 464 } | 496 } |
| 465 | 497 |
| 466 // Set the tracking off to create a new tracking area for the control. | 498 // Set the tracking off to create a new tracking area for the control. |
| 467 // When changing the bounds/frame on a HoverButton, the tracking isn't updated | 499 // When changing the bounds/frame on a HoverButton, the tracking isn't updated |
| 468 // correctly, it needs to be turned off and back on. | 500 // correctly, it needs to be turned off and back on. |
| 469 [hoverCloseButton_ setTrackingEnabled:NO]; | 501 [hoverCloseButton_ setTrackingEnabled:NO]; |
| 470 [hoverCloseButton_ setFrame:bounds]; | 502 [hoverCloseButton_ setFrame:bounds]; |
| 471 [hoverCloseButton_ setTrackingEnabled:YES]; | 503 [hoverCloseButton_ setTrackingEnabled:YES]; |
| 472 } | 504 } |
| 473 @end | 505 @end |
| OLD | NEW |