CSD functionality firefox58
authorWolfgang Rosenauer <wr@rosenauer.org>
Wed, 24 Jan 2018 17:02:23 +0100
branchfirefox58
changeset 1027 7071f6ebfda6
parent 1026 963c89cda54b
child 1028 4ce2b699562f
CSD functionality
MozillaFirefox/MozillaFirefox.changes
MozillaFirefox/MozillaFirefox.spec
MozillaFirefox/mozilla-bmo256180.patch
MozillaFirefox/mozilla-enable-csd.patch
mozilla-bmo256180.patch
mozilla-enable-csd.patch
series
--- a/MozillaFirefox/MozillaFirefox.changes	Tue Jan 23 22:05:20 2018 +0100
+++ b/MozillaFirefox/MozillaFirefox.changes	Wed Jan 24 17:02:23 2018 +0100
@@ -1,4 +1,10 @@
 -------------------------------------------------------------------
+Wed Jan 24 11:24:30 UTC 2018 - wr@rosenauer.org
+
+- readd mozilla-enable-csd.patch as it only lands for FF59 upstream
+- allow larger number of nested elements (mozilla-bmo256180.patch)
+
+-------------------------------------------------------------------
 Tue Jan 23 20:40:57 UTC 2018 - wr@rosenauer.org
 
 - update to Firefox 58.0 (bsc#1077291)
--- a/MozillaFirefox/MozillaFirefox.spec	Tue Jan 23 22:05:20 2018 +0100
+++ b/MozillaFirefox/MozillaFirefox.spec	Wed Jan 24 17:02:23 2018 +0100
@@ -153,6 +153,8 @@
 Patch5:         mozilla-no-stdcxx-check.patch
 Patch6:         mozilla-reduce-files-per-UnifiedBindings.patch
 Patch7:         mozilla-aarch64-startup-crash.patch
+Patch8:         mozilla-enable-csd.patch
+Patch9:         mozilla-bmo256180.patch
 # Firefox/browser
 Patch101:       firefox-kde.patch
 Patch102:       firefox-no-default-ualocale.patch
@@ -263,6 +265,8 @@
 %patch6 -p1
 %endif
 %patch7 -p1
+%patch8 -p1
+%patch9 -p1
 # Firefox
 %patch101 -p1
 %patch102 -p1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-bmo256180.patch	Wed Jan 24 17:02:23 2018 +0100
@@ -0,0 +1,1 @@
+../mozilla-bmo256180.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MozillaFirefox/mozilla-enable-csd.patch	Wed Jan 24 17:02:23 2018 +0100
@@ -0,0 +1,1 @@
+../mozilla-enable-csd.patch
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mozilla-bmo256180.patch	Wed Jan 24 17:02:23 2018 +0100
@@ -0,0 +1,11 @@
+--- a/layout/generic/nsIFrame.h.old	2016-07-11 13:41:39.688276559 +0200
++++ b/layout/generic/nsIFrame.h	2016-07-11 13:42:12.791406976 +0200
+@@ -13,7 +13,7 @@
+ #error This header/class should only be used within Mozilla code. It should not be used by extensions.
+ #endif
+ 
+-#define MAX_REFLOW_DEPTH 200
++#define MAX_REFLOW_DEPTH 1000
+ 
+ /* nsIFrame is in the process of being deCOMtaminated, i.e., this file is eventually
+    going to be eliminated, and all callers will use nsFrame instead.  At the moment
--- a/mozilla-enable-csd.patch	Tue Jan 23 22:05:20 2018 +0100
+++ b/mozilla-enable-csd.patch	Wed Jan 24 17:02:23 2018 +0100
@@ -1,41 +1,7 @@
-# HG changeset patch
-# User Wolfgang Rosenauer <wr@rosenauer.org>
-# Parent  04d0a1058aef5d88bddfca8f37759d7abea4bd5b
-
-diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js
---- a/browser/app/profile/firefox.js
-+++ b/browser/app/profile/firefox.js
-@@ -465,21 +465,17 @@ pref("browser.tabs.warnOnOpen", true);
- pref("browser.tabs.maxOpenBeforeWarn", 15);
- pref("browser.tabs.loadInBackground", true);
- pref("browser.tabs.opentabfor.middleclick", true);
- pref("browser.tabs.loadDivertedInBackground", false);
- pref("browser.tabs.loadBookmarksInBackground", false);
- pref("browser.tabs.loadBookmarksInTabs", false);
- pref("browser.tabs.tabClipWidth", 140);
- pref("browser.tabs.tabMinWidth", 76);
--#ifdef UNIX_BUT_NOT_MAC
--pref("browser.tabs.drawInTitlebar", false);
--#else
- pref("browser.tabs.drawInTitlebar", true);
--#endif
- 
- // Offer additional drag space to the user. The drag space
- // will only be shown if browser.tabs.drawInTitlebar is true.
- pref("browser.tabs.extraDragSpace", false);
- 
- // 0 - Disable the tabbar session restore button.
- // 1 - Enable the tabbar session restore button.
- // 2 - Control group. The tabbar session restore button is disabled,
-diff --git a/browser/base/moz.build b/browser/base/moz.build
---- a/browser/base/moz.build
-+++ b/browser/base/moz.build
-@@ -52,15 +52,15 @@ BROWSER_CHROME_MANIFESTS += [
- DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION']
- DEFINES['MOZ_APP_VERSION_DISPLAY'] = CONFIG['MOZ_APP_VERSION_DISPLAY']
- 
- DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR
- 
+diff -up firefox-58.0/browser/base/moz.build.1399611 firefox-58.0/browser/base/moz.build
+--- firefox-58.0/browser/base/moz.build.1399611	2017-11-02 17:16:30.000000000 +0100
++++ firefox-58.0/browser/base/moz.build	2018-01-24 10:57:03.717031953 +0100
+@@ -57,7 +57,7 @@ DEFINES['APP_LICENSE_BLOCK'] = '%s/conte
  if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
      DEFINES['CONTEXT_COPY_IMAGE_CONTENTS'] = 1
  
@@ -44,39 +10,68 @@
      DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
  
  if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
-     DEFINES['MENUBAR_CAN_AUTOHIDE'] = 1
+diff -up firefox-58.0/browser/themes/linux/browser.css.1399611 firefox-58.0/browser/themes/linux/browser.css
+--- firefox-58.0/browser/themes/linux/browser.css.1399611	2018-01-11 21:16:54.000000000 +0100
++++ firefox-58.0/browser/themes/linux/browser.css	2018-01-24 10:57:03.718031950 +0100
+@@ -717,7 +717,7 @@ html|span.ac-emphasize-text-url {
+   :root[tabsintitlebar] > #titlebar:-moz-lwtheme {
+     visibility: hidden;
+   }
+-  :root[tabsintitlebar] > #titlebar-content:-moz-lwtheme {
++  :root[tabsintitlebar] #titlebar-content:-moz-lwtheme {
+     visibility: visible;
+   }
  
- JAR_MANIFESTS += ['jar.mn']
-diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js
---- a/modules/libpref/init/all.js
-+++ b/modules/libpref/init/all.js
-@@ -4936,16 +4936,17 @@ pref("gfx.content.always-paint", false);
- pref("gfx.apitrace.enabled",false);
- #endif
+diff -up firefox-58.0/layout/style/nsMediaFeatures.cpp.1399611 firefox-58.0/layout/style/nsMediaFeatures.cpp
+--- firefox-58.0/layout/style/nsMediaFeatures.cpp.1399611	2018-01-11 21:17:01.000000000 +0100
++++ firefox-58.0/layout/style/nsMediaFeatures.cpp	2018-01-24 10:57:03.718031950 +0100
+@@ -831,6 +831,42 @@ nsMediaFeatures::features[] = {
+     GetSystemMetric
+   },
  
- #ifdef MOZ_X11
- #ifdef MOZ_WIDGET_GTK
- pref("gfx.xrender.enabled",false);
- pref("widget.chrome.allow-gtk-dark-theme", false);
- pref("widget.content.allow-gtk-dark-theme", false);
-+pref("widget.allow-client-side-decoration", false);
- #endif
- #endif
- 
- pref("widget.window-transforms.disabled", false);
- 
- #ifdef XP_WIN
- // Whether to disable the automatic detection and use of direct2d.
- pref("gfx.direct2d.disabled", false);
-diff --git a/toolkit/modules/moz.build b/toolkit/modules/moz.build
---- a/toolkit/modules/moz.build
-+++ b/toolkit/modules/moz.build
-@@ -254,17 +254,17 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'coco
- EXTRA_JS_MODULES.third_party.jsesc += ['third_party/jsesc/jsesc.js']
- EXTRA_JS_MODULES.sessionstore += [
-     'sessionstore/PrivacyLevel.jsm',
-     'sessionstore/SessionHistory.jsm',
-     'sessionstore/Utils.jsm',
++  {
++    &nsGkAtoms::_moz_gtk_csd_available,
++    nsMediaFeature::eMinMaxNotAllowed,
++    nsMediaFeature::eBoolInteger,
++    nsMediaFeature::eNoRequirements,
++    { &nsGkAtoms::gtk_csd_available },
++    GetSystemMetric
++  },
++
++  {
++    &nsGkAtoms::_moz_gtk_csd_minimize_button,
++    nsMediaFeature::eMinMaxNotAllowed,
++    nsMediaFeature::eBoolInteger,
++    nsMediaFeature::eNoRequirements,
++    { &nsGkAtoms::gtk_csd_minimize_button },
++    GetSystemMetric
++  },
++
++  {
++    &nsGkAtoms::_moz_gtk_csd_maximize_button,
++    nsMediaFeature::eMinMaxNotAllowed,
++    nsMediaFeature::eBoolInteger,
++    nsMediaFeature::eNoRequirements,
++    { &nsGkAtoms::gtk_csd_maximize_button },
++    GetSystemMetric
++  },
++
++  {
++    &nsGkAtoms::_moz_gtk_csd_close_button,
++    nsMediaFeature::eMinMaxNotAllowed,
++    nsMediaFeature::eBoolInteger,
++    nsMediaFeature::eNoRequirements,
++    { &nsGkAtoms::gtk_csd_close_button },
++    GetSystemMetric
++  },
++
+   // Internal -moz-is-glyph media feature: applies only inside SVG glyphs.
+   // Internal because it is really only useful in the user agent anyway
+   //  and therefore not worth standardizing.
+diff -up firefox-58.0/toolkit/modules/moz.build.1399611 firefox-58.0/toolkit/modules/moz.build
+--- firefox-58.0/toolkit/modules/moz.build.1399611	2018-01-11 21:17:05.000000000 +0100
++++ firefox-58.0/toolkit/modules/moz.build	2018-01-24 10:57:03.718031950 +0100
+@@ -259,7 +259,7 @@ EXTRA_JS_MODULES.sessionstore += [
  ]
  
  DEFINES['INSTALL_COMPACT_THEMES'] = 1
@@ -85,8 +80,1233 @@
      DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
  
  if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
-     DEFINES['MENUBAR_CAN_AUTOHIDE'] = 1
+diff -up firefox-58.0/widget/gtk/mozgtk/mozgtk.c.1399611 firefox-58.0/widget/gtk/mozgtk/mozgtk.c
+--- firefox-58.0/widget/gtk/mozgtk/mozgtk.c.1399611	2018-01-11 21:17:06.000000000 +0100
++++ firefox-58.0/widget/gtk/mozgtk/mozgtk.c	2018-01-24 10:11:58.638648276 +0100
+@@ -391,6 +391,7 @@ STUB(gtk_separator_menu_item_new)
+ STUB(gtk_separator_tool_item_new)
+ STUB(gtk_settings_get_default)
+ STUB(gtk_settings_get_for_screen)
++STUB(gtk_show_uri)
+ STUB(gtk_socket_add_id)
+ STUB(gtk_socket_get_id)
+ STUB(gtk_socket_get_type)
+@@ -407,6 +408,7 @@ STUB(gtk_target_list_add_image_targets)
+ STUB(gtk_target_list_new)
+ STUB(gtk_target_list_unref)
+ STUB(gtk_targets_include_image)
++STUB(gtk_targets_include_text)
+ STUB(gtk_target_table_free)
+ STUB(gtk_target_table_new_from_list)
+ STUB(gtk_text_view_new)
+@@ -479,6 +481,7 @@ STUB(gtk_widget_show_all)
+ STUB(gtk_widget_size_allocate)
+ STUB(gtk_widget_style_get)
+ STUB(gtk_widget_unparent)
++STUB(gtk_widget_unrealize)
+ STUB(gtk_window_deiconify)
+ STUB(gtk_window_fullscreen)
+ STUB(gtk_window_get_group)
+@@ -582,6 +585,8 @@ STUB(gtk_style_context_set_state)
+ STUB(gtk_style_properties_lookup_property)
+ STUB(gtk_tree_view_column_get_button)
+ STUB(gtk_widget_get_preferred_size)
++STUB(gtk_widget_get_preferred_width)
++STUB(gtk_widget_get_preferred_height)
+ STUB(gtk_widget_get_state_flags)
+ STUB(gtk_widget_get_style_context)
+ STUB(gtk_widget_path_append_type)
+diff -up firefox-58.0/widget/gtk/nsLookAndFeel.cpp.1399611 firefox-58.0/widget/gtk/nsLookAndFeel.cpp
+--- firefox-58.0/widget/gtk/nsLookAndFeel.cpp.1399611	2018-01-11 21:17:06.000000000 +0100
++++ firefox-58.0/widget/gtk/nsLookAndFeel.cpp	2018-01-24 10:57:03.718031950 +0100
+@@ -24,6 +24,7 @@
+ #include "nsStyleConsts.h"
+ #include "gfxFontConstants.h"
+ #include "WidgetUtils.h"
++#include "nsWindow.h"
+ 
+ #include <dlfcn.h>
+ 
+@@ -740,7 +741,7 @@ GetSystemFontInfo(GtkStyleContext *aStyl
+     // Scale fonts up on HiDPI displays.
+     // This would be done automatically with cairo, but we manually manage
+     // the display scale for platform consistency.
+-    size *= ScreenHelperGTK::GetGTKMonitorScaleFactor();
++    size *= mozilla::widget::ScreenHelperGTK::GetGTKMonitorScaleFactor();
+ 
+     // |size| is now pixels
+ 
+@@ -1076,17 +1077,13 @@ nsLookAndFeel::EnsureInit()
+     gtk_widget_destroy(window);
+     g_object_unref(labelWidget);
+ 
+-    // Require GTK 3.20 for client-side decoration support.
+-    mCSDAvailable = gtk_check_version(3, 20, 0) == nullptr;
+-    if (mCSDAvailable) {
+-        mCSDAvailable =
+-            mozilla::Preferences::GetBool("widget.allow-client-side-decoration",
+-                                          false);
+-    }
++    // Require GTK 3.10 for GtkHeaderBar support and compatible window manager.
++    mCSDAvailable = (gtk_check_version(3, 10, 0) == nullptr &&
++        nsWindow::GetCSDSupportLevel() != nsWindow::CSD_SUPPORT_NONE);
+ 
+     // We need to initialize whole CSD config explicitly because it's queried
+     // as -moz-gtk* media features.
+-    mCSDCloseButton = false;
++    mCSDCloseButton = true;
+     mCSDMaximizeButton = false;
+     mCSDMinimizeButton = false;
+ 
+@@ -1095,18 +1092,24 @@ nsLookAndFeel::EnsureInit()
+           (const gchar* (*)(GtkWidget*))
+           dlsym(RTLD_DEFAULT, "gtk_header_bar_get_decoration_layout");
+ 
+-        GtkWidget* headerBar = GetWidget(MOZ_GTK_HEADER_BAR);
+-        const gchar* decorationLayout =
+-            sGtkHeaderBarGetDecorationLayoutPtr(headerBar);
+-        if (!decorationLayout) {
+-            g_object_get(settings, "gtk-decoration-layout", &decorationLayout,
+-                         nullptr);
+-        }
++        if (sGtkHeaderBarGetDecorationLayoutPtr) {
++            GtkWidget* headerBar = GetWidget(MOZ_GTK_HEADER_BAR);
++            const gchar* decorationLayout =
++                sGtkHeaderBarGetDecorationLayoutPtr(headerBar);
++            if (!decorationLayout) {
++                g_object_get(settings, "gtk-decoration-layout",
++                             &decorationLayout,
++                             nullptr);
++            }
+ 
+-        if (decorationLayout) {
+-            mCSDCloseButton = (strstr(decorationLayout, "close") != nullptr);
+-            mCSDMaximizeButton = (strstr(decorationLayout, "maximize") != nullptr);
+-            mCSDMinimizeButton = (strstr(decorationLayout, "minimize") != nullptr);
++            if (decorationLayout) {
++                mCSDCloseButton =
++                    (strstr(decorationLayout, "close") != nullptr);
++                mCSDMaximizeButton =
++                    (strstr(decorationLayout, "maximize") != nullptr);
++                mCSDMinimizeButton =
++                    (strstr(decorationLayout, "minimize") != nullptr);
++            }
+         }
+     }
+ }
+diff -up firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp.1399611 firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp
+--- firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp.1399611	2018-01-11 21:17:06.000000000 +0100
++++ firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp	2018-01-24 10:57:03.719031946 +0100
+@@ -29,6 +29,7 @@
+ 
+ #include <gdk/gdkprivate.h>
+ #include <gtk/gtk.h>
++#include <gtk/gtkx.h>
+ 
+ #include "gfxContext.h"
+ #include "gfxPlatformGtk.h"
+@@ -51,6 +52,7 @@
+ 
+ using namespace mozilla;
+ using namespace mozilla::gfx;
++using namespace mozilla::widget;
+ 
+ NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeGTK, nsNativeTheme, nsITheme,
+                                                              nsIObserver)
+@@ -1375,6 +1377,10 @@ nsNativeThemeGTK::GetWidgetPadding(nsDev
+   switch (aWidgetType) {
+     case NS_THEME_BUTTON_FOCUS:
+     case NS_THEME_TOOLBARBUTTON:
++    case NS_THEME_WINDOW_BUTTON_CLOSE:
++    case NS_THEME_WINDOW_BUTTON_MINIMIZE:
++    case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
++    case NS_THEME_WINDOW_BUTTON_RESTORE:
+     case NS_THEME_DUALBUTTON:
+     case NS_THEME_TAB_SCROLL_ARROW_BACK:
+     case NS_THEME_TAB_SCROLL_ARROW_FORWARD:
+diff -up firefox-58.0/widget/gtk/nsWindow.cpp.1399611 firefox-58.0/widget/gtk/nsWindow.cpp
+--- firefox-58.0/widget/gtk/nsWindow.cpp.1399611	2018-01-24 10:57:03.714031963 +0100
++++ firefox-58.0/widget/gtk/nsWindow.cpp	2018-01-24 10:57:03.720031943 +0100
+@@ -178,13 +178,8 @@ static int    is_parent_ungrab_enter(Gdk
+ static int    is_parent_grab_leave(GdkEventCrossing *aEvent);
+ 
+ /* callbacks from widgets */
+-#if (MOZ_WIDGET_GTK == 2)
+-static gboolean expose_event_cb           (GtkWidget *widget,
+-                                           GdkEventExpose *event);
+-#else
+ static gboolean expose_event_cb           (GtkWidget *widget,
+                                            cairo_t *rect);
+-#endif
+ static gboolean configure_event_cb        (GtkWidget *widget,
+                                            GdkEventConfigure *event);
+ static void     container_unrealize_cb    (GtkWidget *widget);
+@@ -230,11 +225,9 @@ static void     screen_composited_change
+ static void     widget_composited_changed_cb     (GtkWidget* widget,
+                                                   gpointer user_data);
+ 
+-#if (MOZ_WIDGET_GTK == 3)
+ static void     scale_changed_cb          (GtkWidget* widget,
+                                            GParamSpec* aPSpec,
+                                            gpointer aPointer);
+-#endif
+ #if GTK_CHECK_VERSION(3,4,0)
+ static gboolean touch_event_cb            (GtkWidget* aWidget,
+                                            GdkEventTouch* aEvent);
+@@ -390,7 +383,7 @@ static guint gButtonState;
+ static inline int32_t
+ GetBitmapStride(int32_t width)
+ {
+-#if defined(MOZ_X11) || (MOZ_WIDGET_GTK == 2)
++#if defined(MOZ_X11)
+   return (width+7)/8;
+ #else
+   return cairo_format_stride_for_width(CAIRO_FORMAT_A1, width);
+@@ -458,11 +451,23 @@ nsWindow::nsWindow()
+     mXVisual  = nullptr;
+     mXDepth   = 0;
+ #endif /* MOZ_X11 */
++
+     if (!gGlobalsInitialized) {
+         gGlobalsInitialized = true;
+ 
+         // It's OK if either of these fail, but it may not be one day.
+         initialize_prefs();
++
++#ifdef MOZ_WAYLAND
++        // Wayland provides clipboard data to application on focus-in event
++        // so we need to init our clipboard hooks before we create window
++        // and get focus.
++        if (!mIsX11Display) {
++            nsCOMPtr<nsIClipboard> clipboard =
++                do_GetService("@mozilla.org/widget/clipboard;1");
++            NS_ASSERTION(clipboard, "Failed to init clipboard!");
++        }
++#endif
+     }
+ 
+     mLastMotionPressure = 0;
+@@ -1521,7 +1526,7 @@ nsWindow::UpdateClientOffset()
+ {
+     AUTO_PROFILER_LABEL("nsWindow::UpdateClientOffset", GRAPHICS);
+ 
+-    if (!mIsTopLevel || !mShell || !mGdkWindow || !mIsX11Display ||
++    if (!mIsTopLevel || !mShell || !mIsX11Display ||
+         gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP) {
+         mClientOffset = nsIntPoint(0, 0);
+         return;
+@@ -1534,7 +1539,7 @@ nsWindow::UpdateClientOffset()
+     int length_returned;
+     long *frame_extents;
+ 
+-    if (!gdk_property_get(mGdkWindow,
++    if (!gdk_property_get(gtk_widget_get_window(mShell),
+                           gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE),
+                           cardinal_atom,
+                           0, // offset
+@@ -1710,16 +1715,22 @@ nsWindow::GetNativeData(uint32_t aDataTy
+ #ifdef MOZ_X11
+         GdkDisplay* gdkDisplay = gdk_display_get_default();
+         if (GDK_IS_X11_DISPLAY(gdkDisplay)) {
+-          return GDK_DISPLAY_XDISPLAY(gdkDisplay);
++            return GDK_DISPLAY_XDISPLAY(gdkDisplay);
+         }
+ #endif /* MOZ_X11 */
++        // Don't bother to return native display on Wayland as it's for
++        // X11 only NPAPI plugins.
+         return nullptr;
+     }
+     case NS_NATIVE_SHELLWIDGET:
+         return GetToplevelWidget();
+ 
+     case NS_NATIVE_SHAREABLE_WINDOW:
+-        return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow));
++        if (mIsX11Display) {
++            return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow));
++        }
++        NS_WARNING("nsWindow::GetNativeData(): NS_NATIVE_SHAREABLE_WINDOW is not handled on Wayland!");
++        return nullptr;
+     case NS_RAW_NATIVE_IME_CONTEXT: {
+         void* pseudoIMEContext = GetPseudoIMEContext();
+         if (pseudoIMEContext) {
+@@ -1800,18 +1811,18 @@ nsWindow::SetIcon(const nsAString& aIcon
+         // The last two entries (for the old XPM format) will be ignored unless
+         // no icons are found using other suffixes. XPM icons are deprecated.
+ 
+-        const char extensions[6][7] = { ".png", "16.png", "32.png", "48.png",
+-                                    ".xpm", "16.xpm" };
++        const char16_t extensions[9][8] = { u".png", u"16.png", u"32.png",
++                                            u"48.png", u"64.png", u"128.png",
++                                            u"256.png",
++                                            u".xpm", u"16.xpm" };
+ 
+         for (uint32_t i = 0; i < ArrayLength(extensions); i++) {
+             // Don't bother looking for XPM versions if we found a PNG.
+             if (i == ArrayLength(extensions) - 2 && foundIcon)
+                 break;
+ 
+-            nsAutoString extension;
+-            extension.AppendASCII(extensions[i]);
+-
+-            ResolveIconName(aIconSpec, extension, getter_AddRefs(iconFile));
++            ResolveIconName(aIconSpec, nsDependentString(extensions[i]),
++                            getter_AddRefs(iconFile));
+             if (iconFile) {
+                 iconFile->GetNativePath(path);
+                 GdkPixbuf *icon = gdk_pixbuf_new_from_file(path.get(), nullptr);
+@@ -2024,30 +2035,6 @@ gdk_window_flash(GdkWindow *    aGdkWind
+ #endif // DEBUG
+ #endif
+ 
+-#if (MOZ_WIDGET_GTK == 2)
+-static bool
+-ExtractExposeRegion(LayoutDeviceIntRegion& aRegion, GdkEventExpose* aEvent)
+-{
+-  GdkRectangle* rects;
+-  gint nrects;
+-  gdk_region_get_rectangles(aEvent->region, &rects, &nrects);
+-
+-  if (nrects > MAX_RECTS_IN_REGION) {
+-      // Just use the bounding box
+-      rects[0] = aEvent->area;
+-      nrects = 1;
+-  }
+-
+-  for (GdkRectangle* r = rects; r < rects + nrects; r++) {
+-      aRegion.Or(aRegion, LayoutDeviceIntRect(r->x, r->y, r->width, r->height));
+-      LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height));
+-  }
+-
+-  g_free(rects);
+-  return true;
+-}
+-
+-#else
+ # ifdef cairo_copy_clip_rectangle_list
+ #  error "Looks like we're including Mozilla's cairo instead of system cairo"
+ # endif
+@@ -2069,15 +2056,9 @@ ExtractExposeRegion(LayoutDeviceIntRegio
+   cairo_rectangle_list_destroy(rects);
+   return true;
+ }
+-#endif
+ 
+-#if (MOZ_WIDGET_GTK == 2)
+-gboolean
+-nsWindow::OnExposeEvent(GdkEventExpose *aEvent)
+-#else
+ gboolean
+ nsWindow::OnExposeEvent(cairo_t *cr)
+-#endif
+ {
+     // Send any pending resize events so that layout can update.
+     // May run event loop.
+@@ -2096,11 +2077,7 @@ nsWindow::OnExposeEvent(cairo_t *cr)
+         return FALSE;
+ 
+     LayoutDeviceIntRegion exposeRegion;
+-#if (MOZ_WIDGET_GTK == 2)
+-    if (!ExtractExposeRegion(exposeRegion, aEvent)) {
+-#else
+     if (!ExtractExposeRegion(exposeRegion, cr)) {
+-#endif
+         return FALSE;
+     }
+ 
+@@ -2141,7 +2118,7 @@ nsWindow::OnExposeEvent(cairo_t *cr)
+ 
+     LOGDRAW(("sending expose event [%p] %p 0x%lx (rects follow):\n",
+              (void *)this, (void *)mGdkWindow,
+-             gdk_x11_window_get_xid(mGdkWindow)));
++             mIsX11Display ? gdk_x11_window_get_xid(mGdkWindow) : 0));
+ 
+     // Our bounds may have changed after calling WillPaintWindow.  Clip
+     // to the new bounds here.  The region is relative to this
+@@ -2304,19 +2281,11 @@ nsWindow::OnExposeEvent(cairo_t *cr)
+     listener->DidPaintWindow();
+ 
+     // Synchronously flush any new dirty areas
+-#if (MOZ_WIDGET_GTK == 2)
+-    GdkRegion* dirtyArea = gdk_window_get_update_area(mGdkWindow);
+-#else
+     cairo_region_t* dirtyArea = gdk_window_get_update_area(mGdkWindow);
+-#endif
+ 
+     if (dirtyArea) {
+         gdk_window_invalidate_region(mGdkWindow, dirtyArea, false);
+-#if (MOZ_WIDGET_GTK == 2)
+-        gdk_region_destroy(dirtyArea);
+-#else
+         cairo_region_destroy(dirtyArea);
+-#endif
+         gdk_window_process_updates(mGdkWindow, false);
+     }
+ 
+@@ -2466,7 +2435,7 @@ nsWindow::OnSizeAllocate(GtkAllocation *
+     mBounds.SizeTo(size);
+ 
+ #ifdef MOZ_X11
+-    // Notify the X11CompositorWidget of a ClientSizeChange
++    // Notify the GtkCompositorWidget of a ClientSizeChange
+     if (mCompositorWidgetDelegate) {
+       mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
+     }
+@@ -3550,21 +3519,9 @@ CreateGdkWindow(GdkWindow *parent, GtkWi
+     attributes.visual = gtk_widget_get_visual(widget);
+     attributes.window_type = GDK_WINDOW_CHILD;
+ 
+-#if (MOZ_WIDGET_GTK == 2)
+-    attributes_mask |= GDK_WA_COLORMAP;
+-    attributes.colormap = gtk_widget_get_colormap(widget);
+-#endif
+-
+     GdkWindow *window = gdk_window_new(parent, &attributes, attributes_mask);
+     gdk_window_set_user_data(window, widget);
+ 
+-// GTK3 TODO?
+-#if (MOZ_WIDGET_GTK == 2)
+-    /* set the default pixmap to None so that you don't end up with the
+-       gtk default which is BlackPixel. */
+-    gdk_window_set_back_pixmap(window, nullptr, FALSE);
+-#endif
+-
+     return window;
+ }
+ 
+@@ -3653,10 +3610,14 @@ nsWindow::Create(nsIWidget* aParent,
+         // which will use a Window with the override-redirect attribute
+         // (for temporary windows).
+         // For long-lived windows, their stacking order is managed by the
+-        // window manager, as indicated by GTK_WINDOW_TOPLEVEL ...
+-        GtkWindowType type =
+-            mWindowType != eWindowType_popup || aInitData->mNoAutoHide ?
+-              GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP;
++        // window manager, as indicated by GTK_WINDOW_TOPLEVEL.
++        // For Wayland we have to always use GTK_WINDOW_POPUP to control
++        // popup window position.
++        GtkWindowType type = GTK_WINDOW_TOPLEVEL;
++        if (mWindowType == eWindowType_popup) {
++            type = (mIsX11Display && aInitData->mNoAutoHide) ?
++                GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP;
++        }
+         mShell = gtk_window_new(type);
+ 
+         bool useAlphaVisual = (mWindowType == eWindowType_popup &&
+@@ -3674,13 +3635,8 @@ nsWindow::Create(nsIWidget* aParent,
+         if (useAlphaVisual) {
+             GdkScreen *screen = gtk_widget_get_screen(mShell);
+             if (gdk_screen_is_composited(screen)) {
+-#if (MOZ_WIDGET_GTK == 2)
+-                GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
+-                gtk_widget_set_colormap(mShell, colormap);
+-#else
+                 GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
+                 gtk_widget_set_visual(mShell, visual);
+-#endif
+             }
+         }
+ 
+@@ -3728,9 +3684,11 @@ nsWindow::Create(nsIWidget* aParent,
+ #ifdef MOZ_X11
+                 // ... but when the window manager offers focus through
+                 // WM_TAKE_FOCUS, focus is requested on the parent window.
+-                gtk_widget_realize(mShell);
+-                gdk_window_add_filter(gtk_widget_get_window(mShell),
+-                                      popup_take_focus_filter, nullptr);
++                if (mIsX11Display) {
++                    gtk_widget_realize(mShell);
++                    gdk_window_add_filter(gtk_widget_get_window(mShell),
++                                          popup_take_focus_filter, nullptr);
++                }
+ #endif
+             }
+ 
+@@ -3742,7 +3700,11 @@ nsWindow::Create(nsIWidget* aParent,
+             else {
+                 switch (aInitData->mPopupHint) {
+                     case ePopupTypeMenu:
+-                        gtkTypeHint = GDK_WINDOW_TYPE_HINT_POPUP_MENU;
++                        // Use GDK_WINDOW_TYPE_HINT_UTILITY on Wayland which
++                        // guides Gtk to create the popup as subsurface
++                        // instead of xdg_shell popup (see Bug 1423598).
++                        gtkTypeHint = mIsX11Display ? GDK_WINDOW_TYPE_HINT_POPUP_MENU :
++                                                      GDK_WINDOW_TYPE_HINT_UTILITY;
+                         break;
+                     case ePopupTypeTooltip:
+                         gtkTypeHint = GDK_WINDOW_TYPE_HINT_TOOLTIP;
+@@ -3769,13 +3731,11 @@ nsWindow::Create(nsIWidget* aParent,
+             gtk_window_group_add_window(group, GTK_WINDOW(mShell));
+             g_object_unref(group);
+ 
+-            if (GetCSDSupportLevel() != CSD_SUPPORT_NONE) {
+-                int32_t isCSDAvailable = false;
+-                nsresult rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDAvailable,
+-                                                &isCSDAvailable);
+-                if (NS_SUCCEEDED(rv)) {
+-                   mIsCSDAvailable = isCSDAvailable;
+-                }
++            int32_t isCSDAvailable = false;
++            nsresult rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDAvailable,
++                                              &isCSDAvailable);
++            if (NS_SUCCEEDED(rv)) {
++               mIsCSDAvailable = isCSDAvailable;
+             }
+         }
+ 
+@@ -3783,7 +3743,6 @@ nsWindow::Create(nsIWidget* aParent,
+         GtkWidget *container = moz_container_new();
+         mContainer = MOZ_CONTAINER(container);
+ 
+-#if (MOZ_WIDGET_GTK == 3)
+         // "csd" style is set when widget is realized so we need to call
+         // it explicitly now.
+         gtk_widget_realize(mShell);
+@@ -3793,16 +3752,22 @@ nsWindow::Create(nsIWidget* aParent,
+          * 1) We're running on Gtk+ without client side decorations.
+          *    Content is rendered to mShell window and we listen
+          *    to the Gtk+ events on mShell
+-         * 2) We're running on Gtk+ > 3.20 and client side decorations
++         * 2) We're running on Gtk+ and client side decorations
+          *    are drawn by Gtk+ to mShell. Content is rendered to mContainer
+          *    and we listen to the Gtk+ events on mContainer.
++         * 3) We're running on Wayland. All gecko content is rendered
++         *    to mContainer and we listen to the Gtk+ events on mContainer.
+          */
+         GtkStyleContext* style = gtk_widget_get_style_context(mShell);
+-        drawToContainer = gtk_style_context_has_class(style, "csd");
+-#endif
++        drawToContainer =
++            !mIsX11Display ||
++            (mIsCSDAvailable && GetCSDSupportLevel() == CSD_SUPPORT_FLAT ) ||
++            gtk_style_context_has_class(style, "csd");
+         eventWidget = (drawToContainer) ? container : mShell;
+ 
+         gtk_widget_add_events(eventWidget, kEvents);
++        if (drawToContainer)
++            gtk_widget_add_events(mShell, GDK_PROPERTY_CHANGE_MASK);
+ 
+         // Prevent GtkWindow from painting a background to avoid flickering.
+         gtk_widget_set_app_paintable(eventWidget, TRUE);
+@@ -3839,19 +3804,11 @@ nsWindow::Create(nsIWidget* aParent,
+ 
+             // 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
+             }
+         }
+     }
+@@ -3893,6 +3850,12 @@ nsWindow::Create(nsIWidget* aParent,
+ 
+     // label the drawing window with this object so we can find our way home
+     g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", this);
++    if (drawToContainer) {
++        // Also label mShell toplevel window,
++        // property_notify_event_cb callback also needs to find its way home
++        g_object_set_data(G_OBJECT(gtk_widget_get_window(mShell)),
++                          "nsWindow", this);
++    }
+ 
+     if (mContainer)
+         g_object_set_data(G_OBJECT(mContainer), "nsWindow", this);
+@@ -3910,12 +3873,12 @@ nsWindow::Create(nsIWidget* aParent,
+                          G_CALLBACK(window_state_event_cb), nullptr);
+         g_signal_connect(mShell, "check-resize",
+                          G_CALLBACK(check_resize_cb), nullptr);
+-
+-        GdkScreen *screen = gtk_widget_get_screen(mShell);
+-
+         g_signal_connect(mShell, "composited-changed",
+                          G_CALLBACK(widget_composited_changed_cb), nullptr);
++        g_signal_connect(mShell, "property-notify-event",
++                         G_CALLBACK(property_notify_event_cb), nullptr);
+ 
++        GdkScreen *screen = gtk_widget_get_screen(mShell);
+         if (!g_signal_handler_find(screen, G_SIGNAL_MATCH_FUNC,
+                                    0, 0, nullptr,
+                                    FuncToGpointer(screen_composited_changed_cb), 0)) {
+@@ -3940,21 +3903,14 @@ nsWindow::Create(nsIWidget* aParent,
+                                G_CALLBACK(size_allocate_cb), nullptr);
+         g_signal_connect(mContainer, "hierarchy-changed",
+                          G_CALLBACK(hierarchy_changed_cb), nullptr);
+-#if (MOZ_WIDGET_GTK == 3)
+         g_signal_connect(mContainer, "notify::scale-factor",
+                          G_CALLBACK(scale_changed_cb), nullptr);
+-#endif
+         // Initialize mHasMappedToplevel.
+         hierarchy_changed_cb(GTK_WIDGET(mContainer), nullptr);
+         // Expose, focus, key, and drag events are sent even to GTK_NO_WINDOW
+         // widgets.
+-#if (MOZ_WIDGET_GTK == 2)
+-        g_signal_connect(mContainer, "expose_event",
+-                         G_CALLBACK(expose_event_cb), nullptr);
+-#else
+         g_signal_connect(G_OBJECT(mContainer), "draw",
+                          G_CALLBACK(expose_event_cb), nullptr);
+-#endif
+         g_signal_connect(mContainer, "focus_in_event",
+                          G_CALLBACK(focus_in_event_cb), nullptr);
+         g_signal_connect(mContainer, "focus_out_event",
+@@ -4006,10 +3962,6 @@ nsWindow::Create(nsIWidget* aParent,
+     }
+ 
+     if (eventWidget) {
+-#if (MOZ_WIDGET_GTK == 2)
+-        // Don't let GTK mess with the shapes of our GdkWindows
+-        GTK_PRIVATE_SET_FLAG(eventWidget, GTK_HAS_SHAPE_MASK);
+-#endif
+ 
+         // These events are sent to the owning widget of the relevant window
+         // and propagate up to the first widget that handles the events, so we
+@@ -4025,8 +3977,6 @@ nsWindow::Create(nsIWidget* aParent,
+                          G_CALLBACK(button_press_event_cb), nullptr);
+         g_signal_connect(eventWidget, "button-release-event",
+                          G_CALLBACK(button_release_event_cb), nullptr);
+-        g_signal_connect(eventWidget, "property-notify-event",
+-                         G_CALLBACK(property_notify_event_cb), nullptr);
+         g_signal_connect(eventWidget, "scroll-event",
+                          G_CALLBACK(scroll_event_cb), nullptr);
+ #if GTK_CHECK_VERSION(3,4,0)
+@@ -4039,7 +3989,7 @@ nsWindow::Create(nsIWidget* aParent,
+     if (mShell) {
+         LOG(("\tmShell %p mContainer %p mGdkWindow %p 0x%lx\n",
+              mShell, mContainer, mGdkWindow,
+-             gdk_x11_window_get_xid(mGdkWindow)));
++             mIsX11Display ? gdk_x11_window_get_xid(mGdkWindow) : 0));
+     } else if (mContainer) {
+         LOG(("\tmContainer %p mGdkWindow %p\n", mContainer, mGdkWindow));
+     }
+@@ -4063,8 +4013,12 @@ nsWindow::Create(nsIWidget* aParent,
  
- if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
-     DEFINES['HAVE_SHELL_SERVICE'] = 1
+       mSurfaceProvider.Initialize(mXDisplay, mXWindow, mXVisual, mXDepth);
+     }
++#ifdef MOZ_WAYLAND
++    else if (!mIsX11Display) {
++      mSurfaceProvider.Initialize(this);
++    }
++#endif
+ #endif
+-
+     return NS_OK;
+ }
+ 
+@@ -4099,7 +4053,8 @@ nsWindow::SetWindowClass(const nsAString
+   res_name[0] = toupper(res_name[0]);
+   if (!role) role = res_name;
+ 
+-  gdk_window_set_role(mGdkWindow, role);
++  GdkWindow* gdkWindow = gtk_widget_get_window(mShell);
++  gdk_window_set_role(gdkWindow, role);
+ 
+ #ifdef MOZ_X11
+   if (mIsX11Display) {
+@@ -4115,7 +4070,7 @@ nsWindow::SetWindowClass(const nsAString
+       // a warning & refuses to make the change.
+       GdkDisplay *display = gdk_display_get_default();
+       XSetClassHint(GDK_DISPLAY_XDISPLAY(display),
+-                    gdk_x11_window_get_xid(mGdkWindow),
++                    gdk_x11_window_get_xid(gdkWindow),
+                     class_hint);
+       XFree(class_hint);
+   }
+@@ -4164,7 +4119,7 @@ nsWindow::NativeResize()
+     }
+ 
+ #ifdef MOZ_X11
+-    // Notify the X11CompositorWidget of a ClientSizeChange
++    // Notify the GtkCompositorWidget of a ClientSizeChange
+     // This is different than OnSizeAllocate to catch initial sizing
+     if (mCompositorWidgetDelegate) {
+       mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
+@@ -4220,7 +4175,7 @@ nsWindow::NativeMoveResize()
+     }
+ 
+ #ifdef MOZ_X11
+-    // Notify the X11CompositorWidget of a ClientSizeChange
++    // Notify the GtkCompositorWidget of a ClientSizeChange
+     // This is different than OnSizeAllocate to catch initial sizing
+     if (mCompositorWidgetDelegate) {
+       mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize());
+@@ -4529,17 +4484,6 @@ nsWindow::SetWindowClipRegion(const nsTA
+     if (!mGdkWindow)
+         return NS_OK;
+ 
+-#if (MOZ_WIDGET_GTK == 2)
+-    GdkRegion *region = gdk_region_new(); // aborts on OOM
+-    for (uint32_t i = 0; i < newRects->Length(); ++i) {
+-        const LayoutDeviceIntRect& r = newRects->ElementAt(i);
+-        GdkRectangle rect = { r.x, r.y, r.width, r.height };
+-        gdk_region_union_with_rect(region, &rect);
+-    }
+-
+-    gdk_window_shape_combine_region(mGdkWindow, region, 0, 0);
+-    gdk_region_destroy(region);
+-#else
+     cairo_region_t *region = cairo_region_create();
+     for (uint32_t i = 0; i < newRects->Length(); ++i) {
+         const LayoutDeviceIntRect& r = newRects->ElementAt(i);
+@@ -4549,7 +4493,6 @@ nsWindow::SetWindowClipRegion(const nsTA
+ 
+     gdk_window_shape_combine_region(mGdkWindow, region, 0, 0);
+     cairo_region_destroy(region);
+-#endif
+ 
+     return NS_OK;
+ }
+@@ -4658,17 +4601,6 @@ nsWindow::ApplyTransparencyBitmap()
+                       maskPixmap, ShapeSet);
+     XFreePixmap(xDisplay, maskPixmap);
+ #else
+-#if (MOZ_WIDGET_GTK == 2)
+-    gtk_widget_reset_shapes(mShell);
+-    GdkBitmap* maskBitmap = gdk_bitmap_create_from_data(mGdkWindow,
+-            mTransparencyBitmap,
+-            mTransparencyBitmapWidth, mTransparencyBitmapHeight);
+-    if (!maskBitmap)
+-        return;
+-
+-    gtk_widget_shape_combine_mask(mShell, maskBitmap, 0, 0);
+-    g_object_unref(maskBitmap);
+-#else
+     cairo_surface_t *maskBitmap;
+     maskBitmap = cairo_image_surface_create_for_data((unsigned char*)mTransparencyBitmap,
+                                                      CAIRO_FORMAT_A1,
+@@ -4682,7 +4614,6 @@ nsWindow::ApplyTransparencyBitmap()
+     gtk_widget_shape_combine_region(mShell, maskRegion);
+     cairo_region_destroy(maskRegion);
+     cairo_surface_destroy(maskBitmap);
+-#endif // MOZ_WIDGET_GTK == 2
+ #endif // MOZ_X11
+ }
+ 
+@@ -4779,6 +4710,12 @@ nsWindow::GrabPointer(guint32 aTime)
+     if (!mGdkWindow)
+         return;
+ 
++    if (!mIsX11Display) {
++        // Don't to the grab on Wayland as it causes a regression
++        // from Bug 1377084.
++        return;
++    }
++
+     gint retval;
+     retval = gdk_pointer_grab(mGdkWindow, TRUE,
+                               (GdkEventMask)(GDK_BUTTON_PRESS_MASK |
+@@ -4812,6 +4749,13 @@ nsWindow::ReleaseGrabs(void)
+     LOG(("ReleaseGrabs\n"));
+ 
+     mRetryPointerGrab = false;
++
++    if (!mIsX11Display) {
++        // Don't to the ungrab on Wayland as it causes a regression
++        // from Bug 1377084.
++        return;
++    }
++
+     gdk_pointer_ungrab(GDK_CURRENT_TIME);
+ }
+ 
+@@ -5058,7 +5002,7 @@ nsWindow::MakeFullScreen(bool aFullScree
+     LOG(("nsWindow::MakeFullScreen [%p] aFullScreen %d\n",
+          (void *)this, aFullScreen));
+ 
+-    if (!IsFullscreenSupported(mShell)) {
++    if (mIsX11Display && !IsFullscreenSupported(mShell)) {
+         return NS_ERROR_NOT_AVAILABLE;
+     }
+ 
+@@ -5080,7 +5024,7 @@ nsWindow::MakeFullScreen(bool aFullScree
+ }
+ 
+ void
+-nsWindow::HideWindowChrome(bool aShouldHide)
++nsWindow::SetWindowDecoration(nsBorderStyle aStyle)
+ {
+     if (!mShell) {
+         // Pass the request to the toplevel window
+@@ -5092,30 +5036,29 @@ nsWindow::HideWindowChrome(bool aShouldH
+         if (!topWindow)
+             return;
+ 
+-        topWindow->HideWindowChrome(aShouldHide);
++        topWindow->SetWindowDecoration(aStyle);
+         return;
+     }
+ 
++    // We can't use mGdkWindow directly here as it can be
++    // derived from mContainer which is not a top-level GdkWindow.
++    GdkWindow *window = gtk_widget_get_window(mShell);
++
+     // Sawfish, metacity, and presumably other window managers get
+     // confused if we change the window decorations while the window
+     // is visible.
+     bool wasVisible = false;
+-    if (gdk_window_is_visible(mGdkWindow)) {
+-        gdk_window_hide(mGdkWindow);
++    if (gdk_window_is_visible(window)) {
++        gdk_window_hide(window);
+         wasVisible = true;
+     }
+ 
+-    gint wmd;
+-    if (aShouldHide)
+-        wmd = 0;
+-    else
+-        wmd = ConvertBorderStyles(mBorderStyle);
+-
++    gint wmd = ConvertBorderStyles(aStyle);
+     if (wmd != -1)
+-      gdk_window_set_decorations(mGdkWindow, (GdkWMDecoration) wmd);
++      gdk_window_set_decorations(window, (GdkWMDecoration) wmd);
+ 
+     if (wasVisible)
+-        gdk_window_show(mGdkWindow);
++        gdk_window_show(window);
+ 
+     // For some window managers, adding or removing window decorations
+     // requires unmapping and remapping our toplevel window.  Go ahead
+@@ -5123,10 +5066,19 @@ nsWindow::HideWindowChrome(bool aShouldH
+     // error later when this happens (when the persistence timer fires
+     // and GetWindowPos is called)
+ #ifdef MOZ_X11
+-    XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) , False);
+-#else
+-    gdk_flush ();
++    if (mIsX11Display) {
++        XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) , False);
++    } else
+ #endif /* MOZ_X11 */
++    {
++        gdk_flush ();
++    }
++}
++
++void
++nsWindow::HideWindowChrome(bool aShouldHide)
++{
++    SetWindowDecoration(aShouldHide ? eBorderStyle_none : mBorderStyle);
+ }
+ 
+ bool
+@@ -5237,12 +5189,8 @@ is_mouse_in_window (GdkWindow* aWindow,
+         window = gdk_window_get_parent(window);
+     }
+ 
+-#if (MOZ_WIDGET_GTK == 2)
+-    gdk_drawable_get_size(aWindow, &w, &h);
+-#else
+     w = gdk_window_get_width(aWindow);
+     h = gdk_window_get_height(aWindow);
+-#endif
+ 
+     if (aMouseX > x && aMouseX < x + w &&
+         aMouseY > y && aMouseY < y + h)
+@@ -5498,18 +5446,6 @@ get_gtk_cursor(nsCursor aCursor)
+ 
+ // gtk callbacks
+ 
+-#if (MOZ_WIDGET_GTK == 2)
+-static gboolean
+-expose_event_cb(GtkWidget *widget, GdkEventExpose *event)
+-{
+-    RefPtr<nsWindow> window = get_window_for_gdk_window(event->window);
+-    if (!window)
+-        return FALSE;
+-
+-    window->OnExposeEvent(event);
+-    return FALSE;
+-}
+-#else
+ void
+ draw_window_of_widget(GtkWidget *widget, GdkWindow *aWindow, cairo_t *cr)
+ {
+@@ -5561,7 +5497,6 @@ expose_event_cb(GtkWidget *widget, cairo
+ 
+     return FALSE;
+ }
+-#endif //MOZ_WIDGET_GTK == 2
+ 
+ static gboolean
+ configure_event_cb(GtkWidget *widget,
+@@ -5980,7 +5915,6 @@ widget_composited_changed_cb (GtkWidget*
+     window->OnCompositedChanged();
+ }
+ 
+-#if (MOZ_WIDGET_GTK == 3)
+ static void
+ scale_changed_cb (GtkWidget* widget, GParamSpec* aPSpec, gpointer aPointer)
+ {
+@@ -5996,7 +5930,6 @@ scale_changed_cb (GtkWidget* widget, GPa
+     gtk_widget_get_allocation(widget, &allocation);
+     window->OnSizeAllocate(&allocation);
+ }
+-#endif
+ 
+ #if GTK_CHECK_VERSION(3,4,0)
+ static gboolean
+@@ -6174,11 +6107,7 @@ get_inner_gdk_window (GdkWindow *aWindow
+          child = g_list_previous(child)) {
+         auto *childWindow = (GdkWindow *) child->data;
+         if (get_window_for_gdk_window(childWindow)) {
+-#if (MOZ_WIDGET_GTK == 2)
+-            gdk_window_get_geometry(childWindow, &cx, &cy, &cw, &ch, nullptr);
+-#else
+             gdk_window_get_geometry(childWindow, &cx, &cy, &cw, &ch);
+-#endif
+             if ((cx < x) && (x < (cx + cw)) &&
+                 (cy < y) && (y < (cy + ch)) &&
+                 gdk_window_is_visible(childWindow)) {
+@@ -6386,53 +6315,6 @@ nsWindow::GetEditCommands(NativeKeyBindi
+     keyBindings->GetEditCommands(aEvent, aCommands);
+ }
  
+-#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
+-/* static */ already_AddRefed<DrawTarget>
+-nsWindow::GetDrawTargetForGdkDrawable(GdkDrawable* aDrawable,
+-                                      const IntSize& aSize)
+-{
+-    GdkVisual* visual = gdk_drawable_get_visual(aDrawable);
+-    Screen* xScreen =
+-        gdk_x11_screen_get_xscreen(gdk_drawable_get_screen(aDrawable));
+-    Display* xDisplay = DisplayOfScreen(xScreen);
+-    Drawable xDrawable = gdk_x11_drawable_get_xid(aDrawable);
+-
+-    RefPtr<gfxASurface> surface;
+-
+-    if (visual) {
+-        Visual* xVisual = gdk_x11_visual_get_xvisual(visual);
+-
+-        surface = new gfxXlibSurface(xDisplay, xDrawable, xVisual, aSize);
+-    } else {
+-        // no visual? we must be using an xrender format.  Find a format
+-        // for this depth.
+-        XRenderPictFormat *pf = nullptr;
+-        switch (gdk_drawable_get_depth(aDrawable)) {
+-            case 32:
+-                pf = XRenderFindStandardFormat(xDisplay, PictStandardARGB32);
+-                break;
+-            case 24:
+-                pf = XRenderFindStandardFormat(xDisplay, PictStandardRGB24);
+-                break;
+-            default:
+-                NS_ERROR("Don't know how to handle the given depth!");
+-                break;
+-        }
+-
+-        surface = new gfxXlibSurface(xScreen, xDrawable, pf, aSize);
+-    }
+-
+-    RefPtr<DrawTarget> dt =
+-        gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, aSize);
+-
+-    if (!dt || !dt->IsValid()) {
+-        return nullptr;
+-    }
+-
+-    return dt.forget();
+-}
+-#endif
+-
+ already_AddRefed<DrawTarget>
+ nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode)
+ {
+@@ -6649,9 +6531,66 @@ nsWindow::SetDrawsInTitlebar(bool aState
+       return;
+ 
+   if (mShell) {
+-      gint wmd = aState ? GDK_DECOR_BORDER : ConvertBorderStyles(mBorderStyle);
+-      gdk_window_set_decorations(gtk_widget_get_window(mShell),
+-                                 (GdkWMDecoration) wmd);
++      if (GetCSDSupportLevel() == CSD_SUPPORT_FULL) {
++          SetWindowDecoration(aState ? eBorderStyle_border : mBorderStyle);
++      }
++      else {
++          /* Window manager does not support GDK_DECOR_BORDER,
++           * emulate it by CSD.
++           *
++           * gtk_window_set_titlebar() works on unrealized widgets only,
++           * we need to handle mShell carefully here.
++           * When CSD is enabled mGdkWindow is owned by mContainer which is good
++           * as we can't delete our mGdkWindow. To make mShell unrealized while
++           * mContainer is preserved we temporary reparent mContainer to an
++           * invisible GtkWindow.
++           */
++          NativeShow(false);
++
++          // Using GTK_WINDOW_POPUP rather than
++          // GTK_WINDOW_TOPLEVEL in the hope that POPUP results in less
++          // initialization and window manager interaction.
++          GtkWidget* tmpWindow = gtk_window_new(GTK_WINDOW_POPUP);
++          gtk_widget_realize(tmpWindow);
++
++          gtk_widget_reparent(GTK_WIDGET(mContainer), tmpWindow);
++          gtk_widget_unrealize(GTK_WIDGET(mShell));
++
++          // Available as of GTK 3.10+
++          static auto sGtkWindowSetTitlebar = (void (*)(GtkWindow*, GtkWidget*))
++              dlsym(RTLD_DEFAULT, "gtk_window_set_titlebar");
++          MOZ_ASSERT(sGtkWindowSetTitlebar,
++              "Missing gtk_window_set_titlebar(), old Gtk+ library?");
++
++          if (aState) {
++              // Add a hidden titlebar widget to trigger CSD, but disable the default
++              // titlebar.  GtkFixed is a somewhat random choice for a simple unused
++              // widget. gtk_window_set_titlebar() takes ownership of the titlebar
++              // widget.
++              sGtkWindowSetTitlebar(GTK_WINDOW(mShell), gtk_fixed_new());
++          } else {
++              sGtkWindowSetTitlebar(GTK_WINDOW(mShell), nullptr);
++          }
++
++          /* A workaround for https://bugzilla.gnome.org/show_bug.cgi?id=791081
++           * gtk_widget_realize() throws:
++           * "In pixman_region32_init_rect: Invalid rectangle passed"
++           * when mShell has default 1x1 size.
++           */
++          GtkAllocation allocation = {0, 0, 0, 0};
++          gtk_widget_get_preferred_width(GTK_WIDGET(mShell), nullptr,
++                                         &allocation.width);
++          gtk_widget_get_preferred_height(GTK_WIDGET(mShell), nullptr,
++                                          &allocation.height);
++          gtk_widget_size_allocate(GTK_WIDGET(mShell), &allocation);
++
++          gtk_widget_realize(GTK_WIDGET(mShell));
++          gtk_widget_reparent(GTK_WIDGET(mContainer), GTK_WIDGET(mShell));
++          mNeedsShow = true;
++          NativeResize();
++
++          gtk_widget_destroy(tmpWindow);
++      }
+   }
+ 
+   mIsCSDEnabled = aState;
+@@ -6762,11 +6701,9 @@ nsWindow::SynthesizeNativeMouseEvent(Lay
+     event.button.window = mGdkWindow;
+     event.button.time = GDK_CURRENT_TIME;
+ 
+-#if (MOZ_WIDGET_GTK == 3)
+     // Get device for event source
+     GdkDeviceManager *device_manager = gdk_display_get_device_manager(display);
+     event.button.device = gdk_device_manager_get_client_pointer(device_manager);
+-#endif
+ 
+     event.button.x_root = DevicePixelsToGdkCoordRoundDown(aPoint.x);
+     event.button.y_root = DevicePixelsToGdkCoordRoundDown(aPoint.y);
+@@ -6809,12 +6746,10 @@ nsWindow::SynthesizeNativeMouseScrollEve
+   event.type = GDK_SCROLL;
+   event.scroll.window = mGdkWindow;
+   event.scroll.time = GDK_CURRENT_TIME;
+-#if (MOZ_WIDGET_GTK == 3)
+   // Get device for event source
+   GdkDisplay* display = gdk_window_get_display(mGdkWindow);
+   GdkDeviceManager *device_manager = gdk_display_get_device_manager(display);
+   event.scroll.device = gdk_device_manager_get_client_pointer(device_manager);
+-#endif
+   event.scroll.x_root = DevicePixelsToGdkCoordRoundDown(aPoint.x);
+   event.scroll.y_root = DevicePixelsToGdkCoordRoundDown(aPoint.y);
+ 
+@@ -6938,27 +6873,54 @@ nsWindow::GetCSDSupportLevel() {
+     if (sCSDSupportLevel != CSD_SUPPORT_UNKNOWN) {
+         return sCSDSupportLevel;
+     }
+-    // TODO: MATE
++
+     const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP");
+     if (currentDesktop) {
+-        if (strcmp(currentDesktop, "GNOME") == 0) {
+-            sCSDSupportLevel = CSD_SUPPORT_FULL;
+-        } else if (strcmp(currentDesktop, "XFCE") == 0) {
++        if (strstr(currentDesktop, "GNOME") != nullptr) {
+             sCSDSupportLevel = CSD_SUPPORT_FULL;
+-        } else if (strcmp(currentDesktop, "X-Cinnamon") == 0) {
++        } else if (strstr(currentDesktop, "XFCE") != nullptr) {
++            sCSDSupportLevel = CSD_SUPPORT_FLAT;
++        } else if (strstr(currentDesktop, "X-Cinnamon") != nullptr) {
+             sCSDSupportLevel = CSD_SUPPORT_FULL;
+-        } else if (strcmp(currentDesktop, "KDE") == 0) {
++        } else if (strstr(currentDesktop, "KDE") != nullptr) {
+             sCSDSupportLevel = CSD_SUPPORT_FLAT;
+-        } else if (strcmp(currentDesktop, "LXDE") == 0) {
++        } else if (strstr(currentDesktop, "LXDE") != nullptr) {
+             sCSDSupportLevel = CSD_SUPPORT_FLAT;
+-        } else if (strcmp(currentDesktop, "openbox") == 0) {
++        } else if (strstr(currentDesktop, "openbox") != nullptr) {
+             sCSDSupportLevel = CSD_SUPPORT_FLAT;
+-        } else if (strcmp(currentDesktop, "i3") == 0) {
++        } else if (strstr(currentDesktop, "i3") != nullptr) {
+             sCSDSupportLevel = CSD_SUPPORT_NONE;
++        } else if (strstr(currentDesktop, "MATE") != nullptr) {
++            sCSDSupportLevel = CSD_SUPPORT_FLAT;
++        } else if (strstr(currentDesktop, "Unity") != nullptr) {
++            sCSDSupportLevel = CSD_SUPPORT_FLAT;
++        } else if (strstr(currentDesktop, "Pantheon") != nullptr) {
++            sCSDSupportLevel = CSD_SUPPORT_FULL;
+         } else {
++            sCSDSupportLevel = CSD_SUPPORT_FLAT;
++        }
++    } else {
++        sCSDSupportLevel = CSD_SUPPORT_NONE;
++    }
++
++    // We don't support CSD_SUPPORT_FULL on Wayland
++    if (!GDK_IS_X11_DISPLAY(gdk_display_get_default()) &&
++        sCSDSupportLevel == CSD_SUPPORT_FULL) {
++        sCSDSupportLevel = CSD_SUPPORT_FLAT;
++    }
++
++    // Allow MOZ_GTK_TITLEBAR_DECORATION to override our heuristics
++    const char* decorationOverride = getenv("MOZ_GTK_TITLEBAR_DECORATION");
++    if (decorationOverride) {
++        if (strcmp(decorationOverride, "none") == 0) {
+             sCSDSupportLevel = CSD_SUPPORT_NONE;
++        } else if (strcmp(decorationOverride, "client") == 0) {
++            sCSDSupportLevel = CSD_SUPPORT_FLAT;
++        } else if (strcmp(decorationOverride, "system") == 0) {
++            sCSDSupportLevel = CSD_SUPPORT_FULL;
+         }
+     }
++
+     return sCSDSupportLevel;
+ }
+ 
+@@ -6991,3 +6953,24 @@ nsWindow::IsComposited() const
+          (gdk_window_get_visual(mGdkWindow)
+             == gdk_screen_get_rgba_visual(gdkScreen));
+ }
++
++#ifdef MOZ_WAYLAND
++wl_display*
++nsWindow::GetWaylandDisplay()
++{
++  // Available as of GTK 3.8+
++  static auto sGdkWaylandDisplayGetWlDisplay =
++      (wl_display *(*)(GdkDisplay *))
++      dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display");
++
++  GdkDisplay* gdkDisplay = gdk_display_get_default();
++  return mIsX11Display ? nullptr :
++                         sGdkWaylandDisplayGetWlDisplay(gdkDisplay);
++}
++
++wl_surface*
++nsWindow::GetWaylandSurface()
++{
++  return moz_container_get_wl_surface(MOZ_CONTAINER(mContainer));
++}
++#endif
+diff -up firefox-58.0/widget/gtk/nsWindow.h.1399611 firefox-58.0/widget/gtk/nsWindow.h
+--- firefox-58.0/widget/gtk/nsWindow.h.1399611	2018-01-11 21:17:06.000000000 +0100
++++ firefox-58.0/widget/gtk/nsWindow.h	2018-01-24 10:57:03.720031943 +0100
+@@ -23,7 +23,11 @@
+ 
+ #ifdef MOZ_X11
+ #include <gdk/gdkx.h>
++#include "X11UndefineNone.h"
+ #endif /* MOZ_X11 */
++#ifdef MOZ_WAYLAND
++#include <gdk/gdkwayland.h>
++#endif
+ 
+ #include "mozilla/widget/WindowSurface.h"
+ #include "mozilla/widget/WindowSurfaceProvider.h"
+@@ -172,11 +176,7 @@ public:
+     GdkRectangle DevicePixelsToGdkRectRoundOut(LayoutDeviceIntRect aRect);
+ 
+     // event callbacks
+-#if (MOZ_WIDGET_GTK == 2)
+-    gboolean           OnExposeEvent(GdkEventExpose *aEvent);
+-#else
+     gboolean           OnExposeEvent(cairo_t *cr);
+-#endif
+     gboolean           OnConfigureEvent(GtkWidget *aWidget,
+                                         GdkEventConfigure *aEvent);
+     void               OnContainerUnrealize();
+@@ -315,10 +315,6 @@ public:
+    nsresult            UpdateTranslucentWindowAlphaInternal(const nsIntRect& aRect,
+                                                             uint8_t* aAlphas, int32_t aStride);
+ 
+-#if (MOZ_WIDGET_GTK == 2)
+-    static already_AddRefed<DrawTarget> GetDrawTargetForGdkDrawable(GdkDrawable* aDrawable,
+-                                                                    const mozilla::gfx::IntSize& aSize);
+-#endif
+     virtual void       ReparentNativeWidget(nsIWidget* aNewParent) override;
+ 
+     virtual nsresult SynthesizeNativeMouseEvent(LayoutDeviceIntPoint aPoint,
+@@ -348,9 +344,14 @@ public:
+                                                 nsIObserver* aObserver) override;
+ #endif
+ 
++
+ #ifdef MOZ_X11
+     Display* XDisplay() { return mXDisplay; }
+ #endif
++#ifdef MOZ_WAYLAND
++    wl_display* GetWaylandDisplay();
++    wl_surface* GetWaylandSurface();
++#endif
+     virtual void GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData) override;
+ 
+     virtual nsresult SetNonClientMargins(LayoutDeviceIntMargin& aMargins) override;
+@@ -374,6 +375,18 @@ public:
+     virtual bool WidgetTypeSupportsAcceleration() override;
+ 
+     bool DoDrawTitlebar() const;
++
++    typedef enum { CSD_SUPPORT_FULL,    // CSD including shadows
++                   CSD_SUPPORT_FLAT,    // CSD without shadows
++                   CSD_SUPPORT_NONE,    // WM does not support CSD at all
++                   CSD_SUPPORT_UNKNOWN
++    } CSDSupportLevel;
++    /**
++     * Get the support of Client Side Decoration by checking
++     * the XDG_CURRENT_DESKTOP environment variable.
++     */
++    static CSDSupportLevel GetCSDSupportLevel();
++
+ protected:
+     virtual ~nsWindow();
+ 
+@@ -423,6 +436,7 @@ private:
+     nsWindow          *GetContainerWindow();
+     void               SetUrgencyHint(GtkWidget *top_window, bool state);
+     void               SetDefaultIcon(void);
++    void               SetWindowDecoration(nsBorderStyle aStyle);
+     void               InitButtonEvent(mozilla::WidgetMouseEvent& aEvent,
+                                        GdkEventButton* aGdkEvent);
+     bool               DispatchCommandEvent(nsAtom* aCommand);
+@@ -441,7 +455,6 @@ private:
+     nsIWidgetListener* GetListener();
+     bool               IsComposited() const;
+ 
+-
+     GtkWidget          *mShell;
+     MozContainer       *mContainer;
+     GdkWindow          *mGdkWindow;
+@@ -578,16 +591,6 @@ private:
+     RefPtr<mozilla::widget::IMContextWrapper> mIMContext;
+ 
+     mozilla::UniquePtr<mozilla::CurrentX11TimeGetter> mCurrentTimeGetter;
+-    typedef enum { CSD_SUPPORT_FULL,    // CSD including shadows
+-                   CSD_SUPPORT_FLAT,    // CSD without shadows
+-                   CSD_SUPPORT_NONE,    // WM does not support CSD at all
+-                   CSD_SUPPORT_UNKNOWN
+-    } CSDSupportLevel;
+-    /**
+-     * Get the support of Client Side Decoration by checking
+-     * the XDG_CURRENT_DESKTOP environment variable.
+-     */
+-    static CSDSupportLevel GetCSDSupportLevel();
+     static CSDSupportLevel sCSDSupportLevel;
+ };
+ 
--- a/series	Tue Jan 23 22:05:20 2018 +0100
+++ b/series	Wed Jan 24 17:02:23 2018 +0100
@@ -8,6 +8,7 @@
 mozilla-reduce-files-per-UnifiedBindings.patch
 mozilla-aarch64-startup-crash.patch
 mozilla-enable-csd.patch
+mozilla-bmo256180.patch
 
 # Firefox patches
 firefox-kde.patch