Skip to content

Commit

Permalink
Update status icon even for Windows Store Apps.
Browse files Browse the repository at this point in the history
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
yukawa committed Jan 10, 2016
1 parent 26eec8d commit 0989ef2
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 62 deletions.
2 changes: 1 addition & 1 deletion src/mozc_version_template.txt
Original file line number Diff line number Diff line change
@@ -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.
Expand Down
4 changes: 4 additions & 0 deletions src/win32/tip/tip_lang_bar.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 3 additions & 0 deletions src/win32/tip/tip_lang_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 10 additions & 9 deletions src/win32/tip/tip_text_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -1182,6 +1182,7 @@ class TipTextServiceImpl
}
EnsurePrivateContextExists(context);
}
TipUiHandler::OnDocumentMgrChanged(this, document_mgr);
TipEditSession::OnSetFocusAsync(this, document_mgr);
return S_OK;
}
Expand Down
5 changes: 5 additions & 0 deletions src/win32/tip/tip_text_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
88 changes: 85 additions & 3 deletions src/win32/tip/tip_ui_handler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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()) {
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/win32/tip/tip_ui_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
50 changes: 1 addition & 49 deletions src/win32/tip/tip_ui_handler_conventional.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}

Expand All @@ -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;
}

Expand Down

0 comments on commit 0989ef2

Please sign in to comment.