GTK3 功能键;哪些被消耗了(并且无法从我的 GTK 应用程序中使用)?
GTK3 function keys; which are consumed (and unusable from my GTK app)?
FWIW,引发这个问题的确切程序是(在 Linux/Debian/Sid/x86-64)我的 bismon on github, commit d43a75fb9f8e13。 GTK3 是 3.22.24。如果您需要尝试,请使用 make
和 运行 ./bismon
构建它。它处于 alpha 阶段,除了我之外,其他人仍然没有兴趣。它是某种具有 GTK 接口和持久堆的 DSL 解释器。
如果您想要显示某些内容,请单击以关注中间的小部件,键入 the_system
然后按 Ctrl Return ,但这与这个问题无关。
我成功了,with commandview_BM
(它是中间的小部件)是一个 GtkTextView
小部件
g_signal_connect (commandview_BM, "key-press-event",
G_CALLBACK (handlekeypresscmd_BM), NULL);
处理一些键盘事件(FWIW,我的物理键盘是 AZERTY 布局罗技 G610)
我想在我的程序中处理功能键。但是一些功能键(例如F7、F8、F9、F10 ...) 是 "preempted" 由桌面或环境和不到达我的程序。达到其他人,例如F6 从那个 handlekeypresscmd_BM
函数得到我的 debugging 输出:
gui_BM.c:3135: handlekeypresscmd_BM keyval 0xffc3 KEY_F6
这让我很高兴(因为以后我可以编写一些有用的代码)。相关代码如下:
gboolean
handlekeypresscmd_BM (GtkWidget * widg, GdkEventKey * evk, gpointer data)
{
assert (GTK_IS_TEXT_VIEW (widg));
assert (evk != NULL);
assert (data == NULL);
if (evk->keyval == GDK_KEY_Return) { /* do something unrelated */
return true; }
else if (evk->keyval == GDK_KEY_Tab)
{
tabautocompletecmd_BM ();
return true;
}
else if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F10)
{
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
bool withctrl = (evk->state & modmask) == GDK_CONTROL_MASK;
bool withshift = (evk->state & modmask) == GDK_SHIFT_MASK;
DBGPRINTF_BM ("handlekeypresscmd_BM keyval %#x KEY_F%d %s%s",
evk->keyval, evk->keyval - (GDK_KEY_F1 - 1),
withctrl ? " ctrl" : "", withshift ? " shift" : "");
return false;
};
return false; // propagate the event
} /* end handlekeypresscmd_BM */
显然 DBGPRINTF_BM
(一些调试打印宏)应该达到 F7 而不仅仅是 F6 但它不是(我不明白为什么)。当然我检查过我系统的 /usr/include/gtk-3.0/gdk/gdkkeysyms.h
包含
#define GDK_KEY_F5 0xffc2
#define GDK_KEY_F6 0xffc3
#define GDK_KEY_F7 0xffc4
#define GDK_KEY_F8 0xffc5
#define GDK_KEY_F9 0xffc6
我使用 Gnome、XFCE4 或 LXDE 作为我的桌面环境。据我所知,我没有专门针对功能键配置这些。
是否可以访问并记录预定义功能键列表(那些已经被其他东西使用,也许 window 管理器)?在哪里?我是否应该查看 EWMH、ICCCCM、Gnome 人机界面,深入研究每个 window 经理的文档?
更重要的是,有没有一种方法可以从 GTK3 应用程序以编程方式查询某些小部件将达到哪些功能键(像 GtkTextView
)? 我想不出任何...
否则,我可以合理地期望从 Linux 上的 Gtk3 应用程序(使用 X11,也许稍后使用 Wayland)上使用的一小组功能键是什么?
FWIW, xev
看到从 F1 到 F12
的所有功能键
附录
为了部分回答我的问题,gtk/gtktextview.c
(来自 GTK3 的源代码)大约在第 1630 行:
/* Caret mode */
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F7, 0,
"toggle-cursor-visible", 0);
(顺便说一句,有什么方法可以禁用它吗?)
但这并不能解释 F8 的行为,也不要告诉我如何查询可以使用哪些功能键。
我的文本视图在一些 GtkPaned
里面,在 gtk/gtkpaned.c
第 635 行
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_F8, 0,
"cycle-handle-focus", 1,
G_TYPE_BOOLEAN, FALSE);
所以也许我应该尝试找出如何查询此类绑定键。仍然没有想法。应该调查 GtkBindingSet.
正在尝试分解您的问题以便更容易回答。
首先,我建议阅读 The GTK+ Input and Event Handling Model 并注意“GTK+ 从 windowing 系统 接收事件”。
I'm using either Gnome, or XFCE4, or LXDE as my desktop environments.
AFAIK I did not configure these specially regarding function keys.
嗯,你没有,但 "distributions"/window 经理有。
例如,检查 GNOME Shell Keyboard shortcuts
大多数 window 经理使用 ALT+Fn 键,ALT+F4 最出名的是关闭 window. CTRL键更适合用户"shortcuts/accelerators".
More importantly, is there a way, from a GTK3 application, to
programmatically query which function keys will be reached by some
widget (like a GtkTextView) ? I can't think of any...
不,没有。事件是 emitted/triggered 和小部件,如果被编程为这样做,相应地接收和处理它们,然后通过检查事件,就像您对 key-press-event
处理程序所做的那样,您可以触发 "actions"。好吧,理论上,您可以在自己的小部件中开发一组已处理键的设置器和获取器,但老实说,您看不到这样做的意义。
Or else, what is the small set of function keys that I reasonably can
expect to use from a Gtk3 application on Linux (with X11, and perhaps
later with Wayland)?
我会选择 CTRL+Fn、SHIFT+Fn 和正常的 F1 F12 保留 ALT+Fn 为窗口系统保留。
现在查看 Github 上的具体示例,您的处理程序已经忽略了 F11 和 F12 由于条件:
...
... if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F10)
...
将您的代码与控制台的初始打印相匹配:
gboolean
handlekeypresscmd_BM (GtkWidget * widg, GdkEventKey * evk, gpointer data)
{
assert (GTK_IS_TEXT_VIEW (widg));
assert (evk != NULL);
assert (data == NULL);
if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F12) {
g_print ("handlekeypresscmd_BM KEY_F%d\n", evk->keyval - (GDK_KEY_F1 - 1));
}
// see <gdk/gdkkeysyms.h> for names of keysyms
if (evk->keyval == GDK_KEY_Return)
{
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
bool withctrl = (evk->state & modmask) == GDK_CONTROL_MASK;
bool withshift = (evk->state & modmask) == GDK_SHIFT_MASK;
if (withctrl)
run_then_erase_command_BM ();
else if (withshift)
run_then_keep_command_BM ();
else // plain RETURN key, propagate it
return false;
return true;
}
else if (evk->keyval == GDK_KEY_Tab)
{
tabautocompletecmd_BM ();
return true;
}
else if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F10)
{
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
bool withctrl = (evk->state & modmask) == GDK_CONTROL_MASK;
bool withshift = (evk->state & modmask) == GDK_SHIFT_MASK;
DBGPRINTF_BM ("handlekeypresscmd_BM keyval %#x KEY_F%d %s%s",
evk->keyval, evk->keyval - (GDK_KEY_F1 - 1),
withctrl ? " ctrl" : "", withshift ? " shift" : "");
return false;
}
return false; // propagate the event
}
在 运行 您的应用程序 bismon
之后,将焦点放在 GtkTreeView 上并按下几个 Fn 键和 CTRL+Fn 键,结果为:
handlekeypresscmd_BM KEY_F1
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbe KEY_F1
handlekeypresscmd_BM KEY_F2
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbf KEY_F2
handlekeypresscmd_BM KEY_F3
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc0 KEY_F3
handlekeypresscmd_BM KEY_F4
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc1 KEY_F4
handlekeypresscmd_BM KEY_F5
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc2 KEY_F5
handlekeypresscmd_BM KEY_F6
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc3 KEY_F6
handlekeypresscmd_BM KEY_F7
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc4 KEY_F7
handlekeypresscmd_BM KEY_F8
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc5 KEY_F8
handlekeypresscmd_BM KEY_F9
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc6 KEY_F9
handlekeypresscmd_BM KEY_F11
handlekeypresscmd_BM KEY_F12
handlekeypresscmd_BM KEY_F1
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbe KEY_F1 ctrl
handlekeypresscmd_BM KEY_F2
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbf KEY_F2 ctrl
handlekeypresscmd_BM KEY_F3
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc0 KEY_F3 ctrl
handlekeypresscmd_BM KEY_F4
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc1 KEY_F4 ctrl
handlekeypresscmd_BM KEY_F5
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc2 KEY_F5 ctrl
handlekeypresscmd_BM KEY_F6
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc3 KEY_F6 ctrl
handlekeypresscmd_BM KEY_F7
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc4 KEY_F7 ctrl
handlekeypresscmd_BM KEY_F8
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc5 KEY_F8 ctrl
handlekeypresscmd_BM KEY_F9
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc6 KEY_F9 ctrl
handlekeypresscmd_BM KEY_F10
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc7 KEY_F10 ctrl
handlekeypresscmd_BM KEY_F11
handlekeypresscmd_BM KEY_F12
如您所见,F10 没有显示,那是因为当使用 GtkMenus 时,F10 被保留来触发它们(注意在 GNOME 3 上,F10 被提议用于齿轮菜单虽然没有像 GtkMenuShell 那样硬编码)。
SHIFT+F10 也用作上下文菜单键盘快捷键。
我还注意到在您的应用程序中 F6 和 SHIFT+F6 会将焦点移动到 GtkTreeView 下面的小部件,而不是确定您是否自己编写了此代码,但在您的代码中找不到对它的任何引用(下面的另一个示例中有更多内容)。 F8 也做了类似的事情,但如果在每次按键后你强制将焦点放在 GtkTreeView 上(用鼠标左键单击它),那么你将获得所有按键。 CTRL+Fn 适用于所有键(您有自己的解决方案)。
作为最后一个示例,使用来自 zetcode 的简单、改编的 Treeview 示例,您可以验证所有功能键,使用 ALT 和 [=60 的功能键除外=]SHIFT+F10(上下文菜单),工作:
#include <gtk/gtk.h>
gboolean
keyHandler (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data) {
if (event->keyval >= GDK_KEY_F1 && event->keyval <= GDK_KEY_F12) {
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
gboolean ctrl = (event->state & modmask) == GDK_CONTROL_MASK;
gboolean shift = (event->state & modmask) == GDK_SHIFT_MASK;
g_print ("HANDLED %s%sKEY_F%d\n", ctrl ? "CTRL+" : "", shift ? "SHIFT+" : "", event->keyval - (GDK_KEY_F1 - 1));
}
return FALSE;
}
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *view;
GtkWidget *vbox;
GtkTextBuffer *buffer;
GtkTextIter start, end;
GtkTextIter iter;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_title(GTK_WINDOW(window), "GtkTextView");
vbox = gtk_vbox_new(FALSE, 0);
view = gtk_text_view_new();
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0);
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
gtk_text_buffer_create_tag(buffer, "gap",
"pixels_above_lines", 30, NULL);
gtk_text_buffer_create_tag(buffer, "lmarg",
"left_margin", 5, NULL);
gtk_text_buffer_create_tag(buffer, "blue_fg",
"foreground", "blue", NULL);
gtk_text_buffer_create_tag(buffer, "gray_bg",
"background", "gray", NULL);
gtk_text_buffer_create_tag(buffer, "italic",
"style", PANGO_STYLE_ITALIC, NULL);
gtk_text_buffer_create_tag(buffer, "bold",
"weight", PANGO_WEIGHT_BOLD, NULL);
gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
gtk_text_buffer_insert(buffer, &iter, "Plain text\n", -1);
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
"Colored Text\n", -1, "blue_fg", "lmarg", NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Text with colored background\n", -1, "lmarg", "gray_bg", NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Text in italics\n", -1, "italic", "lmarg", NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Bold text\n", -1, "bold", "lmarg", NULL);
gtk_container_add(GTK_CONTAINER(window), vbox);
g_signal_connect(G_OBJECT(view), "key-press-event", G_CALLBACK(keyHandler), NULL);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
结果是(显示上下文菜单!):
另请注意,应用程序 没有菜单 ,因此 F10 处理没有问题。
编辑:在快捷方式
上检查这个Wikipedia entry
FWIW,引发这个问题的确切程序是(在 Linux/Debian/Sid/x86-64)我的 bismon on github, commit d43a75fb9f8e13。 GTK3 是 3.22.24。如果您需要尝试,请使用 make
和 运行 ./bismon
构建它。它处于 alpha 阶段,除了我之外,其他人仍然没有兴趣。它是某种具有 GTK 接口和持久堆的 DSL 解释器。
如果您想要显示某些内容,请单击以关注中间的小部件,键入 the_system
然后按 Ctrl Return ,但这与这个问题无关。
我成功了,with commandview_BM
(它是中间的小部件)是一个 GtkTextView
小部件
g_signal_connect (commandview_BM, "key-press-event",
G_CALLBACK (handlekeypresscmd_BM), NULL);
处理一些键盘事件(FWIW,我的物理键盘是 AZERTY 布局罗技 G610)
我想在我的程序中处理功能键。但是一些功能键(例如F7、F8、F9、F10 ...) 是 "preempted" 由桌面或环境和不到达我的程序。达到其他人,例如F6 从那个 handlekeypresscmd_BM
函数得到我的 debugging 输出:
gui_BM.c:3135: handlekeypresscmd_BM keyval 0xffc3 KEY_F6
这让我很高兴(因为以后我可以编写一些有用的代码)。相关代码如下:
gboolean
handlekeypresscmd_BM (GtkWidget * widg, GdkEventKey * evk, gpointer data)
{
assert (GTK_IS_TEXT_VIEW (widg));
assert (evk != NULL);
assert (data == NULL);
if (evk->keyval == GDK_KEY_Return) { /* do something unrelated */
return true; }
else if (evk->keyval == GDK_KEY_Tab)
{
tabautocompletecmd_BM ();
return true;
}
else if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F10)
{
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
bool withctrl = (evk->state & modmask) == GDK_CONTROL_MASK;
bool withshift = (evk->state & modmask) == GDK_SHIFT_MASK;
DBGPRINTF_BM ("handlekeypresscmd_BM keyval %#x KEY_F%d %s%s",
evk->keyval, evk->keyval - (GDK_KEY_F1 - 1),
withctrl ? " ctrl" : "", withshift ? " shift" : "");
return false;
};
return false; // propagate the event
} /* end handlekeypresscmd_BM */
显然 DBGPRINTF_BM
(一些调试打印宏)应该达到 F7 而不仅仅是 F6 但它不是(我不明白为什么)。当然我检查过我系统的 /usr/include/gtk-3.0/gdk/gdkkeysyms.h
包含
#define GDK_KEY_F5 0xffc2
#define GDK_KEY_F6 0xffc3
#define GDK_KEY_F7 0xffc4
#define GDK_KEY_F8 0xffc5
#define GDK_KEY_F9 0xffc6
我使用 Gnome、XFCE4 或 LXDE 作为我的桌面环境。据我所知,我没有专门针对功能键配置这些。
是否可以访问并记录预定义功能键列表(那些已经被其他东西使用,也许 window 管理器)?在哪里?我是否应该查看 EWMH、ICCCCM、Gnome 人机界面,深入研究每个 window 经理的文档?
更重要的是,有没有一种方法可以从 GTK3 应用程序以编程方式查询某些小部件将达到哪些功能键(像 GtkTextView
)? 我想不出任何...
否则,我可以合理地期望从 Linux 上的 Gtk3 应用程序(使用 X11,也许稍后使用 Wayland)上使用的一小组功能键是什么?
FWIW, xev
看到从 F1 到 F12
附录
为了部分回答我的问题,gtk/gtktextview.c
(来自 GTK3 的源代码)大约在第 1630 行:
/* Caret mode */
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F7, 0,
"toggle-cursor-visible", 0);
(顺便说一句,有什么方法可以禁用它吗?)
但这并不能解释 F8 的行为,也不要告诉我如何查询可以使用哪些功能键。
我的文本视图在一些 GtkPaned
里面,在 gtk/gtkpaned.c
第 635 行
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_F8, 0,
"cycle-handle-focus", 1,
G_TYPE_BOOLEAN, FALSE);
所以也许我应该尝试找出如何查询此类绑定键。仍然没有想法。应该调查 GtkBindingSet.
正在尝试分解您的问题以便更容易回答。
首先,我建议阅读 The GTK+ Input and Event Handling Model 并注意“GTK+ 从 windowing 系统 接收事件”。
I'm using either Gnome, or XFCE4, or LXDE as my desktop environments. AFAIK I did not configure these specially regarding function keys.
嗯,你没有,但 "distributions"/window 经理有。
例如,检查 GNOME Shell Keyboard shortcuts
大多数 window 经理使用 ALT+Fn 键,ALT+F4 最出名的是关闭 window. CTRL键更适合用户"shortcuts/accelerators".
More importantly, is there a way, from a GTK3 application, to programmatically query which function keys will be reached by some widget (like a GtkTextView) ? I can't think of any...
不,没有。事件是 emitted/triggered 和小部件,如果被编程为这样做,相应地接收和处理它们,然后通过检查事件,就像您对 key-press-event
处理程序所做的那样,您可以触发 "actions"。好吧,理论上,您可以在自己的小部件中开发一组已处理键的设置器和获取器,但老实说,您看不到这样做的意义。
Or else, what is the small set of function keys that I reasonably can expect to use from a Gtk3 application on Linux (with X11, and perhaps later with Wayland)?
我会选择 CTRL+Fn、SHIFT+Fn 和正常的 F1 F12 保留 ALT+Fn 为窗口系统保留。
现在查看 Github 上的具体示例,您的处理程序已经忽略了 F11 和 F12 由于条件:
...
... if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F10)
...
将您的代码与控制台的初始打印相匹配:
gboolean
handlekeypresscmd_BM (GtkWidget * widg, GdkEventKey * evk, gpointer data)
{
assert (GTK_IS_TEXT_VIEW (widg));
assert (evk != NULL);
assert (data == NULL);
if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F12) {
g_print ("handlekeypresscmd_BM KEY_F%d\n", evk->keyval - (GDK_KEY_F1 - 1));
}
// see <gdk/gdkkeysyms.h> for names of keysyms
if (evk->keyval == GDK_KEY_Return)
{
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
bool withctrl = (evk->state & modmask) == GDK_CONTROL_MASK;
bool withshift = (evk->state & modmask) == GDK_SHIFT_MASK;
if (withctrl)
run_then_erase_command_BM ();
else if (withshift)
run_then_keep_command_BM ();
else // plain RETURN key, propagate it
return false;
return true;
}
else if (evk->keyval == GDK_KEY_Tab)
{
tabautocompletecmd_BM ();
return true;
}
else if (evk->keyval >= GDK_KEY_F1 && evk->keyval <= GDK_KEY_F10)
{
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
bool withctrl = (evk->state & modmask) == GDK_CONTROL_MASK;
bool withshift = (evk->state & modmask) == GDK_SHIFT_MASK;
DBGPRINTF_BM ("handlekeypresscmd_BM keyval %#x KEY_F%d %s%s",
evk->keyval, evk->keyval - (GDK_KEY_F1 - 1),
withctrl ? " ctrl" : "", withshift ? " shift" : "");
return false;
}
return false; // propagate the event
}
在 运行 您的应用程序 bismon
之后,将焦点放在 GtkTreeView 上并按下几个 Fn 键和 CTRL+Fn 键,结果为:
handlekeypresscmd_BM KEY_F1
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbe KEY_F1
handlekeypresscmd_BM KEY_F2
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbf KEY_F2
handlekeypresscmd_BM KEY_F3
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc0 KEY_F3
handlekeypresscmd_BM KEY_F4
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc1 KEY_F4
handlekeypresscmd_BM KEY_F5
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc2 KEY_F5
handlekeypresscmd_BM KEY_F6
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc3 KEY_F6
handlekeypresscmd_BM KEY_F7
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc4 KEY_F7
handlekeypresscmd_BM KEY_F8
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc5 KEY_F8
handlekeypresscmd_BM KEY_F9
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc6 KEY_F9
handlekeypresscmd_BM KEY_F11
handlekeypresscmd_BM KEY_F12
handlekeypresscmd_BM KEY_F1
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbe KEY_F1 ctrl
handlekeypresscmd_BM KEY_F2
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffbf KEY_F2 ctrl
handlekeypresscmd_BM KEY_F3
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc0 KEY_F3 ctrl
handlekeypresscmd_BM KEY_F4
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc1 KEY_F4 ctrl
handlekeypresscmd_BM KEY_F5
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc2 KEY_F5 ctrl
handlekeypresscmd_BM KEY_F6
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc3 KEY_F6 ctrl
handlekeypresscmd_BM KEY_F7
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc4 KEY_F7 ctrl
handlekeypresscmd_BM KEY_F8
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc5 KEY_F8 ctrl
handlekeypresscmd_BM KEY_F9
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc6 KEY_F9 ctrl
handlekeypresscmd_BM KEY_F10
gui_BM.c:3138: handlekeypresscmd_BM keyval 0xffc7 KEY_F10 ctrl
handlekeypresscmd_BM KEY_F11
handlekeypresscmd_BM KEY_F12
如您所见,F10 没有显示,那是因为当使用 GtkMenus 时,F10 被保留来触发它们(注意在 GNOME 3 上,F10 被提议用于齿轮菜单虽然没有像 GtkMenuShell 那样硬编码)。 SHIFT+F10 也用作上下文菜单键盘快捷键。
我还注意到在您的应用程序中 F6 和 SHIFT+F6 会将焦点移动到 GtkTreeView 下面的小部件,而不是确定您是否自己编写了此代码,但在您的代码中找不到对它的任何引用(下面的另一个示例中有更多内容)。 F8 也做了类似的事情,但如果在每次按键后你强制将焦点放在 GtkTreeView 上(用鼠标左键单击它),那么你将获得所有按键。 CTRL+Fn 适用于所有键(您有自己的解决方案)。
作为最后一个示例,使用来自 zetcode 的简单、改编的 Treeview 示例,您可以验证所有功能键,使用 ALT 和 [=60 的功能键除外=]SHIFT+F10(上下文菜单),工作:
#include <gtk/gtk.h>
gboolean
keyHandler (GtkWidget *widget,
GdkEventKey *event,
gpointer user_data) {
if (event->keyval >= GDK_KEY_F1 && event->keyval <= GDK_KEY_F12) {
GdkModifierType modmask = gtk_accelerator_get_default_mod_mask ();
gboolean ctrl = (event->state & modmask) == GDK_CONTROL_MASK;
gboolean shift = (event->state & modmask) == GDK_SHIFT_MASK;
g_print ("HANDLED %s%sKEY_F%d\n", ctrl ? "CTRL+" : "", shift ? "SHIFT+" : "", event->keyval - (GDK_KEY_F1 - 1));
}
return FALSE;
}
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *view;
GtkWidget *vbox;
GtkTextBuffer *buffer;
GtkTextIter start, end;
GtkTextIter iter;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_window_set_title(GTK_WINDOW(window), "GtkTextView");
vbox = gtk_vbox_new(FALSE, 0);
view = gtk_text_view_new();
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 0);
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
gtk_text_buffer_create_tag(buffer, "gap",
"pixels_above_lines", 30, NULL);
gtk_text_buffer_create_tag(buffer, "lmarg",
"left_margin", 5, NULL);
gtk_text_buffer_create_tag(buffer, "blue_fg",
"foreground", "blue", NULL);
gtk_text_buffer_create_tag(buffer, "gray_bg",
"background", "gray", NULL);
gtk_text_buffer_create_tag(buffer, "italic",
"style", PANGO_STYLE_ITALIC, NULL);
gtk_text_buffer_create_tag(buffer, "bold",
"weight", PANGO_WEIGHT_BOLD, NULL);
gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0);
gtk_text_buffer_insert(buffer, &iter, "Plain text\n", -1);
gtk_text_buffer_insert_with_tags_by_name(buffer, &iter,
"Colored Text\n", -1, "blue_fg", "lmarg", NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Text with colored background\n", -1, "lmarg", "gray_bg", NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Text in italics\n", -1, "italic", "lmarg", NULL);
gtk_text_buffer_insert_with_tags_by_name (buffer, &iter,
"Bold text\n", -1, "bold", "lmarg", NULL);
gtk_container_add(GTK_CONTAINER(window), vbox);
g_signal_connect(G_OBJECT(view), "key-press-event", G_CALLBACK(keyHandler), NULL);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
结果是(显示上下文菜单!):
另请注意,应用程序 没有菜单 ,因此 F10 处理没有问题。
编辑:在快捷方式
上检查这个Wikipedia entry