mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-24 05:44:10 +00:00
Bug 554919, support panels which can dragged via their backgrounds, r=dao,smaug
This commit is contained in:
parent
f9daca5776
commit
8307283671
@ -190,7 +190,7 @@
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULPopupManager.h"
|
||||
#include "nsIDOMXULControlElement.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsMenuPopupFrame.h"
|
||||
#endif
|
||||
|
||||
#include "xpcprivate.h"
|
||||
@ -10214,9 +10214,28 @@ nsGlobalChromeWindow::GetAttentionWithCycleCount(PRInt32 aCycleCount)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalChromeWindow::BeginWindowMove(nsIDOMEvent *aMouseDownEvent)
|
||||
nsGlobalChromeWindow::BeginWindowMove(nsIDOMEvent *aMouseDownEvent, nsIDOMElement* aPanel)
|
||||
{
|
||||
nsCOMPtr<nsIWidget> widget = GetMainWidget();
|
||||
nsCOMPtr<nsIWidget> widget;
|
||||
|
||||
// if a panel was supplied, use its widget instead.
|
||||
#ifdef MOZ_XUL
|
||||
if (aPanel) {
|
||||
nsCOMPtr<nsIContent> panel = do_QueryInterface(aPanel);
|
||||
NS_ENSURE_TRUE(panel, NS_ERROR_FAILURE);
|
||||
|
||||
nsIFrame* frame = panel->GetPrimaryFrame();
|
||||
NS_ENSURE_TRUE(frame && frame->GetType() == nsGkAtoms::menuPopupFrame, NS_OK);
|
||||
|
||||
(static_cast<nsMenuPopupFrame*>(frame))->GetWidget(getter_AddRefs(widget));
|
||||
}
|
||||
else {
|
||||
#endif
|
||||
widget = GetMainWidget();
|
||||
#ifdef MOZ_XUL
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!widget) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ interface nsIDOMElement;
|
||||
interface nsIDOMEvent;
|
||||
interface nsIChromeFrameMessageManager;
|
||||
|
||||
[scriptable, uuid(ec38cbaf-372f-4874-bc7a-dbf1f0b3d755)]
|
||||
[scriptable, uuid(7cfbc355-cbf9-4408-8e4c-a3c603ff1428)]
|
||||
interface nsIDOMChromeWindow : nsISupports
|
||||
{
|
||||
const unsigned short STATE_MAXIMIZED = 1;
|
||||
@ -84,8 +84,10 @@ interface nsIDOMChromeWindow : nsISupports
|
||||
* start dragging the window. This function will fail unless called
|
||||
* while the left mouse button is held down, callers must check this.
|
||||
*
|
||||
* The optional panel argument should be set when moving a panel.
|
||||
*
|
||||
* Returns NS_ERROR_NOT_IMPLEMENTED (and thus throws in JS) if the OS
|
||||
* doesn't support this.
|
||||
*/
|
||||
void beginWindowMove(in nsIDOMEvent mouseDownEvent);
|
||||
void beginWindowMove(in nsIDOMEvent mouseDownEvent, [optional] in nsIDOMElement panel);
|
||||
};
|
||||
|
@ -40,10 +40,11 @@ function WindowDraggingElement(elem, window) {
|
||||
this._elem = elem;
|
||||
this._window = window;
|
||||
#ifdef XP_WIN
|
||||
this._elem.addEventListener("MozMouseHittest", this, false);
|
||||
#else
|
||||
this._elem.addEventListener("mousedown", this, false);
|
||||
if (!this.isPanel())
|
||||
this._elem.addEventListener("MozMouseHittest", this, false);
|
||||
else
|
||||
#endif
|
||||
this._elem.addEventListener("mousedown", this, false);
|
||||
}
|
||||
|
||||
WindowDraggingElement.prototype = {
|
||||
@ -79,11 +80,20 @@ WindowDraggingElement.prototype = {
|
||||
}
|
||||
return true;
|
||||
},
|
||||
isPanel : function() {
|
||||
return this._elem instanceof Components.interfaces.nsIDOMXULElement &&
|
||||
this._elem.localName == "panel";
|
||||
},
|
||||
handleEvent: function(aEvent) {
|
||||
let isPanel = this.isPanel();
|
||||
#ifdef XP_WIN
|
||||
if (this.shouldDrag(aEvent))
|
||||
aEvent.preventDefault();
|
||||
#else
|
||||
if (!isPanel) {
|
||||
if (this.shouldDrag(aEvent))
|
||||
aEvent.preventDefault();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
switch (aEvent.type) {
|
||||
case "mousedown":
|
||||
if (!this.shouldDrag(aEvent))
|
||||
@ -92,18 +102,27 @@ WindowDraggingElement.prototype = {
|
||||
#ifdef MOZ_WIDGET_GTK2
|
||||
// On GTK, there is a toolkit-level function which handles
|
||||
// window dragging, which must be used.
|
||||
this._window.beginWindowMove(aEvent);
|
||||
this._window.beginWindowMove(aEvent, isPanel ? this._elem : null);
|
||||
#else
|
||||
this._deltaX = aEvent.screenX - this._window.screenX;
|
||||
this._deltaY = aEvent.screenY - this._window.screenY;
|
||||
if (isPanel) {
|
||||
let screenRect = this._elem.getOuterScreenRect();
|
||||
this._deltaX = aEvent.screenX - screenRect.left;
|
||||
this._deltaY = aEvent.screenY - screenRect.top;
|
||||
}
|
||||
else {
|
||||
this._deltaX = aEvent.screenX - this._window.screenX;
|
||||
this._deltaY = aEvent.screenY - this._window.screenY;
|
||||
}
|
||||
this._draggingWindow = true;
|
||||
this._window.addEventListener("mousemove", this, false);
|
||||
this._window.addEventListener("mouseup", this, false);
|
||||
#endif
|
||||
break;
|
||||
case "mousemove":
|
||||
if (this._draggingWindow)
|
||||
this._window.moveTo(aEvent.screenX - this._deltaX, aEvent.screenY - this._deltaY);
|
||||
if (this._draggingWindow) {
|
||||
let toDrag = this.isPanel() ? this._elem : this._window;
|
||||
toDrag.moveTo(aEvent.screenX - this._deltaX, aEvent.screenY - this._deltaY);
|
||||
}
|
||||
break;
|
||||
case "mouseup":
|
||||
if (this._draggingWindow) {
|
||||
@ -113,6 +132,5 @@ WindowDraggingElement.prototype = {
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
@ -227,6 +227,31 @@ var tests = [
|
||||
panel.appendChild(tree);
|
||||
checkTreeCoords();
|
||||
}
|
||||
},
|
||||
{
|
||||
testname: "noautohide panel with backdrag",
|
||||
attrs: { noautohide: true, backdrag: "true" },
|
||||
test: function(panel) {
|
||||
var label = document.createElement("label");
|
||||
label.id = "backdragspot";
|
||||
label.setAttribute("value", "Hello There");
|
||||
panel.appendChild(label);
|
||||
panel.openPopupAtScreen(200, 230);
|
||||
},
|
||||
result: function(testname, panel) {
|
||||
var oldrect = panel.getOuterScreenRect();
|
||||
|
||||
// Linux uses native window moving
|
||||
if (navigator.platform.indexOf("Linux") == -1) {
|
||||
var backdragspot = document.getElementById("backdragspot");
|
||||
synthesizeMouse(backdragspot, 5, 5, { type: "mousedown" });
|
||||
synthesizeMouse(backdragspot, 15, 20, { type: "mousemove" });
|
||||
synthesizeMouse(backdragspot, 15, 20, { type: "mouseup" });
|
||||
|
||||
is(panel.getOuterScreenRect().left, 210, testname + "left");
|
||||
is(panel.getOuterScreenRect().top, 245, testname + "top");
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -229,6 +229,20 @@
|
||||
]]></getter>
|
||||
</property>
|
||||
<field name="_prevFocus">0</field>
|
||||
<field name="_dragBindingAlive">true</field>
|
||||
<constructor>
|
||||
<![CDATA[
|
||||
if (this.getAttribute("backdrag") == "true" && !this._draggableStarted) {
|
||||
this._draggableStarted = true;
|
||||
try {
|
||||
let tmp = {};
|
||||
Components.utils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
|
||||
let draghandle = new tmp.WindowDraggingElement(this, window);
|
||||
draghandle.mouseDownCheck = function () this._dragBindingAlive;
|
||||
} catch (e) {}
|
||||
}
|
||||
]]>
|
||||
</constructor>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
|
Loading…
x
Reference in New Issue
Block a user