Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 66d2190

Browse files
committed
feat: initial custom cursor and cache support
1 parent 3c7ed9f commit 66d2190

File tree

5 files changed

+37
-0
lines changed

5 files changed

+37
-0
lines changed

shell/platform/windows/cursor_handler.cc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
static constexpr char kChannelName[] = "flutter/mousecursor";
1212

1313
static constexpr char kActivateSystemCursorMethod[] = "activateSystemCursor";
14+
static constexpr char kSetSystemCursorMethod[] = "setSystemCursor";
1415

1516
static constexpr char kKindKey[] = "kind";
1617

@@ -45,6 +46,31 @@ void CursorHandler::HandleMethodCall(
4546
const auto& kind = std::get<std::string>(kind_iter->second);
4647
delegate_->UpdateFlutterCursor(kind);
4748
result->Success();
49+
} else if (method.compare(kSetSystemCursorMethod) == 0) {
50+
const auto& map = std::get<EncodableMap>(*method_call.arguments());
51+
auto buffer = std::get<std::vector<uint8_t>>(
52+
map.at(flutter::EncodableValue("buffer")));
53+
auto width = std::get<int>(map.at(flutter::EncodableValue("width")));
54+
auto height = std::get<int>(map.at(flutter::EncodableValue("height")));
55+
auto hotx = std::get<double>(map.at(flutter::EncodableValue("hotx")));
56+
auto hoty = std::get<double>(map.at(flutter::EncodableValue("hoty")));
57+
HCURSOR cursor = nullptr;
58+
// Flutter returns rawRgba, which has 8bits*4channels
59+
auto bitmap = CreateBitmap(width, height, 1, 32, &buffer[0]);
60+
if (bitmap == nullptr) {
61+
result->Error("Argument error", "Invalid rawRgba bitmap from flutter");
62+
return;
63+
}
64+
ICONINFO icon_info;
65+
icon_info.fIcon = 0;
66+
icon_info.xHotspot = hotx;
67+
icon_info.yHotspot = hoty;
68+
icon_info.hbmMask = bitmap;
69+
icon_info.hbmColor = bitmap;
70+
cursor = CreateIconIndirect(&icon_info);
71+
DeleteObject(bitmap);
72+
delegate_->SetFlutterCursor(cursor);
73+
result->Success();
4874
} else {
4975
result->NotImplemented();
5076
}

shell/platform/windows/flutter_window.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ void FlutterWindow::UpdateFlutterCursor(const std::string& cursor_name) {
105105
current_cursor_ = GetCursorByName(cursor_name);
106106
}
107107

108+
void FlutterWindow::SetFlutterCursor(HCURSOR cursor) {
109+
current_cursor_ = cursor;
110+
}
111+
108112
void FlutterWindow::OnWindowResized() {
109113
// Blocking the raster thread until DWM flushes alleviates glitches where
110114
// previous size surface is stretched over current size view.

shell/platform/windows/flutter_window.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ class FlutterWindow : public Window, public WindowBindingHandler {
131131
// |FlutterWindowBindingHandler|
132132
void UpdateFlutterCursor(const std::string& cursor_name) override;
133133

134+
// |FlutterWindowBindingHandler|
135+
void SetFlutterCursor(HCURSOR cursor) override;
136+
134137
// |FlutterWindowBindingHandler|
135138
void OnWindowResized() override;
136139

shell/platform/windows/testing/mock_window_binding_handler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ class MockWindowBindingHandler : public WindowBindingHandler {
3131
MOCK_METHOD0(OnWindowResized, void());
3232
MOCK_METHOD0(GetPhysicalWindowBounds, PhysicalWindowBounds());
3333
MOCK_METHOD1(UpdateFlutterCursor, void(const std::string& cursor_name));
34+
MOCK_METHOD1(SetFlutterCursor, void(HCURSOR cursor_name));
3435
MOCK_METHOD1(OnCursorRectUpdated, void(const Rect& rect));
3536
MOCK_METHOD0(OnResetImeComposing, void());
3637
MOCK_METHOD3(OnBitmapSurfaceUpdated,

shell/platform/windows/window_binding_handler.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ class WindowBindingHandler {
7171
// content. See mouse_cursor.dart for the values and meanings of cursor_name.
7272
virtual void UpdateFlutterCursor(const std::string& cursor_name) = 0;
7373

74+
// Sets the cursor from path
75+
virtual void SetFlutterCursor(HCURSOR cursor) = 0;
76+
7477
// Invoked when the cursor/composing rect has been updated in the framework.
7578
virtual void OnCursorRectUpdated(const Rect& rect) = 0;
7679

0 commit comments

Comments
 (0)