mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-02-03 04:27:43 +01:00
views: mac: Support dynamic resize of title bar height (see #3189)
This is intended for usage with frameless windows that show the standard window buttons, where resizing the title bar height changes the button offset. Returning a different value from CefWindowDelegate::GetTitlebarHeight and forcing a resize of the NSWindow's theme frame (see ViewsWindow::NudgeWindow) will update the title bar height. To test: 1. Run `cefclient --use-views --hide-frame --show-window-buttons --url=http://tests/window` 2. Enter a new value for title bar height and click the "Set Titlebar Height" button
This commit is contained in:
parent
0a2c7a1070
commit
c83b3cda24
@ -393,6 +393,7 @@
|
||||
'tests/cefclient/browser/temp_window_mac.mm',
|
||||
'tests/cefclient/browser/text_input_client_osr_mac.h',
|
||||
'tests/cefclient/browser/text_input_client_osr_mac.mm',
|
||||
'tests/cefclient/browser/views_window_mac.mm',
|
||||
'tests/cefclient/browser/window_test_runner_mac.h',
|
||||
'tests/cefclient/browser/window_test_runner_mac.mm',
|
||||
'tests/cefclient/cefclient_mac.mm',
|
||||
|
@ -6,15 +6,18 @@
|
||||
#define CEF_LIBCEF_BROWSER_VIEWS_NATIVE_WIDGET_MAC_H_
|
||||
#pragma once
|
||||
|
||||
#include "third_party/abseil-cpp/absl/types/optional.h"
|
||||
#include "include/internal/cef_ptr.h"
|
||||
|
||||
#include "ui/views/widget/native_widget_mac.h"
|
||||
|
||||
class CefWindow;
|
||||
class CefWindowDelegate;
|
||||
|
||||
class CefNativeWidgetMac : public views::NativeWidgetMac {
|
||||
public:
|
||||
CefNativeWidgetMac(views::internal::NativeWidgetDelegate* delegate,
|
||||
bool is_frameless,
|
||||
bool with_window_buttons,
|
||||
absl::optional<float> title_bar_height);
|
||||
CefRefPtr<CefWindow> window,
|
||||
CefWindowDelegate* window_delegate);
|
||||
~CefNativeWidgetMac() override = default;
|
||||
|
||||
CefNativeWidgetMac(const CefNativeWidgetMac&) = delete;
|
||||
@ -29,9 +32,8 @@ class CefNativeWidgetMac : public views::NativeWidgetMac {
|
||||
float* titlebar_height) override;
|
||||
|
||||
private:
|
||||
const bool is_frameless_;
|
||||
const bool with_window_buttons_;
|
||||
const absl::optional<float> title_bar_height_;
|
||||
const CefRefPtr<CefWindow> window_;
|
||||
CefWindowDelegate* const window_delegate_;
|
||||
};
|
||||
|
||||
#endif // CEF_LIBCEF_BROWSER_VIEWS_NATIVE_WIDGET_MAC_H_
|
||||
|
@ -4,17 +4,17 @@
|
||||
|
||||
#include "libcef/browser/views/native_widget_mac.h"
|
||||
|
||||
#include "include/views/cef_window.h"
|
||||
#include "include/views/cef_window_delegate.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)
|
||||
CefRefPtr<CefWindow> window,
|
||||
CefWindowDelegate* window_delegate)
|
||||
: views::NativeWidgetMac(delegate),
|
||||
is_frameless_(is_frameless),
|
||||
with_window_buttons_(with_window_buttons),
|
||||
title_bar_height_(title_bar_height) {}
|
||||
window_(window),
|
||||
window_delegate_(window_delegate) {}
|
||||
|
||||
NativeWidgetMacNSWindow* CefNativeWidgetMac::CreateNSWindow(
|
||||
const remote_cocoa::mojom::CreateWindowParams* params) {
|
||||
@ -22,15 +22,18 @@ NativeWidgetMacNSWindow* CefNativeWidgetMac::CreateNSWindow(
|
||||
NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable |
|
||||
NSWindowStyleMaskClosable | NSWindowStyleMaskResizable |
|
||||
NSWindowStyleMaskTexturedBackground;
|
||||
auto window = [[CefNSWindow alloc] initWithStyle:style_mask
|
||||
isFrameless:is_frameless_];
|
||||
|
||||
if (is_frameless_) {
|
||||
bool is_frameless = window_delegate_->IsFrameless(window_);
|
||||
|
||||
auto window = [[CefNSWindow alloc] initWithStyle:style_mask
|
||||
isFrameless:is_frameless];
|
||||
|
||||
if (is_frameless) {
|
||||
[window setTitlebarAppearsTransparent:YES];
|
||||
[window setTitleVisibility:NSWindowTitleHidden];
|
||||
}
|
||||
|
||||
if (!with_window_buttons_) {
|
||||
if (!window_delegate_->WithStandardWindowButtons(window_)) {
|
||||
[[window standardWindowButton:NSWindowCloseButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowMiniaturizeButton] setHidden:YES];
|
||||
[[window standardWindowButton:NSWindowZoomButton] setHidden:YES];
|
||||
@ -42,9 +45,8 @@ NativeWidgetMacNSWindow* CefNativeWidgetMac::CreateNSWindow(
|
||||
void CefNativeWidgetMac::GetWindowFrameTitlebarHeight(
|
||||
bool* override_titlebar_height,
|
||||
float* titlebar_height) {
|
||||
if (title_bar_height_) {
|
||||
if (window_delegate_->GetTitlebarHeight(window_, titlebar_height)) {
|
||||
*override_titlebar_height = true;
|
||||
*titlebar_height = title_bar_height_.value();
|
||||
} else {
|
||||
views::NativeWidgetMac::GetWindowFrameTitlebarHeight(
|
||||
override_titlebar_height, titlebar_height);
|
||||
|
@ -9,7 +9,6 @@
|
||||
#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"
|
||||
|
||||
@ -29,6 +28,8 @@ class NativeWidgetDelegate;
|
||||
}
|
||||
} // namespace views
|
||||
|
||||
class CefWindowDelegate;
|
||||
|
||||
#define CEF_REQUIRE_VALID_RETURN(ret) \
|
||||
if (!ParentClass::IsValid()) \
|
||||
return ret;
|
||||
@ -148,9 +149,8 @@ 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);
|
||||
CefRefPtr<CefWindow> window,
|
||||
CefWindowDelegate* window_delegate);
|
||||
|
||||
} // namespace view_util
|
||||
|
||||
|
@ -44,9 +44,8 @@ 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) {
|
||||
CefRefPtr<CefWindow> window,
|
||||
CefWindowDelegate* window_delegate) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -47,10 +47,8 @@ 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) {
|
||||
return new CefNativeWidgetMac(delegate, is_frameless, with_window_buttons,
|
||||
title_bar_height);
|
||||
CefRefPtr<CefWindow> window,
|
||||
CefWindowDelegate* window_delegate) {
|
||||
return new CefNativeWidgetMac(delegate, window, window_delegate);
|
||||
}
|
||||
} // namespace view_util
|
||||
|
@ -313,13 +313,8 @@ void CefWindowView::CreateWidget(gfx::AcceleratedWidget parent_widget) {
|
||||
} 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);
|
||||
params.native_widget =
|
||||
view_util::CreateNativeWidget(widget, cef_window, cef_delegate());
|
||||
|
||||
can_resize = cef_delegate()->CanResize(cef_window);
|
||||
|
||||
@ -666,14 +661,3 @@ 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,7 +14,6 @@
|
||||
#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"
|
||||
@ -120,9 +119,6 @@ class CefWindowView
|
||||
|
||||
void MoveOverlaysIfNecessary();
|
||||
|
||||
absl::optional<float> GetTitlebarHeight(
|
||||
const CefRefPtr<CefWindow>& window) const;
|
||||
|
||||
// Not owned by this object.
|
||||
Delegate* window_delegate_;
|
||||
|
||||
|
@ -28,6 +28,12 @@ RootWindowViews::~RootWindowViews() {
|
||||
REQUIRE_MAIN_THREAD();
|
||||
}
|
||||
|
||||
void RootWindowViews::SetTitlebarHeight(const std::optional<float>& height) {
|
||||
if (window_) {
|
||||
window_->SetTitlebarHeight(height);
|
||||
}
|
||||
}
|
||||
|
||||
void RootWindowViews::Init(RootWindow::Delegate* delegate,
|
||||
std::unique_ptr<RootWindowConfig> config,
|
||||
const CefBrowserSettings& settings) {
|
||||
|
@ -26,6 +26,8 @@ class RootWindowViews : public RootWindow,
|
||||
RootWindowViews();
|
||||
~RootWindowViews();
|
||||
|
||||
void SetTitlebarHeight(const std::optional<float>& height);
|
||||
|
||||
// RootWindow methods:
|
||||
void Init(RootWindow::Delegate* delegate,
|
||||
std::unique_ptr<RootWindowConfig> config,
|
||||
|
@ -399,6 +399,16 @@ bool ViewsWindow::GetWindowRestorePreferences(
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewsWindow::SetTitlebarHeight(const std::optional<float>& height) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
if (height.has_value()) {
|
||||
override_titlebar_height_ = height;
|
||||
} else {
|
||||
override_titlebar_height_ = default_titlebar_height_;
|
||||
}
|
||||
NudgeWindow();
|
||||
}
|
||||
|
||||
CefRefPtr<CefBrowserViewDelegate> ViewsWindow::GetDelegateForPopupBrowserView(
|
||||
CefRefPtr<CefBrowserView> browser_view,
|
||||
const CefBrowserSettings& settings,
|
||||
@ -735,8 +745,8 @@ 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;
|
||||
if (override_titlebar_height_.has_value()) {
|
||||
*titlebar_height = override_titlebar_height_.value();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -925,6 +935,13 @@ ViewsWindow::ViewsWindow(Delegate* delegate,
|
||||
// If window has frame or flag passed explicitly
|
||||
with_standard_buttons_ = !frameless_ || show_window_buttons;
|
||||
|
||||
#if defined(OS_MAC)
|
||||
if (frameless_ && with_standard_buttons_) {
|
||||
default_titlebar_height_ = kTitleBarHeight;
|
||||
override_titlebar_height_ = kTitleBarHeight;
|
||||
}
|
||||
#endif
|
||||
|
||||
const std::string& toolbar_type =
|
||||
command_line->GetSwitchValue(switches::kShowChromeToolbar);
|
||||
chrome_toolbar_type_ = CalculateChromeToolbarType(toolbar_type, hide_toolbar,
|
||||
@ -1262,4 +1279,10 @@ void ViewsWindow::OnExtensionWindowClosed() {
|
||||
extension_button_pressed_lock_ = nullptr;
|
||||
}
|
||||
|
||||
#if !defined(OS_MAC)
|
||||
void ViewsWindow::NudgeWindow() {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace client
|
||||
|
@ -130,6 +130,7 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
||||
|
||||
bool GetWindowRestorePreferences(cef_show_state_t& show_state,
|
||||
std::optional<CefRect>& dip_bounds);
|
||||
void SetTitlebarHeight(const std::optional<float>& height);
|
||||
|
||||
// CefBrowserViewDelegate methods:
|
||||
CefRefPtr<CefBrowserViewDelegate> GetDelegateForPopupBrowserView(
|
||||
@ -236,6 +237,8 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
||||
const ImageCache::ImageSet& images);
|
||||
void OnExtensionWindowClosed();
|
||||
|
||||
void NudgeWindow();
|
||||
|
||||
Delegate* delegate_; // Not owned by this object.
|
||||
CefRefPtr<CefBrowserView> browser_view_;
|
||||
bool frameless_;
|
||||
@ -258,6 +261,9 @@ class ViewsWindow : public CefBrowserViewDelegate,
|
||||
|
||||
CefRefPtr<ViewsOverlayControls> overlay_controls_;
|
||||
|
||||
std::optional<float> default_titlebar_height_;
|
||||
std::optional<float> override_titlebar_height_;
|
||||
|
||||
// Structure representing an extension.
|
||||
struct ExtensionInfo {
|
||||
ExtensionInfo(CefRefPtr<CefExtension> extension, CefRefPtr<CefImage> image)
|
||||
|
24
tests/cefclient/browser/views_window_mac.mm
Normal file
24
tests/cefclient/browser/views_window_mac.mm
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 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 "tests/cefclient/browser/views_window.h"
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
|
||||
namespace client {
|
||||
|
||||
void ViewsWindow::NudgeWindow() {
|
||||
if (window_) {
|
||||
auto view = CAST_CEF_WINDOW_HANDLE_TO_NSVIEW(window_->GetWindowHandle());
|
||||
NSWindow* main_window = view.window;
|
||||
|
||||
auto theme_frame = main_window.contentView.superview;
|
||||
// Nudge view frame a little to force an update.
|
||||
NSSize size = theme_frame.frame.size;
|
||||
[theme_frame setFrameSize:NSMakeSize(size.width - 1, size.height)];
|
||||
[theme_frame setFrameSize:size];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -35,6 +35,7 @@ const char kMessagePositionName[] = "WindowTest.Position";
|
||||
const char kMessageMinimizeName[] = "WindowTest.Minimize";
|
||||
const char kMessageMaximizeName[] = "WindowTest.Maximize";
|
||||
const char kMessageRestoreName[] = "WindowTest.Restore";
|
||||
const char kMessageTitlebarHeightName[] = "WindowTest.TitlebarHeight";
|
||||
|
||||
// Create the appropriate platform test runner object.
|
||||
std::unique_ptr<WindowTestRunner> CreateWindowTestRunner() {
|
||||
@ -69,6 +70,15 @@ std::vector<int> ParsePosition(const std::string& message_name) {
|
||||
return vec;
|
||||
}
|
||||
|
||||
std::optional<float> ParseHeight(const std::string& message) {
|
||||
if (message.size() > sizeof(kMessageTitlebarHeightName)) {
|
||||
const std::string& val = message.substr(sizeof(kMessageTitlebarHeightName));
|
||||
return std::stof(val);
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
// Handle messages in the browser process.
|
||||
class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
public:
|
||||
@ -91,18 +101,17 @@ class Handler : public CefMessageRouterBrowserSide::Handler {
|
||||
if (message_name.find(kMessagePositionName) == 0) {
|
||||
const auto vec = ParsePosition(message_name);
|
||||
if (vec.size() == 4) {
|
||||
// Execute SetPos() on the main thread.
|
||||
runner_->SetPos(browser, vec[0], vec[1], vec[2], vec[3]);
|
||||
}
|
||||
} else if (message_name == kMessageMinimizeName) {
|
||||
// Execute Minimize() on the main thread.
|
||||
runner_->Minimize(browser);
|
||||
} else if (message_name == kMessageMaximizeName) {
|
||||
// Execute Maximize() on the main thread.
|
||||
runner_->Maximize(browser);
|
||||
} else if (message_name == kMessageRestoreName) {
|
||||
// Execute Restore() on the main thread.
|
||||
runner_->Restore(browser);
|
||||
} else if (message_name.find(kMessageTitlebarHeightName) == 0) {
|
||||
const auto height = ParseHeight(message_name);
|
||||
runner_->SetTitleBarHeight(browser, height);
|
||||
} else {
|
||||
NOTREACHED();
|
||||
}
|
||||
|
@ -36,5 +36,10 @@ void WindowTestRunner::ModifyBounds(const CefRect& display, CefRect& window) {
|
||||
}
|
||||
}
|
||||
|
||||
void WindowTestRunner::SetTitleBarHeight(CefRefPtr<CefBrowser> browser,
|
||||
const std::optional<float>& height) {
|
||||
NOTIMPLEMENTED();
|
||||
}
|
||||
|
||||
} // namespace window_test
|
||||
} // namespace client
|
||||
|
@ -8,6 +8,8 @@
|
||||
|
||||
#include "include/cef_browser.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace client {
|
||||
namespace window_test {
|
||||
|
||||
@ -15,6 +17,8 @@ namespace window_test {
|
||||
// the browser process UI thread unless otherwise indicated.
|
||||
class WindowTestRunner {
|
||||
public:
|
||||
virtual ~WindowTestRunner() = default;
|
||||
|
||||
virtual void SetPos(CefRefPtr<CefBrowser> browser,
|
||||
int x,
|
||||
int y,
|
||||
@ -28,7 +32,8 @@ class WindowTestRunner {
|
||||
// corner of the display.
|
||||
static void ModifyBounds(const CefRect& display, CefRect& window);
|
||||
|
||||
virtual ~WindowTestRunner() {}
|
||||
virtual void SetTitleBarHeight(CefRefPtr<CefBrowser> browser,
|
||||
const std::optional<float>& height);
|
||||
};
|
||||
|
||||
} // namespace window_test
|
||||
|
@ -9,12 +9,15 @@
|
||||
#include "include/views/cef_window.h"
|
||||
#include "include/wrapper/cef_helpers.h"
|
||||
|
||||
#include "tests/cefclient/browser/root_window_views.h"
|
||||
#include "tests/cefclient/browser/views_window.h"
|
||||
|
||||
namespace client {
|
||||
namespace window_test {
|
||||
|
||||
namespace {
|
||||
|
||||
CefRefPtr<CefWindow> GetWindow(CefRefPtr<CefBrowser> browser) {
|
||||
CefRefPtr<CefWindow> GetWindow(const CefRefPtr<CefBrowser>& browser) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
DCHECK(browser->GetHost()->HasView());
|
||||
|
||||
@ -27,6 +30,16 @@ CefRefPtr<CefWindow> GetWindow(CefRefPtr<CefBrowser> browser) {
|
||||
return window;
|
||||
}
|
||||
|
||||
void SetTitlebarHeight(const CefRefPtr<CefBrowser>& browser,
|
||||
const std::optional<float>& height) {
|
||||
CEF_REQUIRE_UI_THREAD();
|
||||
auto root_window = RootWindow::GetForBrowser(browser->GetIdentifier());
|
||||
DCHECK(root_window.get());
|
||||
|
||||
auto root_window_views = static_cast<RootWindowViews*>(root_window.get());
|
||||
root_window_views->SetTitlebarHeight(height);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
WindowTestRunnerViews::WindowTestRunnerViews() {}
|
||||
@ -56,5 +69,11 @@ void WindowTestRunnerViews::Restore(CefRefPtr<CefBrowser> browser) {
|
||||
GetWindow(browser)->Restore();
|
||||
}
|
||||
|
||||
void WindowTestRunnerViews::SetTitleBarHeight(
|
||||
CefRefPtr<CefBrowser> browser,
|
||||
const std::optional<float>& height) {
|
||||
SetTitlebarHeight(browser, height);
|
||||
}
|
||||
|
||||
} // namespace window_test
|
||||
} // namespace client
|
||||
|
@ -24,6 +24,8 @@ class WindowTestRunnerViews : public WindowTestRunner {
|
||||
void Minimize(CefRefPtr<CefBrowser> browser) override;
|
||||
void Maximize(CefRefPtr<CefBrowser> browser) override;
|
||||
void Restore(CefRefPtr<CefBrowser> browser) override;
|
||||
void SetTitleBarHeight(CefRefPtr<CefBrowser> browser,
|
||||
const std::optional<float>& height) override;
|
||||
};
|
||||
|
||||
} // namespace window_test
|
||||
|
@ -1,4 +1,5 @@
|
||||
<html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<title>Window Test</title>
|
||||
<script>
|
||||
@ -47,6 +48,14 @@ function position() {
|
||||
else
|
||||
send_message('Position', x + ',' + y + ',' + width + ',' + height);
|
||||
}
|
||||
|
||||
function setTitlebarHeight() {
|
||||
const height = parseFloat(document.getElementById('title_bar_height').value);
|
||||
if (isNaN(height))
|
||||
send_message('TitlebarHeight');
|
||||
else
|
||||
send_message('TitlebarHeight', height);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body bgcolor="white" onload="setup()">
|
||||
@ -60,6 +69,8 @@ X: <input type="text" size="4" id="x" value="200">
|
||||
Y: <input type="text" size="4" id="y" value="100">
|
||||
Width: <input type="text" size="4" id="width" value="800">
|
||||
Height: <input type="text" size="4" id="height" value="600">
|
||||
<br/><input type="button" onclick="setTitlebarHeight();" value="Set Titlebar Height">
|
||||
<input type="number" min="0" max="100" id="title_bar_height" value="50"> (works on macOS with Views)
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
||||
|
Loading…
x
Reference in New Issue
Block a user