cef/patch/patches/message_loop_443_1992243003...

80 lines
3.8 KiB
Diff
Raw Normal View History

diff --git base/message_loop/message_loop.h base/message_loop/message_loop.h
index 439d364fc54c..6cbe494e7041 100644
--- base/message_loop/message_loop.h
+++ base/message_loop/message_loop.h
@@ -257,6 +257,16 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate,
void AddTaskObserver(TaskObserver* task_observer);
void RemoveTaskObserver(TaskObserver* task_observer);
+#if defined(OS_WIN)
+ void set_os_modal_loop(bool os_modal_loop) {
+ os_modal_loop_ = os_modal_loop;
+ }
+
+ bool os_modal_loop() const {
+ return os_modal_loop_;
+ }
+#endif // OS_WIN
+
// Returns true if the message loop is idle (ignoring delayed tasks). This is
// the same condition which triggers DoWork() to return false: i.e.
// out of tasks which can be processed at the current run-level -- there might
@@ -358,6 +368,12 @@ class BASE_EXPORT MessageLoop : public MessagePump::Delegate,
// is known to generate a system-driven nested loop.
bool task_execution_allowed_ = true;
+#if defined(OS_WIN)
+ // Should be set to true before calling Windows APIs like TrackPopupMenu, etc.
+ // which enter a modal message loop.
+ bool os_modal_loop_ = false;
+#endif
+
// pump_factory_.Run() is called to create a message pump for this loop
// if type_ is TYPE_CUSTOM and pump_ is null.
MessagePumpFactoryCallback pump_factory_;
diff --git base/message_loop/message_pump_win.cc base/message_loop/message_pump_win.cc
index b145a1d54a32..9b28169050b2 100644
--- base/message_loop/message_pump_win.cc
+++ base/message_loop/message_pump_win.cc
@@ -372,20 +372,28 @@ bool MessagePumpForUI::ProcessMessageHelper(const MSG& msg) {
}
bool MessagePumpForUI::ProcessPumpReplacementMessage() {
- // When we encounter a kMsgHaveWork message, this method is called to peek and
- // process a replacement message. The goal is to make the kMsgHaveWork as non-
- // intrusive as possible, even though a continuous stream of such messages are
- // posted. This method carefully peeks a message while there is no chance for
- // a kMsgHaveWork to be pending, then resets the |have_work_| flag (allowing a
- // replacement kMsgHaveWork to possibly be posted), and finally dispatches
- // that peeked replacement. Note that the re-post of kMsgHaveWork may be
- // asynchronous to this thread!!
-
+ // When we encounter a kMsgHaveWork message, this method is called to peek
+ // and process a replacement message, such as a WM_PAINT or WM_TIMER. The
+ // goal is to make the kMsgHaveWork as non-intrusive as possible, even though
+ // a continuous stream of such messages are posted. This method carefully
+ // peeks a message while there is no chance for a kMsgHaveWork to be pending,
+ // then resets the have_work_ flag (allowing a replacement kMsgHaveWork to
+ // possibly be posted), and finally dispatches that peeked replacement. Note
+ // that the re-post of kMsgHaveWork may be asynchronous to this thread!!
+
+ bool have_message = false;
MSG msg;
- const bool have_message =
- PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE) != FALSE;
+ // We should not process all window messages if we are in the context of an
+ // OS modal loop, i.e. in the context of a windows API call like MessageBox.
+ // This is to ensure that these messages are peeked out by the OS modal loop.
+ if (MessageLoop::current()->os_modal_loop()) {
+ // We only peek out WM_PAINT and WM_TIMER here for reasons mentioned above.
+ have_message = PeekMessage(&msg, NULL, WM_PAINT, WM_PAINT, PM_REMOVE) ||
+ PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE);
+ } else {
+ have_message = PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) != FALSE;
+ }
- // Expect no message or a message different than kMsgHaveWork.
DCHECK(!have_message || kMsgHaveWork != msg.message ||
msg.hwnd != message_window_.hwnd());