Bug 1241885 - Implement support for -moz-window-dragging in GTK and remove toolkit toolbar-drag binding. r=dao,bzbarsky,stransky

The restriction preventing fullscreen windows from being dragged is removed.

Differential Revision: https://phabricator.services.mozilla.com/D15075

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tim Nguyen 2019-01-18 22:42:24 +00:00
Родитель f35506cf5d
Коммит 60a5143df0
21 изменённых файлов: 42 добавлений и 235 удалений

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

@ -1542,12 +1542,6 @@ var gBrowserInit = {
gNavToolbox.addEventListener("customizationstarting", CustomizationHandler);
gNavToolbox.addEventListener("customizationending", CustomizationHandler);
if (AppConstants.platform == "linux") {
let { WindowDraggingElement } =
ChromeUtils.import("resource://gre/modules/WindowDraggingUtils.jsm", {});
new WindowDraggingElement(document.getElementById("titlebar"));
}
SessionStore.promiseInitialized.then(() => {
// Bail out if the window has been closed in the meantime.
if (window.closed) {

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

@ -1255,7 +1255,7 @@
// When the tabbar has an unified appearance with the titlebar
// and menubar, a double-click in it should have the same behavior
// as double-clicking the titlebar
if (TabsInTitlebar.enabled || this.parentNode._dragBindingAlive)
if (TabsInTitlebar.enabled)
return;
if (event.button != 0 ||

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

@ -158,9 +158,6 @@ var whitelist = [
{file: "resource://gre/modules/Promise.jsm"},
// Still used by WebIDE, which is going away but not entirely gone.
{file: "resource://gre/modules/ZipUtils.jsm"},
// Bug 1463225 (on Mac and Windows this is only used by a test)
{file: "chrome://global/content/bindings/toolbar.xml",
platforms: ["macosx", "win"]},
// Bug 1483277 (temporarily unreferenced)
{file: AppConstants.BROWSER_CHROME_URL == "chrome://browser/content/browser.xul" ?
"chrome://browser/content/browser.xhtml" : "chrome://browser/content/browser.xul" },

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

@ -480,12 +480,12 @@ notification[value="translation"] menulist > .menulist-dropmarker {
}
#nav-bar {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
-moz-window-dragging: drag;
}
@media (-moz-menubar-drag) {
#TabsToolbar {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
-moz-window-dragging: drag;
}
}

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

@ -10,7 +10,7 @@
@media (-moz-menubar-drag) {
#placesToolbar {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
-moz-window-dragging: drag;
}
}

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

@ -6617,24 +6617,6 @@ void nsGlobalWindowInner::GetAttentionWithCycleCount(int32_t aCycleCount,
}
}
void nsGlobalWindowInner::BeginWindowMove(Event& aMouseDownEvent,
ErrorResult& aError) {
nsCOMPtr<nsIWidget> widget = GetMainWidget();
if (!widget) {
return;
}
WidgetMouseEvent* mouseEvent =
aMouseDownEvent.WidgetEventPtr()->AsMouseEvent();
if (!mouseEvent || mouseEvent->mClass != eMouseEventClass) {
aError.Throw(NS_ERROR_FAILURE);
return;
}
aError = widget->BeginMoveDrag(mouseEvent);
}
already_AddRefed<Promise> nsGlobalWindowInner::PromiseDocumentFlushed(
PromiseDocumentFlushedCallback& aCallback, ErrorResult& aError) {
MOZ_RELEASE_ASSERT(IsChromeWindow());

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

@ -903,8 +903,6 @@ class nsGlobalWindowInner final : public mozilla::dom::EventTarget,
mozilla::dom::ChromeMessageBroadcaster* MessageManager();
mozilla::dom::ChromeMessageBroadcaster* GetGroupMessageManager(
const nsAString& aGroup);
void BeginWindowMove(mozilla::dom::Event& aMouseDownEvent,
mozilla::ErrorResult& aError);
already_AddRefed<mozilla::dom::Promise> PromiseDocumentFlushed(
mozilla::dom::PromiseDocumentFlushedCallback& aCallback,

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

@ -454,17 +454,6 @@ partial interface Window {
[Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"]
ChromeMessageBroadcaster getGroupMessageManager(DOMString aGroup);
/**
* On some operating systems, we must allow the window manager to
* handle window dragging. This function tells the window manager to
* start dragging the window. This function will fail unless called
* while the left mouse button is held down, callers must check this.
*
* Throws NS_ERROR_NOT_IMPLEMENTED if the OS doesn't support this.
*/
[Throws, Func="nsGlobalWindowInner::IsPrivilegedChromeWindow"]
void beginWindowMove(Event mouseDownEvent);
/**
* Calls the given function as soon as a style or layout flush for the
* top-level document is not necessary, and returns a Promise which

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

@ -84,7 +84,6 @@ toolkit.jar:
* content/global/bindings/textbox.xml (widgets/textbox.xml)
content/global/bindings/timekeeper.js (widgets/timekeeper.js)
content/global/bindings/timepicker.js (widgets/timepicker.js)
content/global/bindings/toolbar.xml (widgets/toolbar.xml)
content/global/bindings/toolbarbutton.xml (widgets/toolbarbutton.xml)
content/global/bindings/tree.xml (widgets/tree.xml)
content/global/bindings/videocontrols.xml (widgets/videocontrols.xml)

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

@ -149,9 +149,6 @@ with Files('tests/chrome/rtlchrome/**'):
with Files('tests/chrome/*451540*'):
BUG_COMPONENT = ('Toolkit', 'Find Toolbar')
with Files('tests/chrome/*585946*'):
BUG_COMPONENT = ('Toolkit', 'Toolbars and Toolbar Customization')
with Files('tests/chrome/*557987*'):
BUG_COMPONENT = ('Core', 'XP Toolkit/Widgets: Menus')
with Files('tests/chrome/*562554*'):

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

@ -95,7 +95,6 @@ support-files = bug451540_window.xul
[test_bug557987.xul]
[test_bug562554.xul]
[test_bug570192.xul]
[test_bug585946.xul]
[test_bug624329.xul]
skip-if = (os == 'mac' && os_version == '10.10') # Unexpectedly perma-passes on OSX 10.10
[test_bug792324.xul]

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

@ -1,50 +0,0 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css" type="text/css"?>
<window title="Toolbar" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
onload="startTest();">
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<toolbox>
<toolbarpalette/>
<toolbar id="toolbar" defaultset="node1,node2">
<toolbarbutton id="node1" label="node1" removable="true"/>
<toolbarbutton id="node2" label="node2" removable="true"/>
</toolbar>
</toolbox>
<!-- test resuls are displayed in the html:body -->
<body xmlns="http://www.w3.org/1999/xhtml"
style="height: 300px; overflow: auto;"/>
<!-- test code goes here -->
<script type="application/javascript"><![CDATA[
SimpleTest.waitForExplicitFinish();
function startTest() {
var toolbar = $("toolbar");
var splitter = document.createElement("splitter");
splitter.setAttribute("id", "dynsplitter");
splitter.setAttribute("skipintoolbarset", "true");
toolbar.insertBefore(splitter, $("node2"));
function checkPos() {
is($("dynsplitter").previousSibling, $("node1"));
is($("dynsplitter").nextSibling, $("node2"));
}
checkPos();
toolbar.style.MozBinding = "url(chrome://global/content/bindings/toolbar.xml#toolbar-drag)";
toolbar.clientTop; // style flush
checkPos();
SimpleTest.finish();
}
]]></script>
</window>

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

@ -1,30 +0,0 @@
<?xml version="1.0"?>
<!-- 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/. -->
<bindings id="toolbarBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="toolbar-drag">
<implementation>
<field name="_dragBindingAlive">true</field>
<constructor><![CDATA[
if (!this._draggableStarted) {
this._draggableStarted = true;
try {
let tmp = {};
ChromeUtils.import("resource://gre/modules/WindowDraggingUtils.jsm", tmp);
let draggableThis = new tmp.WindowDraggingElement(this);
draggableThis.mouseDownCheck = function(e) {
return this._dragBindingAlive;
};
} catch (e) {}
}
]]></constructor>
</implementation>
</binding>
</bindings>

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

@ -1,70 +0,0 @@
/* 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/. */
ChromeUtils.import("resource://gre/modules/AppConstants.jsm");
const HAVE_CSS_WINDOW_DRAG_SUPPORT = ["win", "macosx"].includes(AppConstants.platform);
var EXPORTED_SYMBOLS = [ "WindowDraggingElement" ];
function WindowDraggingElement(elem) {
if (HAVE_CSS_WINDOW_DRAG_SUPPORT) {
return;
}
this._elem = elem;
this._window = elem.ownerGlobal;
this._elem.addEventListener("mousedown", this);
}
WindowDraggingElement.prototype = {
mouseDownCheck(e) { return true; },
dragTags: ["box", "hbox", "vbox", "spacer", "label", "statusbarpanel", "stack",
"toolbaritem", "toolbarseparator", "toolbarspring", "toolbarspacer",
"radiogroup", "deck", "scrollbox", "arrowscrollbox", "tabs"],
shouldDrag(aEvent) {
if (aEvent.button != 0 ||
this._window.fullScreen ||
!this.mouseDownCheck.call(this._elem, aEvent) ||
aEvent.defaultPrevented)
return false;
let target = aEvent.originalTarget, parent = aEvent.originalTarget;
// The target may be inside an embedded iframe or browser. (bug 615152)
if (target.ownerGlobal != this._window)
return false;
while (parent != this._elem) {
let mousethrough = parent.getAttribute("mousethrough");
if (mousethrough == "always")
target = parent.parentNode;
else if (mousethrough == "never")
break;
parent = parent.parentNode;
}
while (target != this._elem) {
if (!this.dragTags.includes(target.localName))
return false;
target = target.parentNode;
}
return true;
},
handleEvent(aEvent) {
switch (aEvent.type) {
case "mousedown":
if (this.shouldDrag(aEvent)) {
this._window.addEventListener("mousemove", this, { once: true });
this._window.addEventListener("mouseup", this, { once: true });
}
break;
case "mousemove":
this._window.beginWindowMove(aEvent);
this._window.removeEventListener("mouseup", this);
break;
case "mouseup":
this._window.removeEventListener("mousemove", this);
break;
}
},
};

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

@ -249,7 +249,6 @@ EXTRA_JS_MODULES += [
'UpdateUtils.jsm',
'WebChannel.jsm',
'WebProgressChild.jsm',
'WindowDraggingUtils.jsm',
'ZipUtils.jsm',
]

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

@ -19,7 +19,7 @@
@media (-moz-menubar-drag) {
toolbar[type="menubar"] {
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
-moz-window-dragging: drag;
}
}

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

@ -210,7 +210,6 @@
"version.jsm": ["VERSION"],
"vtt.jsm": ["WebVTT"],
"WebChannel.jsm": ["WebChannel", "WebChannelBroker"],
"WindowDraggingUtils.jsm": ["WindowDraggingElement"],
"windows.jsm": ["BrowserWindows"],
"WindowsJumpLists.jsm": ["WinTaskbarJumpList"],
"WindowsPreviewPerTab.jsm": ["AeroPeek"],

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

@ -2310,6 +2310,31 @@ static LayoutDeviceIntPoint GetRefPoint(nsWindow *aWindow, Event *aEvent) {
}
void nsWindow::OnMotionNotifyEvent(GdkEventMotion *aEvent) {
if (mWindowShouldStartDragging) {
mWindowShouldStartDragging = false;
// find the top-level window
GdkWindow *gdk_window = gdk_window_get_toplevel(mGdkWindow);
MOZ_ASSERT(gdk_window, "gdk_window_get_toplevel should not return null");
bool canDrag = true;
if (mIsX11Display) {
// Workaround for https://bugzilla.gnome.org/show_bug.cgi?id=789054
// To avoid crashes disable double-click on WM without _NET_WM_MOVERESIZE.
// See _should_perform_ewmh_drag() at gdkwindow-x11.c
GdkScreen *screen = gdk_window_get_screen(gdk_window);
GdkAtom atom = gdk_atom_intern("_NET_WM_MOVERESIZE", FALSE);
if (!gdk_x11_screen_supports_net_wm_hint(screen, atom)) {
canDrag = false;
}
}
if (canDrag) {
gdk_window_begin_move_drag(gdk_window, 1, aEvent->x_root, aEvent->y_root,
aEvent->time);
return;
}
}
// see if we can compress this event
// XXXldb Why skip every other motion event when we have multiple,
// but not more than that?
@ -2538,7 +2563,13 @@ void nsWindow::OnButtonPressEvent(GdkEventButton *aEvent) {
InitButtonEvent(event, aEvent);
event.pressure = mLastMotionPressure;
DispatchInputEvent(&event);
nsEventStatus eventStatus = DispatchInputEvent(&event);
if (mDraggableRegion.Contains(aEvent->x, aEvent->y) &&
domButton == WidgetMouseEvent::eLeftButton &&
eventStatus != nsEventStatus_eConsumeNoDefault) {
mWindowShouldStartDragging = true;
}
// right menu click on linux should also pop up a context menu
if (!nsBaseWidget::ShowContextMenuAfterMouseUp()) {
@ -2549,6 +2580,10 @@ void nsWindow::OnButtonPressEvent(GdkEventButton *aEvent) {
void nsWindow::OnButtonReleaseEvent(GdkEventButton *aEvent) {
LOG(("Button %u release on %p\n", aEvent->button, (void *)this));
if (mWindowShouldStartDragging) {
mWindowShouldStartDragging = false;
}
uint16_t domButton;
switch (aEvent->button) {
case 1:
@ -5781,26 +5816,6 @@ bool nsWindow::GetDragInfo(WidgetMouseEvent *aMouseEvent, GdkWindow **aWindow,
return true;
}
nsresult nsWindow::BeginMoveDrag(WidgetMouseEvent *aEvent) {
MOZ_ASSERT(aEvent, "must have event");
MOZ_ASSERT(aEvent->mClass == eMouseEventClass,
"event must have correct struct type");
GdkWindow *gdk_window;
gint button, screenX, screenY;
if (!GetDragInfo(aEvent, &gdk_window, &button, &screenX, &screenY)) {
return NS_ERROR_FAILURE;
}
// tell the window manager to start the move
screenX = DevicePixelsToGdkCoordRoundDown(screenX);
screenY = DevicePixelsToGdkCoordRoundDown(screenY);
gdk_window_begin_move_drag(gdk_window, button, screenX, screenY,
aEvent->mTime);
return NS_OK;
}
nsresult nsWindow::BeginResizeDrag(WidgetGUIEvent *aEvent, int32_t aHorizontal,
int32_t aVertical) {
NS_ENSURE_ARG_POINTER(aEvent);

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

@ -262,8 +262,6 @@ class nsWindow final : public nsBaseWidget {
virtual MOZ_MUST_USE nsresult BeginResizeDrag(mozilla::WidgetGUIEvent* aEvent,
int32_t aHorizontal,
int32_t aVertical) override;
virtual MOZ_MUST_USE nsresult
BeginMoveDrag(mozilla::WidgetMouseEvent* aEvent) override;
MozContainer* GetMozContainer() { return mContainer; }
// GetMozContainerWidget returns the MozContainer even for undestroyed
@ -469,6 +467,7 @@ class nsWindow final : public nsBaseWidget {
GtkWidget* mShell;
MozContainer* mContainer;
GdkWindow* mGdkWindow;
bool mWindowShouldStartDragging = false;
PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate;
uint32_t mHasMappedToplevel : 1, mIsFullyObscured : 1, mRetryPointerGrab : 1;

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

@ -272,10 +272,6 @@ class nsBaseWidget : public nsIWidget, public nsSupportsWeakReference {
int32_t aVertical) override {
return NS_ERROR_NOT_IMPLEMENTED;
}
virtual MOZ_MUST_USE nsresult
BeginMoveDrag(mozilla::WidgetMouseEvent* aEvent) override {
return NS_ERROR_NOT_IMPLEMENTED;
}
virtual nsresult ActivateNativeMenuItemAt(
const nsAString& indexString) override {
return NS_ERROR_NOT_IMPLEMENTED;

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

@ -1461,12 +1461,6 @@ class nsIWidget : public nsISupports {
int32_t aHorizontal,
int32_t aVertical) = 0;
/**
* Begin a window moving drag, based on the event passed in.
*/
virtual MOZ_MUST_USE nsresult
BeginMoveDrag(mozilla::WidgetMouseEvent* aEvent) = 0;
enum Modifiers {
CAPS_LOCK = 0x00000001, // when CapsLock is active
NUM_LOCK = 0x00000002, // when NumLock is active