Bug 782547, allow killfocus and deactivate messages to arrive in any order, remove blur suppression code, r=jmathies

This commit is contained in:
Neil Deakin 2012-10-24 16:05:29 -04:00
Родитель e49711ce62
Коммит e76c2ec778
4 изменённых файлов: 36 добавлений и 80 удалений

Просмотреть файл

@ -825,8 +825,6 @@ protected:
bool CanMoveResizeWindows();
bool GetBlurSuppression();
// If aDoFlush is true, we'll flush our own layout; otherwise we'll try to
// just flush our parent and only flush ourselves if we think we need to.
nsresult GetScrollXY(int32_t* aScrollX, int32_t* aScrollY,

Просмотреть файл

@ -44,27 +44,6 @@ typedef DWORD FILEOPENDIALOGOPTIONS;
///////////////////////////////////////////////////////////////////////////////
// Helper classes
// Manages matching SuppressBlurEvents calls on the parent widget.
class AutoSuppressEvents
{
public:
explicit AutoSuppressEvents(nsIWidget* aWidget) :
mWindow(static_cast<nsWindow *>(aWidget)) {
SuppressWidgetEvents(true);
}
~AutoSuppressEvents() {
SuppressWidgetEvents(false);
}
private:
void SuppressWidgetEvents(bool aFlag) {
if (mWindow) {
mWindow->SuppressBlurEvents(aFlag);
}
}
nsRefPtr<nsWindow> mWindow;
};
// Manages the current working path.
class AutoRestoreWorkingPath
{
@ -1027,8 +1006,6 @@ nsFilePicker::ShowW(int16_t *aReturnVal)
*aReturnVal = returnCancel;
AutoSuppressEvents supress(mParentWidget);
nsAutoString initialDir;
if (mDisplayDirectory)
mDisplayDirectory->GetPath(initialDir);

Просмотреть файл

@ -164,7 +164,7 @@
#include "nsIContent.h"
#include "mozilla/HangMonitor.h"
#include "mozilla/HangMonitor.h"
#include "nsIMM32Handler.h"
using namespace mozilla::widget;
@ -343,7 +343,6 @@ nsWindow::nsWindow() : nsBaseWidget()
mOldExStyle = 0;
mPainting = 0;
mLastKeyboardLayout = 0;
mBlurSuppressLevel = 0;
mLastPaintEndTime = TimeStamp::Now();
#ifdef MOZ_XUL
mTransparentSurface = nullptr;
@ -4012,25 +4011,14 @@ bool nsWindow::DispatchMouseEvent(uint32_t aEventType, WPARAM wParam,
return result;
}
void nsWindow::DispatchFocusToTopLevelWindow(bool aIsActivate)
HWND nsWindow::GetTopLevelForFocus(HWND aCurWnd)
{
if (aIsActivate)
sJustGotActivate = false;
sJustGotDeactivate = false;
if (!aIsActivate && BlurEventsSuppressed())
return;
if (!mWidgetListener)
return;
// retrive the toplevel window or dialog
HWND curWnd = mWnd;
// retrieve the toplevel window or dialog
HWND toplevelWnd = NULL;
while (curWnd) {
toplevelWnd = curWnd;
while (aCurWnd) {
toplevelWnd = aCurWnd;
nsWindow *win = WinUtils::GetNSWindowPtr(curWnd);
nsWindow *win = WinUtils::GetNSWindowPtr(aCurWnd);
if (win) {
nsWindowType wintype;
win->GetWindowType(wintype);
@ -4038,9 +4026,23 @@ void nsWindow::DispatchFocusToTopLevelWindow(bool aIsActivate)
break;
}
curWnd = ::GetParent(curWnd); // Parent or owner (if has no parent)
aCurWnd = ::GetParent(aCurWnd); // Parent or owner (if has no parent)
}
return toplevelWnd;
}
void nsWindow::DispatchFocusToTopLevelWindow(bool aIsActivate)
{
if (aIsActivate)
sJustGotActivate = false;
sJustGotDeactivate = false;
mLastKillFocusWindow = NULL;
if (!mWidgetListener)
return;
HWND toplevelWnd = GetTopLevelForFocus(mWnd);
if (toplevelWnd) {
nsWindow *win = WinUtils::GetNSWindowPtr(toplevelWnd);
if (win) {
@ -4070,36 +4072,6 @@ bool nsWindow::IsTopLevelMouseExit(HWND aWnd)
return WinUtils::GetTopLevelHWND(aWnd) != mouseTopLevel;
}
bool nsWindow::BlurEventsSuppressed()
{
// are they suppressed in this window?
if (mBlurSuppressLevel > 0)
return true;
// are they suppressed by any container widget?
HWND parentWnd = ::GetParent(mWnd);
if (parentWnd) {
nsWindow *parent = WinUtils::GetNSWindowPtr(parentWnd);
if (parent)
return parent->BlurEventsSuppressed();
}
return false;
}
// In some circumstances (opening dependent windows) it makes more sense
// (and fixes a crash bug) to not blur the parent window. Called from
// nsFilePicker.
void nsWindow::SuppressBlurEvents(bool aSuppress)
{
if (aSuppress)
++mBlurSuppressLevel; // for this widget
else {
NS_ASSERTION(mBlurSuppressLevel > 0, "unbalanced blur event suppression");
if (mBlurSuppressLevel > 0)
--mBlurSuppressLevel;
}
}
bool nsWindow::ConvertStatus(nsEventStatus aStatus)
{
return aStatus == nsEventStatus_eConsumeNoDefault;
@ -5030,9 +5002,13 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
int32_t fActive = LOWORD(wParam);
if (WA_INACTIVE == fActive) {
// when minimizing a window, the deactivation and focus events will
// When minimizing a window, the deactivation and focus events will
// be fired in the reverse order. Instead, just deactivate right away.
if (HIWORD(wParam))
// This can also happen when a modal file dialog is opened, so check
// if the last window to receive the WM_KILLFOCUS message was this one
// or a child of this one.
if (HIWORD(wParam) ||
(mLastKillFocusWindow && (GetTopLevelForFocus(mLastKillFocusWindow) == mWnd)))
DispatchFocusToTopLevelWindow(false);
else
sJustGotDeactivate = true;
@ -5108,6 +5084,9 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
if (sJustGotDeactivate) {
DispatchFocusToTopLevelWindow(false);
}
else {
mLastKillFocusWindow = mWnd;
}
break;
case WM_WINDOWPOSCHANGED:
@ -7081,6 +7060,9 @@ void nsWindow::OnDestroy()
mWidgetListener = nullptr;
mAttachedWidgetListener = nullptr;
if (mWnd == mLastKillFocusWindow)
mLastKillFocusWindow = NULL;
// Free our subclass and clear |this| stored in the window props. We will no longer
// receive events from Windows after this point.
SubclassWindow(FALSE);
@ -7095,7 +7077,7 @@ void nsWindow::OnDestroy()
// Release references to children, device context, toolkit, and app shell.
nsBaseWidget::OnDestroy();
// Clear our native parent handle.
// XXX Windows will take care of this in the proper order, and SetParent(nullptr)'s
// remove child on the parent already took place in nsBaseWidget's Destroy call above.

Просмотреть файл

@ -203,8 +203,6 @@ public:
LPARAM aLParam,
bool aDispatchPendingEvents);
void SuppressBlurEvents(bool aSuppress); // Called from nsFilePicker
bool BlurEventsSuppressed();
#ifdef ACCESSIBILITY
Accessible* GetRootAccessible();
#endif // ACCESSIBILITY
@ -329,6 +327,7 @@ protected:
* Event processing helpers
*/
bool DispatchPluginEvent(const MSG &aMsg);
HWND GetTopLevelForFocus(HWND aCurWnd);
void DispatchFocusToTopLevelWindow(bool aIsActivate);
bool DispatchStandardEvent(uint32_t aMsg);
bool DispatchCommandEvent(uint32_t aEventCommand);
@ -470,7 +469,6 @@ protected:
bool mFullscreenMode;
bool mMousePresent;
bool mDestroyCalled;
uint32_t mBlurSuppressLevel;
DWORD_PTR mOldStyle;
DWORD_PTR mOldExStyle;
InputContext mInputContext;
@ -483,6 +481,7 @@ protected:
uint32_t mPickerDisplayCount;
HICON mIconSmall;
HICON mIconBig;
HWND mLastKillFocusWindow;
static bool sDropShadowEnabled;
static uint32_t sInstanceCount;
static TriStateBool sCanQuit;