mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Fix ":set go+=c" and menu autoenabling bugs.
Bug: With 'go+=c' Vim could enter a key wait loop while processInput==TRUE which caused all keyboard input to be dropped. Fix: Don't drop keyboard input when processInput==TRUE Bug: With 'go+c' Vim disabled all menu items before quitting which caused autoenabling not to work so the "New Window" was sometimes grey when no windows were open. Fix: Enable all menu items in recurseSetAutoenablesItems.
This commit is contained in:
@@ -315,12 +315,14 @@ static NSTimeInterval MMTerminateTimeout = 3;
|
||||
|
||||
if (![vimControllers count]) {
|
||||
// Turn on autoenabling of menus (because no Vim is open to handle it),
|
||||
// but do not touch the MacVim menu.
|
||||
// but do not touch the MacVim menu. Note that the menus must be
|
||||
// enabled first otherwise autoenabling does not work.
|
||||
NSMenu *mainMenu = [NSApp mainMenu];
|
||||
int i, count = [mainMenu numberOfItems];
|
||||
for (i = 1; i < count; ++i) {
|
||||
NSMenu *submenu = [[mainMenu itemAtIndex:i] submenu];
|
||||
[submenu recurseSetAutoenablesItems:YES];
|
||||
NSMenuItem *item = [mainMenu itemAtIndex:i];
|
||||
[item setEnabled:YES];
|
||||
[[item submenu] recurseSetAutoenablesItems:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,7 +592,9 @@ static NSTimeInterval MMTerminateTimeout = 3;
|
||||
|
||||
int i, count = [self numberOfItems];
|
||||
for (i = 0; i < count; ++i) {
|
||||
NSMenu *submenu = [[self itemAtIndex:i] submenu];
|
||||
NSMenuItem *item = [self itemAtIndex:i];
|
||||
[item setEnabled:YES];
|
||||
NSMenu *submenu = [item submenu];
|
||||
if (submenu) {
|
||||
[submenu recurseSetAutoenablesItems:on];
|
||||
}
|
||||
|
||||
@@ -13,12 +13,6 @@
|
||||
#import "vim.h"
|
||||
|
||||
|
||||
// If disabled, all input is dropped if input is already being processed. (If
|
||||
// enabled, same thing happens at the moment actually. So this is pretty
|
||||
// useless.)
|
||||
#define MM_USE_INPUT_QUEUE 0
|
||||
|
||||
|
||||
|
||||
|
||||
@interface MMBackend : NSObject <MMBackendProtocol, MMVimServerProtocol,
|
||||
@@ -44,9 +38,6 @@
|
||||
NSTimeInterval blinkOnInterval;
|
||||
NSTimeInterval blinkOffInterval;
|
||||
BOOL inProcessInput;
|
||||
#if MM_USE_INPUT_QUEUE
|
||||
NSMutableArray *inputQueue;
|
||||
#endif
|
||||
NSMutableDictionary *connectionNameDict;
|
||||
NSMutableDictionary *clientProxyDict;
|
||||
NSMutableDictionary *serverReplyDict;
|
||||
|
||||
+31
-80
@@ -64,8 +64,6 @@ enum {
|
||||
- (void)connectionDidDie:(NSNotification *)notification;
|
||||
- (void)blinkTimerFired:(NSTimer *)timer;
|
||||
- (void)focusChange:(BOOL)on;
|
||||
- (void)processInputBegin;
|
||||
- (void)processInputEnd;
|
||||
- (void)handleToggleToolbar;
|
||||
- (void)handleScrollbarEvent:(NSData *)data;
|
||||
- (void)handleSetFont:(NSData *)data;
|
||||
@@ -100,9 +98,6 @@ enum {
|
||||
fontContainerRef = loadFonts();
|
||||
|
||||
queue = [[NSMutableArray alloc] init];
|
||||
#if MM_USE_INPUT_QUEUE
|
||||
inputQueue = [[NSMutableArray alloc] init];
|
||||
#endif
|
||||
drawData = [[NSMutableData alloc] initWithCapacity:1024];
|
||||
connectionNameDict = [[NSMutableDictionary alloc] init];
|
||||
clientProxyDict = [[NSMutableDictionary alloc] init];
|
||||
@@ -137,9 +132,6 @@ enum {
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
|
||||
[blinkTimer release]; blinkTimer = nil;
|
||||
#if MM_USE_INPUT_QUEUE
|
||||
[inputQueue release]; inputQueue = nil;
|
||||
#endif
|
||||
[alternateServerName release]; alternateServerName = nil;
|
||||
[serverReplyDict release]; serverReplyDict = nil;
|
||||
[clientProxyDict release]; clientProxyDict = nil;
|
||||
@@ -1042,51 +1034,40 @@ enum {
|
||||
// dangerous. E.g. say a message causes the screen to be redrawn and then
|
||||
// another message is received causing another simultaneous screen redraw;
|
||||
// this is not good. To deal with this problem at the moment, we simply
|
||||
// drop messages that are received while other input is being processed.
|
||||
if (inProcessInput) {
|
||||
#if MM_USE_INPUT_QUEUE
|
||||
[inputQueue addObject:[NSNumber numberWithInt:msgid]];
|
||||
[inputQueue addObject:data];
|
||||
#else
|
||||
// drop messages that are received while other input is being processed,
|
||||
// unless the message represents keyboard input.
|
||||
|
||||
//NSLog(@"%s%s", _cmd, MessageStrings[msgid]);
|
||||
|
||||
if (inProcessInput && !(InsertTextMsgID == msgid || KeyDownMsgID == msgid
|
||||
|| CmdKeyMsgID == msgid)) {
|
||||
// Just drop the input
|
||||
//NSLog(@"WARNING: Dropping input in %s", _cmd);
|
||||
#endif
|
||||
} else {
|
||||
[self processInputBegin];
|
||||
// Don't flush too soon or update speed will suffer.
|
||||
[lastFlushDate release];
|
||||
lastFlushDate = [[NSDate date] retain];
|
||||
|
||||
inProcessInput = YES;
|
||||
[self handleMessage:msgid data:data];
|
||||
[self processInputEnd];
|
||||
inProcessInput = NO;
|
||||
|
||||
inputReceived = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (oneway void)processInputAndData:(in bycopy NSArray *)messages
|
||||
{
|
||||
// NOTE: See comment in processInput:data:.
|
||||
// TODO: Get rid of this method?
|
||||
|
||||
unsigned i, count = [messages count];
|
||||
if (count % 2) {
|
||||
NSLog(@"WARNING: [messages count] is odd in %s", _cmd);
|
||||
return;
|
||||
}
|
||||
for (i = 0; i < count; i += 2) {
|
||||
int msgid = [[messages objectAtIndex:i] intValue];
|
||||
id data = [messages objectAtIndex:i+1];
|
||||
if ([data isEqual:[NSNull null]])
|
||||
data = nil;
|
||||
|
||||
if (inProcessInput) {
|
||||
#if MM_USE_INPUT_QUEUE
|
||||
[inputQueue addObjectsFromArray:messages];
|
||||
#else
|
||||
// Just drop the input
|
||||
//NSLog(@"WARNING: Dropping input in %s", _cmd);
|
||||
#endif
|
||||
} else {
|
||||
[self processInputBegin];
|
||||
|
||||
for (i = 0; i < count; i += 2) {
|
||||
int msgid = [[messages objectAtIndex:i] intValue];
|
||||
id data = [messages objectAtIndex:i+1];
|
||||
if ([data isEqual:[NSNull null]])
|
||||
data = nil;
|
||||
|
||||
[self handleMessage:msgid data:data];
|
||||
}
|
||||
|
||||
[self processInputEnd];
|
||||
[self processInput:msgid data:data];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1431,6 +1412,14 @@ enum {
|
||||
|
||||
- (void)handleMessage:(int)msgid data:(NSData *)data
|
||||
{
|
||||
// NOTE: Be careful with what you do in this method. Ideally, a message
|
||||
// should be handled by adding something to the input buffer and returning
|
||||
// immediately. If you call a Vim function then it should not enter a loop
|
||||
// waiting for key presses or in any other way block the process. The
|
||||
// reason for this being that only one message can be processed at a time,
|
||||
// so if another message is received while processing, then the new message
|
||||
// is dropped. See also the comment in processInput:data:.
|
||||
|
||||
if (InsertTextMsgID == msgid) {
|
||||
[self handleInsertText:data];
|
||||
} else if (KeyDownMsgID == msgid || CmdKeyMsgID == msgid) {
|
||||
@@ -1798,44 +1787,6 @@ enum {
|
||||
gui_focus_change(on);
|
||||
}
|
||||
|
||||
- (void)processInputBegin
|
||||
{
|
||||
inProcessInput = YES;
|
||||
|
||||
// Don't flush too soon or update speed will suffer.
|
||||
[lastFlushDate release];
|
||||
lastFlushDate = [[NSDate date] retain];
|
||||
}
|
||||
|
||||
- (void)processInputEnd
|
||||
{
|
||||
#if MM_USE_INPUT_QUEUE
|
||||
int count = [inputQueue count];
|
||||
if (count % 2) {
|
||||
// TODO: This is troubling, but it is not hard to get Vim to end up
|
||||
// here. Why does this happen?
|
||||
NSLog(@"WARNING: inputQueue has odd number of objects (%d)", count);
|
||||
[inputQueue removeAllObjects];
|
||||
} else if (count > 0) {
|
||||
// TODO: Dispatch these messages? Maybe not; usually when the
|
||||
// 'inputQueue' is non-empty it means that a LOT of messages has been
|
||||
// sent simultaneously. The only way this happens is when Vim is being
|
||||
// tormented, e.g. if the user holds down <D-`> to rapidly switch
|
||||
// windows.
|
||||
unsigned i;
|
||||
for (i = 0; i < count; i+=2) {
|
||||
int msgid = [[inputQueue objectAtIndex:i] intValue];
|
||||
NSLog(@"%s: Dropping message %s", _cmd, MessageStrings[msgid]);
|
||||
}
|
||||
|
||||
[inputQueue removeAllObjects];
|
||||
}
|
||||
#endif
|
||||
|
||||
inputReceived = YES;
|
||||
inProcessInput = NO;
|
||||
}
|
||||
|
||||
- (void)handleToggleToolbar
|
||||
{
|
||||
// If 'go' contains 'T', then remove it, else add it.
|
||||
|
||||
Reference in New Issue
Block a user