From 60a5143df08c2b776f0568de721e5e55d1280c66 Mon Sep 17 00:00:00 2001 From: Tim Nguyen Date: Fri, 18 Jan 2019 22:42:24 +0000 Subject: [PATCH] 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 --- browser/base/content/browser.js | 6 -- browser/base/content/tabbrowser.xml | 2 +- .../static/browser_all_files_referenced.js | 3 - browser/themes/linux/browser.css | 4 +- browser/themes/linux/places/organizer.css | 2 +- dom/base/nsGlobalWindowInner.cpp | 18 ----- dom/base/nsGlobalWindowInner.h | 2 - dom/webidl/Window.webidl | 11 --- toolkit/content/jar.mn | 1 - toolkit/content/moz.build | 3 - toolkit/content/tests/chrome/chrome.ini | 1 - .../content/tests/chrome/test_bug585946.xul | 50 ------------- toolkit/content/widgets/toolbar.xml | 30 -------- toolkit/modules/WindowDraggingUtils.jsm | 70 ------------------- toolkit/modules/moz.build | 1 - toolkit/themes/linux/global/global.css | 2 +- tools/lint/eslint/modules.json | 1 - widget/gtk/nsWindow.cpp | 57 +++++++++------ widget/gtk/nsWindow.h | 3 +- widget/nsBaseWidget.h | 4 -- widget/nsIWidget.h | 6 -- 21 files changed, 42 insertions(+), 235 deletions(-) delete mode 100644 toolkit/content/tests/chrome/test_bug585946.xul delete mode 100644 toolkit/content/widgets/toolbar.xml delete mode 100644 toolkit/modules/WindowDraggingUtils.jsm diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index d21c2cbe00f3..9958d2486cd0 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -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) { diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 674d7d948683..4a7395da61d0 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -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 || diff --git a/browser/base/content/test/static/browser_all_files_referenced.js b/browser/base/content/test/static/browser_all_files_referenced.js index ff28338465d7..3af0f8ba159f 100644 --- a/browser/base/content/test/static/browser_all_files_referenced.js +++ b/browser/base/content/test/static/browser_all_files_referenced.js @@ -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" }, diff --git a/browser/themes/linux/browser.css b/browser/themes/linux/browser.css index 348fc1710a58..fa0035e5f325 100644 --- a/browser/themes/linux/browser.css +++ b/browser/themes/linux/browser.css @@ -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; } } diff --git a/browser/themes/linux/places/organizer.css b/browser/themes/linux/places/organizer.css index 68236949989d..8c5258c7bdf7 100644 --- a/browser/themes/linux/places/organizer.css +++ b/browser/themes/linux/places/organizer.css @@ -10,7 +10,7 @@ @media (-moz-menubar-drag) { #placesToolbar { - -moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag"); + -moz-window-dragging: drag; } } diff --git a/dom/base/nsGlobalWindowInner.cpp b/dom/base/nsGlobalWindowInner.cpp index 85c91cf6dcc3..c47fdcc38630 100644 --- a/dom/base/nsGlobalWindowInner.cpp +++ b/dom/base/nsGlobalWindowInner.cpp @@ -6617,24 +6617,6 @@ void nsGlobalWindowInner::GetAttentionWithCycleCount(int32_t aCycleCount, } } -void nsGlobalWindowInner::BeginWindowMove(Event& aMouseDownEvent, - ErrorResult& aError) { - nsCOMPtr 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 nsGlobalWindowInner::PromiseDocumentFlushed( PromiseDocumentFlushedCallback& aCallback, ErrorResult& aError) { MOZ_RELEASE_ASSERT(IsChromeWindow()); diff --git a/dom/base/nsGlobalWindowInner.h b/dom/base/nsGlobalWindowInner.h index 90bc710ce7e0..c22862f93b47 100644 --- a/dom/base/nsGlobalWindowInner.h +++ b/dom/base/nsGlobalWindowInner.h @@ -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 PromiseDocumentFlushed( mozilla::dom::PromiseDocumentFlushedCallback& aCallback, diff --git a/dom/webidl/Window.webidl b/dom/webidl/Window.webidl index 5cb941d9072c..703f56ba4386 100644 --- a/dom/webidl/Window.webidl +++ b/dom/webidl/Window.webidl @@ -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 diff --git a/toolkit/content/jar.mn b/toolkit/content/jar.mn index 0a90fe2552ce..b6a735409e88 100644 --- a/toolkit/content/jar.mn +++ b/toolkit/content/jar.mn @@ -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) diff --git a/toolkit/content/moz.build b/toolkit/content/moz.build index ab1fac0a2e5d..547cb749206d 100644 --- a/toolkit/content/moz.build +++ b/toolkit/content/moz.build @@ -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*'): diff --git a/toolkit/content/tests/chrome/chrome.ini b/toolkit/content/tests/chrome/chrome.ini index c46a20010498..866ceb7d18e5 100644 --- a/toolkit/content/tests/chrome/chrome.ini +++ b/toolkit/content/tests/chrome/chrome.ini @@ -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] diff --git a/toolkit/content/tests/chrome/test_bug585946.xul b/toolkit/content/tests/chrome/test_bug585946.xul deleted file mode 100644 index d209066c8434..000000000000 --- a/toolkit/content/tests/chrome/test_bug585946.xul +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/toolkit/content/widgets/toolbar.xml b/toolkit/content/widgets/toolbar.xml deleted file mode 100644 index d185c5a6d839..000000000000 --- a/toolkit/content/widgets/toolbar.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - true - - - - diff --git a/toolkit/modules/WindowDraggingUtils.jsm b/toolkit/modules/WindowDraggingUtils.jsm deleted file mode 100644 index f17c706380e1..000000000000 --- a/toolkit/modules/WindowDraggingUtils.jsm +++ /dev/null @@ -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; - } - }, -}; diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build index cc9bc3313284..d887d94fda18 100644 --- a/toolkit/modules/moz.build +++ b/toolkit/modules/moz.build @@ -249,7 +249,6 @@ EXTRA_JS_MODULES += [ 'UpdateUtils.jsm', 'WebChannel.jsm', 'WebProgressChild.jsm', - 'WindowDraggingUtils.jsm', 'ZipUtils.jsm', ] diff --git a/toolkit/themes/linux/global/global.css b/toolkit/themes/linux/global/global.css index 2a2abdd0fc92..49a389c2666d 100644 --- a/toolkit/themes/linux/global/global.css +++ b/toolkit/themes/linux/global/global.css @@ -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; } } diff --git a/tools/lint/eslint/modules.json b/tools/lint/eslint/modules.json index 0a36a6dbdadb..5a14a0e053e7 100644 --- a/tools/lint/eslint/modules.json +++ b/tools/lint/eslint/modules.json @@ -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"], diff --git a/widget/gtk/nsWindow.cpp b/widget/gtk/nsWindow.cpp index 2abcd8b1584c..47cb9b9261fe 100644 --- a/widget/gtk/nsWindow.cpp +++ b/widget/gtk/nsWindow.cpp @@ -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); diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 57aaba839c73..e370e12743ea 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -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; diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index d669fea9cc1f..54a58d4b8ae6 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -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; diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index bfa659dd2015..36407c6d3a97 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -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