From dd74c0b5206441d2f36314cc9218366ea298d9d3 Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Sat, 25 Oct 2008 20:31:17 +0200 Subject: [PATCH] Connection not in event tracking mode by default Only add backend connection to event tracking mode when it is absolutely needed. At the moment this happens when the window is in "live resize" or when the mouse button is held on some part of a scroller. --- src/MacVim/MMAppController.m | 5 ----- src/MacVim/MMVimController.m | 12 ++++++------ src/MacVim/MMVimView.m | 21 +++++++++++++++++++++ src/MacVim/MMWindowController.m | 17 +++++++++++++++++ 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 3bea328aed..0b75273586 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -231,11 +231,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef, [connection setRequestTimeout:MMRequestTimeout]; [connection setReplyTimeout:MMReplyTimeout]; - // NOTE: When the user is resizing the window the AppKit puts the run - // loop in event tracking mode. Unless the connection listens to - // request in this mode, live resizing won't work. - [connection addRequestMode:NSEventTrackingRunLoopMode]; - // NOTE! If the name of the connection changes here it must also be // updated in MMBackend.m. NSString *name = [NSString stringWithFormat:@"%@-connection", diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index 37d4c26de1..a0857ca242 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -673,12 +673,12 @@ static BOOL isUnsafeMessage(int msgid); BOOL inDefaultMode = [[[NSRunLoop currentRunLoop] currentMode] isEqual:NSDefaultRunLoopMode]; if (!inDefaultMode && isUnsafeMessage(msgid)) { - // NOTE: Because we listen to DO messages in 'event tracking' - // mode we have to take extra care when doing things like - // releasing view items (and other Cocoa objects). Messages - // that may be potentially "unsafe" are delayed until the run - // loop is back to default mode at which time they are safe to - // call again. + // NOTE: Because we may be listening to DO messages in "event + // tracking mode" we have to take extra care when doing things + // like releasing view items (and other Cocoa objects). + // Messages that may be potentially "unsafe" are delayed until + // the run loop is back to default mode at which time they are + // safe to call again. // A problem with this approach is that it is hard to // classify which messages are unsafe. As a rule of thumb, if // a message may release an object used by the Cocoa framework diff --git a/src/MacVim/MMVimView.m b/src/MacVim/MMVimView.m index 0ebc075a1a..08363433ea 100644 --- a/src/MacVim/MMVimView.m +++ b/src/MacVim/MMVimView.m @@ -22,6 +22,7 @@ #import "MMTextView.h" #import "MMVimController.h" #import "MMVimView.h" +#import "MMWindowController.h" #import "Miscellaneous.h" #import @@ -909,4 +910,24 @@ enum { [[(MMVimView*)vimView textView] scrollWheel:event]; } +- (void)mouseDown:(NSEvent *)event +{ + // TODO: This is an ugly way of getting the connection to the backend. + NSConnection *connection = nil; + id wc = [[self window] windowController]; + if ([wc isKindOfClass:[MMWindowController class]]) { + MMVimController *vc = [(MMWindowController*)wc vimController]; + id proxy = [vc backendProxy]; + connection = [(NSDistantObject*)proxy connectionForProxy]; + } + + // NOTE: The scroller goes into "event tracking mode" when the user clicks + // (and holds) the mouse button. We have to manually add the backend + // connection to this mode while the mouse button is held, else DO messages + // from Vim will not be processed until the mouse button is released. + [connection addRequestMode:NSEventTrackingRunLoopMode]; + [super mouseDown:event]; + [connection removeRequestMode:NSEventTrackingRunLoopMode]; +} + @end // MMScroller diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index 403c85c90e..e7938d62bb 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -513,16 +513,33 @@ - (void)liveResizeWillStart { + if (!setupDone) return; + // Save the original title, if we haven't already. if (lastSetTitle == nil) { lastSetTitle = [[decoratedWindow title] retain]; } + + // NOTE: During live resize Cocoa goes into "event tracking mode". We have + // to add the backend connection to this mode in order for resize messages + // from Vim to reach MacVim. We do not wish to always listen to requests + // in event tracking mode since then MacVim could receive DO messages at + // unexpected times (e.g. when a key equivalent is pressed and the menu bar + // momentarily lights up). + id proxy = [vimController backendProxy]; + NSConnection *connection = [(NSDistantObject*)proxy connectionForProxy]; + [connection addRequestMode:NSEventTrackingRunLoopMode]; } - (void)liveResizeDidEnd { if (!setupDone) return; + // See comment above regarding event tracking mode. + id proxy = [vimController backendProxy]; + NSConnection *connection = [(NSDistantObject*)proxy connectionForProxy]; + [connection removeRequestMode:NSEventTrackingRunLoopMode]; + // NOTE: During live resize messages from MacVim to Vim are often dropped // (because too many messages are sent at once). This may lead to // inconsistent states between Vim and MacVim; to avoid this we send a