diff --git a/ChangeLog b/ChangeLog index 84ad29d..eaa1354 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2012-01-15 Eric Wasylishen + + * Source/x11/XGServer.m: Don't read X events in NSConnectionReplyMode + * Source/x11/XGServerEvent.m (-receivedEvent:type:extra:forMode:): + Only read one event from the xlib event queue, instead of all of them. + * Source/x11/XGServerEvent.m (-getEventMatchingMask:beforeDate:inMode:): + Remove call to -receivedEvent:type:extra:forMode: + * Source/x11/XGServerEvent.m (-discardEventsMatchingMask:beforeEvent:): + Remove call to -receivedEvent:type:extra:forMode: + + These changes are an attempt to fix a bug where a steady stream + of X events can postpone autodisplay indefinitely. To see it, open + a long document in Ink and scroll with the mousewheel slowly but + continuously. If you scroll steadily enough, the window will not + update until you stop scrolling. + + This occurs beacuse autodisplay only occurs when the AppKit event + queue is empty and the runloop runs, and without the above changes, + the AppKit event queue was filling up and not emptying until the + mousewheel events stopped arriving. + + In the long run I think we should get rid of the AppKit event queue + and have XGServer override the default implementation of + -[GSDisplayServer getEventMatchingMask:beforeDate:inMode:dequeue:] + and related methods with custom ones that interact + directly with the Xlib event queue. + 2012-01-11 Fred Kiefer * Source/winlib/WIN32FontEnumerator.m: Add missing include. diff --git a/Source/x11/XGServer.m b/Source/x11/XGServer.m index 6d3987d..6b8c185 100644 --- a/Source/x11/XGServer.m +++ b/Source/x11/XGServer.m @@ -475,7 +475,16 @@ _parse_display_name(NSString *name, int *dn, int *sn) [self _initXContext]; [self setupRunLoopInputSourcesForMode: NSDefaultRunLoopMode]; - [self setupRunLoopInputSourcesForMode: NSConnectionReplyMode]; + + // FIXME: Not sure why we were accepting X events in + // NSConnectionReplyMode. This was causing X event processing in + // weird places, like [NSApplication run] -> [_main_menu update] -> + // [NSPasteboard generalPasteboard] -> [NSDistantObject forwardInvocation:] -> + // [NSRunLoop acceptInputForMode:beforeDate:] + // so I am disabling X event listening for NSConnectionReplyMode + // for now. + + //[self setupRunLoopInputSourcesForMode: NSConnectionReplyMode]; [self setupRunLoopInputSourcesForMode: NSModalPanelRunLoopMode]; [self setupRunLoopInputSourcesForMode: NSEventTrackingRunLoopMode]; return self; diff --git a/Source/x11/XGServerEvent.m b/Source/x11/XGServerEvent.m index cd76347..5cca442 100644 --- a/Source/x11/XGServerEvent.m +++ b/Source/x11/XGServerEvent.m @@ -294,8 +294,15 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor { XEvent xEvent; - // loop and grab all of the events from the X queue - while (XPending(dpy) > 0) + // loop and grab ONE of the events from the X queue. + // + // we don't want to flood the AppKit event queue with + // events because it will block autodisplay (which only + // happens when the AppKit queue is empty and we try to + // run the runloop - see: + // [GSDisplayServer getEventMatchingMask:beforeDate:inMode:dequeue:]) + + if (XPending(dpy) > 0) { XNextEvent(dpy, &xEvent); @@ -303,7 +310,7 @@ posixFileDescriptor: (NSPosixFileDescriptor*)fileDescriptor if (XFilterEvent(&xEvent, None)) { NSDebugLLog(@"NSKeyEvent", @"Event filtered (by XIM?)\n"); - continue; + return; } #endif @@ -2548,6 +2555,12 @@ process_modifier_flags(unsigned int state) return p; } +// NOTE: The calls to [self receivedEvent:type:extra:forMode:] +// were commented out because they cause flooding of the AppKit +// event queue and can prevent autodisplay; see comment in +// [self receivedEvent:type:extra:forMode:] + +/* - (NSEvent*) getEventMatchingMask: (unsigned)mask beforeDate: (NSDate*)limit inMode: (NSString*)mode @@ -2567,6 +2580,7 @@ process_modifier_flags(unsigned int state) [super discardEventsMatchingMask: mask beforeEvent: limit]; } +*/ @end