1 /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "nsGDKErrorHandler.h"
10 # include <gdk/gdkx.h>
19 # include "nsX11ErrorHandler.h"
24 /* See https://bugzilla.gnome.org/show_bug.cgi?id=629608#c8
26 * GDK implements X11 error traps to ignore X11 errors.
27 * Unfortunatelly We don't know which X11 events can be ignored
28 * so we have to utilize the Gdk error handler to avoid
29 * false alarms in Gtk3.
31 static void GdkErrorHandler(const gchar
* log_domain
, GLogLevelFlags log_level
,
32 const gchar
* message
, gpointer user_data
) {
34 if (strstr(message
, "X Window System error")) {
36 nsDependentCString
buffer(message
);
39 /* Parse Gdk X Window error message which has this format:
40 * (Details: serial XXXX error_code XXXX request_code XXXX (XXXX) minor_code
43 constexpr auto serialString
= "(Details: serial "_ns
;
44 int32_t start
= buffer
.Find(serialString
);
45 if (start
== kNotFound
) {
46 MOZ_CRASH_UNSAFE(message
);
49 start
+= serialString
.Length();
51 event
.serial
= strtol(buffer
.BeginReading() + start
, &endptr
, 10);
53 MOZ_CRASH_UNSAFE(message
);
56 constexpr auto errorCodeString
= " error_code "_ns
;
57 if (!StringBeginsWith(Substring(endptr
, buffer
.EndReading()),
59 MOZ_CRASH_UNSAFE(message
);
63 event
.error_code
= strtol(endptr
+ errorCodeString
.Length(), &endptr
, 10);
65 MOZ_CRASH_UNSAFE(message
);
68 constexpr auto requestCodeString
= " request_code "_ns
;
69 if (!StringBeginsWith(Substring(endptr
, buffer
.EndReading()),
71 MOZ_CRASH_UNSAFE(message
);
76 strtol(endptr
+ requestCodeString
.Length(), &endptr
, 10);
78 MOZ_CRASH_UNSAFE(message
);
81 constexpr auto minorCodeString
= " minor_code "_ns
;
82 start
= buffer
.Find(minorCodeString
, endptr
- buffer
.BeginReading());
84 MOZ_CRASH_UNSAFE(message
);
88 event
.minor_code
= strtol(
89 buffer
.BeginReading() + start
+ minorCodeString
.Length(), nullptr, 10);
91 MOZ_CRASH_UNSAFE(message
);
94 event
.display
= GDK_DISPLAY_XDISPLAY(gdk_display_get_default());
95 // Gdk does not provide resource ID
98 X11Error(event
.display
, &event
);
102 g_log_default_handler(log_domain
, log_level
, message
, user_data
);
103 MOZ_CRASH_UNSAFE(message
);
107 void InstallGdkErrorHandler() {
108 g_log_set_handler("Gdk",
109 (GLogLevelFlags
)(G_LOG_LEVEL_ERROR
| G_LOG_FLAG_FATAL
|
110 G_LOG_FLAG_RECURSION
),
111 GdkErrorHandler
, nullptr);
113 if (PR_GetEnv("MOZ_X_SYNC")) {
114 XSynchronize(GDK_DISPLAY_XDISPLAY(gdk_display_get_default()), X11True
);