Bug 398928, allow dragging window on Mac by the toolbar, r=neil,sr=roc,a=beltzner

This commit is contained in:
enndeakin@sympatico.ca 2008-04-16 08:29:54 -07:00
Родитель b050b44ac1
Коммит e39b4ffc1c
5 изменённых файлов: 103 добавлений и 2 удалений

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

@ -237,7 +237,7 @@
</vbox>
</tooltip>
<toolbox id="navigator-toolbox" class="toolbox-top" mode="icons"
<toolbox id="navigator-toolbox" type="drag" class="toolbox-top" mode="icons"
defaultmode="icons">
<!-- Menu -->
<toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"

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

@ -850,6 +850,9 @@ GK_ATOM(tokenize, "tokenize")
GK_ATOM(toolbar, "toolbar")
GK_ATOM(toolbarbutton, "toolbarbutton")
GK_ATOM(toolbaritem, "toolbaritem")
GK_ATOM(toolbarseparator, "toolbarseparator")
GK_ATOM(toolbarspacer, "toolbarspacer")
GK_ATOM(toolbarspring, "toolbarspring")
GK_ATOM(toolbox, "toolbox")
GK_ATOM(tooltip, "tooltip")
GK_ATOM(tooltiptext, "tooltiptext")

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

@ -84,6 +84,83 @@ nsTitleBarFrame::Init(nsIContent* aContent,
return rv;
}
class nsDisplayTitleBarRedirector : public nsDisplayWrapList {
public:
nsDisplayTitleBarRedirector(nsIFrame* aFrame, nsDisplayItem* aItem,
nsIFrame* aTargetFrame)
: nsDisplayWrapList(aFrame, aItem), mTargetFrame(aTargetFrame) {}
nsDisplayTitleBarRedirector(nsIFrame* aFrame, nsDisplayList* aList,
nsIFrame* aTargetFrame)
: nsDisplayWrapList(aFrame, aList), mTargetFrame(aTargetFrame) {}
virtual nsIFrame* HitTest(nsDisplayListBuilder* aBuilder, nsPoint aPt,
HitTestState* aState);
NS_DISPLAY_DECL_NAME("XULTitleBarRedirector")
private:
nsIFrame* mTargetFrame;
};
nsIFrame* nsDisplayTitleBarRedirector::HitTest(nsDisplayListBuilder* aBuilder,
nsPoint aPt, HitTestState* aState)
{
nsIFrame* frame = mList.HitTest(aBuilder, aPt, aState);
if (!frame)
return nsnull;
// We want a drag over a background-like child of the titlebar to move the
// window, which means that the event must be retargetted at the titlebar.
// However, other elements such as controls should receive events normally.
// Here, we look for tags that usually represent empty space. A loop that
// iterates up the parent chain is used so that these elements can still
// appear inside a non-background element, for instance an hbox that is
// inside a button should still be targetted as normal.
nsIFrame* foundframe = frame;
while (foundframe && foundframe != mTargetFrame) {
nsIContent* content = foundframe->GetContent();
if (content) {
// not a XUL element so target normally
if (content->GetNameSpaceID() != kNameSpaceID_XUL)
return frame;
nsIAtom* tag = content->Tag();
// if this is not a background-like element, use the original frame that
// was targetted, so that the event is processed as normal
if (tag != nsGkAtoms::box &&
tag != nsGkAtoms::hbox &&
tag != nsGkAtoms::vbox &&
tag != nsGkAtoms::spacer &&
tag != nsGkAtoms::toolbar &&
tag != nsGkAtoms::toolbaritem &&
tag != nsGkAtoms::toolbarspacer &&
tag != nsGkAtoms::toolbarspring &&
tag != nsGkAtoms::toolbarseparator)
return frame;
}
foundframe = foundframe->GetParent();
}
// retarget to the titlebar
return mTargetFrame;
}
class nsXULTitleBarWrapper : public nsDisplayWrapper
{
public:
nsXULTitleBarWrapper(nsIFrame* aTargetFrame)
: mTargetFrame(aTargetFrame) {}
virtual nsDisplayItem* WrapList(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList) {
return new (aBuilder) nsDisplayTitleBarRedirector(aFrame, aList, mTargetFrame);
}
virtual nsDisplayItem* WrapItem(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem) {
return new (aBuilder) nsDisplayTitleBarRedirector(aItem->GetUnderlyingFrame(),
aItem, mTargetFrame);
}
private:
nsIFrame* mTargetFrame;
};
NS_IMETHODIMP
nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
const nsRect& aDirtyRect,
@ -91,9 +168,17 @@ nsTitleBarFrame::BuildDisplayListForChildren(nsDisplayListBuilder* aBuilder,
{
// override, since we don't want children to get events
if (aBuilder->IsForEventDelivery()) {
if (!mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowevents,
if (mTrackingMouseMove ||
!mContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::allowevents,
nsGkAtoms::_true, eCaseMatters))
return NS_OK;
nsDisplayListCollection set;
nsresult rv = nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, set);
NS_ENSURE_SUCCESS(rv, rv);
nsXULTitleBarWrapper wrapper(this);
return wrapper.WrapLists(aBuilder, this, set, aLists);
}
return nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, aLists);
}

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

@ -69,6 +69,13 @@
</implementation>
</binding>
<binding id="toolbox-drag" display="xul:titlebar"
extends="chrome://global/content/bindings/toolbar.xml#toolbox">
<content allowevents="true">
<children/>
</content>
</binding>
<binding id="toolbar" extends="chrome://global/content/bindings/toolbar.xml#toolbar-base">
<implementation implements="nsIAccessibleProvider">
<property name="accessibleType" readonly="true">

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

@ -218,6 +218,12 @@ toolbox {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbox");
-moz-box-orient: vertical;
}
%ifdef XP_MACOSX
toolbox[type="drag"] {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbox-drag");
}
%endif
toolbar {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar");