forked from pool/MozillaFirefox
dd53ed18ec
MFSA 2018-05 * Arbitrary code execution through unsanitized browser UI (bmo#1432966) - fixed language packs (boo#1077590) - readd mozilla-enable-csd.patch as it only lands for FF59 upstream - allow larger number of nested elements (mozilla-bmo256180.patch) OBS-URL: https://build.opensuse.org/package/show/mozilla:Factory/MozillaFirefox?expand=0&rev=630
1313 lines
50 KiB
Diff
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;
|
|
};
|
|
|