Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/licenses_golden/excluded_files
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@
../../../flutter/shell/platform/windows/client_wrapper/flutter_engine_unittests.cc
../../../flutter/shell/platform/windows/client_wrapper/flutter_view_controller_unittests.cc
../../../flutter/shell/platform/windows/client_wrapper/flutter_view_unittests.cc
../../../flutter/shell/platform/windows/client_wrapper/flutter_window_controller_unittests.cc
../../../flutter/shell/platform/windows/client_wrapper/plugin_registrar_windows_unittests.cc
../../../flutter/shell/platform/windows/client_wrapper/testing
../../../flutter/shell/platform/windows/compositor_opengl_unittests.cc
Expand Down
9 changes: 9 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -44407,6 +44407,7 @@ ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/st
ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/windowing.h + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/plugin_registrar.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/standard_codec.cc + ../../../flutter/LICENSE
ORIGIN: ../../../flutter/shell/platform/common/client_wrapper/texture_registrar_impl.h + ../../../flutter/LICENSE
Expand Down Expand Up @@ -47286,6 +47287,7 @@ FILE: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/stan
FILE: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h
FILE: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h
FILE: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h
FILE: ../../../flutter/shell/platform/common/client_wrapper/include/flutter/windowing.h
FILE: ../../../flutter/shell/platform/common/client_wrapper/plugin_registrar.cc
FILE: ../../../flutter/shell/platform/common/client_wrapper/standard_codec.cc
FILE: ../../../flutter/shell/platform/common/client_wrapper/texture_registrar_impl.h
Expand Down Expand Up @@ -48000,11 +48002,18 @@ FILE: ../../../flutter/shell/platform/windows/accessibility_plugin.cc
FILE: ../../../flutter/shell/platform/windows/accessibility_plugin.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/flutter_engine.cc
FILE: ../../../flutter/shell/platform/windows/client_wrapper/flutter_view_controller.cc
FILE: ../../../flutter/shell/platform/windows/client_wrapper/flutter_win32_window.cc
FILE: ../../../flutter/shell/platform/windows/client_wrapper/flutter_window_controller.cc
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/dart_project.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flutter_engine.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flutter_view.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flutter_win32_window.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flutter_window_controller.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/plugin_registrar_windows.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/win32_window.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/win32_wrapper.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/win32_window.cc
FILE: ../../../flutter/shell/platform/windows/compositor.h
FILE: ../../../flutter/shell/platform/windows/compositor_opengl.cc
FILE: ../../../flutter/shell/platform/windows/compositor_opengl.h
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ core_cpp_client_wrapper_includes =
"include/flutter/standard_message_codec.h",
"include/flutter/standard_method_codec.h",
"include/flutter/texture_registrar.h",
"include/flutter/windowing.h",
],
"abspath")

Expand Down
148 changes: 148 additions & 0 deletions shell/platform/common/client_wrapper/include/flutter/windowing.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// 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.

#ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_WINDOWING_H_
#define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_WINDOWING_H_

#include <optional>

namespace flutter {

// The unique identifier for a view.
using FlutterViewId = int64_t;

// A point (x, y) in 2D space for window positioning.
struct WindowPoint {
int x{0};
int y{0};

friend auto operator+(WindowPoint const& lhs,
WindowPoint const& rhs) -> WindowPoint {
return {lhs.x + rhs.x, lhs.y + rhs.y};
}

friend auto operator-(WindowPoint const& lhs,
WindowPoint const& rhs) -> WindowPoint {
return {lhs.x - rhs.x, lhs.y - rhs.y};
}

friend bool operator==(WindowPoint const& lhs, WindowPoint const& rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
};

// A size (width, height) in 2D space.
struct WindowSize {
int width{0};
int height{0};

explicit operator WindowPoint() const { return {width, height}; }

friend bool operator==(WindowSize const& lhs, WindowSize const& rhs) {
return lhs.width == rhs.width && lhs.height == rhs.height;
}
};

// A rectangular area defined by a top-left point and size.
struct WindowRectangle {
WindowPoint top_left;
WindowSize size;

// Checks if this rectangle fully contains |rect|.
// Note: An empty rectangle can still contain other empty rectangles,
// which are treated as points or lines of thickness zero
auto contains(WindowRectangle const& rect) const -> bool {
return rect.top_left.x >= top_left.x &&
rect.top_left.x + rect.size.width <= top_left.x + size.width &&
rect.top_left.y >= top_left.y &&
rect.top_left.y + rect.size.height <= top_left.y + size.height;
}

friend bool operator==(WindowRectangle const& lhs,
WindowRectangle const& rhs) {
return lhs.top_left == rhs.top_left && lhs.size == rhs.size;
}
};

// Defines how a child window should be positioned relative to its parent.
struct WindowPositioner {
// Allowed anchor positions.
enum class Anchor {
center, // Center.
top, // Top, centered horizontally.
bottom, // Bottom, centered horizontally.
left, // Left, centered vertically.
right, // Right, centered vertically.
top_left, // Top-left corner.
bottom_left, // Bottom-left corner.
top_right, // Top-right corner.
bottom_right, // Bottom-right corner.
};

// Specifies how a window should be adjusted if it doesn't fit the placement
// bounds. In order of precedence:
// 1. 'flip_{x|y|any}': reverse the anchor points and offset along an axis.
// 2. 'slide_{x|y|any}': adjust the offset along an axis.
// 3. 'resize_{x|y|any}': adjust the window size along an axis.
enum class ConstraintAdjustment {
none = 0, // No adjustment.
slide_x = 1 << 0, // Slide horizontally to fit.
slide_y = 1 << 1, // Slide vertically to fit.
flip_x = 1 << 2, // Flip horizontally to fit.
flip_y = 1 << 3, // Flip vertically to fit.
resize_x = 1 << 4, // Resize horizontally to fit.
resize_y = 1 << 5, // Resize vertically to fit.
flip_any = flip_x | flip_y, // Flip in any direction to fit.
slide_any = slide_x | slide_y, // Slide in any direction to fit.
resize_any = resize_x | resize_y, // Resize in any direction to fit.
};

// The reference anchor rectangle relative to the client rectangle of the
// parent window. If nullopt, the anchor rectangle is assumed to be the window
// rectangle.
std::optional<WindowRectangle> anchor_rect;
// Specifies which anchor of the parent window to align to.
Anchor parent_anchor{Anchor::center};
// Specifies which anchor of the child window to align with the parent.
Anchor child_anchor{Anchor::center};
// Offset relative to the position of the anchor on the anchor rectangle and
// the anchor on the child.
WindowPoint offset;
// The adjustments to apply if the window doesn't fit the available space.
// The order of precedence is: 1) Flip, 2) Slide, 3) Resize.
ConstraintAdjustment constraint_adjustment{ConstraintAdjustment::none};
};

// Types of windows.
enum class WindowArchetype {
// Regular top-level window.
regular,
// A window that is on a layer above regular windows and is not dockable.
floating_regular,
// Dialog window.
dialog,
// Satellite window attached to a regular, floating_regular or dialog window.
satellite,
// Popup.
popup,
// Tooltip.
tip,
};

// Window metadata returned as the result of creating a Flutter window.
struct WindowMetadata {
// The ID of the view used for this window, which is unique to each window.
FlutterViewId view_id{0};
// The type of the window (e.g., regular, dialog, popup, etc).
WindowArchetype archetype{WindowArchetype::regular};
// Size of the created window, in logical coordinates.
WindowSize size;
// The ID of the view used by the parent window. If not set, the window is
// assumed a top-level window.
std::optional<FlutterViewId> parent_id;
};

} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_WINDOWING_H_
14 changes: 14 additions & 0 deletions shell/platform/windows/client_wrapper/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,19 @@ _wrapper_includes = [
"include/flutter/flutter_engine.h",
"include/flutter/flutter_view_controller.h",
"include/flutter/flutter_view.h",
"include/flutter/flutter_win32_window.h",
"include/flutter/flutter_window_controller.h",
"include/flutter/plugin_registrar_windows.h",
"include/flutter/win32_window.h",
"include/flutter/win32_wrapper.h",
]

_wrapper_sources = [
"flutter_engine.cc",
"flutter_view_controller.cc",
"flutter_win32_window.cc",
"flutter_window_controller.cc",
"win32_window.cc",
]

# This code will be merged into .../common/client_wrapper for client use,
Expand All @@ -40,6 +47,8 @@ source_set("client_wrapper_windows") {
"//flutter/shell/platform/windows:flutter_windows_headers",
]

libs = [ "dwmapi.lib" ]

configs +=
[ "//flutter/shell/platform/common:desktop_library_implementation" ]

Expand Down Expand Up @@ -79,6 +88,7 @@ executable("client_wrapper_windows_unittests") {
"flutter_engine_unittests.cc",
"flutter_view_controller_unittests.cc",
"flutter_view_unittests.cc",
"flutter_window_controller_unittests.cc",
"plugin_registrar_windows_unittests.cc",
]

Expand All @@ -89,6 +99,7 @@ executable("client_wrapper_windows_unittests") {
":client_wrapper_library_stubs_windows",
":client_wrapper_windows",
":client_wrapper_windows_fixtures",
"//flutter/shell/platform/common/client_wrapper",
"//flutter/shell/platform/common/client_wrapper:client_wrapper_library_stubs",
"//flutter/testing",

Expand All @@ -110,6 +121,9 @@ client_wrapper_file_archive_list = [
win_client_wrapper_file_archive_list = [
"flutter_engine.cc",
"flutter_view_controller.cc",
"flutter_win32_window.cc",
"flutter_window_controller.cc",
"win32_window.cc",
]

zip_bundle("client_wrapper_archive") {
Expand Down
5 changes: 2 additions & 3 deletions shell/platform/windows/client_wrapper/flutter_engine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ bool FlutterEngine::Run(const char* entry_point) {
}

void FlutterEngine::ShutDown() {
if (engine_ && owns_engine_) {
if (engine_) {
FlutterDesktopEngineDestroy(engine_);
}
engine_ = nullptr;
Expand Down Expand Up @@ -113,8 +113,7 @@ std::optional<LRESULT> FlutterEngine::ProcessExternalWindowMessage(
return std::nullopt;
}

FlutterDesktopEngineRef FlutterEngine::RelinquishEngine() {
owns_engine_ = false;
FlutterDesktopEngineRef FlutterEngine::engine() const {
return engine_;
}

Expand Down
20 changes: 16 additions & 4 deletions shell/platform/windows/client_wrapper/flutter_view_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,22 @@ namespace flutter {

FlutterViewController::FlutterViewController(int width,
int height,
const DartProject& project) {
engine_ = std::make_shared<FlutterEngine>(project);
controller_ = FlutterDesktopViewControllerCreate(width, height,
engine_->RelinquishEngine());
const DartProject& project)
: FlutterViewController(width,
height,
std::make_shared<FlutterEngine>(project)) {}

FlutterViewController::FlutterViewController(
int width,
int height,
std::shared_ptr<FlutterEngine> engine) {
FlutterDesktopViewControllerProperties properties = {};
properties.width = width;
properties.height = height;

engine_ = std::move(engine);
controller_ =
FlutterDesktopEngineCreateViewController(engine_->engine(), &properties);
if (!controller_) {
std::cerr << "Failed to create view controller." << std::endl;
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,8 @@ namespace {
class TestWindowsApi : public testing::StubFlutterWindowsApi {
public:
// |flutter::testing::StubFlutterWindowsApi|
FlutterDesktopViewControllerRef ViewControllerCreate(
int width,
int height,
FlutterDesktopEngineRef engine) override {
FlutterDesktopViewControllerRef EngineCreateViewController(
const FlutterDesktopViewControllerProperties* properties) override {
return reinterpret_cast<FlutterDesktopViewControllerRef>(2);
}

Expand Down Expand Up @@ -63,11 +61,13 @@ TEST(FlutterViewControllerTest, CreateDestroy) {
testing::ScopedStubFlutterWindowsApi scoped_api_stub(
std::make_unique<TestWindowsApi>());
auto test_api = static_cast<TestWindowsApi*>(scoped_api_stub.stub());

// Create and destroy a view controller.
// This should also create and destroy an engine.
{ FlutterViewController controller(100, 100, project); }

EXPECT_TRUE(test_api->view_controller_destroyed());
// Per the C API, once a view controller has taken ownership of an engine
// the engine destruction method should not be called.
EXPECT_FALSE(test_api->engine_destroyed());
EXPECT_TRUE(test_api->engine_destroyed());
}

TEST(FlutterViewControllerTest, GetViewId) {
Expand Down
Loading