feat: add support for keyboard initialized menu popup (#38903)
* feat: add support for keyboard initialized menu popup * Update docs/api/menu.md Co-authored-by: Erick Zhao <erick@hotmail.ca> * fix: add patch to chromium for keyboard accessibility menu behavior * refactor: s/initiatedByKeyboard/sourceType * fix: ignore initial mouse event to retain keyboard initiated focus * Update docs/api/menu.md Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com> --------- Co-authored-by: Erick Zhao <erick@hotmail.ca> Co-authored-by: Samuel Maddock <samuel.maddock@gmail.com>
This commit is contained in:
parent
607e71d563
commit
499d893040
13 changed files with 282 additions and 33 deletions
|
@ -11,6 +11,7 @@
|
|||
#include "shell/browser/native_window.h"
|
||||
#include "shell/common/gin_converters/accelerator_converter.h"
|
||||
#include "shell/common/gin_converters/callback_converter.h"
|
||||
#include "shell/common/gin_converters/content_converter.h"
|
||||
#include "shell/common/gin_converters/file_path_converter.h"
|
||||
#include "shell/common/gin_converters/gurl_converter.h"
|
||||
#include "shell/common/gin_converters/image_converter.h"
|
||||
|
|
|
@ -78,6 +78,7 @@ class Menu : public gin::Wrappable<Menu>,
|
|||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
ui::MenuSourceType source_type,
|
||||
base::OnceClosure callback) = 0;
|
||||
virtual void ClosePopupAt(int32_t window_id) = 0;
|
||||
virtual std::u16string GetAcceleratorTextAtForTesting(int index) const;
|
||||
|
|
|
@ -24,6 +24,7 @@ class MenuMac : public Menu {
|
|||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
ui::MenuSourceType source_type,
|
||||
base::OnceClosure callback) override;
|
||||
void PopupOnUI(const base::WeakPtr<NativeWindow>& native_window,
|
||||
int32_t window_id,
|
||||
|
|
|
@ -52,6 +52,7 @@ void MenuMac::PopupAt(BaseWindow* window,
|
|||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
ui::MenuSourceType source_type,
|
||||
base::OnceClosure callback) {
|
||||
NativeWindow* native_window = window->window();
|
||||
if (!native_window)
|
||||
|
|
|
@ -22,6 +22,7 @@ void MenuViews::PopupAt(BaseWindow* window,
|
|||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
ui::MenuSourceType source_type,
|
||||
base::OnceClosure callback) {
|
||||
auto* native_window = static_cast<NativeWindowViews*>(window->window());
|
||||
if (!native_window)
|
||||
|
@ -55,7 +56,7 @@ void MenuViews::PopupAt(BaseWindow* window,
|
|||
std::make_unique<MenuRunner>(model(), flags, std::move(close_callback));
|
||||
menu_runners_[window_id]->RunMenuAt(
|
||||
native_window->widget(), nullptr, gfx::Rect(location, gfx::Size()),
|
||||
views::MenuAnchorPosition::kTopLeft, ui::MENU_SOURCE_MOUSE);
|
||||
views::MenuAnchorPosition::kTopLeft, source_type);
|
||||
}
|
||||
|
||||
void MenuViews::ClosePopupAt(int32_t window_id) {
|
||||
|
|
|
@ -25,6 +25,7 @@ class MenuViews : public Menu {
|
|||
int x,
|
||||
int y,
|
||||
int positioning_item,
|
||||
ui::MenuSourceType source_type,
|
||||
base::OnceClosure callback) override;
|
||||
void ClosePopupAt(int32_t window_id) override;
|
||||
|
||||
|
|
|
@ -24,36 +24,81 @@
|
|||
|
||||
namespace gin {
|
||||
|
||||
template <>
|
||||
struct Converter<ui::MenuSourceType> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const ui::MenuSourceType& in) {
|
||||
switch (in) {
|
||||
case ui::MENU_SOURCE_MOUSE:
|
||||
return StringToV8(isolate, "mouse");
|
||||
case ui::MENU_SOURCE_KEYBOARD:
|
||||
return StringToV8(isolate, "keyboard");
|
||||
case ui::MENU_SOURCE_TOUCH:
|
||||
return StringToV8(isolate, "touch");
|
||||
case ui::MENU_SOURCE_TOUCH_EDIT_MENU:
|
||||
return StringToV8(isolate, "touchMenu");
|
||||
case ui::MENU_SOURCE_LONG_PRESS:
|
||||
return StringToV8(isolate, "longPress");
|
||||
case ui::MENU_SOURCE_LONG_TAP:
|
||||
return StringToV8(isolate, "longTap");
|
||||
case ui::MENU_SOURCE_TOUCH_HANDLE:
|
||||
return StringToV8(isolate, "touchHandle");
|
||||
case ui::MENU_SOURCE_STYLUS:
|
||||
return StringToV8(isolate, "stylus");
|
||||
case ui::MENU_SOURCE_ADJUST_SELECTION:
|
||||
return StringToV8(isolate, "adjustSelection");
|
||||
case ui::MENU_SOURCE_ADJUST_SELECTION_RESET:
|
||||
return StringToV8(isolate, "adjustSelectionReset");
|
||||
default:
|
||||
return StringToV8(isolate, "none");
|
||||
}
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<ui::MenuSourceType>::ToV8(
|
||||
v8::Isolate* isolate,
|
||||
const ui::MenuSourceType& in) {
|
||||
switch (in) {
|
||||
case ui::MENU_SOURCE_MOUSE:
|
||||
return StringToV8(isolate, "mouse");
|
||||
case ui::MENU_SOURCE_KEYBOARD:
|
||||
return StringToV8(isolate, "keyboard");
|
||||
case ui::MENU_SOURCE_TOUCH:
|
||||
return StringToV8(isolate, "touch");
|
||||
case ui::MENU_SOURCE_TOUCH_EDIT_MENU:
|
||||
return StringToV8(isolate, "touchMenu");
|
||||
case ui::MENU_SOURCE_LONG_PRESS:
|
||||
return StringToV8(isolate, "longPress");
|
||||
case ui::MENU_SOURCE_LONG_TAP:
|
||||
return StringToV8(isolate, "longTap");
|
||||
case ui::MENU_SOURCE_TOUCH_HANDLE:
|
||||
return StringToV8(isolate, "touchHandle");
|
||||
case ui::MENU_SOURCE_STYLUS:
|
||||
return StringToV8(isolate, "stylus");
|
||||
case ui::MENU_SOURCE_ADJUST_SELECTION:
|
||||
return StringToV8(isolate, "adjustSelection");
|
||||
case ui::MENU_SOURCE_ADJUST_SELECTION_RESET:
|
||||
return StringToV8(isolate, "adjustSelectionReset");
|
||||
case ui::MENU_SOURCE_NONE:
|
||||
return StringToV8(isolate, "none");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// static
|
||||
bool Converter<ui::MenuSourceType>::FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ui::MenuSourceType* out) {
|
||||
std::string type;
|
||||
if (!ConvertFromV8(isolate, val, &type))
|
||||
return false;
|
||||
|
||||
if (type == "mouse") {
|
||||
*out = ui::MENU_SOURCE_MOUSE;
|
||||
return true;
|
||||
} else if (type == "keyboard") {
|
||||
*out = ui::MENU_SOURCE_KEYBOARD;
|
||||
return true;
|
||||
} else if (type == "touch") {
|
||||
*out = ui::MENU_SOURCE_TOUCH;
|
||||
return true;
|
||||
} else if (type == "touchMenu") {
|
||||
*out = ui::MENU_SOURCE_TOUCH_EDIT_MENU;
|
||||
return true;
|
||||
} else if (type == "longPress") {
|
||||
*out = ui::MENU_SOURCE_LONG_PRESS;
|
||||
return true;
|
||||
} else if (type == "longTap") {
|
||||
*out = ui::MENU_SOURCE_LONG_TAP;
|
||||
return true;
|
||||
} else if (type == "touchHandle") {
|
||||
*out = ui::MENU_SOURCE_TOUCH_HANDLE;
|
||||
return true;
|
||||
} else if (type == "stylus") {
|
||||
*out = ui::MENU_SOURCE_STYLUS;
|
||||
return true;
|
||||
} else if (type == "adjustSelection") {
|
||||
*out = ui::MENU_SOURCE_ADJUST_SELECTION;
|
||||
return true;
|
||||
} else if (type == "adjustSelectionReset") {
|
||||
*out = ui::MENU_SOURCE_ADJUST_SELECTION_RESET;
|
||||
return true;
|
||||
} else if (type == "none") {
|
||||
*out = ui::MENU_SOURCE_NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
v8::Local<v8::Value> Converter<blink::mojom::MenuItem::Type>::ToV8(
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "third_party/blink/public/common/permissions/permission_utils.h"
|
||||
#include "third_party/blink/public/mojom/choosers/popup_menu.mojom.h"
|
||||
#include "third_party/blink/public/mojom/permissions/permission_status.mojom.h"
|
||||
#include "ui/base/ui_base_types.h"
|
||||
|
||||
namespace content {
|
||||
struct ContextMenuParams;
|
||||
|
@ -39,6 +40,15 @@ struct Converter<ContextMenuParamsWithRenderFrameHost> {
|
|||
const ContextMenuParamsWithRenderFrameHost& val);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<ui::MenuSourceType> {
|
||||
static v8::Local<v8::Value> ToV8(v8::Isolate* isolate,
|
||||
const ui::MenuSourceType& val);
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
v8::Local<v8::Value> val,
|
||||
ui::MenuSourceType* out);
|
||||
};
|
||||
|
||||
template <>
|
||||
struct Converter<blink::mojom::PermissionStatus> {
|
||||
static bool FromV8(v8::Isolate* isolate,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue