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; |
|
1247 + size.height += mDecorationSize.top + mDecorationSize.bottom; |
|
1248 + } |
|
1249 // This sets the client window size. |
|
1250 gtk_window_resize(GTK_WINDOW(mShell), size.width, size.height); |
|
1251 } |
|
1252 @@ -5524,6 +5680,33 @@ expose_event_cb(GtkWidget *widget, cairo |
|
1253 |
|
1254 return FALSE; |
|
1255 } |
|
1256 + |
|
1257 +/* static */ |
|
1258 +gboolean |
|
1259 +expose_event_decoration_draw_cb(GtkWidget *widget, cairo_t *cr) |
|
1260 +{ |
|
1261 + GdkWindow* gdkWindow = gtk_widget_get_window(widget); |
|
1262 + if (gtk_cairo_should_draw_window(cr, gdkWindow)) { |
|
1263 + RefPtr<nsWindow> window = get_window_for_gtk_widget(widget); |
|
1264 + if (!window) { |
|
1265 + NS_WARNING("Cannot get nsWindow from GtkWidget"); |
|
1266 + } |
|
1267 + else if (window->IsClientDecorated()) { |
|
1268 + cairo_save(cr); |
|
1269 + gtk_cairo_transform_to_window(cr, widget, gdkWindow); |
|
1270 + |
|
1271 + GdkRectangle rect = {0,0,0,0}; |
|
1272 + gtk_window_get_size(GTK_WINDOW(widget), &rect.width, &rect.height); |
|
1273 + moz_gtk_window_decoration_paint(cr, &rect); |
|
1274 + |
|
1275 + rect.height = 40; |
|
1276 + moz_gtk_header_bar_paint(cr, &rect); |
|
1277 + cairo_restore(cr); |
|
1278 + } |
|
1279 + } |
|
1280 + return TRUE; |
|
1281 +} |
|
1282 + |
|
1283 #endif //MOZ_WIDGET_GTK == 2 |
|
1284 |
|
1285 static gboolean |
|
1286 @@ -6576,6 +6759,28 @@ nsWindow::ClearCachedResources() |
|
1287 } |
|
1288 } |
|
1289 |
|
1290 +NS_IMETHODIMP |
|
1291 +nsWindow::SetNonClientMargins(LayoutDeviceIntMargin &aMargins) |
|
1292 +{ |
|
1293 + SetDrawsInTitlebar(aMargins.top == 0); |
|
1294 + return NS_OK; |
|
1295 +} |
|
1296 + |
|
1297 +void |
|
1298 +nsWindow::SetDrawsInTitlebar(bool aState) |
|
1299 +{ |
|
1300 + if (!mIsCSDEnabled || aState == mDrawWindowDecoration) |
|
1301 + return; |
|
1302 + |
|
1303 + if (mShell) { |
|
1304 + gtk_window_set_decorated(GTK_WINDOW(mShell), !aState); |
|
1305 + gtk_widget_set_app_paintable(mShell, aState); |
|
1306 + } |
|
1307 + |
|
1308 + mDrawWindowDecoration = aState; |
|
1309 + UpdateClientDecorations(); |
|
1310 +} |
|
1311 + |
|
1312 gint |
|
1313 nsWindow::GdkScaleFactor() |
|
1314 { |
|
1315 @@ -6846,6 +7051,157 @@ nsWindow::SynthesizeNativeTouchPoint(uin |
|
1316 } |
|
1317 #endif |
|
1318 |
|
1319 +bool |
|
1320 +nsWindow::IsClientDecorated() const |
|
1321 +{ |
|
1322 + return mDrawWindowDecoration && mSizeState == nsSizeMode_Normal; |
|
1323 +} |
|
1324 + |
|
1325 +int |
|
1326 +nsWindow::GetClientResizerSize() |
|
1327 +{ |
|
1328 + if (!mShell) |
|
1329 + return 0; |
|
1330 + |
|
1331 + // GTK uses a default size of 20px as of 3.20. |
|
1332 + gint size = 20; |
|
1333 + gtk_widget_style_get(mShell, "decoration-resize-handle", &size, nullptr); |
|
1334 + |
|
1335 + return GdkCoordToDevicePixels(size); |
|
1336 +} |
|
1337 + |
|
1338 +nsWindow::CSDSupportLevel |
|
1339 +nsWindow::GetCSDSupportLevel() { |
|
1340 + if (mCSDSupportLevel != CSD_SUPPORT_UNKNOWN) { |
|
1341 + return mCSDSupportLevel; |
|
1342 + } |
|
1343 + // TODO: MATE |
|
1344 + const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP"); |
|
1345 + if (currentDesktop) { |
|
1346 + if (strcmp(currentDesktop, "GNOME") == 0) { |
|
1347 + mCSDSupportLevel = CSD_SUPPORT_FULL; |
|
1348 + } else if (strcmp(currentDesktop, "XFCE") == 0) { |
|
1349 + mCSDSupportLevel = CSD_SUPPORT_FULL; |
|
1350 + } else if (strcmp(currentDesktop, "X-Cinnamon") == 0) { |
|
1351 + mCSDSupportLevel = CSD_SUPPORT_FULL; |
|
1352 + } else if (strcmp(currentDesktop, "KDE") == 0) { |
|
1353 + mCSDSupportLevel = CSD_SUPPORT_FLAT; |
|
1354 + } else if (strcmp(currentDesktop, "LXDE") == 0) { |
|
1355 + mCSDSupportLevel = CSD_SUPPORT_FLAT; |
|
1356 + } else if (strcmp(currentDesktop, "openbox") == 0) { |
|
1357 + mCSDSupportLevel = CSD_SUPPORT_FLAT; |
|
1358 + } else if (strcmp(currentDesktop, "i3") == 0) { |
|
1359 + mCSDSupportLevel = CSD_SUPPORT_NONE; |
|
1360 + } else { |
|
1361 + mCSDSupportLevel = CSD_SUPPORT_NONE; |
|
1362 + } |
|
1363 + } |
|
1364 + return mCSDSupportLevel; |
|
1365 +} |
|
1366 + |
|
1367 +void |
|
1368 +nsWindow::UpdateClientDecorations() |
|
1369 +{ |
|
1370 + // When the CSD is not fully supported by window manager (ie. WM is not |
|
1371 + // expecting that application is going to draw window shadows) we can't |
|
1372 + // add shadows widths to the window margin. That would lead to completely |
|
1373 + // opaque black border of the window. |
|
1374 + if (!mDrawWindowDecoration || GetCSDSupportLevel() != CSD_SUPPORT_FULL) |
|
1375 + return; |
|
1376 + |
|
1377 + gint top = 0, right = 0, bottom = 0, left = 0; |
|
1378 + if (mSizeState == nsSizeMode_Normal) { |
|
1379 + moz_gtk_get_window_border(&top, &right, &bottom, &left); |
|
1380 + } |
|
1381 + |
|
1382 + static auto sGdkWindowSetShadowWidth = |
|
1383 + (void (*)(GdkWindow*, gint, gint, gint, gint)) |
|
1384 + dlsym(RTLD_DEFAULT, "gdk_window_set_shadow_width"); |
|
1385 + sGdkWindowSetShadowWidth(gtk_widget_get_window(mShell), |
|
1386 + left, right, top, bottom); |
|
1387 + |
|
1388 + mDecorationSize.left = left; |
|
1389 + mDecorationSize.right = right; |
|
1390 + mDecorationSize.top = top; |
|
1391 + mDecorationSize.bottom = bottom; |
|
1392 + |
|
1393 + // Gtk+ doesn't like when we set mContainer margin bigger than actual |
|
1394 + // mContainer window size. That happens when we're called early and the |
|
1395 + // mShell/mContainer is not allocated/resized yet and has default 1x1 size. |
|
1396 + // Just resize to some minimal value which will be changed |
|
1397 + // by Gecko soon. |
|
1398 + GtkAllocation allocation; |
|
1399 + gtk_widget_get_allocation(GTK_WIDGET(mContainer), &allocation); |
|
1400 + if (allocation.width < left + right || allocation.height < top + bottom) { |
|
1401 + gtk_widget_get_preferred_width(GTK_WIDGET(mContainer), nullptr, |
|
1402 + &allocation.width); |
|
1403 + gtk_widget_get_preferred_height(GTK_WIDGET(mContainer), nullptr, |
|
1404 + &allocation.height); |
|
1405 + allocation.width += left + right + 1; |
|
1406 + allocation.height += top + bottom + 1; |
|
1407 + gtk_widget_size_allocate(GTK_WIDGET(mContainer), &allocation); |
|
1408 + } |
|
1409 + |
|
1410 + gtk_widget_set_margin_left(GTK_WIDGET(mContainer), mDecorationSize.left); |
|
1411 + gtk_widget_set_margin_right(GTK_WIDGET(mContainer), mDecorationSize.right); |
|
1412 + gtk_widget_set_margin_top(GTK_WIDGET(mContainer), mDecorationSize.top); |
|
1413 + gtk_widget_set_margin_bottom(GTK_WIDGET(mContainer), mDecorationSize.bottom); |
|
1414 +} |
|
1415 + |
|
1416 +void |
|
1417 +nsWindow::ApplyCSDClipping() |
|
1418 +{ |
|
1419 + if (IsClientDecorated()) { |
|
1420 + gint top, right, bottom, left; |
|
1421 + moz_gtk_get_header_bar_border(&top, &right, &bottom, &left); |
|
1422 + cairo_rectangle_int_t rect = { 0, top, mBounds.width, mBounds.height}; |
|
1423 + cairo_region_t *region = cairo_region_create_rectangle(&rect); |
|
1424 + gdk_window_shape_combine_region(mGdkWindow, region, 0, 0); |
|
1425 + cairo_region_destroy(region); |
|
1426 + } else { |
|
1427 + gdk_window_shape_combine_region(mGdkWindow, nullptr, 0, 0); |
|
1428 + } |
|
1429 +} |
|
1430 + |
|
1431 +bool |
|
1432 +nsWindow::CheckResizerEdge(LayoutDeviceIntPoint aPoint, GdkWindowEdge& aOutEdge) |
|
1433 +{ |
|
1434 + gint scale = GdkScaleFactor(); |
|
1435 + gint left = scale * mDecorationSize.left; |
|
1436 + gint top = scale * mDecorationSize.top; |
|
1437 + gint right = scale * mDecorationSize.right; |
|
1438 + gint bottom = scale * mDecorationSize.bottom; |
|
1439 + |
|
1440 + int resizerSize = GetClientResizerSize(); |
|
1441 + int topDist = aPoint.y; |
|
1442 + int leftDist = aPoint.x; |
|
1443 + int rightDist = mBounds.width - aPoint.x; |
|
1444 + int bottomDist = mBounds.height - aPoint.y; |
|
1445 + |
|
1446 + //TODO -> wrong sizes |
|
1447 + |
|
1448 + if (leftDist <= resizerSize && topDist <= resizerSize) { |
|
1449 + aOutEdge = GDK_WINDOW_EDGE_NORTH_WEST; |
|
1450 + } else if (rightDist <= resizerSize && topDist <= resizerSize) { |
|
1451 + aOutEdge = GDK_WINDOW_EDGE_NORTH_EAST; |
|
1452 + } else if (leftDist <= resizerSize && bottomDist <= resizerSize) { |
|
1453 + aOutEdge = GDK_WINDOW_EDGE_SOUTH_WEST; |
|
1454 + } else if (rightDist <= resizerSize && bottomDist <= resizerSize) { |
|
1455 + aOutEdge = GDK_WINDOW_EDGE_SOUTH_EAST; |
|
1456 + } else if (topDist <= top) { |
|
1457 + aOutEdge = GDK_WINDOW_EDGE_NORTH; |
|
1458 + } else if (leftDist <= left) { |
|
1459 + aOutEdge = GDK_WINDOW_EDGE_WEST; |
|
1460 + } else if (rightDist <= right) { |
|
1461 + aOutEdge = GDK_WINDOW_EDGE_EAST; |
|
1462 + } else if (bottomDist <= bottom) { |
|
1463 + aOutEdge = GDK_WINDOW_EDGE_SOUTH; |
|
1464 + } else { |
|
1465 + return false; |
|
1466 + } |
|
1467 + return true; |
|
1468 +} |
|
1469 + |
|
1470 int32_t |
|
1471 nsWindow::RoundsWidgetCoordinatesTo() |
|
1472 { |
|
1473 diff -up firefox-57.0b8/widget/gtk/nsWindow.h.1399611 firefox-57.0b8/widget/gtk/nsWindow.h |
|
1474 --- firefox-57.0b8/widget/gtk/nsWindow.h.1399611 2017-09-15 06:15:40.000000000 +0200 |
|
1475 +++ firefox-57.0b8/widget/gtk/nsWindow.h 2017-10-16 12:11:45.369240636 +0200 |
|
1476 @@ -123,6 +123,7 @@ public: |
|
1477 double aHeight, |
|
1478 bool aRepaint) override; |
|
1479 virtual bool IsEnabled() const override; |
|
1480 + bool IsComposited() const; |
|
1481 |
|
1482 void SetZIndex(int32_t aZIndex) override; |
|
1483 virtual void SetSizeMode(nsSizeMode aMode) override; |
|
1484 @@ -351,6 +352,9 @@ public: |
|
1485 #endif |
|
1486 virtual void GetCompositorWidgetInitData(mozilla::widget::CompositorWidgetInitData* aInitData) override; |
|
1487 |
|
1488 + NS_IMETHOD SetNonClientMargins(LayoutDeviceIntMargin& aMargins) override; |
|
1489 + void SetDrawsInTitlebar(bool aState) override; |
|
1490 + |
|
1491 // HiDPI scale conversion |
|
1492 gint GdkScaleFactor(); |
|
1493 |
|
1494 @@ -367,6 +371,9 @@ public: |
|
1495 LayoutDeviceIntRect GdkRectToDevicePixels(GdkRectangle rect); |
|
1496 |
|
1497 virtual bool WidgetTypeSupportsAcceleration() override; |
|
1498 + |
|
1499 + // Decorations |
|
1500 + bool IsClientDecorated() const; |
|
1501 protected: |
|
1502 virtual ~nsWindow(); |
|
1503 |
|
1504 @@ -384,6 +391,16 @@ protected: |
|
1505 |
|
1506 virtual void RegisterTouchWindow() override; |
|
1507 |
|
1508 + int GetClientResizerSize(); |
|
1509 + |
|
1510 + // Informs the window manager about the size of the shadows surrounding |
|
1511 + // a client-side decorated window. |
|
1512 + void UpdateClientDecorations(); |
|
1513 + |
|
1514 + // Returns true if the given point (in device pixels) is within a resizer |
|
1515 + // region of the window. Only used when drawing decorations client side. |
|
1516 + bool CheckResizerEdge(LayoutDeviceIntPoint aPoint, GdkWindowEdge& aOutEdge); |
|
1517 + |
|
1518 nsCOMPtr<nsIWidget> mParent; |
|
1519 // Is this a toplevel window? |
|
1520 bool mIsTopLevel; |
|
1521 @@ -432,12 +449,12 @@ private: |
|
1522 gint* aRootX, gint* aRootY); |
|
1523 void ClearCachedResources(); |
|
1524 nsIWidgetListener* GetListener(); |
|
1525 - bool IsComposited() const; |
|
1526 - |
|
1527 + void ApplyCSDClipping(); |
|
1528 |
|
1529 GtkWidget *mShell; |
|
1530 MozContainer *mContainer; |
|
1531 GdkWindow *mGdkWindow; |
|
1532 + bool mIsCSDEnabled; |
|
1533 PlatformCompositorWidgetDelegate* mCompositorWidgetDelegate; |
|
1534 |
|
1535 |
|
1536 @@ -536,6 +553,10 @@ private: |
|
1537 // leaving fullscreen |
|
1538 nsSizeMode mLastSizeMode; |
|
1539 |
|
1540 + // If true, draw our own window decorations (where supported). |
|
1541 + bool mDrawWindowDecoration; |
|
1542 + GtkBorder mDecorationSize; |
|
1543 + |
|
1544 static bool DragInProgress(void); |
|
1545 |
|
1546 void DispatchMissedButtonReleases(GdkEventCrossing *aGdkEvent); |
|
1547 @@ -567,6 +588,17 @@ private: |
|
1548 RefPtr<mozilla::widget::IMContextWrapper> mIMContext; |
|
1549 |
|
1550 mozilla::UniquePtr<mozilla::CurrentX11TimeGetter> mCurrentTimeGetter; |
|
1551 + typedef enum { CSD_SUPPORT_FULL, // CSD including shadows |
|
1552 + CSD_SUPPORT_FLAT, // CSD without shadows |
|
1553 + CSD_SUPPORT_NONE, // WM does not support CSD at all |
|
1554 + CSD_SUPPORT_UNKNOWN |
|
1555 + } CSDSupportLevel; |
|
1556 + /** |
|
1557 + * Get the support of Client Side Decoration by checking |
|
1558 + * the XDG_CURRENT_DESKTOP environment variable. |
|
1559 + */ |
|
1560 + CSDSupportLevel GetCSDSupportLevel(); |
|
1561 + CSDSupportLevel mCSDSupportLevel; |
|
1562 }; |
|
1563 |
|
1564 #endif /* __nsWindow_h__ */ |
|
1565 diff -up firefox-57.0b8/widget/gtk/WidgetStyleCache.cpp.1399611 firefox-57.0b8/widget/gtk/WidgetStyleCache.cpp |
|
1566 --- firefox-57.0b8/widget/gtk/WidgetStyleCache.cpp.1399611 2017-09-15 06:15:40.000000000 +0200 |
|
1567 +++ firefox-57.0b8/widget/gtk/WidgetStyleCache.cpp 2017-10-16 12:11:45.369240636 +0200 |
|
1568 @@ -26,10 +26,14 @@ static GtkStyleContext* |
|
1569 GetCssNodeStyleInternal(WidgetNodeType aNodeType); |
|
1570 |
|
1571 static GtkWidget* |
|
1572 -CreateWindowWidget() |
|
1573 +CreateWindowWidget(WidgetNodeType type) |
|
1574 { |
|
1575 GtkWidget *widget = gtk_window_new(GTK_WINDOW_POPUP); |
|
1576 gtk_widget_set_name(widget, "MozillaGtkWidget"); |
|
1577 + if (type == MOZ_GTK_WINDOW_CSD) { |
|
1578 + GtkStyleContext* style = gtk_widget_get_style_context(widget); |
|
1579 + gtk_style_context_add_class(style, "csd"); |
|
1580 + } |
|
1581 return widget; |
|
1582 } |
|
1583 |
|
1584 @@ -101,7 +105,7 @@ CreateTooltipWidget() |
|
1585 { |
|
1586 MOZ_ASSERT(gtk_check_version(3, 20, 0) != nullptr, |
|
1587 "CreateTooltipWidget should be used for Gtk < 3.20 only."); |
|
1588 - GtkWidget* widget = CreateWindowWidget(); |
|
1589 + GtkWidget* widget = CreateWindowWidget(MOZ_GTK_WINDOW); |
|
1590 GtkStyleContext* style = gtk_widget_get_style_context(widget); |
|
1591 gtk_style_context_add_class(style, GTK_STYLE_CLASS_TOOLTIP); |
|
1592 return widget; |
|
1593 @@ -529,11 +533,82 @@ CreateNotebookWidget() |
|
1594 } |
|
1595 |
|
1596 static GtkWidget* |
|
1597 +CreateHeaderBar(bool aMaximized) |
|
1598 +{ |
|
1599 + MOZ_ASSERT(gtk_check_version(3, 10, 0) == nullptr, |
|
1600 + "GtkHeaderBar is only available on GTK 3.10+."); |
|
1601 + if (gtk_check_version(3, 10, 0) != nullptr) |
|
1602 + return nullptr; |
|
1603 + |
|
1604 + static auto sGtkHeaderBarNewPtr = (GtkWidget* (*)()) |
|
1605 + dlsym(RTLD_DEFAULT, "gtk_header_bar_new"); |
|
1606 + static const char* MOZ_GTK_STYLE_CLASS_TITLEBAR = "titlebar"; |
|
1607 + |
|
1608 + GtkWidget* headerbar = sGtkHeaderBarNewPtr(); |
|
1609 + if (aMaximized) { |
|
1610 + GtkWidget *window = gtk_window_new(GTK_WINDOW_POPUP); |
|
1611 + gtk_widget_set_name(window, "MozillaMaximizedGtkWidget"); |
|
1612 + GtkStyleContext* style = gtk_widget_get_style_context(window); |
|
1613 + gtk_style_context_add_class(style, "maximized"); |
|
1614 + GtkWidget *fixed = gtk_fixed_new(); |
|
1615 + gtk_container_add(GTK_CONTAINER(window), fixed); |
|
1616 + gtk_container_add(GTK_CONTAINER(fixed), headerbar); |
|
1617 + // Save the window container so we don't leak it. |
|
1618 + sWidgetStorage[MOZ_GTK_WINDOW_MAXIMIZED] = window; |
|
1619 + } else { |
|
1620 + AddToWindowContainer(headerbar); |
|
1621 + } |
|
1622 + |
|
1623 + // Emulate what create_titlebar() at gtkwindow.c does. |
|
1624 + GtkStyleContext* style = gtk_widget_get_style_context(headerbar); |
|
1625 + gtk_style_context_add_class(style, MOZ_GTK_STYLE_CLASS_TITLEBAR); |
|
1626 + gtk_style_context_add_class(style, "default-decoration"); |
|
1627 + |
|
1628 + return headerbar; |
|
1629 +} |
|
1630 + |
|
1631 +// TODO - Also return style for buttons located at Maximized toolbar. |
|
1632 +static GtkWidget* |
|
1633 +CreateHeaderBarButton(WidgetNodeType aWidgetType) |
|
1634 +{ |
|
1635 + MOZ_ASSERT(gtk_check_version(3, 10, 0) == nullptr, |
|
1636 + "GtkHeaderBar is only available on GTK 3.10+."); |
|
1637 + |
|
1638 + if (gtk_check_version(3, 10, 0) != nullptr) |
|
1639 + return nullptr; |
|
1640 + |
|
1641 + static const char* MOZ_GTK_STYLE_CLASS_TITLEBUTTON = "titlebutton"; |
|
1642 + |
|
1643 + GtkWidget* widget = gtk_button_new(); |
|
1644 + gtk_container_add(GTK_CONTAINER(GetWidget(MOZ_GTK_HEADER_BAR)), widget); |
|
1645 + |
|
1646 + GtkStyleContext* style = gtk_widget_get_style_context(widget); |
|
1647 + gtk_style_context_add_class(style, MOZ_GTK_STYLE_CLASS_TITLEBUTTON); |
|
1648 + |
|
1649 + switch (aWidgetType) { |
|
1650 + case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE: |
|
1651 + gtk_style_context_add_class(style, "close"); |
|
1652 + break; |
|
1653 + case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE: |
|
1654 + gtk_style_context_add_class(style, "minimize"); |
|
1655 + break; |
|
1656 + case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE: |
|
1657 + gtk_style_context_add_class(style, "maximize"); |
|
1658 + break; |
|
1659 + default: |
|
1660 + break; |
|
1661 + } |
|
1662 + |
|
1663 + return widget; |
|
1664 +} |
|
1665 + |
|
1666 +static GtkWidget* |
|
1667 CreateWidget(WidgetNodeType aWidgetType) |
|
1668 { |
|
1669 switch (aWidgetType) { |
|
1670 case MOZ_GTK_WINDOW: |
|
1671 - return CreateWindowWidget(); |
|
1672 + case MOZ_GTK_WINDOW_CSD: |
|
1673 + return CreateWindowWidget(aWidgetType); |
|
1674 case MOZ_GTK_WINDOW_CONTAINER: |
|
1675 return CreateWindowContainerWidget(); |
|
1676 case MOZ_GTK_CHECKBUTTON_CONTAINER: |
|
1677 @@ -610,6 +685,13 @@ CreateWidget(WidgetNodeType aWidgetType) |
|
1678 return CreateComboBoxEntryButtonWidget(); |
|
1679 case MOZ_GTK_COMBOBOX_ENTRY_ARROW: |
|
1680 return CreateComboBoxEntryArrowWidget(); |
|
1681 + case MOZ_GTK_HEADER_BAR: |
|
1682 + case MOZ_GTK_HEADER_BAR_MAXIMIZED: |
|
1683 + return CreateHeaderBar(aWidgetType == MOZ_GTK_HEADER_BAR_MAXIMIZED); |
|
1684 + case MOZ_GTK_HEADER_BAR_BUTTON_CLOSE: |
|
1685 + case MOZ_GTK_HEADER_BAR_BUTTON_MINIMIZE: |
|
1686 + case MOZ_GTK_HEADER_BAR_BUTTON_MAXIMIZE: |
|
1687 + return CreateHeaderBarButton(aWidgetType); |
|
1688 default: |
|
1689 /* Not implemented */ |
|
1690 return nullptr; |
|
1691 @@ -1049,6 +1131,10 @@ GetCssNodeStyleInternal(WidgetNodeType a |
|
1692 GtkWidget* widget = GetWidget(MOZ_GTK_NOTEBOOK); |
|
1693 return gtk_widget_get_style_context(widget); |
|
1694 } |
|
1695 + case MOZ_GTK_WINDOW_DECORATION: |
|
1696 + style = CreateChildCSSNode("decoration", |
|
1697 + MOZ_GTK_WINDOW_CSD); |
|
1698 + break; |
|
1699 default: |
|
1700 return GetWidgetRootStyle(aNodeType); |
|
1701 } |
|
1702 @@ -1214,6 +1300,8 @@ ResetWidgetCache(void) |
|
1703 /* This will destroy all of our widgets */ |
|
1704 if (sWidgetStorage[MOZ_GTK_WINDOW]) |
|
1705 gtk_widget_destroy(sWidgetStorage[MOZ_GTK_WINDOW]); |
|
1706 + if (sWidgetStorage[MOZ_GTK_WINDOW_MAXIMIZED]) |
|
1707 + gtk_widget_destroy(sWidgetStorage[MOZ_GTK_WINDOW_MAXIMIZED]); |
|
1708 |
|
1709 /* Clear already freed arrays */ |
|
1710 mozilla::PodArrayZero(sWidgetStorage); |
|
1711 diff -up firefox-57.0b8/widget/LookAndFeel.h.1399611 firefox-57.0b8/widget/LookAndFeel.h |
|
1712 --- firefox-57.0b8/widget/LookAndFeel.h.1399611 2017-09-16 18:22:54.000000000 +0200 |
|
1713 +++ firefox-57.0b8/widget/LookAndFeel.h 2017-10-16 12:11:45.369240636 +0200 |
|
1714 @@ -405,6 +405,30 @@ public: |
|
1715 eIntID_PhysicalHomeButton, |
|
1716 |
|
1717 /* |
|
1718 + * A boolean value indicating whether client-side decorations are |
|
1719 + * supported by the user's GTK version. |
|
1720 + */ |
|
1721 + eIntID_GTKCSDAvailable, |
|
1722 + |
|
1723 + /* |
|
1724 + * A boolean value indicating whether client-side decorations should |
|
1725 + * contain a minimize button. |
|
1726 + */ |
|
1727 + eIntID_GTKCSDMinimizeButton, |
|
1728 + |
|
1729 + /* |
|
1730 + * A boolean value indicating whether client-side decorations should |
|
1731 + * contain a maximize button. |
|
1732 + */ |
|
1733 + eIntID_GTKCSDMaximizeButton, |
|
1734 + |
|
1735 + /* |
|
1736 + * A boolean value indicating whether client-side decorations should |
|
1737 + * contain a close button. |
|
1738 + */ |
|
1739 + eIntID_GTKCSDCloseButton, |
|
1740 + |
|
1741 + /* |
|
1742 * Controls whether overlay scrollbars display when the user moves |
|
1743 * the mouse in a scrollable frame. |
|
1744 */ |
|