forked from mirrors/gecko-dev
Bug 1892835 - Remove delayed NCACTIVATE hack. r=masayuki,win-reviewers,rkraesig
See comment in the bug. This was needed for bogus mouse drivers back in the XP/Vista era. However Win10/11 sends wheel messages to the window under the cursor instead of focused window, so these kinds of issues shouldn't arise there. Try to remove this legacy hack. Differential Revision: https://phabricator.services.mozilla.com/D210302
This commit is contained in:
parent
883f596167
commit
4d4d3470a8
3 changed files with 19 additions and 122 deletions
|
|
@ -25,9 +25,6 @@
|
|||
#define MOZ_WM_HSCROLL (WM_APP + 0x0313)
|
||||
#define MOZ_WM_MOUSEWHEEL_FIRST MOZ_WM_MOUSEVWHEEL
|
||||
#define MOZ_WM_MOUSEWHEEL_LAST MOZ_WM_HSCROLL
|
||||
// If a popup window is being activated, we try to reactivate the previous
|
||||
// window with this message.
|
||||
#define MOZ_WM_REACTIVATE (WM_APP + 0x0314)
|
||||
// If TSFTextStore needs to notify TSF/TIP of layout change later, this
|
||||
// message is posted.
|
||||
#define MOZ_WM_NOTIY_TSF_OF_LAYOUT_CHANGE (WM_APP + 0x0315)
|
||||
|
|
|
|||
|
|
@ -7724,23 +7724,6 @@ bool nsWindow::GetPopupsToRollup(nsIRollupListener* aRollupListener,
|
|||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
bool nsWindow::NeedsToHandleNCActivateDelayed(HWND aWnd) {
|
||||
// While popup is open, popup window might be activated by other application.
|
||||
// At this time, we need to take back focus to the previous window but it
|
||||
// causes flickering its nonclient area because WM_NCACTIVATE comes before
|
||||
// WM_ACTIVATE and we cannot know which window will take focus at receiving
|
||||
// WM_NCACTIVATE. Therefore, we need a hack for preventing the flickerling.
|
||||
//
|
||||
// If non-popup window receives WM_NCACTIVATE at deactivating, default
|
||||
// wndproc shouldn't handle it as deactivating. Instead, at receiving
|
||||
// WM_ACTIVIATE after that, WM_NCACTIVATE should be sent again manually.
|
||||
// This returns true if the window needs to handle WM_NCACTIVATE later.
|
||||
|
||||
nsWindow* window = WinUtils::GetNSWindowPtr(aWnd);
|
||||
return window && !window->IsPopup();
|
||||
}
|
||||
|
||||
static bool IsTouchSupportEnabled(HWND aWnd) {
|
||||
nsWindow* topWindow =
|
||||
WinUtils::GetNSWindowPtr(WinUtils::GetTopLevelHWND(aWnd, true));
|
||||
|
|
@ -7794,8 +7777,6 @@ bool nsWindow::DealWithPopups(HWND aWnd, UINT aMessage, WPARAM aWParam,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool sSendingNCACTIVATE = false;
|
||||
static bool sPendingNCACTIVATE = false;
|
||||
uint32_t popupsToRollup = UINT32_MAX;
|
||||
|
||||
bool consumeRollupEvent = false;
|
||||
|
|
@ -7888,110 +7869,30 @@ bool nsWindow::DealWithPopups(HWND aWnd, UINT aMessage, WPARAM aWParam,
|
|||
break;
|
||||
|
||||
case WM_ACTIVATE: {
|
||||
// This marker should be useless nowadays, but kept just for safety, see
|
||||
// the discussion in D210302. See also bug 1842170.
|
||||
WndProcUrgentInvocation::Marker _marker;
|
||||
|
||||
// NOTE: Don't handle WA_INACTIVE for preventing popup taking focus
|
||||
// because we cannot distinguish it's caused by mouse or not.
|
||||
if (LOWORD(aWParam) == WA_ACTIVE && aLParam) {
|
||||
nsWindow* window = WinUtils::GetNSWindowPtr(aWnd);
|
||||
if (window && (window->IsPopup() || window->mIsAlert)) {
|
||||
// Cancel notifying widget listeners of deactivating the previous
|
||||
// active window (see WM_KILLFOCUS case in ProcessMessage()).
|
||||
sJustGotDeactivate = false;
|
||||
// Reactivate the window later.
|
||||
::PostMessageW(aWnd, MOZ_WM_REACTIVATE, aWParam, aLParam);
|
||||
return true;
|
||||
}
|
||||
// Don't rollup the popup when focus moves back to the parent window
|
||||
// from a popup because such case is caused by strange mouse drivers.
|
||||
nsWindow* prevWindow =
|
||||
WinUtils::GetNSWindowPtr(reinterpret_cast<HWND>(aLParam));
|
||||
if (prevWindow && prevWindow->IsPopup()) {
|
||||
// Consume this message here since previous window must not have
|
||||
// been inactivated since we've already stopped accepting the
|
||||
// inactivation below.
|
||||
return true;
|
||||
}
|
||||
} else if (LOWORD(aWParam) == WA_INACTIVE) {
|
||||
nsWindow* activeWindow =
|
||||
WinUtils::GetNSWindowPtr(reinterpret_cast<HWND>(aLParam));
|
||||
if (sPendingNCACTIVATE && NeedsToHandleNCActivateDelayed(aWnd)) {
|
||||
// If focus moves to non-popup widget or focusable popup, the window
|
||||
// needs to update its nonclient area.
|
||||
if (!activeWindow || !activeWindow->IsPopup()) {
|
||||
sSendingNCACTIVATE = true;
|
||||
::SendMessageW(aWnd, WM_NCACTIVATE, false, 0);
|
||||
sSendingNCACTIVATE = false;
|
||||
}
|
||||
sPendingNCACTIVATE = false;
|
||||
}
|
||||
// If focus moves from/to popup, we don't need to rollup the popup
|
||||
// because such case is caused by strange mouse drivers. And in
|
||||
// such case, we should consume the message here since we need to
|
||||
// hide this odd focus move from our content. (If we didn't consume
|
||||
// the message here, ProcessMessage() will notify widget listener of
|
||||
// inactivation and that causes unnecessary reflow for supporting
|
||||
// -moz-window-inactive pseudo class.
|
||||
if (activeWindow) {
|
||||
if (activeWindow->IsPopup()) {
|
||||
return true;
|
||||
}
|
||||
nsWindow* deactiveWindow = WinUtils::GetNSWindowPtr(aWnd);
|
||||
if (deactiveWindow && deactiveWindow->IsPopup()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (LOWORD(aWParam) == WA_CLICKACTIVE) {
|
||||
// If the WM_ACTIVATE message is caused by a click in a popup,
|
||||
// we should not rollup any popups.
|
||||
nsWindow* window = WinUtils::GetNSWindowPtr(aWnd);
|
||||
if ((window && window->IsPopup()) ||
|
||||
!GetPopupsToRollup(rollupListener, &popupsToRollup)) {
|
||||
return false;
|
||||
}
|
||||
nsWindow* window = WinUtils::GetNSWindowPtr(aWnd);
|
||||
nsWindow* prevWindow =
|
||||
WinUtils::GetNSWindowPtr(reinterpret_cast<HWND>(aLParam));
|
||||
// Don't rollup popups for WM_ACTIVATE from/to a popup.
|
||||
// When we click on a popup (WA_CLICKACTIVE) we don't want to do it.
|
||||
// WA_ACTIVE/WA_INACTIVE shouldn't really happen, but some old
|
||||
// pre-windows-10 drivers used to do this, see bug 953146.
|
||||
// It might be the case that is no longer needed tho, and we can move
|
||||
// this to the WA_CLICKACTIVE condition.
|
||||
if ((window && window->IsPopup()) ||
|
||||
(prevWindow && prevWindow->IsPopup())) {
|
||||
return false;
|
||||
}
|
||||
if (LOWORD(aWParam) == WA_CLICKACTIVE &&
|
||||
!GetPopupsToRollup(rollupListener, &popupsToRollup)) {
|
||||
return false;
|
||||
}
|
||||
allowAnimations = nsIRollupListener::AllowAnimations::No;
|
||||
} break;
|
||||
|
||||
case MOZ_WM_REACTIVATE:
|
||||
// The previous active window should take back focus.
|
||||
if (::IsWindow(reinterpret_cast<HWND>(aLParam))) {
|
||||
// FYI: Even without this API call, you see expected result (e.g., the
|
||||
// owner window of the popup keeps active without flickering
|
||||
// the non-client area). And also this causes initializing
|
||||
// TSF and it causes using CPU time a lot. However, even if we
|
||||
// consume WM_ACTIVE messages, native focus change has already
|
||||
// been occurred. I.e., a popup window is active now. Therefore,
|
||||
// you'll see some odd behavior if we don't reactivate the owner
|
||||
// window here. For example, if you do:
|
||||
// 1. Turn wheel on a bookmark panel.
|
||||
// 2. Turn wheel on another window.
|
||||
// then, you'll see that the another window becomes active but the
|
||||
// owner window of the bookmark panel looks still active and the
|
||||
// bookmark panel keeps open. The reason is that the first wheel
|
||||
// operation gives focus to the bookmark panel. Therefore, when
|
||||
// the next operation gives focus to the another window, previous
|
||||
// focus window is the bookmark panel (i.e., a popup window).
|
||||
// So, in this case, our hack around here prevents to inactivate
|
||||
// the owner window and roll up the bookmark panel.
|
||||
::SetForegroundWindow(reinterpret_cast<HWND>(aLParam));
|
||||
}
|
||||
return true;
|
||||
|
||||
case WM_NCACTIVATE:
|
||||
if (!aWParam && !sSendingNCACTIVATE &&
|
||||
NeedsToHandleNCActivateDelayed(aWnd)) {
|
||||
// Don't just consume WM_NCACTIVATE. It doesn't handle only the
|
||||
// nonclient area state change.
|
||||
::DefWindowProcW(aWnd, aMessage, TRUE, aLParam);
|
||||
// Accept the deactivating because it's necessary to receive following
|
||||
// WM_ACTIVATE.
|
||||
*aResult = TRUE;
|
||||
sPendingNCACTIVATE = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
case WM_MOUSEACTIVATE:
|
||||
if (!EventIsInsideWindow(popupWindow) &&
|
||||
GetPopupsToRollup(rollupListener, &popupsToRollup)) {
|
||||
|
|
|
|||
|
|
@ -598,7 +598,6 @@ class nsWindow final : public nsBaseWidget {
|
|||
static bool GetPopupsToRollup(
|
||||
nsIRollupListener* aRollupListener, uint32_t* aPopupsToRollup,
|
||||
mozilla::Maybe<POINT> aEventPoint = mozilla::Nothing());
|
||||
static bool NeedsToHandleNCActivateDelayed(HWND aWnd);
|
||||
static bool DealWithPopups(HWND inWnd, UINT inMsg, WPARAM inWParam,
|
||||
LPARAM inLParam, LRESULT* outResult);
|
||||
|
||||
|
|
@ -869,7 +868,7 @@ class nsWindow final : public nsBaseWidget {
|
|||
class MOZ_STACK_CLASS ContextMenuPreventer final {
|
||||
public:
|
||||
explicit ContextMenuPreventer(nsWindow* aWindow)
|
||||
: mWindow(aWindow), mNeedsToPreventContextMenu(false){};
|
||||
: mWindow(aWindow), mNeedsToPreventContextMenu(false) {};
|
||||
~ContextMenuPreventer() {
|
||||
mWindow->mNeedsToPreventContextMenu = mNeedsToPreventContextMenu;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue