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

Unified Diff: chrome/browser/ui/cocoa/chrome_tracking_area.mm

Issue 6486002: [Mac] Create CrTrackingArea and use it in TabStripController. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 10 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/chrome_tracking_area.mm
diff --git a/chrome/browser/ui/cocoa/chrome_tracking_area.mm b/chrome/browser/ui/cocoa/chrome_tracking_area.mm
new file mode 100644
index 0000000000000000000000000000000000000000..ed626c20ecbdd75b7df36a4beb5df2cc6df2f6b0
--- /dev/null
+++ b/chrome/browser/ui/cocoa/chrome_tracking_area.mm
@@ -0,0 +1,101 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "chrome/browser/ui/cocoa/chrome_tracking_area.h"
+
+#include "base/logging.h"
+
+// NSTrackingArea does not retain its |owner| so CrTrackingArea wraps the real
+// owner in this proxy, which can stop forwarding messages to the owner when
+// it is no longer |alive_|.
+@interface CrTrackingAreaOwnerProxy : NSProxy {
+ @private
+ // Whether or not the owner is "alive" and should forward calls to the real
+ // owner object.
+ BOOL alive_;
+
+ // The real object for which this is a proxy. Weak.
+ id owner_;
+}
+
+@property(nonatomic, assign) BOOL alive;
+@property(nonatomic, assign) id owner;
+
+- (id)initWithOwner:(id)owner;
+
+@end
+
+@implementation CrTrackingAreaOwnerProxy
+
+@synthesize alive = alive_;
+@synthesize owner = owner_;
+
+- (id)initWithOwner:(id)owner {
+ alive_ = YES;
+ owner_ = owner;
+ return self;
+}
+
+- (void)forwardInvocation:(NSInvocation*)invocation {
+ if (!alive_)
+ return;
+ [invocation setTarget:owner_];
+ [invocation invoke];
+}
+
+- (NSMethodSignature*)methodSignatureForSelector:(SEL)sel {
+ // Even if the owner is not alive, return the method signature so that the
+ // runtime does not throw an exception. |-forwardInvocation:| will block the
+ // message.
+ return [owner_ methodSignatureForSelector:sel];
+}
+
+@end
+
+// Private Interface ///////////////////////////////////////////////////////////
+
+@interface CrTrackingArea (Private)
+- (void)windowWillClose:(NSNotification*)notif;
+@end
+
+////////////////////////////////////////////////////////////////////////////////
+
+@implementation CrTrackingArea
+
+- (id)initWithRect:(NSRect)rect
+ options:(NSTrackingAreaOptions)options
+ owner:(id)owner
+ userInfo:(NSDictionary*)userInfo {
+ ownerProxy_.reset([[CrTrackingAreaOwnerProxy alloc] initWithOwner:owner]);
+ if ((self = static_cast<id>([super initWithRect:rect
+ options:options
+ owner:ownerProxy_.get()
+ userInfo:userInfo]))) {
Scott Hess - ex-Googler 2011/02/11 01:17:12 No need for the empty if(). Actually, the static_
Robert Sesek 2011/02/11 02:30:50 if() is just for convention. The static_cast<> is
+ }
+ return self;
+}
+
+- (void)dealloc {
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
+ [super dealloc];
+}
+
+- (void)clearOwner {
+ [ownerProxy_ setAlive:NO];
+}
+
+- (void)clearOwnerWhenWindowWillClose:(NSWindow*)window {
+ DCHECK(window);
+ NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
+ [center addObserver:self
+ selector:@selector(windowWillClose:)
+ name:NSWindowWillCloseNotification
+ object:window];
+}
+
+- (void)windowWillClose:(NSNotification*)notif {
+ [self clearOwner];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698