summaryrefslogtreecommitdiffstats
path: root/base
diff options
context:
space:
mode:
authorananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-24 03:40:28 +0000
committerananta@chromium.org <ananta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-24 03:40:28 +0000
commit2ec01fe90944d9489cc3949c80fcc0826f9b1c76 (patch)
tree18a9250577efc5c9c8b53f140810f61ea59e10a1 /base
parent72e3c575424b731dcfe66dba8d009fb87c236002 (diff)
downloadchromium_src-2ec01fe90944d9489cc3949c80fcc0826f9b1c76.zip
chromium_src-2ec01fe90944d9489cc3949c80fcc0826f9b1c76.tar.gz
chromium_src-2ec01fe90944d9489cc3949c80fcc0826f9b1c76.tar.bz2
When we process the tickler message in our windows message pump, we should not dispatch
all window messages specifically if we are in the context of a Windows modal loop, i.e. a Windows API like TrackPopupMenu, etc. This is because these API's expect to handle input messages like keyboard and mouse messages by peeking them from the queue and handling them. Our message pump currently dispatches all windows messages while processing the tickler message which causes the windows modal loop to not see keyboard and mouse messages at times. Added a flag in the windows message loop which indicates if we are in the context of an os modal loop. If yes we just peek for WM_PAINT and timer and dispatch those and get out. Fixes bug http://code.google.com/p/chromium/issues/detail?id=59864 BUG=59864 Review URL: http://codereview.chromium.org/6676099 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79248 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r--base/message_loop.cc3
-rw-r--r--base/message_loop.h13
-rw-r--r--base/message_pump_win.cc14
3 files changed, 29 insertions, 1 deletions
diff --git a/base/message_loop.cc b/base/message_loop.cc
index 85e37d4..39881d1 100644
--- a/base/message_loop.cc
+++ b/base/message_loop.cc
@@ -123,6 +123,9 @@ MessageLoop::MessageLoop(Type type)
nestable_tasks_allowed_(true),
exception_restoration_(false),
state_(NULL),
+#ifdef OS_WIN
+ os_modal_loop_(false),
+#endif // OS_WIN
next_sequence_num_(0) {
DCHECK(!current()) << "should only have one message loop per thread";
lazy_tls_ptr.Pointer()->Set(this);
diff --git a/base/message_loop.h b/base/message_loop.h
index c1dce43..e3653f9 100644
--- a/base/message_loop.h
+++ b/base/message_loop.h
@@ -319,6 +319,16 @@ class MessageLoop : public base::MessagePump::Delegate {
// Asserts that the MessageLoop is "idle".
void AssertIdle() const;
+#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
+
//----------------------------------------------------------------------------
protected:
struct RunState {
@@ -476,6 +486,9 @@ class MessageLoop : public base::MessagePump::Delegate {
#if defined(OS_WIN)
base::TimeTicks high_resolution_timer_expiration_;
+ // Should be set to true before calling Windows APIs like TrackPopupMenu, etc
+ // which enter a modal message loop.
+ bool os_modal_loop_;
#endif
// The next sequence number to use for delayed tasks.
diff --git a/base/message_pump_win.cc b/base/message_pump_win.cc
index 778c2f5..1924081 100644
--- a/base/message_pump_win.cc
+++ b/base/message_pump_win.cc
@@ -6,6 +6,7 @@
#include <math.h>
+#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/win/wrapped_window_proc.h"
@@ -371,8 +372,19 @@ bool MessagePumpForUI::ProcessPumpReplacementMessage() {
// 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;
- bool have_message = (0 != PeekMessage(&msg, NULL, 0, 0, PM_REMOVE));
+ // 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 = (0 != PeekMessage(&msg, NULL, 0, 0, PM_REMOVE));
+ }
+
DCHECK(!have_message || kMsgHaveWork != msg.message ||
msg.hwnd != message_hwnd_);