mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 943759, [Australis], support mousethrough on panels to allow mouse events to pass through to the content behind, implemented on Windows, Mac and Linux, use this for the UI tour highlight, r=neil,jmathies,karlt
This commit is contained in:
parent
9e7a6ea388
commit
ee782b7b75
@ -223,7 +223,8 @@
|
||||
noautofocus="true"
|
||||
noautohide="true"
|
||||
flip="none"
|
||||
consumeoutsideclicks="false">
|
||||
consumeoutsideclicks="false"
|
||||
mousethrough="always">
|
||||
<box id="UITourHighlight"></box>
|
||||
</panel>
|
||||
|
||||
|
@ -96,7 +96,7 @@ nsMenuPopupFrame::nsMenuPopupFrame(nsIPresShell* aShell, nsStyleContext* aContex
|
||||
mShouldAutoPosition(true),
|
||||
mInContentShell(true),
|
||||
mIsMenuLocked(false),
|
||||
mIsDragPopup(false),
|
||||
mMouseTransparent(false),
|
||||
mHFlip(false),
|
||||
mVFlip(false)
|
||||
{
|
||||
@ -141,12 +141,6 @@ nsMenuPopupFrame::Init(nsIContent* aContent,
|
||||
mPopupType = ePopupTypeTooltip;
|
||||
}
|
||||
|
||||
if (mPopupType == ePopupTypePanel &&
|
||||
aContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||
nsGkAtoms::drag, eIgnoreCase)) {
|
||||
mIsDragPopup = true;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> dsti = PresContext()->GetDocShell();
|
||||
if (dsti && dsti->ItemType() == nsIDocShellTreeItem::typeChrome) {
|
||||
mInContentShell = false;
|
||||
@ -243,7 +237,22 @@ nsMenuPopupFrame::CreateWidgetForView(nsView* aView)
|
||||
widgetData.clipSiblings = true;
|
||||
widgetData.mPopupHint = mPopupType;
|
||||
widgetData.mNoAutoHide = IsNoAutoHide();
|
||||
widgetData.mIsDragPopup = mIsDragPopup;
|
||||
|
||||
if (!mInContentShell) {
|
||||
// A drag popup may be used for non-static translucent drag feedback
|
||||
bool isDragPopup = false;
|
||||
if (mPopupType == ePopupTypePanel &&
|
||||
mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::type,
|
||||
nsGkAtoms::drag, eIgnoreCase)) {
|
||||
widgetData.mIsDragPopup = true;
|
||||
isDragPopup = true;
|
||||
}
|
||||
|
||||
// If mousethrough="always" is set directly on the popup, then the widget
|
||||
// should ignore mouse events, passing them through to the content behind.
|
||||
mMouseTransparent = GetStateBits() & NS_FRAME_MOUSE_THROUGH_ALWAYS;
|
||||
widgetData.mMouseTransparent = mMouseTransparent;
|
||||
}
|
||||
|
||||
nsAutoString title;
|
||||
if (mContent && widgetData.mNoAutoHide) {
|
||||
@ -1814,19 +1823,6 @@ nsMenuPopupFrame::AttachedDismissalListener()
|
||||
mConsumeRollupEvent = nsIPopupBoxObject::ROLLUP_DEFAULT;
|
||||
}
|
||||
|
||||
void
|
||||
nsMenuPopupFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists)
|
||||
{
|
||||
// don't pass events to drag popups
|
||||
if (aBuilder->IsForEventDelivery() && mIsDragPopup) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsBoxFrame::BuildDisplayList(aBuilder, aDirtyRect, aLists);
|
||||
}
|
||||
|
||||
// helpers /////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -230,7 +230,7 @@ public:
|
||||
bool IsMenu() MOZ_OVERRIDE { return mPopupType == ePopupTypeMenu; }
|
||||
bool IsOpen() MOZ_OVERRIDE { return mPopupState == ePopupOpen || mPopupState == ePopupOpenAndVisible; }
|
||||
|
||||
bool IsDragPopup() { return mIsDragPopup; }
|
||||
bool IsMouseTransparent() { return mMouseTransparent; }
|
||||
|
||||
static nsIContent* GetTriggerContent(nsMenuPopupFrame* aMenuPopupFrame);
|
||||
void ClearTriggerContent() { mTriggerContent = nullptr; }
|
||||
@ -334,10 +334,6 @@ public:
|
||||
// This position is in CSS pixels.
|
||||
nsIntPoint ScreenPosition() const { return nsIntPoint(mScreenXPos, mScreenYPos); }
|
||||
|
||||
virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aDirtyRect,
|
||||
const nsDisplayListSet& aLists) MOZ_OVERRIDE;
|
||||
|
||||
nsIntPoint GetLastClientOffset() const { return mLastClientOffset; }
|
||||
|
||||
// Return the alignment of the popup
|
||||
@ -480,7 +476,7 @@ protected:
|
||||
bool mShouldAutoPosition; // Should SetPopupPosition be allowed to auto position popup?
|
||||
bool mInContentShell; // True if the popup is in a content shell
|
||||
bool mIsMenuLocked; // Should events inside this menu be ignored?
|
||||
bool mIsDragPopup; // True if this is a popup used for drag feedback
|
||||
bool mMouseTransparent; // True if this is a popup is transparent to mouse events
|
||||
|
||||
// the flip modes that were used when the popup was opened
|
||||
bool mHFlip;
|
||||
|
@ -1385,21 +1385,21 @@ nsXULPopupManager::GetVisiblePopups(nsTArray<nsIFrame *>& aPopups)
|
||||
{
|
||||
aPopups.Clear();
|
||||
|
||||
// Iterate over both lists of popups
|
||||
nsMenuChainItem* item = mPopups;
|
||||
while (item) {
|
||||
if (item->Frame()->PopupState() == ePopupOpenAndVisible)
|
||||
aPopups.AppendElement(static_cast<nsIFrame*>(item->Frame()));
|
||||
item = item->GetParent();
|
||||
}
|
||||
for (int32_t list = 0; list < 2; list++) {
|
||||
while (item) {
|
||||
// Skip panels which are not open and visible as well as popups that
|
||||
// are transparent to mouse events.
|
||||
if (item->Frame()->PopupState() == ePopupOpenAndVisible &&
|
||||
!item->Frame()->IsMouseTransparent()) {
|
||||
aPopups.AppendElement(item->Frame());
|
||||
}
|
||||
|
||||
item = mNoHidePanels;
|
||||
while (item) {
|
||||
// skip panels which are not open and visible as well as draggable popups,
|
||||
// as those don't respond to events.
|
||||
if (item->Frame()->PopupState() == ePopupOpenAndVisible && !item->Frame()->IsDragPopup()) {
|
||||
aPopups.AppendElement(static_cast<nsIFrame*>(item->Frame()));
|
||||
item = item->GetParent();
|
||||
}
|
||||
item = item->GetParent();
|
||||
|
||||
item = mNoHidePanels;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -290,7 +290,7 @@ nsresult nsCocoaWindow::Create(nsIWidget *aParent,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mWindowType == eWindowType_popup) {
|
||||
if (aInitData->mIsDragPopup) {
|
||||
if (aInitData->mMouseTransparent) {
|
||||
[mWindow setIgnoresMouseEvents:YES];
|
||||
}
|
||||
// now we can convert newBounds to device pixels for the window we created,
|
||||
|
@ -3586,6 +3586,23 @@ nsWindow::Create(nsIWidget *aParent,
|
||||
if (wmd != -1)
|
||||
gdk_window_set_decorations(gtk_widget_get_window(mShell), (GdkWMDecoration) wmd);
|
||||
}
|
||||
|
||||
// If the popup ignores mouse events, set an empty input shape.
|
||||
if (aInitData->mMouseTransparent) {
|
||||
#if (MOZ_WIDGET_GTK == 2)
|
||||
GdkRectangle rect = { 0, 0, 0, 0 };
|
||||
GdkRegion *region = gdk_region_rectangle(&rect);
|
||||
|
||||
gdk_window_input_shape_combine_region(mGdkWindow, region, 0, 0);
|
||||
gdk_region_destroy(region);
|
||||
#else
|
||||
cairo_rectangle_int_t rect = { 0, 0, 0, 0 };
|
||||
cairo_region_t *region = cairo_region_create_rectangle(&rect);
|
||||
|
||||
gdk_window_input_shape_combine_region(mGdkWindow, region, 0, 0);
|
||||
cairo_region_destroy(region);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -101,7 +101,8 @@ struct nsWidgetInitData {
|
||||
mNoAutoHide(false),
|
||||
mIsDragPopup(false),
|
||||
mIsAnimationSuppressed(false),
|
||||
mSupportTranslucency(false)
|
||||
mSupportTranslucency(false),
|
||||
mMouseTransparent(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -120,6 +121,9 @@ struct nsWidgetInitData {
|
||||
bool mIsAnimationSuppressed;
|
||||
// true if the window should support an alpha channel, if available.
|
||||
bool mSupportTranslucency;
|
||||
// true if the window should be transparent to mouse events. Currently this is
|
||||
// only valid for eWindowType_popup widgets
|
||||
bool mMouseTransparent;
|
||||
};
|
||||
|
||||
#endif // nsWidgetInitData_h__
|
||||
|
@ -334,6 +334,8 @@ nsWindow::nsWindow() : nsWindowBase()
|
||||
mFullscreenMode = false;
|
||||
mMousePresent = false;
|
||||
mDestroyCalled = false;
|
||||
mHasTaskbarIconBeenCreated = false;
|
||||
mMouseTransparent = false;
|
||||
mPickerDisplayCount = 0;
|
||||
mWindowType = eWindowType_child;
|
||||
mBorderStyle = eBorderStyle_default;
|
||||
@ -362,7 +364,6 @@ nsWindow::nsWindow() : nsWindowBase()
|
||||
mForeground = ::GetSysColor(COLOR_WINDOWTEXT);
|
||||
|
||||
mTaskbarPreview = nullptr;
|
||||
mHasTaskbarIconBeenCreated = false;
|
||||
|
||||
// Global initialization
|
||||
if (!sInstanceCount) {
|
||||
@ -490,8 +491,9 @@ nsWindow::Create(nsIWidget *aParent,
|
||||
extendedStyle |= WS_EX_COMPOSITED;
|
||||
}
|
||||
|
||||
if (aInitData->mIsDragPopup) {
|
||||
if (aInitData->mMouseTransparent) {
|
||||
// This flag makes the window transparent to mouse events
|
||||
mMouseTransparent = true;
|
||||
extendedStyle |= WS_EX_TRANSPARENT;
|
||||
}
|
||||
} else if (mWindowType == eWindowType_invisible) {
|
||||
@ -4673,6 +4675,13 @@ nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
|
||||
|
||||
case WM_NCHITTEST:
|
||||
{
|
||||
if (mMouseTransparent) {
|
||||
// Treat this window as transparent.
|
||||
*aRetValue = HTTRANSPARENT;
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* If an nc client area margin has been moved, we are responsible
|
||||
* for calculating where the resize margins are and returning the
|
||||
|
@ -572,6 +572,10 @@ protected:
|
||||
// icon has been created on the taskbar.
|
||||
bool mHasTaskbarIconBeenCreated;
|
||||
|
||||
// Indicates that mouse events should be ignored and pass through to the
|
||||
// window below. This is currently only used for popups.
|
||||
bool mMouseTransparent;
|
||||
|
||||
// The point in time at which the last paint completed. We use this to avoid
|
||||
// painting too rapidly in response to frequent input events.
|
||||
TimeStamp mLastPaintEndTime;
|
||||
|
Loading…
Reference in New Issue
Block a user