From d3d465b32eb7d5204ad4c81d16fc605d368c3cd9 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Wed, 8 Nov 2023 14:27:50 -0500 Subject: [PATCH] views: Support per-accelerator priority config (fixes #3598) --- include/capi/views/cef_browser_view_capi.h | 22 ++++++++++++++-------- include/capi/views/cef_window_capi.h | 15 ++++++++++++--- include/cef_api_hash.h | 8 ++++---- include/views/cef_browser_view.h | 19 ++++++++++++------- include/views/cef_window.h | 13 +++++++++++-- libcef/browser/views/window_impl.cc | 8 ++++++-- libcef/browser/views/window_impl.h | 3 ++- libcef_dll/cpptoc/views/window_cpptoc.cc | 8 +++++--- libcef_dll/ctocpp/views/window_ctocpp.cc | 7 ++++--- libcef_dll/ctocpp/views/window_ctocpp.h | 5 +++-- tests/cefclient/browser/views_window.cc | 7 +++---- tests/ceftests/views/window_unittest.cc | 2 +- 12 files changed, 77 insertions(+), 40 deletions(-) diff --git a/include/capi/views/cef_browser_view_capi.h b/include/capi/views/cef_browser_view_capi.h index 1e190bf7b..fbc8cbcde 100644 --- a/include/capi/views/cef_browser_view_capi.h +++ b/include/capi/views/cef_browser_view_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=f72e94f6bd63b6ea623c4d3170b5ad4333c136d6$ +// $hash=bc80e7f1e467a4e0943dcbf7ea6d08366817d5ca$ // #ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_BROWSER_VIEW_CAPI_H_ @@ -77,13 +77,19 @@ typedef struct _cef_browser_view_t { struct _cef_browser_view_t* self); /// - /// Sets whether accelerators registered with cef_window_t::SetAccelerator are - /// triggered before or after the event is sent to the cef_browser_t. If - /// |prefer_accelerators| is true (1) then the matching accelerator will be - /// triggered immediately and the event will not be sent to the cef_browser_t. - /// If |prefer_accelerators| is false (0) then the matching accelerator will - /// only be triggered if the event is not handled by web content or by - /// cef_keyboard_handler_t. The default value is false (0). + /// Sets whether normal priority accelerators are first forwarded to the web + /// content (`keydown` event handler) or cef_keyboard_handler_t. Normal + /// priority accelerators can be registered via cef_window_t::SetAccelerator + /// (with |high_priority|=false (0)) or internally for standard accelerators + /// supported by the Chrome runtime. If |prefer_accelerators| is true (1) then + /// the matching accelerator will be triggered immediately (calling + /// cef_window_delegate_t::OnAccelerator or + /// cef_command_handler_t::OnChromeCommand respectively) and the event will + /// not be forwarded to the web content or cef_keyboard_handler_t first. If + /// |prefer_accelerators| is false (0) then the matching accelerator will only + /// be triggered if the event is not handled by web content (`keydown` event + /// handler that calls `event.preventDefault()`) or by cef_keyboard_handler_t. + /// The default value is false (0). /// void(CEF_CALLBACK* set_prefer_accelerators)(struct _cef_browser_view_t* self, int prefer_accelerators); diff --git a/include/capi/views/cef_window_capi.h b/include/capi/views/cef_window_capi.h index e5e04e83e..72aba0038 100644 --- a/include/capi/views/cef_window_capi.h +++ b/include/capi/views/cef_window_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=4b43fe0b493d860e8b28d7a6d892db49d1135b34$ +// $hash=a48904fcd0f6be07e27839922d8feb07271ed2b5$ // #ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_CAPI_H_ @@ -332,16 +332,25 @@ typedef struct _cef_window_t { /// /// Set the keyboard accelerator for the specified |command_id|. |key_code| - /// can be any virtual key or character value. + /// can be any virtual key or character value. Required modifier keys are + /// specified by |shift_pressed|, |ctrl_pressed| and/or |alt_pressed|. /// cef_window_delegate_t::OnAccelerator will be called if the keyboard /// combination is triggered while this window has focus. /// + /// The |high_priority| value will be considered if a child cef_browser_view_t + /// has focus when the keyboard combination is triggered. If |high_priority| + /// is true (1) then the key event will not be forwarded to the web content + /// (`keydown` event handler) or cef_keyboard_handler_t first. If + /// |high_priority| is false (0) then the behavior will depend on the + /// cef_browser_view_t::SetPreferAccelerators configuration. + /// void(CEF_CALLBACK* set_accelerator)(struct _cef_window_t* self, int command_id, int key_code, int shift_pressed, int ctrl_pressed, - int alt_pressed); + int alt_pressed, + int high_priority); /// /// Remove the keyboard accelerator for the specified |command_id|. diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index ef4e12e3e..8b9c86893 100644 --- a/include/cef_api_hash.h +++ b/include/cef_api_hash.h @@ -42,13 +42,13 @@ // way that may cause binary incompatibility with other builds. The universal // hash value will change if any platform is affected whereas the platform hash // values will change only if that particular platform is affected. -#define CEF_API_HASH_UNIVERSAL "b6896cd6fe1f0a43197f649b0e18be1aac6b918d" +#define CEF_API_HASH_UNIVERSAL "c0c754c1ca4f72f6ca6a80861b38b34a61ed5116" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "4d4214adb1bb3cb7a3f8862e9241f2983a0175ca" +#define CEF_API_HASH_PLATFORM "b8db902c4604f9447ece1184f0d4f674503d0655" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "762ec50480531244f53add4b884f535c6b11f4be" +#define CEF_API_HASH_PLATFORM "a01475fc7c5d8bdc91e29add1aae56c7445a4d4b" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "a18434cc9be44f6e1040f03655908d0a0838d3e7" +#define CEF_API_HASH_PLATFORM "75cbf2876ee57cc093f9ab7905e19034754a4b8a" #endif #ifdef __cplusplus diff --git a/include/views/cef_browser_view.h b/include/views/cef_browser_view.h index e8b4218ff..dc7efc24a 100644 --- a/include/views/cef_browser_view.h +++ b/include/views/cef_browser_view.h @@ -92,13 +92,18 @@ class CefBrowserView : public CefView { virtual CefRefPtr GetChromeToolbar() = 0; /// - /// Sets whether accelerators registered with CefWindow::SetAccelerator are - /// triggered before or after the event is sent to the CefBrowser. If - /// |prefer_accelerators| is true then the matching accelerator will be - /// triggered immediately and the event will not be sent to the CefBrowser. If - /// |prefer_accelerators| is false then the matching accelerator will only be - /// triggered if the event is not handled by web content or by - /// CefKeyboardHandler. The default value is false. + /// Sets whether normal priority accelerators are first forwarded to the web + /// content (`keydown` event handler) or CefKeyboardHandler. Normal priority + /// accelerators can be registered via CefWindow::SetAccelerator (with + /// |high_priority|=false) or internally for standard accelerators supported + /// by the Chrome runtime. If |prefer_accelerators| is true then the matching + /// accelerator will be triggered immediately (calling + /// CefWindowDelegate::OnAccelerator or CefCommandHandler::OnChromeCommand + /// respectively) and the event will not be forwarded to the web content or + /// CefKeyboardHandler first. If |prefer_accelerators| is false then the + /// matching accelerator will only be triggered if the event is not handled by + /// web content (`keydown` event handler that calls `event.preventDefault()`) + /// or by CefKeyboardHandler. The default value is false. /// /*--cef()--*/ virtual void SetPreferAccelerators(bool prefer_accelerators) = 0; diff --git a/include/views/cef_window.h b/include/views/cef_window.h index ec3843b25..80a522e52 100644 --- a/include/views/cef_window.h +++ b/include/views/cef_window.h @@ -344,16 +344,25 @@ class CefWindow : public CefPanel { /// /// Set the keyboard accelerator for the specified |command_id|. |key_code| - /// can be any virtual key or character value. + /// can be any virtual key or character value. Required modifier keys are + /// specified by |shift_pressed|, |ctrl_pressed| and/or |alt_pressed|. /// CefWindowDelegate::OnAccelerator will be called if the keyboard /// combination is triggered while this window has focus. /// + /// The |high_priority| value will be considered if a child CefBrowserView has + /// focus when the keyboard combination is triggered. If |high_priority| is + /// true then the key event will not be forwarded to the web content + /// (`keydown` event handler) or CefKeyboardHandler first. If |high_priority| + /// is false then the behavior will depend on the + /// CefBrowserView::SetPreferAccelerators configuration. + /// /*--cef()--*/ virtual void SetAccelerator(int command_id, int key_code, bool shift_pressed, bool ctrl_pressed, - bool alt_pressed) = 0; + bool alt_pressed, + bool high_priority) = 0; /// /// Remove the keyboard accelerator for the specified |command_id|. diff --git a/libcef/browser/views/window_impl.cc b/libcef/browser/views/window_impl.cc index 3da94b08a..da73c8ad4 100644 --- a/libcef/browser/views/window_impl.cc +++ b/libcef/browser/views/window_impl.cc @@ -669,7 +669,8 @@ void CefWindowImpl::SetAccelerator(int command_id, int key_code, bool shift_pressed, bool ctrl_pressed, - bool alt_pressed) { + bool alt_pressed, + bool high_priority) { CEF_REQUIRE_VALID_RETURN_VOID(); if (!widget_) { return; @@ -698,7 +699,10 @@ void CefWindowImpl::SetAccelerator(int command_id, views::FocusManager* focus_manager = widget_->GetFocusManager(); DCHECK(focus_manager); focus_manager->RegisterAccelerator( - accelerator, ui::AcceleratorManager::kNormalPriority, this); + accelerator, + high_priority ? ui::AcceleratorManager::kHighPriority + : ui::AcceleratorManager::kNormalPriority, + this); } void CefWindowImpl::RemoveAccelerator(int command_id) { diff --git a/libcef/browser/views/window_impl.h b/libcef/browser/views/window_impl.h index fae0ae832..6b137d1a8 100644 --- a/libcef/browser/views/window_impl.h +++ b/libcef/browser/views/window_impl.h @@ -86,7 +86,8 @@ class CefWindowImpl int key_code, bool shift_pressed, bool ctrl_pressed, - bool alt_pressed) override; + bool alt_pressed, + bool high_priority) override; void RemoveAccelerator(int command_id) override; void RemoveAllAccelerators() override; diff --git a/libcef_dll/cpptoc/views/window_cpptoc.cc b/libcef_dll/cpptoc/views/window_cpptoc.cc index 93ee5341f..e901863a4 100644 --- a/libcef_dll/cpptoc/views/window_cpptoc.cc +++ b/libcef_dll/cpptoc/views/window_cpptoc.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=23777aea864e9abf38c2e2c5d79a40d6bd22876d$ +// $hash=38a50bca35881beb6400f3ad5d81b0a5ec86331d$ // #include "libcef_dll/cpptoc/views/window_cpptoc.h" @@ -672,7 +672,8 @@ void CEF_CALLBACK window_set_accelerator(struct _cef_window_t* self, int key_code, int shift_pressed, int ctrl_pressed, - int alt_pressed) { + int alt_pressed, + int high_priority) { shutdown_checker::AssertNotShutdown(); // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -685,7 +686,8 @@ void CEF_CALLBACK window_set_accelerator(struct _cef_window_t* self, // Execute CefWindowCppToC::Get(self)->SetAccelerator( command_id, key_code, shift_pressed ? true : false, - ctrl_pressed ? true : false, alt_pressed ? true : false); + ctrl_pressed ? true : false, alt_pressed ? true : false, + high_priority ? true : false); } void CEF_CALLBACK window_remove_accelerator(struct _cef_window_t* self, diff --git a/libcef_dll/ctocpp/views/window_ctocpp.cc b/libcef_dll/ctocpp/views/window_ctocpp.cc index 3a0423d28..66ca9db5a 100644 --- a/libcef_dll/ctocpp/views/window_ctocpp.cc +++ b/libcef_dll/ctocpp/views/window_ctocpp.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=b6b0a2a563b475163aa71b20af6ec2ac8c1f0cae$ +// $hash=c8f164d20875c8071837c04abb44e09672d894af$ // #include "libcef_dll/ctocpp/views/window_ctocpp.h" @@ -663,7 +663,8 @@ void CefWindowCToCpp::SetAccelerator(int command_id, int key_code, bool shift_pressed, bool ctrl_pressed, - bool alt_pressed) { + bool alt_pressed, + bool high_priority) { shutdown_checker::AssertNotShutdown(); cef_window_t* _struct = GetStruct(); @@ -675,7 +676,7 @@ void CefWindowCToCpp::SetAccelerator(int command_id, // Execute _struct->set_accelerator(_struct, command_id, key_code, shift_pressed, - ctrl_pressed, alt_pressed); + ctrl_pressed, alt_pressed, high_priority); } NO_SANITIZE("cfi-icall") diff --git a/libcef_dll/ctocpp/views/window_ctocpp.h b/libcef_dll/ctocpp/views/window_ctocpp.h index bc797350c..97f0ffe1f 100644 --- a/libcef_dll/ctocpp/views/window_ctocpp.h +++ b/libcef_dll/ctocpp/views/window_ctocpp.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=2a7aaed7d4296e29dca74345cf2b2d4db221a738$ +// $hash=d0c31c38bf29c9b44f645e69a912b6b8a4030066$ // #ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_CTOCPP_H_ @@ -83,7 +83,8 @@ class CefWindowCToCpp int key_code, bool shift_pressed, bool ctrl_pressed, - bool alt_pressed) override; + bool alt_pressed, + bool high_priority) override; void RemoveAccelerator(int command_id) override; void RemoveAllAccelerators() override; diff --git a/tests/cefclient/browser/views_window.cc b/tests/cefclient/browser/views_window.cc index 11d43e9e4..da59962b1 100644 --- a/tests/cefclient/browser/views_window.cc +++ b/tests/cefclient/browser/views_window.cc @@ -1283,12 +1283,11 @@ void ViewsWindow::AddControls() { } void ViewsWindow::AddAccelerators() { - // Trigger accelerators without first forwarding to web content. - browser_view_->SetPreferAccelerators(true); - // Specify the accelerators to handle. OnAccelerator will be called when the // accelerator is triggered. - window_->SetAccelerator(ID_QUIT, 'X', false, false, true); + window_->SetAccelerator(ID_QUIT, 'X', /*shift_pressed=*/false, + /*ctrl_pressed=*/false, /*alt_pressed=*/true, + /*high_priority=*/true); } void ViewsWindow::SetMenuFocusable(bool focusable) { diff --git a/tests/ceftests/views/window_unittest.cc b/tests/ceftests/views/window_unittest.cc index aa00d1f00..75b267ce6 100644 --- a/tests/ceftests/views/window_unittest.cc +++ b/tests/ceftests/views/window_unittest.cc @@ -562,7 +562,7 @@ bool OnAccelerator(CefRefPtr window, int command_id) { } void RunWindowAccelerator(CefRefPtr window) { - window->SetAccelerator(kCloseWindowId, kChar, false, false, true); + window->SetAccelerator(kCloseWindowId, kChar, false, false, true, false); window->Show(); CefPostDelayedTask(TID_UI, base::BindOnce(TriggerAccelerator, window),