Permalink
Browse files

Update status icon even for Windows Store Apps.

On Windows 10 and later, Windows Store Apps can run in a window mode,
and IME status icons on the notification area are expected to be
updated.  This means that we have to initialize and update status icon
via LanguageBar API even for Windows Store Apps.

For the simplicity, with this CL, we start initializing and updating
status icons on LauguageBar even in immersive mode on Windows 8/8.1.
This can introduce some unnecessary overhead for those platforms but
basically no user-visible change should happen on Windows 8/8.1.

This CL also makes sure to update LanguageBar when
ITfThreadMgrEventSink::OnSetFocus is called.  This has not been obvious
in desktop apps but for Store Apps the lack of force update of
LanguageBar in ITfThreadMgrEventSink::OnSetFocus results in a stale icon
state on the language bar, which is so confusing.

Closes #350.

BUG=#350
TEST=manually done
REF_BUG=24593171,24793812
REF_CL=104530061,105271317,105271439,105279539,105283782
  • Loading branch information...
1 parent 26eec8d commit 0989ef207351294fa5b6810b7cf59c790bbbfd3c @yukawa yukawa committed Jan 10, 2016
@@ -1,6 +1,6 @@
MAJOR=2
MINOR=17
-BUILD=2308
+BUILD=2309
REVISION=102
# NACL_DICTIONARY_VERSION is the target version of the system dictionary to be
# downloaded by NaCl Mozc.
@@ -462,6 +462,10 @@ HRESULT TipLangBar::UpdateMenu(bool enabled, uint32 composition_mode) {
return result;
}
+bool TipLangBar::IsInitialized() const {
+ return input_button_menu_ || input_mode_button_for_win8_;
+}
+
} // namespace tsf
} // namespace win32
} // namespace mozc
@@ -96,6 +96,9 @@ class TipLangBar {
// Updates the selected menu in the language bar.
HRESULT UpdateMenu(bool enabled, uint32 composition_mode);
+ // Returns true if this instance is already initialized.
+ bool IsInitialized() const;
+
private:
// Represents the language bar item manager iff the running OS is Windows 8.
// NOTE: We must use the same instance of this class to initialize and
@@ -608,9 +608,7 @@ class TipTextServiceImpl
UninitKeyEventSink();
// Remove our button menus from the language bar.
- if (!IsImmersiveUI()) {
- UninitLanguageBar();
- }
+ UninitLanguageBar();
// Stop advising the ITfFunctionProvider events.
UninitFunctionProvider();
@@ -716,12 +714,10 @@ class TipTextServiceImpl
return Deactivate();
}
- if (!IsImmersiveUI()) {
- result = InitLanguageBar();
- if (FAILED(result)) {
- LOG(ERROR) << "InitLanguageBar failed: " << result;
- return result;
- }
+ result = InitLanguageBar();
+ if (FAILED(result)) {
+ LOG(ERROR) << "InitLanguageBar failed: " << result;
+ return result;
}
// Start advising the keyboard events (ITfKeyEvent) to this object.
@@ -1152,6 +1148,10 @@ class TipTextServiceImpl
langbar_.UpdateMenu(enabled, mozc_mode);
}
+ virtual bool IsLangbarInitialized() const {
+ return langbar_.IsInitialized();
+ }
+
// Following functions are private utilities.
static void StorePointerForCurrentThread(TipTextServiceImpl *impl) {
if (g_module_unloaded) {
@@ -1182,6 +1182,7 @@ class TipTextServiceImpl
}
EnsurePrivateContextExists(context);
}
+ TipUiHandler::OnDocumentMgrChanged(this, document_mgr);
TipEditSession::OnSetFocusAsync(this, document_mgr);
return S_OK;
}
@@ -73,7 +73,12 @@ class TipTextService : public IUnknown {
// the reference count of the returned object.
virtual ITfCompositionSink *CreateCompositionSink(ITfContext *context) = 0;
+ // Updates the language bar as needed. Does nothing if the language bar is
+ // not available.
virtual void UpdateLangbar(bool enabled, uint32 mozc_mode) = 0;
+
+ // Returns true if the language bar is initialized.
+ virtual bool IsLangbarInitialized() const = 0;
};
class TipTextServiceFactory {
@@ -29,15 +29,84 @@
#include "win32/tip/tip_ui_handler.h"
+#define _ATL_NO_AUTOMATIC_NAMESPACE
+#define _WTL_NO_AUTOMATIC_NAMESPACE
+#include <atlbase.h>
+#include <atlcom.h>
+#include <msctf.h>
+
#include "base/logging.h"
#include "base/util.h"
+#include "protocol/commands.pb.h"
+#include "win32/tip/tip_input_mode_manager.h"
+#include "win32/tip/tip_status.h"
#include "win32/tip/tip_text_service.h"
+#include "win32/tip/tip_thread_context.h"
#include "win32/tip/tip_ui_handler_conventional.h"
#include "win32/tip/tip_ui_handler_immersive.h"
+using ATL::CComPtr;
+using ::mozc::commands::CompositionMode;
+
namespace mozc {
namespace win32 {
namespace tsf {
+namespace {
+
+void UpdateLanguageBarOnFocusChange(TipTextService *text_service,
+ ITfDocumentMgr *document_manager) {
+ if (!text_service) {
+ return;
+ }
+
+ if (!text_service->IsLangbarInitialized()) {
+ // If language bar is not initialized, there is nothing to do here.
+ return;
+ }
+
+ HRESULT result = S_OK;
+ ITfThreadMgr *thread_manager = text_service->GetThreadManager();
+
+ if (thread_manager == nullptr) {
+ return;
+ }
+
+ bool disabled = false;
+ {
+ if (document_manager == nullptr) {
+ // When |document_manager| is null, we should show "disabled" icon
+ // as if |ImmAssociateContext(window_handle, nullptr)| was called.
+ disabled = true;
+ } else {
+ CComPtr<ITfContext> context;
+ result = document_manager->GetTop(&context);
+ if (SUCCEEDED(result)) {
+ disabled = TipStatus::IsDisabledContext(context);
+ }
+ }
+ }
+
+ const TipInputModeManager *input_mode_manager =
+ text_service->GetThreadContext()->GetInputModeManager();
+ const bool open = input_mode_manager->GetEffectiveOpenClose();
+ const CompositionMode mozc_mode =
+ open ? static_cast<CompositionMode>(
+ input_mode_manager->GetEffectiveConversionMode())
+ : commands::DIRECT;
+ text_service->UpdateLangbar(!disabled, static_cast<uint32>(mozc_mode));
+}
+
+bool UpdateInternal(TipTextService *text_service,
+ ITfContext *context,
+ TfEditCookie read_cookie) {
+ if (text_service->IsImmersiveUI()) {
+ return TipUiHandlerImmersive::Update(text_service, context, read_cookie);
+ } else {
+ return TipUiHandlerConventional::Update(text_service, context, read_cookie);
+ }
+}
+
+} // namespace
ITfUIElement *TipUiHandler::CreateUI(UiType type,
TipTextService *text_service,
@@ -76,6 +145,11 @@ void TipUiHandler::OnDeactivate(TipTextService *text_service) {
}
}
+void TipUiHandler::OnDocumentMgrChanged(TipTextService *text_service,
+ ITfDocumentMgr *document_manager) {
+ UpdateLanguageBarOnFocusChange(text_service, document_manager);
+}
+
void TipUiHandler::OnFocusChange(TipTextService *text_service,
ITfDocumentMgr *focused_document_manager) {
if (text_service->IsImmersiveUI()) {
@@ -85,16 +159,24 @@ void TipUiHandler::OnFocusChange(TipTextService *text_service,
TipUiHandlerConventional::OnFocusChange(
text_service, focused_document_manager);
}
+ UpdateLanguageBarOnFocusChange(text_service, focused_document_manager);
}
bool TipUiHandler::Update(TipTextService *text_service,
ITfContext *context,
TfEditCookie read_cookie) {
- if (text_service->IsImmersiveUI()) {
- return TipUiHandlerImmersive::Update(text_service, context, read_cookie);
+ const TipInputModeManager *input_mode_manager =
+ text_service->GetThreadContext()->GetInputModeManager();
+ const bool open = input_mode_manager->GetEffectiveOpenClose();
+ const CompositionMode mozc_mode = static_cast<CompositionMode>(
+ input_mode_manager->GetEffectiveConversionMode());
+ const bool result = UpdateInternal(text_service, context, read_cookie);
+ if (open) {
+ text_service->UpdateLangbar(true, mozc_mode);
} else {
- return TipUiHandlerConventional::Update(text_service, context, read_cookie);
+ text_service->UpdateLangbar(true, commands::DIRECT);
}
+ return result;
}
bool TipUiHandler::OnDllProcessAttach(HINSTANCE module_handle,
@@ -57,6 +57,8 @@ class TipUiHandler {
static void OnActivate(TipTextService *text_service);
static void OnDeactivate(TipTextService *text_service);
+ static void OnDocumentMgrChanged(TipTextService *text_service,
+ ITfDocumentMgr *document_manager);
static void OnFocusChange(TipTextService *text_service,
ITfDocumentMgr *focused_document_manager);
static bool Update(TipTextService *text_service,
@@ -38,6 +38,7 @@
#include "base/logging.h"
#include "base/util.h"
+#include "protocol/commands.pb.h"
#include "protocol/renderer_command.pb.h"
#include "renderer/win32/win32_renderer_client.h"
#include "win32/base/conversion_mode_util.h"
@@ -457,42 +458,6 @@ class UpdateUiEditSessionImpl : public ITfEditSession {
DISALLOW_COPY_AND_ASSIGN(UpdateUiEditSessionImpl);
};
-HRESULT OnUpdateLanguageBar(TipTextService *text_service,
- ITfDocumentMgr *document_manager) {
- HRESULT result = S_OK;
- ITfThreadMgr *thread_manager = text_service->GetThreadManager();
-
- if (thread_manager == nullptr) {
- return E_FAIL;
- }
-
- bool disabled = false;
- {
- if (document_manager == nullptr) {
- // When |document_manager| is null, we should disable an IME like we
- // disable it when ImmAssociateContext(window_handle, nullptr) is
- // called.
- disabled = true;
- } else {
- CComPtr<ITfContext> context;
- result = document_manager->GetTop(&context);
- if (SUCCEEDED(result)) {
- disabled = TipStatus::IsDisabledContext(context);
- }
- }
- }
-
- const TipInputModeManager *input_mode_manager =
- text_service->GetThreadContext()->GetInputModeManager();
- const bool open = input_mode_manager->GetEffectiveOpenClose();
- const CompositionMode mozc_mode =
- open ? static_cast<CompositionMode>(
- input_mode_manager->GetEffectiveConversionMode())
- : commands::DIRECT;
- text_service->UpdateLangbar(!disabled, static_cast<uint32>(mozc_mode));
- return S_OK;
-}
-
} // namespace
ITfUIElement *TipUiHandlerConventional::CreateUI(TipUiHandler::UiType type,
@@ -546,8 +511,6 @@ void TipUiHandlerConventional::OnFocusChange(
command.set_type(RendererCommand::UPDATE);
command.set_visible(false);
Win32RendererClient::OnUpdated(command);
- // Update the langbar.
- OnUpdateLanguageBar(text_service, focused_document_manager);
return;
}
@@ -558,29 +521,18 @@ void TipUiHandlerConventional::OnFocusChange(
if (!context) {
return;
}
- OnUpdateLanguageBar(text_service, focused_document_manager);
UpdateUiEditSessionImpl::BeginRequest(text_service, context);
}
bool TipUiHandlerConventional::Update(TipTextService *text_service,
ITfContext *context,
TfEditCookie read_cookie) {
RendererCommand command;
- const TipInputModeManager *input_mode_manager =
- text_service->GetThreadContext()->GetInputModeManager();
- const bool open = input_mode_manager->GetEffectiveOpenClose();
- const CompositionMode mozc_mode = static_cast<CompositionMode>(
- input_mode_manager->GetEffectiveConversionMode());
bool no_layout = false;
UpdateCommand(text_service, context, read_cookie, &command, &no_layout);
if (!no_layout || !command.visible()) {
Win32RendererClient::OnUpdated(command);
}
- if (open) {
- text_service->UpdateLangbar(true, mozc_mode);
- } else {
- text_service->UpdateLangbar(true, commands::DIRECT);
- }
return true;
}

0 comments on commit 0989ef2

Please sign in to comment.