From fe6e44886b309f66831289868ebd53ae19217c0e Mon Sep 17 00:00:00 2001 From: Pedro de Carvalho Gomes Date: Mon, 5 Aug 2024 12:12:33 -0400 Subject: [PATCH] linux: Add CefWindowDelegate::GetLinuxWindowProperties (fixes #3383) --- include/capi/views/cef_window_delegate_capi.h | 11 +++- include/cef_api_hash.h | 8 +-- include/internal/cef_types.h | 28 ++++++++++ include/internal/cef_types_wrappers.h | 32 ++++++++++++ include/views/cef_window_delegate.h | 10 ++++ libcef/browser/views/window_view.cc | 10 ++++ .../cpptoc/views/window_delegate_cpptoc.cc | 52 ++++++++++++++++++- .../ctocpp/views/window_delegate_ctocpp.cc | 30 ++++++++++- .../ctocpp/views/window_delegate_ctocpp.h | 4 +- tests/cefclient/browser/views_window.cc | 13 +++++ tests/cefclient/browser/views_window.h | 5 ++ 11 files changed, 193 insertions(+), 10 deletions(-) diff --git a/include/capi/views/cef_window_delegate_capi.h b/include/capi/views/cef_window_delegate_capi.h index 338058cdb..b414f84a0 100644 --- a/include/capi/views/cef_window_delegate_capi.h +++ b/include/capi/views/cef_window_delegate_capi.h @@ -33,7 +33,7 @@ // by hand. See the translator.README.txt file in the tools directory for // more information. // -// $hash=a2e5caf4dc0ed5b43a6075678e3b7b7ae83834ae$ +// $hash=bafa7ddf3dfbc3fa82b1fb8a064b51f0791b29b6$ // #ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_ @@ -280,6 +280,15 @@ typedef struct _cef_window_delegate_t { /// cef_runtime_style_t(CEF_CALLBACK* get_window_runtime_style)( struct _cef_window_delegate_t* self); + + /// + /// Return Linux-specific window properties for correctly handling by window + /// managers + /// + int(CEF_CALLBACK* get_linux_window_properties)( + struct _cef_window_delegate_t* self, + struct _cef_window_t* window, + struct _cef_linux_window_properties_t* properties); } cef_window_delegate_t; #ifdef __cplusplus diff --git a/include/cef_api_hash.h b/include/cef_api_hash.h index 000f6be98..f71d6191d 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 "80fd8337eb375cb48d617cd7cf01b531ea577efc" +#define CEF_API_HASH_UNIVERSAL "231671a5669eaa29cd2c01a2e459857945c4ea01" #if defined(OS_WIN) -#define CEF_API_HASH_PLATFORM "81d92ace6598de3106b212d70454022678fb2e2b" +#define CEF_API_HASH_PLATFORM "f8a2808cad9b2250c0a5096c043547f8942e2b7d" #elif defined(OS_MAC) -#define CEF_API_HASH_PLATFORM "c7b1f631ac53d876ea88f60a7f768b8f1ad1f0d8" +#define CEF_API_HASH_PLATFORM "064c88eb32b8b9932d85ed8023a11656647a3ac0" #elif defined(OS_LINUX) -#define CEF_API_HASH_PLATFORM "8dc9b5f33e800f9ac83253d6c7d714952ba8fa85" +#define CEF_API_HASH_PLATFORM "e934aa611c47fda69dbef4e46e11255300e37f9c" #endif #ifdef __cplusplus diff --git a/include/internal/cef_types.h b/include/internal/cef_types.h index 6e490adc3..091202804 100644 --- a/include/internal/cef_types.h +++ b/include/internal/cef_types.h @@ -1847,6 +1847,34 @@ typedef struct _cef_screen_info_t { cef_rect_t available_rect; } cef_screen_info_t; +/// +/// Linux window properties, such as X11's WM_CLASS or Wayland's app_id. +/// Those are passed to CefWindowDelegate, so the client can set them +/// for the CefWindow's top-level. Thus, allowing window managers to correctly +/// display the application's information (e.g., icons). +/// +typedef struct _cef_linux_window_properties_t { + /// + /// Main window's Wayland's app_id + /// + cef_string_t wayland_app_id; + + /// + /// Main window's WM_CLASS_CLASS in X11 + /// + cef_string_t wm_class_class; + + /// + /// Main window's WM_CLASS_NAME in X11 + /// + cef_string_t wm_class_name; + + /// + /// Main window's WM_WINDOW_ROLE in X11 + /// + cef_string_t wm_role_name; +} cef_linux_window_properties_t; + /// /// Supported menu IDs. Non-English translations can be provided for the /// IDS_MENU_* strings in CefResourceBundleHandler::GetLocalizedString(). diff --git a/include/internal/cef_types_wrappers.h b/include/internal/cef_types_wrappers.h index b04ee5d88..1ea6270b4 100644 --- a/include/internal/cef_types_wrappers.h +++ b/include/internal/cef_types_wrappers.h @@ -783,4 +783,36 @@ struct CefTaskInfoTraits { /// using CefTaskInfo = CefStructBase; +struct CefLinuxWindowPropertiesTraits { + using struct_type = cef_linux_window_properties_t; + + static inline void init(struct_type* s) {} + + static inline void clear(struct_type* s) { + cef_string_clear(&s->wayland_app_id); + cef_string_clear(&s->wm_class_class); + cef_string_clear(&s->wm_class_name); + cef_string_clear(&s->wm_role_name); + } + + static inline void set(const struct_type* src, + struct_type* target, + bool copy) { + cef_string_set(src->wayland_app_id.str, src->wayland_app_id.length, + &target->wayland_app_id, copy); + cef_string_set(src->wm_class_class.str, src->wm_class_class.length, + &target->wm_class_class, copy); + cef_string_set(src->wm_class_name.str, src->wm_class_name.length, + &target->wm_class_name, copy); + cef_string_set(src->wm_role_name.str, src->wm_role_name.length, + &target->wm_role_name, copy); + } +}; + +/// +/// Class representing the Linux-specific window properties required +/// for the window managers to correct group and display the window. +/// +using CefLinuxWindowProperties = CefStructBase; + #endif // CEF_INCLUDE_INTERNAL_CEF_TYPES_WRAPPERS_H_ diff --git a/include/views/cef_window_delegate.h b/include/views/cef_window_delegate.h index d5481d059..2773985ae 100644 --- a/include/views/cef_window_delegate.h +++ b/include/views/cef_window_delegate.h @@ -278,6 +278,16 @@ class CefWindowDelegate : public CefPanelDelegate { virtual cef_runtime_style_t GetWindowRuntimeStyle() { return CEF_RUNTIME_STYLE_DEFAULT; } + + /// + /// Return Linux-specific window properties for correctly handling by window + /// managers + /// + /*--cef()--*/ + virtual bool GetLinuxWindowProperties(CefRefPtr window, + CefLinuxWindowProperties& properties) { + return false; + } }; #endif // CEF_INCLUDE_VIEWS_CEF_WINDOW_DELEGATE_H_ diff --git a/libcef/browser/views/window_view.cc b/libcef/browser/views/window_view.cc index d05c7bba0..1295c0379 100644 --- a/libcef/browser/views/window_view.cc +++ b/libcef/browser/views/window_view.cc @@ -429,6 +429,16 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) { auto bounds = cef_delegate()->GetInitialBounds(cef_window); params.bounds = gfx::Rect(bounds.x, bounds.y, bounds.width, bounds.height); +#if BUILDFLAG(IS_LINUX) + CefLinuxWindowProperties linux_props; + if (cef_delegate()->GetLinuxWindowProperties(cef_window, linux_props)) { + params.wayland_app_id = CefString(&linux_props.wayland_app_id); + params.wm_class_class = CefString(&linux_props.wm_class_class); + params.wm_class_name = CefString(&linux_props.wm_class_name); + params.wm_role_name = CefString(&linux_props.wm_role_name); + } +#endif + if (has_native_parent) { DCHECK(!params.bounds.IsEmpty()); } else { diff --git a/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc b/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc index e499e6b14..2b917681b 100644 --- a/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc +++ b/libcef_dll/cpptoc/views/window_delegate_cpptoc.cc @@ -9,14 +9,14 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=bcb4d6aea88f1445def6014708b69087f1a6dc74$ +// $hash=2fca5c473412bd7acef54f5057dc55488271aaf9$ // #include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h" - #include "libcef_dll/ctocpp/views/view_ctocpp.h" #include "libcef_dll/ctocpp/views/window_ctocpp.h" #include "libcef_dll/shutdown_checker.h" +#include "libcef_dll/template_util.h" namespace { @@ -600,6 +600,52 @@ window_delegate_get_window_runtime_style(struct _cef_window_delegate_t* self) { return _retval; } +int CEF_CALLBACK window_delegate_get_linux_window_properties( + struct _cef_window_delegate_t* self, + cef_window_t* window, + struct _cef_linux_window_properties_t* properties) { + shutdown_checker::AssertNotShutdown(); + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + DCHECK(self); + if (!self) { + return 0; + } + // Verify param: window; type: refptr_diff + DCHECK(window); + if (!window) { + return 0; + } + // Verify param: properties; type: struct_byref + DCHECK(properties); + if (!properties) { + return 0; + } + if (!template_util::has_valid_size(properties)) { + DCHECK(false) << "invalid properties->[base.]size"; + return 0; + } + + // Translate param: properties; type: struct_byref + CefLinuxWindowProperties propertiesObj; + if (properties) { + propertiesObj.AttachTo(*properties); + } + + // Execute + bool _retval = CefWindowDelegateCppToC::Get(self)->GetLinuxWindowProperties( + CefWindowCToCpp::Wrap(window), propertiesObj); + + // Restore param: properties; type: struct_byref + if (properties) { + propertiesObj.DetachTo(*properties); + } + + // Return type: bool + return _retval; +} + cef_size_t CEF_CALLBACK window_delegate_get_preferred_size(struct _cef_view_delegate_t* self, cef_view_t* view) { @@ -916,6 +962,8 @@ CefWindowDelegateCppToC::CefWindowDelegateCppToC() { window_delegate_on_theme_colors_changed; GetStruct()->get_window_runtime_style = window_delegate_get_window_runtime_style; + GetStruct()->get_linux_window_properties = + window_delegate_get_linux_window_properties; GetStruct()->base.base.get_preferred_size = window_delegate_get_preferred_size; GetStruct()->base.base.get_minimum_size = window_delegate_get_minimum_size; diff --git a/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc b/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc index 3ffd1f6b3..4a78c4d8f 100644 --- a/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc +++ b/libcef_dll/ctocpp/views/window_delegate_ctocpp.cc @@ -9,11 +9,10 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=da609d625660ca617e1a01d5dc359932142e15a3$ +// $hash=7bdd882f715040d06246576d0bafbbd7b9a39f8f$ // #include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h" - #include "libcef_dll/cpptoc/views/view_cpptoc.h" #include "libcef_dll/cpptoc/views/window_cpptoc.h" #include "libcef_dll/shutdown_checker.h" @@ -579,6 +578,33 @@ cef_runtime_style_t CefWindowDelegateCToCpp::GetWindowRuntimeStyle() { return _retval; } +NO_SANITIZE("cfi-icall") +bool CefWindowDelegateCToCpp::GetLinuxWindowProperties( + CefRefPtr window, + CefLinuxWindowProperties& properties) { + shutdown_checker::AssertNotShutdown(); + + cef_window_delegate_t* _struct = GetStruct(); + if (CEF_MEMBER_MISSING(_struct, get_linux_window_properties)) { + return false; + } + + // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING + + // Verify param: window; type: refptr_diff + DCHECK(window.get()); + if (!window.get()) { + return false; + } + + // Execute + int _retval = _struct->get_linux_window_properties( + _struct, CefWindowCppToC::Wrap(window), &properties); + + // Return type: bool + return _retval ? true : false; +} + NO_SANITIZE("cfi-icall") CefSize CefWindowDelegateCToCpp::GetPreferredSize(CefRefPtr view) { shutdown_checker::AssertNotShutdown(); diff --git a/libcef_dll/ctocpp/views/window_delegate_ctocpp.h b/libcef_dll/ctocpp/views/window_delegate_ctocpp.h index aac6840e1..ebd66be9c 100644 --- a/libcef_dll/ctocpp/views/window_delegate_ctocpp.h +++ b/libcef_dll/ctocpp/views/window_delegate_ctocpp.h @@ -9,7 +9,7 @@ // implementations. See the translator.README.txt file in the tools directory // for more information. // -// $hash=50ace2b6a45a23d4ff5d9a91ab7c37a893f7e0b4$ +// $hash=ef831469d4dd59c3a20f0dfee3e8e945a52d7637$ // #ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_ @@ -67,6 +67,8 @@ class CefWindowDelegateCToCpp void OnThemeColorsChanged(CefRefPtr window, bool chrome_theme) override; cef_runtime_style_t GetWindowRuntimeStyle() override; + bool GetLinuxWindowProperties(CefRefPtr window, + CefLinuxWindowProperties& properties) override; // CefPanelDelegate methods. diff --git a/tests/cefclient/browser/views_window.cc b/tests/cefclient/browser/views_window.cc index 56eec98af..c412e45bc 100644 --- a/tests/cefclient/browser/views_window.cc +++ b/tests/cefclient/browser/views_window.cc @@ -671,6 +671,19 @@ cef_runtime_style_t ViewsWindow::GetWindowRuntimeStyle() { return CEF_RUNTIME_STYLE_DEFAULT; } +#if defined(OS_LINUX) +bool ViewsWindow::GetLinuxWindowProperties( + CefRefPtr window, + CefLinuxWindowProperties& properties) { + CefString(&properties.wayland_app_id) = + CefString(&properties.wm_class_class) = + CefString(&properties.wm_class_name) = + CefString(&properties.wm_role_name) = "cef"; + + return true; +} +#endif + void ViewsWindow::OnWindowCreated(CefRefPtr window) { CEF_REQUIRE_UI_THREAD(); DCHECK(browser_view_); diff --git a/tests/cefclient/browser/views_window.h b/tests/cefclient/browser/views_window.h index 31f1ee313..953a5579b 100644 --- a/tests/cefclient/browser/views_window.h +++ b/tests/cefclient/browser/views_window.h @@ -162,6 +162,11 @@ class ViewsWindow : public CefBrowserViewDelegate, const CefKeyEvent& event) override; // CefWindowDelegate methods: +#if defined(OS_LINUX) + virtual bool GetLinuxWindowProperties( + CefRefPtr window, + CefLinuxWindowProperties& properties) override; +#endif void OnWindowCreated(CefRefPtr window) override; void OnWindowClosing(CefRefPtr window) override; void OnWindowDestroyed(CefRefPtr window) override;