mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	
		
			
				
	
	
		
			89 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| diff --git base/message_loop/message_loop_current.h base/message_loop/message_loop_current.h
 | |
| index c5016dcf20a2..cf1db622f8fb 100644
 | |
| --- base/message_loop/message_loop_current.h
 | |
| +++ base/message_loop/message_loop_current.h
 | |
| @@ -120,6 +120,16 @@ class BASE_EXPORT MessageLoopCurrent {
 | |
|    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
 | |
| +
 | |
|    // Enables or disables the recursive task processing. This happens in the case
 | |
|    // of recursive message loops. Some unwanted message loops may occur when
 | |
|    // using common controls or printer functions. By default, recursive task
 | |
| @@ -188,6 +198,13 @@ class BASE_EXPORT MessageLoopCurrent {
 | |
|    explicit MessageLoopCurrent(MessageLoop* current) : current_(current) {}
 | |
|  
 | |
|    MessageLoop* const current_;
 | |
| +
 | |
| +#if defined(OS_WIN)
 | |
| + private:
 | |
| +  // Should be set to true before calling Windows APIs like TrackPopupMenu, etc.
 | |
| +  // which enter a modal message loop.
 | |
| +  bool os_modal_loop_ = false;
 | |
| +#endif
 | |
|  };
 | |
|  
 | |
|  #if !defined(OS_NACL)
 | |
| diff --git base/message_loop/message_pump_win.cc base/message_loop/message_pump_win.cc
 | |
| index 8e6f1f41def2..b07865ebae37 100644
 | |
| --- base/message_loop/message_pump_win.cc
 | |
| +++ base/message_loop/message_pump_win.cc
 | |
| @@ -11,6 +11,7 @@
 | |
|  
 | |
|  #include "base/debug/alias.h"
 | |
|  #include "base/memory/ptr_util.h"
 | |
| +#include "base/message_loop/message_loop_current.h"
 | |
|  #include "base/metrics/histogram_macros.h"
 | |
|  #include "base/strings/stringprintf.h"
 | |
|  #include "base/trace_event/trace_event.h"
 | |
| @@ -369,20 +370,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 (MessageLoopCurrent::Get()->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());
 | |
|  
 |