1012
|
1 |
diff -up firefox-57.0b8/browser/app/profile/firefox.js.1399611 firefox-57.0b8/browser/app/profile/firefox.js
|
|
2 |
--- firefox-57.0b8/browser/app/profile/firefox.js.1399611 2017-10-16 12:11:45.364240654 +0200
|
|
3 |
+++ firefox-57.0b8/browser/app/profile/firefox.js 2017-10-16 12:28:03.860720910 +0200
|
|
4 |
@@ -457,11 +457,7 @@ pref("browser.tabs.loadBookmarksInBackgr
|
|
5 |
pref("browser.tabs.loadBookmarksInTabs", false);
|
|
6 |
pref("browser.tabs.tabClipWidth", 140);
|
|
7 |
pref("browser.tabs.tabMinWidth", 76);
|
|
8 |
-#ifdef UNIX_BUT_NOT_MAC
|
|
9 |
-pref("browser.tabs.drawInTitlebar", false);
|
|
10 |
-#else
|
|
11 |
pref("browser.tabs.drawInTitlebar", true);
|
|
12 |
-#endif
|
|
13 |
|
|
14 |
// Offer additional drag space to the user. The drag space
|
|
15 |
// will only be shown if browser.tabs.drawInTitlebar is true.
|
|
16 |
diff -up firefox-57.0b8/browser/base/content/browser-tabsintitlebar.js.1399611 firefox-57.0b8/browser/base/content/browser-tabsintitlebar.js
|
|
17 |
--- firefox-57.0b8/browser/base/content/browser-tabsintitlebar.js.1399611 2017-10-09 22:17:13.000000000 +0200
|
|
18 |
+++ firefox-57.0b8/browser/base/content/browser-tabsintitlebar.js 2017-10-16 12:11:45.364240654 +0200
|
|
19 |
@@ -14,6 +14,11 @@ var TabsInTitlebar = {
|
|
20 |
this._readPref();
|
|
21 |
Services.prefs.addObserver(this._prefName, this);
|
|
22 |
|
|
23 |
+ // Always disable on unsupported GTK versions.
|
|
24 |
+ if (AppConstants.MOZ_WIDGET_TOOLKIT == "gtk3") {
|
|
25 |
+ this.allowedBy("gtk", window.matchMedia("(-moz-gtk-csd-available)"));
|
|
26 |
+ }
|
|
27 |
+
|
|
28 |
// We need to update the appearance of the titlebar when the menu changes
|
|
29 |
// from the active to the inactive state. We can't, however, rely on
|
|
30 |
// DOMMenuBarInactive, because the menu fires this event and then removes
|
|
31 |
diff -up firefox-57.0b8/browser/base/moz.build.1399611 firefox-57.0b8/browser/base/moz.build
|
|
32 |
--- firefox-57.0b8/browser/base/moz.build.1399611 2017-09-29 18:16:45.000000000 +0200
|
|
33 |
+++ firefox-57.0b8/browser/base/moz.build 2017-10-16 12:11:45.364240654 +0200
|
|
34 |
@@ -57,7 +57,7 @@ DEFINES['APP_LICENSE_BLOCK'] = '%s/conte
|
|
35 |
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'):
|
|
36 |
DEFINES['CONTEXT_COPY_IMAGE_CONTENTS'] = 1
|
|
37 |
|
|
38 |
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
|
|
39 |
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa', 'gtk3'):
|
|
40 |
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
|
|
41 |
|
|
42 |
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
|
|
43 |
diff -up firefox-57.0b8/browser/themes/linux/browser.css.1399611 firefox-57.0b8/browser/themes/linux/browser.css
|
|
44 |
--- firefox-57.0b8/browser/themes/linux/browser.css.1399611 2017-10-05 06:17:37.000000000 +0200
|
|
45 |
+++ firefox-57.0b8/browser/themes/linux/browser.css 2017-10-16 12:11:45.365240651 +0200
|
|
46 |
@@ -556,7 +556,9 @@ html|span.ac-emphasize-text-url {
|
|
47 |
|
|
48 |
#nav-bar,
|
|
49 |
#toolbar-menubar:not([autohide="true"]):not(:-moz-lwtheme):-moz-system-metric(menubar-drag),
|
|
50 |
-#TabsToolbar:not(:-moz-lwtheme):-moz-system-metric(menubar-drag) {
|
|
51 |
+#TabsToolbar:not(:-moz-lwtheme):-moz-system-metric(menubar-drag),
|
|
52 |
+#main-window[tabsintitlebar] #toolbar-menubar:not([autohide="true"]),
|
|
53 |
+#main-window[tabsintitlebar] #TabsToolbar {
|
|
54 |
-moz-binding: url("chrome://browser/content/customizableui/toolbar.xml#toolbar-drag");
|
|
55 |
}
|
|
56 |
|
|
57 |
@@ -713,3 +715,85 @@ html|span.ac-emphasize-text-url {
|
|
58 |
.restore-tabs-button:hover:active:not([disabled="true"]) {
|
|
59 |
padding: 3px;
|
|
60 |
}
|
|
61 |
+
|
|
62 |
+@media not all and (-moz-gtk-csd-available) {
|
|
63 |
+ #main-window > #titlebar {
|
|
64 |
+ /* We need to hide the titlebar explicitly on versions of GTK without CSD. */
|
|
65 |
+ display: none;
|
|
66 |
+ }
|
|
67 |
+}
|
|
68 |
+
|
|
69 |
+/* Titlebar/CSD */
|
|
70 |
+@media (-moz-gtk-csd-available) {
|
|
71 |
+ #main-window[tabsintitlebar][sizemode="normal"] > #titlebar {
|
|
72 |
+ min-height: calc(var(--tab-min-height) + 12px);
|
|
73 |
+ }
|
|
74 |
+
|
|
75 |
+ #main-window[tabsintitlebar] #titlebar:-moz-lwtheme {
|
|
76 |
+ visibility: hidden;
|
|
77 |
+ }
|
|
78 |
+ #main-window[tabsintitlebar] #titlebar-content:-moz-lwtheme {
|
|
79 |
+ visibility: visible;
|
|
80 |
+ }
|
|
81 |
+
|
|
82 |
+ #main-window[tabsintitlebar][sizemode="normal"] > #titlebar {
|
|
83 |
+ -moz-appearance: -moz-window-titlebar;
|
|
84 |
+ }
|
|
85 |
+ #main-window[tabsintitlebar][sizemode="maximized"] > #titlebar {
|
|
86 |
+ -moz-appearance: -moz-window-titlebar-maximized;
|
|
87 |
+ }
|
|
88 |
+
|
|
89 |
+ /* The button box must appear on top of the navigator-toolbox in order for
|
|
90 |
+ * click and hover mouse events to work properly for the button in the restored
|
|
91 |
+ * window state. Otherwise, elements in the navigator-toolbox, like the menubar,
|
|
92 |
+ * can swallow those events.
|
|
93 |
+ */
|
|
94 |
+ #titlebar-buttonbox {
|
|
95 |
+ z-index: 1;
|
|
96 |
+ }
|
|
97 |
+
|
|
98 |
+ /* titlebar command buttons */
|
|
99 |
+ /* Use full scale icons here as the Gtk+ does. */
|
|
100 |
+ @media (-moz-gtk-csd-minimize-button) {
|
|
101 |
+ #titlebar-min {
|
|
102 |
+ list-style-image: url("moz-icon://stock/window-minimize-symbolic");
|
|
103 |
+ -moz-appearance: -moz-window-button-minimize;
|
|
104 |
+ }
|
|
105 |
+ }
|
|
106 |
+ @media not all and (-moz-gtk-csd-minimize-button) {
|
|
107 |
+ #titlebar-min {
|
|
108 |
+ display: none;
|
|
109 |
+ }
|
|
110 |
+ }
|
|
111 |
+
|
|
112 |
+ @media (-moz-gtk-csd-maximize-button) {
|
|
113 |
+ #titlebar-max {
|
|
114 |
+ list-style-image: url("moz-icon://stock/window-maximize-symbolic");
|
|
115 |
+ -moz-appearance: -moz-window-button-maximize;
|
|
116 |
+ }
|
|
117 |
+ #main-window[sizemode="maximized"] #titlebar-max {
|
|
118 |
+ list-style-image: url("moz-icon://stock/window-restore-symbolic");
|
|
119 |
+ -moz-appearance: -moz-window-button-restore;
|
|
120 |
+ }
|
|
121 |
+ }
|
|
122 |
+ @media not all and (-moz-gtk-csd-maximize-button) {
|
|
123 |
+ #titlebar-max {
|
|
124 |
+ display: none;
|
|
125 |
+ }
|
|
126 |
+ #main-window[sizemode="maximized"] #titlebar-max {
|
|
127 |
+ display: none;
|
|
128 |
+ }
|
|
129 |
+ }
|
|
130 |
+
|
|
131 |
+ @media (-moz-gtk-csd-close-button) {
|
|
132 |
+ #titlebar-close {
|
|
133 |
+ list-style-image: url("moz-icon://stock/window-close-symbolic");
|
|
134 |
+ -moz-appearance: -moz-window-button-close;
|
|
135 |
+ }
|
|
136 |
+ }
|
|
137 |
+ @media not all and (-moz-gtk-csd-close-button) {
|
|
138 |
+ #titlebar-close {
|
|
139 |
+ display: none;
|
|
140 |
+ }
|
|
141 |
+ }
|
|
142 |
+}
|
|
143 |
diff -up firefox-57.0b8/dom/base/nsGkAtomList.h.1399611 firefox-57.0b8/dom/base/nsGkAtomList.h
|
|
144 |
--- firefox-57.0b8/dom/base/nsGkAtomList.h.1399611 2017-09-15 06:15:41.000000000 +0200
|
|
145 |
+++ firefox-57.0b8/dom/base/nsGkAtomList.h 2017-10-16 12:11:45.365240651 +0200
|
|
146 |
@@ -2270,6 +2270,10 @@ GK_ATOM(touch_enabled, "touch-enabled")
|
|
147 |
GK_ATOM(menubar_drag, "menubar-drag")
|
|
148 |
GK_ATOM(swipe_animation_enabled, "swipe-animation-enabled")
|
|
149 |
GK_ATOM(physical_home_button, "physical-home-button")
|
|
150 |
+GK_ATOM(gtk_csd_available, "gtk-csd-available")
|
|
151 |
+GK_ATOM(gtk_csd_minimize_button, "gtk-csd-minimize-button")
|
|
152 |
+GK_ATOM(gtk_csd_maximize_button, "gtk-csd-maximize-button")
|
|
153 |
+GK_ATOM(gtk_csd_close_button, "gtk-csd-close-button")
|
|
154 |
|
|
155 |
// windows theme selector metrics
|
|
156 |
GK_ATOM(windows_classic, "windows-classic")
|
|
157 |
@@ -2306,6 +2310,10 @@ GK_ATOM(_moz_device_orientation, "-moz-d
|
|
158 |
GK_ATOM(_moz_is_resource_document, "-moz-is-resource-document")
|
|
159 |
GK_ATOM(_moz_swipe_animation_enabled, "-moz-swipe-animation-enabled")
|
|
160 |
GK_ATOM(_moz_physical_home_button, "-moz-physical-home-button")
|
|
161 |
+GK_ATOM(_moz_gtk_csd_available, "-moz-gtk-csd-available")
|
|
162 |
+GK_ATOM(_moz_gtk_csd_minimize_button, "-moz-gtk-csd-minimize-button")
|
|
163 |
+GK_ATOM(_moz_gtk_csd_maximize_button, "-moz-gtk-csd-maximize-button")
|
|
164 |
+GK_ATOM(_moz_gtk_csd_close_button, "-moz-gtk-csd-close-button")
|
|
165 |
|
|
166 |
// application commands
|
|
167 |
GK_ATOM(Back, "Back")
|
|
168 |
diff -up firefox-57.0b8/gfx/src/nsThemeConstants.h.1399611 firefox-57.0b8/gfx/src/nsThemeConstants.h
|
|
169 |
--- firefox-57.0b8/gfx/src/nsThemeConstants.h.1399611 2017-06-12 18:37:10.000000000 +0200
|
|
170 |
+++ firefox-57.0b8/gfx/src/nsThemeConstants.h 2017-10-16 12:11:45.365240651 +0200
|
|
171 |
@@ -299,6 +299,7 @@ enum ThemeWidgetType : uint8_t {
|
|
172 |
NS_THEME_MAC_SOURCE_LIST,
|
|
173 |
NS_THEME_MAC_SOURCE_LIST_SELECTION,
|
|
174 |
NS_THEME_MAC_ACTIVE_SOURCE_LIST_SELECTION,
|
|
175 |
+ NS_THEME_GTK_WINDOW_DECORATION,
|
|
176 |
|
|
177 |
ThemeWidgetType_COUNT
|
|
178 |
};
|
|
179 |
diff -up firefox-57.0b8/layout/style/nsCSSRuleProcessor.cpp.1399611 firefox-57.0b8/layout/style/nsCSSRuleProcessor.cpp
|
|
180 |
--- firefox-57.0b8/layout/style/nsCSSRuleProcessor.cpp.1399611 2017-08-02 14:27:54.000000000 +0200
|
|
181 |
+++ firefox-57.0b8/layout/style/nsCSSRuleProcessor.cpp 2017-10-16 12:11:45.365240651 +0200
|
|
182 |
@@ -1180,6 +1180,30 @@ nsCSSRuleProcessor::InitSystemMetrics()
|
|
183 |
sSystemMetrics->AppendElement(nsGkAtoms::physical_home_button);
|
|
184 |
}
|
|
185 |
|
|
186 |
+ rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDAvailable,
|
|
187 |
+ &metricResult);
|
|
188 |
+ if (NS_SUCCEEDED(rv) && metricResult) {
|
|
189 |
+ sSystemMetrics->AppendElement(nsGkAtoms::gtk_csd_available);
|
|
190 |
+ }
|
|
191 |
+
|
|
192 |
+ rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDMinimizeButton,
|
|
193 |
+ &metricResult);
|
|
194 |
+ if (NS_SUCCEEDED(rv) && metricResult) {
|
|
195 |
+ sSystemMetrics->AppendElement(nsGkAtoms::gtk_csd_minimize_button);
|
|
196 |
+ }
|
|
197 |
+
|
|
198 |
+ rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDMaximizeButton,
|
|
199 |
+ &metricResult);
|
|
200 |
+ if (NS_SUCCEEDED(rv) && metricResult) {
|
|
201 |
+ sSystemMetrics->AppendElement(nsGkAtoms::gtk_csd_maximize_button);
|
|
202 |
+ }
|
|
203 |
+
|
|
204 |
+ rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDCloseButton,
|
|
205 |
+ &metricResult);
|
|
206 |
+ if (NS_SUCCEEDED(rv) && metricResult) {
|
|
207 |
+ sSystemMetrics->AppendElement(nsGkAtoms::gtk_csd_close_button);
|
|
208 |
+ }
|
|
209 |
+
|
|
210 |
#ifdef XP_WIN
|
|
211 |
if (NS_SUCCEEDED(
|
|
212 |
LookAndFeel::GetInt(LookAndFeel::eIntID_WindowsThemeIdentifier,
|
|
213 |
diff -up firefox-57.0b8/layout/style/nsMediaFeatures.cpp.1399611 firefox-57.0b8/layout/style/nsMediaFeatures.cpp
|
|
214 |
--- firefox-57.0b8/layout/style/nsMediaFeatures.cpp.1399611 2017-09-15 06:15:42.000000000 +0200
|
|
215 |
+++ firefox-57.0b8/layout/style/nsMediaFeatures.cpp 2017-10-16 12:11:45.366240647 +0200
|
|
216 |
@@ -788,6 +788,42 @@ nsMediaFeatures::features[] = {
|
|
217 |
GetSystemMetric
|
|
218 |
},
|
|
219 |
|
|
220 |
+ {
|
|
221 |
+ &nsGkAtoms::_moz_gtk_csd_available,
|
|
222 |
+ nsMediaFeature::eMinMaxNotAllowed,
|
|
223 |
+ nsMediaFeature::eBoolInteger,
|
|
224 |
+ nsMediaFeature::eNoRequirements,
|
|
225 |
+ { &nsGkAtoms::gtk_csd_available },
|
|
226 |
+ GetSystemMetric
|
|
227 |
+ },
|
|
228 |
+
|
|
229 |
+ {
|
|
230 |
+ &nsGkAtoms::_moz_gtk_csd_minimize_button,
|
|
231 |
+ nsMediaFeature::eMinMaxNotAllowed,
|
|
232 |
+ nsMediaFeature::eBoolInteger,
|
|
233 |
+ nsMediaFeature::eNoRequirements,
|
|
234 |
+ { &nsGkAtoms::gtk_csd_minimize_button },
|
|
235 |
+ GetSystemMetric
|
|
236 |
+ },
|
|
237 |
+
|
|
238 |
+ {
|
|
239 |
+ &nsGkAtoms::_moz_gtk_csd_maximize_button,
|
|
240 |
+ nsMediaFeature::eMinMaxNotAllowed,
|
|
241 |
+ nsMediaFeature::eBoolInteger,
|
|
242 |
+ nsMediaFeature::eNoRequirements,
|
|
243 |
+ { &nsGkAtoms::gtk_csd_maximize_button },
|
|
244 |
+ GetSystemMetric
|
|
245 |
+ },
|
|
246 |
+
|
|
247 |
+ {
|
|
248 |
+ &nsGkAtoms::_moz_gtk_csd_close_button,
|
|
249 |
+ nsMediaFeature::eMinMaxNotAllowed,
|
|
250 |
+ nsMediaFeature::eBoolInteger,
|
|
251 |
+ nsMediaFeature::eNoRequirements,
|
|
252 |
+ { &nsGkAtoms::gtk_csd_close_button },
|
|
253 |
+ GetSystemMetric
|
|
254 |
+ },
|
|
255 |
+
|
|
256 |
// Internal -moz-is-glyph media feature: applies only inside SVG glyphs.
|
|
257 |
// Internal because it is really only useful in the user agent anyway
|
|
258 |
// and therefore not worth standardizing.
|
|
259 |
diff -up firefox-57.0b8/modules/libpref/init/all.js.1399611 firefox-57.0b8/modules/libpref/init/all.js
|
|
260 |
--- firefox-57.0b8/modules/libpref/init/all.js.1399611 2017-10-12 18:12:09.000000000 +0200
|
|
261 |
+++ firefox-57.0b8/modules/libpref/init/all.js 2017-10-16 12:11:45.366240647 +0200
|
|
262 |
@@ -4911,6 +4911,7 @@ pref("gfx.apitrace.enabled",false);
|
|
263 |
pref("gfx.xrender.enabled",false);
|
|
264 |
pref("widget.chrome.allow-gtk-dark-theme", false);
|
|
265 |
pref("widget.content.allow-gtk-dark-theme", false);
|
|
266 |
+pref("widget.allow-client-side-decoration", false);
|
|
267 |
#endif
|
|
268 |
#endif
|
|
269 |
|
|
270 |
diff -up firefox-57.0b8/toolkit/modules/moz.build.1399611 firefox-57.0b8/toolkit/modules/moz.build
|
|
271 |
--- firefox-57.0b8/toolkit/modules/moz.build.1399611 2017-09-15 06:15:40.000000000 +0200
|
|
272 |
+++ firefox-57.0b8/toolkit/modules/moz.build 2017-10-16 12:11:45.366240647 +0200
|
|
273 |
@@ -259,7 +259,7 @@ EXTRA_JS_MODULES.sessionstore += [
|
|
274 |
]
|
|
275 |
|
|
276 |
DEFINES['INSTALL_COMPACT_THEMES'] = 1
|
|
277 |
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'):
|
|
278 |
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa', 'gtk3'):
|
|
279 |
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1
|
|
280 |
|
|
281 |
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'):
|
|
282 |
diff -up firefox-57.0b8/widget/gtk/gtk3drawing.cpp.1399611 firefox-57.0b8/widget/gtk/gtk3drawing.cpp
|
|
283 |
--- firefox-57.0b8/widget/gtk/gtk3drawing.cpp.1399611 2017-09-15 06:15:40.000000000 +0200
|
|
284 |
+++ firefox-57.0b8/widget/gtk/gtk3drawing.cpp 2017-10-16 12:11:45.367240644 +0200
|
|
285 |
@@ -17,6 +17,7 @@
|
|
286 |
#include "WidgetStyleCache.h"
|
|
287 |
|
|
288 |
#include <math.h>
|
|
289 |
+#include <dlfcn.h>
|
|
290 |
|
|
291 |
static gboolean checkbox_check_state;
|
|
292 |
static gboolean notebook_has_tab_gap;
|
|
293 |
@@ -39,9 +40,25 @@ static gint
|
|
294 |
moz_gtk_menu_item_paint(WidgetNodeType widget, cairo_t *cr, GdkRectangle* rect,
|
|
295 |
GtkWidgetState* state, GtkTextDirection direction);
|
|
296 |
|
|
297 |
+static void
|
|
298 |
+moz_gtk_add_style_margin(GtkStyleContext* style,
|
|
299 |
+ gint* left, gint* top, gint* right, gint* bottom);
|
|
300 |
+static void
|
|
301 |
+moz_gtk_add_style_border(GtkStyleContext* style,
|
|
302 |
+ gint* left, gint* top, gint* right, gint* bottom);
|
|
303 |
+static void
|
|
304 |
+moz_gtk_add_style_padding(GtkStyleContext* style,
|
|
305 |
+ gint* left, gint* top, gint* right, gint* bottom);
|
|
306 |
+static void moz_gtk_add_margin_border_padding(GtkStyleContext *style,
|
|
307 |
+ gint* left, gint* top,
|
|
308 |
+ gint* right, gint* bottom);
|
|
309 |
+static void moz_gtk_add_border_padding(GtkStyleContext *style,
|
|
310 |
+ gint* left, gint* top,
|
|
311 |
+ gint* right, gint* bottom);
|
|
312 |
static GtkBorder
|
|
313 |
GetMarginBorderPadding(GtkStyleContext* aStyle);
|
|
314 |
|
|
315 |
+
|
|
316 |
// GetStateFlagsFromGtkWidgetState() can be safely used for the specific
|
|
317 |
// GtkWidgets that set both prelight and active flags. For other widgets,
|
|
318 |
// either the GtkStateFlags or Gecko's GtkWidgetState need to be carefully
|
|
319 |
@@ -233,6 +250,43 @@ moz_gtk_splitter_get_metrics(gint orient
|
|
320 |
return MOZ_GTK_SUCCESS;
|
|
321 |
}
|
|
322 |
|
|
323 |
+void
|
|
324 |
+moz_gtk_get_window_border(gint* top, gint* right, gint* bottom, gint* left)
|
|
325 |
+{
|
|
326 |
+ MOZ_ASSERT(gtk_check_version(3, 20, 0) == nullptr,
|
|
327 |
+ "Window decorations are only supported on GTK 3.20+.");
|
|
328 |
+
|
|
329 |
+ GtkStyleContext* style = GetStyleContext(MOZ_GTK_WINDOW);
|
|
330 |
+
|
|
331 |
+ *top = *right = *bottom = *left = 0;
|
|
332 |
+ moz_gtk_add_border_padding(style, left, top, right, bottom);
|
|
333 |
+ GtkBorder windowMargin;
|
|
334 |
+ gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &windowMargin);
|
|
335 |
+
|
|
336 |
+ style = GetStyleContext(MOZ_GTK_WINDOW_DECORATION);
|
|
337 |
+
|
|
338 |
+ // Available on GTK 3.20+.
|
|
339 |
+ static auto sGtkRenderBackgroundGetClip =
|
|
340 |
+ (void (*)(GtkStyleContext*, gdouble, gdouble, gdouble, gdouble, GdkRectangle*))
|
|
341 |
+ dlsym(RTLD_DEFAULT, "gtk_render_background_get_clip");
|
|
342 |
+
|
|
343 |
+ GdkRectangle shadowClip;
|
|
344 |
+ sGtkRenderBackgroundGetClip(style, 0, 0, 0, 0, &shadowClip);
|
|
345 |
+
|
|
346 |
+ // Transfer returned inset rectangle to GtkBorder
|
|
347 |
+ GtkBorder shadowBorder = {
|
|
348 |
+ static_cast<gint16>(-shadowClip.x), // left
|
|
349 |
+ static_cast<gint16>(shadowClip.width + shadowClip.x), // right
|
|
350 |
+ static_cast<gint16>(-shadowClip.y), // top
|
|
351 |
+ static_cast<gint16>(shadowClip.height + shadowClip.y), // bottom
|
|
352 |
+ };
|
|
353 |
+
|
|
354 |
+ *left += MAX(windowMargin.left, shadowBorder.left);
|
|
355 |
+ *right += MAX(windowMargin.right, shadowBorder.right);
|
|
356 |
+ *top += MAX(windowMargin.top, shadowBorder.top);
|
|
357 |
+ *bottom += MAX(windowMargin.bottom, shadowBorder.bottom);
|
|
358 |
+}
|
|
359 |
+
|
|
360 |
static gint
|
|
361 |
moz_gtk_window_paint(cairo_t *cr, GdkRectangle* rect,
|
|
362 |
GtkTextDirection direction)
|
|
363 |
@@ -302,6 +356,24 @@ moz_gtk_button_paint(cairo_t *cr, GdkRec
|
|
364 |
}
|
|
365 |
|
|
366 |
static gint
|
|
367 |
+moz_gtk_header_bar_button_paint(cairo_t *cr, GdkRectangle* rect,
|
|
368 |
+ GtkWidgetState* state,
|
|
369 |
+ GtkReliefStyle relief, GtkWidget* widget,
|
|
370 |
+ GtkTextDirection direction)
|
|
371 |
+{
|
|
372 |
+ GtkBorder margin;
|
|
373 |
+ GtkStyleContext* style = gtk_widget_get_style_context(widget);
|
|
374 |
+ gtk_style_context_get_margin(style, GTK_STATE_FLAG_NORMAL, &margin);
|
|
375 |
+
|
|
376 |
+ rect->x += margin.left;
|
|
377 |
+ rect->y += margin.top;
|
|
378 |
+ rect->width -= margin.left + margin.right;
|
|
379 |
+ rect->height -= margin.top + margin.bottom;
|
|
380 |
+
|
|
381 |
+ return moz_gtk_button_paint(cr, rect, state, relief, widget, direction);
|
|
382 |
+}
|
|
383 |
+
|
|
384 |
+static gint
|
|
385 |
moz_gtk_toggle_paint(cairo_t *cr, GdkRectangle* rect,
|
|
386 |
GtkWidgetState* state,
|
|
387 |
gboolean selected, gboolean inconsistent,
|
|
388 |
@@ -1948,6 +2020,38 @@ moz_gtk_info_bar_paint(cairo_t *cr, GdkR
|
|
389 |
return MOZ_GTK_SUCCESS;
|
|
390 |
}
|
|
391 |
|
|
392 |
+static gint
|
|
393 |
+moz_gtk_header_bar_paint(WidgetNodeType widgetType,
|
|
394 |
+ cairo_t *cr, GdkRectangle* rect, GtkWidgetState* state)
|
|
395 |
+{
|
|
396 |
+ GtkStateFlags state_flags = GetStateFlagsFromGtkWidgetState(state);
|
|
397 |
+ GtkStyleContext *style;
|
|
398 |
+
|
|
399 |
+ style = GetStyleContext(widgetType, GTK_TEXT_DIR_LTR,
|
|
400 |
+ state_flags);
|
|
401 |
+ InsetByMargin(rect, style);
|
|
402 |
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width,
|
|
403 |
+ rect->height);
|
|
404 |
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
|
|
405 |
+
|
|
406 |
+ return MOZ_GTK_SUCCESS;
|
|
407 |
+}
|
|
408 |
+
|
|
409 |
+void
|
|
410 |
+moz_gtk_header_bar_paint(cairo_t *cr, GdkRectangle* rect)
|
|
411 |
+{
|
|
412 |
+ static GtkWidgetState state;
|
|
413 |
+ moz_gtk_header_bar_paint(MOZ_GTK_HEADER_BAR, cr, rect, &state);
|
|
414 |
+}
|
|
415 |
+
|
|
416 |
+void
|
|
417 |
+moz_gtk_get_header_bar_border(gint* top, gint* right, gint* bottom, gint* left)
|
|
418 |
+{
|
|
419 |
+ *left = *top = *right = *bottom = 0;
|
|
420 |
+ moz_gtk_add_border_padding(GetStyleContext(MOZ_GTK_HEADER_BAR),
|
|
421 |
+ left, top, right, bottom);
|
|
422 |
+}
|
|
423 |
+
|
|
424 |
static void
|
|
425 |
moz_gtk_add_style_margin(GtkStyleContext* style,
|
|
426 |
gint* left, gint* top, gint* right, gint* bottom)
|
|
427 |
@@ -1999,6 +2103,14 @@ static void moz_gtk_add_margin_border_pa
|
|
428 |
moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
429 |
}
|
|
430 |
|
|
431 |
+static void moz_gtk_add_border_padding(GtkStyleContext *style,
|
|
432 |
+ gint* left, gint* top,
|
|
433 |
+ gint* right, gint* bottom)
|
|
434 |
+{
|
|
435 |
+ moz_gtk_add_style_border(style, left, top, right, bottom);
|
|
436 |
+ moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
437 |
+}
|
|
438 |
+
|
|
439 |
static GtkBorder
|
|
440 |
GetMarginBorderPadding(GtkStyleContext* aStyle)
|
|
441 |
{
|
|
442 |
@@ -2054,8 +2166,7 @@ moz_gtk_get_widget_border(WidgetNodeType
|
|
443 |
// XXX: Subtract 1 pixel from the padding to account for the default
|
|
444 |
// padding in forms.css. See bug 1187385.
|
|
445 |
*left = *top = *right = *bottom = -1;
|
|
446 |
- moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
447 |
- moz_gtk_add_style_border(style, left, top, right, bottom);
|
|
448 |
+ moz_gtk_add_border_padding(style, left, top, right, bottom);
|
|
449 |
|
|
450 |
return MOZ_GTK_SUCCESS;
|
|
451 |
}
|
|
452 |
@@ -2076,10 +2187,8 @@ moz_gtk_get_widget_border(WidgetNodeType
|
|
453 |
*left = *top = *right = *bottom =
|
|
454 |
gtk_container_get_border_width(GTK_CONTAINER(
|
|
455 |
GetWidget(MOZ_GTK_TREE_HEADER_CELL)));
|
|
456 |
-
|
|
457 |
style = GetStyleContext(MOZ_GTK_TREE_HEADER_CELL);
|
|
458 |
- moz_gtk_add_style_border(style, left, top, right, bottom);
|
|
459 |
- moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
460 |
+ moz_gtk_add_border_padding(style, left, top, right, bottom);
|
|
461 |
return MOZ_GTK_SUCCESS;
|
|
462 |
}
|
|
463 |
case MOZ_GTK_TREE_HEADER_SORTARROW:
|
|
464 |
@@ -2105,8 +2214,7 @@ moz_gtk_get_widget_border(WidgetNodeType
|
|
465 |
gtk_container_get_border_width(GTK_CONTAINER(
|
|
466 |
GetWidget(MOZ_GTK_COMBOBOX_BUTTON)));
|
|
467 |
style = GetStyleContext(MOZ_GTK_COMBOBOX_BUTTON);
|
|
468 |
- moz_gtk_add_style_padding(style, left, top, right, bottom);
|
|
469 |
- moz_gtk_add_style_border(style, left, top, right, bottom);
|
|
470 |
+ moz_gtk_add_border_padding(style, left, top, right, bottom);
|
|
471 |
|
|
472 |
/* If there is no separator, don't try to count its width. */
|
|
473 |
separator_width = 0;
|
|
474 |
@@ -2160,10 +2268,8 @@ moz_gtk_get_widget_border(WidgetNodeType
|
|
475 |
style = gtk_widget_get_style_context(w);
|
|
476 |
|
|
477 |
*left = *top = *right = *bottom = gtk_container_get_border_width(GTK_CONTAINER(w));
|
|
478 |
- moz_gtk_add_style_border(style,
|
|
479 |
- left, top, right, bottom);
|
|
480 |
- moz_gtk_add_style_padding(style,
|
|
481 |
- left, top, right, bottom);
|
|
482 |
+ moz_gtk_add_border_padding(style,
|
|
483 |
+ left, top, right, bottom);
|
|
484 |
return MOZ_GTK_SUCCESS;
|
|
485 |
}
|
|
486 |
case MOZ_GTK_MENUPOPUP:
|
|
487 |
@@ -2210,6 +2316,21 @@ moz_gtk_get_widget_border(WidgetNodeType
|
|
488 |
|
|
489 |
return MOZ_GTK_SUCCESS;
|
|
490 |
}
|
|
491 |
+ case MOZ_GTK_HEADER_BAR:
|
|
492 |
+ case MOZ_GTK_HEADER_BAR_MAXIMIZED:
|
|
493 |
+ {
|
|
494 |
+ style = GetStyleContext(widget);
|
|
495 |
+ moz_gtk_add_border_padding(style, left, top, right, bottom);
|
|
496 |
+ return MOZ_GTK_SUCCESS;
|
|
497 |
+ }
|
|
498 |
+ case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
|
|
499 |
+ case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE:
|
|
500 |
+ case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE:
|
|
501 |
+ {
|
|
502 |
+ style = GetStyleContext(widget);
|
|
503 |
+ moz_gtk_add_margin_border_padding(style, left, top, right, bottom);
|
|
504 |
+ return MOZ_GTK_SUCCESS;
|
|
505 |
+ }
|
|
506 |
|
|
507 |
/* These widgets have no borders, since they are not containers. */
|
|
508 |
case MOZ_GTK_CHECKBUTTON_LABEL:
|
|
509 |
@@ -2646,6 +2767,36 @@ GetScrollbarMetrics(GtkOrientation aOrie
|
|
510 |
return metrics;
|
|
511 |
}
|
|
512 |
|
|
513 |
+void
|
|
514 |
+moz_gtk_window_decoration_paint(cairo_t *cr, GdkRectangle* rect)
|
|
515 |
+{
|
|
516 |
+ gint top, right, bottom, left;
|
|
517 |
+ moz_gtk_get_window_border(&top, &right, &bottom, &left);
|
|
518 |
+
|
|
519 |
+ cairo_save(cr);
|
|
520 |
+ cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
|
|
521 |
+ cairo_rectangle(cr, rect->x, rect->y, left, rect->height);
|
|
522 |
+ cairo_fill(cr);
|
|
523 |
+ cairo_rectangle(cr, rect->x+rect->width-right, rect->y, right, rect->height);
|
|
524 |
+ cairo_fill(cr);
|
|
525 |
+ cairo_rectangle(cr, rect->x, rect->y, rect->width, top);
|
|
526 |
+ cairo_fill(cr);
|
|
527 |
+ cairo_rectangle(cr, rect->x, rect->height-bottom, rect->width, bottom);
|
|
528 |
+ cairo_fill(cr);
|
|
529 |
+ cairo_restore(cr);
|
|
530 |
+
|
|
531 |
+ GtkStyleContext* style = GetStyleContext(MOZ_GTK_WINDOW_DECORATION,
|
|
532 |
+ GTK_TEXT_DIR_NONE);
|
|
533 |
+ rect->x += left;
|
|
534 |
+ rect->y += top;
|
|
535 |
+ rect->width -= left + right;
|
|
536 |
+ rect->height -= top + bottom;
|
|
537 |
+
|
|
538 |
+ gtk_render_background(style, cr, rect->x, rect->y, rect->width, rect->height);
|
|
539 |
+ gtk_render_frame(style, cr, rect->x, rect->y, rect->width, rect->height);
|
|
540 |
+}
|
|
541 |
+
|
|
542 |
+
|
|
543 |
/* cairo_t *cr argument has to be a system-cairo. */
|
|
544 |
gint
|
|
545 |
moz_gtk_widget_paint(WidgetNodeType widget, cairo_t *cr,
|
|
546 |
@@ -2671,6 +2822,14 @@ moz_gtk_widget_paint(WidgetNodeType widg
|
|
547 |
GetWidget(MOZ_GTK_BUTTON),
|
|
548 |
direction);
|
|
549 |
break;
|
|
550 |
+ case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE:
|
|
551 |
+ case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE:
|
|
552 |
+ case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE:
|
|
553 |
+ return moz_gtk_header_bar_button_paint(cr, rect, state,
|
|
554 |
+ (GtkReliefStyle) flags,
|
|
555 |
+ GetWidget(widget),
|
|
556 |
+ direction);
|
|
557 |
+ break;
|
|
558 |
case MOZ_GTK_CHECKBUTTON:
|
|
559 |
case MOZ_GTK_RADIOBUTTON:
|
|
560 |
return moz_gtk_toggle_paint(cr, rect, state,
|
|
561 |
@@ -2877,6 +3036,10 @@ moz_gtk_widget_paint(WidgetNodeType widg
|
|
562 |
case MOZ_GTK_INFO_BAR:
|
|
563 |
return moz_gtk_info_bar_paint(cr, rect, state);
|
|
564 |
break;
|
|
565 |
+ case MOZ_GTK_HEADER_BAR:
|
|
566 |
+ case MOZ_GTK_HEADER_BAR_MAXIMIZED:
|
|
567 |
+ return moz_gtk_header_bar_paint(widget, cr, rect, state);
|
|
568 |
+ break;
|
|
569 |
default:
|
|
570 |
g_warning("Unknown widget type: %d", widget);
|
|
571 |
}
|
|
572 |
diff -up firefox-57.0b8/widget/gtk/gtkdrawing.h.1399611 firefox-57.0b8/widget/gtk/gtkdrawing.h
|
|
573 |
--- firefox-57.0b8/widget/gtk/gtkdrawing.h.1399611 2017-06-12 18:37:20.000000000 +0200
|
|
574 |
+++ firefox-57.0b8/widget/gtk/gtkdrawing.h 2017-10-16 12:11:45.367240644 +0200
|
|
575 |
@@ -268,8 +268,14 @@ typedef enum {
|
|
576 |
MOZ_GTK_SPLITTER_SEPARATOR_VERTICAL,
|
|
577 |
/* Paints the background of a window, dialog or page. */
|
|
578 |
MOZ_GTK_WINDOW,
|
|
579 |
+ /* Used only as a container for MOZ_GTK_HEADER_BAR_MAXIMIZED. */
|
|
580 |
+ MOZ_GTK_WINDOW_MAXIMIZED,
|
|
581 |
/* Window container for all widgets */
|
|
582 |
MOZ_GTK_WINDOW_CONTAINER,
|
|
583 |
+ /* Window with the 'csd' style class. */
|
|
584 |
+ MOZ_GTK_WINDOW_CSD,
|
|
585 |
+ /* Client-side window decoration node. Available on GTK 3.20+. */
|
|
586 |
+ MOZ_GTK_WINDOW_DECORATION,
|
|
587 |
/* Paints a GtkInfoBar, for notifications. */
|
|
588 |
MOZ_GTK_INFO_BAR,
|
|
589 |
/* Used for widget tree construction. */
|
|
590 |
@@ -290,6 +296,14 @@ typedef enum {
|
|
591 |
MOZ_GTK_COMBOBOX_ENTRY_ARROW,
|
|
592 |
/* Used for scrolled window shell. */
|
|
593 |
MOZ_GTK_SCROLLED_WINDOW,
|
|
594 |
+ /* Paints a GtkHeaderBar */
|
|
595 |
+ MOZ_GTK_HEADER_BAR,
|
|
596 |
+ /* Paints a GtkHeaderBar in maximized state */
|
|
597 |
+ MOZ_GTK_HEADER_BAR_MAXIMIZED,
|
|
598 |
+ /* Paints a GtkHeaderBar title buttons */
|
|
599 |
+ MOZ_GTK_HEADER_BAR_BUTTON_CLOSE,
|
|
600 |
+ MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE,
|
|
601 |
+ MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE,
|
|
602 |
|
|
603 |
MOZ_GTK_WIDGET_NODE_COUNT
|
|
604 |
} WidgetNodeType;
|
|
605 |
@@ -542,6 +556,32 @@ gint moz_gtk_get_menu_separator_height(g
|
|
606 |
*/
|
|
607 |
gint moz_gtk_splitter_get_metrics(gint orientation, gint* size);
|
|
608 |
|
|
609 |
+#if (MOZ_WIDGET_GTK == 3)
|
|
610 |
+/**
|
|
611 |
+ * Gets the margins to be used for window decorations, typically the extra space
|
|
612 |
+ * required to draw a drop shadow (obtained from gtk_render_background_get_clip).
|
|
613 |
+ * Only available on GTK 3.20+.
|
|
614 |
+ */
|
|
615 |
+void moz_gtk_get_window_border(gint* top, gint* right, gint* bottom, gint* left);
|
|
616 |
+
|
|
617 |
+/**
|
|
618 |
+ * Draw window decorations, typically a shadow.
|
|
619 |
+ * Only available on GTK 3.20+.
|
|
620 |
+ */
|
|
621 |
+void moz_gtk_window_decoration_paint(cairo_t *cr, GdkRectangle* rect);
|
|
622 |
+
|
|
623 |
+/**
|
|
624 |
+ * Gets the border of window header bar, only available on GTK 3.20+.
|
|
625 |
+ */
|
|
626 |
+void moz_gtk_get_header_bar_border(gint* top, gint* right, gint* bottom, gint* left);
|
|
627 |
+
|
|
628 |
+/**
|
|
629 |
+ * Draw window header bar, only available on GTK 3.20+.
|
|
630 |
+ */
|
|
631 |
+void moz_gtk_header_bar_paint(cairo_t *cr, GdkRectangle* rect);
|
|
632 |
+
|
|
633 |
+#endif
|
|
634 |
+
|
|
635 |
/**
|
|
636 |
* Get the YTHICKNESS of a tab (notebook extension).
|
|
637 |
*/
|
|
638 |
diff -up firefox-57.0b8/widget/gtk/mozgtk/mozgtk.c.1399611 firefox-57.0b8/widget/gtk/mozgtk/mozgtk.c
|
|
639 |
--- firefox-57.0b8/widget/gtk/mozgtk/mozgtk.c.1399611 2017-10-09 22:17:13.000000000 +0200
|
|
640 |
+++ firefox-57.0b8/widget/gtk/mozgtk/mozgtk.c 2017-10-16 12:11:45.367240644 +0200
|
|
641 |
@@ -580,6 +580,8 @@ STUB(gtk_style_context_set_state)
|
|
642 |
STUB(gtk_style_properties_lookup_property)
|
|
643 |
STUB(gtk_tree_view_column_get_button)
|
|
644 |
STUB(gtk_widget_get_preferred_size)
|
|
645 |
+STUB(gtk_widget_get_preferred_width)
|
|
646 |
+STUB(gtk_widget_get_preferred_height)
|
|
647 |
STUB(gtk_widget_get_state_flags)
|
|
648 |
STUB(gtk_widget_get_style_context)
|
|
649 |
STUB(gtk_widget_path_append_type)
|
|
650 |
@@ -589,6 +591,10 @@ STUB(gtk_widget_path_iter_add_class)
|
|
651 |
STUB(gtk_widget_path_get_object_type)
|
|
652 |
STUB(gtk_widget_path_new)
|
|
653 |
STUB(gtk_widget_path_unref)
|
|
654 |
+STUB(gtk_widget_set_margin_left)
|
|
655 |
+STUB(gtk_widget_set_margin_right)
|
|
656 |
+STUB(gtk_widget_set_margin_top)
|
|
657 |
+STUB(gtk_widget_set_margin_bottom)
|
|
658 |
STUB(gtk_widget_set_visual)
|
|
659 |
STUB(gtk_app_chooser_dialog_new_for_content_type)
|
|
660 |
STUB(gtk_app_chooser_get_type)
|
|
661 |
@@ -601,6 +607,7 @@ STUB(gtk_color_chooser_get_type)
|
|
662 |
STUB(gtk_color_chooser_set_rgba)
|
|
663 |
STUB(gtk_color_chooser_get_rgba)
|
|
664 |
STUB(gtk_color_chooser_set_use_alpha)
|
|
665 |
+STUB(gtk_window_get_size)
|
|
666 |
#endif
|
|
667 |
|
|
668 |
#ifdef GTK2_SYMBOLS
|
|
669 |
diff -up firefox-57.0b8/widget/gtk/nsLookAndFeel.cpp.1399611 firefox-57.0b8/widget/gtk/nsLookAndFeel.cpp
|
|
670 |
--- firefox-57.0b8/widget/gtk/nsLookAndFeel.cpp.1399611 2017-09-21 06:10:10.000000000 +0200
|
|
671 |
+++ firefox-57.0b8/widget/gtk/nsLookAndFeel.cpp 2017-10-16 12:11:45.367240644 +0200
|
|
672 |
@@ -642,6 +642,22 @@ nsLookAndFeel::GetIntImpl(IntID aID, int
|
|
673 |
case eIntID_ContextMenuOffsetHorizontal:
|
|
674 |
aResult = 2;
|
|
675 |
break;
|
|
676 |
+ case eIntID_GTKCSDAvailable:
|
|
677 |
+ EnsureInit();
|
|
678 |
+ aResult = sCSDAvailable;
|
|
679 |
+ break;
|
|
680 |
+ case eIntID_GTKCSDMaximizeButton:
|
|
681 |
+ EnsureInit();
|
|
682 |
+ aResult = sCSDMaximizeButton;
|
|
683 |
+ break;
|
|
684 |
+ case eIntID_GTKCSDMinimizeButton:
|
|
685 |
+ EnsureInit();
|
|
686 |
+ aResult = sCSDMinimizeButton;
|
|
687 |
+ break;
|
|
688 |
+ case eIntID_GTKCSDCloseButton:
|
|
689 |
+ EnsureInit();
|
|
690 |
+ aResult = sCSDCloseButton;
|
|
691 |
+ break;
|
|
692 |
default:
|
|
693 |
aResult = 0;
|
|
694 |
res = NS_ERROR_FAILURE;
|
|
695 |
@@ -1048,6 +1064,40 @@ nsLookAndFeel::EnsureInit()
|
|
696 |
|
|
697 |
gtk_widget_destroy(window);
|
|
698 |
g_object_unref(labelWidget);
|
|
699 |
+
|
|
700 |
+ // Require GTK 3.20 for client-side decoration support.
|
|
701 |
+ // 3.20 exposes gtk_render_background_get_clip, which is required for
|
|
702 |
+ // calculating shadow metrics for decorated windows.
|
|
703 |
+ sCSDAvailable = gtk_check_version(3, 20, 0) == nullptr;
|
|
704 |
+ if (sCSDAvailable) {
|
|
705 |
+ sCSDAvailable =
|
|
706 |
+ mozilla::Preferences::GetBool("widget.allow-client-side-decoration",
|
|
707 |
+ false);
|
|
708 |
+ }
|
|
709 |
+
|
|
710 |
+ const gchar* decorationLayout = nullptr;
|
|
711 |
+ if (gtk_check_version(3, 12, 0) == nullptr) {
|
|
712 |
+ static auto sGtkHeaderBarGetDecorationLayoutPtr =
|
|
713 |
+ (const gchar* (*)(GtkWidget*))
|
|
714 |
+ dlsym(RTLD_DEFAULT, "gtk_header_bar_get_decoration_layout");
|
|
715 |
+
|
|
716 |
+ GtkWidget* headerBar = GetWidget(MOZ_GTK_HEADER_BAR);
|
|
717 |
+ decorationLayout = sGtkHeaderBarGetDecorationLayoutPtr(headerBar);
|
|
718 |
+ if (!decorationLayout) {
|
|
719 |
+ g_object_get(settings, "gtk-decoration-layout", &decorationLayout,
|
|
720 |
+ nullptr);
|
|
721 |
+ }
|
|
722 |
+ }
|
|
723 |
+
|
|
724 |
+ if (decorationLayout) {
|
|
725 |
+ sCSDCloseButton = (strstr(decorationLayout, "close") != nullptr);
|
|
726 |
+ sCSDMaximizeButton = (strstr(decorationLayout, "maximize") != nullptr);
|
|
727 |
+ sCSDMinimizeButton = (strstr(decorationLayout, "minimize") != nullptr);
|
|
728 |
+ } else {
|
|
729 |
+ sCSDCloseButton = true;
|
|
730 |
+ sCSDMaximizeButton = true;
|
|
731 |
+ sCSDMinimizeButton = true;
|
|
732 |
+ }
|
|
733 |
}
|
|
734 |
|
|
735 |
// virtual
|
|
736 |
diff -up firefox-57.0b8/widget/gtk/nsLookAndFeel.h.1399611 firefox-57.0b8/widget/gtk/nsLookAndFeel.h
|
|
737 |
--- firefox-57.0b8/widget/gtk/nsLookAndFeel.h.1399611 2017-09-21 06:10:10.000000000 +0200
|
|
738 |
+++ firefox-57.0b8/widget/gtk/nsLookAndFeel.h 2017-10-16 12:11:45.367240644 +0200
|
|
739 |
@@ -32,6 +32,8 @@ public:
|
|
740 |
virtual char16_t GetPasswordCharacterImpl();
|
|
741 |
virtual bool GetEchoPasswordImpl();
|
|
742 |
|
|
743 |
+ bool IsCSDAvailable() const { return sCSDAvailable; }
|
|
744 |
+
|
|
745 |
protected:
|
|
746 |
|
|
747 |
// Cached fonts
|
|
748 |
@@ -82,6 +84,10 @@ protected:
|
|
749 |
char16_t sInvisibleCharacter;
|
|
750 |
float sCaretRatio;
|
|
751 |
bool sMenuSupportsDrag;
|
|
752 |
+ bool sCSDAvailable;
|
|
753 |
+ bool sCSDMaximizeButton;
|
|
754 |
+ bool sCSDMinimizeButton;
|
|
755 |
+ bool sCSDCloseButton;
|
|
756 |
bool mInitialized;
|
|
757 |
|
|
758 |
void EnsureInit();
|
|
759 |
diff -up firefox-57.0b8/widget/gtk/nsNativeThemeGTK.cpp.1399611 firefox-57.0b8/widget/gtk/nsNativeThemeGTK.cpp
|
|
760 |
--- firefox-57.0b8/widget/gtk/nsNativeThemeGTK.cpp.1399611 2017-09-19 06:18:28.000000000 +0200
|
|
761 |
+++ firefox-57.0b8/widget/gtk/nsNativeThemeGTK.cpp 2017-10-16 12:11:45.368240640 +0200
|
|
762 |
@@ -23,6 +23,7 @@
|
|
763 |
#include "nsIDOMHTMLInputElement.h"
|
|
764 |
#include "nsGkAtoms.h"
|
|
765 |
#include "nsAttrValueInlines.h"
|
|
766 |
+#include "nsWindow.h"
|
|
767 |
|
|
768 |
#include "mozilla/EventStates.h"
|
|
769 |
#include "mozilla/Services.h"
|
|
770 |
@@ -703,6 +704,24 @@ nsNativeThemeGTK::GetGtkWidgetAndState(u
|
|
771 |
case NS_THEME_GTK_INFO_BAR:
|
|
772 |
aGtkWidgetType = MOZ_GTK_INFO_BAR;
|
|
773 |
break;
|
|
774 |
+ case NS_THEME_WINDOW_TITLEBAR:
|
|
775 |
+ aGtkWidgetType = MOZ_GTK_HEADER_BAR;
|
|
776 |
+ break;
|
|
777 |
+ case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
|
778 |
+ aGtkWidgetType = MOZ_GTK_HEADER_BAR_MAXIMIZED;
|
|
779 |
+ break;
|
|
780 |
+ case NS_THEME_WINDOW_BUTTON_CLOSE:
|
|
781 |
+ aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_CLOSE;
|
|
782 |
+ break;
|
|
783 |
+ case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
|
784 |
+ aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE;
|
|
785 |
+ break;
|
|
786 |
+ case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
|
787 |
+ aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE;
|
|
788 |
+ break;
|
|
789 |
+ case NS_THEME_WINDOW_BUTTON_RESTORE:
|
|
790 |
+ aGtkWidgetType = MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE;
|
|
791 |
+ break;
|
|
792 |
default:
|
|
793 |
return false;
|
|
794 |
}
|
|
795 |
@@ -1627,6 +1646,10 @@ nsNativeThemeGTK::GetMinimumWidgetSize(n
|
|
796 |
case NS_THEME_MENULIST:
|
|
797 |
case NS_THEME_TOOLBARBUTTON:
|
|
798 |
case NS_THEME_TREEHEADERCELL:
|
|
799 |
+ case NS_THEME_WINDOW_BUTTON_CLOSE:
|
|
800 |
+ case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
|
801 |
+ case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
|
802 |
+ case NS_THEME_WINDOW_BUTTON_RESTORE:
|
|
803 |
{
|
|
804 |
if (aWidgetType == NS_THEME_MENULIST) {
|
|
805 |
// Include the arrow size.
|
|
806 |
@@ -1892,9 +1915,21 @@ nsNativeThemeGTK::ThemeSupportsWidget(ns
|
|
807 |
case NS_THEME_DIALOG:
|
|
808 |
#if (MOZ_WIDGET_GTK == 3)
|
|
809 |
case NS_THEME_GTK_INFO_BAR:
|
|
810 |
+ case NS_THEME_GTK_WINDOW_DECORATION:
|
|
811 |
#endif
|
|
812 |
return !IsWidgetStyled(aPresContext, aFrame, aWidgetType);
|
|
813 |
|
|
814 |
+ case NS_THEME_WINDOW_BUTTON_CLOSE:
|
|
815 |
+ case NS_THEME_WINDOW_BUTTON_MINIMIZE:
|
|
816 |
+ case NS_THEME_WINDOW_BUTTON_MAXIMIZE:
|
|
817 |
+ case NS_THEME_WINDOW_BUTTON_RESTORE:
|
|
818 |
+ case NS_THEME_WINDOW_TITLEBAR:
|
|
819 |
+ case NS_THEME_WINDOW_TITLEBAR_MAXIMIZED:
|
|
820 |
+ // GtkHeaderBar is available on GTK 3.10+, which is used for styling
|
|
821 |
+ // title bars and title buttons.
|
|
822 |
+ return gtk_check_version(3, 10, 0) == nullptr &&
|
|
823 |
+ !IsWidgetStyled(aPresContext, aFrame, aWidgetType);
|
|
824 |
+
|
|
825 |
case NS_THEME_MENULIST_BUTTON:
|
|
826 |
if (aFrame && aFrame->GetWritingMode().IsVertical()) {
|
|
827 |
return false;
|
|
828 |
@@ -1978,6 +2013,13 @@ nsNativeThemeGTK::GetWidgetTransparency(
|
|
829 |
#else
|
|
830 |
return eTransparent;
|
|
831 |
#endif
|
|
832 |
+ case NS_THEME_GTK_WINDOW_DECORATION:
|
|
833 |
+ {
|
|
834 |
+ nsWindow* window = static_cast<nsWindow*>(aFrame->GetNearestWidget());
|
|
835 |
+ if (window)
|
|
836 |
+ return window->IsComposited() ? eTransparent : eOpaque;
|
|
837 |
+ return eOpaque;
|
|
838 |
+ }
|
|
839 |
}
|
|
840 |
|
|
841 |
return eUnknownTransparency;
|
|
842 |
diff -up firefox-57.0b8/widget/gtk/nsWindow.cpp.1399611 firefox-57.0b8/widget/gtk/nsWindow.cpp
|
|
843 |
--- firefox-57.0b8/widget/gtk/nsWindow.cpp.1399611 2017-10-16 12:11:45.361240666 +0200
|
|
844 |
+++ firefox-57.0b8/widget/gtk/nsWindow.cpp 2017-10-16 12:11:45.369240636 +0200
|
|
845 |
@@ -85,6 +85,7 @@
|
|
846 |
#include "nsIPropertyBag2.h"
|
|
847 |
#include "GLContext.h"
|
|
848 |
#include "gfx2DGlue.h"
|
|
849 |
+#include "nsLookAndFeel.h"
|
|
850 |
|
|
851 |
#ifdef ACCESSIBILITY
|
|
852 |
#include "mozilla/a11y/Accessible.h"
|
|
853 |
@@ -139,6 +140,8 @@ using namespace mozilla::widget;
|
|
854 |
|
|
855 |
#include "mozilla/layers/APZCTreeManager.h"
|
|
856 |
|
|
857 |
+#include "gtkdrawing.h"
|
|
858 |
+
|
|
859 |
using namespace mozilla;
|
|
860 |
using namespace mozilla::gfx;
|
|
861 |
using namespace mozilla::widget;
|
|
862 |
@@ -186,6 +189,8 @@ static gboolean expose_event_cb
|
|
863 |
#else
|
|
864 |
static gboolean expose_event_cb (GtkWidget *widget,
|
|
865 |
cairo_t *rect);
|
|
866 |
+static gboolean expose_event_decoration_draw_cb (GtkWidget *widget,
|
|
867 |
+ cairo_t *cr);
|
|
868 |
#endif
|
|
869 |
static gboolean configure_event_cb (GtkWidget *widget,
|
|
870 |
GdkEventConfigure *event);
|
|
871 |
@@ -231,7 +236,6 @@ static void screen_composited_change
|
|
872 |
gpointer user_data);
|
|
873 |
static void widget_composited_changed_cb (GtkWidget* widget,
|
|
874 |
gpointer user_data);
|
|
875 |
-
|
|
876 |
#if (MOZ_WIDGET_GTK == 3)
|
|
877 |
static void scale_changed_cb (GtkWidget* widget,
|
|
878 |
GParamSpec* aPSpec,
|
|
879 |
@@ -440,6 +444,7 @@ nsWindow::nsWindow()
|
|
880 |
|
|
881 |
mContainer = nullptr;
|
|
882 |
mGdkWindow = nullptr;
|
|
883 |
+ mIsCSDEnabled = false;
|
|
884 |
mShell = nullptr;
|
|
885 |
mCompositorWidgetDelegate = nullptr;
|
|
886 |
mHasMappedToplevel = false;
|
|
887 |
@@ -481,6 +486,9 @@ nsWindow::nsWindow()
|
|
888 |
mLastScrollEventTime = GDK_CURRENT_TIME;
|
|
889 |
#endif
|
|
890 |
mPendingConfigures = 0;
|
|
891 |
+ mDrawWindowDecoration = false;
|
|
892 |
+ mDecorationSize = {0,0,0,0};
|
|
893 |
+ mCSDSupportLevel = CSD_SUPPORT_UNKNOWN;
|
|
894 |
}
|
|
895 |
|
|
896 |
nsWindow::~nsWindow()
|
|
897 |
@@ -1479,8 +1487,8 @@ LayoutDeviceIntRect
|
|
898 |
nsWindow::GetScreenBounds()
|
|
899 |
{
|
|
900 |
LayoutDeviceIntRect rect;
|
|
901 |
- if (mIsTopLevel && mContainer) {
|
|
902 |
- // use the point including window decorations
|
|
903 |
+ if (mIsTopLevel && mContainer && !IsClientDecorated()) {
|
|
904 |
+ // use the point including default Gtk+ window decorations
|
|
905 |
gint x, y;
|
|
906 |
gdk_window_get_root_origin(gtk_widget_get_window(GTK_WIDGET(mContainer)), &x, &y);
|
|
907 |
rect.MoveTo(GdkPointToDevicePixels({ x, y }));
|
|
908 |
@@ -1606,6 +1614,10 @@ nsWindow::SetCursor(nsCursor aCursor)
|
|
909 |
return;
|
|
910 |
|
|
911 |
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mContainer)), newCursor);
|
|
912 |
+ if (IsClientDecorated()) {
|
|
913 |
+ gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mShell)),
|
|
914 |
+ newCursor);
|
|
915 |
+ }
|
|
916 |
}
|
|
917 |
}
|
|
918 |
}
|
|
919 |
@@ -1662,6 +1674,10 @@ nsWindow::SetCursor(imgIContainer* aCurs
|
|
920 |
if (cursor) {
|
|
921 |
if (mContainer) {
|
|
922 |
gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mContainer)), cursor);
|
|
923 |
+ if (IsClientDecorated()) {
|
|
924 |
+ gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(mShell)),
|
|
925 |
+ cursor);
|
|
926 |
+ }
|
|
927 |
rv = NS_OK;
|
|
928 |
}
|
|
929 |
#if (MOZ_WIDGET_GTK == 3)
|
|
930 |
@@ -2176,6 +2192,12 @@ nsWindow::OnExposeEvent(cairo_t *cr)
|
|
931 |
return TRUE;
|
|
932 |
}
|
|
933 |
|
|
934 |
+ // Clip upper part of the mContainer to get visible rounded corners
|
|
935 |
+ // of GtkHeaderBar which is renderd to mShell.
|
|
936 |
+ if (mIsCSDEnabled) {
|
|
937 |
+ ApplyCSDClipping();
|
|
938 |
+ }
|
|
939 |
+
|
|
940 |
// If this widget uses OMTC...
|
|
941 |
if (GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_CLIENT ||
|
|
942 |
GetLayerManager()->GetBackendType() == LayersBackend::LAYERS_WR) {
|
|
943 |
@@ -2586,6 +2608,53 @@ nsWindow::OnMotionNotifyEvent(GdkEventMo
|
|
944 |
}
|
|
945 |
}
|
|
946 |
#endif /* MOZ_X11 */
|
|
947 |
+ // Client is decorated and we're getting the motion event for mShell
|
|
948 |
+ // window which draws the CSD decorations around mContainer.
|
|
949 |
+ if (IsClientDecorated()) {
|
|
950 |
+ if (aEvent->window == gtk_widget_get_window(mShell)) {
|
|
951 |
+ GdkWindowEdge edge;
|
|
952 |
+ LayoutDeviceIntPoint refPoint =
|
|
953 |
+ GdkEventCoordsToDevicePixels(aEvent->x, aEvent->y);
|
|
954 |
+ if (CheckResizerEdge(refPoint, edge)) {
|
|
955 |
+ nsCursor cursor = eCursor_none;
|
|
956 |
+ switch (edge) {
|
|
957 |
+ case GDK_WINDOW_EDGE_NORTH:
|
|
958 |
+ cursor = eCursor_n_resize;
|
|
959 |
+ break;
|
|
960 |
+ case GDK_WINDOW_EDGE_NORTH_WEST:
|
|
961 |
+ cursor = eCursor_nw_resize;
|
|
962 |
+ break;
|
|
963 |
+ case GDK_WINDOW_EDGE_NORTH_EAST:
|
|
964 |
+ cursor = eCursor_ne_resize;
|
|
965 |
+ break;
|
|
966 |
+ case GDK_WINDOW_EDGE_WEST:
|
|
967 |
+ cursor = eCursor_w_resize;
|
|
968 |
+ break;
|
|
969 |
+ case GDK_WINDOW_EDGE_EAST:
|
|
970 |
+ cursor = eCursor_e_resize;
|
|
971 |
+ break;
|
|
972 |
+ case GDK_WINDOW_EDGE_SOUTH:
|
|
973 |
+ cursor = eCursor_s_resize;
|
|
974 |
+ break;
|
|
975 |
+ case GDK_WINDOW_EDGE_SOUTH_WEST:
|
|
976 |
+ cursor = eCursor_sw_resize;
|
|
977 |
+ break;
|
|
978 |
+ case GDK_WINDOW_EDGE_SOUTH_EAST:
|
|
979 |
+ cursor = eCursor_se_resize;
|
|
980 |
+ break;
|
|
981 |
+ }
|
|
982 |
+ SetCursor(cursor);
|
|
983 |
+ return;
|
|
984 |
+ }
|
|
985 |
+ }
|
|
986 |
+ // We're not on resize handle - check if we need to reset cursor back.
|
|
987 |
+ if (mCursor == eCursor_n_resize || mCursor == eCursor_nw_resize ||
|
|
988 |
+ mCursor == eCursor_ne_resize || mCursor == eCursor_w_resize ||
|
|
989 |
+ mCursor == eCursor_e_resize || mCursor == eCursor_s_resize ||
|
|
990 |
+ mCursor == eCursor_sw_resize || mCursor == eCursor_se_resize) {
|
|
991 |
+ SetCursor(eCursor_standard);
|
|
992 |
+ }
|
|
993 |
+ }
|
|
994 |
|
|
995 |
WidgetMouseEvent event(true, eMouseMove, this, WidgetMouseEvent::eReal);
|
|
996 |
|
|
997 |
@@ -2756,6 +2825,20 @@ nsWindow::OnButtonPressEvent(GdkEventBut
|
|
998 |
if (CheckForRollup(aEvent->x_root, aEvent->y_root, false, false))
|
|
999 |
return;
|
|
1000 |
|
|
1001 |
+ if (IsClientDecorated() && aEvent->window == gtk_widget_get_window(mShell)) {
|
|
1002 |
+ // Check to see if the event is within our window's resize region
|
|
1003 |
+ GdkWindowEdge edge;
|
|
1004 |
+ LayoutDeviceIntPoint refPoint =
|
|
1005 |
+ GdkEventCoordsToDevicePixels(aEvent->x, aEvent->y);
|
|
1006 |
+ if (CheckResizerEdge(refPoint, edge)) {
|
|
1007 |
+ gdk_window_begin_resize_drag(gtk_widget_get_window(mShell),
|
|
1008 |
+ edge, aEvent->button,
|
|
1009 |
+ aEvent->x_root, aEvent->y_root,
|
|
1010 |
+ aEvent->time);
|
|
1011 |
+ return;
|
|
1012 |
+ }
|
|
1013 |
+ }
|
|
1014 |
+
|
|
1015 |
gdouble pressure = 0;
|
|
1016 |
gdk_event_get_axis ((GdkEvent*)aEvent, GDK_AXIS_PRESSURE, &pressure);
|
|
1017 |
mLastMotionPressure = pressure;
|
|
1018 |
@@ -3341,6 +3424,8 @@ nsWindow::OnWindowStateEvent(GtkWidget *
|
|
1019 |
#endif //ACCESSIBILITY
|
|
1020 |
}
|
|
1021 |
|
|
1022 |
+ UpdateClientDecorations();
|
|
1023 |
+
|
|
1024 |
if (mWidgetListener) {
|
|
1025 |
mWidgetListener->SizeModeChanged(mSizeState);
|
|
1026 |
if (aEvent->changed_mask & GDK_WINDOW_STATE_FULLSCREEN) {
|
|
1027 |
@@ -3405,6 +3490,7 @@ nsWindow::OnCompositedChanged()
|
|
1028 |
presShell->ThemeChanged();
|
|
1029 |
}
|
|
1030 |
}
|
|
1031 |
+ UpdateClientDecorations();
|
|
1032 |
}
|
|
1033 |
|
|
1034 |
void
|
|
1035 |
@@ -3593,7 +3679,8 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1036 |
GtkWindow *topLevelParent = nullptr;
|
|
1037 |
nsWindow *parentnsWindow = nullptr;
|
|
1038 |
GtkWidget *eventWidget = nullptr;
|
|
1039 |
- bool shellHasCSD = false;
|
|
1040 |
+ GtkWidget *drawWidget = nullptr;
|
|
1041 |
+ bool drawToContainer = false;
|
|
1042 |
|
|
1043 |
if (aParent) {
|
|
1044 |
parentnsWindow = static_cast<nsWindow*>(aParent);
|
|
1045 |
@@ -3640,29 +3727,47 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1046 |
GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP;
|
|
1047 |
mShell = gtk_window_new(type);
|
|
1048 |
|
|
1049 |
- bool useAlphaVisual = (mWindowType == eWindowType_popup &&
|
|
1050 |
- aInitData->mSupportTranslucency);
|
|
1051 |
+ bool useAlphaVisual = false;
|
|
1052 |
+#if (MOZ_WIDGET_GTK == 3)
|
|
1053 |
+ // When CSD is available we can emulate it for toplevel windows.
|
|
1054 |
+ // Content is rendered to mContainer and transparent decorations to mShell.
|
|
1055 |
+ if (GetCSDSupportLevel() != CSD_SUPPORT_NONE &&
|
|
1056 |
+ mWindowType == eWindowType_toplevel) {
|
|
1057 |
+ int32_t isCSDAvailable = false;
|
|
1058 |
+ nsresult rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDAvailable,
|
|
1059 |
+ &isCSDAvailable);
|
|
1060 |
+ if (NS_SUCCEEDED(rv)) {
|
|
1061 |
+ mIsCSDEnabled = useAlphaVisual = isCSDAvailable;
|
|
1062 |
+ }
|
|
1063 |
+ } else
|
|
1064 |
+#endif
|
|
1065 |
+ if (mWindowType == eWindowType_popup) {
|
|
1066 |
+ useAlphaVisual = aInitData->mSupportTranslucency;
|
|
1067 |
+ }
|
|
1068 |
|
|
1069 |
// mozilla.widget.use-argb-visuals is a hidden pref defaulting to false
|
|
1070 |
// to allow experimentation
|
|
1071 |
if (Preferences::GetBool("mozilla.widget.use-argb-visuals", false))
|
|
1072 |
useAlphaVisual = true;
|
|
1073 |
|
|
1074 |
+ // An ARGB visual is only useful if we are on a compositing
|
|
1075 |
+ // window manager.
|
|
1076 |
+ GdkScreen *screen = gtk_widget_get_screen(mShell);
|
|
1077 |
+ if (useAlphaVisual && !gdk_screen_is_composited(screen)) {
|
|
1078 |
+ useAlphaVisual = false;
|
|
1079 |
+ }
|
|
1080 |
+
|
|
1081 |
// We need to select an ARGB visual here instead of in
|
|
1082 |
// SetTransparencyMode() because it has to be done before the
|
|
1083 |
- // widget is realized. An ARGB visual is only useful if we
|
|
1084 |
- // are on a compositing window manager.
|
|
1085 |
+ // widget is realized.
|
|
1086 |
if (useAlphaVisual) {
|
|
1087 |
- GdkScreen *screen = gtk_widget_get_screen(mShell);
|
|
1088 |
- if (gdk_screen_is_composited(screen)) {
|
|
1089 |
#if (MOZ_WIDGET_GTK == 2)
|
|
1090 |
- GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
|
|
1091 |
- gtk_widget_set_colormap(mShell, colormap);
|
|
1092 |
+ GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen);
|
|
1093 |
+ gtk_widget_set_colormap(mShell, colormap);
|
|
1094 |
#else
|
|
1095 |
- GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
|
|
1096 |
- gtk_widget_set_visual(mShell, visual);
|
|
1097 |
+ GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
|
|
1098 |
+ gtk_widget_set_visual(mShell, visual);
|
|
1099 |
#endif
|
|
1100 |
- }
|
|
1101 |
}
|
|
1102 |
|
|
1103 |
// We only move a general managed toplevel window if someone has
|
|
1104 |
@@ -3756,24 +3861,56 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1105 |
mContainer = MOZ_CONTAINER(container);
|
|
1106 |
|
|
1107 |
#if (MOZ_WIDGET_GTK == 3)
|
|
1108 |
- // "csd" style is set when widget is realized so we need to call
|
|
1109 |
- // it explicitly now.
|
|
1110 |
- gtk_widget_realize(mShell);
|
|
1111 |
-
|
|
1112 |
- // We can't draw directly to top-level window when client side
|
|
1113 |
- // decorations are enabled. We use container with GdkWindow instead.
|
|
1114 |
- GtkStyleContext* style = gtk_widget_get_style_context(mShell);
|
|
1115 |
- shellHasCSD = gtk_style_context_has_class(style, "csd");
|
|
1116 |
-#endif
|
|
1117 |
- if (!shellHasCSD) {
|
|
1118 |
- // Use mShell's window for drawing and events.
|
|
1119 |
- gtk_widget_set_has_window(container, FALSE);
|
|
1120 |
- // Prevent GtkWindow from painting a background to flicker.
|
|
1121 |
- gtk_widget_set_app_paintable(mShell, TRUE);
|
|
1122 |
- }
|
|
1123 |
- // Set up event widget
|
|
1124 |
- eventWidget = shellHasCSD ? container : mShell;
|
|
1125 |
+ /* There are tree possible situations here:
|
|
1126 |
+ *
|
|
1127 |
+ * 1) We're running on Gtk+ < 3.20 without any decorations. Content
|
|
1128 |
+ * is rendered to mShell window and we listen Gtk+ events on mShell.
|
|
1129 |
+ * 2) We're running on Gtk+ > 3.20 and window decorations are drawn
|
|
1130 |
+ * by default by Gtk+. Content is rendered to mContainer,
|
|
1131 |
+ * we listen events on mContainer. mShell contains default Gtk+
|
|
1132 |
+ * window decorations rendered by Gtk+.
|
|
1133 |
+ * 3) We're running on Gtk+ > 3.20 and both window decorations and
|
|
1134 |
+ * content is rendered by gecko. We emulate Gtk+ decoration rendering
|
|
1135 |
+ * to mShell and we need to listen Gtk events on both mShell
|
|
1136 |
+ * and mContainer.
|
|
1137 |
+ */
|
|
1138 |
+
|
|
1139 |
+ // When client side decorations are enabled (rendered by us or by Gtk+)
|
|
1140 |
+ // the decoration is rendered to mShell (toplevel) window and
|
|
1141 |
+ // we draw our content to mContainer.
|
|
1142 |
+ if (mIsCSDEnabled) {
|
|
1143 |
+ drawToContainer = true;
|
|
1144 |
+ } else {
|
|
1145 |
+ // mIsCSDEnabled can be disabled by preference so look at actual
|
|
1146 |
+ // toplevel window style to to detect active "csd" style.
|
|
1147 |
+ // The "csd" style is set when widget is realized so we need to call
|
|
1148 |
+ // it explicitly now.
|
|
1149 |
+ gtk_widget_realize(mShell);
|
|
1150 |
+
|
|
1151 |
+ GtkStyleContext* style = gtk_widget_get_style_context(mShell);
|
|
1152 |
+ drawToContainer = gtk_style_context_has_class(style, "csd");
|
|
1153 |
+ }
|
|
1154 |
+#endif
|
|
1155 |
+ drawWidget = (drawToContainer) ? container : mShell;
|
|
1156 |
+ // When we draw decorations on our own we need to handle resize events
|
|
1157 |
+ // because Gtk+ does not provide resizers for undecorated windows.
|
|
1158 |
+ // The CSD on mShell borders act as resize handlers
|
|
1159 |
+ // so we need to listen there.
|
|
1160 |
+ eventWidget = (drawToContainer && !mIsCSDEnabled) ? container : mShell;
|
|
1161 |
+
|
|
1162 |
gtk_widget_add_events(eventWidget, kEvents);
|
|
1163 |
+ if (eventWidget != drawWidget) {
|
|
1164 |
+ // CSD is rendered by us (not by Gtk+) so we also need to listen
|
|
1165 |
+ // at mShell window for events.
|
|
1166 |
+ gtk_widget_add_events(drawWidget, kEvents);
|
|
1167 |
+ }
|
|
1168 |
+
|
|
1169 |
+ // Prevent GtkWindow from painting a background to flicker.
|
|
1170 |
+ gtk_widget_set_app_paintable(drawWidget, TRUE);
|
|
1171 |
+
|
|
1172 |
+ // gtk_container_add() realizes the child widget so we need to
|
|
1173 |
+ // set it now.
|
|
1174 |
+ gtk_widget_set_has_window(container, drawToContainer);
|
|
1175 |
|
|
1176 |
gtk_container_add(GTK_CONTAINER(mShell), container);
|
|
1177 |
gtk_widget_realize(container);
|
|
1178 |
@@ -3783,7 +3920,7 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1179 |
gtk_widget_grab_focus(container);
|
|
1180 |
|
|
1181 |
// the drawing window
|
|
1182 |
- mGdkWindow = gtk_widget_get_window(eventWidget);
|
|
1183 |
+ mGdkWindow = gtk_widget_get_window(drawWidget);
|
|
1184 |
|
|
1185 |
if (mWindowType == eWindowType_popup) {
|
|
1186 |
// gdk does not automatically set the cursor for "temporary"
|
|
1187 |
@@ -3856,6 +3993,11 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1188 |
|
|
1189 |
// label the drawing window with this object so we can find our way home
|
|
1190 |
g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", this);
|
|
1191 |
+ if (mIsCSDEnabled) {
|
|
1192 |
+ // label the CSD window with this object so we can find our way home
|
|
1193 |
+ g_object_set_data(G_OBJECT(gtk_widget_get_window(mShell)),
|
|
1194 |
+ "nsWindow", this);
|
|
1195 |
+ }
|
|
1196 |
|
|
1197 |
if (mContainer)
|
|
1198 |
g_object_set_data(G_OBJECT(mContainer), "nsWindow", this);
|
|
1199 |
@@ -3893,6 +4035,10 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1200 |
g_signal_connect_after(default_settings,
|
|
1201 |
"notify::gtk-font-name",
|
|
1202 |
G_CALLBACK(theme_changed_cb), this);
|
|
1203 |
+ if (mIsCSDEnabled) {
|
|
1204 |
+ g_signal_connect(G_OBJECT(mShell), "draw",
|
|
1205 |
+ G_CALLBACK(expose_event_decoration_draw_cb), nullptr);
|
|
1206 |
+ }
|
|
1207 |
}
|
|
1208 |
|
|
1209 |
if (mContainer) {
|
|
1210 |
@@ -3943,7 +4089,7 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1211 |
G_CALLBACK(drag_data_received_event_cb), nullptr);
|
|
1212 |
|
|
1213 |
GtkWidget *widgets[] = { GTK_WIDGET(mContainer),
|
|
1214 |
- !shellHasCSD ? mShell : nullptr };
|
|
1215 |
+ !drawToContainer ? mShell : nullptr };
|
|
1216 |
for (size_t i = 0; i < ArrayLength(widgets) && widgets[i]; ++i) {
|
|
1217 |
// Visibility events are sent to the owning widget of the relevant
|
|
1218 |
// window but do not propagate to parent widgets so connect on
|
|
1219 |
@@ -3973,7 +4119,6 @@ nsWindow::Create(nsIWidget* aParent,
|
|
1220 |
// Don't let GTK mess with the shapes of our GdkWindows
|
|
1221 |
GTK_PRIVATE_SET_FLAG(eventWidget, GTK_HAS_SHAPE_MASK);
|
|
1222 |
#endif
|
|
1223 |
-
|
|
1224 |
// These events are sent to the owning widget of the relevant window
|
|
1225 |
// and propagate up to the first widget that handles the events, so we
|
|
1226 |
// need only connect on mShell, if it exists, to catch events on its
|
|
1227 |
@@ -4110,6 +4255,12 @@ nsWindow::NativeResize()
|
|
1228 |
size.width, size.height));
|
|
1229 |
|
|
1230 |
if (mIsTopLevel) {
|
|
1231 |
+ // When we draw decorations add extra space to draw shadows
|
|
1232 |
+ // around the main window.
|
|
1233 |
+ if (mDrawWindowDecoration) {
|
|
1234 |
+ size.width += mDecorationSize.left + mDecorationSize.right;
|
|
1235 |
+ size.height += mDecorationSize.top + mDecorationSize.bottom;
|
|
1236 |
+ }
|
|
1237 |
gtk_window_resize(GTK_WINDOW(mShell), size.width, size.height);
|
|
1238 |
}
|
|
1239 |
else if (mContainer) {
|
|
1240 |
@@ -4166,6 +4317,11 @@ nsWindow::NativeMoveResize()
|
|
1241 |
if (mIsTopLevel) {
|
|
1242 |
// x and y give the position of the window manager frame top-left.
|
|
1243 |
gtk_window_move(GTK_WINDOW(mShell), topLeft.x, topLeft.y);
|
|
1244 |
+
|
|
1245 |
+ if (mDrawWindowDecoration) {
|
|
1246 |
+ size.width += mDecorationSize.left + mDecorationSize.right;
|
|