Beispiel #1
0
void
TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent)
{
  nsEventStatus status;

  // When compositon start, notify the rect of first offset character.
  // When not compositon start, notify the rect of selected composition
  // string if text event.
  if (aEvent->message == NS_COMPOSITION_START) {
    nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
    // Update composition start offset
    WidgetQueryContentEvent selectedTextEvent(true,
                                              NS_QUERY_SELECTED_TEXT,
                                              widget);
    widget->DispatchEvent(&selectedTextEvent, status);
    if (selectedTextEvent.mSucceeded) {
      mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
    } else {
      // Unknown offset
      NS_WARNING("Cannot get start offset of IME composition");
      mCompositionStartOffset = 0;
    }
    mCompositionTargetOffset = mCompositionStartOffset;
  } else if (aEvent->mClass != eTextEventClass) {
    return;
  } else {
    mCompositionTargetOffset =
      mCompositionStartOffset + aEvent->AsTextEvent()->TargetClauseOffset();
  }

  NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE);
}
Beispiel #2
0
void
TextComposition::MaybeNotifyIMEOfCompositionEventHandled(
                   const WidgetCompositionEvent* aCompositionEvent)
{
  if (aCompositionEvent->mMessage != eCompositionStart &&
      !aCompositionEvent->CausesDOMTextEvent()) {
    return;
  }

  RefPtr<IMEContentObserver> contentObserver =
    IMEStateManager::GetActiveContentObserver();
  // When IMEContentObserver is managing the editor which has this composition,
  // composition event handled notification should be sent after the observer
  // notifies all pending notifications.  Therefore, we should use it.
  // XXX If IMEContentObserver suddenly loses focus after here and notifying
  //     widget of pending notifications, we won't notify widget of composition
  //     event handled.  Although, this is a bug but it should be okay since
  //     destroying IMEContentObserver notifies IME of blur.  So, native IME
  //     handler can treat it as this notification too.
  if (contentObserver && contentObserver->IsManaging(this)) {
    contentObserver->MaybeNotifyCompositionEventHandled();
    return;
  }
  // Otherwise, e.g., this composition is in non-active window, we should
  // notify widget directly.
  NotifyIME(NOTIFY_IME_OF_COMPOSITION_EVENT_HANDLED);
}
void
TextComposition::NotityUpdateComposition(
                   const WidgetCompositionEvent* aCompositionEvent)
{
  MOZ_RELEASE_ASSERT(!mTabParent);

  nsEventStatus status;

  // When compositon start, notify the rect of first offset character.
  // When not compositon start, notify the rect of selected composition
  // string if compositionchange event.
  if (aCompositionEvent->mMessage == eCompositionStart) {
    nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
    // Update composition start offset
    WidgetQueryContentEvent selectedTextEvent(true, eQuerySelectedText, widget);
    widget->DispatchEvent(&selectedTextEvent, status);
    if (selectedTextEvent.mSucceeded) {
      mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
    } else {
      // Unknown offset
      NS_WARNING("Cannot get start offset of IME composition");
      mCompositionStartOffset = 0;
    }
    mCompositionTargetOffset = mCompositionStartOffset;
  } else if (aCompositionEvent->CausesDOMTextEvent()) {
    mCompositionTargetOffset =
      mCompositionStartOffset + aCompositionEvent->TargetClauseOffset();
  } else {
    return;
  }

  NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE);
}
Beispiel #4
0
// static
void
IMEHandler::SetInputContext(nsWindow* aWindow,
                            InputContext& aInputContext,
                            const InputContextAction& aAction)
{
  // FYI: If there is no composition, this call will do nothing.
  NotifyIME(aWindow, REQUEST_TO_COMMIT_COMPOSITION);

  // Assume that SetInputContext() is called only when aWindow has focus.
  sPluginHasFocus = (aInputContext.mIMEState.mEnabled == IMEState::PLUGIN);

  bool enable = IsIMEEnabled(aInputContext);
  bool adjustOpenState = (enable &&
    aInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE);
  bool open = (adjustOpenState &&
    aInputContext.mIMEState.mOpen == IMEState::OPEN);

  aInputContext.mNativeIMEContext = nullptr;

#ifdef NS_ENABLE_TSF
  // Note that even while a plugin has focus, we need to notify TSF of that.
  if (sIsInTSFMode) {
    nsTextStore::SetInputContext(aWindow, aInputContext, aAction);
    if (IsTSFAvailable()) {
      aInputContext.mNativeIMEContext = nsTextStore::GetTextStore();
      if (adjustOpenState) {
        nsTextStore::SetIMEOpenState(open);
      }
      return;
    }
  } else {
    // Set at least InputScope even when TextStore is not available.
    SetInputScopeForIMM32(aWindow, aInputContext.mHTMLInputType);
  }
#endif // #ifdef NS_ENABLE_TSF

  nsIMEContext IMEContext(aWindow->GetWindowHandle());
  if (enable) {
    IMEContext.AssociateDefaultContext();
    if (!aInputContext.mNativeIMEContext) {
      aInputContext.mNativeIMEContext = static_cast<void*>(IMEContext.get());
    }
  } else if (!aWindow->Destroyed()) {
    // Don't disassociate the context after the window is destroyed.
    IMEContext.Disassociate();
    if (!aInputContext.mNativeIMEContext) {
      // The old InputContext must store the default IMC.
      aInputContext.mNativeIMEContext =
        aWindow->GetInputContext().mNativeIMEContext;
    }
  }

  if (adjustOpenState) {
    IMEContext.SetOpenState(open);
  }
}
// static
void
IMEHandler::SetInputContext(nsWindow* aWindow, InputContext& aInputContext)
{
  // FYI: If there is no composition, this call will do nothing.
  NotifyIME(aWindow, REQUEST_TO_COMMIT_COMPOSITION);

  // Assume that SetInputContext() is called only when aWindow has focus.
  sPluginHasFocus = (aInputContext.mIMEState.mEnabled == IMEState::PLUGIN);

  bool enable = IsIMEEnabled(aInputContext);
  bool adjustOpenState = (enable &&
    aInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE);
  bool open = (adjustOpenState &&
    aInputContext.mIMEState.mOpen == IMEState::OPEN);

  aInputContext.mNativeIMEContext = nullptr;

#ifdef NS_ENABLE_TSF
  // Note that even while a plugin has focus, we need to notify TSF of that.
  if (sIsInTSFMode) {
    nsTextStore::SetInputContext(aInputContext);
    if (IsTSFAvailable()) {
      aInputContext.mNativeIMEContext = nsTextStore::GetTextStore();
    }
    // Currently, nsTextStore doesn't set focus to keyboard disabled document.
    // Therefore, we still need to perform the following legacy code.
  }
#endif // #ifdef NS_ENABLE_TSF

  nsIMEContext IMEContext(aWindow->GetWindowHandle());
  if (enable) {
    IMEContext.AssociateDefaultContext();
    if (!aInputContext.mNativeIMEContext) {
      aInputContext.mNativeIMEContext = static_cast<void*>(IMEContext.get());
    }
  } else if (!aWindow->Destroyed()) {
    // Don't disassociate the context after the window is destroyed.
    IMEContext.Disassociate();
    if (!aInputContext.mNativeIMEContext) {
      // The old InputContext must store the default IMC.
      aInputContext.mNativeIMEContext =
        aWindow->GetInputContext().mNativeIMEContext;
    }
  }

  if (adjustOpenState) {
#ifdef NS_ENABLE_TSF
    if (IsTSFAvailable()) {
      nsTextStore::SetIMEOpenState(open);
      return;
    }
#endif // #ifdef NS_ENABLE_TSF
    IMEContext.SetOpenState(open);
  }
}
void
TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent)
{
  nsEventStatus status;

  // When compositon start, notify the rect of first offset character.
  // When not compositon start, notify the rect of selected composition
  // string if text event.
  if (aEvent->message == NS_COMPOSITION_START) {
    nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
    // Update composition start offset
    WidgetQueryContentEvent selectedTextEvent(true,
                                              NS_QUERY_SELECTED_TEXT,
                                              widget);
    widget->DispatchEvent(&selectedTextEvent, status);
    if (selectedTextEvent.mSucceeded) {
      mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
    } else {
      // Unknown offset
      NS_WARNING("Cannot get start offset of IME composition");
      mCompositionStartOffset = 0;
    }
    mCompositionTargetOffset = mCompositionStartOffset;
  } else if (aEvent->eventStructType != NS_TEXT_EVENT) {
    return;
  } else {
    WidgetTextEvent* textEvent = aEvent->AsTextEvent();
    mCompositionTargetOffset = mCompositionStartOffset;

    for (uint32_t i = 0; i < textEvent->rangeCount; i++) {
      TextRange& range = textEvent->rangeArray[i];
      if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT ||
          range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) {
        mCompositionTargetOffset += range.mStartOffset;
        break;
      }
    }
  }

  NotifyIME(widget::NotificationToIME::NOTIFY_IME_OF_COMPOSITION_UPDATE);
}
Beispiel #7
0
// static
void
IMEHandler::SetInputContext(nsWindow* aWindow,
                            InputContext& aInputContext,
                            const InputContextAction& aAction)
{
  // FYI: If there is no composition, this call will do nothing.
  NotifyIME(aWindow, IMENotification(REQUEST_TO_COMMIT_COMPOSITION));

  const InputContext& oldInputContext = aWindow->GetInputContext();

  // Assume that SetInputContext() is called only when aWindow has focus.
  sPluginHasFocus = (aInputContext.mIMEState.mEnabled == IMEState::PLUGIN);

  bool enable = WinUtils::IsIMEEnabled(aInputContext);
  bool adjustOpenState = (enable &&
    aInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE);
  bool open = (adjustOpenState &&
    aInputContext.mIMEState.mOpen == IMEState::OPEN);

  aInputContext.mNativeIMEContext = nullptr;

#ifdef NS_ENABLE_TSF
  // Note that even while a plugin has focus, we need to notify TSF of that.
  if (sIsInTSFMode) {
    nsTextStore::SetInputContext(aWindow, aInputContext, aAction);
    if (IsTSFAvailable()) {
      aInputContext.mNativeIMEContext = nsTextStore::GetTextStore();
      if (sIsIMMEnabled) {
        // Associate IME context for IMM-IMEs.
        AssociateIMEContext(aWindow, enable);
      } else if (oldInputContext.mIMEState.mEnabled == IMEState::PLUGIN) {
        // Disassociate the IME context from the window when plugin loses focus
        // in pure TSF mode.
        AssociateIMEContext(aWindow, false);
      }
      if (adjustOpenState) {
        nsTextStore::SetIMEOpenState(open);
      }
      return;
    }
  } else {
    // Set at least InputScope even when TextStore is not available.
    SetInputScopeForIMM32(aWindow, aInputContext.mHTMLInputType);
  }
#endif // #ifdef NS_ENABLE_TSF

  AssociateIMEContext(aWindow, enable);

  nsIMEContext IMEContext(aWindow->GetWindowHandle());
  if (adjustOpenState) {
    IMEContext.SetOpenState(open);
  }

  if (aInputContext.mNativeIMEContext) {
    return;
  }

  // The old InputContext must store the default IMC or old TextStore.
  // When IME context is disassociated from the window, use it.
  aInputContext.mNativeIMEContext = enable ?
    static_cast<void*>(IMEContext.get()) : oldInputContext.mNativeIMEContext;
}