зеркало из https://github.com/mozilla/gecko-dev.git
Bug 840409 part.12 Implement widget::IMEHandler::InitInputContext() and widget::IMEHandler::SetInputContext() r=jimm
This commit is contained in:
Родитель
a75d2bc49f
Коммит
053ccfc3c4
|
@ -168,20 +168,6 @@ IMEHandler::GetUpdatePreference()
|
|||
return nsIMEUpdatePreference(false, false);
|
||||
}
|
||||
|
||||
void
|
||||
IMEHandler::SetOpenState(nsWindow* aWindow, bool aOpen)
|
||||
{
|
||||
#ifdef NS_ENABLE_TSF
|
||||
if (sIsInTSFMode) {
|
||||
nsTextStore::SetIMEOpenState(aOpen);
|
||||
return;
|
||||
}
|
||||
#endif //NS_ENABLE_TSF
|
||||
|
||||
nsIMEContext IMEContext(aWindow->GetWindowHandle());
|
||||
IMEContext.SetOpenState(aOpen);
|
||||
}
|
||||
|
||||
// static
|
||||
bool
|
||||
IMEHandler::GetOpenState(nsWindow* aWindow)
|
||||
|
@ -200,10 +186,91 @@ IMEHandler::GetOpenState(nsWindow* aWindow)
|
|||
void
|
||||
IMEHandler::OnDestroyWindow(nsWindow* aWindow)
|
||||
{
|
||||
// We need to do nothing here for TSF. Just restore the default context
|
||||
// if it's been disassociated.
|
||||
nsIMEContext IMEContext(aWindow->GetWindowHandle());
|
||||
IMEContext.AssociateDefaultContext();
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
bool enable = (aInputContext.mIMEState.mEnabled == IMEState::ENABLED ||
|
||||
aInputContext.mIMEState.mEnabled == IMEState::PLUGIN);
|
||||
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
|
||||
if (sIsInTSFMode) {
|
||||
aInputContext.mNativeIMEContext = nsTextStore::GetTextStore();
|
||||
nsTextStore::SetInputContext(aInputContext);
|
||||
// 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 (sIsInTSFMode) {
|
||||
nsTextStore::SetIMEOpenState(open);
|
||||
return;
|
||||
}
|
||||
#endif // #ifdef NS_ENABLE_TSF
|
||||
IMEContext.SetOpenState(open);
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void
|
||||
IMEHandler::InitInputContext(nsWindow* aWindow, InputContext& aInputContext)
|
||||
{
|
||||
// For a11y, the default enabled state should be 'enabled'.
|
||||
aInputContext.mIMEState.mEnabled = IMEState::ENABLED;
|
||||
|
||||
#ifdef NS_ENABLE_TSF
|
||||
if (sIsInTSFMode) {
|
||||
nsTextStore::SetInputContext(aInputContext);
|
||||
aInputContext.mNativeIMEContext = nsTextStore::GetTextStore();
|
||||
MOZ_ASSERT(aInputContext.mNativeIMEContext);
|
||||
return;
|
||||
}
|
||||
#endif // #ifdef NS_ENABLE_TSF
|
||||
|
||||
// NOTE: mNativeIMEContext may be null if IMM module isn't installed.
|
||||
nsIMEContext IMEContext(aWindow->GetWindowHandle());
|
||||
aInputContext.mNativeIMEContext = static_cast<void*>(IMEContext.get());
|
||||
MOZ_ASSERT(aInputContext.mNativeIMEContext || !CurrentKeyboardLayoutHasIME());
|
||||
// If no IME context is available, we should set the widget's pointer since
|
||||
// nullptr indicates there is only one context per process on the platform.
|
||||
if (!aInputContext.mNativeIMEContext) {
|
||||
aInputContext.mNativeIMEContext = static_cast<void*>(aWindow);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// static
|
||||
bool
|
||||
|
|
|
@ -16,6 +16,8 @@ struct nsIMEUpdatePreference;
|
|||
namespace mozilla {
|
||||
namespace widget {
|
||||
|
||||
struct InputContext;
|
||||
|
||||
/**
|
||||
* IMEHandler class is a mediator class. On Windows, there are two IME API
|
||||
* sets: One is IMM which is legacy API set. The other is TSF which is modern
|
||||
|
@ -68,9 +70,8 @@ public:
|
|||
static nsIMEUpdatePreference GetUpdatePreference();
|
||||
|
||||
/**
|
||||
* Sets and Gets IME open state.
|
||||
* Returns IME open state on the window.
|
||||
*/
|
||||
static void SetOpenState(nsWindow* aWindow, bool aOpen);
|
||||
static bool GetOpenState(nsWindow* aWindow);
|
||||
|
||||
/**
|
||||
|
@ -78,6 +79,17 @@ public:
|
|||
*/
|
||||
static void OnDestroyWindow(nsWindow* aWindow);
|
||||
|
||||
/**
|
||||
* Called when nsIWidget::SetInputContext() is called before the window's
|
||||
* InputContext is modified actually.
|
||||
*/
|
||||
static void SetInputContext(nsWindow* aWindow, InputContext& aInputContext);
|
||||
|
||||
/**
|
||||
* Called when the window is created.
|
||||
*/
|
||||
static void InitInputContext(nsWindow* aWindow, InputContext& aInputContext);
|
||||
|
||||
/**
|
||||
* "Kakutei-Undo" of ATOK or WXG (both of them are Japanese IME) causes
|
||||
* strange WM_KEYDOWN/WM_KEYUP/WM_CHAR message pattern. So, when this
|
||||
|
|
|
@ -107,7 +107,7 @@ public:
|
|||
|
||||
static void SetInputContext(const InputContext& aContext)
|
||||
{
|
||||
if (!sTsfTextStore) return;
|
||||
NS_ENSURE_TRUE_VOID(sTsfTextStore);
|
||||
sTsfTextStore->SetInputScope(aContext.mHTMLInputType);
|
||||
sTsfTextStore->SetInputContextInternal(aContext.mIMEState.mEnabled);
|
||||
}
|
||||
|
@ -163,6 +163,11 @@ public:
|
|||
return (void*) & sDisplayAttrMgr;
|
||||
}
|
||||
|
||||
static void* GetTextStore()
|
||||
{
|
||||
return static_cast<void*>(sTsfTextStore);
|
||||
}
|
||||
|
||||
static bool IsInTSFMode()
|
||||
{
|
||||
return sTsfThreadMgr != nullptr;
|
||||
|
|
|
@ -589,16 +589,7 @@ nsWindow::Create(nsIWidget *aParent,
|
|||
|
||||
SubclassWindow(TRUE);
|
||||
|
||||
// NOTE: mNativeIMEContext may be null if IMM module isn't installed.
|
||||
nsIMEContext IMEContext(mWnd);
|
||||
mInputContext.mNativeIMEContext = static_cast<void*>(IMEContext.get());
|
||||
MOZ_ASSERT(mInputContext.mNativeIMEContext ||
|
||||
!IMEHandler::CurrentKeyboardLayoutHasIME());
|
||||
// If no IME context is available, we should set this widget's pointer since
|
||||
// nullptr indicates there is only one context per process on the platform.
|
||||
if (!mInputContext.mNativeIMEContext) {
|
||||
mInputContext.mNativeIMEContext = this;
|
||||
}
|
||||
IMEHandler::InitInputContext(this, mInputContext);
|
||||
|
||||
// If the internal variable set by the config.trim_on_minimize pref has not
|
||||
// been initialized, and if this is the hidden window (conveniently created
|
||||
|
@ -7390,37 +7381,9 @@ NS_IMETHODIMP_(void)
|
|||
nsWindow::SetInputContext(const InputContext& aContext,
|
||||
const InputContextAction& aAction)
|
||||
{
|
||||
#ifdef NS_ENABLE_TSF
|
||||
nsTextStore::SetInputContext(aContext);
|
||||
#endif //NS_ENABLE_TSF
|
||||
if (IMEHandler::IsComposing()) {
|
||||
ResetInputState();
|
||||
}
|
||||
void* nativeIMEContext = mInputContext.mNativeIMEContext;
|
||||
mInputContext = aContext;
|
||||
mInputContext.mNativeIMEContext = nullptr;
|
||||
bool enable = (mInputContext.mIMEState.mEnabled == IMEState::ENABLED ||
|
||||
mInputContext.mIMEState.mEnabled == IMEState::PLUGIN);
|
||||
|
||||
nsIMEContext IMEContext(mWnd);
|
||||
if (enable) {
|
||||
IMEContext.AssociateDefaultContext();
|
||||
mInputContext.mNativeIMEContext = static_cast<void*>(IMEContext.get());
|
||||
} else if (!mOnDestroyCalled) {
|
||||
// Don't disassociate the context after the window is destroyed.
|
||||
IMEContext.Disassociate();
|
||||
}
|
||||
|
||||
// Restore the latest associated context when we cannot get actual context.
|
||||
if (!mInputContext.mNativeIMEContext) {
|
||||
mInputContext.mNativeIMEContext = nativeIMEContext;
|
||||
}
|
||||
|
||||
if (enable &&
|
||||
mInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE) {
|
||||
bool open = (mInputContext.mIMEState.mOpen == IMEState::OPEN);
|
||||
IMEHandler::SetOpenState(this, open);
|
||||
}
|
||||
InputContext newInputContext = aContext;
|
||||
IMEHandler::SetInputContext(this, newInputContext);
|
||||
mInputContext = newInputContext;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(InputContext)
|
||||
|
|
Загрузка…
Ссылка в новой задаче