diff --git a/BUILD.gn b/BUILD.gn index acc131e58..175c3cd05 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1340,7 +1340,6 @@ grit("cef_resources") { template("make_pack_header") { assert(defined(invoker.header)) assert(defined(invoker.inputs)) - assert(defined(invoker.deps)) action("make_pack_header_${target_name}") { script = "tools/make_pack_header.py" @@ -1351,7 +1350,9 @@ template("make_pack_header") { args = rebase_path(outputs, root_build_dir) + rebase_path(inputs, root_build_dir) - deps = invoker.deps + if (defined(invoker.deps)) { + deps = invoker.deps + } } } @@ -1456,6 +1457,14 @@ make_pack_header("strings") { ] } +# Generate cef_command_ids.h. +make_pack_header("command_ids") { + header = "$root_out_dir/includes/include/cef_command_ids.h" + inputs = [ + "//chrome/app/chrome_command_ids.h", + ] +} + # Generate cef_api_hash.h. action("make_api_hash_header") { script = "tools/make_api_hash_header.py" @@ -1487,6 +1496,7 @@ group("cef_make_headers") { deps = [ ":make_pack_header_resources", ":make_pack_header_strings", + ":make_pack_header_command_ids", ":make_api_hash_header", ":make_config_header", ] diff --git a/cef_paths.gypi b/cef_paths.gypi index f3d2a9d14..d234f1154 100644 --- a/cef_paths.gypi +++ b/cef_paths.gypi @@ -8,7 +8,7 @@ # by hand. See the translator.README.txt file in the tools directory for # more information. # -# $hash=3d75809bdc9a72a0df9df727981f0796b7ddbbc8$ +# $hash=5f2e9bf79ec768c0eb978ff5e1dd0178701dcc21$ # { @@ -22,6 +22,7 @@ 'include/cef_browser_process_handler.h', 'include/cef_callback.h', 'include/cef_client.h', + 'include/cef_command_handler.h', 'include/cef_command_line.h', 'include/cef_context_menu_handler.h', 'include/cef_cookie.h', @@ -120,6 +121,7 @@ 'include/capi/cef_browser_process_handler_capi.h', 'include/capi/cef_callback_capi.h', 'include/capi/cef_client_capi.h', + 'include/capi/cef_command_handler_capi.h', 'include/capi/cef_command_line_capi.h', 'include/capi/cef_context_menu_handler_capi.h', 'include/capi/cef_cookie_capi.h', @@ -242,6 +244,8 @@ 'libcef_dll/cpptoc/callback_cpptoc.h', 'libcef_dll/ctocpp/client_ctocpp.cc', 'libcef_dll/ctocpp/client_ctocpp.h', + 'libcef_dll/ctocpp/command_handler_ctocpp.cc', + 'libcef_dll/ctocpp/command_handler_ctocpp.h', 'libcef_dll/cpptoc/command_line_cpptoc.cc', 'libcef_dll/cpptoc/command_line_cpptoc.h', 'libcef_dll/ctocpp/completion_callback_ctocpp.cc', @@ -546,6 +550,8 @@ 'libcef_dll/ctocpp/callback_ctocpp.h', 'libcef_dll/cpptoc/client_cpptoc.cc', 'libcef_dll/cpptoc/client_cpptoc.h', + 'libcef_dll/cpptoc/command_handler_cpptoc.cc', + 'libcef_dll/cpptoc/command_handler_cpptoc.h', 'libcef_dll/ctocpp/command_line_ctocpp.cc', 'libcef_dll/ctocpp/command_line_ctocpp.h', 'libcef_dll/cpptoc/completion_callback_cpptoc.cc', diff --git a/include/capi/cef_client_capi.h b/include/capi/cef_client_capi.h index 30143a212..9f996da2c 100644 --- a/include/capi/cef_client_capi.h +++ b/include/capi/cef_client_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=8b099ca3b9cfbd41840cdf64586a0b884abaffae$ +// $hash=7df3c13b75072c2ad5061cd3a344811222798903$ // #ifndef CEF_INCLUDE_CAPI_CEF_CLIENT_CAPI_H_ @@ -42,6 +42,7 @@ #include "include/capi/cef_audio_handler_capi.h" #include "include/capi/cef_base_capi.h" +#include "include/capi/cef_command_handler_capi.h" #include "include/capi/cef_context_menu_handler_capi.h" #include "include/capi/cef_dialog_handler_capi.h" #include "include/capi/cef_display_handler_capi.h" @@ -78,6 +79,13 @@ typedef struct _cef_client_t { struct _cef_audio_handler_t*(CEF_CALLBACK* get_audio_handler)( struct _cef_client_t* self); + /// + // Return the handler for commands. If no handler is provided the default + // implementation will be used. + /// + struct _cef_command_handler_t*(CEF_CALLBACK* get_command_handler)( + struct _cef_client_t* self); + /// // Return the handler for context menus. If no handler is provided the default // implementation will be used. diff --git a/include/capi/cef_command_handler_capi.h b/include/capi/cef_command_handler_capi.h new file mode 100644 index 000000000..f58faf30d --- /dev/null +++ b/include/capi/cef_command_handler_capi.h @@ -0,0 +1,80 @@ +// Copyright (c) 2022 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool and should not edited +// by hand. See the translator.README.txt file in the tools directory for +// more information. +// +// $hash=54332b79c057df9c8f3be56cc77f1daf877b3ac1$ +// + +#ifndef CEF_INCLUDE_CAPI_CEF_COMMAND_HANDLER_CAPI_H_ +#define CEF_INCLUDE_CAPI_CEF_COMMAND_HANDLER_CAPI_H_ +#pragma once + +#include "include/capi/cef_base_capi.h" +#include "include/capi/cef_browser_capi.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// +// Implement this structure to handle events related to commands. The functions +// of this structure will be called on the UI thread. +/// +typedef struct _cef_command_handler_t { + /// + // Base structure. + /// + cef_base_ref_counted_t base; + + /// + // Called to execute a Chrome command triggered via menu selection or keyboard + // shortcut. Values for |command_id| can be found in the cef_command_ids.h + // file. |disposition| provides information about the intended command target. + // Return true (1) if the command was handled or false (0) for the default + // implementation. For context menu commands this will be called after + // cef_context_menu_handler_t::OnContextMenuCommand. Only used with the Chrome + // runtime. + /// + int(CEF_CALLBACK* on_chrome_command)( + struct _cef_command_handler_t* self, + struct _cef_browser_t* browser, + int command_id, + cef_window_open_disposition_t disposition); +} cef_command_handler_t; + +#ifdef __cplusplus +} +#endif + +#endif // CEF_INCLUDE_CAPI_CEF_COMMAND_HANDLER_CAPI_H_ diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 7adb5095e..78786363e 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 "5065a3791a6b09aac128efd3131b77ac38a4257a" +#define CEF_API_HASH_UNIVERSAL "099de505181a68d5b53885e57d91ae0276259bfa" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "6402341997737ba956460d92af756a3b9e59d0f0" +#define CEF_API_HASH_PLATFORM "0887a2a4ef42c8e2e33aba6662d2891f020e810a" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "cd4c53d8024e52d2041de8a49db69c69edd8e62b" +#define CEF_API_HASH_PLATFORM "3d220485ac3df3a74e15db819ea16c98f78116ae" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "bd498b3ef328a60a11eae6871a13b7c517e583f1" +#define CEF_API_HASH_PLATFORM "ee08ceb06c69dac1ac16361daabe3378c9d2d621" #endif #ifdef __cplusplus diff --git a/include/cef_client.h b/include/cef_client.h index bf485e929..06266a577 100644 --- a/include/cef_client.h +++ b/include/cef_client.h @@ -40,6 +40,7 @@ #include "include/cef_audio_handler.h" #include "include/cef_base.h" +#include "include/cef_command_handler.h" #include "include/cef_context_menu_handler.h" #include "include/cef_dialog_handler.h" #include "include/cef_display_handler.h" @@ -69,6 +70,13 @@ class CefClient : public virtual CefBaseRefCounted { /*--cef()--*/ virtual CefRefPtr GetAudioHandler() { return nullptr; } + /// + // Return the handler for commands. If no handler is provided the default + // implementation will be used. + /// + /*--cef()--*/ + virtual CefRefPtr GetCommandHandler() { return nullptr; } + /// // Return the handler for context menus. If no handler is provided the default // implementation will be used. diff --git a/include/cef_command_handler.h b/include/cef_command_handler.h new file mode 100644 index 000000000..1120d2e8c --- /dev/null +++ b/include/cef_command_handler.h @@ -0,0 +1,68 @@ +// Copyright (c) 2022 Marshall A. Greenblatt. All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the name Chromium Embedded +// Framework nor the names of its contributors may be used to endorse +// or promote products derived from this software without specific prior +// written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// --------------------------------------------------------------------------- +// +// The contents of this file must follow a specific format in order to +// support the CEF translator tool. See the translator.README.txt file in the +// tools directory for more information. +// + +#ifndef CEF_INCLUDE_CEF_COMMAND_HANDLER_H_ +#define CEF_INCLUDE_CEF_COMMAND_HANDLER_H_ +#pragma once + +#include "include/cef_base.h" +#include "include/cef_browser.h" + +/// +// Implement this interface to handle events related to commands. The methods of +// this class will be called on the UI thread. +/// +/*--cef(source=client)--*/ +class CefCommandHandler : public virtual CefBaseRefCounted { + public: + /// + // Called to execute a Chrome command triggered via menu selection or keyboard + // shortcut. Values for |command_id| can be found in the cef_command_ids.h + // file. |disposition| provides information about the intended command target. + // Return true if the command was handled or false for the default + // implementation. For context menu commands this will be called after + // CefContextMenuHandler::OnContextMenuCommand. Only used with the Chrome + // runtime. + /// + /*--cef()--*/ + virtual bool OnChromeCommand(CefRefPtr browser, + int command_id, + cef_window_open_disposition_t disposition) { + return false; + } +}; + +#endif // CEF_INCLUDE_CEF_COMMAND_HANDLER_H_ diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 7a3b68692..6e435a2a7 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -955,15 +955,66 @@ typedef enum { /// typedef enum { WOD_UNKNOWN, + + /// + // Current tab. This is the default in most cases. + /// WOD_CURRENT_TAB, + + /// + // Indicates that only one tab with the url should exist in the same window. + /// WOD_SINGLETON_TAB, + + /// + // Shift key + Middle mouse button or meta/ctrl key while clicking. + /// WOD_NEW_FOREGROUND_TAB, + + /// + // Middle mouse button or meta/ctrl key while clicking. + /// WOD_NEW_BACKGROUND_TAB, + + /// + // New popup window. + /// WOD_NEW_POPUP, + + /// + // Shift key while clicking. + /// WOD_NEW_WINDOW, + + /// + // Alt key while clicking. + /// WOD_SAVE_TO_DISK, + + /// + // New off-the-record (incognito) window. + /// WOD_OFF_THE_RECORD, - WOD_IGNORE_ACTION + + /// + // Special case error condition from the renderer. + /// + WOD_IGNORE_ACTION, + + /// + // Activates an existing tab containing the url, rather than navigating. + // This is similar to SINGLETON_TAB, but searches across all windows from + // the current profile and anonymity (instead of just the current one); + // closes the current tab on switching if the current tab was the NTP with + // no session history; and behaves like CURRENT_TAB instead of + // NEW_FOREGROUND_TAB when no existing tab is found. + /// + WOD_SWITCH_TO_TAB, + + /// + // Creates a new document picture-in-picture window showing a child WebView. + /// + WOD_NEW_PICTURE_IN_PICTURE, } cef_window_open_disposition_t; /// diff --git a/libcef/browser/chrome/browser_delegate.h b/libcef/browser/chrome/browser_delegate.h index 5f738b390..4aa4abde8 100644 --- a/libcef/browser/chrome/browser_delegate.h +++ b/libcef/browser/chrome/browser_delegate.h @@ -10,6 +10,7 @@ #include "base/memory/scoped_refptr.h" #include "content/public/browser/web_contents_delegate.h" +#include "ui/base/window_open_disposition.h" class Browser; @@ -47,6 +48,13 @@ class BrowserDelegate : public content::WebContentsDelegate { virtual bool ShowStatusBubble(bool show_by_default) { return show_by_default; } + + // Return true to handle (or disable) a command. ID values come from + // chrome/app/chrome_command_ids.h. + virtual bool HandleCommand(int command_id, + WindowOpenDisposition disposition) { + return false; + } }; } // namespace cef diff --git a/libcef/browser/chrome/chrome_browser_delegate.cc b/libcef/browser/chrome/chrome_browser_delegate.cc index bd3406446..2b60ba3b4 100644 --- a/libcef/browser/chrome/chrome_browser_delegate.cc +++ b/libcef/browser/chrome/chrome_browser_delegate.cc @@ -88,6 +88,20 @@ bool ChromeBrowserDelegate::ShowStatusBubble(bool show_by_default) { return *show_status_bubble_; } +bool ChromeBrowserDelegate::HandleCommand(int command_id, + WindowOpenDisposition disposition) { + if (auto browser = ChromeBrowserHostImpl::GetBrowserForBrowser(browser_)) { + if (auto client = browser->GetClient()) { + if (auto handler = client->GetCommandHandler()) { + return handler->OnChromeCommand( + browser.get(), command_id, + static_cast(disposition)); + } + } + } + return false; +} + void ChromeBrowserDelegate::WebContentsCreated( content::WebContents* source_contents, int opener_render_process_id, diff --git a/libcef/browser/chrome/chrome_browser_delegate.h b/libcef/browser/chrome/chrome_browser_delegate.h index 25a450174..560ad01ae 100644 --- a/libcef/browser/chrome/chrome_browser_delegate.h +++ b/libcef/browser/chrome/chrome_browser_delegate.h @@ -52,6 +52,8 @@ class ChromeBrowserDelegate : public cef::BrowserDelegate { void SetAsDelegate(content::WebContents* web_contents, bool set_delegate) override; bool ShowStatusBubble(bool show_by_default) override; + bool HandleCommand(int command_id, + WindowOpenDisposition disposition) override; // WebContentsDelegate methods: void WebContentsCreated(content::WebContents* source_contents, diff --git a/libcef_dll/cpptoc/client_cpptoc.cc b/libcef_dll/cpptoc/client_cpptoc.cc index aae3c916f..919370adb 100644 --- a/libcef_dll/cpptoc/client_cpptoc.cc +++ b/libcef_dll/cpptoc/client_cpptoc.cc @@ -9,11 +9,12 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=5c9e95dca457958e3b49c85b9fd39b36bf555d4e$ +// $hash=b299c22d4f97022efefefeb17a7848b0b44d4af3$ // #include "libcef_dll/cpptoc/client_cpptoc.h" #include "libcef_dll/cpptoc/audio_handler_cpptoc.h" +#include "libcef_dll/cpptoc/command_handler_cpptoc.h" #include "libcef_dll/cpptoc/context_menu_handler_cpptoc.h" #include "libcef_dll/cpptoc/dialog_handler_cpptoc.h" #include "libcef_dll/cpptoc/display_handler_cpptoc.h" @@ -53,6 +54,22 @@ client_get_audio_handler(struct _cef_client_t* self) { return CefAudioHandlerCppToC::Wrap(_retval); } +struct _cef_command_handler_t* CEF_CALLBACK +client_get_command_handler(struct _cef_client_t* self) { + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return NULL; + + // Execute + CefRefPtr _retval = + CefClientCppToC::Get(self)->GetCommandHandler(); + + // Return type: refptr_same + return CefCommandHandlerCppToC::Wrap(_retval); +} + struct _cef_context_menu_handler_t* CEF_CALLBACK client_get_context_menu_handler(struct _cef_client_t* self) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -332,6 +349,7 @@ client_on_process_message_received(struct _cef_client_t* self, CefClientCppToC::CefClientCppToC() { GetStruct()->get_audio_handler = client_get_audio_handler; + GetStruct()->get_command_handler = client_get_command_handler; GetStruct()->get_context_menu_handler = client_get_context_menu_handler; GetStruct()->get_dialog_handler = client_get_dialog_handler; GetStruct()->get_display_handler = client_get_display_handler; diff --git a/libcef_dll/cpptoc/command_handler_cpptoc.cc b/libcef_dll/cpptoc/command_handler_cpptoc.cc new file mode 100644 index 000000000..d737db382 --- /dev/null +++ b/libcef_dll/cpptoc/command_handler_cpptoc.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=929bc6804bc4beb1601ee44f3300a42ecc917c74$ +// + +#include "libcef_dll/cpptoc/command_handler_cpptoc.h" +#include "libcef_dll/ctocpp/browser_ctocpp.h" +#include "libcef_dll/shutdown_checker.h" + +namespace { + +// MEMBER FUNCTIONS - Body may be edited by hand. + +int CEF_CALLBACK +command_handler_on_chrome_command(struct _cef_command_handler_t* self, + cef_browser_t* browser, + int command_id, + cef_window_open_disposition_t disposition) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) + return 0; + // Verify param: browser; type: refptr_diff + DCHECK(browser); + if (!browser) + return 0; + + // Execute + bool _retval = CefCommandHandlerCppToC::Get(self)->OnChromeCommand( + CefBrowserCToCpp::Wrap(browser), command_id, disposition); + + // Return type: bool + return _retval; +} + +} // namespace + +// CONSTRUCTOR - Do not edit by hand. + +CefCommandHandlerCppToC::CefCommandHandlerCppToC() { + GetStruct()->on_chrome_command = command_handler_on_chrome_command; +} + +// DESTRUCTOR - Do not edit by hand. + +CefCommandHandlerCppToC::~CefCommandHandlerCppToC() { + shutdown_checker::AssertNotShutdown(); +} + +template <> +CefRefPtr CefCppToCRefCounted< + CefCommandHandlerCppToC, + CefCommandHandler, + cef_command_handler_t>::UnwrapDerived(CefWrapperType type, + cef_command_handler_t* s) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCppToCRefCounted::kWrapperType = + WT_COMMAND_HANDLER; diff --git a/libcef_dll/cpptoc/command_handler_cpptoc.h b/libcef_dll/cpptoc/command_handler_cpptoc.h new file mode 100644 index 000000000..2242427d2 --- /dev/null +++ b/libcef_dll/cpptoc/command_handler_cpptoc.h @@ -0,0 +1,38 @@ +// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=85e5de7b82a22ab4738de3a6a2bb141eb5c79579$ +// + +#ifndef CEF_LIBCEF_DLL_CPPTOC_COMMAND_HANDLER_CPPTOC_H_ +#define CEF_LIBCEF_DLL_CPPTOC_COMMAND_HANDLER_CPPTOC_H_ +#pragma once + +#if !defined(WRAPPING_CEF_SHARED) +#error This file can be included wrapper-side only +#endif + +#include "include/capi/cef_command_handler_capi.h" +#include "include/cef_command_handler.h" +#include "libcef_dll/cpptoc/cpptoc_ref_counted.h" + +// Wrap a C++ class with a C structure. +// This class may be instantiated and accessed wrapper-side only. +class CefCommandHandlerCppToC + : public CefCppToCRefCounted { + public: + CefCommandHandlerCppToC(); + virtual ~CefCommandHandlerCppToC(); +}; + +#endif // CEF_LIBCEF_DLL_CPPTOC_COMMAND_HANDLER_CPPTOC_H_ diff --git a/libcef_dll/ctocpp/client_ctocpp.cc b/libcef_dll/ctocpp/client_ctocpp.cc index 3ba40c3a5..84e7d9f62 100644 --- a/libcef_dll/ctocpp/client_ctocpp.cc +++ b/libcef_dll/ctocpp/client_ctocpp.cc @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=f31f5010a3c5c4624b93d994b6fce1e795eeac93$ +// $hash=8e158f3ea54211b95f0b716b1eeec2ff475f1245$ // #include "libcef_dll/ctocpp/client_ctocpp.h" @@ -17,6 +17,7 @@ #include "libcef_dll/cpptoc/frame_cpptoc.h" #include "libcef_dll/cpptoc/process_message_cpptoc.h" #include "libcef_dll/ctocpp/audio_handler_ctocpp.h" +#include "libcef_dll/ctocpp/command_handler_ctocpp.h" #include "libcef_dll/ctocpp/context_menu_handler_ctocpp.h" #include "libcef_dll/ctocpp/dialog_handler_ctocpp.h" #include "libcef_dll/ctocpp/display_handler_ctocpp.h" @@ -50,6 +51,21 @@ CefRefPtr CefClientCToCpp::GetAudioHandler() { return CefAudioHandlerCToCpp::Wrap(_retval); } +NO_SANITIZE("cfi-icall") +CefRefPtr CefClientCToCpp::GetCommandHandler() { + cef_client_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_command_handler)) + return nullptr; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Execute + cef_command_handler_t* _retval = _struct->get_command_handler(_struct); + + // Return type: refptr_same + return CefCommandHandlerCToCpp::Wrap(_retval); +} + NO_SANITIZE("cfi-icall") CefRefPtr CefClientCToCpp::GetContextMenuHandler() { cef_client_t* _struct = GetStruct(); diff --git a/libcef_dll/ctocpp/client_ctocpp.h b/libcef_dll/ctocpp/client_ctocpp.h index 6ce9fd3db..8513fc32f 100644 --- a/libcef_dll/ctocpp/client_ctocpp.h +++ b/libcef_dll/ctocpp/client_ctocpp.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=c4370b0b3a14c9739b5a639eda06c286f6981e10$ +// $hash=69f82ee575779deaf1d3581dbedcf8aa75f35710$ // #ifndef CEF_LIBCEF_DLL_CTOCPP_CLIENT_CTOCPP_H_ @@ -34,6 +34,7 @@ class CefClientCToCpp // CefClient methods. CefRefPtr GetAudioHandler() override; + CefRefPtr GetCommandHandler() override; CefRefPtr GetContextMenuHandler() override; CefRefPtr GetDialogHandler() override; CefRefPtr GetDisplayHandler() override; diff --git a/libcef_dll/ctocpp/command_handler_ctocpp.cc b/libcef_dll/ctocpp/command_handler_ctocpp.cc new file mode 100644 index 000000000..3e04344f2 --- /dev/null +++ b/libcef_dll/ctocpp/command_handler_ctocpp.cc @@ -0,0 +1,71 @@ +// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=431d97965f00a504f09790fd524ee23f69f16a82$ +// + +#include "libcef_dll/ctocpp/command_handler_ctocpp.h" +#include "libcef_dll/cpptoc/browser_cpptoc.h" +#include "libcef_dll/shutdown_checker.h" + +// VIRTUAL METHODS - Body may be edited by hand. + +NO_SANITIZE("cfi-icall") +bool CefCommandHandlerCToCpp::OnChromeCommand( + CefRefPtr browser, + int command_id, + cef_window_open_disposition_t disposition) { + shutdown_checker::AssertNotShutdown(); + + cef_command_handler_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, on_chrome_command)) + return false; + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: browser; type: refptr_diff + DCHECK(browser.get()); + if (!browser.get()) + return false; + + // Execute + int _retval = _struct->on_chrome_command( + _struct, CefBrowserCppToC::Wrap(browser), command_id, disposition); + + // Return type: bool + return _retval ? true : false; +} + +// CONSTRUCTOR - Do not edit by hand. + +CefCommandHandlerCToCpp::CefCommandHandlerCToCpp() {} + +// DESTRUCTOR - Do not edit by hand. + +CefCommandHandlerCToCpp::~CefCommandHandlerCToCpp() { + shutdown_checker::AssertNotShutdown(); +} + +template <> +cef_command_handler_t* CefCToCppRefCounted< + CefCommandHandlerCToCpp, + CefCommandHandler, + cef_command_handler_t>::UnwrapDerived(CefWrapperType type, + CefCommandHandler* c) { + NOTREACHED() << "Unexpected class type: " << type; + return nullptr; +} + +template <> +CefWrapperType CefCToCppRefCounted::kWrapperType = + WT_COMMAND_HANDLER; diff --git a/libcef_dll/ctocpp/command_handler_ctocpp.h b/libcef_dll/ctocpp/command_handler_ctocpp.h new file mode 100644 index 000000000..2b5f90afd --- /dev/null +++ b/libcef_dll/ctocpp/command_handler_ctocpp.h @@ -0,0 +1,43 @@ +// Copyright (c) 2022 The Chromium Embedded Framework Authors. All rights +// reserved. Use of this source code is governed by a BSD-style license that +// can be found in the LICENSE file. +// +// --------------------------------------------------------------------------- +// +// This file was generated by the CEF translator tool. If making changes by +// hand only do so within the body of existing method and function +// implementations. See the translator.README.txt file in the tools directory +// for more information. +// +// $hash=986b761d9c3bca7980b4144bb0802a9eafff9e0e$ +// + +#ifndef CEF_LIBCEF_DLL_CTOCPP_COMMAND_HANDLER_CTOCPP_H_ +#define CEF_LIBCEF_DLL_CTOCPP_COMMAND_HANDLER_CTOCPP_H_ +#pragma once + +#if !defined(BUILDING_CEF_SHARED) +#error This file can be included DLL-side only +#endif + +#include "include/capi/cef_command_handler_capi.h" +#include "include/cef_command_handler.h" +#include "libcef_dll/ctocpp/ctocpp_ref_counted.h" + +// Wrap a C structure with a C++ class. +// This class may be instantiated and accessed DLL-side only. +class CefCommandHandlerCToCpp + : public CefCToCppRefCounted { + public: + CefCommandHandlerCToCpp(); + virtual ~CefCommandHandlerCToCpp(); + + // CefCommandHandler methods. + bool OnChromeCommand(CefRefPtr browser, + int command_id, + cef_window_open_disposition_t disposition) override; +}; + +#endif // CEF_LIBCEF_DLL_CTOCPP_COMMAND_HANDLER_CTOCPP_H_ diff --git a/libcef_dll/wrapper_types.h b/libcef_dll/wrapper_types.h index c28d05a5e..4caaae615 100644 --- a/libcef_dll/wrapper_types.h +++ b/libcef_dll/wrapper_types.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=4e961a86c94ee512e3c282c0b620e35992bf862b$ +// $hash=7a247cc26167ddbc4fbe23ed939fa9e39c48a09c$ // #ifndef CEF_LIBCEF_DLL_WRAPPER_TYPES_H_ @@ -35,6 +35,7 @@ enum CefWrapperType { WT_BUTTON_DELEGATE, WT_CALLBACK, WT_CLIENT, + WT_COMMAND_HANDLER, WT_COMMAND_LINE, WT_COMPLETION_CALLBACK, WT_CONTEXT_MENU_HANDLER, diff --git a/patch/patches/chrome_runtime_views.patch b/patch/patches/chrome_runtime_views.patch index c3220f8ea..c6e899248 100644 --- a/patch/patches/chrome_runtime_views.patch +++ b/patch/patches/chrome_runtime_views.patch @@ -1,5 +1,5 @@ diff --git chrome/browser/ui/browser_command_controller.cc chrome/browser/ui/browser_command_controller.cc -index cff1df2490bb6..9d156bd9993fa 100644 +index cff1df2490bb6..864a03a2e29c9 100644 --- chrome/browser/ui/browser_command_controller.cc +++ chrome/browser/ui/browser_command_controller.cc @@ -371,8 +371,10 @@ bool BrowserCommandController::ExecuteCommandWithDisposition( @@ -14,7 +14,21 @@ index cff1df2490bb6..9d156bd9993fa 100644 // No commands are enabled if there is not yet any selected tab. // TODO(pkasting): It seems like we should not need this, because either -@@ -985,11 +987,13 @@ void BrowserCommandController::TabRestoreServiceLoaded( +@@ -387,6 +389,13 @@ bool BrowserCommandController::ExecuteCommandWithDisposition( + DCHECK(command_updater_.IsCommandEnabled(id)) + << "Invalid/disabled command " << id; + ++#if BUILDFLAG(ENABLE_CEF) ++ if (browser_->cef_delegate() && ++ browser_->cef_delegate()->HandleCommand(id, disposition)) { ++ return true; ++ } ++#endif ++ + // The order of commands in this switch statement must match the function + // declaration order in browser.h! + switch (id) { +@@ -985,11 +994,13 @@ void BrowserCommandController::TabRestoreServiceLoaded( // BrowserCommandController, private: bool BrowserCommandController::IsShowingMainUI() { diff --git a/tests/cefclient/browser/browser_window_osr_gtk.cc b/tests/cefclient/browser/browser_window_osr_gtk.cc index 78585a56b..155f7b72c 100644 --- a/tests/cefclient/browser/browser_window_osr_gtk.cc +++ b/tests/cefclient/browser/browser_window_osr_gtk.cc @@ -934,6 +934,7 @@ class ScopedGLContext { } // namespace BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate, + bool with_controls, const std::string& startup_url, const OsrRendererSettings& settings) : BrowserWindow(delegate), @@ -951,7 +952,8 @@ BrowserWindowOsrGtk::BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate, drag_leave_(false), drag_drop_(false), device_scale_factor_(1.0f) { - client_handler_ = new ClientHandlerOsr(this, this, startup_url); + client_handler_ = + new ClientHandlerOsr(this, this, with_controls, startup_url); g_browser_windows.push_back(this); } diff --git a/tests/cefclient/browser/browser_window_osr_gtk.h b/tests/cefclient/browser/browser_window_osr_gtk.h index 7802516d8..18bd38059 100644 --- a/tests/cefclient/browser/browser_window_osr_gtk.h +++ b/tests/cefclient/browser/browser_window_osr_gtk.h @@ -25,6 +25,7 @@ class BrowserWindowOsrGtk : public BrowserWindow, // Constructor may be called on any thread. // |delegate| must outlive this object. BrowserWindowOsrGtk(BrowserWindow::Delegate* delegate, + bool with_controls, const std::string& startup_url, const OsrRendererSettings& settings); diff --git a/tests/cefclient/browser/browser_window_osr_mac.h b/tests/cefclient/browser/browser_window_osr_mac.h index 2755d5e6f..130a77c10 100644 --- a/tests/cefclient/browser/browser_window_osr_mac.h +++ b/tests/cefclient/browser/browser_window_osr_mac.h @@ -24,6 +24,7 @@ class BrowserWindowOsrMac : public BrowserWindow, // Constructor may be called on any thread. // |delegate| must outlive this object. BrowserWindowOsrMac(BrowserWindow::Delegate* delegate, + bool with_controls, const std::string& startup_url, const OsrRendererSettings& settings); ~BrowserWindowOsrMac(); diff --git a/tests/cefclient/browser/browser_window_osr_mac.mm b/tests/cefclient/browser/browser_window_osr_mac.mm index 7729b58bf..182739196 100644 --- a/tests/cefclient/browser/browser_window_osr_mac.mm +++ b/tests/cefclient/browser/browser_window_osr_mac.mm @@ -1760,10 +1760,12 @@ void BrowserWindowOsrMacImpl::Create(ClientWindowHandle parent_handle, } BrowserWindowOsrMac::BrowserWindowOsrMac(BrowserWindow::Delegate* delegate, + bool with_controls, const std::string& startup_url, const OsrRendererSettings& settings) : BrowserWindow(delegate) { - client_handler_ = new ClientHandlerOsr(this, this, startup_url); + client_handler_ = + new ClientHandlerOsr(this, this, with_controls, startup_url); impl_.reset( new BrowserWindowOsrMacImpl(delegate, startup_url, settings, *this)); } diff --git a/tests/cefclient/browser/browser_window_osr_win.cc b/tests/cefclient/browser/browser_window_osr_win.cc index ac3081d46..c2835b28f 100644 --- a/tests/cefclient/browser/browser_window_osr_win.cc +++ b/tests/cefclient/browser/browser_window_osr_win.cc @@ -9,11 +9,13 @@ namespace client { BrowserWindowOsrWin::BrowserWindowOsrWin(BrowserWindow::Delegate* delegate, + bool with_controls, const std::string& startup_url, const OsrRendererSettings& settings) : BrowserWindow(delegate), osr_hwnd_(nullptr), device_scale_factor_(0) { osr_window_ = new OsrWindowWin(this, settings); - client_handler_ = new ClientHandlerOsr(this, osr_window_.get(), startup_url); + client_handler_ = + new ClientHandlerOsr(this, osr_window_.get(), with_controls, startup_url); } void BrowserWindowOsrWin::CreateBrowser( diff --git a/tests/cefclient/browser/browser_window_osr_win.h b/tests/cefclient/browser/browser_window_osr_win.h index 42ba2b385..e8caf7183 100644 --- a/tests/cefclient/browser/browser_window_osr_win.h +++ b/tests/cefclient/browser/browser_window_osr_win.h @@ -20,6 +20,7 @@ class BrowserWindowOsrWin : public BrowserWindow, // Constructor may be called on any thread. // |delegate| must outlive this object. BrowserWindowOsrWin(BrowserWindow::Delegate* delegate, + bool with_controls, const std::string& startup_url, const OsrRendererSettings& settings); diff --git a/tests/cefclient/browser/browser_window_std_gtk.cc b/tests/cefclient/browser/browser_window_std_gtk.cc index f832a373d..916d3aaa1 100644 --- a/tests/cefclient/browser/browser_window_std_gtk.cc +++ b/tests/cefclient/browser/browser_window_std_gtk.cc @@ -82,9 +82,10 @@ void SetXWindowBounds(XDisplay* xdisplay, } // namespace BrowserWindowStdGtk::BrowserWindowStdGtk(Delegate* delegate, + bool with_controls, const std::string& startup_url) : BrowserWindow(delegate), xdisplay_(nullptr) { - client_handler_ = new ClientHandlerStd(this, startup_url); + client_handler_ = new ClientHandlerStd(this, with_controls, startup_url); } void BrowserWindowStdGtk::set_xdisplay(XDisplay* xdisplay) { diff --git a/tests/cefclient/browser/browser_window_std_gtk.h b/tests/cefclient/browser/browser_window_std_gtk.h index 80b5b2941..28d507802 100644 --- a/tests/cefclient/browser/browser_window_std_gtk.h +++ b/tests/cefclient/browser/browser_window_std_gtk.h @@ -17,7 +17,9 @@ class BrowserWindowStdGtk : public BrowserWindow { public: // Constructor may be called on any thread. // |delegate| must outlive this object. - BrowserWindowStdGtk(Delegate* delegate, const std::string& startup_url); + BrowserWindowStdGtk(Delegate* delegate, + bool with_controls, + const std::string& startup_url); // Called from RootWindowGtk::CreateRootWindow before CreateBrowser. void set_xdisplay(XDisplay* xdisplay); diff --git a/tests/cefclient/browser/browser_window_std_mac.h b/tests/cefclient/browser/browser_window_std_mac.h index c95556030..8a91d8d1f 100644 --- a/tests/cefclient/browser/browser_window_std_mac.h +++ b/tests/cefclient/browser/browser_window_std_mac.h @@ -17,7 +17,9 @@ class BrowserWindowStdMac : public BrowserWindow { public: // Constructor may be called on any thread. // |delegate| must outlive this object. - BrowserWindowStdMac(Delegate* delegate, const std::string& startup_url); + BrowserWindowStdMac(Delegate* delegate, + bool with_controls, + const std::string& startup_url); // BrowserWindow methods. void CreateBrowser(ClientWindowHandle parent_handle, diff --git a/tests/cefclient/browser/browser_window_std_mac.mm b/tests/cefclient/browser/browser_window_std_mac.mm index 510fd41e6..4c1a56de2 100644 --- a/tests/cefclient/browser/browser_window_std_mac.mm +++ b/tests/cefclient/browser/browser_window_std_mac.mm @@ -13,9 +13,10 @@ namespace client { BrowserWindowStdMac::BrowserWindowStdMac(Delegate* delegate, + bool with_controls, const std::string& startup_url) : BrowserWindow(delegate) { - client_handler_ = new ClientHandlerStd(this, startup_url); + client_handler_ = new ClientHandlerStd(this, with_controls, startup_url); } void BrowserWindowStdMac::CreateBrowser( diff --git a/tests/cefclient/browser/browser_window_std_win.cc b/tests/cefclient/browser/browser_window_std_win.cc index 980077748..b8fa24c32 100644 --- a/tests/cefclient/browser/browser_window_std_win.cc +++ b/tests/cefclient/browser/browser_window_std_win.cc @@ -10,9 +10,10 @@ namespace client { BrowserWindowStdWin::BrowserWindowStdWin(Delegate* delegate, + bool with_controls, const std::string& startup_url) : BrowserWindow(delegate) { - client_handler_ = new ClientHandlerStd(this, startup_url); + client_handler_ = new ClientHandlerStd(this, with_controls, startup_url); } void BrowserWindowStdWin::CreateBrowser( diff --git a/tests/cefclient/browser/browser_window_std_win.h b/tests/cefclient/browser/browser_window_std_win.h index 6048c4cf2..5a7ee2a7f 100644 --- a/tests/cefclient/browser/browser_window_std_win.h +++ b/tests/cefclient/browser/browser_window_std_win.h @@ -17,7 +17,9 @@ class BrowserWindowStdWin : public BrowserWindow { public: // Constructor may be called on any thread. // |delegate| must outlive this object. - BrowserWindowStdWin(Delegate* delegate, const std::string& startup_url); + BrowserWindowStdWin(Delegate* delegate, + bool with_controls, + const std::string& startup_url); // BrowserWindow methods. void CreateBrowser(ClientWindowHandle parent_handle, diff --git a/tests/cefclient/browser/client_handler.cc b/tests/cefclient/browser/client_handler.cc index 80348b448..c46d187ef 100644 --- a/tests/cefclient/browser/client_handler.cc +++ b/tests/cefclient/browser/client_handler.cc @@ -11,7 +11,9 @@ #include #include "include/base/cef_callback.h" +#include "include/base/cef_cxx17_backports.h" #include "include/cef_browser.h" +#include "include/cef_command_ids.h" #include "include/cef_frame.h" #include "include/cef_parser.h" #include "include/cef_ssl_status.h" @@ -244,8 +246,10 @@ class ClientDownloadImageCallback : public CefDownloadImageCallback { ClientHandler::ClientHandler(Delegate* delegate, bool is_osr, + bool with_controls, const std::string& startup_url) : is_osr_(is_osr), + with_controls_(with_controls), startup_url_(startup_url), download_favicon_images_(false), delegate_(delegate), @@ -310,18 +314,42 @@ bool ClientHandler::OnProcessMessageReceived( return false; } +bool ClientHandler::OnChromeCommand(CefRefPtr browser, + int command_id, + cef_window_open_disposition_t disposition) { + CEF_REQUIRE_UI_THREAD(); + DCHECK(MainContext::Get()->UseChromeRuntime()); + + if (!with_controls_ && + (disposition != WOD_CURRENT_TAB || !IsAllowedCommandId(command_id))) { + // Block everything that doesn't target the current tab or isn't an + // allowed command ID. + LOG(INFO) << "Blocking command " << command_id << " with disposition " + << disposition; + return true; + } + + // Default handling. + return false; +} + void ClientHandler::OnBeforeContextMenu(CefRefPtr browser, CefRefPtr frame, CefRefPtr params, CefRefPtr model) { CEF_REQUIRE_UI_THREAD(); + const bool use_chrome_runtime = MainContext::Get()->UseChromeRuntime(); + if (use_chrome_runtime && !with_controls_) { + // Remove all disallowed menu items. + FilterMenuModel(model); + } + if ((params->GetTypeFlags() & (CM_TYPEFLAG_PAGE | CM_TYPEFLAG_FRAME)) != 0) { // Add a separator if the menu already has items. if (model->GetCount() > 0) model->AddSeparator(); - const bool use_chrome_runtime = MainContext::Get()->UseChromeRuntime(); if (!use_chrome_runtime) { // TODO(chrome-runtime): Add support for this. // Add DevTools items to all context menus. @@ -720,8 +748,8 @@ bool ClientHandler::OnOpenURLFromTab( // Handle middle-click and ctrl + left-click by opening the URL in a new // browser window. auto config = std::make_unique(); - config->with_controls = true; - config->with_osr = is_osr(); + config->with_controls = with_controls_; + config->with_osr = is_osr_; config->url = target_url; MainContext::Get()->GetRootWindowManager()->CreateRootWindow( std::move(config)); @@ -1023,7 +1051,7 @@ void ClientHandler::ShowSSLInformation(CefRefPtr browser) { auto config = std::make_unique(); config->with_controls = false; - config->with_osr = is_osr(); + config->with_osr = is_osr_; config->url = test_runner::GetDataURI(ss.str(), "text/html"); MainContext::Get()->GetRootWindowManager()->CreateRootWindow( std::move(config)); @@ -1051,7 +1079,8 @@ bool ClientHandler::CreatePopupWindow(CefRefPtr browser, // The popup browser will be parented to a new native window. // Don't show URL bar and navigation buttons on DevTools windows. MainContext::Get()->GetRootWindowManager()->CreateRootWindowAsPopup( - !is_devtools, is_osr(), popupFeatures, windowInfo, client, settings); + with_controls_ && !is_devtools, is_osr_, popupFeatures, windowInfo, + client, settings); return true; } @@ -1238,4 +1267,59 @@ void ClientHandler::SetOfflineState(CefRefPtr browser, /*message_id=*/0, "Network.emulateNetworkConditions", params); } +void ClientHandler::FilterMenuModel(CefRefPtr model) { + // Evaluate from the bottom to the top because we'll be removing menu items. + for (int i = model->GetCount() - 1; i >= 0; --i) { + const auto type = model->GetTypeAt(i); + if (type == MENUITEMTYPE_SUBMENU) { + // Filter sub-menu and remove if empty. + auto sub_model = model->GetSubMenuAt(i); + FilterMenuModel(sub_model); + if (sub_model->GetCount() == 0) { + model->RemoveAt(i); + } + } else if (type == MENUITEMTYPE_SEPARATOR) { + // A separator shouldn't be the first or last element in the menu, and + // there shouldn't be multiple in a row. + if (i == 0 || i == model->GetCount() - 1 || + model->GetTypeAt(i + 1) == MENUITEMTYPE_SEPARATOR) { + model->RemoveAt(i); + } + } else if (!IsAllowedCommandId(model->GetCommandIdAt(i))) { + model->RemoveAt(i); + } + } +} + +bool ClientHandler::IsAllowedCommandId(int command_id) { + // Only the commands in this array will be allowed. + static const int kAllowedCommandIds[] = { + // Page navigation. + IDC_BACK, + IDC_FORWARD, + IDC_RELOAD, + IDC_RELOAD_BYPASSING_CACHE, + IDC_RELOAD_CLEARING_CACHE, + IDC_STOP, + + // Printing. + IDC_PRINT, + + // Edit controls. + IDC_CONTENT_CONTEXT_CUT, + IDC_CONTENT_CONTEXT_COPY, + IDC_CONTENT_CONTEXT_PASTE, + IDC_CONTENT_CONTEXT_PASTE_AND_MATCH_STYLE, + IDC_CONTENT_CONTEXT_DELETE, + IDC_CONTENT_CONTEXT_SELECTALL, + IDC_CONTENT_CONTEXT_UNDO, + IDC_CONTENT_CONTEXT_REDO, + }; + for (size_t i = 0; i < base::size(kAllowedCommandIds); ++i) { + if (command_id == kAllowedCommandIds[i]) + return true; + } + return false; +} + } // namespace client diff --git a/tests/cefclient/browser/client_handler.h b/tests/cefclient/browser/client_handler.h index c2fdc2fb5..00e3b3f26 100644 --- a/tests/cefclient/browser/client_handler.h +++ b/tests/cefclient/browser/client_handler.h @@ -28,6 +28,7 @@ class ClientDownloadImageCallback; // Client handler abstract base class. Provides common functionality shared by // all concrete client handler implementations. class ClientHandler : public CefClient, + public CefCommandHandler, public CefContextMenuHandler, public CefDisplayHandler, public CefDownloadHandler, @@ -93,6 +94,7 @@ class ClientHandler : public CefClient, // |delegate| must outlive this object or DetachDelegate() must be called. ClientHandler(Delegate* delegate, bool is_osr, + bool with_controls, const std::string& startup_url); // This object may outlive the Delegate object so it's necessary for the @@ -100,6 +102,7 @@ class ClientHandler : public CefClient, void DetachDelegate(); // CefClient methods + CefRefPtr GetCommandHandler() override { return this; } CefRefPtr GetContextMenuHandler() override { return this; } @@ -128,6 +131,11 @@ class ClientHandler : public CefClient, } #endif + // CefCommandHandler methods + bool OnChromeCommand(CefRefPtr browser, + int command_id, + cef_window_open_disposition_t disposition) override; + // CefContextMenuHandler methods void OnBeforeContextMenu(CefRefPtr browser, CefRefPtr frame, @@ -312,9 +320,6 @@ class ClientHandler : public CefClient, // Returns the startup URL. std::string startup_url() const { return startup_url_; } - // Returns true if this handler uses off-screen rendering. - bool is_osr() const { return is_osr_; } - // Set/get whether the client should download favicon images. Only safe to // call immediately after client creation or on the browser process UI thread. bool download_favicon_images() const { return download_favicon_images_; } @@ -355,12 +360,19 @@ class ClientHandler : public CefClient, void SetOfflineState(CefRefPtr browser, bool offline); + // Filter menu and keyboard shortcut commands. + void FilterMenuModel(CefRefPtr model); + bool IsAllowedCommandId(int command_id); + // THREAD SAFE MEMBERS // The following members may be accessed from any thread. // True if this handler uses off-screen rendering. const bool is_osr_; + // True if this handler shows controls. + const bool with_controls_; + // The startup URL. const std::string startup_url_; diff --git a/tests/cefclient/browser/client_handler_osr.cc b/tests/cefclient/browser/client_handler_osr.cc index 5b3ac1533..14ea3286e 100644 --- a/tests/cefclient/browser/client_handler_osr.cc +++ b/tests/cefclient/browser/client_handler_osr.cc @@ -12,8 +12,10 @@ namespace client { ClientHandlerOsr::ClientHandlerOsr(Delegate* delegate, OsrDelegate* osr_delegate, + bool with_controls, const std::string& startup_url) - : ClientHandler(delegate, true, startup_url), osr_delegate_(osr_delegate) { + : ClientHandler(delegate, /*is_osr=*/true, with_controls, startup_url), + osr_delegate_(osr_delegate) { DCHECK(osr_delegate_); } diff --git a/tests/cefclient/browser/client_handler_osr.h b/tests/cefclient/browser/client_handler_osr.h index 2f31b05e2..1fe247ea6 100644 --- a/tests/cefclient/browser/client_handler_osr.h +++ b/tests/cefclient/browser/client_handler_osr.h @@ -77,6 +77,7 @@ class ClientHandlerOsr : public ClientHandler, ClientHandlerOsr(Delegate* delegate, OsrDelegate* osr_delegate, + bool with_controls, const std::string& startup_url); // This object may outlive the OsrDelegate object so it's necessary for the diff --git a/tests/cefclient/browser/client_handler_std.cc b/tests/cefclient/browser/client_handler_std.cc index 803028f6e..e78166d93 100644 --- a/tests/cefclient/browser/client_handler_std.cc +++ b/tests/cefclient/browser/client_handler_std.cc @@ -7,7 +7,8 @@ namespace client { ClientHandlerStd::ClientHandlerStd(Delegate* delegate, + bool with_controls, const std::string& startup_url) - : ClientHandler(delegate, false, startup_url) {} + : ClientHandler(delegate, /*is_osr=*/false, with_controls, startup_url) {} } // namespace client diff --git a/tests/cefclient/browser/client_handler_std.h b/tests/cefclient/browser/client_handler_std.h index 5a73a3eec..02aa74767 100644 --- a/tests/cefclient/browser/client_handler_std.h +++ b/tests/cefclient/browser/client_handler_std.h @@ -14,7 +14,9 @@ namespace client { // one browser per handler instance. class ClientHandlerStd : public ClientHandler { public: - ClientHandlerStd(Delegate* delegate, const std::string& startup_url); + ClientHandlerStd(Delegate* delegate, + bool with_controls, + const std::string& startup_url); private: // Include the default reference counting implementation. diff --git a/tests/cefclient/browser/root_window_gtk.cc b/tests/cefclient/browser/root_window_gtk.cc index 186126c82..ff11eaf94 100644 --- a/tests/cefclient/browser/root_window_gtk.cc +++ b/tests/cefclient/browser/root_window_gtk.cc @@ -274,9 +274,11 @@ void RootWindowGtk::CreateBrowserWindow(const std::string& startup_url) { if (with_osr_) { OsrRendererSettings settings = {}; MainContext::Get()->PopulateOsrSettings(&settings); - browser_window_.reset(new BrowserWindowOsrGtk(this, startup_url, settings)); + browser_window_.reset( + new BrowserWindowOsrGtk(this, with_controls_, startup_url, settings)); } else { - browser_window_.reset(new BrowserWindowStdGtk(this, startup_url)); + browser_window_.reset( + new BrowserWindowStdGtk(this, with_controls_, startup_url)); } } diff --git a/tests/cefclient/browser/root_window_mac.mm b/tests/cefclient/browser/root_window_mac.mm index a2fdd6f77..c72b94f38 100644 --- a/tests/cefclient/browser/root_window_mac.mm +++ b/tests/cefclient/browser/root_window_mac.mm @@ -356,10 +356,11 @@ void RootWindowMacImpl::CreateBrowserWindow(const std::string& startup_url) { if (with_osr_) { OsrRendererSettings settings = {}; MainContext::Get()->PopulateOsrSettings(&settings); - browser_window_.reset( - new BrowserWindowOsrMac(&root_window_, startup_url, settings)); + browser_window_.reset(new BrowserWindowOsrMac(&root_window_, with_controls_, + startup_url, settings)); } else { - browser_window_.reset(new BrowserWindowStdMac(&root_window_, startup_url)); + browser_window_.reset( + new BrowserWindowStdMac(&root_window_, with_controls_, startup_url)); } } diff --git a/tests/cefclient/browser/root_window_views.cc b/tests/cefclient/browser/root_window_views.cc index 7cee5ebbc..dcc533293 100644 --- a/tests/cefclient/browser/root_window_views.cc +++ b/tests/cefclient/browser/root_window_views.cc @@ -464,7 +464,7 @@ void RootWindowViews::OnBeforeContextMenu(CefRefPtr model) { void RootWindowViews::CreateClientHandler(const std::string& url) { DCHECK(!client_handler_); - client_handler_ = new ClientHandlerStd(this, url); + client_handler_ = new ClientHandlerStd(this, config_->with_controls, url); client_handler_->set_download_favicon_images(true); } diff --git a/tests/cefclient/browser/root_window_win.cc b/tests/cefclient/browser/root_window_win.cc index 1cb3e8a3c..3de4de8f3 100644 --- a/tests/cefclient/browser/root_window_win.cc +++ b/tests/cefclient/browser/root_window_win.cc @@ -308,9 +308,11 @@ void RootWindowWin::CreateBrowserWindow(const std::string& startup_url) { if (with_osr_) { OsrRendererSettings settings = {}; MainContext::Get()->PopulateOsrSettings(&settings); - browser_window_.reset(new BrowserWindowOsrWin(this, startup_url, settings)); + browser_window_.reset( + new BrowserWindowOsrWin(this, with_controls_, startup_url, settings)); } else { - browser_window_.reset(new BrowserWindowStdWin(this, startup_url)); + browser_window_.reset( + new BrowserWindowStdWin(this, with_controls_, startup_url)); } } diff --git a/tools/make_distrib.py b/tools/make_distrib.py index b89a4acb1..8e38d0bb0 100644 --- a/tools/make_distrib.py +++ b/tools/make_distrib.py @@ -719,6 +719,7 @@ if mode == 'standard' or mode == 'minimal': # Transfer generated include files. generated_includes = [ + 'cef_command_ids.h', 'cef_config.h', 'cef_pack_resources.h', 'cef_pack_strings.h', diff --git a/tools/make_pack_header.py b/tools/make_pack_header.py index 4f65d7669..1afe8d069 100644 --- a/tools/make_pack_header.py +++ b/tools/make_pack_header.py @@ -34,7 +34,7 @@ def MakeFileSegment(input, all_names): # #define IDR_RESOURCE_NAME 12345 # [1] See https://crbug.com/684788#c18 - regex = '#define\s([A-Za-z0-9_]{1,})\s' + regex = '#define\s([A-Za-z0-9_]{1,})\s+' if contents.find('ui::WhitelistedResource') > 0: regex += '.*<' regex += '([0-9]{1,})'