Commit 9c79e1fe authored by Gary Kacmarcik's avatar Gary Kacmarcik Committed by Commit Bot

[KeyboardMap] Initial Linux(gdk) version for getLayoutMap

See spec: https://wicg.github.io/keyboard-map/

Bug: 832811
Change-Id: I74bf2ecd3581bd4e68a1c17390b24101a79721ab
Reviewed-on: https://chromium-review.googlesource.com/1053398Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: default avatarThomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Gary Kacmarcik <garykac@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558723}
parent a60c8b67
...@@ -110,6 +110,7 @@ template("libgtkui") { ...@@ -110,6 +110,7 @@ template("libgtkui") {
"//ui/base/ime", "//ui/base/ime",
"//ui/display", "//ui/display",
"//ui/events", "//ui/events",
"//ui/events:dom_keycode_converter",
"//ui/events:events_base", "//ui/events:events_base",
"//ui/events/platform/x11", "//ui/events/platform/x11",
"//ui/gfx", "//ui/gfx",
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/ui/libgtkui/gtk_ui.h" #include "chrome/browser/ui/libgtkui/gtk_ui.h"
#include <dlfcn.h> #include <dlfcn.h>
#include <gdk/gdk.h>
#include <math.h> #include <math.h>
#include <pango/pango.h> #include <pango/pango.h>
...@@ -45,6 +46,8 @@ ...@@ -45,6 +46,8 @@
#include "third_party/skia/include/core/SkShader.h" #include "third_party/skia/include/core/SkShader.h"
#include "ui/base/resource/resource_bundle.h" #include "ui/base/resource/resource_bundle.h"
#include "ui/display/display.h" #include "ui/display/display.h"
#include "ui/events/keycodes/dom/dom_code.h"
#include "ui/events/keycodes/dom/keycode_converter.h"
#include "ui/gfx/canvas.h" #include "ui/gfx/canvas.h"
#include "ui/gfx/font_render_params.h" #include "ui/gfx/font_render_params.h"
#include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect.h"
...@@ -838,6 +841,47 @@ std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() { ...@@ -838,6 +841,47 @@ std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
} }
#endif #endif
base::flat_map<std::string, std::string> GtkUi::GetKeyboardLayoutMap() {
GdkDisplay* display = gdk_display_get_default();
GdkKeymap* keymap = gdk_keymap_get_for_display(display);
auto map = base::flat_map<std::string, std::string>();
if (!keymap)
return map;
for (unsigned int i = 0; i < ui::kWritingSystemKeyDomCodeEntries; ++i) {
ui::DomCode domcode = ui::writing_system_key_domcodes[i];
guint16 keycode = ui::KeycodeConverter::DomCodeToNativeKeycode(domcode);
GdkKeymapKey* keys = nullptr;
guint* keyvals = nullptr;
gint n_entries = 0;
// The order of the layouts is based on the system default ordering in
// Keyboard Settings. The currently active layout does not affect this
// order.
if (gdk_keymap_get_entries_for_keycode(keymap, keycode, &keys, &keyvals,
&n_entries)) {
for (gint i = 0; i < n_entries; ++i) {
// There are 4 entries per layout, one each for shift level 0..3.
// We only care about the unshifted values (level = 0).
if (keys[i].level != 0 || keyvals[i] >= 255)
continue;
char keystring[2];
keystring[0] = keyvals[i];
keystring[1] = '\0';
map.emplace(ui::KeycodeConverter::DomCodeToCodeString(domcode),
keystring);
break;
}
}
g_free(keys);
keys = nullptr;
g_free(keyvals);
keyvals = nullptr;
}
return map;
}
bool GtkUi::MatchEvent(const ui::Event& event, bool GtkUi::MatchEvent(const ui::Event& event,
std::vector<ui::TextEditCommandAuraLinux>* commands) { std::vector<ui::TextEditCommandAuraLinux>* commands) {
// Ensure that we have a keyboard handler. // Ensure that we have a keyboard handler.
......
...@@ -112,6 +112,7 @@ class GtkUi : public views::LinuxUI { ...@@ -112,6 +112,7 @@ class GtkUi : public views::LinuxUI {
#if BUILDFLAG(ENABLE_NATIVE_WINDOW_NAV_BUTTONS) #if BUILDFLAG(ENABLE_NATIVE_WINDOW_NAV_BUTTONS)
std::unique_ptr<views::NavButtonProvider> CreateNavButtonProvider() override; std::unique_ptr<views::NavButtonProvider> CreateNavButtonProvider() override;
#endif #endif
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
// ui::TextEditKeybindingDelegate: // ui::TextEditKeybindingDelegate:
bool MatchEvent(const ui::Event& event, bool MatchEvent(const ui::Event& event,
......
...@@ -113,18 +113,9 @@ void KeyboardLockServiceImpl::CancelKeyboardLock() { ...@@ -113,18 +113,9 @@ void KeyboardLockServiceImpl::CancelKeyboardLock() {
void KeyboardLockServiceImpl::GetKeyboardLayoutMap( void KeyboardLockServiceImpl::GetKeyboardLayoutMap(
GetKeyboardLayoutMapCallback callback) { GetKeyboardLayoutMapCallback callback) {
auto response = GetKeyboardLayoutMapResult::New(); auto response = GetKeyboardLayoutMapResult::New();
response->status = blink::mojom::GetKeyboardLayoutMapStatus::kSuccess; response->status = blink::mojom::GetKeyboardLayoutMapStatus::kSuccess;
response->layout_map =
// TODO(garykac): Call platform specific APIs to populate the layout map render_frame_host_->GetRenderWidgetHost()->GetKeyboardLayoutMap();
// correctly.
// E.g., render_frame_host_->GetRenderWidgetHost()->GetKeyboardLayoutMap()
response->layout_map.emplace("KeyC", "c");
response->layout_map.emplace("KeyH", "h");
response->layout_map.emplace("KeyR", "r");
response->layout_map.emplace("KeyO", "o");
response->layout_map.emplace("KeyM", "m");
response->layout_map.emplace("KeyE", "e");
std::move(callback).Run(std::move(response)); std::move(callback).Run(std::move(response));
} }
......
...@@ -2355,6 +2355,13 @@ void RenderWidgetHostImpl::CancelKeyboardLock() { ...@@ -2355,6 +2355,13 @@ void RenderWidgetHostImpl::CancelKeyboardLock() {
keyboard_keys_to_lock_.reset(); keyboard_keys_to_lock_.reset();
} }
base::flat_map<std::string, std::string>
RenderWidgetHostImpl::GetKeyboardLayoutMap() {
if (!view_)
return {};
return view_->GetKeyboardLayoutMap();
}
void RenderWidgetHostImpl::OnShowDisambiguationPopup( void RenderWidgetHostImpl::OnShowDisambiguationPopup(
const gfx::Rect& rect_pixels, const gfx::Rect& rect_pixels,
const gfx::Size& size, const gfx::Size& size,
......
...@@ -703,6 +703,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl ...@@ -703,6 +703,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Indicates whether keyboard lock is active. // Indicates whether keyboard lock is active.
bool IsKeyboardLocked() const; bool IsKeyboardLocked() const;
// Returns the keyboard layout mapping.
base::flat_map<std::string, std::string> GetKeyboardLayoutMap();
void DidStopFlinging() override; void DidStopFlinging() override;
void GetContentRenderingTimeoutFrom(RenderWidgetHostImpl* other); void GetContentRenderingTimeoutFrom(RenderWidgetHostImpl* other);
......
...@@ -1157,6 +1157,14 @@ bool RenderWidgetHostViewAura::IsKeyboardLocked() { ...@@ -1157,6 +1157,14 @@ bool RenderWidgetHostViewAura::IsKeyboardLocked() {
return event_handler_->IsKeyboardLocked(); return event_handler_->IsKeyboardLocked();
} }
base::flat_map<std::string, std::string>
RenderWidgetHostViewAura::GetKeyboardLayoutMap() {
aura::WindowTreeHost* host = window_->GetHost();
if (host)
return host->GetKeyboardLayoutMap();
return {};
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// RenderWidgetHostViewAura, ui::TextInputClient implementation: // RenderWidgetHostViewAura, ui::TextInputClient implementation:
void RenderWidgetHostViewAura::SetCompositionText( void RenderWidgetHostViewAura::SetCompositionText(
......
...@@ -169,6 +169,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura ...@@ -169,6 +169,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override; bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
void UnlockKeyboard() override; void UnlockKeyboard() override;
bool IsKeyboardLocked() override; bool IsKeyboardLocked() override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
void DidCreateNewRendererCompositorFrameSink( void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink) viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override; override;
......
...@@ -90,6 +90,12 @@ bool HeadlessWindowTreeHost::IsKeyLocked(ui::DomCode dom_code) { ...@@ -90,6 +90,12 @@ bool HeadlessWindowTreeHost::IsKeyLocked(ui::DomCode dom_code) {
return false; return false;
} }
base::flat_map<std::string, std::string>
HeadlessWindowTreeHost::GetKeyboardLayoutMap() {
NOTIMPLEMENTED();
return {};
}
void HeadlessWindowTreeHost::SetCursorNative(gfx::NativeCursor cursor_type) {} void HeadlessWindowTreeHost::SetCursorNative(gfx::NativeCursor cursor_type) {}
void HeadlessWindowTreeHost::MoveCursorToScreenLocationInPixels( void HeadlessWindowTreeHost::MoveCursorToScreenLocationInPixels(
......
...@@ -55,6 +55,7 @@ class HeadlessWindowTreeHost : public aura::WindowTreeHost, ...@@ -55,6 +55,7 @@ class HeadlessWindowTreeHost : public aura::WindowTreeHost,
base::Optional<base::flat_set<ui::DomCode>> codes) override; base::Optional<base::flat_set<ui::DomCode>> codes) override;
void ReleaseSystemKeyEventCapture() override; void ReleaseSystemKeyEventCapture() override;
bool IsKeyLocked(ui::DomCode dom_code) override; bool IsKeyLocked(ui::DomCode dom_code) override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
void SetCursorNative(gfx::NativeCursor cursor_type) override; void SetCursorNative(gfx::NativeCursor cursor_type) override;
void MoveCursorToScreenLocationInPixels(const gfx::Point& location) override; void MoveCursorToScreenLocationInPixels(const gfx::Point& location) override;
void OnCursorVisibilityChangedNative(bool show) override; void OnCursorVisibilityChangedNative(bool show) override;
......
...@@ -8,7 +8,9 @@ ...@@ -8,7 +8,9 @@
#include <stdint.h> #include <stdint.h>
#include <memory> #include <memory>
#include <string>
#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h" #include "base/containers/flat_set.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -211,6 +213,9 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate, ...@@ -211,6 +213,9 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
std::unique_ptr<ScopedKeyboardHook> CaptureSystemKeyEvents( std::unique_ptr<ScopedKeyboardHook> CaptureSystemKeyEvents(
base::Optional<base::flat_set<ui::DomCode>> codes); base::Optional<base::flat_set<ui::DomCode>> codes);
// Returns a map of KeyboardEvent code to KeyboardEvent key values.
virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0;
protected: protected:
friend class ScopedKeyboardHook; friend class ScopedKeyboardHook;
friend class TestScreen; // TODO(beng): see if we can remove/consolidate. friend class TestScreen; // TODO(beng): see if we can remove/consolidate.
......
...@@ -152,6 +152,12 @@ bool WindowTreeHostPlatform::IsKeyLocked(ui::DomCode dom_code) { ...@@ -152,6 +152,12 @@ bool WindowTreeHostPlatform::IsKeyLocked(ui::DomCode dom_code) {
return keyboard_hook_ && keyboard_hook_->IsKeyLocked(dom_code); return keyboard_hook_ && keyboard_hook_->IsKeyLocked(dom_code);
} }
base::flat_map<std::string, std::string>
WindowTreeHostPlatform::GetKeyboardLayoutMap() {
NOTIMPLEMENTED();
return {};
}
void WindowTreeHostPlatform::SetCursorNative(gfx::NativeCursor cursor) { void WindowTreeHostPlatform::SetCursorNative(gfx::NativeCursor cursor) {
if (cursor == current_cursor_) if (cursor == current_cursor_)
return; return;
......
...@@ -82,6 +82,7 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost, ...@@ -82,6 +82,7 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost,
base::Optional<base::flat_set<ui::DomCode>> dom_codes) override; base::Optional<base::flat_set<ui::DomCode>> dom_codes) override;
void ReleaseSystemKeyEventCapture() override; void ReleaseSystemKeyEventCapture() override;
bool IsKeyLocked(ui::DomCode dom_code) override; bool IsKeyLocked(ui::DomCode dom_code) override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
private: private:
gfx::AcceleratedWidget widget_; gfx::AcceleratedWidget widget_;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversion_utils.h" #include "base/strings/utf_string_conversion_utils.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "ui/events/keycodes/dom/dom_code.h" #include "ui/events/keycodes/dom/dom_code.h"
...@@ -317,4 +318,30 @@ int KeycodeConverter::CodeStringToNativeKeycode(const std::string& code) { ...@@ -317,4 +318,30 @@ int KeycodeConverter::CodeStringToNativeKeycode(const std::string& code) {
return UsbKeycodeToNativeKeycode(CodeStringToUsbKeycode(code)); return UsbKeycodeToNativeKeycode(CodeStringToUsbKeycode(code));
} }
const DomCode writing_system_key_domcodes[] = {
// Keyboard Row E
DomCode::BACKQUOTE, DomCode::DIGIT1, DomCode::DIGIT2, DomCode::DIGIT3,
DomCode::DIGIT4, DomCode::DIGIT5, DomCode::DIGIT6, DomCode::DIGIT7,
DomCode::DIGIT8, DomCode::DIGIT9, DomCode::DIGIT0, DomCode::MINUS,
DomCode::EQUAL, DomCode::INTL_YEN,
// Keyboard Row D
DomCode::US_Q, DomCode::US_W, DomCode::US_E, DomCode::US_R, DomCode::US_T,
DomCode::US_Y, DomCode::US_U, DomCode::US_I, DomCode::US_O, DomCode::US_P,
DomCode::BRACKET_LEFT, DomCode::BRACKET_RIGHT, DomCode::BACKSLASH,
// Keyboard Row C
DomCode::US_A, DomCode::US_S, DomCode::US_D, DomCode::US_F, DomCode::US_G,
DomCode::US_H, DomCode::US_J, DomCode::US_K, DomCode::US_L,
DomCode::SEMICOLON, DomCode::QUOTE,
// Keyboard Row B
DomCode::INTL_BACKSLASH, DomCode::US_Z, DomCode::US_X, DomCode::US_C,
DomCode::US_V, DomCode::US_B, DomCode::US_N, DomCode::US_M, DomCode::COMMA,
DomCode::PERIOD, DomCode::SLASH, DomCode::INTL_RO,
};
const size_t kWritingSystemKeyDomCodeEntries =
base::size(writing_system_key_domcodes);
} // namespace ui } // namespace ui
...@@ -21,6 +21,19 @@ enum class DomCode; ...@@ -21,6 +21,19 @@ enum class DomCode;
enum class DomKeyLocation { STANDARD, LEFT, RIGHT, NUMPAD }; enum class DomKeyLocation { STANDARD, LEFT, RIGHT, NUMPAD };
// An array of DomCodes that identifies the Writing System Keys on the
// keyboard.
//
// The Writing System Keys are those that change meaning (i.e., they produce
// a different KeyboardEvent key value) based on the current keyboard layout.
// See https://www.w3.org/TR/uievents-code/#key-alphanumeric-writing-system
//
// This is used by the Keyboard Map API
// (see https://wicg.github.io/keyboard-map/)
extern const DomCode writing_system_key_domcodes[];
extern const size_t kWritingSystemKeyDomCodeEntries;
// This structure is used to define the keycode mapping table. // This structure is used to define the keycode mapping table.
// It is defined here because the unittests need access to it. // It is defined here because the unittests need access to it.
typedef struct { typedef struct {
......
...@@ -196,6 +196,9 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory, ...@@ -196,6 +196,9 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
// toolkit does not support drawing client-side navigation buttons. // toolkit does not support drawing client-side navigation buttons.
virtual std::unique_ptr<NavButtonProvider> CreateNavButtonProvider() = 0; virtual std::unique_ptr<NavButtonProvider> CreateNavButtonProvider() = 0;
#endif #endif
// Returns a map of KeyboardEvent code to KeyboardEvent key values.
virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0;
}; };
} // namespace views } // namespace views
......
...@@ -585,6 +585,12 @@ bool DesktopWindowTreeHostWin::IsKeyLocked(ui::DomCode dom_code) { ...@@ -585,6 +585,12 @@ bool DesktopWindowTreeHostWin::IsKeyLocked(ui::DomCode dom_code) {
return keyboard_hook_ && keyboard_hook_->IsKeyLocked(dom_code); return keyboard_hook_ && keyboard_hook_->IsKeyLocked(dom_code);
} }
base::flat_map<std::string, std::string>
DesktopWindowTreeHostWin::GetKeyboardLayoutMap() {
NOTIMPLEMENTED();
return {};
}
void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) { void DesktopWindowTreeHostWin::SetCursorNative(gfx::NativeCursor cursor) {
ui::CursorLoaderWin cursor_loader; ui::CursorLoaderWin cursor_loader;
cursor_loader.SetPlatformCursor(&cursor); cursor_loader.SetPlatformCursor(&cursor);
......
...@@ -137,6 +137,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin ...@@ -137,6 +137,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
base::Optional<base::flat_set<ui::DomCode>> dom_codes) override; base::Optional<base::flat_set<ui::DomCode>> dom_codes) override;
void ReleaseSystemKeyEventCapture() override; void ReleaseSystemKeyEventCapture() override;
bool IsKeyLocked(ui::DomCode dom_code) override; bool IsKeyLocked(ui::DomCode dom_code) override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
void SetCursorNative(gfx::NativeCursor cursor) override; void SetCursorNative(gfx::NativeCursor cursor) override;
void OnCursorVisibilityChangedNative(bool show) override; void OnCursorVisibilityChangedNative(bool show) override;
void MoveCursorToScreenLocationInPixels( void MoveCursorToScreenLocationInPixels(
......
...@@ -2369,6 +2369,13 @@ aura::Window* DesktopWindowTreeHostX11::content_window() { ...@@ -2369,6 +2369,13 @@ aura::Window* DesktopWindowTreeHostX11::content_window() {
return desktop_native_widget_aura_->content_window(); return desktop_native_widget_aura_->content_window();
} }
base::flat_map<std::string, std::string>
DesktopWindowTreeHostX11::GetKeyboardLayoutMap() {
if (views::LinuxUI::instance())
return views::LinuxUI::instance()->GetKeyboardLayoutMap();
return {};
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// DesktopWindowTreeHost, public: // DesktopWindowTreeHost, public:
......
...@@ -88,6 +88,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11 ...@@ -88,6 +88,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
// Disables event listening to make |dialog| modal. // Disables event listening to make |dialog| modal.
std::unique_ptr<base::Closure> DisableEventListening(); std::unique_ptr<base::Closure> DisableEventListening();
// Returns a map of KeyboardEvent code to KeyboardEvent key values.
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
protected: protected:
// Overridden from DesktopWindowTreeHost: // Overridden from DesktopWindowTreeHost:
void Init(const Widget::InitParams& params) override; void Init(const Widget::InitParams& params) override;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment