Bug 840409 part.12 Implement widget::IMEHandler::InitInputContext() and widget::IMEHandler::SetInputContext() r=jimm

This commit is contained in:
Masayuki Nakano 2013-02-25 13:00:06 +09:00
Родитель a75d2bc49f
Коммит 053ccfc3c4
4 изменённых файлов: 105 добавлений и 58 удалений

Просмотреть файл

@ -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)