# HG changeset patch # User Wolfgang Rosenauer # Date 1516809743 -3600 # Node ID 7071f6ebfda6cae7b789f84fbd16262b7397c927 # Parent 963c89cda54b5375d6000b12678cabcb5454eee2 CSD functionality diff -r 963c89cda54b -r 7071f6ebfda6 MozillaFirefox/MozillaFirefox.changes --- 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) diff -r 963c89cda54b -r 7071f6ebfda6 MozillaFirefox/MozillaFirefox.spec --- 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 diff -r 963c89cda54b -r 7071f6ebfda6 MozillaFirefox/mozilla-bmo256180.patch --- /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 diff -r 963c89cda54b -r 7071f6ebfda6 MozillaFirefox/mozilla-enable-csd.patch --- /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 diff -r 963c89cda54b -r 7071f6ebfda6 mozilla-bmo256180.patch --- /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 diff -r 963c89cda54b -r 7071f6ebfda6 mozilla-enable-csd.patch --- 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 -# 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 + +@@ -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 + #include ++#include + + #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 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 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 +-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 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 dt = +- gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, aSize); +- +- if (!dt || !dt->IsValid()) { +- return nullptr; +- } +- +- return dt.forget(); +-} +-#endif +- + already_AddRefed + 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 ++#include "X11UndefineNone.h" + #endif /* MOZ_X11 */ ++#ifdef MOZ_WAYLAND ++#include ++#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 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 mIMContext; + + mozilla::UniquePtr 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; + }; + diff -r 963c89cda54b -r 7071f6ebfda6 series --- 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