views: mac: Fix frameless window behavior (fixes issue #3189)
Frameless windows now display as expected. Default traffic light buttons can optionally be shown at configurable vertical position. Layout respects text direction.
This commit is contained in:
parent
6926287894
commit
f6de0344cb
4
BUILD.gn
4
BUILD.gn
|
@ -1145,6 +1145,10 @@ source_set("libcef_static") {
|
|||
"libcef/browser/native/menu_runner_mac.mm",
|
||||
"libcef/browser/osr/browser_platform_delegate_osr_mac.h",
|
||||
"libcef/browser/osr/browser_platform_delegate_osr_mac.mm",
|
||||
"libcef/browser/views/native_widget_mac.h",
|
||||
"libcef/browser/views/native_widget_mac.mm",
|
||||
"libcef/browser/views/ns_window.h",
|
||||
"libcef/browser/views/ns_window.mm",
|
||||
"libcef/browser/views/view_util_mac.mm",
|
||||
"libcef/common/util_mac.h",
|
||||
"libcef/common/util_mac.mm",
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
// by hand. See the translator.README.txt file in the tools directory for
|
||||
// more information.
|
||||
//
|
||||
// $hash=019abf16be4e151d31181a6bdcb1ad8dfef03d00$
|
||||
// $hash=9f0389a439e6787282880d53375369829adb6a3d$
|
||||
//
|
||||
|
||||
#ifndef CEF_INCLUDE_CAPI_VIEWS_CEF_WINDOW_DELEGATE_CAPI_H_
|
||||
|
@ -137,6 +137,25 @@ typedef struct _cef_window_delegate_t {
|
|||
int(CEF_CALLBACK* is_frameless)(struct _cef_window_delegate_t* self,
|
||||
struct _cef_window_t* window);
|
||||
|
||||
///
|
||||
/// Return true (1) if |window| should be created with standard window buttons
|
||||
/// like close, minimize and zoom.
|
||||
///
|
||||
int(CEF_CALLBACK* with_standard_window_buttons)(
|
||||
struct _cef_window_delegate_t* self,
|
||||
struct _cef_window_t* window);
|
||||
|
||||
///
|
||||
/// Return whether the titlebar height should be overridden, and sets the
|
||||
/// height of the titlebar in |titlebar_height|. On macOS, it can also be used
|
||||
/// to adjust the vertical position of the traffic light buttons in frameless
|
||||
/// windows. The buttons will be positioned halfway down the titlebar at a
|
||||
/// height of |titlebar_height| / 2.
|
||||
///
|
||||
int(CEF_CALLBACK* get_titlebar_height)(struct _cef_window_delegate_t* self,
|
||||
struct _cef_window_t* window,
|
||||
float* titlebar_height);
|
||||
|
||||
///
|
||||
/// Return true (1) if |window| can be resized.
|
||||
///
|
||||
|
|
|
@ -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 "17e2f5f1944618780d9d2f445d6f7ca17ad31f2a"
|
||||
#define CEF_API_HASH_UNIVERSAL "1d8347d8e06dc0dd17f882ca253e1c7bf43d5863"
|
||||
#if defined(OS_WIN)
|
||||
#define CEF_API_HASH_PLATFORM "43e4bd792e5b0bbe8004dcecca0997803d1effbb"
|
||||
#define CEF_API_HASH_PLATFORM "b6865f1992a10dcefc0bbc450cf296b648003271"
|
||||
#elif defined(OS_MAC)
|
||||
#define CEF_API_HASH_PLATFORM "a3e1a9d8eeda6791d3a990d0e94407b4d0569aca"
|
||||
#define CEF_API_HASH_PLATFORM "d04c2a5ab471493c185eb7c7aa894bc4a79d5a7c"
|
||||
#elif defined(OS_LINUX)
|
||||
#define CEF_API_HASH_PLATFORM "63cbcad670b313815a78186a5e029c8b09339e36"
|
||||
#define CEF_API_HASH_PLATFORM "d7d4cbffa4a798fea97e7b9f3610b5cb803d949e"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -128,6 +128,29 @@ class CefWindowDelegate : public CefPanelDelegate {
|
|||
/*--cef()--*/
|
||||
virtual bool IsFrameless(CefRefPtr<CefWindow> window) { return false; }
|
||||
|
||||
///
|
||||
/// Return true if |window| should be created with standard window buttons
|
||||
/// like close, minimize and zoom.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool WithStandardWindowButtons(CefRefPtr<CefWindow> window) {
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Return whether the titlebar height should be overridden,
|
||||
/// and sets the height of the titlebar in |titlebar_height|.
|
||||
/// On macOS, it can also be used to adjust the vertical position
|
||||
/// of the traffic light buttons in frameless windows.
|
||||
/// The buttons will be positioned halfway down the titlebar
|
||||
/// at a height of |titlebar_height| / 2.
|
||||
///
|
||||
/*--cef()--*/
|
||||
virtual bool GetTitlebarHeight(CefRefPtr<CefWindow> window,
|
||||
float* titlebar_height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
///
|
||||
/// Return true if |window| can be resized.
|
||||
///
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_VIEWS_NATIVE_WIDGET_MAC_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_NATIVE_WIDGET_MAC_H_
|
||||
#pragma once
|
||||
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "ui/views/widget/native_widget_mac.h"
|
||||
|
||||
class CefNativeWidgetMac : public views::NativeWidgetMac {
|
||||
public:
|
||||
CefNativeWidgetMac(views::internal::NativeWidgetDelegate* delegate,
|
||||
bool is_frameless,
|
||||
bool with_window_buttons,
|
||||
absl::optional<float> title_bar_height);
|
||||
~CefNativeWidgetMac() override = default;
|
||||
|
||||
CefNativeWidgetMac(const CefNativeWidgetMac&) = delete;
|
||||
CefNativeWidgetMac& operator=(const CefNativeWidgetMac&) = delete;
|
||||
|
||||
protected:
|
||||
// NativeWidgetMac:
|
||||
NativeWidgetMacNSWindow* CreateNSWindow(
|
||||
const remote_cocoa::mojom::CreateWindowParams* params) override;
|
||||
|
||||
void GetWindowFrameTitlebarHeight(bool* override_titlebar_height,
|
||||
float* titlebar_height) override;
|
||||
|
||||
private:
|
||||
const bool is_frameless_;
|
||||
const bool with_window_buttons_;
|
||||
const absl::optional<float> title_bar_height_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_NATIVE_WIDGET_MAC_H_
|
|
@ -0,0 +1,52 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
#include "libcef/browser/views/native_widget_mac.h"
|
||||
|
||||
#include "libcef/browser/views/ns_window.h"
|
||||
|
||||
CefNativeWidgetMac::CefNativeWidgetMac(
|
||||
views::internal::NativeWidgetDelegate* delegate,
|
||||
bool is_frameless,
|
||||
bool with_window_buttons,
|
||||
absl::optional<float> title_bar_height)
|
||||
: views::NativeWidgetMac(delegate),
|
||||
is_frameless_(is_frameless),
|
||||
with_window_buttons_(with_window_buttons),
|
||||
title_bar_height_(title_bar_height) {}
|
||||
|
||||
NativeWidgetMacNSWindow* CefNativeWidgetMac::CreateNSWindow(
|
||||
const remote_cocoa::mojom::CreateWindowParams* params) {
|
||||
NSUInteger style_mask =
|
||||
NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable |
|
||||
NSWindowStyleMaskClosable | NSWindowStyleMaskResizable |
|
||||
NSWindowStyleMaskTexturedBackground;
|
||||
auto window = [[CefNSWindow alloc] initWithStyle:style_mask
|
||||
isFrameless:is_frameless_];
|
||||
|
||||
if (is_frameless_) {
|
||||
[window setTitlebarAppearsTransparent:YES];
|
||||
[window setTitleVisibility:NSWindowTitleHidden];
|
||||
}
|
||||
|
||||
if (!with_window_buttons_) {
|
||||
[[window standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||
}
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
void CefNativeWidgetMac::GetWindowFrameTitlebarHeight(
|
||||
bool* override_titlebar_height,
|
||||
float* titlebar_height) {
|
||||
if (title_bar_height_) {
|
||||
*override_titlebar_height = true;
|
||||
*titlebar_height = title_bar_height_.value();
|
||||
} else {
|
||||
views::NativeWidgetMac::GetWindowFrameTitlebarHeight(
|
||||
override_titlebar_height, titlebar_height);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
#ifndef CEF_LIBCEF_BROWSER_VIEWS_NS_WINDOW_H_
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_NS_WINDOW_H_
|
||||
#pragma once
|
||||
|
||||
#include "components/remote_cocoa/app_shim/native_widget_mac_nswindow.h"
|
||||
|
||||
@interface CefNSWindow : NativeWidgetMacNSWindow {
|
||||
@private
|
||||
bool is_frameless_;
|
||||
}
|
||||
- (id)initWithStyle:(NSUInteger)style_mask isFrameless:(bool)is_frameless;
|
||||
|
||||
- (BOOL)shouldCenterTrafficLights;
|
||||
@end
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_NS_WINDOW_H_
|
|
@ -0,0 +1,104 @@
|
|||
// Copyright 2023 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.
|
||||
|
||||
#include "libcef/browser/views/ns_window.h"
|
||||
|
||||
#include "base/i18n/rtl.h"
|
||||
#include "components/remote_cocoa/app_shim/native_widget_ns_window_bridge.h"
|
||||
#include "components/remote_cocoa/common/native_widget_ns_window_host.mojom.h"
|
||||
#include "ui/base/cocoa/window_size_constants.h"
|
||||
|
||||
@interface CefThemeFrame : NativeWidgetMacNSWindowTitledFrame
|
||||
@end
|
||||
|
||||
// NSThemeFrame (PrivateAPI) definitions.
|
||||
@interface NSThemeFrame (PrivateAPI)
|
||||
- (void)setStyleMask:(NSUInteger)styleMask;
|
||||
- (CGFloat)_titlebarHeight;
|
||||
- (BOOL)_shouldCenterTrafficLights;
|
||||
@end
|
||||
|
||||
@implementation CefThemeFrame {
|
||||
bool in_full_screen_;
|
||||
}
|
||||
|
||||
// NSThemeFrame (PrivateAPI) overrides.
|
||||
- (void)setStyleMask:(NSUInteger)styleMask {
|
||||
in_full_screen_ = (styleMask & NSWindowStyleMaskFullScreen) != 0;
|
||||
[super setStyleMask:styleMask];
|
||||
}
|
||||
|
||||
- (CGFloat)_titlebarHeight {
|
||||
if (!in_full_screen_) {
|
||||
bool override_titlebar_height = false;
|
||||
float titlebar_height = 0;
|
||||
auto* window = base::mac::ObjCCast<CefNSWindow>([self window]);
|
||||
if (auto* bridge = [window bridge]) {
|
||||
bridge->host()->GetWindowFrameTitlebarHeight(&override_titlebar_height,
|
||||
&titlebar_height);
|
||||
|
||||
if (override_titlebar_height)
|
||||
return titlebar_height;
|
||||
}
|
||||
}
|
||||
|
||||
return [super _titlebarHeight];
|
||||
}
|
||||
|
||||
- (BOOL)_shouldCenterTrafficLights {
|
||||
auto* window = base::mac::ObjCCast<CefNSWindow>([self window]);
|
||||
return [window shouldCenterTrafficLights];
|
||||
}
|
||||
|
||||
- (BOOL)_shouldFlipTrafficLightsForRTL {
|
||||
return base::i18n::IsRTL() ? YES : NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@interface NSWindow (PrivateAPI)
|
||||
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle;
|
||||
@end
|
||||
|
||||
@implementation CefNSWindow
|
||||
|
||||
- (id)initWithStyle:(NSUInteger)style_mask isFrameless:(bool)is_frameless {
|
||||
if ((self = [super initWithContentRect:ui::kWindowSizeDeterminedLater
|
||||
styleMask:style_mask
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO])) {
|
||||
is_frameless_ = is_frameless;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)shouldCenterTrafficLights {
|
||||
return is_frameless_ ? YES : NO;
|
||||
}
|
||||
|
||||
// NSWindow overrides.
|
||||
- (NSRect)contentRectForFrameRect:(NSRect)frameRect {
|
||||
if (is_frameless_) {
|
||||
return frameRect;
|
||||
}
|
||||
return [super contentRectForFrameRect:frameRect];
|
||||
}
|
||||
|
||||
- (NSRect)frameRectForContentRect:(NSRect)contentRect {
|
||||
if (is_frameless_) {
|
||||
return contentRect;
|
||||
}
|
||||
return [super frameRectForContentRect:contentRect];
|
||||
}
|
||||
|
||||
// NSWindow (PrivateAPI) overrides.
|
||||
+ (Class)frameViewClassForStyleMask:(NSUInteger)windowStyle {
|
||||
if (Class custom_frame = [CefThemeFrame class]) {
|
||||
return custom_frame;
|
||||
}
|
||||
|
||||
return [super frameViewClassForStyleMask:windowStyle];
|
||||
}
|
||||
|
||||
@end
|
|
@ -9,6 +9,7 @@
|
|||
#include "include/views/cef_view.h"
|
||||
#include "include/views/cef_window.h"
|
||||
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "ui/gfx/native_widget_types.h"
|
||||
#include "ui/views/view.h"
|
||||
|
||||
|
@ -21,8 +22,12 @@ class Point;
|
|||
}
|
||||
|
||||
namespace views {
|
||||
class NativeWidget;
|
||||
class Widget;
|
||||
namespace internal {
|
||||
class NativeWidgetDelegate;
|
||||
}
|
||||
} // namespace views
|
||||
|
||||
#define CEF_REQUIRE_VALID_RETURN(ret) \
|
||||
if (!ParentClass::IsValid()) \
|
||||
|
@ -141,6 +146,12 @@ CefWindowHandle GetWindowHandle(views::Widget* widget);
|
|||
// Returns the platform window handle for |window|. May return nullptr.
|
||||
CefWindowHandle GetWindowHandle(gfx::NativeWindow window);
|
||||
|
||||
views::NativeWidget* CreateNativeWidget(
|
||||
views::internal::NativeWidgetDelegate* delegate,
|
||||
bool is_frameless,
|
||||
bool with_window_buttons,
|
||||
absl::optional<float> title_bar_height);
|
||||
|
||||
} // namespace view_util
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_VIEW_UTIL_H_
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "ui/aura/window.h"
|
||||
#include "ui/aura/window_tree_host.h"
|
||||
#include "ui/views/widget/native_widget.h"
|
||||
#include "ui/views/widget/native_widget_delegate.h"
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
namespace view_util {
|
||||
|
@ -40,4 +42,12 @@ CefWindowHandle GetWindowHandle(gfx::NativeWindow window) {
|
|||
return kNullWindowHandle;
|
||||
}
|
||||
|
||||
views::NativeWidget* CreateNativeWidget(
|
||||
views::internal::NativeWidgetDelegate* delegate,
|
||||
bool is_frameless,
|
||||
bool with_window_buttons,
|
||||
absl::optional<float> title_bar_height) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace view_util
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#include "include/internal/cef_types_mac.h"
|
||||
#include "libcef/browser/views/native_widget_mac.h"
|
||||
|
||||
#include "ui/views/widget/widget.h"
|
||||
|
||||
|
@ -44,4 +45,12 @@ CefWindowHandle GetWindowHandle(gfx::NativeWindow window) {
|
|||
return kNullWindowHandle;
|
||||
}
|
||||
|
||||
views::NativeWidget* CreateNativeWidget(
|
||||
views::internal::NativeWidgetDelegate* delegate,
|
||||
bool is_frameless,
|
||||
bool with_window_buttons,
|
||||
absl::optional<float> title_bar_height) {
|
||||
return new CefNativeWidgetMac(delegate, is_frameless, with_window_buttons,
|
||||
title_bar_height);
|
||||
}
|
||||
} // namespace view_util
|
||||
|
|
|
@ -312,6 +312,15 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
|
|||
DCHECK(!params.bounds.IsEmpty());
|
||||
} else {
|
||||
is_frameless_ = cef_delegate()->IsFrameless(cef_window);
|
||||
|
||||
const bool with_standard_buttons =
|
||||
cef_delegate()->WithStandardWindowButtons(cef_window);
|
||||
|
||||
const auto title_bar_height = GetTitlebarHeight(cef_window);
|
||||
|
||||
params.native_widget = view_util::CreateNativeWidget(
|
||||
widget, is_frameless_, with_standard_buttons, title_bar_height);
|
||||
|
||||
can_resize = cef_delegate()->CanResize(cef_window);
|
||||
|
||||
const auto show_state = cef_delegate()->GetInitialShowState(cef_window);
|
||||
|
@ -657,3 +666,14 @@ views::NonClientFrameView* CefWindowView::GetNonClientFrameView() const {
|
|||
}
|
||||
return widget->non_client_view()->frame_view();
|
||||
}
|
||||
|
||||
absl::optional<float> CefWindowView::GetTitlebarHeight(
|
||||
const CefRefPtr<CefWindow>& window) const {
|
||||
float title_bar_height = 0;
|
||||
const bool has_title_bar_height =
|
||||
cef_delegate()->GetTitlebarHeight(window, &title_bar_height);
|
||||
if (has_title_bar_height) {
|
||||
return title_bar_height;
|
||||
}
|
||||
return absl::nullopt;
|
||||
}
|
|
@ -14,6 +14,7 @@
|
|||
#include "libcef/browser/views/overlay_view_host.h"
|
||||
#include "libcef/browser/views/panel_view.h"
|
||||
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "third_party/skia/include/core/SkRegion.h"
|
||||
#include "ui/display/display.h"
|
||||
#include "ui/views/widget/widget_delegate.h"
|
||||
|
@ -119,6 +120,9 @@ class CefWindowView
|
|||
|
||||
void MoveOverlaysIfNecessary();
|
||||
|
||||
absl::optional<float> GetTitlebarHeight(
|
||||
const CefRefPtr<CefWindow>& window) const;
|
||||
|
||||
// Not owned by this object.
|
||||
Delegate* window_delegate_;
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=af80a36cdcb47a18eb1ac8bc3315dfd322f4e96e$
|
||||
// $hash=18f715de465689a4e8484bbced8ad92d9434438a$
|
||||
//
|
||||
|
||||
#include "libcef_dll/cpptoc/views/window_delegate_cpptoc.h"
|
||||
|
@ -270,6 +270,62 @@ window_delegate_is_frameless(struct _cef_window_delegate_t* self,
|
|||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK window_delegate_with_standard_window_buttons(
|
||||
struct _cef_window_delegate_t* self,
|
||||
cef_window_t* window) {
|
||||
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;
|
||||
}
|
||||
|
||||
// Execute
|
||||
bool _retval = CefWindowDelegateCppToC::Get(self)->WithStandardWindowButtons(
|
||||
CefWindowCToCpp::Wrap(window));
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK
|
||||
window_delegate_get_titlebar_height(struct _cef_window_delegate_t* self,
|
||||
cef_window_t* window,
|
||||
float* titlebar_height) {
|
||||
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: titlebar_height; type: simple_byaddr
|
||||
DCHECK(titlebar_height);
|
||||
if (!titlebar_height) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Execute
|
||||
bool _retval = CefWindowDelegateCppToC::Get(self)->GetTitlebarHeight(
|
||||
CefWindowCToCpp::Wrap(window), titlebar_height);
|
||||
|
||||
// Return type: bool
|
||||
return _retval;
|
||||
}
|
||||
|
||||
int CEF_CALLBACK window_delegate_can_resize(struct _cef_window_delegate_t* self,
|
||||
cef_window_t* window) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
@ -705,6 +761,9 @@ CefWindowDelegateCppToC::CefWindowDelegateCppToC() {
|
|||
GetStruct()->get_initial_bounds = window_delegate_get_initial_bounds;
|
||||
GetStruct()->get_initial_show_state = window_delegate_get_initial_show_state;
|
||||
GetStruct()->is_frameless = window_delegate_is_frameless;
|
||||
GetStruct()->with_standard_window_buttons =
|
||||
window_delegate_with_standard_window_buttons;
|
||||
GetStruct()->get_titlebar_height = window_delegate_get_titlebar_height;
|
||||
GetStruct()->can_resize = window_delegate_can_resize;
|
||||
GetStruct()->can_maximize = window_delegate_can_maximize;
|
||||
GetStruct()->can_minimize = window_delegate_can_minimize;
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=18f601c8e152c39928595e1f02c9274f0dc6ce8a$
|
||||
// $hash=40aea12873a3c8803c9d2d6c06a0270197ead58e$
|
||||
//
|
||||
|
||||
#include "libcef_dll/ctocpp/views/window_delegate_ctocpp.h"
|
||||
|
@ -257,6 +257,63 @@ bool CefWindowDelegateCToCpp::IsFrameless(CefRefPtr<CefWindow> window) {
|
|||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefWindowDelegateCToCpp::WithStandardWindowButtons(
|
||||
CefRefPtr<CefWindow> window) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_window_delegate_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, with_standard_window_buttons)) {
|
||||
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->with_standard_window_buttons(
|
||||
_struct, CefWindowCppToC::Wrap(window));
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefWindowDelegateCToCpp::GetTitlebarHeight(CefRefPtr<CefWindow> window,
|
||||
float* titlebar_height) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
||||
cef_window_delegate_t* _struct = GetStruct();
|
||||
if (CEF_MEMBER_MISSING(_struct, get_titlebar_height)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
|
||||
|
||||
// Verify param: window; type: refptr_diff
|
||||
DCHECK(window.get());
|
||||
if (!window.get()) {
|
||||
return false;
|
||||
}
|
||||
// Verify param: titlebar_height; type: simple_byaddr
|
||||
DCHECK(titlebar_height);
|
||||
if (!titlebar_height) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Execute
|
||||
int _retval = _struct->get_titlebar_height(
|
||||
_struct, CefWindowCppToC::Wrap(window), titlebar_height);
|
||||
|
||||
// Return type: bool
|
||||
return _retval ? true : false;
|
||||
}
|
||||
|
||||
NO_SANITIZE("cfi-icall")
|
||||
bool CefWindowDelegateCToCpp::CanResize(CefRefPtr<CefWindow> window) {
|
||||
shutdown_checker::AssertNotShutdown();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// implementations. See the translator.README.txt file in the tools directory
|
||||
// for more information.
|
||||
//
|
||||
// $hash=1a923e68b1e07234f97d3c219cc70cc91c118a77$
|
||||
// $hash=d100d8866a7eab2a163d4ddb3cacd00141f65757$
|
||||
//
|
||||
|
||||
#ifndef CEF_LIBCEF_DLL_CTOCPP_VIEWS_WINDOW_DELEGATE_CTOCPP_H_
|
||||
|
@ -50,6 +50,9 @@ class CefWindowDelegateCToCpp
|
|||
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override;
|
||||
cef_show_state_t GetInitialShowState(CefRefPtr<CefWindow> window) override;
|
||||
bool IsFrameless(CefRefPtr<CefWindow> window) override;
|
||||
bool WithStandardWindowButtons(CefRefPtr<CefWindow> window) override;
|
||||
bool GetTitlebarHeight(CefRefPtr<CefWindow> window,
|
||||
float* titlebar_height) override;
|
||||
bool CanResize(CefRefPtr<CefWindow> window) override;
|
||||
bool CanMaximize(CefRefPtr<CefWindow> window) override;
|
||||
bool CanMinimize(CefRefPtr<CefWindow> window) override;
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "tests/cefclient/browser/views_overlay_controls.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "include/views/cef_box_layout.h"
|
||||
|
@ -34,9 +35,37 @@ std::string GetLabel(ViewsOverlayControls::Command command, bool maximized) {
|
|||
return std::string();
|
||||
}
|
||||
|
||||
std::array<ViewsOverlayControls::Command, 3> GetButtons() {
|
||||
#if defined(OS_MAC)
|
||||
return {ViewsOverlayControls::Command::kClose,
|
||||
ViewsOverlayControls::Command::kMaximize,
|
||||
ViewsOverlayControls::Command::kMinimize};
|
||||
#else
|
||||
return {ViewsOverlayControls::Command::kMinimize,
|
||||
ViewsOverlayControls::Command::kMaximize,
|
||||
ViewsOverlayControls::Command::kClose};
|
||||
#endif
|
||||
}
|
||||
|
||||
cef_docking_mode_t GetPanelDockingMode() {
|
||||
#if defined(OS_MAC)
|
||||
return CEF_DOCKING_MODE_TOP_LEFT;
|
||||
#else
|
||||
return CEF_DOCKING_MODE_TOP_RIGHT;
|
||||
#endif
|
||||
}
|
||||
cef_docking_mode_t GetMenuDockingMode() {
|
||||
#if defined(OS_MAC)
|
||||
return CEF_DOCKING_MODE_TOP_RIGHT;
|
||||
#else
|
||||
return CEF_DOCKING_MODE_TOP_LEFT;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
ViewsOverlayControls::ViewsOverlayControls() = default;
|
||||
ViewsOverlayControls::ViewsOverlayControls(bool with_window_buttons)
|
||||
: with_window_buttons_(with_window_buttons) {}
|
||||
|
||||
void ViewsOverlayControls::Initialize(CefRefPtr<CefWindow> window,
|
||||
CefRefPtr<CefMenuButton> menu_button,
|
||||
|
@ -49,9 +78,11 @@ void ViewsOverlayControls::Initialize(CefRefPtr<CefWindow> window,
|
|||
window_ = window;
|
||||
window_maximized_ = window_->IsMaximized();
|
||||
|
||||
// Window control buttons. These controls are currently text which means that
|
||||
// we can't use a transparent background because subpixel text rendering will
|
||||
// break. See comments on the related DCHECK in Label::PaintText.
|
||||
if (with_window_buttons_) {
|
||||
// Window control buttons. These controls are currently text which means
|
||||
// that we can't use a transparent background because subpixel text
|
||||
// rendering will break.
|
||||
// See comments on the related DCHECK in Label::PaintText.
|
||||
panel_ = CefPanel::CreatePanel(nullptr);
|
||||
views_style::ApplyTo(panel_);
|
||||
|
||||
|
@ -60,19 +91,18 @@ void ViewsOverlayControls::Initialize(CefRefPtr<CefWindow> window,
|
|||
panel_layout_settings.horizontal = true;
|
||||
panel_->SetToBoxLayout(panel_layout_settings);
|
||||
|
||||
panel_->AddChildView(CreateButton(ViewsOverlayControls::Command::kMinimize));
|
||||
panel_->AddChildView(CreateButton(ViewsOverlayControls::Command::kMaximize));
|
||||
panel_->AddChildView(CreateButton(ViewsOverlayControls::Command::kClose));
|
||||
|
||||
panel_controller_ =
|
||||
window->AddOverlayView(panel_, CEF_DOCKING_MODE_TOP_RIGHT);
|
||||
for (auto button : GetButtons()) {
|
||||
panel_->AddChildView(CreateButton(button));
|
||||
}
|
||||
panel_controller_ = window->AddOverlayView(panel_, GetPanelDockingMode());
|
||||
panel_controller_->SetInsets(CefInsets(kInsets, kInsets, 0, kInsets));
|
||||
panel_controller_->SetVisible(true);
|
||||
}
|
||||
|
||||
// Menu button.
|
||||
menu_button->SetBackgroundColor(kBackgroundColor);
|
||||
menu_controller_ =
|
||||
window_->AddOverlayView(menu_button, CEF_DOCKING_MODE_TOP_LEFT);
|
||||
menu_controller_->SetInsets(CefInsets(kInsets, kInsets, 0, 0));
|
||||
menu_controller_ = window_->AddOverlayView(menu_button, GetMenuDockingMode());
|
||||
menu_controller_->SetInsets(CefInsets(kInsets, kInsets, 0, kInsets));
|
||||
menu_controller_->SetVisible(true);
|
||||
|
||||
// Location bar. Will be made visible in UpdateControls().
|
||||
|
@ -87,8 +117,10 @@ void ViewsOverlayControls::Initialize(CefRefPtr<CefWindow> window,
|
|||
void ViewsOverlayControls::Destroy() {
|
||||
window_ = nullptr;
|
||||
panel_ = nullptr;
|
||||
if (panel_controller_) {
|
||||
panel_controller_->Destroy();
|
||||
panel_controller_ = nullptr;
|
||||
}
|
||||
menu_controller_->Destroy();
|
||||
menu_controller_ = nullptr;
|
||||
location_bar_ = nullptr;
|
||||
|
@ -180,7 +212,7 @@ CefRefPtr<CefLabelButton> ViewsOverlayControls::CreateButton(Command command) {
|
|||
}
|
||||
|
||||
void ViewsOverlayControls::MaybeUpdateMaximizeButton() {
|
||||
if (window_->IsMaximized() == window_maximized_) {
|
||||
if (!with_window_buttons_ || window_->IsMaximized() == window_maximized_) {
|
||||
return;
|
||||
}
|
||||
window_maximized_ = !window_maximized_;
|
||||
|
|
|
@ -25,7 +25,7 @@ class ViewsOverlayControls : public CefButtonDelegate {
|
|||
kClose,
|
||||
};
|
||||
|
||||
ViewsOverlayControls();
|
||||
explicit ViewsOverlayControls(bool with_window_buttons);
|
||||
|
||||
void Initialize(CefRefPtr<CefWindow> window,
|
||||
CefRefPtr<CefMenuButton> menu_button,
|
||||
|
@ -53,6 +53,7 @@ class ViewsOverlayControls : public CefButtonDelegate {
|
|||
// Window control buttons.
|
||||
CefRefPtr<CefPanel> panel_;
|
||||
CefRefPtr<CefOverlayController> panel_controller_;
|
||||
const bool with_window_buttons_;
|
||||
|
||||
// Location bar.
|
||||
CefRefPtr<CefView> location_bar_;
|
||||
|
|
|
@ -34,6 +34,11 @@ const char kDefaultExtensionIcon[] = "window_icon";
|
|||
constexpr int kDefaultWidth = 800;
|
||||
constexpr int kDefaultHeight = 600;
|
||||
|
||||
#if defined(OS_MAC)
|
||||
constexpr int kTitleBarHeight = 35;
|
||||
constexpr int kWindowButtonsWidth = 80;
|
||||
#endif
|
||||
|
||||
// Control IDs for Views in the top-level Window.
|
||||
enum ControlIds {
|
||||
ID_WINDOW = 1,
|
||||
|
@ -106,6 +111,22 @@ void AddFileMenuItems(CefRefPtr<CefMenuModel> file_menu) {
|
|||
true);
|
||||
}
|
||||
|
||||
CefBrowserViewDelegate::ChromeToolbarType CalculateChromeToolbarType(
|
||||
const std::string& toolbar_type,
|
||||
bool hide_toolbar,
|
||||
bool with_overlay_controls) {
|
||||
if (!MainContext::Get()->UseChromeRuntime() || toolbar_type == "none" ||
|
||||
hide_toolbar) {
|
||||
return CEF_CTT_NONE;
|
||||
}
|
||||
|
||||
if (toolbar_type == "location") {
|
||||
return CEF_CTT_LOCATION;
|
||||
}
|
||||
|
||||
return with_overlay_controls ? CEF_CTT_LOCATION : CEF_CTT_NORMAL;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
|
@ -278,17 +299,13 @@ void ViewsWindow::SetDraggableRegions(
|
|||
return;
|
||||
}
|
||||
|
||||
std::vector<CefDraggableRegion> window_regions;
|
||||
|
||||
// Convert the regions from BrowserView to Window coordinates.
|
||||
std::vector<CefDraggableRegion>::const_iterator it = regions.begin();
|
||||
for (; it != regions.end(); ++it) {
|
||||
CefDraggableRegion region = *it;
|
||||
std::vector<CefDraggableRegion> window_regions = regions;
|
||||
for (auto& region : window_regions) {
|
||||
CefPoint origin = CefPoint(region.bounds.x, region.bounds.y);
|
||||
browser_view_->ConvertPointToWindow(origin);
|
||||
region.bounds.x = origin.x;
|
||||
region.bounds.y = origin.y;
|
||||
window_regions.push_back(region);
|
||||
}
|
||||
|
||||
if (overlay_controls_) {
|
||||
|
@ -653,6 +670,14 @@ void ViewsWindow::OnWindowBoundsChanged(CefRefPtr<CefWindow> window,
|
|||
// Track the last visible bounds for window restore purposes.
|
||||
last_visible_bounds_ = new_bounds;
|
||||
}
|
||||
|
||||
#if defined(OS_MAC)
|
||||
if (frameless_ && with_standard_buttons_ && top_toolbar_) {
|
||||
auto insets = top_toolbar_->GetInsets();
|
||||
insets.left = window->IsFullscreen() ? 0 : kWindowButtonsWidth;
|
||||
top_toolbar_->SetInsets(insets);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ViewsWindow::CanClose(CefRefPtr<CefWindow> window) {
|
||||
|
@ -701,6 +726,24 @@ bool ViewsWindow::IsFrameless(CefRefPtr<CefWindow> window) {
|
|||
return frameless_;
|
||||
}
|
||||
|
||||
bool ViewsWindow::WithStandardWindowButtons(CefRefPtr<CefWindow> window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
return with_standard_buttons_;
|
||||
}
|
||||
|
||||
bool ViewsWindow::GetTitlebarHeight(CefRefPtr<CefWindow> window,
|
||||
float* titlebar_height) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
#if defined(OS_MAC)
|
||||
if (frameless_ && with_standard_buttons_) {
|
||||
*titlebar_height = kTitleBarHeight;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ViewsWindow::CanResize(CefRefPtr<CefWindow> window) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
// Don't allow windows hosting extensions to resize.
|
||||
|
@ -815,7 +858,9 @@ void ViewsWindow::OnWindowChanged(CefRefPtr<CefView> view, bool added) {
|
|||
}
|
||||
|
||||
if (with_overlay_controls_) {
|
||||
overlay_controls_ = new ViewsOverlayControls();
|
||||
// Add window buttons if we don't have standard ones
|
||||
const bool with_window_buttons = !with_standard_buttons_;
|
||||
overlay_controls_ = new ViewsOverlayControls(with_window_buttons);
|
||||
overlay_controls_->Initialize(window_, CreateMenuButton(),
|
||||
CreateLocationBar(),
|
||||
chrome_toolbar_type_ != CEF_CTT_NONE);
|
||||
|
@ -865,6 +910,10 @@ ViewsWindow::ViewsWindow(Delegate* delegate,
|
|||
|
||||
const bool hide_frame = command_line->HasSwitch(switches::kHideFrame);
|
||||
const bool hide_overlays = command_line->HasSwitch(switches::kHideOverlays);
|
||||
const bool hide_toolbar =
|
||||
hide_frame && hide_overlays && !delegate_->WithControls();
|
||||
const bool show_window_buttons =
|
||||
command_line->HasSwitch(switches::kShowWindowButtons);
|
||||
|
||||
// Without a window frame.
|
||||
frameless_ = hide_frame || delegate_->WithExtension();
|
||||
|
@ -873,20 +922,13 @@ ViewsWindow::ViewsWindow(Delegate* delegate,
|
|||
with_overlay_controls_ =
|
||||
hide_frame && !hide_overlays && !delegate_->WithControls();
|
||||
|
||||
if (MainContext::Get()->UseChromeRuntime()) {
|
||||
// If window has frame or flag passed explicitly
|
||||
with_standard_buttons_ = !frameless_ || show_window_buttons;
|
||||
|
||||
const std::string& toolbar_type =
|
||||
command_line->GetSwitchValue(switches::kShowChromeToolbar);
|
||||
if (toolbar_type == "none") {
|
||||
chrome_toolbar_type_ = CEF_CTT_NONE;
|
||||
} else if (toolbar_type == "location") {
|
||||
chrome_toolbar_type_ = CEF_CTT_LOCATION;
|
||||
} else {
|
||||
chrome_toolbar_type_ =
|
||||
with_overlay_controls_ ? CEF_CTT_LOCATION : CEF_CTT_NORMAL;
|
||||
}
|
||||
} else {
|
||||
chrome_toolbar_type_ = CEF_CTT_NONE;
|
||||
}
|
||||
chrome_toolbar_type_ = CalculateChromeToolbarType(toolbar_type, hide_toolbar,
|
||||
with_overlay_controls_);
|
||||
|
||||
#if !defined(OS_MAC)
|
||||
// On Mac we don't show a top menu on the window. The options are available in
|
||||
|
@ -1025,9 +1067,8 @@ void ViewsWindow::AddControls() {
|
|||
top_panel->SetToBoxLayout(top_panel_layout_settings);
|
||||
|
||||
// Add the buttons and URL textfield to |top_panel|.
|
||||
for (size_t i = 0U; i < browse_buttons.size(); ++i) {
|
||||
top_panel->AddChildView(browse_buttons[i]);
|
||||
}
|
||||
for (auto& browse_button : browse_buttons)
|
||||
top_panel->AddChildView(browse_button);
|
||||
top_panel->AddChildView(location_bar_);
|
||||
|
||||
UpdateExtensionControls();
|
||||
|
@ -1043,6 +1084,14 @@ void ViewsWindow::AddControls() {
|
|||
top_toolbar_ = top_panel;
|
||||
}
|
||||
|
||||
#if defined(OS_MAC)
|
||||
if (frameless_ && with_standard_buttons_) {
|
||||
auto insets = top_toolbar_->GetInsets();
|
||||
insets.left = kWindowButtonsWidth;
|
||||
top_toolbar_->SetInsets(insets);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Add the top panel and browser view to |window|.
|
||||
int top_index = 0;
|
||||
if (top_menu_panel) {
|
||||
|
@ -1061,8 +1110,10 @@ void ViewsWindow::AddControls() {
|
|||
// Lay out |window| again with the new button sizes.
|
||||
window_->Layout();
|
||||
|
||||
const int buttons_number = static_cast<int>(browse_buttons.size());
|
||||
|
||||
// Minimum window width is the size of all buttons plus some extra.
|
||||
min_width = browse_buttons[0]->GetBounds().width * 4 +
|
||||
min_width = browse_buttons[0]->GetBounds().width * buttons_number +
|
||||
menu_button_->GetBounds().width + 100;
|
||||
}
|
||||
|
||||
|
|
|
@ -174,6 +174,9 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||
CefRect GetInitialBounds(CefRefPtr<CefWindow> window) override;
|
||||
cef_show_state_t GetInitialShowState(CefRefPtr<CefWindow> window) override;
|
||||
bool IsFrameless(CefRefPtr<CefWindow> window) override;
|
||||
bool WithStandardWindowButtons(CefRefPtr<CefWindow> window) override;
|
||||
bool GetTitlebarHeight(CefRefPtr<CefWindow> window,
|
||||
float* titlebar_height) override;
|
||||
bool CanResize(CefRefPtr<CefWindow> window) override;
|
||||
bool CanClose(CefRefPtr<CefWindow> window) override;
|
||||
bool OnAccelerator(CefRefPtr<CefWindow> window, int command_id) override;
|
||||
|
@ -238,6 +241,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
|||
bool frameless_;
|
||||
bool with_controls_;
|
||||
bool with_overlay_controls_;
|
||||
bool with_standard_buttons_;
|
||||
ChromeToolbarType chrome_toolbar_type_;
|
||||
CefRefPtr<CefWindow> window_;
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ const char kHideChromeStatusBubble[] = "hide-chrome-status-bubble";
|
|||
const char kUseDefaultPopup[] = "use-default-popup";
|
||||
const char kUseClientDialogs[] = "use-client-dialogs";
|
||||
const char kUseTestHttpServer[] = "use-test-http-server";
|
||||
const char kShowWindowButtons[] = "show-window-buttons";
|
||||
|
||||
} // namespace switches
|
||||
} // namespace client
|
||||
|
|
|
@ -46,6 +46,7 @@ extern const char kHideChromeStatusBubble[];
|
|||
extern const char kUseDefaultPopup[];
|
||||
extern const char kUseClientDialogs[];
|
||||
extern const char kUseTestHttpServer[];
|
||||
extern const char kShowWindowButtons[];
|
||||
|
||||
} // namespace switches
|
||||
} // namespace client
|
||||
|
|
Loading…
Reference in New Issue