зеркало из https://github.com/mozilla/pjs.git
Bug 665315 - OOPP Contextmenu loses messages; r=jmathies
This commit is contained in:
Родитель
bd43cc1726
Коммит
1f1b6b4402
|
@ -60,6 +60,7 @@ using mozilla::gfx::SharedDIBSurface;
|
|||
#include "gfxAlphaRecovery.h"
|
||||
|
||||
#include "mozilla/ipc/SyncChannel.h"
|
||||
#include "mozilla/AutoRestore.h"
|
||||
|
||||
using mozilla::ipc::ProcessChild;
|
||||
using namespace mozilla::plugins;
|
||||
|
@ -1547,14 +1548,8 @@ PluginInstanceChild::TrackPopupHookProc(HMENU hMenu,
|
|||
// can act on the menu item selected.
|
||||
bool isRetCmdCall = (uFlags & TPM_RETURNCMD);
|
||||
|
||||
// A little trick scrounged from chromium's code - set the focus
|
||||
// to our surrogate parent so keyboard nav events go to the menu.
|
||||
HWND focusHwnd = SetFocus(surrogateHwnd);
|
||||
DWORD res = sUser32TrackPopupMenuStub(hMenu, uFlags|TPM_RETURNCMD, x, y,
|
||||
nReserved, surrogateHwnd, prcRect);
|
||||
if (IsWindow(focusHwnd)) {
|
||||
SetFocus(focusHwnd);
|
||||
}
|
||||
|
||||
if (!isRetCmdCall && res) {
|
||||
SendMessage(hWnd, WM_COMMAND, MAKEWPARAM(res, 0), 0);
|
||||
|
@ -1620,6 +1615,8 @@ PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
|
|||
// Events that might generate nested event dispatch loops need
|
||||
// special handling during delivery.
|
||||
int16_t handled;
|
||||
|
||||
HWND focusHwnd = NULL;
|
||||
|
||||
// TrackPopupMenu will fail if the parent window is not associated with
|
||||
// our ui thread. So we hook TrackPopupMenu so we can hand in a surrogate
|
||||
|
@ -1628,12 +1625,23 @@ PluginInstanceChild::WinlessHandleEvent(NPEvent& event)
|
|||
(event.event == WM_RBUTTONDOWN || // flash
|
||||
event.event == WM_RBUTTONUP)) { // silverlight
|
||||
sWinlessPopupSurrogateHWND = mWinlessPopupSurrogateHWND;
|
||||
|
||||
// A little trick scrounged from chromium's code - set the focus
|
||||
// to our surrogate parent so keyboard nav events go to the menu.
|
||||
focusHwnd = SetFocus(mWinlessPopupSurrogateHWND);
|
||||
}
|
||||
|
||||
MessageLoop* loop = MessageLoop::current();
|
||||
AutoRestore<bool> modalLoop(loop->os_modal_loop());
|
||||
|
||||
handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&event));
|
||||
|
||||
sWinlessPopupSurrogateHWND = NULL;
|
||||
|
||||
if (IsWindow(focusHwnd)) {
|
||||
SetFocus(focusHwnd);
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
|
|
|
@ -2289,12 +2289,13 @@ PluginModuleChild::NestedInputEventHook(int nCode, WPARAM wParam, LPARAM lParam)
|
|||
PluginModuleChild* self = current();
|
||||
PRUint32 len = self->mIncallPumpingStack.Length();
|
||||
if (nCode >= 0 && len && !self->mIncallPumpingStack[len - 1]._spinning) {
|
||||
MessageLoop* loop = MessageLoop::current();
|
||||
self->SendProcessNativeEventsInRPCCall();
|
||||
IncallFrame& f = self->mIncallPumpingStack[len - 1];
|
||||
f._spinning = true;
|
||||
MessageLoop* loop = MessageLoop::current();
|
||||
f._savedNestableTasksAllowed = loop->NestableTasksAllowed();
|
||||
loop->SetNestableTasksAllowed(true);
|
||||
loop->set_os_modal_loop(true);
|
||||
}
|
||||
|
||||
return CallNextHookEx(NULL, nCode, wParam, lParam);
|
||||
|
|
|
@ -92,6 +92,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);
|
||||
|
|
|
@ -264,6 +264,16 @@ public:
|
|||
exception_restoration_ = restore;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
void set_os_modal_loop(bool os_modal_loop) {
|
||||
os_modal_loop_ = os_modal_loop;
|
||||
}
|
||||
|
||||
bool & os_modal_loop() {
|
||||
return os_modal_loop_;
|
||||
}
|
||||
#endif // OS_WIN
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
protected:
|
||||
struct RunState {
|
||||
|
@ -424,6 +434,12 @@ public:
|
|||
|
||||
RunState* state_;
|
||||
|
||||
#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_;
|
||||
#endif
|
||||
|
||||
// The next sequence number to use for delayed tasks.
|
||||
int next_sequence_num_;
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
#include "base/message_loop.h"
|
||||
#include "base/histogram.h"
|
||||
#include "base/win_util.h"
|
||||
|
||||
|
@ -380,11 +381,18 @@ bool MessagePumpForUI::ProcessPumpReplacementMessage() {
|
|||
// that the re-post of kMsgHaveWork may be asynchronous to this thread!!
|
||||
|
||||
MSG msg;
|
||||
bool have_message = (0 != PeekMessage(&msg, NULL, 0, 0, PM_REMOVE));
|
||||
|
||||
if (have_message && msg.message == WM_NULL)
|
||||
bool have_message = false;
|
||||
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));
|
||||
|
||||
if (have_message && msg.message == WM_NULL)
|
||||
have_message = (0 != PeekMessage(&msg, NULL, 0, 0, PM_REMOVE));
|
||||
}
|
||||
|
||||
DCHECK(!have_message || kMsgHaveWork != msg.message ||
|
||||
msg.hwnd != message_hwnd_);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче