From eae9ff0ab058fd48b94dd181d8c6bd75d609b0ac Mon Sep 17 00:00:00 2001 From: Andy Holmes Date: Sun, 20 Aug 2023 15:16:46 -0700 Subject: [PATCH] libworkbench: implement GLogWriterFunc and library initialization Add `Workbench.init()` to initialize resources and other setup tasks. Currently, this only implements a `GLogWriterFunc` for silencing specific messages that Workbench users shouldn't see. This method has some limitations running on other threads in GJS, and should be more performant in C anyways. --- src/init.js | 4 + src/libworkbench/meson.build | 2 + src/libworkbench/workbench-global.c | 121 ++++++++++++++++++++++++++++ src/libworkbench/workbench-global.h | 18 +++++ src/libworkbench/workbench.h | 1 + src/log_handler.js | 119 --------------------------- src/main.js | 1 - 7 files changed, 146 insertions(+), 120 deletions(-) create mode 100644 src/libworkbench/workbench-global.c create mode 100644 src/libworkbench/workbench-global.h delete mode 100644 src/log_handler.js diff --git a/src/init.js b/src/init.js index d433c97e7..d5d5d175f 100644 --- a/src/init.js +++ b/src/init.js @@ -12,6 +12,10 @@ import Adw from "gi://Adw"; import Xdp from "gi://Xdp"; import Source from "gi://GtkSource"; import WebKit from "gi://WebKit"; +import Workbench from "gi://Workbench"; + + +Workbench.init(); Gio._promisify(Adw.MessageDialog.prototype, "choose", "choose_finish"); Gio._promisify(Xdp.Portal.prototype, "trash_file", "trash_file_finish"); diff --git a/src/libworkbench/meson.build b/src/libworkbench/meson.build index 2764b3de4..75db65d95 100644 --- a/src/libworkbench/meson.build +++ b/src/libworkbench/meson.build @@ -61,11 +61,13 @@ libworkbench_headers = files([ 'workbench.h', 'workbench-completion-provider.h', 'workbench-completion-request.h', + 'workbench-global.h', ]) libworkbench_sources = files([ 'workbench-completion-provider.c', 'workbench-completion-request.c', + 'workbench-global.c', ]) install_headers(libworkbench_headers, diff --git a/src/libworkbench/workbench-global.c b/src/libworkbench/workbench-global.c new file mode 100644 index 000000000..1942483d4 --- /dev/null +++ b/src/libworkbench/workbench-global.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: Workbench Contributors +// SPDX-FileContributor: Andy Holmes + +#include + +#include "workbench-global.h" + + +/* + * Silenced log messages + */ +struct +{ + const char *log_domain; + GLogLevelFlags log_level; + const char *message; +} ignored_messages[] = { + /* GDK4 */ + { + "Gdk", + G_LOG_LEVEL_CRITICAL, + "gdk_scroll_event_get_direction: assertion 'GDK_IS_EVENT_TYPE (event, GDK_SCROLL)' failed", + }, + { + "Gdk", + G_LOG_LEVEL_CRITICAL, + "gdk_scroll_event_get_direction: assertion 'GDK_IS_EVENT (event)' failed", + }, + + /* GTK4 */ + { + "Gtk", + G_LOG_LEVEL_CRITICAL, + "Unable to connect to the accessibility bus at 'unix:path=/run/flatpak/at-spi-bus': Could not connect: No such file or directory", + }, + + /* Adwaita */ + { + "Adwaita", + G_LOG_LEVEL_WARNING, + "Using GtkSettings:gtk-application-prefer-dark-theme with libadwaita is unsupported. Please use AdwStyleManager:color-scheme instead.", + }, + + /* GVFS */ + { + "GVFS", + G_LOG_LEVEL_WARNING, + "The peer-to-peer connection failed: Error when getting information for file “/run/user/1000/gvfsd”: No such file or directory. Falling back to the session bus. Your application is probably missing --filesystem=xdg-run/gvfsd privileges.", + }, +}; + +static inline gboolean +workbench_log_ignore (const char *log_domain, + GLogLevelFlags log_level, + const char *message) +{ + if G_UNLIKELY (log_domain == NULL || message == NULL) + return FALSE; + + for (unsigned int i = 0; i < G_N_ELEMENTS (ignored_messages); i++) + { + if (ignored_messages[i].log_level == log_level && + g_str_equal (ignored_messages[i].log_domain, log_domain) && + g_str_equal (ignored_messages[i].message, message)) + return TRUE; + } + + return FALSE; +} + +static GLogWriterOutput +workbench_log_writer (GLogLevelFlags log_level, + const GLogField *fields, + gsize n_fields, + gpointer user_data) +{ + const char *log_domain = NULL; + const char *message = NULL; + + /* Respect default handling of log levels and domains */ + if (g_log_writer_default_would_drop (log_level, log_domain)) + return G_LOG_WRITER_HANDLED; + + /* Silence specific messages */ + for (gsize i = 0; i < n_fields; i++) + { + GLogField field = fields[i]; + + if (g_str_equal (field.key, "GLIB_DOMAIN")) + log_domain = field.value; + else if (g_str_equal (field.key, "MESSAGE")) + message = field.value; + + if (log_domain != NULL && message != NULL) + break; + } + + if (workbench_log_ignore (log_domain, log_level, message)) + return G_LOG_WRITER_HANDLED; + + return g_log_writer_standard_streams (log_level, fields, n_fields, user_data); +} + + +/** + * workbench_init: + * + * Initialize the internal library for Workbench. + */ +void +workbench_init (void) +{ + gsize initialized = 0; + + if (g_once_init_enter (&initialized)) + { + g_log_set_writer_func (workbench_log_writer, NULL, NULL); + g_once_init_leave (&initialized, TRUE); + } +} diff --git a/src/libworkbench/workbench-global.h b/src/libworkbench/workbench-global.h new file mode 100644 index 000000000..f51e7905d --- /dev/null +++ b/src/libworkbench/workbench-global.h @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0-only +// SPDX-FileCopyrightText: Workbench Contributors +// SPDX-FileContributor: Andy Holmes + +#pragma once + +#if !defined (WORKBENCH_INSIDE) && !defined (WORKBENCH_COMPILATION) +# error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +WORKBENCH_EXPORT +void workbench_init (void); + +G_END_DECLS diff --git a/src/libworkbench/workbench.h b/src/libworkbench/workbench.h index f0257ecfb..e6e001f98 100644 --- a/src/libworkbench/workbench.h +++ b/src/libworkbench/workbench.h @@ -10,6 +10,7 @@ #include "workbench-completion-provider.h" #include "workbench-completion-request.h" +#include "workbench-global.h" #undef WORKBENCH_INSIDE diff --git a/src/log_handler.js b/src/log_handler.js deleted file mode 100644 index 8b350c8ca..000000000 --- a/src/log_handler.js +++ /dev/null @@ -1,119 +0,0 @@ -import GLib from "gi://GLib"; - -// Does not wok for some reason -// const all_log_levels = -// GLib.LogLevelFlags.LEVEL_MASK & -// GLib.LogLevelFlags.FLAG_FATAL & -// GLib.LogLevelFlags.FLAG_RECURSION; - -const all_log_levels = - GLib.LogLevelFlags.FLAG_FATAL | - GLib.LogLevelFlags.FLAG_RECURSION | - GLib.LogLevelFlags.LEVEL_CRITICAL | - GLib.LogLevelFlags.LEVEL_DEBUG | - GLib.LogLevelFlags.LEVEL_ERROR | - GLib.LogLevelFlags.LEVEL_INFO | - // GLib.LogLevelFlags.LEVEL_MASK | - GLib.LogLevelFlags.LEVEL_MESSAGE | - GLib.LogLevelFlags.LEVEL_WARNING; - -/* Cannot use GLib.log_set_writer_func because it is not safe to use https://gitlab.gnome.org/GNOME/gjs/-/issues/481 */ -// const decoder = new TextDecoder(); -// GLib.log_set_writer_func((level, fields) => { -// const domain = decoder.decode(fields.GLIB_DOMAIN); -// const message = decoder.decode(fields.MESSAGE); -// log_handler(domain, level, message); -// return GLib.LogWriterOutput.HANDLED; -// }); - -// Not working - Gjs-Console uses structured logging -// GLib.log_set_handler("Gjs-Console", all_log_levels, log_handler); -GLib.log_set_handler("Gdk", all_log_levels, log_handler); -GLib.log_set_handler("Adwaita", all_log_levels, log_handler); -GLib.log_set_handler("GVFS", all_log_levels, log_handler); -GLib.log_set_handler("Workbench", all_log_levels, log_handler); -// Not working - Gtk is probably using structured logging -// GLib.log_set_handler("Gtk", all_log_levels, log_handler); - -// https://docs.gtk.org/glib/flags.LogLevelFlags.html -// https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 -function get_log_level_name(log_level, domain) { - switch (log_level) { - case GLib.LogLevelFlags.FLAG_RECURSION: - return "\x1b[1;31mRecursion\x1b[0m"; - case GLib.LogLevelFlags.FLAG_FATAL: - return "\x1b[1;31mFatal\x1b[0m"; - case GLib.LogLevelFlags.LEVEL_CRITICAL: - // This is what console.error use - return domain === "Gjs-Console" - ? "\x1b[1;31mError\x1b[0m" - : "\x1b[1;35mCritical\x1b[0m"; - case GLib.LogLevelFlags.LEVEL_ERROR: - return "\x1b[1;31mError\x1b[0m"; - case GLib.LogLevelFlags.LEVEL_WARNING: - return "\x1b[1;33mWarning\x1b[0m"; - // case GLib.LogLevelFlags.LEVEL_MESSAGE: - // case GLib.LogLevelFlags.LEVEL_INFO: - // case GLib.LogLevelFlags.LEVEL_DEBUG: - default: - return ""; - } -} - -function log_handler(domain, level, message) { - // if (level === GLib.LogLevelFlags.LEVEL_DEBUG) { - // return GLib.LogWriterOutput.HANDLED; - // } - - if ( - domain === "Gdk" && - level === GLib.LogLevelFlags.LEVEL_CRITICAL && - [ - "gdk_scroll_event_get_direction: assertion 'GDK_IS_EVENT_TYPE (event, GDK_SCROLL)' failed", - "gdk_scroll_event_get_direction: assertion 'GDK_IS_EVENT (event)' failed", - ].includes(message) - ) { - return GLib.LogWriterOutput.HANDLED; - } - - if ( - domain === "Gtk" && - level === GLib.LogLevelFlags.LEVEL_CRITICAL && - message === - "Unable to connect to the accessibility bus at 'unix:path=/run/flatpak/at-spi-bus': Could not connect: No such file or directory" - ) { - return GLib.LogWriterOutput.HANDLED; - } - - if ( - domain === "Adwaita" && - level === GLib.LogLevelFlags.LEVEL_WARNING && - message === - "Using GtkSettings:gtk-application-prefer-dark-theme with libadwaita is unsupported. Please use AdwStyleManager:color-scheme instead." - ) { - return GLib.LogWriterOutput.HANDLED; - } - - if ( - domain === "GVFS" && - level === GLib.LogLevelFlags.LEVEL_WARNING && - message === - "The peer-to-peer connection failed: Error when getting information for file “/run/user/1000/gvfsd”: No such file or directory. Falling back to the session bus. Your application is probably missing --filesystem=xdg-run/gvfsd privileges." - ) { - return GLib.LogWriterOutput.HANDLED; - } - - let str = "\n"; - - if (!["Gjs", "Gjs-Console"].includes(domain)) { - str += `${domain}-`; - } - - const level_name = get_log_level_name(level, domain); - str += level_name ? `${level_name}: ` : ""; - str += message; - str += "\n"; - - // console.terminal.fork_command(`echo ${str}`); - print(str); -} diff --git a/src/main.js b/src/main.js index 53bd97214..040ef5839 100644 --- a/src/main.js +++ b/src/main.js @@ -1,5 +1,4 @@ import "./init.js"; -import "./log_handler.js"; import application from "./application.js"; pkg.initGettext();