From 50b3a7f8e75a2f5b640d037b36eb7d595a36638d Mon Sep 17 00:00:00 2001 From: Bjorn Winckler Date: Sat, 18 Dec 2010 18:14:37 +0100 Subject: [PATCH] Fix proxy icon response to modified buffers The proxy icon is only disabled when the current buffer is modified (previously this happened when any buffer was modified). This also has the consequence that the dot in the red "close button" only appears when the current buffer is modified. --- src/MacVim/MMAppController.m | 13 +++++-------- src/MacVim/MMBackend.m | 26 ++++++++++++++++---------- src/MacVim/MMVimController.h | 2 ++ src/MacVim/MMVimController.m | 24 ++++++++++++++++++++---- src/MacVim/MMWindowController.h | 2 +- src/MacVim/MMWindowController.m | 2 +- src/MacVim/MacVim.h | 3 +-- src/MacVim/MacVim.m | 3 +-- 8 files changed, 47 insertions(+), 28 deletions(-) diff --git a/src/MacVim/MMAppController.m b/src/MacVim/MMAppController.m index 7cb7b887f4..8eadcf13c3 100644 --- a/src/MacVim/MMAppController.m +++ b/src/MacVim/MMAppController.m @@ -481,13 +481,11 @@ fsEventCallback(ConstFSEventStreamRef streamRef, int reply = NSTerminateNow; BOOL modifiedBuffers = NO; - // Go through windows, checking for modified buffers. (Each Vim process - // tells MacVim when any buffer has been modified and MacVim sets the - // 'documentEdited' flag of the window correspondingly.) - NSEnumerator *e = [[NSApp windows] objectEnumerator]; - id window; - while ((window = [e nextObject])) { - if ([window isDocumentEdited]) { + // Go through Vim controllers, checking for modified buffers. + NSEnumerator *e = [vimControllers objectEnumerator]; + id vc; + while ((vc = [e nextObject])) { + if ([vc hasModifiedBuffer]) { modifiedBuffers = YES; break; } @@ -519,7 +517,6 @@ fsEventCallback(ConstFSEventStreamRef streamRef, // Count the number of open tabs e = [vimControllers objectEnumerator]; - id vc; while ((vc = [e nextObject])) numTabs += [[vc objectForVimStateKey:@"numTabs"] intValue]; diff --git a/src/MacVim/MMBackend.m b/src/MacVim/MMBackend.m index 92d6899367..2d389c14e5 100644 --- a/src/MacVim/MMBackend.m +++ b/src/MacVim/MMBackend.m @@ -191,7 +191,7 @@ extern GuiFont gui_mch_retain_font(GuiFont font); - (void)startOdbEditWithArguments:(NSDictionary *)args; - (void)handleXcodeMod:(NSData *)data; - (void)handleOpenWithArguments:(NSDictionary *)args; -- (BOOL)checkForModifiedBuffers; +- (int)checkForModifiedBuffers; - (void)addInput:(NSString *)input; - (void)redrawScreen; - (void)handleFindReplace:(NSDictionary *)args; @@ -1182,12 +1182,10 @@ extern GuiFont gui_mch_retain_font(GuiFont font); - (void)updateModifiedFlag { - // Notify MacVim if _any_ buffer has changed from unmodified to modified or - // vice versa. - int msgid = [self checkForModifiedBuffers] - ? BuffersModifiedMsgID : BuffersNotModifiedMsgID; - - [self queueMessage:msgid data:nil]; + int state = [self checkForModifiedBuffers]; + NSMutableData *data = [NSMutableData data]; + [data appendBytes:&state length:sizeof(int)]; + [self queueMessage:SetBuffersModifiedMsgID data:data]; } - (oneway void)processInput:(int)msgid data:(in bycopy NSData *)data @@ -1818,6 +1816,8 @@ static void netbeansReadCallback(CFSocketRef s, nil]; // Put the state before all other messages. + // TODO: If called multiple times the oldest state will be used! Should + // remove any current Vim state messages from the queue first. int msgid = SetVimStateMsgID; [outputQueue insertObject:[vimState dictionaryAsData] atIndex:0]; [outputQueue insertObject:[NSData dataWithBytes:&msgid length:sizeof(int)] @@ -2836,16 +2836,22 @@ static void netbeansReadCallback(CFSocketRef s, } } -- (BOOL)checkForModifiedBuffers +- (int)checkForModifiedBuffers { + // Return 1 if current buffer is modified, -1 if other buffer is modified, + // otherwise return 0. + + if (curbuf && bufIsChanged(curbuf)) + return 1; + buf_T *buf; for (buf = firstbuf; buf != NULL; buf = buf->b_next) { if (bufIsChanged(buf)) { - return YES; + return -1; } } - return NO; + return 0; } - (void)addInput:(NSString *)input diff --git a/src/MacVim/MMVimController.h b/src/MacVim/MMVimController.h index b9fbaac0c5..7246e68460 100644 --- a/src/MacVim/MMVimController.h +++ b/src/MacVim/MMVimController.h @@ -34,6 +34,7 @@ NSDictionary *vimState; BOOL isPreloading; NSDate *creationDate; + BOOL hasModifiedBuffer; } - (id)initWithBackend:(id)backend pid:(int)processIdentifier; @@ -48,6 +49,7 @@ - (NSMenu *)mainMenu; - (BOOL)isPreloading; - (void)setIsPreloading:(BOOL)yn; +- (BOOL)hasModifiedBuffer; - (NSDate *)creationDate; - (void)cleanup; - (void)dropFiles:(NSArray *)filenames forceOpen:(BOOL)force; diff --git a/src/MacVim/MMVimController.m b/src/MacVim/MMVimController.m index d56745df6d..897843848a 100644 --- a/src/MacVim/MMVimController.m +++ b/src/MacVim/MMVimController.m @@ -220,6 +220,11 @@ static BOOL isUnsafeMessage(int msgid); isPreloading = yn; } +- (BOOL)hasModifiedBuffer +{ + return hasModifiedBuffer; +} + - (NSDate *)creationDate { return creationDate; @@ -765,10 +770,21 @@ static BOOL isUnsafeMessage(int msgid); [windowController enterFullscreen:fuoptions backgroundColor:back]; } else if (LeaveFullscreenMsgID == msgid) { [windowController leaveFullscreen]; - } else if (BuffersNotModifiedMsgID == msgid) { - [windowController setBuffersModified:NO]; - } else if (BuffersModifiedMsgID == msgid) { - [windowController setBuffersModified:YES]; + } else if (SetBuffersModifiedMsgID == msgid) { + const void *bytes = [data bytes]; + // state < 0 <-> some buffer modified + // state > 0 <-> current buffer modified + int state = *((int*)bytes); bytes += sizeof(int); + + // NOTE: The window controller tracks whether current buffer is + // modified or not (and greys out the proxy icon as well as putting a + // dot in the red "close button" if necessary). The Vim controller + // tracks whether any buffer has been modified (used to decide whether + // to show a warning or not when quitting). + // + // TODO: Make 'hasModifiedBuffer' part of the Vim state? + [windowController setBufferModified:(state > 0)]; + hasModifiedBuffer = (state != 0); } else if (SetPreEditPositionMsgID == msgid) { const int *dim = (const int*)[data bytes]; [[[windowController vimView] textView] setPreEditRow:dim[0] diff --git a/src/MacVim/MMWindowController.h b/src/MacVim/MMWindowController.h index 12084520c0..99884c4e40 100644 --- a/src/MacVim/MMWindowController.h +++ b/src/MacVim/MMWindowController.h @@ -79,7 +79,7 @@ - (void)leaveFullscreen; - (void)setFullscreenBackgroundColor:(NSColor *)back; -- (void)setBuffersModified:(BOOL)mod; +- (void)setBufferModified:(BOOL)mod; - (void)setTopLeft:(NSPoint)pt; - (BOOL)getDefaultTopLeft:(NSPoint*)pt; diff --git a/src/MacVim/MMWindowController.m b/src/MacVim/MMWindowController.m index a6e2ffea9a..f367145551 100644 --- a/src/MacVim/MMWindowController.m +++ b/src/MacVim/MMWindowController.m @@ -670,7 +670,7 @@ [fullscreenWindow setBackgroundColor:back]; } -- (void)setBuffersModified:(BOOL)mod +- (void)setBufferModified:(BOOL)mod { // NOTE: We only set the document edited flag on the decorated window since // the full-screen window has no close button anyway. (It also saves us diff --git a/src/MacVim/MacVim.h b/src/MacVim/MacVim.h index 26b5af775e..20ff1a6a9d 100644 --- a/src/MacVim/MacVim.h +++ b/src/MacVim/MacVim.h @@ -158,8 +158,7 @@ enum { SetServerNameMsgID, EnterFullscreenMsgID, LeaveFullscreenMsgID, - BuffersNotModifiedMsgID, - BuffersModifiedMsgID, + SetBuffersModifiedMsgID, AddInputMsgID, SetPreEditPositionMsgID, TerminateNowMsgID, diff --git a/src/MacVim/MacVim.m b/src/MacVim/MacVim.m index 2b10c8bfed..25f5776c6c 100644 --- a/src/MacVim/MacVim.m +++ b/src/MacVim/MacVim.m @@ -68,8 +68,7 @@ char *MessageStrings[] = "SetServerNameMsgID", "EnterFullscreenMsgID", "LeaveFullscreenMsgID", - "BuffersNotModifiedMsgID", - "BuffersModifiedMsgID", + "SetBuffersModifiedMsgID", "AddInputMsgID", "SetPreEditPositionMsgID", "TerminateNowMsgID",