diff --git a/firefox-wayland-crash-mozbz1507475.patch b/firefox-wayland-crash-mozbz1507475.patch new file mode 100644 index 0000000..bab96bc --- /dev/null +++ b/firefox-wayland-crash-mozbz1507475.patch @@ -0,0 +1,94 @@ +diff -up firefox-63.0.3/widget/gtk/mozcontainer.cpp.mozbz1507475 firefox-63.0.3/widget/gtk/mozcontainer.cpp +--- firefox-63.0.3/widget/gtk/mozcontainer.cpp.mozbz1507475 2018-11-15 01:20:56.000000000 +0100 ++++ firefox-63.0.3/widget/gtk/mozcontainer.cpp 2018-11-21 15:41:41.858692640 +0100 +@@ -169,6 +169,8 @@ moz_container_class_init (MozContainerCl + } + + #if defined(MOZ_WAYLAND) ++static struct wl_subcompositor *subcompositor; ++ + static void + registry_handle_global (void *data, + struct wl_registry *registry, +@@ -176,9 +178,8 @@ registry_handle_global (void *data, + const char *interface, + uint32_t version) + { +- MozContainer *container = MOZ_CONTAINER(data); + if(strcmp(interface, "wl_subcompositor") == 0) { +- container->subcompositor = ++ subcompositor = + static_cast(wl_registry_bind(registry, + name, + &wl_subcompositor_interface, +@@ -197,6 +198,24 @@ static const struct wl_registry_listener + registry_handle_global, + registry_handle_global_remove + }; ++ ++struct wl_subcompositor* subcompositor_get(void) ++{ ++ if (!subcompositor) { ++ GdkDisplay *gdk_display = 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(gdk_display); ++ wl_registry* registry = wl_display_get_registry(display); ++ wl_registry_add_listener(registry, ®istry_listener, nullptr); ++ wl_display_dispatch(display); ++ wl_display_roundtrip(display); ++ } ++ return subcompositor; ++} + #endif + + void +@@ -208,25 +227,10 @@ moz_container_init (MozContainer *contai + + #if defined(MOZ_WAYLAND) + { +- container->subcompositor = nullptr; + container->surface = nullptr; + container->subsurface = nullptr; + container->eglwindow = nullptr; + container->parent_surface_committed = false; +- +- 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); +- } + } + #endif + } +@@ -298,7 +302,7 @@ moz_container_map_surface(MozContainer * + } + + container->subsurface = +- wl_subcompositor_get_subsurface (container->subcompositor, ++ wl_subcompositor_get_subsurface (subcompositor_get(), + container->surface, + gtk_surface); + gint x, y; +diff -up firefox-63.0.3/widget/gtk/mozcontainer.h.mozbz1507475 firefox-63.0.3/widget/gtk/mozcontainer.h +--- firefox-63.0.3/widget/gtk/mozcontainer.h.mozbz1507475 2018-11-15 01:20:56.000000000 +0100 ++++ firefox-63.0.3/widget/gtk/mozcontainer.h 2018-11-21 14:16:54.412397805 +0100 +@@ -69,7 +69,6 @@ struct _MozContainer + GList *children; + + #ifdef MOZ_WAYLAND +- struct wl_subcompositor *subcompositor; + struct wl_surface *surface; + struct wl_subsurface *subsurface; + struct wl_egl_window *eglwindow; diff --git a/firefox-wayland.patch b/firefox-wayland.patch index d5d1306..00b408c 100644 --- a/firefox-wayland.patch +++ b/firefox-wayland.patch @@ -1,523 +1,6 @@ -diff -up thunderbird-60.3.0/widget/gtk/gtk3drawing.cpp.wayland thunderbird-60.3.0/widget/gtk/gtk3drawing.cpp ---- thunderbird-60.3.0/widget/gtk/gtk3drawing.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/gtk3drawing.cpp 2018-11-20 12:04:43.731787368 +0100 -@@ -24,7 +24,7 @@ static gboolean checkbox_check_state; - static gboolean notebook_has_tab_gap; - - static ScrollbarGTKMetrics sScrollbarMetrics[2]; --static ScrollbarGTKMetrics sScrollbarMetricsActive[2]; -+static ScrollbarGTKMetrics sActiveScrollbarMetrics[2]; - static ToggleGTKMetrics sCheckboxMetrics; - static ToggleGTKMetrics sRadioMetrics; - static ToolbarGTKMetrics sToolbarMetrics; -@@ -39,6 +39,28 @@ static ToolbarGTKMetrics sToolbarMetrics - #endif - - static GtkBorder -+operator-(const GtkBorder& first, const GtkBorder& second) -+{ -+ GtkBorder result; -+ result.left = first.left - second.left; -+ result.right = first.right - second.right; -+ result.top = first.top - second.top; -+ result.bottom = first.bottom - second.bottom; -+ return result; -+} -+ -+static GtkBorder -+operator+(const GtkBorder& first, const GtkBorder& second) -+{ -+ GtkBorder result; -+ result.left = first.left + second.left; -+ result.right = first.right + second.right; -+ result.top = first.top + second.top; -+ result.bottom = first.bottom + second.bottom; -+ return result; -+} -+ -+static GtkBorder - operator+=(GtkBorder& first, const GtkBorder& second) - { - first.left += second.left; -@@ -84,7 +106,7 @@ moz_gtk_add_style_border(GtkStyleContext - { - GtkBorder border; - -- gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); - - *left += border.left; - *right += border.right; -@@ -98,7 +120,7 @@ moz_gtk_add_style_padding(GtkStyleContex - { - GtkBorder padding; - -- gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - - *left += padding.left; - *right += padding.right; -@@ -193,8 +215,8 @@ moz_gtk_refresh() - - sScrollbarMetrics[GTK_ORIENTATION_HORIZONTAL].initialized = false; - sScrollbarMetrics[GTK_ORIENTATION_VERTICAL].initialized = false; -- sScrollbarMetricsActive[GTK_ORIENTATION_HORIZONTAL].initialized = false; -- sScrollbarMetricsActive[GTK_ORIENTATION_VERTICAL].initialized = false; -+ sActiveScrollbarMetrics[GTK_ORIENTATION_HORIZONTAL].initialized = false; -+ sActiveScrollbarMetrics[GTK_ORIENTATION_VERTICAL].initialized = false; - sCheckboxMetrics.initialized = false; - sRadioMetrics.initialized = false; - sToolbarMetrics.initialized = false; -@@ -229,8 +251,8 @@ moz_gtk_get_focus_outline_size(GtkStyleC - { - GtkBorder border; - GtkBorder padding; -- gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); -- gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - *focus_h_width = border.left + padding.left; - *focus_v_width = border.top + padding.top; - return MOZ_GTK_SUCCESS; -@@ -688,8 +710,8 @@ calculate_button_inner_rect(GtkWidget* b - style = gtk_widget_get_style_context(button); - - /* This mirrors gtkbutton's child positioning */ -- gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); -- gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - - inner_rect->x = rect->x + border.left + padding.left; - inner_rect->y = rect->y + padding.top + border.top; -@@ -1008,19 +1030,21 @@ moz_gtk_scrollbar_thumb_paint(WidgetNode - GtkTextDirection direction) - { - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); -+ GtkStyleContext* style = GetStyleContext(widget, direction, state_flags); -+ -+ GtkOrientation orientation = (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ? -+ GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; - - GdkRectangle rect = *aRect; -- GtkStyleContext* style = GetStyleContext(widget, direction, state_flags); -- InsetByMargin(&rect, style); - -- gtk_render_slider(style, cr, -- rect.x, -- rect.y, -- rect.width, -- rect.height, -- (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ? -- GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); -+ const ScrollbarGTKMetrics* metrics = -+ (state->depressed || state->active || state->inHover) ? -+ GetActiveScrollbarMetrics(orientation) : -+ GetScrollbarMetrics(orientation); -+ Inset(&rect, metrics->margin.thumb); - -+ gtk_render_slider(style, cr, rect.x, rect.y, rect.width, rect.height, -+ orientation); - - return MOZ_GTK_SUCCESS; - } -@@ -1217,7 +1241,7 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect - GtkStyleContext* style) - { - gint x = rect->x, y = rect->y, width = rect->width, height = rect->height; -- int draw_focus_outline_only = state->depressed; // NS_THEME_FOCUS_OUTLINE -+ int draw_focus_outline_only = state->depressed; // StyleAppearance::FocusOutline - - if (draw_focus_outline_only) { - // Inflate the given 'rect' with the focus outline size. -@@ -1621,7 +1645,7 @@ moz_gtk_toolbar_separator_paint(cairo_t - rect->height * (end_fraction - start_fraction)); - } else { - GtkBorder padding; -- gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - - paint_width = padding.left; - if (paint_width > rect->width) -@@ -1790,7 +1814,7 @@ moz_gtk_get_tab_thickness(GtkStyleContex - return 0; /* tabs do not overdraw the tabpanel border with "no gap" style */ - - GtkBorder border; -- gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); - if (border.top < 2) - return 2; /* some themes don't set ythickness correctly */ - -@@ -2127,7 +2151,7 @@ moz_gtk_menu_separator_paint(cairo_t *cr - GtkBorder padding; - - style = GetStyleContext(MOZ_GTK_MENUSEPARATOR, direction); -- gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - - x = rect->x; - y = rect->y; -@@ -2433,7 +2457,7 @@ moz_gtk_get_widget_border(WidgetNodeType - NULL); - - if (!wide_separators) { -- gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), - &border); - separator_width = border.left; - } -@@ -2606,13 +2630,13 @@ moz_gtk_get_tab_border(gint* left, gint* - } else { - GtkBorder margin; - -- gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin); -+ gtk_style_context_get_margin(style, gtk_style_context_get_state(style), &margin); - *left += margin.left; - *right += margin.right; - - if (flags & MOZ_GTK_TAB_FIRST) { - style = GetStyleContext(MOZ_GTK_NOTEBOOK_HEADER, direction); -- gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin); -+ gtk_style_context_get_margin(style, gtk_style_context_get_state(style), &margin); - *left += margin.left; - *right += margin.right; - } -@@ -2687,7 +2711,7 @@ moz_gtk_get_toolbar_separator_width(gint - "separator-width", &separator_width, - NULL); - /* Just in case... */ -- gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); - *size = MAX(*size, (wide_separators ? separator_width : border.left)); - return MOZ_GTK_SUCCESS; - } -@@ -2718,7 +2742,7 @@ moz_gtk_get_menu_separator_height(gint * - gint separator_height; - GtkBorder padding; - GtkStyleContext* style = GetStyleContext(MOZ_GTK_MENUSEPARATOR); -- gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_SEPARATOR); -@@ -2750,8 +2774,8 @@ moz_gtk_get_entry_min_height(gint* heigh - - GtkBorder border; - GtkBorder padding; -- gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); -- gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - - *height += (border.top + border.bottom + padding.top + padding.bottom); - } -@@ -2901,23 +2925,17 @@ GetToggleMetrics(bool isRadio) - return metrics; - } - --const ScrollbarGTKMetrics* --GetScrollbarMetrics(GtkOrientation aOrientation, bool aActive) -+static void -+InitScrollbarMetrics(ScrollbarGTKMetrics* aMetrics, -+ GtkOrientation aOrientation, -+ GtkStateFlags aStateFlags) - { -- auto metrics = aActive ? &sScrollbarMetricsActive[aOrientation] : -- &sScrollbarMetrics[aOrientation]; -- if (metrics->initialized) -- return metrics; -- -- metrics->initialized = true; -- - WidgetNodeType scrollbar = aOrientation == GTK_ORIENTATION_HORIZONTAL ? - MOZ_GTK_SCROLLBAR_HORIZONTAL : MOZ_GTK_SCROLLBAR_VERTICAL; - - gboolean backward, forward, secondary_backward, secondary_forward; - GtkStyleContext* style = GetStyleContext(scrollbar, GTK_TEXT_DIR_NONE, -- aActive ? GTK_STATE_FLAG_PRELIGHT : -- GTK_STATE_FLAG_NORMAL); -+ aStateFlags); - gtk_style_context_get_style(style, - "has-backward-stepper", &backward, - "has-forward-stepper", &forward, -@@ -2938,15 +2956,15 @@ GetScrollbarMetrics(GtkOrientation aOrie - "min-slider-length", &min_slider_size, - nullptr); - -- metrics->size.thumb = -+ aMetrics->size.thumb = - SizeFromLengthAndBreadth(aOrientation, min_slider_size, slider_width); -- metrics->size.button = -+ aMetrics->size.button = - SizeFromLengthAndBreadth(aOrientation, stepper_size, slider_width); - // overall scrollbar - gint breadth = slider_width + 2 * trough_border; - // Require room for the slider in the track if we don't have buttons. - gint length = hasButtons ? 0 : min_slider_size + 2 * trough_border; -- metrics->size.scrollbar = -+ aMetrics->size.scrollbar = - SizeFromLengthAndBreadth(aOrientation, length, breadth); - - // Borders on the major axis are set on the outermost scrollbar -@@ -2956,23 +2974,24 @@ GetScrollbarMetrics(GtkOrientation aOrie - // receives mouse events, as in GTK. - // Other borders have been zero-initialized. - if (aOrientation == GTK_ORIENTATION_HORIZONTAL) { -- metrics->border.scrollbar.left = -- metrics->border.scrollbar.right = -- metrics->border.track.top = -- metrics->border.track.bottom = trough_border; -+ aMetrics->border.scrollbar.left = -+ aMetrics->border.scrollbar.right = -+ aMetrics->border.track.top = -+ aMetrics->border.track.bottom = trough_border; - } else { -- metrics->border.scrollbar.top = -- metrics->border.scrollbar.bottom = -- metrics->border.track.left = -- metrics->border.track.right = trough_border; -+ aMetrics->border.scrollbar.top = -+ aMetrics->border.scrollbar.bottom = -+ aMetrics->border.track.left = -+ aMetrics->border.track.right = trough_border; - } - -- return metrics; -+ // We're done here for Gtk+ < 3.20... -+ return; - } - - // GTK version > 3.20 - // scrollbar -- metrics->border.scrollbar = GetMarginBorderPadding(style); -+ aMetrics->border.scrollbar = GetMarginBorderPadding(style); - - WidgetNodeType contents, track, thumb; - if (aOrientation == GTK_ORIENTATION_HORIZONTAL) { -@@ -3003,72 +3022,102 @@ GetScrollbarMetrics(GtkOrientation aOrie - */ - - // thumb -- style = CreateStyleContextWithStates(thumb, GTK_TEXT_DIR_NONE, -- aActive ? GTK_STATE_FLAG_PRELIGHT : -- GTK_STATE_FLAG_NORMAL); -- metrics->size.thumb = GetMinMarginBox(style); -+ style = CreateStyleContextWithStates(thumb, GTK_TEXT_DIR_NONE, aStateFlags); -+ aMetrics->size.thumb = GetMinMarginBox(style); -+ gtk_style_context_get_margin(style, gtk_style_context_get_state(style), -+ &aMetrics->margin.thumb); - g_object_unref(style); - - // track -- style = CreateStyleContextWithStates(track, GTK_TEXT_DIR_NONE, -- aActive ? GTK_STATE_FLAG_PRELIGHT : -- GTK_STATE_FLAG_NORMAL); -- metrics->border.track = GetMarginBorderPadding(style); -- MozGtkSize trackMinSize = GetMinContentBox(style) + metrics->border.track; -- MozGtkSize trackSizeForThumb = metrics->size.thumb + metrics->border.track; -+ style = CreateStyleContextWithStates(track, GTK_TEXT_DIR_NONE, aStateFlags); -+ aMetrics->border.track = GetMarginBorderPadding(style); -+ MozGtkSize trackMinSize = GetMinContentBox(style) + aMetrics->border.track; -+ MozGtkSize trackSizeForThumb = aMetrics->size.thumb + aMetrics->border.track; - g_object_unref(style); - - // button - if (hasButtons) { - style = CreateStyleContextWithStates(MOZ_GTK_SCROLLBAR_BUTTON, -- GTK_TEXT_DIR_NONE, -- aActive ? GTK_STATE_FLAG_PRELIGHT : -- GTK_STATE_FLAG_NORMAL); -- metrics->size.button = GetMinMarginBox(style); -+ GTK_TEXT_DIR_NONE, aStateFlags); -+ aMetrics->size.button = GetMinMarginBox(style); - g_object_unref(style); - } else { -- metrics->size.button = {0, 0}; -+ aMetrics->size.button = {0, 0}; - } - if (aOrientation == GTK_ORIENTATION_HORIZONTAL) { -- metrics->size.button.Rotate(); -+ aMetrics->size.button.Rotate(); - // If the track is wider than necessary for the thumb, including when - // the buttons will cause Gecko to expand the track to fill - // available breadth, then add to the track border to prevent Gecko - // from expanding the thumb to fill available breadth. - gint extra = - std::max(trackMinSize.height, -- metrics->size.button.height) - trackSizeForThumb.height; -+ aMetrics->size.button.height) - trackSizeForThumb.height; - if (extra > 0) { - // If extra is odd, then the thumb is 0.5 pixels above - // center as in gtk_range_compute_slider_position(). -- metrics->border.track.top += extra / 2; -- metrics->border.track.bottom += extra - extra / 2; -+ aMetrics->border.track.top += extra / 2; -+ aMetrics->border.track.bottom += extra - extra / 2; - // Update size for change in border. - trackSizeForThumb.height += extra; - } - } else { - gint extra = - std::max(trackMinSize.width, -- metrics->size.button.width) - trackSizeForThumb.width; -+ aMetrics->size.button.width) - trackSizeForThumb.width; - if (extra > 0) { - // If extra is odd, then the thumb is 0.5 pixels to the left - // of center as in gtk_range_compute_slider_position(). -- metrics->border.track.left += extra / 2; -- metrics->border.track.right += extra - extra / 2; -+ aMetrics->border.track.left += extra / 2; -+ aMetrics->border.track.right += extra - extra / 2; - trackSizeForThumb.width += extra; - } - } - - style = CreateStyleContextWithStates(contents, GTK_TEXT_DIR_NONE, -- aActive ? GTK_STATE_FLAG_PRELIGHT : -- GTK_STATE_FLAG_NORMAL); -+ aStateFlags); - GtkBorder contentsBorder = GetMarginBorderPadding(style); - g_object_unref(style); - -- metrics->size.scrollbar = -- trackSizeForThumb + contentsBorder + metrics->border.scrollbar; -+ aMetrics->size.scrollbar = -+ trackSizeForThumb + contentsBorder + aMetrics->border.scrollbar; -+} -+ -+const ScrollbarGTKMetrics* -+GetScrollbarMetrics(GtkOrientation aOrientation) -+{ -+ auto metrics = &sScrollbarMetrics[aOrientation]; -+ if (!metrics->initialized) { -+ InitScrollbarMetrics(metrics, aOrientation, GTK_STATE_FLAG_NORMAL); -+ -+ // We calculate thumb margin here because it's composited from -+ // thumb class margin + difference margin between active and inactive -+ // scrollbars. It's a workaround which alows us to emulate -+ // overlay scrollbars for some Gtk+ themes (Ubuntu/Ambiance), -+ // when an inactive scrollbar thumb is smaller than the active one. -+ const ScrollbarGTKMetrics *metricsActive = -+ GetActiveScrollbarMetrics(aOrientation); -+ -+ if (metrics->size.thumb < metricsActive->size.thumb) { -+ metrics->margin.thumb += -+ (metrics->border.scrollbar + metrics->border.track) - -+ (metricsActive->border.scrollbar + metricsActive->border.track); -+ } - -- return metrics; -+ metrics->initialized = true; -+ } -+ return metrics; -+} -+ -+const ScrollbarGTKMetrics* -+GetActiveScrollbarMetrics(GtkOrientation aOrientation) -+{ -+ auto metrics = &sActiveScrollbarMetrics[aOrientation]; -+ if (!metrics->initialized) { -+ InitScrollbarMetrics(metrics, aOrientation, GTK_STATE_FLAG_PRELIGHT); -+ metrics->initialized = true; -+ } -+ return metrics; - } - - /* -@@ -3078,6 +3127,16 @@ GetScrollbarMetrics(GtkOrientation aOrie - bool - GetCSDDecorationSize(GtkWindow *aGtkWindow, GtkBorder* aDecorationSize) - { -+ // Available on GTK 3.20+. -+ static auto sGtkRenderBackgroundGetClip = -+ (void (*)(GtkStyleContext*, gdouble, gdouble, gdouble, gdouble, GdkRectangle*)) -+ dlsym(RTLD_DEFAULT, "gtk_render_background_get_clip"); -+ -+ if (!sGtkRenderBackgroundGetClip) { -+ *aDecorationSize = {0,0,0,0}; -+ return false; -+ } -+ - GtkStyleContext* context = gtk_widget_get_style_context(GTK_WIDGET(aGtkWindow)); - bool solidDecorations = gtk_style_context_has_class(context, "solid-csd"); - context = GetStyleContext(solidDecorations ? -@@ -3091,54 +3150,32 @@ GetCSDDecorationSize(GtkWindow *aGtkWind - gtk_style_context_get_padding(context, state, &padding); - *aDecorationSize += padding; - -- // Available on GTK 3.20+. -- static auto sGtkRenderBackgroundGetClip = -- (void (*)(GtkStyleContext*, gdouble, gdouble, gdouble, gdouble, GdkRectangle*)) -- dlsym(RTLD_DEFAULT, "gtk_render_background_get_clip"); - - GtkBorder margin; - gtk_style_context_get_margin(context, state, &margin); - -- GtkBorder extents = {0, 0, 0, 0}; -- if (sGtkRenderBackgroundGetClip) { -- /* Get shadow extents but combine with style margin; use the bigger value. -- */ -- GdkRectangle clip; -- sGtkRenderBackgroundGetClip(context, 0, 0, 0, 0, &clip); -- -- extents.top = -clip.y; -- extents.right = clip.width + clip.x; -- extents.bottom = clip.height + clip.y; -- extents.left = -clip.x; -- -- // Margin is used for resize grip size - it's not present on -- // popup windows. -- if (gtk_window_get_window_type(aGtkWindow) != GTK_WINDOW_POPUP) { -- extents.top = MAX(extents.top, margin.top); -- extents.right = MAX(extents.right, margin.right); -- extents.bottom = MAX(extents.bottom, margin.bottom); -- extents.left = MAX(extents.left, margin.left); -- } -- } else { -- /* If we can't get shadow extents use decoration-resize-handle instead -- * as a workaround. This is inspired by update_border_windows() -- * from gtkwindow.c although this is not 100% accurate as we emulate -- * the extents here. -- */ -- gint handle; -- gtk_widget_style_get(GetWidget(MOZ_GTK_WINDOW), -- "decoration-resize-handle", &handle, -- NULL); -- -- extents.top = handle + margin.top; -- extents.right = handle + margin.right; -- extents.bottom = handle + margin.bottom; -- extents.left = handle + margin.left; -+ /* Get shadow extents but combine with style margin; use the bigger value. -+ */ -+ GdkRectangle clip; -+ sGtkRenderBackgroundGetClip(context, 0, 0, 0, 0, &clip); -+ -+ GtkBorder extents; -+ extents.top = -clip.y; -+ extents.right = clip.width + clip.x; -+ extents.bottom = clip.height + clip.y; -+ extents.left = -clip.x; -+ -+ // Margin is used for resize grip size - it's not present on -+ // popup windows. -+ if (gtk_window_get_window_type(aGtkWindow) != GTK_WINDOW_POPUP) { -+ extents.top = MAX(extents.top, margin.top); -+ extents.right = MAX(extents.right, margin.right); -+ extents.bottom = MAX(extents.bottom, margin.bottom); -+ extents.left = MAX(extents.left, margin.left); - } - - *aDecorationSize += extents; -- -- return (sGtkRenderBackgroundGetClip != nullptr); -+ return true; - } - - /* cairo_t *cr argument has to be a system-cairo. */ diff -up thunderbird-60.3.0/widget/gtk/GtkCompositorWidget.cpp.wayland thunderbird-60.3.0/widget/gtk/GtkCompositorWidget.cpp --- thunderbird-60.3.0/widget/gtk/GtkCompositorWidget.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/GtkCompositorWidget.cpp 2018-11-20 12:04:43.731787368 +0100 ++++ thunderbird-60.3.0/widget/gtk/GtkCompositorWidget.cpp 2018-11-21 13:42:00.757025666 +0100 @@ -40,7 +40,9 @@ GtkCompositorWidget::GtkCompositorWidget // Grab the window's visual and depth @@ -529,1438 +12,19 @@ diff -up thunderbird-60.3.0/widget/gtk/GtkCompositorWidget.cpp.wayland thunderbi Visual* visual = windowAttrs.visual; int depth = windowAttrs.depth; -@@ -50,8 +52,8 @@ GtkCompositorWidget::GtkCompositorWidget +@@ -50,8 +52,7 @@ GtkCompositorWidget::GtkCompositorWidget mXDisplay, mXWindow, visual, - depth - ); -+ depth, -+ aInitData.Shaped()); ++ depth); } mClientSize = aInitData.InitialClientSize(); } -diff -up thunderbird-60.3.0/widget/gtk/gtkdrawing.h.wayland thunderbird-60.3.0/widget/gtk/gtkdrawing.h ---- thunderbird-60.3.0/widget/gtk/gtkdrawing.h.wayland 2018-10-30 12:45:37.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/gtkdrawing.h 2018-11-20 12:04:43.731787368 +0100 -@@ -83,6 +83,9 @@ typedef struct { - GtkBorder scrollbar; - GtkBorder track; - } border; -+ struct { -+ GtkBorder thumb; -+ } margin; - } ScrollbarGTKMetrics; - - typedef struct { -@@ -502,11 +505,17 @@ moz_gtk_get_scalethumb_metrics(GtkOrient - /** - * Get the metrics in GTK pixels for a scrollbar. - * aOrientation: [IN] the scrollbar orientation -- * aActive: [IN] Metricts for scrollbar with mouse pointer over it. -- * - */ - const ScrollbarGTKMetrics* --GetScrollbarMetrics(GtkOrientation aOrientation, bool aActive = false); -+GetScrollbarMetrics(GtkOrientation aOrientation); -+ -+/** -+ * Get the metrics in GTK pixels for a scrollbar which is active -+ * (selected by mouse pointer). -+ * aOrientation: [IN] the scrollbar orientation -+ */ -+const ScrollbarGTKMetrics* -+GetActiveScrollbarMetrics(GtkOrientation aOrientation); - - /** - * Get the desired size of a dropdown arrow button -diff -up thunderbird-60.3.0/widget/gtk/IMContextWrapper.cpp.wayland thunderbird-60.3.0/widget/gtk/IMContextWrapper.cpp ---- thunderbird-60.3.0/widget/gtk/IMContextWrapper.cpp.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/IMContextWrapper.cpp 2018-11-20 12:04:43.732787365 +0100 -@@ -14,6 +14,7 @@ - #include "mozilla/Likely.h" - #include "mozilla/MiscEvents.h" - #include "mozilla/Preferences.h" -+#include "mozilla/Telemetry.h" - #include "mozilla/TextEventDispatcher.h" - #include "mozilla/TextEvents.h" - #include "WritingModes.h" -@@ -59,6 +60,73 @@ GetEventType(GdkEventKey* aKeyEvent) - } - } - -+class GetEventStateName : public nsAutoCString -+{ -+public: -+ explicit GetEventStateName(guint aState, -+ IMContextWrapper::IMContextID aIMContextID = -+ IMContextWrapper::IMContextID::eUnknown) -+ { -+ if (aState & GDK_SHIFT_MASK) { -+ AppendModifier("shift"); -+ } -+ if (aState & GDK_CONTROL_MASK) { -+ AppendModifier("control"); -+ } -+ if (aState & GDK_MOD1_MASK) { -+ AppendModifier("mod1"); -+ } -+ if (aState & GDK_MOD2_MASK) { -+ AppendModifier("mod2"); -+ } -+ if (aState & GDK_MOD3_MASK) { -+ AppendModifier("mod3"); -+ } -+ if (aState & GDK_MOD4_MASK) { -+ AppendModifier("mod4"); -+ } -+ if (aState & GDK_MOD4_MASK) { -+ AppendModifier("mod5"); -+ } -+ if (aState & GDK_MOD4_MASK) { -+ AppendModifier("mod5"); -+ } -+ switch (aIMContextID) { -+ case IMContextWrapper::IMContextID::eIBus: -+ static const guint IBUS_HANDLED_MASK = 1 << 24; -+ static const guint IBUS_IGNORED_MASK = 1 << 25; -+ if (aState & IBUS_HANDLED_MASK) { -+ AppendModifier("IBUS_HANDLED_MASK"); -+ } -+ if (aState & IBUS_IGNORED_MASK) { -+ AppendModifier("IBUS_IGNORED_MASK"); -+ } -+ break; -+ case IMContextWrapper::IMContextID::eFcitx: -+ static const guint FcitxKeyState_HandledMask = 1 << 24; -+ static const guint FcitxKeyState_IgnoredMask = 1 << 25; -+ if (aState & FcitxKeyState_HandledMask) { -+ AppendModifier("FcitxKeyState_HandledMask"); -+ } -+ if (aState & FcitxKeyState_IgnoredMask) { -+ AppendModifier("FcitxKeyState_IgnoredMask"); -+ } -+ break; -+ default: -+ break; -+ } -+ } -+ -+private: -+ void AppendModifier(const char* aModifierName) -+ { -+ if (!IsEmpty()) { -+ AppendLiteral(" + "); -+ } -+ Append(aModifierName); -+ } -+}; -+ - class GetWritingModeName : public nsAutoCString - { - public: -@@ -281,12 +349,17 @@ IMContextWrapper::IMContextWrapper(nsWin - , mCompositionStart(UINT32_MAX) - , mProcessingKeyEvent(nullptr) - , mCompositionState(eCompositionState_NotComposing) -+ , mIMContextID(IMContextID::eUnknown) - , mIsIMFocused(false) -+ , mFallbackToKeyEvent(false) -+ , mKeyboardEventWasDispatched(false) - , mIsDeletingSurrounding(false) - , mLayoutChanged(false) - , mSetCursorPositionOnKeyEvent(true) - , mPendingResettingIMContext(false) - , mRetrieveSurroundingSignalReceived(false) -+ , mMaybeInDeadKeySequence(false) -+ , mIsIMInAsyncKeyHandlingMode(false) - { - static bool sFirstInstance = true; - if (sFirstInstance) { -@@ -299,15 +372,101 @@ IMContextWrapper::IMContextWrapper(nsWin - Init(); - } - -+static bool -+IsIBusInSyncMode() -+{ -+ // See ibus_im_context_class_init() in client/gtk2/ibusimcontext.c -+ // https://github.com/ibus/ibus/blob/86963f2f94d1e4fc213b01c2bc2ba9dcf4b22219/client/gtk2/ibusimcontext.c#L610 -+ const char* env = PR_GetEnv("IBUS_ENABLE_SYNC_MODE"); -+ -+ // See _get_boolean_env() in client/gtk2/ibusimcontext.c -+ // https://github.com/ibus/ibus/blob/86963f2f94d1e4fc213b01c2bc2ba9dcf4b22219/client/gtk2/ibusimcontext.c#L520-L537 -+ if (!env) { -+ return false; -+ } -+ nsDependentCString envStr(env); -+ if (envStr.IsEmpty() || -+ envStr.EqualsLiteral("0") || -+ envStr.EqualsLiteral("false") || -+ envStr.EqualsLiteral("False") || -+ envStr.EqualsLiteral("FALSE")) { -+ return false; -+ } -+ return true; -+} -+ -+static bool -+GetFcitxBoolEnv(const char* aEnv) -+{ -+ // See fcitx_utils_get_boolean_env in src/lib/fcitx-utils/utils.c -+ // https://github.com/fcitx/fcitx/blob/0c87840dc7d9460c2cb5feaeefec299d0d3d62ec/src/lib/fcitx-utils/utils.c#L721-L736 -+ const char* env = PR_GetEnv(aEnv); -+ if (!env) { -+ return false; -+ } -+ nsDependentCString envStr(env); -+ if (envStr.IsEmpty() || -+ envStr.EqualsLiteral("0") || -+ envStr.EqualsLiteral("false")) { -+ return false; -+ } -+ return true; -+} -+ -+static bool -+IsFcitxInSyncMode() -+{ -+ // See fcitx_im_context_class_init() in src/frontend/gtk2/fcitximcontext.c -+ // https://github.com/fcitx/fcitx/blob/78b98d9230dc9630e99d52e3172bdf440ffd08c4/src/frontend/gtk2/fcitximcontext.c#L395-L398 -+ return GetFcitxBoolEnv("IBUS_ENABLE_SYNC_MODE") || -+ GetFcitxBoolEnv("FCITX_ENABLE_SYNC_MODE"); -+} -+ -+nsDependentCSubstring -+IMContextWrapper::GetIMName() const -+{ -+ const char* contextIDChar = -+ gtk_im_multicontext_get_context_id(GTK_IM_MULTICONTEXT(mContext)); -+ if (!contextIDChar) { -+ return nsDependentCSubstring(); -+ } -+ -+ nsDependentCSubstring im(contextIDChar, strlen(contextIDChar)); -+ -+ // If the context is XIM, actual engine must be specified with -+ // |XMODIFIERS=@im=foo|. -+ const char* xmodifiersChar = PR_GetEnv("XMODIFIERS"); -+ if (!im.EqualsLiteral("xim") || !xmodifiersChar) { -+ return im; -+ } -+ -+ nsDependentCString xmodifiers(xmodifiersChar); -+ int32_t atIMValueStart = xmodifiers.Find("@im=") + 4; -+ if (atIMValueStart < 4 || -+ xmodifiers.Length() <= static_cast(atIMValueStart)) { -+ return im; -+ } -+ -+ int32_t atIMValueEnd = -+ xmodifiers.Find("@", false, atIMValueStart); -+ if (atIMValueEnd > atIMValueStart) { -+ return nsDependentCSubstring(xmodifiersChar + atIMValueStart, -+ atIMValueEnd - atIMValueStart); -+ } -+ -+ if (atIMValueEnd == kNotFound) { -+ return nsDependentCSubstring(xmodifiersChar + atIMValueStart, -+ strlen(xmodifiersChar) - atIMValueStart); -+ } -+ -+ return im; -+} -+ - void - IMContextWrapper::Init() - { -- MOZ_LOG(gGtkIMLog, LogLevel::Info, -- ("0x%p Init(), mOwnerWindow=0x%p", -- this, mOwnerWindow)); -- - MozContainer* container = mOwnerWindow->GetMozContainer(); -- NS_PRECONDITION(container, "container is null"); -+ MOZ_ASSERT(container, "container is null"); - GdkWindow* gdkWindow = gtk_widget_get_window(GTK_WIDGET(container)); - - // Overwrite selection colors of the window before associating the window -@@ -333,6 +492,47 @@ IMContextWrapper::Init() - G_CALLBACK(IMContextWrapper::OnStartCompositionCallback), this); - g_signal_connect(mContext, "preedit_end", - G_CALLBACK(IMContextWrapper::OnEndCompositionCallback), this); -+ nsDependentCSubstring im = GetIMName(); -+ if (im.EqualsLiteral("ibus")) { -+ mIMContextID = IMContextID::eIBus; -+ mIsIMInAsyncKeyHandlingMode = !IsIBusInSyncMode(); -+ // Although ibus has key snooper mode, it's forcibly disabled on Firefox -+ // in default settings by its whitelist since we always send key events -+ // to IME before handling shortcut keys. The whitelist can be -+ // customized with env, IBUS_NO_SNOOPER_APPS, but we don't need to -+ // support such rare cases for reducing maintenance cost. -+ mIsKeySnooped = false; -+ } else if (im.EqualsLiteral("fcitx")) { -+ mIMContextID = IMContextID::eFcitx; -+ mIsIMInAsyncKeyHandlingMode = !IsFcitxInSyncMode(); -+ // Although Fcitx has key snooper mode similar to ibus, it's also -+ // disabled on Firefox in default settings by its whitelist. The -+ // whitelist can be customized with env, IBUS_NO_SNOOPER_APPS or -+ // FCITX_NO_SNOOPER_APPS, but we don't need to support such rare cases -+ // for reducing maintenance cost. -+ mIsKeySnooped = false; -+ } else if (im.EqualsLiteral("uim")) { -+ mIMContextID = IMContextID::eUim; -+ mIsIMInAsyncKeyHandlingMode = false; -+ // We cannot know if uim uses key snooper since it's build option of -+ // uim. Therefore, we need to retrieve the consideration from the -+ // pref for making users and distributions allowed to choose their -+ // preferred value. -+ mIsKeySnooped = -+ Preferences::GetBool("intl.ime.hack.uim.using_key_snooper", true); -+ } else if (im.EqualsLiteral("scim")) { -+ mIMContextID = IMContextID::eScim; -+ mIsIMInAsyncKeyHandlingMode = false; -+ mIsKeySnooped = false; -+ } else if (im.EqualsLiteral("iiim")) { -+ mIMContextID = IMContextID::eIIIMF; -+ mIsIMInAsyncKeyHandlingMode = false; -+ mIsKeySnooped = false; -+ } else { -+ mIMContextID = IMContextID::eUnknown; -+ mIsIMInAsyncKeyHandlingMode = false; -+ mIsKeySnooped = false; -+ } - - // Simple context - if (sUseSimpleContext) { -@@ -361,6 +561,18 @@ IMContextWrapper::Init() - // Dummy context - mDummyContext = gtk_im_multicontext_new(); - gtk_im_context_set_client_window(mDummyContext, gdkWindow); -+ -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p Init(), mOwnerWindow=%p, mContext=%p (im=\"%s\"), " -+ "mIsIMInAsyncKeyHandlingMode=%s, mIsKeySnooped=%s, " -+ "mSimpleContext=%p, mDummyContext=%p, " -+ "gtk_im_multicontext_get_context_id()=\"%s\", " -+ "PR_GetEnv(\"XMODIFIERS\")=\"%s\"", -+ this, mOwnerWindow, mContext, nsAutoCString(im).get(), -+ ToChar(mIsIMInAsyncKeyHandlingMode), ToChar(mIsKeySnooped), -+ mSimpleContext, mDummyContext, -+ gtk_im_multicontext_get_context_id(GTK_IM_MULTICONTEXT(mContext)), -+ PR_GetEnv("XMODIFIERS"))); - } - - /* static */ -@@ -469,7 +681,7 @@ IMContextWrapper::OnDestroyWindow(nsWind - "mOwnerWindow=0x%p, mLastFocusedModule=0x%p", - this, aWindow, mLastFocusedWindow, mOwnerWindow, sLastFocusedContext)); - -- NS_PRECONDITION(aWindow, "aWindow must not be null"); -+ MOZ_ASSERT(aWindow, "aWindow must not be null"); - - if (mLastFocusedWindow == aWindow) { - EndIMEComposition(aWindow); -@@ -524,46 +736,46 @@ IMContextWrapper::OnDestroyWindow(nsWind - mOwnerWindow = nullptr; - mLastFocusedWindow = nullptr; - mInputContext.mIMEState.mEnabled = IMEState::DISABLED; -+ mPostingKeyEvents.Clear(); - - MOZ_LOG(gGtkIMLog, LogLevel::Debug, - ("0x%p OnDestroyWindow(), succeeded, Completely destroyed", - this)); - } - --// Work around gtk bug http://bugzilla.gnome.org/show_bug.cgi?id=483223: --// (and the similar issue of GTK+ IIIM) --// The GTK+ XIM and IIIM modules register handlers for the "closed" signal --// on the display, but: --// * The signal handlers are not disconnected when the module is unloaded. --// --// The GTK+ XIM module has another problem: --// * When the signal handler is run (with the module loaded) it tries --// XFree (and fails) on a pointer that did not come from Xmalloc. --// --// To prevent these modules from being unloaded, use static variables to --// hold ref of GtkIMContext class. --// For GTK+ XIM module, to prevent the signal handler from being run, --// find the signal handlers and remove them. --// --// GtkIMContextXIMs share XOpenIM connections and display closed signal --// handlers (where possible). -- - void - IMContextWrapper::PrepareToDestroyContext(GtkIMContext* aContext) - { -- GtkIMContext *slave = nullptr; //TODO GTK3 -- if (!slave) { -- return; -- } -- -- GType slaveType = G_TYPE_FROM_INSTANCE(slave); -- const gchar *im_type_name = g_type_name(slaveType); -- if (strcmp(im_type_name, "GtkIMContextIIIM") == 0) { -- // Add a reference to prevent the IIIM module from being unloaded -- static gpointer gtk_iiim_context_class = -- g_type_class_ref(slaveType); -- // Mute unused variable warning: -- (void)gtk_iiim_context_class; -+ if (mIMContextID == IMContextID::eIIIMF) { -+ // IIIM module registers handlers for the "closed" signal on the -+ // display, but the signal handler is not disconnected when the module -+ // is unloaded. To prevent the module from being unloaded, use static -+ // variable to hold reference of slave context class declared by IIIM. -+ // Note that this does not grab any instance, it grabs the "class". -+ static gpointer sGtkIIIMContextClass = nullptr; -+ if (!sGtkIIIMContextClass) { -+ // We retrieved slave context class with g_type_name() and actual -+ // slave context instance when our widget was GTK2. That must be -+ // _GtkIMContext::priv::slave in GTK3. However, _GtkIMContext::priv -+ // is an opacity struct named _GtkIMMulticontextPrivate, i.e., it's -+ // not exposed by GTK3. Therefore, we cannot access the instance -+ // safely. So, we need to retrieve the slave context class with -+ // g_type_from_name("GtkIMContextIIIM") directly (anyway, we needed -+ // to compare the class name with "GtkIMContextIIIM"). -+ GType IIMContextType = g_type_from_name("GtkIMContextIIIM"); -+ if (IIMContextType) { -+ sGtkIIIMContextClass = g_type_class_ref(IIMContextType); -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p PrepareToDestroyContext(), added to reference to " -+ "GtkIMContextIIIM class to prevent it from being unloaded", -+ this)); -+ } else { -+ MOZ_LOG(gGtkIMLog, LogLevel::Error, -+ ("0x%p PrepareToDestroyContext(), FAILED to prevent the " -+ "IIIM module from being uploaded", -+ this)); -+ } -+ } - } - } - -@@ -603,9 +815,9 @@ IMContextWrapper::OnBlurWindow(nsWindow* - bool - IMContextWrapper::OnKeyEvent(nsWindow* aCaller, - GdkEventKey* aEvent, -- bool aKeyDownEventWasSent /* = false */) -+ bool aKeyboardEventWasDispatched /* = false */) - { -- NS_PRECONDITION(aEvent, "aEvent must be non-null"); -+ MOZ_ASSERT(aEvent, "aEvent must be non-null"); - - if (!mInputContext.mIMEState.MaybeEditable() || - MOZ_UNLIKELY(IsDestroyed())) { -@@ -613,13 +825,24 @@ IMContextWrapper::OnKeyEvent(nsWindow* a - } - - MOZ_LOG(gGtkIMLog, LogLevel::Info, -- ("0x%p OnKeyEvent(aCaller=0x%p, aKeyDownEventWasSent=%s), " -- "mCompositionState=%s, current context=0x%p, active context=0x%p, " -- "aEvent(0x%p): { type=%s, keyval=%s, unicode=0x%X }", -- this, aCaller, ToChar(aKeyDownEventWasSent), -+ ("0x%p OnKeyEvent(aCaller=0x%p, " -+ "aEvent(0x%p): { type=%s, keyval=%s, unicode=0x%X, state=%s, " -+ "time=%u, hardware_keycode=%u, group=%u }, " -+ "aKeyboardEventWasDispatched=%s)", -+ this, aCaller, aEvent, GetEventType(aEvent), -+ gdk_keyval_name(aEvent->keyval), -+ gdk_keyval_to_unicode(aEvent->keyval), -+ GetEventStateName(aEvent->state, mIMContextID).get(), -+ aEvent->time, aEvent->hardware_keycode, aEvent->group, -+ ToChar(aKeyboardEventWasDispatched))); -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p OnKeyEvent(), mMaybeInDeadKeySequence=%s, " -+ "mCompositionState=%s, current context=%p, active context=%p, " -+ "mIMContextID=%s, mIsIMInAsyncKeyHandlingMode=%s", -+ this, ToChar(mMaybeInDeadKeySequence), - GetCompositionStateName(), GetCurrentContext(), GetActiveContext(), -- aEvent, GetEventType(aEvent), gdk_keyval_name(aEvent->keyval), -- gdk_keyval_to_unicode(aEvent->keyval))); -+ GetIMContextIDName(mIMContextID), -+ ToChar(mIsIMInAsyncKeyHandlingMode))); - - if (aCaller != mLastFocusedWindow) { - MOZ_LOG(gGtkIMLog, LogLevel::Error, -@@ -644,49 +867,158 @@ IMContextWrapper::OnKeyEvent(nsWindow* a - mSetCursorPositionOnKeyEvent = false; - } - -- mKeyDownEventWasSent = aKeyDownEventWasSent; -- mFilterKeyEvent = true; -+ // Let's support dead key event even if active keyboard layout also -+ // supports complicated composition like CJK IME. -+ bool isDeadKey = -+ KeymapWrapper::ComputeDOMKeyNameIndex(aEvent) == KEY_NAME_INDEX_Dead; -+ mMaybeInDeadKeySequence |= isDeadKey; -+ -+ // If current context is mSimpleContext, both ibus and fcitx handles key -+ // events synchronously. So, only when current context is mContext which -+ // is GtkIMMulticontext, the key event may be handled by IME asynchronously. -+ bool maybeHandledAsynchronously = -+ mIsIMInAsyncKeyHandlingMode && currentContext == mContext; -+ -+ // If IM is ibus or fcitx and it handles key events asynchronously, -+ // they mark aEvent->state as "handled by me" when they post key event -+ // to another process. Unfortunately, we need to check this hacky -+ // flag because it's difficult to store all pending key events by -+ // an array or a hashtable. -+ if (maybeHandledAsynchronously) { -+ switch (mIMContextID) { -+ case IMContextID::eIBus: -+ // ibus won't send back key press events in a dead key sequcne. -+ if (mMaybeInDeadKeySequence && aEvent->type == GDK_KEY_PRESS) { -+ maybeHandledAsynchronously = false; -+ break; -+ } -+ // ibus handles key events synchronously if focused editor is -+ // or |ime-mode: disabled;|. -+ if (mInputContext.mIMEState.mEnabled == IMEState::PASSWORD) { -+ maybeHandledAsynchronously = false; -+ break; -+ } -+ // See src/ibustypes.h -+ static const guint IBUS_IGNORED_MASK = 1 << 25; -+ // If IBUS_IGNORED_MASK was set to aEvent->state, the event -+ // has already been handled by another process and it wasn't -+ // used by IME. -+ if (aEvent->state & IBUS_IGNORED_MASK) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p OnKeyEvent(), aEvent->state has " -+ "IBUS_IGNORED_MASK, so, it won't be handled " -+ "asynchronously anymore. Removing posted events from " -+ "the queue", -+ this)); -+ maybeHandledAsynchronously = false; -+ mPostingKeyEvents.RemoveEvent(aEvent); -+ break; -+ } -+ break; -+ case IMContextID::eFcitx: -+ // fcitx won't send back key press events in a dead key sequcne. -+ if (mMaybeInDeadKeySequence && aEvent->type == GDK_KEY_PRESS) { -+ maybeHandledAsynchronously = false; -+ break; -+ } -+ -+ // fcitx handles key events asynchronously even if focused -+ // editor cannot use IME actually. -+ -+ // See src/lib/fcitx-utils/keysym.h -+ static const guint FcitxKeyState_IgnoredMask = 1 << 25; -+ // If FcitxKeyState_IgnoredMask was set to aEvent->state, -+ // the event has already been handled by another process and -+ // it wasn't used by IME. -+ if (aEvent->state & FcitxKeyState_IgnoredMask) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p OnKeyEvent(), aEvent->state has " -+ "FcitxKeyState_IgnoredMask, so, it won't be handled " -+ "asynchronously anymore. Removing posted events from " -+ "the queue", -+ this)); -+ maybeHandledAsynchronously = false; -+ mPostingKeyEvents.RemoveEvent(aEvent); -+ break; -+ } -+ break; -+ default: -+ MOZ_ASSERT_UNREACHABLE("IME may handle key event " -+ "asyncrhonously, but not yet confirmed if it comes agian " -+ "actually"); -+ } -+ } -+ -+ mKeyboardEventWasDispatched = aKeyboardEventWasDispatched; -+ mFallbackToKeyEvent = false; - mProcessingKeyEvent = aEvent; - gboolean isFiltered = - gtk_im_context_filter_keypress(currentContext, aEvent); -- mProcessingKeyEvent = nullptr; - -- // We filter the key event if the event was not committed (because -- // it's probably part of a composition) or if the key event was -- // committed _and_ changed. This way we still let key press -- // events go through as simple key press events instead of -- // composed characters. -- bool filterThisEvent = isFiltered && mFilterKeyEvent; -- -- if (IsComposingOnCurrentContext() && !isFiltered) { -- if (aEvent->type == GDK_KEY_PRESS) { -- if (!mDispatchedCompositionString.IsEmpty()) { -- // If there is composition string, we shouldn't dispatch -- // any keydown events during composition. -- filterThisEvent = true; -- } else { -- // A Hangul input engine for SCIM doesn't emit preedit_end -- // signal even when composition string becomes empty. On the -- // other hand, we should allow to make composition with empty -- // string for other languages because there *might* be such -- // IM. For compromising this issue, we should dispatch -- // compositionend event, however, we don't need to reset IM -- // actually. -- DispatchCompositionCommitEvent(currentContext, &EmptyString()); -- filterThisEvent = false; -- } -- } else { -- // Key release event may not be consumed by IM, however, we -- // shouldn't dispatch any keyup event during composition. -- filterThisEvent = true; -+ // The caller of this shouldn't handle aEvent anymore if we've dispatched -+ // composition events or modified content with other events. -+ bool filterThisEvent = isFiltered && !mFallbackToKeyEvent; -+ -+ if (IsComposingOnCurrentContext() && !isFiltered && -+ aEvent->type == GDK_KEY_PRESS && -+ mDispatchedCompositionString.IsEmpty()) { -+ // A Hangul input engine for SCIM doesn't emit preedit_end -+ // signal even when composition string becomes empty. On the -+ // other hand, we should allow to make composition with empty -+ // string for other languages because there *might* be such -+ // IM. For compromising this issue, we should dispatch -+ // compositionend event, however, we don't need to reset IM -+ // actually. -+ // NOTE: Don't dispatch key events as "processed by IME" since -+ // we need to dispatch keyboard events as IME wasn't handled it. -+ mProcessingKeyEvent = nullptr; -+ DispatchCompositionCommitEvent(currentContext, &EmptyString()); -+ mProcessingKeyEvent = aEvent; -+ // In this case, even though we handle the keyboard event here, -+ // but we should dispatch keydown event as -+ filterThisEvent = false; -+ } -+ -+ if (filterThisEvent && !mKeyboardEventWasDispatched) { -+ // If IME handled the key event but we've not dispatched eKeyDown nor -+ // eKeyUp event yet, we need to dispatch here unless the key event is -+ // now being handled by other IME process. -+ if (!maybeHandledAsynchronously) { -+ MaybeDispatchKeyEventAsProcessedByIME(eVoidEvent); -+ // Be aware, the widget might have been gone here. -+ } -+ // If we need to wait reply from IM, IM may send some signals to us -+ // without sending the key event again. In such case, we need to -+ // dispatch keyboard events with a copy of aEvent. Therefore, we -+ // need to use information of this key event to dispatch an KeyDown -+ // or eKeyUp event later. -+ else { -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p OnKeyEvent(), putting aEvent into the queue...", -+ this)); -+ mPostingKeyEvents.PutEvent(aEvent); - } - } - -+ mProcessingKeyEvent = nullptr; -+ -+ if (aEvent->type == GDK_KEY_PRESS && !filterThisEvent) { -+ // If the key event hasn't been handled by active IME nor keyboard -+ // layout, we can assume that the dead key sequence has been or was -+ // ended. Note that we should not reset it when the key event is -+ // GDK_KEY_RELEASE since it may not be filtered by active keyboard -+ // layout even in composition. -+ mMaybeInDeadKeySequence = false; -+ } -+ - MOZ_LOG(gGtkIMLog, LogLevel::Debug, - ("0x%p OnKeyEvent(), succeeded, filterThisEvent=%s " -- "(isFiltered=%s, mFilterKeyEvent=%s), mCompositionState=%s", -+ "(isFiltered=%s, mFallbackToKeyEvent=%s, " -+ "maybeHandledAsynchronously=%s), mCompositionState=%s, " -+ "mMaybeInDeadKeySequence=%s", - this, ToChar(filterThisEvent), ToChar(isFiltered), -- ToChar(mFilterKeyEvent), GetCompositionStateName())); -+ ToChar(mFallbackToKeyEvent), ToChar(maybeHandledAsynchronously), -+ GetCompositionStateName(), ToChar(mMaybeInDeadKeySequence))); - - return filterThisEvent; - } -@@ -1005,6 +1337,10 @@ IMContextWrapper::Focus() - - sLastFocusedContext = this; - -+ // Forget all posted key events when focus is moved since they shouldn't -+ // be fired in different editor. -+ mPostingKeyEvents.Clear(); -+ - gtk_im_context_focus_in(currentContext); - mIsIMFocused = true; - mSetCursorPositionOnKeyEvent = true; -@@ -1400,6 +1736,7 @@ IMContextWrapper::OnCommitCompositionNat - { - const gchar emptyStr = 0; - const gchar *commitString = aUTF8Char ? aUTF8Char : &emptyStr; -+ NS_ConvertUTF8toUTF16 utf16CommitString(commitString); - - MOZ_LOG(gGtkIMLog, LogLevel::Info, - ("0x%p OnCommitCompositionNative(aContext=0x%p), " -@@ -1422,7 +1759,7 @@ IMContextWrapper::OnCommitCompositionNat - // signal, we would dispatch compositionstart, text, compositionend - // events with empty string. Of course, they are unnecessary events - // for Web applications and our editor. -- if (!IsComposingOn(aContext) && !commitString[0]) { -+ if (!IsComposingOn(aContext) && utf16CommitString.IsEmpty()) { - MOZ_LOG(gGtkIMLog, LogLevel::Warning, - ("0x%p OnCommitCompositionNative(), Warning, does nothing " - "because has not started composition and commit string is empty", -@@ -1431,11 +1768,14 @@ IMContextWrapper::OnCommitCompositionNat - } - - // If IME doesn't change their keyevent that generated this commit, -- // don't send it through XIM - just send it as a normal key press -- // event. -+ // we should treat that IME didn't handle the key event because -+ // web applications want to receive "keydown" and "keypress" event -+ // in such case. - // NOTE: While a key event is being handled, this might be caused on - // current context. Otherwise, this may be caused on active context. -- if (!IsComposingOn(aContext) && mProcessingKeyEvent && -+ if (!IsComposingOn(aContext) && -+ mProcessingKeyEvent && -+ mProcessingKeyEvent->type == GDK_KEY_PRESS && - aContext == GetCurrentContext()) { - char keyval_utf8[8]; /* should have at least 6 bytes of space */ - gint keyval_utf8_len; -@@ -1445,12 +1785,80 @@ IMContextWrapper::OnCommitCompositionNat - keyval_utf8_len = g_unichar_to_utf8(keyval_unicode, keyval_utf8); - keyval_utf8[keyval_utf8_len] = '\0'; - -+ // If committing string is exactly same as a character which is -+ // produced by the key, eKeyDown and eKeyPress event should be -+ // dispatched by the caller of OnKeyEvent() normally. Note that -+ // mMaybeInDeadKeySequence will be set to false by OnKeyEvent() -+ // since we set mFallbackToKeyEvent to true here. - if (!strcmp(commitString, keyval_utf8)) { - MOZ_LOG(gGtkIMLog, LogLevel::Info, - ("0x%p OnCommitCompositionNative(), " - "we'll send normal key event", - this)); -- mFilterKeyEvent = false; -+ mFallbackToKeyEvent = true; -+ return; -+ } -+ -+ // If we're in a dead key sequence, commit string is a character in -+ // the BMP and mProcessingKeyEvent produces some characters but it's -+ // not same as committing string, we should dispatch an eKeyPress -+ // event from here. -+ WidgetKeyboardEvent keyDownEvent(true, eKeyDown, -+ mLastFocusedWindow); -+ KeymapWrapper::InitKeyEvent(keyDownEvent, mProcessingKeyEvent, false); -+ if (mMaybeInDeadKeySequence && -+ utf16CommitString.Length() == 1 && -+ keyDownEvent.mKeyNameIndex == KEY_NAME_INDEX_USE_STRING) { -+ mKeyboardEventWasDispatched = true; -+ // Anyway, we're not in dead key sequence anymore. -+ mMaybeInDeadKeySequence = false; -+ -+ RefPtr dispatcher = GetTextEventDispatcher(); -+ nsresult rv = dispatcher->BeginNativeInputTransaction(); -+ if (NS_WARN_IF(NS_FAILED(rv))) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Error, -+ ("0x%p OnCommitCompositionNative(), FAILED, " -+ "due to BeginNativeInputTransaction() failure", -+ this)); -+ return; -+ } -+ -+ // First, dispatch eKeyDown event. -+ keyDownEvent.mKeyValue = utf16CommitString; -+ nsEventStatus status = nsEventStatus_eIgnore; -+ bool dispatched = -+ dispatcher->DispatchKeyboardEvent(eKeyDown, keyDownEvent, -+ status, mProcessingKeyEvent); -+ if (!dispatched || status == nsEventStatus_eConsumeNoDefault) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p OnCommitCompositionNative(), " -+ "doesn't dispatch eKeyPress event because the preceding " -+ "eKeyDown event was not dispatched or was consumed", -+ this)); -+ return; -+ } -+ if (mLastFocusedWindow != keyDownEvent.mWidget || -+ mLastFocusedWindow->Destroyed()) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Warning, -+ ("0x%p OnCommitCompositionNative(), Warning, " -+ "stop dispatching eKeyPress event because the preceding " -+ "eKeyDown event caused changing focused widget or " -+ "destroyed", -+ this)); -+ return; -+ } -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p OnCommitCompositionNative(), " -+ "dispatched eKeyDown event for the committed character", -+ this)); -+ -+ // Next, dispatch eKeyPress event. -+ dispatcher->MaybeDispatchKeypressEvents(keyDownEvent, status, -+ mProcessingKeyEvent); -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p OnCommitCompositionNative(), " -+ "dispatched eKeyPress event for the committed character", -+ this)); - return; - } - } -@@ -1470,7 +1878,7 @@ IMContextWrapper::GetCompositionString(G - gtk_im_context_get_preedit_string(aContext, &preedit_string, - &feedback_list, &cursor_pos); - if (preedit_string && *preedit_string) { -- CopyUTF8toUTF16(preedit_string, aCompositionString); -+ CopyUTF8toUTF16(MakeStringSpan(preedit_string), aCompositionString); - } else { - aCompositionString.Truncate(); - } -@@ -1485,6 +1893,173 @@ IMContextWrapper::GetCompositionString(G - } - - bool -+IMContextWrapper::MaybeDispatchKeyEventAsProcessedByIME( -+ EventMessage aFollowingEvent) -+{ -+ if (!mLastFocusedWindow) { -+ return false; -+ } -+ -+ if (!mIsKeySnooped && -+ ((!mProcessingKeyEvent && mPostingKeyEvents.IsEmpty()) || -+ (mProcessingKeyEvent && mKeyboardEventWasDispatched))) { -+ return true; -+ } -+ -+ // A "keydown" or "keyup" event handler may change focus with the -+ // following event. In such case, we need to cancel this composition. -+ // So, we need to store IM context now because mComposingContext may be -+ // overwritten with different context if calling this method recursively. -+ // Note that we don't need to grab the context here because |context| -+ // will be used only for checking if it's same as mComposingContext. -+ GtkIMContext* oldCurrentContext = GetCurrentContext(); -+ GtkIMContext* oldComposingContext = mComposingContext; -+ -+ RefPtr lastFocusedWindow(mLastFocusedWindow); -+ -+ if (mProcessingKeyEvent || !mPostingKeyEvents.IsEmpty()) { -+ if (mProcessingKeyEvent) { -+ mKeyboardEventWasDispatched = true; -+ } -+ // If we're not handling a key event synchronously, the signal may be -+ // sent by IME without sending key event to us. In such case, we -+ // should dispatch keyboard event for the last key event which was -+ // posted to other IME process. -+ GdkEventKey* sourceEvent = -+ mProcessingKeyEvent ? mProcessingKeyEvent : -+ mPostingKeyEvents.GetFirstEvent(); -+ -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p MaybeDispatchKeyEventAsProcessedByIME(" -+ "aFollowingEvent=%s), dispatch %s %s " -+ "event: { type=%s, keyval=%s, unicode=0x%X, state=%s, " -+ "time=%u, hardware_keycode=%u, group=%u }", -+ this, ToChar(aFollowingEvent), -+ ToChar(sourceEvent->type == GDK_KEY_PRESS ? eKeyDown : eKeyUp), -+ mProcessingKeyEvent ? "processing" : "posted", -+ GetEventType(sourceEvent), gdk_keyval_name(sourceEvent->keyval), -+ gdk_keyval_to_unicode(sourceEvent->keyval), -+ GetEventStateName(sourceEvent->state, mIMContextID).get(), -+ sourceEvent->time, sourceEvent->hardware_keycode, -+ sourceEvent->group)); -+ -+ // Let's dispatch eKeyDown event or eKeyUp event now. Note that only -+ // when we're not in a dead key composition, we should mark the -+ // eKeyDown and eKeyUp event as "processed by IME" since we should -+ // expose raw keyCode and key value to web apps the key event is a -+ // part of a dead key sequence. -+ // FYI: We should ignore if default of preceding keydown or keyup -+ // event is prevented since even on the other browsers, web -+ // applications cannot cancel the following composition event. -+ // Spec bug: https://github.com/w3c/uievents/issues/180 -+ bool isCancelled; -+ lastFocusedWindow->DispatchKeyDownOrKeyUpEvent(sourceEvent, -+ !mMaybeInDeadKeySequence, -+ &isCancelled); -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p MaybeDispatchKeyEventAsProcessedByIME(), keydown or keyup " -+ "event is dispatched", -+ this)); -+ -+ if (!mProcessingKeyEvent) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p MaybeDispatchKeyEventAsProcessedByIME(), removing first " -+ "event from the queue", -+ this)); -+ mPostingKeyEvents.RemoveEvent(sourceEvent); -+ } -+ } else { -+ MOZ_ASSERT(mIsKeySnooped); -+ // Currently, we support key snooper mode of uim only. -+ MOZ_ASSERT(mIMContextID == IMContextID::eUim); -+ // uim sends "preedit_start" signal and "preedit_changed" separately -+ // at starting composition, "commit" and "preedit_end" separately at -+ // committing composition. -+ -+ // Currently, we should dispatch only fake eKeyDown event because -+ // we cannot decide which is the last signal of each key operation -+ // and Chromium also dispatches only "keydown" event in this case. -+ bool dispatchFakeKeyDown = false; -+ switch (aFollowingEvent) { -+ case eCompositionStart: -+ case eCompositionCommit: -+ case eCompositionCommitAsIs: -+ dispatchFakeKeyDown = true; -+ break; -+ // XXX Unfortunately, I don't have a good idea to prevent to -+ // dispatch redundant eKeyDown event for eCompositionStart -+ // immediately after "delete_surrounding" signal. However, -+ // not dispatching eKeyDown event is worse than dispatching -+ // redundant eKeyDown events. -+ case eContentCommandDelete: -+ dispatchFakeKeyDown = true; -+ break; -+ // We need to prevent to dispatch redundant eKeyDown event for -+ // eCompositionChange immediately after eCompositionStart. So, -+ // We should not dispatch eKeyDown event if dispatched composition -+ // string is still empty string. -+ case eCompositionChange: -+ dispatchFakeKeyDown = !mDispatchedCompositionString.IsEmpty(); -+ break; -+ default: -+ MOZ_ASSERT_UNREACHABLE("Do you forget to handle the case?"); -+ break; -+ } -+ -+ if (dispatchFakeKeyDown) { -+ WidgetKeyboardEvent fakeKeyDownEvent(true, eKeyDown, -+ lastFocusedWindow); -+ fakeKeyDownEvent.mKeyCode = NS_VK_PROCESSKEY; -+ fakeKeyDownEvent.mKeyNameIndex = KEY_NAME_INDEX_Process; -+ // It's impossible to get physical key information in this case but -+ // this should be okay since web apps shouldn't do anything with -+ // physical key information during composition. -+ fakeKeyDownEvent.mCodeNameIndex = CODE_NAME_INDEX_UNKNOWN; -+ -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p MaybeDispatchKeyEventAsProcessedByIME(" -+ "aFollowingEvent=%s), dispatch fake eKeyDown event", -+ this, ToChar(aFollowingEvent))); -+ -+ bool isCancelled; -+ lastFocusedWindow->DispatchKeyDownOrKeyUpEvent(fakeKeyDownEvent, -+ &isCancelled); -+ MOZ_LOG(gGtkIMLog, LogLevel::Info, -+ ("0x%p MaybeDispatchKeyEventAsProcessedByIME(), " -+ "fake keydown event is dispatched", -+ this)); -+ } -+ } -+ -+ if (lastFocusedWindow->IsDestroyed() || -+ lastFocusedWindow != mLastFocusedWindow) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Warning, -+ ("0x%p MaybeDispatchKeyEventAsProcessedByIME(), Warning, the " -+ "focused widget was destroyed/changed by a key event", -+ this)); -+ return false; -+ } -+ -+ // If the dispatched keydown event caused moving focus and that also -+ // caused changing active context, we need to cancel composition here. -+ if (GetCurrentContext() != oldCurrentContext) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Warning, -+ ("0x%p MaybeDispatchKeyEventAsProcessedByIME(), Warning, the key " -+ "event causes changing active IM context", -+ this)); -+ if (mComposingContext == oldComposingContext) { -+ // Only when the context is still composing, we should call -+ // ResetIME() here. Otherwise, it should've already been -+ // cleaned up. -+ ResetIME(); -+ } -+ return false; -+ } -+ -+ return true; -+} -+ -+bool - IMContextWrapper::DispatchCompositionStart(GtkIMContext* aContext) - { - MOZ_LOG(gGtkIMLog, LogLevel::Info, -@@ -1528,50 +2103,16 @@ IMContextWrapper::DispatchCompositionSta - mCompositionStart = mSelection.mOffset; - mDispatchedCompositionString.Truncate(); - -- if (mProcessingKeyEvent && !mKeyDownEventWasSent && -- mProcessingKeyEvent->type == GDK_KEY_PRESS) { -- // A keydown event handler may change focus with the following keydown -- // event. In such case, we need to cancel this composition. So, we -- // need to store IM context now because mComposingContext may be -- // overwritten with different context if calling this method -- // recursively. -- // Note that we don't need to grab the context here because |context| -- // will be used only for checking if it's same as mComposingContext. -- GtkIMContext* context = mComposingContext; -- -- // If this composition is started by a native keydown event, we need to -- // dispatch our keydown event here (before composition start). -- bool isCancelled; -- mLastFocusedWindow->DispatchKeyDownEvent(mProcessingKeyEvent, -- &isCancelled); -- MOZ_LOG(gGtkIMLog, LogLevel::Debug, -- ("0x%p DispatchCompositionStart(), preceding keydown event is " -- "dispatched", -+ // If this composition is started by a key press, we need to dispatch -+ // eKeyDown or eKeyUp event before dispatching eCompositionStart event. -+ // Note that dispatching a keyboard event which is marked as "processed -+ // by IME" is okay since Chromium also dispatches keyboard event as so. -+ if (!MaybeDispatchKeyEventAsProcessedByIME(eCompositionStart)) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Warning, -+ ("0x%p DispatchCompositionStart(), Warning, " -+ "MaybeDispatchKeyEventAsProcessedByIME() returned false", - this)); -- if (lastFocusedWindow->IsDestroyed() || -- lastFocusedWindow != mLastFocusedWindow) { -- MOZ_LOG(gGtkIMLog, LogLevel::Warning, -- ("0x%p DispatchCompositionStart(), Warning, the focused " -- "widget was destroyed/changed by keydown event", -- this)); -- return false; -- } -- -- // If the dispatched keydown event caused moving focus and that also -- // caused changing active context, we need to cancel composition here. -- if (GetCurrentContext() != context) { -- MOZ_LOG(gGtkIMLog, LogLevel::Warning, -- ("0x%p DispatchCompositionStart(), Warning, the preceding " -- "keydown event causes changing active IM context", -- this)); -- if (mComposingContext == context) { -- // Only when the context is still composing, we should call -- // ResetIME() here. Otherwise, it should've already been -- // cleaned up. -- ResetIME(); -- } -- return false; -- } -+ return false; - } - - RefPtr dispatcher = GetTextEventDispatcher(); -@@ -1584,6 +2125,25 @@ IMContextWrapper::DispatchCompositionSta - return false; - } - -+ static bool sHasSetTelemetry = false; -+ if (!sHasSetTelemetry) { -+ sHasSetTelemetry = true; -+ NS_ConvertUTF8toUTF16 im(GetIMName()); -+ // 72 is kMaximumKeyStringLength in TelemetryScalar.cpp -+ if (im.Length() > 72) { -+ if (NS_IS_LOW_SURROGATE(im[72 - 1]) && -+ NS_IS_HIGH_SURROGATE(im[72 - 2])) { -+ im.Truncate(72 - 2); -+ } else { -+ im.Truncate(72 - 1); -+ } -+ // U+2026 is "..." -+ im.Append(char16_t(0x2026)); -+ } -+ Telemetry::ScalarSet(Telemetry::ScalarID::WIDGET_IME_NAME_ON_LINUX, -+ im, true); -+ } -+ - MOZ_LOG(gGtkIMLog, LogLevel::Debug, - ("0x%p DispatchCompositionStart(), dispatching " - "compositionstart... (mCompositionStart=%u)", -@@ -1629,6 +2189,15 @@ IMContextWrapper::DispatchCompositionCha - return false; - } - } -+ // If this composition string change caused by a key press, we need to -+ // dispatch eKeyDown or eKeyUp before dispatching eCompositionChange event. -+ else if (!MaybeDispatchKeyEventAsProcessedByIME(eCompositionChange)) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Warning, -+ ("0x%p DispatchCompositionChangeEvent(), Warning, " -+ "MaybeDispatchKeyEventAsProcessedByIME() returned false", -+ this)); -+ return false; -+ } - - RefPtr dispatcher = GetTextEventDispatcher(); - nsresult rv = dispatcher->BeginNativeInputTransaction(); -@@ -1718,6 +2287,14 @@ IMContextWrapper::DispatchCompositionCom - return false; - } - -+ // TODO: We need special care to handle request to commit composition -+ // by content while we're committing composition because we have -+ // commit string information now but IME may not have composition -+ // anymore. Therefore, we may not be able to handle commit as -+ // expected. However, this is rare case because this situation -+ // never occurs with remote content. So, it's okay to fix this -+ // issue later. (Perhaps, TextEventDisptcher should do it for -+ // all platforms. E.g., creating WillCommitComposition()?) - if (!IsComposing()) { - if (!aCommitString || aCommitString->IsEmpty()) { - MOZ_LOG(gGtkIMLog, LogLevel::Error, -@@ -1734,6 +2311,17 @@ IMContextWrapper::DispatchCompositionCom - return false; - } - } -+ // If this commit caused by a key press, we need to dispatch eKeyDown or -+ // eKeyUp before dispatching composition events. -+ else if (!MaybeDispatchKeyEventAsProcessedByIME( -+ aCommitString ? eCompositionCommit : eCompositionCommitAsIs)) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Warning, -+ ("0x%p DispatchCompositionCommitEvent(), Warning, " -+ "MaybeDispatchKeyEventAsProcessedByIME() returned false", -+ this)); -+ mCompositionState = eCompositionState_NotComposing; -+ return false; -+ } - - RefPtr dispatcher = GetTextEventDispatcher(); - nsresult rv = dispatcher->BeginNativeInputTransaction(); -@@ -1755,6 +2343,11 @@ IMContextWrapper::DispatchCompositionCom - mSelection.mWritingMode); - - mCompositionState = eCompositionState_NotComposing; -+ // Reset dead key sequence too because GTK doesn't support dead key chain -+ // (i.e., a key press doesn't cause both producing some characters and -+ // restarting new dead key sequence at one time). So, committing -+ // composition means end of a dead key sequence. -+ mMaybeInDeadKeySequence = false; - mCompositionStart = UINT32_MAX; - mCompositionTargetRange.Clear(); - mDispatchedCompositionString.Truncate(); -@@ -2427,6 +3020,16 @@ IMContextWrapper::DeleteText(GtkIMContex - this)); - return NS_ERROR_FAILURE; - } -+ -+ // If this deleting text caused by a key press, we need to dispatch -+ // eKeyDown or eKeyUp before dispatching eContentCommandDelete event. -+ if (!MaybeDispatchKeyEventAsProcessedByIME(eContentCommandDelete)) { -+ MOZ_LOG(gGtkIMLog, LogLevel::Warning, -+ ("0x%p DeleteText(), Warning, " -+ "MaybeDispatchKeyEventAsProcessedByIME() returned false", -+ this)); -+ return NS_ERROR_FAILURE; -+ } - - // Delete the selection - WidgetContentCommandEvent contentCommandEvent(true, eContentCommandDelete, -diff -up thunderbird-60.3.0/widget/gtk/IMContextWrapper.h.wayland thunderbird-60.3.0/widget/gtk/IMContextWrapper.h ---- thunderbird-60.3.0/widget/gtk/IMContextWrapper.h.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/IMContextWrapper.h 2018-11-20 12:04:43.733787362 +0100 -@@ -70,13 +70,26 @@ public: - // OnThemeChanged is called when desktop theme is changed. - static void OnThemeChanged(); - -- // OnKeyEvent is called when aWindow gets a native key press event or a -- // native key release event. If this returns TRUE, the key event was -- // filtered by IME. Otherwise, this returns FALSE. -- // NOTE: When the keypress event starts composition, this returns TRUE but -- // this dispatches keydown event before compositionstart event. -+ /** -+ * OnKeyEvent() is called when aWindow gets a native key press event or a -+ * native key release event. If this returns true, the key event was -+ * filtered by IME. Otherwise, this returns false. -+ * NOTE: When the native key press event starts composition, this returns -+ * true but dispatches an eKeyDown event or eKeyUp event before -+ * dispatching composition events or content command event. -+ * -+ * @param aWindow A window on which user operate the -+ * key. -+ * @param aEvent A native key press or release -+ * event. -+ * @param aKeyboardEventWasDispatched true if eKeyDown or eKeyUp event -+ * for aEvent has already been -+ * dispatched. In this case, -+ * this class doesn't dispatch -+ * keyboard event anymore. -+ */ - bool OnKeyEvent(nsWindow* aWindow, GdkEventKey* aEvent, -- bool aKeyDownEventWasSent = false); -+ bool aKeyboardEventWasDispatched = false); - - // IME related nsIWidget methods. - nsresult EndIMEComposition(nsWindow* aCaller); -@@ -89,6 +102,43 @@ public: - - TextEventDispatcher* GetTextEventDispatcher(); - -+ // TODO: Typically, new IM comes every several years. And now, our code -+ // becomes really IM behavior dependent. So, perhaps, we need prefs -+ // to control related flags for IM developers. -+ enum class IMContextID : uint8_t -+ { -+ eFcitx, -+ eIBus, -+ eIIIMF, -+ eScim, -+ eUim, -+ eUnknown, -+ }; -+ -+ static const char* GetIMContextIDName(IMContextID aIMContextID) -+ { -+ switch (aIMContextID) { -+ case IMContextID::eFcitx: -+ return "eFcitx"; -+ case IMContextID::eIBus: -+ return "eIBus"; -+ case IMContextID::eIIIMF: -+ return "eIIIMF"; -+ case IMContextID::eScim: -+ return "eScim"; -+ case IMContextID::eUim: -+ return "eUim"; -+ default: -+ return "eUnknown"; -+ } -+ } -+ -+ /** -+ * GetIMName() returns IM name associated with mContext. If the context is -+ * xim, this look for actual engine from XMODIFIERS environment variable. -+ */ -+ nsDependentCSubstring GetIMName() const; -+ - protected: - ~IMContextWrapper(); - -@@ -144,6 +194,100 @@ protected: - // event. - GdkEventKey* mProcessingKeyEvent; - -+ /** -+ * GdkEventKeyQueue stores *copy* of GdkEventKey instances. However, this -+ * must be safe to our usecase since it has |time| and the value should not -+ * be same as older event. -+ */ -+ class GdkEventKeyQueue final -+ { -+ public: -+ ~GdkEventKeyQueue() { Clear(); } -+ -+ void Clear() -+ { -+ if (!mEvents.IsEmpty()) { -+ RemoveEventsAt(0, mEvents.Length()); -+ } -+ } -+ -+ /** -+ * PutEvent() puts new event into the queue. -+ */ -+ void PutEvent(const GdkEventKey* aEvent) -+ { -+ GdkEventKey* newEvent = -+ reinterpret_cast( -+ gdk_event_copy(reinterpret_cast(aEvent))); -+ newEvent->state &= GDK_MODIFIER_MASK; -+ mEvents.AppendElement(newEvent); -+ } -+ -+ /** -+ * RemoveEvent() removes oldest same event and its preceding events -+ * from the queue. -+ */ -+ void RemoveEvent(const GdkEventKey* aEvent) -+ { -+ size_t index = IndexOf(aEvent); -+ if (NS_WARN_IF(index == mEvents.NoIndex)) { -+ return; -+ } -+ RemoveEventsAt(0, index + 1); -+ } -+ -+ /** -+ * FirstEvent() returns oldest event in the queue. -+ */ -+ GdkEventKey* GetFirstEvent() const -+ { -+ if (mEvents.IsEmpty()) { -+ return nullptr; -+ } -+ return mEvents[0]; -+ } -+ -+ bool IsEmpty() const { return mEvents.IsEmpty(); } -+ -+ private: -+ nsTArray mEvents; -+ -+ void RemoveEventsAt(size_t aStart, size_t aCount) -+ { -+ for (size_t i = aStart; i < aStart + aCount; i++) { -+ gdk_event_free(reinterpret_cast(mEvents[i])); -+ } -+ mEvents.RemoveElementsAt(aStart, aCount); -+ } -+ -+ size_t IndexOf(const GdkEventKey* aEvent) const -+ { -+ static_assert(!(GDK_MODIFIER_MASK & (1 << 24)), -+ "We assumes 25th bit is used by some IM, but used by GDK"); -+ static_assert(!(GDK_MODIFIER_MASK & (1 << 25)), -+ "We assumes 26th bit is used by some IM, but used by GDK"); -+ for (size_t i = 0; i < mEvents.Length(); i++) { -+ GdkEventKey* event = mEvents[i]; -+ // It must be enough to compare only type, time, keyval and -+ // part of state. Note that we cannot compaire two events -+ // simply since IME may have changed unused bits of state. -+ if (event->time == aEvent->time) { -+ if (NS_WARN_IF(event->type != aEvent->type) || -+ NS_WARN_IF(event->keyval != aEvent->keyval) || -+ NS_WARN_IF(event->state != -+ (aEvent->state & GDK_MODIFIER_MASK))) { -+ continue; -+ } -+ } -+ return i; -+ } -+ return mEvents.NoIndex; -+ } -+ }; -+ // OnKeyEvent() append mPostingKeyEvents when it believes that a key event -+ // is posted to other IME process. -+ GdkEventKeyQueue mPostingKeyEvents; -+ - struct Range - { - uint32_t mOffset; -@@ -167,7 +311,8 @@ protected: - Range mCompositionTargetRange; - - // mCompositionState indicates current status of composition. -- enum eCompositionState { -+ enum eCompositionState : uint8_t -+ { - eCompositionState_NotComposing, - eCompositionState_CompositionStartDispatched, - eCompositionState_CompositionChangeEventDispatched -@@ -219,6 +364,10 @@ protected: - } - } - -+ // mIMContextID indicates the ID of mContext. This is actually indicates -+ // IM which user selected. -+ IMContextID mIMContextID; -+ - struct Selection final - { - nsString mString; -@@ -268,16 +417,20 @@ protected: - // mIsIMFocused is set to TRUE when we call gtk_im_context_focus_in(). And - // it's set to FALSE when we call gtk_im_context_focus_out(). - bool mIsIMFocused; -- // mFilterKeyEvent is used by OnKeyEvent(). If the commit event should -- // be processed as simple key event, this is set to TRUE by the commit -- // handler. -- bool mFilterKeyEvent; -- // mKeyDownEventWasSent is used by OnKeyEvent() and -- // DispatchCompositionStart(). DispatchCompositionStart() dispatches -- // a keydown event if the composition start is caused by a native -- // keypress event. If this is true, the keydown event has been dispatched. -- // Then, DispatchCompositionStart() doesn't dispatch keydown event. -- bool mKeyDownEventWasSent; -+ // mFallbackToKeyEvent is set to false when this class starts to handle -+ // a native key event (at that time, mProcessingKeyEvent is set to the -+ // native event). If active IME just commits composition with a character -+ // which is produced by the key with current keyboard layout, this is set -+ // to true. -+ bool mFallbackToKeyEvent; -+ // mKeyboardEventWasDispatched is used by OnKeyEvent() and -+ // MaybeDispatchKeyEventAsProcessedByIME(). -+ // MaybeDispatchKeyEventAsProcessedByIME() dispatches an eKeyDown or -+ // eKeyUp event event if the composition is caused by a native -+ // key press event. If this is true, a keyboard event has been dispatched -+ // for the native event. If so, MaybeDispatchKeyEventAsProcessedByIME() -+ // won't dispatch keyboard event anymore. -+ bool mKeyboardEventWasDispatched; - // mIsDeletingSurrounding is true while OnDeleteSurroundingNative() is - // trying to delete the surrounding text. - bool mIsDeletingSurrounding; -@@ -298,6 +451,24 @@ protected: - // mRetrieveSurroundingSignalReceived is true after "retrieve_surrounding" - // signal is received until selection is changed in Gecko. - bool mRetrieveSurroundingSignalReceived; -+ // mMaybeInDeadKeySequence is set to true when we detect a dead key press -+ // and set to false when we're sure dead key sequence has been finished. -+ // Note that we cannot detect which key event causes ending a dead key -+ // sequence. For example, when you press dead key grave with ibus Spanish -+ // keyboard layout, it just consumes the key event when we call -+ // gtk_im_context_filter_keypress(). Then, pressing "Escape" key cancels -+ // the dead key sequence but we don't receive any signal and it's consumed -+ // by gtk_im_context_filter_keypress() normally. On the other hand, when -+ // pressing "Shift" key causes exactly same behavior but dead key sequence -+ // isn't finished yet. -+ bool mMaybeInDeadKeySequence; -+ // mIsIMInAsyncKeyHandlingMode is set to true if we know that IM handles -+ // key events asynchronously. I.e., filtered key event may come again -+ // later. -+ bool mIsIMInAsyncKeyHandlingMode; -+ // mIsKeySnooped is set to true if IM uses key snooper to listen key events. -+ // In such case, we won't receive key events if IME consumes the event. -+ bool mIsKeySnooped; - - // sLastFocusedContext is a pointer to the last focused instance of this - // class. When a instance is destroyed and sLastFocusedContext refers it, -@@ -448,12 +619,31 @@ protected: - * Following methods dispatch gecko events. Then, the focused widget - * can be destroyed, and also it can be stolen focus. If they returns - * FALSE, callers cannot continue the composition. -+ * - MaybeDispatchKeyEventAsProcessedByIME - * - DispatchCompositionStart - * - DispatchCompositionChangeEvent - * - DispatchCompositionCommitEvent - */ - - /** -+ * Dispatch an eKeyDown or eKeyUp event whose mKeyCode value is -+ * NS_VK_PROCESSKEY and mKeyNameIndex is KEY_NAME_INDEX_Process if -+ * we're not in a dead key sequence, mProcessingKeyEvent is nullptr -+ * but mPostingKeyEvents is not empty or mProcessingKeyEvent is not -+ * nullptr and mKeyboardEventWasDispatched is still false. If this -+ * dispatches a keyboard event, this sets mKeyboardEventWasDispatched -+ * to true. -+ * -+ * @param aFollowingEvent The following event message. -+ * @return If the caller can continue to handle -+ * composition, returns true. Otherwise, -+ * false. For example, if focus is moved -+ * by dispatched keyboard event, returns -+ * false. -+ */ -+ bool MaybeDispatchKeyEventAsProcessedByIME(EventMessage aFollowingEvent); -+ -+ /** - * Dispatches a composition start event. - * - * @param aContext A GtkIMContext which is being handled. -diff -up thunderbird-60.3.0/widget/gtk/InProcessGtkCompositorWidget.h.wayland thunderbird-60.3.0/widget/gtk/InProcessGtkCompositorWidget.h ---- thunderbird-60.3.0/widget/gtk/InProcessGtkCompositorWidget.h.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/InProcessGtkCompositorWidget.h 2018-11-20 12:04:43.733787362 +0100 -@@ -3,8 +3,8 @@ - * 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 widget_gtk_InProcessGtkCompositorWidgetParent_h --#define widget_gtk_InProcessGtkCompositorWidgetParent_h -+#ifndef widget_gtk_InProcessGtkCompositorWidget_h -+#define widget_gtk_InProcessGtkCompositorWidget_h - - #include "GtkCompositorWidget.h" - -@@ -28,4 +28,4 @@ public: - } // namespace widget - } // namespace mozilla - --#endif // widget_gtk_InProcessGtkCompositorWidgetParent_h -+#endif // widget_gtk_InProcessGtkCompositorWidget_h diff -up thunderbird-60.3.0/widget/gtk/moz.build.wayland thunderbird-60.3.0/widget/gtk/moz.build --- thunderbird-60.3.0/widget/gtk/moz.build.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/moz.build 2018-11-20 12:09:34.756903818 +0100 ++++ thunderbird-60.3.0/widget/gtk/moz.build 2018-11-21 13:42:00.757025666 +0100 @@ -123,6 +123,7 @@ include('/ipc/chromium/chromium-config.m FINAL_LIBRARY = 'xul' @@ -1971,7 +35,7 @@ diff -up thunderbird-60.3.0/widget/gtk/moz.build.wayland thunderbird-60.3.0/widg '/other-licenses/atk-1.0', diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.cpp.wayland thunderbird-60.3.0/widget/gtk/mozcontainer.cpp --- thunderbird-60.3.0/widget/gtk/mozcontainer.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/mozcontainer.cpp 2018-11-20 12:04:43.733787362 +0100 ++++ thunderbird-60.3.0/widget/gtk/mozcontainer.cpp 2018-11-21 13:42:00.757025666 +0100 @@ -10,6 +10,7 @@ #ifdef MOZ_WAYLAND #include @@ -2049,7 +113,7 @@ diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.cpp.wayland thunderbird-60.3 static void moz_container_unmap_surface(MozContainer *container) { -+ g_clear_pointer(&container->eglwindow, wl_egl_window_destroy); ++ //g_clear_pointer(&container->eglwindow, wl_egl_window_destroy); g_clear_pointer(&container->subsurface, wl_subsurface_destroy); g_clear_pointer(&container->surface, wl_surface_destroy); + @@ -2068,18 +132,6 @@ diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.cpp.wayland thunderbird-60.3 } #endif -@@ -434,6 +479,11 @@ moz_container_size_allocate (GtkWidget - gdk_window_get_position(gtk_widget_get_window(widget), &x, &y); - wl_subsurface_set_position(container->subsurface, x, y); - } -+ if (container->eglwindow) { -+ wl_egl_window_resize(container->eglwindow, -+ allocation->width, allocation->height, -+ 0, 0); -+ } - #endif - } - @@ -555,8 +605,40 @@ moz_container_get_wl_surface(MozContaine return nullptr; @@ -2100,7 +152,7 @@ diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.cpp.wayland thunderbird-60.3 + +struct wl_egl_window * +moz_container_get_wl_egl_window(MozContainer *container) -+{ ++{ /* + if (!container->eglwindow) { + struct wl_surface *wlsurf = moz_container_get_wl_surface(container); + if (!wlsurf) @@ -2112,7 +164,7 @@ diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.cpp.wayland thunderbird-60.3 + gdk_window_get_width(window), + gdk_window_get_height(window)); + } -+ return container->eglwindow; ++ return container->eglwindow;*/ return nullptr; +} + +gboolean @@ -2123,7 +175,7 @@ diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.cpp.wayland thunderbird-60.3 #endif diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.h.wayland thunderbird-60.3.0/widget/gtk/mozcontainer.h --- thunderbird-60.3.0/widget/gtk/mozcontainer.h.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/mozcontainer.h 2018-11-20 12:04:43.733787362 +0100 ++++ thunderbird-60.3.0/widget/gtk/mozcontainer.h 2018-11-21 13:42:00.757025666 +0100 @@ -72,6 +72,9 @@ struct _MozContainer struct wl_subcompositor *subcompositor; struct wl_surface *surface; @@ -2145,7 +197,7 @@ diff -up thunderbird-60.3.0/widget/gtk/mozcontainer.h.wayland thunderbird-60.3.0 #endif /* __MOZ_CONTAINER_H__ */ diff -up thunderbird-60.3.0/widget/gtk/mozgtk/mozgtk.c.wayland thunderbird-60.3.0/widget/gtk/mozgtk/mozgtk.c --- thunderbird-60.3.0/widget/gtk/mozgtk/mozgtk.c.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/mozgtk/mozgtk.c 2018-11-20 12:04:43.734787359 +0100 ++++ thunderbird-60.3.0/widget/gtk/mozgtk/mozgtk.c 2018-11-21 13:42:00.757025666 +0100 @@ -135,6 +135,8 @@ STUB(gdk_x11_get_xatom_by_name) STUB(gdk_x11_get_xatom_by_name_for_display) STUB(gdk_x11_lookup_xdisplay) @@ -2165,7 +217,7 @@ diff -up thunderbird-60.3.0/widget/gtk/mozgtk/mozgtk.c.wayland thunderbird-60.3. STUB(gtk_info_bar_get_type) diff -up thunderbird-60.3.0/widget/gtk/mozwayland/mozwayland.c.wayland thunderbird-60.3.0/widget/gtk/mozwayland/mozwayland.c --- thunderbird-60.3.0/widget/gtk/mozwayland/mozwayland.c.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/mozwayland/mozwayland.c 2018-11-20 12:04:43.734787359 +0100 ++++ thunderbird-60.3.0/widget/gtk/mozwayland/mozwayland.c 2018-11-21 13:42:00.758025661 +0100 @@ -271,3 +271,21 @@ wl_log_set_handler_client(wl_log_func_t { } @@ -2188,57 +240,9 @@ diff -up thunderbird-60.3.0/widget/gtk/mozwayland/mozwayland.c.wayland thunderbi + int dx, int dy) +{ +} -diff -up thunderbird-60.3.0/widget/gtk/nsAppShell.cpp.wayland thunderbird-60.3.0/widget/gtk/nsAppShell.cpp ---- thunderbird-60.3.0/widget/gtk/nsAppShell.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsAppShell.cpp 2018-11-20 12:04:43.734787359 +0100 -@@ -14,7 +14,8 @@ - #include "nsWindow.h" - #include "mozilla/Logging.h" - #include "prenv.h" --#include "mozilla/HangMonitor.h" -+#include "mozilla/BackgroundHangMonitor.h" -+#include "mozilla/Hal.h" - #include "mozilla/Unused.h" - #include "mozilla/WidgetUtils.h" - #include "GeckoProfiler.h" -@@ -46,13 +47,14 @@ static GPollFunc sPollFunc; - static gint - PollWrapper(GPollFD *ufds, guint nfsd, gint timeout_) - { -- mozilla::HangMonitor::Suspend(); -+ mozilla::BackgroundHangMonitor().NotifyWait(); - gint result; - { -+ AUTO_PROFILER_LABEL("PollWrapper", IDLE); - AUTO_PROFILER_THREAD_SLEEP; - result = (*sPollFunc)(ufds, nfsd, timeout_); - } -- mozilla::HangMonitor::NotifyActivity(); -+ mozilla::BackgroundHangMonitor().NotifyActivity(); - return result; - } - -@@ -133,6 +135,8 @@ nsAppShell::EventProcessorCallback(GIOCh - - nsAppShell::~nsAppShell() - { -+ mozilla::hal::Shutdown(); -+ - if (mTag) - g_source_remove(mTag); - if (mPipeFDs[0]) -@@ -150,6 +154,8 @@ nsAppShell::Init() - // is a no-op. - g_type_init(); - -+ mozilla::hal::Init(); -+ - #ifdef MOZ_ENABLE_DBUS - if (XRE_IsParentProcess()) { - nsCOMPtr powerManagerService = diff -up thunderbird-60.3.0/widget/gtk/nsClipboard.cpp.wayland thunderbird-60.3.0/widget/gtk/nsClipboard.cpp --- thunderbird-60.3.0/widget/gtk/nsClipboard.cpp.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsClipboard.cpp 2018-11-20 12:04:43.734787359 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsClipboard.cpp 2018-11-21 13:42:00.758025661 +0100 @@ -671,11 +671,9 @@ void ConvertHTMLtoUCS2(const char* data, *unicodeData = reinterpret_cast @@ -2301,7 +305,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsClipboard.cpp.wayland thunderbird-60.3. } diff -up thunderbird-60.3.0/widget/gtk/nsClipboardWayland.cpp.wayland thunderbird-60.3.0/widget/gtk/nsClipboardWayland.cpp --- thunderbird-60.3.0/widget/gtk/nsClipboardWayland.cpp.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsClipboardWayland.cpp 2018-11-20 12:04:43.735787356 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsClipboardWayland.cpp 2018-11-21 13:42:00.758025661 +0100 @@ -23,6 +23,7 @@ #include "mozilla/Services.h" #include "mozilla/RefPtr.h" @@ -2914,7 +918,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsClipboardWayland.cpp.wayland thunderbir return GetClipboardData(sTextMimeTypes[i], aWhichClipboard, diff -up thunderbird-60.3.0/widget/gtk/nsClipboardWayland.h.wayland thunderbird-60.3.0/widget/gtk/nsClipboardWayland.h --- thunderbird-60.3.0/widget/gtk/nsClipboardWayland.h.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsClipboardWayland.h 2018-11-20 12:04:43.735787356 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsClipboardWayland.h 2018-11-21 13:42:00.759025657 +0100 @@ -32,6 +32,7 @@ public: private: virtual bool RequestDataTransfer(const char* aMimeType, int fd) = 0; @@ -3021,52 +1025,9 @@ diff -up thunderbird-60.3.0/widget/gtk/nsClipboardWayland.h.wayland thunderbird- int mClipboardRequestNumber; char* mClipboardData; -diff -up thunderbird-60.3.0/widget/gtk/nsDeviceContextSpecG.cpp.wayland thunderbird-60.3.0/widget/gtk/nsDeviceContextSpecG.cpp ---- thunderbird-60.3.0/widget/gtk/nsDeviceContextSpecG.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsDeviceContextSpecG.cpp 2018-11-20 12:04:43.735787356 +0100 -@@ -33,6 +33,9 @@ - #include - #include - -+// To check if we need to use flatpak portal for printing -+#include "nsIGIOService.h" -+ - using namespace mozilla; - - using mozilla::gfx::IntSize; -@@ -355,6 +358,20 @@ NS_IMETHODIMP nsDeviceContextSpecGTK::En - // If you're not familiar with umasks, they contain the bits of what NOT to set in the permissions - // (thats because files and directories have different numbers of bits for their permissions) - destFile->SetPermissions(0666 & ~(mask)); -+ -+ // Notify flatpak printing portal that file is completely written -+ nsCOMPtr giovfs = -+ do_GetService(NS_GIOSERVICE_CONTRACTID); -+ bool shouldUsePortal; -+ if (giovfs) { -+ giovfs->ShouldUseFlatpakPortal(&shouldUsePortal); -+ if (shouldUsePortal) { -+ // Use the name of the file for printing to match with nsFlatpakPrintPortal -+ nsCOMPtr os = mozilla::services::GetObserverService(); -+ // Pass filename to be sure that observer process the right data -+ os->NotifyObservers(nullptr, "print-to-file-finished", targetPath.get()); -+ } -+ } - } - return NS_OK; - } -@@ -421,7 +438,7 @@ nsPrinterEnumeratorGTK::InitPrintSetting - } - - if (path) { -- CopyUTF8toUTF16(path, filename); -+ CopyUTF8toUTF16(MakeStringSpan(path), filename); - filename.AppendLiteral("/mozilla.pdf"); - } else { - filename.AssignLiteral("mozilla.pdf"); diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60.3.0/widget/gtk/nsDragService.cpp --- thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsDragService.cpp 2018-11-20 12:04:43.736787353 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsDragService.cpp 2018-11-21 13:42:00.759025657 +0100 @@ -34,7 +34,6 @@ #include "nsPresContext.h" #include "nsIContent.h" @@ -3096,81 +1057,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. { // We have to destroy the hidden widget before the event loop stops // running. -@@ -179,7 +185,7 @@ nsDragService::Observe(nsISupports *aSub - } - TargetResetData(); - } else { -- NS_NOTREACHED("unexpected topic"); -+ MOZ_ASSERT_UNREACHABLE("unexpected topic"); - return NS_ERROR_UNEXPECTED; - } - -@@ -269,13 +275,12 @@ OnSourceGrabEventAfter(GtkWidget *widget - } - - static GtkWindow* --GetGtkWindow(nsIDOMDocument *aDocument) -+GetGtkWindow(nsIDocument *aDocument) - { -- nsCOMPtr doc = do_QueryInterface(aDocument); -- if (!doc) -+ if (!aDocument) - return nullptr; - -- nsCOMPtr presShell = doc->GetShell(); -+ nsCOMPtr presShell = aDocument->GetShell(); - if (!presShell) - return nullptr; - -@@ -304,10 +309,9 @@ GetGtkWindow(nsIDOMDocument *aDocument) - // nsIDragService - - NS_IMETHODIMP --nsDragService::InvokeDragSession(nsIDOMNode *aDOMNode, -+nsDragService::InvokeDragSession(nsINode *aDOMNode, - const nsACString& aPrincipalURISpec, - nsIArray * aArrayTransferables, -- nsIScriptableRegion * aRegion, - uint32_t aActionType, - nsContentPolicyType aContentPolicyType = - nsIContentPolicy::TYPE_OTHER) -@@ -323,14 +327,14 @@ nsDragService::InvokeDragSession(nsIDOMN - - return nsBaseDragService::InvokeDragSession(aDOMNode, aPrincipalURISpec, - aArrayTransferables, -- aRegion, aActionType, -+ aActionType, - aContentPolicyType); - } - - // nsBaseDragService - nsresult - nsDragService::InvokeDragSessionImpl(nsIArray* aArrayTransferables, -- nsIScriptableRegion* aRegion, -+ const Maybe& aRegion, - uint32_t aActionType) - { - // make sure that we have an array of transferables to use -@@ -346,9 +350,6 @@ nsDragService::InvokeDragSessionImpl(nsI - if (!sourceList) - return NS_OK; - -- // stored temporarily until the drag-begin signal has been received -- mSourceRegion = aRegion; -- - // save our action type - GdkDragAction action = GDK_ACTION_DEFAULT; - -@@ -391,8 +392,6 @@ nsDragService::InvokeDragSessionImpl(nsI - 1, - &event); - -- mSourceRegion = nullptr; -- - nsresult rv; - if (context) { - StartDragSession(); -@@ -516,6 +515,9 @@ nsDragService::EndDragSession(bool aDone +@@ -516,6 +522,9 @@ nsDragService::EndDragSession(bool aDone // We're done with the drag context. mTargetDragContextForRemote = nullptr; @@ -3180,7 +1067,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. return nsBaseDragService::EndDragSession(aDoneDrag, aKeyModifiers); } -@@ -636,6 +638,14 @@ nsDragService::GetNumDropItems(uint32_t +@@ -636,6 +645,14 @@ nsDragService::GetNumDropItems(uint32_t return NS_OK; } @@ -3195,7 +1082,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. bool isList = IsTargetContextList(); if (isList) mSourceDataItems->GetLength(aNumItems); -@@ -1027,9 +1037,18 @@ nsDragService::IsDataFlavorSupported(con +@@ -1027,9 +1044,18 @@ nsDragService::IsDataFlavorSupported(con } // check the target context vs. this flavor, one at a time @@ -3217,7 +1104,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. /* Bug 331198 */ GdkAtom atom = GDK_POINTER_TO_ATOM(tmp->data); gchar *name = nullptr; -@@ -1074,6 +1093,15 @@ nsDragService::IsDataFlavorSupported(con +@@ -1074,6 +1100,15 @@ nsDragService::IsDataFlavorSupported(con } g_free(name); } @@ -3233,7 +1120,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. return NS_OK; } -@@ -1105,6 +1133,36 @@ nsDragService::ReplyToDragMotion(GdkDrag +@@ -1105,6 +1140,36 @@ nsDragService::ReplyToDragMotion(GdkDrag gdk_drag_status(aDragContext, action, mTargetTime); } @@ -3270,7 +1157,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. void nsDragService::TargetDataReceived(GtkWidget *aWidget, GdkDragContext *aContext, -@@ -1136,6 +1194,12 @@ nsDragService::IsTargetContextList(void) +@@ -1136,6 +1201,12 @@ nsDragService::IsTargetContextList(void) { bool retval = false; @@ -3283,7 +1170,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. // 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 -@@ -1174,17 +1238,28 @@ nsDragService::GetTargetDragData(GdkAtom +@@ -1174,17 +1245,28 @@ nsDragService::GetTargetDragData(GdkAtom mTargetDragContext.get())); // reset our target data areas TargetResetData(); @@ -3321,7 +1208,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. MOZ_LOG(sDragLm, LogLevel::Debug, ("finished inner iteration\n")); } -@@ -1435,7 +1510,7 @@ nsDragService::SourceEndDragSession(GdkD +@@ -1435,7 +1517,7 @@ nsDragService::SourceEndDragSession(GdkD } // Schedule the appropriate drag end dom events. @@ -3330,18 +1217,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. } static void -@@ -1642,8 +1717,8 @@ void nsDragService::SetDragIcon(GdkDragC - LayoutDeviceIntRect dragRect; - nsPresContext* pc; - RefPtr surface; -- DrawDrag(mSourceNode, mSourceRegion, mScreenPosition, -- &dragRect, &surface, &pc); -+ DrawDrag(mSourceNode, mRegion, -+ mScreenPosition, &dragRect, &surface, &pc); - if (!pc) - return; - -@@ -1785,9 +1860,10 @@ invisibleSourceDragEnd(GtkWidget +@@ -1785,9 +1867,10 @@ invisibleSourceDragEnd(GtkWidget gboolean nsDragService::ScheduleMotionEvent(nsWindow *aWindow, GdkDragContext *aDragContext, @@ -3353,7 +1229,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. // 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 -@@ -1798,7 +1874,7 @@ nsDragService::ScheduleMotionEvent(nsWin +@@ -1798,7 +1881,7 @@ nsDragService::ScheduleMotionEvent(nsWin // Returning TRUE means we'll reply with a status message, unless we first // get a leave. @@ -3362,7 +1238,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. aWindowPoint, aTime); } -@@ -1808,7 +1884,8 @@ nsDragService::ScheduleLeaveEvent() +@@ -1808,7 +1891,8 @@ 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. @@ -3372,7 +1248,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. NS_WARNING("Drag leave after drop"); } } -@@ -1816,10 +1893,11 @@ nsDragService::ScheduleLeaveEvent() +@@ -1816,10 +1900,11 @@ nsDragService::ScheduleLeaveEvent() gboolean nsDragService::ScheduleDropEvent(nsWindow *aWindow, GdkDragContext *aDragContext, @@ -3385,7 +1261,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. NS_WARNING("Additional drag drop ignored"); return FALSE; } -@@ -1833,6 +1911,7 @@ nsDragService::ScheduleDropEvent(nsWindo +@@ -1833,6 +1918,7 @@ nsDragService::ScheduleDropEvent(nsWindo gboolean nsDragService::Schedule(DragTask aTask, nsWindow *aWindow, GdkDragContext *aDragContext, @@ -3393,7 +1269,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. LayoutDeviceIntPoint aWindowPoint, guint aTime) { // If there is an existing leave or motion task scheduled, then that -@@ -1851,6 +1930,9 @@ nsDragService::Schedule(DragTask aTask, +@@ -1851,6 +1937,9 @@ nsDragService::Schedule(DragTask aTask, mScheduledTask = aTask; mPendingWindow = aWindow; mPendingDragContext = aDragContext; @@ -3403,7 +1279,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. mPendingWindowPoint = aWindowPoint; mPendingTime = aTime; -@@ -1927,6 +2009,9 @@ nsDragService::RunScheduledTask() +@@ -1927,6 +2016,9 @@ nsDragService::RunScheduledTask() // succeeed. mTargetWidget = mTargetWindow->GetMozContainerWidget(); mTargetDragContext.steal(mPendingDragContext); @@ -3413,7 +1289,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. mTargetTime = mPendingTime; // http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-and-drop-processing-model -@@ -1958,10 +2043,20 @@ nsDragService::RunScheduledTask() +@@ -1958,10 +2050,20 @@ nsDragService::RunScheduledTask() if (task == eDragTaskMotion) { if (TakeDragEventDispatchedToChildProcess()) { mTargetDragContextForRemote = mTargetDragContext; @@ -3435,7 +1311,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. } } } -@@ -1972,8 +2067,10 @@ nsDragService::RunScheduledTask() +@@ -1972,8 +2074,10 @@ 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. @@ -3448,7 +1324,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. // This drag is over, so clear out our reference to the previous // window. -@@ -1986,6 +2083,9 @@ nsDragService::RunScheduledTask() +@@ -1986,6 +2090,9 @@ nsDragService::RunScheduledTask() // We're done with the drag context. mTargetWidget = nullptr; mTargetDragContext = nullptr; @@ -3458,7 +1334,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. // If we got another drag signal while running the sheduled task, that // must have happened while running a nested event loop. Leave the task -@@ -2015,7 +2115,16 @@ nsDragService::UpdateDragAction() +@@ -2015,7 +2122,16 @@ nsDragService::UpdateDragAction() // default is to do nothing int action = nsIDragService::DRAGDROP_ACTION_NONE; @@ -3476,7 +1352,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. // set the default just in case nothing matches below if (gdkAction & GDK_ACTION_DEFAULT) -@@ -2044,6 +2153,12 @@ nsDragService::UpdateDragEffect() +@@ -2044,6 +2160,12 @@ nsDragService::UpdateDragEffect() ReplyToDragMotion(mTargetDragContextForRemote); mTargetDragContextForRemote = nullptr; } @@ -3491,7 +1367,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.cpp.wayland thunderbird-60. diff -up thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland thunderbird-60.3.0/widget/gtk/nsDragService.h --- thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland 2018-10-30 12:45:37.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsDragService.h 2018-11-20 12:04:43.736787353 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsDragService.h 2018-11-21 13:42:00.759025657 +0100 @@ -14,6 +14,7 @@ #include @@ -3500,23 +1376,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland thunderbird-60.3. namespace mozilla { namespace gfx { -@@ -60,13 +61,12 @@ public: - - // nsBaseDragService - virtual nsresult InvokeDragSessionImpl(nsIArray* anArrayTransferables, -- nsIScriptableRegion* aRegion, -+ const mozilla::Maybe& aRegion, - uint32_t aActionType) override; - // nsIDragService -- NS_IMETHOD InvokeDragSession (nsIDOMNode *aDOMNode, -+ NS_IMETHOD InvokeDragSession (nsINode *aDOMNode, - const nsACString& aPrincipalURISpec, - nsIArray * anArrayTransferables, -- nsIScriptableRegion * aRegion, - uint32_t aActionType, - nsContentPolicyType aContentPolicyType) override; - NS_IMETHOD StartDragSession() override; -@@ -98,11 +98,13 @@ public: +@@ -98,11 +99,13 @@ public: gboolean ScheduleMotionEvent(nsWindow *aWindow, GdkDragContext *aDragContext, @@ -3530,7 +1390,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland thunderbird-60.3. mozilla::LayoutDeviceIntPoint aWindowPoint, guint aTime); -@@ -158,6 +160,9 @@ private: +@@ -158,6 +161,9 @@ private: RefPtr mPendingWindow; mozilla::LayoutDeviceIntPoint mPendingWindowPoint; nsCountedRef mPendingDragContext; @@ -3540,7 +1400,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland thunderbird-60.3. guint mPendingTime; // mTargetWindow and mTargetWindowPoint record the position of the last -@@ -169,9 +174,15 @@ private: +@@ -169,9 +175,15 @@ private: // motion or drop events. mTime records the corresponding timestamp. nsCountedRef mTargetWidget; nsCountedRef mTargetDragContext; @@ -3556,16 +1416,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland thunderbird-60.3. guint mTargetTime; // is it OK to drop on us? -@@ -197,8 +208,6 @@ private: - // our source data items - nsCOMPtr mSourceDataItems; - -- nsCOMPtr mSourceRegion; -- - // get a list of the sources in gtk's format - GtkTargetList *GetSourceList(void); - -@@ -212,6 +221,7 @@ private: +@@ -212,6 +224,7 @@ private: gboolean Schedule(DragTask aTask, nsWindow *aWindow, GdkDragContext *aDragContext, @@ -3573,7 +1424,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland thunderbird-60.3. mozilla::LayoutDeviceIntPoint aWindowPoint, guint aTime); // Callback for g_idle_add_full() to run mScheduledTask. -@@ -220,9 +230,11 @@ private: +@@ -220,9 +233,11 @@ private: void UpdateDragAction(); void DispatchMotionEvents(); void ReplyToDragMotion(GdkDragContext* aDragContext); @@ -3586,21 +1437,9 @@ diff -up thunderbird-60.3.0/widget/gtk/nsDragService.h.wayland thunderbird-60.3. #endif // nsDragService_h__ - -diff -up thunderbird-60.3.0/widget/gtk/nsFilePicker.cpp.wayland thunderbird-60.3.0/widget/gtk/nsFilePicker.cpp ---- thunderbird-60.3.0/widget/gtk/nsFilePicker.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsFilePicker.cpp 2018-11-20 12:04:43.736787353 +0100 -@@ -346,7 +346,7 @@ nsFilePicker::GetFiles(nsISimpleEnumerat - NS_ENSURE_ARG_POINTER(aFiles); - - if (mMode == nsIFilePicker::modeOpenMultiple) { -- return NS_NewArrayEnumerator(aFiles, mFiles); -+ return NS_NewArrayEnumerator(aFiles, mFiles, NS_GET_IID(nsIFile)); - } - - return NS_ERROR_FAILURE; diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.cpp.wayland thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.cpp --- thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.cpp.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.cpp 2018-11-20 12:04:43.736787353 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.cpp 2018-11-21 13:42:00.760025653 +0100 @@ -28,6 +28,10 @@ #include "mozilla/MouseEvents.h" #include "mozilla/TextEvents.h" @@ -3847,44 +1686,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.cpp.wayland thunderbird-60. KeymapWrapper::~KeymapWrapper() { gdk_window_remove_filter(nullptr, FilterEvents, this); -@@ -931,14 +1141,19 @@ KeymapWrapper::ComputeDOMCodeNameIndex(c - - /* static */ void - KeymapWrapper::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent, -- GdkEventKey* aGdkKeyEvent) -+ GdkEventKey* aGdkKeyEvent, -+ bool aIsProcessedByIME) - { -+ MOZ_ASSERT(!aIsProcessedByIME || aKeyEvent.mMessage != eKeyPress, -+ "If the key event is handled by IME, keypress event shouldn't be fired"); -+ - KeymapWrapper* keymapWrapper = GetInstance(); - - aKeyEvent.mCodeNameIndex = ComputeDOMCodeNameIndex(aGdkKeyEvent); - MOZ_ASSERT(aKeyEvent.mCodeNameIndex != CODE_NAME_INDEX_USE_STRING); - aKeyEvent.mKeyNameIndex = -- keymapWrapper->ComputeDOMKeyNameIndex(aGdkKeyEvent); -+ aIsProcessedByIME ? KEY_NAME_INDEX_Process : -+ keymapWrapper->ComputeDOMKeyNameIndex(aGdkKeyEvent); - if (aKeyEvent.mKeyNameIndex == KEY_NAME_INDEX_Unidentified) { - uint32_t charCode = GetCharCodeFor(aGdkKeyEvent); - if (!charCode) { -@@ -951,10 +1166,11 @@ KeymapWrapper::InitKeyEvent(WidgetKeyboa - AppendUCS4ToUTF16(charCode, aKeyEvent.mKeyValue); - } - } -- aKeyEvent.mKeyCode = ComputeDOMKeyCode(aGdkKeyEvent); - -- if (aKeyEvent.mKeyNameIndex != KEY_NAME_INDEX_USE_STRING || -- aKeyEvent.mMessage != eKeyPress) { -+ if (aIsProcessedByIME) { -+ aKeyEvent.mKeyCode = NS_VK_PROCESSKEY; -+ } else if (aKeyEvent.mKeyNameIndex != KEY_NAME_INDEX_USE_STRING || -+ aKeyEvent.mMessage != eKeyPress) { - aKeyEvent.mKeyCode = ComputeDOMKeyCode(aGdkKeyEvent); - } else { - aKeyEvent.mKeyCode = 0; -@@ -1405,6 +1621,14 @@ void +@@ -1405,6 +1615,14 @@ void KeymapWrapper::WillDispatchKeyboardEventInternal(WidgetKeyboardEvent& aKeyEvent, GdkEventKey* aGdkKeyEvent) { @@ -3901,7 +1703,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.cpp.wayland thunderbird-60. MOZ_LOG(gKeymapWrapperLog, LogLevel::Info, diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h.wayland thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h --- thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h 2018-11-20 12:04:43.737787350 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h 2018-11-21 13:42:00.760025653 +0100 @@ -13,6 +13,10 @@ #include @@ -3913,20 +1715,15 @@ diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h.wayland thunderbird-60.3. namespace mozilla { namespace widget { -@@ -131,9 +135,11 @@ public: +@@ -131,6 +135,7 @@ public: * @param aKeyEvent It's an WidgetKeyboardEvent which needs to be * initialized. * @param aGdkKeyEvent A native GDK key event. + * @param aIsProcessedByIME true if aGdkKeyEvent is handled by IME. */ static void InitKeyEvent(WidgetKeyboardEvent& aKeyEvent, -- GdkEventKey* aGdkKeyEvent); -+ GdkEventKey* aGdkKeyEvent, -+ bool aIsProcessedByIME); - - /** - * WillDispatchKeyboardEvent() is called via -@@ -148,6 +154,14 @@ public: + GdkEventKey* aGdkKeyEvent); +@@ -148,6 +153,14 @@ public: static void WillDispatchKeyboardEvent(WidgetKeyboardEvent& aKeyEvent, GdkEventKey* aGdkKeyEvent); @@ -3941,7 +1738,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h.wayland thunderbird-60.3. /** * Destroys the singleton KeymapWrapper instance, if it exists. */ -@@ -172,7 +186,10 @@ protected: +@@ -172,7 +185,10 @@ protected: */ void Init(); void InitXKBExtension(); @@ -3953,7 +1750,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h.wayland thunderbird-60.3. /** * mModifierKeys stores each hardware key information. -@@ -374,6 +391,15 @@ protected: +@@ -374,6 +390,15 @@ protected: */ void WillDispatchKeyboardEventInternal(WidgetKeyboardEvent& aKeyEvent, GdkEventKey* aGdkKeyEvent); @@ -3971,16 +1768,8 @@ diff -up thunderbird-60.3.0/widget/gtk/nsGtkKeyUtils.h.wayland thunderbird-60.3. } // namespace widget diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp --- thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp 2018-11-20 12:04:43.737787350 +0100 -@@ -18,6 +18,7 @@ - - #include - #include "gfxPlatformGtk.h" -+#include "mozilla/FontPropertyTypes.h" - #include "ScreenHelperGTK.h" - - #include "gtkdrawing.h" -@@ -31,7 +32,9 @@ ++++ thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp 2018-11-21 13:42:00.760025653 +0100 +@@ -31,7 +31,9 @@ #include #include "WidgetStyleCache.h" #include "prenv.h" @@ -3990,7 +1779,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60. using mozilla::LookAndFeel; #define GDK_COLOR_TO_NS_RGB(c) \ -@@ -182,7 +185,7 @@ GetBorderColors(GtkStyleContext* aContex +@@ -182,7 +184,7 @@ GetBorderColors(GtkStyleContext* aContex // 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; @@ -3999,7 +1788,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60. visible = border.top != 0 || border.right != 0 || border.bottom != 0 || border.left != 0; } -@@ -213,6 +216,58 @@ GetBorderColors(GtkStyleContext* aContex +@@ -213,6 +215,58 @@ GetBorderColors(GtkStyleContext* aContex return ret; } @@ -4058,7 +1847,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60. void nsLookAndFeel::NativeInit() { -@@ -269,7 +324,6 @@ nsLookAndFeel::NativeGetColor(ColorID aI +@@ -269,7 +323,6 @@ nsLookAndFeel::NativeGetColor(ColorID aI case eColorID_IMESelectedRawTextBackground: case eColorID_IMESelectedConvertedTextBackground: case eColorID__moz_dragtargetzone: @@ -4066,7 +1855,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60. case eColorID__moz_html_cellhighlight: case eColorID_highlight: // preference selected item, aColor = mTextSelectedBackground; -@@ -279,10 +333,15 @@ nsLookAndFeel::NativeGetColor(ColorID aI +@@ -279,10 +332,15 @@ nsLookAndFeel::NativeGetColor(ColorID aI case eColorID_IMESelectedRawTextForeground: case eColorID_IMESelectedConvertedTextForeground: case eColorID_highlighttext: @@ -4083,47 +1872,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60. case eColorID_Widget3DHighlight: aColor = NS_RGB(0xa0,0xa0,0xa0); break; -@@ -668,6 +727,17 @@ nsLookAndFeel::GetIntImpl(IntID aID, int - EnsureInit(); - aResult = mCSDCloseButton; - break; -+ case eIntID_PrefersReducedMotion: { -+ GtkSettings *settings; -+ gboolean enableAnimations; -+ -+ settings = gtk_settings_get_default(); -+ g_object_get(settings, -+ "gtk-enable-animations", -+ &enableAnimations, nullptr); -+ aResult = enableAnimations ? 0 : 1; -+ break; -+ } - default: - aResult = 0; - res = NS_ERROR_FAILURE; -@@ -708,7 +778,7 @@ GetSystemFontInfo(GtkStyleContext *aStyl - nsString *aFontName, - gfxFontStyle *aFontStyle) - { -- aFontStyle->style = NS_FONT_STYLE_NORMAL; -+ aFontStyle->style = FontSlantStyle::Normal(); - - // As in - // https://git.gnome.org/browse/gtk+/tree/gtk/gtkwidget.c?h=3.22.19#n10333 -@@ -722,10 +792,10 @@ GetSystemFontInfo(GtkStyleContext *aStyl - NS_ConvertUTF8toUTF16 family(pango_font_description_get_family(desc)); - *aFontName = quote + family + quote; - -- aFontStyle->weight = pango_font_description_get_weight(desc); -+ aFontStyle->weight = FontWeight(pango_font_description_get_weight(desc)); - - // FIXME: Set aFontStyle->stretch correctly! -- aFontStyle->stretch = NS_FONT_STRETCH_NORMAL; -+ aFontStyle->stretch = FontStretch::Normal(); - - float size = float(pango_font_description_get_size(desc)) / PANGO_SCALE; - -@@ -1009,6 +1079,9 @@ nsLookAndFeel::EnsureInit() +@@ -1009,6 +1067,9 @@ nsLookAndFeel::EnsureInit() mOddCellBackground = GDK_RGBA_TO_NS_RGBA(color); gtk_style_context_restore(style); @@ -4135,7 +1884,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.cpp.wayland thunderbird-60. // root node, so check the root node if no border is found on the border diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.h.wayland thunderbird-60.3.0/widget/gtk/nsLookAndFeel.h --- thunderbird-60.3.0/widget/gtk/nsLookAndFeel.h.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsLookAndFeel.h 2018-11-20 12:04:43.737787350 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsLookAndFeel.h 2018-11-21 13:42:00.760025653 +0100 @@ -77,6 +77,8 @@ protected: nscolor mMozWindowActiveBorder; nscolor mMozWindowInactiveBorder; @@ -4154,1888 +1903,10 @@ diff -up thunderbird-60.3.0/widget/gtk/nsLookAndFeel.h.wayland thunderbird-60.3. + nsresult InitCellHighlightColors(); }; - #endif -diff -up thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.cpp.wayland thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.cpp ---- thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.cpp 2018-11-20 12:04:43.738787347 +0100 -@@ -4,7 +4,7 @@ - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - - #include "nsNativeThemeGTK.h" --#include "nsThemeConstants.h" -+#include "nsStyleConsts.h" - #include "gtkdrawing.h" - #include "ScreenHelperGTK.h" - -@@ -39,6 +39,8 @@ - #include "mozilla/gfx/HelpersCairo.h" - #include "mozilla/gfx/PathHelpers.h" - #include "mozilla/Preferences.h" -+#include "mozilla/layers/StackingContextHelper.h" -+#include "mozilla/StaticPrefs.h" - - #ifdef MOZ_X11 - # ifdef CAIRO_HAS_XLIB_SURFACE -@@ -119,7 +121,7 @@ nsNativeThemeGTK::Observe(nsISupports *a - if (!nsCRT::strcmp(aTopic, "xpcom-shutdown")) { - moz_gtk_shutdown(); - } else { -- NS_NOTREACHED("unexpected topic"); -+ MOZ_ASSERT_UNREACHABLE("unexpected topic"); - return NS_ERROR_UNEXPECTED; - } - -@@ -149,41 +151,43 @@ static bool IsFrameContentNodeInNamespac - return content->IsInNamespace(aNamespace); - } - --static bool IsWidgetTypeDisabled(uint8_t* aDisabledVector, uint8_t aWidgetType) { -- MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT); -- return (aDisabledVector[aWidgetType >> 3] & (1 << (aWidgetType & 7))) != 0; -+static bool IsWidgetTypeDisabled(uint8_t* aDisabledVector, StyleAppearance aWidgetType) { -+ auto type = static_cast(aWidgetType); -+ MOZ_ASSERT(type < static_cast(mozilla::StyleAppearance::Count)); -+ return (aDisabledVector[type >> 3] & (1 << (type & 7))) != 0; - } - --static void SetWidgetTypeDisabled(uint8_t* aDisabledVector, uint8_t aWidgetType) { -- MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT); -- aDisabledVector[aWidgetType >> 3] |= (1 << (aWidgetType & 7)); -+static void SetWidgetTypeDisabled(uint8_t* aDisabledVector, StyleAppearance aWidgetType) { -+ auto type = static_cast(aWidgetType); -+ MOZ_ASSERT(type < static_cast(mozilla::StyleAppearance::Count)); -+ aDisabledVector[type >> 3] |= (1 << (type & 7)); - } - - static inline uint16_t --GetWidgetStateKey(uint8_t aWidgetType, GtkWidgetState *aWidgetState) -+GetWidgetStateKey(StyleAppearance aWidgetType, GtkWidgetState *aWidgetState) - { - return (aWidgetState->active | - aWidgetState->focused << 1 | - aWidgetState->inHover << 2 | - aWidgetState->disabled << 3 | - aWidgetState->isDefault << 4 | -- aWidgetType << 5); -+ static_cast(aWidgetType) << 5); - } - - static bool IsWidgetStateSafe(uint8_t* aSafeVector, -- uint8_t aWidgetType, -- GtkWidgetState *aWidgetState) -+ StyleAppearance aWidgetType, -+ GtkWidgetState *aWidgetState) - { -- MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT); -+ MOZ_ASSERT(static_cast(aWidgetType) < static_cast(mozilla::StyleAppearance::Count)); - uint16_t key = GetWidgetStateKey(aWidgetType, aWidgetState); - return (aSafeVector[key >> 3] & (1 << (key & 7))) != 0; - } - - static void SetWidgetStateSafe(uint8_t *aSafeVector, -- uint8_t aWidgetType, -+ StyleAppearance aWidgetType, - GtkWidgetState *aWidgetState) - { -- MOZ_ASSERT(aWidgetType < ThemeWidgetType_COUNT); -+ MOZ_ASSERT(static_cast(aWidgetType) < static_cast(mozilla::StyleAppearance::Count)); - uint16_t key = GetWidgetStateKey(aWidgetType, aWidgetState); - aSafeVector[key >> 3] |= (1 << (key & 7)); - } -@@ -213,33 +217,38 @@ nsNativeThemeGTK::GetTabMarginPixels(nsI - } - - static bool ShouldScrollbarButtonBeDisabled(int32_t aCurpos, int32_t aMaxpos, -- uint8_t aWidgetType) -+ StyleAppearance aWidgetType) - { -- return ((aCurpos == 0 && (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT)) -- || (aCurpos == aMaxpos && (aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT))); -+ return ((aCurpos == 0 && (aWidgetType == StyleAppearance::ScrollbarbuttonUp || -+ aWidgetType == StyleAppearance::ScrollbarbuttonLeft)) -+ || (aCurpos == aMaxpos && (aWidgetType == StyleAppearance::ScrollbarbuttonDown || -+ aWidgetType == StyleAppearance::ScrollbarbuttonRight))); - } - - bool --nsNativeThemeGTK::GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, -+nsNativeThemeGTK::GetGtkWidgetAndState(StyleAppearance aWidgetType, nsIFrame* aFrame, - WidgetNodeType& aGtkWidgetType, - GtkWidgetState* aState, - gint* aWidgetFlags) - { -+ if (aWidgetType == StyleAppearance::MenulistButton && -+ StaticPrefs::layout_css_webkit_appearance_enabled()) { -+ aWidgetType = StyleAppearance::Menulist; -+ } -+ - if (aState) { - // For XUL checkboxes and radio buttons, the state of the parent - // determines our state. - nsIFrame *stateFrame = aFrame; -- if (aFrame && ((aWidgetFlags && (aWidgetType == NS_THEME_CHECKBOX || -- aWidgetType == NS_THEME_RADIO)) || -- aWidgetType == NS_THEME_CHECKBOX_LABEL || -- aWidgetType == NS_THEME_RADIO_LABEL)) { -+ if (aFrame && ((aWidgetFlags && (aWidgetType == StyleAppearance::Checkbox || -+ aWidgetType == StyleAppearance::Radio)) || -+ aWidgetType == StyleAppearance::CheckboxLabel || -+ aWidgetType == StyleAppearance::RadioLabel)) { - - nsAtom* atom = nullptr; - if (IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) { -- if (aWidgetType == NS_THEME_CHECKBOX_LABEL || -- aWidgetType == NS_THEME_RADIO_LABEL) { -+ if (aWidgetType == StyleAppearance::CheckboxLabel || -+ aWidgetType == StyleAppearance::RadioLabel) { - // Adjust stateFrame so GetContentState finds the correct state. - stateFrame = aFrame = aFrame->GetParent()->GetParent(); - } else { -@@ -249,8 +258,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - if (aWidgetFlags) { - if (!atom) { -- atom = (aWidgetType == NS_THEME_CHECKBOX || -- aWidgetType == NS_THEME_CHECKBOX_LABEL) ? nsGkAtoms::checked -+ atom = (aWidgetType == StyleAppearance::Checkbox || -+ aWidgetType == StyleAppearance::CheckboxLabel) ? nsGkAtoms::checked - : nsGkAtoms::selected; - } - *aWidgetFlags = CheckBooleanAttr(aFrame, atom); -@@ -258,7 +267,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } else { - if (aWidgetFlags) { - *aWidgetFlags = 0; -- HTMLInputElement* inputElt = HTMLInputElement::FromContent(aFrame->GetContent()); -+ HTMLInputElement* inputElt = HTMLInputElement::FromNode(aFrame->GetContent()); - if (inputElt && inputElt->Checked()) - *aWidgetFlags |= MOZ_GTK_WIDGET_CHECKED; - -@@ -266,12 +275,12 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - *aWidgetFlags |= MOZ_GTK_WIDGET_INCONSISTENT; - } - } -- } else if (aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -- aWidgetType == NS_THEME_TREEHEADERSORTARROW || -- aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS || -- aWidgetType == NS_THEME_BUTTON_ARROW_NEXT || -- aWidgetType == NS_THEME_BUTTON_ARROW_UP || -- aWidgetType == NS_THEME_BUTTON_ARROW_DOWN) { -+ } else if (aWidgetType == StyleAppearance::ToolbarbuttonDropdown || -+ aWidgetType == StyleAppearance::Treeheadersortarrow || -+ aWidgetType == StyleAppearance::ButtonArrowPrevious || -+ aWidgetType == StyleAppearance::ButtonArrowNext || -+ aWidgetType == StyleAppearance::ButtonArrowUp || -+ aWidgetType == StyleAppearance::ButtonArrowDown) { - // The state of an arrow comes from its parent. - stateFrame = aFrame = aFrame->GetParent(); - } -@@ -287,7 +296,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - aState->canDefault = FALSE; // XXX fix me - aState->depressed = FALSE; - -- if (aWidgetType == NS_THEME_FOCUS_OUTLINE) { -+ if (aWidgetType == StyleAppearance::FocusOutline) { - aState->disabled = FALSE; - aState->active = FALSE; - aState->inHover = FALSE; -@@ -296,15 +305,16 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - - aState->focused = TRUE; - aState->depressed = TRUE; // see moz_gtk_entry_paint() -- } else if (aWidgetType == NS_THEME_BUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON || -- aWidgetType == NS_THEME_DUALBUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -- aWidgetType == NS_THEME_MENULIST || -- aWidgetType == NS_THEME_MENULIST_BUTTON) { -+ } else if (aWidgetType == StyleAppearance::Button || -+ aWidgetType == StyleAppearance::Toolbarbutton || -+ aWidgetType == StyleAppearance::Dualbutton || -+ aWidgetType == StyleAppearance::ToolbarbuttonDropdown || -+ aWidgetType == StyleAppearance::Menulist || -+ aWidgetType == StyleAppearance::MenulistButton || -+ aWidgetType == StyleAppearance::MozMenulistButton) { - aState->active &= aState->inHover; -- } else if (aWidgetType == NS_THEME_TREETWISTY || -- aWidgetType == NS_THEME_TREETWISTYOPEN) { -+ } else if (aWidgetType == StyleAppearance::Treetwisty || -+ aWidgetType == StyleAppearance::Treetwistyopen) { - nsTreeBodyFrame *treeBodyFrame = do_QueryFrame(aFrame); - if (treeBodyFrame) { - const mozilla::AtomArray& atoms = -@@ -318,22 +328,22 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - // For these widget types, some element (either a child or parent) - // actually has element focus, so we check the focused attribute - // to see whether to draw in the focused state. -- if (aWidgetType == NS_THEME_NUMBER_INPUT || -- aWidgetType == NS_THEME_TEXTFIELD || -- aWidgetType == NS_THEME_TEXTFIELD_MULTILINE || -- aWidgetType == NS_THEME_MENULIST_TEXTFIELD || -- aWidgetType == NS_THEME_SPINNER_TEXTFIELD || -- aWidgetType == NS_THEME_RADIO_CONTAINER || -- aWidgetType == NS_THEME_RADIO_LABEL) { -+ if (aWidgetType == StyleAppearance::NumberInput || -+ aWidgetType == StyleAppearance::Textfield || -+ aWidgetType == StyleAppearance::TextfieldMultiline || -+ aWidgetType == StyleAppearance::MenulistTextfield || -+ aWidgetType == StyleAppearance::SpinnerTextfield || -+ aWidgetType == StyleAppearance::RadioContainer || -+ aWidgetType == StyleAppearance::RadioLabel) { - aState->focused = IsFocused(aFrame); -- } else if (aWidgetType == NS_THEME_RADIO || -- aWidgetType == NS_THEME_CHECKBOX) { -+ } else if (aWidgetType == StyleAppearance::Radio || -+ aWidgetType == StyleAppearance::Checkbox) { - // In XUL, checkboxes and radios shouldn't have focus rings, their labels do - aState->focused = FALSE; - } - -- if (aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL || -- aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) { -+ if (aWidgetType == StyleAppearance::ScrollbarthumbVertical || -+ aWidgetType == StyleAppearance::ScrollbarthumbHorizontal) { - // for scrollbars we need to go up two to go from the thumb to - // the slider to the actual scrollbar object - nsIFrame *tmpFrame = aFrame->GetParent()->GetParent(); -@@ -348,10 +358,10 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - } - -- if (aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) { -+ if (aWidgetType == StyleAppearance::ScrollbarbuttonUp || -+ aWidgetType == StyleAppearance::ScrollbarbuttonDown || -+ aWidgetType == StyleAppearance::ScrollbarbuttonLeft || -+ aWidgetType == StyleAppearance::ScrollbarbuttonRight) { - // set the state to disabled when the scrollbar is scrolled to - // the beginning or the end, depending on the button type. - int32_t curpos = CheckIntAttr(aFrame, nsGkAtoms::curpos, 0); -@@ -369,7 +379,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - - if (aWidgetFlags) { - *aWidgetFlags = GetScrollbarButtonType(aFrame); -- if (aWidgetType - NS_THEME_SCROLLBARBUTTON_UP < 2) -+ if (static_cast(aWidgetType) - -+ static_cast(StyleAppearance::ScrollbarbuttonUp) < 2) - *aWidgetFlags |= MOZ_GTK_STEPPER_VERTICAL; - } - } -@@ -379,11 +390,11 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - // menus which are children of a menu bar are only marked as prelight - // if they are open, not on normal hover. - -- if (aWidgetType == NS_THEME_MENUITEM || -- aWidgetType == NS_THEME_CHECKMENUITEM || -- aWidgetType == NS_THEME_RADIOMENUITEM || -- aWidgetType == NS_THEME_MENUSEPARATOR || -- aWidgetType == NS_THEME_MENUARROW) { -+ if (aWidgetType == StyleAppearance::Menuitem || -+ aWidgetType == StyleAppearance::Checkmenuitem || -+ aWidgetType == StyleAppearance::Radiomenuitem || -+ aWidgetType == StyleAppearance::Menuseparator || -+ aWidgetType == StyleAppearance::Menuarrow) { - bool isTopLevel = false; - nsMenuFrame *menuFrame = do_QueryFrame(aFrame); - if (menuFrame) { -@@ -398,8 +409,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - - aState->active = FALSE; - -- if (aWidgetType == NS_THEME_CHECKMENUITEM || -- aWidgetType == NS_THEME_RADIOMENUITEM) { -+ if (aWidgetType == StyleAppearance::Checkmenuitem || -+ aWidgetType == StyleAppearance::Radiomenuitem) { - *aWidgetFlags = 0; - if (aFrame && aFrame->GetContent() && - aFrame->GetContent()->IsElement()) { -@@ -412,12 +423,13 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - - // A button with drop down menu open or an activated toggle button - // should always appear depressed. -- if (aWidgetType == NS_THEME_BUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON || -- aWidgetType == NS_THEME_DUALBUTTON || -- aWidgetType == NS_THEME_TOOLBARBUTTON_DROPDOWN || -- aWidgetType == NS_THEME_MENULIST || -- aWidgetType == NS_THEME_MENULIST_BUTTON) { -+ if (aWidgetType == StyleAppearance::Button || -+ aWidgetType == StyleAppearance::Toolbarbutton || -+ aWidgetType == StyleAppearance::Dualbutton || -+ aWidgetType == StyleAppearance::ToolbarbuttonDropdown || -+ aWidgetType == StyleAppearance::Menulist || -+ aWidgetType == StyleAppearance::MenulistButton || -+ aWidgetType == StyleAppearance::MozMenulistButton) { - bool menuOpen = IsOpenButton(aFrame); - aState->depressed = IsCheckedButton(aFrame) || menuOpen; - // we must not highlight buttons with open drop down menus on hover. -@@ -426,79 +438,81 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - - // When the input field of the drop down button has focus, some themes - // should draw focus for the drop down button as well. -- if (aWidgetType == NS_THEME_MENULIST_BUTTON && aWidgetFlags) { -+ if ((aWidgetType == StyleAppearance::MenulistButton || -+ aWidgetType == StyleAppearance::MozMenulistButton) && -+ aWidgetFlags) { - *aWidgetFlags = CheckBooleanAttr(aFrame, nsGkAtoms::parentfocused); - } - } - } - - switch (aWidgetType) { -- case NS_THEME_BUTTON: -+ case StyleAppearance::Button: - if (aWidgetFlags) - *aWidgetFlags = GTK_RELIEF_NORMAL; - aGtkWidgetType = MOZ_GTK_BUTTON; - break; -- case NS_THEME_TOOLBARBUTTON: -- case NS_THEME_DUALBUTTON: -+ case StyleAppearance::Toolbarbutton: -+ case StyleAppearance::Dualbutton: - if (aWidgetFlags) - *aWidgetFlags = GTK_RELIEF_NONE; - aGtkWidgetType = MOZ_GTK_TOOLBAR_BUTTON; - break; -- case NS_THEME_FOCUS_OUTLINE: -+ case StyleAppearance::FocusOutline: - aGtkWidgetType = MOZ_GTK_ENTRY; - break; -- case NS_THEME_CHECKBOX: -- case NS_THEME_RADIO: -- aGtkWidgetType = (aWidgetType == NS_THEME_RADIO) ? MOZ_GTK_RADIOBUTTON : MOZ_GTK_CHECKBUTTON; -- break; -- case NS_THEME_SCROLLBARBUTTON_UP: -- case NS_THEME_SCROLLBARBUTTON_DOWN: -- case NS_THEME_SCROLLBARBUTTON_LEFT: -- case NS_THEME_SCROLLBARBUTTON_RIGHT: -+ case StyleAppearance::Checkbox: -+ case StyleAppearance::Radio: -+ aGtkWidgetType = (aWidgetType == StyleAppearance::Radio) ? MOZ_GTK_RADIOBUTTON : MOZ_GTK_CHECKBUTTON; -+ break; -+ case StyleAppearance::ScrollbarbuttonUp: -+ case StyleAppearance::ScrollbarbuttonDown: -+ case StyleAppearance::ScrollbarbuttonLeft: -+ case StyleAppearance::ScrollbarbuttonRight: - aGtkWidgetType = MOZ_GTK_SCROLLBAR_BUTTON; - break; -- case NS_THEME_SCROLLBAR_VERTICAL: -+ case StyleAppearance::ScrollbarVertical: - aGtkWidgetType = MOZ_GTK_SCROLLBAR_VERTICAL; - if (GetWidgetTransparency(aFrame, aWidgetType) == eOpaque) - *aWidgetFlags = MOZ_GTK_TRACK_OPAQUE; - else - *aWidgetFlags = 0; - break; -- case NS_THEME_SCROLLBAR_HORIZONTAL: -+ case StyleAppearance::ScrollbarHorizontal: - aGtkWidgetType = MOZ_GTK_SCROLLBAR_HORIZONTAL; - if (GetWidgetTransparency(aFrame, aWidgetType) == eOpaque) - *aWidgetFlags = MOZ_GTK_TRACK_OPAQUE; - else - *aWidgetFlags = 0; - break; -- case NS_THEME_SCROLLBARTRACK_HORIZONTAL: -+ case StyleAppearance::ScrollbartrackHorizontal: - aGtkWidgetType = MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL; - break; -- case NS_THEME_SCROLLBARTRACK_VERTICAL: -+ case StyleAppearance::ScrollbartrackVertical: - aGtkWidgetType = MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL; - break; -- case NS_THEME_SCROLLBARTHUMB_VERTICAL: -+ case StyleAppearance::ScrollbarthumbVertical: - aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_VERTICAL; - break; -- case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: -+ case StyleAppearance::ScrollbarthumbHorizontal: - aGtkWidgetType = MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL; - break; -- case NS_THEME_INNER_SPIN_BUTTON: -+ case StyleAppearance::InnerSpinButton: - aGtkWidgetType = MOZ_GTK_INNER_SPIN_BUTTON; - break; -- case NS_THEME_SPINNER: -+ case StyleAppearance::Spinner: - aGtkWidgetType = MOZ_GTK_SPINBUTTON; - break; -- case NS_THEME_SPINNER_UPBUTTON: -+ case StyleAppearance::SpinnerUpbutton: - aGtkWidgetType = MOZ_GTK_SPINBUTTON_UP; - break; -- case NS_THEME_SPINNER_DOWNBUTTON: -+ case StyleAppearance::SpinnerDownbutton: - aGtkWidgetType = MOZ_GTK_SPINBUTTON_DOWN; - break; -- case NS_THEME_SPINNER_TEXTFIELD: -+ case StyleAppearance::SpinnerTextfield: - aGtkWidgetType = MOZ_GTK_SPINBUTTON_ENTRY; - break; -- case NS_THEME_RANGE: -+ case StyleAppearance::Range: - { - if (IsRangeHorizontal(aFrame)) { - if (aWidgetFlags) -@@ -511,7 +525,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - break; - } -- case NS_THEME_RANGE_THUMB: -+ case StyleAppearance::RangeThumb: - { - if (IsRangeHorizontal(aFrame)) { - if (aWidgetFlags) -@@ -524,51 +538,51 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - break; - } -- case NS_THEME_SCALE_HORIZONTAL: -+ case StyleAppearance::ScaleHorizontal: - if (aWidgetFlags) - *aWidgetFlags = GTK_ORIENTATION_HORIZONTAL; - aGtkWidgetType = MOZ_GTK_SCALE_HORIZONTAL; - break; -- case NS_THEME_SCALETHUMB_HORIZONTAL: -+ case StyleAppearance::ScalethumbHorizontal: - if (aWidgetFlags) - *aWidgetFlags = GTK_ORIENTATION_HORIZONTAL; - aGtkWidgetType = MOZ_GTK_SCALE_THUMB_HORIZONTAL; - break; -- case NS_THEME_SCALE_VERTICAL: -+ case StyleAppearance::ScaleVertical: - if (aWidgetFlags) - *aWidgetFlags = GTK_ORIENTATION_VERTICAL; - aGtkWidgetType = MOZ_GTK_SCALE_VERTICAL; - break; -- case NS_THEME_SEPARATOR: -+ case StyleAppearance::Separator: - aGtkWidgetType = MOZ_GTK_TOOLBAR_SEPARATOR; - break; -- case NS_THEME_SCALETHUMB_VERTICAL: -+ case StyleAppearance::ScalethumbVertical: - if (aWidgetFlags) - *aWidgetFlags = GTK_ORIENTATION_VERTICAL; - aGtkWidgetType = MOZ_GTK_SCALE_THUMB_VERTICAL; - break; -- case NS_THEME_TOOLBARGRIPPER: -+ case StyleAppearance::Toolbargripper: - aGtkWidgetType = MOZ_GTK_GRIPPER; - break; -- case NS_THEME_RESIZER: -+ case StyleAppearance::Resizer: - aGtkWidgetType = MOZ_GTK_RESIZER; - break; -- case NS_THEME_NUMBER_INPUT: -- case NS_THEME_TEXTFIELD: -+ case StyleAppearance::NumberInput: -+ case StyleAppearance::Textfield: - aGtkWidgetType = MOZ_GTK_ENTRY; - break; -- case NS_THEME_TEXTFIELD_MULTILINE: -+ case StyleAppearance::TextfieldMultiline: - #ifdef MOZ_WIDGET_GTK - aGtkWidgetType = MOZ_GTK_TEXT_VIEW; - #else - aGtkWidgetType = MOZ_GTK_ENTRY; - #endif - break; -- case NS_THEME_LISTBOX: -- case NS_THEME_TREEVIEW: -+ case StyleAppearance::Listbox: -+ case StyleAppearance::Treeview: - aGtkWidgetType = MOZ_GTK_TREEVIEW; - break; -- case NS_THEME_TREEHEADERCELL: -+ case StyleAppearance::Treeheadercell: - if (aWidgetFlags) { - // In this case, the flag denotes whether the header is the sorted one or not - if (GetTreeSortDirection(aFrame) == eTreeSortDirection_Natural) -@@ -578,7 +592,7 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - aGtkWidgetType = MOZ_GTK_TREE_HEADER_CELL; - break; -- case NS_THEME_TREEHEADERSORTARROW: -+ case StyleAppearance::Treeheadersortarrow: - if (aWidgetFlags) { - switch (GetTreeSortDirection(aFrame)) { - case eTreeSortDirection_Ascending: -@@ -598,74 +612,75 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - aGtkWidgetType = MOZ_GTK_TREE_HEADER_SORTARROW; - break; -- case NS_THEME_TREETWISTY: -+ case StyleAppearance::Treetwisty: - aGtkWidgetType = MOZ_GTK_TREEVIEW_EXPANDER; - if (aWidgetFlags) - *aWidgetFlags = GTK_EXPANDER_COLLAPSED; - break; -- case NS_THEME_TREETWISTYOPEN: -+ case StyleAppearance::Treetwistyopen: - aGtkWidgetType = MOZ_GTK_TREEVIEW_EXPANDER; - if (aWidgetFlags) - *aWidgetFlags = GTK_EXPANDER_EXPANDED; - break; -- case NS_THEME_MENULIST: -+ case StyleAppearance::Menulist: - aGtkWidgetType = MOZ_GTK_DROPDOWN; - if (aWidgetFlags) - *aWidgetFlags = IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XHTML); - break; -- case NS_THEME_MENULIST_TEXT: -+ case StyleAppearance::MenulistText: - return false; // nothing to do, but prevents the bg from being drawn -- case NS_THEME_MENULIST_TEXTFIELD: -+ case StyleAppearance::MenulistTextfield: - aGtkWidgetType = MOZ_GTK_DROPDOWN_ENTRY; - break; -- case NS_THEME_MENULIST_BUTTON: -+ case StyleAppearance::MenulistButton: -+ case StyleAppearance::MozMenulistButton: - aGtkWidgetType = MOZ_GTK_DROPDOWN_ARROW; - break; -- case NS_THEME_TOOLBARBUTTON_DROPDOWN: -- case NS_THEME_BUTTON_ARROW_DOWN: -- case NS_THEME_BUTTON_ARROW_UP: -- case NS_THEME_BUTTON_ARROW_NEXT: -- case NS_THEME_BUTTON_ARROW_PREVIOUS: -+ case StyleAppearance::ToolbarbuttonDropdown: -+ case StyleAppearance::ButtonArrowDown: -+ case StyleAppearance::ButtonArrowUp: -+ case StyleAppearance::ButtonArrowNext: -+ case StyleAppearance::ButtonArrowPrevious: - aGtkWidgetType = MOZ_GTK_TOOLBARBUTTON_ARROW; - if (aWidgetFlags) { - *aWidgetFlags = GTK_ARROW_DOWN; - -- if (aWidgetType == NS_THEME_BUTTON_ARROW_UP) -+ if (aWidgetType == StyleAppearance::ButtonArrowUp) - *aWidgetFlags = GTK_ARROW_UP; -- else if (aWidgetType == NS_THEME_BUTTON_ARROW_NEXT) -+ else if (aWidgetType == StyleAppearance::ButtonArrowNext) - *aWidgetFlags = GTK_ARROW_RIGHT; -- else if (aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS) -+ else if (aWidgetType == StyleAppearance::ButtonArrowPrevious) - *aWidgetFlags = GTK_ARROW_LEFT; - } - break; -- case NS_THEME_CHECKBOX_CONTAINER: -+ case StyleAppearance::CheckboxContainer: - aGtkWidgetType = MOZ_GTK_CHECKBUTTON_CONTAINER; - break; -- case NS_THEME_RADIO_CONTAINER: -+ case StyleAppearance::RadioContainer: - aGtkWidgetType = MOZ_GTK_RADIOBUTTON_CONTAINER; - break; -- case NS_THEME_CHECKBOX_LABEL: -+ case StyleAppearance::CheckboxLabel: - aGtkWidgetType = MOZ_GTK_CHECKBUTTON_LABEL; - break; -- case NS_THEME_RADIO_LABEL: -+ case StyleAppearance::RadioLabel: - aGtkWidgetType = MOZ_GTK_RADIOBUTTON_LABEL; - break; -- case NS_THEME_TOOLBAR: -+ case StyleAppearance::Toolbar: - aGtkWidgetType = MOZ_GTK_TOOLBAR; - break; -- case NS_THEME_TOOLTIP: -+ case StyleAppearance::Tooltip: - aGtkWidgetType = MOZ_GTK_TOOLTIP; - break; -- case NS_THEME_STATUSBARPANEL: -- case NS_THEME_RESIZERPANEL: -+ case StyleAppearance::Statusbarpanel: -+ case StyleAppearance::Resizerpanel: - aGtkWidgetType = MOZ_GTK_FRAME; - break; -- case NS_THEME_PROGRESSBAR: -- case NS_THEME_PROGRESSBAR_VERTICAL: -+ case StyleAppearance::Progressbar: -+ case StyleAppearance::ProgressbarVertical: - aGtkWidgetType = MOZ_GTK_PROGRESSBAR; - break; -- case NS_THEME_PROGRESSCHUNK: -- case NS_THEME_PROGRESSCHUNK_VERTICAL: -+ case StyleAppearance::Progresschunk: -+ case StyleAppearance::ProgresschunkVertical: - { - nsIFrame* stateFrame = aFrame->GetParent(); - EventStates eventStates = GetContentState(stateFrame, aWidgetType); -@@ -677,17 +692,17 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - : MOZ_GTK_PROGRESS_CHUNK; - } - break; -- case NS_THEME_TAB_SCROLL_ARROW_BACK: -- case NS_THEME_TAB_SCROLL_ARROW_FORWARD: -+ case StyleAppearance::TabScrollArrowBack: -+ case StyleAppearance::TabScrollArrowForward: - if (aWidgetFlags) -- *aWidgetFlags = aWidgetType == NS_THEME_TAB_SCROLL_ARROW_BACK ? -+ *aWidgetFlags = aWidgetType == StyleAppearance::TabScrollArrowBack ? - GTK_ARROW_LEFT : GTK_ARROW_RIGHT; - aGtkWidgetType = MOZ_GTK_TAB_SCROLLARROW; - break; -- case NS_THEME_TABPANELS: -+ case StyleAppearance::Tabpanels: - aGtkWidgetType = MOZ_GTK_TABPANELS; - break; -- case NS_THEME_TAB: -+ case StyleAppearance::Tab: - { - if (IsBottomTab(aFrame)) { - aGtkWidgetType = MOZ_GTK_TAB_BOTTOM; -@@ -709,19 +724,19 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - } - break; -- case NS_THEME_SPLITTER: -+ case StyleAppearance::Splitter: - if (IsHorizontal(aFrame)) - aGtkWidgetType = MOZ_GTK_SPLITTER_VERTICAL; - else - aGtkWidgetType = MOZ_GTK_SPLITTER_HORIZONTAL; - break; -- case NS_THEME_MENUBAR: -+ case StyleAppearance::Menubar: - aGtkWidgetType = MOZ_GTK_MENUBAR; - break; -- case NS_THEME_MENUPOPUP: -+ case StyleAppearance::Menupopup: - aGtkWidgetType = MOZ_GTK_MENUPOPUP; - break; -- case NS_THEME_MENUITEM: -+ case StyleAppearance::Menuitem: - { - nsMenuFrame *menuFrame = do_QueryFrame(aFrame); - if (menuFrame && menuFrame->IsOnMenuBar()) { -@@ -731,41 +746,41 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u - } - aGtkWidgetType = MOZ_GTK_MENUITEM; - break; -- case NS_THEME_MENUSEPARATOR: -+ case StyleAppearance::Menuseparator: - aGtkWidgetType = MOZ_GTK_MENUSEPARATOR; - break; -- case NS_THEME_MENUARROW: -+ case StyleAppearance::Menuarrow: - aGtkWidgetType = MOZ_GTK_MENUARROW; - break; -- case NS_THEME_CHECKMENUITEM: -+ case StyleAppearance::Checkmenuitem: - aGtkWidgetType = MOZ_GTK_CHECKMENUITEM; - break; -- case NS_THEME_RADIOMENUITEM: -+ case StyleAppearance::Radiomenuitem: - aGtkWidgetType = MOZ_GTK_RADIOMENUITEM; - break; -- case NS_THEME_WINDOW: -- case NS_THEME_DIALOG: -+ case StyleAppearance::Window: -+ case StyleAppearance::Dialog: - aGtkWidgetType = MOZ_GTK_WINDOW; - break; -- case NS_THEME_GTK_INFO_BAR: -+ case StyleAppearance::MozGtkInfoBar: - aGtkWidgetType = MOZ_GTK_INFO_BAR; - break; -- case NS_THEME_WINDOW_TITLEBAR: -+ case StyleAppearance::MozWindowTitlebar: - aGtkWidgetType = MOZ_GTK_HEADER_BAR; - break; -- case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED: -+ case StyleAppearance::MozWindowTitlebarMaximized: - aGtkWidgetType = MOZ_GTK_HEADER_BAR_MAXIMIZED; - break; -- case NS_THEME_WINDOW_BUTTON_CLOSE: -+ case StyleAppearance::MozWindowButtonClose: - aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_CLOSE; - break; -- case NS_THEME_WINDOW_BUTTON_MINIMIZE: -+ case StyleAppearance::MozWindowButtonMinimize: - aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE; - break; -- case NS_THEME_WINDOW_BUTTON_MAXIMIZE: -+ case StyleAppearance::MozWindowButtonMaximize: - aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE; - break; -- case NS_THEME_WINDOW_BUTTON_RESTORE: -+ case StyleAppearance::MozWindowButtonRestore: - aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE_RESTORE; - break; - default: -@@ -1025,7 +1040,8 @@ DrawThemeWithCairo(gfxContext* aContext, - } - - bool --nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType, -+nsNativeThemeGTK::GetExtraSizeForWidget(nsIFrame* aFrame, -+ StyleAppearance aWidgetType, - nsIntMargin* aExtra) - { - *aExtra = nsIntMargin(0,0,0,0); -@@ -1033,14 +1049,14 @@ nsNativeThemeGTK::GetExtraSizeForWidget( - // GTK2 themes (Ximian Industrial, Bluecurve, Misty, at least); - // We modify the frame's overflow area. See bug 297508. - switch (aWidgetType) { -- case NS_THEME_SCROLLBARTHUMB_VERTICAL: -+ case StyleAppearance::ScrollbarthumbVertical: - aExtra->top = aExtra->bottom = 1; - break; -- case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: -+ case StyleAppearance::ScrollbarthumbHorizontal: - aExtra->left = aExtra->right = 1; - break; - -- case NS_THEME_BUTTON : -+ case StyleAppearance::Button : - { - if (IsDefaultButton(aFrame)) { - // Some themes draw a default indicator outside the widget, -@@ -1055,14 +1071,14 @@ nsNativeThemeGTK::GetExtraSizeForWidget( - } - return false; - } -- case NS_THEME_FOCUS_OUTLINE: -+ case StyleAppearance::FocusOutline: - { - moz_gtk_get_focus_outline_size(&aExtra->left, &aExtra->top); - aExtra->right = aExtra->left; - aExtra->bottom = aExtra->top; - break; - } -- case NS_THEME_TAB : -+ case StyleAppearance::Tab : - { - if (!IsSelectedTab(aFrame)) - return false; -@@ -1097,7 +1113,7 @@ nsNativeThemeGTK::GetExtraSizeForWidget( - NS_IMETHODIMP - nsNativeThemeGTK::DrawWidgetBackground(gfxContext* aContext, - nsIFrame* aFrame, -- uint8_t aWidgetType, -+ StyleAppearance aWidgetType, - const nsRect& aRect, - const nsRect& aDirtyRect) - { -@@ -1191,8 +1207,8 @@ nsNativeThemeGTK::DrawWidgetBackground(g - #ifdef DEBUG - printf("GTK theme failed for widget type %d, error was %d, state was " - "[active=%d,focused=%d,inHover=%d,disabled=%d]\n", -- aWidgetType, gLastGdkError, state.active, state.focused, -- state.inHover, state.disabled); -+ static_cast(aWidgetType), gLastGdkError, state.active, -+ state.focused, state.inHover, state.disabled); - #endif - NS_WARNING("GTK theme failed; disabling unsafe widget"); - SetWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType); -@@ -1221,16 +1237,16 @@ nsNativeThemeGTK::CreateWebRenderCommand - const mozilla::layers::StackingContextHelper& aSc, - mozilla::layers::WebRenderLayerManager* aManager, - nsIFrame* aFrame, -- uint8_t aWidgetType, -+ StyleAppearance aWidgetType, - const nsRect& aRect) - { - nsPresContext* presContext = aFrame->PresContext(); -- wr::LayoutRect bounds = aSc.ToRelativeLayoutRect( -+ wr::LayoutRect bounds = wr::ToRoundedLayoutRect( - LayoutDeviceRect::FromAppUnits(aRect, presContext->AppUnitsPerDevPixel())); - - switch (aWidgetType) { -- case NS_THEME_WINDOW: -- case NS_THEME_DIALOG: -+ case StyleAppearance::Window: -+ case StyleAppearance::Dialog: - aBuilder.PushRect(bounds, bounds, true, - wr::ToColorF(Color::FromABGR( - LookAndFeel::GetColor(LookAndFeel::eColorID_WindowBackground, -@@ -1243,7 +1259,7 @@ nsNativeThemeGTK::CreateWebRenderCommand - } - - WidgetNodeType --nsNativeThemeGTK::NativeThemeToGtkTheme(uint8_t aWidgetType, nsIFrame* aFrame) -+nsNativeThemeGTK::NativeThemeToGtkTheme(StyleAppearance aWidgetType, nsIFrame* aFrame) - { - WidgetNodeType gtkWidgetType; - gint unusedFlags; -@@ -1258,9 +1274,10 @@ nsNativeThemeGTK::NativeThemeToGtkTheme( - } - - void --nsNativeThemeGTK::GetCachedWidgetBorder(nsIFrame* aFrame, uint8_t aWidgetType, -+nsNativeThemeGTK::GetCachedWidgetBorder(nsIFrame* aFrame, -+ StyleAppearance aWidgetType, - GtkTextDirection aDirection, -- nsIntMargin* aResult) -+ LayoutDeviceIntMargin* aResult) - { - aResult->SizeTo(0, 0, 0, 0); - -@@ -1277,7 +1294,7 @@ nsNativeThemeGTK::GetCachedWidgetBorder( - } else { - moz_gtk_get_widget_border(gtkWidgetType, &aResult->left, &aResult->top, - &aResult->right, &aResult->bottom, aDirection); -- if (aWidgetType != MOZ_GTK_DROPDOWN) { // depends on aDirection -+ if (gtkWidgetType != MOZ_GTK_DROPDOWN) { // depends on aDirection - mBorderCacheValid[cacheIndex] |= cacheBit; - mBorderCache[gtkWidgetType] = *aResult; - } -@@ -1285,49 +1302,52 @@ nsNativeThemeGTK::GetCachedWidgetBorder( - } - } - --NS_IMETHODIMP --nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, -- uint8_t aWidgetType, nsIntMargin* aResult) -+LayoutDeviceIntMargin -+nsNativeThemeGTK::GetWidgetBorder(nsDeviceContext* aContext, -+ nsIFrame* aFrame, -+ StyleAppearance aWidgetType) - { -+ LayoutDeviceIntMargin result; - GtkTextDirection direction = GetTextDirection(aFrame); -- aResult->top = aResult->left = aResult->right = aResult->bottom = 0; - switch (aWidgetType) { -- case NS_THEME_SCROLLBAR_HORIZONTAL: -- case NS_THEME_SCROLLBAR_VERTICAL: -+ case StyleAppearance::ScrollbarHorizontal: -+ case StyleAppearance::ScrollbarVertical: - { - GtkOrientation orientation = -- aWidgetType == NS_THEME_SCROLLBAR_HORIZONTAL ? -+ aWidgetType == StyleAppearance::ScrollbarHorizontal ? - GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; -- const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation, true); -+ const ScrollbarGTKMetrics* metrics = -+ GetActiveScrollbarMetrics(orientation); - - const GtkBorder& border = metrics->border.scrollbar; -- aResult->top = border.top; -- aResult->right = border.right; -- aResult->bottom = border.bottom; -- aResult->left = border.left; -+ result.top = border.top; -+ result.right = border.right; -+ result.bottom = border.bottom; -+ result.left = border.left; - } - break; -- case NS_THEME_SCROLLBARTRACK_HORIZONTAL: -- case NS_THEME_SCROLLBARTRACK_VERTICAL: -+ case StyleAppearance::ScrollbartrackHorizontal: -+ case StyleAppearance::ScrollbartrackVertical: - { - GtkOrientation orientation = -- aWidgetType == NS_THEME_SCROLLBARTRACK_HORIZONTAL ? -+ aWidgetType == StyleAppearance::ScrollbartrackHorizontal ? - GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; -- const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation, true); -+ const ScrollbarGTKMetrics* metrics = -+ GetActiveScrollbarMetrics(orientation); - - const GtkBorder& border = metrics->border.track; -- aResult->top = border.top; -- aResult->right = border.right; -- aResult->bottom = border.bottom; -- aResult->left = border.left; -+ result.top = border.top; -+ result.right = border.right; -+ result.bottom = border.bottom; -+ result.left = border.left; - } - break; -- case NS_THEME_TOOLBOX: -+ case StyleAppearance::Toolbox: - // gtk has no toolbox equivalent. So, although we map toolbox to - // gtk's 'toolbar' for purposes of painting the widget background, - // we don't use the toolbar border for toolbox. - break; -- case NS_THEME_DUALBUTTON: -+ case StyleAppearance::Dualbutton: - // TOOLBAR_DUAL_BUTTON is an interesting case. We want a border to draw - // around the entire button + dropdown, and also an inner border if you're - // over the button part. But, we want the inner button to be right up -@@ -1335,23 +1355,23 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi - // To make this happen, we draw a button border for the outer button, - // but don't reserve any space for it. - break; -- case NS_THEME_TAB: -+ case StyleAppearance::Tab: - { - WidgetNodeType gtkWidgetType; - gint flags; - - if (!GetGtkWidgetAndState(aWidgetType, aFrame, gtkWidgetType, nullptr, -- &flags)) -- return NS_OK; -- -- moz_gtk_get_tab_border(&aResult->left, &aResult->top, -- &aResult->right, &aResult->bottom, direction, -+ &flags)) { -+ return result; -+ } -+ moz_gtk_get_tab_border(&result.left, &result.top, -+ &result.right, &result.bottom, direction, - (GtkTabFlags)flags, gtkWidgetType); - } - break; -- case NS_THEME_MENUITEM: -- case NS_THEME_CHECKMENUITEM: -- case NS_THEME_RADIOMENUITEM: -+ case StyleAppearance::Menuitem: -+ case StyleAppearance::Checkmenuitem: -+ case StyleAppearance::Radiomenuitem: - // For regular menuitems, we will be using GetWidgetPadding instead of - // GetWidgetBorder to pad up the widget's internals; other menuitems - // will need to fall through and use the default case as before. -@@ -1360,50 +1380,57 @@ nsNativeThemeGTK::GetWidgetBorder(nsDevi - MOZ_FALLTHROUGH; - default: - { -- GetCachedWidgetBorder(aFrame, aWidgetType, direction, aResult); -+ GetCachedWidgetBorder(aFrame, aWidgetType, direction, &result); - } - } - - gint scale = GetMonitorScaleFactor(aFrame); -- aResult->top *= scale; -- aResult->right *= scale; -- aResult->bottom *= scale; -- aResult->left *= scale; -- return NS_OK; -+ result.top *= scale; -+ result.right *= scale; -+ result.bottom *= scale; -+ result.left *= scale; -+ return result; - } - - bool - nsNativeThemeGTK::GetWidgetPadding(nsDeviceContext* aContext, -- nsIFrame* aFrame, uint8_t aWidgetType, -- nsIntMargin* aResult) --{ -+ nsIFrame* aFrame, -+ StyleAppearance aWidgetType, -+ LayoutDeviceIntMargin* aResult) -+{ -+ if (aWidgetType == StyleAppearance::MenulistButton && -+ StaticPrefs::layout_css_webkit_appearance_enabled()) { -+ aWidgetType = StyleAppearance::Menulist; -+ } -+ - switch (aWidgetType) { -- case NS_THEME_BUTTON_FOCUS: -- case NS_THEME_TOOLBARBUTTON: -- case NS_THEME_WINDOW_BUTTON_CLOSE: -- case NS_THEME_WINDOW_BUTTON_MINIMIZE: -- case NS_THEME_WINDOW_BUTTON_MAXIMIZE: -- case NS_THEME_WINDOW_BUTTON_RESTORE: -- case NS_THEME_DUALBUTTON: -- case NS_THEME_TAB_SCROLL_ARROW_BACK: -- case NS_THEME_TAB_SCROLL_ARROW_FORWARD: -- case NS_THEME_MENULIST_BUTTON: -- case NS_THEME_TOOLBARBUTTON_DROPDOWN: -- case NS_THEME_BUTTON_ARROW_UP: -- case NS_THEME_BUTTON_ARROW_DOWN: -- case NS_THEME_BUTTON_ARROW_NEXT: -- case NS_THEME_BUTTON_ARROW_PREVIOUS: -- case NS_THEME_RANGE_THUMB: -+ case StyleAppearance::ButtonFocus: -+ case StyleAppearance::Toolbarbutton: -+ case StyleAppearance::MozWindowButtonClose: -+ case StyleAppearance::MozWindowButtonMinimize: -+ case StyleAppearance::MozWindowButtonMaximize: -+ case StyleAppearance::MozWindowButtonRestore: -+ case StyleAppearance::Dualbutton: -+ case StyleAppearance::TabScrollArrowBack: -+ case StyleAppearance::TabScrollArrowForward: -+ case StyleAppearance::MenulistButton: -+ case StyleAppearance::MozMenulistButton: -+ case StyleAppearance::ToolbarbuttonDropdown: -+ case StyleAppearance::ButtonArrowUp: -+ case StyleAppearance::ButtonArrowDown: -+ case StyleAppearance::ButtonArrowNext: -+ case StyleAppearance::ButtonArrowPrevious: -+ case StyleAppearance::RangeThumb: - // Radios and checkboxes return a fixed size in GetMinimumWidgetSize - // and have a meaningful baseline, so they can't have - // author-specified padding. -- case NS_THEME_CHECKBOX: -- case NS_THEME_RADIO: -+ case StyleAppearance::Checkbox: -+ case StyleAppearance::Radio: - aResult->SizeTo(0, 0, 0, 0); - return true; -- case NS_THEME_MENUITEM: -- case NS_THEME_CHECKMENUITEM: -- case NS_THEME_RADIOMENUITEM: -+ case StyleAppearance::Menuitem: -+ case StyleAppearance::Checkmenuitem: -+ case StyleAppearance::Radiomenuitem: - { - // Menubar and menulist have their padding specified in CSS. - if (!IsRegularMenuItem(aFrame)) -@@ -1413,8 +1440,7 @@ nsNativeThemeGTK::GetWidgetPadding(nsDev - aResult); - - gint horizontal_padding; -- -- if (aWidgetType == NS_THEME_MENUITEM) -+ if (aWidgetType == StyleAppearance::Menuitem) - moz_gtk_menuitem_get_horizontal_padding(&horizontal_padding); - else - moz_gtk_checkmenuitem_get_horizontal_padding(&horizontal_padding); -@@ -1430,6 +1456,8 @@ nsNativeThemeGTK::GetWidgetPadding(nsDev - - return true; - } -+ default: -+ break; - } - - return false; -@@ -1437,7 +1465,8 @@ nsNativeThemeGTK::GetWidgetPadding(nsDev - - bool - nsNativeThemeGTK::GetWidgetOverflow(nsDeviceContext* aContext, -- nsIFrame* aFrame, uint8_t aWidgetType, -+ nsIFrame* aFrame, -+ StyleAppearance aWidgetType, - nsRect* aOverflowRect) - { - nsIntMargin extraSize; -@@ -1456,37 +1485,43 @@ nsNativeThemeGTK::GetWidgetOverflow(nsDe - - NS_IMETHODIMP - nsNativeThemeGTK::GetMinimumWidgetSize(nsPresContext* aPresContext, -- nsIFrame* aFrame, uint8_t aWidgetType, -+ nsIFrame* aFrame, -+ StyleAppearance aWidgetType, - LayoutDeviceIntSize* aResult, - bool* aIsOverridable) - { - aResult->width = aResult->height = 0; - *aIsOverridable = true; - -+ if (aWidgetType == StyleAppearance::MenulistButton && -+ StaticPrefs::layout_css_webkit_appearance_enabled()) { -+ aWidgetType = StyleAppearance::Menulist; -+ } -+ - switch (aWidgetType) { -- case NS_THEME_SCROLLBARBUTTON_UP: -- case NS_THEME_SCROLLBARBUTTON_DOWN: -+ case StyleAppearance::ScrollbarbuttonUp: -+ case StyleAppearance::ScrollbarbuttonDown: - { - const ScrollbarGTKMetrics* metrics = -- GetScrollbarMetrics(GTK_ORIENTATION_VERTICAL, true); -+ GetActiveScrollbarMetrics(GTK_ORIENTATION_VERTICAL); - - aResult->width = metrics->size.button.width; - aResult->height = metrics->size.button.height; - *aIsOverridable = false; - } - break; -- case NS_THEME_SCROLLBARBUTTON_LEFT: -- case NS_THEME_SCROLLBARBUTTON_RIGHT: -+ case StyleAppearance::ScrollbarbuttonLeft: -+ case StyleAppearance::ScrollbarbuttonRight: - { - const ScrollbarGTKMetrics* metrics = -- GetScrollbarMetrics(GTK_ORIENTATION_HORIZONTAL, true); -+ GetActiveScrollbarMetrics(GTK_ORIENTATION_HORIZONTAL); - - aResult->width = metrics->size.button.width; - aResult->height = metrics->size.button.height; - *aIsOverridable = false; - } - break; -- case NS_THEME_SPLITTER: -+ case StyleAppearance::Splitter: - { - gint metrics; - if (IsHorizontal(aFrame)) { -@@ -1501,8 +1536,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - *aIsOverridable = false; - } - break; -- case NS_THEME_SCROLLBAR_HORIZONTAL: -- case NS_THEME_SCROLLBAR_VERTICAL: -+ case StyleAppearance::ScrollbarHorizontal: -+ case StyleAppearance::ScrollbarVertical: - { - /* While we enforce a minimum size for the thumb, this is ignored - * for the some scrollbars if buttons are hidden (bug 513006) because -@@ -1510,28 +1545,30 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - * or track. So add a minimum size to the track as well to prevent a - * 0-width scrollbar. */ - GtkOrientation orientation = -- aWidgetType == NS_THEME_SCROLLBAR_HORIZONTAL ? -+ aWidgetType == StyleAppearance::ScrollbarHorizontal ? - GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; -- const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation, true); -+ const ScrollbarGTKMetrics* metrics = -+ GetActiveScrollbarMetrics(orientation); - - aResult->width = metrics->size.scrollbar.width; - aResult->height = metrics->size.scrollbar.height; - } - break; -- case NS_THEME_SCROLLBARTHUMB_VERTICAL: -- case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: -+ case StyleAppearance::ScrollbarthumbVertical: -+ case StyleAppearance::ScrollbarthumbHorizontal: - { - GtkOrientation orientation = -- aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL ? -+ aWidgetType == StyleAppearance::ScrollbarthumbHorizontal ? - GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL; -- const ScrollbarGTKMetrics* metrics = GetScrollbarMetrics(orientation, true); -+ const ScrollbarGTKMetrics* metrics = -+ GetActiveScrollbarMetrics(orientation); - - aResult->width = metrics->size.thumb.width; - aResult->height = metrics->size.thumb.height; - *aIsOverridable = false; - } - break; -- case NS_THEME_RANGE_THUMB: -+ case StyleAppearance::RangeThumb: - { - gint thumb_length, thumb_height; - -@@ -1546,7 +1583,7 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - *aIsOverridable = false; - } - break; -- case NS_THEME_RANGE: -+ case StyleAppearance::Range: - { - gint scale_width, scale_height; - -@@ -1559,12 +1596,12 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - *aIsOverridable = true; - } - break; -- case NS_THEME_SCALETHUMB_HORIZONTAL: -- case NS_THEME_SCALETHUMB_VERTICAL: -+ case StyleAppearance::ScalethumbHorizontal: -+ case StyleAppearance::ScalethumbVertical: - { - gint thumb_length, thumb_height; - -- if (aWidgetType == NS_THEME_SCALETHUMB_VERTICAL) { -+ if (aWidgetType == StyleAppearance::ScalethumbVertical) { - moz_gtk_get_scalethumb_metrics(GTK_ORIENTATION_VERTICAL, &thumb_length, &thumb_height); - aResult->width = thumb_height; - aResult->height = thumb_length; -@@ -1577,21 +1614,22 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - *aIsOverridable = false; - } - break; -- case NS_THEME_TAB_SCROLL_ARROW_BACK: -- case NS_THEME_TAB_SCROLL_ARROW_FORWARD: -+ case StyleAppearance::TabScrollArrowBack: -+ case StyleAppearance::TabScrollArrowForward: - { - moz_gtk_get_tab_scroll_arrow_size(&aResult->width, &aResult->height); - *aIsOverridable = false; - } - break; -- case NS_THEME_MENULIST_BUTTON: -+ case StyleAppearance::MenulistButton: -+ case StyleAppearance::MozMenulistButton: - { - moz_gtk_get_combo_box_entry_button_size(&aResult->width, - &aResult->height); - *aIsOverridable = false; - } - break; -- case NS_THEME_MENUSEPARATOR: -+ case StyleAppearance::Menuseparator: - { - gint separator_height; - -@@ -1601,26 +1639,26 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - *aIsOverridable = false; - } - break; -- case NS_THEME_CHECKBOX: -- case NS_THEME_RADIO: -+ case StyleAppearance::Checkbox: -+ case StyleAppearance::Radio: - { -- const ToggleGTKMetrics* metrics = GetToggleMetrics(aWidgetType == NS_THEME_RADIO); -+ const ToggleGTKMetrics* metrics = GetToggleMetrics(aWidgetType == StyleAppearance::Radio); - aResult->width = metrics->minSizeWithBorder.width; - aResult->height = metrics->minSizeWithBorder.height; - } - break; -- case NS_THEME_TOOLBARBUTTON_DROPDOWN: -- case NS_THEME_BUTTON_ARROW_UP: -- case NS_THEME_BUTTON_ARROW_DOWN: -- case NS_THEME_BUTTON_ARROW_NEXT: -- case NS_THEME_BUTTON_ARROW_PREVIOUS: -+ case StyleAppearance::ToolbarbuttonDropdown: -+ case StyleAppearance::ButtonArrowUp: -+ case StyleAppearance::ButtonArrowDown: -+ case StyleAppearance::ButtonArrowNext: -+ case StyleAppearance::ButtonArrowPrevious: - { - moz_gtk_get_arrow_size(MOZ_GTK_TOOLBARBUTTON_ARROW, - &aResult->width, &aResult->height); - *aIsOverridable = false; - } - break; -- case NS_THEME_WINDOW_BUTTON_CLOSE: -+ case StyleAppearance::MozWindowButtonClose: - { - const ToolbarButtonGTKMetrics* metrics = - GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_CLOSE); -@@ -1628,7 +1666,7 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - aResult->height = metrics->minSizeWithBorderMargin.height; - break; - } -- case NS_THEME_WINDOW_BUTTON_MINIMIZE: -+ case StyleAppearance::MozWindowButtonMinimize: - { - const ToolbarButtonGTKMetrics* metrics = - GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE); -@@ -1636,8 +1674,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - aResult->height = metrics->minSizeWithBorderMargin.height; - break; - } -- case NS_THEME_WINDOW_BUTTON_MAXIMIZE: -- case NS_THEME_WINDOW_BUTTON_RESTORE: -+ case StyleAppearance::MozWindowButtonMaximize: -+ case StyleAppearance::MozWindowButtonRestore: - { - const ToolbarButtonGTKMetrics* metrics = - GetToolbarButtonMetrics(MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE); -@@ -1645,16 +1683,16 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - aResult->height = metrics->minSizeWithBorderMargin.height; - break; - } -- case NS_THEME_CHECKBOX_CONTAINER: -- case NS_THEME_RADIO_CONTAINER: -- case NS_THEME_CHECKBOX_LABEL: -- case NS_THEME_RADIO_LABEL: -- case NS_THEME_BUTTON: -- case NS_THEME_MENULIST: -- case NS_THEME_TOOLBARBUTTON: -- case NS_THEME_TREEHEADERCELL: -+ case StyleAppearance::CheckboxContainer: -+ case StyleAppearance::RadioContainer: -+ case StyleAppearance::CheckboxLabel: -+ case StyleAppearance::RadioLabel: -+ case StyleAppearance::Button: -+ case StyleAppearance::Menulist: -+ case StyleAppearance::Toolbarbutton: -+ case StyleAppearance::Treeheadercell: - { -- if (aWidgetType == NS_THEME_MENULIST) { -+ if (aWidgetType == StyleAppearance::Menulist) { - // Include the arrow size. - moz_gtk_get_arrow_size(MOZ_GTK_DROPDOWN, - &aResult->width, &aResult->height); -@@ -1663,21 +1701,21 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - // descendants; the value returned here will not be helpful, but the - // box model may consider border and padding with child minimum sizes. - -- nsIntMargin border; -+ LayoutDeviceIntMargin border; - GetCachedWidgetBorder(aFrame, aWidgetType, GetTextDirection(aFrame), &border); - aResult->width += border.left + border.right; - aResult->height += border.top + border.bottom; - } - break; - #ifdef MOZ_WIDGET_GTK -- case NS_THEME_NUMBER_INPUT: -- case NS_THEME_TEXTFIELD: -+ case StyleAppearance::NumberInput: -+ case StyleAppearance::Textfield: - { - moz_gtk_get_entry_min_height(&aResult->height); - } - break; - #endif -- case NS_THEME_SEPARATOR: -+ case StyleAppearance::Separator: - { - gint separator_width; - -@@ -1686,26 +1724,26 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - aResult->width = separator_width; - } - break; -- case NS_THEME_INNER_SPIN_BUTTON: -- case NS_THEME_SPINNER: -+ case StyleAppearance::InnerSpinButton: -+ case StyleAppearance::Spinner: - // hard code these sizes - aResult->width = 14; - aResult->height = 26; - break; -- case NS_THEME_TREEHEADERSORTARROW: -- case NS_THEME_SPINNER_UPBUTTON: -- case NS_THEME_SPINNER_DOWNBUTTON: -+ case StyleAppearance::Treeheadersortarrow: -+ case StyleAppearance::SpinnerUpbutton: -+ case StyleAppearance::SpinnerDownbutton: - // hard code these sizes - aResult->width = 14; - aResult->height = 13; - break; -- case NS_THEME_RESIZER: -+ case StyleAppearance::Resizer: - // same as Windows to make our lives easier - aResult->width = aResult->height = 15; - *aIsOverridable = false; - break; -- case NS_THEME_TREETWISTY: -- case NS_THEME_TREETWISTYOPEN: -+ case StyleAppearance::Treetwisty: -+ case StyleAppearance::Treetwistyopen: - { - gint expander_size; - -@@ -1714,6 +1752,8 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - *aIsOverridable = false; - } - break; -+ default: -+ break; - } - - *aResult = *aResult * GetMonitorScaleFactor(aFrame); -@@ -1722,41 +1762,42 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - } - - NS_IMETHODIMP --nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, -+nsNativeThemeGTK::WidgetStateChanged(nsIFrame* aFrame, -+ StyleAppearance aWidgetType, - nsAtom* aAttribute, bool* aShouldRepaint, - const nsAttrValue* aOldValue) - { - // Some widget types just never change state. -- if (aWidgetType == NS_THEME_TOOLBOX || -- aWidgetType == NS_THEME_TOOLBAR || -- aWidgetType == NS_THEME_STATUSBAR || -- aWidgetType == NS_THEME_STATUSBARPANEL || -- aWidgetType == NS_THEME_RESIZERPANEL || -- aWidgetType == NS_THEME_PROGRESSCHUNK || -- aWidgetType == NS_THEME_PROGRESSCHUNK_VERTICAL || -- aWidgetType == NS_THEME_PROGRESSBAR || -- aWidgetType == NS_THEME_PROGRESSBAR_VERTICAL || -- aWidgetType == NS_THEME_MENUBAR || -- aWidgetType == NS_THEME_MENUPOPUP || -- aWidgetType == NS_THEME_TOOLTIP || -- aWidgetType == NS_THEME_MENUSEPARATOR || -- aWidgetType == NS_THEME_WINDOW || -- aWidgetType == NS_THEME_DIALOG) { -+ if (aWidgetType == StyleAppearance::Toolbox || -+ aWidgetType == StyleAppearance::Toolbar || -+ aWidgetType == StyleAppearance::Statusbar || -+ aWidgetType == StyleAppearance::Statusbarpanel || -+ aWidgetType == StyleAppearance::Resizerpanel || -+ aWidgetType == StyleAppearance::Progresschunk || -+ aWidgetType == StyleAppearance::ProgresschunkVertical || -+ aWidgetType == StyleAppearance::Progressbar || -+ aWidgetType == StyleAppearance::ProgressbarVertical || -+ aWidgetType == StyleAppearance::Menubar || -+ aWidgetType == StyleAppearance::Menupopup || -+ aWidgetType == StyleAppearance::Tooltip || -+ aWidgetType == StyleAppearance::Menuseparator || -+ aWidgetType == StyleAppearance::Window || -+ aWidgetType == StyleAppearance::Dialog) { - *aShouldRepaint = false; - return NS_OK; - } - -- if ((aWidgetType == NS_THEME_SCROLLBARTHUMB_VERTICAL || -- aWidgetType == NS_THEME_SCROLLBARTHUMB_HORIZONTAL) && -+ if ((aWidgetType == StyleAppearance::ScrollbarthumbVertical || -+ aWidgetType == StyleAppearance::ScrollbarthumbHorizontal) && - aAttribute == nsGkAtoms::active) { - *aShouldRepaint = true; - return NS_OK; - } - -- if ((aWidgetType == NS_THEME_SCROLLBARBUTTON_UP || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_DOWN || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_LEFT || -- aWidgetType == NS_THEME_SCROLLBARBUTTON_RIGHT) && -+ if ((aWidgetType == StyleAppearance::ScrollbarbuttonUp || -+ aWidgetType == StyleAppearance::ScrollbarbuttonDown || -+ aWidgetType == StyleAppearance::ScrollbarbuttonLeft || -+ aWidgetType == StyleAppearance::ScrollbarbuttonRight) && - (aAttribute == nsGkAtoms::curpos || - aAttribute == nsGkAtoms::maxpos)) { - // If 'curpos' has changed and we are passed its old value, we can -@@ -1820,120 +1861,135 @@ nsNativeThemeGTK::ThemeChanged() - NS_IMETHODIMP_(bool) - nsNativeThemeGTK::ThemeSupportsWidget(nsPresContext* aPresContext, - nsIFrame* aFrame, -- uint8_t aWidgetType) -+ StyleAppearance aWidgetType) - { - if (IsWidgetTypeDisabled(mDisabledWidgetTypes, aWidgetType)) - return false; - -+ if (IsWidgetScrollbarPart(aWidgetType)) { -+ ComputedStyle* cs = nsLayoutUtils::StyleForScrollbar(aFrame); -+ if (cs->StyleUI()->HasCustomScrollbars() || -+ // We cannot handle thin scrollbar on GTK+ widget directly as well. -+ cs->StyleUIReset()->mScrollbarWidth == StyleScrollbarWidth::Thin) { -+ return false; -+ } -+ } -+ -+ if (aWidgetType == StyleAppearance::MenulistButton && -+ StaticPrefs::layout_css_webkit_appearance_enabled()) { -+ aWidgetType = StyleAppearance::Menulist; -+ } -+ - switch (aWidgetType) { - // Combobox dropdowns don't support native theming in vertical mode. -- case NS_THEME_MENULIST: -- case NS_THEME_MENULIST_TEXT: -- case NS_THEME_MENULIST_TEXTFIELD: -+ case StyleAppearance::Menulist: -+ case StyleAppearance::MenulistText: -+ case StyleAppearance::MenulistTextfield: - if (aFrame && aFrame->GetWritingMode().IsVertical()) { - return false; - } - MOZ_FALLTHROUGH; - -- case NS_THEME_BUTTON: -- case NS_THEME_BUTTON_FOCUS: -- case NS_THEME_RADIO: -- case NS_THEME_CHECKBOX: -- case NS_THEME_TOOLBOX: // N/A -- case NS_THEME_TOOLBAR: -- case NS_THEME_TOOLBARBUTTON: -- case NS_THEME_DUALBUTTON: // so we can override the border with 0 -- case NS_THEME_TOOLBARBUTTON_DROPDOWN: -- case NS_THEME_BUTTON_ARROW_UP: -- case NS_THEME_BUTTON_ARROW_DOWN: -- case NS_THEME_BUTTON_ARROW_NEXT: -- case NS_THEME_BUTTON_ARROW_PREVIOUS: -- case NS_THEME_SEPARATOR: -- case NS_THEME_TOOLBARGRIPPER: -- case NS_THEME_STATUSBAR: -- case NS_THEME_STATUSBARPANEL: -- case NS_THEME_RESIZERPANEL: -- case NS_THEME_RESIZER: -- case NS_THEME_LISTBOX: -- // case NS_THEME_LISTITEM: -- case NS_THEME_TREEVIEW: -- // case NS_THEME_TREEITEM: -- case NS_THEME_TREETWISTY: -- // case NS_THEME_TREELINE: -- // case NS_THEME_TREEHEADER: -- case NS_THEME_TREEHEADERCELL: -- case NS_THEME_TREEHEADERSORTARROW: -- case NS_THEME_TREETWISTYOPEN: -- case NS_THEME_PROGRESSBAR: -- case NS_THEME_PROGRESSCHUNK: -- case NS_THEME_PROGRESSBAR_VERTICAL: -- case NS_THEME_PROGRESSCHUNK_VERTICAL: -- case NS_THEME_TAB: -- // case NS_THEME_TABPANEL: -- case NS_THEME_TABPANELS: -- case NS_THEME_TAB_SCROLL_ARROW_BACK: -- case NS_THEME_TAB_SCROLL_ARROW_FORWARD: -- case NS_THEME_TOOLTIP: -- case NS_THEME_INNER_SPIN_BUTTON: -- case NS_THEME_SPINNER: -- case NS_THEME_SPINNER_UPBUTTON: -- case NS_THEME_SPINNER_DOWNBUTTON: -- case NS_THEME_SPINNER_TEXTFIELD: -- // case NS_THEME_SCROLLBAR: (n/a for gtk) -- // case NS_THEME_SCROLLBAR_SMALL: (n/a for gtk) -- case NS_THEME_SCROLLBARBUTTON_UP: -- case NS_THEME_SCROLLBARBUTTON_DOWN: -- case NS_THEME_SCROLLBARBUTTON_LEFT: -- case NS_THEME_SCROLLBARBUTTON_RIGHT: -- case NS_THEME_SCROLLBAR_HORIZONTAL: -- case NS_THEME_SCROLLBAR_VERTICAL: -- case NS_THEME_SCROLLBARTRACK_HORIZONTAL: -- case NS_THEME_SCROLLBARTRACK_VERTICAL: -- case NS_THEME_SCROLLBARTHUMB_HORIZONTAL: -- case NS_THEME_SCROLLBARTHUMB_VERTICAL: -- case NS_THEME_NUMBER_INPUT: -- case NS_THEME_TEXTFIELD: -- case NS_THEME_TEXTFIELD_MULTILINE: -- case NS_THEME_RANGE: -- case NS_THEME_RANGE_THUMB: -- case NS_THEME_SCALE_HORIZONTAL: -- case NS_THEME_SCALETHUMB_HORIZONTAL: -- case NS_THEME_SCALE_VERTICAL: -- case NS_THEME_SCALETHUMB_VERTICAL: -- // case NS_THEME_SCALETHUMBSTART: -- // case NS_THEME_SCALETHUMBEND: -- // case NS_THEME_SCALETHUMBTICK: -- case NS_THEME_CHECKBOX_CONTAINER: -- case NS_THEME_RADIO_CONTAINER: -- case NS_THEME_CHECKBOX_LABEL: -- case NS_THEME_RADIO_LABEL: -- case NS_THEME_MENUBAR: -- case NS_THEME_MENUPOPUP: -- case NS_THEME_MENUITEM: -- case NS_THEME_MENUARROW: -- case NS_THEME_MENUSEPARATOR: -- case NS_THEME_CHECKMENUITEM: -- case NS_THEME_RADIOMENUITEM: -- case NS_THEME_SPLITTER: -- case NS_THEME_WINDOW: -- case NS_THEME_DIALOG: -+ case StyleAppearance::Button: -+ case StyleAppearance::ButtonFocus: -+ case StyleAppearance::Radio: -+ case StyleAppearance::Checkbox: -+ case StyleAppearance::Toolbox: // N/A -+ case StyleAppearance::Toolbar: -+ case StyleAppearance::Toolbarbutton: -+ case StyleAppearance::Dualbutton: // so we can override the border with 0 -+ case StyleAppearance::ToolbarbuttonDropdown: -+ case StyleAppearance::ButtonArrowUp: -+ case StyleAppearance::ButtonArrowDown: -+ case StyleAppearance::ButtonArrowNext: -+ case StyleAppearance::ButtonArrowPrevious: -+ case StyleAppearance::Separator: -+ case StyleAppearance::Toolbargripper: -+ case StyleAppearance::Statusbar: -+ case StyleAppearance::Statusbarpanel: -+ case StyleAppearance::Resizerpanel: -+ case StyleAppearance::Resizer: -+ case StyleAppearance::Listbox: -+ // case StyleAppearance::Listitem: -+ case StyleAppearance::Treeview: -+ // case StyleAppearance::Treeitem: -+ case StyleAppearance::Treetwisty: -+ // case StyleAppearance::Treeline: -+ // case StyleAppearance::Treeheader: -+ case StyleAppearance::Treeheadercell: -+ case StyleAppearance::Treeheadersortarrow: -+ case StyleAppearance::Treetwistyopen: -+ case StyleAppearance::Progressbar: -+ case StyleAppearance::Progresschunk: -+ case StyleAppearance::ProgressbarVertical: -+ case StyleAppearance::ProgresschunkVertical: -+ case StyleAppearance::Tab: -+ // case StyleAppearance::Tabpanel: -+ case StyleAppearance::Tabpanels: -+ case StyleAppearance::TabScrollArrowBack: -+ case StyleAppearance::TabScrollArrowForward: -+ case StyleAppearance::Tooltip: -+ case StyleAppearance::InnerSpinButton: -+ case StyleAppearance::Spinner: -+ case StyleAppearance::SpinnerUpbutton: -+ case StyleAppearance::SpinnerDownbutton: -+ case StyleAppearance::SpinnerTextfield: -+ // case StyleAppearance::Scrollbar: (n/a for gtk) -+ // case StyleAppearance::ScrollbarSmall: (n/a for gtk) -+ case StyleAppearance::ScrollbarbuttonUp: -+ case StyleAppearance::ScrollbarbuttonDown: -+ case StyleAppearance::ScrollbarbuttonLeft: -+ case StyleAppearance::ScrollbarbuttonRight: -+ case StyleAppearance::ScrollbarHorizontal: -+ case StyleAppearance::ScrollbarVertical: -+ case StyleAppearance::ScrollbartrackHorizontal: -+ case StyleAppearance::ScrollbartrackVertical: -+ case StyleAppearance::ScrollbarthumbHorizontal: -+ case StyleAppearance::ScrollbarthumbVertical: -+ case StyleAppearance::NumberInput: -+ case StyleAppearance::Textfield: -+ case StyleAppearance::TextfieldMultiline: -+ case StyleAppearance::Range: -+ case StyleAppearance::RangeThumb: -+ case StyleAppearance::ScaleHorizontal: -+ case StyleAppearance::ScalethumbHorizontal: -+ case StyleAppearance::ScaleVertical: -+ case StyleAppearance::ScalethumbVertical: -+ // case StyleAppearance::Scalethumbstart: -+ // case StyleAppearance::Scalethumbend: -+ // case StyleAppearance::Scalethumbtick: -+ case StyleAppearance::CheckboxContainer: -+ case StyleAppearance::RadioContainer: -+ case StyleAppearance::CheckboxLabel: -+ case StyleAppearance::RadioLabel: -+ case StyleAppearance::Menubar: -+ case StyleAppearance::Menupopup: -+ case StyleAppearance::Menuitem: -+ case StyleAppearance::Menuarrow: -+ case StyleAppearance::Menuseparator: -+ case StyleAppearance::Checkmenuitem: -+ case StyleAppearance::Radiomenuitem: -+ case StyleAppearance::Splitter: -+ case StyleAppearance::Window: -+ case StyleAppearance::Dialog: - #ifdef MOZ_WIDGET_GTK -- case NS_THEME_GTK_INFO_BAR: -+ case StyleAppearance::MozGtkInfoBar: - #endif - return !IsWidgetStyled(aPresContext, aFrame, aWidgetType); - -- case NS_THEME_WINDOW_BUTTON_CLOSE: -- case NS_THEME_WINDOW_BUTTON_MINIMIZE: -- case NS_THEME_WINDOW_BUTTON_MAXIMIZE: -- case NS_THEME_WINDOW_BUTTON_RESTORE: -- case NS_THEME_WINDOW_TITLEBAR: -- case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED: -+ case StyleAppearance::MozWindowButtonClose: -+ case StyleAppearance::MozWindowButtonMinimize: -+ case StyleAppearance::MozWindowButtonMaximize: -+ case StyleAppearance::MozWindowButtonRestore: -+ case StyleAppearance::MozWindowTitlebar: -+ case StyleAppearance::MozWindowTitlebarMaximized: - // GtkHeaderBar is available on GTK 3.10+, which is used for styling - // title bars and title buttons. - return gtk_check_version(3, 10, 0) == nullptr && - !IsWidgetStyled(aPresContext, aFrame, aWidgetType); - -- case NS_THEME_MENULIST_BUTTON: -+ case StyleAppearance::MenulistButton: -+ case StyleAppearance::MozMenulistButton: - if (aFrame && aFrame->GetWritingMode().IsVertical()) { - return false; - } -@@ -1942,37 +1998,50 @@ nsNativeThemeGTK::ThemeSupportsWidget(ns - return (!aFrame || IsFrameContentNodeInNamespace(aFrame, kNameSpaceID_XUL)) && - !IsWidgetStyled(aPresContext, aFrame, aWidgetType); - -- case NS_THEME_FOCUS_OUTLINE: -+ case StyleAppearance::FocusOutline: - return true; -+ default: -+ break; - } - - return false; - } - - NS_IMETHODIMP_(bool) --nsNativeThemeGTK::WidgetIsContainer(uint8_t aWidgetType) -+nsNativeThemeGTK::WidgetIsContainer(StyleAppearance aWidgetType) - { -+ if (aWidgetType == StyleAppearance::MenulistButton && -+ StaticPrefs::layout_css_webkit_appearance_enabled()) { -+ aWidgetType = StyleAppearance::Menulist; -+ } -+ - // XXXdwh At some point flesh all of this out. -- if (aWidgetType == NS_THEME_MENULIST_BUTTON || -- aWidgetType == NS_THEME_RADIO || -- aWidgetType == NS_THEME_RANGE_THUMB || -- aWidgetType == NS_THEME_CHECKBOX || -- aWidgetType == NS_THEME_TAB_SCROLL_ARROW_BACK || -- aWidgetType == NS_THEME_TAB_SCROLL_ARROW_FORWARD || -- aWidgetType == NS_THEME_BUTTON_ARROW_UP || -- aWidgetType == NS_THEME_BUTTON_ARROW_DOWN || -- aWidgetType == NS_THEME_BUTTON_ARROW_NEXT || -- aWidgetType == NS_THEME_BUTTON_ARROW_PREVIOUS) -+ if (aWidgetType == StyleAppearance::MenulistButton || -+ aWidgetType == StyleAppearance::MozMenulistButton || -+ aWidgetType == StyleAppearance::Radio || -+ aWidgetType == StyleAppearance::RangeThumb || -+ aWidgetType == StyleAppearance::Checkbox || -+ aWidgetType == StyleAppearance::TabScrollArrowBack || -+ aWidgetType == StyleAppearance::TabScrollArrowForward || -+ aWidgetType == StyleAppearance::ButtonArrowUp || -+ aWidgetType == StyleAppearance::ButtonArrowDown || -+ aWidgetType == StyleAppearance::ButtonArrowNext || -+ aWidgetType == StyleAppearance::ButtonArrowPrevious) - return false; - return true; - } - - bool --nsNativeThemeGTK::ThemeDrawsFocusForWidget(uint8_t aWidgetType) -+nsNativeThemeGTK::ThemeDrawsFocusForWidget(StyleAppearance aWidgetType) - { -- if (aWidgetType == NS_THEME_MENULIST || -- aWidgetType == NS_THEME_BUTTON || -- aWidgetType == NS_THEME_TREEHEADERCELL) -+ if (aWidgetType == StyleAppearance::MenulistButton && -+ StaticPrefs::layout_css_webkit_appearance_enabled()) { -+ aWidgetType = StyleAppearance::Menulist; -+ } -+ -+ if (aWidgetType == StyleAppearance::Menulist || -+ aWidgetType == StyleAppearance::Button || -+ aWidgetType == StyleAppearance::Treeheadercell) - return true; - - return false; -@@ -1985,16 +2054,17 @@ nsNativeThemeGTK::ThemeNeedsComboboxDrop - } - - nsITheme::Transparency --nsNativeThemeGTK::GetWidgetTransparency(nsIFrame* aFrame, uint8_t aWidgetType) -+nsNativeThemeGTK::GetWidgetTransparency(nsIFrame* aFrame, -+ StyleAppearance aWidgetType) - { - switch (aWidgetType) { - // These widgets always draw a default background. -- case NS_THEME_MENUPOPUP: -- case NS_THEME_WINDOW: -- case NS_THEME_DIALOG: -+ case StyleAppearance::Menupopup: -+ case StyleAppearance::Window: -+ case StyleAppearance::Dialog: - return eOpaque; -- case NS_THEME_SCROLLBAR_VERTICAL: -- case NS_THEME_SCROLLBAR_HORIZONTAL: -+ case StyleAppearance::ScrollbarVertical: -+ case StyleAppearance::ScrollbarHorizontal: - #ifdef MOZ_WIDGET_GTK - // Make scrollbar tracks opaque on the window's scroll frame to prevent - // leaf layers from overlapping. See bug 1179780. -@@ -2006,9 +2076,10 @@ nsNativeThemeGTK::GetWidgetTransparency( - return eOpaque; - // Tooltips use gtk_paint_flat_box() on Gtk2 - // but are shaped on Gtk3 -- case NS_THEME_TOOLTIP: -+ case StyleAppearance::Tooltip: - return eTransparent; -+ default: -+ return eUnknownTransparency; - } - -- return eUnknownTransparency; - } -diff -up thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.h.wayland thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.h ---- thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.h.wayland 2018-10-30 12:45:37.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsNativeThemeGTK.h 2018-11-20 12:04:43.739787343 +0100 -@@ -11,7 +11,7 @@ - #include "nsAtom.h" - #include "nsIObserver.h" - #include "nsNativeTheme.h" --#include "nsThemeConstants.h" -+#include "nsStyleConsts.h" - - #include - #include "gtkdrawing.h" -@@ -26,7 +26,7 @@ public: - - // The nsITheme interface. - NS_IMETHOD DrawWidgetBackground(gfxContext* aContext, -- nsIFrame* aFrame, uint8_t aWidgetType, -+ nsIFrame* aFrame, WidgetType aWidgetType, - const nsRect& aRect, - const nsRect& aDirtyRect) override; - -@@ -35,29 +35,29 @@ public: - const mozilla::layers::StackingContextHelper& aSc, - mozilla::layers::WebRenderLayerManager* aManager, - nsIFrame* aFrame, -- uint8_t aWidgetType, -+ WidgetType aWidgetType, - const nsRect& aRect) override; - -- NS_IMETHOD GetWidgetBorder(nsDeviceContext* aContext, nsIFrame* aFrame, -- uint8_t aWidgetType, -- nsIntMargin* aResult) override; -- -- virtual bool GetWidgetPadding(nsDeviceContext* aContext, -- nsIFrame* aFrame, -- uint8_t aWidgetType, -- nsIntMargin* aResult) override; -+ MOZ_MUST_USE LayoutDeviceIntMargin GetWidgetBorder(nsDeviceContext* aContext, -+ nsIFrame* aFrame, -+ WidgetType aWidgetType) override; -+ -+ bool GetWidgetPadding(nsDeviceContext* aContext, -+ nsIFrame* aFrame, -+ WidgetType aWidgetType, -+ LayoutDeviceIntMargin* aResult) override; - - virtual bool GetWidgetOverflow(nsDeviceContext* aContext, - nsIFrame* aFrame, -- uint8_t aWidgetType, -+ WidgetType aWidgetType, - nsRect* aOverflowRect) override; - - NS_IMETHOD GetMinimumWidgetSize(nsPresContext* aPresContext, -- nsIFrame* aFrame, uint8_t aWidgetType, -+ nsIFrame* aFrame, WidgetType aWidgetType, - mozilla::LayoutDeviceIntSize* aResult, - bool* aIsOverridable) override; - -- NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, uint8_t aWidgetType, -+ NS_IMETHOD WidgetStateChanged(nsIFrame* aFrame, WidgetType aWidgetType, - nsAtom* aAttribute, - bool* aShouldRepaint, - const nsAttrValue* aOldValue) override; -@@ -66,16 +66,16 @@ public: - - NS_IMETHOD_(bool) ThemeSupportsWidget(nsPresContext* aPresContext, - nsIFrame* aFrame, -- uint8_t aWidgetType) override; -+ WidgetType aWidgetType) override; - -- NS_IMETHOD_(bool) WidgetIsContainer(uint8_t aWidgetType) override; -+ NS_IMETHOD_(bool) WidgetIsContainer(WidgetType aWidgetType) override; - -- NS_IMETHOD_(bool) ThemeDrawsFocusForWidget(uint8_t aWidgetType) override; -+ NS_IMETHOD_(bool) ThemeDrawsFocusForWidget(WidgetType aWidgetType) override; - - virtual bool ThemeNeedsComboboxDropmarker() override; - - virtual Transparency GetWidgetTransparency(nsIFrame* aFrame, -- uint8_t aWidgetType) override; -+ WidgetType aWidgetType) override; - nsNativeThemeGTK(); - - protected: -@@ -84,26 +84,27 @@ protected: - private: - GtkTextDirection GetTextDirection(nsIFrame* aFrame); - gint GetTabMarginPixels(nsIFrame* aFrame); -- bool GetGtkWidgetAndState(uint8_t aWidgetType, nsIFrame* aFrame, -+ bool GetGtkWidgetAndState(WidgetType aWidgetType, nsIFrame* aFrame, - WidgetNodeType& aGtkWidgetType, - GtkWidgetState* aState, gint* aWidgetFlags); -- bool GetExtraSizeForWidget(nsIFrame* aFrame, uint8_t aWidgetType, -+ bool GetExtraSizeForWidget(nsIFrame* aFrame, WidgetType aWidgetType, - nsIntMargin* aExtra); - - void RefreshWidgetWindow(nsIFrame* aFrame); -- WidgetNodeType NativeThemeToGtkTheme(uint8_t aWidgetType, nsIFrame* aFrame); -+ WidgetNodeType NativeThemeToGtkTheme(WidgetType aWidgetType, nsIFrame* aFrame); - -- uint8_t mDisabledWidgetTypes[(ThemeWidgetType_COUNT + 7) / 8]; -- uint8_t mSafeWidgetStates[ThemeWidgetType_COUNT * 4]; // 32 bits per widget -+ uint8_t mDisabledWidgetTypes[(static_cast(mozilla::StyleAppearance::Count) + 7) / 8]; -+ uint8_t mSafeWidgetStates[static_cast(mozilla::StyleAppearance::Count) * 4]; // 32 bits per widget - static const char* sDisabledEngines[]; - - // Because moz_gtk_get_widget_border can be slow, we cache its results - // by widget type. Each bit in mBorderCacheValid says whether the - // corresponding entry in mBorderCache is valid. -- void GetCachedWidgetBorder(nsIFrame* aFrame, uint8_t aWidgetType, -- GtkTextDirection aDirection, nsIntMargin* aResult); -+ void GetCachedWidgetBorder(nsIFrame* aFrame, WidgetType aWidgetType, -+ GtkTextDirection aDirection, -+ LayoutDeviceIntMargin* aResult); - uint8_t mBorderCacheValid[(MOZ_GTK_WIDGET_NODE_COUNT + 7) / 8]; -- nsIntMargin mBorderCache[MOZ_GTK_WIDGET_NODE_COUNT]; -+ LayoutDeviceIntMargin mBorderCache[MOZ_GTK_WIDGET_NODE_COUNT]; - }; - #endif diff -up thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp.wayland thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp --- thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp 2018-11-20 12:04:43.739787343 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp 2018-11-21 13:45:42.405091067 +0100 @@ -24,7 +24,20 @@ #include "nsIBaseWindow.h" #include "nsIDocShellTreeItem.h" @@ -6075,7 +1946,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp.wayland thunderbird- NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE); GtkPrintSettings* settings = gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dialog)); -@@ -513,13 +526,522 @@ nsPrintDialogServiceGTK::Init() +@@ -513,13 +526,521 @@ nsPrintDialogServiceGTK::Init() return NS_OK; } @@ -6556,8 +2427,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp.wayland thunderbird- + // Check for the flatpak portal first + nsCOMPtr giovfs = + do_GetService(NS_GIOSERVICE_CONTRACTID); -+ bool shouldUsePortal; -+ giovfs->ShouldUseFlatpakPortal(&shouldUsePortal); ++ bool shouldUsePortal = false; + if (shouldUsePortal && gtk_check_version(3, 22, 0) == nullptr) { + nsCOMPtr widget = WidgetUtils::DOMWindowToWidget(aParent); + NS_ASSERTION(widget, "Need a widget for dialog to be modal."); @@ -6600,7 +2470,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp.wayland thunderbird- nsPrintDialogWidgetGTK printDialog(aParent, aSettings); nsresult rv = printDialog.ImportSettings(aSettings); -@@ -553,8 +1075,8 @@ NS_IMETHODIMP +@@ -553,8 +1074,8 @@ NS_IMETHODIMP nsPrintDialogServiceGTK::ShowPageSetup(nsPIDOMWindowOuter *aParent, nsIPrintSettings *aNSSettings) { @@ -6611,131 +2481,9 @@ diff -up thunderbird-60.3.0/widget/gtk/nsPrintDialogGTK.cpp.wayland thunderbird- NS_ENSURE_TRUE(aNSSettings, NS_ERROR_FAILURE); nsCOMPtr widget = WidgetUtils::DOMWindowToWidget(aParent); -diff -up thunderbird-60.3.0/widget/gtk/nsSound.cpp.wayland thunderbird-60.3.0/widget/gtk/nsSound.cpp ---- thunderbird-60.3.0/widget/gtk/nsSound.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsSound.cpp 2018-11-20 12:04:43.739787343 +0100 -@@ -417,43 +417,3 @@ NS_IMETHODIMP nsSound::PlayEventSound(ui - } - return NS_OK; - } -- --NS_IMETHODIMP nsSound::PlaySystemSound(const nsAString &aSoundAlias) --{ -- if (NS_IsMozAliasSound(aSoundAlias)) { -- NS_WARNING("nsISound::playSystemSound is called with \"_moz_\" events, they are obsolete, use nsISound::playEventSound instead"); -- uint32_t eventId; -- if (aSoundAlias.Equals(NS_SYSSOUND_ALERT_DIALOG)) -- eventId = EVENT_ALERT_DIALOG_OPEN; -- else if (aSoundAlias.Equals(NS_SYSSOUND_CONFIRM_DIALOG)) -- eventId = EVENT_CONFIRM_DIALOG_OPEN; -- else if (aSoundAlias.Equals(NS_SYSSOUND_MAIL_BEEP)) -- eventId = EVENT_NEW_MAIL_RECEIVED; -- else if (aSoundAlias.Equals(NS_SYSSOUND_MENU_EXECUTE)) -- eventId = EVENT_MENU_EXECUTE; -- else if (aSoundAlias.Equals(NS_SYSSOUND_MENU_POPUP)) -- eventId = EVENT_MENU_POPUP; -- else -- return NS_OK; -- return PlayEventSound(eventId); -- } -- -- nsresult rv; -- nsCOMPtr fileURI; -- -- // create a nsIFile and then a nsIFileURL from that -- nsCOMPtr soundFile; -- rv = NS_NewLocalFile(aSoundAlias, true, -- getter_AddRefs(soundFile)); -- NS_ENSURE_SUCCESS(rv,rv); -- -- rv = NS_NewFileURI(getter_AddRefs(fileURI), soundFile); -- NS_ENSURE_SUCCESS(rv,rv); -- -- nsCOMPtr fileURL = do_QueryInterface(fileURI,&rv); -- NS_ENSURE_SUCCESS(rv,rv); -- -- rv = Play(fileURL); -- -- return rv; --} -diff -up thunderbird-60.3.0/widget/gtk/nsWidgetFactory.cpp.wayland thunderbird-60.3.0/widget/gtk/nsWidgetFactory.cpp ---- thunderbird-60.3.0/widget/gtk/nsWidgetFactory.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsWidgetFactory.cpp 2018-11-20 12:04:43.739787343 +0100 -@@ -27,6 +27,7 @@ - #ifdef MOZ_WIDGET_GTK - #include "nsApplicationChooser.h" - #endif -+#include "TaskbarProgress.h" - #include "nsColorPicker.h" - #include "nsFilePicker.h" - #include "nsSound.h" -@@ -60,7 +61,6 @@ - using namespace mozilla; - using namespace mozilla::widget; - --NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow) - NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable) - NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard) - NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter) -@@ -72,6 +72,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR - NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsISound, nsSound::GetInstance) - NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(ScreenManager, ScreenManager::GetAddRefedSingleton) - NS_GENERIC_FACTORY_CONSTRUCTOR(nsImageToPixbuf) -+NS_GENERIC_FACTORY_CONSTRUCTOR(TaskbarProgress) - - - // from nsWindow.cpp -@@ -196,14 +197,13 @@ nsClipboardConstructor(nsISupports *aOut - return inst->QueryInterface(aIID, aResult); - } - --NS_DEFINE_NAMED_CID(NS_WINDOW_CID); --NS_DEFINE_NAMED_CID(NS_CHILD_CID); - NS_DEFINE_NAMED_CID(NS_APPSHELL_CID); - NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID); - NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID); - #ifdef MOZ_WIDGET_GTK - NS_DEFINE_NAMED_CID(NS_APPLICATIONCHOOSER_CID); - #endif -+NS_DEFINE_NAMED_CID(NS_GTK_TASKBARPROGRESS_CID); - NS_DEFINE_NAMED_CID(NS_SOUND_CID); - NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID); - #ifdef MOZ_X11 -@@ -230,14 +230,13 @@ NS_DEFINE_NAMED_CID(NS_GFXINFO_CID); - - - static const mozilla::Module::CIDEntry kWidgetCIDs[] = { -- { &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor }, -- { &kNS_CHILD_CID, false, nullptr, nsWindowConstructor }, - { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor, Module::ALLOW_IN_GPU_PROCESS }, - { &kNS_COLORPICKER_CID, false, nullptr, nsColorPickerConstructor, Module::MAIN_PROCESS_ONLY }, - { &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerConstructor, Module::MAIN_PROCESS_ONLY }, - #ifdef MOZ_WIDGET_GTK - { &kNS_APPLICATIONCHOOSER_CID, false, nullptr, nsApplicationChooserConstructor, Module::MAIN_PROCESS_ONLY }, - #endif -+ { &kNS_GTK_TASKBARPROGRESS_CID, false, nullptr, TaskbarProgressConstructor}, - { &kNS_SOUND_CID, false, nullptr, nsISoundConstructor, Module::MAIN_PROCESS_ONLY }, - { &kNS_TRANSFERABLE_CID, false, nullptr, nsTransferableConstructor }, - #ifdef MOZ_X11 -@@ -266,14 +265,13 @@ static const mozilla::Module::CIDEntry k - }; - - static const mozilla::Module::ContractIDEntry kWidgetContracts[] = { -- { "@mozilla.org/widget/window/gtk;1", &kNS_WINDOW_CID }, -- { "@mozilla.org/widgets/child_window/gtk;1", &kNS_CHILD_CID }, - { "@mozilla.org/widget/appshell/gtk;1", &kNS_APPSHELL_CID, Module::ALLOW_IN_GPU_PROCESS }, - { "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::MAIN_PROCESS_ONLY }, - { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::MAIN_PROCESS_ONLY }, - #ifdef MOZ_WIDGET_GTK - { "@mozilla.org/applicationchooser;1", &kNS_APPLICATIONCHOOSER_CID, Module::MAIN_PROCESS_ONLY }, - #endif -+ { "@mozilla.org/widget/taskbarprogress/gtk;1", &kNS_GTK_TASKBARPROGRESS_CID }, - { "@mozilla.org/sound;1", &kNS_SOUND_CID, Module::MAIN_PROCESS_ONLY }, - { "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID }, - #ifdef MOZ_X11 diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/widget/gtk/nsWindow.cpp --- thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsWindow.cpp 2018-11-20 12:04:43.741787337 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsWindow.cpp 2018-11-21 13:42:00.762025644 +0100 @@ -18,6 +18,7 @@ #include "mozilla/TouchEvents.h" #include "mozilla/UniquePtrExtensions.h" @@ -6832,41 +2580,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w this); nsIRollupListener* rollupListener = nsBaseWidget::GetActiveRollupListener(); -@@ -838,11 +843,48 @@ nsWindow::GetDesktopToDeviceScale() - return DesktopToLayoutDeviceScale(1.0); - } - -+DesktopToLayoutDeviceScale -+nsWindow::GetDesktopToDeviceScaleByScreen() -+{ -+#ifdef MOZ_WAYLAND -+ GdkDisplay* gdkDisplay = gdk_display_get_default(); -+ // In Wayland there's no way to get absolute position of the window and use it to -+ // determine the screen factor of the monitor on which the window is placed. -+ // The window is notified of the current scale factor but not at this point, -+ // so the GdkScaleFactor can return wrong value which can lead to wrong popup -+ // placement. -+ // We need to use parent's window scale factor for the new one. -+ if (GDK_IS_WAYLAND_DISPLAY(gdkDisplay)) { -+ nsView* view = nsView::GetViewFor(this); -+ if (view) { -+ nsView* parentView = view->GetParent(); -+ if (parentView) { -+ nsIWidget* parentWidget = parentView->GetNearestWidget(nullptr); -+ if (parentWidget) { -+ return DesktopToLayoutDeviceScale(parentWidget->RoundsWidgetCoordinatesTo()); -+ } else { -+ NS_WARNING("Widget has no parent"); -+ } -+ } -+ } else { -+ NS_WARNING("Cannot find widget view"); -+ } -+ } -+#endif -+ return nsBaseWidget::GetDesktopToDeviceScale(); -+} -+ +@@ -841,8 +846,14 @@ nsWindow::GetDesktopToDeviceScale() void nsWindow::SetParent(nsIWidget *aNewParent) { @@ -6883,7 +2597,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w return; } -@@ -886,7 +928,7 @@ nsWindow::WidgetTypeSupportsAcceleration +@@ -886,7 +897,7 @@ nsWindow::WidgetTypeSupportsAcceleration void nsWindow::ReparentNativeWidget(nsIWidget* aNewParent) { @@ -6892,7 +2606,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w NS_ASSERTION(!mIsDestroyed, ""); NS_ASSERTION(!static_cast(aNewParent)->mIsDestroyed, ""); -@@ -1517,7 +1559,7 @@ nsWindow::GetClientBounds() +@@ -1517,7 +1528,7 @@ nsWindow::GetClientBounds() void nsWindow::UpdateClientOffset() { @@ -6901,23 +2615,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w if (!mIsTopLevel || !mShell || !mIsX11Display || gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP) { -@@ -1738,6 +1780,15 @@ nsWindow::GetNativeData(uint32_t aDataTy - case NS_NATIVE_COMPOSITOR_DISPLAY: - return gfxPlatformGtk::GetPlatform()->GetCompositorDisplay(); - #endif // MOZ_X11 -+ case NS_NATIVE_EGL_WINDOW: { -+ if (mIsX11Display) -+ return mGdkWindow ? (void*)GDK_WINDOW_XID(mGdkWindow) : nullptr; -+#ifdef MOZ_WAYLAND -+ if (mContainer) -+ return moz_container_get_wl_egl_window(mContainer); -+#endif -+ return nullptr; -+ } - default: - NS_WARNING("nsWindow::GetNativeData called with bad value"); - return nullptr; -@@ -2057,6 +2108,12 @@ nsWindow::OnExposeEvent(cairo_t *cr) +@@ -2057,6 +2068,12 @@ nsWindow::OnExposeEvent(cairo_t *cr) if (!mGdkWindow || mIsFullyObscured || !mHasMappedToplevel) return FALSE; @@ -6930,174 +2628,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w nsIWidgetListener *listener = GetListener(); if (!listener) return FALSE; -@@ -2112,10 +2169,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) - - bool shaped = false; - if (eTransparencyTransparent == GetTransparencyMode()) { -- GdkScreen *screen = gdk_window_get_screen(mGdkWindow); -- if (gdk_screen_is_composited(screen) && -- gdk_window_get_visual(mGdkWindow) == -- gdk_screen_get_rgba_visual(screen)) { -+ if (mHasAlphaVisual) { - // Remove possible shape mask from when window manger was not - // previously compositing. - static_cast(GetTopLevelWidget())-> -@@ -2216,12 +2270,9 @@ nsWindow::OnExposeEvent(cairo_t *cr) - bool painted = false; - { - if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_BASIC) { -- GdkScreen *screen = gdk_window_get_screen(mGdkWindow); - if (GetTransparencyMode() == eTransparencyTransparent && - layerBuffering == BufferMode::BUFFER_NONE && -- gdk_screen_is_composited(screen) && -- gdk_window_get_visual(mGdkWindow) == -- gdk_screen_get_rgba_visual(screen)) { -+ mHasAlphaVisual) { - // If our draw target is unbuffered and we use an alpha channel, - // clear the image beforehand to ensure we don't get artifacts from a - // reused SHM image. See bug 1258086. -@@ -2354,7 +2405,7 @@ nsWindow::OnConfigureEvent(GtkWidget *aW - // - // These windows should not be moved by the window manager, and so any - // change in position is a result of our direction. mBounds has -- // already been set in Move() or Resize(), and that is more -+ // already been set in std::move() or Resize(), and that is more - // up-to-date than the position in the ConfigureNotify event if the - // event is from an earlier window move. - // -@@ -2888,7 +2939,7 @@ nsWindow::OnContainerFocusOutEvent(GdkEv - bool shouldRollup = !dragSession; - if (!shouldRollup) { - // we also roll up when a drag is from a different application -- nsCOMPtr sourceNode; -+ nsCOMPtr sourceNode; - dragSession->GetSourceNode(getter_AddRefs(sourceNode)); - shouldRollup = (sourceNode == nullptr); - } -@@ -2915,8 +2966,8 @@ bool - nsWindow::DispatchCommandEvent(nsAtom* aCommand) - { - nsEventStatus status; -- WidgetCommandEvent event(true, nsGkAtoms::onAppCommand, aCommand, this); -- DispatchEvent(&event, status); -+ WidgetCommandEvent appCommandEvent(true, aCommand, this); -+ DispatchEvent(&appCommandEvent, status); - return TRUE; - } - -@@ -2938,30 +2989,44 @@ IsCtrlAltTab(GdkEventKey *aEvent) - } - - bool --nsWindow::DispatchKeyDownEvent(GdkEventKey *aEvent, bool *aCancelled) -+nsWindow::DispatchKeyDownOrKeyUpEvent(GdkEventKey* aEvent, -+ bool aIsProcessedByIME, -+ bool* aIsCancelled) - { -- NS_PRECONDITION(aCancelled, "aCancelled must not be null"); -+ MOZ_ASSERT(aIsCancelled, "aIsCancelled must not be nullptr"); - -- *aCancelled = false; -+ *aIsCancelled = false; - -- if (IsCtrlAltTab(aEvent)) { -+ if (aEvent->type == GDK_KEY_PRESS && IsCtrlAltTab(aEvent)) { - return false; - } - -+ EventMessage message = -+ aEvent->type == GDK_KEY_PRESS ? eKeyDown : eKeyUp; -+ WidgetKeyboardEvent keyEvent(true, message, this); -+ KeymapWrapper::InitKeyEvent(keyEvent, aEvent, aIsProcessedByIME); -+ return DispatchKeyDownOrKeyUpEvent(keyEvent, aIsCancelled); -+} -+bool -+nsWindow::DispatchKeyDownOrKeyUpEvent(WidgetKeyboardEvent& aKeyboardEvent, -+ bool* aIsCancelled) -+{ -+ MOZ_ASSERT(aIsCancelled, "aIsCancelled must not be nullptr"); -+ -+ *aIsCancelled = false; -+ - RefPtr dispatcher = GetTextEventDispatcher(); - nsresult rv = dispatcher->BeginNativeInputTransaction(); - if (NS_WARN_IF(NS_FAILED(rv))) { - return FALSE; - } - -- WidgetKeyboardEvent keydownEvent(true, eKeyDown, this); -- KeymapWrapper::InitKeyEvent(keydownEvent, aEvent); - nsEventStatus status = nsEventStatus_eIgnore; - bool dispatched = -- dispatcher->DispatchKeyboardEvent(eKeyDown, keydownEvent, -- status, aEvent); -- *aCancelled = (status == nsEventStatus_eConsumeNoDefault); -- return dispatched ? TRUE : FALSE; -+ dispatcher->DispatchKeyboardEvent(aKeyboardEvent.mMessage, -+ aKeyboardEvent, status, nullptr); -+ *aIsCancelled = (status == nsEventStatus_eConsumeNoDefault); -+ return dispatched; - } - - WidgetEventTime -@@ -3046,7 +3111,7 @@ nsWindow::OnKeyPressEvent(GdkEventKey *a - // KEYDOWN -> KEYPRESS -> KEYUP -> KEYDOWN -> KEYPRESS -> KEYUP... - - bool isKeyDownCancelled = false; -- if (DispatchKeyDownEvent(aEvent, &isKeyDownCancelled) && -+ if (DispatchKeyDownOrKeyUpEvent(aEvent, false, &isKeyDownCancelled) && - (MOZ_UNLIKELY(mIsDestroyed) || isKeyDownCancelled)) { - return TRUE; - } -@@ -3095,7 +3160,7 @@ nsWindow::OnKeyPressEvent(GdkEventKey *a - } - - WidgetKeyboardEvent keypressEvent(true, eKeyPress, this); -- KeymapWrapper::InitKeyEvent(keypressEvent, aEvent); -+ KeymapWrapper::InitKeyEvent(keypressEvent, aEvent, false); - - // before we dispatch a key, check if it's the context menu key. - // If so, send a context menu key event instead. -@@ -3179,7 +3244,7 @@ nsWindow::MaybeDispatchContextMenuEvent( - } - - gboolean --nsWindow::OnKeyReleaseEvent(GdkEventKey *aEvent) -+nsWindow::OnKeyReleaseEvent(GdkEventKey* aEvent) - { - LOGFOCUS(("OnKeyReleaseEvent [%p]\n", (void *)this)); - -@@ -3187,17 +3252,11 @@ nsWindow::OnKeyReleaseEvent(GdkEventKey - return TRUE; - } - -- RefPtr dispatcher = GetTextEventDispatcher(); -- nsresult rv = dispatcher->BeginNativeInputTransaction(); -- if (NS_WARN_IF(NS_FAILED(rv))) { -- return false; -+ bool isCancelled = false; -+ if (NS_WARN_IF(!DispatchKeyDownOrKeyUpEvent(aEvent, false, &isCancelled))) { -+ return FALSE; - } - -- WidgetKeyboardEvent keyupEvent(true, eKeyUp, this); -- KeymapWrapper::InitKeyEvent(keyupEvent, aEvent); -- nsEventStatus status = nsEventStatus_eIgnore; -- dispatcher->DispatchKeyboardEvent(eKeyUp, keyupEvent, status, aEvent); -- - return TRUE; - } - -@@ -3214,7 +3273,7 @@ nsWindow::OnScrollEvent(GdkEventScroll * - return; - #endif - WidgetWheelEvent wheelEvent(true, eWheel, this); -- wheelEvent.mDeltaMode = nsIDOMWheelEvent::DOM_DELTA_LINE; -+ wheelEvent.mDeltaMode = dom::WheelEvent_Binding::DOM_DELTA_LINE; - switch (aEvent->direction) { - #if GTK_CHECK_VERSION(3,4,0) - case GDK_SCROLL_SMOOTH: -@@ -3318,6 +3377,33 @@ nsWindow::OnWindowStateEvent(GtkWidget * +@@ -3318,6 +3335,33 @@ nsWindow::OnWindowStateEvent(GtkWidget * } // else the widget is a shell widget. @@ -7131,7 +2662,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w // We don't care about anything but changes in the maximized/icon/fullscreen // states if ((aEvent->changed_mask -@@ -3404,6 +3490,7 @@ nsWindow::OnDPIChanged() +@@ -3404,6 +3448,7 @@ nsWindow::OnDPIChanged() // Update menu's font size etc presShell->ThemeChanged(); } @@ -7139,81 +2670,26 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w } } -@@ -3611,6 +3698,8 @@ nsWindow::Create(nsIWidget* aParent, +@@ -3611,6 +3656,7 @@ nsWindow::Create(nsIWidget* aParent, nsWindow *parentnsWindow = nullptr; GtkWidget *eventWidget = nullptr; bool drawToContainer = false; -+ bool needsAlphaVisual = (mWindowType == eWindowType_popup && -+ aInitData->mSupportTranslucency); ++ bool useAlphaVisual = false; if (aParent) { parentnsWindow = static_cast(aParent); -@@ -3661,23 +3750,47 @@ nsWindow::Create(nsIWidget* aParent, +@@ -3661,8 +3707,8 @@ nsWindow::Create(nsIWidget* aParent, } mShell = gtk_window_new(type); - bool useAlphaVisual = (mWindowType == eWindowType_popup && - aInitData->mSupportTranslucency); -- -- // mozilla.widget.use-argb-visuals is a hidden pref defaulting to false -- // to allow experimentation -- if (Preferences::GetBool("mozilla.widget.use-argb-visuals", false)) -- useAlphaVisual = true; -- -- // We need to select an ARGB visual here instead of in -- // SetTransparencyMode() because it has to be done before the -- // widget is realized. An ARGB visual is only useful if we -- // are on a compositing window manager. -- if (useAlphaVisual) { -- GdkScreen *screen = gtk_widget_get_screen(mShell); -- if (gdk_screen_is_composited(screen)) { -- GdkVisual *visual = gdk_screen_get_rgba_visual(screen); -- gtk_widget_set_visual(mShell, visual); -+#ifdef MOZ_X11 -+ // Ensure gfxPlatform is initialized, since that is what initializes -+ // gfxVars, used below. -+ Unused << gfxPlatform::GetPlatform(); -+ -+ bool useWebRender = gfx::gfxVars::UseWebRender() && -+ AllowWebRenderForThisWindow(); -+ -+ // If using WebRender on X11, we need to select a visual with a depth buffer, -+ // as well as an alpha channel if transparency is requested. This must be done -+ // before the widget is realized. -+ if (mIsX11Display && useWebRender) { -+ auto display = -+ GDK_DISPLAY_XDISPLAY(gtk_widget_get_display(mShell)); -+ auto screen = gtk_widget_get_screen(mShell); -+ int screenNumber = GDK_SCREEN_XNUMBER(screen); -+ int visualId = 0; -+ if (GLContextGLX::FindVisual(display, screenNumber, -+ useWebRender, needsAlphaVisual, -+ &visualId)) { -+ // If we're using CSD, rendering will go through mContainer, but -+ // it will inherit this visual as it is a child of mShell. -+ gtk_widget_set_visual(mShell, -+ gdk_x11_screen_lookup_visual(screen, -+ visualId)); -+ mHasAlphaVisual = needsAlphaVisual; -+ } else { -+ NS_WARNING("We're missing X11 Visual for WebRender!"); -+ } -+ } else -+#endif // MOZ_X11 -+ { -+ if (needsAlphaVisual) { -+ GdkScreen *screen = gtk_widget_get_screen(mShell); -+ if (gdk_screen_is_composited(screen)) { -+ GdkVisual *visual = gdk_screen_get_rgba_visual(screen); -+ if (visual) { -+ gtk_widget_set_visual(mShell, visual); -+ mHasAlphaVisual = true; -+ } -+ } - } - } ++ useAlphaVisual = (mWindowType == eWindowType_popup && ++ aInitData->mSupportTranslucency); -@@ -3784,7 +3897,7 @@ nsWindow::Create(nsIWidget* aParent, + // mozilla.widget.use-argb-visuals is a hidden pref defaulting to false + // to allow experimentation +@@ -3784,7 +3830,7 @@ nsWindow::Create(nsIWidget* aParent, // it explicitly now. gtk_widget_realize(mShell); @@ -7222,7 +2698,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w * * 1) We're running on Gtk+ without client side decorations. * Content is rendered to mShell window and we listen -@@ -3859,17 +3972,7 @@ nsWindow::Create(nsIWidget* aParent, +@@ -3859,17 +3905,7 @@ nsWindow::Create(nsIWidget* aParent, // If the window were to get unredirected, there could be visible // tearing because Gecko does not align its framebuffer updates with // vblank. @@ -7241,7 +2717,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w #endif } break; -@@ -3949,10 +4052,13 @@ nsWindow::Create(nsIWidget* aParent, +@@ -3949,10 +3985,13 @@ nsWindow::Create(nsIWidget* aParent, GtkSettings* default_settings = gtk_settings_get_default(); g_signal_connect_after(default_settings, "notify::gtk-theme-name", @@ -7257,19 +2733,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w } if (mContainer) { -@@ -4070,8 +4176,10 @@ nsWindow::Create(nsIWidget* aParent, - GdkVisual* gdkVisual = gdk_window_get_visual(mGdkWindow); - mXVisual = gdk_x11_visual_get_xvisual(gdkVisual); - mXDepth = gdk_visual_get_depth(gdkVisual); -+ bool shaped = needsAlphaVisual && !mHasAlphaVisual; - -- mSurfaceProvider.Initialize(mXDisplay, mXWindow, mXVisual, mXDepth); -+ mSurfaceProvider.Initialize(mXDisplay, mXWindow, mXVisual, mXDepth, -+ shaped); - } - #ifdef MOZ_WAYLAND - else if (!mIsX11Display) { -@@ -4083,60 +4191,70 @@ nsWindow::Create(nsIWidget* aParent, +@@ -4083,60 +4122,70 @@ nsWindow::Create(nsIWidget* aParent, } void @@ -7384,7 +2848,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w } void -@@ -4162,6 +4280,8 @@ nsWindow::NativeResize() +@@ -4162,6 +4211,8 @@ nsWindow::NativeResize() size.width, size.height)); if (mIsTopLevel) { @@ -7393,7 +2857,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w gtk_window_resize(GTK_WINDOW(mShell), size.width, size.height); } else if (mContainer) { -@@ -4207,6 +4327,8 @@ nsWindow::NativeMoveResize() +@@ -4207,6 +4258,8 @@ nsWindow::NativeMoveResize() NativeShow(false); } NativeMove(); @@ -7402,7 +2866,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w } GdkRectangle size = DevicePixelsToGdkSizeRoundUp(mBounds.Size()); -@@ -4219,6 +4341,8 @@ nsWindow::NativeMoveResize() +@@ -4219,6 +4272,8 @@ 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. @@ -7411,7 +2875,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w gtk_window_resize(GTK_WINDOW(mShell), size.width, size.height); } else if (mContainer) { -@@ -4271,6 +4395,16 @@ nsWindow::NativeShow(bool aAction) +@@ -4271,6 +4326,16 @@ nsWindow::NativeShow(bool aAction) } } else { @@ -7428,7 +2892,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w if (mIsTopLevel) { // Workaround window freezes on GTK versions before 3.21.2 by // ensuring that configure events get dispatched to windows before -@@ -4946,6 +5080,8 @@ FullscreenTransitionWindow::FullscreenTr +@@ -4946,6 +5011,8 @@ FullscreenTransitionWindow::FullscreenTr gdk_screen_get_monitor_geometry(screen, monitorNum, &monitorRect); gtk_window_set_screen(gtkWin, screen); gtk_window_move(gtkWin, monitorRect.x, monitorRect.y); @@ -7437,7 +2901,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w gtk_window_resize(gtkWin, monitorRect.width, monitorRect.height); GdkColor bgColor; -@@ -5951,7 +6087,7 @@ window_state_event_cb (GtkWidget *widget +@@ -5951,7 +6018,7 @@ window_state_event_cb (GtkWidget *widget } static void @@ -7446,7 +2910,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w { RefPtr window = data; window->ThemeChanged(); -@@ -6032,13 +6168,13 @@ nsWindow::InitDragEvent(WidgetDragEvent +@@ -6032,13 +6099,13 @@ nsWindow::InitDragEvent(WidgetDragEvent KeymapWrapper::InitInputEvent(aEvent, modifierState); } @@ -7467,7 +2931,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w { RefPtr window = get_window_for_gtk_widget(aWidget); if (!window) -@@ -6063,15 +6199,24 @@ drag_motion_event_cb(GtkWidget *aWidget, +@@ -6063,15 +6130,24 @@ drag_motion_event_cb(GtkWidget *aWidget, RefPtr dragService = nsDragService::GetInstance(); return dragService-> @@ -7498,7 +2962,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w { RefPtr window = get_window_for_gtk_widget(aWidget); if (!window) -@@ -6104,14 +6249,22 @@ drag_leave_event_cb(GtkWidget *aWidget, +@@ -6104,14 +6180,22 @@ drag_leave_event_cb(GtkWidget *aWidget, dragService->ScheduleLeaveEvent(); } @@ -7528,7 +2992,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w { RefPtr window = get_window_for_gtk_widget(aWidget); if (!window) -@@ -6136,10 +6289,21 @@ drag_drop_event_cb(GtkWidget *aWidget, +@@ -6136,10 +6220,21 @@ drag_drop_event_cb(GtkWidget *aWidget, RefPtr dragService = nsDragService::GetInstance(); return dragService-> @@ -7551,7 +3015,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w static void drag_data_received_event_cb(GtkWidget *aWidget, GdkDragContext *aDragContext, -@@ -6554,12 +6718,6 @@ nsWindow::GetLayerManager(PLayerTransact +@@ -6554,12 +6649,6 @@ nsWindow::GetLayerManager(PLayerTransact return mLayerManager; } @@ -7564,7 +3028,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w return nsBaseWidget::GetLayerManager(aShadowManager, aBackendHint, aPersistence); } -@@ -6601,6 +6759,13 @@ nsWindow::ClearCachedResources() +@@ -6601,6 +6690,13 @@ nsWindow::ClearCachedResources() void nsWindow::UpdateClientOffsetForCSDWindow() { @@ -7578,7 +3042,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w // _NET_FRAME_EXTENTS is not set on client decorated windows, // so we need to read offset between mContainer and toplevel mShell // window. -@@ -6692,6 +6857,15 @@ nsWindow::SetDrawsInTitlebar(bool aState +@@ -6692,6 +6788,15 @@ nsWindow::SetDrawsInTitlebar(bool aState mNeedsShow = true; NativeResize(); @@ -7594,7 +3058,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w // 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. -@@ -6998,6 +7172,8 @@ nsWindow::GetSystemCSDSupportLevel() { +@@ -6998,6 +7103,8 @@ nsWindow::GetSystemCSDSupportLevel() { // KDE Plasma } else if (strstr(currentDesktop, "KDE") != nullptr) { sCSDSupportLevel = CSD_SUPPORT_CLIENT; @@ -7603,7 +3067,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w } else if (strstr(currentDesktop, "LXDE") != nullptr) { sCSDSupportLevel = CSD_SUPPORT_CLIENT; } else if (strstr(currentDesktop, "openbox") != nullptr) { -@@ -7014,6 +7190,8 @@ nsWindow::GetSystemCSDSupportLevel() { +@@ -7014,6 +7121,8 @@ nsWindow::GetSystemCSDSupportLevel() { sCSDSupportLevel = CSD_SUPPORT_SYSTEM; } else if (strstr(currentDesktop, "LXQt") != nullptr) { sCSDSupportLevel = CSD_SUPPORT_SYSTEM; @@ -7612,7 +3076,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w } else { // Release or beta builds are not supposed to be broken // so disable titlebar rendering on untested/unknown systems. -@@ -7066,26 +7244,19 @@ nsWindow::RoundsWidgetCoordinatesTo() +@@ -7066,26 +7175,18 @@ nsWindow::RoundsWidgetCoordinatesTo() void nsWindow::GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData) { @@ -7625,7 +3089,6 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w *aInitData = mozilla::widget::GtkCompositorWidgetInitData( (mXWindow != X11None) ? mXWindow : (uintptr_t)nullptr, mXDisplay ? nsCString(XDisplayString(mXDisplay)) : nsCString(), -+ mIsTransparent && !mHasAlphaVisual, GetClientSize()); } @@ -7646,7 +3109,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w #ifdef MOZ_WAYLAND wl_display* nsWindow::GetWaylandDisplay() -@@ -7110,3 +7281,120 @@ nsWindow::GetWaylandSurface() +@@ -7110,3 +7211,85 @@ nsWindow::GetWaylandSurface() return nullptr; } #endif @@ -7731,45 +3194,10 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.cpp.wayland thunderbird-60.3.0/w +} +#endif + -+nsresult -+nsWindow::SetSystemFont(const nsCString& aFontName) -+{ -+ GtkSettings* settings = gtk_settings_get_default(); -+ g_object_set(settings, "gtk-font-name", aFontName.get(), nullptr); -+ return NS_OK; -+} + -+nsresult -+nsWindow::GetSystemFont(nsCString& aFontName) -+{ -+ GtkSettings* settings = gtk_settings_get_default(); -+ gchar* fontName = nullptr; -+ g_object_get(settings, -+ "gtk-font-name", &fontName, -+ nullptr); -+ if (fontName) { -+ aFontName.Assign(fontName); -+ g_free(fontName); -+ } -+ return NS_OK; -+} -+ -+already_AddRefed -+nsIWidget::CreateTopLevelWindow() -+{ -+ nsCOMPtr window = new nsWindow(); -+ return window.forget(); -+} -+ -+already_AddRefed -+nsIWidget::CreateChildWindow() -+{ -+ nsCOMPtr window = new nsWindow(); -+ return window.forget(); -+} diff -up thunderbird-60.3.0/widget/gtk/nsWindow.h.wayland thunderbird-60.3.0/widget/gtk/nsWindow.h --- thunderbird-60.3.0/widget/gtk/nsWindow.h.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/nsWindow.h 2018-11-20 12:04:43.741787337 +0100 ++++ thunderbird-60.3.0/widget/gtk/nsWindow.h 2018-11-21 13:42:00.762025644 +0100 @@ -66,6 +66,21 @@ extern mozilla::LazyLogModule gWidgetDra #endif /* MOZ_LOGGING */ @@ -7800,15 +3228,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.h.wayland thunderbird-60.3.0/wid typedef mozilla::widget::PlatformCompositorWidgetDelegate PlatformCompositorWidgetDelegate; nsWindow(); -@@ -108,6 +124,7 @@ public: - virtual float GetDPI() override; - virtual double GetDefaultScaleInternal() override; - mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override; -+ mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScaleByScreen() override; - virtual void SetParent(nsIWidget* aNewParent) override; - virtual void SetModal(bool aModal) override; - virtual bool IsVisible() const override; -@@ -115,8 +132,7 @@ public: +@@ -115,8 +131,7 @@ public: int32_t *aX, int32_t *aY) override; virtual void SetSizeConstraints(const SizeConstraints& aConstraints) override; @@ -7818,7 +3238,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.h.wayland thunderbird-60.3.0/wid virtual void Show (bool aState) override; virtual void Resize (double aWidth, double aHeight, -@@ -228,6 +244,8 @@ public: +@@ -228,6 +243,8 @@ public: virtual void EndRemoteDrawingInRegion(mozilla::gfx::DrawTarget* aDrawTarget, LayoutDeviceIntRegion& aInvalidRegion) override; @@ -7827,54 +3247,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.h.wayland thunderbird-60.3.0/wid private: void UpdateAlpha(mozilla::gfx::SourceSurface* aSourceSurface, nsIntRect aBoundsRect); -@@ -278,10 +296,32 @@ public: - guint aTime); - static void UpdateDragStatus (GdkDragContext *aDragContext, - nsIDragService *aDragService); -- // If this dispatched the keydown event actually, this returns TRUE, -- // otherwise, FALSE. -- bool DispatchKeyDownEvent(GdkEventKey *aEvent, -- bool *aIsCancelled); -+ /** -+ * DispatchKeyDownOrKeyUpEvent() dispatches eKeyDown or eKeyUp event. -+ * -+ * @param aEvent A native GDK_KEY_PRESS or GDK_KEY_RELEASE -+ * event. -+ * @param aProcessedByIME true if the event is handled by IME. -+ * @param aIsCancelled [Out] true if the default is prevented. -+ * @return true if eKeyDown event is actually dispatched. -+ * Otherwise, false. -+ */ -+ bool DispatchKeyDownOrKeyUpEvent(GdkEventKey* aEvent, -+ bool aProcessedByIME, -+ bool* aIsCancelled); -+ -+ /** -+ * DispatchKeyDownOrKeyUpEvent() dispatches eKeyDown or eKeyUp event. -+ * -+ * @param aEvent An eKeyDown or eKeyUp event. This will be -+ * dispatched as is. -+ * @param aIsCancelled [Out] true if the default is prevented. -+ * @return true if eKeyDown event is actually dispatched. -+ * Otherwise, false. -+ */ -+ bool DispatchKeyDownOrKeyUpEvent(WidgetKeyboardEvent& aEvent, -+ bool* aIsCancelled); -+ - WidgetEventTime GetWidgetEventTime(guint32 aEventTime); - mozilla::TimeStamp GetEventTimeStamp(guint32 aEventTime); - mozilla::CurrentX11TimeGetter* GetCurrentTimeGetter(); -@@ -375,6 +415,9 @@ public: - - virtual bool WidgetTypeSupportsAcceleration() override; - -+ nsresult SetSystemFont(const nsCString& aFontName) override; -+ nsresult GetSystemFont(nsCString& aFontName) override; -+ - typedef enum { CSD_SUPPORT_SYSTEM, // CSD including shadows - CSD_SUPPORT_CLIENT, // CSD without shadows - CSD_SUPPORT_NONE, // WM does not support CSD at all -@@ -452,13 +495,24 @@ private: +@@ -452,13 +469,24 @@ private: gint* aRootX, gint* aRootY); void ClearCachedResources(); nsIWidgetListener* GetListener(); @@ -7900,7 +3273,7 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.h.wayland thunderbird-60.3.0/wid GtkWidget *mShell; MozContainer *mContainer; GdkWindow *mGdkWindow; -@@ -558,6 +612,9 @@ private: +@@ -558,6 +586,9 @@ private: // full translucency at this time; each pixel is either fully opaque // or fully transparent. gchar* mTransparencyBitmap; @@ -7910,96 +3283,9 @@ diff -up thunderbird-60.3.0/widget/gtk/nsWindow.h.wayland thunderbird-60.3.0/wid // all of our DND stuff void InitDragEvent(mozilla::WidgetDragEvent& aEvent); -diff -up thunderbird-60.3.0/widget/gtk/PlatformWidgetTypes.ipdlh.wayland thunderbird-60.3.0/widget/gtk/PlatformWidgetTypes.ipdlh ---- thunderbird-60.3.0/widget/gtk/PlatformWidgetTypes.ipdlh.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/PlatformWidgetTypes.ipdlh 2018-11-20 12:04:43.741787337 +0100 -@@ -15,6 +15,7 @@ struct GtkCompositorWidgetInitData - { - uintptr_t XWindow; - nsCString XDisplayString; -+ bool Shaped; - - LayoutDeviceIntSize InitialClientSize; - }; -diff -up thunderbird-60.3.0/widget/gtk/ScreenHelperGTK.cpp.wayland thunderbird-60.3.0/widget/gtk/ScreenHelperGTK.cpp ---- thunderbird-60.3.0/widget/gtk/ScreenHelperGTK.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/ScreenHelperGTK.cpp 2018-11-20 12:04:43.741787337 +0100 -@@ -197,7 +197,7 @@ ScreenHelperGTK::RefreshScreens() - } - - ScreenManager& screenManager = ScreenManager::GetSingleton(); -- screenManager.Refresh(Move(screenList)); -+ screenManager.Refresh(std::move(screenList)); - } - - } // namespace widget -diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.cpp.wayland thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.cpp ---- thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.cpp.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.cpp 2018-11-20 12:04:43.741787337 +0100 -@@ -31,6 +31,7 @@ WindowSurfaceProvider::WindowSurfaceProv - #ifdef MOZ_WAYLAND - , mWidget(nullptr) - #endif -+ , mIsShaped(false) - { - } - -@@ -38,7 +39,8 @@ void WindowSurfaceProvider::Initialize( - Display* aDisplay, - Window aWindow, - Visual* aVisual, -- int aDepth) -+ int aDepth, -+ bool aIsShaped) - { - // We should not be initialized - MOZ_ASSERT(!mXDisplay); -@@ -50,6 +52,7 @@ void WindowSurfaceProvider::Initialize( - mXWindow = aWindow; - mXVisual = aVisual; - mXDepth = aDepth; -+ mIsShaped = aIsShaped; - mIsX11Display = true; - } - -@@ -88,21 +91,22 @@ WindowSurfaceProvider::CreateWindowSurfa - // 3. XPutImage - - #ifdef MOZ_WIDGET_GTK -- if (gfxVars::UseXRender()) { -+ if (!mIsShaped && gfxVars::UseXRender()) { - LOGDRAW(("Drawing to nsWindow %p using XRender\n", (void*)this)); - return MakeUnique(mXDisplay, mXWindow, mXVisual, mXDepth); - } - #endif // MOZ_WIDGET_GTK - - #ifdef MOZ_HAVE_SHMIMAGE -- if (nsShmImage::UseShm()) { -+ if (!mIsShaped && nsShmImage::UseShm()) { - LOGDRAW(("Drawing to nsWindow %p using MIT-SHM\n", (void*)this)); - return MakeUnique(mXDisplay, mXWindow, mXVisual, mXDepth); - } - #endif // MOZ_HAVE_SHMIMAGE - - LOGDRAW(("Drawing to nsWindow %p using XPutImage\n", (void*)this)); -- return MakeUnique(mXDisplay, mXWindow, mXVisual, mXDepth); -+ return MakeUnique(mXDisplay, mXWindow, mXVisual, -+ mXDepth, mIsShaped); - } - - already_AddRefed -@@ -125,7 +129,7 @@ WindowSurfaceProvider::StartRemoteDrawin - // We can't use WindowSurfaceX11Image fallback on Wayland but - // Lock() call on WindowSurfaceWayland should never fail. - gfxWarningOnce() << "Failed to lock WindowSurface, falling back to XPutImage backend."; -- mWindowSurface = MakeUnique(mXDisplay, mXWindow, mXVisual, mXDepth); -+ mWindowSurface = MakeUnique(mXDisplay, mXWindow, mXVisual, mXDepth, mIsShaped); - dt = mWindowSurface->Lock(aInvalidRegion); - } - return dt.forget(); diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.h.wayland thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.h --- thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.h.wayland 2018-10-30 12:45:34.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.h 2018-11-20 12:04:43.742787334 +0100 ++++ thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.h 2018-11-21 13:42:00.762025644 +0100 @@ -17,6 +17,7 @@ #include #endif @@ -8008,27 +3294,9 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceProvider.h.wayland thunderbi class nsWindow; -@@ -43,7 +44,8 @@ public: - Display* aDisplay, - Window aWindow, - Visual* aVisual, -- int aDepth); -+ int aDepth, -+ bool aIsShaped); - - #ifdef MOZ_WAYLAND - void Initialize(nsWindow *aWidget); -@@ -75,6 +77,7 @@ private: - #ifdef MOZ_WAYLAND - nsWindow* mWidget; - #endif -+ bool mIsShaped; - }; - - } // namespace widget diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp --- thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp 2018-11-20 12:04:43.742787334 +0100 ++++ thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp 2018-11-21 13:42:00.763025640 +0100 @@ -151,8 +151,9 @@ static nsWaylandDisplay* WaylandDisplayG static void WaylandDisplayRelease(wl_display *aDisplay); static void WaylandDisplayLoop(wl_display *aDisplay); @@ -8072,16 +3340,7 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb return gfxPlatform::CreateDrawTargetForData(static_cast(mShmPool.GetImageData()), lockSize, BUFFER_BPP * mWidth, -@@ -551,6 +551,8 @@ frame_callback_handler(void *data, struc - { - auto surface = reinterpret_cast(data); - surface->FrameCallbackHandler(); -+ -+ gfxPlatformGtk::GetPlatform()->SetWaylandLastVsync(time); - } - - static const struct wl_callback_listener frame_listener = { -@@ -560,26 +562,40 @@ static const struct wl_callback_listener +@@ -560,26 +560,40 @@ static const struct wl_callback_listener WindowSurfaceWayland::WindowSurfaceWayland(nsWindow *aWindow) : mWindow(aWindow) , mWaylandDisplay(WaylandDisplayGet(aWindow->GetWaylandDisplay())) @@ -8129,7 +3388,7 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb 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 -@@ -593,162 +609,309 @@ WindowSurfaceWayland::~WindowSurfaceWayl +@@ -593,162 +607,309 @@ WindowSurfaceWayland::~WindowSurfaceWayl } } @@ -8216,13 +3475,14 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb + WindowBackBuffer* buffer = GetWaylandBufferToDraw(aWidth, aHeight); + if (buffer) { + return buffer->Lock(); -+ } -+ + } + +- return mFrontBuffer; + NS_WARNING("WindowSurfaceWayland::LockWaylandBuffer(): No buffer available"); + return nullptr; -+} -+ -+already_AddRefed + } + + already_AddRefed +WindowSurfaceWayland::LockImageSurface(const gfx::IntSize& aLockSize) +{ + if (!mImageSurface || mImageSurface->CairoStatus() || @@ -8232,15 +3492,14 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb + if (mImageSurface->CairoStatus()) { + return nullptr; + } - } - -- return mFrontBuffer; ++ } ++ + return gfxPlatform::CreateDrawTargetForData(mImageSurface->Data(), + mImageSurface->GetSize(), + mImageSurface->Stride(), + mWaylandDisplay->GetSurfaceFormat()); - } - ++} ++ +/* + There are some situations which can happen here: + @@ -8254,7 +3513,7 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb + 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 ++already_AddRefed WindowSurfaceWayland::Lock(const LayoutDeviceIntRegion& aRegion) { MOZ_ASSERT(mIsMainThread == NS_IsMainThread()); @@ -8287,9 +3546,8 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb + // We don't have any front buffer available. Try indirect drawing + // to mImageSurface which is mirrored to front buffer at commit. + mDrawToWaylandBufferDirectly = false; - } - -- return buffer->Lock(aRegion); ++ } ++ + return LockImageSurface(lockSize); +} + @@ -8314,8 +3572,9 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb + mImageSurface->Format()); + if (!dt || !surf) { + return false; -+ } -+ + } + +- return buffer->Lock(aRegion); + uint32_t numRects = aRegion.GetNumRects(); + if (numRects != 1) { + AutoTArray rects; @@ -8529,7 +3788,7 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.cpp.wayland thunderb diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.h.wayland thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.h --- thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.h.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.h 2018-11-20 12:04:43.742787334 +0100 ++++ thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.h 2018-11-21 13:42:00.763025640 +0100 @@ -8,6 +8,7 @@ #define _MOZILLA_WIDGET_GTK_WINDOW_SURFACE_WAYLAND_H @@ -8594,238 +3853,4 @@ diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceWayland.h.wayland thunderbir + bool mNeedScaleFactorUpdate; }; - } // namespace widget -diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.cpp.wayland thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.cpp ---- thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.cpp.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.cpp 2018-11-20 12:04:43.743787331 +0100 -@@ -12,19 +12,42 @@ - #include "gfxPlatform.h" - #include "gfx2DGlue.h" - -+#include -+ - namespace mozilla { - namespace widget { - -+// gfxImageSurface pixel format configuration. -+#define SHAPED_IMAGE_SURFACE_BPP 4 -+#ifdef IS_BIG_ENDIAN -+ #define SHAPED_IMAGE_SURFACE_ALPHA_INDEX 0 -+#else -+ #define SHAPED_IMAGE_SURFACE_ALPHA_INDEX 3 -+#endif -+ - WindowSurfaceX11Image::WindowSurfaceX11Image(Display* aDisplay, - Window aWindow, - Visual* aVisual, -- unsigned int aDepth) -+ unsigned int aDepth, -+ bool aIsShaped) - : WindowSurfaceX11(aDisplay, aWindow, aVisual, aDepth) -+ , mTransparencyBitmap(nullptr) -+ , mTransparencyBitmapWidth(0) -+ , mTransparencyBitmapHeight(0) -+ , mIsShaped(aIsShaped) - { - } - - WindowSurfaceX11Image::~WindowSurfaceX11Image() - { -+ if (mTransparencyBitmap) { -+ delete[] mTransparencyBitmap; -+ -+ Display* xDisplay = mWindowSurface->XDisplay(); -+ Window xDrawable = mWindowSurface->XDrawable(); -+ -+ XShapeCombineMask(xDisplay, xDrawable, ShapeBounding, 0, 0, X11None, ShapeSet); -+ } - } - - already_AddRefed -@@ -50,6 +73,13 @@ WindowSurfaceX11Image::Lock(const Layout - gfx::SurfaceFormat::X8R8G8B8_UINT32; - } - -+ // Use alpha image format for shaped window as we derive -+ // the shape bitmap from alpha channel. Must match SHAPED_IMAGE_SURFACE_BPP -+ // and SHAPED_IMAGE_SURFACE_ALPHA_INDEX. -+ if (mIsShaped) { -+ format = gfx::SurfaceFormat::A8R8G8B8_UINT32; -+ } -+ - mImageSurface = new gfxImageSurface(size, format); - if (mImageSurface->CairoStatus()) { - return nullptr; -@@ -82,6 +112,132 @@ WindowSurfaceX11Image::Lock(const Layout - ImageFormatToSurfaceFormat(format)); - } - -+// The transparency bitmap routines are derived form the ones at nsWindow.cpp. -+// The difference here is that we compose to RGBA image and then create -+// the shape mask from final image alpha channel. -+static inline int32_t -+GetBitmapStride(int32_t width) -+{ -+ return (width+7)/8; -+} -+ -+static bool -+ChangedMaskBits(gchar* aMaskBits, int32_t aMaskWidth, int32_t aMaskHeight, -+ const nsIntRect& aRect, uint8_t* aImageData) -+{ -+ int32_t stride = aMaskWidth*SHAPED_IMAGE_SURFACE_BPP; -+ int32_t x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); -+ int32_t maskBytesPerRow = GetBitmapStride(aMaskWidth); -+ for (y = aRect.y; y < yMax; y++) { -+ gchar* maskBytes = aMaskBits + y*maskBytesPerRow; -+ uint8_t* alphas = aImageData; -+ for (x = aRect.x; x < xMax; x++) { -+ bool newBit = *(alphas+SHAPED_IMAGE_SURFACE_ALPHA_INDEX) > 0x7f; -+ alphas += SHAPED_IMAGE_SURFACE_BPP; -+ -+ gchar maskByte = maskBytes[x >> 3]; -+ bool maskBit = (maskByte & (1 << (x & 7))) != 0; -+ -+ if (maskBit != newBit) { -+ return true; -+ } -+ } -+ aImageData += stride; -+ } -+ -+ return false; -+} -+ -+static void -+UpdateMaskBits(gchar* aMaskBits, int32_t aMaskWidth, int32_t aMaskHeight, -+ const nsIntRect& aRect, uint8_t* aImageData) -+{ -+ int32_t stride = aMaskWidth*SHAPED_IMAGE_SURFACE_BPP; -+ int32_t x, y, xMax = aRect.XMost(), yMax = aRect.YMost(); -+ int32_t maskBytesPerRow = GetBitmapStride(aMaskWidth); -+ for (y = aRect.y; y < yMax; y++) { -+ gchar* maskBytes = aMaskBits + y*maskBytesPerRow; -+ uint8_t* alphas = aImageData; -+ for (x = aRect.x; x < xMax; x++) { -+ bool newBit = *(alphas+SHAPED_IMAGE_SURFACE_ALPHA_INDEX) > 0x7f; -+ alphas += SHAPED_IMAGE_SURFACE_BPP; -+ -+ gchar mask = 1 << (x & 7); -+ gchar maskByte = maskBytes[x >> 3]; -+ // Note: '-newBit' turns 0 into 00...00 and 1 into 11...11 -+ maskBytes[x >> 3] = (maskByte & ~mask) | (-newBit & mask); -+ } -+ aImageData += stride; -+ } -+} -+ -+void -+WindowSurfaceX11Image::ResizeTransparencyBitmap(int aWidth, int aHeight) -+{ -+ int32_t actualSize = -+ GetBitmapStride(mTransparencyBitmapWidth)*mTransparencyBitmapHeight; -+ int32_t newSize = GetBitmapStride(aWidth)*aHeight; -+ -+ if (actualSize < newSize) { -+ delete[] mTransparencyBitmap; -+ mTransparencyBitmap = new gchar[newSize]; -+ } -+ -+ mTransparencyBitmapWidth = aWidth; -+ mTransparencyBitmapHeight = aHeight; -+} -+ -+void -+WindowSurfaceX11Image::ApplyTransparencyBitmap() -+{ -+ gfx::IntSize size = mWindowSurface->GetSize(); -+ bool maskChanged = true; -+ -+ if (!mTransparencyBitmap) { -+ mTransparencyBitmapWidth = size.width; -+ mTransparencyBitmapHeight = size.height; -+ -+ int32_t byteSize = -+ GetBitmapStride(mTransparencyBitmapWidth)*mTransparencyBitmapHeight; -+ mTransparencyBitmap = new gchar[byteSize]; -+ } else { -+ bool sizeChanged = (size.width != mTransparencyBitmapWidth || -+ size.height != mTransparencyBitmapHeight); -+ -+ if (sizeChanged) { -+ ResizeTransparencyBitmap(size.width, size.height); -+ } else { -+ maskChanged = ChangedMaskBits(mTransparencyBitmap, -+ mTransparencyBitmapWidth, mTransparencyBitmapHeight, -+ nsIntRect(0, 0, size.width, size.height), -+ (uint8_t*)mImageSurface->Data()); -+ } -+ } -+ -+ if (maskChanged) { -+ UpdateMaskBits(mTransparencyBitmap, -+ mTransparencyBitmapWidth, -+ mTransparencyBitmapHeight, -+ nsIntRect(0, 0, size.width, size.height), -+ (uint8_t*)mImageSurface->Data()); -+ -+ // We use X11 calls where possible, because GDK handles expose events -+ // for shaped windows in a way that's incompatible with us (Bug 635903). -+ // It doesn't occur when the shapes are set through X. -+ Display* xDisplay = mWindowSurface->XDisplay(); -+ Window xDrawable = mWindowSurface->XDrawable(); -+ Pixmap maskPixmap = XCreateBitmapFromData(xDisplay, -+ xDrawable, -+ mTransparencyBitmap, -+ mTransparencyBitmapWidth, -+ mTransparencyBitmapHeight); -+ XShapeCombineMask(xDisplay, xDrawable, -+ ShapeBounding, 0, 0, -+ maskPixmap, ShapeSet); -+ XFreePixmap(xDisplay, maskPixmap); -+ } -+} -+ - void - WindowSurfaceX11Image::Commit(const LayoutDeviceIntRegion& aInvalidRegion) - { -@@ -112,6 +268,10 @@ WindowSurfaceX11Image::Commit(const Layo - dt->PushDeviceSpaceClipRects(rects.Elements(), rects.Length()); - } - -+ if (mIsShaped) { -+ ApplyTransparencyBitmap(); -+ } -+ - dt->DrawSurface(surf, rect, rect); - - if (numRects != 1) { -diff -up thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.h.wayland thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.h ---- thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.h.wayland 2018-10-30 12:45:35.000000000 +0100 -+++ thunderbird-60.3.0/widget/gtk/WindowSurfaceX11Image.h 2018-11-20 12:04:43.743787331 +0100 -@@ -19,7 +19,7 @@ namespace widget { - class WindowSurfaceX11Image : public WindowSurfaceX11 { - public: - WindowSurfaceX11Image(Display* aDisplay, Window aWindow, Visual* aVisual, -- unsigned int aDepth); -+ unsigned int aDepth, bool aIsShaped); - ~WindowSurfaceX11Image(); - - already_AddRefed Lock(const LayoutDeviceIntRegion& aRegion) override; -@@ -27,8 +27,16 @@ public: - bool IsFallback() const override { return true; } - - private: -+ void ResizeTransparencyBitmap(int aWidth, int aHeight); -+ void ApplyTransparencyBitmap(); -+ - RefPtr mWindowSurface; - RefPtr mImageSurface; -+ -+ gchar* mTransparencyBitmap; -+ int32_t mTransparencyBitmapWidth; -+ int32_t mTransparencyBitmapHeight; -+ bool mIsShaped; - }; - } // namespace widget diff --git a/thunderbird.spec b/thunderbird.spec index 0f8882c..4fb592a 100644 --- a/thunderbird.spec +++ b/thunderbird.spec @@ -84,7 +84,7 @@ Summary: Mozilla Thunderbird mail/newsgroup client Name: thunderbird Version: 60.3.0 -Release: 4%{?dist} +Release: 5%{?dist} URL: http://www.mozilla.org/projects/thunderbird/ License: MPLv1.1 or GPLv2+ or LGPLv2+ Group: Applications/Internet @@ -128,6 +128,7 @@ Patch309: mozilla-1460871-ldap-query.patch Patch310: disable-dbus-remote.patch Patch311: firefox-wayland.patch Patch312: thunderbird-dbus-remote.patch +Patch313: firefox-wayland-crash-mozbz1507475.patch # Upstream patches @@ -189,8 +190,6 @@ BuildRequires: dbus-glib-devel Obsoletes: thunderbird-lightning Provides: thunderbird-lightning Obsoletes: thunderbird-lightning-gdata <= 1:3.3.0.14 -#Conflicts: thunderbird-lightning-gdata <= 1:3.3.0.14 -#Obsoletes: thunderbird-52.9.1 BuildRequires: rust BuildRequires: cargo BuildRequires: clang-devel @@ -271,9 +270,9 @@ debug %{name}, you want to install %{name}-debuginfo instead. #cd .. # TODO - needs fixes -#%patch311 -p1 -b .wayland +%patch311 -p1 -b .wayland #%patch312 -p1 -b .thunderbird-dbus-remote - +%patch313 -p1 -b .mozbz1507475 %if %{official_branding} # Required by Mozilla Corporation @@ -693,6 +692,10 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : #=============================================================================== %changelog +* Wed Nov 21 2018 Martin Stransky - 60.3.0-5 +- Backported Wayland related code from Firefox 63 +- Added fix for mozbz#1507475 - crash when display changes + * Tue Nov 20 2018 Martin Stransky - 60.3.0-4 - Build with Wayland support - Enabled DBus remote for Wayland