Skip to content

Commit edb8982

Browse files
committed
more pieces
1 parent 3bdd05c commit edb8982

File tree

13 files changed

+157
-64
lines changed

13 files changed

+157
-64
lines changed

tfserving-flutter/codelab2/finished/windows/CMakeLists.txt

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
1+
# Project-level configuration.
12
cmake_minimum_required(VERSION 3.14)
23
project(tfserving_flutter LANGUAGES CXX)
34

5+
# The name of the executable created for the application. Change this to change
6+
# the on-disk name of your application.
47
set(BINARY_NAME "tfserving_flutter")
58

6-
cmake_policy(SET CMP0063 NEW)
9+
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
10+
# versions of CMake.
11+
cmake_policy(VERSION 3.14...3.25)
712

8-
set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
9-
10-
# Configure build options.
13+
# Define build configuration option.
1114
get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
1215
if(IS_MULTICONFIG)
1316
set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
@@ -20,7 +23,7 @@ else()
2023
"Debug" "Profile" "Release")
2124
endif()
2225
endif()
23-
26+
# Define settings for the Profile build mode.
2427
set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
2528
set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
2629
set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
@@ -30,6 +33,10 @@ set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
3033
add_definitions(-DUNICODE -D_UNICODE)
3134

3235
# Compilation settings that should be applied to most targets.
36+
#
37+
# Be cautious about adding new options here, as plugins use this function by
38+
# default. In most cases, you should add new options to specific targets instead
39+
# of modifying this function.
3340
function(APPLY_STANDARD_SETTINGS TARGET)
3441
target_compile_features(${TARGET} PUBLIC cxx_std_17)
3542
target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
@@ -38,14 +45,14 @@ function(APPLY_STANDARD_SETTINGS TARGET)
3845
target_compile_definitions(${TARGET} PRIVATE "$<$<CONFIG:Debug>:_DEBUG>")
3946
endfunction()
4047

41-
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
42-
4348
# Flutter library and tool build rules.
49+
set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
4450
add_subdirectory(${FLUTTER_MANAGED_DIR})
4551

46-
# Application build
52+
# Application build; see runner/CMakeLists.txt.
4753
add_subdirectory("runner")
4854

55+
4956
# Generated plugin build rules, which manage building the plugins and adding
5057
# them to the application.
5158
include(flutter/generated_plugins.cmake)
@@ -80,6 +87,12 @@ if(PLUGIN_BUNDLED_LIBRARIES)
8087
COMPONENT Runtime)
8188
endif()
8289

90+
# Copy the native assets provided by the build.dart from all packages.
91+
set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/")
92+
install(DIRECTORY "${NATIVE_ASSETS_DIR}"
93+
DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
94+
COMPONENT Runtime)
95+
8396
# Fully re-copy the assets directory on each build to avoid having stale files
8497
# from a previous install.
8598
set(FLUTTER_ASSET_DIR_NAME "flutter_assets")

tfserving-flutter/codelab2/finished/windows/flutter/CMakeLists.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# This file controls Flutter-level build steps. It should not be edited.
12
cmake_minimum_required(VERSION 3.14)
23

34
set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
@@ -9,6 +10,11 @@ include(${EPHEMERAL_DIR}/generated_config.cmake)
910
# https://github.com/flutter/flutter/issues/57146.
1011
set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
1112

13+
# Set fallback configurations for older versions of the flutter tool.
14+
if (NOT DEFINED FLUTTER_TARGET_PLATFORM)
15+
set(FLUTTER_TARGET_PLATFORM "windows-x64")
16+
endif()
17+
1218
# === Flutter Library ===
1319
set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
1420

@@ -91,7 +97,7 @@ add_custom_command(
9197
COMMAND ${CMAKE_COMMAND} -E env
9298
${FLUTTER_TOOL_ENVIRONMENT}
9399
"${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
94-
windows-x64 $<CONFIG>
100+
${FLUTTER_TARGET_PLATFORM} $<CONFIG>
95101
VERBATIM
96102
)
97103
add_custom_target(flutter_assemble DEPENDS

tfserving-flutter/codelab2/finished/windows/runner/CMakeLists.txt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
cmake_minimum_required(VERSION 3.14)
22
project(runner LANGUAGES CXX)
33

4+
# Define the application target. To change its name, change BINARY_NAME in the
5+
# top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
6+
# work.
7+
#
8+
# Any new source files that you add to the application should be added here.
49
add_executable(${BINARY_NAME} WIN32
510
"flutter_window.cpp"
611
"main.cpp"
@@ -10,8 +15,26 @@ add_executable(${BINARY_NAME} WIN32
1015
"Runner.rc"
1116
"runner.exe.manifest"
1217
)
18+
19+
# Apply the standard set of build settings. This can be removed for applications
20+
# that need different build settings.
1321
apply_standard_settings(${BINARY_NAME})
22+
23+
# Add preprocessor definitions for the build version.
24+
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
25+
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
26+
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
27+
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
28+
target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
29+
30+
# Disable Windows macros that collide with C++ standard library functions.
1431
target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
32+
33+
# Add dependency libraries and include directories. Add any application-specific
34+
# dependencies here.
1535
target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
36+
target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
1637
target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
38+
39+
# Run the Flutter tool portions of the build. This must not be removed.
1740
add_dependencies(${BINARY_NAME} flutter_assemble)

tfserving-flutter/codelab2/finished/windows/runner/Runner.rc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,14 +60,14 @@ IDI_APP_ICON ICON "resources\\app_icon.ico"
6060
// Version
6161
//
6262

63-
#ifdef FLUTTER_BUILD_NUMBER
64-
#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER
63+
#if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
64+
#define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
6565
#else
66-
#define VERSION_AS_NUMBER 1,0,0
66+
#define VERSION_AS_NUMBER 1,0,0,0
6767
#endif
6868

69-
#ifdef FLUTTER_BUILD_NAME
70-
#define VERSION_AS_STRING #FLUTTER_BUILD_NAME
69+
#if defined(FLUTTER_VERSION)
70+
#define VERSION_AS_STRING FLUTTER_VERSION
7171
#else
7272
#define VERSION_AS_STRING "1.0.0"
7373
#endif
@@ -93,7 +93,7 @@ BEGIN
9393
VALUE "FileDescription", "tfserving_flutter" "\0"
9494
VALUE "FileVersion", VERSION_AS_STRING "\0"
9595
VALUE "InternalName", "tfserving_flutter" "\0"
96-
VALUE "LegalCopyright", "Copyright (C) 2022 com.example. All rights reserved." "\0"
96+
VALUE "LegalCopyright", "Copyright (C) 2025 com.example. All rights reserved." "\0"
9797
VALUE "OriginalFilename", "tfserving_flutter.exe" "\0"
9898
VALUE "ProductName", "tfserving_flutter" "\0"
9999
VALUE "ProductVersion", VERSION_AS_STRING "\0"

tfserving-flutter/codelab2/finished/windows/runner/flutter_window.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,16 @@ bool FlutterWindow::OnCreate() {
2626
}
2727
RegisterPlugins(flutter_controller_->engine());
2828
SetChildContent(flutter_controller_->view()->GetNativeWindow());
29+
30+
flutter_controller_->engine()->SetNextFrameCallback([&]() {
31+
this->Show();
32+
});
33+
34+
// Flutter can complete the first frame before the "show window" callback is
35+
// registered. The following call ensures a frame is pending to ensure the
36+
// window is shown. It is a no-op if the first frame hasn't completed yet.
37+
flutter_controller_->ForceRedraw();
38+
2939
return true;
3040
}
3141

tfserving-flutter/codelab2/finished/windows/runner/main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
2727
FlutterWindow window(project);
2828
Win32Window::Point origin(10, 10);
2929
Win32Window::Size size(1280, 720);
30-
if (!window.CreateAndShow(L"tfserving_flutter", origin, size)) {
30+
if (!window.Create(L"tfserving_flutter", origin, size)) {
3131
return EXIT_FAILURE;
3232
}
3333
window.SetQuitOnClose(true);

tfserving-flutter/codelab2/finished/windows/runner/runner.exe.manifest

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,8 @@
77
</application>
88
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
99
<application>
10-
<!-- Windows 10 -->
10+
<!-- Windows 10 and Windows 11 -->
1111
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
12-
<!-- Windows 8.1 -->
13-
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
14-
<!-- Windows 8 -->
15-
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
16-
<!-- Windows 7 -->
17-
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
1812
</application>
1913
</compatibility>
2014
</assembly>

tfserving-flutter/codelab2/finished/windows/runner/utils.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,19 @@ std::string Utf8FromUtf16(const wchar_t* utf16_string) {
4545
if (utf16_string == nullptr) {
4646
return std::string();
4747
}
48-
int target_length = ::WideCharToMultiByte(
48+
unsigned int target_length = ::WideCharToMultiByte(
4949
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
50-
-1, nullptr, 0, nullptr, nullptr);
51-
if (target_length == 0) {
52-
return std::string();
53-
}
50+
-1, nullptr, 0, nullptr, nullptr)
51+
-1; // remove the trailing null character
52+
int input_length = (int)wcslen(utf16_string);
5453
std::string utf8_string;
54+
if (target_length == 0 || target_length > utf8_string.max_size()) {
55+
return utf8_string;
56+
}
5557
utf8_string.resize(target_length);
5658
int converted_length = ::WideCharToMultiByte(
5759
CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
58-
-1, utf8_string.data(),
59-
target_length, nullptr, nullptr);
60+
input_length, utf8_string.data(), target_length, nullptr, nullptr);
6061
if (converted_length == 0) {
6162
return std::string();
6263
}

tfserving-flutter/codelab2/finished/windows/runner/win32_window.cpp

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,31 @@
11
#include "win32_window.h"
22

3+
#include <dwmapi.h>
34
#include <flutter_windows.h>
45

56
#include "resource.h"
67

78
namespace {
89

10+
/// Window attribute that enables dark mode window decorations.
11+
///
12+
/// Redefined in case the developer's machine has a Windows SDK older than
13+
/// version 10.0.22000.0.
14+
/// See: https://docs.microsoft.com/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
15+
#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
16+
#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
17+
#endif
18+
919
constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW";
1020

21+
/// Registry key for app theme preference.
22+
///
23+
/// A value of 0 indicates apps should use dark mode. A non-zero or missing
24+
/// value indicates apps should use light mode.
25+
constexpr const wchar_t kGetPreferredBrightnessRegKey[] =
26+
L"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize";
27+
constexpr const wchar_t kGetPreferredBrightnessRegValue[] = L"AppsUseLightTheme";
28+
1129
// The number of Win32Window objects that currently exist.
1230
static int g_active_window_count = 0;
1331

@@ -31,8 +49,8 @@ void EnableFullDpiSupportIfAvailable(HWND hwnd) {
3149
GetProcAddress(user32_module, "EnableNonClientDpiScaling"));
3250
if (enable_non_client_dpi_scaling != nullptr) {
3351
enable_non_client_dpi_scaling(hwnd);
34-
FreeLibrary(user32_module);
3552
}
53+
FreeLibrary(user32_module);
3654
}
3755

3856
} // namespace
@@ -42,7 +60,7 @@ class WindowClassRegistrar {
4260
public:
4361
~WindowClassRegistrar() = default;
4462

45-
// Returns the singleton registar instance.
63+
// Returns the singleton registrar instance.
4664
static WindowClassRegistrar* GetInstance() {
4765
if (!instance_) {
4866
instance_ = new WindowClassRegistrar();
@@ -102,9 +120,9 @@ Win32Window::~Win32Window() {
102120
Destroy();
103121
}
104122

105-
bool Win32Window::CreateAndShow(const std::wstring& title,
106-
const Point& origin,
107-
const Size& size) {
123+
bool Win32Window::Create(const std::wstring& title,
124+
const Point& origin,
125+
const Size& size) {
108126
Destroy();
109127

110128
const wchar_t* window_class =
@@ -117,7 +135,7 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
117135
double scale_factor = dpi / 96.0;
118136

119137
HWND window = CreateWindow(
120-
window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE,
138+
window_class, title.c_str(), WS_OVERLAPPEDWINDOW,
121139
Scale(origin.x, scale_factor), Scale(origin.y, scale_factor),
122140
Scale(size.width, scale_factor), Scale(size.height, scale_factor),
123141
nullptr, nullptr, GetModuleHandle(nullptr), this);
@@ -126,9 +144,15 @@ bool Win32Window::CreateAndShow(const std::wstring& title,
126144
return false;
127145
}
128146

147+
UpdateTheme(window);
148+
129149
return OnCreate();
130150
}
131151

152+
bool Win32Window::Show() {
153+
return ShowWindow(window_handle_, SW_SHOWNORMAL);
154+
}
155+
132156
// static
133157
LRESULT CALLBACK Win32Window::WndProc(HWND const window,
134158
UINT const message,
@@ -188,6 +212,10 @@ Win32Window::MessageHandler(HWND hwnd,
188212
SetFocus(child_content_);
189213
}
190214
return 0;
215+
216+
case WM_DWMCOLORIZATIONCOLORCHANGED:
217+
UpdateTheme(hwnd);
218+
return 0;
191219
}
192220

193221
return DefWindowProc(window_handle_, message, wparam, lparam);
@@ -243,3 +271,18 @@ bool Win32Window::OnCreate() {
243271
void Win32Window::OnDestroy() {
244272
// No-op; provided for subclasses.
245273
}
274+
275+
void Win32Window::UpdateTheme(HWND const window) {
276+
DWORD light_mode;
277+
DWORD light_mode_size = sizeof(light_mode);
278+
LSTATUS result = RegGetValue(HKEY_CURRENT_USER, kGetPreferredBrightnessRegKey,
279+
kGetPreferredBrightnessRegValue,
280+
RRF_RT_REG_DWORD, nullptr, &light_mode,
281+
&light_mode_size);
282+
283+
if (result == ERROR_SUCCESS) {
284+
BOOL enable_dark_mode = light_mode == 0;
285+
DwmSetWindowAttribute(window, DWMWA_USE_IMMERSIVE_DARK_MODE,
286+
&enable_dark_mode, sizeof(enable_dark_mode));
287+
}
288+
}

tfserving-flutter/codelab2/finished/windows/runner/win32_window.h

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,16 @@ class Win32Window {
2828
Win32Window();
2929
virtual ~Win32Window();
3030

31-
// Creates and shows a win32 window with |title| and position and size using
31+
// Creates a win32 window with |title| that is positioned and sized using
3232
// |origin| and |size|. New windows are created on the default monitor. Window
3333
// sizes are specified to the OS in physical pixels, hence to ensure a
34-
// consistent size to will treat the width height passed in to this function
35-
// as logical pixels and scale to appropriate for the default monitor. Returns
36-
// true if the window was created successfully.
37-
bool CreateAndShow(const std::wstring& title,
38-
const Point& origin,
39-
const Size& size);
34+
// consistent size this function will scale the inputted width and height as
35+
// as appropriate for the default monitor. The window is invisible until
36+
// |Show| is called. Returns true if the window was created successfully.
37+
bool Create(const std::wstring& title, const Point& origin, const Size& size);
38+
39+
// Show the current window. Returns true if the window was successfully shown.
40+
bool Show();
4041

4142
// Release OS resources associated with window.
4243
void Destroy();
@@ -76,7 +77,7 @@ class Win32Window {
7677
// OS callback called by message pump. Handles the WM_NCCREATE message which
7778
// is passed when the non-client area is being created and enables automatic
7879
// non-client DPI scaling so that the non-client area automatically
79-
// responsponds to changes in DPI. All other messages are handled by
80+
// responds to changes in DPI. All other messages are handled by
8081
// MessageHandler.
8182
static LRESULT CALLBACK WndProc(HWND const window,
8283
UINT const message,
@@ -86,6 +87,9 @@ class Win32Window {
8687
// Retrieves a class instance pointer for |window|
8788
static Win32Window* GetThisFromHandle(HWND const window) noexcept;
8889

90+
// Update the window frame's theme to match the system theme.
91+
static void UpdateTheme(HWND const window);
92+
8993
bool quit_on_close_ = false;
9094

9195
// window handle for top level window.

0 commit comments

Comments
 (0)