diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 8726e49d8ff..b403933a4e7 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -1290,11 +1290,6 @@ public: static void TraceWrapper(nsWrapperCache* aCache, TraceCallback aCallback, void *aClosure); - /** - * Convert nsIContent::IME_STATUS_* to nsIWidget::IME_STATUS_* - */ - static PRUint32 GetWidgetStatusFromIMEStatus(PRUint32 aState); - /* * Notify when the first XUL menu is opened and when the all XUL menus are * closed. At opening, aInstalling should be TRUE, otherwise, it should be diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index fcd5f0fc8f0..2285ab4c84a 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -4027,25 +4027,6 @@ nsContentUtils::DropJSObjects(void* aScriptObjectHolder) return rv; } -/* static */ -PRUint32 -nsContentUtils::GetWidgetStatusFromIMEStatus(PRUint32 aState) -{ - switch (aState & nsIContent::IME_STATUS_MASK_ENABLED) { - case nsIContent::IME_STATUS_DISABLE: - return InputContext::IME_DISABLED; - case nsIContent::IME_STATUS_ENABLE: - return InputContext::IME_ENABLED; - case nsIContent::IME_STATUS_PASSWORD: - return InputContext::IME_PASSWORD; - case nsIContent::IME_STATUS_PLUGIN: - return InputContext::IME_PLUGIN; - default: - NS_ERROR("The given state doesn't have valid enable state"); - return InputContext::IME_ENABLED; - } -} - /* static */ void nsContentUtils::NotifyInstalledMenuKeyboardListener(bool aInstalling) diff --git a/content/events/src/nsIMEStateManager.cpp b/content/events/src/nsIMEStateManager.cpp index 65cf97f22bb..746ac0e5449 100644 --- a/content/events/src/nsIMEStateManager.cpp +++ b/content/events/src/nsIMEStateManager.cpp @@ -69,6 +69,26 @@ using namespace mozilla::widget; +static +/* static */ +IMEState::Enabled +GetWidgetStatusFromIMEStatus(PRUint32 aState) +{ + switch (aState & nsIContent::IME_STATUS_MASK_ENABLED) { + case nsIContent::IME_STATUS_DISABLE: + return IMEState::DISABLED; + case nsIContent::IME_STATUS_ENABLE: + return IMEState::ENABLED; + case nsIContent::IME_STATUS_PASSWORD: + return IMEState::PASSWORD; + case nsIContent::IME_STATUS_PLUGIN: + return IMEState::PLUGIN; + default: + NS_ERROR("The given state doesn't have valid enable state"); + return IMEState::ENABLED; + } +} + /******************************************************************/ /* nsIMEStateManager */ /******************************************************************/ @@ -181,8 +201,8 @@ nsIMEStateManager::OnChangeFocusInternal(nsPresContext* aPresContext, return NS_OK; } InputContext context = widget->GetInputContext(); - if (context.mIMEEnabled == - nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) { + if (context.mIMEState.mEnabled == + GetWidgetStatusFromIMEStatus(newEnabledState)) { // the enabled state isn't changing. return NS_OK; } @@ -245,8 +265,8 @@ nsIMEStateManager::UpdateIMEState(PRUint32 aNewIMEState, nsIContent* aContent) // Don't update IME state when enabled state isn't actually changed. InputContext context = widget->GetInputContext(); PRUint32 newEnabledState = aNewIMEState & nsIContent::IME_STATUS_MASK_ENABLED; - if (context.mIMEEnabled == - nsContentUtils::GetWidgetStatusFromIMEStatus(newEnabledState)) { + if (context.mIMEState.mEnabled == + GetWidgetStatusFromIMEStatus(newEnabledState)) { return; } @@ -311,61 +331,60 @@ nsIMEStateManager::SetIMEState(PRUint32 aState, nsIWidget* aWidget, InputContextAction aAction) { - if (aState & nsIContent::IME_STATUS_MASK_ENABLED) { - if (!aWidget) - return; + NS_ENSURE_TRUE(aWidget, ); - PRUint32 state = nsContentUtils::GetWidgetStatusFromIMEStatus(aState); - InputContext context; - context.mIMEEnabled = state; + InputContext context; + context.mIMEState.mEnabled = GetWidgetStatusFromIMEStatus(aState); - if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML && - (aContent->Tag() == nsGkAtoms::input || - aContent->Tag() == nsGkAtoms::textarea)) { - aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, - context.mHTMLInputType); - aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint, - context.mActionHint); + if (aContent && aContent->GetNameSpaceID() == kNameSpaceID_XHTML && + (aContent->Tag() == nsGkAtoms::input || + aContent->Tag() == nsGkAtoms::textarea)) { + aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, + context.mHTMLInputType); + aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::moz_action_hint, + context.mActionHint); - // if we don't have an action hint and return won't submit the form use "next" - if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) { - bool willSubmit = false; - nsCOMPtr control(do_QueryInterface(aContent)); - mozilla::dom::Element* formElement = control->GetFormElement(); - nsCOMPtr form; - if (control) { - // is this a form and does it have a default submit element? - if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) { - willSubmit = true; - // is this an html form and does it only have a single text input element? - } else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() && - static_cast(formElement)->HasSingleTextControl()) { - willSubmit = true; - } + // if we don't have an action hint and return won't submit the form use "next" + if (context.mActionHint.IsEmpty() && aContent->Tag() == nsGkAtoms::input) { + bool willSubmit = false; + nsCOMPtr control(do_QueryInterface(aContent)); + mozilla::dom::Element* formElement = control->GetFormElement(); + nsCOMPtr form; + if (control) { + // is this a form and does it have a default submit element? + if ((form = do_QueryInterface(formElement)) && form->GetDefaultSubmitElement()) { + willSubmit = true; + // is this an html form and does it only have a single text input element? + } else if (formElement && formElement->Tag() == nsGkAtoms::form && formElement->IsHTML() && + static_cast(formElement)->HasSingleTextControl()) { + willSubmit = true; } - context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH - ? NS_LITERAL_STRING("search") - : NS_LITERAL_STRING("go") - : formElement - ? NS_LITERAL_STRING("next") - : EmptyString()); } + context.mActionHint.Assign(willSubmit ? control->GetType() == NS_FORM_INPUT_SEARCH + ? NS_LITERAL_STRING("search") + : NS_LITERAL_STRING("go") + : formElement + ? NS_LITERAL_STRING("next") + : EmptyString()); } - - // XXX I think that we should use nsContentUtils::IsCallerChrome() instead - // of the process type. - if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN && - XRE_GetProcessType() != GeckoProcessType_Content) { - aAction.mCause = InputContextAction::CAUSE_UNKNOWN_CHROME; - } - - aWidget->SetInputContext(context, aAction); - - nsContentUtils::AddScriptRunner(new IMEEnabledStateChangedEvent(state)); } + + // XXX I think that we should use nsContentUtils::IsCallerChrome() instead + // of the process type. + if (aAction.mCause == InputContextAction::CAUSE_UNKNOWN && + XRE_GetProcessType() != GeckoProcessType_Content) { + aAction.mCause = InputContextAction::CAUSE_UNKNOWN_CHROME; + } + if (aState & nsIContent::IME_STATUS_MASK_OPENED) { bool open = !!(aState & nsIContent::IME_STATUS_OPEN); - aWidget->SetIMEOpenState(open); + context.mIMEState.mOpen = open ? IMEState::OPEN : IMEState::CLOSED; + } + + aWidget->SetInputContext(context, aAction); + if (aState & nsIContent::IME_STATUS_MASK_ENABLED) { + nsContentUtils::AddScriptRunner( + new IMEEnabledStateChangedEvent(context.mIMEState.mEnabled)); } } diff --git a/content/events/src/nsIMEStateManager.h b/content/events/src/nsIMEStateManager.h index c3d5cf03ca7..71627d7359a 100644 --- a/content/events/src/nsIMEStateManager.h +++ b/content/events/src/nsIMEStateManager.h @@ -55,6 +55,7 @@ class nsISelection; class nsIMEStateManager { protected: + typedef mozilla::widget::IMEState IMEState; typedef mozilla::widget::InputContext InputContext; typedef mozilla::widget::InputContextAction InputContextAction; diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp index 1c4f4402448..3d4a38f9d86 100644 --- a/dom/base/nsDOMWindowUtils.cpp +++ b/dom/base/nsDOMWindowUtils.cpp @@ -1041,11 +1041,15 @@ nsDOMWindowUtils::GetIMEIsOpen(bool *aState) // Open state should not be available when IME is not enabled. InputContext context = widget->GetInputContext(); - if (context.mIMEEnabled != InputContext::IME_ENABLED) { + if (context.mIMEState.mEnabled != IMEState::ENABLED) { return NS_ERROR_NOT_AVAILABLE; } - return widget->GetIMEOpenState(aState); + if (context.mIMEState.mOpen == IMEState::OPEN_STATE_NOT_SUPPORTED) { + return NS_ERROR_NOT_IMPLEMENTED; + } + *aState = (context.mIMEState.mOpen == IMEState::OPEN); + return NS_OK; } NS_IMETHODIMP @@ -1058,7 +1062,7 @@ nsDOMWindowUtils::GetIMEStatus(PRUint32 *aState) return NS_ERROR_FAILURE; InputContext context = widget->GetInputContext(); - *aState = context.mIMEEnabled; + *aState = static_cast(context.mIMEState.mEnabled); return NS_OK; } diff --git a/dom/ipc/PBrowser.ipdl b/dom/ipc/PBrowser.ipdl index e6da4fbcda3..4074fd16aba 100644 --- a/dom/ipc/PBrowser.ipdl +++ b/dom/ipc/PBrowser.ipdl @@ -172,18 +172,15 @@ parent: */ sync EndIMEComposition(bool cancel) returns (nsString composition); - sync GetInputContext() returns (PRUint32 value); + sync GetInputContext() returns (PRInt32 IMEEnabled, PRInt32 IMEOpen); - SetInputContext(PRUint32 value, + SetInputContext(PRInt32 IMEEnabled, + PRInt32 IMEOpen, nsString type, nsString actionHint, PRInt32 cause, PRInt32 focusChange); - sync GetIMEOpenState() returns (bool value); - - SetIMEOpenState(bool value); - /** * Gets the DPI of the screen corresponding to this browser. */ diff --git a/dom/ipc/TabParent.cpp b/dom/ipc/TabParent.cpp index fe200f630c7..73dec07f6f7 100644 --- a/dom/ipc/TabParent.cpp +++ b/dom/ipc/TabParent.cpp @@ -564,35 +564,42 @@ TabParent::RecvEndIMEComposition(const bool& aCancel, } bool -TabParent::RecvGetInputContext(PRUint32* aValue) +TabParent::RecvGetInputContext(PRInt32* aIMEEnabled, + PRInt32* aIMEOpen) { nsCOMPtr widget = GetWidget(); if (!widget) { - *aValue = InputContext::IME_DISABLED; + *aIMEEnabled = IMEState::DISABLED; + *aIMEOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; return true; } InputContext context = widget->GetInputContext(); - *aValue = context.mIMEEnabled; + *aIMEEnabled = static_cast(context.mIMEState.mEnabled); + *aIMEOpen = static_cast(context.mIMEState.mOpen); return true; } bool -TabParent::RecvSetInputContext(const PRUint32& aValue, +TabParent::RecvSetInputContext(const PRInt32& aIMEEnabled, + const PRInt32& aIMEOpen, const nsString& aType, const nsString& aActionHint, const PRInt32& aCause, const PRInt32& aFocusChange) { // mIMETabParent (which is actually static) tracks which if any TabParent has IMEFocus - // When the input mode is set to anything but IME_STATUS_NONE, mIMETabParent should be set to this - mIMETabParent = aValue & nsIContent::IME_STATUS_MASK_ENABLED ? this : nsnull; + // When the input mode is set to anything but IMEState::DISABLED, + // mIMETabParent should be set to this + mIMETabParent = + aIMEEnabled != static_cast(IMEState::DISABLED) ? this : nsnull; nsCOMPtr widget = GetWidget(); if (!widget || !AllowContentIME()) return true; InputContext context; - context.mIMEEnabled = aValue; + context.mIMEState.mEnabled = static_cast(aIMEEnabled); + context.mIMEState.mOpen = static_cast(aIMEOpen); context.mHTMLInputType.Assign(aType); context.mActionHint.Assign(aActionHint); InputContextAction action( @@ -605,30 +612,12 @@ TabParent::RecvSetInputContext(const PRUint32& aValue, return true; nsAutoString state; - state.AppendInt(aValue); + state.AppendInt(aIMEEnabled); observerService->NotifyObservers(nsnull, "ime-enabled-state-changed", state.get()); return true; } -bool -TabParent::RecvGetIMEOpenState(bool* aValue) -{ - nsCOMPtr widget = GetWidget(); - if (widget) - widget->GetIMEOpenState(aValue); - return true; -} - -bool -TabParent::RecvSetIMEOpenState(const bool& aValue) -{ - nsCOMPtr widget = GetWidget(); - if (widget && AllowContentIME()) - widget->SetIMEOpenState(aValue); - return true; -} - bool TabParent::RecvGetDPI(float* aValue) { diff --git a/dom/ipc/TabParent.h b/dom/ipc/TabParent.h index 32ab053ba06..6776bfdd67e 100644 --- a/dom/ipc/TabParent.h +++ b/dom/ipc/TabParent.h @@ -103,14 +103,14 @@ public: virtual bool RecvNotifyIMETextHint(const nsString& aText); virtual bool RecvEndIMEComposition(const bool& aCancel, nsString* aComposition); - virtual bool RecvGetInputContext(PRUint32* aValue); - virtual bool RecvSetInputContext(const PRUint32& aValue, + virtual bool RecvGetInputContext(PRInt32* aIMEEnabled, + PRInt32* aIMEOpen); + virtual bool RecvSetInputContext(const PRInt32& aIMEEnabled, + const PRInt32& aIMEOpen, const nsString& aType, const nsString& aActionHint, const PRInt32& aCause, const PRInt32& aFocusChange); - virtual bool RecvGetIMEOpenState(bool* aValue); - virtual bool RecvSetIMEOpenState(const bool& aValue); virtual bool RecvSetCursor(const PRUint32& aValue); virtual bool RecvSetBackgroundColor(const nscolor& aValue); virtual bool RecvGetDPI(float* aValue); diff --git a/widget/public/nsIWidget.h b/widget/public/nsIWidget.h index 8f55ee00c4b..f8b89cf449d 100644 --- a/widget/public/nsIWidget.h +++ b/widget/public/nsIWidget.h @@ -118,9 +118,8 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event); #endif #define NS_IWIDGET_IID \ - { 0xb4fa00ae, 0x913c, 0x42b1, \ - { 0x93, 0xc8, 0x41, 0x57, 0x1e, 0x3d, 0x94, 0x99 } } - + { 0x34460b01, 0x3dc2, 0x4b58, \ + { 0x8e, 0xd3, 0x7e, 0x7c, 0x33, 0xb5, 0x78, 0x8b } } /* * Window shadow styles * Also used for the -moz-window-shadow CSS property @@ -235,9 +234,9 @@ struct nsIMEUpdatePreference { namespace mozilla { namespace widget { -struct InputContext { +struct IMEState { /** - * IME enabled states, the mIMEEnabled value of + * IME enabled states, the mEnabled value of * SetInputContext()/GetInputContext() should be one value of following * values. * @@ -245,45 +244,77 @@ struct InputContext { * nsIDOMWindowUtils.idl * nsContentUtils::GetWidgetStatusFromIMEStatus */ - enum { + enum Enabled { /** * 'Disabled' means the user cannot use IME. So, the IME open state should * be 'closed' during 'disabled'. */ - IME_DISABLED = 0, + DISABLED, /** * 'Enabled' means the user can use IME. */ - IME_ENABLED = 1, + ENABLED, /** * 'Password' state is a special case for the password editors. * E.g., on mac, the password editors should disable the non-Roman * keyboard layouts at getting focus. Thus, the password editor may have * special rules on some platforms. */ - IME_PASSWORD = 2, + PASSWORD, /** * This state is used when a plugin is focused. * When a plug-in is focused content, we should send native events * directly. Because we don't process some native events, but they may * be needed by the plug-in. */ - IME_PLUGIN = 3, - /** - * IME enabled state mask. - */ - IME_ENABLED_STATE_MASK = 0xF + PLUGIN }; + Enabled mEnabled; - PRUint32 mIMEEnabled; + /** + * IME open states the mOpen value of SetInputContext() should be one value of + * OPEN, CLOSE or DONT_CHANGE_OPEN_STATE. GetInputContext() should return + * OPEN, CLOSE or OPEN_STATE_NOT_SUPPORTED. + */ + enum Open { + /** + * 'Unsupported' means the platform cannot return actual IME open state. + * This value is used only by GetInputContext(). + */ + OPEN_STATE_NOT_SUPPORTED, + /** + * 'Don't change' means the widget shouldn't change IME open state when + * SetInputContext() is called. + */ + DONT_CHANGE_OPEN_STATE = OPEN_STATE_NOT_SUPPORTED, + /** + * 'Open' means that IME should compose in its primary language (or latest + * input mode except direct ASCII character input mode). Even if IME is + * opened by this value, users should be able to close IME by theirselves. + * Web contents can specify this value by |ime-mode: active;|. + */ + OPEN, + /** + * 'Closed' means that IME shouldn't handle key events (or should handle + * as ASCII character inputs on mobile device). Even if IME is closed by + * this value, users should be able to open IME by theirselves. + * Web contents can specify this value by |ime-mode: inactive;|. + */ + CLOSED + }; + Open mOpen; + + IMEState() : mEnabled(ENABLED), mOpen(DONT_CHANGE_OPEN_STATE) { } +}; + +struct InputContext { + IMEState mIMEState; /* The type of the input if the input is a html input field */ nsString mHTMLInputType; /* A hint for the action that is performed when the input is submitted */ nsString mActionHint; - - InputContext() : mIMEEnabled(IME_ENABLED) {} }; struct InputContextAction { @@ -355,6 +386,7 @@ class nsIWidget : public nsISupports { typedef mozilla::layers::LayerManager LayerManager; typedef LayerManager::LayersBackend LayersBackend; typedef mozilla::layers::PLayersChild PLayersChild; + typedef mozilla::widget::IMEState IMEState; typedef mozilla::widget::InputContext InputContext; typedef mozilla::widget::InputContextAction InputContextAction; @@ -1326,20 +1358,6 @@ class nsIWidget : public nsISupports { * http://bugzilla.mozilla.org/show_bug.cgi?id=16940#c48 */ - /* - * Set the state to 'Opened' or 'Closed'. - * If aState is TRUE, IME open state is set to 'Opened'. - * If aState is FALSE, set to 'Closed'. - */ - NS_IMETHOD SetIMEOpenState(bool aState) = 0; - - /* - * Get IME is 'Opened' or 'Closed'. - * If IME is 'Opened', aState is set true. - * If IME is 'Closed', aState is set false. - */ - NS_IMETHOD GetIMEOpenState(bool* aState) = 0; - /* * Destruct and don't commit the IME composition string. */ diff --git a/widget/src/android/nsWindow.cpp b/widget/src/android/nsWindow.cpp index e09968a737d..bdaa9d835d9 100644 --- a/widget/src/android/nsWindow.cpp +++ b/widget/src/android/nsWindow.cpp @@ -2050,21 +2050,22 @@ NS_IMETHODIMP_(void) nsWindow::SetInputContext(const InputContext& aContext, const InputContextAction& aAction) { - ALOGIME("IME: SetInputContext: s=%d action=0x%X, 0x%X", - aContext.mIMEEnabled, aAction.mCause, aAction.mFocusChange); + ALOGIME("IME: SetInputContext: s=0x%X, 0x%X, action=0x%X, 0x%X", + aContext.mIMEState.mEnabled, aContext.mIMEState.mOpen, + aAction.mCause, aAction.mFocusChange); mInputContext = aContext; // Ensure that opening the virtual keyboard is allowed for this specific // InputContext depending on the content.ime.strict.policy pref - if (aContext.mIMEEnabled != InputContext::IME_DISABLED && - aContext.mIMEEnabled != InputContext::IME_PLUGIN && + if (aContext.mIMEState.mEnabled != IMEState::DISABLED && + aContext.mIMEState.mEnabled != IMEState::PLUGIN && Preferences::GetBool("content.ime.strict_policy", false) && !aAction.ContentGotFocusByTrustedCause()) { return; } - AndroidBridge::NotifyIMEEnabled(int(aContext.mIMEEnabled), + AndroidBridge::NotifyIMEEnabled(int(aContext.mIMEState.mEnabled), aContext.mHTMLInputType, aContext.mActionHint); } @@ -2072,6 +2073,7 @@ nsWindow::SetInputContext(const InputContext& aContext, NS_IMETHODIMP_(InputContext) nsWindow::GetInputContext() { + mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; return mInputContext; } diff --git a/widget/src/cocoa/nsChildView.h b/widget/src/cocoa/nsChildView.h index 092242a81d9..cf4c528b4ac 100644 --- a/widget/src/cocoa/nsChildView.h +++ b/widget/src/cocoa/nsChildView.h @@ -446,8 +446,6 @@ public: NS_IMETHOD ForceUpdateNativeMenuAt(const nsAString& indexString); NS_IMETHOD ResetInputState(); - NS_IMETHOD SetIMEOpenState(bool aState); - NS_IMETHOD GetIMEOpenState(bool* aState); NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, const InputContextAction& aAction); NS_IMETHOD_(InputContext) GetInputContext(); diff --git a/widget/src/cocoa/nsChildView.mm b/widget/src/cocoa/nsChildView.mm index 53a1b51258c..07b7c1982f8 100644 --- a/widget/src/cocoa/nsChildView.mm +++ b/widget/src/cocoa/nsChildView.mm @@ -1673,39 +1673,27 @@ NS_IMETHODIMP nsChildView::ResetInputState() return NS_OK; } -// 'open' means that it can take non-ASCII chars -NS_IMETHODIMP nsChildView::SetIMEOpenState(bool aState) -{ - NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE); - mTextInputHandler->SetIMEOpenState(aState); - return NS_OK; -} - -// 'open' means that it can take non-ASCII chars -NS_IMETHODIMP nsChildView::GetIMEOpenState(bool* aState) -{ - NS_ENSURE_TRUE(mTextInputHandler, NS_ERROR_NOT_AVAILABLE); - *aState = mTextInputHandler->IsIMEOpened(); - return NS_OK; -} - NS_IMETHODIMP_(void) nsChildView::SetInputContext(const InputContext& aContext, const InputContextAction& aAction) { NS_ENSURE_TRUE(mTextInputHandler, ); mInputContext = aContext; - switch (aContext.mIMEEnabled) { - case InputContext::IME_ENABLED: - case InputContext::IME_PLUGIN: + switch (aContext.mIMEState.mEnabled) { + case IMEState::ENABLED: + case IMEState::PLUGIN: mTextInputHandler->SetASCIICapableOnly(false); mTextInputHandler->EnableIME(true); + if (mInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE) { + mTextInputHandler->SetIMEOpenState( + mInputContext.mIMEState.mOpen == IMEState::OPEN); + } break; - case InputContext::IME_DISABLED: + case IMEState::DISABLED: mTextInputHandler->SetASCIICapableOnly(false); mTextInputHandler->EnableIME(false); break; - case InputContext::IME_PASSWORD: + case IMEState::PASSWORD: mTextInputHandler->SetASCIICapableOnly(true); mTextInputHandler->EnableIME(false); break; @@ -1717,6 +1705,19 @@ nsChildView::SetInputContext(const InputContext& aContext, NS_IMETHODIMP_(InputContext) nsChildView::GetInputContext() { + switch (mInputContext.mIMEState.mEnabled) { + case IMEState::ENABLED: + case IMEState::PLUGIN: + if (mTextInputHandler) { + mInputContext.mIMEState.mOpen = + mTextInputHandler->IsIMEOpened() ? IMEState::OPEN : IMEState::CLOSED; + break; + } + // If mTextInputHandler is null, set CLOSED instead... + default: + mInputContext.mIMEState.mOpen = IMEState::CLOSED; + break; + } return mInputContext; } diff --git a/widget/src/gtk2/nsGtkIMModule.cpp b/widget/src/gtk2/nsGtkIMModule.cpp index 851529e888d..eb1c2036d88 100644 --- a/widget/src/gtk2/nsGtkIMModule.cpp +++ b/widget/src/gtk2/nsGtkIMModule.cpp @@ -86,13 +86,13 @@ static const char* GetEnabledStateName(PRUint32 aState) { switch (aState) { - case InputContext::IME_DISABLED: + case IMEState::DISABLED: return "DISABLED"; - case InputContext::IME_ENABLED: + case IMEState::ENABLED: return "ENABLED"; - case InputContext::IME_PASSWORD: + case IMEState::PASSWORD: return "PASSWORD"; - case InputContext::IME_PLUGIN: + case IMEState::PLUGIN: return "PLUG_IN"; default: return "UNKNOWN ENABLED STATUS!!"; @@ -122,7 +122,6 @@ nsGtkIMModule::nsGtkIMModule(nsWindow* aOwnerWindow) : gGtkIMLog = PR_NewLogModule("nsGtkIMModuleWidgets"); } #endif - mInputContext.mIMEEnabled = InputContext::IME_ENABLED; Init(); } @@ -258,7 +257,7 @@ nsGtkIMModule::OnDestroyWindow(nsWindow* aWindow) mOwnerWindow = nsnull; mLastFocusedWindow = nsnull; - mInputContext.mIMEEnabled = InputContext::IME_DISABLED; + mInputContext.mIMEState.mEnabled = IMEState::DISABLED; PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, (" SUCCEEDED, Completely destroyed")); @@ -547,14 +546,14 @@ nsGtkIMModule::SetInputContext(nsWindow* aCaller, const InputContext* aContext, const InputContextAction* aAction) { - if (aContext->mIMEEnabled == mInputContext.mIMEEnabled || + if (aContext->mIMEState.mEnabled == mInputContext.mIMEState.mEnabled || NS_UNLIKELY(IsDestroyed())) { return; } PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, ("GtkIMModule(%p): SetInputContext, aCaller=%p, aState=%s mHTMLInputType=%s", - this, aCaller, GetEnabledStateName(aContext->mIMEEnabled), + this, aCaller, GetEnabledStateName(aContext->mIMEState.mEnabled), NS_ConvertUTF16toUTF8(aContext->mHTMLInputType).get())); if (aCaller != mLastFocusedWindow) { @@ -598,8 +597,8 @@ nsGtkIMModule::SetInputContext(nsWindow* aCaller, if (IsEnabled()) { // Ensure that opening the virtual keyboard is allowed for this specific // InputContext depending on the content.ime.strict.policy pref - if (mInputContext.mIMEEnabled != InputContext::IME_DISABLED && - mInputContext.mIMEEnabled != InputContext::IME_PLUGIN && + if (mInputContext.mIMEState.mEnabled != IMEState::DISABLED && + mInputContext.mIMEState.mEnabled != IMEState::PLUGIN && Preferences::GetBool("content.ime.strict_policy", false) && !aAction->ContentGotFocusByTrustedCause()) { return; @@ -611,10 +610,10 @@ nsGtkIMModule::SetInputContext(nsWindow* aCaller, int mode; g_object_get(im, "hildon-input-mode", &mode, NULL); - if (mInputContext.mIMEEnabled == InputContext::IME_ENABLED || - mInputContext.mIMEEnabled == InputContext::IME_PLUGIN) { + if (mInputContext.mIMEState.mEnabled == IMEState::ENABLED || + mInputContext.mIMEState.mEnabled == IMEState::PLUGIN) { mode &= ~HILDON_GTK_INPUT_MODE_INVISIBLE; - } else if (mInputContext.mIMEEnabled == InputContext::IME_PASSWORD) { + } else if (mInputContext.mIMEState.mEnabled == IMEState::PASSWORD) { mode |= HILDON_GTK_INPUT_MODE_INVISIBLE; } @@ -659,6 +658,7 @@ nsGtkIMModule::SetInputContext(nsWindow* aCaller, InputContext nsGtkIMModule::GetInputContext() { + mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; return mInputContext; } @@ -681,7 +681,7 @@ nsGtkIMModule::GetContext() } #ifndef NS_IME_ENABLED_ON_PASSWORD_FIELD - if (mInputContext.mIMEEnabled == InputContext::IME_PASSWORD) { + if (mInputContext.mIMEState.mEnabled == IMEState::PASSWORD) { return mSimpleContext; } #endif // NS_IME_ENABLED_ON_PASSWORD_FIELD @@ -692,19 +692,19 @@ nsGtkIMModule::GetContext() bool nsGtkIMModule::IsEnabled() { - return mInputContext.mIMEEnabled == InputContext::IME_ENABLED || + return mInputContext.mIMEState.mEnabled == IMEState::ENABLED || #ifdef NS_IME_ENABLED_ON_PASSWORD_FIELD - mInputContext.mIMEEnabled == InputContext::IME_PASSWORD || + mInputContext.mIMEState.mEnabled == IMEState::PASSWORD || #endif // NS_IME_ENABLED_ON_PASSWORD_FIELD - mInputContext.mIMEEnabled == InputContext::IME_PLUGIN; + mInputContext.mIMEState.mEnabled == IMEState::PLUGIN; } bool nsGtkIMModule::IsEditable() { - return mInputContext.mIMEEnabled == InputContext::IME_ENABLED || - mInputContext.mIMEEnabled == InputContext::IME_PLUGIN || - mInputContext.mIMEEnabled == InputContext::IME_PASSWORD; + return mInputContext.mIMEState.mEnabled == IMEState::ENABLED || + mInputContext.mIMEState.mEnabled == IMEState::PLUGIN || + mInputContext.mIMEState.mEnabled == IMEState::PASSWORD; } void diff --git a/widget/src/gtk2/nsWindow.cpp b/widget/src/gtk2/nsWindow.cpp index bed36e29933..b530521edf0 100644 --- a/widget/src/gtk2/nsWindow.cpp +++ b/widget/src/gtk2/nsWindow.cpp @@ -6591,7 +6591,8 @@ nsWindow::GetInputContext() { InputContext context; if (!mIMModule) { - context.mIMEEnabled = InputContext::IME_DISABLED; + context.mIMEState.mEnabled = IMEState::DISABLED; + context.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; } else { context = mIMModule->GetInputContext(); } diff --git a/widget/src/qt/nsWindow.cpp b/widget/src/qt/nsWindow.cpp index a2ae0ec75f3..569ff0eea86 100644 --- a/widget/src/qt/nsWindow.cpp +++ b/widget/src/qt/nsWindow.cpp @@ -3228,12 +3228,12 @@ nsWindow::SetInputContext(const InputContext& aContext, #if defined(MOZ_X11) && (MOZ_PLATFORM_MAEMO == 6) if (sPluginIMEAtom) { static QCoreApplication::EventFilter currentEventFilter = NULL; - if (mInputContext.mIMEEnabled == InputContext::IME_PLUGIN && + if (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN && currentEventFilter != x11EventFilter) { // Install event filter for listening Plugin IME state changes previousEventFilter = QCoreApplication::instance()->setEventFilter(x11EventFilter); currentEventFilter = x11EventFilter; - } else if (mInputContext.mIMEEnabled != InputContext::IME_PLUGIN && + } else if (mInputContext.mIMEState.mEnabled != IMEState::PLUGIN && currentEventFilter == x11EventFilter) { // Remove event filter QCoreApplication::instance()->setEventFilter(previousEventFilter); @@ -3247,10 +3247,10 @@ nsWindow::SetInputContext(const InputContext& aContext, } #endif - switch (mInputContext.mIMEEnabled) { - case InputContext::IME_ENABLED: - case InputContext::IME_PASSWORD: - case InputContext::IME_PLUGIN: + switch (mInputContext.mIMEState.mEnabled) { + case IMEState::ENABLED: + case IMEState::PASSWORD: + case IMEState::PLUGIN: SetSoftwareKeyboardState(true, aAction); break; default: @@ -3262,6 +3262,7 @@ nsWindow::SetInputContext(const InputContext& aContext, NS_IMETHODIMP_(InputContext) nsWindow::GetInputContext() { + mInputContext.mIMEState.mOpen = IMEState::OPEN_STATE_NOT_SUPPORTED; return mInputContext; } @@ -3270,12 +3271,11 @@ nsWindow::SetSoftwareKeyboardState(bool aOpen, const InputContextAction& aAction) { if (aOpen) { - NS_ENSURE_TRUE(mInputContext.mIMEEnabled != - InputContext::IME_DISABLED, ); + NS_ENSURE_TRUE(mInputContext.mIMEState.mEnabled != IMEState::DISABLED,); // Ensure that opening the virtual keyboard is allowed for this specific // InputContext depending on the content.ime.strict.policy pref - if (mInputContext.mIMEEnabled != InputContext::IME_PLUGIN && + if (mInputContext.mIMEState.mEnabled != IMEState::PLUGIN && Preferences::GetBool("content.ime.strict_policy", false) && !aAction.ContentGotFocusByTrustedCause()) { return; diff --git a/widget/src/windows/nsTextStore.cpp b/widget/src/windows/nsTextStore.cpp index 527e7d2d92b..af5bf21240b 100644 --- a/widget/src/windows/nsTextStore.cpp +++ b/widget/src/windows/nsTextStore.cpp @@ -88,7 +88,7 @@ nsTextStore::~nsTextStore() bool nsTextStore::Create(nsWindow* aWindow, - PRUint32 aIMEState) + IMEState::Enabled aIMEEnabled) { if (!mDocumentMgr) { // Create document manager @@ -101,7 +101,7 @@ nsTextStore::Create(nsWindow* aWindow, static_cast(this), getter_AddRefs(mContext), &mEditCookie); if (SUCCEEDED(hr)) { - SetInputContextInternal(aIMEState); + SetInputContextInternal(aIMEEnabled); hr = mDocumentMgr->Push(mContext); } if (SUCCEEDED(hr)) { @@ -1478,7 +1478,7 @@ nsTextStore::OnEndComposition(ITfCompositionView* pComposition) nsresult nsTextStore::OnFocusChange(bool aFocus, nsWindow* aWindow, - PRUint32 aIMEEnabled) + IMEState::Enabled aIMEEnabled) { // no change notifications if TSF is disabled if (!sTsfThreadMgr || !sTsfTextStore) @@ -1631,14 +1631,14 @@ nsTextStore::GetIMEOpenState(void) } void -nsTextStore::SetInputContextInternal(PRUint32 aState) +nsTextStore::SetInputContextInternal(IMEState::Enabled aState) { PR_LOG(sTextStoreLog, PR_LOG_ALWAYS, - ("TSF: SetInputContext, state=%lu\n", aState)); + ("TSF: SetInputContext, state=%ld\n", static_cast(aState))); VARIANT variant; variant.vt = VT_I4; - variant.lVal = aState != InputContext::IME_ENABLED; + variant.lVal = (aState != IMEState::ENABLED); // Set two contexts, the base context (mContext) and the top // if the top context is not the same as the base context diff --git a/widget/src/windows/nsTextStore.h b/widget/src/windows/nsTextStore.h index 9ff61085b31..36ce1258019 100644 --- a/widget/src/windows/nsTextStore.h +++ b/widget/src/windows/nsTextStore.h @@ -111,6 +111,7 @@ public: /*ITfContextOwnerCompositionSink*/ STDMETHODIMP OnEndComposition(ITfCompositionView*); protected: + typedef mozilla::widget::IMEState IMEState; typedef mozilla::widget::InputContext InputContext; public: @@ -128,10 +129,10 @@ public: static void SetInputContext(const InputContext& aContext) { if (!sTsfTextStore) return; - sTsfTextStore->SetInputContextInternal(aContext.mIMEEnabled); + sTsfTextStore->SetInputContextInternal(aContext.mIMEState.mEnabled); } - static nsresult OnFocusChange(bool, nsWindow*, PRUint32); + static nsresult OnFocusChange(bool, nsWindow*, IMEState::Enabled); static nsresult OnTextChange(PRUint32 aStart, PRUint32 aOldEnd, @@ -183,7 +184,7 @@ protected: nsTextStore(); ~nsTextStore(); - bool Create(nsWindow*, PRUint32); + bool Create(nsWindow*, IMEState::Enabled); bool Destroy(void); // If aDispatchTextEvent is true, this method will dispatch text event if @@ -194,7 +195,7 @@ protected: bool aDispatchTextEvent = false); HRESULT OnStartCompositionInternal(ITfCompositionView*, ITfRange*, bool); void CommitCompositionInternal(bool); - void SetInputContextInternal(PRUint32 aState); + void SetInputContextInternal(IMEState::Enabled aState); nsresult OnTextChangeInternal(PRUint32, PRUint32, PRUint32); void OnTextChangeMsgInternal(void); nsresult OnSelectionChangeInternal(void); diff --git a/widget/src/windows/nsWindow.cpp b/widget/src/windows/nsWindow.cpp index 63ddda77206..feee2d9cfb9 100644 --- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -406,7 +406,6 @@ nsWindow::nsWindow() : nsBaseWidget() mLastKeyboardLayout = 0; mAssumeWheelIsZoomUntil = 0; mBlurSuppressLevel = 0; - mInputContext.mIMEEnabled = InputContext::IME_ENABLED; #ifdef MOZ_XUL mTransparentSurface = nsnull; mMemoryDC = nsnull; @@ -8031,72 +8030,56 @@ NS_IMETHODIMP nsWindow::ResetInputState() return NS_OK; } -NS_IMETHODIMP nsWindow::SetIMEOpenState(bool aState) -{ -#ifdef DEBUG_KBSTATE - PR_LOG(gWindowsLog, PR_LOG_ALWAYS, - ("SetIMEOpenState %s\n", (aState ? "Open" : "Close"))); -#endif - -#ifdef NS_ENABLE_TSF - nsTextStore::SetIMEOpenState(aState); -#endif //NS_ENABLE_TSF - - nsIMEContext IMEContext(mWnd); - if (IMEContext.IsValid()) { - ::ImmSetOpenStatus(IMEContext.get(), aState ? TRUE : FALSE); - } - return NS_OK; -} - -NS_IMETHODIMP nsWindow::GetIMEOpenState(bool* aState) -{ - nsIMEContext IMEContext(mWnd); - if (IMEContext.IsValid()) { - BOOL isOpen = ::ImmGetOpenStatus(IMEContext.get()); - *aState = isOpen ? true : false; - } else - *aState = false; - -#ifdef NS_ENABLE_TSF - *aState |= nsTextStore::GetIMEOpenState(); -#endif //NS_ENABLE_TSF - - return NS_OK; -} - NS_IMETHODIMP_(void) nsWindow::SetInputContext(const InputContext& aContext, const InputContextAction& aAction) { - PRUint32 status = aContext.mIMEEnabled; #ifdef NS_ENABLE_TSF nsTextStore::SetInputContext(aContext); #endif //NS_ENABLE_TSF -#ifdef DEBUG_KBSTATE - PR_LOG(gWindowsLog, PR_LOG_ALWAYS, - ("SetInputMode: %s\n", (status == InputContext::IME_ENABLED || - status == InputContext::IME_PLUGIN) ? - "Enabled" : "Disabled")); -#endif if (nsIMM32Handler::IsComposing()) { ResetInputState(); } mInputContext = aContext; - bool enable = (status == InputContext::IME_ENABLED || - status == InputContext::IME_PLUGIN); + bool enable = (mInputContext.mIMEState.mEnabled == IMEState::ENABLED || + mInputContext.mIMEState.mEnabled == IMEState::PLUGIN); AssociateDefaultIMC(enable); + + if (enable && + mInputContext.mIMEState.mOpen != IMEState::DONT_CHANGE_OPEN_STATE) { + bool open = (mInputContext.mIMEState.mOpen == IMEState::OPEN); +#ifdef NS_ENABLE_TSF + nsTextStore::SetIMEOpenState(open); +#endif //NS_ENABLE_TSF + nsIMEContext IMEContext(mWnd); + if (IMEContext.IsValid()) { + ::ImmSetOpenStatus(IMEContext.get(), open); + } + } } NS_IMETHODIMP_(InputContext) nsWindow::GetInputContext() { -#ifdef DEBUG_KBSTATE - PR_LOG(gWindowsLog, PR_LOG_ALWAYS, - ("GetInputMode: %s\n", mInputContext.mIMEEnabled ? - "Enabled" : "Disabled"); -#endif + mInputContext.mIMEState.mOpen = IMEState::CLOSED; + switch (mInputContext.mIMEState.mEnabled) { + case IMEState::ENABLED: + case IMEState::PLUGIN: { + nsIMEContext IMEContext(mWnd); + if (IMEContext.IsValid()) { + mInputContext.mIMEState.mOpen = + ::ImmGetOpenStatus(IMEContext.get()) ? IMEState::OPEN : + IMEState::CLOSED; + } +#ifdef NS_ENABLE_TSF + if (mInputContext.mIMEState.mOpen == IMEState::CLOSED && + nsTextStore::GetIMEOpenState()) { + mInputContext.mIMEState.mOpen = IMEState::OPEN; + } +#endif //NS_ENABLE_TSF + } + } return mInputContext; } @@ -8130,7 +8113,7 @@ NS_IMETHODIMP nsWindow::OnIMEFocusChange(bool aFocus) { nsresult rv = nsTextStore::OnFocusChange(aFocus, this, - mInputContext.mIMEEnabled); + mInputContext.mIMEState.mEnabled); if (rv == NS_ERROR_NOT_AVAILABLE) rv = NS_ERROR_NOT_IMPLEMENTED; // TSF is not enabled, maybe. return rv; diff --git a/widget/src/windows/nsWindow.h b/widget/src/windows/nsWindow.h index 30d2c083285..d01a9574d73 100644 --- a/widget/src/windows/nsWindow.h +++ b/widget/src/windows/nsWindow.h @@ -179,8 +179,6 @@ public: PRUint32 aNativeMessage, PRUint32 aModifierFlags); NS_IMETHOD ResetInputState(); - NS_IMETHOD SetIMEOpenState(bool aState); - NS_IMETHOD GetIMEOpenState(bool* aState); NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, const InputContextAction& aAction); NS_IMETHOD_(InputContext) GetInputContext(); @@ -265,7 +263,7 @@ public: // needed in nsIMM32Handler.cpp bool PluginHasFocus() { - return mInputContext.mIMEEnabled == InputContext::IME_PLUGIN; + return (mInputContext.mIMEState.mEnabled == IMEState::PLUGIN); } bool IsTopLevelWidget() { return mIsTopWidgetWindow; } /** diff --git a/widget/src/xpwidgets/PuppetWidget.cpp b/widget/src/xpwidgets/PuppetWidget.cpp index 7be8b8fcaac..e80ea688aca 100644 --- a/widget/src/xpwidgets/PuppetWidget.cpp +++ b/widget/src/xpwidgets/PuppetWidget.cpp @@ -399,15 +399,6 @@ PuppetWidget::CancelComposition() return IMEEndComposition(true); } -NS_IMETHODIMP -PuppetWidget::SetIMEOpenState(bool aState) -{ - if (mTabChild && - mTabChild->SendSetIMEOpenState(aState)) - return NS_OK; - return NS_ERROR_FAILURE; -} - NS_IMETHODIMP_(void) PuppetWidget::SetInputContext(const InputContext& aContext, const InputContextAction& aAction) @@ -415,20 +406,13 @@ PuppetWidget::SetInputContext(const InputContext& aContext, if (!mTabChild) { return; } - mTabChild->SendSetInputContext(aContext.mIMEEnabled, - aContext.mHTMLInputType, - aContext.mActionHint, - static_cast(aAction.mCause), - static_cast(aAction.mFocusChange)); -} - -NS_IMETHODIMP -PuppetWidget::GetIMEOpenState(bool *aState) -{ - if (mTabChild && - mTabChild->SendGetIMEOpenState(aState)) - return NS_OK; - return NS_ERROR_FAILURE; + mTabChild->SendSetInputContext( + static_cast(aContext.mIMEState.mEnabled), + static_cast(aContext.mIMEState.mOpen), + aContext.mHTMLInputType, + aContext.mActionHint, + static_cast(aAction.mCause), + static_cast(aAction.mFocusChange)); } NS_IMETHODIMP_(InputContext) @@ -436,7 +420,10 @@ PuppetWidget::GetInputContext() { InputContext context; if (mTabChild) { - mTabChild->SendGetInputContext(&context.mIMEEnabled); + PRInt32 enabled, open; + mTabChild->SendGetInputContext(&enabled, &open); + context.mIMEState.mEnabled = static_cast(enabled); + context.mIMEState.mOpen = static_cast(open); } return context; } diff --git a/widget/src/xpwidgets/PuppetWidget.h b/widget/src/xpwidgets/PuppetWidget.h index 6f39ff7e49e..95e0489747b 100644 --- a/widget/src/xpwidgets/PuppetWidget.h +++ b/widget/src/xpwidgets/PuppetWidget.h @@ -168,8 +168,6 @@ public: virtual gfxASurface* GetThebesSurface(); NS_IMETHOD ResetInputState(); - NS_IMETHOD SetIMEOpenState(bool aState); - NS_IMETHOD GetIMEOpenState(bool *aState); NS_IMETHOD_(void) SetInputContext(const InputContext& aContext, const InputContextAction& aAction); NS_IMETHOD_(InputContext) GetInputContext(); diff --git a/widget/src/xpwidgets/nsBaseWidget.h b/widget/src/xpwidgets/nsBaseWidget.h index 86c08debe75..bc5f41ad3d2 100644 --- a/widget/src/xpwidgets/nsBaseWidget.h +++ b/widget/src/xpwidgets/nsBaseWidget.h @@ -142,8 +142,6 @@ public: virtual nsresult ActivateNativeMenuItemAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; } virtual nsresult ForceUpdateNativeMenuAt(const nsAString& indexString) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHOD ResetInputState() { return NS_OK; } - NS_IMETHOD SetIMEOpenState(bool aState) { return NS_ERROR_NOT_IMPLEMENTED; } - NS_IMETHOD GetIMEOpenState(bool* aState) { return NS_ERROR_NOT_IMPLEMENTED; } NS_IMETHOD CancelIMEComposition() { return NS_OK; } NS_IMETHOD SetAcceleratedRendering(bool aEnabled); virtual bool GetAcceleratedRendering();