Skip to content

Commit

Permalink
[KeyboardMap] Initial Linux(gdk) version for getLayoutMap
Browse files Browse the repository at this point in the history
See spec: https://wicg.github.io/keyboard-map/

Bug: 832811
Change-Id: I74bf2ecd3581bd4e68a1c17390b24101a79721ab
Reviewed-on: https://chromium-review.googlesource.com/1053398
Reviewed-by: Scott Violet <sky@chromium.org>
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: Thomas Anderson <thomasanderson@chromium.org>
Commit-Queue: Gary Kacmarcik <garykac@chromium.org>
Cr-Commit-Position: refs/heads/master@{#558723}
  • Loading branch information
garykac authored and Commit Bot committed May 15, 2018
1 parent a60c8b6 commit 9c79e1f
Show file tree
Hide file tree
Showing 20 changed files with 146 additions and 11 deletions.
1 change: 1 addition & 0 deletions chrome/browser/ui/libgtkui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ template("libgtkui") {
"//ui/base/ime",
"//ui/display",
"//ui/events",
"//ui/events:dom_keycode_converter",
"//ui/events:events_base",
"//ui/events/platform/x11",
"//ui/gfx",
Expand Down
44 changes: 44 additions & 0 deletions chrome/browser/ui/libgtkui/gtk_ui.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "chrome/browser/ui/libgtkui/gtk_ui.h"

#include <dlfcn.h>
#include <gdk/gdk.h>
#include <math.h>
#include <pango/pango.h>

Expand Down Expand Up @@ -45,6 +46,8 @@
#include "third_party/skia/include/core/SkShader.h"
#include "ui/base/resource/resource_bundle.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/font_render_params.h"
#include "ui/gfx/geometry/rect.h"
Expand Down Expand Up @@ -838,6 +841,47 @@ std::unique_ptr<views::NavButtonProvider> GtkUi::CreateNavButtonProvider() {
}
#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,
std::vector<ui::TextEditCommandAuraLinux>* commands) {
// Ensure that we have a keyboard handler.
Expand Down
1 change: 1 addition & 0 deletions chrome/browser/ui/libgtkui/gtk_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class GtkUi : public views::LinuxUI {
#if BUILDFLAG(ENABLE_NATIVE_WINDOW_NAV_BUTTONS)
std::unique_ptr<views::NavButtonProvider> CreateNavButtonProvider() override;
#endif
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;

// ui::TextEditKeybindingDelegate:
bool MatchEvent(const ui::Event& event,
Expand Down
13 changes: 2 additions & 11 deletions content/browser/keyboard_lock/keyboard_lock_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,9 @@ void KeyboardLockServiceImpl::CancelKeyboardLock() {
void KeyboardLockServiceImpl::GetKeyboardLayoutMap(
GetKeyboardLayoutMapCallback callback) {
auto response = GetKeyboardLayoutMapResult::New();

response->status = blink::mojom::GetKeyboardLayoutMapStatus::kSuccess;

// TODO(garykac): Call platform specific APIs to populate the layout map
// 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");
response->layout_map =
render_frame_host_->GetRenderWidgetHost()->GetKeyboardLayoutMap();

std::move(callback).Run(std::move(response));
}
Expand Down
7 changes: 7 additions & 0 deletions content/browser/renderer_host/render_widget_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2355,6 +2355,13 @@ void RenderWidgetHostImpl::CancelKeyboardLock() {
keyboard_keys_to_lock_.reset();
}

base::flat_map<std::string, std::string>
RenderWidgetHostImpl::GetKeyboardLayoutMap() {
if (!view_)
return {};
return view_->GetKeyboardLayoutMap();
}

void RenderWidgetHostImpl::OnShowDisambiguationPopup(
const gfx::Rect& rect_pixels,
const gfx::Size& size,
Expand Down
3 changes: 3 additions & 0 deletions content/browser/renderer_host/render_widget_host_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,9 @@ class CONTENT_EXPORT RenderWidgetHostImpl
// Indicates whether keyboard lock is active.
bool IsKeyboardLocked() const;

// Returns the keyboard layout mapping.
base::flat_map<std::string, std::string> GetKeyboardLayoutMap();

void DidStopFlinging() override;

void GetContentRenderingTimeoutFrom(RenderWidgetHostImpl* other);
Expand Down
8 changes: 8 additions & 0 deletions content/browser/renderer_host/render_widget_host_view_aura.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1157,6 +1157,14 @@ bool RenderWidgetHostViewAura::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:
void RenderWidgetHostViewAura::SetCompositionText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ class CONTENT_EXPORT RenderWidgetHostViewAura
bool LockKeyboard(base::Optional<base::flat_set<ui::DomCode>> codes) override;
void UnlockKeyboard() override;
bool IsKeyboardLocked() override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
void DidCreateNewRendererCompositorFrameSink(
viz::mojom::CompositorFrameSinkClient* renderer_compositor_frame_sink)
override;
Expand Down
6 changes: 6 additions & 0 deletions headless/lib/browser/headless_window_tree_host.cc
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,12 @@ bool HeadlessWindowTreeHost::IsKeyLocked(ui::DomCode dom_code) {
return false;
}

base::flat_map<std::string, std::string>
HeadlessWindowTreeHost::GetKeyboardLayoutMap() {
NOTIMPLEMENTED();
return {};
}

void HeadlessWindowTreeHost::SetCursorNative(gfx::NativeCursor cursor_type) {}

void HeadlessWindowTreeHost::MoveCursorToScreenLocationInPixels(
Expand Down
1 change: 1 addition & 0 deletions headless/lib/browser/headless_window_tree_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class HeadlessWindowTreeHost : public aura::WindowTreeHost,
base::Optional<base::flat_set<ui::DomCode>> codes) override;
void ReleaseSystemKeyEventCapture() 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 MoveCursorToScreenLocationInPixels(const gfx::Point& location) override;
void OnCursorVisibilityChangedNative(bool show) override;
Expand Down
5 changes: 5 additions & 0 deletions ui/aura/window_tree_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include <stdint.h>

#include <memory>
#include <string>

#include "base/containers/flat_map.h"
#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
Expand Down Expand Up @@ -211,6 +213,9 @@ class AURA_EXPORT WindowTreeHost : public ui::internal::InputMethodDelegate,
std::unique_ptr<ScopedKeyboardHook> CaptureSystemKeyEvents(
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:
friend class ScopedKeyboardHook;
friend class TestScreen; // TODO(beng): see if we can remove/consolidate.
Expand Down
6 changes: 6 additions & 0 deletions ui/aura/window_tree_host_platform.cc
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ bool WindowTreeHostPlatform::IsKeyLocked(ui::DomCode 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) {
if (cursor == current_cursor_)
return;
Expand Down
1 change: 1 addition & 0 deletions ui/aura/window_tree_host_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class AURA_EXPORT WindowTreeHostPlatform : public WindowTreeHost,
base::Optional<base::flat_set<ui::DomCode>> dom_codes) override;
void ReleaseSystemKeyEventCapture() override;
bool IsKeyLocked(ui::DomCode dom_code) override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;

private:
gfx::AcceleratedWidget widget_;
Expand Down
27 changes: 27 additions & 0 deletions ui/events/keycodes/dom/keycode_converter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "base/logging.h"
#include "base/macros.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversion_utils.h"
#include "build/build_config.h"
#include "ui/events/keycodes/dom/dom_code.h"
Expand Down Expand Up @@ -317,4 +318,30 @@ int KeycodeConverter::CodeStringToNativeKeycode(const std::string& 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
13 changes: 13 additions & 0 deletions ui/events/keycodes/dom/keycode_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ enum class DomCode;

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.
// It is defined here because the unittests need access to it.
typedef struct {
Expand Down
3 changes: 3 additions & 0 deletions ui/views/linux_ui/linux_ui.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ class VIEWS_EXPORT LinuxUI : public ui::LinuxInputMethodContextFactory,
// toolkit does not support drawing client-side navigation buttons.
virtual std::unique_ptr<NavButtonProvider> CreateNavButtonProvider() = 0;
#endif

// Returns a map of KeyboardEvent code to KeyboardEvent key values.
virtual base::flat_map<std::string, std::string> GetKeyboardLayoutMap() = 0;
};

} // namespace views
Expand Down
6 changes: 6 additions & 0 deletions ui/views/widget/desktop_aura/desktop_window_tree_host_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,12 @@ bool DesktopWindowTreeHostWin::IsKeyLocked(ui::DomCode 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) {
ui::CursorLoaderWin cursor_loader;
cursor_loader.SetPlatformCursor(&cursor);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ class VIEWS_EXPORT DesktopWindowTreeHostWin
base::Optional<base::flat_set<ui::DomCode>> dom_codes) override;
void ReleaseSystemKeyEventCapture() override;
bool IsKeyLocked(ui::DomCode dom_code) override;
base::flat_map<std::string, std::string> GetKeyboardLayoutMap() override;
void SetCursorNative(gfx::NativeCursor cursor) override;
void OnCursorVisibilityChangedNative(bool show) override;
void MoveCursorToScreenLocationInPixels(
Expand Down
7 changes: 7 additions & 0 deletions ui/views/widget/desktop_aura/desktop_window_tree_host_x11.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2369,6 +2369,13 @@ aura::Window* DesktopWindowTreeHostX11::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:

Expand Down
3 changes: 3 additions & 0 deletions ui/views/widget/desktop_aura/desktop_window_tree_host_x11.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ class VIEWS_EXPORT DesktopWindowTreeHostX11
// Disables event listening to make |dialog| modal.
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:
// Overridden from DesktopWindowTreeHost:
void Init(const Widget::InitParams& params) override;
Expand Down

0 comments on commit 9c79e1f

Please sign in to comment.