Index: ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc |
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 a756db9131a69dfdc20747c23bf5f8514021a2f6..21083b76d742343c4c9dea8547a87a18c918ccda 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,10 @@ |
#include <xkbcommon/xkbcommon-names.h> |
+#include "base/bind.h" |
+#include "base/location.h" |
#include "base/logging.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" |
@@ -618,6 +621,56 @@ const PrintableSimpleEntry kSimpleMap[] = { |
} // anonymous namespace |
+XkbKeyboardLayoutEngine::XkbKeymapLoader::XkbKeymapLoader( |
+ XkbKeyboardLayoutEngine* layout_engine) : layout_engine_(layout_engine) { |
+} |
+ |
+void XkbKeyboardLayoutEngine::XkbKeymapLoader::loadKeymap( |
+ 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; |
+ std::string layout_variant = ""; |
+ if (parentheses_index != std::string::npos) { |
+ layout_id = layout_name.substr(0, parentheses_index); |
+ size_t close_index = layout_name.find(')', parentheses_index); |
+ if (close_index == std::string::npos) |
+ close_index = layout_name.size(); |
+ layout_variant = layout_name.substr(parentheses_index + 1, |
+ close_index - parentheses_index - 1); |
+ } else if (dash_index != std::string::npos) { |
+ layout_id = layout_name.substr(0, dash_index); |
+ layout_variant = layout_name.substr(dash_index + 1); |
+ } |
+ names = new xkb_rule_names { |
+ .rules = NULL, |
+ .model = "pc101", |
+ .layout = layout_id.c_str(), |
+ .variant = layout_variant.c_str(), |
+ .options = "" |
+ }; |
+ base::WorkerPool::PostTask( |
+ FROM_HERE, |
+ base::Bind(&XkbKeyboardLayoutEngine::XkbKeymapLoader::startLoadKeymap, |
+ base::Unretained(this), |
Shu Chen
2014/12/23 08:46:49
base::Owned(this)
FengYuan
2014/12/23 15:24:57
Done.
|
+ layout_name, |
+ base::Unretained(names)), |
+ true); |
+} |
+ |
+void XkbKeyboardLayoutEngine::XkbKeymapLoader::startLoadKeymap( |
+ const std::string& layout_name, xkb_rule_names* names) { |
Shu Chen
2014/12/23 08:46:49
You need to delete names in this method.
FengYuan
2014/12/23 15:24:57
Done.
|
+ xkb_keymap* keymap = xkb_keymap_new_from_names( |
+ layout_engine_->xkb_context_.get(), |
+ names, |
+ XKB_KEYMAP_COMPILE_NO_FLAGS); |
+ |
+ if (keymap) { |
+ layout_engine_->xkb_keymaps_[layout_name] = keymap; |
Shu Chen
2014/12/23 08:46:49
Please make sure these operations are executed in
FengYuan
2014/12/23 15:24:57
These operations are in the worker thread, and rep
|
+ layout_engine_->SetKeymap(keymap); |
+ } |
+} |
+ |
XkbKeyCodeConverter::XkbKeyCodeConverter() { |
} |
@@ -634,6 +687,10 @@ XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( |
} |
XkbKeyboardLayoutEngine::~XkbKeyboardLayoutEngine() { |
+ std::map<std::string, xkb_keymap*>::const_iterator it = xkb_keymaps_.begin(); |
+ for(;it != xkb_keymaps_.end(); ++it) { |
+ xkb_keymap_unref(it->second); |
+ } |
} |
bool XkbKeyboardLayoutEngine::CanSetCurrentLayout() const { |
@@ -647,35 +704,14 @@ bool XkbKeyboardLayoutEngine::CanSetCurrentLayout() const { |
bool XkbKeyboardLayoutEngine::SetCurrentLayoutByName( |
const std::string& layout_name) { |
#if defined(OS_CHROMEOS) |
- size_t dash_index = layout_name.find('-'); |
- size_t parentheses_index = layout_name.find('('); |
- std::string layout_id = layout_name; |
- std::string layout_variant = ""; |
- if (parentheses_index != std::string::npos) { |
- layout_id = layout_name.substr(0, parentheses_index); |
- size_t close_index = layout_name.find(')', parentheses_index); |
- if (close_index == std::string::npos) |
- close_index = layout_name.size(); |
- layout_variant = layout_name.substr(parentheses_index + 1, |
- close_index - parentheses_index - 1); |
- } else if (dash_index != std::string::npos) { |
- 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); |
+ xkb_keymap* keymap = xkb_keymaps_[layout_name]; |
if (keymap) { |
SetKeymap(keymap); |
- return true; |
+ } else { |
+ XkbKeymapLoader* keymap_loader = new XkbKeymapLoader(this); |
Shu Chen
2014/12/23 08:46:49
nowhere to delete keymap_loader? Suggest to make i
FengYuan
2014/12/23 15:24:57
Done.
|
+ keymap_loader->loadKeymap(layout_name); |
} |
+ return true; |
#endif // defined(OS_CHROMEOS) |
return false; |
} |