author | Wolfgang Rosenauer <wr@rosenauer.org> |
Wed, 24 Jan 2018 17:02:23 +0100 | |
branch | firefox58 |
changeset 1027 | 7071f6ebfda6 |
parent 1024 | d14085eee2b2 |
permissions | -rw-r--r-- |
1027 | 1 |
diff -up firefox-58.0/browser/base/moz.build.1399611 firefox-58.0/browser/base/moz.build |
2 |
--- firefox-58.0/browser/base/moz.build.1399611 2017-11-02 17:16:30.000000000 +0100 |
|
3 |
+++ firefox-58.0/browser/base/moz.build 2018-01-24 10:57:03.717031953 +0100 |
|
4 |
@@ -57,7 +57,7 @@ DEFINES['APP_LICENSE_BLOCK'] = '%s/conte |
|
1024
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
5 |
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'): |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
6 |
DEFINES['CONTEXT_COPY_IMAGE_CONTENTS'] = 1 |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
7 |
|
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
8 |
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'): |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
9 |
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa', 'gtk3'): |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
10 |
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1 |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
11 |
|
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
12 |
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'): |
1027 | 13 |
diff -up firefox-58.0/browser/themes/linux/browser.css.1399611 firefox-58.0/browser/themes/linux/browser.css |
14 |
--- firefox-58.0/browser/themes/linux/browser.css.1399611 2018-01-11 21:16:54.000000000 +0100 |
|
15 |
+++ firefox-58.0/browser/themes/linux/browser.css 2018-01-24 10:57:03.718031950 +0100 |
|
16 |
@@ -717,7 +717,7 @@ html|span.ac-emphasize-text-url { |
|
17 |
:root[tabsintitlebar] > #titlebar:-moz-lwtheme { |
|
18 |
visibility: hidden; |
|
19 |
} |
|
20 |
- :root[tabsintitlebar] > #titlebar-content:-moz-lwtheme { |
|
21 |
+ :root[tabsintitlebar] #titlebar-content:-moz-lwtheme { |
|
22 |
visibility: visible; |
|
23 |
} |
|
1024
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
24 |
|
1027 | 25 |
diff -up firefox-58.0/layout/style/nsMediaFeatures.cpp.1399611 firefox-58.0/layout/style/nsMediaFeatures.cpp |
26 |
--- firefox-58.0/layout/style/nsMediaFeatures.cpp.1399611 2018-01-11 21:17:01.000000000 +0100 |
|
27 |
+++ firefox-58.0/layout/style/nsMediaFeatures.cpp 2018-01-24 10:57:03.718031950 +0100 |
|
28 |
@@ -831,6 +831,42 @@ nsMediaFeatures::features[] = { |
|
29 |
GetSystemMetric |
|
30 |
}, |
|
1024
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
31 |
|
1027 | 32 |
+ { |
33 |
+ &nsGkAtoms::_moz_gtk_csd_available, |
|
34 |
+ nsMediaFeature::eMinMaxNotAllowed, |
|
35 |
+ nsMediaFeature::eBoolInteger, |
|
36 |
+ nsMediaFeature::eNoRequirements, |
|
37 |
+ { &nsGkAtoms::gtk_csd_available }, |
|
38 |
+ GetSystemMetric |
|
39 |
+ }, |
|
40 |
+ |
|
41 |
+ { |
|
42 |
+ &nsGkAtoms::_moz_gtk_csd_minimize_button, |
|
43 |
+ nsMediaFeature::eMinMaxNotAllowed, |
|
44 |
+ nsMediaFeature::eBoolInteger, |
|
45 |
+ nsMediaFeature::eNoRequirements, |
|
46 |
+ { &nsGkAtoms::gtk_csd_minimize_button }, |
|
47 |
+ GetSystemMetric |
|
48 |
+ }, |
|
49 |
+ |
|
50 |
+ { |
|
51 |
+ &nsGkAtoms::_moz_gtk_csd_maximize_button, |
|
52 |
+ nsMediaFeature::eMinMaxNotAllowed, |
|
53 |
+ nsMediaFeature::eBoolInteger, |
|
54 |
+ nsMediaFeature::eNoRequirements, |
|
55 |
+ { &nsGkAtoms::gtk_csd_maximize_button }, |
|
56 |
+ GetSystemMetric |
|
57 |
+ }, |
|
58 |
+ |
|
59 |
+ { |
|
60 |
+ &nsGkAtoms::_moz_gtk_csd_close_button, |
|
61 |
+ nsMediaFeature::eMinMaxNotAllowed, |
|
62 |
+ nsMediaFeature::eBoolInteger, |
|
63 |
+ nsMediaFeature::eNoRequirements, |
|
64 |
+ { &nsGkAtoms::gtk_csd_close_button }, |
|
65 |
+ GetSystemMetric |
|
66 |
+ }, |
|
67 |
+ |
|
68 |
// Internal -moz-is-glyph media feature: applies only inside SVG glyphs. |
|
69 |
// Internal because it is really only useful in the user agent anyway |
|
70 |
// and therefore not worth standardizing. |
|
71 |
diff -up firefox-58.0/toolkit/modules/moz.build.1399611 firefox-58.0/toolkit/modules/moz.build |
|
72 |
--- firefox-58.0/toolkit/modules/moz.build.1399611 2018-01-11 21:17:05.000000000 +0100 |
|
73 |
+++ firefox-58.0/toolkit/modules/moz.build 2018-01-24 10:57:03.718031950 +0100 |
|
74 |
@@ -259,7 +259,7 @@ EXTRA_JS_MODULES.sessionstore += [ |
|
1024
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
75 |
] |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
76 |
|
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
77 |
DEFINES['INSTALL_COMPACT_THEMES'] = 1 |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
78 |
-if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa'): |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
79 |
+if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'cocoa', 'gtk3'): |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
80 |
DEFINES['CAN_DRAW_IN_TITLEBAR'] = 1 |
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
81 |
|
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
82 |
if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3'): |
1027 | 83 |
diff -up firefox-58.0/widget/gtk/mozgtk/mozgtk.c.1399611 firefox-58.0/widget/gtk/mozgtk/mozgtk.c |
84 |
--- firefox-58.0/widget/gtk/mozgtk/mozgtk.c.1399611 2018-01-11 21:17:06.000000000 +0100 |
|
85 |
+++ firefox-58.0/widget/gtk/mozgtk/mozgtk.c 2018-01-24 10:11:58.638648276 +0100 |
|
86 |
@@ -391,6 +391,7 @@ STUB(gtk_separator_menu_item_new) |
|
87 |
STUB(gtk_separator_tool_item_new) |
|
88 |
STUB(gtk_settings_get_default) |
|
89 |
STUB(gtk_settings_get_for_screen) |
|
90 |
+STUB(gtk_show_uri) |
|
91 |
STUB(gtk_socket_add_id) |
|
92 |
STUB(gtk_socket_get_id) |
|
93 |
STUB(gtk_socket_get_type) |
|
94 |
@@ -407,6 +408,7 @@ STUB(gtk_target_list_add_image_targets) |
|
95 |
STUB(gtk_target_list_new) |
|
96 |
STUB(gtk_target_list_unref) |
|
97 |
STUB(gtk_targets_include_image) |
|
98 |
+STUB(gtk_targets_include_text) |
|
99 |
STUB(gtk_target_table_free) |
|
100 |
STUB(gtk_target_table_new_from_list) |
|
101 |
STUB(gtk_text_view_new) |
|
102 |
@@ -479,6 +481,7 @@ STUB(gtk_widget_show_all) |
|
103 |
STUB(gtk_widget_size_allocate) |
|
104 |
STUB(gtk_widget_style_get) |
|
105 |
STUB(gtk_widget_unparent) |
|
106 |
+STUB(gtk_widget_unrealize) |
|
107 |
STUB(gtk_window_deiconify) |
|
108 |
STUB(gtk_window_fullscreen) |
|
109 |
STUB(gtk_window_get_group) |
|
110 |
@@ -582,6 +585,8 @@ STUB(gtk_style_context_set_state) |
|
111 |
STUB(gtk_style_properties_lookup_property) |
|
112 |
STUB(gtk_tree_view_column_get_button) |
|
113 |
STUB(gtk_widget_get_preferred_size) |
|
114 |
+STUB(gtk_widget_get_preferred_width) |
|
115 |
+STUB(gtk_widget_get_preferred_height) |
|
116 |
STUB(gtk_widget_get_state_flags) |
|
117 |
STUB(gtk_widget_get_style_context) |
|
118 |
STUB(gtk_widget_path_append_type) |
|
119 |
diff -up firefox-58.0/widget/gtk/nsLookAndFeel.cpp.1399611 firefox-58.0/widget/gtk/nsLookAndFeel.cpp |
|
120 |
--- firefox-58.0/widget/gtk/nsLookAndFeel.cpp.1399611 2018-01-11 21:17:06.000000000 +0100 |
|
121 |
+++ firefox-58.0/widget/gtk/nsLookAndFeel.cpp 2018-01-24 10:57:03.718031950 +0100 |
|
122 |
@@ -24,6 +24,7 @@ |
|
123 |
#include "nsStyleConsts.h" |
|
124 |
#include "gfxFontConstants.h" |
|
125 |
#include "WidgetUtils.h" |
|
126 |
+#include "nsWindow.h" |
|
127 |
||
128 |
#include <dlfcn.h> |
|
129 |
||
130 |
@@ -740,7 +741,7 @@ GetSystemFontInfo(GtkStyleContext *aStyl |
|
131 |
// Scale fonts up on HiDPI displays. |
|
132 |
// This would be done automatically with cairo, but we manually manage |
|
133 |
// the display scale for platform consistency. |
|
134 |
- size *= ScreenHelperGTK::GetGTKMonitorScaleFactor(); |
|
135 |
+ size *= mozilla::widget::ScreenHelperGTK::GetGTKMonitorScaleFactor(); |
|
136 |
||
137 |
// |size| is now pixels |
|
138 |
||
139 |
@@ -1076,17 +1077,13 @@ nsLookAndFeel::EnsureInit() |
|
140 |
gtk_widget_destroy(window); |
|
141 |
g_object_unref(labelWidget); |
|
142 |
||
143 |
- // Require GTK 3.20 for client-side decoration support. |
|
144 |
- mCSDAvailable = gtk_check_version(3, 20, 0) == nullptr; |
|
145 |
- if (mCSDAvailable) { |
|
146 |
- mCSDAvailable = |
|
147 |
- mozilla::Preferences::GetBool("widget.allow-client-side-decoration", |
|
148 |
- false); |
|
149 |
- } |
|
150 |
+ // Require GTK 3.10 for GtkHeaderBar support and compatible window manager. |
|
151 |
+ mCSDAvailable = (gtk_check_version(3, 10, 0) == nullptr && |
|
152 |
+ nsWindow::GetCSDSupportLevel() != nsWindow::CSD_SUPPORT_NONE); |
|
153 |
||
154 |
// We need to initialize whole CSD config explicitly because it's queried |
|
155 |
// as -moz-gtk* media features. |
|
156 |
- mCSDCloseButton = false; |
|
157 |
+ mCSDCloseButton = true; |
|
158 |
mCSDMaximizeButton = false; |
|
159 |
mCSDMinimizeButton = false; |
|
160 |
||
161 |
@@ -1095,18 +1092,24 @@ nsLookAndFeel::EnsureInit() |
|
162 |
(const gchar* (*)(GtkWidget*)) |
|
163 |
dlsym(RTLD_DEFAULT, "gtk_header_bar_get_decoration_layout"); |
|
164 |
||
165 |
- GtkWidget* headerBar = GetWidget(MOZ_GTK_HEADER_BAR); |
|
166 |
- const gchar* decorationLayout = |
|
167 |
- sGtkHeaderBarGetDecorationLayoutPtr(headerBar); |
|
168 |
- if (!decorationLayout) { |
|
169 |
- g_object_get(settings, "gtk-decoration-layout", &decorationLayout, |
|
170 |
- nullptr); |
|
171 |
- } |
|
172 |
+ if (sGtkHeaderBarGetDecorationLayoutPtr) { |
|
173 |
+ GtkWidget* headerBar = GetWidget(MOZ_GTK_HEADER_BAR); |
|
174 |
+ const gchar* decorationLayout = |
|
175 |
+ sGtkHeaderBarGetDecorationLayoutPtr(headerBar); |
|
176 |
+ if (!decorationLayout) { |
|
177 |
+ g_object_get(settings, "gtk-decoration-layout", |
|
178 |
+ &decorationLayout, |
|
179 |
+ nullptr); |
|
180 |
+ } |
|
181 |
||
182 |
- if (decorationLayout) { |
|
183 |
- mCSDCloseButton = (strstr(decorationLayout, "close") != nullptr); |
|
184 |
- mCSDMaximizeButton = (strstr(decorationLayout, "maximize") != nullptr); |
|
185 |
- mCSDMinimizeButton = (strstr(decorationLayout, "minimize") != nullptr); |
|
186 |
+ if (decorationLayout) { |
|
187 |
+ mCSDCloseButton = |
|
188 |
+ (strstr(decorationLayout, "close") != nullptr); |
|
189 |
+ mCSDMaximizeButton = |
|
190 |
+ (strstr(decorationLayout, "maximize") != nullptr); |
|
191 |
+ mCSDMinimizeButton = |
|
192 |
+ (strstr(decorationLayout, "minimize") != nullptr); |
|
193 |
+ } |
|
194 |
} |
|
195 |
} |
|
196 |
} |
|
197 |
diff -up firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp.1399611 firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp |
|
198 |
--- firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp.1399611 2018-01-11 21:17:06.000000000 +0100 |
|
199 |
+++ firefox-58.0/widget/gtk/nsNativeThemeGTK.cpp 2018-01-24 10:57:03.719031946 +0100 |
|
200 |
@@ -29,6 +29,7 @@ |
|
201 |
||
202 |
#include <gdk/gdkprivate.h> |
|
203 |
#include <gtk/gtk.h> |
|
204 |
+#include <gtk/gtkx.h> |
|
205 |
||
206 |
#include "gfxContext.h" |
|
207 |
#include "gfxPlatformGtk.h" |
|
208 |
@@ -51,6 +52,7 @@ |
|
209 |
||
210 |
using namespace mozilla; |
|
211 |
using namespace mozilla::gfx; |
|
212 |
+using namespace mozilla::widget; |
|
213 |
||
214 |
NS_IMPL_ISUPPORTS_INHERITED(nsNativeThemeGTK, nsNativeTheme, nsITheme, |
|
215 |
nsIObserver) |
|
216 |
@@ -1375,6 +1377,10 @@ nsNativeThemeGTK::GetWidgetPadding(nsDev |
|
217 |
switch (aWidgetType) { |
|
218 |
case NS_THEME_BUTTON_FOCUS: |
|
219 |
case NS_THEME_TOOLBARBUTTON: |
|
220 |
+ case NS_THEME_WINDOW_BUTTON_CLOSE: |
|
221 |
+ case NS_THEME_WINDOW_BUTTON_MINIMIZE: |
|
222 |
+ case NS_THEME_WINDOW_BUTTON_MAXIMIZE: |
|
223 |
+ case NS_THEME_WINDOW_BUTTON_RESTORE: |
|
224 |
case NS_THEME_DUALBUTTON: |
|
225 |
case NS_THEME_TAB_SCROLL_ARROW_BACK: |
|
226 |
case NS_THEME_TAB_SCROLL_ARROW_FORWARD: |
|
227 |
diff -up firefox-58.0/widget/gtk/nsWindow.cpp.1399611 firefox-58.0/widget/gtk/nsWindow.cpp |
|
228 |
--- firefox-58.0/widget/gtk/nsWindow.cpp.1399611 2018-01-24 10:57:03.714031963 +0100 |
|
229 |
+++ firefox-58.0/widget/gtk/nsWindow.cpp 2018-01-24 10:57:03.720031943 +0100 |
|
230 |
@@ -178,13 +178,8 @@ static int is_parent_ungrab_enter(Gdk |
|
231 |
static int is_parent_grab_leave(GdkEventCrossing *aEvent); |
|
232 |
||
233 |
/* callbacks from widgets */ |
|
234 |
-#if (MOZ_WIDGET_GTK == 2) |
|
235 |
-static gboolean expose_event_cb (GtkWidget *widget, |
|
236 |
- GdkEventExpose *event); |
|
237 |
-#else |
|
238 |
static gboolean expose_event_cb (GtkWidget *widget, |
|
239 |
cairo_t *rect); |
|
240 |
-#endif |
|
241 |
static gboolean configure_event_cb (GtkWidget *widget, |
|
242 |
GdkEventConfigure *event); |
|
243 |
static void container_unrealize_cb (GtkWidget *widget); |
|
244 |
@@ -230,11 +225,9 @@ static void screen_composited_change |
|
245 |
static void widget_composited_changed_cb (GtkWidget* widget, |
|
246 |
gpointer user_data); |
|
247 |
||
248 |
-#if (MOZ_WIDGET_GTK == 3) |
|
249 |
static void scale_changed_cb (GtkWidget* widget, |
|
250 |
GParamSpec* aPSpec, |
|
251 |
gpointer aPointer); |
|
252 |
-#endif |
|
253 |
#if GTK_CHECK_VERSION(3,4,0) |
|
254 |
static gboolean touch_event_cb (GtkWidget* aWidget, |
|
255 |
GdkEventTouch* aEvent); |
|
256 |
@@ -390,7 +383,7 @@ static guint gButtonState; |
|
257 |
static inline int32_t |
|
258 |
GetBitmapStride(int32_t width) |
|
259 |
{ |
|
260 |
-#if defined(MOZ_X11) || (MOZ_WIDGET_GTK == 2) |
|
261 |
+#if defined(MOZ_X11) |
|
262 |
return (width+7)/8; |
|
263 |
#else |
|
264 |
return cairo_format_stride_for_width(CAIRO_FORMAT_A1, width); |
|
265 |
@@ -458,11 +451,23 @@ nsWindow::nsWindow() |
|
266 |
mXVisual = nullptr; |
|
267 |
mXDepth = 0; |
|
268 |
#endif /* MOZ_X11 */ |
|
269 |
+ |
|
270 |
if (!gGlobalsInitialized) { |
|
271 |
gGlobalsInitialized = true; |
|
272 |
||
273 |
// It's OK if either of these fail, but it may not be one day. |
|
274 |
initialize_prefs(); |
|
275 |
+ |
|
276 |
+#ifdef MOZ_WAYLAND |
|
277 |
+ // Wayland provides clipboard data to application on focus-in event |
|
278 |
+ // so we need to init our clipboard hooks before we create window |
|
279 |
+ // and get focus. |
|
280 |
+ if (!mIsX11Display) { |
|
281 |
+ nsCOMPtr<nsIClipboard> clipboard = |
|
282 |
+ do_GetService("@mozilla.org/widget/clipboard;1"); |
|
283 |
+ NS_ASSERTION(clipboard, "Failed to init clipboard!"); |
|
284 |
+ } |
|
285 |
+#endif |
|
286 |
} |
|
287 |
||
288 |
mLastMotionPressure = 0; |
|
289 |
@@ -1521,7 +1526,7 @@ nsWindow::UpdateClientOffset() |
|
290 |
{ |
|
291 |
AUTO_PROFILER_LABEL("nsWindow::UpdateClientOffset", GRAPHICS); |
|
292 |
||
293 |
- if (!mIsTopLevel || !mShell || !mGdkWindow || !mIsX11Display || |
|
294 |
+ if (!mIsTopLevel || !mShell || !mIsX11Display || |
|
295 |
gtk_window_get_window_type(GTK_WINDOW(mShell)) == GTK_WINDOW_POPUP) { |
|
296 |
mClientOffset = nsIntPoint(0, 0); |
|
297 |
return; |
|
298 |
@@ -1534,7 +1539,7 @@ nsWindow::UpdateClientOffset() |
|
299 |
int length_returned; |
|
300 |
long *frame_extents; |
|
301 |
||
302 |
- if (!gdk_property_get(mGdkWindow, |
|
303 |
+ if (!gdk_property_get(gtk_widget_get_window(mShell), |
|
304 |
gdk_atom_intern ("_NET_FRAME_EXTENTS", FALSE), |
|
305 |
cardinal_atom, |
|
306 |
0, // offset |
|
307 |
@@ -1710,16 +1715,22 @@ nsWindow::GetNativeData(uint32_t aDataTy |
|
308 |
#ifdef MOZ_X11 |
|
309 |
GdkDisplay* gdkDisplay = gdk_display_get_default(); |
|
310 |
if (GDK_IS_X11_DISPLAY(gdkDisplay)) { |
|
311 |
- return GDK_DISPLAY_XDISPLAY(gdkDisplay); |
|
312 |
+ return GDK_DISPLAY_XDISPLAY(gdkDisplay); |
|
313 |
} |
|
314 |
#endif /* MOZ_X11 */ |
|
315 |
+ // Don't bother to return native display on Wayland as it's for |
|
316 |
+ // X11 only NPAPI plugins. |
|
317 |
return nullptr; |
|
318 |
} |
|
319 |
case NS_NATIVE_SHELLWIDGET: |
|
320 |
return GetToplevelWidget(); |
|
321 |
||
322 |
case NS_NATIVE_SHAREABLE_WINDOW: |
|
323 |
- return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow)); |
|
324 |
+ if (mIsX11Display) { |
|
325 |
+ return (void *) GDK_WINDOW_XID(gdk_window_get_toplevel(mGdkWindow)); |
|
326 |
+ } |
|
327 |
+ NS_WARNING("nsWindow::GetNativeData(): NS_NATIVE_SHAREABLE_WINDOW is not handled on Wayland!"); |
|
328 |
+ return nullptr; |
|
329 |
case NS_RAW_NATIVE_IME_CONTEXT: { |
|
330 |
void* pseudoIMEContext = GetPseudoIMEContext(); |
|
331 |
if (pseudoIMEContext) { |
|
332 |
@@ -1800,18 +1811,18 @@ nsWindow::SetIcon(const nsAString& aIcon |
|
333 |
// The last two entries (for the old XPM format) will be ignored unless |
|
334 |
// no icons are found using other suffixes. XPM icons are deprecated. |
|
335 |
||
336 |
- const char extensions[6][7] = { ".png", "16.png", "32.png", "48.png", |
|
337 |
- ".xpm", "16.xpm" }; |
|
338 |
+ const char16_t extensions[9][8] = { u".png", u"16.png", u"32.png", |
|
339 |
+ u"48.png", u"64.png", u"128.png", |
|
340 |
+ u"256.png", |
|
341 |
+ u".xpm", u"16.xpm" }; |
|
342 |
||
343 |
for (uint32_t i = 0; i < ArrayLength(extensions); i++) { |
|
344 |
// Don't bother looking for XPM versions if we found a PNG. |
|
345 |
if (i == ArrayLength(extensions) - 2 && foundIcon) |
|
346 |
break; |
|
347 |
||
348 |
- nsAutoString extension; |
|
349 |
- extension.AppendASCII(extensions[i]); |
|
350 |
- |
|
351 |
- ResolveIconName(aIconSpec, extension, getter_AddRefs(iconFile)); |
|
352 |
+ ResolveIconName(aIconSpec, nsDependentString(extensions[i]), |
|
353 |
+ getter_AddRefs(iconFile)); |
|
354 |
if (iconFile) { |
|
355 |
iconFile->GetNativePath(path); |
|
356 |
GdkPixbuf *icon = gdk_pixbuf_new_from_file(path.get(), nullptr); |
|
357 |
@@ -2024,30 +2035,6 @@ gdk_window_flash(GdkWindow * aGdkWind |
|
358 |
#endif // DEBUG |
|
359 |
#endif |
|
360 |
||
361 |
-#if (MOZ_WIDGET_GTK == 2) |
|
362 |
-static bool |
|
363 |
-ExtractExposeRegion(LayoutDeviceIntRegion& aRegion, GdkEventExpose* aEvent) |
|
364 |
-{ |
|
365 |
- GdkRectangle* rects; |
|
366 |
- gint nrects; |
|
367 |
- gdk_region_get_rectangles(aEvent->region, &rects, &nrects); |
|
368 |
- |
|
369 |
- if (nrects > MAX_RECTS_IN_REGION) { |
|
370 |
- // Just use the bounding box |
|
371 |
- rects[0] = aEvent->area; |
|
372 |
- nrects = 1; |
|
373 |
- } |
|
374 |
- |
|
375 |
- for (GdkRectangle* r = rects; r < rects + nrects; r++) { |
|
376 |
- aRegion.Or(aRegion, LayoutDeviceIntRect(r->x, r->y, r->width, r->height)); |
|
377 |
- LOGDRAW(("\t%d %d %d %d\n", r->x, r->y, r->width, r->height)); |
|
378 |
- } |
|
379 |
- |
|
380 |
- g_free(rects); |
|
381 |
- return true; |
|
382 |
-} |
|
383 |
- |
|
384 |
-#else |
|
385 |
# ifdef cairo_copy_clip_rectangle_list |
|
386 |
# error "Looks like we're including Mozilla's cairo instead of system cairo" |
|
387 |
# endif |
|
388 |
@@ -2069,15 +2056,9 @@ ExtractExposeRegion(LayoutDeviceIntRegio |
|
389 |
cairo_rectangle_list_destroy(rects); |
|
390 |
return true; |
|
391 |
} |
|
392 |
-#endif |
|
393 |
||
394 |
-#if (MOZ_WIDGET_GTK == 2) |
|
395 |
-gboolean |
|
396 |
-nsWindow::OnExposeEvent(GdkEventExpose *aEvent) |
|
397 |
-#else |
|
398 |
gboolean |
|
399 |
nsWindow::OnExposeEvent(cairo_t *cr) |
|
400 |
-#endif |
|
401 |
{ |
|
402 |
// Send any pending resize events so that layout can update. |
|
403 |
// May run event loop. |
|
404 |
@@ -2096,11 +2077,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) |
|
405 |
return FALSE; |
|
406 |
||
407 |
LayoutDeviceIntRegion exposeRegion; |
|
408 |
-#if (MOZ_WIDGET_GTK == 2) |
|
409 |
- if (!ExtractExposeRegion(exposeRegion, aEvent)) { |
|
410 |
-#else |
|
411 |
if (!ExtractExposeRegion(exposeRegion, cr)) { |
|
412 |
-#endif |
|
413 |
return FALSE; |
|
414 |
} |
|
415 |
||
416 |
@@ -2141,7 +2118,7 @@ nsWindow::OnExposeEvent(cairo_t *cr) |
|
417 |
||
418 |
LOGDRAW(("sending expose event [%p] %p 0x%lx (rects follow):\n", |
|
419 |
(void *)this, (void *)mGdkWindow, |
|
420 |
- gdk_x11_window_get_xid(mGdkWindow))); |
|
421 |
+ mIsX11Display ? gdk_x11_window_get_xid(mGdkWindow) : 0)); |
|
422 |
||
423 |
// Our bounds may have changed after calling WillPaintWindow. Clip |
|
424 |
// to the new bounds here. The region is relative to this |
|
425 |
@@ -2304,19 +2281,11 @@ nsWindow::OnExposeEvent(cairo_t *cr) |
|
426 |
listener->DidPaintWindow(); |
|
427 |
||
428 |
// Synchronously flush any new dirty areas |
|
429 |
-#if (MOZ_WIDGET_GTK == 2) |
|
430 |
- GdkRegion* dirtyArea = gdk_window_get_update_area(mGdkWindow); |
|
431 |
-#else |
|
432 |
cairo_region_t* dirtyArea = gdk_window_get_update_area(mGdkWindow); |
|
433 |
-#endif |
|
434 |
||
435 |
if (dirtyArea) { |
|
436 |
gdk_window_invalidate_region(mGdkWindow, dirtyArea, false); |
|
437 |
-#if (MOZ_WIDGET_GTK == 2) |
|
438 |
- gdk_region_destroy(dirtyArea); |
|
439 |
-#else |
|
440 |
cairo_region_destroy(dirtyArea); |
|
441 |
-#endif |
|
442 |
gdk_window_process_updates(mGdkWindow, false); |
|
443 |
} |
|
444 |
||
445 |
@@ -2466,7 +2435,7 @@ nsWindow::OnSizeAllocate(GtkAllocation * |
|
446 |
mBounds.SizeTo(size); |
|
447 |
||
448 |
#ifdef MOZ_X11 |
|
449 |
- // Notify the X11CompositorWidget of a ClientSizeChange |
|
450 |
+ // Notify the GtkCompositorWidget of a ClientSizeChange |
|
451 |
if (mCompositorWidgetDelegate) { |
|
452 |
mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize()); |
|
453 |
} |
|
454 |
@@ -3550,21 +3519,9 @@ CreateGdkWindow(GdkWindow *parent, GtkWi |
|
455 |
attributes.visual = gtk_widget_get_visual(widget); |
|
456 |
attributes.window_type = GDK_WINDOW_CHILD; |
|
457 |
||
458 |
-#if (MOZ_WIDGET_GTK == 2) |
|
459 |
- attributes_mask |= GDK_WA_COLORMAP; |
|
460 |
- attributes.colormap = gtk_widget_get_colormap(widget); |
|
461 |
-#endif |
|
462 |
- |
|
463 |
GdkWindow *window = gdk_window_new(parent, &attributes, attributes_mask); |
|
464 |
gdk_window_set_user_data(window, widget); |
|
465 |
||
466 |
-// GTK3 TODO? |
|
467 |
-#if (MOZ_WIDGET_GTK == 2) |
|
468 |
- /* set the default pixmap to None so that you don't end up with the |
|
469 |
- gtk default which is BlackPixel. */ |
|
470 |
- gdk_window_set_back_pixmap(window, nullptr, FALSE); |
|
471 |
-#endif |
|
472 |
- |
|
473 |
return window; |
|
474 |
} |
|
475 |
||
476 |
@@ -3653,10 +3610,14 @@ nsWindow::Create(nsIWidget* aParent, |
|
477 |
// which will use a Window with the override-redirect attribute |
|
478 |
// (for temporary windows). |
|
479 |
// For long-lived windows, their stacking order is managed by the |
|
480 |
- // window manager, as indicated by GTK_WINDOW_TOPLEVEL ... |
|
481 |
- GtkWindowType type = |
|
482 |
- mWindowType != eWindowType_popup || aInitData->mNoAutoHide ? |
|
483 |
- GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP; |
|
484 |
+ // window manager, as indicated by GTK_WINDOW_TOPLEVEL. |
|
485 |
+ // For Wayland we have to always use GTK_WINDOW_POPUP to control |
|
486 |
+ // popup window position. |
|
487 |
+ GtkWindowType type = GTK_WINDOW_TOPLEVEL; |
|
488 |
+ if (mWindowType == eWindowType_popup) { |
|
489 |
+ type = (mIsX11Display && aInitData->mNoAutoHide) ? |
|
490 |
+ GTK_WINDOW_TOPLEVEL : GTK_WINDOW_POPUP; |
|
491 |
+ } |
|
492 |
mShell = gtk_window_new(type); |
|
493 |
||
494 |
bool useAlphaVisual = (mWindowType == eWindowType_popup && |
|
495 |
@@ -3674,13 +3635,8 @@ nsWindow::Create(nsIWidget* aParent, |
|
496 |
if (useAlphaVisual) { |
|
497 |
GdkScreen *screen = gtk_widget_get_screen(mShell); |
|
498 |
if (gdk_screen_is_composited(screen)) { |
|
499 |
-#if (MOZ_WIDGET_GTK == 2) |
|
500 |
- GdkColormap *colormap = gdk_screen_get_rgba_colormap(screen); |
|
501 |
- gtk_widget_set_colormap(mShell, colormap); |
|
502 |
-#else |
|
503 |
GdkVisual *visual = gdk_screen_get_rgba_visual(screen); |
|
504 |
gtk_widget_set_visual(mShell, visual); |
|
505 |
-#endif |
|
506 |
} |
|
507 |
} |
|
508 |
||
509 |
@@ -3728,9 +3684,11 @@ nsWindow::Create(nsIWidget* aParent, |
|
510 |
#ifdef MOZ_X11 |
|
511 |
// ... but when the window manager offers focus through |
|
512 |
// WM_TAKE_FOCUS, focus is requested on the parent window. |
|
513 |
- gtk_widget_realize(mShell); |
|
514 |
- gdk_window_add_filter(gtk_widget_get_window(mShell), |
|
515 |
- popup_take_focus_filter, nullptr); |
|
516 |
+ if (mIsX11Display) { |
|
517 |
+ gtk_widget_realize(mShell); |
|
518 |
+ gdk_window_add_filter(gtk_widget_get_window(mShell), |
|
519 |
+ popup_take_focus_filter, nullptr); |
|
520 |
+ } |
|
521 |
#endif |
|
522 |
} |
|
523 |
||
524 |
@@ -3742,7 +3700,11 @@ nsWindow::Create(nsIWidget* aParent, |
|
525 |
else { |
|
526 |
switch (aInitData->mPopupHint) { |
|
527 |
case ePopupTypeMenu: |
|
528 |
- gtkTypeHint = GDK_WINDOW_TYPE_HINT_POPUP_MENU; |
|
529 |
+ // Use GDK_WINDOW_TYPE_HINT_UTILITY on Wayland which |
|
530 |
+ // guides Gtk to create the popup as subsurface |
|
531 |
+ // instead of xdg_shell popup (see Bug 1423598). |
|
532 |
+ gtkTypeHint = mIsX11Display ? GDK_WINDOW_TYPE_HINT_POPUP_MENU : |
|
533 |
+ GDK_WINDOW_TYPE_HINT_UTILITY; |
|
534 |
break; |
|
535 |
case ePopupTypeTooltip: |
|
536 |
gtkTypeHint = GDK_WINDOW_TYPE_HINT_TOOLTIP; |
|
537 |
@@ -3769,13 +3731,11 @@ nsWindow::Create(nsIWidget* aParent, |
|
538 |
gtk_window_group_add_window(group, GTK_WINDOW(mShell)); |
|
539 |
g_object_unref(group); |
|
540 |
||
541 |
- if (GetCSDSupportLevel() != CSD_SUPPORT_NONE) { |
|
542 |
- int32_t isCSDAvailable = false; |
|
543 |
- nsresult rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDAvailable, |
|
544 |
- &isCSDAvailable); |
|
545 |
- if (NS_SUCCEEDED(rv)) { |
|
546 |
- mIsCSDAvailable = isCSDAvailable; |
|
547 |
- } |
|
548 |
+ int32_t isCSDAvailable = false; |
|
549 |
+ nsresult rv = LookAndFeel::GetInt(LookAndFeel::eIntID_GTKCSDAvailable, |
|
550 |
+ &isCSDAvailable); |
|
551 |
+ if (NS_SUCCEEDED(rv)) { |
|
552 |
+ mIsCSDAvailable = isCSDAvailable; |
|
553 |
} |
|
554 |
} |
|
555 |
||
556 |
@@ -3783,7 +3743,6 @@ nsWindow::Create(nsIWidget* aParent, |
|
557 |
GtkWidget *container = moz_container_new(); |
|
558 |
mContainer = MOZ_CONTAINER(container); |
|
559 |
||
560 |
-#if (MOZ_WIDGET_GTK == 3) |
|
561 |
// "csd" style is set when widget is realized so we need to call |
|
562 |
// it explicitly now. |
|
563 |
gtk_widget_realize(mShell); |
|
564 |
@@ -3793,16 +3752,22 @@ nsWindow::Create(nsIWidget* aParent, |
|
565 |
* 1) We're running on Gtk+ without client side decorations. |
|
566 |
* Content is rendered to mShell window and we listen |
|
567 |
* to the Gtk+ events on mShell |
|
568 |
- * 2) We're running on Gtk+ > 3.20 and client side decorations |
|
569 |
+ * 2) We're running on Gtk+ and client side decorations |
|
570 |
* are drawn by Gtk+ to mShell. Content is rendered to mContainer |
|
571 |
* and we listen to the Gtk+ events on mContainer. |
|
572 |
+ * 3) We're running on Wayland. All gecko content is rendered |
|
573 |
+ * to mContainer and we listen to the Gtk+ events on mContainer. |
|
574 |
*/ |
|
575 |
GtkStyleContext* style = gtk_widget_get_style_context(mShell); |
|
576 |
- drawToContainer = gtk_style_context_has_class(style, "csd"); |
|
577 |
-#endif |
|
578 |
+ drawToContainer = |
|
579 |
+ !mIsX11Display || |
|
580 |
+ (mIsCSDAvailable && GetCSDSupportLevel() == CSD_SUPPORT_FLAT ) || |
|
581 |
+ gtk_style_context_has_class(style, "csd"); |
|
582 |
eventWidget = (drawToContainer) ? container : mShell; |
|
583 |
||
584 |
gtk_widget_add_events(eventWidget, kEvents); |
|
585 |
+ if (drawToContainer) |
|
586 |
+ gtk_widget_add_events(mShell, GDK_PROPERTY_CHANGE_MASK); |
|
587 |
||
588 |
// Prevent GtkWindow from painting a background to avoid flickering. |
|
589 |
gtk_widget_set_app_paintable(eventWidget, TRUE); |
|
590 |
@@ -3839,19 +3804,11 @@ nsWindow::Create(nsIWidget* aParent, |
|
591 |
||
592 |
// If the popup ignores mouse events, set an empty input shape. |
|
593 |
if (aInitData->mMouseTransparent) { |
|
594 |
-#if (MOZ_WIDGET_GTK == 2) |
|
595 |
- GdkRectangle rect = { 0, 0, 0, 0 }; |
|
596 |
- GdkRegion *region = gdk_region_rectangle(&rect); |
|
597 |
- |
|
598 |
- gdk_window_input_shape_combine_region(mGdkWindow, region, 0, 0); |
|
599 |
- gdk_region_destroy(region); |
|
600 |
-#else |
|
601 |
cairo_rectangle_int_t rect = { 0, 0, 0, 0 }; |
|
602 |
cairo_region_t *region = cairo_region_create_rectangle(&rect); |
|
603 |
||
604 |
gdk_window_input_shape_combine_region(mGdkWindow, region, 0, 0); |
|
605 |
cairo_region_destroy(region); |
|
606 |
-#endif |
|
607 |
} |
|
608 |
} |
|
609 |
} |
|
610 |
@@ -3893,6 +3850,12 @@ nsWindow::Create(nsIWidget* aParent, |
|
611 |
||
612 |
// label the drawing window with this object so we can find our way home |
|
613 |
g_object_set_data(G_OBJECT(mGdkWindow), "nsWindow", this); |
|
614 |
+ if (drawToContainer) { |
|
615 |
+ // Also label mShell toplevel window, |
|
616 |
+ // property_notify_event_cb callback also needs to find its way home |
|
617 |
+ g_object_set_data(G_OBJECT(gtk_widget_get_window(mShell)), |
|
618 |
+ "nsWindow", this); |
|
619 |
+ } |
|
620 |
||
621 |
if (mContainer) |
|
622 |
g_object_set_data(G_OBJECT(mContainer), "nsWindow", this); |
|
623 |
@@ -3910,12 +3873,12 @@ nsWindow::Create(nsIWidget* aParent, |
|
624 |
G_CALLBACK(window_state_event_cb), nullptr); |
|
625 |
g_signal_connect(mShell, "check-resize", |
|
626 |
G_CALLBACK(check_resize_cb), nullptr); |
|
627 |
- |
|
628 |
- GdkScreen *screen = gtk_widget_get_screen(mShell); |
|
629 |
- |
|
630 |
g_signal_connect(mShell, "composited-changed", |
|
631 |
G_CALLBACK(widget_composited_changed_cb), nullptr); |
|
632 |
+ g_signal_connect(mShell, "property-notify-event", |
|
633 |
+ G_CALLBACK(property_notify_event_cb), nullptr); |
|
634 |
||
635 |
+ GdkScreen *screen = gtk_widget_get_screen(mShell); |
|
636 |
if (!g_signal_handler_find(screen, G_SIGNAL_MATCH_FUNC, |
|
637 |
0, 0, nullptr, |
|
638 |
FuncToGpointer(screen_composited_changed_cb), 0)) { |
|
639 |
@@ -3940,21 +3903,14 @@ nsWindow::Create(nsIWidget* aParent, |
|
640 |
G_CALLBACK(size_allocate_cb), nullptr); |
|
641 |
g_signal_connect(mContainer, "hierarchy-changed", |
|
642 |
G_CALLBACK(hierarchy_changed_cb), nullptr); |
|
643 |
-#if (MOZ_WIDGET_GTK == 3) |
|
644 |
g_signal_connect(mContainer, "notify::scale-factor", |
|
645 |
G_CALLBACK(scale_changed_cb), nullptr); |
|
646 |
-#endif |
|
647 |
// Initialize mHasMappedToplevel. |
|
648 |
hierarchy_changed_cb(GTK_WIDGET(mContainer), nullptr); |
|
649 |
// Expose, focus, key, and drag events are sent even to GTK_NO_WINDOW |
|
650 |
// widgets. |
|
651 |
-#if (MOZ_WIDGET_GTK == 2) |
|
652 |
- g_signal_connect(mContainer, "expose_event", |
|
653 |
- G_CALLBACK(expose_event_cb), nullptr); |
|
654 |
-#else |
|
655 |
g_signal_connect(G_OBJECT(mContainer), "draw", |
|
656 |
G_CALLBACK(expose_event_cb), nullptr); |
|
657 |
-#endif |
|
658 |
g_signal_connect(mContainer, "focus_in_event", |
|
659 |
G_CALLBACK(focus_in_event_cb), nullptr); |
|
660 |
g_signal_connect(mContainer, "focus_out_event", |
|
661 |
@@ -4006,10 +3962,6 @@ nsWindow::Create(nsIWidget* aParent, |
|
662 |
} |
|
663 |
||
664 |
if (eventWidget) { |
|
665 |
-#if (MOZ_WIDGET_GTK == 2) |
|
666 |
- // Don't let GTK mess with the shapes of our GdkWindows |
|
667 |
- GTK_PRIVATE_SET_FLAG(eventWidget, GTK_HAS_SHAPE_MASK); |
|
668 |
-#endif |
|
669 |
||
670 |
// These events are sent to the owning widget of the relevant window |
|
671 |
// and propagate up to the first widget that handles the events, so we |
|
672 |
@@ -4025,8 +3977,6 @@ nsWindow::Create(nsIWidget* aParent, |
|
673 |
G_CALLBACK(button_press_event_cb), nullptr); |
|
674 |
g_signal_connect(eventWidget, "button-release-event", |
|
675 |
G_CALLBACK(button_release_event_cb), nullptr); |
|
676 |
- g_signal_connect(eventWidget, "property-notify-event", |
|
677 |
- G_CALLBACK(property_notify_event_cb), nullptr); |
|
678 |
g_signal_connect(eventWidget, "scroll-event", |
|
679 |
G_CALLBACK(scroll_event_cb), nullptr); |
|
680 |
#if GTK_CHECK_VERSION(3,4,0) |
|
681 |
@@ -4039,7 +3989,7 @@ nsWindow::Create(nsIWidget* aParent, |
|
682 |
if (mShell) { |
|
683 |
LOG(("\tmShell %p mContainer %p mGdkWindow %p 0x%lx\n", |
|
684 |
mShell, mContainer, mGdkWindow, |
|
685 |
- gdk_x11_window_get_xid(mGdkWindow))); |
|
686 |
+ mIsX11Display ? gdk_x11_window_get_xid(mGdkWindow) : 0)); |
|
687 |
} else if (mContainer) { |
|
688 |
LOG(("\tmContainer %p mGdkWindow %p\n", mContainer, mGdkWindow)); |
|
689 |
} |
|
690 |
@@ -4063,8 +4013,12 @@ nsWindow::Create(nsIWidget* aParent, |
|
1024
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
691 |
|
1027 | 692 |
mSurfaceProvider.Initialize(mXDisplay, mXWindow, mXVisual, mXDepth); |
693 |
} |
|
694 |
+#ifdef MOZ_WAYLAND |
|
695 |
+ else if (!mIsX11Display) { |
|
696 |
+ mSurfaceProvider.Initialize(this); |
|
697 |
+ } |
|
698 |
+#endif |
|
699 |
#endif |
|
700 |
- |
|
701 |
return NS_OK; |
|
702 |
} |
|
703 |
||
704 |
@@ -4099,7 +4053,8 @@ nsWindow::SetWindowClass(const nsAString |
|
705 |
res_name[0] = toupper(res_name[0]); |
|
706 |
if (!role) role = res_name; |
|
707 |
||
708 |
- gdk_window_set_role(mGdkWindow, role); |
|
709 |
+ GdkWindow* gdkWindow = gtk_widget_get_window(mShell); |
|
710 |
+ gdk_window_set_role(gdkWindow, role); |
|
711 |
||
712 |
#ifdef MOZ_X11 |
|
713 |
if (mIsX11Display) { |
|
714 |
@@ -4115,7 +4070,7 @@ nsWindow::SetWindowClass(const nsAString |
|
715 |
// a warning & refuses to make the change. |
|
716 |
GdkDisplay *display = gdk_display_get_default(); |
|
717 |
XSetClassHint(GDK_DISPLAY_XDISPLAY(display), |
|
718 |
- gdk_x11_window_get_xid(mGdkWindow), |
|
719 |
+ gdk_x11_window_get_xid(gdkWindow), |
|
720 |
class_hint); |
|
721 |
XFree(class_hint); |
|
722 |
} |
|
723 |
@@ -4164,7 +4119,7 @@ nsWindow::NativeResize() |
|
724 |
} |
|
725 |
||
726 |
#ifdef MOZ_X11 |
|
727 |
- // Notify the X11CompositorWidget of a ClientSizeChange |
|
728 |
+ // Notify the GtkCompositorWidget of a ClientSizeChange |
|
729 |
// This is different than OnSizeAllocate to catch initial sizing |
|
730 |
if (mCompositorWidgetDelegate) { |
|
731 |
mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize()); |
|
732 |
@@ -4220,7 +4175,7 @@ nsWindow::NativeMoveResize() |
|
733 |
} |
|
734 |
||
735 |
#ifdef MOZ_X11 |
|
736 |
- // Notify the X11CompositorWidget of a ClientSizeChange |
|
737 |
+ // Notify the GtkCompositorWidget of a ClientSizeChange |
|
738 |
// This is different than OnSizeAllocate to catch initial sizing |
|
739 |
if (mCompositorWidgetDelegate) { |
|
740 |
mCompositorWidgetDelegate->NotifyClientSizeChanged(GetClientSize()); |
|
741 |
@@ -4529,17 +4484,6 @@ nsWindow::SetWindowClipRegion(const nsTA |
|
742 |
if (!mGdkWindow) |
|
743 |
return NS_OK; |
|
744 |
||
745 |
-#if (MOZ_WIDGET_GTK == 2) |
|
746 |
- GdkRegion *region = gdk_region_new(); // aborts on OOM |
|
747 |
- for (uint32_t i = 0; i < newRects->Length(); ++i) { |
|
748 |
- const LayoutDeviceIntRect& r = newRects->ElementAt(i); |
|
749 |
- GdkRectangle rect = { r.x, r.y, r.width, r.height }; |
|
750 |
- gdk_region_union_with_rect(region, &rect); |
|
751 |
- } |
|
752 |
- |
|
753 |
- gdk_window_shape_combine_region(mGdkWindow, region, 0, 0); |
|
754 |
- gdk_region_destroy(region); |
|
755 |
-#else |
|
756 |
cairo_region_t *region = cairo_region_create(); |
|
757 |
for (uint32_t i = 0; i < newRects->Length(); ++i) { |
|
758 |
const LayoutDeviceIntRect& r = newRects->ElementAt(i); |
|
759 |
@@ -4549,7 +4493,6 @@ nsWindow::SetWindowClipRegion(const nsTA |
|
760 |
||
761 |
gdk_window_shape_combine_region(mGdkWindow, region, 0, 0); |
|
762 |
cairo_region_destroy(region); |
|
763 |
-#endif |
|
764 |
||
765 |
return NS_OK; |
|
766 |
} |
|
767 |
@@ -4658,17 +4601,6 @@ nsWindow::ApplyTransparencyBitmap() |
|
768 |
maskPixmap, ShapeSet); |
|
769 |
XFreePixmap(xDisplay, maskPixmap); |
|
770 |
#else |
|
771 |
-#if (MOZ_WIDGET_GTK == 2) |
|
772 |
- gtk_widget_reset_shapes(mShell); |
|
773 |
- GdkBitmap* maskBitmap = gdk_bitmap_create_from_data(mGdkWindow, |
|
774 |
- mTransparencyBitmap, |
|
775 |
- mTransparencyBitmapWidth, mTransparencyBitmapHeight); |
|
776 |
- if (!maskBitmap) |
|
777 |
- return; |
|
778 |
- |
|
779 |
- gtk_widget_shape_combine_mask(mShell, maskBitmap, 0, 0); |
|
780 |
- g_object_unref(maskBitmap); |
|
781 |
-#else |
|
782 |
cairo_surface_t *maskBitmap; |
|
783 |
maskBitmap = cairo_image_surface_create_for_data((unsigned char*)mTransparencyBitmap, |
|
784 |
CAIRO_FORMAT_A1, |
|
785 |
@@ -4682,7 +4614,6 @@ nsWindow::ApplyTransparencyBitmap() |
|
786 |
gtk_widget_shape_combine_region(mShell, maskRegion); |
|
787 |
cairo_region_destroy(maskRegion); |
|
788 |
cairo_surface_destroy(maskBitmap); |
|
789 |
-#endif // MOZ_WIDGET_GTK == 2 |
|
790 |
#endif // MOZ_X11 |
|
791 |
} |
|
792 |
||
793 |
@@ -4779,6 +4710,12 @@ nsWindow::GrabPointer(guint32 aTime) |
|
794 |
if (!mGdkWindow) |
|
795 |
return; |
|
796 |
||
797 |
+ if (!mIsX11Display) { |
|
798 |
+ // Don't to the grab on Wayland as it causes a regression |
|
799 |
+ // from Bug 1377084. |
|
800 |
+ return; |
|
801 |
+ } |
|
802 |
+ |
|
803 |
gint retval; |
|
804 |
retval = gdk_pointer_grab(mGdkWindow, TRUE, |
|
805 |
(GdkEventMask)(GDK_BUTTON_PRESS_MASK | |
|
806 |
@@ -4812,6 +4749,13 @@ nsWindow::ReleaseGrabs(void) |
|
807 |
LOG(("ReleaseGrabs\n")); |
|
808 |
||
809 |
mRetryPointerGrab = false; |
|
810 |
+ |
|
811 |
+ if (!mIsX11Display) { |
|
812 |
+ // Don't to the ungrab on Wayland as it causes a regression |
|
813 |
+ // from Bug 1377084. |
|
814 |
+ return; |
|
815 |
+ } |
|
816 |
+ |
|
817 |
gdk_pointer_ungrab(GDK_CURRENT_TIME); |
|
818 |
} |
|
819 |
||
820 |
@@ -5058,7 +5002,7 @@ nsWindow::MakeFullScreen(bool aFullScree |
|
821 |
LOG(("nsWindow::MakeFullScreen [%p] aFullScreen %d\n", |
|
822 |
(void *)this, aFullScreen)); |
|
823 |
||
824 |
- if (!IsFullscreenSupported(mShell)) { |
|
825 |
+ if (mIsX11Display && !IsFullscreenSupported(mShell)) { |
|
826 |
return NS_ERROR_NOT_AVAILABLE; |
|
827 |
} |
|
828 |
||
829 |
@@ -5080,7 +5024,7 @@ nsWindow::MakeFullScreen(bool aFullScree |
|
830 |
} |
|
831 |
||
832 |
void |
|
833 |
-nsWindow::HideWindowChrome(bool aShouldHide) |
|
834 |
+nsWindow::SetWindowDecoration(nsBorderStyle aStyle) |
|
835 |
{ |
|
836 |
if (!mShell) { |
|
837 |
// Pass the request to the toplevel window |
|
838 |
@@ -5092,30 +5036,29 @@ nsWindow::HideWindowChrome(bool aShouldH |
|
839 |
if (!topWindow) |
|
840 |
return; |
|
841 |
||
842 |
- topWindow->HideWindowChrome(aShouldHide); |
|
843 |
+ topWindow->SetWindowDecoration(aStyle); |
|
844 |
return; |
|
845 |
} |
|
846 |
||
847 |
+ // We can't use mGdkWindow directly here as it can be |
|
848 |
+ // derived from mContainer which is not a top-level GdkWindow. |
|
849 |
+ GdkWindow *window = gtk_widget_get_window(mShell); |
|
850 |
+ |
|
851 |
// Sawfish, metacity, and presumably other window managers get |
|
852 |
// confused if we change the window decorations while the window |
|
853 |
// is visible. |
|
854 |
bool wasVisible = false; |
|
855 |
- if (gdk_window_is_visible(mGdkWindow)) { |
|
856 |
- gdk_window_hide(mGdkWindow); |
|
857 |
+ if (gdk_window_is_visible(window)) { |
|
858 |
+ gdk_window_hide(window); |
|
859 |
wasVisible = true; |
|
860 |
} |
|
861 |
||
862 |
- gint wmd; |
|
863 |
- if (aShouldHide) |
|
864 |
- wmd = 0; |
|
865 |
- else |
|
866 |
- wmd = ConvertBorderStyles(mBorderStyle); |
|
867 |
- |
|
868 |
+ gint wmd = ConvertBorderStyles(aStyle); |
|
869 |
if (wmd != -1) |
|
870 |
- gdk_window_set_decorations(mGdkWindow, (GdkWMDecoration) wmd); |
|
871 |
+ gdk_window_set_decorations(window, (GdkWMDecoration) wmd); |
|
872 |
||
873 |
if (wasVisible) |
|
874 |
- gdk_window_show(mGdkWindow); |
|
875 |
+ gdk_window_show(window); |
|
876 |
||
877 |
// For some window managers, adding or removing window decorations |
|
878 |
// requires unmapping and remapping our toplevel window. Go ahead |
|
879 |
@@ -5123,10 +5066,19 @@ nsWindow::HideWindowChrome(bool aShouldH |
|
880 |
// error later when this happens (when the persistence timer fires |
|
881 |
// and GetWindowPos is called) |
|
882 |
#ifdef MOZ_X11 |
|
883 |
- XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) , False); |
|
884 |
-#else |
|
885 |
- gdk_flush (); |
|
886 |
+ if (mIsX11Display) { |
|
887 |
+ XSync(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()) , False); |
|
888 |
+ } else |
|
889 |
#endif /* MOZ_X11 */ |
|
890 |
+ { |
|
891 |
+ gdk_flush (); |
|
892 |
+ } |
|
893 |
+} |
|
894 |
+ |
|
895 |
+void |
|
896 |
+nsWindow::HideWindowChrome(bool aShouldHide) |
|
897 |
+{ |
|
898 |
+ SetWindowDecoration(aShouldHide ? eBorderStyle_none : mBorderStyle); |
|
899 |
} |
|
900 |
||
901 |
bool |
|
902 |
@@ -5237,12 +5189,8 @@ is_mouse_in_window (GdkWindow* aWindow, |
|
903 |
window = gdk_window_get_parent(window); |
|
904 |
} |
|
905 |
||
906 |
-#if (MOZ_WIDGET_GTK == 2) |
|
907 |
- gdk_drawable_get_size(aWindow, &w, &h); |
|
908 |
-#else |
|
909 |
w = gdk_window_get_width(aWindow); |
|
910 |
h = gdk_window_get_height(aWindow); |
|
911 |
-#endif |
|
912 |
||
913 |
if (aMouseX > x && aMouseX < x + w && |
|
914 |
aMouseY > y && aMouseY < y + h) |
|
915 |
@@ -5498,18 +5446,6 @@ get_gtk_cursor(nsCursor aCursor) |
|
916 |
||
917 |
// gtk callbacks |
|
918 |
||
919 |
-#if (MOZ_WIDGET_GTK == 2) |
|
920 |
-static gboolean |
|
921 |
-expose_event_cb(GtkWidget *widget, GdkEventExpose *event) |
|
922 |
-{ |
|
923 |
- RefPtr<nsWindow> window = get_window_for_gdk_window(event->window); |
|
924 |
- if (!window) |
|
925 |
- return FALSE; |
|
926 |
- |
|
927 |
- window->OnExposeEvent(event); |
|
928 |
- return FALSE; |
|
929 |
-} |
|
930 |
-#else |
|
931 |
void |
|
932 |
draw_window_of_widget(GtkWidget *widget, GdkWindow *aWindow, cairo_t *cr) |
|
933 |
{ |
|
934 |
@@ -5561,7 +5497,6 @@ expose_event_cb(GtkWidget *widget, cairo |
|
935 |
||
936 |
return FALSE; |
|
937 |
} |
|
938 |
-#endif //MOZ_WIDGET_GTK == 2 |
|
939 |
||
940 |
static gboolean |
|
941 |
configure_event_cb(GtkWidget *widget, |
|
942 |
@@ -5980,7 +5915,6 @@ widget_composited_changed_cb (GtkWidget* |
|
943 |
window->OnCompositedChanged(); |
|
944 |
} |
|
945 |
||
946 |
-#if (MOZ_WIDGET_GTK == 3) |
|
947 |
static void |
|
948 |
scale_changed_cb (GtkWidget* widget, GParamSpec* aPSpec, gpointer aPointer) |
|
949 |
{ |
|
950 |
@@ -5996,7 +5930,6 @@ scale_changed_cb (GtkWidget* widget, GPa |
|
951 |
gtk_widget_get_allocation(widget, &allocation); |
|
952 |
window->OnSizeAllocate(&allocation); |
|
953 |
} |
|
954 |
-#endif |
|
955 |
||
956 |
#if GTK_CHECK_VERSION(3,4,0) |
|
957 |
static gboolean |
|
958 |
@@ -6174,11 +6107,7 @@ get_inner_gdk_window (GdkWindow *aWindow |
|
959 |
child = g_list_previous(child)) { |
|
960 |
auto *childWindow = (GdkWindow *) child->data; |
|
961 |
if (get_window_for_gdk_window(childWindow)) { |
|
962 |
-#if (MOZ_WIDGET_GTK == 2) |
|
963 |
- gdk_window_get_geometry(childWindow, &cx, &cy, &cw, &ch, nullptr); |
|
964 |
-#else |
|
965 |
gdk_window_get_geometry(childWindow, &cx, &cy, &cw, &ch); |
|
966 |
-#endif |
|
967 |
if ((cx < x) && (x < (cx + cw)) && |
|
968 |
(cy < y) && (y < (cy + ch)) && |
|
969 |
gdk_window_is_visible(childWindow)) { |
|
970 |
@@ -6386,53 +6315,6 @@ nsWindow::GetEditCommands(NativeKeyBindi |
|
971 |
keyBindings->GetEditCommands(aEvent, aCommands); |
|
972 |
} |
|
1024
d14085eee2b2
bring back CSD (but not ported yet)
Wolfgang Rosenauer <wr@rosenauer.org>
parents:
diff
changeset
|
973 |
|
1027 | 974 |
-#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2) |
975 |
-/* static */ already_AddRefed<DrawTarget> |
|
976 |
-nsWindow::GetDrawTargetForGdkDrawable(GdkDrawable* aDrawable, |
|
977 |
- const IntSize& aSize) |
|
978 |
-{ |
|
979 |
- GdkVisual* visual = gdk_drawable_get_visual(aDrawable); |
|
980 |
- Screen* xScreen = |
|
981 |
- gdk_x11_screen_get_xscreen(gdk_drawable_get_screen(aDrawable)); |
|
982 |
- Display* xDisplay = DisplayOfScreen(xScreen); |
|
983 |
- Drawable xDrawable = gdk_x11_drawable_get_xid(aDrawable); |
|
984 |
- |
|
985 |
- RefPtr<gfxASurface> surface; |
|
986 |
- |
|
987 |
- if (visual) { |
|
988 |
- Visual* xVisual = gdk_x11_visual_get_xvisual(visual); |
|
989 |
- |
|
990 |
- surface = new gfxXlibSurface(xDisplay, xDrawable, xVisual, aSize); |
|
991 |
- } else { |
|
992 |
- // no visual? we must be using an xrender format. Find a format |
|
993 |
- // for this depth. |
|
994 |
- XRenderPictFormat *pf = nullptr; |
|
995 |
- switch (gdk_drawable_get_depth(aDrawable)) { |
|
996 |
- case 32: |
|
997 |
- pf = XRenderFindStandardFormat(xDisplay, PictStandardARGB32); |
|
998 |
- break; |
|
999 |
- case 24: |
|
1000 |
- pf = XRenderFindStandardFormat(xDisplay, PictStandardRGB24); |
|
1001 |
- break; |
|
1002 |
- default: |
|
1003 |
- NS_ERROR("Don't know how to handle the given depth!"); |
|
1004 |
- break; |
|
1005 |
- } |
|
1006 |
- |
|
1007 |
- surface = new gfxXlibSurface(xScreen, xDrawable, pf, aSize); |
|
1008 |
- } |
|
1009 |
- |
|
1010 |
- RefPtr<DrawTarget> dt = |
|
1011 |
- gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, aSize); |
|
1012 |
- |
|
1013 |
- if (!dt || !dt->IsValid()) { |
|
1014 |
- return nullptr; |
|
1015 |
- } |
|
1016 |
- |
|
1017 |
- return dt.forget(); |
|
1018 |
-} |
|
1019 |
-#endif |
|
1020 |
- |
|
1021 |
already_AddRefed<DrawTarget> |
|
1022 |
nsWindow::StartRemoteDrawingInRegion(LayoutDeviceIntRegion& aInvalidRegion, BufferMode* aBufferMode) |
|
1023 |
{ |
|
1024 |
@@ -6649,9 +6531,66 @@ nsWindow::SetDrawsInTitlebar(bool aState |
|
1025 |
return; |
|
1026 |
||
1027 |
if (mShell) { |
|
1028 |
- gint wmd = aState ? GDK_DECOR_BORDER : ConvertBorderStyles(mBorderStyle); |
|
1029 |
- gdk_window_set_decorations(gtk_widget_get_window(mShell), |
|
1030 |
- (GdkWMDecoration) wmd); |
|
1031 |
+ if (GetCSDSupportLevel() == CSD_SUPPORT_FULL) { |
|
1032 |
+ SetWindowDecoration(aState ? eBorderStyle_border : mBorderStyle); |
|
1033 |
+ } |
|
1034 |
+ else { |
|
1035 |
+ /* Window manager does not support GDK_DECOR_BORDER, |
|
1036 |
+ * emulate it by CSD. |
|
1037 |
+ * |
|
1038 |
+ * gtk_window_set_titlebar() works on unrealized widgets only, |
|
1039 |
+ * we need to handle mShell carefully here. |
|
1040 |
+ * When CSD is enabled mGdkWindow is owned by mContainer which is good |
|
1041 |
+ * as we can't delete our mGdkWindow. To make mShell unrealized while |
|
1042 |
+ * mContainer is preserved we temporary reparent mContainer to an |
|
1043 |
+ * invisible GtkWindow. |
|
1044 |
+ */ |
|
1045 |
+ NativeShow(false); |
|
1046 |
+ |
|
1047 |
+ // Using GTK_WINDOW_POPUP rather than |
|
1048 |
+ // GTK_WINDOW_TOPLEVEL in the hope that POPUP results in less |
|
1049 |
+ // initialization and window manager interaction. |
|
1050 |
+ GtkWidget* tmpWindow = gtk_window_new(GTK_WINDOW_POPUP); |
|
1051 |
+ gtk_widget_realize(tmpWindow); |
|
1052 |
+ |
|
1053 |
+ gtk_widget_reparent(GTK_WIDGET(mContainer), tmpWindow); |
|
1054 |
+ gtk_widget_unrealize(GTK_WIDGET(mShell)); |
|
1055 |
+ |
|
1056 |
+ // Available as of GTK 3.10+ |
|
1057 |
+ static auto sGtkWindowSetTitlebar = (void (*)(GtkWindow*, GtkWidget*)) |
|
1058 |
+ dlsym(RTLD_DEFAULT, "gtk_window_set_titlebar"); |
|
1059 |
+ MOZ_ASSERT(sGtkWindowSetTitlebar, |
|
1060 |
+ "Missing gtk_window_set_titlebar(), old Gtk+ library?"); |
|
1061 |
+ |
|
1062 |
+ if (aState) { |
|
1063 |
+ // Add a hidden titlebar widget to trigger CSD, but disable the default |
|
1064 |
+ // titlebar. GtkFixed is a somewhat random choice for a simple unused |
|
1065 |
+ // widget. gtk_window_set_titlebar() takes ownership of the titlebar |
|
1066 |
+ // widget. |
|
1067 |
+ sGtkWindowSetTitlebar(GTK_WINDOW(mShell), gtk_fixed_new()); |
|
1068 |
+ } else { |
|
1069 |
+ sGtkWindowSetTitlebar(GTK_WINDOW(mShell), nullptr); |
|
1070 |
+ } |
|
1071 |
+ |
|
1072 |
+ /* A workaround for https://bugzilla.gnome.org/show_bug.cgi?id=791081 |
|
1073 |
+ * gtk_widget_realize() throws: |
|
1074 |
+ * "In pixman_region32_init_rect: Invalid rectangle passed" |
|
1075 |
+ * when mShell has default 1x1 size. |
|
1076 |
+ */ |
|
1077 |
+ GtkAllocation allocation = {0, 0, 0, 0}; |
|
1078 |
+ gtk_widget_get_preferred_width(GTK_WIDGET(mShell), nullptr, |
|
1079 |
+ &allocation.width); |
|
1080 |
+ gtk_widget_get_preferred_height(GTK_WIDGET(mShell), nullptr, |
|
1081 |
+ &allocation.height); |
|
1082 |
+ gtk_widget_size_allocate(GTK_WIDGET(mShell), &allocation); |
|
1083 |
+ |
|
1084 |
+ gtk_widget_realize(GTK_WIDGET(mShell)); |
|
1085 |
+ gtk_widget_reparent(GTK_WIDGET(mContainer), GTK_WIDGET(mShell)); |
|
1086 |
+ mNeedsShow = true; |
|
1087 |
+ NativeResize(); |
|
1088 |
+ |
|
1089 |
+ gtk_widget_destroy(tmpWindow); |
|
1090 |
+ } |
|
1091 |
} |
|
1092 |
||
1093 |
mIsCSDEnabled = aState; |
|
1094 |
@@ -6762,11 +6701,9 @@ nsWindow::SynthesizeNativeMouseEvent(Lay |
|
1095 |
event.button.window = mGdkWindow; |
|
1096 |
event.button.time = GDK_CURRENT_TIME; |
|
1097 |
||
1098 |
-#if (MOZ_WIDGET_GTK == 3) |
|
1099 |
// Get device for event source |
|
1100 |
GdkDeviceManager *device_manager = gdk_display_get_device_manager(display); |
|
1101 |
event.button.device = gdk_device_manager_get_client_pointer(device_manager); |
|
1102 |
-#endif |
|
1103 |
||
1104 |
event.button.x_root = DevicePixelsToGdkCoordRoundDown(aPoint.x); |
|
1105 |
event.button.y_root = DevicePixelsToGdkCoordRoundDown(aPoint.y); |
|
1106 |
@@ -6809,12 +6746,10 @@ nsWindow::SynthesizeNativeMouseScrollEve |
|
1107 |
event.type = GDK_SCROLL; |
|
1108 |
event.scroll.window = mGdkWindow; |
|
1109 |
event.scroll.time = GDK_CURRENT_TIME; |
|
1110 |
-#if (MOZ_WIDGET_GTK == 3) |
|
1111 |
// Get device for event source |
|
1112 |
GdkDisplay* display = gdk_window_get_display(mGdkWindow); |
|
1113 |
GdkDeviceManager *device_manager = gdk_display_get_device_manager(display); |
|
1114 |
event.scroll.device = gdk_device_manager_get_client_pointer(device_manager); |
|
1115 |
-#endif |
|
1116 |
event.scroll.x_root = DevicePixelsToGdkCoordRoundDown(aPoint.x); |
|
1117 |
event.scroll.y_root = DevicePixelsToGdkCoordRoundDown(aPoint.y); |
|
1118 |
||
1119 |
@@ -6938,27 +6873,54 @@ nsWindow::GetCSDSupportLevel() { |
|
1120 |
if (sCSDSupportLevel != CSD_SUPPORT_UNKNOWN) { |
|
1121 |
return sCSDSupportLevel; |
|
1122 |
} |
|
1123 |
- // TODO: MATE |
|
1124 |
+ |
|
1125 |
const char* currentDesktop = getenv("XDG_CURRENT_DESKTOP"); |
|
1126 |
if (currentDesktop) { |
|
1127 |
- if (strcmp(currentDesktop, "GNOME") == 0) { |
|
1128 |
- sCSDSupportLevel = CSD_SUPPORT_FULL; |
|
1129 |
- } else if (strcmp(currentDesktop, "XFCE") == 0) { |
|
1130 |
+ if (strstr(currentDesktop, "GNOME") != nullptr) { |
|
1131 |
sCSDSupportLevel = CSD_SUPPORT_FULL; |
|
1132 |
- } else if (strcmp(currentDesktop, "X-Cinnamon") == 0) { |
|
1133 |
+ } else if (strstr(currentDesktop, "XFCE") != nullptr) { |
|
1134 |
+ sCSDSupportLevel = CSD_SUPPORT_FLAT; |
|
1135 |
+ } else if (strstr(currentDesktop, "X-Cinnamon") != nullptr) { |
|
1136 |
sCSDSupportLevel = CSD_SUPPORT_FULL; |
|
1137 |
- } else if (strcmp(currentDesktop, "KDE") == 0) { |
|
1138 |
+ } else if (strstr(currentDesktop, "KDE") != nullptr) { |
|
1139 |
sCSDSupportLevel = CSD_SUPPORT_FLAT; |
|
1140 |
- } else if (strcmp(currentDesktop, "LXDE") == 0) { |
|