Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 2 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,8 @@ FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flu
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/flutter_view_controller.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/include/flutter/plugin_registrar_windows.h
FILE: ../../../flutter/shell/platform/windows/client_wrapper/plugin_registrar_windows_unittests.cc
FILE: ../../../flutter/shell/platform/windows/cursor_handler.cc
FILE: ../../../flutter/shell/platform/windows/cursor_handler.h
FILE: ../../../flutter/shell/platform/windows/flutter_windows.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.cc
FILE: ../../../flutter/shell/platform/windows/flutter_windows_view.h
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/windows/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ source_set("flutter_windows_source") {
sources = [
"angle_surface_manager.cc",
"angle_surface_manager.h",
"cursor_handler.cc",
"cursor_handler.h",
"flutter_windows.cc",
"flutter_windows_view.cc",
"flutter_windows_view.h",
Expand Down
53 changes: 53 additions & 0 deletions shell/platform/windows/cursor_handler.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// 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/cursor_handler.h"

#include <windows.h>

#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/standard_method_codec.h"

static constexpr char kChannelName[] = "flutter/mousecursor";

static constexpr char kActivateSystemCursorMethod[] = "activateSystemCursor";

static constexpr char kKindKey[] = "kind";

namespace flutter {

CursorHandler::CursorHandler(flutter::BinaryMessenger* messenger,
WindowBindingHandler* delegate)
: channel_(std::make_unique<flutter::MethodChannel<EncodableValue>>(
messenger,
kChannelName,
&flutter::StandardMethodCodec::GetInstance())),
delegate_(delegate) {
channel_->SetMethodCallHandler(
[this](const flutter::MethodCall<EncodableValue>& call,
std::unique_ptr<flutter::MethodResult<EncodableValue>> result) {
HandleMethodCall(call, std::move(result));
});
}

void CursorHandler::HandleMethodCall(
const flutter::MethodCall<EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<EncodableValue>> result) {
const std::string& method = method_call.method_name();
if (method.compare(kActivateSystemCursorMethod) == 0) {
const flutter::EncodableMap& arguments =
method_call.arguments()->MapValue();
auto kind_iter = arguments.find(EncodableValue(kKindKey));
if (kind_iter == arguments.end()) {
result->Error("Argument error",
"Missing argument while trying to activate system cursor");
}
const std::string& kind = kind_iter->second.StringValue();
delegate_->UpdateFlutterCursor(kind);
result->Success();
} else {
result->NotImplemented();
}
}

} // namespace flutter
37 changes: 37 additions & 0 deletions shell/platform/windows/cursor_handler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// 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_WINDOWS_CURSOR_HANDLER_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_CURSOR_HANDLER_H_

#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/binary_messenger.h"
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/encodable_value.h"
#include "flutter/shell/platform/common/cpp/client_wrapper/include/flutter/method_channel.h"
#include "flutter/shell/platform/windows/public/flutter_windows.h"
#include "flutter/shell/platform/windows/window_binding_handler.h"

namespace flutter {

// Handler for the cursor system channel.
class CursorHandler {
public:
explicit CursorHandler(flutter::BinaryMessenger* messenger,
WindowBindingHandler* delegate);

private:
// Called when a method is called on |channel_|;
void HandleMethodCall(
const flutter::MethodCall<EncodableValue>& method_call,
std::unique_ptr<flutter::MethodResult<EncodableValue>> result);

// The MethodChannel used for communication with the Flutter engine.
std::unique_ptr<flutter::MethodChannel<EncodableValue>> channel_;

// The delegate for cursor updates.
WindowBindingHandler* delegate_;
};

} // namespace flutter

#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_CURSOR_HANDLER_H_
3 changes: 0 additions & 3 deletions shell/platform/windows/flutter_windows.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@
#include "flutter/shell/platform/common/cpp/path_utils.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/key_event_handler.h"
#include "flutter/shell/platform/windows/keyboard_hook_handler.h"
#include "flutter/shell/platform/windows/text_input_plugin.h"
#include "flutter/shell/platform/windows/win32_dpi_utils.h"
#include "flutter/shell/platform/windows/win32_flutter_window.h"
#include "flutter/shell/platform/windows/win32_platform_handler.h"
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/windows/flutter_windows_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ void FlutterWindowsView::SetState(FLUTTER_API_SYMBOL(FlutterEngine) eng) {
std::make_unique<flutter::TextInputPlugin>(internal_plugin_messenger));
platform_handler_ = std::make_unique<flutter::PlatformHandler>(
internal_plugin_messenger, this);
cursor_handler_ = std::make_unique<flutter::CursorHandler>(
internal_plugin_messenger, binding_handler_.get());

PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();

Expand Down
4 changes: 4 additions & 0 deletions shell/platform/windows/flutter_windows_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h"
#include "flutter/shell/platform/embedder/embedder.h"
#include "flutter/shell/platform/windows/angle_surface_manager.h"
#include "flutter/shell/platform/windows/cursor_handler.h"
#include "flutter/shell/platform/windows/key_event_handler.h"
#include "flutter/shell/platform/windows/keyboard_hook_handler.h"
#include "flutter/shell/platform/windows/public/flutter_windows.h"
Expand Down Expand Up @@ -213,6 +214,9 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate {
// Handler for the flutter/platform channel.
std::unique_ptr<flutter::PlatformHandler> platform_handler_;

// Handler for cursor events.
std::unique_ptr<flutter::CursorHandler> cursor_handler_;

// Currently configured WindowBindingHandler for view.
std::unique_ptr<flutter::WindowBindingHandler> binding_handler_;
};
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/windows/testing/win32_window_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ void Win32WindowTest::OnPointerUp(double x, double y, UINT button) {}

void Win32WindowTest::OnPointerLeave() {}

void Win32WindowTest::OnSetCursor() {}

void Win32WindowTest::OnText(const std::u16string& text) {}

void Win32WindowTest::OnKey(int key,
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/windows/testing/win32_window_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ class Win32WindowTest : public Win32Window {
// |Win32Window|
void OnPointerLeave() override;

// |Win32Window|
void OnSetCursor() override;

// |Win32Window|
void OnText(const std::u16string& text) override;

Expand Down
35 changes: 35 additions & 0 deletions shell/platform/windows/win32_flutter_window.cc
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#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;
Expand All @@ -12,9 +15,33 @@ constexpr int base_dpi = 96;
// 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.
static HCURSOR GetCursorByName(const std::string& cursor_name) {
static auto* cursors = new std::map<std::string, const wchar_t*>{
{"none", nullptr},
{"basic", IDC_ARROW},
{"click", IDC_HAND},
{"text", IDC_IBEAM},
{"forbidden", IDC_NO},
{"horizontalDoubleArrow", IDC_SIZEWE},
{"verticalDoubleArrow", IDC_SIZENS},
};
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() {}
Expand All @@ -35,6 +62,10 @@ 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) {
Expand Down Expand Up @@ -90,6 +121,10 @@ 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);
}
Expand Down
11 changes: 10 additions & 1 deletion shell/platform/windows/win32_flutter_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
#include <vector>

#include "flutter/shell/platform/embedder/embedder.h"

#include "flutter/shell/platform/windows/flutter_windows_view.h"
#include "flutter/shell/platform/windows/win32_window.h"
#include "flutter/shell/platform/windows/window_binding_handler.h"
Expand Down Expand Up @@ -48,6 +47,9 @@ class Win32FlutterWindow : public Win32Window, public WindowBindingHandler {
// |Win32Window|
void OnPointerLeave() override;

// |Win32Window|
void OnSetCursor() override;

// |Win32Window|
void OnText(const std::u16string& text) override;

Expand All @@ -72,9 +74,16 @@ class Win32FlutterWindow : public Win32Window, public WindowBindingHandler {
// |FlutterWindowBindingHandler|
PhysicalWindowBounds GetPhysicalWindowBounds() override;

// |FlutterWindowBindingHandler|
void UpdateFlutterCursor(const std::string& cursor_name) override;

private:
// A pointer to a FlutterWindowsView that can be used to update engine
// windowing and input state.
WindowBindingHandlerDelegate* binding_handler_delegate_;

// The last cursor set by Flutter. Defaults to the arrow cursor.
HCURSOR current_cursor_;
};

} // namespace flutter
Expand Down
8 changes: 8 additions & 0 deletions shell/platform/windows/win32_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@ Win32Window::MessageHandler(HWND hwnd,
// detected again.
tracking_mouse_leave_ = false;
break;
case WM_SETCURSOR: {
UINT hit_test_result = LOWORD(lparam);
if (hit_test_result == HTCLIENT) {
window->OnSetCursor();
return TRUE;
}
break;
}
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/windows/win32_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class Win32Window {
// Called when the mouse leaves the window.
virtual void OnPointerLeave() = 0;

// Called when the cursor should be set for the client area.
virtual void OnSetCursor() = 0;

// Called when text input occurs.
virtual void OnText(const std::u16string& text) = 0;

Expand Down
9 changes: 6 additions & 3 deletions shell/platform/windows/window_binding_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@
#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_H_
#define FLUTTER_SHELL_PLATFORM_WINDOWS_WINDOW_BINDING_HANDLER_H_

#include "flutter/shell/platform/windows/public/flutter_windows.h"
#include <windows.h>

#include <string>
#include <variant>

#include <windows.h>

#include "flutter/shell/platform/windows/public/flutter_windows.h"
#include "flutter/shell/platform/windows/window_binding_handler_delegate.h"

namespace flutter {
Expand Down Expand Up @@ -45,6 +44,10 @@ class WindowBindingHandler {

// Returns the bounds of the backing window in physical pixels.
virtual PhysicalWindowBounds GetPhysicalWindowBounds() = 0;

// Sets the cursor that should be used when the mouse is over the Flutter
// content. See mouse_cursor.dart for the values and meanings of cursor_name.
virtual void UpdateFlutterCursor(const std::string& cursor_name) = 0;
};

} // namespace flutter
Expand Down