Commit 1cb7b440 authored by Alexander Dunaev's avatar Alexander Dunaev Committed by Commit Bot

[ozone/x11] Enabled shortcuts in DBus menus.

The DBus Menu supports rendering keyboard shortcuts for its items,
for which the 'shortcut' property should be set for the menu item.  The
shortcut is built from the key code using platform-specific conversions.

This CL adds a platform interface that allows the DBus menu to query the
platform for the key sym string for the given key code, and enables the
menu shortcuts for Ozone X11.

Bug: 1121908
Change-Id: I42828f967cc2c0eec24d86ba0e0ad0528435bb1e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2450192
Commit-Queue: Alexander Dunaev <adunaev@igalia.com>
Reviewed-by: default avatarScott Violet <sky@chromium.org>
Reviewed-by: default avatarMaksim Sisov (GMT+3) <msisov@igalia.com>
Reviewed-by: default avatarThomas Anderson <thomasanderson@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815611}
parent ccffff33
......@@ -29,6 +29,9 @@ component("menu") {
"//ui/gfx/x",
]
}
if (use_ozone) {
deps += [ "//ui/ozone" ]
}
}
source_set("unit_tests") {
......
......@@ -4,4 +4,5 @@ include_rules = [
"+ui/events/keycodes",
"+ui/gfx/image",
"+ui/gfx/x",
"+ui/ozone/public",
]
......@@ -8,19 +8,65 @@
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/accelerators/menu_label_accelerator_util_linux.h"
#include "ui/base/models/image_model.h"
#include "ui/base/models/menu_model.h"
#include "ui/events/keycodes/keysym_to_unicode.h"
#include "ui/gfx/image/image.h"
#if defined(USE_X11)
#include "ui/base/ui_base_features.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h" // nogncheck
#include "ui/events/keycodes/keysym_to_unicode.h" // nogncheck
#include "ui/gfx/x/x11.h" // nogncheck
#endif
#if defined(USE_OZONE)
#include "ui/base/ui_base_features.h" // nogncheck
#include "ui/ozone/public/ozone_platform.h" // nogncheck
#include "ui/ozone/public/platform_menu_utils.h" // nogncheck
#endif
namespace {
std::string ToDBusKeySym(ui::KeyboardCode code) {
#if defined(USE_OZONE)
if (features::IsUsingOzonePlatform()) {
const auto* const platorm_menu_utils =
ui::OzonePlatform::GetInstance()->GetPlatformMenuUtils();
if (platorm_menu_utils)
return platorm_menu_utils->ToDBusKeySym(code);
return {};
}
#endif
#if defined(USE_X11)
return base::UTF16ToUTF8(
base::string16(1, ui::GetUnicodeCharacterFromXKeySym(
XKeysymForWindowsKeyCode(code, false))));
#endif
return {};
}
std::vector<DbusString> GetDbusMenuShortcut(ui::Accelerator accelerator) {
auto dbus_key_sym = ToDBusKeySym(accelerator.key_code());
if (dbus_key_sym.empty())
return {};
std::vector<DbusString> parts;
if (accelerator.IsCtrlDown())
parts.emplace_back("Control");
if (accelerator.IsAltDown())
parts.emplace_back("Alt");
if (accelerator.IsShiftDown())
parts.emplace_back("Shift");
if (accelerator.IsCmdDown())
parts.emplace_back("Super");
parts.emplace_back(dbus_key_sym);
return parts;
}
} // namespace
MenuItemProperties ComputeMenuPropertiesForMenuItem(ui::MenuModel* menu,
int i) {
// Properties should only be set if they differ from the default values.
......@@ -48,26 +94,11 @@ MenuItemProperties ComputeMenuPropertiesForMenuItem(ui::MenuModel* menu,
ui::Accelerator accelerator;
if (menu->GetAcceleratorAt(i, &accelerator)) {
std::vector<DbusString> parts;
if (accelerator.IsCtrlDown())
parts.emplace_back("Control");
if (accelerator.IsAltDown())
parts.emplace_back("Alt");
if (accelerator.IsShiftDown())
parts.emplace_back("Shift");
if (accelerator.IsCmdDown())
parts.emplace_back("Super");
#if defined(USE_X11)
if (!features::IsUsingOzonePlatform()) {
uint16_t keysym = ui::GetUnicodeCharacterFromXKeySym(
XKeysymForWindowsKeyCode(accelerator.key_code(), false));
parts.emplace_back(base::UTF16ToUTF8(base::string16(1, keysym)));
auto parts = GetDbusMenuShortcut(accelerator);
if (!parts.empty()) {
properties["shortcut"] = MakeDbusVariant(
MakeDbusArray(DbusArray<DbusString>(std::move(parts))));
}
#else
NOTIMPLEMENTED();
#endif
}
switch (menu->GetTypeAt(i)) {
......
......@@ -7,6 +7,7 @@
#include <memory>
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/dbus/properties/types.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/accelerators/accelerator.h"
......@@ -318,7 +319,7 @@ TEST(MenuPropertyListTest, ComputePropertiesIcon) {
EXPECT_EQ(menu->ComputeProperties(), props);
}
#if defined(USE_X11)
#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
TEST(MenuPropertyListTest, ComputePropertiesAccelerator) {
if (features::IsUsingOzonePlatform())
return;
......
......@@ -90,6 +90,8 @@ component("ozone_base") {
"public/ozone_switches.h",
"public/platform_clipboard.h",
"public/platform_gl_egl_utility.h",
"public/platform_menu_utils.cc",
"public/platform_menu_utils.h",
"public/platform_screen.cc",
"public/platform_screen.h",
"public/platform_window_surface.h",
......
......@@ -47,12 +47,6 @@ source_set("wayland") {
"host/gtk_primary_selection_device_manager.h",
"host/gtk_primary_selection_offer.cc",
"host/gtk_primary_selection_offer.h",
"host/zwp_primary_selection_device.cc",
"host/zwp_primary_selection_device.h",
"host/zwp_primary_selection_device_manager.cc",
"host/zwp_primary_selection_device_manager.h",
"host/zwp_primary_selection_offer.cc",
"host/zwp_primary_selection_offer.h",
"host/shell_object_factory.cc",
"host/shell_object_factory.h",
"host/shell_popup_wrapper.cc",
......@@ -99,6 +93,8 @@ source_set("wayland") {
"host/wayland_input_method_context_factory.h",
"host/wayland_keyboard.cc",
"host/wayland_keyboard.h",
"host/wayland_menu_utils.cc",
"host/wayland_menu_utils.h",
"host/wayland_output.cc",
"host/wayland_output.h",
"host/wayland_output_manager.cc",
......@@ -138,6 +134,12 @@ source_set("wayland") {
"host/xdg_popup_wrapper_impl.h",
"host/xdg_surface_wrapper_impl.cc",
"host/xdg_surface_wrapper_impl.h",
"host/zwp_primary_selection_device.cc",
"host/zwp_primary_selection_device.h",
"host/zwp_primary_selection_device_manager.cc",
"host/zwp_primary_selection_device_manager.h",
"host/zwp_primary_selection_offer.cc",
"host/zwp_primary_selection_offer.h",
"host/zwp_text_input_wrapper.h",
"host/zwp_text_input_wrapper_v1.cc",
"host/zwp_text_input_wrapper_v1.h",
......
// Copyright 2020 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 "ui/ozone/platform/wayland/host/wayland_menu_utils.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
namespace ui {
WaylandMenuUtils::WaylandMenuUtils(WaylandConnection* connection)
: connection_(connection) {}
WaylandMenuUtils::~WaylandMenuUtils() = default;
int WaylandMenuUtils::GetCurrentKeyModifiers() const {
DCHECK(connection_);
DCHECK(connection_->event_source());
return connection_->event_source()->keyboard_modifiers();
}
} // namespace ui
// Copyright 2020 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.
#ifndef UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_MENU_UTILS_H_
#define UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_MENU_UTILS_H_
#include "ui/ozone/public/platform_menu_utils.h"
namespace ui {
class WaylandConnection;
class WaylandMenuUtils : public PlatformMenuUtils {
public:
explicit WaylandMenuUtils(WaylandConnection* connection);
WaylandMenuUtils(const WaylandMenuUtils&) = delete;
WaylandMenuUtils& operator=(const WaylandMenuUtils&) = delete;
~WaylandMenuUtils() override;
int GetCurrentKeyModifiers() const override;
private:
WaylandConnection* const connection_;
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_WAYLAND_HOST_WAYLAND_MENU_UTILS_H_
......@@ -30,13 +30,14 @@
#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_connector.h"
#include "ui/ozone/platform/wayland/host/wayland_buffer_manager_host.h"
#include "ui/ozone/platform/wayland/host/wayland_connection.h"
#include "ui/ozone/platform/wayland/host/wayland_event_source.h"
#include "ui/ozone/platform/wayland/host/wayland_input_method_context_factory.h"
#include "ui/ozone/platform/wayland/host/wayland_menu_utils.h"
#include "ui/ozone/platform/wayland/host/wayland_output_manager.h"
#include "ui/ozone/platform/wayland/host/wayland_window.h"
#include "ui/ozone/public/gpu_platform_support_host.h"
#include "ui/ozone/public/input_controller.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/platform_menu_utils.h"
#include "ui/ozone/public/system_input_injector.h"
#include "ui/platform_window/platform_window_init_properties.h"
......@@ -123,12 +124,6 @@ class OzonePlatformWayland : public OzonePlatform {
return connection_->clipboard();
}
int GetKeyModifiers() const override {
DCHECK(connection_);
DCHECK(connection_->event_source());
return connection_->event_source()->keyboard_modifiers();
}
std::unique_ptr<InputMethod> CreateInputMethod(
internal::InputMethodDelegate* delegate,
gfx::AcceleratedWidget widget) override {
......@@ -145,6 +140,10 @@ class OzonePlatformWayland : public OzonePlatform {
return std::make_unique<InputMethodAuraLinux>(delegate);
}
PlatformMenuUtils* GetPlatformMenuUtils() override {
return menu_utils_.get();
}
bool IsNativePixmapConfigSupported(gfx::BufferFormat format,
gfx::BufferUsage usage) const override {
// If there is no drm render node device available, native pixmaps are not
......@@ -189,6 +188,8 @@ class OzonePlatformWayland : public OzonePlatform {
GtkUiDelegate::SetInstance(gtk_ui_delegate_.get());
#endif
menu_utils_ = std::make_unique<WaylandMenuUtils>(connection_.get());
// TODO(crbug.com/1097007): report which Wayland compositor is used.
}
......@@ -278,6 +279,7 @@ class OzonePlatformWayland : public OzonePlatform {
std::unique_ptr<WaylandInputMethodContextFactory>
input_method_context_factory_;
std::unique_ptr<WaylandBufferManagerConnector> buffer_manager_connector_;
std::unique_ptr<WaylandMenuUtils> menu_utils_;
// Objects, which solely live in the GPU process.
std::unique_ptr<WaylandBufferManagerGpu> buffer_manager_;
......
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef UI_OZONE_PLATFORM_DRM_OZONE_PLATFORM_WAYLAND_H_
#define UI_OZONE_PLATFORM_DRM_OZONE_PLATFORM_WAYLAND_H_
#ifndef UI_OZONE_PLATFORM_OZONE_PLATFORM_WAYLAND_H_
#define UI_OZONE_PLATFORM_OZONE_PLATFORM_WAYLAND_H_
namespace ui {
......@@ -14,4 +14,4 @@ OzonePlatform* CreateOzonePlatformWayland();
} // namespace ui
#endif // UI_OZONE_PLATFORM_DRM_OZONE_PLATFORM_WAYLAND_H_
#endif // UI_OZONE_PLATFORM_OZONE_PLATFORM_WAYLAND_H_
......@@ -24,6 +24,8 @@ source_set("x11") {
"x11_canvas_surface.h",
"x11_clipboard_ozone.cc",
"x11_clipboard_ozone.h",
"x11_menu_utils.cc",
"x11_menu_utils.h",
"x11_screen_ozone.cc",
"x11_screen_ozone.h",
"x11_surface_factory.cc",
......
......@@ -10,6 +10,7 @@
#include "base/message_loop/message_pump_type.h"
#include "base/metrics/histogram_functions.h"
#include "base/no_destructor.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "ui/base/buildflags.h"
......@@ -24,12 +25,12 @@
#include "ui/events/ozone/layout/keyboard_layout_engine_manager.h"
#include "ui/events/ozone/layout/stub/stub_keyboard_layout_engine.h"
#include "ui/events/platform/x11/x11_event_source.h"
#include "ui/events/x/events_x_utils.h"
#include "ui/gfx/native_widget_types.h"
#include "ui/gfx/x/x11_types.h"
#include "ui/ozone/common/stub_overlay_manager.h"
#include "ui/ozone/platform/x11/gl_egl_utility_x11.h"
#include "ui/ozone/platform/x11/x11_clipboard_ozone.h"
#include "ui/ozone/platform/x11/x11_menu_utils.h"
#include "ui/ozone/platform/x11/x11_screen_ozone.h"
#include "ui/ozone/platform/x11/x11_surface_factory.h"
#include "ui/ozone/public/gpu_platform_support_host.h"
......@@ -125,8 +126,6 @@ class OzonePlatformX11 : public OzonePlatform,
return gl_egl_utility_.get();
}
int GetKeyModifiers() const override { return GetModifierKeyState(); }
std::unique_ptr<InputMethod> CreateInputMethod(
internal::InputMethodDelegate* delegate,
gfx::AcceleratedWidget) override {
......@@ -143,6 +142,10 @@ class OzonePlatformX11 : public OzonePlatform,
#endif
}
PlatformMenuUtils* GetPlatformMenuUtils() override {
return menu_utils_.get();
}
std::unique_ptr<OSExchangeDataProvider> CreateProvider() override {
#if defined(OS_CHROMEOS)
return std::make_unique<OSExchangeDataProviderNonBacked>();
......@@ -205,6 +208,8 @@ class OzonePlatformX11 : public OzonePlatform,
GtkUiDelegate::SetInstance(gtk_ui_delegate_.get());
#endif
menu_utils_ = std::make_unique<X11MenuUtils>();
base::UmaHistogramEnumeration("Linux.WindowManager", GetWindowManagerUMA());
}
......@@ -269,6 +274,7 @@ class OzonePlatformX11 : public OzonePlatform,
std::unique_ptr<X11ClipboardOzone> clipboard_;
std::unique_ptr<CursorFactory> cursor_factory_;
std::unique_ptr<GpuPlatformSupportHost> gpu_platform_support_host_;
std::unique_ptr<X11MenuUtils> menu_utils_;
// Objects in the GPU process.
std::unique_ptr<X11SurfaceFactory> surface_factory_ozone_;
......
// Copyright 2020 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 "ui/ozone/platform/x11/x11_menu_utils.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/events/keycodes/keyboard_code_conversion_x.h"
#include "ui/events/keycodes/keysym_to_unicode.h"
#include "ui/events/x/events_x_utils.h"
namespace ui {
X11MenuUtils::X11MenuUtils() = default;
X11MenuUtils::~X11MenuUtils() = default;
int X11MenuUtils::GetCurrentKeyModifiers() const {
return GetModifierKeyState();
}
std::string X11MenuUtils::ToDBusKeySym(KeyboardCode code) const {
return base::UTF16ToUTF8(
base::string16(1, ui::GetUnicodeCharacterFromXKeySym(
XKeysymForWindowsKeyCode(code, false))));
}
} // namespace ui
// Copyright 2020 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.
#ifndef UI_OZONE_PLATFORM_X11_X11_MENU_UTILS_H_
#define UI_OZONE_PLATFORM_X11_X11_MENU_UTILS_H_
#include "ui/ozone/public/platform_menu_utils.h"
namespace ui {
class X11MenuUtils : public PlatformMenuUtils {
public:
X11MenuUtils();
X11MenuUtils(const X11MenuUtils&) = delete;
X11MenuUtils& operator=(const X11MenuUtils&) = delete;
~X11MenuUtils() override;
int GetCurrentKeyModifiers() const override;
std::string ToDBusKeySym(KeyboardCode code) const override;
};
} // namespace ui
#endif // UI_OZONE_PLATFORM_X11_X11_MENU_UTILS_H_
......@@ -13,6 +13,7 @@
#include "ui/events/devices/device_data_manager.h"
#include "ui/ozone/platform_object.h"
#include "ui/ozone/platform_selection.h"
#include "ui/ozone/public/platform_menu_utils.h"
#include "ui/ozone/public/platform_screen.h"
namespace ui {
......@@ -98,9 +99,8 @@ PlatformGLEGLUtility* OzonePlatform::GetPlatformGLEGLUtility() {
return nullptr;
}
int OzonePlatform::GetKeyModifiers() const {
// Platform may override this to provide the current state of modifier keys.
return 0;
PlatformMenuUtils* OzonePlatform::GetPlatformMenuUtils() {
return nullptr;
}
bool OzonePlatform::IsNativePixmapConfigSupported(
......
......@@ -24,14 +24,15 @@ class NativeDisplayDelegate;
namespace ui {
class CursorFactory;
class InputController;
class GpuPlatformSupportHost;
class InputController;
class OverlayManagerOzone;
class PlatformClipboard;
class PlatformGLEGLUtility;
class PlatformMenuUtils;
class PlatformScreen;
class SurfaceFactoryOzone;
class SystemInputInjector;
class PlatformClipboard;
class PlatformGLEGLUtility;
namespace internal {
class InputMethodDelegate;
......@@ -188,10 +189,7 @@ class COMPONENT_EXPORT(OZONE) OzonePlatform {
internal::InputMethodDelegate* delegate,
gfx::AcceleratedWidget widget) = 0;
virtual PlatformGLEGLUtility* GetPlatformGLEGLUtility();
// Returns a bitmask of EventFlags showing the state of Alt, Shift and Ctrl
// keys that came with the most recent UI event.
virtual int GetKeyModifiers() const;
virtual PlatformMenuUtils* GetPlatformMenuUtils();
// Returns true if the specified buffer format is supported.
virtual bool IsNativePixmapConfigSupported(gfx::BufferFormat format,
......
// Copyright 2020 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 "ui/ozone/public/platform_menu_utils.h"
#include "base/notreached.h"
namespace ui {
PlatformMenuUtils::PlatformMenuUtils() = default;
PlatformMenuUtils::~PlatformMenuUtils() = default;
int PlatformMenuUtils::GetCurrentKeyModifiers() const {
NOTIMPLEMENTED_LOG_ONCE();
return {};
}
std::string PlatformMenuUtils::ToDBusKeySym(KeyboardCode code) const {
NOTIMPLEMENTED_LOG_ONCE();
return {};
}
} // namespace ui
// Copyright 2020 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.
#ifndef UI_OZONE_PUBLIC_PLATFORM_MENU_UTILS_H_
#define UI_OZONE_PUBLIC_PLATFORM_MENU_UTILS_H_
#include <string>
#include "base/component_export.h"
#include "ui/events/keycodes/keyboard_codes_posix.h"
namespace ui {
enum class DomCode;
// Platform-specific functions related to menus.
class COMPONENT_EXPORT(OZONE_BASE) PlatformMenuUtils {
public:
PlatformMenuUtils();
PlatformMenuUtils(const PlatformMenuUtils&) = delete;
PlatformMenuUtils& operator=(const PlatformMenuUtils&) = delete;
virtual ~PlatformMenuUtils();
// Returns a bitmask of EventFlags showing the state of Alt, Shift and Ctrl
// keys that came with the most recent UI event.
virtual int GetCurrentKeyModifiers() const;
// Converts the keyboard code into a keysym label compatible with DBus menu
// protocol.
virtual std::string ToDBusKeySym(KeyboardCode code) const;
};
} // namespace ui
#endif // UI_OZONE_PUBLIC_PLATFORM_MENU_UTILS_H_
......@@ -31,6 +31,7 @@
#include "ui/base/ui_base_features.h"
#include "ui/events/event_constants.h"
#include "ui/ozone/public/ozone_platform.h"
#include "ui/ozone/public/platform_menu_utils.h"
#endif
namespace views {
......@@ -54,8 +55,11 @@ void FireFocusAfterMenuClose(base::WeakPtr<Widget> widget) {
bool IsAltPressed() {
#if defined(USE_OZONE)
if (features::IsUsingOzonePlatform()) {
return (ui::OzonePlatform::GetInstance()->GetKeyModifiers() &
ui::EF_ALT_DOWN) != 0;
const auto* const platorm_menu_utils =
ui::OzonePlatform::GetInstance()->GetPlatformMenuUtils();
if (platorm_menu_utils)
return (platorm_menu_utils->GetCurrentKeyModifiers() & ui::EF_ALT_DOWN) !=
0;
}
#endif
#if defined(USE_X11)
......
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