GTK 对可加载模块的支持可以追溯到很久以前,这就是为什么 GTK 有很多代码来处理 GTypeModules 以及搜索路径等。 很久之后,Alex 为 GVfs 重新审视了这个主题,并提出了扩展点和实现它们的 GIO 模块的概念。这是一个好得多的框架,而 GTK 4 是我们切换到使用它的绝佳机会。
GTK+ 4 中的更改
因此,我最近花了一些时间在 GTK 中的模块支持上。这里的主要变化如下:
- 我们不再支持通用的可加载模块。 少数仍然使用此功能的程序之一是 libcanberra,我们将考虑直接在 GTK+ 中实现“事件声音”功能,而不是依赖于模块来实现它。 如果您依赖于加载 GTK+ 模块,请来和我们讨论其他实现您正在执行的操作的方法。
- 打印后端现在使用名为“gtk-print-backend”的扩展点定义,该扩展点需要 GtkPrintBackend 类型。现有的打印后端已转换为实现此扩展点的 GIO 模块。 由于我们从未支持过树外的打印后端,因此这不应影响其他任何人。
- 输入法也使用扩展点定义,名为“gtk-im-module”,该扩展点需要 GtkIMContext 类型。我们已删除所有非平台 IM 模块,并将平台 IM 模块移到 GTK+ 本身,同时还实现了扩展点。
调整现有的输入法
由于我们仍然支持树外的 IM 模块,我想使用本文的其余部分来简要概述一下 GTK+ 4 的树外 IM 模块必须如何实现。
要将传统的基于 GTypeModule 的 IM 模块转换为新的扩展点,需要几个步骤。 下面的示例代码取自 Broadway 输入法。
使用 G_DEFINE_DYNAMIC_TYPE
我们将从模块加载一个类型,而 G_DEFINE_DYNAMIC_TYPE 是定义此类类型的正确方法
G_DEFINE_DYNAMIC_TYPE (GtkIMContextBroadway, gtk_im_context_broadway, GTK_TYPE_IM_CONTEXT)
请注意,此宏定义了一个 gtk_im_context_broadway_register_type() 函数,我们将在下一步中使用该函数。
请注意,除了更常见的 class_init 之外,动态类型还需要有一个 class_finalize 函数,该函数可以很简单
static void gtk_im_context_broadway_class_finalize (GtkIMContextBroadwayClass *class) { }
实现 GIO 模块 API
为了可以作为 GIOModule 使用,模块必须实现三个函数:g_io_module_load()、g_io_module_unload() 和 g_io_module_query()(严格来说,最后一个是可选的,但我们无论如何都会在此处实现它)。
void g_io_module_load (GIOModule *module) { g_type_module_use (G_TYPE_MODULE (module)); gtk_im_context_broadway_register_type (G_TYPE_MODULE (module)); g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME, GTK_TYPE_IM_CONTEXT_BROADWAY, "broadway", 10); }
void g_io_module_unload (GIOModule *module) { }
char ** g_io_module_query (void) { char *eps[] = { GTK_IM_MODULE_EXTENSION_POINT_NAME, NULL }; return g_strdupv (eps); }
正确安装模块
GTK+ 仍会在 $LIBDIR/gtk-4.0/immodules/ 中查找要加载的输入法,但是 GIO 仅查找名称以 “lib” 开头的共享对象,因此请确保您遵循该约定。
调试
就是这样!
现在,GTK+ 4 应该会加载您的输入法,如果您使用 GTK_DEBUG=modules 运行 GTK+ 4 应用程序,您应该会在调试输出中看到您的模块。
为了确保,我理解是否正确,此更改会影响输入法框架(即 ibus 或 fcitx 之类的东西),而不是输入法引擎?(例如 ibus-cangjie 或 fcitx-libpinyin 之类的东西)
它影响 GTK+ 加载输入法模块的方式。如果您将某些东西安装到 /usr/lib/gtk-3.0/immodules/ 中,那么当涉及到 /usr/lib/gtk-4.0/immodules/ 时,您需要进行更改