firefox/mozilla-1399611.patch

1313 lines
50 KiB
Diff

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
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa', 'gtk3'):
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
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;
}
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
},
+ {
+ &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
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa', 'gtk3'):
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
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,
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;
};