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

Conversation

yaakovschectman
Copy link
Contributor

Use WM_SIZE, WM_SHOWWINDOW, WM_SETFOCUS, and WM_KILLFOCUS to update the application lifecycle state on Windows.

flutter/flutter#103637

Pre-launch Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I read the Tree Hygiene wiki page, which explains my responsibilities.
  • I read and followed the Flutter Style Guide and the C++, Objective-C, Java style guides.
  • I listed at least one issue that this PR fixes in the description above.
  • I added new tests to check the change I am making or feature I am adding, or Hixie said the PR is test-exempt. See testing the engine for instructions on writing and running engine tests.
  • I updated/added relevant documentation (doc comments with ///).
  • I signed the CLA.
  • All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on Discord.

@@ -229,6 +230,8 @@ TEST(FlutterWindowTest, OnPointerStarSendsDeviceType) {
kDefaultPointerDeviceId, WM_LBUTTONDOWN);
win32window.OnPointerLeave(10.0, 10.0, kFlutterPointerDeviceKindStylus,
kDefaultPointerDeviceId);

win32window.SetView(nullptr);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added because FlutterWindow will try to send a HIDE update to the binding delegate upon its deconstruction, and this test sets the binding delegate to the address of a local stack variable, which means it is no longer valid once execution leaves the scope of this test function. Alternatively, we could replace delegate with a unique_ptr and get its raw pointer before moving it to pass to EXPECT_CALL

Copy link
Member

Choose a reason for hiding this comment

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

From a lifetime perspective, if the delegate is always strictly owned by the window and its lifetime is constrained to (at most) the lifetime of the owning window, then using a unique_ptr seems reasonable. We should do a quick audit of the code to be sure. If not, then I'd add a one-line comment explaining the rationale here as a breadcrumb for future archaeologists.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, it looks to be the other way around. The delegate i.e. FlutterWindowsView owns a pointer to the handler i.e. FlutterWindow, but where we're using a MockWindowBindingHandlerDelegate in these unit tests, the window is just scoped to the function it's created in. For now I will put a comment here, though moving ownership of win32window in these tests to inside the mock delegate may be feasible.

@yaakovschectman yaakovschectman marked this pull request as ready for review July 11, 2023 17:41

case WM_DESTROY:
OnWindowStateEvent(hwnd, HIDE);
break;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Note in case anyone is curious: The top level runner window receives a SETFOCUS message when it first comes up, but then does not receive further SETFOCUS or KILLFOCUS messages when the Flutter application gains or loses focus, so we are not listening for it here.

Copy link
Member

@cbracken cbracken left a comment

Choose a reason for hiding this comment

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

Overall looks great - just a few comments.

@@ -34,12 +47,43 @@ class WindowsLifecycleManager {
std::optional<LPARAM> lparam,
UINT exit_code);

// Intercept top level window messages, only paying attention to WM_CLOSE.
// Intercept top level window WM_CLOSE message and listen to events that may
// update the application lifecycle.
bool WindowProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l, LRESULT* result);
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps consider adding a little more context in comments for outsiders unfamiliar with this codebase:

  1. WindowProc: for top-level Flutter HWNDs
  2. ExternalWindowMessage: for top-level "external" HWNDs
  3. OnWindowStateEvent: for "inner" HWNDs that back Flutter views

Perhaps a different name could help clarify too? Perhaps OnTopLevelFlutterWindowMessage, OnTopLevelExternalWindowMessage, and OnWindowStateEvent? I don't feel strongly about any of this, feel free to use different names or keep the current ones :)

Copy link
Member

@loic-sharma loic-sharma left a comment

Choose a reason for hiding this comment

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

LGTM once the last few nits are addressed. Nice work! 🎉

@@ -34,12 +47,43 @@ class WindowsLifecycleManager {
std::optional<LPARAM> lparam,
UINT exit_code);

// Intercept top level window messages, only paying attention to WM_CLOSE.
// Intercept top level window WM_CLOSE message and listen to events that may
// update the application lifecycle.
bool WindowProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l, LRESULT* result);
Copy link
Member

@loic-sharma loic-sharma Jul 28, 2023

Choose a reason for hiding this comment

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

Consider making this also return std::optional<LRESULT> for consistency. I don't feel strongly, feel free to skip this

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This method gets used, albeit indirectly, by a call to RegisterTopLevelWindowProcDelegate, with an argument of a function with a certain signature and must return bool. So to make this change would mean adding some extra logic to a lambda in FlutterWindowsEngine, so I think it may be better to leave it for now.

@yaakovschectman yaakovschectman merged commit da3721a into flutter:main Jul 28, 2023
engine-flutter-autoroll added a commit to engine-flutter-autoroll/flutter that referenced this pull request Jul 28, 2023
@yaakovschectman yaakovschectman deleted the win_lifecycle branch July 28, 2023 21:40
fluttermirroringbot pushed a commit to flutter/flutter that referenced this pull request Jul 28, 2023
…131514)

flutter/engine@aa1278e...da3721a

2023-07-28 109111084+yaakovschectman@users.noreply.github.com Listen to window notifications to update application lifecycle (flutter/engine#43558)
2023-07-28 skia-flutter-autoroll@skia.org Roll ANGLE from 391bfa35798d to 0abd6f549ff1 (2 revisions) (flutter/engine#44114)
2023-07-28 dkwingsmt@users.noreply.github.com Remove a temporary lint ignore (flutter/engine#44091)
2023-07-28 skia-flutter-autoroll@skia.org Roll ANGLE from c319f34c4c8c to 391bfa35798d (1 revision) (flutter/engine#44112)
2023-07-28 43054281+camsim99@users.noreply.github.com [Android] Removes handling of Flutter splash screen (flutter/engine#44047)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC jonahwilliams@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
LouiseHsu pushed a commit to LouiseHsu/flutter that referenced this pull request Jul 31, 2023
…lutter#131514)

flutter/engine@aa1278e...da3721a

2023-07-28 109111084+yaakovschectman@users.noreply.github.com Listen to window notifications to update application lifecycle (flutter/engine#43558)
2023-07-28 skia-flutter-autoroll@skia.org Roll ANGLE from 391bfa35798d to 0abd6f549ff1 (2 revisions) (flutter/engine#44114)
2023-07-28 dkwingsmt@users.noreply.github.com Remove a temporary lint ignore (flutter/engine#44091)
2023-07-28 skia-flutter-autoroll@skia.org Roll ANGLE from c319f34c4c8c to 391bfa35798d (1 revision) (flutter/engine#44112)
2023-07-28 43054281+camsim99@users.noreply.github.com [Android] Removes handling of Flutter splash screen (flutter/engine#44047)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC jonahwilliams@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
loic-sharma added a commit that referenced this pull request Aug 2, 2023
auto-submit bot pushed a commit that referenced this pull request Aug 2, 2023
…e" (#44275)

Reverts #43558

Customer reported a crash on shutdown:

```
flutter::Window::HandleMessage(unsigned int,unsigned __int64,__int64)
...
?NtUserDestroyWindow
flutter::Window::Destroy()
flutter::Window::~Window()
flutter::FlutterWindow::`vector deleting destructor'`adjustor{312}' (unsigned int)
flutter::FlutterWindowsView::~FlutterWindowsView()
flutter::FlutterWindowsView::~FlutterWindowsView
FlutterDesktopViewControllerDestroy
flutter::FlutterViewController::~FlutterViewController
FlutterWindow::~FlutterWindow()
wWinMain
```

The message causing the crash is `WM_KILLFOCUS`.
vashworth pushed a commit to vashworth/flutter that referenced this pull request Aug 2, 2023
…lutter#131514)

flutter/engine@aa1278e...da3721a

2023-07-28 109111084+yaakovschectman@users.noreply.github.com Listen to window notifications to update application lifecycle (flutter/engine#43558)
2023-07-28 skia-flutter-autoroll@skia.org Roll ANGLE from 391bfa35798d to 0abd6f549ff1 (2 revisions) (flutter/engine#44114)
2023-07-28 dkwingsmt@users.noreply.github.com Remove a temporary lint ignore (flutter/engine#44091)
2023-07-28 skia-flutter-autoroll@skia.org Roll ANGLE from c319f34c4c8c to 391bfa35798d (1 revision) (flutter/engine#44112)
2023-07-28 43054281+camsim99@users.noreply.github.com [Android] Removes handling of Flutter splash screen (flutter/engine#44047)

If this roll has caused a breakage, revert this CL and stop the roller
using the controls here:
https://autoroll.skia.org/r/flutter-engine-flutter-autoroll
Please CC jonahwilliams@google.com,rmistry@google.com,zra@google.com on the revert to ensure that a human
is aware of the problem.

To file a bug in Flutter: https://github.com/flutter/flutter/issues/new/choose

To report a problem with the AutoRoller itself, please file a bug:
https://bugs.chromium.org/p/skia/issues/entry?template=Autoroller+Bug

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
gaaclarke pushed a commit to gaaclarke/engine that referenced this pull request Aug 30, 2023
…er#43558)

Use `WM_SIZE, WM_SHOWWINDOW, WM_SETFOCUS, and WM_KILLFOCUS` to update
the application lifecycle state on Windows.

flutter/flutter#103637

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [x] I read and followed the [Flutter Style Guide] and the [C++,
Objective-C, Java style guides].
- [x] I listed at least one issue that this PR fixes in the description
above.
- [x] I added new tests to check the change I am making or feature I am
adding, or Hixie said the PR is test-exempt. See [testing the engine]
for instructions on writing and running engine tests.
- [x] I updated/added relevant documentation (doc comments with `///`).
- [ ] I signed the [CLA].
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#overview
[Tree Hygiene]: https://github.com/flutter/flutter/wiki/Tree-hygiene
[Flutter Style Guide]:
https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[C++, Objective-C, Java style guides]:
https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
[testing the engine]:
https://github.com/flutter/flutter/wiki/Testing-the-engine
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/wiki/Tree-hygiene#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/wiki/Chat

---------

Co-authored-by: Brandon DeRosier <bdero@google.com>
Co-authored-by: skia-flutter-autoroll <skia-flutter-autoroll@skia.org>
gaaclarke pushed a commit to gaaclarke/engine that referenced this pull request Aug 30, 2023
…e" (flutter#44275)

Reverts flutter#43558

Customer reported a crash on shutdown:

```
flutter::Window::HandleMessage(unsigned int,unsigned __int64,__int64)
...
?NtUserDestroyWindow
flutter::Window::Destroy()
flutter::Window::~Window()
flutter::FlutterWindow::`vector deleting destructor'`adjustor{312}' (unsigned int)
flutter::FlutterWindowsView::~FlutterWindowsView()
flutter::FlutterWindowsView::~FlutterWindowsView
FlutterDesktopViewControllerDestroy
flutter::FlutterViewController::~FlutterViewController
FlutterWindow::~FlutterWindow()
wWinMain
```

The message causing the crash is `WM_KILLFOCUS`.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

6 participants