Bug 1372560 TSFTextStore should cache compartment for keyboard open/close r?m_kato
TSFTextStore::GetIMEOpenState() may be called a lot. Therefore, TSFTextStore should cache the compartment until shutting down.
MozReview-Commit-ID: 2jz8zQMBHRS
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -1629,16 +1629,17 @@ public:
/* TSFTextStore */
/******************************************************************/
StaticRefPtr<ITfThreadMgr> TSFTextStore::sThreadMgr;
StaticRefPtr<ITfMessagePump> TSFTextStore::sMessagePump;
StaticRefPtr<ITfKeystrokeMgr> TSFTextStore::sKeystrokeMgr;
StaticRefPtr<ITfDisplayAttributeMgr> TSFTextStore::sDisplayAttrMgr;
StaticRefPtr<ITfCategoryMgr> TSFTextStore::sCategoryMgr;
+StaticRefPtr<ITfCompartment> TSFTextStore::sCompartmentForOpenClose;
StaticRefPtr<ITfDocumentMgr> TSFTextStore::sDisabledDocumentMgr;
StaticRefPtr<ITfContext> TSFTextStore::sDisabledContext;
StaticRefPtr<ITfInputProcessorProfiles> TSFTextStore::sInputProcessorProfiles;
StaticRefPtr<TSFTextStore> TSFTextStore::sEnabledTextStore;
DWORD TSFTextStore::sClientId = 0;
#define TEXTSTORE_DEFAULT_VIEW (1)
@@ -5987,53 +5988,79 @@ GetCompartment(IUnknown* pUnk,
// static
void
TSFTextStore::SetIMEOpenState(bool aState)
{
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
("TSFTextStore::SetIMEOpenState(aState=%s)",
GetBoolName(aState)));
- RefPtr<ITfCompartment> comp;
- if (!GetCompartment(sThreadMgr,
- GUID_COMPARTMENT_KEYBOARD_OPENCLOSE,
- getter_AddRefs(comp))) {
+ if (!sThreadMgr) {
+ return;
+ }
+
+ RefPtr<ITfCompartment> comp = GetCompartmentForOpenClose();
+ if (NS_WARN_IF(!comp)) {
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
(" TSFTextStore::SetIMEOpenState() FAILED due to"
"no compartment available"));
return;
}
VARIANT variant;
variant.vt = VT_I4;
variant.lVal = aState;
+ HRESULT hr = comp->SetValue(sClientId, &variant);
+ if (NS_WARN_IF(FAILED(hr))) {
+ MOZ_LOG(sTextStoreLog, LogLevel::Error,
+ (" TSFTextStore::SetIMEOpenState() FAILED due to "
+ "ITfCompartment::SetValue() failure, hr=0x%08X", hr));
+ return;
+ }
MOZ_LOG(sTextStoreLog, LogLevel::Debug,
(" TSFTextStore::SetIMEOpenState(), setting "
"0x%04X to GUID_COMPARTMENT_KEYBOARD_OPENCLOSE...",
variant.lVal));
- comp->SetValue(sClientId, &variant);
}
// static
bool
TSFTextStore::GetIMEOpenState()
{
- RefPtr<ITfCompartment> comp;
- if (!GetCompartment(sThreadMgr,
- GUID_COMPARTMENT_KEYBOARD_OPENCLOSE,
- getter_AddRefs(comp)))
+ if (!sThreadMgr) {
return false;
+ }
+
+ RefPtr<ITfCompartment> comp = GetCompartmentForOpenClose();
+ if (NS_WARN_IF(!comp)) {
+ return false;
+ }
VARIANT variant;
::VariantInit(&variant);
- if (SUCCEEDED(comp->GetValue(&variant)) && variant.vt == VT_I4)
- return variant.lVal != 0;
-
- ::VariantClear(&variant); // clear up in case variant.vt != VT_I4
- return false;
+ HRESULT hr = comp->GetValue(&variant);
+ if (NS_WARN_IF(FAILED(hr))) {
+ MOZ_LOG(sTextStoreLog, LogLevel::Error,
+ ("TSFTextStore::GetIMEOpenState() FAILED due to "
+ "ITfCompartment::GetValue() failure, hr=0x%08X", hr));
+ return false;
+ }
+ // Until IME is open in this process, the result may be empty.
+ if (variant.vt == VT_EMPTY) {
+ return false;
+ }
+ if (NS_WARN_IF(variant.vt != VT_I4)) {
+ MOZ_LOG(sTextStoreLog, LogLevel::Error,
+ ("TSFTextStore::GetIMEOpenState() FAILED due to "
+ "invalid result of ITfCompartment::GetValue()"));
+ ::VariantClear(&variant);
+ return false;
+ }
+
+ return variant.lVal != 0;
}
// static
void
TSFTextStore::SetInputContext(nsWindowBase* aWidget,
const InputContext& aContext,
const InputContextAction& aAction)
{
@@ -6278,16 +6305,53 @@ TSFTextStore::GetCategoryMgr()
"a category manager instance, hr=0x%08X", hr));
return nullptr;
}
sCategoryMgr = categoryMgr;
return categoryMgr.forget();
}
// static
+already_AddRefed<ITfCompartment>
+TSFTextStore::GetCompartmentForOpenClose()
+{
+ if (sCompartmentForOpenClose) {
+ RefPtr<ITfCompartment> compartment = sCompartmentForOpenClose;
+ return compartment.forget();
+ }
+
+ if (!sThreadMgr) {
+ return nullptr;
+ }
+
+ RefPtr<ITfCompartmentMgr> compartmentMgr;
+ HRESULT hr = sThreadMgr->QueryInterface(IID_ITfCompartmentMgr,
+ getter_AddRefs(compartmentMgr));
+ if (NS_WARN_IF(FAILED(hr)) || NS_WARN_IF(!compartmentMgr)) {
+ MOZ_LOG(sTextStoreLog, LogLevel::Error,
+ ("TSFTextStore::GetCompartmentForOpenClose() FAILED due to"
+ "sThreadMgr not having ITfCompartmentMgr, hr=0x%08X", hr));
+ return nullptr;
+ }
+
+ RefPtr<ITfCompartment> compartment;
+ hr = compartmentMgr->GetCompartment(GUID_COMPARTMENT_KEYBOARD_OPENCLOSE,
+ getter_AddRefs(compartment));
+ if (NS_WARN_IF(FAILED(hr)) || NS_WARN_IF(!compartment)) {
+ MOZ_LOG(sTextStoreLog, LogLevel::Error,
+ ("TSFTextStore::GetCompartmentForOpenClose() FAILED due to"
+ "ITfCompartmentMgr::GetCompartment() failuere, hr=0x%08X", hr));
+ return nullptr;
+ }
+
+ sCompartmentForOpenClose = compartment;
+ return compartment.forget();
+}
+
+// static
already_AddRefed<ITfInputProcessorProfiles>
TSFTextStore::GetInputProcessorProfiles()
{
RefPtr<ITfInputProcessorProfiles> inputProcessorProfiles;
if (sInputProcessorProfiles) {
inputProcessorProfiles = sInputProcessorProfiles;
return inputProcessorProfiles.forget();
}
@@ -6318,16 +6382,17 @@ TSFTextStore::Terminate()
TSFStaticSink::Shutdown();
sDisplayAttrMgr = nullptr;
sCategoryMgr = nullptr;
sEnabledTextStore = nullptr;
sDisabledDocumentMgr = nullptr;
sDisabledContext = nullptr;
+ sCompartmentForOpenClose = nullptr;
sInputProcessorProfiles = nullptr;
sClientId = 0;
if (sThreadMgr) {
sThreadMgr->Deactivate();
sThreadMgr = nullptr;
sMessagePump = nullptr;
sKeystrokeMgr = nullptr;
}
--- a/widget/windows/TSFTextStore.h
+++ b/widget/windows/TSFTextStore.h
@@ -1009,16 +1009,19 @@ private:
// sKeystrokeMgr is QI'ed from sThreadMgr
static StaticRefPtr<ITfKeystrokeMgr> sKeystrokeMgr;
// TSF display attribute manager
static StaticRefPtr<ITfDisplayAttributeMgr> sDisplayAttrMgr;
static already_AddRefed<ITfDisplayAttributeMgr> GetDisplayAttributeMgr();
// TSF category manager
static StaticRefPtr<ITfCategoryMgr> sCategoryMgr;
static already_AddRefed<ITfCategoryMgr> GetCategoryMgr();
+ // Compartment for (Get|Set)IMEOpenState()
+ static StaticRefPtr<ITfCompartment> sCompartmentForOpenClose;
+ static already_AddRefed<ITfCompartment> GetCompartmentForOpenClose();
// Current text store which is managing a keyboard enabled editor (i.e.,
// editable editor). Currently only ONE TSFTextStore instance is ever used,
// although Create is called when an editor is focused and Destroy called
// when the focused editor is blurred.
static StaticRefPtr<TSFTextStore> sEnabledTextStore;
// For IME (keyboard) disabled state: