mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Originally font change notification was handled by forwarding WM_FONTCHANGE to the Flutter HWND, to avoid adding new API surface, but that's not a good solution in a multi-window scenario, and it would require a completely different solution for UWP. It also requires non-obvious plumbing in the runner. This replaces that with an explicit API, so that there's a clean and obvious way for the runner to trigger this event.
175 lines
5.3 KiB
C++
175 lines
5.3 KiB
C++
// 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/windows/win32_flutter_window.h"
|
|
|
|
#include <chrono>
|
|
#include <map>
|
|
|
|
namespace flutter {
|
|
|
|
namespace {
|
|
|
|
// The Windows DPI system is based on this
|
|
// constant for machines running at 100% scaling.
|
|
constexpr int base_dpi = 96;
|
|
|
|
// TODO: See if this can be queried from the OS; this value is chosen
|
|
// arbitrarily to get something that feels reasonable.
|
|
constexpr int kScrollOffsetMultiplier = 20;
|
|
|
|
// Maps a Flutter cursor name to an HCURSOR.
|
|
//
|
|
// Returns the arrow cursor for unknown constants.
|
|
//
|
|
// This map must be kept in sync with Flutter framework's
|
|
// rendering/mouse_cursor.dart.
|
|
static HCURSOR GetCursorByName(const std::string& cursor_name) {
|
|
static auto* cursors = new std::map<std::string, const wchar_t*>{
|
|
{"allScroll", IDC_SIZEALL},
|
|
{"basic", IDC_ARROW},
|
|
{"click", IDC_HAND},
|
|
{"forbidden", IDC_NO},
|
|
{"help", IDC_HELP},
|
|
{"move", IDC_SIZEALL},
|
|
{"none", nullptr},
|
|
{"noDrop", IDC_NO},
|
|
{"precise", IDC_CROSS},
|
|
{"progress", IDC_APPSTARTING},
|
|
{"text", IDC_IBEAM},
|
|
{"resizeColumn", IDC_SIZEWE},
|
|
{"resizeDown", IDC_SIZENS},
|
|
{"resizeDownLeft", IDC_SIZENESW},
|
|
{"resizeDownRight", IDC_SIZENWSE},
|
|
{"resizeLeft", IDC_SIZEWE},
|
|
{"resizeLeftRight", IDC_SIZEWE},
|
|
{"resizeRight", IDC_SIZEWE},
|
|
{"resizeRow", IDC_SIZENS},
|
|
{"resizeUp", IDC_SIZENS},
|
|
{"resizeUpDown", IDC_SIZENS},
|
|
{"resizeUpLeft", IDC_SIZENWSE},
|
|
{"resizeUpRight", IDC_SIZENESW},
|
|
{"resizeUpLeftDownRight", IDC_SIZENWSE},
|
|
{"resizeUpRightDownLeft", IDC_SIZENESW},
|
|
{"wait", IDC_WAIT},
|
|
};
|
|
const wchar_t* idc_name = IDC_ARROW;
|
|
auto it = cursors->find(cursor_name);
|
|
if (it != cursors->end()) {
|
|
idc_name = it->second;
|
|
}
|
|
return ::LoadCursor(nullptr, idc_name);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
Win32FlutterWindow::Win32FlutterWindow(int width, int height)
|
|
: binding_handler_delegate_(nullptr) {
|
|
Win32Window::InitializeChild("FLUTTERVIEW", width, height);
|
|
current_cursor_ = ::LoadCursor(nullptr, IDC_ARROW);
|
|
}
|
|
|
|
Win32FlutterWindow::~Win32FlutterWindow() {}
|
|
|
|
void Win32FlutterWindow::SetView(WindowBindingHandlerDelegate* window) {
|
|
binding_handler_delegate_ = window;
|
|
}
|
|
|
|
WindowsRenderTarget Win32FlutterWindow::GetRenderTarget() {
|
|
return WindowsRenderTarget(GetWindowHandle());
|
|
}
|
|
|
|
float Win32FlutterWindow::GetDpiScale() {
|
|
return static_cast<float>(GetCurrentDPI()) / static_cast<float>(base_dpi);
|
|
}
|
|
|
|
PhysicalWindowBounds Win32FlutterWindow::GetPhysicalWindowBounds() {
|
|
return {GetCurrentWidth(), GetCurrentHeight()};
|
|
}
|
|
|
|
void Win32FlutterWindow::UpdateFlutterCursor(const std::string& cursor_name) {
|
|
current_cursor_ = GetCursorByName(cursor_name);
|
|
}
|
|
|
|
// Translates button codes from Win32 API to FlutterPointerMouseButtons.
|
|
static uint64_t ConvertWinButtonToFlutterButton(UINT button) {
|
|
switch (button) {
|
|
case WM_LBUTTONDOWN:
|
|
case WM_LBUTTONUP:
|
|
return kFlutterPointerButtonMousePrimary;
|
|
case WM_RBUTTONDOWN:
|
|
case WM_RBUTTONUP:
|
|
return kFlutterPointerButtonMouseSecondary;
|
|
case WM_MBUTTONDOWN:
|
|
case WM_MBUTTONUP:
|
|
return kFlutterPointerButtonMouseMiddle;
|
|
case XBUTTON1:
|
|
return kFlutterPointerButtonMouseBack;
|
|
case XBUTTON2:
|
|
return kFlutterPointerButtonMouseForward;
|
|
}
|
|
std::cerr << "Mouse button not recognized: " << button << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
void Win32FlutterWindow::OnDpiScale(unsigned int dpi){};
|
|
|
|
// When DesktopWindow notifies that a WM_Size message has come in
|
|
// lets FlutterEngine know about the new size.
|
|
void Win32FlutterWindow::OnResize(unsigned int width, unsigned int height) {
|
|
if (binding_handler_delegate_ != nullptr) {
|
|
binding_handler_delegate_->OnWindowSizeChanged(width, height);
|
|
}
|
|
}
|
|
|
|
void Win32FlutterWindow::OnPointerMove(double x, double y) {
|
|
binding_handler_delegate_->OnPointerMove(x, y);
|
|
}
|
|
|
|
void Win32FlutterWindow::OnPointerDown(double x, double y, UINT button) {
|
|
uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
|
|
if (flutter_button != 0) {
|
|
binding_handler_delegate_->OnPointerDown(
|
|
x, y, static_cast<FlutterPointerMouseButtons>(flutter_button));
|
|
}
|
|
}
|
|
|
|
void Win32FlutterWindow::OnPointerUp(double x, double y, UINT button) {
|
|
uint64_t flutter_button = ConvertWinButtonToFlutterButton(button);
|
|
if (flutter_button != 0) {
|
|
binding_handler_delegate_->OnPointerUp(
|
|
x, y, static_cast<FlutterPointerMouseButtons>(flutter_button));
|
|
}
|
|
}
|
|
|
|
void Win32FlutterWindow::OnPointerLeave() {
|
|
binding_handler_delegate_->OnPointerLeave();
|
|
}
|
|
|
|
void Win32FlutterWindow::OnSetCursor() {
|
|
::SetCursor(current_cursor_);
|
|
}
|
|
|
|
void Win32FlutterWindow::OnText(const std::u16string& text) {
|
|
binding_handler_delegate_->OnText(text);
|
|
}
|
|
|
|
void Win32FlutterWindow::OnKey(int key,
|
|
int scancode,
|
|
int action,
|
|
char32_t character) {
|
|
binding_handler_delegate_->OnKey(key, scancode, action, character);
|
|
}
|
|
|
|
void Win32FlutterWindow::OnScroll(double delta_x, double delta_y) {
|
|
POINT point;
|
|
GetCursorPos(&point);
|
|
|
|
ScreenToClient(GetWindowHandle(), &point);
|
|
binding_handler_delegate_->OnScroll(point.x, point.y, delta_x, delta_y,
|
|
kScrollOffsetMultiplier);
|
|
}
|
|
|
|
} // namespace flutter
|