diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 33569a6ced33a..a08cdddf65180 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -1031,6 +1031,7 @@ FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/vmservice_objec FILE: ../../../flutter/shell/platform/fuchsia/runtime/dart/utils/vmservice_object.h FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller.cc FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_controller_unittests.cc +FILE: ../../../flutter/shell/platform/glfw/client_wrapper/flutter_window_unittests.cc FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window_controller.h FILE: ../../../flutter/shell/platform/glfw/client_wrapper/include/flutter/plugin_registrar_glfw.h diff --git a/shell/platform/glfw/client_wrapper/BUILD.gn b/shell/platform/glfw/client_wrapper/BUILD.gn index 18dd862993c0a..8d9e94a82b26c 100644 --- a/shell/platform/glfw/client_wrapper/BUILD.gn +++ b/shell/platform/glfw/client_wrapper/BUILD.gn @@ -75,6 +75,7 @@ executable("client_wrapper_glfw_unittests") { # TODO: Add more unit tests. sources = [ "flutter_window_controller_unittests.cc", + "flutter_window_unittests.cc", ] deps = [ diff --git a/shell/platform/glfw/client_wrapper/flutter_window_unittests.cc b/shell/platform/glfw/client_wrapper/flutter_window_unittests.cc new file mode 100644 index 0000000000000..31065d7e771d3 --- /dev/null +++ b/shell/platform/glfw/client_wrapper/flutter_window_unittests.cc @@ -0,0 +1,57 @@ +// Copyright 2013 The Flutter 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 "flutter/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h" + +#include +#include + +#include "flutter/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h" +#include "gtest/gtest.h" + +namespace flutter { + +namespace { + +// Stub implementation to validate calls to the API. +class TestGlfwApi : public testing::StubFlutterGlfwApi { + public: + // |flutter::testing::StubFlutterGlfwApi| + void SetSizeLimits(FlutterDesktopSize minimum_size, + FlutterDesktopSize maximum_size) override { + set_size_limits_called_ = true; + } + + bool set_size_limits_called() { return set_size_limits_called_; } + + private: + bool set_size_limits_called_ = false; +}; + +} // namespace + +TEST(FlutterWindowTest, SetSizeLimits) { + const std::string icu_data_path = "fake/path/to/icu"; + testing::ScopedStubFlutterGlfwApi scoped_api_stub( + std::make_unique()); + auto test_api = static_cast(scoped_api_stub.stub()); + // This is not actually used so any non-zero value works. + auto raw_window = reinterpret_cast(1); + + auto window = std::make_unique(raw_window); + + FlutterDesktopSize minimum_size = {}; + minimum_size.width = 100; + minimum_size.height = 100; + + FlutterDesktopSize maximum_size = {}; + maximum_size.width = -1; + maximum_size.height = -1; + + window->SetSizeLimits(minimum_size, maximum_size); + + EXPECT_EQ(test_api->set_size_limits_called(), true); +} + +} // namespace flutter diff --git a/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h index 854e96a46293b..2933c5a256b60 100644 --- a/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h +++ b/shell/platform/glfw/client_wrapper/include/flutter/flutter_window.h @@ -88,6 +88,13 @@ class FlutterWindow { FlutterDesktopWindowSetPixelRatioOverride(window_, pixel_ratio); } + // Sets the min/max size of |flutter_window| in screen coordinates. Use + // kFlutterDesktopDontCare for any dimension you wish to leave unconstrained. + void SetSizeLimits(FlutterDesktopSize minimum_size, + FlutterDesktopSize maximum_size) { + FlutterDesktopWindowSetSizeLimits(window_, minimum_size, maximum_size); + } + private: // Handle for interacting with the C API's window. // diff --git a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc index 02219f59bdf7b..51b0e6b5f1cd2 100644 --- a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc +++ b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.cc @@ -107,6 +107,14 @@ void FlutterDesktopWindowSetFrame(FlutterDesktopWindowRef flutter_window, } } +void FlutterDesktopWindowSetSizeLimits(FlutterDesktopWindowRef flutter_window, + FlutterDesktopSize minimum_size, + FlutterDesktopSize maximum_size) { + if (s_stub_implementation) { + s_stub_implementation->SetSizeLimits(minimum_size, maximum_size); + } +} + double FlutterDesktopWindowGetScaleFactor( FlutterDesktopWindowRef flutter_window) { if (s_stub_implementation) { diff --git a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h index 61ff639eb169f..b0c57c46d9e24 100644 --- a/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h +++ b/shell/platform/glfw/client_wrapper/testing/stub_flutter_glfw_api.h @@ -68,6 +68,10 @@ class StubFlutterGlfwApi { // Called for FlutterDesktopWindowSetPixelRatioOverride. virtual void SetPixelRatioOverride(double pixel_ratio) {} + // Called for FlutterDesktopWindowSetSizeLimits. + virtual void SetSizeLimits(FlutterDesktopSize minimum_size, + FlutterDesktopSize maximum_size) {} + // Called for FlutterDesktopRunWindowEventLoopWithTimeout. virtual bool RunWindowEventLoopWithTimeout(uint32_t millisecond_timeout) { return true; diff --git a/shell/platform/glfw/flutter_glfw.cc b/shell/platform/glfw/flutter_glfw.cc index b91dbdd93cf62..a38cb60ae8a47 100644 --- a/shell/platform/glfw/flutter_glfw.cc +++ b/shell/platform/glfw/flutter_glfw.cc @@ -34,6 +34,8 @@ using UniqueGLFWwindowPtr = std::unique_ptr; static_assert(FLUTTER_ENGINE_VERSION == 1, ""); +const int kFlutterDesktopDontCare = GLFW_DONT_CARE; + static constexpr double kDpPerInch = 160.0; // Struct for storing state within an instance of the GLFW Window. @@ -736,6 +738,14 @@ void FlutterDesktopWindowSetPixelRatioOverride( } } +void FlutterDesktopWindowSetSizeLimits(FlutterDesktopWindowRef flutter_window, + FlutterDesktopSize minimum_size, + FlutterDesktopSize maximum_size) { + glfwSetWindowSizeLimits(flutter_window->window, minimum_size.width, + minimum_size.height, maximum_size.width, + maximum_size.height); +} + bool FlutterDesktopRunWindowEventLoopWithTimeout( FlutterDesktopWindowControllerRef controller, uint32_t timeout_milliseconds) { diff --git a/shell/platform/glfw/public/flutter_glfw.h b/shell/platform/glfw/public/flutter_glfw.h index ed6f87fb0d7c8..610c63ff7948a 100644 --- a/shell/platform/glfw/public/flutter_glfw.h +++ b/shell/platform/glfw/public/flutter_glfw.h @@ -16,6 +16,9 @@ extern "C" { #endif +// Indicates that any value is acceptable for an otherwise required property. +extern const int32_t kFlutterDesktopDontCare; + // Opaque reference to a Flutter window controller. typedef struct FlutterDesktopWindowControllerState* FlutterDesktopWindowControllerRef; @@ -26,6 +29,12 @@ typedef struct FlutterDesktopWindow* FlutterDesktopWindowRef; // Opaque reference to a Flutter engine instance. typedef struct FlutterDesktopEngineState* FlutterDesktopEngineRef; +// Properties representing a generic rectangular size. +typedef struct { + int32_t width; + int32_t height; +} FlutterDesktopSize; + // Properties for configuring a Flutter engine instance. typedef struct { // The path to the flutter_assets folder for the application to be run. @@ -167,6 +176,13 @@ FLUTTER_EXPORT void FlutterDesktopWindowSetPixelRatioOverride( FlutterDesktopWindowRef flutter_window, double pixel_ratio); +// Sets the min/max size of |flutter_window| in screen coordinates. Use +// kFlutterDesktopDontCare for any dimension you wish to leave unconstrained. +FLUTTER_EXPORT void FlutterDesktopWindowSetSizeLimits( + FlutterDesktopWindowRef flutter_window, + FlutterDesktopSize minimum_size, + FlutterDesktopSize maximum_size); + // Runs an instance of a headless Flutter engine. // // Returns a null pointer in the event of an error.