Para o GTK 2, adicione a seguinte linha a ~/.gtkrc-2.0
:
gtk-auto-mnemonic = 0
Para o GTK 3 até o GTK 3.9:
do_dconf /org/gnome/desktop/interface/automatic-mnemonics false
No GTK 3.10, a opção foi removida (em este commit , cuja mensagem de log apenas informa que o recurso foi removido). Olhando para a fonte, não há como ativá-la. O comportamento maluco de mostrar os mnemônicos somente depois que Alt foi pressionado por pelo menos 300ms (o tempo limite é codificado como uma constante de tempo de compilação) é o único possível.
Eu me propus a substituir esse comportamento pelo pré-carregamento de um wrapper de biblioteca que força os mnemônicos a Seja visível. Não foi fácil, porque a maioria das chamadas é interna. Eu finalmente encontrei uma maneira de fazer a consulta que informa ao exibidor de rótulos se o widget deseja exibir mnemônicos sempre retornar true. Na maioria das vezes funciona, eu posso ver os mnemônicos o tempo todo nas caixas de diálogo do GEdit e do Evince, mas não completamente: alguns aceleradores de menu estão faltando, não sei por quê.
O código:
#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;
}
Como usar: escreva isso em um arquivo chamado gtk_window_get_mnemonics_visible.c
. Instale o GCC e o pacote de desenvolvimento do GTK3 (por exemplo, sudo apt-get install gcc libgtk-3-dev
no Debian / Ubuntu). Compile com
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
Execute aplicativos Gnome como este:
LD_PRELOAD=/path/to/gtk_window_get_mnemonics_visible.so gedit
ou coloque isso no seu .profile
:
export LD_PRELOAD=/path/to/gtk_window_get_mnemonics_visible.so
Observe que LD_PRELOAD
é um hack, pode causar um comportamento estranho às vezes. Eu só dei a este um teste superficial. Bug conhecido:
- Se
GTK_IM_MODULE
estiver definido comoxim
, usarLD_PRELOAD
para qualquer coisa (até mesmo um arquivo C vazio!) fará com que o GEdit seja interrompido quando eu pressionar Alt (observado no Debian jessie) . Eu não tenho ideia do porquê.