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

[Windows] handle repaint message in FlutterView window #34306

Merged
merged 4 commits into from
Jul 13, 2022
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
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ Callum Moffat <[email protected]>
Koutaro Mori <[email protected]>
TheOneWithTheBraid <[email protected]>
Twin Sun, LLC <[email protected]>
Qixing Cao <[email protected]>
6 changes: 6 additions & 0 deletions shell/platform/windows/flutter_window_win32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ void FlutterWindowWin32::OnResize(unsigned int width, unsigned int height) {
}
}

void FlutterWindowWin32::OnPaint() {
if (binding_handler_delegate_ != nullptr) {
binding_handler_delegate_->OnWindowRepaint();
}
}

void FlutterWindowWin32::OnPointerMove(double x,
double y,
FlutterPointerDeviceKind device_kind,
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/windows/flutter_window_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ class FlutterWindowWin32 : public WindowWin32, public WindowBindingHandler {
// |WindowWin32|
void OnResize(unsigned int width, unsigned int height) override;

// |WindowWin32|
void OnPaint() override;

// |WindowWin32|
void OnPointerMove(double x,
double y,
Expand Down
17 changes: 17 additions & 0 deletions shell/platform/windows/flutter_window_win32_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,13 @@ class MockFlutterWindowWin32 : public FlutterWindowWin32 {
// Wrapper for GetCurrentDPI() which is a protected method.
UINT GetDpi() { return GetCurrentDPI(); }

// Simulates a WindowProc message from the OS.
LRESULT InjectWindowMessage(UINT const message,
WPARAM const wparam,
LPARAM const lparam) {
return HandleMessage(message, wparam, lparam);
}

MOCK_METHOD1(OnDpiScale, void(unsigned int));
MOCK_METHOD2(OnResize, void(unsigned int, unsigned int));
MOCK_METHOD4(OnPointerMove,
Expand Down Expand Up @@ -346,5 +353,15 @@ TEST(FlutterWindowWin32Test, OnScrollCallsGetScrollOffsetMultiplier) {
kDefaultPointerDeviceId);
}

TEST(FlutterWindowWin32Test, OnWindowRepaint) {
MockFlutterWindowWin32 win32window;
MockWindowBindingHandlerDelegate delegate;
win32window.SetView(&delegate);

EXPECT_CALL(delegate, OnWindowRepaint()).Times(1);

win32window.InjectWindowMessage(WM_PAINT, 0, 0);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The inject window message is really nice! 🏅

Could you also add a test that calls OnPaint directly too since it's a public API?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done


} // namespace testing
} // namespace flutter
6 changes: 6 additions & 0 deletions shell/platform/windows/flutter_windows_view.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,10 @@ void FlutterWindowsView::OnWindowSizeChanged(size_t width, size_t height) {
}
}

void FlutterWindowsView::OnWindowRepaint() {
ForceRedraw();
}

void FlutterWindowsView::OnPointerMove(double x,
double y,
FlutterPointerDeviceKind device_kind,
Expand Down Expand Up @@ -603,6 +607,8 @@ void FlutterWindowsView::CreateRenderSurface() {
PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds();
engine_->surface_manager()->CreateSurface(GetRenderTarget(), bounds.width,
bounds.height);
resize_target_width_ = bounds.width;
resize_target_height_ = bounds.height;
}
}

Expand Down
3 changes: 3 additions & 0 deletions shell/platform/windows/flutter_windows_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ class FlutterWindowsView : public WindowBindingHandlerDelegate,
// |WindowBindingHandlerDelegate|
void OnWindowSizeChanged(size_t width, size_t height) override;

// |WindowBindingHandlerDelegate|
void OnWindowRepaint() override;

// |WindowBindingHandlerDelegate|
void OnPointerMove(double x,
double y,
Expand Down
29 changes: 29 additions & 0 deletions shell/platform/windows/flutter_windows_view_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "flutter/shell/platform/common/json_message_codec.h"
#include "flutter/shell/platform/embedder/test_utils/proc_table_replacement.h"
#include "flutter/shell/platform/windows/flutter_window_win32.h"
#include "flutter/shell/platform/windows/flutter_windows_engine.h"
#include "flutter/shell/platform/windows/flutter_windows_texture_registrar.h"
#include "flutter/shell/platform/windows/testing/engine_modifier.h"
Expand Down Expand Up @@ -577,5 +578,33 @@ TEST(FlutterWindowsViewTest, WindowResizeTests) {
EXPECT_TRUE(send_window_metrics_event_called);
}

TEST(FlutterWindowsViewTest, WindowRepaintTests) {
std::unique_ptr<FlutterWindowsEngine> engine = GetTestEngine();
EngineModifier modifier(engine.get());

FlutterWindowsView view(
std::make_unique<flutter::FlutterWindowWin32>(100, 100));
view.SetEngine(std::move(engine));
view.CreateRenderSurface();

bool send_window_metrics_event_called = false;
size_t width = 0;
size_t height = 0;
modifier.embedder_api().SendWindowMetricsEvent = MOCK_ENGINE_PROC(
SendWindowMetricsEvent,
([&send_window_metrics_event_called, &width, &height](
auto engine, const FlutterWindowMetricsEvent* event) {
send_window_metrics_event_called = true;
width = event->width;
height = event->height;
return kSuccess;
}));

view.OnWindowRepaint();
EXPECT_TRUE(send_window_metrics_event_called);
EXPECT_EQ(width, 100);
EXPECT_EQ(height, 100);
}

} // namespace testing
} // namespace flutter
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class MockWindowBindingHandlerDelegate : public WindowBindingHandlerDelegate {
MockWindowBindingHandlerDelegate const&) = delete;

MOCK_METHOD2(OnWindowSizeChanged, void(size_t, size_t));
MOCK_METHOD0(OnWindowRepaint, void());
MOCK_METHOD4(OnPointerMove,
void(double, double, FlutterPointerDeviceKind, int32_t));
MOCK_METHOD5(OnPointerDown,
Expand Down
1 change: 1 addition & 0 deletions shell/platform/windows/testing/mock_window_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class MockWin32Window : public WindowWin32 {

MOCK_METHOD1(OnDpiScale, void(unsigned int));
MOCK_METHOD2(OnResize, void(unsigned int, unsigned int));
MOCK_METHOD0(OnPaint, void());
MOCK_METHOD4(OnPointerMove,
void(double, double, FlutterPointerDeviceKind, int32_t));
MOCK_METHOD5(OnPointerDown,
Expand Down
22 changes: 13 additions & 9 deletions shell/platform/windows/window_binding_handler_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,54 +22,58 @@ class WindowBindingHandlerDelegate {
// called on the platform thread.
virtual void OnWindowSizeChanged(size_t width, size_t height) = 0;

// Notifies delegate that backing window needs to be repainted.
// Typically called by currently configured WindowBindingHandler.
virtual void OnWindowRepaint() = 0;

// Notifies delegate that backing window mouse has moved.
// Typically called by currently configured WindowBindingHandler
// Typically called by currently configured WindowBindingHandler.
virtual void OnPointerMove(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id) = 0;

// Notifies delegate that backing window mouse pointer button has been
// pressed. Typically called by currently configured WindowBindingHandler
// pressed. Typically called by currently configured WindowBindingHandler.
virtual void OnPointerDown(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id,
FlutterPointerMouseButtons button) = 0;

// Notifies delegate that backing window mouse pointer button has been
// released. Typically called by currently configured WindowBindingHandler
// released. Typically called by currently configured WindowBindingHandler.
virtual void OnPointerUp(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id,
FlutterPointerMouseButtons button) = 0;

// Notifies delegate that backing window mouse pointer has left the window.
// Typically called by currently configured WindowBindingHandler
// Typically called by currently configured WindowBindingHandler.
virtual void OnPointerLeave(double x,
double y,
FlutterPointerDeviceKind device_kind,
int32_t device_id) = 0;

// Notifies delegate that a pan/zoom gesture has started.
// Typically called by DirectManipulationEventHandler
// Typically called by DirectManipulationEventHandler.
virtual void OnPointerPanZoomStart(int32_t device_id) = 0;

// Notifies delegate that a pan/zoom gesture has updated.
// Typically called by DirectManipulationEventHandler
// Typically called by DirectManipulationEventHandler.
virtual void OnPointerPanZoomUpdate(int32_t device_id,
double pan_x,
double pan_y,
double scale,
double rotation) = 0;

// Notifies delegate that a pan/zoom gesture has ended.
// Typically called by DirectManipulationEventHandler
// Typically called by DirectManipulationEventHandler.
virtual void OnPointerPanZoomEnd(int32_t device_id) = 0;

// Notifies delegate that backing window has received text.
// Typically called by currently configured WindowBindingHandler
// Typically called by currently configured WindowBindingHandler.
virtual void OnText(const std::u16string&) = 0;

// Notifies delegate that backing window size has received key press. Should
Expand Down Expand Up @@ -109,7 +113,7 @@ class WindowBindingHandlerDelegate {
virtual void OnComposeChange(const std::u16string& text, int cursor_pos) = 0;

// Notifies delegate that backing window size has recevied scroll.
// Typically called by currently configured WindowBindingHandler
// Typically called by currently configured WindowBindingHandler.
virtual void OnScroll(double x,
double y,
double delta_x,
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/windows/window_win32.cc
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ WindowWin32::HandleMessage(UINT const message,
current_height_ = height;
HandleResize(width, height);
break;
case WM_PAINT:
OnPaint();
break;
case WM_TOUCH: {
UINT num_points = LOWORD(wparam);
touch_points_.resize(num_points);
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/windows/window_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ class WindowWin32 : public KeyboardManagerWin32::WindowDelegate {
// Called when a resize occurs.
virtual void OnResize(UINT width, UINT height) = 0;

// Called when a paint is requested.
virtual void OnPaint() = 0;

// Called when the pointer moves within the
// window bounds.
virtual void OnPointerMove(double x,
Expand Down
6 changes: 6 additions & 0 deletions shell/platform/windows/window_win32_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -273,5 +273,11 @@ TEST(MockWin32Window, KeyDownWithCtrlToggled) {
SetKeyboardState(keyboard_state);
}

TEST(MockWin32Window, Paint) {
MockWin32Window window;
EXPECT_CALL(window, OnPaint()).Times(1);
window.InjectWindowMessage(WM_PAINT, 0, 0);
}

} // namespace testing
} // namespace flutter