C:读取终端组合键(Ctrl+Shift+)

问题描述 投票:0回答:1

我正在尝试使用

ncurses
构建一个简单的终端程序,但我很难尝试读取 (Ctrl+shift+) 或 (Ctrl+) 等组合键

我尝试了其他库,例如

libtickit
,它可以在桌面终端中读取这些组合,但在仅 TTY 中效果不佳(我使用的是 Linux)。

我看到nano使用ncurses,他们支持这种组合(如Ctrl+shift+箭头),但代码非常复杂。

有人知道一种方法或任何其他库(甚至是其他语言)可以检测大多数现代 UNIX 终端的这个组合键吗?

谢谢。

c unix terminal keyboard ncurses
1个回答
0
投票

首先,不存在“简单”终端程序。对不起。

某些修饰符+按键组合可以很好地检测到,但不是全部,也不是给定修饰符集的所有键。

你绝对可以解码 Ctrl+Shift+左箭头

您可以在 *nixen 和 Windows 上执行此操作!但我们将根据您的问题标签重点关注 *nixen(包括 WSL)。

例如,只需按 Ctrl+A 即可获得

^A
,其键码值为
1
。同样,Ctrl+B 可以获取
2
的键值。 (在 C 语言中,您可以将它们写为
'\1'
'\2'
。) 这些是您的标准“控制代码”。并非键盘上的每个键都会产生控制代码,有些键不需要
Ctrl
键即可产生控制代码,例如
Return
Backspace

无论如何,退格键都是*nixen上的老鼠窝——你需要额外的逻辑来向你的程序返回正确的
值,具体取决于你问的是谁。但这是另一天的问题了。

大多数带有 Alt 键的东西只是以 Esc 键代码 (27) 为前缀的键代码。同样,并非每个键都可以成功地与 Alt 组合使用。

同样,Shift的效果取决于按键。除了特殊功能(如箭头键)之外,它仅适用于字母数字键(切换其状态 - 大写锁定也必须被跟踪!就像,WT--?!)


幸运的是,按 Ctrl+Shift+左箭头 会产生一个简短的、可识别的转义序列(具体为:Esc6D)。那里的

6
是识别按下哪个修饰键的关键:减去 1,设置的位就是您的修饰键代码:

一点 2 1 0
修饰符 Ctrl 替代 移动

不过,使用 Curses 时你不会得到这样的结果。如果您使用 Curses,您可以使用

keyname()
函数 (man 3NCURSES util) 获取“键名称”。对于Ctrl+Shift+左箭头,按键名称是...“
kLFT6
”!非常方便!

这表明您应该使用查找表来确定是否输入了特定(修饰符+箭头键)组合,而不是尝试单独选择它们。

不要太担心如何提高字符串和其他东西的效率。即使使用字符串查找,它也会在用户的手指离开按键之前完成。


让这一切变得更加复杂的是“meta”键的历史使用,它莫名其妙地映射到Esc键,使得计时成为一个问题。换句话说,读取关键响应序列时必须特别小心。确保将初始化代码添加到您的程序中,以将

esc_delay()
设置为相当小的值:

int DEFAULT_ESC_DELAY = 100; // 50..150 ms are reasonable values,
// assuming you are using a local terminal. If user is using dialup/
// network terminal, he/she should have ESCDELAY set in the environment
// anyway!

int get_esc_delay_value(void)
{
  const char * s = getenv( "ESCDELAY" );
  if (!s) return DEFAULT_ESC_DELAY;

  errno = 0;
  char * end;
  long n = strtol( s, &end, 0 );
  if ((s == end) or (errno) or (*end)) return DEFAULT_ESC_DELAY;

  if (n <    0) return 0;
  if (n > 5000) return 5000; // 5 sec is insanely large, but...

  return n;
}

...

esc_delay( get_esc_delay_value() );

最后,终端本身、操作系统甚至终端仿真器选项可能会施加一些限制!

例如,很可能 Ctrl+Shift+向上箭头 已被您的终端模拟器捕获,这意味着您的程序永远不会看到它。让用户弄清楚如何从他或她的 TE 中删除一个方便的快捷方式,你可以将其放入“太难计算”的桶中。

啊啊啊啊啊啊啊啊啊啊啊啊啊啊!

© www.soinside.com 2019 - 2024. All rights reserved.