为 Gnome 中的按钮启用“Alt”热键?

为 Gnome 中的按钮启用“Alt”热键?

我的意思是:每当按钮文本中的字母带有下划线时,按Alt加该字母即可单击该按钮。我已经浏览了KeyboardTweak Tool小程序但没有成功。

按确实Alt会在字母下划线,但我更喜欢事先给它们加上下划线。

答案1

对于 GTK 2,将以下行添加到~/.gtkrc-2.0

gtk-auto-mnemonic = 0

对于 GTK 3 至 GTK 3.9:

do_dconf /org/gnome/desktop/interface/automatic-mnemonics false

在 GTK 3.10 中,该选项被删除(在这次提交,其日志消息仅表明该功能已被删除)。查看源码,没有办法打开它。仅Alt在按下至少 300 毫秒(超时被硬编码为编译时常量)后才显示助记符的疯狂行为是唯一可能的行为。

我打算通过以下方式覆盖这种行为预加载强制助记符可见的库包装。这并不容易,因为大多数电话都是内部的。我终于找到了一种方法,使告诉标签显示器小部件是否要显示助记符的查询始终返回 true。它大部分工作正常,我一直可以在 GEdit 和 Evince 的对话框中看到助记符,但不完全:一些菜单加速器丢失了,我不知道为什么。

代码:

#define _GNU_SOURCE
#include <dlfcn.h>
#include <stdio.h>
#include <glib.h>
#include <gtk/gtk.h>

#define PROP_MNEMONICS_VISIBLE 31

#ifdef DEBUG
#define DBG(args...) printf(args)
#else
#define DBG(args...)
#endif

static void (*original_gtk_window_get_property)(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
static void wrap_gtk_window_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
    original_gtk_window_get_property(object, prop_id, value, pspec);
    if (prop_id == PROP_MNEMONICS_VISIBLE) {
        DBG("%s(%p, %u, &%u, %p)\n", __FUNCTION__, object, prop_id, *(unsigned*)value, pspec);
        g_value_set_boolean(value, TRUE);
    }
}

inline void override_gtk_window_get_property(GType object_type, GObject *obj)
{
    static int first_window_creation = 1;
    if (object_type == GTK_TYPE_WINDOW && first_window_creation) {
        first_window_creation = 0;
        GtkWidgetClass *gtk_widget_class = GTK_WIDGET_GET_CLASS(obj);
        GObjectClass *gobject_class = G_OBJECT_CLASS(gtk_widget_class);
        original_gtk_window_get_property = gobject_class->get_property;
        gobject_class->get_property = wrap_gtk_window_get_property;
    }
}

GObject* g_object_new_valist(GType object_type, const gchar *first_property_name, va_list var_args)
{
    static GObject* (*original_g_object_new_valist)(GType object_type, const gchar *first_property_name, va_list var_args) = NULL;
    if (original_g_object_new_valist == NULL) {
        original_g_object_new_valist = dlsym(RTLD_NEXT, "g_object_new_valist");
    }
    GObject* obj = original_g_object_new_valist(object_type, first_property_name, var_args);
    override_gtk_window_get_property(object_type, obj);
    return obj;
}
gpointer g_object_new(GType object_type, const gchar *first_property_name, ...)
{
    va_list var_args;
    va_start(var_args, first_property_name);
    gpointer obj = g_object_new_valist(object_type, first_property_name, var_args);
    va_end(var_args);
    return obj;
}
gpointer g_object_newv(GType object_type, guint n_parameters, GParameter *parameters)
{
    static gpointer (*original_g_object_newv)(GType object_type, guint n_parameters, GParameter *parameters);
    if (original_g_object_newv == NULL) {
        original_g_object_newv = dlsym(RTLD_NEXT, "g_object_newv");
    }
    GObject* obj = original_g_object_newv(object_type, n_parameters, parameters);
    override_gtk_window_get_property(object_type, obj);
    return obj;
}

如何使用它:将其写入一个名为gtk_window_get_mnemonics_visible.c.安装GCC 和GTK3 开发包(例如sudo apt-get install gcc libgtk-3-dev在Debian/Ubuntu 上)。编译用

gcc -Wall -fPIC -shared `pkg-config --cflags gtk+-3.0` `pkg-config --libs gtk+-3.0` -o gtk_window_get_mnemonics_visible.so gtk_window_get_mnemonics_visible.c

像这样运行 Gnome 应用程序:

LD_PRELOAD=/path/to/gtk_window_get_mnemonics_visible.so gedit

或将其放入您的.profile

export LD_PRELOAD=/path/to/gtk_window_get_mnemonics_visible.so

请注意,这LD_PRELOAD是一个黑客行为,有时可能会导致奇怪的行为。我只对此进行了粗略的测试。已知错误:

  • 如果GTK_IM_MODULE设置为xim,那么使用LD_PRELOAD任何东西(甚至是空的 C 文件!)都会导致 GEdit 在我按下时挂起Alt(在 Debian jessie 上观察到)。我不知道为什么。

相关内容