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 |