gpt4 book ai didi

linux - GTK3 功能键;哪些被消耗了(并且无法从我的 GTK 应用程序中使用)?

转载 作者:太空狗 更新时间:2023-10-29 12:10:28 27 4
gpt4 key购买 nike

FWIW,引发这个问题的确切程序是(在 Linux/Debian/Sid/x86-64 上)我的 bismon在 github 上,提交 d43a75fb9f8e13 . GTK3 是 3.22.24。如果您需要尝试,请使用 make 构建它并运行 ./bismon。它处于 alpha 阶段,除了我之外,其他人仍然没有兴趣。它是某种具有 GTK 接口(interface)和持久堆的 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)

我想在我的程序中处理功能键。但是一些功能键(例如 F7F8F9F10 ...)被“抢占”了桌面或环境,但无法访问我的程序。达到其他人,例如F6 给出我的 debugging handlekeypresscmd_BM 函数的输出:

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 作为我的桌面环境。据我所知,我没有专门针对功能键配置这些。

预定义的功能键列表(那些已经被其他东西使用过的,也许是窗口管理器)是否可以访问和记录?在哪里?我是否应该查看 EWMH、ICCCCM、Gnome 人机界面,深入研究每个窗口管理器的文档?

更重要的是,有没有办法从 GTK3 应用程序以编程方式查询某些小部件将达到哪些功能键(如 GtkTextView) ? 我想不出任何...

否则,我可以合理地期望从 Linux 上的 Gtk3 应用程序(使用 X11,也许稍后使用 Wayland)使用的一小组功能键是什么?

FWIW,xev 可以看到从 F1F12 的所有功能键

附录

为了部分回答我的问题,gtk/gtktextview.c (来自 GTK3 的源代码)大约在第 1630 行:

  /* Caret mode */
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F7, 0,
"toggle-cursor-visible", 0);

(顺便说一句,有什么方法可以禁用它吗?)

但这并没有解释 F8 的行为,也没有告诉我如何查询可以使用哪些功能键。

我的 TextView 在一些 GtkPaned 中,它在 gtk/gtkpaned.c 中第635行

  gtk_binding_entry_add_signal (binding_set,
GDK_KEY_F8, 0,
"cycle-handle-focus", 1,
G_TYPE_BOOLEAN, FALSE);

所以也许我应该尝试找出如何查询此类绑定(bind)键。仍然没有想法。应查GtkBindingSet .

最佳答案

尝试分解您的问题,以便更容易回答。

首先,我建议阅读 The GTK+ Input and Event Handling Model并注意“GTK+ 从窗口系统接收事件”。

I'm using either Gnome, or XFCE4, or LXDE as my desktop environments. AFAIK I did not configure these specially regarding function keys.

好吧,你没有,但“发行版”/窗口管理器有。

例如,检查 GNOME Shell Keyboard shortcuts

大多数窗口管理器使用 ALT+Fn 键,其中 ALT+F4 最常用于关闭窗口。 CTRL 键更适合用户“快捷键/加速器”。

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...

不,没有。事件被发出/触发,小部件,如果被编程为这样做,相应地接收和处理它们,然后通过检查事件,就像你对你的 key-press-event 处理程序一样,你可以触发“ Action ”。好吧,理论上,您可以在自己的小部件中开发一组已处理键的 setter 和 getter,但老实说,您看不到这样做的意义。

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+FnSHIFT+Fn 和正常的 F1F12 离开 ALT+Fn 为 Window 系统保留。

现在看看你在 Github 上的具体例子,你的处理程序已经忽略了 F11F12 由于条件:

...
... 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 也用作上下文菜单键盘快捷键。

我还注意到在您的应用程序上 F6SHIFT+F6 会将焦点移动到 GtkTreeView 下方的小部件,不确定您是否自己编写了此代码但不能' 在您的代码中找到对它的任何引用(更多内容见下文另一个示例)。 F8 也做了类似的事情,但如果在每次按键后你强制将焦点放在 GtkTreeView 上(用鼠标左键单击它)那么你将获得所有按键。 CTRL+Fn 适用于所有键(您有自己的解决方案)。

作为最后一个示例,使用来自 zetcode 的一个简单的、改编的 Treeview 示例您可以验证所有功能键,除了那些使用 ALTSHIFT+F10(ContextMenu) 的功能键,是否有效:

#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;
}

结果是(显示上下文菜单!):

screenshot

另请注意,该应用程序没有菜单,因此可以毫无问题地处理 F10。

编辑:检查这个 Wikipedia entry关于快捷方式

关于linux - GTK3 功能键;哪些被消耗了(并且无法从我的 GTK 应用程序中使用)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46809878/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com