Completion Session Doesn't Consistently Open

SyntaxEditor for WPF Forum

Posted 5 years ago by Matt Gerrans
Version: 14.2.0610
Avatar

I'm opening a CompletionSession in OnDocumentTextChange (pretty much as described in the documentation) specific character is typed ("{").    Sometimes it works, but more often than not, the completion list doesn't appear.   I can't tell why it isn't appearing; I added some logging to ensure that the case is hit and session.Open() is really being called every time the "{" is typed (because debugging can interfere with this kind of behavior, of course).   When it does work, it seems normal, looks and works fine.

 

private void OnDocumentTextChanged(object sender, EditorSnapshotChangedEventArgs args)
{
   if (args.TextChange.Source == Editor.ActiveView)
   {
      switch (args.TypedText)
      {
          case "{":
             var session = new CompletionSession();
             AddConceptCompletionItems(session); // Adds all the CompletionItems to the session.
             Log.Info("Opening the Completion session; there are {0} items.", session.Items.Count);
             session.Open(Editor.ActiveView);
             break;
      }
   }
} 

Comments (10)

Posted 5 years ago by Matt Gerrans
Avatar

A little additional information.   Interestingly, if I type in the { and no completion list appears, then select that one character and type { again, the completion list appears consistently.    Is the session looking at some internal state or something about the change that makes it appear or not?   If I select more text, it is also a replace operation, but the completion list doesn't appear.   In all cases, I get log events that indicate that session.Open() was called (i.e. it isn't a case of the TypeText not matching, or the Source not being the ActiveView or something like that).

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

Are you sure there is at least one item added to the session in the cases where it's closing?  You mention that it works sometimes but not others for the same text range.  That leads me to think that your add item logic is depending on parse data that might be delayed in updating due to the parser running asynchronously.

If you are sure there is at least one item in the list, you might also be able to try and track down the reason it's closing if you attach to the session's Closed event and see what the stack trace is.


Actipro Software Support

Posted 5 years ago by Matt Gerrans
Avatar

Yes, it is definitely getting populated; there is no dependency on the parse data the "{" key triggers a lookup of existing "Concepts" that aren't dependent on the parsing.   Also the logging is showing the count of items in session.Items.Count, which is correct.

Thanks for the tip on the Closed event; I'll see if I can get any clues from that.

Posted 5 years ago by Matt Gerrans
Avatar

Here's what the top of the stack looks like.   Is the PossiblyDeactivate() the culprit?

2014-10-17 09:31:57.5365|Info | 9|Session closed; at System.Environment.GetStackTrace(Exception e, Boolean needFileInfo)
at System.Environment.get_StackTrace()
at VoiceBox.ACE.SyntaxEditorControl.SyntaxEditorInternal.<DoAutoCompletion>b__c(Object sender, CancelEventArgs cancelEventArgs) in C:\ace\ACE_2.0_Release_Branch_1_AddingArabicHandling\SyntaxEditorControl\SyntaxEditorInternal.cs:line 741
at ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt.Implementation.IntelliPromptSessionBase.OnClosed(CancelEventArgs e)
at ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt.Implementation.CompletionSession.OnClosed(CancelEventArgs e)
at ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt.Implementation.IntelliPromptSessionBase.Close(Boolean cancelled)
at ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt.Implementation.IntelliPromptManager.#0jc(Object #xhb, EventArgs #yhb)
at ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt.Implementation.IntelliPromptManager.#23b.#8jc()
at ActiproSoftware.Windows.Controls.SyntaxEditor.IntelliPrompt.Implementation.IntelliPromptManager.#23b.#6jc(Object #xhb, KeyboardFocusChangedEventArgs #yhb)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.KeyboardDevice.ChangeFocus(DependencyObject focus, Int32 timestamp)
at System.Windows.Input.InputManager.RaiseProcessInputEventHandlers(ProcessInputEventHandler postProcessInput, ProcessInputEventArgs processInputEventArgs)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Interop.HwndKeyboardInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawKeyboardActions actions, Int32 scanCode, Boolean isExtendedKey, Boolean isSystemKey, Int32 virtualKey)
at System.Windows.Interop.HwndKeyboardInputProvider.PossiblyDeactivate(IntPtr hwndFocus)
at System.Windows.Interop.HwndKeyboardInputProvider.FilterMessage(IntPtr hwnd, WindowMessage message, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at System.Windows.Forms.UnsafeNativeMethods.SetFocus(HandleRef hWnd)
at System.Windows.Forms.UnsafeNativeMethods.SetFocus(HandleRef hWnd)
at System.Windows.Forms.Control.FocusInternal()
at System.Windows.Forms.Control.Focus()

I looked at the stack trace diff between when it does display and when it doesn't and can't see anything obious that points to why it doesn't display.

Posted 5 years ago by Matt Gerrans
Avatar

I'm not able to make any headway on this with the information available to me at this point.  I've compared stack traces of working vs. not working cases, added logging to show what the TypedText was, whether the session opened and closed events were triggered.

Based on the fact that it pretty reliably doesn't pop up when I just type in a "{" and does show up when I select a "{" and type "{" again, it seems like there is something about the state of the session, editor, or the ActiveView that determines whether the auto complete popup appears.   It doesn't seem to be a problem with winforms hosting WPF (because then it seems it would consistently fail, regardless of whether something was selected first in the editor or not).

Is there any way I can get more information about how the session is deciding whether or not to display the popup?

Thanks,

- Matt

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

From the stack trace it appears that you have some Windows Forms control getting focus.  Our IntelliPromptManager's focus tracker watches for focus changes, detects that scenario, and then closes the completion list.  You should probably try and determine what that other WinForms control is that is getting focused.  Then sort out why it's happening and block it from happening.


Actipro Software Support

Posted 5 years ago by Matt Gerrans
Avatar

Where do you see that in the stack trace?   As it happens, this part of the stack trace is identical whether the popup appeared or not.

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

The root item there is "System.Windows.Forms.Control.Focus()" and everything up the chain there appears to be related to processing the focus change Win32 message.  That eventually leads to a KeyboardDevice.ChangeFocus, which then later leads to a focus change event handler within our IntelliPromptManager.

If you could break on the HwndKeyboardInputProvider.FilterMessage call, you could see which Win32 message ID it's passing.  Such as if it is in fact a focus change or a key input message.


Actipro Software Support

Posted 5 years ago by Matt Gerrans
Avatar

It seems like the auto-complete dropdown does not appear unless a replace operation occurred, for some odd reason.   By adding this code:

case "{":
   var offset = args.TextChange.Operations[0].StartOffset;
   Editor.Document.DeleteText(TextChangeTypes.Delete, new TextRange(offset, offset + 1));
   Editor.Document.InsertText(TextChangeTypes.Replace, offset, "{");

   session = new CompletionSession { CanCommitWithoutPopup = true };

   // Since we're adding the } after the concept name, we needs to shift the caret accordingly:
   session.Committed += (committedSender, committedArgs) => Editor.Caret.Offset++;

   // ... populate the Items, etc...

   Log.Info("Opening the Completion session; there are {0} items.", session.Items.Count);
   session.Open(Editor.ActiveView);
   break;

 It then reliably appears.    It it a pretty silly hack, though...

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Matt,

There has to be something really odd going on here. You shouldn't have to do anything like that, nor have we ever seen the need for that sort of thing to get the completion list to show.

I would recommend trying to simplify things down a bit and try some of this in a WPF app (not a WinForms app) to see if it's working there. That will at least tell us if something in WinForms is causing the problem.


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.