diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2016-09-06 13:41:54 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2016-09-06 14:03:58 +0000 |
commit | f949f75e040c75ff59ecb2c0335152fe8ac6a4be (patch) | |
tree | c1fd4ddcf8285ef288f3b2df0c43df4811be3899 /testing/firefox | |
parent | 9d5e8fb6cf32aca41ad342104dd0a83f59a407c7 (diff) | |
download | aports-f949f75e040c75ff59ecb2c0335152fe8ac6a4be.tar.bz2 aports-f949f75e040c75ff59ecb2c0335152fe8ac6a4be.tar.xz |
testing/firefox: upgrade to 48.0.2
Diffstat (limited to 'testing/firefox')
-rw-r--r-- | testing/firefox/APKBUILD | 54 | ||||
-rw-r--r-- | testing/firefox/disable-hunspell_hooks.patch | 11 | ||||
-rw-r--r-- | testing/firefox/firefox-gtk3-20.patch | 3345 | ||||
-rw-r--r-- | testing/firefox/fix-toolkit.patch | 92 | ||||
-rw-r--r-- | testing/firefox/fix-tools.patch | 85 | ||||
-rw-r--r-- | testing/firefox/mozconfig | 10 |
6 files changed, 2164 insertions, 1433 deletions
diff --git a/testing/firefox/APKBUILD b/testing/firefox/APKBUILD index 938b3a7fd9..bc489ce30c 100644 --- a/testing/firefox/APKBUILD +++ b/testing/firefox/APKBUILD @@ -1,10 +1,10 @@ # Contributor: William Pitcock <nenolod@dereferenced.org> # Maintainer: Natanael Copa <ncopa@alpinelinux.org> pkgname=firefox -pkgver=46.0.1 +pkgver=48.0.2 _pkgver=$pkgver _xulver=$pkgver -pkgrel=1 +pkgrel=0 pkgdesc="Firefox web browser" url="http://www.firefox.com" arch="all !aarch64" @@ -15,8 +15,6 @@ depends_dev=" bzip2-dev dbus-glib-dev gconf-dev - gst-plugins-base1-dev - gstreamer1-dev gtk+2.0-dev hunspell-dev icu-dev @@ -38,7 +36,7 @@ depends_dev=" wireless-tools-dev " makedepends="$depends_dev - autoconf + autoconf2.13 automake bsd-compat-headers libtool @@ -54,6 +52,7 @@ subpackages="$pkgname-dev" source="https://ftp.mozilla.org/pub/firefox/releases/$pkgver/source/firefox-$pkgver.source.tar.xz mozconfig vendor.js + stab.h 0002-Use-C99-math-isfinite.patch fix-arm-atomics-grsec.patch @@ -62,7 +61,7 @@ source="https://ftp.mozilla.org/pub/firefox/releases/$pkgver/source/firefox-$pkg fix-seccomp-bpf.patch mozilla-build-arm.patch disable-moz-stackwalk.patch - stab.h + disable-hunspell_hooks.patch rhbz-966424.patch fix-fortify-inline.patch @@ -71,7 +70,6 @@ source="https://ftp.mozilla.org/pub/firefox/releases/$pkgver/source/firefox-$pkg libavutil.patch mallinfo.patch firefox-gtk3-20.patch - fix-stack-overflow.patch firefox.desktop firefox-safe.desktop" @@ -171,66 +169,66 @@ dev() { default_dev } -md5sums="3e3b90268b8a634f7c60a25eb3a04c8c firefox-46.0.1.source.tar.xz -8f4dda0e7c0e27926b477ba69fdf347e mozconfig +md5sums="bd6410592a8c608c0f771c056351493c firefox-48.0.2.source.tar.xz +bf933892f1f004b253a644b72fd0ae84 mozconfig 99b27aeac58923f318d083e5e71879ba vendor.js +4383d038b8d8411ea46f4a109197c19e stab.h 6ab77b80c8c7d6fd07ab53c54561f4df 0002-Use-C99-math-isfinite.patch b18bd948aae828e5c8f5f63e440c96d6 fix-arm-atomics-grsec.patch -94ae976a54d1f84bf13d059c1e44ddf5 fix-toolkit.patch -fe88db05a9a1adfd79babd137b0e8de8 fix-tools.patch +d46da3e75dfc3abd38d6191d26fea3f1 fix-toolkit.patch +4ee6ff4b8961315a1b18932abb75a12d fix-tools.patch aed3b88014fbfbe73db79851e52ca7fa fix-seccomp-bpf.patch 308ba5b54116a035fe68d0d5c3974857 mozilla-build-arm.patch 4c7a5a634e53c05d8cc67cbd40a3174e disable-moz-stackwalk.patch -4383d038b8d8411ea46f4a109197c19e stab.h +16b597e346d2172b4dea7b47382017f4 disable-hunspell_hooks.patch 15ebeeeb6823c185f4fed98e9bf1b786 rhbz-966424.patch f29e0036edc7b3a4158a82fa97bde500 fix-fortify-inline.patch 9aba3811121f113fe547947591802d2b fix-fortify-system-wrappers.patch 1feef5ea2fd5acc2a71a29350754d006 allow-utf8-fallback.patch b8b2a3cdb38f402e4eb4885908233811 libavutil.patch 0db0cce8350d59a91ae2c4f0400f7146 mallinfo.patch -4398feb7543ef216a9f4a3690ea97180 firefox-gtk3-20.patch -0538d10d2a14576c5aad6048c942a42c fix-stack-overflow.patch +dd5ebfe5142855540bbd2b9164767a9b firefox-gtk3-20.patch ba96924ece1d77453e462429037a2ce5 firefox.desktop 6f38a5899034b7786cb1f75ad42032b8 firefox-safe.desktop" -sha256sums="98b8292a31b7e3e426f3204de1fed2a6ab38dcf64dd27bdfae556b407a198bf9 firefox-46.0.1.source.tar.xz -99259ffe136dba371a2329749a9a6aadd29576ab48bbcd6c02b0e739f6eb4adb mozconfig +sha256sums="6efbe0cc8dd120f16ff6d9394d96ea1b13bf6b4163d3b25d4210e06d23ea44b3 firefox-48.0.2.source.tar.xz +13af3dba823cd4237106d844f0feb0fbbd973762547efb47f5adc2309438ad0b mozconfig afecb8c17a2bedafe600dd572d24eff24e540cda02f675705d11168040379ce6 vendor.js +960d82bbfdc88c95f5cb4f2e1c1bf23dae7519b3b7203914d7b3ddbff1ba4c28 stab.h 080a55182b865471a86fa4b70a66ed9495f1e536f7fdc4060cb8c675b4749c6e 0002-Use-C99-math-isfinite.patch ff7cb3c9c4712e0517a6f11e3bf08e9b0d13dbe6384930bdc7f55b1ceed039b5 fix-arm-atomics-grsec.patch -195cc0b2008f6728e9d85ca787960bb47d7fba723e10d29e255baaa3bd5dd4dc fix-toolkit.patch -b7d43391006443da851c03546f2772ded7770a0ea045e8130be7011cf6718708 fix-tools.patch +485297df325002728c15a87077ef6f762fa057265ca8d977c13fa0ffdc4028dd fix-toolkit.patch +6162d1508ab0afa52684ae955fb8a18b14ae9501d32167c9faa75af249e27935 fix-tools.patch 517d95225b3323c373c11da6ab867deb76ffdb0b50c1762bdd893abd9b39d4c9 fix-seccomp-bpf.patch 6f5f5e4d2a17182b72b248e896450235ccdaf63252fdb89a8deb55da8adc9be3 mozilla-build-arm.patch d87bbd011ec499f93119223360cd79afc628e5f0d020c4e8f0039627c85017e7 disable-moz-stackwalk.patch -960d82bbfdc88c95f5cb4f2e1c1bf23dae7519b3b7203914d7b3ddbff1ba4c28 stab.h +3325749c2554aa24bb376358153fa2f6ca28809e9db2fa5308620e3689aa24b2 disable-hunspell_hooks.patch a50d15a640f230a2c66e1eb2afd2bed4117605d0f1591dcfec1ca30f0bc2352f rhbz-966424.patch ecf808ef1bc2920f6f7a4786fafb46c74e8a2c3bc628f28f10d6e8e1a265e609 fix-fortify-inline.patch cd19195cb4c316ad9f7d377cd8581218c888863b1bc4d112c97f48a4425fb946 fix-fortify-system-wrappers.patch a1ba79ec0c50c19edcfb24bb2686a718a77b02035e412989b9208b9b818abe14 allow-utf8-fallback.patch 83113f1fbc0389602b3623e8a5428d41837c4ec9557615c37ca05619526a7404 libavutil.patch 2f564fa5f347f3c7f20d589ef273f000ca9c9aeca2c6ad0fb5b15bfc715d8b81 mallinfo.patch -440c3e22d98ecf8c44dcedbe90bbb302da3a059e3fc3fba205d89f0eca329cbf firefox-gtk3-20.patch -e568adf5d43220b831fd538b4387c14c046efc1bdab4257467fbfd86ee5830aa fix-stack-overflow.patch +c984c8bda3c173349d98f3fa71ec8ff8e8b74e6ca20a3f39f33596dbb4c4d1e8 firefox-gtk3-20.patch b571c4a49884a3c98806246c9cc3e60c73d5a8f4aeb7f96217db0be1d6210eda firefox.desktop 4b6de45753856a890f4482055666e77f9b01bdfb7e0df08bafaa3a4d9937eed3 firefox-safe.desktop" -sha512sums="c58642774f93ceaef4f99bc3fe578db6e4f6de7f1d23080da97b61bc4fc6b516ce99fa04368893c0fa2cb9cd0b36e96955656daa97d0bd0d8f4da6a2d364cb98 firefox-46.0.1.source.tar.xz -344e46fbfc5b0bd9b1e3ad81eb4695b336482a1bddd1632b845e7a0bc87928a2936db97af1a41b48df83274aa4453dce215b45e383a756f2ccdb5d2e57f19b52 mozconfig +sha512sums="d5addb0cd01e2aeb0fd9387800e82e385f3986716887840322d261d772a442f6fdb1d910cd53f2373f0fb82ed0b2a45356ac83f3ef230e14a2b9db8999ad8a4e firefox-48.0.2.source.tar.xz +9eb1ec4b892e736f9f23e3921e4e3a0a8726821180450dc474037de3030c4f2f4fe7b0e0aa07b619bb88b9234ab4508008ea9b04875dc5ee2658810dbf40fc81 mozconfig cc10dba32d9c7faf1d99b8fdebc71bf0200ad10b976105edb45df696bf64a668b2b7aa8c3892a8056eb71fb071b0e0ae51c3ce2fb75acfb7e7035104c0e4fce3 vendor.js +0b3f1e4b9fdc868e4738b5c81fd6c6128ce8885b260affcb9a65ff9d164d7232626ce1291aaea70132b3e3124f5e13fef4d39326b8e7173e362a823722a85127 stab.h 7e123144bc2b1efed149dfb41b255c447d43ea93a63ebe114d01945e6a6d69edc2f2a3c36980a93279106c1842355851b8b6c1d96679ee6be7b9b30513e0b1a8 0002-Use-C99-math-isfinite.patch 4311464ae52b6d2e2b02c789c6d5fca9b3c211888a983aa609a62c2f2554516fea735ea90673387c69b38a30aa8453ed79faa44b5163df4293880d40df676b2d fix-arm-atomics-grsec.patch -d3f2ec8684aa485e1d08df325281629adb120f2e79c0065b96e14b99ca2968a3c701d18dda1fd1cab482aec2bc4ee8f294b9fda970ae159f8dab655f2c91aca9 fix-toolkit.patch -6322912a8b496332c593ee5c2069d346552299781148d6c829321a10be7f6550a6f7aab3d0cfeb08e1c4ecca2a79272ea7a6f31f1d2eb430c1b0041e3699c06c fix-tools.patch +a2925045154f4fd34e5fc056656f4f9da100341529e5d4104d249154db0c7863384083f421ce6e47e0f20566a8b20787fa35444c7933c03cd03f96f06dcd4532 fix-toolkit.patch +bc112a134618ffb8173af6a5c7d8e99500fd70e5773c780fac8175a5859bb0247cfb13fe01d02e0c89a6c272385b85a6139b6c597888752b7bdef1ba5e79b7f9 fix-tools.patch 70863b985427b9653ce5e28d6064f078fb6d4ccf43dd1b68e72f97f44868fc0ce063161c39a4e77a0a1a207b7365d5dc7a7ca5e68c726825eba814f2b93e2f5d fix-seccomp-bpf.patch e61664bc93eadce5016a06a4d0684b34a05074f1815e88ef2613380d7b369c6fd305fb34f83b5eb18b9e3138273ea8ddcfdcb1084fdcaa922a1e5b30146a3b18 mozilla-build-arm.patch c69cdb2d6c66180d6a67c386b862a5ed953aab4db434b054c9e1e6702bcc56ba219a4cb22747d9c891040a286388168e0cf5ca28a503389cd9708012fddf6c2b disable-moz-stackwalk.patch -0b3f1e4b9fdc868e4738b5c81fd6c6128ce8885b260affcb9a65ff9d164d7232626ce1291aaea70132b3e3124f5e13fef4d39326b8e7173e362a823722a85127 stab.h +0fcc647af53a3ce21c2bc36e5631eb0935e7243ebb3ab59b5719542cc54a6ac023a4a857b43b75756efb9ed80c0aecaa94dc5679a3b3792f82e87bf2c1af82e1 disable-hunspell_hooks.patch 06ededcd196af98b77991dcba3b710b0dfc061404adb4676fcc380be80410a2621f64d67257b0aefdf36f566e0ea1294b5405b7b4db43e83281a1c64d02da579 rhbz-966424.patch 09bc32cf9ee81b9cc6bb58ddbc66e6cc5c344badff8de3435cde5848e5a451e0172153231db85c2385ff05b5d9c20760cb18e4138dfc99060a9e960de2befbd5 fix-fortify-inline.patch 2a967e4619fd89a046bd40be7fdcef646fcb1eba5e47afc96aa1d59c25bcc8747cb07baee6c11f3b803db0981aced181534b806778e4d21e74958f5f4d74c784 fix-fortify-system-wrappers.patch ebbc2b1336197c289e9b7c073d196fb5734e1dad0109fe70538f8089b1873e4b55305cd39cefcf95cd4eb36715be6dff298856c496616e935ff5579452e62b09 allow-utf8-fallback.patch 2213dbd7eb36f954add09977c0bb979aea79376164bc98d7e8957ecf584776bc11cc88b6d8235f9e04ac69d5975a47c2f52fd9aff9076326f15997657af8c9f3 libavutil.patch bdcd1b402d2ec94957ba5d08cbad7b1a7f59c251c311be9095208491a05abb05a956c79f27908e1f26b54a3679387b2f33a51e945b650671ad85c0a2d59a5a29 mallinfo.patch -ee891acc644bea7eeccea8414292ada80d813864ce003d03189c9ef4f7e2c97e7209301725b1d55a02dd7af497eb9c7493fafc208b5a5fde574ddcf1bf7870c4 firefox-gtk3-20.patch -c815131b04e25162d8b32e75e58c3f670492996a41a0cc27a72432ed37fb3a5488a6eb474c2a1bf455d3546cde3b6871b46bcdbef8e2f37d1133c40819aa6f11 fix-stack-overflow.patch +161a1151b817d82e14923c8aa0cf31a7c36379f0c2c6b5a8407b804db9fe78d86142911b00e6d232d7ca3b241d6ad6a451d67823484ba9d011cc96ce821c3ce0 firefox-gtk3-20.patch f3b7c3e804ce04731012a46cb9e9a6b0769e3772aef9c0a4a8c7520b030fdf6cd703d5e9ff49275f14b7d738fe82a0a4fde3bc3219dff7225d5db0e274987454 firefox.desktop 5dcb6288d0444a8a471d669bbaf61cdb1433663eff38b72ee5e980843f5fc07d0d60c91627a2c1159215d0ad77ae3f115dcc5fdfe87e64ca704b641aceaa44ed firefox-safe.desktop" diff --git a/testing/firefox/disable-hunspell_hooks.patch b/testing/firefox/disable-hunspell_hooks.patch new file mode 100644 index 0000000000..1eaa4d0351 --- /dev/null +++ b/testing/firefox/disable-hunspell_hooks.patch @@ -0,0 +1,11 @@ +--- a/mozilla-config.h.in 2016-07-06 15:16:06.621880293 +0200 ++++ b/mozilla-config.h.in 2016-07-06 15:16:42.958428126 +0200 +@@ -54,7 +54,7 @@ + * HUNSPELL_STATIC is defined in extensions/spellcheck/hunspell/src/Makefile.in, + * unless --enable-system-hunspell is defined. + */ +-#if defined(HUNSPELL_STATIC) ++#if 0 + #include "hunspell_alloc_hooks.h" + #include "hunspell_fopen_hooks.h" + #endif diff --git a/testing/firefox/firefox-gtk3-20.patch b/testing/firefox/firefox-gtk3-20.patch index e3c3a00592..eccbc5e8d7 100644 --- a/testing/firefox/firefox-gtk3-20.patch +++ b/testing/firefox/firefox-gtk3-20.patch @@ -1,1614 +1,2333 @@ -diff -up firefox-46.0/widget/gtk/gtk3drawing.c.gtk3-20 firefox-46.0/widget/gtk/gtk3drawing.c ---- firefox-46.0/widget/gtk/gtk3drawing.c.gtk3-20 2016-04-22 02:37:27.000000000 +0200 -+++ firefox-46.0/widget/gtk/gtk3drawing.c 2016-04-25 14:56:19.006992927 +0200 -@@ -17,32 +17,79 @@ +diff -up firefox-48.0/widget/gtk/gtk3drawing.cpp.gtk3-20 firefox-48.0/widget/gtk/gtk3drawing.cpp +--- firefox-48.0/widget/gtk/gtk3drawing.cpp.gtk3-20 2016-07-25 22:22:07.000000000 +0200 ++++ firefox-48.0/widget/gtk/gtk3drawing.cpp 2016-07-29 09:15:11.822285857 +0200 +@@ -18,15 +18,9 @@ #include <math.h> -+#define MOZ_WIDGET_STYLES 4 -+ -+typedef struct { -+ GtkWidget* widget; -+ -+ union { -+ struct { -+ GtkStyleContext* style; -+ GtkStyleContext* styleSelection; -+ } entry; -+ -+ struct { -+ GtkStyleContext* style; -+ } button; -+ -+ struct { -+ GtkStyleContext* style; -+ GtkStyleContext* styleContents; -+ GtkStyleContext* styleTrough; -+ GtkStyleContext* styleSlider; -+ } scroll; -+ -+ struct { -+ GtkStyleContext* style; -+ GtkStyleContext* styleCheck; -+ GtkStyleContext* styleLabel; -+ } check; -+ -+ struct { -+ GtkStyleContext* style; -+ GtkStyleContext* styleTrough; -+ GtkStyleContext* styleProgress; -+ } progress; -+ -+ struct { -+ GtkStyleContext* style; -+ GtkStyleContext* styleEntry; -+ GtkStyleContext* styleButtonUp; -+ GtkStyleContext* styleButtonDown; -+ } spin; -+ -+ struct { -+ GtkStyleContext* style[MOZ_WIDGET_STYLES]; -+ } all; -+ }; -+} MozGtkWidget; -+ - static GtkWidget* gProtoWindow; +-static GtkWidget* gProtoWindow; static GtkWidget* gProtoLayout; -static GtkWidget* gButtonWidget; -+static MozGtkWidget gButton; - static GtkWidget* gToggleButtonWidget; - static GtkWidget* gButtonArrowWidget; --static GtkWidget* gCheckboxWidget; --static GtkWidget* gRadiobuttonWidget; --static GtkWidget* gHorizScrollbarWidget; --static GtkWidget* gVertScrollbarWidget; +-static GtkWidget* gToggleButtonWidget; +-static GtkWidget* gButtonArrowWidget; -static GtkWidget* gSpinWidget; -+static MozGtkWidget gCheckbox; -+static MozGtkWidget gRadiobutton; -+static MozGtkWidget gVertScrollbar; -+static MozGtkWidget gHorizScrollbar; -+static MozGtkWidget gSpin; static GtkWidget* gHScaleWidget; static GtkWidget* gVScaleWidget; -static GtkWidget* gEntryWidget; -+static MozGtkWidget gEntry; static GtkWidget* gComboBoxWidget; static GtkWidget* gComboBoxButtonWidget; static GtkWidget* gComboBoxArrowWidget; - static GtkWidget* gComboBoxSeparatorWidget; - static GtkWidget* gComboBoxEntryWidget; --static GtkWidget* gComboBoxEntryTextareaWidget; -+static MozGtkWidget gComboBoxEntryTextarea; +@@ -35,30 +29,15 @@ static GtkWidget* gComboBoxEntryWidget; + static GtkWidget* gComboBoxEntryTextareaWidget; static GtkWidget* gComboBoxEntryButtonWidget; static GtkWidget* gComboBoxEntryArrowWidget; - static GtkWidget* gHandleBoxWidget; - static GtkWidget* gToolbarWidget; - static GtkWidget* gFrameWidget; - static GtkWidget* gStatusbarWidget; +-static GtkWidget* gHandleBoxWidget; +-static GtkWidget* gToolbarWidget; +-static GtkWidget* gFrameWidget; -static GtkWidget* gProgressWidget; -+static MozGtkWidget gProgressBar; static GtkWidget* gTabWidget; - static GtkWidget* gTooltipWidget; - static GtkWidget* gMenuBarWidget; -@@ -78,6 +125,37 @@ static gboolean is_initialized; - #define GTK_STATE_FLAG_CHECKED (1 << 11) - #endif - -+void moz_gtk_widget_free(MozGtkWidget *aMozWidget) -+{ -+ // This was removed as a child of gProtoWindow -+ if (aMozWidget->widget) { -+ aMozWidget->widget = NULL; -+ } -+ -+ for(int i = 0; i < MOZ_WIDGET_STYLES; i++) { -+ if (aMozWidget->all.style[i]) { -+ g_object_unref(aMozWidget->all.style[i]); -+ aMozWidget->all.style[i] = NULL; -+ } -+ } -+} -+ -+// TODO - weak dep!! (dlsym) -+#if GTK_CHECK_VERSION(3, 19, 2) -+#define moz_gtk_path_set_class_name gtk_widget_path_iter_set_object_name -+#else -+#define moz_gtk_path_set_class_name gtk_widget_path_iter_add_class -+#endif -+//gtk_widget_path_iter_get_state -+ -+static void -+moz_gtk_get_style_border(GtkStyleContext* style, GtkStateFlags state_flags, -+ GtkBorder *border); -+ -+static void -+moz_gtk_get_style_padding(GtkStyleContext* style, GtkStateFlags state_flags, -+ GtkBorder *padding); -+ - static GtkStateFlags - GetStateFlagsFromGtkWidgetState(GtkWidgetState* state) - { -@@ -97,6 +175,41 @@ GetStateFlagsFromGtkWidgetState(GtkWidge +-static GtkWidget* gTextViewWidget; +-static GtkWidget* gTooltipWidget; +-static GtkWidget* gMenuBarWidget; +-static GtkWidget* gMenuBarItemWidget; +-static GtkWidget* gMenuPopupWidget; +-static GtkWidget* gMenuItemWidget; + static GtkWidget* gImageMenuItemWidget; + static GtkWidget* gCheckMenuItemWidget; + static GtkWidget* gTreeViewWidget; + static GtkTreeViewColumn* gMiddleTreeViewColumn; + static GtkWidget* gTreeHeaderCellWidget; + static GtkWidget* gTreeHeaderSortArrowWidget; +-static GtkWidget* gExpanderWidget; +-static GtkWidget* gToolbarSeparatorWidget; +-static GtkWidget* gMenuSeparatorWidget; + static GtkWidget* gHPanedWidget; + static GtkWidget* gVPanedWidget; +-static GtkWidget* gScrolledWindowWidget; +-static GtkWidget* gInfoBar; + + static style_prop_t style_prop_func; + static gboolean have_arrow_scaling; +@@ -94,15 +73,6 @@ GetStateFlagsFromGtkWidgetState(GtkWidge return stateFlags; } -+GtkStyleContext * -+moz_gtk_style_create(GtkCssNode *node, GtkStyleContext *parent) -+{ -+ GtkWidgetPath *path; -+ GtkStyleContext *context; -+ -+ if (parent) -+ path = gtk_widget_path_copy (gtk_style_context_get_path (parent)); -+ else -+ path = gtk_widget_path_new (); -+ -+ gtk_widget_path_append_type (path, node->type); -+ if (node->name) -+ moz_gtk_path_set_class_name(path, -1, node->name); -+ if (node->class1) -+ gtk_widget_path_iter_add_class(path, -1, node->class1); -+ if (node->class2) -+ gtk_widget_path_iter_add_class(path, -1, node->class2); -+ -+ context = gtk_style_context_new (); -+ gtk_style_context_set_path (context, path); -+ gtk_style_context_set_parent (context, parent); -+ -+ if(!gtk_check_version(3, 14, 0)) { -+ /* Unfortunately, we have to explicitly set the state again here -+ * for it to take effect -+ */ -+ gtk_style_context_set_state (context, gtk_widget_path_iter_get_state (path, -1)); -+ } -+ -+ gtk_widget_path_unref (path); -+ -+ return context; -+} -+ - /* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine - that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific - things they may want to do. */ -@@ -141,9 +254,16 @@ setup_widget_prototype(GtkWidget* widget - static gint - ensure_button_widget() - { -- if (!gButtonWidget) { -- gButtonWidget = gtk_button_new_with_label("M"); -- setup_widget_prototype(gButtonWidget); -+ if (!gButton.widget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_BUTTON, "button", NULL, NULL } -+ }; -+ -+ gButton.widget = gtk_button_new_with_label("M"); -+ setup_widget_prototype(gButton.widget); -+ gtk_widget_show(gButton.widget); -+ -+ gButton.button.style = moz_gtk_style_create(&path[0], NULL); - } - return MOZ_GTK_SUCCESS; - } -@@ -195,9 +315,21 @@ ensure_button_arrow_widget() - static gint - ensure_checkbox_widget() +-/* Because we have such an unconventional way of drawing widgets, signal to the GTK theme engine +- that they are drawing for Mozilla instead of a conventional GTK app so they can do any specific +- things they may want to do. */ +-static void +-moz_gtk_set_widget_name(GtkWidget* widget) +-{ +- gtk_widget_set_name(widget, "MozillaGtkWidget"); +-} +- + gint + moz_gtk_enable_style_props(style_prop_t styleGetProp) { -- if (!gCheckboxWidget) { -- gCheckboxWidget = gtk_check_button_new_with_label("M"); -- setup_widget_prototype(gCheckboxWidget); -+ if (!gCheckbox.widget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_TOGGLE_BUTTON, "checkbutton", NULL, NULL }, -+ { G_TYPE_NONE, "check", NULL, NULL }, -+ { G_TYPE_NONE, "label", NULL, NULL } -+ }; -+ -+ gCheckbox.widget = gtk_check_button_new_with_label("M"); -+ setup_widget_prototype(gCheckbox.widget); -+ -+ gCheckbox.check.style = moz_gtk_style_create(&path[0], NULL); -+ gCheckbox.check.styleCheck = moz_gtk_style_create(&path[1], -+ gCheckbox.check.style); -+ gCheckbox.check.styleLabel = moz_gtk_style_create(&path[2], -+ gCheckbox.check.style); - } - return MOZ_GTK_SUCCESS; +@@ -111,15 +81,6 @@ moz_gtk_enable_style_props(style_prop_t } -@@ -205,9 +337,21 @@ ensure_checkbox_widget() + static gint - ensure_radiobutton_widget() +-ensure_window_widget() +-{ +- if (!gProtoWindow) { +- gProtoWindow = GetWidget(MOZ_GTK_WINDOW); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint + setup_widget_prototype(GtkWidget* widget) { -- if (!gRadiobuttonWidget) { -- gRadiobuttonWidget = gtk_radio_button_new_with_label(NULL, "M"); -- setup_widget_prototype(gRadiobuttonWidget); -+ if (!gRadiobutton.widget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_TOGGLE_BUTTON, "radiobutton", NULL, NULL }, -+ { G_TYPE_NONE, "radio", NULL, NULL }, -+ { G_TYPE_NONE, "label", NULL, NULL } -+ }; -+ -+ gRadiobutton.widget = gtk_radio_button_new_with_label(NULL, "M"); -+ setup_widget_prototype(gRadiobutton.widget); -+ -+ gRadiobutton.check.style = moz_gtk_style_create(&path[0], NULL); -+ gRadiobutton.check.styleCheck = moz_gtk_style_create(&path[1], -+ gRadiobutton.check.style); -+ gRadiobutton.check.styleLabel = moz_gtk_style_create(&path[2], -+ gRadiobutton.check.style); - } - return MOZ_GTK_SUCCESS; + if (!gProtoLayout) { +@@ -130,16 +91,6 @@ setup_widget_prototype(GtkWidget* widget } -@@ -215,25 +359,62 @@ ensure_radiobutton_widget() + static gint - ensure_scrollbar_widget() - { -- if (!gVertScrollbarWidget) { -- gVertScrollbarWidget = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL); -- setup_widget_prototype(gVertScrollbarWidget); -- } -- if (!gHorizScrollbarWidget) { -- gHorizScrollbarWidget = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL); -- setup_widget_prototype(gHorizScrollbarWidget); +-ensure_button_widget() +-{ +- if (!gButtonWidget) { +- gButtonWidget = gtk_button_new_with_label("M"); +- setup_widget_prototype(gButtonWidget); - } -+ if (!gVertScrollbar.widget && !gHorizScrollbar.widget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_SCROLLBAR, "scrollbar", "horizontal", "bottom"}, -+ { GTK_TYPE_SCROLLBAR, "scrollbar", "vertical", "right" }, -+ { G_TYPE_NONE, "contents", NULL, NULL }, -+ { G_TYPE_NONE, "trough", NULL, NULL }, -+ { G_TYPE_NONE, "slider", NULL, NULL } -+ }; -+ -+ gHorizScrollbar.widget = gtk_scrollbar_new(GTK_ORIENTATION_HORIZONTAL, NULL); -+ setup_widget_prototype(gHorizScrollbar.widget); -+ -+ gHorizScrollbar.scroll.style = moz_gtk_style_create(path, NULL); -+ gHorizScrollbar.scroll.styleContents = moz_gtk_style_create(path+2, -+ gHorizScrollbar.scroll.style); -+ gHorizScrollbar.scroll.styleTrough = moz_gtk_style_create(path+3, -+ gHorizScrollbar.scroll.styleContents); -+ gHorizScrollbar.scroll.styleSlider = moz_gtk_style_create(path+4, -+ gHorizScrollbar.scroll.styleTrough); -+ -+ gVertScrollbar.widget = gtk_scrollbar_new(GTK_ORIENTATION_VERTICAL, NULL); -+ setup_widget_prototype(gVertScrollbar.widget); -+ -+ gVertScrollbar.scroll.style = moz_gtk_style_create(path+1, NULL); -+ gVertScrollbar.scroll.styleContents = moz_gtk_style_create(path+2, -+ gVertScrollbar.scroll.style); -+ gVertScrollbar.scroll.styleTrough = moz_gtk_style_create(path+3, -+ gVertScrollbar.scroll.styleContents); -+ gVertScrollbar.scroll.styleSlider = moz_gtk_style_create(path+4, -+ gVertScrollbar.scroll.styleTrough); -+ -+ } - return MOZ_GTK_SUCCESS; +- return MOZ_GTK_SUCCESS; +-} +- +-static gint + ensure_hpaned_widget() + { + if (!gHPanedWidget) { +@@ -160,40 +111,6 @@ ensure_vpaned_widget() } static gint - ensure_spin_widget() - { +-ensure_toggle_button_widget() +-{ +- if (!gToggleButtonWidget) { +- gToggleButtonWidget = gtk_toggle_button_new(); +- setup_widget_prototype(gToggleButtonWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_button_arrow_widget() +-{ +- if (!gButtonArrowWidget) { +- ensure_toggle_button_widget(); +- +- gButtonArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT); +- gtk_container_add(GTK_CONTAINER(gToggleButtonWidget), gButtonArrowWidget); +- gtk_widget_realize(gButtonArrowWidget); +- gtk_widget_show(gButtonArrowWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_spin_widget() +-{ - if (!gSpinWidget) { - gSpinWidget = gtk_spin_button_new(NULL, 1, 0); - setup_widget_prototype(gSpinWidget); - } - return MOZ_GTK_SUCCESS; -+ if (!gSpin.widget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_SPIN_BUTTON, "spinbutton", "horizontal", NULL }, -+ { GTK_TYPE_SPIN_BUTTON, "spinbutton", "vertical", NULL }, -+ { GTK_TYPE_ENTRY, "entry", NULL, NULL }, -+ { G_TYPE_NONE, "button", "up", NULL }, -+ { G_TYPE_NONE, "button", "down", NULL } -+ }; -+ -+ gSpin.widget = gtk_spin_button_new(NULL, 1, 0); -+ setup_widget_prototype(gSpin.widget); -+ -+ gSpin.spin.style = moz_gtk_style_create(path, NULL); -+ gSpin.spin.styleButtonUp = moz_gtk_style_create(path+3, gSpin.spin.style); -+ gSpin.spin.styleButtonDown = moz_gtk_style_create(path+4, gSpin.spin.style); -+ gSpin.spin.styleEntry = moz_gtk_style_create(path+2, gSpin.spin.style); -+ } -+ return MOZ_GTK_SUCCESS; +-} +- +-static gint + ensure_scale_widget() + { + if (!gHScaleWidget) { +@@ -207,16 +124,6 @@ ensure_scale_widget() + return MOZ_GTK_SUCCESS; } - static gint -@@ -253,9 +434,19 @@ ensure_scale_widget() - static gint - ensure_entry_widget() - { +-static gint +-ensure_entry_widget() +-{ - if (!gEntryWidget) { - gEntryWidget = gtk_entry_new(); - setup_widget_prototype(gEntryWidget); -+ if (!gEntry.widget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_ENTRY, "entry", NULL, NULL }, -+ { G_TYPE_NONE, "selection", NULL, NULL } -+ }; -+ -+ gEntry.widget = gtk_entry_new(); -+ setup_widget_prototype(gEntry.widget); -+ gtk_widget_show(gEntry.widget); -+ -+ gEntry.entry.style = moz_gtk_style_create(&path[0], NULL); -+ gEntry.entry.styleSelection = moz_gtk_style_create(&path[1], -+ gEntry.entry.style); +- } +- return MOZ_GTK_SUCCESS; +-} +- + /* We need to have pointers to the inner widgets (button, separator, arrow) + * of the ComboBox to get the correct rendering from theme engines which + * special cases their look. Since the inner layout can change, we ask GTK +@@ -225,7 +132,7 @@ ensure_entry_widget() + * g_object_add_weak_pointer(). + * Note that if we don't find the inner widgets (which shouldn't happen), we + * fallback to use generic "non-inner" widgets, and they don't need that kind +- * of weak pointer since they are explicit children of gProtoWindow and as ++ * of weak pointer since they are explicit children of gProtoLayout and as + * such GTK holds a strong reference to them. */ + static void + moz_gtk_get_combo_box_inner_button(GtkWidget *widget, gpointer client_data) +@@ -297,16 +204,14 @@ ensure_combo_box_widgets() + /* Shouldn't be reached with current internal gtk implementation; we + * use a generic toggle button as last resort fallback to avoid + * crashing. */ +- ensure_toggle_button_widget(); +- gComboBoxButtonWidget = gToggleButtonWidget; ++ gComboBoxButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON); + } + + if (!gComboBoxArrowWidget) { + /* Shouldn't be reached with current internal gtk implementation; + * we gButtonArrowWidget as last resort fallback to avoid + * crashing. */ +- ensure_button_arrow_widget(); +- gComboBoxArrowWidget = gButtonArrowWidget; ++ gComboBoxArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW); } + + /* We don't test the validity of gComboBoxSeparatorWidget since there +@@ -316,15 +221,6 @@ ensure_combo_box_widgets() return MOZ_GTK_SUCCESS; } -@@ -387,9 +578,9 @@ moz_gtk_get_combo_box_entry_inner_widget - g_object_add_weak_pointer(G_OBJECT(widget), - (gpointer) &gComboBoxEntryButtonWidget); - } else if (GTK_IS_ENTRY(widget)) { -- gComboBoxEntryTextareaWidget = widget; -+ gComboBoxEntryTextarea.widget = widget; - g_object_add_weak_pointer(G_OBJECT(widget), -- (gpointer) &gComboBoxEntryTextareaWidget); -+ (gpointer) &gComboBoxEntryTextarea.widget); - } else - return; - gtk_widget_realize(widget); -@@ -411,7 +602,7 @@ ensure_combo_box_entry_widgets() - { - GtkWidget* buttonChild; - -- if (gComboBoxEntryTextareaWidget && -+ if (gComboBoxEntryTextarea.widget && - gComboBoxEntryButtonWidget && - gComboBoxEntryArrowWidget) - return MOZ_GTK_SUCCESS; -@@ -427,9 +618,9 @@ ensure_combo_box_entry_widgets() - moz_gtk_get_combo_box_entry_inner_widgets, + +-static void +-ensure_info_bar() +-{ +- if (!gInfoBar) { +- gInfoBar = gtk_info_bar_new(); +- setup_widget_prototype(gInfoBar); +- } +-} +- + /* We need to have pointers to the inner widgets (entry, button, arrow) of + * the ComboBoxEntry to get the correct rendering from theme engines which + * special cases their look. Since the inner layout can change, we ask GTK +@@ -333,7 +229,7 @@ ensure_info_bar() + * g_object_add_weak_pointer(). + * Note that if we don't find the inner widgets (which shouldn't happen), we + * fallback to use generic "non-inner" widgets, and they don't need that kind +- * of weak pointer since they are explicit children of gProtoWindow and as ++ * of weak pointer since they are explicit children of gProtoLayout and as + * such GTK holds a strong reference to them. */ + static void + moz_gtk_get_combo_box_entry_inner_widgets(GtkWidget *widget, +@@ -385,8 +281,7 @@ ensure_combo_box_entry_widgets() NULL); -- if (!gComboBoxEntryTextareaWidget) { -+ if (!gComboBoxEntryTextarea.widget) { - ensure_entry_widget(); + if (!gComboBoxEntryTextareaWidget) { +- ensure_entry_widget(); - gComboBoxEntryTextareaWidget = gEntryWidget; -+ gComboBoxEntryTextarea.widget = gEntry.widget; ++ gComboBoxEntryTextareaWidget = GetWidget(MOZ_GTK_ENTRY); } if (gComboBoxEntryButtonWidget) { -@@ -530,9 +721,21 @@ ensure_tab_widget() +@@ -412,68 +307,19 @@ ensure_combo_box_entry_widgets() + /* Shouldn't be reached with current internal gtk implementation; + * we use a generic toggle button as last resort fallback to avoid + * crashing. */ +- ensure_toggle_button_widget(); +- gComboBoxEntryButtonWidget = gToggleButtonWidget; ++ gComboBoxEntryButtonWidget = GetWidget(MOZ_GTK_TOGGLE_BUTTON); + } + + if (!gComboBoxEntryArrowWidget) { + /* Shouldn't be reached with current internal gtk implementation; + * we gButtonArrowWidget as last resort fallback to avoid + * crashing. */ +- ensure_button_arrow_widget(); +- gComboBoxEntryArrowWidget = gButtonArrowWidget; ++ gComboBoxEntryArrowWidget = GetWidget(MOZ_GTK_BUTTON_ARROW); + } + + return MOZ_GTK_SUCCESS; + } + +- +-static gint +-ensure_handlebox_widget() +-{ +- if (!gHandleBoxWidget) { +- gHandleBoxWidget = gtk_handle_box_new(); +- setup_widget_prototype(gHandleBoxWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_toolbar_widget() +-{ +- if (!gToolbarWidget) { +- ensure_handlebox_widget(); +- gToolbarWidget = gtk_toolbar_new(); +- gtk_container_add(GTK_CONTAINER(gHandleBoxWidget), gToolbarWidget); +- gtk_widget_realize(gToolbarWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_toolbar_separator_widget() +-{ +- if (!gToolbarSeparatorWidget) { +- ensure_toolbar_widget(); +- gToolbarSeparatorWidget = GTK_WIDGET(gtk_separator_tool_item_new()); +- setup_widget_prototype(gToolbarSeparatorWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_tooltip_widget() +-{ +- if (!gTooltipWidget) { +- gTooltipWidget = gtk_window_new(GTK_WINDOW_POPUP); +- GtkStyleContext* style = gtk_widget_get_style_context(gTooltipWidget); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP); +- gtk_widget_realize(gTooltipWidget); +- moz_gtk_set_widget_name(gTooltipWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- static gint - ensure_progress_widget() + ensure_tab_widget() { +@@ -485,81 +331,11 @@ ensure_tab_widget() + } + + static gint +-ensure_progress_widget() +-{ - if (!gProgressWidget) { - gProgressWidget = gtk_progress_bar_new(); - setup_widget_prototype(gProgressWidget); -+ if (!gProgressBar.widget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_LABEL, "progressbar", NULL, NULL }, -+ { G_TYPE_NONE, "trough", NULL, NULL }, -+ { G_TYPE_NONE, "progress", NULL, NULL }, -+ }; -+ -+ gProgressBar.widget = gtk_progress_bar_new(); -+ setup_widget_prototype(gProgressBar.widget); -+ -+ gProgressBar.progress.style = moz_gtk_style_create(&path[0], NULL); -+ gProgressBar.progress.styleTrough = moz_gtk_style_create(&path[1], -+ gProgressBar.progress.style); -+ gProgressBar.progress.styleProgress = moz_gtk_style_create(&path[2], -+ gProgressBar.progress.styleTrough); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_frame_widget() +-{ +- if (!gFrameWidget) { +- gFrameWidget = gtk_frame_new(NULL); +- setup_widget_prototype(gFrameWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_menu_bar_widget() +-{ +- if (!gMenuBarWidget) { +- gMenuBarWidget = gtk_menu_bar_new(); +- setup_widget_prototype(gMenuBarWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_menu_bar_item_widget() +-{ +- if (!gMenuBarItemWidget) { +- ensure_menu_bar_widget(); +- gMenuBarItemWidget = gtk_menu_item_new(); +- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuBarWidget), +- gMenuBarItemWidget); +- gtk_widget_realize(gMenuBarItemWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_menu_popup_widget() +-{ +- if (!gMenuPopupWidget) { +- ensure_window_widget(); +- gMenuPopupWidget = gtk_menu_new(); +- gtk_menu_attach_to_widget(GTK_MENU(gMenuPopupWidget), gProtoWindow, +- NULL); +- gtk_widget_realize(gMenuPopupWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_menu_item_widget() +-{ +- if (!gMenuItemWidget) { +- ensure_menu_popup_widget(); +- gMenuItemWidget = gtk_menu_item_new_with_label("M"); +- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget), +- gMenuItemWidget); +- gtk_widget_realize(gMenuItemWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint + ensure_image_menu_item_widget() + { + if (!gImageMenuItemWidget) { +- ensure_menu_popup_widget(); + gImageMenuItemWidget = gtk_image_menu_item_new(); +- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget), ++ gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), + gImageMenuItemWidget); + gtk_widget_realize(gImageMenuItemWidget); } - return MOZ_GTK_SUCCESS; +@@ -567,25 +343,11 @@ ensure_image_menu_item_widget() } -@@ -638,6 +841,11 @@ static gint + + static gint +-ensure_menu_separator_widget() +-{ +- if (!gMenuSeparatorWidget) { +- ensure_menu_popup_widget(); +- gMenuSeparatorWidget = gtk_separator_menu_item_new(); +- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget), +- gMenuSeparatorWidget); +- gtk_widget_realize(gMenuSeparatorWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint ensure_check_menu_item_widget() { if (!gCheckMenuItemWidget) { -+ GtkCssNode path[] = { -+ { GTK_TYPE_CHECK_MENU_ITEM, "menuitem", NULL, NULL }, -+ { G_TYPE_NONE, "check", NULL, NULL } -+ }; -+ - ensure_menu_popup_widget(); - gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M"); - gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget), -@@ -752,7 +960,7 @@ moz_gtk_checkbox_get_metrics(gint* indic - { - ensure_checkbox_widget(); - -- gtk_widget_style_get (gCheckboxWidget, -+ gtk_widget_style_get (gCheckbox.widget, - "indicator_size", indicator_size, - "indicator_spacing", indicator_spacing, - NULL); -@@ -765,7 +973,7 @@ moz_gtk_radio_get_metrics(gint* indicato +- ensure_menu_popup_widget(); +- gCheckMenuItemWidget = gtk_check_menu_item_new_with_label("M"); +- gtk_menu_shell_append(GTK_MENU_SHELL(gMenuPopupWidget), ++ gCheckMenuItemWidget = gtk_check_menu_item_new(); ++ gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), + gCheckMenuItemWidget); + gtk_widget_realize(gCheckMenuItemWidget); + } +@@ -646,37 +408,6 @@ ensure_tree_header_cell_widget() + return MOZ_GTK_SUCCESS; + } + +-static gint +-ensure_expander_widget() +-{ +- if (!gExpanderWidget) { +- gExpanderWidget = gtk_expander_new("M"); +- setup_widget_prototype(gExpanderWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static gint +-ensure_scrolled_window_widget() +-{ +- if (!gScrolledWindowWidget) { +- gScrolledWindowWidget = gtk_scrolled_window_new(NULL, NULL); +- setup_widget_prototype(gScrolledWindowWidget); +- } +- return MOZ_GTK_SUCCESS; +-} +- +-static void +-ensure_text_view_widget() +-{ +- if (gTextViewWidget) +- return; +- +- gTextViewWidget = gtk_text_view_new(); +- ensure_scrolled_window_widget(); +- gtk_container_add(GTK_CONTAINER(gScrolledWindowWidget), gTextViewWidget); +-} +- + gint + moz_gtk_init() { - ensure_radiobutton_widget(); - -- gtk_widget_style_get (gRadiobuttonWidget, -+ gtk_widget_style_get (gRadiobutton.widget, - "indicator_size", indicator_size, - "indicator_spacing", indicator_spacing, - NULL); -@@ -778,13 +986,12 @@ moz_gtk_get_focus_outline_size(gint* foc +@@ -729,26 +460,21 @@ moz_gtk_get_focus_outline_size(gint* foc { GtkBorder border; GtkBorder padding; - GtkStyleContext *style; -+ GtkStyleContext* style = gEntry.entry.style; - - ensure_entry_widget(); +- +- ensure_entry_widget(); - style = gtk_widget_get_style_context(gEntryWidget); - -- gtk_style_context_get_border(style, 0, &border); -- gtk_style_context_get_padding(style, 0, &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); +- ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_ENTRY); + gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); + gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); *focus_h_width = border.left + padding.left; *focus_v_width = border.top + padding.top; ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; -@@ -821,7 +1028,7 @@ moz_gtk_button_get_default_overflow(gint - GtkBorder* default_outside_border; - - ensure_button_widget(); -- gtk_widget_style_get(gButtonWidget, -+ gtk_widget_style_get(gButton.widget, - "default-outside-border", &default_outside_border, - NULL); - -@@ -844,7 +1051,7 @@ moz_gtk_button_get_default_border(gint* - GtkBorder* default_border; + } - ensure_button_widget(); -- gtk_widget_style_get(gButtonWidget, -+ gtk_widget_style_get(gButton.widget, - "default-border", &default_border, - NULL); + gint + moz_gtk_menuitem_get_horizontal_padding(gint* horizontal_padding) + { +- ensure_menu_item_widget(); +- +- gtk_style_context_get_style(gtk_widget_get_style_context(gMenuItemWidget), +- "horizontal-padding", horizontal_padding, +- NULL); ++ gtk_widget_style_get(GetWidget(MOZ_GTK_MENUITEM), ++ "horizontal-padding", horizontal_padding, ++ nullptr); -@@ -935,7 +1142,7 @@ moz_gtk_button_paint(cairo_t *cr, GdkRec - - if (state->focused) { - GtkBorder border; -- gtk_style_context_get_border(style, state_flags, &border); -+ moz_gtk_get_style_border(style, state_flags, &border); - x += border.left; - y += border.top; - width -= (border.left + border.right); -@@ -956,15 +1163,14 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec - gint indicator_size, indicator_spacing; - gint x, y, width, height; - gint focus_x, focus_y, focus_width, focus_height; -- GtkWidget *w; -- GtkStyleContext *style; -+ MozGtkWidget *w; + return MOZ_GTK_SUCCESS; + } +@@ -771,10 +497,11 @@ moz_gtk_button_get_default_overflow(gint + { + GtkBorder* default_outside_border; - if (isradio) { - moz_gtk_radio_get_metrics(&indicator_size, &indicator_spacing); -- w = gRadiobuttonWidget; -+ w = &gRadiobutton; - } else { - moz_gtk_checkbox_get_metrics(&indicator_size, &indicator_spacing); -- w = gCheckboxWidget; -+ w = &gCheckbox; - } +- ensure_button_widget(); +- gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget), ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON); ++ gtk_style_context_get_style(style, + "default-outside-border", &default_outside_border, + NULL); ++ ReleaseStyleContext(style); + + if (default_outside_border) { + *border_top = default_outside_border->top; +@@ -794,10 +521,11 @@ moz_gtk_button_get_default_border(gint* + { + GtkBorder* default_border; - // XXX we should assert rect->height >= indicator_size too -@@ -983,11 +1189,9 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec - focus_width = width + 2 * indicator_spacing; - focus_height = height + 2 * indicator_spacing; - -- style = gtk_widget_get_style_context(w); +- ensure_button_widget(); +- gtk_style_context_get_style(gtk_widget_get_style_context(gButtonWidget), ++ GtkStyleContext *style = ClaimStyleContext(MOZ_GTK_BUTTON); ++ gtk_style_context_get_style(style, + "default-border", &default_border, + NULL); ++ ReleaseStyleContext(style); + + if (default_border) { + *border_top = default_border->top; +@@ -831,17 +559,15 @@ static gint + moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect, + GtkTextDirection direction) + { +- GtkStyleContext* style; - -- gtk_widget_set_sensitive(w, !state->disabled); -- gtk_widget_set_direction(w, direction); -- gtk_style_context_save(style); -+ gtk_widget_set_sensitive(w->widget, !state->disabled); -+ gtk_widget_set_direction(w->widget, direction); -+ gtk_style_context_save(w->check.styleCheck); +- ensure_window_widget(); +- gtk_widget_set_direction(gProtoWindow, direction); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction); - if (selected) - state_flags |= checkbox_check_state; -@@ -995,13 +1199,15 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec - if (inconsistent) - state_flags |= GTK_STATE_FLAG_INCONSISTENT; +- style = gtk_widget_get_style_context(gProtoWindow); + gtk_style_context_save(style); + gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); + gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); + gtk_style_context_restore(style); -- gtk_style_context_set_state(style, state_flags); -+ gtk_style_context_set_state(w->check.styleCheck, state_flags); ++ ReleaseStyleContext(style); + -+ gtk_render_background(w->check.styleCheck, cr, x, y, width, height); -+ gtk_render_frame(w->check.styleCheck, cr, x, y, width, height); - - if (isradio) { -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO); -- gtk_render_option(style, cr, x, y, width, height); -+ gtk_render_option(w->check.styleCheck, cr, x, y, width, height); - if (state->focused) { -- gtk_render_focus(style, cr, focus_x, focus_y, -+ gtk_render_focus(w->check.styleCheck, cr, focus_x, focus_y, - focus_width, focus_height); - } - } -@@ -1010,15 +1216,14 @@ moz_gtk_toggle_paint(cairo_t *cr, GdkRec - * 'indeterminate' type on checkboxes. In GTK, the shadow type - * must also be changed for the state to be drawn. - */ -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK); -- gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(gCheckboxWidget), inconsistent); -- gtk_render_check(style, cr, x, y, width, height); -+ gtk_toggle_button_set_inconsistent(GTK_TOGGLE_BUTTON(w->widget), inconsistent); -+ gtk_render_check(w->check.styleCheck, cr, x, y, width, height); - if (state->focused) { -- gtk_render_focus(style, cr, -+ gtk_render_focus(w->check.styleCheck, cr, - focus_x, focus_y, focus_width, focus_height); - } - } -- gtk_style_context_restore(style); -+ gtk_style_context_restore(w->check.styleCheck); + return MOZ_GTK_SUCCESS; + } +@@ -1118,6 +844,36 @@ moz_gtk_scrollbar_button_paint(cairo_t * return MOZ_GTK_SUCCESS; } -@@ -1035,8 +1240,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, 0, &border); -- gtk_style_context_get_padding(style, 0, &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; -@@ -1099,9 +1304,9 @@ moz_gtk_scrollbar_button_paint(cairo_t * - ensure_scrollbar_widget(); - - if (flags & MOZ_GTK_STEPPER_VERTICAL) -- scrollbar = gVertScrollbarWidget; -+ scrollbar = gVertScrollbar.widget; - else -- scrollbar = gHorizScrollbarWidget; -+ scrollbar = gHorizScrollbar.widget; - - gtk_widget_set_direction(scrollbar, direction); - -@@ -1181,25 +1386,22 @@ moz_gtk_scrollbar_trough_paint(GtkThemeW + ++static void ++moz_gtk_update_scrollbar_style(GtkStyleContext* style, ++ WidgetNodeType widget, ++ GtkTextDirection direction) ++{ ++ if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) { ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_BOTTOM); ++ } else { ++ if (direction == GTK_TEXT_DIR_LTR) { ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_RIGHT); ++ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_LEFT); ++ } else { ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_LEFT); ++ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_RIGHT); ++ } ++ } ++} ++ ++static void ++moz_gtk_draw_styled_frame(GtkStyleContext* style, cairo_t *cr, ++ GdkRectangle* rect, bool drawFocus) ++{ ++ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); ++ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); ++ if (drawFocus) { ++ gtk_render_focus(style, cr, ++ rect->x, rect->y, rect->width, rect->height); ++ } ++} ++ + static gint + moz_gtk_scrollbar_trough_paint(WidgetNodeType widget, + cairo_t *cr, GdkRectangle* rect, +@@ -1126,26 +882,34 @@ moz_gtk_scrollbar_trough_paint(WidgetNod GtkTextDirection direction) { - GtkStyleContext* style; -- GtkScrollbar *scrollbar; - - ensure_scrollbar_widget(); - -- if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) -- scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget); -- else -- scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget); -- -- gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction); -- if (flags & MOZ_GTK_TRACK_OPAQUE) { - style = gtk_widget_get_style_context(GTK_WIDGET(gProtoWindow)); - gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); +- GtkStyleContext* style = +- gtk_widget_get_style_context(GTK_WIDGET(gProtoWindow)); +- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_WINDOW, direction); ++ gtk_render_background(style, cr, ++ rect->x, rect->y, rect->width, rect->height); ++ ReleaseStyleContext(style); } -- style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar)); -- gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH); -+ if (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL) { -+ gtk_widget_set_direction(GTK_WIDGET(gHorizScrollbar.widget), direction); -+ style = gHorizScrollbar.scroll.style; -+ } -+ else { -+ gtk_widget_set_direction(GTK_WIDGET(gVertScrollbar.widget), direction); -+ style = gVertScrollbar.scroll.style; -+ } +- GtkStyleContext* style = +- ClaimStyleContext(widget == MOZ_GTK_SCROLLBAR_HORIZONTAL ? +- MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL : +- MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL, +- direction); +- // TODO - integate with ClaimStyleContext()? +- gtk_style_context_set_direction(style, direction); ++ bool isHorizontal = (widget == MOZ_GTK_SCROLLBAR_HORIZONTAL); ++ GtkStyleContext* style; - gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); - gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); -@@ -1208,7 +1410,6 @@ moz_gtk_scrollbar_trough_paint(GtkThemeW - gtk_render_focus(style, cr, - rect->x, rect->y, rect->width, rect->height); +- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); +- gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); ++ // Draw all child CSS Nodes for Gtk >= 3.20 ++ if (gtk_check_version(3, 20, 0) == nullptr) { ++ style = ClaimStyleContext(widget, direction); ++ moz_gtk_update_scrollbar_style(style, widget, direction); ++ moz_gtk_draw_styled_frame(style, cr, rect, state->focused); ++ ReleaseStyleContext(style); + +- if (state->focused) { +- gtk_render_focus(style, cr, +- rect->x, rect->y, rect->width, rect->height); ++ style = ClaimStyleContext(isHorizontal ? ++ MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL : ++ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL, ++ direction); ++ moz_gtk_draw_styled_frame(style, cr, rect, state->focused); ++ ReleaseStyleContext(style); } -- gtk_style_context_restore(style); - return MOZ_GTK_SUCCESS; - } ++ style = ClaimStyleContext(isHorizontal ? ++ MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL : ++ MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL, ++ direction); ++ moz_gtk_draw_styled_frame(style, cr, rect, state->focused); + ReleaseStyleContext(style); -@@ -1220,24 +1421,20 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWi - { + return MOZ_GTK_SUCCESS; +@@ -1160,12 +924,7 @@ moz_gtk_scrollbar_thumb_paint(WidgetNode GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - GtkStyleContext* style; -- GtkScrollbar *scrollbar; GtkBorder margin; - ensure_scrollbar_widget(); - -- if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) -- scrollbar = GTK_SCROLLBAR(gHorizScrollbarWidget); -- else -- scrollbar = GTK_SCROLLBAR(gVertScrollbarWidget); +- GtkStyleContext* style = ClaimStyleContext(widget, direction); - -- gtk_widget_set_direction(GTK_WIDGET(scrollbar), direction); -- -- style = gtk_widget_get_style_context(GTK_WIDGET(scrollbar)); -- gtk_style_context_save(style); -+ if (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) { -+ style = gHorizScrollbar.scroll.styleSlider; -+ gtk_widget_set_direction(GTK_WIDGET(gHorizScrollbar.widget), direction); -+ } -+ else { -+ style = gVertScrollbar.scroll.styleSlider; -+ gtk_widget_set_direction(GTK_WIDGET(gVertScrollbar.widget), direction); -+ } - -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER); - gtk_style_context_set_state(style, state_flags); +- // TODO - integate those with ClaimStyleContext()? +- gtk_style_context_set_state(style, state_flags); +- gtk_style_context_set_direction(style, direction); - ++ GtkStyleContext* style = ClaimStyleContext(widget, direction, state_flags); gtk_style_context_get_margin (style, state_flags, &margin); gtk_render_slider(style, cr, -@@ -1248,8 +1445,6 @@ moz_gtk_scrollbar_thumb_paint(GtkThemeWi - (widget == MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL) ? - GTK_ORIENTATION_HORIZONTAL : GTK_ORIENTATION_VERTICAL); - -- gtk_style_context_restore(style); +@@ -1185,17 +944,10 @@ static gint + moz_gtk_spin_paint(cairo_t *cr, GdkRectangle* rect, + GtkTextDirection direction) + { +- GtkStyleContext* style; - - return MOZ_GTK_SUCCESS; - } - -@@ -1260,8 +1455,8 @@ moz_gtk_spin_paint(cairo_t *cr, GdkRecta - GtkStyleContext* style; - - ensure_spin_widget(); +- ensure_spin_widget(); - gtk_widget_set_direction(gSpinWidget, direction); - style = gtk_widget_get_style_context(gSpinWidget); -+ gtk_widget_set_direction(gSpin.widget, direction); -+ style = gSpin.spin.style; - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction); gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); -@@ -1280,11 +1475,10 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G - GtkStyleContext* style; + gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); +- gtk_style_context_restore(style); +- ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } - ensure_spin_widget(); +@@ -1204,21 +956,14 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G + gboolean isDown, GtkWidgetState* state, + GtkTextDirection direction) + { +- GdkRectangle arrow_rect; +- GtkStyleContext* style; +- +- ensure_spin_widget(); - style = gtk_widget_get_style_context(gSpinWidget); -+ style = gSpin.spin.style; - gtk_style_context_save(style); +- gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_SPINBUTTON); - gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); +- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); - gtk_widget_set_direction(gSpinWidget, direction); -+ gtk_widget_set_direction(gSpin.widget, direction); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_SPINBUTTON, direction, ++ GetStateFlagsFromGtkWidgetState(state)); gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); -@@ -1450,15 +1644,13 @@ moz_gtk_vpaned_paint(cairo_t *cr, GdkRec - static gint - moz_gtk_entry_paint(cairo_t *cr, GdkRectangle* rect, - GtkWidgetState* state, -- GtkWidget* widget, GtkTextDirection direction) -+ MozGtkWidget* w, GtkTextDirection direction) + +- + /* hard code these values */ ++ GdkRectangle arrow_rect; + arrow_rect.width = 6; + arrow_rect.height = 6; + arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2; +@@ -1229,7 +974,8 @@ moz_gtk_spin_updown_paint(cairo_t *cr, G + isDown ? ARROW_DOWN : ARROW_UP, + arrow_rect.x, arrow_rect.y, + arrow_rect.width); +- gtk_style_context_restore(style); ++ ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } + +@@ -1295,8 +1041,8 @@ moz_gtk_scale_thumb_paint(cairo_t *cr, G + gtk_widget_set_direction(widget, direction); + + style = gtk_widget_get_style_context(widget); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER); + gtk_style_context_save(style); ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_SLIDER); + gtk_style_context_set_state(style, state_flags); + /* determine the thumb size, and position the thumb in the center in the opposite axis + */ +@@ -1321,20 +1067,12 @@ moz_gtk_gripper_paint(cairo_t *cr, GdkRe + GtkWidgetState* state, + GtkTextDirection direction) { - gint x = rect->x, y = rect->y, width = rect->width, height = rect->height; - GtkStyleContext* style; - int draw_focus_outline_only = state->depressed; // NS_THEME_FOCUS_OUTLINE -+ GtkStyleContext* style = w->entry.style; - -- gtk_widget_set_direction(widget, direction); - -- style = gtk_widget_get_style_context(widget); -+ gtk_widget_set_direction(w->widget, direction); +- ensure_handlebox_widget(); +- gtk_widget_set_direction(gHandleBoxWidget, direction); +- +- style = gtk_widget_get_style_context(gHandleBoxWidget); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); +- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); +- ++ GtkStyleContext* style = ++ ClaimStyleContext(MOZ_GTK_GRIPPER, direction, ++ GetStateFlagsFromGtkWidgetState(state)); + gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); + gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); +- gtk_style_context_restore(style); +- ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } - if (draw_focus_outline_only) { - // Inflate the given 'rect' with the focus outline size. -@@ -1478,10 +1670,9 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect - * textarea window uses gtk_paint_flat_box when exposed */ +@@ -1435,6 +1173,38 @@ moz_gtk_entry_paint(cairo_t *cr, GdkRect + return MOZ_GTK_SUCCESS; + } - /* This gets us a lovely greyish disabledish look */ -- gtk_widget_set_sensitive(widget, !state->disabled); -+ gtk_widget_set_sensitive(w->widget, !state->disabled); ++static gint ++moz_gtk_text_view_paint(cairo_t *cr, GdkRectangle* rect, ++ GtkWidgetState* state, ++ GtkTextDirection direction) ++{ ++ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); ++ ++ GtkStyleContext* style_frame = ++ ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction, state_flags); ++ gtk_render_frame(style_frame, cr, rect->x, rect->y, rect->width, rect->height); ++ ++ GtkBorder border, padding; ++ gtk_style_context_get_border(style_frame, state_flags, &border); ++ gtk_style_context_get_padding(style_frame, state_flags, &padding); ++ ReleaseStyleContext(style_frame); ++ ++ GtkStyleContext* style = ++ ClaimStyleContext(MOZ_GTK_TEXT_VIEW, direction, state_flags); ++ ++ gint xthickness = border.left + padding.left; ++ gint ythickness = border.top + padding.top; ++ ++ gtk_render_background(style, cr, ++ rect->x + xthickness, rect->y + ythickness, ++ rect->width - 2 * xthickness, ++ rect->height - 2 * ythickness); ++ ++ ReleaseStyleContext(style); ++ ++ return MOZ_GTK_SUCCESS; ++} ++ + static gint + moz_gtk_treeview_paint(cairo_t *cr, GdkRectangle* rect, + GtkWidgetState* state, +@@ -1447,18 +1217,13 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR + GtkBorder border; - gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_ENTRY); - - /* Now paint the shadow and focus border. - * We do like in gtk_entry_draw_frame, we first draw the shadow, a tad -@@ -1531,7 +1722,7 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR - style = gtk_widget_get_style_context(gScrolledWindowWidget); - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME); -- gtk_style_context_get_border(style, state_flags, &border); -+ moz_gtk_get_style_border(style, state_flags, &border); + ensure_tree_view_widget(); +- ensure_scrolled_window_widget(); +- + gtk_widget_set_direction(gTreeViewWidget, direction); +- gtk_widget_set_direction(gScrolledWindowWidget, direction); + + /* only handle disabled and normal states, otherwise the whole background + * area will be painted differently with other states */ + state_flags = state->disabled ? GTK_STATE_FLAG_INSENSITIVE : GTK_STATE_FLAG_NORMAL; + +- style = gtk_widget_get_style_context(gScrolledWindowWidget); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME); ++ style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW, direction); + gtk_style_context_get_border(style, state_flags, &border); xthickness = border.left; ythickness = border.top; - -@@ -1702,7 +1893,7 @@ moz_gtk_combo_box_paint(cairo_t *cr, Gdk - if (direction == GTK_TEXT_DIR_LTR) { - GtkBorder padding; - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); -- gtk_style_context_get_padding(style, state_flags, &padding); -+ moz_gtk_get_style_padding(style, state_flags, &padding); - arrow_rect.x -= padding.left; - } - else -@@ -1804,29 +1995,27 @@ moz_gtk_container_paint(cairo_t *cr, Gdk - gboolean isradio, GtkTextDirection direction) +@@ -1473,7 +1238,7 @@ moz_gtk_treeview_paint(cairo_t *cr, GdkR + rect->height - 2 * ythickness); + gtk_render_frame(style, cr, + rect->x, rect->y, rect->width, rect->height); +- gtk_style_context_restore(style); ++ ReleaseStyleContext(style); + gtk_style_context_restore(style_tree); + return MOZ_GTK_SUCCESS; + } +@@ -1648,20 +1413,9 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect + GtkWidgetState* state, + GtkArrowType arrow_type, GtkTextDirection direction) { - GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); - GtkStyleContext* style; -- GtkWidget *widget; -+ MozGtkWidget *widget; - - if (isradio) { - ensure_radiobutton_widget(); -- widget = gRadiobuttonWidget; -+ widget = &gRadiobutton; - } else { - ensure_checkbox_widget(); -- widget = gCheckboxWidget; -+ widget = &gCheckbox; - } -- gtk_widget_set_direction(widget, direction); -+ gtk_widget_set_direction(widget->widget, direction); +- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); + GdkRectangle arrow_rect; + gdouble arrow_angle; -- style = gtk_widget_get_style_context(widget); +- ensure_button_arrow_widget(); +- style = gtk_widget_get_style_context(gButtonArrowWidget); - gtk_style_context_save(style); - gtk_style_context_set_state(style, state_flags); -+ gtk_style_context_save(widget->check.style); -+ gtk_style_context_set_state(widget->check.style, state_flags); - - /* this is for drawing a prelight box */ - if (state_flags & GTK_STATE_FLAG_PRELIGHT) { -- gtk_render_background(style, cr, -+ gtk_render_background(widget->check.style, cr, - rect->x, rect->y, rect->width, rect->height); +- gtk_widget_set_direction(gButtonArrowWidget, direction); +- +- calculate_arrow_rect(gButtonArrowWidget, rect, &arrow_rect, +- direction); +- + if (direction == GTK_TEXT_DIR_RTL) { + arrow_type = (arrow_type == GTK_ARROW_LEFT) ? + GTK_ARROW_RIGHT : GTK_ARROW_LEFT; +@@ -1680,10 +1434,17 @@ moz_gtk_arrow_paint(cairo_t *cr, GdkRect + arrow_angle = ARROW_UP; + break; } - +- if (arrow_type != GTK_ARROW_NONE) +- gtk_render_arrow(style, cr, arrow_angle, +- arrow_rect.x, arrow_rect.y, arrow_rect.width); - gtk_style_context_restore(style); -+ gtk_style_context_restore(widget->check.style); - ++ if (arrow_type == GTK_ARROW_NONE) ++ return MOZ_GTK_SUCCESS; ++ ++ calculate_arrow_rect(GetWidget(MOZ_GTK_BUTTON_ARROW), rect, &arrow_rect, ++ direction); ++ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_BUTTON_ARROW, ++ direction, state_flags); ++ gtk_render_arrow(style, cr, arrow_angle, ++ arrow_rect.x, arrow_rect.y, arrow_rect.width); ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -1836,32 +2025,26 @@ moz_gtk_toggle_label_paint(cairo_t *cr, - GtkWidgetState* state, - gboolean isradio, GtkTextDirection direction) - { -- GtkStyleContext *style; -- GtkWidget *widget; -+ MozGtkWidget *widget; - if (!state->focused) - return MOZ_GTK_SUCCESS; +@@ -1776,19 +1537,10 @@ static gint + moz_gtk_toolbar_paint(cairo_t *cr, GdkRectangle* rect, + GtkTextDirection direction) + { +- GtkStyleContext* style; +- +- ensure_toolbar_widget(); +- gtk_widget_set_direction(gToolbarWidget, direction); +- +- style = gtk_widget_get_style_context(gToolbarWidget); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLBAR); +- ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR, direction); + gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); + gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); +- gtk_style_context_restore(style); +- ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } - if (isradio) { - ensure_radiobutton_widget(); -- widget = gRadiobuttonWidget; -+ widget = &gRadiobutton; - } else { - ensure_checkbox_widget(); -- widget = gCheckboxWidget; -+ widget = &gCheckbox; +@@ -1798,7 +1550,6 @@ static gint + moz_gtk_toolbar_separator_paint(cairo_t *cr, GdkRectangle* rect, + GtkTextDirection direction) + { +- GtkStyleContext* style; + gint separator_width; + gint paint_width; + gboolean wide_separators; +@@ -1807,16 +1558,14 @@ moz_gtk_toolbar_separator_paint(cairo_t + const double start_fraction = 0.2; + const double end_fraction = 0.8; + +- ensure_toolbar_separator_widget(); +- gtk_widget_set_direction(gToolbarSeparatorWidget, direction); +- +- style = gtk_widget_get_style_context(gToolbarSeparatorWidget); +- +- gtk_style_context_get_style(gtk_widget_get_style_context(gToolbarWidget), ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR); ++ gtk_style_context_get_style(style, + "wide-separators", &wide_separators, + "separator-width", &separator_width, + NULL); ++ ReleaseStyleContext(style); + ++ style = ClaimStyleContext(MOZ_GTK_TOOLBAR_SEPARATOR, direction); + if (wide_separators) { + if (separator_width > rect->width) + separator_width = rect->width; +@@ -1840,7 +1589,7 @@ moz_gtk_toolbar_separator_paint(cairo_t + rect->x + (rect->width - paint_width) / 2, + rect->y + rect->height * end_fraction); } -- style = gtk_widget_get_style_context(widget); -- gtk_style_context_save(style); -- if (isradio) { -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_RADIO); -- } else { -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_CHECK); -- } -- gtk_widget_set_direction(widget, direction); -+ gtk_style_context_save(widget->check.styleLabel); -+ gtk_widget_set_direction(widget->widget, direction); +- ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } + +@@ -1848,14 +1597,10 @@ static gint + moz_gtk_tooltip_paint(cairo_t *cr, GdkRectangle* rect, + GtkTextDirection direction) + { +- GtkStyleContext* style; +- +- ensure_tooltip_widget(); +- gtk_widget_set_direction(gTooltipWidget, direction); +- +- style = gtk_widget_get_style_context(gTooltipWidget); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLTIP, direction); + gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); + gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } +@@ -1870,14 +1615,11 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe + // GTK_STYLE_CLASS_VIEW to match the background with textarea elements. + // The resizer is drawn with shaded variants of the background color, and + // so a transparent background would lead to a transparent resizer. +- ensure_text_view_widget(); +- gtk_widget_set_direction(gTextViewWidget, GTK_TEXT_DIR_LTR); +- +- style = gtk_widget_get_style_context(gTextViewWidget); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW); ++ style = ClaimStyleContext(MOZ_GTK_TEXT_VIEW, GTK_TEXT_DIR_LTR, ++ GetStateFlagsFromGtkWidgetState(state)); ++ // TODO - we need to save/restore style when gtk 3.20 CSS node path ++ // is used + gtk_style_context_add_class(style, GTK_STYLE_CLASS_GRIP); - gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); -- gtk_render_focus(style, cr, -+ gtk_style_context_set_state(widget->check.styleLabel, -+ GetStateFlagsFromGtkWidgetState(state)); -+ gtk_render_focus(widget->check.styleLabel, cr, - rect->x, rect->y, rect->width, rect->height); + + // Workaround unico not respecting the text direction for resizers. + // See bug 1174248. +@@ -1891,7 +1633,7 @@ moz_gtk_resizer_paint(cairo_t *cr, GdkRe + + gtk_render_handle(style, cr, rect->x, rect->y, rect->width, rect->height); + cairo_restore(cr); - gtk_style_context_restore(style); -+ gtk_style_context_restore(widget->check.styleLabel); ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -1922,7 +2105,7 @@ moz_gtk_toolbar_separator_paint(cairo_t - rect->height * (end_fraction - start_fraction)); - } else { - GtkBorder padding; -- gtk_style_context_get_padding(style, 0, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); - - paint_width = padding.left; - if (paint_width > rect->width) -@@ -2006,18 +2189,13 @@ static gint +@@ -1900,16 +1642,9 @@ static gint + moz_gtk_frame_paint(cairo_t *cr, GdkRectangle* rect, + GtkTextDirection direction) + { +- GtkStyleContext* style; +- +- ensure_frame_widget(); +- gtk_widget_set_direction(gFrameWidget, direction); +- style = gtk_widget_get_style_context(gFrameWidget); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME); +- ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_FRAME, direction); + gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); +- gtk_style_context_restore(style); ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } + +@@ -1917,18 +1652,11 @@ static gint moz_gtk_progressbar_paint(cairo_t *cr, GdkRectangle* rect, GtkTextDirection direction) { - GtkStyleContext* style; - - ensure_progress_widget(); +- ensure_progress_widget(); - gtk_widget_set_direction(gProgressWidget, direction); -+ gtk_widget_set_direction(gProgressBar.widget, direction); - +- - style = gtk_widget_get_style_context(gProgressWidget); - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH); - -- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); -- gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH, ++ direction); + gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); + gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); - gtk_style_context_restore(style); -+ gtk_render_background(gProgressBar.progress.styleTrough, cr, -+ rect->x, rect->y, rect->width, rect->height); -+ gtk_render_frame(gProgressBar.progress.styleTrough, cr, -+ rect->x, rect->y, rect->width, rect->height); ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -2027,15 +2205,8 @@ moz_gtk_progress_chunk_paint(cairo_t *cr - GtkTextDirection direction, - GtkThemeWidgetType widget) +@@ -1940,13 +1668,15 @@ moz_gtk_progress_chunk_paint(cairo_t *cr { -- GtkStyleContext* style; -- - ensure_progress_widget(); + GtkStyleContext* style; + +- ensure_progress_widget(); - gtk_widget_set_direction(gProgressWidget, direction); - - style = gtk_widget_get_style_context(gProgressWidget); - gtk_style_context_save(style); - gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR); -+ gtk_widget_set_direction(gProgressBar.widget, direction); ++ if (gtk_check_version(3, 20, 0) != nullptr) { ++ /* Ask for MOZ_GTK_PROGRESS_TROUGH instead of MOZ_GTK_PROGRESSBAR ++ * because ClaimStyleContext() saves/restores that style */ ++ style = ClaimStyleContext(MOZ_GTK_PROGRESS_TROUGH, direction); ++ gtk_style_context_remove_class(style, GTK_STYLE_CLASS_TROUGH); ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_PROGRESSBAR); ++ } else { ++ style = ClaimStyleContext(MOZ_GTK_PROGRESS_CHUNK, direction); ++ } if (widget == MOZ_GTK_PROGRESS_CHUNK_INDETERMINATE || widget == MOZ_GTK_PROGRESS_CHUNK_VERTICAL_INDETERMINATE) { -@@ -2074,12 +2245,14 @@ moz_gtk_progress_chunk_paint(cairo_t *cr - // gtk_render_activity was used to render progress chunks on GTK versions - // before 3.13.7, see bug 1173907. - if (!gtk_check_version(3, 13, 7)) { -- gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); -- gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); -+ gtk_render_background(gProgressBar.progress.styleProgress, cr, -+ rect->x, rect->y, rect->width, rect->height); -+ gtk_render_frame(gProgressBar.progress.styleProgress, cr, -+ rect->x, rect->y, rect->width, rect->height); +@@ -1990,7 +1720,7 @@ moz_gtk_progress_chunk_paint(cairo_t *cr } else { -- gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height); -+ gtk_render_activity(gProgressBar.progress.styleProgress, cr, -+ rect->x, rect->y, rect->width, rect->height); + gtk_render_activity(style, cr, rect->x, rect->y, rect->width, rect->height); } - gtk_style_context_restore(style); ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -2096,7 +2269,7 @@ moz_gtk_get_tab_thickness(void) +@@ -2324,10 +2054,10 @@ moz_gtk_menu_bar_paint(cairo_t *cr, GdkR + { + GtkStyleContext* style; + +- ensure_menu_bar_widget(); +- gtk_widget_set_direction(gMenuBarWidget, direction); ++ GtkWidget* widget = GetWidget(MOZ_GTK_MENUBAR); ++ gtk_widget_set_direction(widget, direction); - style = gtk_widget_get_style_context(gTabWidget); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_NOTEBOOK); -- gtk_style_context_get_border(style, 0, &border); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); +- style = gtk_widget_get_style_context(gMenuBarWidget); ++ style = gtk_widget_get_style_context(widget); + gtk_style_context_save(style); + gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR); + gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height); +@@ -2343,14 +2073,14 @@ moz_gtk_menu_popup_paint(cairo_t *cr, Gd + { + GtkStyleContext* style; - if (border.top < 2) - return 2; /* some themes don't set ythickness correctly */ -@@ -2292,7 +2465,7 @@ moz_gtk_tab_paint(cairo_t *cr, GdkRectan - gtk_style_context_save(style); - moz_gtk_tab_prepare_style_context(style, flags); +- ensure_menu_popup_widget(); +- gtk_widget_set_direction(gMenuPopupWidget, direction); ++ GtkWidget* widget = GetWidget(MOZ_GTK_MENUPOPUP); ++ gtk_widget_set_direction(widget, direction); -- gtk_style_context_get_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding); -+ moz_gtk_get_style_padding(style, GetStateFlagsFromGtkWidgetState(state), &padding); + // Draw a backing toplevel. This fixes themes that don't provide a menu + // background, and depend on the GtkMenu's implementation window to provide it. + moz_gtk_window_paint(cr, rect, direction); - focusRect.x += padding.left; - focusRect.width -= (padding.left + padding.right); -@@ -2408,7 +2581,7 @@ moz_gtk_tab_scroll_arrow_paint(cairo_t * - } +- style = gtk_widget_get_style_context(gMenuPopupWidget); ++ style = gtk_widget_get_style_context(widget); + gtk_style_context_save(style); + gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENU); - static gint --moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect, -+moz_gtk_menu_bar_paint(cairo_t *cr, GdkRectangle* rect, GtkWidgetState* state, - GtkTextDirection direction) - { - GtkStyleContext* style; -@@ -2468,7 +2641,7 @@ moz_gtk_menu_separator_paint(cairo_t *cr - border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget)); +@@ -2373,12 +2103,10 @@ moz_gtk_menu_separator_paint(cairo_t *cr + gint x, y, w; + GtkBorder padding; - style = gtk_widget_get_style_context(gMenuSeparatorWidget); -- gtk_style_context_get_padding(style, 0, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); +- ensure_menu_separator_widget(); +- gtk_widget_set_direction(gMenuSeparatorWidget, direction); +- +- border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget)); +- +- style = gtk_widget_get_style_context(gMenuSeparatorWidget); ++ border_width = ++ gtk_container_get_border_width(GTK_CONTAINER( ++ GetWidget(MOZ_GTK_MENUSEPARATOR))); ++ style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR, direction); + gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); x = rect->x + border_width; - y = rect->y + border_width; -@@ -2521,7 +2694,8 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk - item_widget = gMenuItemWidget; - } - style = gtk_widget_get_style_context(item_widget); +@@ -2408,42 +2136,36 @@ moz_gtk_menu_separator_paint(cairo_t *cr + } + + gtk_style_context_restore(style); ++ ReleaseStyleContext(style); + + return MOZ_GTK_SUCCESS; + } + + // See gtk_menu_item_draw() for reference. + static gint +-moz_gtk_menu_item_paint(cairo_t *cr, GdkRectangle* rect, +- GtkWidgetState* state, +- gint flags, GtkTextDirection direction) ++moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect, ++ GtkWidgetState* state, GtkTextDirection direction) + { +- GtkStyleContext* style; +- GtkWidget* item_widget; +- guint border_width; + gint x, y, w, h; + + if (state->inHover && !state->disabled) { +- if (flags & MOZ_TOPLEVEL_MENU_ITEM) { +- ensure_menu_bar_item_widget(); +- item_widget = gMenuBarItemWidget; +- } else { +- ensure_menu_item_widget(); +- item_widget = gMenuItemWidget; +- } +- style = gtk_widget_get_style_context(item_widget); - gtk_style_context_save(style); -+// TODO - FIX! -+// gtk_style_context_save(style); ++ guint border_width = ++ gtk_container_get_border_width(GTK_CONTAINER(GetWidget(widget))); ++ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); ++ GtkStyleContext* style = ++ ClaimStyleContext(widget, direction, state_flags); + +- if (flags & MOZ_TOPLEVEL_MENU_ITEM) { +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR); ++ bool pre_3_6 = gtk_check_version(3, 6, 0) != nullptr; ++ if (pre_3_6) { ++ // GTK+ 3.4 saves the style context and adds the menubar class to ++ // menubar children, but does each of these only when drawing, not ++ // during layout. ++ gtk_style_context_save(style); ++ if (widget == MOZ_GTK_MENUBARITEM) { ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR); ++ } + } - if (flags & MOZ_TOPLEVEL_MENU_ITEM) { - gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUBAR); -@@ -2540,7 +2714,7 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk +- gtk_widget_set_direction(item_widget, direction); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM); +- gtk_style_context_set_state(style, GetStateFlagsFromGtkWidgetState(state)); +- +- border_width = gtk_container_get_border_width(GTK_CONTAINER(item_widget)); +- + x = rect->x + border_width; + y = rect->y + border_width; + w = rect->width - border_width * 2; +@@ -2451,7 +2173,11 @@ moz_gtk_menu_item_paint(cairo_t *cr, Gdk gtk_render_background(style, cr, x, y, w, h); gtk_render_frame(style, cr, x, y, w, h); - gtk_style_context_restore(style); -+// gtk_style_context_restore(style); ++ ++ if (pre_3_6) { ++ gtk_style_context_restore(style); ++ } ++ ReleaseStyleContext(style); } return MOZ_GTK_SUCCESS; -@@ -2556,7 +2730,10 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd - - ensure_menu_item_widget(); - gtk_widget_set_direction(gMenuItemWidget, direction); -- -+/* -+ state_flags |= (direction == GTK_TEXT_DIR_LTR) ? GTK_STATE_FLAG_DIR_LTR : -+ GTK_STATE_FLAG_DIR_RTL; -+*/ - style = gtk_widget_get_style_context(gMenuItemWidget); - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM); -@@ -2606,7 +2783,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c - } - - gtk_style_context_set_state(style, state_flags); -- gtk_style_context_get_padding(style, state_flags, &padding); -+ moz_gtk_get_style_padding(style, state_flags, &padding); - - offset = gtk_container_get_border_width(GTK_CONTAINER(gCheckMenuItemWidget)) + - padding.left + 2; -@@ -2658,7 +2835,7 @@ moz_gtk_add_style_border(GtkStyleContext +@@ -2462,21 +2188,13 @@ moz_gtk_menu_arrow_paint(cairo_t *cr, Gd + GtkWidgetState* state, + GtkTextDirection direction) { - GtkBorder border; +- GtkStyleContext* style; + GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); +- +- ensure_menu_item_widget(); +- gtk_widget_set_direction(gMenuItemWidget, direction); +- +- style = gtk_widget_get_style_context(gMenuItemWidget); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_MENUITEM); +- gtk_style_context_set_state(style, state_flags); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_MENUITEM, ++ direction, state_flags); + gtk_render_arrow(style, cr, + (direction == GTK_TEXT_DIR_LTR) ? ARROW_RIGHT : ARROW_LEFT, + rect->x, rect->y, rect->width); +- gtk_style_context_restore(style); +- ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } -- gtk_style_context_get_border(style, 0, &border); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); +@@ -2494,7 +2212,7 @@ moz_gtk_check_menu_item_paint(cairo_t *c + gint indicator_size, horizontal_padding; + gint x, y; - *left += border.left; - *right += border.right; -@@ -2667,12 +2844,22 @@ moz_gtk_add_style_border(GtkStyleContext - } +- moz_gtk_menu_item_paint(cr, rect, state, FALSE, direction); ++ moz_gtk_menu_item_paint(MOZ_GTK_MENUITEM, cr, rect, state, direction); - static void -+moz_gtk_get_style_border(GtkStyleContext* style, GtkStateFlags state_flags, -+ GtkBorder *border) -+{ -+ gtk_style_context_save(style); -+ gtk_style_context_set_state(style, state_flags); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), border); -+ gtk_style_context_restore(style); -+} -+ -+static void - moz_gtk_add_style_padding(GtkStyleContext* style, - gint* left, gint* top, gint* right, gint* bottom) + ensure_check_menu_item_widget(); + gtk_widget_set_direction(gCheckMenuItemWidget, direction); +@@ -2545,21 +2263,13 @@ static gint + moz_gtk_info_bar_paint(cairo_t *cr, GdkRectangle* rect, + GtkWidgetState* state) { - GtkBorder padding; - -- gtk_style_context_get_padding(style, 0, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); +- GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state); +- GtkStyleContext *style; +- ensure_info_bar(); +- +- style = gtk_widget_get_style_context(gInfoBar); +- gtk_style_context_save(style); +- +- gtk_style_context_set_state(style, state_flags); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO); +- ++ GtkStyleContext *style = ++ ClaimStyleContext(MOZ_GTK_INFO_BAR, GTK_TEXT_DIR_LTR, ++ GetStateFlagsFromGtkWidgetState(state)); + gtk_render_background(style, cr, rect->x, rect->y, rect->width, + rect->height); + gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height); +- +- gtk_style_context_restore(style); ++ ReleaseStyleContext(style); - *left += padding.left; - *right += padding.right; -@@ -2680,6 +2867,16 @@ moz_gtk_add_style_padding(GtkStyleContex - *bottom += padding.bottom; + return MOZ_GTK_SUCCESS; } - -+static void -+moz_gtk_get_style_padding(GtkStyleContext* style, GtkStateFlags state_flags, -+ GtkBorder *padding) -+{ -+ gtk_style_context_save(style); -+ gtk_style_context_set_state(style, state_flags); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), padding); -+ gtk_style_context_restore(style); -+} -+ - gint - moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top, - gint* right, gint* bottom, GtkTextDirection direction, -@@ -2694,36 +2891,27 @@ moz_gtk_get_widget_border(GtkThemeWidget +@@ -2605,18 +2315,18 @@ moz_gtk_get_widget_border(WidgetNodeType + case MOZ_GTK_BUTTON: case MOZ_GTK_TOOLBAR_BUTTON: { - ensure_button_widget(); +- ensure_button_widget(); - style = gtk_widget_get_style_context(gButtonWidget); -- ++ style = ClaimStyleContext(MOZ_GTK_BUTTON); + - *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButtonWidget)); ++ *left = *top = *right = *bottom = ++ gtk_container_get_border_width(GTK_CONTAINER(GetWidget(MOZ_GTK_BUTTON))); -- if (widget == MOZ_GTK_TOOLBAR_BUTTON) { -- gtk_style_context_save(style); -- gtk_style_context_add_class(style, "image-button"); -- } + if (widget == MOZ_GTK_TOOLBAR_BUTTON) { + gtk_style_context_save(style); + gtk_style_context_add_class(style, "image-button"); + } - -- moz_gtk_add_style_padding(style, left, top, right, bottom); ++ + moz_gtk_add_style_padding(style, left, top, right, bottom); - -- if (widget == MOZ_GTK_TOOLBAR_BUTTON) -- gtk_style_context_restore(style); -+ *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(gButton.widget)); -+ moz_gtk_add_style_padding(gButton.button.style, left, top, right, bottom); ++ + if (widget == MOZ_GTK_TOOLBAR_BUTTON) + gtk_style_context_restore(style); - // XXX: Subtract 1 pixel from the border to account for the added +@@ -2624,12 +2334,13 @@ moz_gtk_get_widget_border(WidgetNodeType // -moz-focus-inner border (Bug 1228281). *left -= 1; *top -= 1; *right -= 1; *bottom -= 1; -- moz_gtk_add_style_border(style, left, top, right, bottom); -+ moz_gtk_add_style_border(gButton.button.style, left, top, right, bottom); + moz_gtk_add_style_border(style, left, top, right, bottom); + ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } case MOZ_GTK_ENTRY: { - ensure_entry_widget(); +- ensure_entry_widget(); - style = gtk_widget_get_style_context(gEntryWidget); ++ style = ClaimStyleContext(MOZ_GTK_ENTRY); // XXX: Subtract 1 pixel from the padding to account for the default // padding in forms.css. See bug 1187385. - *left = *top = *right = *bottom = -1; -- moz_gtk_add_style_padding(style, left, top, right, bottom); -- moz_gtk_add_style_border(style, left, top, right, bottom); -+ -+ moz_gtk_add_style_padding(gEntry.entry.style, left, top, right, bottom); -+ moz_gtk_add_style_border(gEntry.entry.style, left, top, right, bottom); +@@ -2637,16 +2348,15 @@ moz_gtk_get_widget_border(WidgetNodeType + moz_gtk_add_style_padding(style, left, top, right, bottom); + moz_gtk_add_style_border(style, left, top, right, bottom); ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -2759,7 +2947,7 @@ moz_gtk_get_widget_border(GtkThemeWidget - break; - case MOZ_GTK_DROPDOWN_ENTRY: - ensure_combo_box_entry_widgets(); -- w = gComboBoxEntryTextareaWidget; -+ w = gComboBoxEntryTextarea.widget; - break; - case MOZ_GTK_DROPDOWN_ARROW: - ensure_combo_box_entry_widgets(); -@@ -2795,7 +2983,7 @@ moz_gtk_get_widget_border(GtkThemeWidget - - if (!wide_separators) { - style = gtk_widget_get_style_context(gComboBoxSeparatorWidget); -- gtk_style_context_get_border(style, 0, &border); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); - separator_width = border.left; - } - } -@@ -2814,14 +3002,17 @@ moz_gtk_get_widget_border(GtkThemeWidget ++ case MOZ_GTK_TEXT_VIEW: + case MOZ_GTK_TREEVIEW: + { +- ensure_scrolled_window_widget(); +- style = gtk_widget_get_style_context(gScrolledWindowWidget); +- gtk_style_context_save(style); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_FRAME); ++ style = ClaimStyleContext(MOZ_GTK_SCROLLED_WINDOW); + moz_gtk_add_style_border(style, left, top, right, bottom); +- gtk_style_context_restore(style); ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; + } + case MOZ_GTK_TREE_HEADER_CELL: +@@ -2726,14 +2436,12 @@ moz_gtk_get_widget_border(WidgetNodeType w = gTabWidget; break; case MOZ_GTK_PROGRESSBAR: - ensure_progress_widget(); - w = gProgressWidget; -- break; -+ { -+ ensure_progress_widget(); -+ moz_gtk_add_style_border(gProgressBar.progress.styleTrough, -+ left, top, right, bottom); -+ return MOZ_GTK_SUCCESS; -+ } ++ w = GetWidget(MOZ_GTK_PROGRESSBAR); + break; case MOZ_GTK_SPINBUTTON_ENTRY: case MOZ_GTK_SPINBUTTON_UP: case MOZ_GTK_SPINBUTTON_DOWN: - ensure_spin_widget(); +- ensure_spin_widget(); - w = gSpinWidget; -+ w = gSpin.widget; ++ w = GetWidget(MOZ_GTK_SPINBUTTON); break; case MOZ_GTK_SCALE_HORIZONTAL: ensure_scale_widget(); -@@ -2840,12 +3031,13 @@ moz_gtk_get_widget_border(GtkThemeWidget +@@ -2744,8 +2452,7 @@ moz_gtk_get_widget_border(WidgetNodeType + w = gVScaleWidget; + break; + case MOZ_GTK_FRAME: +- ensure_frame_widget(); +- w = gFrameWidget; ++ w = GetWidget(MOZ_GTK_FRAME); + break; + case MOZ_GTK_CHECKBUTTON_CONTAINER: + case MOZ_GTK_RADIOBUTTON_CONTAINER: +@@ -2761,19 +2468,17 @@ moz_gtk_get_widget_border(WidgetNodeType + return MOZ_GTK_SUCCESS; + } + case MOZ_GTK_MENUPOPUP: +- ensure_menu_popup_widget(); +- w = gMenuPopupWidget; ++ w = GetWidget(MOZ_GTK_MENUPOPUP); + break; ++ case MOZ_GTK_MENUBARITEM: + case MOZ_GTK_MENUITEM: + case MOZ_GTK_CHECKMENUITEM: + case MOZ_GTK_RADIOMENUITEM: { - if (widget == MOZ_GTK_CHECKBUTTON_CONTAINER) { - ensure_checkbox_widget(); -- w = gCheckboxWidget; -+ w = gCheckbox.widget; -+ style = gCheckbox.check.styleCheck; - } else { - ensure_radiobutton_widget(); -- w = gRadiobuttonWidget; -+ w = gRadiobutton.widget; -+ style = gRadiobutton.check.styleCheck; +- if (widget == MOZ_GTK_MENUITEM) { +- ensure_menu_item_widget(); +- ensure_menu_bar_item_widget(); +- w = gMenuItemWidget; +- } +- else { ++ if (widget == MOZ_GTK_MENUBARITEM || widget == MOZ_GTK_MENUITEM) { ++ // Bug 1274143 for MOZ_GTK_MENUBARITEM ++ w = GetWidget(MOZ_GTK_MENUITEM); ++ } else { + ensure_check_menu_item_widget(); + w = gCheckMenuItemWidget; } -- style = gtk_widget_get_style_context(w); +@@ -2784,9 +2489,16 @@ moz_gtk_get_widget_border(WidgetNodeType + return MOZ_GTK_SUCCESS; + } + case MOZ_GTK_INFO_BAR: +- ensure_info_bar(); +- w = gInfoBar; ++ w = GetWidget(MOZ_GTK_INFO_BAR); + break; ++ case MOZ_GTK_TOOLTIP: ++ { ++ style = ClaimStyleContext(MOZ_GTK_TOOLTIP); ++ moz_gtk_add_style_border(style, left, top, right, bottom); ++ moz_gtk_add_style_padding(style, left, top, right, bottom); ++ ReleaseStyleContext(style); ++ return MOZ_GTK_SUCCESS; ++ } + /* These widgets have no borders, since they are not containers. */ + case MOZ_GTK_CHECKBUTTON_LABEL: + case MOZ_GTK_RADIOBUTTON_LABEL: +@@ -2810,7 +2522,6 @@ moz_gtk_get_widget_border(WidgetNodeType + case MOZ_GTK_MENUSEPARATOR: + /* These widgets have no borders.*/ + case MOZ_GTK_SPINBUTTON: +- case MOZ_GTK_TOOLTIP: + case MOZ_GTK_WINDOW: + case MOZ_GTK_RESIZER: + case MOZ_GTK_MENUARROW: +@@ -2908,8 +2619,7 @@ moz_gtk_get_arrow_size(WidgetNodeType wi + widget = gComboBoxArrowWidget; + break; + default: +- ensure_button_arrow_widget(); +- widget = gButtonArrowWidget; ++ widget = GetWidget(MOZ_GTK_BUTTON_ARROW); + break; + } + +@@ -2924,11 +2634,9 @@ moz_gtk_get_toolbar_separator_width(gint + { + gboolean wide_separators; + gint separator_width; +- GtkStyleContext* style; + GtkBorder border; - *left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w)); - moz_gtk_add_style_border(style, -@@ -2978,6 +3170,32 @@ moz_gtk_get_combo_box_entry_button_size( +- ensure_toolbar_widget(); +- style = gtk_widget_get_style_context(gToolbarWidget); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_TOOLBAR); + gtk_style_context_get_style(style, + "space-size", size, + "wide-separators", &wide_separators, +@@ -2937,17 +2645,18 @@ moz_gtk_get_toolbar_separator_width(gint + /* Just in case... */ + gtk_style_context_get_border(style, GTK_STATE_FLAG_NORMAL, &border); + *size = MAX(*size, (wide_separators ? separator_width : border.left)); ++ ReleaseStyleContext(style); + return MOZ_GTK_SUCCESS; } gint -+moz_gtk_get_entry_height(gint* height) -+{ -+ GtkRequisition requisition; -+ ensure_entry_widget(); -+ -+ gtk_widget_get_preferred_size(gEntry.widget, NULL, &requisition); -+ *height = requisition.height; -+ -+ return MOZ_GTK_SUCCESS; -+} -+ -+ -+gint -+moz_gtk_get_button_height(gint* height) -+{ -+ GtkRequisition requisition; -+ ensure_entry_widget(); -+ -+ gtk_widget_get_preferred_size(gButton.widget, NULL, &requisition); -+ *height = requisition.height; -+ -+ return MOZ_GTK_SUCCESS; -+} -+ -+ -+gint - moz_gtk_get_tab_scroll_arrow_size(gint* width, gint* height) + moz_gtk_get_expander_size(gint* size) { - gint arrow_size; -@@ -3030,7 +3248,7 @@ moz_gtk_get_toolbar_separator_width(gint - "separator-width", &separator_width, - NULL); - /* Just in case... */ -- gtk_style_context_get_border(style, 0, &border); -+ gtk_style_context_get_border(style, gtk_style_context_get_state(style), &border); - *size = MAX(*size, (wide_separators ? separator_width : border.left)); +- ensure_expander_widget(); +- gtk_style_context_get_style(gtk_widget_get_style_context(gExpanderWidget), ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_EXPANDER); ++ gtk_style_context_get_style(style, + "expander-size", size, + NULL); +- ++ ReleaseStyleContext(style); return MOZ_GTK_SUCCESS; } -@@ -3072,7 +3290,7 @@ moz_gtk_get_menu_separator_height(gint * - border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget)); - style = gtk_widget_get_style_context(gMenuSeparatorWidget); -- gtk_style_context_get_padding(style, 0, &padding); -+ gtk_style_context_get_padding(style, gtk_style_context_get_state(style), &padding); +@@ -2972,11 +2681,11 @@ moz_gtk_get_menu_separator_height(gint * + GtkStyleContext* style; + guint border_width; + +- ensure_menu_separator_widget(); +- +- border_width = gtk_container_get_border_width(GTK_CONTAINER(gMenuSeparatorWidget)); ++ border_width = ++ gtk_container_get_border_width(GTK_CONTAINER( ++ GetWidget(MOZ_GTK_MENUSEPARATOR))); + +- style = gtk_widget_get_style_context(gMenuSeparatorWidget); ++ style = ClaimStyleContext(MOZ_GTK_MENUSEPARATOR); + gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_SEPARATOR); -@@ -3130,15 +3348,21 @@ moz_gtk_get_scrollbar_metrics(MozGtkScro - { - ensure_scrollbar_widget(); - -- gtk_widget_style_get (gHorizScrollbarWidget, -+ gtk_widget_style_get (gHorizScrollbar.widget, - "slider_width", &metrics->slider_width, - "trough_border", &metrics->trough_border, - "stepper_size", &metrics->stepper_size, - "stepper_spacing", &metrics->stepper_spacing, - NULL); - -- metrics->min_slider_size = -- gtk_range_get_min_slider_size(GTK_RANGE(gHorizScrollbarWidget)); -+ if (!gtk_check_version(3,19,7)) { -+ gtk_style_context_get(gVertScrollbar.scroll.styleSlider, -+ gtk_style_context_get_state(gVertScrollbar.scroll.styleSlider), -+ "min-height", &metrics->min_slider_size, NULL); -+ } else { -+ metrics->min_slider_size = -+ gtk_range_get_min_slider_size(GTK_RANGE(gVertScrollbar.widget)); -+ } +@@ -2988,6 +2697,7 @@ moz_gtk_get_menu_separator_height(gint * + NULL); - return MOZ_GTK_SUCCESS; + gtk_style_context_restore(style); ++ ReleaseStyleContext(style); + + *size = padding.top + padding.bottom + border_width*2; + *size += (wide_separators) ? separator_height : 1; +@@ -2998,8 +2708,7 @@ moz_gtk_get_menu_separator_height(gint * + void + moz_gtk_get_entry_min_height(gint* height) + { +- ensure_entry_widget(); +- GtkStyleContext* style = gtk_widget_get_style_context(gEntryWidget); ++ GtkStyleContext* style = ClaimStyleContext(MOZ_GTK_ENTRY); + if (!gtk_check_version(3, 20, 0)) { + gtk_style_context_get(style, gtk_style_context_get_state(style), + "min-height", height, +@@ -3014,6 +2723,7 @@ moz_gtk_get_entry_min_height(gint* heigh + gtk_style_context_get_padding(style, GTK_STATE_FLAG_NORMAL, &padding); + + *height += (border.top + border.bottom + padding.top + padding.bottom); ++ ReleaseStyleContext(style); } -@@ -3163,7 +3387,7 @@ moz_gtk_images_in_buttons() + + void +@@ -3094,8 +2804,7 @@ moz_gtk_images_in_buttons() + gboolean result; GtkSettings* settings; - ensure_button_widget(); +- ensure_button_widget(); - settings = gtk_widget_get_settings(gButtonWidget); -+ settings = gtk_widget_get_settings(gButton.widget); ++ settings = gtk_widget_get_settings(GetWidget(MOZ_GTK_BUTTON)); g_object_get(settings, "gtk-button-images", &result, NULL); return result; -@@ -3191,7 +3415,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType +@@ -3116,14 +2825,14 @@ moz_gtk_widget_paint(WidgetNodeType widg + case MOZ_GTK_BUTTON: + case MOZ_GTK_TOOLBAR_BUTTON: + if (state->depressed) { +- ensure_toggle_button_widget(); + return moz_gtk_button_paint(cr, rect, state, + (GtkReliefStyle) flags, +- gToggleButtonWidget, direction); ++ GetWidget(MOZ_GTK_TOGGLE_BUTTON), ++ direction); } - ensure_button_widget(); +- ensure_button_widget(); return moz_gtk_button_paint(cr, rect, state, - (GtkReliefStyle) flags, gButtonWidget, -+ (GtkReliefStyle) flags, gButton.widget, ++ (GtkReliefStyle) flags, ++ GetWidget(MOZ_GTK_BUTTON), direction); break; case MOZ_GTK_CHECKBUTTON: -@@ -3241,7 +3465,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType +@@ -3171,9 +2880,9 @@ moz_gtk_widget_paint(WidgetNodeType widg + state, direction); + break; case MOZ_GTK_SPINBUTTON_ENTRY: - ensure_spin_widget(); +- ensure_spin_widget(); ++ // TODO - use MOZ_GTK_SPINBUTTON_ENTRY style directly return moz_gtk_entry_paint(cr, rect, state, - gSpinWidget, direction); -+ &gSpin, direction); ++ GetWidget(MOZ_GTK_SPINBUTTON), direction); break; case MOZ_GTK_GRIPPER: return moz_gtk_gripper_paint(cr, rect, state, -@@ -3268,7 +3492,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType +@@ -3198,9 +2907,11 @@ moz_gtk_widget_paint(WidgetNodeType widg + (GtkExpanderStyle) flags, direction); + break; case MOZ_GTK_ENTRY: - ensure_entry_widget(); - return moz_gtk_entry_paint(cr, rect, state, +- ensure_entry_widget(); +- return moz_gtk_entry_paint(cr, rect, state, - gEntryWidget, direction); -+ &gEntry, direction); ++ return moz_gtk_entry_paint(cr, rect, state, GetWidget(MOZ_GTK_ENTRY), ++ direction); ++ break; ++ case MOZ_GTK_TEXT_VIEW: ++ return moz_gtk_text_view_paint(cr, rect, state, direction); break; case MOZ_GTK_DROPDOWN: return moz_gtk_combo_box_paint(cr, rect, state, direction); -@@ -3280,7 +3504,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType - case MOZ_GTK_DROPDOWN_ENTRY: - ensure_combo_box_entry_widgets(); - return moz_gtk_entry_paint(cr, rect, state, -- gComboBoxEntryTextareaWidget, direction); -+ &gComboBoxEntryTextarea, direction); - break; - case MOZ_GTK_CHECKBUTTON_CONTAINER: - case MOZ_GTK_RADIOBUTTON_CONTAINER: -@@ -3332,7 +3556,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType - (GtkArrowType) flags, direction); +@@ -3271,9 +2982,9 @@ moz_gtk_widget_paint(WidgetNodeType widg + return moz_gtk_menu_separator_paint(cr, rect, + direction); break; - case MOZ_GTK_MENUBAR: -- return moz_gtk_menu_bar_paint(cr, rect, direction); -+ return moz_gtk_menu_bar_paint(cr, rect, state, direction); ++ case MOZ_GTK_MENUBARITEM: + case MOZ_GTK_MENUITEM: +- return moz_gtk_menu_item_paint(cr, rect, state, flags, +- direction); ++ return moz_gtk_menu_item_paint(widget, cr, rect, state, direction); break; - case MOZ_GTK_MENUPOPUP: - return moz_gtk_menu_popup_paint(cr, rect, direction); -@@ -3383,7 +3607,7 @@ GtkWidget* moz_gtk_get_scrollbar_widget( + case MOZ_GTK_MENUARROW: + return moz_gtk_menu_arrow_paint(cr, rect, state, +@@ -3333,25 +3044,16 @@ gboolean moz_gtk_has_scrollbar_buttons(v + gint + moz_gtk_shutdown() { - MOZ_ASSERT(is_initialized, "Forgot to call moz_gtk_init()"); - ensure_scrollbar_widget(); -- return gHorizScrollbarWidget; -+ return gVertScrollbar.widget; - } +- if (gTooltipWidget) +- gtk_widget_destroy(gTooltipWidget); + /* This will destroy all of our widgets */ +- + ResetWidgetCache(); + + /* TODO - replace it with appropriate widget */ + if (gTreeHeaderSortArrowWidget) + gtk_widget_destroy(gTreeHeaderSortArrowWidget); - gboolean moz_gtk_has_scrollbar_buttons(void) -@@ -3391,7 +3615,7 @@ gboolean moz_gtk_has_scrollbar_buttons(v - gboolean backward, forward, secondary_backward, secondary_forward; - MOZ_ASSERT(is_initialized, "Forgot to call moz_gtk_init()"); - ensure_scrollbar_widget(); -- gtk_widget_style_get (gHorizScrollbarWidget, -+ gtk_widget_style_get (gHorizScrollbar.widget, - "has-backward-stepper", &backward, - "has-forward-stepper", &forward, - "has-secondary-backward-stepper", &secondary_backward, -@@ -3415,17 +3639,19 @@ moz_gtk_shutdown() - - gProtoWindow = NULL; +- gProtoWindow = NULL; gProtoLayout = NULL; - gButtonWidget = NULL; -+ -+ // MozWidgets -+ moz_gtk_widget_free(&gButton); - gToggleButtonWidget = NULL; - gButtonArrowWidget = NULL; -- gCheckboxWidget = NULL; -- gRadiobuttonWidget = NULL; -- gHorizScrollbarWidget = NULL; -- gVertScrollbarWidget = NULL; +- gToggleButtonWidget = NULL; +- gButtonArrowWidget = NULL; - gSpinWidget = NULL; -+ moz_gtk_widget_free(&gCheckbox); -+ moz_gtk_widget_free(&gRadiobutton); -+ moz_gtk_widget_free(&gHorizScrollbar); -+ moz_gtk_widget_free(&gVertScrollbar); -+ moz_gtk_widget_free(&gSpin); gHScaleWidget = NULL; gVScaleWidget = NULL; - gEntryWidget = NULL; -+ moz_gtk_widget_free(&gEntry); gComboBoxWidget = NULL; gComboBoxButtonWidget = NULL; gComboBoxSeparatorWidget = NULL; -@@ -3433,12 +3659,12 @@ moz_gtk_shutdown() - gComboBoxEntryWidget = NULL; +@@ -3360,29 +3062,15 @@ moz_gtk_shutdown() gComboBoxEntryButtonWidget = NULL; gComboBoxEntryArrowWidget = NULL; -- gComboBoxEntryTextareaWidget = NULL; -+ moz_gtk_widget_free(&gComboBoxEntryTextarea); - gHandleBoxWidget = NULL; - gToolbarWidget = NULL; - gStatusbarWidget = NULL; - gFrameWidget = NULL; + gComboBoxEntryTextareaWidget = NULL; +- gHandleBoxWidget = NULL; +- gToolbarWidget = NULL; +- gFrameWidget = NULL; - gProgressWidget = NULL; -+ moz_gtk_widget_free(&gProgressBar); gTabWidget = NULL; - gTooltipWidget = NULL; - gMenuBarWidget = NULL; -diff -up firefox-46.0/widget/gtk/gtkdrawing.h.gtk3-20 firefox-46.0/widget/gtk/gtkdrawing.h ---- firefox-46.0/widget/gtk/gtkdrawing.h.gtk3-20 2016-04-22 02:37:27.000000000 +0200 -+++ firefox-46.0/widget/gtk/gtkdrawing.h 2016-04-25 14:42:42.000000000 +0200 -@@ -67,6 +67,13 @@ typedef enum { +- gTextViewWidget = nullptr; +- gTooltipWidget = NULL; +- gMenuBarWidget = NULL; +- gMenuBarItemWidget = NULL; +- gMenuPopupWidget = NULL; +- gMenuItemWidget = NULL; + gImageMenuItemWidget = NULL; + gCheckMenuItemWidget = NULL; + gTreeViewWidget = NULL; + gMiddleTreeViewColumn = NULL; + gTreeHeaderCellWidget = NULL; + gTreeHeaderSortArrowWidget = NULL; +- gExpanderWidget = NULL; +- gToolbarSeparatorWidget = NULL; +- gMenuSeparatorWidget = NULL; + gHPanedWidget = NULL; + gVPanedWidget = NULL; +- gScrolledWindowWidget = NULL; + + is_initialized = FALSE; + +diff -up firefox-48.0/widget/gtk/gtkdrawing.h.gtk3-20 firefox-48.0/widget/gtk/gtkdrawing.h +--- firefox-48.0/widget/gtk/gtkdrawing.h.gtk3-20 2016-07-25 22:22:07.000000000 +0200 ++++ firefox-48.0/widget/gtk/gtkdrawing.h 2016-07-29 09:15:11.822285857 +0200 +@@ -69,12 +69,6 @@ typedef enum { MOZ_GTK_TAB_SELECTED = 1 << 10 } GtkTabFlags; -+typedef struct { -+ GType type; -+ const gchar *name; -+ const gchar *class1; -+ const gchar *class2; -+} GtkCssNode; -+ - /** flags for menuitems **/ - typedef enum { - /* menuitem is part of the menubar */ -@@ -396,6 +403,9 @@ void - moz_gtk_get_arrow_size(GtkThemeWidgetType widgetType, - gint* width, gint* height); - -+gint moz_gtk_get_entry_height(gint* height); -+gint moz_gtk_get_button_height(gint* height); -+ - /** - * Get the desired size of a toolbar separator - * size: [OUT] the desired width -@@ -466,6 +476,12 @@ gboolean moz_gtk_images_in_buttons(void) - */ - gboolean moz_gtk_has_scrollbar_buttons(void); - -+ -+GtkStyleContext * -+moz_gtk_style_create(GtkCssNode *node, GtkStyleContext *parent); -+ -+ -+ - #ifdef __cplusplus - } - #endif /* __cplusplus */ -diff -up firefox-46.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20 firefox-46.0/widget/gtk/mozgtk/mozgtk.c ---- firefox-46.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20 2016-04-22 02:37:27.000000000 +0200 -+++ firefox-46.0/widget/gtk/mozgtk/mozgtk.c 2016-04-25 14:46:15.299592716 +0200 -@@ -504,6 +504,11 @@ STUB(gtk_window_set_type_hint) - STUB(gtk_window_set_wmclass) - STUB(gtk_window_unfullscreen) - STUB(gtk_window_unmaximize) -+STUB(gtk_widget_get_preferred_height_and_baseline_for_width) -+STUB(gtk_entry_get_text_area) -+STUB(gtk_check_menu_item_get_type) -+STUB(gtk_spin_button_get_type) -+STUB(gtk_button_get_type) - #endif - - #ifdef GTK3_SYMBOLS -@@ -581,6 +586,13 @@ STUB(gtk_color_chooser_get_type) +-/** flags for menuitems **/ +-typedef enum { +- /* menuitem is part of the menubar */ +- MOZ_TOPLEVEL_MENU_ITEM = 1 << 0 +-} GtkMenuItemFlags; +- + /* function type for moz_gtk_enable_style_props */ + typedef gint (*style_prop_t)(GtkStyle*, const gchar*, gint); + +@@ -93,6 +87,10 @@ typedef enum { + MOZ_GTK_BUTTON, + /* Paints a button with image and no text */ + MOZ_GTK_TOOLBAR_BUTTON, ++ /* Paints a toggle button */ ++ MOZ_GTK_TOGGLE_BUTTON, ++ /* Paints a button arrow */ ++ MOZ_GTK_BUTTON_ARROW, + + /* Paints the container part of a GtkCheckButton. */ + MOZ_GTK_CHECKBUTTON_CONTAINER, +@@ -115,6 +113,7 @@ typedef enum { + + /* Horizontal GtkScrollbar counterparts */ + MOZ_GTK_SCROLLBAR_HORIZONTAL, ++ MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL, + /* Paints the trough (track) of a GtkScrollbar. */ + MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL, + /* Paints the slider (thumb) of a GtkScrollbar. */ +@@ -122,6 +121,7 @@ typedef enum { + + /* Vertical GtkScrollbar counterparts */ + MOZ_GTK_SCROLLBAR_VERTICAL, ++ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL, + MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL, + MOZ_GTK_SCROLLBAR_THUMB_VERTICAL, + +@@ -140,6 +140,10 @@ typedef enum { + MOZ_GTK_GRIPPER, + /* Paints a GtkEntry. */ + MOZ_GTK_ENTRY, ++ /* Paints a GtkExpander. */ ++ MOZ_GTK_EXPANDER, ++ /* Paints a GtkTextView. */ ++ MOZ_GTK_TEXT_VIEW, + /* Paints a GtkOptionMenu. */ + MOZ_GTK_DROPDOWN, + /* Paints a dropdown arrow (a GtkButton containing a down GtkArrow). */ +@@ -159,6 +163,8 @@ typedef enum { + MOZ_GTK_RESIZER, + /* Paints a GtkProgressBar. */ + MOZ_GTK_PROGRESSBAR, ++ /* Paints a trough (track) of a GtkProgressBar */ ++ MOZ_GTK_PROGRESS_TROUGH, + /* Paints a progress chunk of a GtkProgressBar. */ + MOZ_GTK_PROGRESS_CHUNK, + /* Paints a progress chunk of an indeterminated GtkProgressBar. */ +@@ -187,7 +193,9 @@ typedef enum { + MOZ_GTK_MENUARROW, + /* Paints an arrow in a toolbar button. flags is a GtkArrowType. */ + MOZ_GTK_TOOLBARBUTTON_ARROW, +- /* Paints items of menubar and popups. */ ++ /* Paints items of menubar. */ ++ MOZ_GTK_MENUBARITEM, ++ /* Paints items of popup menus. */ + MOZ_GTK_MENUITEM, + MOZ_GTK_CHECKMENUITEM, + MOZ_GTK_RADIOMENUITEM, +@@ -202,6 +210,8 @@ typedef enum { + MOZ_GTK_WINDOW_CONTAINER, + /* Paints a GtkInfoBar, for notifications. */ + MOZ_GTK_INFO_BAR, ++ /* Used for scrolled window shell. */ ++ MOZ_GTK_SCROLLED_WINDOW, + + MOZ_GTK_WIDGET_NODE_COUNT + } WidgetNodeType; +diff -up firefox-48.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20 firefox-48.0/widget/gtk/mozgtk/mozgtk.c +--- firefox-48.0/widget/gtk/mozgtk/mozgtk.c.gtk3-20 2016-07-25 22:22:07.000000000 +0200 ++++ firefox-48.0/widget/gtk/mozgtk/mozgtk.c 2016-07-29 09:15:11.823285862 +0200 +@@ -517,6 +517,7 @@ STUB(gdk_event_get_source_device) + STUB(gdk_window_get_type) + STUB(gdk_x11_window_get_xid) + STUB(gdk_x11_display_get_type) ++STUB(gtk_box_new) + STUB(gtk_cairo_should_draw_window) + STUB(gtk_cairo_transform_to_window) + STUB(gtk_combo_box_text_append) +@@ -570,6 +571,7 @@ STUB(gtk_tree_view_column_get_button) + STUB(gtk_widget_get_preferred_size) + STUB(gtk_widget_get_state_flags) + STUB(gtk_widget_get_style_context) ++STUB(gtk_widget_path_append_for_widget) + STUB(gtk_widget_path_append_type) + STUB(gtk_widget_path_copy) + STUB(gtk_widget_path_free) +@@ -587,6 +589,10 @@ STUB(gtk_color_chooser_get_type) STUB(gtk_color_chooser_set_rgba) STUB(gtk_color_chooser_get_rgba) STUB(gtk_color_chooser_set_use_alpha) -+STUB(gtk_style_context_get_path) -+STUB(gtk_widget_path_copy) -+STUB(gtk_widget_path_iter_set_object_name) -+STUB(gtk_widget_path_iter_add_class) -+STUB(gtk_widget_path_iter_get_state) -+STUB(gtk_style_context_set_parent) -+STUB(gtk_widget_path_unref) ++STUB(gtk_check_menu_item_new) ++STUB(gtk_style_context_get_direction) ++STUB(gtk_style_context_invalidate) ++STUB(gtk_tooltip_get_type) #endif #ifdef GTK2_SYMBOLS -diff -up firefox-46.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20 firefox-46.0/widget/gtk/nsLookAndFeel.cpp ---- firefox-46.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20 2016-04-22 02:37:27.000000000 +0200 -+++ firefox-46.0/widget/gtk/nsLookAndFeel.cpp 2016-04-25 14:18:25.000000000 +0200 -@@ -353,14 +353,18 @@ nsLookAndFeel::NativeGetColor(ColorID aI - case eColorID_activeborder: - // active window border - gtk_style_context_get_border_color(mBackgroundStyle, -- GTK_STATE_FLAG_NORMAL, &gdk_color); -+ gtk_style_context_get_state(mBackgroundStyle), -+ &gdk_color); - aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); - break; - case eColorID_inactiveborder: - // inactive window border -+ gtk_style_context_save(mBackgroundStyle); -+ gtk_style_context_set_state(mBackgroundStyle, GTK_STATE_FLAG_INSENSITIVE); - gtk_style_context_get_border_color(mBackgroundStyle, -- GTK_STATE_FLAG_INSENSITIVE, -+ gtk_style_context_get_state(mBackgroundStyle), - &gdk_color); -+ gtk_style_context_restore(mBackgroundStyle); - aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); - break; - case eColorID_graytext: // disabled text in windows, menus, etc. -@@ -369,9 +373,12 @@ nsLookAndFeel::NativeGetColor(ColorID aI - break; - case eColorID_inactivecaption: - // inactive window caption -+ gtk_style_context_save(mBackgroundStyle); -+ gtk_style_context_set_state(mBackgroundStyle, GTK_STATE_FLAG_INSENSITIVE); - gtk_style_context_get_background_color(mBackgroundStyle, -- GTK_STATE_FLAG_INSENSITIVE, -+ gtk_style_context_get_state(mBackgroundStyle), - &gdk_color); -+ gtk_style_context_restore(mBackgroundStyle); - aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); - break; +diff -up firefox-48.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20 firefox-48.0/widget/gtk/nsLookAndFeel.cpp +--- firefox-48.0/widget/gtk/nsLookAndFeel.cpp.gtk3-20 2016-06-01 06:11:44.000000000 +0200 ++++ firefox-48.0/widget/gtk/nsLookAndFeel.cpp 2016-07-29 09:15:54.943459700 +0200 +@@ -31,6 +31,7 @@ + + #if MOZ_WIDGET_GTK != 2 + #include <cairo-gobject.h> ++#include "WidgetStyleCache.h" #endif -@@ -497,13 +504,17 @@ nsLookAndFeel::NativeGetColor(ColorID aI - case eColorID__moz_buttondefault: - // default button border color - gtk_style_context_get_border_color(mButtonStyle, -- GTK_STATE_FLAG_NORMAL, &gdk_color); -+ gtk_style_context_get_state(mButtonStyle), -+ &gdk_color); - aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); - break; - case eColorID__moz_buttonhoverface: -+ gtk_style_context_save(mButtonStyle); -+ gtk_style_context_set_state(mButtonStyle, GTK_STATE_FLAG_PRELIGHT); - gtk_style_context_get_background_color(mButtonStyle, -- GTK_STATE_FLAG_PRELIGHT, -+ gtk_style_context_get_state(mButtonStyle), - &gdk_color); -+ gtk_style_context_restore(mButtonStyle); - aColor = GDK_RGBA_TO_NS_RGBA(gdk_color); - break; - case eColorID__moz_buttonhovertext: -@@ -1110,7 +1121,7 @@ nsLookAndFeel::Init() - style = create_context(path); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_SCROLLBAR); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_TROUGH); -- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color); - sMozScrollbar = GDK_RGBA_TO_NS_RGBA(color); - g_object_unref(style); - -@@ -1118,18 +1129,18 @@ nsLookAndFeel::Init() - style = create_context(path); - gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); -- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color); - sMozWindowBackground = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); + + using mozilla::LookAndFeel; +@@ -1135,15 +1136,24 @@ nsLookAndFeel::Init() + gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); sMozWindowText = GDK_RGBA_TO_NS_RGBA(color); gtk_style_context_restore(style); ++ g_object_unref(style); // tooltip foreground and background - gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); -- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP); +- gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); ++ style = ClaimStyleContext(MOZ_GTK_TOOLTIP); + gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); sInfoBackground = GDK_RGBA_TO_NS_RGBA(color); - gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); ++ { ++ GtkStyleContext* boxStyle = ++ CreateStyleForWidget(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0), ++ style); ++ GtkStyleContext* labelStyle = ++ CreateStyleForWidget(gtk_label_new(nullptr), boxStyle); ++ gtk_style_context_get_color(labelStyle, GTK_STATE_FLAG_NORMAL, &color); ++ g_object_unref(labelStyle); ++ g_object_unref(boxStyle); ++ } sInfoText = GDK_RGBA_TO_NS_RGBA(color); - g_object_unref(style); +- g_object_unref(style); ++ ReleaseStyleContext(style); + + // menu foreground & menu background + GtkWidget *accel_label = gtk_accel_label_new("M"); +diff -up firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp +--- firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 2016-07-25 22:22:07.000000000 +0200 ++++ firefox-48.0/widget/gtk/nsNativeThemeGTK.cpp 2016-07-29 09:15:11.824285865 +0200 +@@ -354,10 +354,8 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u + + if (isTopLevel) { + aState->inHover = menuFrame->IsOpen(); +- *aWidgetFlags |= MOZ_TOPLEVEL_MENU_ITEM; + } else { + aState->inHover = CheckBooleanAttr(aFrame, nsGkAtoms::menuactive); +- *aWidgetFlags &= ~MOZ_TOPLEVEL_MENU_ITEM; + } + + aState->active = FALSE; +@@ -510,8 +508,14 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u + break; + case NS_THEME_NUMBER_INPUT: + case NS_THEME_TEXTFIELD: ++ aGtkWidgetType = MOZ_GTK_ENTRY; ++ break; + case NS_THEME_TEXTFIELD_MULTILINE: ++#if (MOZ_WIDGET_GTK == 3) ++ aGtkWidgetType = MOZ_GTK_TEXT_VIEW; ++#else + aGtkWidgetType = MOZ_GTK_ENTRY; ++#endif + break; + case NS_THEME_LISTBOX: + case NS_THEME_TREEVIEW: +@@ -673,6 +677,13 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u + aGtkWidgetType = MOZ_GTK_MENUPOPUP; + break; + case NS_THEME_MENUITEM: ++ { ++ nsMenuFrame *menuFrame = do_QueryFrame(aFrame); ++ if (menuFrame && menuFrame->IsOnMenuBar()) { ++ aGtkWidgetType = MOZ_GTK_MENUBARITEM; ++ break; ++ } ++ } + aGtkWidgetType = MOZ_GTK_MENUITEM; + break; + case NS_THEME_MENUSEPARATOR: +diff -up firefox-48.0/widget/gtk/WidgetStyleCache.cpp.gtk3-20 firefox-48.0/widget/gtk/WidgetStyleCache.cpp +--- firefox-48.0/widget/gtk/WidgetStyleCache.cpp.gtk3-20 2016-07-25 22:22:07.000000000 +0200 ++++ firefox-48.0/widget/gtk/WidgetStyleCache.cpp 2016-07-29 09:15:11.825285869 +0200 +@@ -22,7 +22,7 @@ static bool sStyleContextNeedsRestore; + static GtkStyleContext* sCurrentStyleContext; + #endif + static GtkStyleContext* +-GetStyleInternal(WidgetNodeType aNodeType); ++GetCssNodeStyleInternal(WidgetNodeType aNodeType); + + static GtkWidget* + CreateWindowWidget() +@@ -67,12 +67,175 @@ CreateCheckboxWidget() + static GtkWidget* + CreateRadiobuttonWidget() + { +- GtkWidget* widget = gtk_radio_button_new_with_label(NULL, "M"); ++ GtkWidget* widget = gtk_radio_button_new_with_label(nullptr, "M"); + AddToWindowContainer(widget); + return widget; + } -@@ -1144,20 +1155,26 @@ nsLookAndFeel::Init() - gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem); + static GtkWidget* ++CreateMenuBarWidget() ++{ ++ GtkWidget* widget = gtk_menu_bar_new(); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateMenuPopupWidget() ++{ ++ GtkWidget* widget = gtk_menu_new(); ++ gtk_menu_attach_to_widget(GTK_MENU(widget), GetWidget(MOZ_GTK_WINDOW), ++ nullptr); ++ return widget; ++} ++ ++static GtkWidget* ++CreateMenuItemWidget(WidgetNodeType aShellType) ++{ ++ GtkWidget* widget = gtk_menu_item_new(); ++ gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(aShellType)), widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateProgressWidget() ++{ ++ GtkWidget* widget = gtk_progress_bar_new(); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateTooltipWidget() ++{ ++ MOZ_ASSERT(gtk_check_version(3, 20, 0) != nullptr, ++ "CreateTooltipWidget should be used for Gtk < 3.20 only."); ++ GtkWidget* widget = CreateWindowWidget(); ++ GtkStyleContext* style = gtk_widget_get_style_context(widget); ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP); ++ return widget; ++} ++ ++static GtkWidget* ++CreateExpanderWidget() ++{ ++ GtkWidget* widget = gtk_expander_new("M"); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateFrameWidget() ++{ ++ GtkWidget* widget = gtk_frame_new(nullptr); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateGripperWidget() ++{ ++ GtkWidget* widget = gtk_handle_box_new(); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateToolbarWidget() ++{ ++ GtkWidget* widget = gtk_toolbar_new(); ++ gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_GRIPPER)), widget); ++ gtk_widget_realize(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateToolbarSeparatorWidget() ++{ ++ GtkWidget* widget = GTK_WIDGET(gtk_separator_tool_item_new()); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateInfoBarWidget() ++{ ++ GtkWidget* widget = gtk_info_bar_new(); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateButtonWidget() ++{ ++ GtkWidget* widget = gtk_button_new_with_label("M"); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateToggleButtonWidget() ++{ ++ GtkWidget* widget = gtk_toggle_button_new(); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateButtonArrowWidget() ++{ ++ GtkWidget* widget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT); ++ gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_TOGGLE_BUTTON)), widget); ++ gtk_widget_realize(widget); ++ gtk_widget_show(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateSpinWidget() ++{ ++ GtkWidget* widget = gtk_spin_button_new(nullptr, 1, 0); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateEntryWidget() ++{ ++ GtkWidget* widget = gtk_entry_new(); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateScrolledWindowWidget() ++{ ++ GtkWidget* widget = gtk_scrolled_window_new(nullptr, nullptr); ++ AddToWindowContainer(widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateTextViewWidget() ++{ ++ GtkWidget* widget = gtk_text_view_new(); ++ gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_SCROLLED_WINDOW)), ++ widget); ++ return widget; ++} ++ ++static GtkWidget* ++CreateMenuSeparatorWidget() ++{ ++ GtkWidget* widget = gtk_separator_menu_item_new(); ++ gtk_menu_shell_append(GTK_MENU_SHELL(GetWidget(MOZ_GTK_MENUPOPUP)), ++ widget); ++ gtk_widget_realize(widget); ++ return widget; ++} ++ ++ ++static GtkWidget* + CreateWidget(WidgetNodeType aWidgetType) + { + switch (aWidgetType) { +@@ -80,16 +243,54 @@ CreateWidget(WidgetNodeType aWidgetType) + return CreateWindowWidget(); + case MOZ_GTK_WINDOW_CONTAINER: + return CreateWindowContainerWidget(); ++ case MOZ_GTK_CHECKBUTTON_CONTAINER: ++ return CreateCheckboxWidget(); ++ case MOZ_GTK_PROGRESSBAR: ++ return CreateProgressWidget(); ++ case MOZ_GTK_RADIOBUTTON_CONTAINER: ++ return CreateRadiobuttonWidget(); + case MOZ_GTK_SCROLLBAR_HORIZONTAL: + return CreateScrollbarWidget(aWidgetType, + GTK_ORIENTATION_HORIZONTAL); + case MOZ_GTK_SCROLLBAR_VERTICAL: + return CreateScrollbarWidget(aWidgetType, + GTK_ORIENTATION_VERTICAL); +- case MOZ_GTK_CHECKBUTTON_CONTAINER: +- return CreateCheckboxWidget(); +- case MOZ_GTK_RADIOBUTTON_CONTAINER: +- return CreateRadiobuttonWidget(); ++ case MOZ_GTK_MENUBAR: ++ return CreateMenuBarWidget(); ++ case MOZ_GTK_MENUPOPUP: ++ return CreateMenuPopupWidget(); ++ case MOZ_GTK_MENUBARITEM: ++ return CreateMenuItemWidget(MOZ_GTK_MENUBAR); ++ case MOZ_GTK_MENUITEM: ++ return CreateMenuItemWidget(MOZ_GTK_MENUPOPUP); ++ case MOZ_GTK_MENUSEPARATOR: ++ return CreateMenuSeparatorWidget(); ++ case MOZ_GTK_EXPANDER: ++ return CreateExpanderWidget(); ++ case MOZ_GTK_FRAME: ++ return CreateFrameWidget(); ++ case MOZ_GTK_GRIPPER: ++ return CreateGripperWidget(); ++ case MOZ_GTK_TOOLBAR: ++ return CreateToolbarWidget(); ++ case MOZ_GTK_TOOLBAR_SEPARATOR: ++ return CreateToolbarSeparatorWidget(); ++ case MOZ_GTK_INFO_BAR: ++ return CreateInfoBarWidget(); ++ case MOZ_GTK_SPINBUTTON: ++ return CreateSpinWidget(); ++ case MOZ_GTK_BUTTON: ++ return CreateButtonWidget(); ++ case MOZ_GTK_TOGGLE_BUTTON: ++ return CreateToggleButtonWidget(); ++ case MOZ_GTK_BUTTON_ARROW: ++ return CreateButtonArrowWidget(); ++ case MOZ_GTK_ENTRY: ++ return CreateEntryWidget(); ++ case MOZ_GTK_SCROLLED_WINDOW: ++ return CreateScrolledWindowWidget(); ++ case MOZ_GTK_TEXT_VIEW: ++ return CreateTextViewWidget(); + default: + /* Not implemented */ + return nullptr; +@@ -107,17 +308,42 @@ GetWidget(WidgetNodeType aWidgetType) + return widget; + } - style = gtk_widget_get_style_context(accel_label); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sMenuText = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_INSENSITIVE, &color); -+ gtk_style_context_save(style); -+ gtk_style_context_set_state(style, GTK_STATE_FLAG_INSENSITIVE); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sMenuTextInactive = GDK_RGBA_TO_NS_RGBA(color); -+ gtk_style_context_restore(style); - - style = gtk_widget_get_style_context(menu); -- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color); - sMenuBackground = GDK_RGBA_TO_NS_RGBA(color); - - style = gtk_widget_get_style_context(menuitem); -- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_PRELIGHT, &color); -+ gtk_style_context_save(style); -+ gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT); -+ gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color); - sMenuHover = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sMenuHoverText = GDK_RGBA_TO_NS_RGBA(color); -+ gtk_style_context_restore(style); - - g_object_unref(menu); - #endif -@@ -1266,44 +1283,54 @@ nsLookAndFeel::Init() - GDK_COLOR_TO_NS_RGB(style->dark[GTK_STATE_NORMAL]); - } - #else -+ GtkCssNode labelPath[] = { -+ { GTK_TYPE_LABEL, "label", "view", NULL }, -+ { G_TYPE_NONE, "selection", NULL, NULL } -+ }; +-static GtkStyleContext* +-CreateCSSNode(const char* aName, GtkStyleContext *aParentStyle) ++GtkStyleContext* ++CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle) ++{ ++ GtkWidgetPath* path = aParentStyle ? ++ gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) : ++ gtk_widget_path_new(); ++ ++ // Work around https://bugzilla.gnome.org/show_bug.cgi?id=767312 ++ // which exists in GTK+ 3.20. ++ gtk_widget_get_style_context(aWidget); + -+ GtkStyleContext *styleLabel; -+ GtkStyleContext *styleSelection; -+ GtkBorder padding; ++ gtk_widget_path_append_for_widget(path, aWidget); ++ // Release any floating reference on aWidget. ++ g_object_ref_sink(aWidget); ++ g_object_unref(aWidget); + - // Text colors -- style = gtk_widget_get_style_context(textView); ++ GtkStyleContext *context = gtk_style_context_new(); ++ gtk_style_context_set_path(context, path); ++ gtk_style_context_set_parent(context, aParentStyle); ++ gtk_widget_path_unref(path); ++ ++ return context; ++} ++ ++GtkStyleContext* ++CreateCSSNode(const char* aName, GtkStyleContext* aParentStyle, GType aType) + { + static auto sGtkWidgetPathIterSetObjectName = + reinterpret_cast<void (*)(GtkWidgetPath *, gint, const char *)> + (dlsym(RTLD_DEFAULT, "gtk_widget_path_iter_set_object_name")); + +- GtkWidgetPath* path = +- gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)); ++ GtkWidgetPath* path = aParentStyle ? ++ gtk_widget_path_copy(gtk_style_context_get_path(aParentStyle)) : ++ gtk_widget_path_new(); + +- gtk_widget_path_append_type(path, G_TYPE_NONE); ++ gtk_widget_path_append_type(path, aType); + + (*sGtkWidgetPathIterSetObjectName)(path, -1, aName); + +@@ -130,95 +356,168 @@ CreateCSSNode(const char* aName, GtkStyl + } + + static GtkStyleContext* +-GetChildNodeStyle(WidgetNodeType aStyleType, +- WidgetNodeType aWidgetType, +- const gchar* aStyleClass, +- WidgetNodeType aParentNodeType) ++CreateChildCSSNode(const char* aName, WidgetNodeType aParentNodeType) + { +- GtkStyleContext* style; +- +- if (gtk_check_version(3, 20, 0) != nullptr) { +- style = gtk_widget_get_style_context(sWidgetStorage[aWidgetType]); +- - gtk_style_context_save(style); -- gtk_style_context_add_class(style, GTK_STYLE_CLASS_VIEW); -- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ styleLabel = moz_gtk_style_create(labelPath, NULL); -+ styleSelection = moz_gtk_style_create(labelPath+1, styleLabel); +- MOZ_ASSERT(!sStyleContextNeedsRestore); +- sStyleContextNeedsRestore = true; +- +- gtk_style_context_add_class(style, aStyleClass); +- } +- else { +- style = sStyleStorage[aStyleType]; +- if (!style) { +- style = CreateCSSNode(aStyleClass, GetStyleInternal(aParentNodeType)); +- MOZ_ASSERT(!sStyleContextNeedsRestore); +- sStyleStorage[aStyleType] = style; +- } +- } ++ return CreateCSSNode(aName, GetCssNodeStyleInternal(aParentNodeType)); ++} + ++static GtkStyleContext* ++GetWidgetStyleWithClass(WidgetNodeType aWidgetType, const gchar* aStyleClass) ++{ ++ GtkStyleContext* style = gtk_widget_get_style_context(GetWidget(aWidgetType)); ++ gtk_style_context_save(style); ++ MOZ_ASSERT(!sStyleContextNeedsRestore); ++ sStyleContextNeedsRestore = true; ++ gtk_style_context_add_class(style, aStyleClass); + return style; + } + ++/* GetCssNodeStyleInternal is used by Gtk >= 3.20 */ + static GtkStyleContext* +-GetStyleInternal(WidgetNodeType aNodeType) ++GetCssNodeStyleInternal(WidgetNodeType aNodeType) + { ++ GtkStyleContext* style = sStyleStorage[aNodeType]; ++ if (style) ++ return style; + -+ gtk_style_context_get_background_color(styleLabel, gtk_style_context_get_state(styleLabel), &color); - sMozFieldBackground = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(styleLabel, gtk_style_context_get_state(styleLabel), &color); - sMozFieldText = GDK_RGBA_TO_NS_RGBA(color); - - // Selected text and background -- gtk_style_context_get_background_color(style, -- static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED), -- &color); -+ gtk_style_context_get_background_color(styleSelection, gtk_style_context_get_state(styleSelection), &color); - sTextSelectedBackground = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_get_color(style, -- static_cast<GtkStateFlags>(GTK_STATE_FLAG_FOCUSED|GTK_STATE_FLAG_SELECTED), -- &color); -+ gtk_style_context_get_color(styleSelection, gtk_style_context_get_state(styleSelection), &color); - sTextSelectedText = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_restore(style); + switch (aNodeType) { +- case MOZ_GTK_SCROLLBAR_HORIZONTAL: +- /* Root CSS node / widget for scrollbars */ ++ case MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL: ++ style = CreateChildCSSNode("contents", ++ MOZ_GTK_SCROLLBAR_HORIZONTAL); + break; + case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL: +- return GetChildNodeStyle(aNodeType, +- MOZ_GTK_SCROLLBAR_HORIZONTAL, +- GTK_STYLE_CLASS_TROUGH, +- MOZ_GTK_SCROLLBAR_HORIZONTAL); +- ++ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH, ++ MOZ_GTK_SCROLLBAR_CONTENTS_HORIZONTAL); ++ break; + case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL: +- return GetChildNodeStyle(aNodeType, +- MOZ_GTK_SCROLLBAR_HORIZONTAL, +- GTK_STYLE_CLASS_SLIDER, +- MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL); +- +- case MOZ_GTK_SCROLLBAR_VERTICAL: +- /* Root CSS node / widget for scrollbars */ ++ style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER, ++ MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL); ++ break; ++ case MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL: ++ style = CreateChildCSSNode("contents", ++ MOZ_GTK_SCROLLBAR_VERTICAL); + break; + case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL: +- return GetChildNodeStyle(aNodeType, +- MOZ_GTK_SCROLLBAR_VERTICAL, +- GTK_STYLE_CLASS_TROUGH, +- MOZ_GTK_SCROLLBAR_VERTICAL); +- ++ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH, ++ MOZ_GTK_SCROLLBAR_CONTENTS_VERTICAL); ++ break; + case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL: +- return GetChildNodeStyle(aNodeType, +- MOZ_GTK_SCROLLBAR_VERTICAL, +- GTK_STYLE_CLASS_SLIDER, +- MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL); +- +- case MOZ_GTK_RADIOBUTTON_CONTAINER: +- /* Root CSS node / widget for checkboxes */ ++ style = CreateChildCSSNode(GTK_STYLE_CLASS_SLIDER, ++ MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL); + break; + case MOZ_GTK_RADIOBUTTON: +- return GetChildNodeStyle(aNodeType, +- MOZ_GTK_RADIOBUTTON_CONTAINER, +- GTK_STYLE_CLASS_RADIO, +- MOZ_GTK_RADIOBUTTON_CONTAINER); +- case MOZ_GTK_CHECKBUTTON_CONTAINER: +- /* Root CSS node / widget for radiobuttons */ ++ style = CreateChildCSSNode(GTK_STYLE_CLASS_RADIO, ++ MOZ_GTK_RADIOBUTTON_CONTAINER); + break; + case MOZ_GTK_CHECKBUTTON: +- return GetChildNodeStyle(aNodeType, +- MOZ_GTK_CHECKBUTTON_CONTAINER, +- GTK_STYLE_CLASS_CHECK, +- MOZ_GTK_CHECKBUTTON_CONTAINER); +- default: ++ style = CreateChildCSSNode(GTK_STYLE_CLASS_CHECK, ++ MOZ_GTK_CHECKBUTTON_CONTAINER); ++ break; ++ case MOZ_GTK_PROGRESS_TROUGH: ++ /* Progress bar background (trough) */ ++ style = CreateChildCSSNode(GTK_STYLE_CLASS_TROUGH, ++ MOZ_GTK_PROGRESSBAR); ++ break; ++ case MOZ_GTK_PROGRESS_CHUNK: ++ style = CreateChildCSSNode("progress", ++ MOZ_GTK_PROGRESS_TROUGH); + break; ++ case MOZ_GTK_TOOLTIP: ++ // We create this from the path because GtkTooltipWindow is not public. ++ style = CreateCSSNode("tooltip", nullptr, GTK_TYPE_TOOLTIP); ++ gtk_style_context_add_class(style, GTK_STYLE_CLASS_BACKGROUND); ++ break; ++ case MOZ_GTK_GRIPPER: ++ // TODO - create from CSS node ++ return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER, ++ GTK_STYLE_CLASS_GRIP); ++ case MOZ_GTK_INFO_BAR: ++ // TODO - create from CSS node ++ return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR, ++ GTK_STYLE_CLASS_INFO); ++ case MOZ_GTK_SPINBUTTON_ENTRY: ++ // TODO - create from CSS node ++ return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON, ++ GTK_STYLE_CLASS_ENTRY); ++ case MOZ_GTK_SCROLLED_WINDOW: ++ // TODO - create from CSS node ++ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW, ++ GTK_STYLE_CLASS_FRAME); ++ case MOZ_GTK_TEXT_VIEW: ++ // TODO - create from CSS node ++ return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, ++ GTK_STYLE_CLASS_VIEW); ++ default: ++ // TODO - create style from style path ++ GtkWidget* widget = GetWidget(aNodeType); ++ return gtk_widget_get_style_context(widget); + } + +- GtkWidget* widget = GetWidget(aNodeType); +- if (widget) { +- return gtk_widget_get_style_context(widget); +- } ++ MOZ_ASSERT(style, "missing style context for node type"); ++ sStyleStorage[aNodeType] = style; ++ return style; ++} - // Button text, background, border - style = gtk_widget_get_style_context(label); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sButtonText = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); -+ gtk_style_context_save(style); -+ gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sButtonHoverText = GDK_RGBA_TO_NS_RGBA(color); -+ gtk_style_context_restore(style); - - // Combobox text color - style = gtk_widget_get_style_context(comboboxLabel); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sComboBoxText = GDK_RGBA_TO_NS_RGBA(color); +- MOZ_ASSERT_UNREACHABLE("missing style context for node type"); +- return nullptr; ++/* GetWidgetStyleInternal is used by Gtk < 3.20 */ ++static GtkStyleContext* ++GetWidgetStyleInternal(WidgetNodeType aNodeType) ++{ ++ switch (aNodeType) { ++ case MOZ_GTK_SCROLLBAR_TROUGH_HORIZONTAL: ++ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL, ++ GTK_STYLE_CLASS_TROUGH); ++ case MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL: ++ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_HORIZONTAL, ++ GTK_STYLE_CLASS_SLIDER); ++ case MOZ_GTK_SCROLLBAR_TROUGH_VERTICAL: ++ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL, ++ GTK_STYLE_CLASS_TROUGH); ++ case MOZ_GTK_SCROLLBAR_THUMB_VERTICAL: ++ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLBAR_VERTICAL, ++ GTK_STYLE_CLASS_SLIDER); ++ case MOZ_GTK_RADIOBUTTON: ++ return GetWidgetStyleWithClass(MOZ_GTK_RADIOBUTTON_CONTAINER, ++ GTK_STYLE_CLASS_RADIO); ++ case MOZ_GTK_CHECKBUTTON: ++ return GetWidgetStyleWithClass(MOZ_GTK_CHECKBUTTON_CONTAINER, ++ GTK_STYLE_CLASS_CHECK); ++ case MOZ_GTK_PROGRESS_TROUGH: ++ return GetWidgetStyleWithClass(MOZ_GTK_PROGRESSBAR, ++ GTK_STYLE_CLASS_TROUGH); ++ case MOZ_GTK_TOOLTIP: { ++ GtkStyleContext* style = sStyleStorage[aNodeType]; ++ if (style) ++ return style; ++ ++ // The tooltip style class is added first in CreateTooltipWidget() so ++ // that gtk_widget_path_append_for_widget() in CreateStyleForWidget() ++ // will find it. ++ GtkWidget* tooltipWindow = CreateTooltipWidget(); ++ style = CreateStyleForWidget(tooltipWindow, nullptr); ++ gtk_widget_destroy(tooltipWindow); // Release GtkWindow self-reference. ++ sStyleStorage[aNodeType] = style; ++ return style; ++ } ++ case MOZ_GTK_GRIPPER: ++ return GetWidgetStyleWithClass(MOZ_GTK_GRIPPER, ++ GTK_STYLE_CLASS_GRIP); ++ case MOZ_GTK_INFO_BAR: ++ return GetWidgetStyleWithClass(MOZ_GTK_INFO_BAR, ++ GTK_STYLE_CLASS_INFO); ++ case MOZ_GTK_SPINBUTTON_ENTRY: ++ return GetWidgetStyleWithClass(MOZ_GTK_SPINBUTTON, ++ GTK_STYLE_CLASS_ENTRY); ++ case MOZ_GTK_SCROLLED_WINDOW: ++ return GetWidgetStyleWithClass(MOZ_GTK_SCROLLED_WINDOW, ++ GTK_STYLE_CLASS_FRAME); ++ case MOZ_GTK_TEXT_VIEW: ++ return GetWidgetStyleWithClass(MOZ_GTK_TEXT_VIEW, ++ GTK_STYLE_CLASS_VIEW); ++ default: ++ GtkWidget* widget = GetWidget(aNodeType); ++ MOZ_ASSERT(widget); ++ return gtk_widget_get_style_context(widget); ++ } + } - // Menubar text and hover text colors - style = gtk_widget_get_style_context(menuBar); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sMenuBarText = GDK_RGBA_TO_NS_RGBA(color); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_PRELIGHT, &color); -+ gtk_style_context_save(style); -+ gtk_style_context_set_state(style, GTK_STATE_FLAG_PRELIGHT); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sMenuBarHoverText = GDK_RGBA_TO_NS_RGBA(color); -+ gtk_style_context_restore(style); - - // GTK's guide to fancy odd row background colors: - // 1) Check if a theme explicitly defines an odd row color -@@ -1316,7 +1343,7 @@ nsLookAndFeel::Init() - // Get odd row background color - gtk_style_context_save(style); - gtk_style_context_add_region(style, GTK_STYLE_REGION_ROW, GTK_REGION_ODD); -- gtk_style_context_get_background_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_background_color(style, gtk_style_context_get_state(style), &color); - sOddCellBackground = GDK_RGBA_TO_NS_RGBA(color); - gtk_style_context_restore(style); + void +@@ -245,13 +544,39 @@ ResetWidgetCache(void) -@@ -1334,9 +1361,11 @@ nsLookAndFeel::Init() - gtk_container_add(GTK_CONTAINER(parent), infoBar); - gtk_container_add(GTK_CONTAINER(infoBarContent), infoBarLabel); - style = gtk_widget_get_style_context(infoBarLabel); -+ gtk_style_context_save(style); - gtk_style_context_add_class(style, GTK_STYLE_CLASS_INFO); -- gtk_style_context_get_color(style, GTK_STATE_FLAG_NORMAL, &color); -+ gtk_style_context_get_color(style, gtk_style_context_get_state(style), &color); - sInfoBarText = GDK_RGBA_TO_NS_RGBA(color); -+ gtk_style_context_restore(style); + GtkStyleContext* + ClaimStyleContext(WidgetNodeType aNodeType, GtkTextDirection aDirection, +- StyleFlags aFlags) ++ GtkStateFlags aStateFlags, StyleFlags aFlags) + { +- GtkStyleContext* style = GetStyleInternal(aNodeType); ++ MOZ_ASSERT(!sStyleContextNeedsRestore); ++ GtkStyleContext* style; ++ if (gtk_check_version(3, 20, 0) != nullptr) { ++ style = GetWidgetStyleInternal(aNodeType); ++ } else { ++ style = GetCssNodeStyleInternal(aNodeType); ++ } + #ifdef DEBUG + MOZ_ASSERT(!sCurrentStyleContext); + sCurrentStyleContext = style; #endif - // Some themes have a unified menu bar, and support window dragging on it - gboolean supports_menubar_drag = FALSE; -diff -up firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp ---- firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp.gtk3-20 2016-04-25 14:46:15.300592722 +0200 -+++ firefox-46.0/widget/gtk/nsNativeThemeGTK.cpp 2016-04-25 14:40:42.000000000 +0200 -@@ -1567,9 +1567,6 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - case NS_THEME_RADIO_CONTAINER: - case NS_THEME_CHECKBOX_LABEL: - case NS_THEME_RADIO_LABEL: -- case NS_THEME_BUTTON: -- case NS_THEME_DROPDOWN: -- case NS_THEME_TOOLBAR_BUTTON: - case NS_THEME_TREEVIEW_HEADER_CELL: - { - if (aWidgetType == NS_THEME_DROPDOWN) { -@@ -1588,6 +1585,21 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n - aResult->height += border.top + border.bottom; - } - break; -+ case NS_THEME_BUTTON: -+ case NS_THEME_DROPDOWN: -+ case NS_THEME_TOOLBAR_BUTTON: -+ { -+ moz_gtk_get_button_height(&aResult->height); ++ GtkStateFlags oldState = gtk_style_context_get_state(style); ++ GtkTextDirection oldDirection = gtk_style_context_get_direction(style); ++ if (oldState != aStateFlags || oldDirection != aDirection) { ++ // From GTK 3.8, set_state() will overwrite the direction, so set ++ // direction after state. ++ gtk_style_context_set_state(style, aStateFlags); ++ gtk_style_context_set_direction(style, aDirection); ++ ++ // This invalidate is necessary for unsaved style contexts from GtkWidgets ++ // in pre-3.18 GTK, because automatic invalidation of such contexts ++ // was delayed until a resize event runs. ++ // ++ // https://bugzilla.mozilla.org/show_bug.cgi?id=1272194#c7 ++ // ++ // Avoid calling invalidate on saved contexts to avoid performing ++ // build_properties() (in 3.16 stylecontext.c) unnecessarily early. ++ if (!sStyleContextNeedsRestore) { ++ gtk_style_context_invalidate(style); + } -+ break; -+ case NS_THEME_FOCUS_OUTLINE: -+ case NS_THEME_NUMBER_INPUT: -+ case NS_THEME_TEXTFIELD: -+ case NS_THEME_TEXTFIELD_MULTILINE: -+ { -+ moz_gtk_get_entry_height(&aResult->height); -+ } -+ break; - case NS_THEME_TOOLBAR_SEPARATOR: - { - gint separator_width; ++ } + return style; + } + +diff -up firefox-48.0/widget/gtk/WidgetStyleCache.h.gtk3-20 firefox-48.0/widget/gtk/WidgetStyleCache.h +--- firefox-48.0/widget/gtk/WidgetStyleCache.h.gtk3-20 2016-07-25 22:22:07.000000000 +0200 ++++ firefox-48.0/widget/gtk/WidgetStyleCache.h 2016-07-29 09:15:11.825285869 +0200 +@@ -21,10 +21,24 @@ enum : StyleFlags { + GtkWidget* + GetWidget(WidgetNodeType aNodeType); + ++/* ++ * Return a new style context based on aWidget, as a child of aParentStyle. ++ * If aWidget still has a floating reference, then it is sunk and released. ++ */ ++GtkStyleContext* ++CreateStyleForWidget(GtkWidget* aWidget, GtkStyleContext* aParentStyle); ++ ++// CreateCSSNode is implemented for gtk >= 3.20 only. ++GtkStyleContext* ++CreateCSSNode(const char* aName, ++ GtkStyleContext* aParentStyle, ++ GType aType = G_TYPE_NONE); ++ + // Callers must call ReleaseStyleContext() on the returned context. + GtkStyleContext* + ClaimStyleContext(WidgetNodeType aNodeType, + GtkTextDirection aDirection = GTK_TEXT_DIR_LTR, ++ GtkStateFlags aStateFlags = GTK_STATE_FLAG_NORMAL, + StyleFlags aFlags = NO_STYLE_FLAGS); + void + ReleaseStyleContext(GtkStyleContext* style); diff --git a/testing/firefox/fix-toolkit.patch b/testing/firefox/fix-toolkit.patch index 9fd8ef497c..58fe5a3a9a 100644 --- a/testing/firefox/fix-toolkit.patch +++ b/testing/firefox/fix-toolkit.patch @@ -1,6 +1,7 @@ -diff -ru mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc mozilla-release/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc ---- mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc 2014-03-15 05:19:36.000000000 +0000 -+++ mozilla-release/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc 2014-04-17 10:24:33.793431933 +0000 +diff --git a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc b/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc +index 4222ce3..4d40c6a 100644 +--- a/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc ++++ b/toolkit/crashreporter/google-breakpad/src/common/linux/dump_symbols.cc @@ -45,6 +45,7 @@ #include <sys/mman.h> #include <sys/stat.h> @@ -9,9 +10,10 @@ diff -ru mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/l #include <iostream> #include <set> -diff -ru mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/stabs_reader.cc mozilla-release/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc ---- mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/stabs_reader.cc 2014-03-15 05:19:36.000000000 +0000 -+++ mozilla-release/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc 2014-04-17 10:24:33.793431933 +0000 +diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc +index 6019fc7..5953e32 100644 +--- a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc ++++ b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.cc @@ -41,6 +41,10 @@ #include "common/using_std_string.h" @@ -23,37 +25,41 @@ diff -ru mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/s using std::vector; namespace google_breakpad { -diff -ru mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/stabs_reader.h mozilla-release/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h ---- mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/common/stabs_reader.h 2014-03-15 05:19:36.000000000 +0000 -+++ mozilla-release/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h 2014-04-17 10:24:33.793431933 +0000 -@@ -53,9 +53,10 @@ - #include <config.h> - #endif +diff --git a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h +index 98ee2dd..d57aa68 100644 +--- a/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h ++++ b/toolkit/crashreporter/google-breakpad/src/common/stabs_reader.h +@@ -55,7 +55,7 @@ --#ifdef HAVE_A_OUT_H -+#if 0 - #include <a.out.h> - #endif -+ #ifdef HAVE_MACH_O_NLIST_H #include <mach-o/nlist.h> +-#elif defined(HAVE_A_OUT_H) ++#elif 0 + #include <a.out.h> #endif -diff -ru mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h mozilla-release/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h ---- mozilla-release/toolkit.orig/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h 2014-03-15 05:19:37.000000000 +0000 -+++ mozilla-release/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h 2014-04-17 10:24:33.793431933 +0000 -@@ -2813,7 +2813,7 @@ - LSS_INLINE _syscall6(void*, mmap, void*, s, - size_t, l, int, p, - int, f, int, d, -- __off64_t, o) -+ off_t, o) - LSS_INLINE _syscall4(int, newfstatat, int, d, - const char *, p, -diff -ru mozilla-release/toolkit.orig/mozapps/update/common/updatedefines.h mozilla-release/toolkit/mozapps/update/common/updatedefines.h ---- mozilla-release/toolkit.orig/mozapps/update/common/updatedefines.h 2014-03-15 05:19:37.000000000 +0000 -+++ mozilla-release/toolkit/mozapps/update/common/updatedefines.h 2014-04-17 10:24:33.793431933 +0000 -@@ -105,7 +105,7 @@ +diff --git a/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h b/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h +index 93fdad7..f34e5e0 100644 +--- a/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h ++++ b/toolkit/crashreporter/google-breakpad/src/third_party/lss/linux_syscall_support.h +@@ -1134,6 +1134,12 @@ struct kernel_statfs { + #ifndef __NR_fallocate + #define __NR_fallocate 285 + #endif ++ ++#undef __NR_pread ++#define __NR_pread __NR_pread64 ++#undef __NR_pwrite ++#define __NR_pwrite __NR_pwrite64 ++ + /* End of x86-64 definitions */ + #elif defined(__mips__) + #if _MIPS_SIM == _MIPS_SIM_ABI32 +diff --git a/toolkit/mozapps/update/common/updatedefines.h b/toolkit/mozapps/update/common/updatedefines.h +index 026e7ed..0801f14 100644 +--- a/toolkit/mozapps/update/common/updatedefines.h ++++ b/toolkit/mozapps/update/common/updatedefines.h +@@ -117,7 +117,7 @@ static inline int mywcsprintf(WCHAR* dest, size_t count, const WCHAR* fmt, ...) #ifdef SOLARIS # include <sys/stat.h> @@ -62,10 +68,11 @@ diff -ru mozilla-release/toolkit.orig/mozapps/update/common/updatedefines.h mozi # include <fts.h> #endif # include <dirent.h> -diff -ru mozilla-release/toolkit.orig/mozapps/update/updater/updater.cpp mozilla-release/toolkit/mozapps/update/updater/updater.cpp ---- mozilla-release/toolkit.orig/mozapps/update/updater/updater.cpp 2014-03-15 05:19:37.000000000 +0000 -+++ mozilla-release/toolkit/mozapps/update/updater/updater.cpp 2014-04-17 10:24:33.796765327 +0000 -@@ -3432,6 +3432,7 @@ +diff --git a/toolkit/mozapps/update/updater/updater.cpp b/toolkit/mozapps/update/updater/updater.cpp +index 257ccb4..01314e4 100644 +--- a/toolkit/mozapps/update/updater/updater.cpp ++++ b/toolkit/mozapps/update/updater/updater.cpp +@@ -3737,6 +3737,7 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list) int add_dir_entries(const NS_tchar *dirpath, ActionList *list) { int rv = OK; @@ -73,7 +80,7 @@ diff -ru mozilla-release/toolkit.orig/mozapps/update/updater/updater.cpp mozilla FTS *ftsdir; FTSENT *ftsdirEntry; NS_tchar searchpath[MAXPATHLEN]; -@@ -3534,6 +3535,7 @@ +@@ -3840,6 +3841,7 @@ int add_dir_entries(const NS_tchar *dirpath, ActionList *list) } fts_close(ftsdir); @@ -81,14 +88,3 @@ diff -ru mozilla-release/toolkit.orig/mozapps/update/updater/updater.cpp mozilla return rv; } -diff -ru mozilla-release/toolkit.orig/xre/nsSigHandlers.cpp mozilla-release/toolkit/xre/nsSigHandlers.cpp ---- mozilla-release/toolkit.orig/xre/nsSigHandlers.cpp 2014-03-15 05:19:38.000000000 +0000 -+++ mozilla-release/toolkit/xre/nsSigHandlers.cpp 2014-04-17 10:24:33.796765327 +0000 -@@ -15,6 +15,7 @@ - #include <signal.h> - #include <stdio.h> - #include <string.h> -+#include <stdint.h> - #include "prthread.h" - #include "plstr.h" - #include "prenv.h" diff --git a/testing/firefox/fix-tools.patch b/testing/firefox/fix-tools.patch index cf1589d633..522d7e1a27 100644 --- a/testing/firefox/fix-tools.patch +++ b/testing/firefox/fix-tools.patch @@ -1,8 +1,55 @@ -diff --git a/tools/profiler/LulElf.cpp b/tools/profiler/LulElf.cpp -index 203b15d..08a270a 100644 +diff --git a/media/libav/config_unix.h b/media/libav/config_unix.h +index 3921293..df8b855 100644 +--- a/media/libav/config_unix.h ++++ b/media/libav/config_unix.h +@@ -219,7 +219,11 @@ + #define HAVE_STRERROR_R 1 + #define HAVE_STRPTIME 1 + #define HAVE_SYSCONF 1 ++#if !defined(__linux__) || defined(__GLIBC__) + #define HAVE_SYSCTL 1 ++#else ++#define HAVE_SYSCTL 0 ++#endif + #define HAVE_USLEEP 1 + #define HAVE_VIRTUALALLOC 0 + #define HAVE_PTHREADS 0 +diff --git a/tools/profiler/core/platform-linux.cc b/tools/profiler/core/platform-linux.cc +index 0df1e8f..d868895 100644 +--- a/tools/profiler/core/platform-linux.cc ++++ b/tools/profiler/core/platform-linux.cc +@@ -711,11 +711,13 @@ void OS::Startup() { + void TickSample::PopulateContext(void* aContext) + { + MOZ_ASSERT(aContext); ++#if defined(__GLIBC__) + ucontext_t* pContext = reinterpret_cast<ucontext_t*>(aContext); + if (!getcontext(pContext)) { + context = pContext; + SetSampleContext(this, aContext); + } ++#endif + } + + void OS::SleepMicro(int microseconds) +diff --git a/tools/profiler/core/platform.h b/tools/profiler/core/platform.h +index a38b3b5..170bd75 100644 +--- a/tools/profiler/core/platform.h ++++ b/tools/profiler/core/platform.h +@@ -34,6 +34,8 @@ + #define MOZ_COUNT_DTOR(name) + #endif + ++#include <sys/types.h> ++ + #ifdef ANDROID + #include <android/log.h> + #else +diff --git a/tools/profiler/lul/LulElf.cpp b/tools/profiler/lul/LulElf.cpp +index a922137..d01dde1 100644 --- a/tools/profiler/lul/LulElf.cpp +++ b/tools/profiler/lul/LulElf.cpp -@@ -612,10 +612,10 @@ string FormatIdentifier(unsigned char identifier[16]) { +@@ -483,10 +483,10 @@ string FormatIdentifier(unsigned char identifier[16]) { // Return the non-directory portion of FILENAME: the portion after the // last slash, or the whole filename if there are no slashes. string BaseFileName(const string &filename) { @@ -17,35 +64,3 @@ index 203b15d..08a270a 100644 return base; } -diff --git a/tools/profiler/local_debug_info_symbolizer.cc b/tools/profiler/local_debug_info_symbolizer.cc -index 2232130..41dabc8 100644 ---- a/tools/profiler/gecko/local_debug_info_symbolizer.cc -+++ b/tools/profiler/gecko/local_debug_info_symbolizer.cc -@@ -3,6 +3,7 @@ - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -+#include <sys/types.h> - #include "PlatformMacros.h" - #include "nsAutoPtr.h" - ---- ./tools/profiler/core/platform.h.orig -+++ ./tools/profiler/core/platform.h -@@ -34,6 +34,8 @@ - #define MOZ_COUNT_DTOR(name) - #endif - -+#include <sys/types.h> -+ - #ifdef ANDROID - #include <android/log.h> - #else -@@ -60,7 +62,7 @@ - - // We need a definition of gettid(), but glibc doesn't provide a - // wrapper for it. --#if defined(__GLIBC__) -+#if defined(__linux__) - #include <unistd.h> - #include <sys/syscall.h> - static inline pid_t gettid() diff --git a/testing/firefox/mozconfig b/testing/firefox/mozconfig index b8bf5d5c08..5632e5bdd1 100644 --- a/testing/firefox/mozconfig +++ b/testing/firefox/mozconfig @@ -1,7 +1,6 @@ . $topsrcdir/browser/config/mozconfig ac_add_options --prefix=/usr -ac_add_options --libdir=/usr/lib ac_add_options --with-pthreads ac_add_options --with-system-bz2 @@ -23,25 +22,18 @@ ac_add_options --enable-system-ffi # ac_add_options --enable-debug-symbols=-g ac_add_options --disable-install-strip -ac_add_options --enable-gstreamer=1.0 ac_add_options --enable-official-branding ac_add_options --enable-optimize="$CFLAGS" ac_add_options --enable-startup-notification +ac_add_options --enable-gold=no -ac_add_options --disable-cpp-exceptions ac_add_options --disable-crashreporter ac_add_options --disable-elf-hack -ac_add_options --disable-gnomevfs -ac_add_options --disable-installer -ac_add_options --disable-javaxpcom ac_add_options --disable-jemalloc -ac_add_options --disable-mochitest ac_add_options --disable-pulseaudio -ac_add_options --disable-static ac_add_options --disable-strip ac_add_options --disable-tests ac_add_options --disable-updater -ac_add_options --disable-xprint export BUILD_OFFICIAL=1 export MOZILLA_OFFICIAL=1 |