/// <summary> /// Updates the location where the preedit box will be shown. /// </summary> void SetImeCursorLocation() { var rootSite = AssociatedSimpleRootSite; IVwGraphics graphics; Rect rcSrcRoot, rcDstRoot; rootSite.GetGraphics(rootSite.RootBox, out graphics, out rcSrcRoot, out rcDstRoot); try { // we have to set location of the cursor so that a preedit box shows up correctly. if (rootSite.RootBox != null) { var sel = rootSite.RootBox.Selection; if (sel != null) { Rect rcPrimary; Rect rcSecondary; bool fSplit; bool fEndBeforeAnchor; sel.Location(graphics, rcSrcRoot, rcDstRoot, out rcPrimary, out rcSecondary, out fSplit, out fEndBeforeAnchor); var rectScreen = rootSite.RectangleToScreen(rcPrimary); IBusCommunicator.SetCursorLocation(rectScreen.Left, rectScreen.Top, 0, rectScreen.Height); } } } finally { rootSite.ReleaseGraphics(rootSite.RootBox, graphics); } }
/// <summary> /// Synchronize on a commit. /// </summary> protected void ResetAndWaitForCommit() { IBusCommunicator.Reset(); // This should allow any generated commits to be handled by the message pump. // TODO: find a better way to synchronize Application.DoEvents(); }
/// <summary> /// Unfocus the input context /// </summary> public void KillFocus() { if (!IBusCommunicator.Connected) { return; } IBusCommunicator.FocusOut(); }
/// <summary> /// Focus the input context /// </summary> public void Focus() { if (!IBusCommunicator.Connected) { return; } m_ignoreInitialPreedit = true; IBusCommunicator.FocusIn(); SetImeCursorLocation(); }
/// <summary/> protected virtual void Dispose(bool fDisposing) { System.Diagnostics.Debug.WriteLineIf(!fDisposing, "****************** Missing Dispose() call for " + GetType() + "******************"); if (fDisposing) { if (IBusCommunicator != null) { IBusCommunicator.CommitText -= CommitTextEventHandler; IBusCommunicator.UpdatePreeditText -= UpdatePreeditTextEventHandler; IBusCommunicator.HidePreeditText -= HidePreeditTextEventHandler; IBusCommunicator.ForwardKeyEvent -= HandleIBusCommunicatorForwardKeyEvent; IBusCommunicator.Dispose(); } } IBusCommunicator = null; }
/// <summary> /// Handle actual key presses. /// </summary> /// <returns> /// true if we handled keypress /// false if keypress needs handling by someone else /// </returns> public bool NotifyKeyPress(uint charCodeUtf16, uint lParam, Keys modifierKeys) { if (!IBusCommunicator.Connected) { return(false); } m_ignoreInitialPreedit = false; // reset saved preedit selection that we might have set in NotifyMouseClick(). m_savedPreeditSelection = null; // modifierKeys doesn't contains CapsLock and // mono Control.IsKeyLocked(Keys.CapsLock) doesn't work on mono. // so we guess the caps state by unicode value and the shift state // this is far from ideal. if (char.IsUpper((char)charCodeUtf16) && (modifierKeys & Keys.Shift) == 0) { modifierKeys |= Keys.CapsLock; } else if (char.IsLower((char)charCodeUtf16) && (modifierKeys & Keys.Shift) != 0) { modifierKeys |= Keys.CapsLock; } IBusKey key = KeysConverter.Convert(lParam, modifierKeys); if (IBusCommunicator.ProcessKeyEvent(key.keyval, key.keycode, key.state)) { return(true); } // if ProcessKeyEvent doesn't consume the key // we need to kill any preedits and // sync before continuing processing the keypress ResetAndWaitForCommit(); return(false); }