--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -136,16 +136,17 @@
#include "nsIMemoryInfoDumper.h"
#include "nsIMemoryReporter.h"
#include "nsIMozBrowserFrame.h"
#include "nsIMutable.h"
#include "nsIObserverService.h"
#include "nsIParentChannel.h"
#include "nsIPresShell.h"
#include "nsIRemoteWindowContext.h"
+#include "nsIRollupListener.h"
#include "nsIScriptError.h"
#include "nsIScriptSecurityManager.h"
#include "nsISiteSecurityService.h"
#include "nsISound.h"
#include "nsISpellChecker.h"
#include "nsISupportsPrimitives.h"
#include "nsITimer.h"
#include "nsIURIFixup.h"
@@ -167,16 +168,17 @@
#include "nsServiceManagerUtils.h"
#include "nsStyleSheetService.h"
#include "nsThreadUtils.h"
#include "nsToolkitCompsCID.h"
#include "nsWidgetsCID.h"
#include "PreallocatedProcessManager.h"
#include "ProcessPriorityManager.h"
#include "SandboxHal.h"
+#include "SelectRollupListener.h"
#include "SourceSurfaceRawData.h"
#include "TabParent.h"
#include "URIUtils.h"
#include "nsIWebBrowserChrome.h"
#include "nsIDocShell.h"
#include "nsDocShell.h"
#include "nsOpenURIInFrameParams.h"
#include "mozilla/net/NeckoMessageUtils.h"
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -159,16 +159,21 @@ parent:
/**
* When content moves focus from a native plugin window that's a child
* of the native browser window we need to move native focus to the
* browser. Otherwise the plugin window will never relinquish focus.
*/
sync DispatchFocusToTopLevelWindow();
+ /**
+ * Checks for rollup commands
+ */
+ async CaptureRollupEvents(LayoutDeviceIntRect aRect, bool aDroppedDown);
+
parent:
/**
* When child sends this message, parent should move focus to
* the next or previous focusable element or document.
*/
async MoveFocus(bool forward, bool forDocumentNavigation);
/**
@@ -613,16 +618,21 @@ child:
async SizeModeChanged(nsSizeMode sizeMode);
async ParentActivated(bool aActivated);
async SetKeyboardIndicators(UIStateChangeType showAccelerators,
UIStateChangeType showFocusRings);
/**
+ * Rolls up the popup in the child process
+ */
+ async RollupPopup();
+
+ /**
* StopIMEStateManagement() is called when the process loses focus and
* should stop managing IME state.
*/
async StopIMEStateManagement();
/**
* @see nsIDOMWindowUtils sendMouseEvent.
*/
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -429,16 +429,17 @@ TabChild::TabChild(nsIContentChild* aMan
#endif
, mPendingDocShellIsActive(false)
, mPendingDocShellReceivedMessage(false)
, mPendingRenderLayers(false)
, mPendingRenderLayersReceivedMessage(false)
, mPendingLayerObserverEpoch(0)
, mPendingDocShellBlockers(0)
, mWidgetNativeData(0)
+ , mCombobox(nullptr)
{
mozilla::HoldJSObjects(this);
nsWeakPtr weakPtrThis(do_GetWeakReference(static_cast<nsITabChild*>(this))); // for capture by the lambda
mSetAllowedTouchBehaviorCallback = [weakPtrThis](uint64_t aInputBlockId,
const nsTArray<TouchBehaviorFlags>& aFlags)
{
if (nsCOMPtr<nsITabChild> tabChild = do_QueryReferent(weakPtrThis)) {
@@ -1315,16 +1316,31 @@ TabChild::RecvUpdateDimensions(const Dim
mPuppetWidget->Resize(screenRect.x + mClientOffset.x + mChromeOffset.x,
screenRect.y + mClientOffset.y + mChromeOffset.y,
screenSize.width, screenSize.height, true);
return IPC_OK();
}
mozilla::ipc::IPCResult
+TabChild::RecvRollupPopup()
+{
+ //At this point the child will know that we need to close the popup
+ //We will call rollup using the nsIRollupListener within nsCombobox
+ mCombobox->Rollup(0, false, nullptr, nullptr);
+ return IPC_OK();
+}
+
+void
+TabChild::SetCombobox(nsComboboxControlFrame* aCombobox)
+{
+ mCombobox = aCombobox;
+}
+
+mozilla::ipc::IPCResult
TabChild::RecvSizeModeChanged(const nsSizeMode& aSizeMode)
{
mPuppetWidget->SetSizeMode(aSizeMode);
if (!mPuppetWidget->IsVisible()) {
return IPC_OK();
}
nsCOMPtr<nsIDocument> document(GetDocument());
nsPresContext* presContext = document->GetPresContext();
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -15,16 +15,17 @@
#include "nsIWebBrowserChrome2.h"
#include "nsIEmbeddingSiteWindow.h"
#include "nsIWebBrowserChromeFocus.h"
#include "nsIDOMEventListener.h"
#include "nsIInterfaceRequestor.h"
#include "nsIWindowProvider.h"
#include "nsIDOMWindow.h"
#include "nsIDocShell.h"
+#include "nsComboboxControlFrame.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsFrameMessageManager.h"
#include "nsIPresShell.h"
#include "nsIScriptObjectPrincipal.h"
#include "nsWeakReference.h"
#include "nsITabChild.h"
#include "nsITooltipListener.h"
#include "mozilla/Attributes.h"
@@ -317,16 +318,21 @@ public:
RecvInitRendering(const TextureFactoryIdentifier& aTextureFactoryIdentifier,
const layers::LayersId& aLayersId,
const mozilla::layers::CompositorOptions& aCompositorOptions,
const bool& aLayersConnected,
PRenderFrameChild* aRenderFrame) override;
virtual mozilla::ipc::IPCResult
RecvUpdateDimensions(const mozilla::dom::DimensionInfo& aDimensionInfo) override;
+
+ virtual mozilla::ipc::IPCResult RecvRollupPopup() override;
+
+ void SetCombobox(nsComboboxControlFrame* aCombobox);
+
virtual mozilla::ipc::IPCResult
RecvSizeModeChanged(const nsSizeMode& aSizeMode) override;
mozilla::ipc::IPCResult RecvActivate();
mozilla::ipc::IPCResult RecvDeactivate();
MOZ_CAN_RUN_SCRIPT
@@ -914,16 +920,18 @@ private:
bool mPendingRenderLayersReceivedMessage;
uint64_t mPendingLayerObserverEpoch;
// When mPendingDocShellBlockers is greater than 0, the DocShell is blocked,
// and once it reaches 0, it is no longer blocked.
uint32_t mPendingDocShellBlockers;
WindowsHandle mWidgetNativeData;
+ nsComboboxControlFrame* mCombobox;
+
// This state is used to keep track of the current visible tabs (the ones rendering
// layers). There may be more than one if there are multiple browser windows open, or
// tabs are being warmed up. There may be none if this process does not host any
// visible or warming tabs.
static nsTHashtable<nsPtrHashKey<TabChild>>* sVisibleTabs;
DISALLOW_EVIL_CONSTRUCTORS(TabChild);
};
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -63,16 +63,18 @@
#include "nsIWindowWatcher.h"
#include "nsIWebBrowserChrome.h"
#include "nsIXULBrowserWindow.h"
#include "nsIXULWindow.h"
#include "nsIRemoteBrowser.h"
#include "nsViewManager.h"
#include "nsVariant.h"
#include "nsIWidget.h"
+#include "nsIRollupListener.h"
+#include "SelectRollupListener.h"
#include "nsNetUtil.h"
#ifndef XP_WIN
#include "nsJARProtocolHandler.h"
#endif
#include "nsPIDOMWindow.h"
#include "nsPrintfCString.h"
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
@@ -154,16 +156,17 @@ TabParent::TabParent(nsIContentParent* a
, mManager(aManager)
, mDocShellIsActive(false)
, mMarkedDestroying(false)
, mIsDestroyed(false)
, mChromeFlags(aChromeFlags)
, mDragValid(false)
, mInitedByParent(false)
, mTabId(aTabId)
+ , mListener(nullptr)
, mCreatingWindow(false)
, mCursor(eCursorInvalid)
, mTabSetsCursor(false)
, mHasContentOpener(false)
#ifdef DEBUG
, mActiveSupressDisplayportCount(0)
#endif
, mLayerTreeEpoch(1)
@@ -391,16 +394,19 @@ TabParent::Destroy()
if (XRE_IsParentProcess()) {
ContentParent::NotifyTabDestroying(this->GetTabId(), Manager()->AsContentParent()->ChildID());
} else {
ContentParent::NotifyTabDestroying(this->GetTabId(), Manager()->ChildID());
}
mMarkedDestroying = true;
+
+ delete mListener;
+ mListener = nullptr;
}
mozilla::ipc::IPCResult
TabParent::RecvEnsureLayersConnected(CompositorOptions* aCompositorOptions)
{
if (RenderFrameParent* frame = GetRenderFrame()) {
frame->EnsureLayersConnected(aCompositorOptions);
}
@@ -2528,16 +2534,46 @@ TabParent::RecvDispatchFocusToTopLevelWi
{
nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
if (widget) {
widget->SetFocus(false);
}
return IPC_OK();
}
+mozilla::ipc::IPCResult
+TabParent::RecvCaptureRollupEvents(const LayoutDeviceIntRect& aRect, const bool& aDroppedDown)
+{
+ nsCOMPtr<nsIWidget> widget = GetTopLevelWidget();
+
+ if (aDroppedDown) {
+ if (mListener) {
+ mListener->SetRect(aRect);
+ } else {
+ SelectRollupListener* listener = new SelectRollupListener(this, aRect);
+ SetListener(listener);
+ }
+ nsBaseWidget::SetActiveRollupListener(mListener);
+ // widget->CaptureRollupEvents(mListener, true);
+ } else {
+ delete mListener;
+ mListener = nullptr;
+ nsBaseWidget::SetActiveRollupListener(mListener);
+ // widget->CaptureRollupEvents(mListener, false);
+ }
+
+ return IPC_OK();
+}
+
+void
+TabParent::SetListener(SelectRollupListener* aListener)
+{
+ mListener = aListener;
+}
+
bool
TabParent::ReceiveMessage(const nsString& aMessage,
bool aSync,
StructuredCloneData* aData,
CpowHolder* aCpows,
nsIPrincipal* aPrincipal,
nsTArray<StructuredCloneData>* aRetVal)
{
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -27,16 +27,17 @@
#include "nsIKeyEventInPluginCallback.h"
#include "nsISecureBrowserUI.h"
#include "nsITabParent.h"
#include "nsIXULBrowserWindow.h"
#include "nsRefreshDriver.h"
#include "nsWeakReference.h"
#include "Units.h"
#include "nsIWidget.h"
+#include "SelectRollupListener.h"
class nsFrameLoader;
class nsIContent;
class nsIPrincipal;
class nsIURI;
class nsILoadContext;
class nsIDocShell;
class nsIWebBrowserPersistDocumentReceiver;
@@ -292,16 +293,18 @@ public:
virtual mozilla::ipc::IPCResult RecvHideTooltip() override;
virtual mozilla::ipc::IPCResult RecvSetNativeChildOfShareableWindow(const uintptr_t& childWindow) override;
virtual mozilla::ipc::IPCResult RecvDispatchFocusToTopLevelWindow() override;
+ virtual mozilla::ipc::IPCResult RecvCaptureRollupEvents(const LayoutDeviceIntRect& aRect, const bool& aDroppedDown) override;
+
virtual mozilla::ipc::IPCResult RecvRespondStartSwipeEvent(const uint64_t& aInputBlockId,
const bool& aStartSwipe) override;
virtual mozilla::ipc::IPCResult
RecvDispatchWheelEvent(const mozilla::WidgetWheelEvent& aEvent) override;
virtual mozilla::ipc::IPCResult
RecvDispatchMouseEvent(const mozilla::WidgetMouseEvent& aEvent) override;
@@ -623,16 +626,18 @@ protected:
virtual mozilla::ipc::IPCResult RecvSetDimensions(const uint32_t& aFlags,
const int32_t& aX, const int32_t& aY,
const int32_t& aCx, const int32_t& aCy) override;
virtual mozilla::ipc::IPCResult RecvGetTabCount(uint32_t* aValue) override;
virtual mozilla::ipc::IPCResult RecvShowCanvasPermissionPrompt(const nsCString& aFirstPartyURI) override;
+ void SetListener(SelectRollupListener* aListener);
+
ContentCacheInParent mContentCache;
nsIntRect mRect;
ScreenIntSize mDimensions;
ScreenOrientationInternal mOrientation;
float mDPI;
int32_t mRounding;
CSSToLayoutDeviceScale mDefaultScale;
@@ -690,16 +695,18 @@ private:
// We keep a strong reference to the frameloader after we've sent the
// Destroy message and before we've received __delete__. This allows us to
// dispatch message manager messages during this time.
RefPtr<nsFrameLoader> mFrameLoader;
TabId mTabId;
+ SelectRollupListener* mListener;
+
// When loading a new tab or window via window.open, the child is
// responsible for loading the URL it wants into the new TabChild. When the
// parent receives the CreateWindow message, though, it sends a LoadURL
// message, usually for about:blank. It's important for the about:blank load
// to get processed because the Firefox frontend expects every new window to
// immediately start loading something (see bug 1123090). However, we want
// the child to process the LoadURL message before it returns from
// ProvideWindow so that the URL sent from the parent doesn't override the
--- a/layout/forms/moz.build
+++ b/layout/forms/moz.build
@@ -6,16 +6,17 @@
with Files('**'):
BUG_COMPONENT = ('Core', 'Layout: Form Controls')
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
MOCHITEST_CHROME_MANIFESTS += ['test/chrome.ini']
EXPORTS += [
+ 'nsComboboxControlFrame.h',
'nsIComboboxControlFrame.h',
'nsIFormControlFrame.h',
'nsIListControlFrame.h',
'nsISelectControlFrame.h',
'nsITextControlFrame.h',
]
UNIFIED_SOURCES += [
--- a/layout/forms/nsComboboxControlFrame.cpp
+++ b/layout/forms/nsComboboxControlFrame.cpp
@@ -9,16 +9,17 @@
#include "gfxContext.h"
#include "gfxUtils.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathHelpers.h"
#include "nsCOMPtr.h"
#include "nsFocusManager.h"
#include "nsCheckboxRadioFrame.h"
#include "nsGkAtoms.h"
+#include "nsCanvasFrame.h"
#include "nsCSSAnonBoxes.h"
#include "nsHTMLParts.h"
#include "nsIFormControl.h"
#include "nsNameSpaceManager.h"
#include "nsIListControlFrame.h"
#include "nsPIDOMWindow.h"
#include "nsIPresShell.h"
#include "mozilla/PresState.h"
@@ -46,25 +47,28 @@
#include "mozilla/AsyncEventDispatcher.h"
#include "mozilla/EventStates.h"
#include "mozilla/LookAndFeel.h"
#include "mozilla/MouseEvents.h"
#include "mozilla/Unused.h"
#include "gfx2DGlue.h"
#include "mozilla/widget/nsAutoRollup.h"
#include "nsILayoutHistoryState.h"
+#include "mozilla/dom/TabChild.h"
+#include "mozilla/dom/TabParent.h"
#ifdef XP_WIN
#define COMBOBOX_ROLLUP_CONSUME_EVENT 0
#else
#define COMBOBOX_ROLLUP_CONSUME_EVENT 1
#endif
using namespace mozilla;
using namespace mozilla::gfx;
+using namespace mozilla::dom;
NS_IMETHODIMP
nsComboboxControlFrame::RedisplayTextEvent::Run()
{
if (mControlFrame)
mControlFrame->HandleRedisplayTextEvent();
return NS_OK;
}
@@ -303,16 +307,30 @@ nsComboboxControlFrame::SetFocus(bool aO
InvalidateFrame();
}
void
nsComboboxControlFrame::ShowPopup(bool aShowPopup)
{
// TODO(kuoe0) Remove this function when content-select is enabled.
+ if (nsLayoutUtils::IsContentSelectEnabled()) {
+ nsCanvasFrame* canvasFrame = do_QueryFrame(mDropdownFrame->GetParent());
+ if (aShowPopup){
+ mDroppedDown = true;
+ canvasFrame->SetDropdownFrame(mDropdownFrame);
+ } else {
+ PresShell()->FrameNeedsReflow(mDisplayFrame, nsIPresShell::eStyleChange,
+ NS_FRAME_IS_DIRTY);
+ mDroppedDown = false;
+ canvasFrame->SetDropdownFrame(nullptr);
+ }
+ return;
+ }
+
nsView* view = mDropdownFrame->GetView();
nsViewManager* viewManager = view->GetViewManager();
if (aShowPopup) {
nsRect rect = mDropdownFrame->GetRect();
rect.x = rect.y = 0;
viewManager->ResizeView(view, rect);
viewManager->SetViewVisibility(view, nsViewVisibility_kShow);
@@ -331,23 +349,28 @@ nsComboboxControlFrame::ShowPopup(bool a
shell->HandleDOMEventWithTarget(mContent, &event, &status);
}
}
bool
nsComboboxControlFrame::ShowList(bool aShowList)
{
-
- // TODO(kuoe0) Remove this function when content-select is enabled.
- //
- // This function is used to handle the widget/view stuff, so we just return
- // when content-select is enabled. And the following callee, ShowPopup(), will
- // also be ignored, it is only used to show and hide the widget.
if (nsLayoutUtils::IsContentSelectEnabled()) {
+ TabChild* tabChild = mozilla::dom::TabChild::GetFrom(PresContext()->GetPresShell());
+ if (aShowList) {
+ LayoutDeviceIntRect rect = LayoutDeviceIntRect::FromAppUnitsToNearest(mDropdownFrame->GetScreenRectInAppUnits(),
+ mDropdownFrame->PresContext()->AppUnitsPerDevPixel());
+ tabChild->SetCombobox(this);
+ tabChild->SendCaptureRollupEvents(rect, true);
+ } else {
+ tabChild->SetCombobox(nullptr);
+ tabChild->SendCaptureRollupEvents(LayoutDeviceIntRect(), false);
+ }
+ ShowPopup(aShowList);
return true;
}
nsView* view = mDropdownFrame->GetView();
if (aShowList) {
NS_ASSERTION(!view->HasWidget(),
"We shouldn't have a widget before we need to display the popup");
@@ -584,17 +607,21 @@ public:
};
void
nsComboboxControlFrame::GetAvailableDropdownSpace(WritingMode aWM,
nscoord* aBefore,
nscoord* aAfter,
LogicalPoint* aTranslation)
{
- MOZ_ASSERT(!XRE_IsContentProcess());
+ if (!nsLayoutUtils::IsContentSelectEnabled()) {
+ // TODO(kuoe0) remove this assertion after content-select is enabled
+ MOZ_ASSERT(!XRE_IsContentProcess());
+ }
+
// Note: At first glance, it appears that you could simply get the
// absolute bounding box for the dropdown list by first getting its
// view, then getting the view's nsIWidget, then asking the nsIWidget
// for its AbsoluteBounds.
// The problem with this approach, is that the dropdown list's bcoord
// location can change based on whether the dropdown is placed after
// or before the display frame. The approach taken here is to get the
// absolute position of the display frame and use its location to
@@ -652,17 +679,18 @@ nsComboboxControlFrame::GetAvailableDrop
*aAfter = after;
*aBefore = before;
}
nsComboboxControlFrame::DropDownPositionState
nsComboboxControlFrame::AbsolutelyPositionDropDown()
{
- if (XRE_IsContentProcess()) {
+ if (!nsLayoutUtils::IsContentSelectEnabled() && XRE_IsContentProcess()) {
+ // TODO(kuoe0) remove this after content-select is enabled
return eDropDownPositionSuppressed;
}
WritingMode wm = GetWritingMode();
LogicalPoint translation(wm);
nscoord before, after;
mLastDropDownAfterScreenBCoord = nscoord_MIN;
GetAvailableDropdownSpace(wm, &before, &after, &translation);
@@ -692,18 +720,18 @@ nsComboboxControlFrame::AbsolutelyPositi
// schedule a resize to show more rows if it has more rows to show.
// (1.5 rows for good measure to avoid any rounding issues that would
// lead to a loop of reflow requests)
NS_DispatchToCurrentThread(new nsAsyncResize(this));
return eDropDownPositionPendingResize;
}
// Position the drop-down after if there is room, otherwise place it before
- // if there is room. If there is no room for it on either side then place
- // it after (to avoid overlapping UI like the URL bar).
+ // if there is room. If there is no room for it on either side then place
+ // it after (to avoid overlapping UI like the URL bar)
bool b = dropdownSize.BSize(wm)<= after || dropdownSize.BSize(wm) > before;
LogicalPoint dropdownPosition(wm, 0, b ? BSize(wm) : -dropdownSize.BSize(wm));
// Don't position the view unless the position changed since it might cause
// a call to NotifyGeometryChange() and an infinite loop here.
nsSize containerSize = GetSize();
const LogicalPoint currentPos =
mDropdownFrame->GetLogicalPosition(containerSize);
@@ -1186,16 +1214,23 @@ nsComboboxControlFrame::HandleEvent(nsPr
}
#endif
// If we have style that affects how we are selected, feed event down to
// nsFrame::HandleEvent so that selection takes place when appropriate.
if (IsContentDisabled()) {
return nsBlockFrame::HandleEvent(aPresContext, aEvent, aEventStatus);
}
+
+ // We handle the drop-down and roll-up actions here.
+ if (nsLayoutUtils::IsContentSelectEnabled() &&
+ aEvent->mMessage == eMouseDown) {
+ ShowDropDown(!mDroppedDown);
+ }
+
return NS_OK;
}
nsresult
nsComboboxControlFrame::SetFormProperty(nsAtom* aName, const nsAString& aValue)
{
nsIFormControlFrame* fcFrame = do_QueryFrame(mDropdownFrame);
@@ -1434,16 +1469,19 @@ nsComboboxControlFrame::DestroyFrom(nsIF
nsView* view = mDropdownFrame->GetView();
MOZ_ASSERT(view);
nsIWidget* widget = view->GetWidget();
if (widget) {
widget->CaptureRollupEvents(this, false);
}
}
+ nsCanvasFrame* canvasFrame = do_QueryFrame(mDropdownFrame->GetParent());
+ canvasFrame->SetDropdownFrame(nullptr);
+
// Cleanup frames in popup child list
mPopupFrames.DestroyFramesFrom(aDestructRoot, aPostDestroyData);
aPostDestroyData.AddAnonymousContent(mDisplayContent.forget());
aPostDestroyData.AddAnonymousContent(mButtonContent.forget());
nsBlockFrame::DestroyFrom(aDestructRoot, aPostDestroyData);
}
const nsFrameList&
--- a/layout/forms/nsListControlFrame.cpp
+++ b/layout/forms/nsListControlFrame.cpp
@@ -176,16 +176,22 @@ nsListControlFrame::BuildDisplayList(nsD
// XXX why do we need this here? we should never reach this. Maybe
// because these can have widgets? Hmm
if (aBuilder->IsBackgroundOnly())
return;
DO_GLOBAL_REFLOW_COUNT_DSP("nsListControlFrame");
if (IsInDropDownMode()) {
+ if (nsLayoutUtils::IsContentSelectEnabled() &&
+ !mComboboxFrame->IsDroppedDown()) {
+ // Don't build the display list when the list is not dropped down.
+ return;
+ }
+
NS_ASSERTION(NS_GET_A(mLastDropdownBackstopColor) == 255,
"need an opaque backstop color");
// XXX Because we have an opaque widget and we get called to paint with
// this frame as the root of a stacking context we need make sure to draw
// some opaque color over the whole widget. (Bug 511323)
aLists.BorderBackground()->AppendToBottom(
MakeDisplayItem<nsDisplaySolidColor>(aBuilder,
this, nsRect(aBuilder->ToReferenceFrame(this), GetSize()),
@@ -567,17 +573,17 @@ nsListControlFrame::ReflowAsDropdown(nsP
// we're depending on?
nsHTMLScrollFrame::DidReflow(aPresContext, &state);
// Now compute the block size we want to have.
// Note: no need to apply min/max constraints, since we have no such
// rules applied to the combobox dropdown.
mDropdownCanGrow = false;
- if (visibleBSize <= 0 || blockSizeOfARow <= 0 || XRE_IsContentProcess()) {
+ if (visibleBSize <= 0 || blockSizeOfARow <= 0 || XRE_IsContentProcess) {
// Looks like we have no options. Just size us to a single row
// block size.
state.SetComputedBSize(blockSizeOfARow);
mNumDisplayRows = 1;
} else {
nsComboboxControlFrame* combobox =
static_cast<nsComboboxControlFrame*>(mComboboxFrame);
LogicalPoint translation(wm);
@@ -1831,16 +1837,19 @@ nsListControlFrame::MouseDown(dom::Event
CaptureMouseEvents(true);
AutoWeakFrame weakFrame(this);
bool change =
HandleListSelection(aMouseEvent, selectedIndex); // might destroy us
if (!weakFrame.IsAlive()) {
return NS_OK;
}
mChangesSinceDragStart = change;
+ } else if (nsLayoutUtils::IsContentSelectEnabled()) {
+ // We handle the drop-down and roll-up action in the combo box.
+ return NS_OK;
} else {
// NOTE: the combo box is responsible for dropping it down
if (mComboboxFrame) {
// Ignore the click that occurs on the option element when one is
// selected from the parent process popup.
if (mComboboxFrame->IsOpenInParentProcess()) {
nsCOMPtr<nsIContent> econtent =
do_QueryInterface(aMouseEvent->GetTarget());
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -177,16 +177,22 @@ ViewportFrame::BuildDisplayListForTopLay
BuildDisplayListForTopLayerFrame(aBuilder, backdropFrame, aList);
}
BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
}
}
nsIPresShell* shell = PresShell();
if (nsCanvasFrame* canvasFrame = shell->GetCanvasFrame()) {
+ // Build display items for the dropped-down menu
+ if (nsIFrame* dropdownFrame = canvasFrame->GetDropdownFrame()) {
+ BuildDisplayListForTopLayerFrame(aBuilder, dropdownFrame, aList);
+ MOZ_ASSERT(dropdownFrame->StyleDisplay()->mTopLayer == NS_STYLE_TOP_LAYER_TOP);
+ }
+
if (Element* container = canvasFrame->GetCustomContentContainer()) {
if (nsIFrame* frame = container->GetPrimaryFrame()) {
MOZ_ASSERT(frame->StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE,
"ua.css should ensure this");
MOZ_ASSERT(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW);
BuildDisplayListForTopLayerFrame(aBuilder, frame, aList);
}
}
--- a/layout/generic/moz.build
+++ b/layout/generic/moz.build
@@ -63,35 +63,39 @@ with Files('Sticky*'):
with Files('nsPluginFrame.*'):
BUG_COMPONENT = ('Core', 'Plug-ins')
with Files('nsVideoFrame.*'):
BUG_COMPONENT = ('Core', 'Audio/Video')
EXPORTS += [
+ 'nsBlockFrame.h',
'nsCanvasFrame.h',
'nsContainerFrame.h',
'nsDirection.h',
+ 'nsFloatManager.h',
'nsFrame.h',
'nsFrameIdList.h',
'nsFrameList.h',
'nsFrameSelection.h',
'nsFrameState.h',
'nsFrameStateBits.h',
'nsHTMLParts.h',
'nsIAnonymousContentCreator.h',
'nsIFrame.h',
'nsIFrameInlines.h',
'nsILineIterator.h',
+ 'nsIntervalSet.h',
'nsIObjectFrame.h',
'nsIPageSequenceFrame.h',
'nsIScrollableFrame.h',
'nsIScrollPositionListener.h',
'nsIStatefulFrame.h',
+ 'nsLineBox.h',
'nsPluginFrame.h',
'nsQueryFrame.h',
'nsRubyBaseContainerFrame.h',
'nsRubyBaseFrame.h',
'nsRubyFrame.h',
'nsRubyTextContainerFrame.h',
'nsRubyTextFrame.h',
'nsSplittableFrame.h',
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -258,16 +258,25 @@ nsRect nsCanvasFrame::CanvasArea() const
if (scrollableFrame) {
nsRect portRect = scrollableFrame->GetScrollPortRect();
result.UnionRect(result, nsRect(nsPoint(0, 0), portRect.Size()));
}
return result;
}
void
+nsCanvasFrame::SetDropdownFrame(nsIFrame* aDropdownFrame) {
+ if (aDropdownFrame) {
+ MOZ_ASSERT(aDropdownFrame->IsListControlFrame(),
+ "Only nsListControlFrame can be dropped down.");
+ }
+ mDropdownFrame = aDropdownFrame;
+}
+
+void
nsDisplayCanvasBackgroundColor::Paint(nsDisplayListBuilder* aBuilder,
gfxContext* aCtx)
{
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
nsPoint offset = ToReferenceFrame();
nsRect bgClipRect = frame->CanvasArea() + offset;
if (NS_GET_A(mColor) > 0) {
DrawTarget* drawTarget = aCtx->GetDrawTarget();
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -33,16 +33,17 @@ class nsCanvasFrame final : public nsCon
public nsIScrollPositionListener,
public nsIAnonymousContentCreator
{
public:
explicit nsCanvasFrame(ComputedStyle* aStyle)
: nsContainerFrame(aStyle, kClassID)
, mDoPaintFocus(false)
, mAddedScrollPositionListener(false)
+ , mDropdownFrame(nullptr)
{}
NS_DECL_QUERYFRAME
NS_DECL_FRAMEARENA_HELPERS(nsCanvasFrame)
virtual void DestroyFrom(nsIFrame* aDestructRoot, PostDestroyData& aPostDestroyData) override;
@@ -108,26 +109,33 @@ public:
#ifdef DEBUG_FRAME_DUMP
virtual nsresult GetFrameName(nsAString& aResult) const override;
#endif
virtual nsresult GetContentForEvent(mozilla::WidgetEvent* aEvent,
nsIContent** aContent) override;
nsRect CanvasArea() const;
+ // The frame should be dropped down
+ nsIFrame* GetDropdownFrame() const { return mDropdownFrame; }
+ void SetDropdownFrame(nsIFrame* aDropDownFrame);
+
protected:
// Utility function to propagate the WritingMode from our first child to
// 'this' and all its ancestors.
void MaybePropagateRootElementWritingMode();
// Data members
bool mDoPaintFocus;
bool mAddedScrollPositionListener;
nsCOMPtr<mozilla::dom::Element> mCustomContentContainer;
+
+private:
+ nsIFrame* mDropdownFrame;
};
/**
* Override nsDisplayBackground methods so that we pass aBGClipRect to
* PaintBackground, covering the whole overflow area.
* We can also paint an "extra background color" behind the normal
* background.
*/
--- a/layout/generic/nsLineBox.h
+++ b/layout/generic/nsLineBox.h
@@ -9,16 +9,17 @@
#ifndef nsLineBox_h___
#define nsLineBox_h___
#include "mozilla/Attributes.h"
#include "mozilla/Likely.h"
#include "nsILineIterator.h"
#include "nsIFrame.h"
+#include "X11UndefineNone.h"
#include <algorithm>
class nsLineBox;
class nsFloatCache;
class nsFloatCacheList;
class nsFloatCacheFreeList;
// State cached after reflowing a float. This state is used during
new file mode 100644
--- /dev/null
+++ b/widget/SelectRollupListener.cpp
@@ -0,0 +1,25 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SelectRollupListener.h"
+
+SelectRollupListener::SelectRollupListener(mozilla::dom::TabParent* aParent, LayoutDeviceIntRect aRect)
+{
+ mParent = aParent;
+ mRect = aRect;
+}
+
+nsIWidget* SelectRollupListener::GetRollupWidget()
+{
+ nsIWidget* widget = nullptr;
+ return widget;
+}
+
+bool
+SelectRollupListener::Rollup(uint32_t aCount, bool aFlush,
+ const nsIntPoint* pos, nsIContent** aLastRolledUp)
+{
+ return mParent->SendRollupPopup();
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/widget/SelectRollupListener.h
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef SelectRollupListener_h__
+#define SelectRollupListener_h__
+
+#include "nsIRollupListener.h"
+#include "nsCOMPtr.h"
+#include "mozilla/widget/nsAutoRollup.h"
+
+class nsIWidget;
+
+class SelectRollupListener : public nsIRollupListener
+{
+
+public:
+ SelectRollupListener(mozilla::dom::TabParent* aParent, mozilla::LayoutDeviceIntRect aRect);
+
+ virtual ~SelectRollupListener() {}
+
+ //nsIRollupListener
+ /**
+ * Hide the dropdown menu and stop capturing mouse events.
+ * @note This method might destroy |this|.
+ */
+ virtual bool Rollup(uint32_t aCount, bool aFlush,
+ const nsIntPoint* pos, nsIContent** aLastRolledUp) override;
+
+ virtual void NotifyGeometryChange() override
+ { return; }
+
+ /**
+ * A combobox should roll up if a mousewheel event happens outside of
+ * the popup area.
+ */
+ virtual bool ShouldRollupOnMouseWheelEvent() override
+ { return true; }
+
+ virtual bool ShouldConsumeOnMouseWheelEvent() override
+ { return false; }
+
+ /**
+ * A combobox should not roll up if activated by a mouse activate message
+ * (eg. X-mouse).
+ */
+ virtual bool ShouldRollupOnMouseActivate() override
+ { return false; }
+
+ virtual uint32_t GetSubmenuWidgetChain(nsTArray<nsIWidget*> *aWidgetChain) override
+ { return 0; }
+
+ virtual nsIWidget* GetRollupWidget() override;
+
+ void SetRect(mozilla::LayoutDeviceIntRect aRect)
+ { mRect = aRect; }
+
+ mozilla::LayoutDeviceIntRect GetRect()
+ { return mRect; }
+
+protected:
+ mozilla::LayoutDeviceIntRect mRect;
+ mozilla::dom::TabParent* mParent;
+};
+
+#endif // SelectRollupListener_h__
+
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -28,16 +28,17 @@
#include "nsObjCExceptions.h"
#include "nsCOMPtr.h"
#include "nsThreadUtils.h"
#include "nsToolkit.h"
#include "nsCRT.h"
#include "nsFontMetrics.h"
#include "nsIRollupListener.h"
+#include "SelectRollupListener.h"
#include "nsViewManager.h"
#include "nsIInterfaceRequestor.h"
#include "nsIFile.h"
#include "nsILocalFileMac.h"
#include "nsGfxCIID.h"
#include "nsThemeConstants.h"
#include "nsIWidgetListener.h"
#include "nsIPresShell.h"
@@ -4079,30 +4080,44 @@ NSEvent* gLastDragMouseDownEvent = nil;
[[NSDistributedNotificationCenter defaultCenter]
postNotificationName:@"com.apple.HIToolbox.beginMenuTrackingNotification"
object:@"org.mozilla.gecko.PopupWindow"];
[(PopupWindow*)popupWindow setIsContextMenu:YES];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
+- (BOOL)IsEventOverSpace:(NSEvent*)theEvent : (nsIRollupListener*)aRollupListener
+{
+ nsCOMPtr<nsIWidget> rollupWidget = aRollupListener->GetRollupWidget();
+ if (!rollupWidget) {
+ SelectRollupListener* selectRollupListener = (SelectRollupListener*) aRollupListener;
+ if (selectRollupListener) {
+ LayoutDeviceIntRect rollupRect = selectRollupListener->GetRect();
+ double backingScale = mGeckoChild->BackingScaleFactor();
+ return nsCocoaUtils::IsEventOverRect(theEvent, rollupRect, backingScale);
+ }
+ } else {
+ NSWindow* currentPopup = static_cast<NSWindow*>(rollupWidget->GetNativeData(NS_NATIVE_WINDOW));
+ return nsCocoaUtils::IsEventOverWindow(theEvent, currentPopup);
+ }
+}
+
// Returns true if the event should no longer be processed, false otherwise.
// This does not return whether or not anything was rolled up.
- (BOOL)maybeRollup:(NSEvent*)theEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
BOOL consumeEvent = NO;
nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener();
NS_ENSURE_TRUE(rollupListener, false);
- nsCOMPtr<nsIWidget> rollupWidget = rollupListener->GetRollupWidget();
- if (rollupWidget) {
- NSWindow* currentPopup = static_cast<NSWindow*>(rollupWidget->GetNativeData(NS_NATIVE_WINDOW));
- if (!nsCocoaUtils::IsEventOverWindow(theEvent, currentPopup)) {
+ if (rollupListener) {
+ if (![self IsEventOverSpace:theEvent :rollupListener]) {
// event is not over the rollup window, default is to roll up
bool shouldRollup = true;
// check to see if scroll events should roll up the popup
if ([theEvent type] == NSScrollWheel) {
shouldRollup = rollupListener->ShouldRollupOnMouseWheelEvent();
// consume scroll events that aren't over the popup
// unless the popup is an arrow panel
--- a/widget/cocoa/nsCocoaUtils.h
+++ b/widget/cocoa/nsCocoaUtils.h
@@ -228,21 +228,25 @@ public:
static mozilla::LayoutDeviceIntRect CocoaRectToGeckoRectDevPix(
const NSRect& aCocoaRect, CGFloat aBackingScale);
// Gives the location for the event in screen coordinates. Do not call this
// unless the window the event was originally targeted at is still alive!
// anEvent may be nil -- in that case the current mouse location is returned.
static NSPoint ScreenLocationForEvent(NSEvent* anEvent);
-
+
// Determines if an event happened over a window, whether or not the event
// is for the window. Does not take window z-order into account.
static BOOL IsEventOverWindow(NSEvent* anEvent, NSWindow* aWindow);
+ // Determines if an event happened over the rect, specifically for select
+ // elements.
+ static BOOL IsEventOverRect(NSEvent* anEvent, LayoutDeviceIntRect aRect, double aScaleFactor);
+
// Events are set up so that their coordinates refer to the window to which they
// were originally sent. If we reroute the event somewhere else, we'll have
// to get the window coordinates this way. Do not call this unless the window
// the event was originally targeted at is still alive!
static NSPoint EventLocationForWindow(NSEvent* anEvent, NSWindow* aWindow);
// Compatibility wrappers for the -[NSEvent phase], -[NSEvent momentumPhase],
// -[NSEvent hasPreciseScrollingDeltas] and -[NSEvent scrollingDeltaX/Y] APIs
--- a/widget/cocoa/nsCocoaUtils.mm
+++ b/widget/cocoa/nsCocoaUtils.mm
@@ -131,16 +131,37 @@ BOOL nsCocoaUtils::IsEventOverWindow(NSE
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
return NSPointInRect(ScreenLocationForEvent(anEvent), [aWindow frame]);
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
}
+BOOL nsCocoaUtils::IsEventOverRect(NSEvent* anEvent, LayoutDeviceIntRect aRect, double aScaleFactor)
+{
+ //we need to convert both the event and rect to the same coordinate space
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
+
+ NSRect cocoaRect = DevPixelsToCocoaPoints(aRect, aScaleFactor);
+ NSPoint event = ScreenLocationForEvent(anEvent);
+ float eventY = MenuBarScreenHeight() - event.y;
+
+ float xMax = cocoaRect.origin.x + cocoaRect.size.width;
+ float yMax = cocoaRect.origin.y + cocoaRect.size.height;
+
+ if ((eventY >= cocoaRect.origin.y && eventY <= yMax) &&
+ (event.x >= cocoaRect.origin.x && event.x <= xMax)) {
+ return true;
+ }
+ return false;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NO);
+}
+
NSPoint nsCocoaUtils::EventLocationForWindow(NSEvent* anEvent, NSWindow* aWindow)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
return nsCocoaUtils::ConvertPointFromScreen(aWindow, ScreenLocationForEvent(anEvent));
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NSMakePoint(0.0, 0.0));
}
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -14,16 +14,17 @@
#include "mozilla/RefPtr.h"
#include "mozilla/TextEventDispatcher.h"
#include "mozilla/TextEvents.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/TouchEvents.h"
#include "mozilla/UniquePtrExtensions.h"
#include "mozilla/WidgetUtils.h"
#include "mozilla/dom/WheelEventBinding.h"
+#include "SelectRollupListener.h"
#include <algorithm>
#include "GeckoProfiler.h"
#include "prlink.h"
#include "nsGTKToolkit.h"
#include "nsIRollupListener.h"
#include "nsINode.h"
@@ -5244,73 +5245,92 @@ nsWindow::SetWindowDecoration(nsBorderSt
}
void
nsWindow::HideWindowChrome(bool aShouldHide)
{
SetWindowDecoration(aShouldHide ? eBorderStyle_none : mBorderStyle);
}
+static bool
+is_mouse_in_rect (LayoutDeviceIntRect aRect, gdouble aMouseX, gdouble aMouseY)
+{
+ if (aMouseX >= aRect.x && aMouseX <= aRect.XMost()
+ && aMouseY >= aRect.y && aMouseY <= aRect.YMost()) {
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+is_event_over_space(nsIRollupListener* aRollupListener, gdouble aMouseX, gdouble aMouseY)
+{
+ nsCOMPtr<nsIWidget> rollupWidget = aRollupListener->GetRollupWidget();
+ if (!rollupWidget) {
+ SelectRollupListener* selectRollupListener = (SelectRollupListener*) aRollupListener;
+ if (selectRollupListener){
+ LayoutDeviceIntRect rollupRect = selectRollupListener->GetRect();
+ return is_mouse_in_rect(rollupRect, aMouseX, aMouseY);
+ }
+ } else {
+ auto *currentPopup = (GdkWindow*)rollupWidget->GetNativeData(NS_NATIVE_WINDOW);
+ return is_mouse_in_window(currentPopup, aMouseX, aMouseY);
+ }
+}
+
bool
nsWindow::CheckForRollup(gdouble aMouseX, gdouble aMouseY,
- bool aIsWheel, bool aAlwaysRollup)
+ bool aIsWheel, bool aAlwaysRollup)
{
nsIRollupListener* rollupListener = GetActiveRollupListener();
- nsCOMPtr<nsIWidget> rollupWidget;
- if (rollupListener) {
- rollupWidget = rollupListener->GetRollupWidget();
- }
- if (!rollupWidget) {
- nsBaseWidget::gRollupListener = nullptr;
- return false;
- }
bool retVal = false;
- auto *currentPopup =
- (GdkWindow *)rollupWidget->GetNativeData(NS_NATIVE_WINDOW);
- if (aAlwaysRollup || !is_mouse_in_window(currentPopup, aMouseX, aMouseY)) {
+ if (rollupListener) {
+ if (aAlwaysRollup || !is_event_over_space(rollupListener, aMouseX, aMouseY)) {
bool rollup = true;
if (aIsWheel) {
rollup = rollupListener->ShouldRollupOnMouseWheelEvent();
retVal = rollupListener->ShouldConsumeOnMouseWheelEvent();
}
// if we're dealing with menus, we probably have submenus and
// we don't want to rollup if the click is in a parent menu of
// the current submenu
uint32_t popupsToRollup = UINT32_MAX;
if (!aAlwaysRollup) {
- AutoTArray<nsIWidget*, 5> widgetChain;
- uint32_t sameTypeCount = rollupListener->GetSubmenuWidgetChain(&widgetChain);
- for (uint32_t i=0; i<widgetChain.Length(); ++i) {
- nsIWidget* widget = widgetChain[i];
- auto* currWindow =
- (GdkWindow*) widget->GetNativeData(NS_NATIVE_WINDOW);
- if (is_mouse_in_window(currWindow, aMouseX, aMouseY)) {
- // don't roll up if the mouse event occurred within a
- // menu of the same type. If the mouse event occurred
- // in a menu higher than that, roll up, but pass the
- // number of popups to Rollup so that only those of the
- // same type close up.
- if (i < sameTypeCount) {
- rollup = false;
- }
- else {
- popupsToRollup = sameTypeCount;
- }
- break;
+ AutoTArray<nsIWidget*, 5> widgetChain;
+ uint32_t sameTypeCount = rollupListener->GetSubmenuWidgetChain(&widgetChain);
+ for (uint32_t i=0; i<widgetChain.Length(); ++i) {
+ nsIWidget* widget = widgetChain[i];
+ auto* currWindow =
+ (GdkWindow*) widget->GetNativeData(NS_NATIVE_WINDOW);
+ if (is_mouse_in_window(currWindow, aMouseX, aMouseY)) {
+ // don't roll up if the mouse event occurred within a
+ // menu of the same type. If the mouse event occurred
+ // in a menu higher than that, roll up, but pass the
+ // number of popups to Rollup so that only those of the
+ // same type close up.
+ if (i < sameTypeCount) {
+ rollup = false;
}
- } // foreach parent menu widget
+ else {
+ popupsToRollup = sameTypeCount;
+ }
+ break;
+ }
+ } // foreach parent menu widget
} // if rollup listener knows about menus
// if we've determined that we should still rollup, do it.
bool usePoint = !aIsWheel && !aAlwaysRollup;
IntPoint point = IntPoint::Truncate(aMouseX, aMouseY);
if (rollup && rollupListener->Rollup(popupsToRollup, true, usePoint ? &point : nullptr, nullptr)) {
- retVal = true;
+ retVal = true;
}
+ }
}
return retVal;
}
/* static */
bool
nsWindow::DragInProgress(void)
{
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -131,16 +131,17 @@ EXPORTS += [
'nsIPluginWidget.h',
'nsIPrintDialogService.h',
'nsIRollupListener.h',
'nsIWidget.h',
'nsIWidgetListener.h',
'nsWidgetInitData.h',
'nsWidgetsCID.h',
'PuppetWidget.h',
+ 'SelectRollupListener.h',
]
EXPORTS.mozilla += [
'BasicEvents.h',
'CommandList.h',
'ContentCache.h',
'ContentEvents.h',
'EventClassList.h',
@@ -195,16 +196,17 @@ UNIFIED_SOURCES += [
'nsPrintSettingsImpl.cpp',
'nsSoundProxy.cpp',
'nsTransferable.cpp',
'nsXPLookAndFeel.cpp',
'PuppetBidiKeyboard.cpp',
'PuppetWidget.cpp',
'Screen.cpp',
'ScreenManager.cpp',
+ 'SelectRollupListener.cpp',
'SharedWidgetUtils.cpp',
'TextEventDispatcher.cpp',
'VsyncDispatcher.cpp',
'WidgetEventImpl.cpp',
'WidgetUtils.cpp',
]
if CONFIG['OS_ARCH'] == 'Linux':
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1812,16 +1812,22 @@ nsBaseWidget::GetActiveRollupListener()
// If set, then this is likely an <html:select> dropdown.
if (gRollupListener)
return gRollupListener;
return nsXULPopupManager::GetInstance();
}
void
+nsBaseWidget::SetActiveRollupListener(nsIRollupListener* aRollupListener)
+{
+ gRollupListener = aRollupListener;
+}
+
+void
nsBaseWidget::NotifyWindowDestroyed()
{
if (!mWidgetListener)
return;
nsCOMPtr<nsIXULWindow> window = mWidgetListener->GetXULWindow();
nsCOMPtr<nsIBaseWindow> xulWindow(do_QueryInterface(window));
if (xulWindow) {
--- a/widget/nsBaseWidget.h
+++ b/widget/nsBaseWidget.h
@@ -393,16 +393,18 @@ public:
RefPtr<BasicLayerManager> mLayerManager;
};
friend class AutoLayerManagerSetup;
virtual bool ShouldUseOffMainThreadCompositing();
static nsIRollupListener* GetActiveRollupListener();
+ static void SetActiveRollupListener(nsIRollupListener* aRollupListener);
+
void Shutdown();
#if defined(XP_WIN)
uint64_t CreateScrollCaptureContainer() override;
#endif
// These functions should be called at the start and end of a "live" widget
// resize (i.e. when the window contents are repainting during the resize,
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -105,16 +105,17 @@
#include "nsNativeCharsetUtils.h"
#include "nsGkAtoms.h"
#include "nsCRT.h"
#include "nsAppDirectoryServiceDefs.h"
#include "nsWidgetsCID.h"
#include "nsTHashtable.h"
#include "nsHashKeys.h"
#include "nsString.h"
+#include "SelectRollupListener.h"
#include "mozilla/Services.h"
#include "nsNativeThemeWin.h"
#include "nsWindowsDllInterceptor.h"
#include "nsLayoutUtils.h"
#include "nsView.h"
#include "nsIWindowMediator.h"
#include "nsIServiceManager.h"
#include "nsWindowGfx.h"
@@ -7882,16 +7883,49 @@ nsWindow::EventIsInsideWindow(nsWindow*
POINT mp;
mp.x = GET_X_LPARAM(pos);
mp.y = GET_Y_LPARAM(pos);
// was the event inside this window?
return static_cast<bool>(::PtInRect(&r, mp));
}
+bool
+nsWindow::EventIsInsideRect(LayoutDeviceIntRect rollupRect)
+{
+ //Screenlocation for event:
+ DWORD pos = ::GetMessagePos();
+ POINT mp;
+ mp.x = GET_X_LPARAM(pos);
+ mp.y = GET_Y_LPARAM(pos);
+
+ if ((mp.y >= rollupRect.y && mp.y <= rollupRect.YMost()) &&
+ (mp.x >= rollupRect.x && mp.x <= rollupRect.XMost())) {
+ return true;
+ }
+ return false;
+}
+
+//static
+bool
+nsWindow::IsEventOverSpace(nsIRollupListener* aRollupListener) {
+ nsCOMPtr<nsIWidget> widget = aRollupListener->GetRollupWidget();
+ if (widget) {
+ nsWindow* popupWindow = static_cast<nsWindow*>(widget.get());
+ return EventIsInsideWindow(popupWindow);
+ } else {
+ if (aRollupListener) {
+ SelectRollupListener* rollupListener = (SelectRollupListener*) aRollupListener;
+ LayoutDeviceIntRect rect = rollupListener->GetRect();
+ return EventIsInsideRect(rect);
+ }
+ }
+ return false;
+}
+
// static
bool
nsWindow::GetPopupsToRollup(nsIRollupListener* aRollupListener,
uint32_t* aPopupsToRollup)
{
// If we're dealing with menus, we probably have submenus and we don't want
// to rollup some of them if the click is in a parent menu of the current
// submenu.
@@ -7953,265 +7987,262 @@ nsWindow::DealWithPopups(HWND aWnd, UINT
// XXX Why do we use the return value of WM_MOUSEACTIVATE for all messages?
*aResult = MA_NOACTIVATE;
if (!::IsWindowVisible(aWnd)) {
return false;
}
nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener();
+ nsCOMPtr<nsIWidget> widget = rollupListener->GetRollupWidget();
NS_ENSURE_TRUE(rollupListener, false);
- nsCOMPtr<nsIWidget> popup = rollupListener->GetRollupWidget();
- if (!popup) {
- return false;
- }
-
- static bool sSendingNCACTIVATE = false;
- static bool sPendingNCACTIVATE = false;
- uint32_t popupsToRollup = UINT32_MAX;
-
- bool consumeRollupEvent = false;
-
- nsWindow* popupWindow = static_cast<nsWindow*>(popup.get());
- UINT nativeMessage = WinUtils::GetNativeMessage(aMessage);
- switch (nativeMessage) {
- case WM_TOUCH:
- if (!IsTouchSupportEnabled(aWnd)) {
- // If APZ is disabled, don't allow touch inputs to dismiss popups. The
- // compatibility mouse events will do it instead.
- return false;
- }
- MOZ_FALLTHROUGH;
- case WM_LBUTTONDOWN:
- case WM_RBUTTONDOWN:
- case WM_MBUTTONDOWN:
- case WM_NCLBUTTONDOWN:
- case WM_NCRBUTTONDOWN:
- case WM_NCMBUTTONDOWN:
- if (nativeMessage != WM_TOUCH &&
- IsTouchSupportEnabled(aWnd) &&
- MOUSE_INPUT_SOURCE() == MouseEventBinding::MOZ_SOURCE_TOUCH) {
- // If any of these mouse events are really compatibility events that
- // Windows is sending for touch inputs, then don't allow them to dismiss
- // popups when APZ is enabled (instead we do the dismissing as part of
- // WM_TOUCH handling which is more correct).
- // If we don't do this, then when the user lifts their finger after a
- // long-press, the WM_RBUTTONDOWN compatibility event that Windows sends
- // us will dismiss the contextmenu popup that we displayed as part of
- // handling the long-tap-up.
- return false;
- }
- if (!EventIsInsideWindow(popupWindow) &&
- GetPopupsToRollup(rollupListener, &popupsToRollup)) {
- break;
- }
- return false;
- case WM_POINTERDOWN:
- {
- WinPointerEvents pointerEvents;
- if (!pointerEvents.ShouldRollupOnPointerEvent(nativeMessage, aWParam)) {
+ if (rollupListener) {
+ bool consumeEvent = false;
+ static bool sSendingNCACTIVATE = false;
+ static bool sPendingNCACTIVATE = false;
+ uint32_t popupsToRollup = UINT32_MAX;
+
+ bool consumeRollupEvent = false;
+
+ UINT nativeMessage = WinUtils::GetNativeMessage(aMessage);
+ switch (nativeMessage) {
+ case WM_TOUCH:
+ if (!IsTouchSupportEnabled(aWnd)) {
+ // If APZ is disabled, don't allow touch inputs to dismiss popups. The
+ // compatibility mouse events will do it instead.
+ return false;
+ }
+ MOZ_FALLTHROUGH;
+ case WM_LBUTTONDOWN:
+ case WM_RBUTTONDOWN:
+ case WM_MBUTTONDOWN:
+ case WM_NCLBUTTONDOWN:
+ case WM_NCRBUTTONDOWN:
+ case WM_NCMBUTTONDOWN:
+ if (nativeMessage != WM_TOUCH &&
+ IsTouchSupportEnabled(aWnd) &&
+ MOUSE_INPUT_SOURCE() == MouseEventBinding::MOZ_SOURCE_TOUCH) {
+ // If any of these mouse events are really compatibility events that
+ // Windows is sending for touch inputs, then don't allow them to dismiss
+ // popups when APZ is enabled (instead we do the dismissing as part of
+ // WM_TOUCH handling which is more correct).
+ // If we don't do this, then when the user lifts their finger after a
+ // long-press, the WM_RBUTTONDOWN compatibility event that Windows sends
+ // us will dismiss the contextmenu popup that we displayed as part of
+ // handling the long-tap-up.
return false;
}
- if (!GetPopupsToRollup(rollupListener, &popupsToRollup)) {
+ if (!IsEventOverSpace(rollupListener) && GetPopupsToRollup(rollupListener, &popupsToRollup)) {
+ break;
+ }
+ return false;
+ case WM_POINTERDOWN:
+ {
+ WinPointerEvents pointerEvents;
+ if (!pointerEvents.ShouldRollupOnPointerEvent(nativeMessage, aWParam)) {
+ return false;
+ }
+ if (widget) {
+ if (!GetPopupsToRollup(rollupListener, &popupsToRollup)) {
+ return false;
+ }
+ nsWindow* popupWindow = static_cast<nsWindow*>(widget.get());
+ // Can't use EventIsInsideWindow to check whether the event is inside
+ // the popup window. It's because EventIsInsideWindow gets message
+ // coordinates by GetMessagePos, which returns physical screen
+ // coordinates at WM_POINTERDOWN.
+ POINT pt;
+ pt.x = GET_X_LPARAM(aLParam);
+ pt.y = GET_Y_LPARAM(aLParam);
+ RECT r;
+ ::GetWindowRect(popupWindow->mWnd, &r);
+ if (::PtInRect(&r, pt) != 0) {
+ // Don't roll up if the event is inside the popup window.
+ return false;
+ }
+ }
+ }
+ break;
+ case WM_MOUSEWHEEL:
+ case WM_MOUSEHWHEEL:
+ // We need to check if the popup thinks that it should cause closing
+ // itself when mouse wheel events are fired outside the rollup widget.
+ if (!IsEventOverSpace(rollupListener)){
+ // Check if we should consume this event even if we don't roll-up:
+ consumeRollupEvent =
+ rollupListener->ShouldConsumeOnMouseWheelEvent();
+ *aResult = MA_ACTIVATE;
+ if (rollupListener->ShouldRollupOnMouseWheelEvent() &&
+ GetPopupsToRollup(rollupListener, &popupsToRollup)) {
+ break;
+ }
+ }
+ return consumeRollupEvent;
+
+ case WM_ACTIVATEAPP:
+ break;
+
+ case WM_ACTIVATE:
+ // 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()) {
+ // 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()) {
+ return false;
+ }
+ } 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.
+ if (activeWindow) {
+ if (activeWindow->IsPopup()) {
+ return false;
+ }
+ nsWindow* deactiveWindow = WinUtils::GetNSWindowPtr(aWnd);
+ if (deactiveWindow && deactiveWindow->IsPopup()) {
+ return false;
+ }
+ }
+ } 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;
+ }
+ }
+ break;
+
+ case MOZ_WM_REACTIVATE:
+ // The previous active window should take back focus.
+ if (::IsWindow(reinterpret_cast<HWND>(aLParam))) {
+ ::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 (!IsEventOverSpace(rollupListener) && GetPopupsToRollup(rollupListener, &popupsToRollup)) {
+ // WM_MOUSEACTIVATE may be caused by moving the mouse (e.g., X-mouse
+ // of TweakUI is enabled. Then, check if the popup should be rolled up
+ // with rollup listener. If not, just consume the message.
+ if (HIWORD(aLParam) == WM_MOUSEMOVE &&
+ !rollupListener->ShouldRollupOnMouseActivate()) {
+ return true;
+ }
+ // Otherwise, it should be handled by wndproc.
return false;
}
- // Can't use EventIsInsideWindow to check whether the event is inside
- // the popup window. It's because EventIsInsideWindow gets message
- // coordinates by GetMessagePos, which returns physical screen
- // coordinates at WM_POINTERDOWN.
+
+ // Prevent the click inside the popup from causing a change in window
+ // activation. Since the popup is shown non-activated, we need to eat any
+ // requests to activate the window while it is displayed. Windows will
+ // automatically activate the popup on the mousedown otherwise.
+ return true;
+
+ case WM_SHOWWINDOW:
+ // If the window is being minimized, close popups.
+ if (aLParam == SW_PARENTCLOSING) {
+ break;
+ }
+ return false;
+
+ case WM_KILLFOCUS:
+ // If focus moves to other window created in different process/thread,
+ // e.g., a plugin window, popups should be rolled up.
+ if (IsDifferentThreadWindow(reinterpret_cast<HWND>(aWParam))) {
+ break;
+ }
+ return false;
+
+ case WM_MOVING:
+ case WM_MENUSELECT:
+ break;
+
+ default:
+ return false;
+ }
+
+ // Only need to deal with the last rollup for left mouse down events.
+ NS_ASSERTION(!nsAutoRollup::GetLastRollup(), "last rollup is null");
+
+ if (nativeMessage == WM_TOUCH || nativeMessage == WM_LBUTTONDOWN || nativeMessage == WM_POINTERDOWN) {
+ nsIntPoint pos;
+ if (nativeMessage == WM_TOUCH) {
+ if (nsWindow* win = WinUtils::GetNSWindowPtr(aWnd)) {
+ pos = win->GetTouchCoordinates(aWParam, aLParam);
+ }
+ } else {
POINT pt;
pt.x = GET_X_LPARAM(aLParam);
pt.y = GET_Y_LPARAM(aLParam);
- RECT r;
- ::GetWindowRect(popupWindow->mWnd, &r);
- if (::PtInRect(&r, pt) != 0) {
- // Don't roll up if the event is inside the popup window.
- return false;
- }
- }
- break;
- case WM_MOUSEWHEEL:
- case WM_MOUSEHWHEEL:
- // We need to check if the popup thinks that it should cause closing
- // itself when mouse wheel events are fired outside the rollup widget.
- if (!EventIsInsideWindow(popupWindow)) {
- // Check if we should consume this event even if we don't roll-up:
- consumeRollupEvent =
- rollupListener->ShouldConsumeOnMouseWheelEvent();
- *aResult = MA_ACTIVATE;
- if (rollupListener->ShouldRollupOnMouseWheelEvent() &&
- GetPopupsToRollup(rollupListener, &popupsToRollup)) {
- break;
- }
+ ::ClientToScreen(aWnd, &pt);
+ pos = nsIntPoint(pt.x, pt.y);
}
- return consumeRollupEvent;
-
- case WM_ACTIVATEAPP:
- break;
-
- case WM_ACTIVATE:
- // 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()) {
- // 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()) {
- return false;
- }
- } 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.
- if (activeWindow) {
- if (activeWindow->IsPopup()) {
- return false;
- }
- nsWindow* deactiveWindow = WinUtils::GetNSWindowPtr(aWnd);
- if (deactiveWindow && deactiveWindow->IsPopup()) {
- return false;
- }
- }
- } 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;
- }
- }
- break;
-
- case MOZ_WM_REACTIVATE:
- // The previous active window should take back focus.
- if (::IsWindow(reinterpret_cast<HWND>(aLParam))) {
- ::SetForegroundWindow(reinterpret_cast<HWND>(aLParam));
- }
+
+ nsIContent* lastRollup;
+ consumeRollupEvent =
+ rollupListener->Rollup(popupsToRollup, true, &pos, &lastRollup);
+ } else {
+ consumeRollupEvent = rollupListener->Rollup(popupsToRollup, true, nullptr, nullptr);
+ }
+
+ // Tell hook to stop processing messages
+ sProcessHook = false;
+ sRollupMsgId = 0;
+ sRollupMsgWnd = nullptr;
+
+ // If we are NOT supposed to be consuming events, let it go through
+ if (consumeRollupEvent && nativeMessage != WM_RBUTTONDOWN) {
+ *aResult = MA_ACTIVATE;
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)) {
- // WM_MOUSEACTIVATE may be caused by moving the mouse (e.g., X-mouse
- // of TweakUI is enabled. Then, check if the popup should be rolled up
- // with rollup listener. If not, just consume the message.
- if (HIWORD(aLParam) == WM_MOUSEMOVE &&
- !rollupListener->ShouldRollupOnMouseActivate()) {
- return true;
- }
- // Otherwise, it should be handled by wndproc.
- return false;
- }
-
- // Prevent the click inside the popup from causing a change in window
- // activation. Since the popup is shown non-activated, we need to eat any
- // requests to activate the window while it is displayed. Windows will
- // automatically activate the popup on the mousedown otherwise.
- return true;
-
- case WM_SHOWWINDOW:
- // If the window is being minimized, close popups.
- if (aLParam == SW_PARENTCLOSING) {
- break;
- }
- return false;
-
- case WM_KILLFOCUS:
- // If focus moves to other window created in different process/thread,
- // e.g., a plugin window, popups should be rolled up.
- if (IsDifferentThreadWindow(reinterpret_cast<HWND>(aWParam))) {
- break;
- }
- return false;
-
- case WM_MOVING:
- case WM_MENUSELECT:
- break;
-
- default:
- return false;
- }
-
- // Only need to deal with the last rollup for left mouse down events.
- NS_ASSERTION(!nsAutoRollup::GetLastRollup(), "last rollup is null");
-
- if (nativeMessage == WM_TOUCH || nativeMessage == WM_LBUTTONDOWN || nativeMessage == WM_POINTERDOWN) {
- nsIntPoint pos;
- if (nativeMessage == WM_TOUCH) {
- if (nsWindow* win = WinUtils::GetNSWindowPtr(aWnd)) {
- pos = win->GetTouchCoordinates(aWParam, aLParam);
- }
- } else {
- POINT pt;
- pt.x = GET_X_LPARAM(aLParam);
- pt.y = GET_Y_LPARAM(aLParam);
- ::ClientToScreen(aWnd, &pt);
- pos = nsIntPoint(pt.x, pt.y);
- }
-
- nsIContent* lastRollup;
- consumeRollupEvent =
- rollupListener->Rollup(popupsToRollup, true, &pos, &lastRollup);
- nsAutoRollup::SetLastRollup(lastRollup);
- } else {
- consumeRollupEvent =
- rollupListener->Rollup(popupsToRollup, true, nullptr, nullptr);
- }
-
- // Tell hook to stop processing messages
- sProcessHook = false;
- sRollupMsgId = 0;
- sRollupMsgWnd = nullptr;
-
- // If we are NOT supposed to be consuming events, let it go through
- if (consumeRollupEvent && nativeMessage != WM_RBUTTONDOWN) {
- *aResult = MA_ACTIVATE;
- return true;
- }
-
+ }
+ }
return false;
}
+
/**************************************************************
**************************************************************
**
** BLOCK: Misc. utility methods and functions.
**
** General use.
**
**************************************************************
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -413,16 +413,19 @@ protected:
MSGResult& aResult);
LRESULT ProcessCharMessage(const MSG &aMsg,
bool *aEventDispatched);
LRESULT ProcessKeyUpMessage(const MSG &aMsg,
bool *aEventDispatched);
LRESULT ProcessKeyDownMessage(const MSG &aMsg,
bool *aEventDispatched);
static bool EventIsInsideWindow(nsWindow* aWindow);
+ static bool EventIsInsideRect(LayoutDeviceIntRect aRect);
+ static bool IsEventOverSpace(nsIRollupListener* aListener);
+ static bool EventIsInsideRect(LayoutDeviceIntRect aRect, LayoutDeviceIntRect aButtonRect);
// Convert nsEventStatus value to a windows boolean
static bool ConvertStatus(nsEventStatus aStatus);
static void PostSleepWakeNotification(const bool aIsSleepMode);
int32_t ClientMarginHitTestPoint(int32_t mx, int32_t my);
TimeStamp GetMessageTimeStamp(LONG aEventTime) const;
static void UpdateFirstEventTime(DWORD aEventTime);
void FinishLiveResizing(ResizeState aNewState);
nsIntPoint GetTouchCoordinates(WPARAM wParam, LPARAM lParam);