123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/ime/ime_controller_impl.h"
- #include <utility>
- #include "ash/ime/ime_mode_indicator_view.h"
- #include "ash/ime/ime_switch_type.h"
- #include "ash/ime/mode_indicator_observer.h"
- #include "ash/shell.h"
- #include "ash/system/tray/system_tray_notifier.h"
- #include "base/callback_helpers.h"
- #include "base/containers/contains.h"
- #include "base/metrics/histogram_macros.h"
- #include "ui/base/accelerators/accelerator.h"
- #include "ui/base/ime/ash/extension_ime_util.h"
- #include "ui/display/manager/display_manager.h"
- namespace ash {
- namespace {
- // The result of pressing VKEY_MODECHANGE (for metrics).
- // These values are persisted to logs. Entries should not be renumbered and
- // numeric values should never be reused.
- enum class ModeChangeKeyAction {
- kShowIndicator = 0,
- kSwitchIme = 1,
- kMaxValue = kSwitchIme
- };
- // The ID for the Accessibility Common IME (used for Dictation).
- const char* kAccessibilityCommonIMEId =
- "_ext_ime_egfdjlfmgnehecnclamagfafdccgfndpdictation";
- } // namespace
- ImeControllerImpl::ImeControllerImpl()
- : mode_indicator_observer_(std::make_unique<ModeIndicatorObserver>()) {}
- ImeControllerImpl::~ImeControllerImpl() {
- SetClient(nullptr);
- }
- void ImeControllerImpl::AddObserver(Observer* observer) {
- observers_.AddObserver(observer);
- }
- void ImeControllerImpl::RemoveObserver(Observer* observer) {
- observers_.RemoveObserver(observer);
- }
- const std::vector<ImeInfo>& ImeControllerImpl::GetVisibleImes() const {
- return visible_imes_;
- }
- bool ImeControllerImpl::IsCurrentImeVisible() const {
- return current_ime_.id != kAccessibilityCommonIMEId;
- }
- void ImeControllerImpl::SetClient(ImeControllerClient* client) {
- if (client_) {
- if (CastConfigController::Get())
- CastConfigController::Get()->RemoveObserver(this);
- Shell::Get()->display_manager()->RemoveObserver(this);
- Shell::Get()->system_tray_notifier()->RemoveScreenCaptureObserver(this);
- }
- client_ = client;
- if (client_) {
- if (CastConfigController::Get())
- CastConfigController::Get()->AddObserver(this);
- Shell::Get()->system_tray_notifier()->AddScreenCaptureObserver(this);
- Shell::Get()->display_manager()->AddObserver(this);
- }
- }
- bool ImeControllerImpl::CanSwitchIme() const {
- // Cannot switch unless there is an active IME.
- if (current_ime_.id.empty())
- return false;
- // Do not consume key event if there is only one input method is enabled.
- // Ctrl+Space or Alt+Shift may be used by other application.
- return GetVisibleImes().size() > 1;
- }
- void ImeControllerImpl::SwitchToNextIme() {
- if (client_)
- client_->SwitchToNextIme();
- }
- void ImeControllerImpl::SwitchToLastUsedIme() {
- if (client_)
- client_->SwitchToLastUsedIme();
- }
- void ImeControllerImpl::SwitchImeById(const std::string& ime_id,
- bool show_message) {
- if (client_)
- client_->SwitchImeById(ime_id, show_message);
- }
- void ImeControllerImpl::ActivateImeMenuItem(const std::string& key) {
- if (client_)
- client_->ActivateImeMenuItem(key);
- }
- bool ImeControllerImpl::CanSwitchImeWithAccelerator(
- const ui::Accelerator& accelerator) const {
- // If none of the input methods associated with |accelerator| are active, we
- // should ignore the accelerator.
- std::vector<std::string> candidate_ids =
- GetCandidateImesForAccelerator(accelerator);
- return !candidate_ids.empty();
- }
- void ImeControllerImpl::SwitchImeWithAccelerator(
- const ui::Accelerator& accelerator) {
- if (!client_)
- return;
- std::vector<std::string> candidate_ids =
- GetCandidateImesForAccelerator(accelerator);
- if (candidate_ids.empty())
- return;
- auto it =
- std::find(candidate_ids.begin(), candidate_ids.end(), current_ime_.id);
- if (it != candidate_ids.end())
- ++it;
- if (it == candidate_ids.end())
- it = candidate_ids.begin();
- client_->SwitchImeById(*it, true /* show_message */);
- }
- // ImeControllerImpl:
- void ImeControllerImpl::RefreshIme(const std::string& current_ime_id,
- std::vector<ImeInfo> available_imes,
- std::vector<ImeMenuItem> menu_items) {
- if (current_ime_id.empty())
- current_ime_ = ImeInfo();
- available_imes_.clear();
- available_imes_.reserve(available_imes.size());
- visible_imes_.clear();
- visible_imes_.reserve(visible_imes_.size());
- for (const auto& ime : available_imes) {
- if (ime.id.empty()) {
- DLOG(ERROR) << "Received IME with invalid ID.";
- continue;
- }
- available_imes_.push_back(ime);
- if (ime.id != kAccessibilityCommonIMEId) {
- visible_imes_.push_back(ime);
- }
- if (ime.id == current_ime_id)
- current_ime_ = ime;
- }
- // Either there is no current IME or we found a valid one in the list of
- // available IMEs.
- DCHECK(current_ime_id.empty() || !current_ime_.id.empty());
- current_ime_menu_items_.clear();
- current_ime_menu_items_.reserve(menu_items.size());
- for (const auto& item : menu_items)
- current_ime_menu_items_.push_back(item);
- Shell::Get()->system_tray_notifier()->NotifyRefreshIME();
- }
- void ImeControllerImpl::SetImesManagedByPolicy(bool managed) {
- managed_by_policy_ = managed;
- Shell::Get()->system_tray_notifier()->NotifyRefreshIME();
- }
- void ImeControllerImpl::ShowImeMenuOnShelf(bool show) {
- is_menu_active_ = show;
- Shell::Get()->system_tray_notifier()->NotifyRefreshIMEMenu(show);
- }
- void ImeControllerImpl::UpdateCapsLockState(bool caps_enabled) {
- is_caps_lock_enabled_ = caps_enabled;
- for (ImeControllerImpl::Observer& observer : observers_)
- observer.OnCapsLockChanged(caps_enabled);
- }
- void ImeControllerImpl::OnKeyboardLayoutNameChanged(
- const std::string& layout_name) {
- keyboard_layout_name_ = layout_name;
- for (ImeControllerImpl::Observer& observer : observers_)
- observer.OnKeyboardLayoutNameChanged(layout_name);
- }
- void ImeControllerImpl::SetExtraInputOptionsEnabledState(
- bool is_extra_input_options_enabled,
- bool is_emoji_enabled,
- bool is_handwriting_enabled,
- bool is_voice_enabled) {
- is_extra_input_options_enabled_ = is_extra_input_options_enabled;
- is_emoji_enabled_ = is_emoji_enabled;
- is_handwriting_enabled_ = is_handwriting_enabled;
- is_voice_enabled_ = is_voice_enabled;
- }
- void ImeControllerImpl::ShowModeIndicator(
- const gfx::Rect& anchor_bounds,
- const std::u16string& ime_short_name) {
- ImeModeIndicatorView* mi_view =
- new ImeModeIndicatorView(anchor_bounds, ime_short_name);
- views::BubbleDialogDelegateView::CreateBubble(mi_view);
- mode_indicator_observer_->AddModeIndicatorWidget(mi_view->GetWidget());
- mi_view->ShowAndFadeOut();
- }
- void ImeControllerImpl::OnDisplayMetricsChanged(const display::Display& display,
- uint32_t changed_metrics) {
- if (changed_metrics & display::DisplayObserver::DISPLAY_METRIC_MIRROR_STATE) {
- Shell* shell = Shell::Get();
- client_->UpdateMirroringState(shell->display_manager()->IsInMirrorMode());
- }
- }
- void ImeControllerImpl::OnDevicesUpdated(
- const std::vector<SinkAndRoute>& devices) {
- DCHECK(client_);
- bool casting_desktop = false;
- for (const auto& receiver : devices) {
- if (receiver.route.content_source == ContentSource::kDesktop) {
- casting_desktop = true;
- break;
- }
- }
- client_->UpdateCastingState(casting_desktop);
- }
- void ImeControllerImpl::SetCapsLockEnabled(bool caps_enabled) {
- is_caps_lock_enabled_ = caps_enabled;
- if (client_)
- client_->SetCapsLockEnabled(caps_enabled);
- }
- void ImeControllerImpl::OverrideKeyboardKeyset(input_method::ImeKeyset keyset) {
- OverrideKeyboardKeyset(keyset, base::DoNothing());
- }
- void ImeControllerImpl::OverrideKeyboardKeyset(
- input_method::ImeKeyset keyset,
- ImeControllerClient::OverrideKeyboardKeysetCallback callback) {
- if (client_)
- client_->OverrideKeyboardKeyset(keyset, std::move(callback));
- }
- bool ImeControllerImpl::IsCapsLockEnabled() const {
- return is_caps_lock_enabled_;
- }
- std::vector<std::string> ImeControllerImpl::GetCandidateImesForAccelerator(
- const ui::Accelerator& accelerator) const {
- std::vector<std::string> candidate_ids;
- using extension_ime_util::GetInputMethodIDByEngineID;
- std::vector<std::string> input_method_ids_to_switch;
- switch (accelerator.key_code()) {
- case ui::VKEY_CONVERT: // Henkan key on JP106 keyboard
- input_method_ids_to_switch.push_back(
- GetInputMethodIDByEngineID("nacl_mozc_jp"));
- break;
- case ui::VKEY_NONCONVERT: // Muhenkan key on JP106 keyboard
- input_method_ids_to_switch.push_back(
- GetInputMethodIDByEngineID("xkb:jp::jpn"));
- break;
- case ui::VKEY_DBE_SBCSCHAR: // ZenkakuHankaku key on JP106 keyboard
- case ui::VKEY_DBE_DBCSCHAR:
- input_method_ids_to_switch.push_back(
- GetInputMethodIDByEngineID("nacl_mozc_jp"));
- input_method_ids_to_switch.push_back(
- GetInputMethodIDByEngineID("xkb:jp::jpn"));
- break;
- default:
- break;
- }
- if (input_method_ids_to_switch.empty()) {
- DVLOG(1) << "Unexpected VKEY: " << accelerator.key_code();
- return std::vector<std::string>();
- }
- // Obtain the intersection of input_method_ids_to_switch and available_imes_.
- for (const ImeInfo& ime : available_imes_) {
- if (base::Contains(input_method_ids_to_switch, ime.id))
- candidate_ids.push_back(ime.id);
- }
- return candidate_ids;
- }
- void ImeControllerImpl::OnScreenCaptureStart(
- const base::RepeatingClosure& stop_callback,
- const base::RepeatingClosure& source_callback,
- const std::u16string& screen_capture_status) {
- client_->UpdateCastingState(true);
- }
- void ImeControllerImpl::OnScreenCaptureStop() {
- client_->UpdateCastingState(false);
- }
- } // namespace ash
|