diff --git a/.gitignore b/.gitignore index 90801e6..f2a8d9c 100644 --- a/.gitignore +++ b/.gitignore @@ -254,3 +254,6 @@ thunderbird-langpacks-3.1.2-20100803.tar.bz2 /thunderbird-60.8.0.source.tar.xz /thunderbird-langpacks-60.8.0-20190704.tar.xz /lightning-langpacks-60.8.0.tar.xz +/thunderbird-68.0.source.tar.xz +/thunderbird-langpacks-68.0-20190829.tar.xz +/lightning-langpacks-68.0.tar.xz diff --git a/build-aarch64-skia.patch b/build-aarch64-skia.patch deleted file mode 100644 index b23296e..0000000 --- a/build-aarch64-skia.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -up thunderbird-60.0/gfx/skia/skia/src/jumper/SkJumper_stages.cpp.aarch64-skia thunderbird-60.0/gfx/skia/skia/src/jumper/SkJumper_stages.cpp ---- thunderbird-60.0/gfx/skia/skia/src/jumper/SkJumper_stages.cpp.aarch64-skia 2018-08-28 14:36:13.555012053 +0200 -+++ thunderbird-60.0/gfx/skia/skia/src/jumper/SkJumper_stages.cpp 2018-08-28 14:38:17.160274150 +0200 -@@ -666,7 +666,7 @@ SI F approx_powf(F x, F y) { - } - - SI F from_half(U16 h) { --#if defined(JUMPER_IS_NEON) && defined(__aarch64__) && !defined(SK_BUILD_FOR_GOOGLE3) // Temporary workaround for some Google3 builds. -+#if 0 && defined(JUMPER_IS_NEON) && defined(__aarch64__) && !defined(SK_BUILD_FOR_GOOGLE3) // Temporary workaround for some Google3 builds. - return vcvt_f32_f16(h); - - #elif defined(JUMPER_IS_HSW) || defined(JUMPER_IS_AVX512) -@@ -686,7 +686,7 @@ SI F from_half(U16 h) { - } - - SI U16 to_half(F f) { --#if defined(JUMPER_IS_NEON) && defined(__aarch64__) && !defined(SK_BUILD_FOR_GOOGLE3) // Temporary workaround for some Google3 builds. -+#if 0 && defined(JUMPER_IS_NEON) && defined(__aarch64__) && !defined(SK_BUILD_FOR_GOOGLE3) // Temporary workaround for some Google3 builds. - return vcvt_f16_f32(f); - - #elif defined(JUMPER_IS_HSW) || defined(JUMPER_IS_AVX512) diff --git a/build-disable-elfhack.patch b/build-disable-elfhack.patch index 11e6a54..0856e5c 100644 --- a/build-disable-elfhack.patch +++ b/build-disable-elfhack.patch @@ -1,12 +1,12 @@ -diff -up firefox-62.0.2/toolkit/moz.configure.elfhack firefox-62.0.2/toolkit/moz.configure ---- firefox-62.0.2/toolkit/moz.configure.elfhack 2018-09-27 14:32:56.549507561 +0200 -+++ firefox-62.0.2/toolkit/moz.configure 2018-09-27 14:33:08.219532121 +0200 -@@ -1195,7 +1195,7 @@ with only_when(has_elfhack): - option('--disable-elf-hack', help='Disable elf hacks') +diff -up thunderbird-68.0/toolkit/moz.configure.elfhack thunderbird-68.0/toolkit/moz.configure +--- thunderbird-68.0/toolkit/moz.configure.elfhack 2019-08-29 16:33:28.491708653 +0200 ++++ thunderbird-68.0/toolkit/moz.configure 2019-08-29 16:33:58.019805525 +0200 +@@ -1130,7 +1130,7 @@ with only_when('--enable-compile-environ + help='{Enable|Disable} elf hacks') - set_config('USE_ELF_HACK', -- depends_if('--enable-elf-hack')(lambda _: True)) -+ depends_if('--enable-elf-hack')(lambda _: False)) + set_config('USE_ELF_HACK', +- depends_if('--enable-elf-hack')(lambda _: True)) ++ depends_if('--enable-elf-hack')(lambda _: False)) @depends(check_build_environment) diff --git a/build-jit-atomic-always-lucky.patch b/build-jit-atomic-always-lucky.patch deleted file mode 100644 index ab99524..0000000 --- a/build-jit-atomic-always-lucky.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up firefox-60.5.0/js/src/jit/AtomicOperations.h.jit-atomic-lucky firefox-60.5.0/js/src/jit/AtomicOperations.h ---- firefox-60.5.0/js/src/jit/AtomicOperations.h.jit-atomic-lucky 2019-01-22 10:20:27.993697161 +0100 -+++ firefox-60.5.0/js/src/jit/AtomicOperations.h 2019-01-22 10:23:15.337873762 +0100 -@@ -394,7 +394,7 @@ inline bool AtomicOperations::isLockfree - #elif defined(__s390__) || defined(__s390x__) - #include "jit/none/AtomicOperations-feeling-lucky.h" - #else --#error "No AtomicOperations support provided for this platform" -+#include "jit/none/AtomicOperations-feeling-lucky.h" - #endif - - #endif // jit_AtomicOperations_h diff --git a/firefox-SIOCGSTAMP.patch b/firefox-SIOCGSTAMP.patch new file mode 100644 index 0000000..673cb07 --- /dev/null +++ b/firefox-SIOCGSTAMP.patch @@ -0,0 +1,16 @@ +diff -up firefox-68.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium.old firefox-68.0/media/libyuv/libyuv/tools_libyuv/autoroller/unittests/testdata/DEPS.chromium +diff -up firefox-68.0/media/webrtc/trunk/Makefile.old firefox-68.0/media/webrtc/trunk/Makefile +diff -up firefox-68.0/media/webrtc/trunk/webrtc/rtc_base/physicalsocketserver.cc.old firefox-68.0/media/webrtc/trunk/webrtc/rtc_base/physicalsocketserver.cc +--- firefox-68.0/media/webrtc/trunk/webrtc/rtc_base/physicalsocketserver.cc.old 2019-07-10 20:10:04.420328534 +0200 ++++ firefox-68.0/media/webrtc/trunk/webrtc/rtc_base/physicalsocketserver.cc 2019-07-10 20:13:48.766658793 +0200 +@@ -62,6 +62,10 @@ typedef void* SockOptArg; + + #if defined(WEBRTC_POSIX) && !defined(WEBRTC_MAC) && !defined(WEBRTC_BSD) && !defined(__native_client__) + ++#ifndef SIOCGSTAMP ++#define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ ++#endif ++ + int64_t GetSocketRecvTimestamp(int socket) { + struct timeval tv_ioctl; + int ret = ioctl(socket, SIOCGSTAMP, &tv_ioctl); diff --git a/firefox-wayland.patch b/firefox-wayland.patch deleted file mode 100644 index ec42d9f..0000000 --- a/firefox-wayland.patch +++ /dev/null @@ -1,4441 +0,0 @@ -diff -up thunderbird-60.5.0/widget/gtk/GtkCompositorWidget.cpp.wayland thunderbird-60.5.0/widget/gtk/GtkCompositorWidget.cpp ---- thunderbird-60.5.0/widget/gtk/GtkCompositorWidget.cpp.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/GtkCompositorWidget.cpp 2019-02-05 14:26:16.973316654 +0100 -@@ -38,7 +38,9 @@ GtkCompositorWidget::GtkCompositorWidget - - // Grab the window's visual and depth - XWindowAttributes windowAttrs; -- XGetWindowAttributes(mXDisplay, mXWindow, &windowAttrs); -+ if (!XGetWindowAttributes(mXDisplay, mXWindow, &windowAttrs)) { -+ NS_WARNING("GtkCompositorWidget(): XGetWindowAttributes() failed!"); -+ } - - Visual* visual = windowAttrs.visual; - int depth = windowAttrs.depth; -diff -up thunderbird-60.5.0/widget/gtk/moz.build.wayland thunderbird-60.5.0/widget/gtk/moz.build ---- thunderbird-60.5.0/widget/gtk/moz.build.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/moz.build 2019-02-05 14:26:16.974316651 +0100 -@@ -99,6 +99,7 @@ if CONFIG['MOZ_X11']: - if CONFIG['MOZ_WAYLAND']: - UNIFIED_SOURCES += [ - 'nsClipboardWayland.cpp', -+ 'nsWaylandDisplay.cpp', - 'WindowSurfaceWayland.cpp', - ] - -@@ -123,6 +124,7 @@ include('/ipc/chromium/chromium-config.m - FINAL_LIBRARY = 'xul' - - LOCAL_INCLUDES += [ -+ '/layout/base', - '/layout/generic', - '/layout/xul', - '/other-licenses/atk-1.0', -diff -up thunderbird-60.5.0/widget/gtk/mozcontainer.cpp.wayland thunderbird-60.5.0/widget/gtk/mozcontainer.cpp ---- thunderbird-60.5.0/widget/gtk/mozcontainer.cpp.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/mozcontainer.cpp 2019-02-05 15:09:24.116970135 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -7,9 +7,10 @@ - - #include "mozcontainer.h" - #include --#ifdef MOZ_WAYLAND - #include --#include -+#ifdef MOZ_WAYLAND -+#include "nsWaylandDisplay.h" -+#include - #endif - #include - #include -@@ -19,12 +20,20 @@ - #include "maiRedundantObjectFactory.h" - #endif - -+#ifdef MOZ_WAYLAND -+using namespace mozilla; -+using namespace mozilla::widget; -+#endif -+ - /* init methods */ - static void moz_container_class_init(MozContainerClass *klass); - static void moz_container_init(MozContainer *container); - - /* widget class methods */ - static void moz_container_map(GtkWidget *widget); -+#if defined(MOZ_WAYLAND) -+static gboolean moz_container_map_wayland(GtkWidget *widget, GdkEventAny *event); -+#endif - static void moz_container_unmap(GtkWidget *widget); - static void moz_container_realize(GtkWidget *widget); - static void moz_container_size_allocate(GtkWidget *widget, -@@ -114,29 +123,6 @@ void moz_container_put(MozContainer *con - gtk_widget_set_parent(child_widget, GTK_WIDGET(container)); - } - --void moz_container_move(MozContainer *container, GtkWidget *child_widget, -- gint x, gint y, gint width, gint height) { -- MozContainerChild *child; -- GtkAllocation new_allocation; -- -- child = moz_container_get_child(container, child_widget); -- -- child->x = x; -- child->y = y; -- -- new_allocation.x = x; -- new_allocation.y = y; -- new_allocation.width = width; -- new_allocation.height = height; -- -- /* printf("moz_container_move %p %p will allocate to %d %d %d %d\n", -- (void *)container, (void *)child_widget, -- new_allocation.x, new_allocation.y, -- new_allocation.width, new_allocation.height); */ -- -- gtk_widget_size_allocate(child_widget, &new_allocation); --} -- - /* static methods */ - - void moz_container_class_init(MozContainerClass *klass) { -@@ -146,6 +132,11 @@ void moz_container_class_init(MozContain - GtkWidgetClass *widget_class = GTK_WIDGET_CLASS(klass); - - widget_class->map = moz_container_map; -+#if defined(MOZ_WAYLAND) -+ if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) { -+ widget_class->map_event = moz_container_map_wayland; -+ } -+#endif - widget_class->unmap = moz_container_unmap; - widget_class->realize = moz_container_realize; - widget_class->size_allocate = moz_container_size_allocate; -@@ -155,109 +146,81 @@ void moz_container_class_init(MozContain - container_class->add = moz_container_add; - } - --#if defined(MOZ_WAYLAND) --static void registry_handle_global(void *data, struct wl_registry *registry, -- uint32_t name, const char *interface, -- uint32_t version) { -- MozContainer *container = MOZ_CONTAINER(data); -- if (strcmp(interface, "wl_subcompositor") == 0) { -- container->subcompositor = static_cast( -- wl_registry_bind(registry, name, &wl_subcompositor_interface, 1)); -- } --} -- --static void registry_handle_global_remove(void *data, -- struct wl_registry *registry, -- uint32_t name) {} -- --static const struct wl_registry_listener registry_listener = { -- registry_handle_global, registry_handle_global_remove}; --#endif -- - void moz_container_init(MozContainer *container) { - gtk_widget_set_can_focus(GTK_WIDGET(container), TRUE); - gtk_container_set_resize_mode(GTK_CONTAINER(container), GTK_RESIZE_IMMEDIATE); - gtk_widget_set_redraw_on_allocate(GTK_WIDGET(container), FALSE); - - #if defined(MOZ_WAYLAND) -- { -- GdkDisplay *gdk_display = gtk_widget_get_display(GTK_WIDGET(container)); -- if (GDK_IS_WAYLAND_DISPLAY(gdk_display)) { -- // Available as of GTK 3.8+ -- static auto sGdkWaylandDisplayGetWlDisplay = -- (wl_display * (*)(GdkDisplay *)) -- dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display"); -- -- wl_display *display = sGdkWaylandDisplayGetWlDisplay(gdk_display); -- wl_registry *registry = wl_display_get_registry(display); -- wl_registry_add_listener(registry, ®istry_listener, container); -- wl_display_dispatch(display); -- wl_display_roundtrip(display); -- } -- } -+ container->surface = nullptr; -+ container->subsurface = nullptr; -+ container->eglwindow = nullptr; -+ container->frame_callback_handler = nullptr; -+ // We can draw to x11 window any time. -+ container->ready_to_draw = GDK_IS_X11_DISPLAY(gdk_display_get_default()); -+ container->surface_needs_clear = true; - #endif - } - - #if defined(MOZ_WAYLAND) --/* We want to draw to GdkWindow owned by mContainer from Compositor thread but -- * Gtk+ can be used in main thread only. So we create wayland wl_surface -- * and attach it as an overlay to GdkWindow. -- * -- * see gtk_clutter_embed_ensure_subsurface() at gtk-clutter-embed.c -- * for reference. -- */ --static gboolean moz_container_map_surface(MozContainer *container) { -- // Available as of GTK 3.8+ -- static auto sGdkWaylandDisplayGetWlCompositor = -- (wl_compositor * (*)(GdkDisplay *)) -- dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_compositor"); -+static wl_surface *moz_container_get_gtk_container_surface( -+ MozContainer *container) { - static auto sGdkWaylandWindowGetWlSurface = (wl_surface * (*)(GdkWindow *)) - dlsym(RTLD_DEFAULT, "gdk_wayland_window_get_wl_surface"); - -- GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container)); -- if (GDK_IS_X11_DISPLAY(display)) return false; -+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container)); -+ return sGdkWaylandWindowGetWlSurface(window); -+} - -- if (container->subsurface && container->surface) return true; -+static void frame_callback_handler(void *data, struct wl_callback *callback, -+ uint32_t time) { -+ MozContainer *container = MOZ_CONTAINER(data); -+ g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy); -+ container->ready_to_draw = true; -+} - -- if (!container->surface) { -- struct wl_compositor *compositor; -- compositor = sGdkWaylandDisplayGetWlCompositor(display); -- container->surface = wl_compositor_create_surface(compositor); -- } -+static const struct wl_callback_listener frame_listener = { -+ frame_callback_handler}; - -- if (!container->subsurface) { -- GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container)); -- wl_surface *gtk_surface = sGdkWaylandWindowGetWlSurface(window); -- if (!gtk_surface) { -- // We requested the underlying wl_surface too early when container -- // is not realized yet. We'll try again before first rendering -- // to mContainer. -- return false; -- } -+static gboolean moz_container_map_wayland(GtkWidget *widget, GdkEventAny *event) { -+ MozContainer* container = MOZ_CONTAINER(widget); - -- container->subsurface = wl_subcompositor_get_subsurface( -- container->subcompositor, container->surface, gtk_surface); -- gint x, y; -- gdk_window_get_position(window, &x, &y); -- wl_subsurface_set_position(container->subsurface, x, y); -- wl_subsurface_set_desync(container->subsurface); -+ if (container->ready_to_draw || container->frame_callback_handler) { -+ return FALSE; -+ } - -- // Route input to parent wl_surface owned by Gtk+ so we get input -- // events from Gtk+. -- GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container)); -- wl_compositor *compositor = sGdkWaylandDisplayGetWlCompositor(display); -- wl_region *region = wl_compositor_create_region(compositor); -- wl_surface_set_input_region(container->surface, region); -- wl_region_destroy(region); -+ wl_surface *gtk_container_surface = -+ moz_container_get_gtk_container_surface(container); -+ -+ if (gtk_container_surface) { -+ container->frame_callback_handler = wl_surface_frame(gtk_container_surface); -+ wl_callback_add_listener(container->frame_callback_handler, &frame_listener, -+ container); - } -- return true; -+ -+ return FALSE; - } - --static void moz_container_unmap_surface(MozContainer *container) { -+static void moz_container_unmap_wayland(MozContainer *container) { - g_clear_pointer(&container->subsurface, wl_subsurface_destroy); - g_clear_pointer(&container->surface, wl_surface_destroy); -+ g_clear_pointer(&container->frame_callback_handler, wl_callback_destroy); -+ -+ container->surface_needs_clear = true; -+ container->ready_to_draw = false; - } - -+static gint moz_container_get_scale(MozContainer *container) { -+ static auto sGdkWindowGetScaleFactorPtr = (gint(*)(GdkWindow *))dlsym( -+ RTLD_DEFAULT, "gdk_window_get_scale_factor"); -+ -+ if (sGdkWindowGetScaleFactorPtr) { -+ GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container)); -+ return (*sGdkWindowGetScaleFactorPtr)(window); -+ } -+ -+ return 1; -+} - #endif - - void moz_container_map(GtkWidget *widget) { -@@ -283,7 +246,9 @@ void moz_container_map(GtkWidget *widget - if (gtk_widget_get_has_window(widget)) { - gdk_window_show(gtk_widget_get_window(widget)); - #if defined(MOZ_WAYLAND) -- moz_container_map_surface(MOZ_CONTAINER(widget)); -+ if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) { -+ moz_container_map_wayland(widget, nullptr); -+ } - #endif - } - } -@@ -296,7 +261,9 @@ void moz_container_unmap(GtkWidget *widg - if (gtk_widget_get_has_window(widget)) { - gdk_window_hide(gtk_widget_get_window(widget)); - #if defined(MOZ_WAYLAND) -- moz_container_unmap_surface(MOZ_CONTAINER(widget)); -+ if (!GDK_IS_X11_DISPLAY(gdk_display_get_default())) { -+ moz_container_unmap_wayland(MOZ_CONTAINER(widget)); -+ } - #endif - } - } -@@ -485,13 +452,62 @@ static void moz_container_add(GtkContain - - #ifdef MOZ_WAYLAND - struct wl_surface *moz_container_get_wl_surface(MozContainer *container) { -- if (!container->subsurface || !container->surface) { -+ if (!container->surface) { -+ if (!container->ready_to_draw) { -+ return nullptr; -+ } -+ GdkDisplay *display = gtk_widget_get_display(GTK_WIDGET(container)); -+ -+ // Available as of GTK 3.8+ -+ static auto sGdkWaylandDisplayGetWlCompositor = -+ (wl_compositor * (*)(GdkDisplay *)) -+ dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_compositor"); -+ struct wl_compositor *compositor = -+ sGdkWaylandDisplayGetWlCompositor(display); -+ container->surface = wl_compositor_create_surface(compositor); -+ -+ nsWaylandDisplay *waylandDisplay = WaylandDisplayGet(display); -+ container->subsurface = wl_subcompositor_get_subsurface( -+ waylandDisplay->GetSubcompositor(), container->surface, -+ moz_container_get_gtk_container_surface(container)); -+ WaylandDisplayRelease(waylandDisplay); -+ - GdkWindow *window = gtk_widget_get_window(GTK_WIDGET(container)); -- if (!gdk_window_is_visible(window)) return nullptr; -+ gint x, y; -+ gdk_window_get_position(window, &x, &y); -+ wl_subsurface_set_position(container->subsurface, x, y); -+ wl_subsurface_set_desync(container->subsurface); - -- moz_container_map_surface(container); -+ // Route input to parent wl_surface owned by Gtk+ so we get input -+ // events from Gtk+. -+ wl_region *region = wl_compositor_create_region(compositor); -+ wl_surface_set_input_region(container->surface, region); -+ wl_region_destroy(region); -+ -+ wl_surface_set_buffer_scale(container->surface, -+ moz_container_get_scale(container)); - } - - return container->surface; - } -+ -+struct wl_egl_window *moz_container_get_wl_egl_window(MozContainer *container) { -+ if (!container->eglwindow) { -+ wl_surface *surface = moz_container_get_wl_surface(container); -+ if (!surface) { -+ return nullptr; -+ } -+ } -+ return container->eglwindow; -+} -+ -+gboolean moz_container_has_wl_egl_window(MozContainer *container) { -+ return container->eglwindow ? true : false; -+} -+ -+gboolean moz_container_surface_needs_clear(MozContainer *container) { -+ gboolean state = container->surface_needs_clear; -+ container->surface_needs_clear = false; -+ return state; -+} - #endif -diff -up thunderbird-60.5.0/widget/gtk/mozcontainer.h.wayland thunderbird-60.5.0/widget/gtk/mozcontainer.h ---- thunderbird-60.5.0/widget/gtk/mozcontainer.h.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/mozcontainer.h 2019-02-05 14:26:16.974316651 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -63,7 +63,6 @@ typedef struct _MozContainerClass MozCon - * present in wayland-devel < 1.12 - */ - #ifdef MOZ_WAYLAND --struct wl_subcompositor; - struct wl_surface; - struct wl_subsurface; - #endif -@@ -73,9 +72,12 @@ struct _MozContainer { - GList *children; - - #ifdef MOZ_WAYLAND -- struct wl_subcompositor *subcompositor; - struct wl_surface *surface; - struct wl_subsurface *subsurface; -+ struct wl_egl_window *eglwindow; -+ struct wl_callback *frame_callback_handler; -+ gboolean surface_needs_clear; -+ gboolean ready_to_draw; - #endif - }; - -@@ -87,11 +89,13 @@ GType moz_container_get_type(void); - GtkWidget *moz_container_new(void); - void moz_container_put(MozContainer *container, GtkWidget *child_widget, gint x, - gint y); --void moz_container_move(MozContainer *container, GtkWidget *child_widget, -- gint x, gint y, gint width, gint height); - - #ifdef MOZ_WAYLAND - struct wl_surface *moz_container_get_wl_surface(MozContainer *container); -+struct wl_egl_window *moz_container_get_wl_egl_window(MozContainer *container); -+ -+gboolean moz_container_has_wl_egl_window(MozContainer *container); -+gboolean moz_container_surface_needs_clear(MozContainer *container); - #endif - - #endif /* __MOZ_CONTAINER_H__ */ -diff -up thunderbird-60.5.0/widget/gtk/mozgtk/mozgtk.c.wayland thunderbird-60.5.0/widget/gtk/mozgtk/mozgtk.c ---- thunderbird-60.5.0/widget/gtk/mozgtk/mozgtk.c.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/mozgtk/mozgtk.c 2019-02-05 14:26:16.974316651 +0100 -@@ -26,6 +26,7 @@ STUB(gdk_display_sync) - STUB(gdk_display_warp_pointer) - STUB(gdk_drag_context_get_actions) - STUB(gdk_drag_context_get_dest_window) -+STUB(gdk_drag_context_get_source_window) - STUB(gdk_drag_context_list_targets) - STUB(gdk_drag_status) - STUB(gdk_error_trap_pop) -@@ -55,6 +56,7 @@ STUB(gdk_pointer_grab) - STUB(gdk_pointer_ungrab) - STUB(gdk_property_change) - STUB(gdk_property_get) -+STUB(gdk_property_delete) - STUB(gdk_screen_get_default) - STUB(gdk_screen_get_display) - STUB(gdk_screen_get_font_options) -@@ -136,6 +138,8 @@ STUB(gdk_x11_get_xatom_by_name) - STUB(gdk_x11_get_xatom_by_name_for_display) - STUB(gdk_x11_lookup_xdisplay) - STUB(gdk_x11_screen_get_xscreen) -+STUB(gdk_x11_screen_get_screen_number) -+STUB(gdk_x11_screen_lookup_visual) - STUB(gdk_x11_screen_supports_net_wm_hint) - STUB(gdk_x11_visual_get_xvisual) - STUB(gdk_x11_window_foreign_new_for_display) -@@ -267,6 +271,7 @@ STUB(gtk_im_context_set_client_window) - STUB(gtk_im_context_set_cursor_location) - STUB(gtk_im_context_set_surrounding) - STUB(gtk_im_context_simple_new) -+STUB(gtk_im_multicontext_get_context_id) - STUB(gtk_im_multicontext_get_type) - STUB(gtk_im_multicontext_new) - STUB(gtk_info_bar_get_type) -@@ -411,6 +416,7 @@ STUB(gtk_table_get_type) - STUB(gtk_table_new) - STUB(gtk_target_list_add) - STUB(gtk_target_list_add_image_targets) -+STUB(gtk_target_list_add_text_targets) - STUB(gtk_target_list_new) - STUB(gtk_target_list_unref) - STUB(gtk_targets_include_image) -@@ -491,6 +497,7 @@ STUB(gtk_widget_unrealize) - STUB(gtk_window_deiconify) - STUB(gtk_window_fullscreen) - STUB(gtk_window_get_group) -+STUB(gtk_window_get_modal) - STUB(gtk_window_get_transient_for) - STUB(gtk_window_get_type) - STUB(gtk_window_get_type_hint) -diff -up thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.c.wayland thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.c ---- thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.c.wayland 2019-01-22 20:44:02.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.c 2019-02-05 14:26:16.974316651 +0100 -@@ -1,14 +1,23 @@ --/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -+#include - #include "mozilla/Types.h" - #include -+#include - #include - -+union wl_argument; -+ -+/* Those strucures are just placeholders and will be replaced by -+ * real symbols from libwayland during run-time linking. We need to make -+ * them explicitly visible. -+ */ -+#pragma GCC visibility push(default) - const struct wl_interface wl_buffer_interface; - const struct wl_interface wl_callback_interface; - const struct wl_interface wl_data_device_interface; -@@ -22,6 +31,7 @@ const struct wl_interface wl_seat_interf - const struct wl_interface wl_surface_interface; - const struct wl_interface wl_subsurface_interface; - const struct wl_interface wl_subcompositor_interface; -+#pragma GCC visibility pop - - MOZ_EXPORT void wl_event_queue_destroy(struct wl_event_queue *queue) {} - -@@ -75,6 +85,10 @@ MOZ_EXPORT const void *wl_proxy_get_list - return NULL; - } - -+typedef int (*wl_dispatcher_func_t)(const void *, void *, uint32_t, -+ const struct wl_message *, -+ union wl_argument *); -+ - MOZ_EXPORT int wl_proxy_add_dispatcher(struct wl_proxy *proxy, - wl_dispatcher_func_t dispatcher_func, - const void *dispatcher_data, -@@ -160,3 +174,13 @@ MOZ_EXPORT void wl_display_cancel_read(s - MOZ_EXPORT int wl_display_read_events(struct wl_display *display) { return -1; } - - MOZ_EXPORT void wl_log_set_handler_client(wl_log_func_t handler) {} -+ -+MOZ_EXPORT struct wl_egl_window *wl_egl_window_create( -+ struct wl_surface *surface, int width, int height) { -+ return NULL; -+} -+ -+MOZ_EXPORT void wl_egl_window_destroy(struct wl_egl_window *egl_window) {} -+ -+MOZ_EXPORT void wl_egl_window_resize(struct wl_egl_window *egl_window, -+ int width, int height, int dx, int dy) {} -diff -up thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.h.wayland thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.h ---- thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.h.wayland 2019-02-05 14:26:16.975316648 +0100 -+++ thunderbird-60.5.0/widget/gtk/mozwayland/mozwayland.h 2019-02-05 14:26:16.975316648 +0100 -@@ -0,0 +1,115 @@ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim:expandtab:shiftwidth=4:tabstop=4: -+ */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+/* Wayland compatibility header, it makes Firefox build with -+ wayland-1.2 and Gtk+ 3.10. -+*/ -+ -+#ifndef __MozWayland_h_ -+#define __MozWayland_h_ -+ -+#include "mozilla/Types.h" -+#include -+#include -+ -+#ifdef __cplusplus -+extern "C" { -+#endif -+ -+MOZ_EXPORT int wl_display_roundtrip_queue(struct wl_display *display, -+ struct wl_event_queue *queue); -+MOZ_EXPORT uint32_t wl_proxy_get_version(struct wl_proxy *proxy); -+MOZ_EXPORT struct wl_proxy *wl_proxy_marshal_constructor( -+ struct wl_proxy *proxy, uint32_t opcode, -+ const struct wl_interface *interface, ...); -+ -+/* We need implement some missing functions from wayland-client-protocol.h -+ */ -+#ifndef WL_DATA_DEVICE_MANAGER_DND_ACTION_ENUM -+enum wl_data_device_manager_dnd_action { -+ WL_DATA_DEVICE_MANAGER_DND_ACTION_NONE = 0, -+ WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY = 1, -+ WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE = 2, -+ WL_DATA_DEVICE_MANAGER_DND_ACTION_ASK = 4 -+}; -+#endif -+ -+#ifndef WL_DATA_OFFER_SET_ACTIONS -+#define WL_DATA_OFFER_SET_ACTIONS 4 -+ -+struct moz_wl_data_offer_listener { -+ void (*offer)(void *data, struct wl_data_offer *wl_data_offer, -+ const char *mime_type); -+ void (*source_actions)(void *data, struct wl_data_offer *wl_data_offer, -+ uint32_t source_actions); -+ void (*action)(void *data, struct wl_data_offer *wl_data_offer, -+ uint32_t dnd_action); -+}; -+ -+static inline void wl_data_offer_set_actions( -+ struct wl_data_offer *wl_data_offer, uint32_t dnd_actions, -+ uint32_t preferred_action) { -+ wl_proxy_marshal((struct wl_proxy *)wl_data_offer, WL_DATA_OFFER_SET_ACTIONS, -+ dnd_actions, preferred_action); -+} -+#else -+typedef struct wl_data_offer_listener moz_wl_data_offer_listener; -+#endif -+ -+#ifndef WL_SUBCOMPOSITOR_GET_SUBSURFACE -+#define WL_SUBCOMPOSITOR_GET_SUBSURFACE 1 -+struct wl_subcompositor; -+ -+// Emulate what mozilla header wrapper does - make the -+// wl_subcompositor_interface always visible. -+#pragma GCC visibility push(default) -+extern const struct wl_interface wl_subsurface_interface; -+extern const struct wl_interface wl_subcompositor_interface; -+#pragma GCC visibility pop -+ -+#define WL_SUBSURFACE_DESTROY 0 -+#define WL_SUBSURFACE_SET_POSITION 1 -+#define WL_SUBSURFACE_PLACE_ABOVE 2 -+#define WL_SUBSURFACE_PLACE_BELOW 3 -+#define WL_SUBSURFACE_SET_SYNC 4 -+#define WL_SUBSURFACE_SET_DESYNC 5 -+ -+static inline struct wl_subsurface *wl_subcompositor_get_subsurface( -+ struct wl_subcompositor *wl_subcompositor, struct wl_surface *surface, -+ struct wl_surface *parent) { -+ struct wl_proxy *id; -+ -+ id = wl_proxy_marshal_constructor( -+ (struct wl_proxy *)wl_subcompositor, WL_SUBCOMPOSITOR_GET_SUBSURFACE, -+ &wl_subsurface_interface, NULL, surface, parent); -+ -+ return (struct wl_subsurface *)id; -+} -+ -+static inline void wl_subsurface_set_position( -+ struct wl_subsurface *wl_subsurface, int32_t x, int32_t y) { -+ wl_proxy_marshal((struct wl_proxy *)wl_subsurface, WL_SUBSURFACE_SET_POSITION, -+ x, y); -+} -+ -+static inline void wl_subsurface_set_desync( -+ struct wl_subsurface *wl_subsurface) { -+ wl_proxy_marshal((struct wl_proxy *)wl_subsurface, WL_SUBSURFACE_SET_DESYNC); -+} -+ -+static inline void wl_subsurface_destroy(struct wl_subsurface *wl_subsurface) { -+ wl_proxy_marshal((struct wl_proxy *)wl_subsurface, WL_SUBSURFACE_DESTROY); -+ -+ wl_proxy_destroy((struct wl_proxy *)wl_subsurface); -+} -+#endif -+ -+#ifdef __cplusplus -+} -+#endif -+ -+#endif /* __MozWayland_h_ */ -diff -up thunderbird-60.5.0/widget/gtk/nsClipboard.cpp.wayland thunderbird-60.5.0/widget/gtk/nsClipboard.cpp ---- thunderbird-60.5.0/widget/gtk/nsClipboard.cpp.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsClipboard.cpp 2019-02-05 14:26:16.975316648 +0100 -@@ -72,7 +72,7 @@ nsClipboard::~nsClipboard() { - } - } - --NS_IMPL_ISUPPORTS(nsClipboard, nsIClipboard) -+NS_IMPL_ISUPPORTS(nsClipboard, nsIClipboard, nsIObserver) - - nsresult nsClipboard::Init(void) { - GdkDisplay *display = gdk_display_get_default(); -diff -up thunderbird-60.5.0/widget/gtk/nsClipboardWayland.cpp.wayland thunderbird-60.5.0/widget/gtk/nsClipboardWayland.cpp ---- thunderbird-60.5.0/widget/gtk/nsClipboardWayland.cpp.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsClipboardWayland.cpp 2019-02-05 14:26:16.975316648 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -20,9 +20,11 @@ - #include "nsImageToPixbuf.h" - #include "nsStringStream.h" - #include "nsIObserverService.h" --#include "mozilla/Services.h" - #include "mozilla/RefPtr.h" - #include "mozilla/TimeStamp.h" -+#include "nsDragService.h" -+#include "mozwayland/mozwayland.h" -+#include "nsWaylandDisplay.h" - - #include "imgIContainer.h" - -@@ -31,15 +33,43 @@ - #include - #include - #include --#include --#include - #include - --#include "wayland/gtk-primary-selection-client-protocol.h" -- - const char *nsRetrievalContextWayland::sTextMimeTypes[TEXT_MIME_TYPES_NUM] = { - "text/plain;charset=utf-8", "UTF8_STRING", "COMPOUND_TEXT"}; - -+static inline GdkDragAction wl_to_gdk_actions(uint32_t dnd_actions) { -+ GdkDragAction actions = GdkDragAction(0); -+ -+ if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY) -+ actions = GdkDragAction(actions | GDK_ACTION_COPY); -+ if (dnd_actions & WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE) -+ actions = GdkDragAction(actions | GDK_ACTION_MOVE); -+ -+ return actions; -+} -+ -+static inline uint32_t gdk_to_wl_actions(GdkDragAction action) { -+ uint32_t dnd_actions = 0; -+ -+ if (action & (GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_PRIVATE)) -+ dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY; -+ if (action & GDK_ACTION_MOVE) -+ dnd_actions |= WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; -+ -+ return dnd_actions; -+} -+ -+static GtkWidget *get_gtk_widget_for_wl_surface(struct wl_surface *surface) { -+ GdkWindow *gdkParentWindow = -+ static_cast(wl_surface_get_user_data(surface)); -+ -+ gpointer user_data = nullptr; -+ gdk_window_get_user_data(gdkParentWindow, &user_data); -+ -+ return GTK_WIDGET(user_data); -+} -+ - void DataOffer::AddMIMEType(const char *aMimeType) { - GdkAtom atom = gdk_atom_intern(aMimeType, FALSE); - mTargetMIMETypes.AppendElement(atom); -@@ -98,7 +128,7 @@ char *DataOffer::GetData(wl_display *aDi - - GIOChannel *channel = g_io_channel_unix_new(pipe_fd[0]); - GError *error = nullptr; -- char *clipboardData; -+ char *clipboardData = nullptr; - - g_io_channel_set_encoding(channel, nullptr, &error); - if (!error) { -@@ -138,31 +168,92 @@ bool WaylandDataOffer::RequestDataTransf - return false; - } - -+void WaylandDataOffer::DragOfferAccept(const char *aMimeType, uint32_t aTime) { -+ wl_data_offer_accept(mWaylandDataOffer, aTime, aMimeType); -+} -+ -+/* We follow logic of gdk_wayland_drag_context_commit_status()/gdkdnd-wayland.c -+ * here. -+ */ -+void WaylandDataOffer::SetDragStatus(GdkDragAction aAction, uint32_t aTime) { -+ uint32_t dnd_actions = gdk_to_wl_actions(aAction); -+ uint32_t all_actions = WL_DATA_DEVICE_MANAGER_DND_ACTION_COPY | -+ WL_DATA_DEVICE_MANAGER_DND_ACTION_MOVE; -+ -+ wl_data_offer_set_actions(mWaylandDataOffer, all_actions, dnd_actions); -+ -+ /* Workaround Wayland D&D architecture here. To get the data_device_drop() -+ signal (which routes to nsDragService::GetData() call) we need to -+ accept at least one mime type before data_device_leave(). -+ -+ Real wl_data_offer_accept() for actualy requested data mime type is -+ called from nsDragService::GetData(). -+ */ -+ if (mTargetMIMETypes[0]) { -+ wl_data_offer_accept(mWaylandDataOffer, aTime, -+ gdk_atom_name(mTargetMIMETypes[0])); -+ } -+} -+ -+void WaylandDataOffer::SetSelectedDragAction(uint32_t aWaylandAction) { -+ mSelectedDragAction = aWaylandAction; -+} -+ -+GdkDragAction WaylandDataOffer::GetSelectedDragAction() { -+ return wl_to_gdk_actions(mSelectedDragAction); -+} -+ -+void WaylandDataOffer::SetAvailableDragActions(uint32_t aWaylandActions) { -+ mAvailableDragAction = aWaylandActions; -+} -+ -+GdkDragAction WaylandDataOffer::GetAvailableDragActions() { -+ return wl_to_gdk_actions(mAvailableDragAction); -+} -+ - static void data_offer_offer(void *data, struct wl_data_offer *wl_data_offer, - const char *type) { - auto *offer = static_cast(data); - offer->AddMIMEType(type); - } - -+/* Advertise all available drag and drop actions from source. -+ * We don't use that but follow gdk_wayland_drag_context_commit_status() -+ * from gdkdnd-wayland.c here. -+ */ - static void data_offer_source_actions(void *data, - struct wl_data_offer *wl_data_offer, -- uint32_t source_actions) {} -+ uint32_t source_actions) { -+ auto *offer = static_cast(data); -+ offer->SetAvailableDragActions(source_actions); -+} - -+/* Advertise recently selected drag and drop action by compositor, based -+ * on source actions and user choice (key modifiers, etc.). -+ */ - static void data_offer_action(void *data, struct wl_data_offer *wl_data_offer, -- uint32_t dnd_action) {} -+ uint32_t dnd_action) { -+ auto *offer = static_cast(data); -+ offer->SetSelectedDragAction(dnd_action); -+} - - /* wl_data_offer callback description: - * - * data_offer_offer - Is called for each MIME type available at wl_data_offer. -- * data_offer_source_actions - Exposes all available D&D actions. -- * data_offer_action - Expose one actually selected D&D action. -+ * data_offer_source_actions - This event indicates the actions offered by -+ * the data source. -+ * data_offer_action - This event indicates the action selected by -+ * the compositor after matching the source/destination -+ * side actions. - */ --static const struct wl_data_offer_listener data_offer_listener = { -+static const moz_wl_data_offer_listener data_offer_listener = { - data_offer_offer, data_offer_source_actions, data_offer_action}; - - WaylandDataOffer::WaylandDataOffer(wl_data_offer *aWaylandDataOffer) - : mWaylandDataOffer(aWaylandDataOffer) { -- wl_data_offer_add_listener(mWaylandDataOffer, &data_offer_listener, this); -+ wl_data_offer_add_listener( -+ mWaylandDataOffer, (struct wl_data_offer_listener *)&data_offer_listener, -+ this); - } - - WaylandDataOffer::~WaylandDataOffer(void) { -@@ -207,20 +298,93 @@ PrimaryDataOffer::~PrimaryDataOffer(void - } - } - --void nsRetrievalContextWayland::RegisterDataOffer( -+NS_IMPL_ISUPPORTS(nsWaylandDragContext, nsISupports); -+ -+nsWaylandDragContext::nsWaylandDragContext(WaylandDataOffer *aDataOffer, -+ wl_display *aDisplay) -+ : mDataOffer(aDataOffer), -+ mDisplay(aDisplay), -+ mTime(0), -+ mGtkWidget(nullptr), -+ mX(0), -+ mY(0) {} -+ -+void nsWaylandDragContext::DropDataEnter(GtkWidget *aGtkWidget, uint32_t aTime, -+ nscoord aX, nscoord aY) { -+ mTime = aTime; -+ mGtkWidget = aGtkWidget; -+ mX = aX; -+ mY = aY; -+} -+ -+void nsWaylandDragContext::DropMotion(uint32_t aTime, nscoord aX, nscoord aY) { -+ mTime = aTime; -+ mX = aX; -+ mY = aY; -+} -+ -+void nsWaylandDragContext::GetLastDropInfo(uint32_t *aTime, nscoord *aX, -+ nscoord *aY) { -+ *aTime = mTime; -+ *aX = mX; -+ *aY = mY; -+} -+ -+void nsWaylandDragContext::SetDragStatus(GdkDragAction aAction) { -+ mDataOffer->SetDragStatus(aAction, mTime); -+} -+ -+GdkDragAction nsWaylandDragContext::GetSelectedDragAction() { -+ GdkDragAction gdkAction = mDataOffer->GetSelectedDragAction(); -+ -+ // We emulate gdk_drag_context_get_actions() here. -+ if (!gdkAction) { -+ gdkAction = mDataOffer->GetAvailableDragActions(); -+ } -+ -+ return gdkAction; -+} -+ -+GList *nsWaylandDragContext::GetTargets() { -+ int targetNums; -+ GdkAtom *atoms = mDataOffer->GetTargets(&targetNums); -+ -+ GList *targetList = nullptr; -+ for (int i = 0; i < targetNums; i++) { -+ targetList = g_list_append(targetList, GDK_ATOM_TO_POINTER(atoms[i])); -+ } -+ -+ return targetList; -+} -+ -+char *nsWaylandDragContext::GetData(const char *aMimeType, -+ uint32_t *aContentLength) { -+ mDataOffer->DragOfferAccept(aMimeType, mTime); -+ return mDataOffer->GetData(mDisplay, aMimeType, aContentLength); -+} -+ -+void nsRetrievalContextWayland::RegisterNewDataOffer( - wl_data_offer *aWaylandDataOffer) { - DataOffer *dataOffer = static_cast( - g_hash_table_lookup(mActiveOffers, aWaylandDataOffer)); -+ MOZ_ASSERT( -+ dataOffer == nullptr, -+ "Registered WaylandDataOffer already exists. Wayland protocol error?"); -+ - if (!dataOffer) { - dataOffer = new WaylandDataOffer(aWaylandDataOffer); - g_hash_table_insert(mActiveOffers, aWaylandDataOffer, dataOffer); - } - } - --void nsRetrievalContextWayland::RegisterDataOffer( -+void nsRetrievalContextWayland::RegisterNewDataOffer( - gtk_primary_selection_offer *aPrimaryDataOffer) { - DataOffer *dataOffer = static_cast( - g_hash_table_lookup(mActiveOffers, aPrimaryDataOffer)); -+ MOZ_ASSERT( -+ dataOffer == nullptr, -+ "Registered PrimaryDataOffer already exists. Wayland protocol error?"); -+ - if (!dataOffer) { - dataOffer = new PrimaryDataOffer(aPrimaryDataOffer); - g_hash_table_insert(mActiveOffers, aPrimaryDataOffer, dataOffer); -@@ -229,21 +393,30 @@ void nsRetrievalContextWayland::Register - - void nsRetrievalContextWayland::SetClipboardDataOffer( - wl_data_offer *aWaylandDataOffer) { -- DataOffer *dataOffer = static_cast( -- g_hash_table_lookup(mActiveOffers, aWaylandDataOffer)); -- NS_ASSERTION(dataOffer, "We're missing clipboard data offer!"); -- if (dataOffer) { -- g_hash_table_remove(mActiveOffers, aWaylandDataOffer); -- mClipboardOffer = dataOffer; -+ // Delete existing clipboard data offer -+ mClipboardOffer = nullptr; -+ -+ // null aWaylandDataOffer indicates that our clipboard content -+ // is no longer valid and should be release. -+ if (aWaylandDataOffer != nullptr) { -+ DataOffer *dataOffer = static_cast( -+ g_hash_table_lookup(mActiveOffers, aWaylandDataOffer)); -+ NS_ASSERTION(dataOffer, "We're missing stored clipboard data offer!"); -+ if (dataOffer) { -+ g_hash_table_remove(mActiveOffers, aWaylandDataOffer); -+ mClipboardOffer = dataOffer; -+ } - } - } - - void nsRetrievalContextWayland::SetPrimaryDataOffer( - gtk_primary_selection_offer *aPrimaryDataOffer) { -- if (aPrimaryDataOffer == nullptr) { -- // Release any primary offer we have. -- mPrimaryOffer = nullptr; -- } else { -+ // Release any primary offer we have. -+ mPrimaryOffer = nullptr; -+ -+ // aPrimaryDataOffer can be null which means we lost -+ // the mouse selection. -+ if (aPrimaryDataOffer) { - DataOffer *dataOffer = static_cast( - g_hash_table_lookup(mActiveOffers, aPrimaryDataOffer)); - NS_ASSERTION(dataOffer, "We're missing primary data offer!"); -@@ -254,9 +427,26 @@ void nsRetrievalContextWayland::SetPrima - } - } - --void nsRetrievalContextWayland::ClearDataOffers(void) { -- if (mClipboardOffer) mClipboardOffer = nullptr; -- if (mPrimaryOffer) mPrimaryOffer = nullptr; -+void nsRetrievalContextWayland::AddDragAndDropDataOffer( -+ wl_data_offer *aDropDataOffer) { -+ // Remove any existing D&D contexts. -+ mDragContext = nullptr; -+ -+ WaylandDataOffer *dataOffer = static_cast( -+ g_hash_table_lookup(mActiveOffers, aDropDataOffer)); -+ NS_ASSERTION(dataOffer, "We're missing drag and drop data offer!"); -+ if (dataOffer) { -+ g_hash_table_remove(mActiveOffers, aDropDataOffer); -+ mDragContext = new nsWaylandDragContext(dataOffer, mDisplay->GetDisplay()); -+ } -+} -+ -+nsWaylandDragContext *nsRetrievalContextWayland::GetDragContext(void) { -+ return mDragContext; -+} -+ -+void nsRetrievalContextWayland::ClearDragAndDropDataOffer(void) { -+ mDragContext = nullptr; - } - - // We have a new fresh data content. -@@ -266,7 +456,7 @@ static void data_device_data_offer(void - struct wl_data_offer *offer) { - nsRetrievalContextWayland *context = - static_cast(data); -- context->RegisterDataOffer(offer); -+ context->RegisterNewDataOffer(offer); - } - - // The new fresh data content is clipboard. -@@ -281,15 +471,65 @@ static void data_device_selection(void * - // The new fresh wayland data content is drag and drop. - static void data_device_enter(void *data, struct wl_data_device *data_device, - uint32_t time, struct wl_surface *surface, -- int32_t x, int32_t y, -- struct wl_data_offer *offer) {} -+ int32_t x_fixed, int32_t y_fixed, -+ struct wl_data_offer *offer) { -+ nsRetrievalContextWayland *context = -+ static_cast(data); -+ context->AddDragAndDropDataOffer(offer); -+ -+ nsWaylandDragContext *dragContext = context->GetDragContext(); -+ -+ GtkWidget *gtkWidget = get_gtk_widget_for_wl_surface(surface); -+ if (!gtkWidget) { -+ NS_WARNING("DragAndDrop: Unable to get GtkWidget for wl_surface!"); -+ return; -+ } -+ -+ LOGDRAG(("nsWindow data_device_enter for GtkWidget %p\n", (void *)gtkWidget)); -+ -+ dragContext->DropDataEnter(gtkWidget, time, wl_fixed_to_int(x_fixed), -+ wl_fixed_to_int(y_fixed)); -+} -+ -+static void data_device_leave(void *data, struct wl_data_device *data_device) { -+ nsRetrievalContextWayland *context = -+ static_cast(data); - --static void data_device_leave(void *data, struct wl_data_device *data_device) {} -+ nsWaylandDragContext *dropContext = context->GetDragContext(); -+ WindowDragLeaveHandler(dropContext->GetWidget()); -+ -+ context->ClearDragAndDropDataOffer(); -+} - - static void data_device_motion(void *data, struct wl_data_device *data_device, -- uint32_t time, int32_t x, int32_t y) {} -+ uint32_t time, int32_t x_fixed, -+ int32_t y_fixed) { -+ nsRetrievalContextWayland *context = -+ static_cast(data); -+ -+ nsWaylandDragContext *dropContext = context->GetDragContext(); - --static void data_device_drop(void *data, struct wl_data_device *data_device) {} -+ nscoord x = wl_fixed_to_int(x_fixed); -+ nscoord y = wl_fixed_to_int(y_fixed); -+ dropContext->DropMotion(time, x, y); -+ -+ WindowDragMotionHandler(dropContext->GetWidget(), nullptr, dropContext, x, y, -+ time); -+} -+ -+static void data_device_drop(void *data, struct wl_data_device *data_device) { -+ nsRetrievalContextWayland *context = -+ static_cast(data); -+ -+ nsWaylandDragContext *dropContext = context->GetDragContext(); -+ -+ uint32_t time; -+ nscoord x, y; -+ dropContext->GetLastDropInfo(&time, &x, &y); -+ -+ WindowDragDropHandler(dropContext->GetWidget(), nullptr, dropContext, x, y, -+ time); -+} - - /* wl_data_device callback description: - * -@@ -323,7 +563,7 @@ static void primary_selection_data_offer - // create and add listener - nsRetrievalContextWayland *context = - static_cast(data); -- context->RegisterDataOffer(gtk_primary_offer); -+ context->RegisterNewDataOffer(gtk_primary_offer); - } - - static void primary_selection_selection( -@@ -335,6 +575,19 @@ static void primary_selection_selection( - context->SetPrimaryDataOffer(gtk_primary_offer); - } - -+/* gtk_primary_selection_device callback description: -+ * -+ * primary_selection_data_offer - It's called when there's a new -+ * gtk_primary_selection_offer available. We need to -+ * attach gtk_primary_selection_offer_listener to it -+ * to get available MIME types. -+ * -+ * primary_selection_selection - It's called when the new -+ * gtk_primary_selection_offer is a primary selection -+ * content. It can be also called with -+ * gtk_primary_selection_offer = null which means -+ * there's no primary selection. -+ */ - static const struct gtk_primary_selection_device_listener - primary_selection_device_listener = { - primary_selection_data_offer, -@@ -342,149 +595,29 @@ static const struct gtk_primary_selectio - }; - - bool nsRetrievalContextWayland::HasSelectionSupport(void) { -- return mPrimarySelectionDataDeviceManager != nullptr; --} -- --static void keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard, -- uint32_t format, int fd, uint32_t size) {} -- --static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard, -- uint32_t serial, struct wl_surface *surface, -- struct wl_array *keys) {} -- --static void keyboard_handle_leave(void *data, struct wl_keyboard *keyboard, -- uint32_t serial, struct wl_surface *surface) { -- // We lost focus so our clipboard data are outdated -- nsRetrievalContextWayland *context = -- static_cast(data); -- -- context->ClearDataOffers(); -+ return mDisplay->GetPrimarySelectionDeviceManager() != nullptr; - } - --static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard, -- uint32_t serial, uint32_t time, uint32_t key, -- uint32_t state) {} -- --static void keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard, -- uint32_t serial, uint32_t mods_depressed, -- uint32_t mods_latched, -- uint32_t mods_locked, uint32_t group) {} -- --static const struct wl_keyboard_listener keyboard_listener = { -- keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, -- keyboard_handle_key, keyboard_handle_modifiers, --}; -- --void nsRetrievalContextWayland::ConfigureKeyboard(wl_seat_capability caps) { -- // ConfigureKeyboard() is called when wl_seat configuration is changed. -- // We look for the keyboard only, get it when is't available and release it -- // when it's lost (we don't have focus for instance). -- if (caps & WL_SEAT_CAPABILITY_KEYBOARD) { -- mKeyboard = wl_seat_get_keyboard(mSeat); -- wl_keyboard_add_listener(mKeyboard, &keyboard_listener, this); -- } else if (mKeyboard && !(caps & WL_SEAT_CAPABILITY_KEYBOARD)) { -- wl_keyboard_destroy(mKeyboard); -- mKeyboard = nullptr; -- } --} -- --static void seat_handle_capabilities(void *data, struct wl_seat *seat, -- unsigned int caps) { -- nsRetrievalContextWayland *context = -- static_cast(data); -- context->ConfigureKeyboard((wl_seat_capability)caps); --} -- --static const struct wl_seat_listener seat_listener = { -- seat_handle_capabilities, --}; -- --void nsRetrievalContextWayland::InitDataDeviceManager(wl_registry *registry, -- uint32_t id, -- uint32_t version) { -- int data_device_manager_version = MIN(version, 3); -- mDataDeviceManager = (wl_data_device_manager *)wl_registry_bind( -- registry, id, &wl_data_device_manager_interface, -- data_device_manager_version); --} -- --void nsRetrievalContextWayland::InitPrimarySelectionDataDeviceManager( -- wl_registry *registry, uint32_t id) { -- mPrimarySelectionDataDeviceManager = -- (gtk_primary_selection_device_manager *)wl_registry_bind( -- registry, id, >k_primary_selection_device_manager_interface, 1); --} -- --void nsRetrievalContextWayland::InitSeat(wl_registry *registry, uint32_t id, -- uint32_t version, void *data) { -- mSeat = (wl_seat *)wl_registry_bind(registry, id, &wl_seat_interface, 1); -- wl_seat_add_listener(mSeat, &seat_listener, data); --} -- --static void gdk_registry_handle_global(void *data, struct wl_registry *registry, -- uint32_t id, const char *interface, -- uint32_t version) { -- nsRetrievalContextWayland *context = -- static_cast(data); -- -- if (strcmp(interface, "wl_data_device_manager") == 0) { -- context->InitDataDeviceManager(registry, id, version); -- } else if (strcmp(interface, "wl_seat") == 0) { -- context->InitSeat(registry, id, version, data); -- } else if (strcmp(interface, "gtk_primary_selection_device_manager") == 0) { -- context->InitPrimarySelectionDataDeviceManager(registry, id); -- } --} -- --static void gdk_registry_handle_global_remove(void *data, -- struct wl_registry *registry, -- uint32_t id) {} -- --static const struct wl_registry_listener clipboard_registry_listener = { -- gdk_registry_handle_global, gdk_registry_handle_global_remove}; -- - nsRetrievalContextWayland::nsRetrievalContextWayland(void) - : mInitialized(false), -- mSeat(nullptr), -- mDataDeviceManager(nullptr), -- mPrimarySelectionDataDeviceManager(nullptr), -- mKeyboard(nullptr), -+ mDisplay(WaylandDisplayGet()), - mActiveOffers(g_hash_table_new(NULL, NULL)), - mClipboardOffer(nullptr), - mPrimaryOffer(nullptr), -+ mDragContext(nullptr), - mClipboardRequestNumber(0), - mClipboardData(nullptr), - mClipboardDataLength(0) { -- // Available as of GTK 3.8+ -- static auto sGdkWaylandDisplayGetWlDisplay = (wl_display * (*)(GdkDisplay *)) -- dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display"); -- -- mDisplay = sGdkWaylandDisplayGetWlDisplay(gdk_display_get_default()); -- wl_registry_add_listener(wl_display_get_registry(mDisplay), -- &clipboard_registry_listener, this); -- // Call wl_display_roundtrip() twice to make sure all -- // callbacks are processed. -- wl_display_roundtrip(mDisplay); -- wl_display_roundtrip(mDisplay); -- -- // mSeat/mDataDeviceManager should be set now by -- // gdk_registry_handle_global() as a response to -- // wl_registry_add_listener() call. -- if (!mDataDeviceManager || !mSeat) return; -- -- wl_data_device *dataDevice = -- wl_data_device_manager_get_data_device(mDataDeviceManager, mSeat); -+ wl_data_device *dataDevice = wl_data_device_manager_get_data_device( -+ mDisplay->GetDataDeviceManager(), mDisplay->GetSeat()); - wl_data_device_add_listener(dataDevice, &data_device_listener, this); -- // We have to call wl_display_roundtrip() twice otherwise data_offer_listener -- // may not be processed because it's called from data_device_data_offer -- // callback. -- wl_display_roundtrip(mDisplay); -- wl_display_roundtrip(mDisplay); - -- if (mPrimarySelectionDataDeviceManager) { -+ gtk_primary_selection_device_manager *manager = -+ mDisplay->GetPrimarySelectionDeviceManager(); -+ if (manager) { - gtk_primary_selection_device *primaryDataDevice = -- gtk_primary_selection_device_manager_get_device( -- mPrimarySelectionDataDeviceManager, mSeat); -+ gtk_primary_selection_device_manager_get_device(manager, -+ mDisplay->GetSeat()); - gtk_primary_selection_device_add_listener( - primaryDataDevice, &primary_selection_device_listener, this); - } -@@ -492,8 +625,21 @@ nsRetrievalContextWayland::nsRetrievalCo - mInitialized = true; - } - -+static gboolean offer_hash_remove(gpointer wl_offer, gpointer aDataOffer, -+ gpointer user_data) { -+#ifdef DEBUG -+ nsPrintfCString msg("nsRetrievalContextWayland(): leaked nsDataOffer %p\n", -+ aDataOffer); -+ NS_WARNING(msg.get()); -+#endif -+ delete static_cast(aDataOffer); -+ return true; -+} -+ - nsRetrievalContextWayland::~nsRetrievalContextWayland(void) { -+ g_hash_table_foreach_remove(mActiveOffers, offer_hash_remove, nullptr); - g_hash_table_destroy(mActiveOffers); -+ WaylandDisplayRelease(mDisplay); - } - - GdkAtom *nsRetrievalContextWayland::GetTargets(int32_t aWhichClipboard, -@@ -533,12 +679,14 @@ static void wayland_clipboard_contents_r - void nsRetrievalContextWayland::TransferFastTrackClipboard( - int aClipboardRequestNumber, GtkSelectionData *aSelectionData) { - if (mClipboardRequestNumber == aClipboardRequestNumber) { -- mClipboardDataLength = gtk_selection_data_get_length(aSelectionData); -- if (mClipboardDataLength > 0) { -+ int dataLength = gtk_selection_data_get_length(aSelectionData); -+ if (dataLength > 0) { -+ mClipboardDataLength = dataLength; - mClipboardData = reinterpret_cast( -- g_malloc(sizeof(char) * mClipboardDataLength)); -+ g_malloc(sizeof(char) * (mClipboardDataLength + 1))); - memcpy(mClipboardData, gtk_selection_data_get_data(aSelectionData), - sizeof(char) * mClipboardDataLength); -+ mClipboardData[mClipboardDataLength] = '\0'; - } - } else { - NS_WARNING("Received obsoleted clipboard data!"); -@@ -572,8 +720,8 @@ const char *nsRetrievalContextWayland::G - mClipboardData = nullptr; - mClipboardDataLength = 0; - } else { -- mClipboardData = -- dataOffer->GetData(mDisplay, aMimeType, &mClipboardDataLength); -+ mClipboardData = dataOffer->GetData(mDisplay->GetDisplay(), aMimeType, -+ &mClipboardDataLength); - } - } - -@@ -588,7 +736,7 @@ const char *nsRetrievalContextWayland::G - (selection == GDK_SELECTION_PRIMARY) ? mPrimaryOffer : mClipboardOffer; - if (!dataOffer) return nullptr; - -- for (unsigned int i = 0; i < sizeof(sTextMimeTypes); i++) { -+ for (unsigned int i = 0; i < TEXT_MIME_TYPES_NUM; i++) { - if (dataOffer->HasTarget(sTextMimeTypes[i])) { - uint32_t unused; - return GetClipboardData(sTextMimeTypes[i], aWhichClipboard, &unused); -diff -up thunderbird-60.5.0/widget/gtk/nsClipboardWayland.h.wayland thunderbird-60.5.0/widget/gtk/nsClipboardWayland.h ---- thunderbird-60.5.0/widget/gtk/nsClipboardWayland.h.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsClipboardWayland.h 2019-02-05 14:26:16.975316648 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -9,6 +9,7 @@ - #define __nsClipboardWayland_h_ - - #include "nsIClipboard.h" -+#include "mozwayland/mozwayland.h" - #include "wayland/gtk-primary-selection-client-protocol.h" - - #include -@@ -32,31 +33,75 @@ class DataOffer { - private: - virtual bool RequestDataTransfer(const char* aMimeType, int fd) = 0; - -+ protected: - nsTArray mTargetMIMETypes; - }; - - class WaylandDataOffer : public DataOffer { - public: -- WaylandDataOffer(wl_data_offer* aWaylandDataOffer); -+ explicit WaylandDataOffer(wl_data_offer* aWaylandDataOffer); -+ -+ void DragOfferAccept(const char* aMimeType, uint32_t aTime); -+ void SetDragStatus(GdkDragAction aAction, uint32_t aTime); -+ -+ GdkDragAction GetSelectedDragAction(); -+ void SetSelectedDragAction(uint32_t aWaylandAction); -+ -+ void SetAvailableDragActions(uint32_t aWaylandActions); -+ GdkDragAction GetAvailableDragActions(); - -- private: - virtual ~WaylandDataOffer(); -+ -+ private: - bool RequestDataTransfer(const char* aMimeType, int fd) override; - - wl_data_offer* mWaylandDataOffer; -+ uint32_t mSelectedDragAction; -+ uint32_t mAvailableDragAction; - }; - - class PrimaryDataOffer : public DataOffer { - public: -- PrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer); -+ explicit PrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer); -+ void SetAvailableDragActions(uint32_t aWaylandActions){}; - -- private: - virtual ~PrimaryDataOffer(); -+ -+ private: - bool RequestDataTransfer(const char* aMimeType, int fd) override; - - gtk_primary_selection_offer* mPrimaryDataOffer; - }; - -+class nsWaylandDragContext : public nsISupports { -+ NS_DECL_ISUPPORTS -+ -+ public: -+ nsWaylandDragContext(WaylandDataOffer* aWaylandDataOffer, -+ wl_display* aDisplay); -+ -+ void DropDataEnter(GtkWidget* aGtkWidget, uint32_t aTime, nscoord aX, -+ nscoord aY); -+ void DropMotion(uint32_t aTime, nscoord aX, nscoord aY); -+ void GetLastDropInfo(uint32_t* aTime, nscoord* aX, nscoord* aY); -+ -+ void SetDragStatus(GdkDragAction action); -+ GdkDragAction GetSelectedDragAction(); -+ -+ GtkWidget* GetWidget() { return mGtkWidget; } -+ GList* GetTargets(); -+ char* GetData(const char* aMimeType, uint32_t* aContentLength); -+ -+ private: -+ virtual ~nsWaylandDragContext(){}; -+ -+ nsAutoPtr mDataOffer; -+ wl_display* mDisplay; -+ uint32_t mTime; -+ GtkWidget* mGtkWidget; -+ nscoord mX, mY; -+}; -+ - class nsRetrievalContextWayland : public nsRetrievalContext { - public: - nsRetrievalContextWayland(); -@@ -71,38 +116,30 @@ class nsRetrievalContextWayland : public - int* aTargetNum) override; - virtual bool HasSelectionSupport(void) override; - -- void RegisterDataOffer(wl_data_offer* aWaylandDataOffer); -- void RegisterDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer); -+ void RegisterNewDataOffer(wl_data_offer* aWaylandDataOffer); -+ void RegisterNewDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer); - - void SetClipboardDataOffer(wl_data_offer* aWaylandDataOffer); - void SetPrimaryDataOffer(gtk_primary_selection_offer* aPrimaryDataOffer); -+ void AddDragAndDropDataOffer(wl_data_offer* aWaylandDataOffer); -+ nsWaylandDragContext* GetDragContext(); - -- void ClearDataOffers(); -+ void ClearDragAndDropDataOffer(); - -- void ConfigureKeyboard(wl_seat_capability caps); - void TransferFastTrackClipboard(int aClipboardRequestNumber, - GtkSelectionData* aSelectionData); - -- void InitDataDeviceManager(wl_registry* registry, uint32_t id, -- uint32_t version); -- void InitPrimarySelectionDataDeviceManager(wl_registry* registry, -- uint32_t id); -- void InitSeat(wl_registry* registry, uint32_t id, uint32_t version, -- void* data); - virtual ~nsRetrievalContextWayland() override; - - private: - bool mInitialized; -- wl_display* mDisplay; -- wl_seat* mSeat; -- wl_data_device_manager* mDataDeviceManager; -- gtk_primary_selection_device_manager* mPrimarySelectionDataDeviceManager; -- wl_keyboard* mKeyboard; -+ nsWaylandDisplay* mDisplay; - - // Data offers provided by Wayland data device - GHashTable* mActiveOffers; - nsAutoPtr mClipboardOffer; - nsAutoPtr mPrimaryOffer; -+ RefPtr mDragContext; - - int mClipboardRequestNumber; - char* mClipboardData; -diff -up thunderbird-60.5.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60.5.0/widget/gtk/nsDragService.cpp ---- thunderbird-60.5.0/widget/gtk/nsDragService.cpp.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsDragService.cpp 2019-02-05 14:26:16.976316645 +0100 -@@ -1,5 +1,5 @@ --/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ --/* vim: set ts=4 et sw=4 tw=80: */ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim: set ts=4 et sw=2 tw=80: */ - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -@@ -9,6 +9,7 @@ - #include "nsIObserverService.h" - #include "nsWidgetsCID.h" - #include "nsWindow.h" -+#include "nsSystemInfo.h" - #include "nsIServiceManager.h" - #include "nsXPCOM.h" - #include "nsISupportsPrimitives.h" -@@ -34,7 +35,6 @@ - #include "nsPresContext.h" - #include "nsIContent.h" - #include "nsIDocument.h" --#include "nsISelection.h" - #include "nsViewManager.h" - #include "nsIFrame.h" - #include "nsGtkUtils.h" -@@ -43,10 +43,15 @@ - #include "gfxPlatform.h" - #include "ScreenHelperGTK.h" - #include "nsArrayUtils.h" -+#ifdef MOZ_WAYLAND -+#include "nsClipboardWayland.h" -+#endif - - using namespace mozilla; - using namespace mozilla::gfx; - -+#define NS_SYSTEMINFO_CONTRACTID "@mozilla.org/system-info;1" -+ - // This sets how opaque the drag image is - #define DRAG_IMAGE_ALPHA_LEVEL 0.5 - -@@ -68,6 +73,7 @@ static const char gMimeListType[] = "app - static const char gMozUrlType[] = "_NETSCAPE_URL"; - static const char gTextUriListType[] = "text/uri-list"; - static const char gTextPlainUTF8Type[] = "text/plain;charset=utf-8"; -+static const char gXdndDirectSaveType[] = "XdndDirectSave0"; - - static void invisibleSourceDragBegin(GtkWidget *aWidget, - GdkDragContext *aContext, gpointer aData); -@@ -85,7 +91,15 @@ static void invisibleSourceDragDataGet(G - guint aInfo, guint32 aTime, - gpointer aData); - --nsDragService::nsDragService() : mScheduledTask(eDragTaskNone), mTaskSource(0) { -+nsDragService::nsDragService() -+ : mScheduledTask(eDragTaskNone), -+ mTaskSource(0) -+#ifdef MOZ_WAYLAND -+ , -+ mPendingWaylandDragContext(nullptr), -+ mTargetWaylandDragContext(nullptr) -+#endif -+{ - // We have to destroy the hidden widget before the event loop stops - // running. - nsCOMPtr obsServ = -@@ -159,7 +173,7 @@ nsDragService::Observe(nsISupports *aSub - } - TargetResetData(); - } else { -- NS_NOTREACHED("unexpected topic"); -+ MOZ_ASSERT_UNREACHABLE("unexpected topic"); - return NS_ERROR_UNEXPECTED; - } - -@@ -457,6 +471,9 @@ nsDragService::EndDragSession(bool aDone - - // We're done with the drag context. - mTargetDragContextForRemote = nullptr; -+#ifdef MOZ_WAYLAND -+ mTargetWaylandDragContextForRemote = nullptr; -+#endif - - return nsBaseDragService::EndDragSession(aDoneDrag, aKeyModifiers); - } -@@ -550,6 +567,14 @@ nsDragService::GetNumDropItems(uint32_t - return NS_OK; - } - -+#ifdef MOZ_WAYLAND -+ // TODO: Wayland implementation of text/uri-list. -+ if (!mTargetDragContext) { -+ *aNumItems = 1; -+ return NS_OK; -+ } -+#endif -+ - bool isList = IsTargetContextList(); - if (isList) - mSourceDataItems->GetLength(aNumItems); -@@ -907,9 +932,18 @@ nsDragService::IsDataFlavorSupported(con - } - - // check the target context vs. this flavor, one at a time -- GList *tmp; -- for (tmp = gdk_drag_context_list_targets(mTargetDragContext); tmp; -- tmp = tmp->next) { -+ GList *tmp = nullptr; -+ if (mTargetDragContext) { -+ tmp = gdk_drag_context_list_targets(mTargetDragContext); -+ } -+#ifdef MOZ_WAYLAND -+ else if (mTargetWaylandDragContext) { -+ tmp = mTargetWaylandDragContext->GetTargets(); -+ } -+ GList *tmp_head = tmp; -+#endif -+ -+ for (; tmp; tmp = tmp->next) { - /* Bug 331198 */ - GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data); - gchar *name = nullptr; -@@ -946,6 +980,15 @@ nsDragService::IsDataFlavorSupported(con - } - g_free(name); - } -+ -+#ifdef MOZ_WAYLAND -+ // mTargetWaylandDragContext->GetTargets allocates the list -+ // so we need to free it here. -+ if (!mTargetDragContext && tmp_head) { -+ g_list_free(tmp_head); -+ } -+#endif -+ - return NS_OK; - } - -@@ -975,6 +1018,34 @@ void nsDragService::ReplyToDragMotion(Gd - gdk_drag_status(aDragContext, action, mTargetTime); - } - -+#ifdef MOZ_WAYLAND -+void nsDragService::ReplyToDragMotion(nsWaylandDragContext *aDragContext) { -+ MOZ_LOG(sDragLm, LogLevel::Debug, -+ ("nsDragService::ReplyToDragMotion %d", mCanDrop)); -+ -+ GdkDragAction action = (GdkDragAction)0; -+ if (mCanDrop) { -+ // notify the dragger if we can drop -+ switch (mDragAction) { -+ case DRAGDROP_ACTION_COPY: -+ action = GDK_ACTION_COPY; -+ break; -+ case DRAGDROP_ACTION_LINK: -+ action = GDK_ACTION_LINK; -+ break; -+ case DRAGDROP_ACTION_NONE: -+ action = (GdkDragAction)0; -+ break; -+ default: -+ action = GDK_ACTION_MOVE; -+ break; -+ } -+ } -+ -+ aDragContext->SetDragStatus(action); -+} -+#endif -+ - void nsDragService::TargetDataReceived(GtkWidget *aWidget, - GdkDragContext *aContext, gint aX, - gint aY, -@@ -999,6 +1070,11 @@ void nsDragService::TargetDataReceived(G - bool nsDragService::IsTargetContextList(void) { - bool retval = false; - -+#ifdef MOZ_WAYLAND -+ // TODO: We need a wayland implementation here. -+ if (!mTargetDragContext) return retval; -+#endif -+ - // gMimeListType drags only work for drags within a single process. The - // gtk_drag_get_source_widget() function will return nullptr if the source - // of the drag is another app, so we use it to check if a gMimeListType -@@ -1032,17 +1108,27 @@ void nsDragService::GetTargetDragData(Gd - mTargetDragContext.get())); - // reset our target data areas - TargetResetData(); -- gtk_drag_get_data(mTargetWidget, mTargetDragContext, aFlavor, mTargetTime); - -- MOZ_LOG(sDragLm, LogLevel::Debug, ("about to start inner iteration.")); -- PRTime entryTime = PR_Now(); -- while (!mTargetDragDataReceived && mDoingDrag) { -- // check the number of iterations -- MOZ_LOG(sDragLm, LogLevel::Debug, ("doing iteration...\n")); -- PR_Sleep(20 * PR_TicksPerSecond() / 1000); /* sleep for 20 ms/iteration */ -- if (PR_Now() - entryTime > NS_DND_TIMEOUT) break; -- gtk_main_iteration(); -+ if (mTargetDragContext) { -+ gtk_drag_get_data(mTargetWidget, mTargetDragContext, aFlavor, mTargetTime); -+ -+ MOZ_LOG(sDragLm, LogLevel::Debug, ("about to start inner iteration.")); -+ PRTime entryTime = PR_Now(); -+ while (!mTargetDragDataReceived && mDoingDrag) { -+ // check the number of iterations -+ MOZ_LOG(sDragLm, LogLevel::Debug, ("doing iteration...\n")); -+ PR_Sleep(20 * PR_TicksPerSecond() / 1000); /* sleep for 20 ms/iteration */ -+ if (PR_Now() - entryTime > NS_DND_TIMEOUT) break; -+ gtk_main_iteration(); -+ } - } -+#ifdef MOZ_WAYLAND -+ else { -+ mTargetDragData = mTargetWaylandDragContext->GetData(gdk_atom_name(aFlavor), -+ &mTargetDragDataLen); -+ mTargetDragDataReceived = true; -+ } -+#endif - MOZ_LOG(sDragLm, LogLevel::Debug, ("finished inner iteration\n")); - } - -@@ -1218,6 +1304,10 @@ void nsDragService::SourceEndDragSession - // this just releases the list of data items that we provide - mSourceDataItems = nullptr; - -+ // Remove this property, if it exists, to satisfy the Direct Save Protocol. -+ GdkAtom property = gdk_atom_intern(gXdndDirectSaveType, FALSE); -+ gdk_property_delete(gdk_drag_context_get_source_window(aContext), property); -+ - if (!mDoingDrag || mScheduledTask == eDragTaskSourceEnd) - // EndDragSession() was already called on drop - // or SourceEndDragSession on drag-failed -@@ -1276,7 +1366,7 @@ void nsDragService::SourceEndDragSession - } - - // Schedule the appropriate drag end dom events. -- Schedule(eDragTaskSourceEnd, nullptr, nullptr, LayoutDeviceIntPoint(), 0); -+ Schedule(eDragTaskSourceEnd, nullptr, nullptr, nullptr, LayoutDeviceIntPoint(), 0); - } - - static void CreateUriList(nsIArray *items, gchar **text, gint *length) { -@@ -1585,11 +1675,11 @@ static void invisibleSourceDragEnd(GtkWi - // Gecko drag events are in flight. This helps event handlers that may not - // expect nested events, while accessing an event's dataTransfer for example. - --gboolean nsDragService::ScheduleMotionEvent(nsWindow *aWindow, -- GdkDragContext *aDragContext, -- LayoutDeviceIntPoint aWindowPoint, -- guint aTime) { -- if (mScheduledTask == eDragTaskMotion) { -+gboolean nsDragService::ScheduleMotionEvent( -+ nsWindow *aWindow, GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, -+ LayoutDeviceIntPoint aWindowPoint, guint aTime) { -+ if (aDragContext && mScheduledTask == eDragTaskMotion) { - // The drag source has sent another motion message before we've - // replied to the previous. That shouldn't happen with Xdnd. The - // spec for Motif drags is less clear, but we'll just update the -@@ -1600,23 +1690,26 @@ gboolean nsDragService::ScheduleMotionEv - - // Returning TRUE means we'll reply with a status message, unless we first - // get a leave. -- return Schedule(eDragTaskMotion, aWindow, aDragContext, aWindowPoint, aTime); -+ return Schedule(eDragTaskMotion, aWindow, aDragContext, aWaylandDragContext, -+ aWindowPoint, aTime); - } - - void nsDragService::ScheduleLeaveEvent() { - // We don't know at this stage whether a drop signal will immediately - // follow. If the drop signal gets sent it will happen before we return - // to the main loop and the scheduled leave task will be replaced. -- if (!Schedule(eDragTaskLeave, nullptr, nullptr, LayoutDeviceIntPoint(), 0)) { -+ if (!Schedule(eDragTaskLeave, nullptr, nullptr, nullptr, -+ LayoutDeviceIntPoint(), 0)) { - NS_WARNING("Drag leave after drop"); - } - } - --gboolean nsDragService::ScheduleDropEvent(nsWindow *aWindow, -- GdkDragContext *aDragContext, -- LayoutDeviceIntPoint aWindowPoint, -- guint aTime) { -- if (!Schedule(eDragTaskDrop, aWindow, aDragContext, aWindowPoint, aTime)) { -+gboolean nsDragService::ScheduleDropEvent( -+ nsWindow *aWindow, GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, -+ LayoutDeviceIntPoint aWindowPoint, guint aTime) { -+ if (!Schedule(eDragTaskDrop, aWindow, aDragContext, aWaylandDragContext, -+ aWindowPoint, aTime)) { - NS_WARNING("Additional drag drop ignored"); - return FALSE; - } -@@ -1629,6 +1722,7 @@ gboolean nsDragService::ScheduleDropEven - - gboolean nsDragService::Schedule(DragTask aTask, nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, - LayoutDeviceIntPoint aWindowPoint, - guint aTime) { - // If there is an existing leave or motion task scheduled, then that -@@ -1647,6 +1741,9 @@ gboolean nsDragService::Schedule(DragTas - mScheduledTask = aTask; - mPendingWindow = aWindow; - mPendingDragContext = aDragContext; -+#ifdef MOZ_WAYLAND -+ mPendingWaylandDragContext = aWaylandDragContext; -+#endif - mPendingWindowPoint = aWindowPoint; - mPendingTime = aTime; - -@@ -1717,6 +1814,9 @@ gboolean nsDragService::RunScheduledTask - // succeeed. - mTargetWidget = mTargetWindow->GetMozContainerWidget(); - mTargetDragContext.steal(mPendingDragContext); -+#ifdef MOZ_WAYLAND -+ mTargetWaylandDragContext = mPendingWaylandDragContext.forget(); -+#endif - mTargetTime = mPendingTime; - - // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-and-drop-processing-model -@@ -1748,10 +1848,20 @@ gboolean nsDragService::RunScheduledTask - if (task == eDragTaskMotion) { - if (TakeDragEventDispatchedToChildProcess()) { - mTargetDragContextForRemote = mTargetDragContext; -+#ifdef MOZ_WAYLAND -+ mTargetWaylandDragContextForRemote = mTargetWaylandDragContext; -+#endif - } else { - // Reply to tell the source whether we can drop and what - // action would be taken. -- ReplyToDragMotion(mTargetDragContext); -+ if (mTargetDragContext) { -+ ReplyToDragMotion(mTargetDragContext); -+ } -+#ifdef MOZ_WAYLAND -+ else if (mTargetWaylandDragContext) { -+ ReplyToDragMotion(mTargetWaylandDragContext); -+ } -+#endif - } - } - } -@@ -1762,8 +1872,10 @@ gboolean nsDragService::RunScheduledTask - // Perhaps we should set the del parameter to TRUE when the drag - // action is move, but we don't know whether the data was successfully - // transferred. -- gtk_drag_finish(mTargetDragContext, success, -- /* del = */ FALSE, mTargetTime); -+ if (mTargetDragContext) { -+ gtk_drag_finish(mTargetDragContext, success, -+ /* del = */ FALSE, mTargetTime); -+ } - - // This drag is over, so clear out our reference to the previous - // window. -@@ -1776,6 +1888,9 @@ gboolean nsDragService::RunScheduledTask - // We're done with the drag context. - mTargetWidget = nullptr; - mTargetDragContext = nullptr; -+#ifdef MOZ_WAYLAND -+ mTargetWaylandDragContext = nullptr; -+#endif - - // If we got another drag signal while running the sheduled task, that - // must have happened while running a nested event loop. Leave the task -@@ -1802,7 +1917,16 @@ void nsDragService::UpdateDragAction() { - - // default is to do nothing - int action = nsIDragService::DRAGDROP_ACTION_NONE; -- GdkDragAction gdkAction = gdk_drag_context_get_actions(mTargetDragContext); -+ GdkDragAction gdkAction = GDK_ACTION_DEFAULT; -+ if (mTargetDragContext) { -+ gdkAction = gdk_drag_context_get_actions(mTargetDragContext); -+ } -+#ifdef MOZ_WAYLAND -+ else if (mTargetWaylandDragContext) { -+ // We got the selected D&D action from compositor on Wayland. -+ gdkAction = mTargetWaylandDragContext->GetSelectedDragAction(); -+ } -+#endif - - // set the default just in case nothing matches below - if (gdkAction & GDK_ACTION_DEFAULT) -@@ -1830,6 +1954,12 @@ nsDragService::UpdateDragEffect() { - ReplyToDragMotion(mTargetDragContextForRemote); - mTargetDragContextForRemote = nullptr; - } -+#ifdef MOZ_WAYLAND -+ else if (mTargetWaylandDragContextForRemote) { -+ ReplyToDragMotion(mTargetWaylandDragContextForRemote); -+ mTargetWaylandDragContextForRemote = nullptr; -+ } -+#endif - return NS_OK; - } - -diff -up thunderbird-60.5.0/widget/gtk/nsDragService.h.wayland thunderbird-60.5.0/widget/gtk/nsDragService.h ---- thunderbird-60.5.0/widget/gtk/nsDragService.h.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsDragService.h 2019-02-05 14:26:16.976316645 +0100 -@@ -1,5 +1,5 @@ --/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ --/* vim: set ts=4 et sw=4 tw=80: */ -+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim: set ts=4 et sw=2 tw=80: */ - /* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -@@ -14,6 +14,7 @@ - #include - - class nsWindow; -+class nsWaylandDragContext; - - namespace mozilla { - namespace gfx { -@@ -91,10 +92,12 @@ class nsDragService final : public nsBas - guint aInfo, guint32 aTime); - - gboolean ScheduleMotionEvent(nsWindow *aWindow, GdkDragContext *aDragContext, -+ nsWaylandDragContext *aPendingWaylandDragContext, - mozilla::LayoutDeviceIntPoint aWindowPoint, - guint aTime); - void ScheduleLeaveEvent(); - gboolean ScheduleDropEvent(nsWindow *aWindow, GdkDragContext *aDragContext, -+ nsWaylandDragContext *aPendingWaylandDragContext, - mozilla::LayoutDeviceIntPoint aWindowPoint, - guint aTime); - -@@ -111,6 +114,8 @@ class nsDragService final : public nsBas - void SourceDataGet(GtkWidget *widget, GdkDragContext *context, - GtkSelectionData *selection_data, guint32 aTime); - -+ void SourceBeginDrag(GdkDragContext *aContext); -+ - // set the drag icon during drag-begin - void SetDragIcon(GdkDragContext *aContext); - -@@ -144,6 +149,9 @@ class nsDragService final : public nsBas - RefPtr mPendingWindow; - mozilla::LayoutDeviceIntPoint mPendingWindowPoint; - nsCountedRef mPendingDragContext; -+#ifdef MOZ_WAYLAND -+ RefPtr mPendingWaylandDragContext; -+#endif - guint mPendingTime; - - // mTargetWindow and mTargetWindowPoint record the position of the last -@@ -155,9 +163,15 @@ class nsDragService final : public nsBas - // motion or drop events. mTime records the corresponding timestamp. - nsCountedRef mTargetWidget; - nsCountedRef mTargetDragContext; -+#ifdef MOZ_WAYLAND -+ RefPtr mTargetWaylandDragContext; -+#endif - // mTargetDragContextForRemote is set while waiting for a reply from - // a child process. - nsCountedRef mTargetDragContextForRemote; -+#ifdef MOZ_WAYLAND -+ RefPtr mTargetWaylandDragContextForRemote; -+#endif - guint mTargetTime; - - // is it OK to drop on us? -@@ -196,6 +210,7 @@ class nsDragService final : public nsBas - - gboolean Schedule(DragTask aTask, nsWindow *aWindow, - GdkDragContext *aDragContext, -+ nsWaylandDragContext *aPendingWaylandDragContext, - mozilla::LayoutDeviceIntPoint aWindowPoint, guint aTime); - - // Callback for g_idle_add_full() to run mScheduledTask. -@@ -204,6 +219,9 @@ class nsDragService final : public nsBas - void UpdateDragAction(); - void DispatchMotionEvents(); - void ReplyToDragMotion(GdkDragContext *aDragContext); -+#ifdef MOZ_WAYLAND -+ void ReplyToDragMotion(nsWaylandDragContext *aDragContext); -+#endif - gboolean DispatchDropEvent(); - static uint32_t GetCurrentModifiers(); - }; -diff -up thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.cpp.wayland thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.cpp ---- thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.cpp.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.cpp 2019-02-05 14:26:16.976316645 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -28,6 +28,10 @@ - #include "mozilla/MouseEvents.h" - #include "mozilla/TextEvents.h" - -+#ifdef MOZ_WAYLAND -+#include -+#endif -+ - namespace mozilla { - namespace widget { - -@@ -200,7 +204,11 @@ void KeymapWrapper::Init() { - mModifierKeys.Clear(); - memset(mModifierMasks, 0, sizeof(mModifierMasks)); - -- if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) InitBySystemSettings(); -+ if (GDK_IS_X11_DISPLAY(gdk_display_get_default())) InitBySystemSettingsX11(); -+#ifdef MOZ_WAYLAND -+ else -+ InitBySystemSettingsWayland(); -+#endif - - gdk_window_add_filter(nullptr, FilterEvents, this); - -@@ -276,9 +284,9 @@ void KeymapWrapper::InitXKBExtension() { - ("%p InitXKBExtension, Succeeded", this)); - } - --void KeymapWrapper::InitBySystemSettings() { -+void KeymapWrapper::InitBySystemSettingsX11() { - MOZ_LOG(gKeymapWrapperLog, LogLevel::Info, -- ("%p InitBySystemSettings, mGdkKeymap=%p", this, mGdkKeymap)); -+ ("%p InitBySystemSettingsX11, mGdkKeymap=%p", this, mGdkKeymap)); - - Display* display = gdk_x11_display_get_xdisplay(gdk_display_get_default()); - -@@ -439,6 +447,163 @@ void KeymapWrapper::InitBySystemSettings - XFree(xkeymap); - } - -+#ifdef MOZ_WAYLAND -+void KeymapWrapper::SetModifierMask(xkb_keymap* aKeymap, -+ ModifierIndex aModifierIndex, -+ const char* aModifierName) { -+ static auto sXkbKeymapModGetIndex = -+ (xkb_mod_index_t(*)(struct xkb_keymap*, const char*))dlsym( -+ RTLD_DEFAULT, "xkb_keymap_mod_get_index"); -+ -+ xkb_mod_index_t index = sXkbKeymapModGetIndex(aKeymap, aModifierName); -+ if (index != XKB_MOD_INVALID) { -+ mModifierMasks[aModifierIndex] = (1 << index); -+ } -+} -+ -+void KeymapWrapper::SetModifierMasks(xkb_keymap* aKeymap) { -+ KeymapWrapper* keymapWrapper = GetInstance(); -+ -+ // This mapping is derived from get_xkb_modifiers() at gdkkeys-wayland.c -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_NUM_LOCK, XKB_MOD_NAME_NUM); -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_ALT, XKB_MOD_NAME_ALT); -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_META, "Meta"); -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_SUPER, "Super"); -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_HYPER, "Hyper"); -+ -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_SCROLL_LOCK, "ScrollLock"); -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_LEVEL3, "Level3"); -+ keymapWrapper->SetModifierMask(aKeymap, INDEX_LEVEL5, "Level5"); -+ -+ MOZ_LOG(gKeymapWrapperLog, LogLevel::Info, -+ ("%p KeymapWrapper::SetModifierMasks, CapsLock=0x%X, NumLock=0x%X, " -+ "ScrollLock=0x%X, Level3=0x%X, Level5=0x%X, " -+ "Shift=0x%X, Ctrl=0x%X, Alt=0x%X, Meta=0x%X, Super=0x%X, Hyper=0x%X", -+ keymapWrapper, keymapWrapper->GetModifierMask(CAPS_LOCK), -+ keymapWrapper->GetModifierMask(NUM_LOCK), -+ keymapWrapper->GetModifierMask(SCROLL_LOCK), -+ keymapWrapper->GetModifierMask(LEVEL3), -+ keymapWrapper->GetModifierMask(LEVEL5), -+ keymapWrapper->GetModifierMask(SHIFT), -+ keymapWrapper->GetModifierMask(CTRL), -+ keymapWrapper->GetModifierMask(ALT), -+ keymapWrapper->GetModifierMask(META), -+ keymapWrapper->GetModifierMask(SUPER), -+ keymapWrapper->GetModifierMask(HYPER))); -+} -+ -+/* This keymap routine is derived from weston-2.0.0/clients/simple-im.c -+ */ -+static void keyboard_handle_keymap(void* data, struct wl_keyboard* wl_keyboard, -+ uint32_t format, int fd, uint32_t size) { -+ if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) { -+ close(fd); -+ return; -+ } -+ -+ char* mapString = (char*)mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0); -+ if (mapString == MAP_FAILED) { -+ close(fd); -+ return; -+ } -+ -+ static auto sXkbContextNew = -+ (struct xkb_context * (*)(enum xkb_context_flags)) -+ dlsym(RTLD_DEFAULT, "xkb_context_new"); -+ static auto sXkbKeymapNewFromString = -+ (struct xkb_keymap * (*)(struct xkb_context*, const char*, -+ enum xkb_keymap_format, -+ enum xkb_keymap_compile_flags)) -+ dlsym(RTLD_DEFAULT, "xkb_keymap_new_from_string"); -+ -+ struct xkb_context* xkb_context = sXkbContextNew(XKB_CONTEXT_NO_FLAGS); -+ struct xkb_keymap* keymap = -+ sXkbKeymapNewFromString(xkb_context, mapString, XKB_KEYMAP_FORMAT_TEXT_V1, -+ XKB_KEYMAP_COMPILE_NO_FLAGS); -+ -+ munmap(mapString, size); -+ close(fd); -+ -+ if (!keymap) { -+ NS_WARNING("keyboard_handle_keymap(): Failed to compile keymap!\n"); -+ return; -+ } -+ -+ KeymapWrapper::SetModifierMasks(keymap); -+ -+ static auto sXkbKeymapUnRef = -+ (void (*)(struct xkb_keymap*))dlsym(RTLD_DEFAULT, "xkb_keymap_unref"); -+ sXkbKeymapUnRef(keymap); -+ -+ static auto sXkbContextUnref = -+ (void (*)(struct xkb_context*))dlsym(RTLD_DEFAULT, "xkb_context_unref"); -+ sXkbContextUnref(xkb_context); -+} -+ -+static void keyboard_handle_enter(void* data, struct wl_keyboard* keyboard, -+ uint32_t serial, struct wl_surface* surface, -+ struct wl_array* keys) {} -+static void keyboard_handle_leave(void* data, struct wl_keyboard* keyboard, -+ uint32_t serial, struct wl_surface* surface) { -+} -+static void keyboard_handle_key(void* data, struct wl_keyboard* keyboard, -+ uint32_t serial, uint32_t time, uint32_t key, -+ uint32_t state) {} -+static void keyboard_handle_modifiers(void* data, struct wl_keyboard* keyboard, -+ uint32_t serial, uint32_t mods_depressed, -+ uint32_t mods_latched, -+ uint32_t mods_locked, uint32_t group) {} -+ -+static const struct wl_keyboard_listener keyboard_listener = { -+ keyboard_handle_keymap, keyboard_handle_enter, keyboard_handle_leave, -+ keyboard_handle_key, keyboard_handle_modifiers, -+}; -+ -+static void seat_handle_capabilities(void* data, struct wl_seat* seat, -+ unsigned int caps) { -+ static wl_keyboard* keyboard = nullptr; -+ -+ if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !keyboard) { -+ keyboard = wl_seat_get_keyboard(seat); -+ wl_keyboard_add_listener(keyboard, &keyboard_listener, nullptr); -+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && keyboard) { -+ wl_keyboard_destroy(keyboard); -+ keyboard = nullptr; -+ } -+} -+ -+static const struct wl_seat_listener seat_listener = { -+ seat_handle_capabilities, -+}; -+ -+static void gdk_registry_handle_global(void* data, struct wl_registry* registry, -+ uint32_t id, const char* interface, -+ uint32_t version) { -+ if (strcmp(interface, "wl_seat") == 0) { -+ wl_seat* seat = -+ (wl_seat*)wl_registry_bind(registry, id, &wl_seat_interface, 1); -+ wl_seat_add_listener(seat, &seat_listener, data); -+ } -+} -+ -+static void gdk_registry_handle_global_remove(void* data, -+ struct wl_registry* registry, -+ uint32_t id) {} -+ -+static const struct wl_registry_listener keyboard_registry_listener = { -+ gdk_registry_handle_global, gdk_registry_handle_global_remove}; -+ -+void KeymapWrapper::InitBySystemSettingsWayland() { -+ // Available as of GTK 3.8+ -+ static auto sGdkWaylandDisplayGetWlDisplay = (wl_display * (*)(GdkDisplay*)) -+ dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display"); -+ wl_display* display = -+ sGdkWaylandDisplayGetWlDisplay(gdk_display_get_default()); -+ wl_registry_add_listener(wl_display_get_registry(display), -+ &keyboard_registry_listener, this); -+} -+#endif -+ - KeymapWrapper::~KeymapWrapper() { - gdk_window_remove_filter(nullptr, FilterEvents, this); - g_signal_handlers_disconnect_by_func(mGdkKeymap, -@@ -1473,6 +1638,14 @@ void KeymapWrapper::WillDispatchKeyboard - - void KeymapWrapper::WillDispatchKeyboardEventInternal( - WidgetKeyboardEvent& aKeyEvent, GdkEventKey* aGdkKeyEvent) { -+ if (!aGdkKeyEvent) { -+ // If aGdkKeyEvent is nullptr, we're trying to dispatch a fake keyboard -+ // event in such case, we don't need to set alternative char codes. -+ // So, we don't need to do nothing here. This case is typically we're -+ // dispatching eKeyDown or eKeyUp event during composition. -+ return; -+ } -+ - uint32_t charCode = GetCharCodeFor(aGdkKeyEvent); - if (!charCode) { - MOZ_LOG(gKeymapWrapperLog, LogLevel::Info, -diff -up thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.h.wayland thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.h ---- thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.h.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsGtkKeyUtils.h 2019-02-05 14:26:16.976316645 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -13,6 +13,10 @@ - - #include - #include -+#ifdef MOZ_WAYLAND -+#include -+#include -+#endif - - namespace mozilla { - namespace widget { -@@ -145,6 +149,14 @@ class KeymapWrapper { - static void WillDispatchKeyboardEvent(WidgetKeyboardEvent& aKeyEvent, - GdkEventKey* aGdkKeyEvent); - -+#ifdef MOZ_WAYLAND -+ /** -+ * Utility function to set all supported modifier masks -+ * from xkb_keymap. We call that from Wayland backend routines. -+ */ -+ static void SetModifierMasks(xkb_keymap* aKeymap); -+#endif -+ - /** - * Destroys the singleton KeymapWrapper instance, if it exists. - */ -@@ -168,7 +180,10 @@ class KeymapWrapper { - */ - void Init(); - void InitXKBExtension(); -- void InitBySystemSettings(); -+ void InitBySystemSettingsX11(); -+#ifdef MOZ_WAYLAND -+ void InitBySystemSettingsWayland(); -+#endif - - /** - * mModifierKeys stores each hardware key information. -@@ -360,6 +375,14 @@ class KeymapWrapper { - */ - void WillDispatchKeyboardEventInternal(WidgetKeyboardEvent& aKeyEvent, - GdkEventKey* aGdkKeyEvent); -+ -+#ifdef MOZ_WAYLAND -+ /** -+ * Utility function to set Xkb modifier key mask. -+ */ -+ void SetModifierMask(xkb_keymap* aKeymap, ModifierIndex aModifierIndex, -+ const char* aModifierName); -+#endif - }; - - } // namespace widget -diff -up thunderbird-60.5.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60.5.0/widget/gtk/nsLookAndFeel.cpp ---- thunderbird-60.5.0/widget/gtk/nsLookAndFeel.cpp.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsLookAndFeel.cpp 2019-02-05 14:26:16.977316642 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -18,6 +18,7 @@ - - #include - #include "gfxPlatformGtk.h" -+//#include "mozilla/FontPropertyTypes.h" - #include "ScreenHelperGTK.h" - - #include "gtkdrawing.h" -@@ -31,7 +32,9 @@ - #include - #include "WidgetStyleCache.h" - #include "prenv.h" -+#include "nsCSSColorUtils.h" - -+using namespace mozilla; - using mozilla::LookAndFeel; - - #define GDK_COLOR_TO_NS_RGB(c) \ -@@ -170,7 +173,7 @@ static bool GetBorderColors(GtkStyleCont - // GTK has an initial value of zero for border-widths, and so themes - // need to explicitly set border-widths to make borders visible. - GtkBorder border; -- gtk_style_context_get_border(aContext, GTK_STATE_FLAG_NORMAL, &border); -+ gtk_style_context_get_border(aContext, state, &border); - visible = border.top != 0 || border.right != 0 || border.bottom != 0 || - border.left != 0; - } -@@ -199,6 +202,57 @@ static bool GetBorderColors(GtkStyleCont - return ret; - } - -+// Finds ideal cell highlight colors used for unfocused+selected cells distinct -+// from both Highlight, used as focused+selected background, and the listbox -+// background which is assumed to be similar to -moz-field -+nsresult nsLookAndFeel::InitCellHighlightColors() { -+ // NS_SUFFICIENT_LUMINOSITY_DIFFERENCE is the a11y standard for text -+ // on a background. Use 20% of that standard since we have a background -+ // on top of another background -+ int32_t minLuminosityDifference = NS_SUFFICIENT_LUMINOSITY_DIFFERENCE / 5; -+ int32_t backLuminosityDifference = -+ NS_LUMINOSITY_DIFFERENCE(mMozWindowBackground, mMozFieldBackground); -+ if (backLuminosityDifference >= minLuminosityDifference) { -+ mMozCellHighlightBackground = mMozWindowBackground; -+ mMozCellHighlightText = mMozWindowText; -+ return NS_OK; -+ } -+ -+ uint16_t hue, sat, luminance; -+ uint8_t alpha; -+ mMozCellHighlightBackground = mMozFieldBackground; -+ mMozCellHighlightText = mMozFieldText; -+ -+ NS_RGB2HSV(mMozCellHighlightBackground, hue, sat, luminance, alpha); -+ -+ uint16_t step = 30; -+ // Lighten the color if the color is very dark -+ if (luminance <= step) { -+ luminance += step; -+ } -+ // Darken it if it is very light -+ else if (luminance >= 255 - step) { -+ luminance -= step; -+ } -+ // Otherwise, compute what works best depending on the text luminance. -+ else { -+ uint16_t textHue, textSat, textLuminance; -+ uint8_t textAlpha; -+ NS_RGB2HSV(mMozCellHighlightText, textHue, textSat, textLuminance, -+ textAlpha); -+ // Text is darker than background, use a lighter shade -+ if (textLuminance < luminance) { -+ luminance += step; -+ } -+ // Otherwise, use a darker shade -+ else { -+ luminance -= step; -+ } -+ } -+ NS_HSV2RGB(mMozCellHighlightBackground, hue, sat, luminance, alpha); -+ return NS_OK; -+} -+ - void nsLookAndFeel::NativeInit() { EnsureInit(); } - - void nsLookAndFeel::RefreshImpl() { -@@ -248,7 +302,6 @@ nsresult nsLookAndFeel::NativeGetColor(C - case eColorID_IMESelectedRawTextBackground: - case eColorID_IMESelectedConvertedTextBackground: - case eColorID__moz_dragtargetzone: -- case eColorID__moz_cellhighlight: - case eColorID__moz_html_cellhighlight: - case eColorID_highlight: // preference selected item, - aColor = mTextSelectedBackground; -@@ -258,10 +311,15 @@ nsresult nsLookAndFeel::NativeGetColor(C - case eColorID_IMESelectedRawTextForeground: - case eColorID_IMESelectedConvertedTextForeground: - case eColorID_highlighttext: -- case eColorID__moz_cellhighlighttext: - case eColorID__moz_html_cellhighlighttext: - aColor = mTextSelectedText; - break; -+ case eColorID__moz_cellhighlight: -+ aColor = mMozCellHighlightBackground; -+ break; -+ case eColorID__moz_cellhighlighttext: -+ aColor = mMozCellHighlightText; -+ break; - case eColorID_Widget3DHighlight: - aColor = NS_RGB(0xa0, 0xa0, 0xa0); - break; -@@ -961,6 +1019,9 @@ void nsLookAndFeel::EnsureInit() { - mOddCellBackground = GDK_RGBA_TO_NS_RGBA(color); - gtk_style_context_restore(style); - -+ // Compute cell highlight colors -+ InitCellHighlightColors(); -+ - // GtkFrame has a "border" subnode on which Adwaita draws the border. - // Some themes do not draw on this node but draw a border on the widget - // root node, so check the root node if no border is found on the border -diff -up thunderbird-60.5.0/widget/gtk/nsLookAndFeel.h.wayland thunderbird-60.5.0/widget/gtk/nsLookAndFeel.h ---- thunderbird-60.5.0/widget/gtk/nsLookAndFeel.h.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsLookAndFeel.h 2019-02-05 14:26:16.977316642 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -8,6 +8,7 @@ - #ifndef __nsLookAndFeel - #define __nsLookAndFeel - -+#include "X11UndefineNone.h" - #include "nsXPLookAndFeel.h" - #include "nsCOMPtr.h" - #include "gfxFont.h" -@@ -75,6 +76,8 @@ class nsLookAndFeel final : public nsXPL - nscolor mMozWindowActiveBorder; - nscolor mMozWindowInactiveBorder; - nscolor mMozWindowInactiveCaption; -+ nscolor mMozCellHighlightBackground; -+ nscolor mMozCellHighlightText; - nscolor mTextSelectedText; - nscolor mTextSelectedBackground; - nscolor mMozScrollbar; -@@ -89,6 +92,9 @@ class nsLookAndFeel final : public nsXPL - bool mInitialized; - - void EnsureInit(); -+ -+ private: -+ nsresult InitCellHighlightColors(); - }; - - #endif -diff -up thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.cpp.wayland thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.cpp ---- thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.cpp.wayland 2019-02-05 14:26:16.977316642 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.cpp 2019-02-05 14:26:16.977316642 +0100 -@@ -0,0 +1,222 @@ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim:expandtab:shiftwidth=4:tabstop=4: -+ */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#include "nsWaylandDisplay.h" -+ -+#include "base/message_loop.h" // for MessageLoop -+#include "base/task.h" // for NewRunnableMethod, etc -+#include "mozilla/StaticMutex.h" -+ -+namespace mozilla { -+namespace widget { -+ -+#define MAX_DISPLAY_CONNECTIONS 2 -+ -+static nsWaylandDisplay *gWaylandDisplays[MAX_DISPLAY_CONNECTIONS]; -+static StaticMutex gWaylandDisplaysMutex; -+ -+// Each thread which is using wayland connection (wl_display) has to operate -+// its own wl_event_queue. Main Firefox thread wl_event_queue is handled -+// by Gtk main loop, other threads/wl_event_queue has to be handled by us. -+// -+// nsWaylandDisplay is our interface to wayland compositor. It provides wayland -+// global objects as we need (wl_display, wl_shm) and operates wl_event_queue on -+// compositor (not the main) thread. -+static void WaylandDisplayLoop(wl_display *aDisplay); -+ -+// Get WaylandDisplay for given wl_display and actual calling thread. -+static nsWaylandDisplay *WaylandDisplayGetLocked(wl_display *aDisplay, -+ const StaticMutexAutoLock &) { -+ for (auto &display : gWaylandDisplays) { -+ if (display && display->Matches(aDisplay)) { -+ NS_ADDREF(display); -+ return display; -+ } -+ } -+ -+ for (auto &display : gWaylandDisplays) { -+ if (display == nullptr) { -+ display = new nsWaylandDisplay(aDisplay); -+ NS_ADDREF(display); -+ return display; -+ } -+ } -+ -+ MOZ_CRASH("There's too many wayland display conections!"); -+ return nullptr; -+} -+ -+nsWaylandDisplay *WaylandDisplayGet(GdkDisplay *aGdkDisplay) { -+ if (!aGdkDisplay) { -+ aGdkDisplay = gdk_display_get_default(); -+ } -+ -+ // Available as of GTK 3.8+ -+ static auto sGdkWaylandDisplayGetWlDisplay = (wl_display * (*)(GdkDisplay *)) -+ dlsym(RTLD_DEFAULT, "gdk_wayland_display_get_wl_display"); -+ -+ wl_display *display = sGdkWaylandDisplayGetWlDisplay(aGdkDisplay); -+ -+ StaticMutexAutoLock lock(gWaylandDisplaysMutex); -+ return WaylandDisplayGetLocked(display, lock); -+} -+ -+static bool WaylandDisplayReleaseLocked(nsWaylandDisplay *aDisplay, -+ const StaticMutexAutoLock &) { -+ for (auto &display : gWaylandDisplays) { -+ if (display == aDisplay) { -+ int rc = display->Release(); -+ if (rc == 0) { -+ display = nullptr; -+ } -+ return true; -+ } -+ } -+ MOZ_ASSERT(false, "Missing nsWaylandDisplay for this thread!"); -+ return false; -+} -+ -+void WaylandDisplayRelease(nsWaylandDisplay *aDisplay) { -+ StaticMutexAutoLock lock(gWaylandDisplaysMutex); -+ WaylandDisplayReleaseLocked(aDisplay, lock); -+} -+ -+static void WaylandDisplayLoopLocked(wl_display *aDisplay, -+ const StaticMutexAutoLock &) { -+ for (auto &display : gWaylandDisplays) { -+ if (display && display->Matches(aDisplay)) { -+ if (display->DisplayLoop()) { -+ MessageLoop::current()->PostDelayedTask( -+ NewRunnableFunction("WaylandDisplayLoop", &WaylandDisplayLoop, -+ aDisplay), -+ EVENT_LOOP_DELAY); -+ } -+ break; -+ } -+ } -+} -+ -+static void WaylandDisplayLoop(wl_display *aDisplay) { -+ MOZ_ASSERT(!NS_IsMainThread()); -+ StaticMutexAutoLock lock(gWaylandDisplaysMutex); -+ WaylandDisplayLoopLocked(aDisplay, lock); -+} -+ -+void nsWaylandDisplay::SetShm(wl_shm *aShm) { mShm = aShm; } -+ -+void nsWaylandDisplay::SetSubcompositor(wl_subcompositor *aSubcompositor) { -+ mSubcompositor = aSubcompositor; -+} -+ -+void nsWaylandDisplay::SetDataDeviceManager( -+ wl_data_device_manager *aDataDeviceManager) { -+ mDataDeviceManager = aDataDeviceManager; -+} -+ -+void nsWaylandDisplay::SetSeat(wl_seat *aSeat) { mSeat = aSeat; } -+ -+void nsWaylandDisplay::SetPrimarySelectionDeviceManager( -+ gtk_primary_selection_device_manager *aPrimarySelectionDeviceManager) { -+ mPrimarySelectionDeviceManager = aPrimarySelectionDeviceManager; -+} -+ -+static void global_registry_handler(void *data, wl_registry *registry, -+ uint32_t id, const char *interface, -+ uint32_t version) { -+ auto display = reinterpret_cast(data); -+ -+ if (strcmp(interface, "wl_shm") == 0) { -+ auto shm = static_cast( -+ wl_registry_bind(registry, id, &wl_shm_interface, 1)); -+ wl_proxy_set_queue((struct wl_proxy *)shm, display->GetEventQueue()); -+ display->SetShm(shm); -+ } else if (strcmp(interface, "wl_data_device_manager") == 0) { -+ int data_device_manager_version = MIN(version, 3); -+ auto data_device_manager = static_cast( -+ wl_registry_bind(registry, id, &wl_data_device_manager_interface, -+ data_device_manager_version)); -+ wl_proxy_set_queue((struct wl_proxy *)data_device_manager, -+ display->GetEventQueue()); -+ display->SetDataDeviceManager(data_device_manager); -+ } else if (strcmp(interface, "wl_seat") == 0) { -+ auto seat = static_cast( -+ wl_registry_bind(registry, id, &wl_seat_interface, 1)); -+ wl_proxy_set_queue((struct wl_proxy *)seat, display->GetEventQueue()); -+ display->SetSeat(seat); -+ } else if (strcmp(interface, "gtk_primary_selection_device_manager") == 0) { -+ auto primary_selection_device_manager = -+ static_cast(wl_registry_bind( -+ registry, id, >k_primary_selection_device_manager_interface, 1)); -+ wl_proxy_set_queue((struct wl_proxy *)primary_selection_device_manager, -+ display->GetEventQueue()); -+ display->SetPrimarySelectionDeviceManager(primary_selection_device_manager); -+ } else if (strcmp(interface, "wl_subcompositor") == 0) { -+ auto subcompositor = static_cast( -+ wl_registry_bind(registry, id, &wl_subcompositor_interface, 1)); -+ wl_proxy_set_queue((struct wl_proxy *)subcompositor, -+ display->GetEventQueue()); -+ display->SetSubcompositor(subcompositor); -+ } -+} -+ -+static void global_registry_remover(void *data, wl_registry *registry, -+ uint32_t id) {} -+ -+static const struct wl_registry_listener registry_listener = { -+ global_registry_handler, global_registry_remover}; -+ -+bool nsWaylandDisplay::DisplayLoop() { -+ wl_display_dispatch_queue_pending(mDisplay, mEventQueue); -+ return true; -+} -+ -+bool nsWaylandDisplay::Matches(wl_display *aDisplay) { -+ return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay; -+} -+ -+NS_IMPL_ISUPPORTS(nsWaylandDisplay, nsISupports); -+ -+nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay) -+ : mThreadId(PR_GetCurrentThread()), -+ mDisplay(aDisplay), -+ mEventQueue(nullptr), -+ mDataDeviceManager(nullptr), -+ mSubcompositor(nullptr), -+ mSeat(nullptr), -+ mShm(nullptr), -+ mPrimarySelectionDeviceManager(nullptr) { -+ wl_registry *registry = wl_display_get_registry(mDisplay); -+ wl_registry_add_listener(registry, ®istry_listener, this); -+ -+ if (NS_IsMainThread()) { -+ // Use default event queue in main thread operated by Gtk+. -+ mEventQueue = nullptr; -+ wl_display_roundtrip(mDisplay); -+ wl_display_roundtrip(mDisplay); -+ } else { -+ mEventQueue = wl_display_create_queue(mDisplay); -+ MessageLoop::current()->PostTask(NewRunnableFunction( -+ "WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay)); -+ wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue); -+ wl_display_roundtrip_queue(mDisplay, mEventQueue); -+ wl_display_roundtrip_queue(mDisplay, mEventQueue); -+ } -+} -+ -+nsWaylandDisplay::~nsWaylandDisplay() { -+ MOZ_ASSERT(mThreadId == PR_GetCurrentThread()); -+ // Owned by Gtk+, we don't need to release -+ mDisplay = nullptr; -+ -+ if (mEventQueue) { -+ wl_event_queue_destroy(mEventQueue); -+ mEventQueue = nullptr; -+ } -+} -+ -+} // namespace widget -+} // namespace mozilla -diff -up thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.h.wayland thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.h ---- thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.h.wayland 2019-02-05 14:26:16.977316642 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsWaylandDisplay.h 2019-02-05 14:26:16.977316642 +0100 -@@ -0,0 +1,72 @@ -+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -+/* vim:expandtab:shiftwidth=4:tabstop=4: -+ */ -+/* This Source Code Form is subject to the terms of the Mozilla Public -+ * License, v. 2.0. If a copy of the MPL was not distributed with this -+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -+ -+#ifndef __MOZ_WAYLAND_REGISTRY_H__ -+#define __MOZ_WAYLAND_REGISTRY_H__ -+ -+#include "nsISupports.h" -+#include "mozwayland/mozwayland.h" -+#include "wayland/gtk-primary-selection-client-protocol.h" -+ -+namespace mozilla { -+namespace widget { -+ -+// TODO: Bug 1467125 - We need to integrate wl_display_dispatch_queue_pending() -+// with compositor event loop. -+#define EVENT_LOOP_DELAY (1000 / 240) -+ -+// Our general connection to Wayland display server, -+// holds our display connection and runs event loop. -+class nsWaylandDisplay : public nsISupports { -+ NS_DECL_THREADSAFE_ISUPPORTS -+ -+ public: -+ explicit nsWaylandDisplay(wl_display* aDisplay); -+ -+ bool DisplayLoop(); -+ bool Matches(wl_display* aDisplay); -+ -+ wl_display* GetDisplay() { return mDisplay; }; -+ wl_event_queue* GetEventQueue() { return mEventQueue; }; -+ wl_subcompositor* GetSubcompositor(void) { return mSubcompositor; }; -+ wl_data_device_manager* GetDataDeviceManager(void) { -+ return mDataDeviceManager; -+ }; -+ wl_seat* GetSeat(void) { return mSeat; }; -+ wl_shm* GetShm(void) { return mShm; }; -+ gtk_primary_selection_device_manager* GetPrimarySelectionDeviceManager(void) { -+ return mPrimarySelectionDeviceManager; -+ }; -+ -+ public: -+ void SetShm(wl_shm* aShm); -+ void SetSubcompositor(wl_subcompositor* aSubcompositor); -+ void SetDataDeviceManager(wl_data_device_manager* aDataDeviceManager); -+ void SetSeat(wl_seat* aSeat); -+ void SetPrimarySelectionDeviceManager( -+ gtk_primary_selection_device_manager* aPrimarySelectionDeviceManager); -+ -+ private: -+ virtual ~nsWaylandDisplay(); -+ -+ PRThread* mThreadId; -+ wl_display* mDisplay; -+ wl_event_queue* mEventQueue; -+ wl_data_device_manager* mDataDeviceManager; -+ wl_subcompositor* mSubcompositor; -+ wl_seat* mSeat; -+ wl_shm* mShm; -+ gtk_primary_selection_device_manager* mPrimarySelectionDeviceManager; -+}; -+ -+nsWaylandDisplay* WaylandDisplayGet(GdkDisplay* aGdkDisplay = nullptr); -+void WaylandDisplayRelease(nsWaylandDisplay* aDisplay); -+ -+} // namespace widget -+} // namespace mozilla -+ -+#endif // __MOZ_WAYLAND_REGISTRY_H__ -diff -up thunderbird-60.5.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.5.0/widget/gtk/nsWindow.cpp ---- thunderbird-60.5.0/widget/gtk/nsWindow.cpp.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsWindow.cpp 2019-02-05 14:26:16.978316639 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -18,6 +18,7 @@ - #include "mozilla/TouchEvents.h" - #include "mozilla/UniquePtrExtensions.h" - #include "mozilla/WidgetUtils.h" -+#include "mozilla/dom/WheelEventBinding.h" - #include - - #include "GeckoProfiler.h" -@@ -25,13 +26,15 @@ - #include "prlink.h" - #include "nsGTKToolkit.h" - #include "nsIRollupListener.h" --#include "nsIDOMNode.h" -+#include "nsINode.h" - - #include "nsWidgetsCID.h" - #include "nsDragService.h" - #include "nsIWidgetListener.h" - #include "nsIScreenManager.h" - #include "SystemTimeConverter.h" -+#include "nsIPresShell.h" -+#include "nsViewManager.h" - - #include "nsGtkKeyUtils.h" - #include "nsGtkCursors.h" -@@ -56,6 +59,7 @@ - - #if defined(MOZ_WAYLAND) - #include -+#include "nsView.h" - #endif - - #include "nsGkAtoms.h" -@@ -116,6 +120,7 @@ using namespace mozilla::widget; - #include "mozilla/layers/CompositorThread.h" - - #ifdef MOZ_X11 -+#include "GLContextGLX.h" // for GLContextGLX::FindVisual() - #include "GtkCompositorWidget.h" - #include "gfxXlibSurface.h" - #include "WindowSurfaceX11Image.h" -@@ -129,8 +134,6 @@ using namespace mozilla::widget; - #include "nsShmImage.h" - #include "gtkdrawing.h" - --#include "nsIDOMWheelEvent.h" -- - #include "NativeKeyBindings.h" - - #include -@@ -140,6 +143,7 @@ using namespace mozilla::gfx; - using namespace mozilla::widget; - using namespace mozilla::layers; - using mozilla::gl::GLContext; -+using mozilla::gl::GLContextGLX; - - // Don't put more than this many rects in the dirty region, just fluff - // out to the bounding-box if there are more -@@ -152,9 +156,12 @@ const gint kEvents = - #if GTK_CHECK_VERSION(3, 4, 0) - GDK_SMOOTH_SCROLL_MASK | GDK_TOUCH_MASK | - #endif -- GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK; -+ GDK_SCROLL_MASK | GDK_POINTER_MOTION_MASK | GDK_PROPERTY_CHANGE_MASK | -+ GDK_FOCUS_CHANGE_MASK; - - /* utility functions */ -+static void theme_changed_cb(GtkSettings *settings, GParamSpec *pspec, -+ nsWindow *data); - static bool is_mouse_in_window(GdkWindow *aWindow, gdouble aMouseX, - gdouble aMouseY); - static nsWindow *get_window_for_gtk_widget(GtkWidget *widget); -@@ -196,8 +203,6 @@ static void hierarchy_changed_cb(GtkWidg - GtkWidget *previous_toplevel); - static gboolean window_state_event_cb(GtkWidget *widget, - GdkEventWindowState *event); --static void theme_changed_cb(GtkSettings *settings, GParamSpec *pspec, -- nsWindow *data); - static void check_resize_cb(GtkContainer *container, gpointer user_data); - static void screen_composited_changed_cb(GdkScreen *screen, gpointer user_data); - static void widget_composited_changed_cb(GtkWidget *widget, gpointer user_data); -@@ -550,7 +555,7 @@ static GtkWidget *EnsureInvisibleContain - } - - static void CheckDestroyInvisibleContainer() { -- NS_PRECONDITION(gInvisibleContainer, "oh, no"); -+ MOZ_ASSERT(gInvisibleContainer, "oh, no"); - - if (!gdk_window_peek_children(gtk_widget_get_window(gInvisibleContainer))) { - // No children, so not in use. -@@ -639,9 +644,6 @@ void nsWindow::Destroy() { - - ClearCachedResources(); - -- g_signal_handlers_disconnect_by_func(gtk_settings_get_default(), -- FuncToGpointer(theme_changed_cb), this); -- - nsIRollupListener *rollupListener = nsBaseWidget::GetActiveRollupListener(); - if (rollupListener) { - nsCOMPtr rollupWidget = rollupListener->GetRollupWidget(); -@@ -725,7 +727,7 @@ double nsWindow::GetDefaultScaleInternal - DesktopToLayoutDeviceScale nsWindow::GetDesktopToDeviceScale() { - #ifdef MOZ_WAYLAND - GdkDisplay *gdkDisplay = gdk_display_get_default(); -- if (GDK_IS_WAYLAND_DISPLAY(gdkDisplay)) { -+ if (!GDK_IS_X11_DISPLAY(gdkDisplay)) { - return DesktopToLayoutDeviceScale(GdkScaleFactor()); - } - #endif -@@ -735,8 +737,14 @@ DesktopToLayoutDeviceScale nsWindow::Get - } - - void nsWindow::SetParent(nsIWidget *aNewParent) { -- if (mContainer || !mGdkWindow) { -- NS_NOTREACHED("nsWindow::SetParent called illegally"); -+ if (!mGdkWindow) { -+ MOZ_ASSERT_UNREACHABLE("The native window has already been destroyed"); -+ return; -+ } -+ -+ if (mContainer) { -+ // FIXME bug 1469183 -+ NS_ERROR("nsWindow should not have a container here"); - return; - } - -@@ -774,7 +782,7 @@ void nsWindow::SetParent(nsIWidget *aNew - bool nsWindow::WidgetTypeSupportsAcceleration() { return !IsSmallPopup(); } - - void nsWindow::ReparentNativeWidget(nsIWidget *aNewParent) { -- NS_PRECONDITION(aNewParent, ""); -+ MOZ_ASSERT(aNewParent, "null widget"); - NS_ASSERTION(!mIsDestroyed, ""); - NS_ASSERTION(!static_cast(aNewParent)->mIsDestroyed, ""); - -@@ -1331,7 +1339,7 @@ LayoutDeviceIntRect nsWindow::GetClientB - } - - void nsWindow::UpdateClientOffset() { -- AUTO_PROFILER_LABEL("nsWindow::UpdateClientOffset", GRAPHICS); -+ AUTO_PROFILER_LABEL("nsWindow::UpdateClientOffset", OTHER); - - if (!mIsTopLevel || !mShell || !mIsX11Display || - gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP) { -@@ -1373,9 +1381,7 @@ LayoutDeviceIntPoint nsWindow::GetClient - } - - gboolean nsWindow::OnPropertyNotifyEvent(GtkWidget *aWidget, -- GdkEventProperty *aEvent) -- --{ -+ GdkEventProperty *aEvent) { - if (aEvent->atom == gdk_atom_intern("_NET_FRAME_EXTENTS", FALSE)) { - UpdateClientOffset(); - -@@ -1820,6 +1826,9 @@ gboolean nsWindow::OnExposeEvent(cairo_t - - // Windows that are not visible will be painted after they become visible. - if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel) return FALSE; -+#ifdef MOZ_WAYLAND -+ if (mContainer && !mContainer->ready_to_draw) return FALSE; -+#endif - - nsIWidgetListener *listener = GetListener(); - if (!listener) return FALSE; -@@ -3000,6 +3009,33 @@ void nsWindow::OnWindowStateEvent(GtkWid - } - // else the widget is a shell widget. - -+ // The block below is a bit evil. -+ // -+ // When a window is resized before it is shown, gtk_window_resize() delays -+ // resizes until the window is shown. If gtk_window_state_event() sees a -+ // GDK_WINDOW_STATE_MAXIMIZED change [1] before the window is shown, then -+ // gtk_window_compute_configure_request_size() ignores the values from the -+ // resize [2]. See bug 1449166 for an example of how this could happen. -+ // -+ // [1] https://gitlab.gnome.org/GNOME/gtk/blob/3.22.30/gtk/gtkwindow.c#L7967 -+ // [2] https://gitlab.gnome.org/GNOME/gtk/blob/3.22.30/gtk/gtkwindow.c#L9377 -+ // -+ // In order to provide a sensible size for the window when the user exits -+ // maximized state, we hide the GDK_WINDOW_STATE_MAXIMIZED change from -+ // gtk_window_state_event() so as to trick GTK into using the values from -+ // gtk_window_resize() in its configure request. -+ // -+ // We instead notify gtk_window_state_event() of the maximized state change -+ // once the window is shown. -+ if (!mIsShown) { -+ aEvent->changed_mask = static_cast( -+ aEvent->changed_mask & ~GDK_WINDOW_STATE_MAXIMIZED); -+ } else if (aEvent->changed_mask & GDK_WINDOW_STATE_WITHDRAWN && -+ aEvent->new_window_state & GDK_WINDOW_STATE_MAXIMIZED) { -+ aEvent->changed_mask = static_cast( -+ aEvent->changed_mask | GDK_WINDOW_STATE_MAXIMIZED); -+ } -+ - // We don't care about anything but changes in the maximized/icon/fullscreen - // states - if ((aEvent->changed_mask & -@@ -3075,6 +3111,7 @@ void nsWindow::OnDPIChanged() { - // Update menu's font size etc - presShell->ThemeChanged(); - } -+ mWidgetListener->UIResolutionChanged(); - } - } - -@@ -3443,13 +3480,15 @@ nsresult nsWindow::Create(nsIWidget *aPa - 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); - -+ gtk_widget_add_events(eventWidget, kEvents); -+ if (drawToContainer) { -+ gtk_widget_add_events(mShell, GDK_PROPERTY_CHANGE_MASK); -+ gtk_widget_set_app_paintable(mShell, TRUE); -+ } -+ - // If we draw to mContainer window then configure it now because - // gtk_container_add() realizes the child widget. - gtk_widget_set_has_window(container, drawToContainer); -@@ -3698,6 +3737,15 @@ nsresult nsWindow::Create(nsIWidget *aPa - mXDepth = gdk_visual_get_depth(gdkVisual); - - mSurfaceProvider.Initialize(mXDisplay, mXWindow, mXVisual, mXDepth); -+ -+ if (mIsTopLevel) { -+ // Set window manager hint to keep fullscreen windows composited. -+ // -+ // If the window were to get unredirected, there could be visible -+ // tearing because Gecko does not align its framebuffer updates with -+ // vblank. -+ // SetCompositorHint(GTK_WIDGET_COMPOSIDED_ENABLED); -+ } - } - #ifdef MOZ_WAYLAND - else if (!mIsX11Display) { -@@ -3708,12 +3756,37 @@ nsresult nsWindow::Create(nsIWidget *aPa - return NS_OK; - } - -+void nsWindow::RefreshWindowClass(void) { -+ if (mGtkWindowTypeName.IsEmpty() || mGtkWindowRoleName.IsEmpty()) return; -+ -+ GdkWindow *gdkWindow = gtk_widget_get_window(mShell); -+ gdk_window_set_role(gdkWindow, mGtkWindowRoleName.get()); -+ -+#ifdef MOZ_X11 -+ if (mIsX11Display) { -+ XClassHint *class_hint = XAllocClassHint(); -+ if (!class_hint) { -+ return; -+ } -+ const char *res_class = gdk_get_program_class(); -+ if (!res_class) return; -+ -+ class_hint->res_name = const_cast(mGtkWindowTypeName.get()); -+ class_hint->res_class = const_cast(res_class); -+ -+ // Can't use gtk_window_set_wmclass() for this; it prints -+ // a warning & refuses to make the change. -+ GdkDisplay *display = gdk_display_get_default(); -+ XSetClassHint(GDK_DISPLAY_XDISPLAY(display), -+ gdk_x11_window_get_xid(gdkWindow), class_hint); -+ XFree(class_hint); -+ } -+#endif /* MOZ_X11 */ -+} -+ - void nsWindow::SetWindowClass(const nsAString &xulWinType) { - if (!mShell) return; - -- const char *res_class = gdk_get_program_class(); -- if (!res_class) return; -- - char *res_name = ToNewCString(xulWinType); - if (!res_name) return; - -@@ -3733,29 +3806,11 @@ void nsWindow::SetWindowClass(const nsAS - res_name[0] = toupper(res_name[0]); - if (!role) role = res_name; - -- GdkWindow *gdkWindow = gtk_widget_get_window(mShell); -- gdk_window_set_role(gdkWindow, role); -- --#ifdef MOZ_X11 -- if (mIsX11Display) { -- XClassHint *class_hint = XAllocClassHint(); -- if (!class_hint) { -- free(res_name); -- return; -- } -- class_hint->res_name = res_name; -- class_hint->res_class = const_cast(res_class); -- -- // Can't use gtk_window_set_wmclass() for this; it prints -- // a warning & refuses to make the change. -- GdkDisplay *display = gdk_display_get_default(); -- XSetClassHint(GDK_DISPLAY_XDISPLAY(display), -- gdk_x11_window_get_xid(gdkWindow), class_hint); -- XFree(class_hint); -- } --#endif /* MOZ_X11 */ -- -+ mGtkWindowTypeName = res_name; -+ mGtkWindowRoleName = role; - free(res_name); -+ -+ RefreshWindowClass(); - } - - void nsWindow::NativeResize() { -@@ -3820,6 +3875,8 @@ void nsWindow::NativeMoveResize() { - NativeShow(false); - } - NativeMove(); -+ -+ return; - } - - GdkRectangle size = DevicePixelsToGdkSizeRoundUp(mBounds.Size()); -@@ -3832,6 +3889,8 @@ void nsWindow::NativeMoveResize() { - // x and y give the position of the window manager frame top-left. - gtk_window_move(GTK_WINDOW(mShell), topLeft.x, topLeft.y); - // This sets the client window size. -+ MOZ_ASSERT(size.width > 0 && size.height > 0, -+ "Can't resize window smaller than 1x1."); - gtk_window_resize(GTK_WINDOW(mShell), size.width, size.height); - } else if (mContainer) { - GtkAllocation allocation; -@@ -3877,6 +3936,16 @@ void nsWindow::NativeShow(bool aAction) - gdk_window_show_unraised(mGdkWindow); - } - } else { -+#ifdef MOZ_WAYLAND -+ if (mContainer && moz_container_has_wl_egl_window(mContainer)) { -+ // Because wl_egl_window is destroyed on moz_container_unmap(), -+ // the current compositor cannot use it anymore. To avoid crash, -+ // destroy the compositor & recreate a new compositor on next -+ // expose event. -+ DestroyLayerManager(); -+ } -+#endif -+ - if (mIsTopLevel) { - // Workaround window freezes on GTK versions before 3.21.2 by - // ensuring that configure events get dispatched to windows before -@@ -5436,9 +5505,10 @@ void nsWindow::InitDragEvent(WidgetDragE - KeymapWrapper::InitInputEvent(aEvent, modifierState); - } - --static gboolean drag_motion_event_cb(GtkWidget *aWidget, -- GdkDragContext *aDragContext, gint aX, -- gint aY, guint aTime, gpointer aData) { -+gboolean WindowDragMotionHandler(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, -+ gint aX, gint aY, guint aTime) { - RefPtr window = get_window_for_gtk_widget(aWidget); - if (!window) return FALSE; - -@@ -5459,13 +5529,17 @@ static gboolean drag_motion_event_cb(Gtk - LayoutDeviceIntPoint point = window->GdkPointToDevicePixels({retx, rety}); - - RefPtr dragService = nsDragService::GetInstance(); -- return dragService->ScheduleMotionEvent(innerMostWindow, aDragContext, point, -- aTime); -+ return dragService->ScheduleMotionEvent(innerMostWindow, aDragContext, -+ aWaylandDragContext, point, aTime); - } - --static void drag_leave_event_cb(GtkWidget *aWidget, -- GdkDragContext *aDragContext, guint aTime, -- gpointer aData) { -+static gboolean drag_motion_event_cb(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, gint aX, -+ gint aY, guint aTime, gpointer aData) { -+ return WindowDragMotionHandler(aWidget, aDragContext, nullptr, aX, aY, aTime); -+} -+ -+void WindowDragLeaveHandler(GtkWidget *aWidget) { - RefPtr window = get_window_for_gtk_widget(aWidget); - if (!window) return; - -@@ -5495,9 +5569,15 @@ static void drag_leave_event_cb(GtkWidge - dragService->ScheduleLeaveEvent(); - } - --static gboolean drag_drop_event_cb(GtkWidget *aWidget, -- GdkDragContext *aDragContext, gint aX, -- gint aY, guint aTime, gpointer aData) { -+static void drag_leave_event_cb(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, guint aTime, -+ gpointer aData) { -+ WindowDragLeaveHandler(aWidget); -+} -+ -+gboolean WindowDragDropHandler(GtkWidget *aWidget, GdkDragContext *aDragContext, -+ nsWaylandDragContext *aWaylandDragContext, -+ gint aX, gint aY, guint aTime) { - RefPtr window = get_window_for_gtk_widget(aWidget); - if (!window) return FALSE; - -@@ -5518,8 +5598,14 @@ static gboolean drag_drop_event_cb(GtkWi - LayoutDeviceIntPoint point = window->GdkPointToDevicePixels({retx, rety}); - - RefPtr dragService = nsDragService::GetInstance(); -- return dragService->ScheduleDropEvent(innerMostWindow, aDragContext, point, -- aTime); -+ return dragService->ScheduleDropEvent(innerMostWindow, aDragContext, -+ aWaylandDragContext, point, aTime); -+} -+ -+static gboolean drag_drop_event_cb(GtkWidget *aWidget, -+ GdkDragContext *aDragContext, gint aX, -+ gint aY, guint aTime, gpointer aData) { -+ return WindowDragDropHandler(aWidget, aDragContext, nullptr, aX, aY, aTime); - } - - static void drag_data_received_event_cb(GtkWidget *aWidget, -@@ -5877,11 +5963,6 @@ nsIWidget::LayerManager *nsWindow::GetLa - return mLayerManager; - } - -- if (!mLayerManager && !IsComposited() && -- eTransparencyTransparent == GetTransparencyMode()) { -- mLayerManager = CreateBasicLayerManager(); -- } -- - return nsBaseWidget::GetLayerManager(aShadowManager, aBackendHint, - aPersistence); - } -@@ -5919,6 +6000,13 @@ void nsWindow::ClearCachedResources() { - * It works only for CSD decorated GtkWindow. - */ - void nsWindow::UpdateClientOffsetForCSDWindow() { -+ // We update window offset on X11 as the window position is calculated -+ // relatively to mShell. We don't do that on Wayland as our wl_subsurface -+ // is attached to mContainer and mShell is ignored. -+ if (!mIsX11Display) { -+ return; -+ } -+ - // _NET_FRAME_EXTENTS is not set on client decorated windows, - // so we need to read offset between mContainer and toplevel mShell - // window. -@@ -6005,6 +6093,15 @@ void nsWindow::SetDrawsInTitlebar(bool a - mNeedsShow = true; - NativeResize(); - -+ // Label mShell toplevel window so property_notify_event_cb callback -+ // can find its way home. -+ g_object_set_data(G_OBJECT(gtk_widget_get_window(mShell)), "nsWindow", -+ this); -+#ifdef MOZ_X11 -+ // SetCompositorHint(GTK_WIDGET_COMPOSIDED_ENABLED); -+#endif -+ RefreshWindowClass(); -+ - // When we use system titlebar setup managed by Gtk+ we also get - // _NET_FRAME_EXTENTS property for our toplevel window so we can't - // update the client offset it here. -@@ -6019,13 +6116,11 @@ void nsWindow::SetDrawsInTitlebar(bool a - } - - gint nsWindow::GdkScaleFactor() { --#if (MOZ_WIDGET_GTK >= 3) - // Available as of GTK 3.10+ - static auto sGdkWindowGetScaleFactorPtr = - (gint(*)(GdkWindow *))dlsym(RTLD_DEFAULT, "gdk_window_get_scale_factor"); - if (sGdkWindowGetScaleFactorPtr && mGdkWindow) - return (*sGdkWindowGetScaleFactorPtr)(mGdkWindow); --#endif - return ScreenHelperGTK::GetGTKMonitorScaleFactor(); - } - -@@ -6287,6 +6382,8 @@ nsWindow::CSDSupportLevel nsWindow::GetS - // KDE Plasma - } else if (strstr(currentDesktop, "KDE") != nullptr) { - sCSDSupportLevel = CSD_SUPPORT_CLIENT; -+ } else if (strstr(currentDesktop, "Enlightenment") != nullptr) { -+ sCSDSupportLevel = CSD_SUPPORT_CLIENT; - } else if (strstr(currentDesktop, "LXDE") != nullptr) { - sCSDSupportLevel = CSD_SUPPORT_CLIENT; - } else if (strstr(currentDesktop, "openbox") != nullptr) { -@@ -6303,6 +6400,8 @@ nsWindow::CSDSupportLevel nsWindow::GetS - sCSDSupportLevel = CSD_SUPPORT_SYSTEM; - } else if (strstr(currentDesktop, "LXQt") != nullptr) { - sCSDSupportLevel = CSD_SUPPORT_SYSTEM; -+ } else if (strstr(currentDesktop, "Deepin") != nullptr) { -+ sCSDSupportLevel = CSD_SUPPORT_SYSTEM; - } else { - // Release or beta builds are not supposed to be broken - // so disable titlebar rendering on untested/unknown systems. -@@ -6351,34 +6450,19 @@ int32_t nsWindow::RoundsWidgetCoordinate - - void nsWindow::GetCompositorWidgetInitData( - mozilla::widget::CompositorWidgetInitData *aInitData) { -+ // Make sure the window XID is propagated to X server, we can fail otherwise -+ // in GPU process (Bug 1401634). -+ if (mXDisplay && mXWindow != X11None) { -+ XFlush(mXDisplay); -+ } -+ - *aInitData = mozilla::widget::GtkCompositorWidgetInitData( - (mXWindow != X11None) ? mXWindow : (uintptr_t) nullptr, - mXDisplay ? nsCString(XDisplayString(mXDisplay)) : nsCString(), - GetClientSize()); - } - --bool nsWindow::IsComposited() const { -- if (!mGdkWindow) { -- NS_WARNING("nsWindow::HasARGBVisual called before realization!"); -- return false; -- } -- -- GdkScreen *gdkScreen = gdk_screen_get_default(); -- return gdk_screen_is_composited(gdkScreen) && -- (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() { - if (mContainer) - return moz_container_get_wl_surface(MOZ_CONTAINER(mContainer)); -@@ -6388,4 +6472,80 @@ wl_surface *nsWindow::GetWaylandSurface( - "drawing!"); - return nullptr; - } -+ -+bool nsWindow::WaylandSurfaceNeedsClear() { -+ if (mContainer) { -+ return moz_container_surface_needs_clear(MOZ_CONTAINER(mContainer)); -+ } -+ -+ NS_WARNING( -+ "nsWindow::WaylandSurfaceNeedsClear(): We don't have any mContainer!"); -+ return false; -+} - #endif -+ -+#ifdef MOZ_X11 -+/* XApp progress support currently works by setting a property -+ * on a window with this Atom name. A supporting window manager -+ * will notice this and pass it along to whatever handling has -+ * been implemented on that end (e.g. passing it on to a taskbar -+ * widget.) There is no issue if WM support is lacking, this is -+ * simply ignored in that case. -+ * -+ * See https://github.com/linuxmint/xapps/blob/master/libxapp/xapp-gtk-window.c -+ * for further details. -+ */ -+ -+#define PROGRESS_HINT "_NET_WM_XAPP_PROGRESS" -+ -+static void set_window_hint_cardinal(Window xid, const gchar *atom_name, -+ gulong cardinal) { -+ GdkDisplay *display; -+ -+ display = gdk_display_get_default(); -+ -+ if (cardinal > 0) { -+ XChangeProperty(GDK_DISPLAY_XDISPLAY(display), xid, -+ gdk_x11_get_xatom_by_name_for_display(display, atom_name), -+ XA_CARDINAL, 32, PropModeReplace, (guchar *)&cardinal, 1); -+ } else { -+ XDeleteProperty(GDK_DISPLAY_XDISPLAY(display), xid, -+ gdk_x11_get_xatom_by_name_for_display(display, atom_name)); -+ } -+} -+#endif // MOZ_X11 -+ -+void nsWindow::SetProgress(unsigned long progressPercent) { -+#ifdef MOZ_X11 -+ -+ if (!mIsX11Display) { -+ return; -+ } -+ -+ if (!mShell) { -+ return; -+ } -+ -+ progressPercent = MIN(progressPercent, 100); -+ -+ set_window_hint_cardinal(GDK_WINDOW_XID(gtk_widget_get_window(mShell)), -+ PROGRESS_HINT, progressPercent); -+#endif // MOZ_X11 -+} -+ -+#ifdef MOZ_X11 -+void nsWindow::SetCompositorHint(WindowComposeRequest aState) { -+ if (mIsX11Display && -+ (!GetLayerManager() || -+ GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC)) { -+ gulong value = aState; -+ GdkAtom cardinal_atom = gdk_x11_xatom_to_atom(XA_CARDINAL); -+ gdk_property_change(gtk_widget_get_window(mShell), -+ gdk_atom_intern("_NET_WM_BYPASS_COMPOSITOR", FALSE), -+ cardinal_atom, -+ 32, // format -+ GDK_PROP_MODE_REPLACE, (guchar *)&value, 1); -+ } -+} -+#endif -+ -diff -up thunderbird-60.5.0/widget/gtk/nsWindow.h.wayland thunderbird-60.5.0/widget/gtk/nsWindow.h ---- thunderbird-60.5.0/widget/gtk/nsWindow.h.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/nsWindow.h 2019-02-05 14:26:16.978316639 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ - /* vim:expandtab:shiftwidth=4:tabstop=4: - */ - /* This Source Code Form is subject to the terms of the Mozilla Public -@@ -8,19 +8,8 @@ - #ifndef __nsWindow_h__ - #define __nsWindow_h__ - --#include "mozcontainer.h" --#include "mozilla/RefPtr.h" --#include "mozilla/UniquePtr.h" --#include "nsIDragService.h" --#include "nsITimer.h" --#include "nsGkAtoms.h" --#include "nsRefPtrHashtable.h" -- --#include "nsBaseWidget.h" --#include "CompositorWidget.h" - #include - #include -- - #ifdef MOZ_X11 - #include - #include "X11UndefineNone.h" -@@ -28,7 +17,16 @@ - #ifdef MOZ_WAYLAND - #include - #endif -- -+#include "mozcontainer.h" -+#include "mozilla/RefPtr.h" -+#include "mozilla/UniquePtr.h" -+#include "nsIDragService.h" -+#include "nsITimer.h" -+#include "nsGkAtoms.h" -+#include "nsRefPtrHashtable.h" -+#include "nsIFrame.h" -+#include "nsBaseWidget.h" -+#include "CompositorWidget.h" - #include "mozilla/widget/WindowSurface.h" - #include "mozilla/widget/WindowSurfaceProvider.h" - -@@ -66,6 +64,19 @@ extern mozilla::LazyLogModule gWidgetDra - - #endif /* MOZ_LOGGING */ - -+#ifdef MOZ_WAYLAND -+class nsWaylandDragContext; -+ -+gboolean WindowDragMotionHandler(GtkWidget* aWidget, -+ GdkDragContext* aDragContext, -+ nsWaylandDragContext* aWaylandDragContext, -+ gint aX, gint aY, guint aTime); -+gboolean WindowDragDropHandler(GtkWidget* aWidget, GdkDragContext* aDragContext, -+ nsWaylandDragContext* aWaylandDragContext, -+ gint aX, gint aY, guint aTime); -+void WindowDragLeaveHandler(GtkWidget* aWidget); -+#endif -+ - class gfxPattern; - - namespace mozilla { -@@ -77,6 +88,7 @@ class nsWindow final : public nsBaseWidg - public: - typedef mozilla::gfx::DrawTarget DrawTarget; - typedef mozilla::WidgetEventTime WidgetEventTime; -+ typedef mozilla::WidgetKeyboardEvent WidgetKeyboardEvent; - typedef mozilla::widget::PlatformCompositorWidgetDelegate - PlatformCompositorWidgetDelegate; - -@@ -216,6 +228,8 @@ class nsWindow final : public nsBaseWidg - mozilla::gfx::DrawTarget* aDrawTarget, - LayoutDeviceIntRegion& aInvalidRegion) override; - -+ void SetProgress(unsigned long progressPercent); -+ - private: - void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface, - nsIntRect aBoundsRect); -@@ -335,6 +349,7 @@ class nsWindow final : public nsBaseWidg - #ifdef MOZ_WAYLAND - wl_display* GetWaylandDisplay(); - wl_surface* GetWaylandSurface(); -+ bool WaylandSurfaceNeedsClear(); - #endif - virtual void GetCompositorWidgetInitData( - mozilla::widget::CompositorWidgetInitData* aInitData) override; -@@ -436,13 +451,23 @@ class nsWindow final : public nsBaseWidg - gint* aButton, gint* aRootX, gint* aRootY); - void ClearCachedResources(); - nsIWidgetListener* GetListener(); -- bool IsComposited() const; - - void UpdateClientOffsetForCSDWindow(); - - nsWindow* GetTransientForWindowIfPopup(); - bool IsHandlingTouchSequence(GdkEventSequence* aSequence); - -+#ifdef MOZ_X11 -+ typedef enum {GTK_WIDGET_COMPOSIDED_DEFAULT = 0, -+ GTK_WIDGET_COMPOSIDED_DISABLED = 1, -+ GTK_WIDGET_COMPOSIDED_ENABLED = 2} WindowComposeRequest; -+ -+ void SetCompositorHint(WindowComposeRequest aState); -+#endif -+ nsCString mGtkWindowTypeName; -+ nsCString mGtkWindowRoleName; -+ void RefreshWindowClass(); -+ - GtkWidget* mShell; - MozContainer* mContainer; - GdkWindow* mGdkWindow; -diff -up thunderbird-60.5.0/widget/gtk/WindowSurfaceProvider.h.wayland thunderbird-60.5.0/widget/gtk/WindowSurfaceProvider.h ---- thunderbird-60.5.0/widget/gtk/WindowSurfaceProvider.h.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/WindowSurfaceProvider.h 2019-02-05 14:26:16.978316639 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this -@@ -17,6 +17,7 @@ - #include - #endif - #include // for Window, Display, Visual, etc. -+#include "X11UndefineNone.h" - - class nsWindow; - -@@ -70,6 +71,7 @@ class WindowSurfaceProvider final { - #ifdef MOZ_WAYLAND - nsWindow* mWidget; - #endif -+ bool mIsShaped; - }; - - } // namespace widget -diff -up thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.cpp ---- thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.cpp.wayland 2019-01-22 20:44:04.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.cpp 2019-02-05 14:26:16.979316635 +0100 -@@ -1,27 +1,28 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -+#include "nsWaylandDisplay.h" - #include "WindowSurfaceWayland.h" - --#include "base/message_loop.h" // for MessageLoop --#include "base/task.h" // for NewRunnableMethod, etc - #include "nsPrintfCString.h" - #include "mozilla/gfx/2D.h" - #include "mozilla/gfx/Tools.h" - #include "gfxPlatform.h" - #include "mozcontainer.h" --#include "nsCOMArray.h" --#include "mozilla/StaticMutex.h" -+#include "nsTArray.h" -+#include "base/message_loop.h" // for MessageLoop -+#include "base/task.h" // for NewRunnableMethod, etc - --#include - #include --#include - #include - #include - -+namespace mozilla { -+namespace widget { -+ - /* - Wayland multi-thread rendering scheme - -@@ -131,188 +132,16 @@ handle to wayland compositor by WindowBa - (wl_buffer/wl_surface). - */ - --namespace mozilla { --namespace widget { -- - #define BUFFER_BPP 4 -- --// TODO: How many rendering threads do we actualy handle? --static nsCOMArray gWaylandDisplays; --static StaticMutex gWaylandDisplaysMutex; -- --// Each thread which is using wayland connection (wl_display) has to operate --// its own wl_event_queue. Main Firefox thread wl_event_queue is handled --// by Gtk main loop, other threads/wl_event_queue has to be handled by us. --// --// nsWaylandDisplay is our interface to wayland compositor. It provides wayland --// global objects as we need (wl_display, wl_shm) and operates wl_event_queue on --// compositor (not the main) thread. --static nsWaylandDisplay *WaylandDisplayGet(wl_display *aDisplay); --static void WaylandDisplayRelease(wl_display *aDisplay); --static void WaylandDisplayLoop(wl_display *aDisplay); -- --// TODO: is the 60pfs loop correct? --#define EVENT_LOOP_DELAY (1000 / 60) -- --// Get WaylandDisplay for given wl_display and actual calling thread. --static nsWaylandDisplay *WaylandDisplayGetLocked(wl_display *aDisplay, -- const StaticMutexAutoLock &) { -- nsWaylandDisplay *waylandDisplay = nullptr; -- -- int len = gWaylandDisplays.Count(); -- for (int i = 0; i < len; i++) { -- if (gWaylandDisplays[i]->Matches(aDisplay)) { -- waylandDisplay = gWaylandDisplays[i]; -- break; -- } -- } -- -- if (!waylandDisplay) { -- waylandDisplay = new nsWaylandDisplay(aDisplay); -- gWaylandDisplays.AppendObject(waylandDisplay); -- } -- -- NS_ADDREF(waylandDisplay); -- return waylandDisplay; --} -- --static nsWaylandDisplay *WaylandDisplayGet(wl_display *aDisplay) { -- StaticMutexAutoLock lock(gWaylandDisplaysMutex); -- return WaylandDisplayGetLocked(aDisplay, lock); --} -- --static bool WaylandDisplayReleaseLocked(wl_display *aDisplay, -- const StaticMutexAutoLock &) { -- int len = gWaylandDisplays.Count(); -- for (int i = 0; i < len; i++) { -- if (gWaylandDisplays[i]->Matches(aDisplay)) { -- int rc = gWaylandDisplays[i]->Release(); -- // nsCOMArray::AppendObject()/RemoveObjectAt() also call -- // AddRef()/Release() so remove WaylandDisplay when ref count is 1. -- if (rc == 1) { -- gWaylandDisplays.RemoveObjectAt(i); -- } -- return true; -- } -- } -- MOZ_ASSERT(false, "Missing nsWaylandDisplay for this thread!"); -- return false; --} -- --static void WaylandDisplayRelease(wl_display *aDisplay) { -- StaticMutexAutoLock lock(gWaylandDisplaysMutex); -- WaylandDisplayReleaseLocked(aDisplay, lock); --} -- --static void WaylandDisplayLoopLocked(wl_display *aDisplay, -- const StaticMutexAutoLock &) { -- int len = gWaylandDisplays.Count(); -- for (int i = 0; i < len; i++) { -- if (gWaylandDisplays[i]->Matches(aDisplay)) { -- if (gWaylandDisplays[i]->DisplayLoop()) { -- MessageLoop::current()->PostDelayedTask( -- NewRunnableFunction("WaylandDisplayLoop", &WaylandDisplayLoop, -- aDisplay), -- EVENT_LOOP_DELAY); -- } -- break; -- } -- } --} -- --static void WaylandDisplayLoop(wl_display *aDisplay) { -- MOZ_ASSERT(!NS_IsMainThread()); -- StaticMutexAutoLock lock(gWaylandDisplaysMutex); -- WaylandDisplayLoopLocked(aDisplay, lock); --} -- --static void global_registry_handler(void *data, wl_registry *registry, -- uint32_t id, const char *interface, -- uint32_t version) { -- if (strcmp(interface, "wl_shm") == 0) { -- auto interface = reinterpret_cast(data); -- auto shm = static_cast( -- wl_registry_bind(registry, id, &wl_shm_interface, 1)); -- wl_proxy_set_queue((struct wl_proxy *)shm, interface->GetEventQueue()); -- interface->SetShm(shm); -- } --} -- --static void global_registry_remover(void *data, wl_registry *registry, -- uint32_t id) {} -- --static const struct wl_registry_listener registry_listener = { -- global_registry_handler, global_registry_remover}; -- --wl_shm *nsWaylandDisplay::GetShm() { -- MOZ_ASSERT(mThreadId == PR_GetCurrentThread()); -- -- if (!mShm) { -- // wl_shm is not provided by Gtk so we need to query wayland directly -- // See weston/simple-shm.c and create_display() for reference. -- wl_registry *registry = wl_display_get_registry(mDisplay); -- wl_registry_add_listener(registry, ®istry_listener, this); -- -- wl_proxy_set_queue((struct wl_proxy *)registry, mEventQueue); -- if (mEventQueue) { -- wl_display_roundtrip_queue(mDisplay, mEventQueue); -- } else { -- wl_display_roundtrip(mDisplay); -- } -- -- MOZ_RELEASE_ASSERT(mShm, "Wayland registry query failed!"); -- } -- -- return (mShm); --} -- --bool nsWaylandDisplay::DisplayLoop() { -- wl_display_dispatch_queue_pending(mDisplay, mEventQueue); -- return true; --} -- --bool nsWaylandDisplay::Matches(wl_display *aDisplay) { -- return mThreadId == PR_GetCurrentThread() && aDisplay == mDisplay; --} -- --NS_IMPL_ISUPPORTS(nsWaylandDisplay, nsISupports); -- --nsWaylandDisplay::nsWaylandDisplay(wl_display *aDisplay) -- : mThreadId(PR_GetCurrentThread()) -- // gfx::SurfaceFormat::B8G8R8A8 is a basic Wayland format -- // and is always present. -- , -- mFormat(gfx::SurfaceFormat::B8G8R8A8), -- mShm(nullptr), -- mDisplay(aDisplay) { -- if (NS_IsMainThread()) { -- // Use default event queue in main thread operated by Gtk+. -- mEventQueue = nullptr; -- } else { -- mEventQueue = wl_display_create_queue(mDisplay); -- MessageLoop::current()->PostTask(NewRunnableFunction( -- "WaylandDisplayLoop", &WaylandDisplayLoop, mDisplay)); -- } --} -- --nsWaylandDisplay::~nsWaylandDisplay() { -- MOZ_ASSERT(mThreadId == PR_GetCurrentThread()); -- // Owned by Gtk+, we don't need to release -- mDisplay = nullptr; -- -- if (mEventQueue) { -- wl_event_queue_destroy(mEventQueue); -- mEventQueue = nullptr; -- } --} -+gfx::SurfaceFormat WindowBackBuffer::mFormat = gfx::SurfaceFormat::B8G8R8A8; - - int WaylandShmPool::CreateTemporaryFile(int aSize) { -- const char *tmppath = getenv("XDG_RUNTIME_DIR"); -+ const char* tmppath = getenv("XDG_RUNTIME_DIR"); - MOZ_RELEASE_ASSERT(tmppath, "Missing XDG_RUNTIME_DIR env variable."); - - nsPrintfCString tmpname("%s/mozilla-shared-XXXXXX", tmppath); - -- char *filename; -+ char* filename; - int fd = -1; - int ret = 0; - -@@ -353,7 +182,7 @@ int WaylandShmPool::CreateTemporaryFile( - return fd; - } - --WaylandShmPool::WaylandShmPool(nsWaylandDisplay *aWaylandDisplay, int aSize) -+WaylandShmPool::WaylandShmPool(nsWaylandDisplay* aWaylandDisplay, int aSize) - : mAllocatedSize(aSize) { - mShmPoolFd = CreateTemporaryFile(mAllocatedSize); - mImageData = mmap(nullptr, mAllocatedSize, PROT_READ | PROT_WRITE, MAP_SHARED, -@@ -365,7 +194,7 @@ WaylandShmPool::WaylandShmPool(nsWayland - wl_shm_create_pool(aWaylandDisplay->GetShm(), mShmPoolFd, mAllocatedSize); - - // We set our queue to get mShmPool events at compositor thread. -- wl_proxy_set_queue((struct wl_proxy *)mShmPool, -+ wl_proxy_set_queue((struct wl_proxy*)mShmPool, - aWaylandDisplay->GetEventQueue()); - } - -@@ -394,7 +223,7 @@ bool WaylandShmPool::Resize(int aSize) { - return true; - } - --void WaylandShmPool::SetImageDataFromPool(class WaylandShmPool *aSourcePool, -+void WaylandShmPool::SetImageDataFromPool(class WaylandShmPool* aSourcePool, - int aImageDataSize) { - MOZ_ASSERT(mAllocatedSize >= aImageDataSize, "WaylandShmPool overflows!"); - memcpy(mImageData, aSourcePool->GetImageData(), aImageDataSize); -@@ -406,8 +235,8 @@ WaylandShmPool::~WaylandShmPool() { - close(mShmPoolFd); - } - --static void buffer_release(void *data, wl_buffer *buffer) { -- auto surface = reinterpret_cast(data); -+static void buffer_release(void* data, wl_buffer* buffer) { -+ auto surface = reinterpret_cast(data); - surface->Detach(); - } - -@@ -422,7 +251,7 @@ void WindowBackBuffer::Create(int aWidth - mWaylandBuffer = - wl_shm_pool_create_buffer(mShmPool.GetShmPool(), 0, aWidth, aHeight, - aWidth * BUFFER_BPP, WL_SHM_FORMAT_ARGB8888); -- wl_proxy_set_queue((struct wl_proxy *)mWaylandBuffer, -+ wl_proxy_set_queue((struct wl_proxy*)mWaylandBuffer, - mWaylandDisplay->GetEventQueue()); - wl_buffer_add_listener(mWaylandBuffer, &buffer_listener, this); - -@@ -435,7 +264,11 @@ void WindowBackBuffer::Release() { - mWidth = mHeight = 0; - } - --WindowBackBuffer::WindowBackBuffer(nsWaylandDisplay *aWaylandDisplay, -+void WindowBackBuffer::Clear() { -+ memset(mShmPool.GetImageData(), 0, mHeight * mWidth * BUFFER_BPP); -+} -+ -+WindowBackBuffer::WindowBackBuffer(nsWaylandDisplay* aWaylandDisplay, - int aWidth, int aHeight) - : mShmPool(aWaylandDisplay, aWidth * aHeight * BUFFER_BPP), - mWaylandBuffer(nullptr), -@@ -457,7 +290,7 @@ bool WindowBackBuffer::Resize(int aWidth - return (mWaylandBuffer != nullptr); - } - --void WindowBackBuffer::Attach(wl_surface *aSurface) { -+void WindowBackBuffer::Attach(wl_surface* aSurface) { - wl_surface_attach(aSurface, mWaylandBuffer, 0, 0); - wl_surface_commit(aSurface); - wl_display_flush(mWaylandDisplay->GetDisplay()); -@@ -466,8 +299,8 @@ void WindowBackBuffer::Attach(wl_surface - - void WindowBackBuffer::Detach() { mAttached = false; } - --bool WindowBackBuffer::SetImageDataFromBackBuffer( -- class WindowBackBuffer *aSourceBuffer) { -+bool WindowBackBuffer::SetImageDataFromBuffer( -+ class WindowBackBuffer* aSourceBuffer) { - if (!IsMatchingSize(aSourceBuffer)) { - Resize(aSourceBuffer->mWidth, aSourceBuffer->mHeight); - } -@@ -478,204 +311,381 @@ bool WindowBackBuffer::SetImageDataFromB - return true; - } - --already_AddRefed WindowBackBuffer::Lock( -- const LayoutDeviceIntRegion &aRegion) { -- gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); -- gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); -- -+already_AddRefed WindowBackBuffer::Lock() { -+ gfx::IntSize lockSize(mWidth, mHeight); - return gfxPlatform::CreateDrawTargetForData( -- static_cast(mShmPool.GetImageData()), lockSize, -- BUFFER_BPP * mWidth, mWaylandDisplay->GetSurfaceFormat()); -+ static_cast(mShmPool.GetImageData()), lockSize, -+ BUFFER_BPP * mWidth, mFormat); - } - --static void frame_callback_handler(void *data, struct wl_callback *callback, -+static void frame_callback_handler(void* data, struct wl_callback* callback, - uint32_t time) { -- auto surface = reinterpret_cast(data); -+ auto surface = reinterpret_cast(data); - surface->FrameCallbackHandler(); - } - - static const struct wl_callback_listener frame_listener = { - frame_callback_handler}; - --WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow) -+WindowSurfaceWayland::WindowSurfaceWayland(nsWindow* aWindow) - : mWindow(aWindow), -- mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay())), -- mFrontBuffer(nullptr), -- mBackBuffer(nullptr), -+ mWaylandDisplay(WaylandDisplayGet()), -+ mWaylandBuffer(nullptr), - mFrameCallback(nullptr), -- mFrameCallbackSurface(nullptr), -+ mLastCommittedSurface(nullptr), - mDisplayThreadMessageLoop(MessageLoop::current()), -- mDelayedCommit(false), -- mFullScreenDamage(false), -- mIsMainThread(NS_IsMainThread()) {} -+ mDelayedCommitHandle(nullptr), -+ mDrawToWaylandBufferDirectly(true), -+ mPendingCommit(false), -+ mWaylandBufferFullScreenDamage(false), -+ mIsMainThread(NS_IsMainThread()), -+ mNeedScaleFactorUpdate(true) { -+ for (int i = 0; i < BACK_BUFFER_NUM; i++) mBackupBuffer[i] = nullptr; -+} - - WindowSurfaceWayland::~WindowSurfaceWayland() { -- delete mFrontBuffer; -- delete mBackBuffer; -+ if (mPendingCommit) { -+ NS_WARNING("Deleted WindowSurfaceWayland with a pending commit!"); -+ } -+ -+ if (mDelayedCommitHandle) { -+ // Delete reference to this to prevent WaylandBufferDelayCommitHandler() -+ // operate on released this. mDelayedCommitHandle itself will -+ // be released at WaylandBufferDelayCommitHandler(). -+ *mDelayedCommitHandle = nullptr; -+ } - - if (mFrameCallback) { - wl_callback_destroy(mFrameCallback); - } - -+ delete mWaylandBuffer; -+ -+ for (int i = 0; i < BACK_BUFFER_NUM; i++) { -+ if (mBackupBuffer[i]) { -+ delete mBackupBuffer[i]; -+ } -+ } -+ - if (!mIsMainThread) { - // We can be destroyed from main thread even though we was created/used - // in compositor thread. We have to unref/delete WaylandDisplay in - // compositor thread then and we can't use MessageLoop::current() here. -- mDisplayThreadMessageLoop->PostTask( -- NewRunnableFunction("WaylandDisplayRelease", &WaylandDisplayRelease, -- mWaylandDisplay->GetDisplay())); -+ mDisplayThreadMessageLoop->PostTask(NewRunnableFunction( -+ "WaylandDisplayRelease", &WaylandDisplayRelease, mWaylandDisplay)); - } else { -- WaylandDisplayRelease(mWaylandDisplay->GetDisplay()); -- } --} -- --void WindowSurfaceWayland::UpdateScaleFactor() { -- wl_surface *waylandSurface = mWindow->GetWaylandSurface(); -- if (waylandSurface) { -- wl_surface_set_buffer_scale(waylandSurface, mWindow->GdkScaleFactor()); -+ WaylandDisplayRelease(mWaylandDisplay); - } - } - --WindowBackBuffer *WindowSurfaceWayland::GetBufferToDraw(int aWidth, -- int aHeight) { -- if (!mFrontBuffer) { -- mFrontBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); -- mBackBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); -- return mFrontBuffer; -+WindowBackBuffer* WindowSurfaceWayland::GetWaylandBufferToDraw(int aWidth, -+ int aHeight) { -+ if (!mWaylandBuffer) { -+ mWaylandBuffer = new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); -+ return mWaylandBuffer; - } - -- if (!mFrontBuffer->IsAttached()) { -- if (!mFrontBuffer->IsMatchingSize(aWidth, aHeight)) { -- mFrontBuffer->Resize(aWidth, aHeight); -+ if (!mWaylandBuffer->IsAttached()) { -+ if (!mWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { -+ mWaylandBuffer->Resize(aWidth, aHeight); - // There's a chance that scale factor has been changed - // when buffer size changed -- UpdateScaleFactor(); -+ mNeedScaleFactorUpdate = true; -+ } -+ return mWaylandBuffer; -+ } -+ -+ MOZ_ASSERT(!mPendingCommit, -+ "Uncommitted buffer switch, screen artifacts ahead."); -+ -+ // Front buffer is used by compositor, select a back buffer -+ int availableBuffer; -+ for (availableBuffer = 0; availableBuffer < BACK_BUFFER_NUM; -+ availableBuffer++) { -+ if (!mBackupBuffer[availableBuffer]) { -+ mBackupBuffer[availableBuffer] = -+ new WindowBackBuffer(mWaylandDisplay, aWidth, aHeight); -+ break; -+ } -+ -+ if (!mBackupBuffer[availableBuffer]->IsAttached()) { -+ break; - } -- return mFrontBuffer; - } - -- // Front buffer is used by compositor, draw to back buffer -- if (mBackBuffer->IsAttached()) { -+ if (MOZ_UNLIKELY(availableBuffer == BACK_BUFFER_NUM)) { - NS_WARNING("No drawing buffer available"); - return nullptr; - } - -- MOZ_ASSERT(!mDelayedCommit, -- "Uncommitted buffer switch, screen artifacts ahead."); -- -- WindowBackBuffer *tmp = mFrontBuffer; -- mFrontBuffer = mBackBuffer; -- mBackBuffer = tmp; -+ WindowBackBuffer* lastWaylandBuffer = mWaylandBuffer; -+ mWaylandBuffer = mBackupBuffer[availableBuffer]; -+ mBackupBuffer[availableBuffer] = lastWaylandBuffer; - -- if (mBackBuffer->IsMatchingSize(aWidth, aHeight)) { -+ if (lastWaylandBuffer->IsMatchingSize(aWidth, aHeight)) { - // Former front buffer has the same size as a requested one. - // Gecko may expect a content already drawn on screen so copy - // existing data to the new buffer. -- mFrontBuffer->SetImageDataFromBackBuffer(mBackBuffer); -+ mWaylandBuffer->SetImageDataFromBuffer(lastWaylandBuffer); - // When buffer switches we need to damage whole screen - // (https://bugzilla.redhat.com/show_bug.cgi?id=1418260) -- mFullScreenDamage = true; -+ mWaylandBufferFullScreenDamage = true; - } else { - // Former buffer has different size from the new request. Only resize - // the new buffer and leave gecko to render new whole content. -- mFrontBuffer->Resize(aWidth, aHeight); -+ mWaylandBuffer->Resize(aWidth, aHeight); - } - -- return mFrontBuffer; -+ return mWaylandBuffer; - } - --already_AddRefed WindowSurfaceWayland::Lock( -- const LayoutDeviceIntRegion &aRegion) { -- MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); -- -- // We allocate back buffer to widget size but return only -- // portion requested by aRegion. -- LayoutDeviceIntRect rect = mWindow->GetBounds(); -- WindowBackBuffer *buffer = GetBufferToDraw(rect.width, rect.height); -+already_AddRefed WindowSurfaceWayland::LockWaylandBuffer( -+ int aWidth, int aHeight, bool aClearBuffer) { -+ WindowBackBuffer* buffer = GetWaylandBufferToDraw(aWidth, aHeight); - if (!buffer) { -- NS_WARNING("No drawing buffer available"); -+ NS_WARNING( -+ "WindowSurfaceWayland::LockWaylandBuffer(): No buffer available"); - return nullptr; - } - -- return buffer->Lock(aRegion); -+ if (aClearBuffer) { -+ buffer->Clear(); -+ } -+ -+ return buffer->Lock(); -+} -+ -+already_AddRefed WindowSurfaceWayland::LockImageSurface( -+ const gfx::IntSize& aLockSize) { -+ if (!mImageSurface || mImageSurface->CairoStatus() || -+ !(aLockSize <= mImageSurface->GetSize())) { -+ mImageSurface = new gfxImageSurface( -+ aLockSize, -+ SurfaceFormatToImageFormat(WindowBackBuffer::GetSurfaceFormat())); -+ if (mImageSurface->CairoStatus()) { -+ return nullptr; -+ } -+ } -+ -+ return gfxPlatform::CreateDrawTargetForData( -+ mImageSurface->Data(), mImageSurface->GetSize(), mImageSurface->Stride(), -+ WindowBackBuffer::GetSurfaceFormat()); - } - --void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion &aInvalidRegion) { -+/* -+ There are some situations which can happen here: -+ -+ A) Lock() is called to whole surface. In that case we don't need -+ to clip/buffer the drawing and we can return wl_buffer directly -+ for drawing. -+ - mWaylandBuffer is available - that's an ideal situation. -+ - mWaylandBuffer is locked by compositor - flip buffers and draw. -+ - if we can't flip buffers - go B) -+ -+ B) Lock() is requested for part(s) of screen. We need to provide temporary -+ surface to draw into and copy result (clipped) to target wl_surface. -+ */ -+already_AddRefed WindowSurfaceWayland::Lock( -+ const LayoutDeviceIntRegion& aRegion) { - MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); - -- wl_surface *waylandSurface = mWindow->GetWaylandSurface(); -+ LayoutDeviceIntRect screenRect = mWindow->GetBounds(); -+ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); -+ gfx::IntSize lockSize(bounds.XMost(), bounds.YMost()); -+ -+ // Are we asked for entire nsWindow to draw? -+ mDrawToWaylandBufferDirectly = -+ (aRegion.GetNumRects() == 1 && bounds.x == 0 && bounds.y == 0 && -+ lockSize.width == screenRect.width && -+ lockSize.height == screenRect.height); -+ -+ if (mDrawToWaylandBufferDirectly) { -+ RefPtr dt = -+ LockWaylandBuffer(screenRect.width, screenRect.height, -+ mWindow->WaylandSurfaceNeedsClear()); -+ if (dt) { -+ return dt.forget(); -+ } -+ -+ // We don't have any front buffer available. Try indirect drawing -+ // to mImageSurface which is mirrored to front buffer at commit. -+ mDrawToWaylandBufferDirectly = false; -+ } -+ -+ return LockImageSurface(lockSize); -+} -+ -+bool WindowSurfaceWayland::CommitImageSurfaceToWaylandBuffer( -+ const LayoutDeviceIntRegion& aRegion) { -+ MOZ_ASSERT(!mDrawToWaylandBufferDirectly); -+ -+ LayoutDeviceIntRect screenRect = mWindow->GetBounds(); -+ gfx::IntRect bounds = aRegion.GetBounds().ToUnknownRect(); -+ -+ gfx::Rect rect(bounds); -+ if (rect.IsEmpty()) { -+ return false; -+ } -+ -+ RefPtr dt = LockWaylandBuffer( -+ screenRect.width, screenRect.height, mWindow->WaylandSurfaceNeedsClear()); -+ RefPtr surf = -+ gfx::Factory::CreateSourceSurfaceForCairoSurface( -+ mImageSurface->CairoSurface(), mImageSurface->GetSize(), -+ mImageSurface->Format()); -+ if (!dt || !surf) { -+ return false; -+ } -+ -+ uint32_t numRects = aRegion.GetNumRects(); -+ if (numRects != 1) { -+ AutoTArray rects; -+ rects.SetCapacity(numRects); -+ for (auto iter = aRegion.RectIter(); !iter.Done(); iter.Next()) { -+ rects.AppendElement(iter.Get().ToUnknownRect()); -+ } -+ dt->PushDeviceSpaceClipRects(rects.Elements(), rects.Length()); -+ } -+ -+ dt->DrawSurface(surf, rect, rect); -+ -+ if (numRects != 1) { -+ dt->PopClip(); -+ } -+ -+ return true; -+} -+ -+static void WaylandBufferDelayCommitHandler(WindowSurfaceWayland** aSurface) { -+ if (*aSurface) { -+ (*aSurface)->DelayedCommitHandler(); -+ } else { -+ // Referenced WindowSurfaceWayland is already deleted. -+ // Do nothing but just release the mDelayedCommitHandle allocated at -+ // WindowSurfaceWayland::CommitWaylandBuffer(). -+ free(aSurface); -+ } -+} -+ -+void WindowSurfaceWayland::CommitWaylandBuffer() { -+ MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); -+ -+ wl_surface* waylandSurface = mWindow->GetWaylandSurface(); - if (!waylandSurface) { -- // Target window is already destroyed - don't bother to render there. -+ // Target window is not created yet - delay the commit. This can happen only -+ // when the window is newly created and there's no active -+ // frame callback pending. -+ MOZ_ASSERT(!mFrameCallback || waylandSurface != mLastCommittedSurface, -+ "Missing wayland surface at frame callback!"); -+ -+ // Do nothing if there's already mDelayedCommitHandle pending. -+ if (!mDelayedCommitHandle) { -+ mDelayedCommitHandle = static_cast( -+ moz_xmalloc(sizeof(*mDelayedCommitHandle))); -+ *mDelayedCommitHandle = this; -+ -+ MessageLoop::current()->PostDelayedTask( -+ NewRunnableFunction("WaylandBackBufferCommit", -+ &WaylandBufferDelayCommitHandler, -+ mDelayedCommitHandle), -+ EVENT_LOOP_DELAY); -+ } - return; - } -- wl_proxy_set_queue((struct wl_proxy *)waylandSurface, -+ wl_proxy_set_queue((struct wl_proxy*)waylandSurface, - mWaylandDisplay->GetEventQueue()); - -- if (mFullScreenDamage) { -+ // We have an active frame callback request so handle it. -+ if (mFrameCallback) { -+ if (waylandSurface == mLastCommittedSurface) { -+ // We have an active frame callback pending from our recent surface. -+ // It means we should defer the commit to FrameCallbackHandler(). -+ return; -+ } -+ // If our stored wl_surface does not match the actual one it means the frame -+ // callback is no longer active and we should release it. -+ wl_callback_destroy(mFrameCallback); -+ mFrameCallback = nullptr; -+ mLastCommittedSurface = nullptr; -+ } -+ -+ if (mWaylandBufferFullScreenDamage) { - LayoutDeviceIntRect rect = mWindow->GetBounds(); - wl_surface_damage(waylandSurface, 0, 0, rect.width, rect.height); -- mFullScreenDamage = false; -+ mWaylandBufferFullScreenDamage = false; - } else { -- for (auto iter = aInvalidRegion.RectIter(); !iter.Done(); iter.Next()) { -- const mozilla::LayoutDeviceIntRect &r = iter.Get(); -- wl_surface_damage(waylandSurface, r.x, r.y, r.width, r.height); -+ gint scaleFactor = mWindow->GdkScaleFactor(); -+ for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); -+ iter.Next()) { -+ const mozilla::LayoutDeviceIntRect& r = iter.Get(); -+ // We need to remove the scale factor because the wl_surface_damage -+ // also multiplies by current scale factor. -+ wl_surface_damage(waylandSurface, r.x / scaleFactor, r.y / scaleFactor, -+ r.width / scaleFactor, r.height / scaleFactor); - } - } - -- // Frame callback is always connected to actual wl_surface. When the surface -- // is unmapped/deleted the frame callback is never called. Unfortunatelly -- // we don't know if the frame callback is not going to be called. -- // But our mozcontainer code deletes wl_surface when the GdkWindow is hidden -- // creates a new one when is visible. -- if (mFrameCallback && mFrameCallbackSurface == waylandSurface) { -- // Do nothing here - we have a valid wl_surface and the buffer will be -- // commited to compositor in next frame callback event. -- mDelayedCommit = true; -- return; -- } else { -- if (mFrameCallback) { -- // Delete frame callback connected to obsoleted wl_surface. -- wl_callback_destroy(mFrameCallback); -- } -+ // Clear all back buffer damage as we're committing -+ // all requested regions. -+ mWaylandBufferDamage.SetEmpty(); - -- mFrameCallback = wl_surface_frame(waylandSurface); -- wl_callback_add_listener(mFrameCallback, &frame_listener, this); -- mFrameCallbackSurface = waylandSurface; -- -- // There's no pending frame callback so we can draw immediately -- // and create frame callback for possible subsequent drawing. -- mFrontBuffer->Attach(waylandSurface); -- mDelayedCommit = false; -+ mFrameCallback = wl_surface_frame(waylandSurface); -+ wl_callback_add_listener(mFrameCallback, &frame_listener, this); -+ -+ if (mNeedScaleFactorUpdate || mLastCommittedSurface != waylandSurface) { -+ wl_surface_set_buffer_scale(waylandSurface, mWindow->GdkScaleFactor()); -+ mNeedScaleFactorUpdate = false; - } -+ -+ mWaylandBuffer->Attach(waylandSurface); -+ mLastCommittedSurface = waylandSurface; -+ -+ // There's no pending commit, all changes are sent to compositor. -+ mPendingCommit = false; -+} -+ -+void WindowSurfaceWayland::Commit(const LayoutDeviceIntRegion& aInvalidRegion) { -+ MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); -+ -+ // We have new content at mImageSurface - copy data to mWaylandBuffer first. -+ if (!mDrawToWaylandBufferDirectly) { -+ CommitImageSurfaceToWaylandBuffer(aInvalidRegion); -+ } -+ -+ // If we're not at fullscreen damage add drawing area from aInvalidRegion -+ if (!mWaylandBufferFullScreenDamage) { -+ mWaylandBufferDamage.OrWith(aInvalidRegion); -+ } -+ -+ // We're ready to commit. -+ mPendingCommit = true; -+ CommitWaylandBuffer(); - } - - void WindowSurfaceWayland::FrameCallbackHandler() { - MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); -+ MOZ_ASSERT(mFrameCallback != nullptr, -+ "FrameCallbackHandler() called without valid frame callback!"); -+ MOZ_ASSERT(mLastCommittedSurface != nullptr, -+ "FrameCallbackHandler() called without valid wl_surface!"); - -- if (mFrameCallback) { -- wl_callback_destroy(mFrameCallback); -- mFrameCallback = nullptr; -- mFrameCallbackSurface = nullptr; -+ wl_callback_destroy(mFrameCallback); -+ mFrameCallback = nullptr; -+ -+ if (mPendingCommit) { -+ CommitWaylandBuffer(); - } -+} - -- if (mDelayedCommit) { -- wl_surface *waylandSurface = mWindow->GetWaylandSurface(); -- if (!waylandSurface) { -- // Target window is already destroyed - don't bother to render there. -- NS_WARNING("No drawing buffer available"); -- return; -- } -- wl_proxy_set_queue((struct wl_proxy *)waylandSurface, -- mWaylandDisplay->GetEventQueue()); -+void WindowSurfaceWayland::DelayedCommitHandler() { -+ MOZ_ASSERT(mDelayedCommitHandle != nullptr, "Missing mDelayedCommitHandle!"); - -- // Send pending surface to compositor and register frame callback -- // for possible subsequent drawing. -- mFrameCallback = wl_surface_frame(waylandSurface); -- wl_callback_add_listener(mFrameCallback, &frame_listener, this); -- mFrameCallbackSurface = waylandSurface; -+ *mDelayedCommitHandle = nullptr; -+ free(mDelayedCommitHandle); -+ mDelayedCommitHandle = nullptr; - -- mFrontBuffer->Attach(waylandSurface); -- mDelayedCommit = false; -+ if (mPendingCommit) { -+ CommitWaylandBuffer(); - } - } - -diff -up thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.h.wayland thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.h ---- thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.h.wayland 2019-01-22 20:44:03.000000000 +0100 -+++ thunderbird-60.5.0/widget/gtk/WindowSurfaceWayland.h 2019-02-05 14:26:16.979316635 +0100 -@@ -1,4 +1,4 @@ --/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- -+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this -@@ -8,37 +8,14 @@ - #define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H - - #include -+#include "mozilla/gfx/Types.h" -+#include "nsWaylandDisplay.h" -+ -+#define BACK_BUFFER_NUM 2 - - namespace mozilla { - namespace widget { - --// Our general connection to Wayland display server, --// holds our display connection and runs event loop. --class nsWaylandDisplay : public nsISupports { -- NS_DECL_THREADSAFE_ISUPPORTS -- -- public: -- nsWaylandDisplay(wl_display* aDisplay); -- -- wl_shm* GetShm(); -- void SetShm(wl_shm* aShm) { mShm = aShm; }; -- -- wl_display* GetDisplay() { return mDisplay; }; -- wl_event_queue* GetEventQueue() { return mEventQueue; }; -- gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; }; -- bool DisplayLoop(); -- bool Matches(wl_display* aDisplay); -- -- private: -- virtual ~nsWaylandDisplay(); -- -- PRThread* mThreadId; -- gfx::SurfaceFormat mFormat; -- wl_shm* mShm; -- wl_event_queue* mEventQueue; -- wl_display* mDisplay; --}; -- - // Allocates and owns shared memory for Wayland drawing surface - class WaylandShmPool { - public: -@@ -66,14 +43,15 @@ class WindowBackBuffer { - WindowBackBuffer(nsWaylandDisplay* aDisplay, int aWidth, int aHeight); - ~WindowBackBuffer(); - -- already_AddRefed Lock(const LayoutDeviceIntRegion& aRegion); -+ already_AddRefed Lock(); - - void Attach(wl_surface* aSurface); - void Detach(); - bool IsAttached() { return mAttached; } - -+ void Clear(); - bool Resize(int aWidth, int aHeight); -- bool SetImageDataFromBackBuffer(class WindowBackBuffer* aSourceBuffer); -+ bool SetImageDataFromBuffer(class WindowBackBuffer* aSourceBuffer); - - bool IsMatchingSize(int aWidth, int aHeight) { - return aWidth == mWidth && aHeight == mHeight; -@@ -82,6 +60,8 @@ class WindowBackBuffer { - return aBuffer->mWidth == mWidth && aBuffer->mHeight == mHeight; - } - -+ static gfx::SurfaceFormat GetSurfaceFormat() { return mFormat; } -+ - private: - void Create(int aWidth, int aHeight); - void Release(); -@@ -96,35 +76,48 @@ class WindowBackBuffer { - int mHeight; - bool mAttached; - nsWaylandDisplay* mWaylandDisplay; -+ static gfx::SurfaceFormat mFormat; - }; - - // WindowSurfaceWayland is an abstraction for wl_surface - // and related management - class WindowSurfaceWayland : public WindowSurface { - public: -- WindowSurfaceWayland(nsWindow* aWindow); -+ explicit WindowSurfaceWayland(nsWindow* aWindow); - ~WindowSurfaceWayland(); - - already_AddRefed Lock( - const LayoutDeviceIntRegion& aRegion) override; - void Commit(const LayoutDeviceIntRegion& aInvalidRegion) final; - void FrameCallbackHandler(); -+ void DelayedCommitHandler(); - - private: -- WindowBackBuffer* GetBufferToDraw(int aWidth, int aHeight); -- void UpdateScaleFactor(); -+ WindowBackBuffer* GetWaylandBufferToDraw(int aWidth, int aHeight); -+ -+ already_AddRefed LockWaylandBuffer(int aWidth, int aHeight, -+ bool aClearBuffer); -+ already_AddRefed LockImageSurface( -+ const gfx::IntSize& aLockSize); -+ bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion); -+ void CommitWaylandBuffer(); - - // TODO: Do we need to hold a reference to nsWindow object? - nsWindow* mWindow; - nsWaylandDisplay* mWaylandDisplay; -- WindowBackBuffer* mFrontBuffer; -- WindowBackBuffer* mBackBuffer; -+ WindowBackBuffer* mWaylandBuffer; -+ LayoutDeviceIntRegion mWaylandBufferDamage; -+ WindowBackBuffer* mBackupBuffer[BACK_BUFFER_NUM]; -+ RefPtr mImageSurface; - wl_callback* mFrameCallback; -- wl_surface* mFrameCallbackSurface; -+ wl_surface* mLastCommittedSurface; - MessageLoop* mDisplayThreadMessageLoop; -- bool mDelayedCommit; -- bool mFullScreenDamage; -+ WindowSurfaceWayland** mDelayedCommitHandle; -+ bool mDrawToWaylandBufferDirectly; -+ bool mPendingCommit; -+ bool mWaylandBufferFullScreenDamage; - bool mIsMainThread; -+ bool mNeedScaleFactorUpdate; - }; - - } // namespace widget -diff -up thunderbird-60.6.1/widget/gtk/WindowSurfaceProvider.cpp.old thunderbird-60.6.1/widget/gtk/WindowSurfaceProvider.cpp ---- thunderbird-60.6.1/widget/gtk/WindowSurfaceProvider.cpp.old 2019-05-14 21:11:50.219841534 +0200 -+++ thunderbird-60.6.1/widget/gtk/WindowSurfaceProvider.cpp 2019-05-14 21:11:58.228755117 +0200 -@@ -52,9 +52,6 @@ void WindowSurfaceProvider::Initialize(D - - #ifdef MOZ_WAYLAND - void WindowSurfaceProvider::Initialize(nsWindow* aWidget) { -- MOZ_ASSERT(aWidget->GetWaylandDisplay(), -- "We are supposed to have a Wayland display!"); -- - mWidget = aWidget; - mIsX11Display = false; - } diff --git a/mozilla-1353817.patch b/mozilla-1353817.patch index dc8d8f8..8bdac06 100644 --- a/mozilla-1353817.patch +++ b/mozilla-1353817.patch @@ -1,27 +1,12 @@ -From 1cc652f5525f458b0b4ceb12af24bf5a4367db32 Mon Sep 17 00:00:00 2001 -From: Nicolas Dufresne -Date: Tue, 23 May 2017 13:09:48 -0400 -Subject: [PATCH] Bug 1353817: Include SkNx_neon.h for ARM64 too - -This fixes build errors as arm_neon.h was missing along with some -missing converters. ---- - gfx/skia/skia/src/core/SkNx.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/gfx/skia/skia/src/core/SkNx.h b/gfx/skia/skia/src/core/SkNx.h -index 6bca856..b0427aa 100644 ---- a/gfx/skia/skia/src/core/SkNx.h -+++ b/gfx/skia/skia/src/core/SkNx.h -@@ -299,7 +299,7 @@ typedef SkNx<4, uint32_t> Sk4u; +diff -up thunderbird-68.0/gfx/skia/skia/include/private/SkNx.h.1353817 thunderbird-68.0/gfx/skia/skia/include/private/SkNx.h +--- thunderbird-68.0/gfx/skia/skia/include/private/SkNx.h.1353817 2019-08-29 16:31:20.892290062 +0200 ++++ thunderbird-68.0/gfx/skia/skia/include/private/SkNx.h 2019-08-29 16:32:05.430436157 +0200 +@@ -416,7 +416,7 @@ typedef SkNx<8, uint32_t> Sk8u; // Include platform specific specializations if available. #if !defined(SKNX_NO_SIMD) && SK_CPU_SSE_LEVEL >= SK_CPU_SSE_LEVEL_SSE2 - #include "../opts/SkNx_sse.h" + #include "SkNx_sse.h" -#elif !defined(SKNX_NO_SIMD) && defined(SK_ARM_HAS_NEON) +#elif !defined(SKNX_NO_SIMD) && (defined(SK_ARM_HAS_NEON) || defined(SK_CPU_ARM64)) - #include "../opts/SkNx_neon.h" + #include "SkNx_neon.h" #else --- -2.9.4 - diff --git a/mozilla-1460871-ldap-query.patch b/mozilla-1460871-ldap-query.patch deleted file mode 100644 index 2f9c23d..0000000 --- a/mozilla-1460871-ldap-query.patch +++ /dev/null @@ -1,164 +0,0 @@ -diff -up thunderbird-60.2.1/comm/ldap/xpcom/public/nsILDAPOperation.idl.1460871-ldap-query thunderbird-60.2.1/comm/ldap/xpcom/public/nsILDAPOperation.idl ---- thunderbird-60.2.1/comm/ldap/xpcom/public/nsILDAPOperation.idl.1460871-ldap-query 2018-10-01 16:52:39.000000000 +0200 -+++ thunderbird-60.2.1/comm/ldap/xpcom/public/nsILDAPOperation.idl 2018-10-04 09:40:04.491575949 +0200 -@@ -52,6 +52,10 @@ interface nsILDAPOperation : nsISupports - * private parameter (anything caller desires) - */ - attribute nsISupports closure; -+ /** -+ * number of the request for compare that the request is still valid. -+ */ -+ attribute unsigned long requestNum; - - /** - * No time and/or size limit specified -diff -up thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.cpp.1460871-ldap-query thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.cpp ---- thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.cpp.1460871-ldap-query 2018-10-01 16:52:39.000000000 +0200 -+++ thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.cpp 2018-10-04 09:40:04.491575949 +0200 -@@ -400,6 +400,19 @@ convertControlArray(nsIArray *aXpcomArra - return NS_OK; - } - -+ /* attribute unsigned long requestNum; */ -+NS_IMETHODIMP nsLDAPOperation::GetRequestNum(uint32_t *aRequestNum) -+{ -+ *aRequestNum = mRequestNum; -+ return NS_OK; -+} -+ -+NS_IMETHODIMP nsLDAPOperation::SetRequestNum(uint32_t aRequestNum) -+{ -+ mRequestNum = aRequestNum; -+ return NS_OK; -+} -+ - NS_IMETHODIMP - nsLDAPOperation::SearchExt(const nsACString& aBaseDn, int32_t aScope, - const nsACString& aFilter, -diff -up thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.h.1460871-ldap-query thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.h ---- thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.h.1460871-ldap-query 2018-10-01 16:52:39.000000000 +0200 -+++ thunderbird-60.2.1/comm/ldap/xpcom/src/nsLDAPOperation.h 2018-10-04 09:40:04.491575949 +0200 -@@ -36,6 +36,8 @@ class nsLDAPOperation : public nsILDAPOp - * used to break cycles - */ - void Clear(); -+ // Stores the request number for later check of the operation is still valid -+ int32_t mRequestNum; - - private: - virtual ~nsLDAPOperation(); -diff -up thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp.1460871-ldap-query thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp ---- thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp.1460871-ldap-query 2018-10-01 16:52:43.000000000 +0200 -+++ thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPDirectoryQuery.cpp 2018-10-04 09:40:55.334670404 +0200 -@@ -22,6 +22,8 @@ - - using namespace mozilla; - -+extern mozilla::LazyLogModule gLDAPLogModule; // defined in nsLDAPService.cpp -+ - // nsAbLDAPListenerBase inherits nsILDAPMessageListener - class nsAbQueryLDAPMessageListener : public nsAbLDAPListenerBase - { -@@ -66,7 +68,6 @@ protected: - - bool mFinished; - bool mCanceled; -- bool mWaitingForPrevQueryToFinish; - - nsCOMPtr mServerSearchControls; - nsCOMPtr mClientSearchControls; -@@ -94,7 +95,6 @@ nsAbQueryLDAPMessageListener::nsAbQueryL - mResultLimit(resultLimit), - mFinished(false), - mCanceled(false), -- mWaitingForPrevQueryToFinish(false), - mServerSearchControls(serverSearchControls), - mClientSearchControls(clientSearchControls) - { -@@ -116,9 +116,6 @@ nsresult nsAbQueryLDAPMessageListener::C - return NS_OK; - - mCanceled = true; -- if (!mFinished) -- mWaitingForPrevQueryToFinish = true; -- - return NS_OK; - } - -@@ -129,6 +126,8 @@ NS_IMETHODIMP nsAbQueryLDAPMessageListen - - int32_t messageType; - rv = aMessage->GetType(&messageType); -+ uint32_t requestNum; -+ mOperation->GetRequestNum(&requestNum); - NS_ENSURE_SUCCESS(rv, rv); - - bool cancelOperation = false; -@@ -137,6 +136,14 @@ NS_IMETHODIMP nsAbQueryLDAPMessageListen - { - MutexAutoLock lock (mLock); - -+ if (requestNum != sCurrentRequestNum) { -+ MOZ_LOG(gLDAPLogModule, mozilla::LogLevel::Debug, -+ ("nsAbQueryLDAPMessageListener::OnLDAPMessage: Ignoring message with " -+ "request num %d, current request num is %d.", -+ requestNum, sCurrentRequestNum)); -+ return NS_OK; -+ } -+ - if (mFinished) - return NS_OK; - -@@ -166,11 +173,10 @@ NS_IMETHODIMP nsAbQueryLDAPMessageListen - rv = OnLDAPMessageSearchResult(aMessage); - break; - case nsILDAPMessage::RES_SEARCH_ENTRY: -- if (!mFinished && !mWaitingForPrevQueryToFinish) -+ if (!mFinished) - rv = OnLDAPMessageSearchEntry(aMessage); - break; - case nsILDAPMessage::RES_SEARCH_RESULT: -- mWaitingForPrevQueryToFinish = false; - rv = OnLDAPMessageSearchResult(aMessage); - NS_ENSURE_SUCCESS(rv, rv); - break; -@@ -207,6 +213,8 @@ nsresult nsAbQueryLDAPMessageListener::D - rv = mOperation->Init(mConnection, this, nullptr); - NS_ENSURE_SUCCESS(rv, rv); - -+ mOperation->SetRequestNum(++sCurrentRequestNum); -+ - nsAutoCString dn; - rv = mSearchUrl->GetDn(dn); - NS_ENSURE_SUCCESS(rv, rv); -diff -up thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.cpp.1460871-ldap-query thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.cpp ---- thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.cpp.1460871-ldap-query 2018-10-01 16:52:43.000000000 +0200 -+++ thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.cpp 2018-10-04 09:40:04.492575951 +0200 -@@ -20,6 +20,8 @@ - - using namespace mozilla; - -+uint32_t nsAbLDAPListenerBase::sCurrentRequestNum = 0; -+ - nsAbLDAPListenerBase::nsAbLDAPListenerBase(nsILDAPURL* url, - nsILDAPConnection* connection, - const nsACString &login, -@@ -249,6 +251,7 @@ NS_IMETHODIMP nsAbLDAPListenerBase::OnLD - InitFailed(); - return rv; - } -+ mOperation->SetRequestNum(++sCurrentRequestNum); - - // Try non-password mechanisms first - if (mSaslMechanism.EqualsLiteral("GSSAPI")) -diff -up thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.h.1460871-ldap-query thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.h ---- thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.h.1460871-ldap-query 2018-10-01 16:52:43.000000000 +0200 -+++ thunderbird-60.2.1/comm/mailnews/addrbook/src/nsAbLDAPListenerBase.h 2018-10-04 09:40:04.492575951 +0200 -@@ -47,6 +47,7 @@ protected: - int32_t mTimeOut; - bool mBound; - bool mInitialized; -+ static uint32_t sCurrentRequestNum; - - mozilla::Mutex mLock; - }; diff --git a/mozilla-1508378.patch b/mozilla-1508378.patch deleted file mode 100644 index 127256e..0000000 --- a/mozilla-1508378.patch +++ /dev/null @@ -1,55 +0,0 @@ -diff -up thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.cpp.1508378 thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.cpp ---- thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.cpp.1508378 2019-04-12 09:23:26.846503741 +0200 -+++ thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.cpp 2019-04-12 09:25:45.661937077 +0200 -@@ -567,6 +567,23 @@ static void WaylandBufferDelayCommitHand - } - } - -+void WindowSurfaceWayland::CalcRectScale(LayoutDeviceIntRect& aRect, int aScale) { -+ if (aRect.x & 0x1) { -+ aRect.width += 1; -+ } -+ aRect.x = aRect.x / aScale; -+ -+ if (aRect.y & 0x1) { -+ aRect.height += 1; -+ } -+ aRect.y = aRect.y / aScale; -+ -+ aRect.width = (aRect.width & 0x1) ? aRect.width / aScale + 1 : -+ aRect.width / aScale; -+ aRect.height = (aRect.height & 0x1) ? aRect.height / aScale + 1 : -+ aRect.height / aScale; -+} -+ - void WindowSurfaceWayland::CommitWaylandBuffer() { - MOZ_ASSERT(mPendingCommit, "Committing empty surface!"); - -@@ -617,11 +634,13 @@ void WindowSurfaceWayland::CommitWayland - gint scaleFactor = mWindow->GdkScaleFactor(); - for (auto iter = mWaylandBufferDamage.RectIter(); !iter.Done(); - iter.Next()) { -- const mozilla::LayoutDeviceIntRect& r = iter.Get(); -+ mozilla::LayoutDeviceIntRect r = iter.Get(); - // We need to remove the scale factor because the wl_surface_damage - // also multiplies by current scale factor. -- wl_surface_damage(waylandSurface, r.x / scaleFactor, r.y / scaleFactor, -- r.width / scaleFactor, r.height / scaleFactor); -+ if (scaleFactor > 1) { -+ CalcRectScale(r, scaleFactor); -+ } -+ wl_surface_damage(waylandSurface, r.x, r.y, r.width, r.height); - } - } - -diff -up thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.h.1508378 thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.h ---- thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.h.1508378 2019-04-12 09:23:26.817503860 +0200 -+++ thunderbird-60.6.1/widget/gtk/WindowSurfaceWayland.h 2019-04-12 09:23:26.846503741 +0200 -@@ -101,6 +101,7 @@ class WindowSurfaceWayland : public Wind - const gfx::IntSize& aLockSize); - bool CommitImageSurfaceToWaylandBuffer(const LayoutDeviceIntRegion& aRegion); - void CommitWaylandBuffer(); -+ void CalcRectScale(LayoutDeviceIntRect& aRect, int scale); - - // TODO: Do we need to hold a reference to nsWindow object? - nsWindow* mWindow; diff --git a/mozilla-1522780.patch b/mozilla-1522780.patch deleted file mode 100644 index 701f43b..0000000 --- a/mozilla-1522780.patch +++ /dev/null @@ -1,42 +0,0 @@ -diff -up thunderbird-60.5.0/toolkit/xre/nsAppRunner.cpp.1522780 thunderbird-60.5.0/toolkit/xre/nsAppRunner.cpp ---- thunderbird-60.5.0/toolkit/xre/nsAppRunner.cpp.1522780 2019-02-05 20:57:28.384820067 +0100 -+++ thunderbird-60.5.0/toolkit/xre/nsAppRunner.cpp 2019-02-05 21:05:27.623511428 +0100 -@@ -3872,10 +3872,26 @@ int XREMain::XRE_mainStartup(bool* aExit - saveDisplayArg = true; - } - -- // On Wayland disabled builds read X11 DISPLAY env exclusively -- // and don't care about different displays. --#if !defined(MOZ_WAYLAND) -- if (!display_name) { -+ bool disableWayland = true; -+#if defined(MOZ_WAYLAND) -+ // Make X11 backend the default one. -+ // Enable Wayland backend only when GDK_BACKEND is set and -+ // Gtk+ >= 3.22 where we can expect recent enough -+ // compositor & libwayland interface. -+ disableWayland = (PR_GetEnv("GDK_BACKEND") == nullptr) || -+ (gtk_check_version(3, 22, 0) != nullptr); -+ // Enable Wayland on Gtk+ >= 3.22 where we can expect recent enough -+ disableWayland = (gtk_check_version(3, 22, 0) != nullptr); -+ if (!disableWayland) { -+ // Make X11 backend the default one unless MOZ_ENABLE_WAYLAND or -+ // GDK_BACKEND are specified. -+ disableWayland = (PR_GetEnv("GDK_BACKEND") == nullptr) && -+ (PR_GetEnv("MOZ_ENABLE_WAYLAND") == nullptr); -+ } -+#endif -+ // On Wayland disabled builds read X11 DISPLAY env exclusively -+ // and don't care about different displays. -+ if (disableWayland && !display_name) { - display_name = PR_GetEnv("DISPLAY"); - if (!display_name) { - PR_fprintf(PR_STDERR, -@@ -3883,7 +3899,6 @@ int XREMain::XRE_mainStartup(bool* aExit - return 1; - } - } --#endif - - if (display_name) { - mGdkDisplay = gdk_display_open(display_name); diff --git a/mozilla-1526243.patch b/mozilla-1526243.patch deleted file mode 100644 index 2d12378..0000000 --- a/mozilla-1526243.patch +++ /dev/null @@ -1,340 +0,0 @@ -changeset: 465480:a86f3560fb17 -parent: 465477:26d9b7ffbd6b -user: Martin Stransky -date: Fri Mar 29 15:30:15 2019 +0100 -summary: Bug 1526243 - [Linux] Don't use nsGConfService in nsGNOMEShellService.cpp, r=glandium - -diff --git a/browser/components/shell/nsGNOMEShellService.cpp b/browser/components/shell/nsGNOMEShellService.cpp ---- a/browser/components/shell/nsGNOMEShellService.cpp -+++ b/browser/components/shell/nsGNOMEShellService.cpp -@@ -10,17 +10,16 @@ - #include "nsShellService.h" - #include "nsIServiceManager.h" - #include "nsIFile.h" - #include "nsIProperties.h" - #include "nsDirectoryServiceDefs.h" - #include "nsIPrefService.h" - #include "prenv.h" - #include "nsString.h" --#include "nsIGConfService.h" - #include "nsIGIOService.h" - #include "nsIGSettingsService.h" - #include "nsIStringBundle.h" - #include "nsIOutputStream.h" - #include "nsIProcess.h" - #include "nsServiceManagerUtils.h" - #include "nsComponentManagerUtils.h" - #include "nsIImageLoadingContent.h" -@@ -65,48 +64,39 @@ static const ProtocolAssociation appProt - - static const MimeTypeAssociation appTypes[] = { - // clang-format off - { "text/html", "htm html shtml" }, - { "application/xhtml+xml", "xhtml xht" } - // clang-format on - }; - --// GConf registry key constants --#define DG_BACKGROUND "/desktop/gnome/background" -- --#define kDesktopImageKey DG_BACKGROUND "/picture_filename" --#define kDesktopOptionsKey DG_BACKGROUND "/picture_options" --#define kDesktopDrawBGKey DG_BACKGROUND "/draw_background" --#define kDesktopColorKey DG_BACKGROUND "/primary_color" -- - #define kDesktopBGSchema "org.gnome.desktop.background" - #define kDesktopImageGSKey "picture-uri" - #define kDesktopOptionGSKey "picture-options" - #define kDesktopDrawBGGSKey "draw-background" - #define kDesktopColorGSKey "primary-color" - - static bool IsRunningAsASnap() { return (PR_GetEnv("SNAP") != nullptr); } - - nsresult nsGNOMEShellService::Init() { - nsresult rv; - - if (gfxPlatform::IsHeadless()) { - return NS_ERROR_NOT_AVAILABLE; - } - -- // GConf, GSettings or GIO _must_ be available, or we do not allow -+ // GSettings or GIO _must_ be available, or we do not allow - // CreateInstance to succeed. - -- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - nsCOMPtr gsettings = - do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); - -- if (!gconf && !giovfs && !gsettings) return NS_ERROR_NOT_AVAILABLE; -+ if (!giovfs && !gsettings) return NS_ERROR_NOT_AVAILABLE; - - // Check G_BROKEN_FILENAMES. If it's set, then filenames in glib use - // the locale encoding. If it's not set, they use UTF-8. - mUseLocaleFilenames = PR_GetEnv("G_BROKEN_FILENAMES") != nullptr; - - if (GetAppPathFromLauncher()) return NS_OK; - - nsCOMPtr dirSvc( -@@ -212,35 +202,23 @@ nsGNOMEShellService::IsDefaultBrowser(bo - } - if (strcmp(output, "yes\n") == 0) { - *aIsDefaultBrowser = true; - } - g_free(output); - return NS_OK; - } - -- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); -- -- bool enabled; - nsAutoCString handler; - nsCOMPtr gioApp; - - for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) { - if (!appProtocols[i].essential) continue; - -- if (gconf) { -- handler.Truncate(); -- gconf->GetAppForProtocol(nsDependentCString(appProtocols[i].name), -- &enabled, handler); -- -- if (!CheckHandlerMatchesAppName(handler) || !enabled) -- return NS_OK; // the handler is disabled or set to another app -- } -- - if (giovfs) { - handler.Truncate(); - nsCOMPtr handlerApp; - giovfs->GetAppForURIScheme(nsDependentCString(appProtocols[i].name), - getter_AddRefs(handlerApp)); - gioApp = do_QueryInterface(handlerApp); - if (!gioApp) return NS_OK; - -@@ -270,39 +248,17 @@ nsGNOMEShellService::SetDefaultBrowser(b - GSpawnFlags flags = static_cast(G_SPAWN_SEARCH_PATH | - G_SPAWN_STDOUT_TO_DEV_NULL | - G_SPAWN_STDERR_TO_DEV_NULL); - g_spawn_sync(nullptr, (gchar **)argv, nullptr, flags, nullptr, nullptr, - nullptr, nullptr, nullptr, nullptr); - return NS_OK; - } - -- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); - nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); -- if (gconf) { -- nsAutoCString appKeyValue; -- if (mAppIsInPath) { -- // mAppPath is in the users path, so use only the basename as the launcher -- gchar *tmp = g_path_get_basename(mAppPath.get()); -- appKeyValue = tmp; -- g_free(tmp); -- } else { -- appKeyValue = mAppPath; -- } -- -- appKeyValue.AppendLiteral(" %s"); -- -- for (unsigned int i = 0; i < ArrayLength(appProtocols); ++i) { -- if (appProtocols[i].essential || aClaimAllTypes) { -- gconf->SetAppForProtocol(nsDependentCString(appProtocols[i].name), -- appKeyValue); -- } -- } -- } -- - if (giovfs) { - nsresult rv; - nsCOMPtr bundleService = - do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - nsCOMPtr brandBundle; - rv = bundleService->CreateBundle(BRAND_PROPERTIES, -@@ -353,19 +309,21 @@ nsGNOMEShellService::SetDefaultBrowser(b - } - - return NS_OK; - } - - NS_IMETHODIMP - nsGNOMEShellService::GetCanSetDesktopBackground(bool *aResult) { - // setting desktop background is currently only supported -- // for Gnome or desktops using the same GSettings and GConf keys -- const char *gnomeSession = getenv("GNOME_DESKTOP_SESSION_ID"); -- if (gnomeSession) { -+ // for Gnome or desktops using the same GSettings keys -+ const char *currentDesktop = getenv("XDG_CURRENT_DESKTOP"); -+ if (currentDesktop && -+ (strstr(currentDesktop, "GNOME-Flashback:GNOME") != nullptr || -+ strstr(currentDesktop, "GNOME") != nullptr)) { - *aResult = true; - } else { - *aResult = false; - } - - return NS_OK; - } - -@@ -439,20 +397,16 @@ nsGNOMEShellService::SetDesktopBackgroun - filePath.Append('/'); - filePath.Append(NS_ConvertUTF16toUTF8(brandName)); - filePath.AppendLiteral("_wallpaper.png"); - - // write the image to a file in the home dir - rv = WriteImage(filePath, container); - NS_ENSURE_SUCCESS(rv, rv); - -- // Try GSettings first. If we don't have GSettings or the right schema, fall -- // back to using GConf instead. Note that if GSettings works ok, the changes -- // get mirrored to GConf by the gsettings->gconf bridge in -- // gnome-settings-daemon - nsCOMPtr gsettings = - do_GetService(NS_GSETTINGSSERVICE_CONTRACTID); - if (gsettings) { - nsCOMPtr background_settings; - gsettings->GetCollectionForSchema(NS_LITERAL_CSTRING(kDesktopBGSchema), - getter_AddRefs(background_settings)); - if (background_settings) { - gchar *file_uri = g_filename_to_uri(filePath.get(), nullptr, nullptr); -@@ -465,32 +419,17 @@ nsGNOMEShellService::SetDesktopBackgroun - nsDependentCString(file_uri)); - g_free(file_uri); - background_settings->SetBoolean(NS_LITERAL_CSTRING(kDesktopDrawBGGSKey), - true); - return rv; - } - } - -- // if the file was written successfully, set it as the system wallpaper -- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- -- if (gconf) { -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopOptionsKey), options); -- -- // Set the image to an empty string first to force a refresh -- // (since we could be writing a new image on top of an existing -- // Firefox_wallpaper.png and nautilus doesn't monitor the file for changes) -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), EmptyCString()); -- -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopImageKey), filePath); -- gconf->SetBool(NS_LITERAL_CSTRING(kDesktopDrawBGKey), true); -- } -- -- return rv; -+ return NS_ERROR_FAILURE; - } - - #define COLOR_16_TO_8_BIT(_c) ((_c) >> 8) - #define COLOR_8_TO_16_BIT(_c) ((_c) << 8 | (_c)) - - NS_IMETHODIMP - nsGNOMEShellService::GetDesktopBackgroundColor(uint32_t *aColor) { - nsCOMPtr gsettings = -@@ -502,22 +441,16 @@ nsGNOMEShellService::GetDesktopBackgroun - gsettings->GetCollectionForSchema(NS_LITERAL_CSTRING(kDesktopBGSchema), - getter_AddRefs(background_settings)); - if (background_settings) { - background_settings->GetString(NS_LITERAL_CSTRING(kDesktopColorGSKey), - background); - } - } - -- if (!background_settings) { -- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- if (gconf) -- gconf->GetString(NS_LITERAL_CSTRING(kDesktopColorKey), background); -- } -- - if (background.IsEmpty()) { - *aColor = 0; - return NS_OK; - } - - GdkColor color; - gboolean success = gdk_color_parse(background.get(), &color); - -@@ -555,23 +488,17 @@ nsGNOMEShellService::SetDesktopBackgroun - getter_AddRefs(background_settings)); - if (background_settings) { - background_settings->SetString(NS_LITERAL_CSTRING(kDesktopColorGSKey), - colorString); - return NS_OK; - } - } - -- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- -- if (gconf) { -- gconf->SetString(NS_LITERAL_CSTRING(kDesktopColorKey), colorString); -- } -- -- return NS_OK; -+ return NS_ERROR_FAILURE; - } - - NS_IMETHODIMP - nsGNOMEShellService::OpenApplication(int32_t aApplication) { - nsAutoCString scheme; - if (aApplication == APPLICATION_MAIL) - scheme.AssignLiteral("mailto"); - else if (aApplication == APPLICATION_NEWS) -@@ -581,55 +508,17 @@ nsGNOMEShellService::OpenApplication(int - - nsCOMPtr giovfs = do_GetService(NS_GIOSERVICE_CONTRACTID); - if (giovfs) { - nsCOMPtr handlerApp; - giovfs->GetAppForURIScheme(scheme, getter_AddRefs(handlerApp)); - if (handlerApp) return handlerApp->LaunchWithURI(nullptr, nullptr); - } - -- nsCOMPtr gconf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- if (!gconf) return NS_ERROR_FAILURE; -- -- bool enabled; -- nsAutoCString appCommand; -- gconf->GetAppForProtocol(scheme, &enabled, appCommand); -- -- if (!enabled) return NS_ERROR_FAILURE; -- -- // XXX we don't currently handle launching a terminal window. -- // If the handler requires a terminal, bail. -- bool requiresTerminal; -- gconf->HandlerRequiresTerminal(scheme, &requiresTerminal); -- if (requiresTerminal) return NS_ERROR_FAILURE; -- -- // Perform shell argument expansion -- int argc; -- char **argv; -- if (!g_shell_parse_argv(appCommand.get(), &argc, &argv, nullptr)) -- return NS_ERROR_FAILURE; -- -- char **newArgv = new char *[argc + 1]; -- int newArgc = 0; -- -- // Run through the list of arguments. Copy all of them to the new -- // argv except for %s, which we skip. -- for (int i = 0; i < argc; ++i) { -- if (strcmp(argv[i], "%s") != 0) newArgv[newArgc++] = argv[i]; -- } -- -- newArgv[newArgc] = nullptr; -- -- gboolean err = g_spawn_async(nullptr, newArgv, nullptr, G_SPAWN_SEARCH_PATH, -- nullptr, nullptr, nullptr, nullptr); -- -- g_strfreev(argv); -- delete[] newArgv; -- -- return err ? NS_OK : NS_ERROR_FAILURE; -+ return NS_ERROR_FAILURE; - } - - NS_IMETHODIMP - nsGNOMEShellService::OpenApplicationWithURI(nsIFile *aApplication, - const nsACString &aURI) { - nsresult rv; - nsCOMPtr process = - do_CreateInstance("@mozilla.org/process/util;1", &rv); - diff --git a/mozilla-1533969.patch b/mozilla-1533969.patch deleted file mode 100644 index f84d77a..0000000 --- a/mozilla-1533969.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up thunderbird-60.6.1/js/src/util/NativeStack.cpp.1533969 thunderbird-60.6.1/js/src/util/NativeStack.cpp -diff -up thunderbird-60.6.1/tools/profiler/core/platform.h.1533969 thunderbird-60.6.1/tools/profiler/core/platform.h ---- thunderbird-60.6.1/tools/profiler/core/platform.h.1533969 2019-03-26 12:51:50.138988424 +0100 -+++ thunderbird-60.6.1/tools/profiler/core/platform.h 2019-03-26 12:54:57.576579732 +0100 -@@ -47,11 +47,11 @@ - #if defined(__GLIBC__) - #include - #include --static inline pid_t gettid() { return (pid_t)syscall(SYS_gettid); } -+# define gettid() static_cast(syscall(SYS_gettid)) - #elif defined(GP_OS_darwin) - #include - #include --static inline pid_t gettid() { return (pid_t)syscall(SYS_thread_selfid); } -+# define gettid() static_cast(syscall(SYS_thread_selfid)) - #elif defined(GP_OS_android) - #include - #elif defined(GP_OS_windows) diff --git a/mozilla-1540145.patch b/mozilla-1540145.patch deleted file mode 100644 index efdf89d..0000000 --- a/mozilla-1540145.patch +++ /dev/null @@ -1,168 +0,0 @@ -diff -up firefox-66.0.1/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.mozilla-1540145 firefox-66.0.1/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp ---- firefox-66.0.1/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp.mozilla-1540145 2019-03-22 06:06:07.000000000 +0100 -+++ firefox-66.0.1/toolkit/system/unixproxy/nsUnixSystemProxySettings.cpp 2019-04-01 09:33:18.621166482 +0200 -@@ -6,7 +6,6 @@ - #include "nsISystemProxySettings.h" - #include "mozilla/ModuleUtils.h" - #include "nsIServiceManager.h" --#include "nsIGConfService.h" - #include "nsIURI.h" - #include "nsReadableUtils.h" - #include "nsArrayUtils.h" -@@ -32,16 +31,10 @@ class nsUnixSystemProxySettings final : - private: - ~nsUnixSystemProxySettings() = default; - -- nsCOMPtr mGConf; -- nsCOMPtr mGSettings; -+ nsCOMPtr mGSettings; - nsCOMPtr mProxySettings; - nsInterfaceHashtable - mSchemeProxySettings; -- bool IsProxyMode(const char* aMode); -- nsresult SetProxyResultFromGConf(const char* aKeyBase, const char* aType, -- nsACString& aResult); -- nsresult GetProxyFromGConf(const nsACString& aScheme, const nsACString& aHost, -- int32_t aPort, nsACString& aResult); - nsresult GetProxyFromGSettings(const nsACString& aScheme, - const nsACString& aHost, int32_t aPort, - nsACString& aResult); -@@ -66,20 +59,10 @@ nsresult nsUnixSystemProxySettings::Init - NS_LITERAL_CSTRING("org.gnome.system.proxy"), - getter_AddRefs(mProxySettings)); - } -- if (!mProxySettings) { -- mGConf = do_GetService(NS_GCONFSERVICE_CONTRACTID); -- } - - return NS_OK; - } - --bool nsUnixSystemProxySettings::IsProxyMode(const char* aMode) { -- nsAutoCString mode; -- return NS_SUCCEEDED(mGConf->GetString( -- NS_LITERAL_CSTRING("/system/proxy/mode"), mode)) && -- mode.EqualsASCII(aMode); --} -- - nsresult nsUnixSystemProxySettings::GetPACURI(nsACString& aResult) { - if (mProxySettings) { - nsCString proxyMode; -@@ -92,14 +75,8 @@ nsresult nsUnixSystemProxySettings::GetP - } - /* The org.gnome.system.proxy schema has been found, but auto mode is not - * set. Don't try the GConf and return empty string. */ -- aResult.Truncate(); -- return NS_OK; - } - -- if (mGConf && IsProxyMode("auto")) { -- return mGConf->GetString(NS_LITERAL_CSTRING("/system/proxy/autoconfig_url"), -- aResult); -- } - // Return an empty string when auto mode is not set. - aResult.Truncate(); - return NS_OK; -@@ -217,30 +194,6 @@ static nsresult GetProxyFromEnvironment( - return NS_OK; - } - --nsresult nsUnixSystemProxySettings::SetProxyResultFromGConf( -- const char* aKeyBase, const char* aType, nsACString& aResult) { -- nsAutoCString hostKey; -- hostKey.AppendASCII(aKeyBase); -- hostKey.AppendLiteral("host"); -- nsAutoCString host; -- nsresult rv = mGConf->GetString(hostKey, host); -- NS_ENSURE_SUCCESS(rv, rv); -- if (host.IsEmpty()) return NS_ERROR_FAILURE; -- -- nsAutoCString portKey; -- portKey.AppendASCII(aKeyBase); -- portKey.AppendLiteral("port"); -- int32_t port; -- rv = mGConf->GetInt(portKey, &port); -- NS_ENSURE_SUCCESS(rv, rv); -- -- /* When port is 0, proxy is not considered as enabled even if host is set. */ -- if (port == 0) return NS_ERROR_FAILURE; -- -- SetProxyResult(aType, host, port, aResult); -- return NS_OK; --} -- - nsresult nsUnixSystemProxySettings::SetProxyResultFromGSettings( - const char* aKeyBase, const char* aType, nsACString& aResult) { - nsDependentCString key(aKeyBase); -@@ -366,63 +319,6 @@ static bool HostIgnoredByProxy(const nsA - return memcmp(&ignoreAddr, &hostAddr, sizeof(PRIPv6Addr)) == 0; - } - --nsresult nsUnixSystemProxySettings::GetProxyFromGConf(const nsACString& aScheme, -- const nsACString& aHost, -- int32_t aPort, -- nsACString& aResult) { -- bool masterProxySwitch = false; -- mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_http_proxy"), -- &masterProxySwitch); -- // if no proxy is set in GConf return NS_ERROR_FAILURE -- if (!(IsProxyMode("manual") || masterProxySwitch)) { -- return NS_ERROR_FAILURE; -- } -- -- nsCOMPtr ignoreList; -- if (NS_SUCCEEDED(mGConf->GetStringList( -- NS_LITERAL_CSTRING("/system/http_proxy/ignore_hosts"), -- getter_AddRefs(ignoreList))) && -- ignoreList) { -- uint32_t len = 0; -- ignoreList->GetLength(&len); -- for (uint32_t i = 0; i < len; ++i) { -- nsCOMPtr str = do_QueryElementAt(ignoreList, i); -- if (str) { -- nsAutoString s; -- if (NS_SUCCEEDED(str->GetData(s)) && !s.IsEmpty()) { -- if (HostIgnoredByProxy(NS_ConvertUTF16toUTF8(s), aHost)) { -- aResult.AppendLiteral("DIRECT"); -- return NS_OK; -- } -- } -- } -- } -- } -- -- bool useHttpProxyForAll = false; -- // This setting sometimes doesn't exist, don't bail on failure -- mGConf->GetBool(NS_LITERAL_CSTRING("/system/http_proxy/use_same_proxy"), -- &useHttpProxyForAll); -- -- nsresult rv; -- if (!useHttpProxyForAll) { -- rv = SetProxyResultFromGConf("/system/proxy/socks_", "SOCKS", aResult); -- if (NS_SUCCEEDED(rv)) return rv; -- } -- -- if (aScheme.LowerCaseEqualsLiteral("http") || useHttpProxyForAll) { -- rv = SetProxyResultFromGConf("/system/http_proxy/", "PROXY", aResult); -- } else if (aScheme.LowerCaseEqualsLiteral("https")) { -- rv = SetProxyResultFromGConf("/system/proxy/secure_", "PROXY", aResult); -- } else if (aScheme.LowerCaseEqualsLiteral("ftp")) { -- rv = SetProxyResultFromGConf("/system/proxy/ftp_", "PROXY", aResult); -- } else { -- rv = NS_ERROR_FAILURE; -- } -- -- return rv; --} -- - nsresult nsUnixSystemProxySettings::GetProxyFromGSettings( - const nsACString& aScheme, const nsACString& aHost, int32_t aPort, - nsACString& aResult) { -@@ -494,7 +390,6 @@ nsresult nsUnixSystemProxySettings::GetP - nsresult rv = GetProxyFromGSettings(aScheme, aHost, aPort, aResult); - if (NS_SUCCEEDED(rv)) return rv; - } -- if (mGConf) return GetProxyFromGConf(aScheme, aHost, aPort, aResult); - - return GetProxyFromEnvironment(aScheme, aHost, aPort, aResult); - } diff --git a/rust-1.33-build.patch b/rust-1.33-build.patch deleted file mode 100644 index 746145f..0000000 --- a/rust-1.33-build.patch +++ /dev/null @@ -1,47 +0,0 @@ -diff -up thunderbird-60.8.0/servo/components/style_traits/values.rs.rust-1.33-build thunderbird-60.8.0/servo/components/style_traits/values.rs ---- thunderbird-60.8.0/servo/components/style_traits/values.rs.rust-1.33-build 2019-07-03 17:25:28.000000000 +0200 -+++ thunderbird-60.8.0/servo/components/style_traits/values.rs 2019-07-11 13:38:53.687318154 +0200 -@@ -135,6 +135,7 @@ where - } - } - -+/// Some comment - #[macro_export] - macro_rules! serialize_function { - ($dest: expr, $name: ident($( $arg: expr, )+)) => { -@@ -404,6 +405,7 @@ impl_to_css_for_predefined_type!(::csspa - impl_to_css_for_predefined_type!(::cssparser::Color); - impl_to_css_for_predefined_type!(::cssparser::UnicodeRange); - -+/// Some comment - #[macro_export] - macro_rules! define_css_keyword_enum { - (pub enum $name:ident { $($variant:ident = $css:expr,)+ }) => { -diff -up thunderbird-60.8.0/servo/components/style/properties/properties.mako.rs.old thunderbird-60.8.0/servo/components/style/properties/properties.mako.rs ---- thunderbird-60.8.0/servo/components/style/properties/properties.mako.rs.old 2019-07-11 14:22:51.393784701 +0200 -+++ thunderbird-60.8.0/servo/components/style/properties/properties.mako.rs 2019-07-11 14:24:03.182578100 +0200 -@@ -55,6 +55,7 @@ use style_adjuster::StyleAdjuster; - - pub use self::declaration_block::*; - -+/// Neco - #[cfg(feature = "gecko")] - #[macro_export] - macro_rules! property_name { -@@ -3852,7 +3853,7 @@ impl fmt::Debug for AliasId { - } - } - --// NOTE(emilio): Callers are responsible to deal with prefs. -+/// NOTE(emilio): Callers are responsible to deal with prefs. - #[macro_export] - macro_rules! css_properties_accessors { - ($macro_name: ident) => { -@@ -3875,6 +3876,7 @@ macro_rules! css_properties_accessors { - } - } - -+/// Neco - #[macro_export] - macro_rules! longhand_properties_idents { - ($macro_name: ident) => { diff --git a/sources b/sources index bb7ac03..6f69d8d 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -SHA512 (thunderbird-60.8.0.source.tar.xz) = b465544a8cbedf0aff0f737cf98e2d030331f1ea016b2e541dfe30a5cf3172f9075e5a9c8d6b7e0f97ffc2e0d3eebbaf9a39e76a499b9fc976bbc0c944dfd058 -SHA512 (thunderbird-langpacks-60.8.0-20190704.tar.xz) = 9613f678dde57ef2c99bf389a180a7c222472df74d935b80b49ab68e61cd36ad4950d7bad79fe11fdbbb728954b50297d80c4c4e422e4edfc0268fff012bf259 -SHA512 (lightning-langpacks-60.8.0.tar.xz) = 9ee5321810cc316e5d9725e6e43c95f24ab907a75962c1e78c9f24fe0eda421a4608f242018f1d52aa8fbc1d9be4a4e1e01cc707e0b8a9ae466505d0e3468fe2 +SHA512 (thunderbird-68.0.source.tar.xz) = 91f82016b71d65b58c1383248ac6f7a8cd8217409323eb14e8aabf2e509391bba4d18e0aa6d0cdac191d10e9794977f22f509078b7c5e3ac7c22afe379a0f299 +SHA512 (thunderbird-langpacks-68.0-20190829.tar.xz) = c11ca1f39c146cfbad8b2e4d5e1e8698caa6d97c9bb650b788a7df487dc3e2ee551aec9b814baae064b06543f0ae832583005e02c9d5cab1f3e66dbe1b28b08f +SHA512 (lightning-langpacks-68.0.tar.xz) = d51c99a5d3dd95b66552fab6fdf9d55d00f56dcc73389790354846078a0f973bbd6273ada0d342f09a4045f3453c7e2bdd166821b4100efc0bc511f77a099148 diff --git a/thunderbird-mozconfig b/thunderbird-mozconfig index c6e3cc4..805c81c 100644 --- a/thunderbird-mozconfig +++ b/thunderbird-mozconfig @@ -9,14 +9,12 @@ ac_add_options --libdir="$LIBDIR" ac_add_options --with-system-jpeg ac_add_options --with-system-zlib ac_add_options --with-system-libvpx -ac_add_options --with-pthreads ac_add_options --disable-tests ac_add_options --disable-strip # temporary disable system cairo, because compilation fails ac_add_options --disable-necko-wifi ac_add_options --disable-updater ac_add_options --enable-startup-notification -ac_add_options --enable-pie ac_add_options --with-system-icu # lightning related diff --git a/thunderbird.spec b/thunderbird.spec index 94fc335..65a47cc 100644 --- a/thunderbird.spec +++ b/thunderbird.spec @@ -14,6 +14,7 @@ ExcludeArch: s390x %define system_ffi 1 %define build_langpacks 1 +%global build_with_clang 0 %global disable_elfhack 0 %if 0%{?fedora} > 28 @@ -88,13 +89,13 @@ ExcludeArch: s390x Summary: Mozilla Thunderbird mail/newsgroup client Name: thunderbird -Version: 60.8.0 -Release: 2%{?dist} +Version: 68.0 +Release: 1%{?dist} URL: http://www.mozilla.org/projects/thunderbird/ License: MPLv1.1 or GPLv2+ or LGPLv2+ Source0: ftp://ftp.mozilla.org/pub/thunderbird/releases/%{version}%{?pre_version}/source/thunderbird-%{version}%{?pre_version}.source.tar.xz %if %{build_langpacks} -Source1: thunderbird-langpacks-%{version}-20190704.tar.xz +Source1: thunderbird-langpacks-%{version}-20190829.tar.xz # Locales for lightning Source2: lightning-langpacks-%{version}.tar.xz %endif @@ -109,15 +110,12 @@ Source28: thunderbird-wayland.sh.in Source29: thunderbird-wayland.desktop # Build patches -Patch1: rust-1.33-build.patch Patch9: mozilla-build-arm.patch Patch26: build-icu-big-endian.patch -Patch37: build-jit-atomic-always-lucky.patch -Patch40: build-aarch64-skia.patch Patch226: rhbz-1354671.patch Patch415: Bug-1238661---fix-mozillaSignalTrampoline-to-work-.patch +Patch416: firefox-SIOCGSTAMP.patch Patch103: rhbz-1219542-s390-build.patch -Patch104: mozilla-1533969.patch Patch105: thunderbird-debug.patch # PPC fix @@ -125,17 +123,11 @@ Patch304: mozilla-1245783.patch Patch305: build-big-endian.patch Patch306: mozilla-1353817.patch Patch307: build-disable-elfhack.patch -Patch309: mozilla-1460871-ldap-query.patch # Fedora specific patches -Patch311: firefox-wayland.patch -Patch312: mozilla-1522780.patch # Upstream patches -Patch400: mozilla-1526243.patch -Patch401: mozilla-1540145.patch Patch402: mozilla-526293.patch -Patch403: mozilla-1508378.patch %if %{official_branding} # Required by Mozilla Corporation @@ -170,8 +162,9 @@ BuildRequires: libXrender-devel BuildRequires: hunspell-devel BuildRequires: llvm BuildRequires: llvm-devel -BuildRequires: clang -BuildRequires: clang-libs +%if 0%{?build_with_clang} +BuildRequires: lld +%endif %if %{?system_sqlite} BuildRequires: sqlite-devel >= %{sqlite_version} Requires: sqlite >= %{sqlite_build_version} @@ -238,24 +231,19 @@ debug %{name}, you want to install %{name}-debuginfo instead. %setup -q # Build patches -%patch1 -p1 -b .rust-1.33-build %patch9 -p2 -b .arm %ifarch s390 %patch103 -p1 -b .rhbz-1219542-s390-build %endif -%patch104 -p1 -b .1533969 %patch105 -p1 -b .debug %patch304 -p1 -b .1245783 -%patch309 -p1 -b .1460871-ldap-query # Patch for big endian platforms only %if 0%{?big_endian} %patch26 -p1 -b .icu %patch305 -p1 -b .big-endian %endif -%patch37 -p1 -b .jit-atomic-lucky -%patch40 -p1 -b .aarch64-skia #ARM run-time patch %ifarch aarch64 %patch226 -p1 -b .1354671 @@ -263,6 +251,7 @@ debug %{name}, you want to install %{name}-debuginfo instead. %ifarch %{arm} %patch415 -p1 -b .mozilla-1238661 %endif +%patch416 -p1 -b .SIOCGSTAMP %patch306 -p1 -b .1353817 %if 0%{?disable_elfhack} @@ -270,13 +259,8 @@ debug %{name}, you want to install %{name}-debuginfo instead. %endif #cd .. -%patch311 -p1 -b .wayland -%patch312 -p1 -b .1522780 -%patch400 -p1 -b .1526243 -%patch401 -p1 -b .1540145 %patch402 -p1 -b .526293 -%patch403 -p1 -b .1508378 %if %{official_branding} # Required by Mozilla Corporation @@ -445,9 +429,11 @@ MOZ_OPT_FLAGS=$(echo "$MOZ_OPT_FLAGS" | %{__sed} -e 's/-g/-g1/') # (OOM when linking, rhbz#1238225) export MOZ_DEBUG_FLAGS=" " %endif +%if !0%{?build_with_clang} %ifarch s390 %{arm} ppc aarch64 i686 MOZ_LINK_FLAGS="-Wl,--no-keep-memory -Wl,--reduce-memory-overheads" %endif +%endif export CFLAGS=`echo $MOZ_OPT_FLAGS |sed -e 's/-fpermissive//g'` export CXXFLAGS=$MOZ_OPT_FLAGS @@ -456,6 +442,25 @@ export LDFLAGS=$MOZ_LINK_FLAGS export PREFIX='%{_prefix}' export LIBDIR='%{_libdir}' +%if 0%{?build_with_clang} +export LLVM_PROFDATA="llvm-profdata" +export AR="llvm-ar" +export NM="llvm-nm" +export RANLIB="llvm-ranlib" +echo "ac_add_options --enable-linker=lld" >> .mozconfig +%else +export CC=gcc +export CXX=g++ +export AR="gcc-ar" +export NM="gcc-nm" +export RANLIB="gcc-ranlib" +%endif + +%if 0%{?build_with_pgo} +echo "ac_add_options MOZ_PGO=1" >> .mozconfig +echo "ac_add_options --enable-lto" >> .mozconfig +%endif + MOZ_SMP_FLAGS=-j1 # On x86 architectures, Mozilla can build up to 4 jobs at once in parallel, # however builds tend to fail on other arches when building in parallel. @@ -657,8 +662,6 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{mozappdir}/plugin-container %{mozappdir}/defaults %{mozappdir}/dictionaries -%dir %{mozappdir}/extensions -%{mozappdir}/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}.xpi %if %{build_langpacks} %dir %{langpackdir} %endif @@ -698,6 +701,9 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #=============================================================================== %changelog +* Thu Aug 29 2019 Jan Horak - 68.0-1 +- Update to 68.0 + * Sat Jul 27 2019 Fedora Release Engineering - 60.8.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild