diff options
author | fengyuan <fengyuan@chromium.org> | 2015-01-05 11:15:20 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-05 19:16:08 +0000 |
commit | f0b38f78f146cedf336ac9ad0236f681833c7263 (patch) | |
tree | 33a1e2e433464d72b1443a19777b53972f1e6677 /ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc | |
parent | 8d3cbe82703919d05287c3e0427ba1f499bbeffa (diff) | |
download | chromium_src-f0b38f78f146cedf336ac9ad0236f681833c7263.zip chromium_src-f0b38f78f146cedf336ac9ad0236f681833c7263.tar.gz chromium_src-f0b38f78f146cedf336ac9ad0236f681833c7263.tar.bz2 |
ozone: xkb: Load keymaps on worker thread & cache them
1. Free xkb keymaps in the destructor.
2. Moves kemap load into another worker thread.
3. Adds keymap caching.
BUG=430194
Review URL: https://codereview.chromium.org/817983002
Cr-Commit-Position: refs/heads/master@{#309928}
Diffstat (limited to 'ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc')
-rw-r--r-- | ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc | 81 |
1 files changed, 66 insertions, 15 deletions
diff --git a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc index a756db9..5f77975 100644 --- a/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc +++ b/ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc @@ -6,7 +6,13 @@ #include <xkbcommon/xkbcommon-names.h> +#include "base/bind.h" +#include "base/location.h" #include "base/logging.h" +#include "base/single_thread_task_runner.h" +#include "base/task_runner.h" +#include "base/thread_task_runner_handle.h" +#include "base/threading/worker_pool.h" #include "ui/events/event_constants.h" #include "ui/events/keycodes/dom3/dom_code.h" #include "ui/events/keycodes/dom3/dom_key.h" @@ -18,6 +24,10 @@ namespace ui { namespace { +typedef base::Callback<void(const std::string&, + scoped_ptr<xkb_keymap, XkbKeymapDeleter> keymap)> + LoadKeymapCallback; + DomKey CharacterToDomKey(base::char16 character) { switch (character) { case 0x08: @@ -616,6 +626,18 @@ const PrintableSimpleEntry kSimpleMap[] = { {0x0259, VKEY_OEM_3}, // schwa }; +void LoadKeymap(const std::string& layout_name, + scoped_ptr<xkb_rule_names> names, + xkb_context* context, + scoped_refptr<base::SingleThreadTaskRunner> reply_runner, + const LoadKeymapCallback& reply_callback) { + scoped_ptr<xkb_keymap, XkbKeymapDeleter> keymap; + keymap.reset(xkb_keymap_new_from_names(context, names.get(), + XKB_KEYMAP_COMPILE_NO_FLAGS)); + reply_runner->PostTask(FROM_HERE, base::Bind(reply_callback, layout_name, + base::Passed(&keymap))); +} + } // anonymous namespace XkbKeyCodeConverter::XkbKeyCodeConverter() { @@ -626,7 +648,7 @@ XkbKeyCodeConverter::~XkbKeyCodeConverter() { XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( const XkbKeyCodeConverter& converter) - : key_code_converter_(converter) { + : key_code_converter_(converter), weak_ptr_factory_(this) { // TODO: add XKB_CONTEXT_NO_ENVIRONMENT_NAMES xkb_context_.reset(xkb_context_new(XKB_CONTEXT_NO_DEFAULT_INCLUDES)); xkb_context_include_path_append(xkb_context_.get(), @@ -634,6 +656,9 @@ XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( } XkbKeyboardLayoutEngine::~XkbKeyboardLayoutEngine() { + for (const auto& entry : xkb_keymaps_) { + xkb_keymap_unref(entry.keymap); + } } bool XkbKeyboardLayoutEngine::CanSetCurrentLayout() const { @@ -647,6 +672,29 @@ bool XkbKeyboardLayoutEngine::CanSetCurrentLayout() const { bool XkbKeyboardLayoutEngine::SetCurrentLayoutByName( const std::string& layout_name) { #if defined(OS_CHROMEOS) + current_layout_name_ = layout_name; + for (const auto& entry : xkb_keymaps_) { + if (entry.layout_name == layout_name) { + SetKeymap(entry.keymap); + return true; + } + } + LoadKeymapCallback reply_callback = base::Bind( + &XkbKeyboardLayoutEngine::OnKeymapLoaded, weak_ptr_factory_.GetWeakPtr()); + scoped_ptr<xkb_rule_names> names = GetXkbRuleNames(layout_name); + base::WorkerPool::PostTask( + FROM_HERE, + base::Bind(&LoadKeymap, layout_name, base::Passed(&names), + base::Unretained(xkb_context_.get()), + base::ThreadTaskRunnerHandle::Get(), reply_callback), + true); + return true; +#endif // defined(OS_CHROMEOS) + return false; +} + +scoped_ptr<xkb_rule_names> XkbKeyboardLayoutEngine::GetXkbRuleNames( + const std::string& layout_name) { size_t dash_index = layout_name.find('-'); size_t parentheses_index = layout_name.find('('); std::string layout_id = layout_name; @@ -662,22 +710,25 @@ bool XkbKeyboardLayoutEngine::SetCurrentLayoutByName( layout_id = layout_name.substr(0, dash_index); layout_variant = layout_name.substr(dash_index + 1); } - struct xkb_rule_names names = { - .rules = NULL, - .model = "pc101", - .layout = layout_id.c_str(), - .variant = layout_variant.c_str(), - .options = "" - }; - xkb_keymap* keymap = xkb_keymap_new_from_names(xkb_context_.get(), - &names, - XKB_KEYMAP_COMPILE_NO_FLAGS); + return make_scoped_ptr<xkb_rule_names>( + new xkb_rule_names{.rules = NULL, + .model = "pc101", + .layout = layout_id.c_str(), + .variant = layout_variant.c_str(), + .options = ""}); +} + +void XkbKeyboardLayoutEngine::OnKeymapLoaded( + const std::string& layout_name, + scoped_ptr<xkb_keymap, XkbKeymapDeleter> keymap) { if (keymap) { - SetKeymap(keymap); - return true; + XkbKeymapEntry entry = {layout_name, xkb_keymap_ref(keymap.get())}; + xkb_keymaps_.push_back(entry); + if (layout_name == current_layout_name_) + SetKeymap(keymap.get()); + } else { + LOG(ERROR) << "Keymap file fail to load: " << layout_name; } -#endif // defined(OS_CHROMEOS) - return false; } bool XkbKeyboardLayoutEngine::UsesISOLevel5Shift() const { |