如何在 bash 中获取 MouseMove 和 MouseClick?

2024-11-01 08:41:00
admin
原创
37
摘要:问题描述:我想知道如何在 Bash 脚本中获取 MouseClick 和 MouseMove 事件用于我自己的简单操作系统事件。请告诉我如何获取该事件。解决方案 1:xterm 终端仿真器定义了一些控制序列来执行鼠标跟踪,您可以在 xterm 发行版的文档ctlseqs中的“鼠标跟踪”部分中了解有关它们的更多...

问题描述:

我想知道如何在 Bash 脚本中获取 MouseClick 和 MouseMove 事件用于我自己的简单操作系统事件。

请告诉我如何获取该事件。


解决方案 1:

xterm 终端仿真器定义了一些控制序列来执行鼠标跟踪,您可以在 xterm 发行版的文档ctlseqs中的“鼠标跟踪”部分中了解有关它们的更多信息。如果您安装了 xterm,您可能会在或类似路径中有一个副本。/usr/share/doc/xterm/ctlseqs.txt.gz

在 X Window 系统上运行的大多数终端仿真器(例如:Konsole、gnome-terminal、eterm 等)至少能理解其中的一些控制序列。如果您想在 Linux 的虚拟终端上直接使用它们,您可能必须运行gpm(8)

有几种用于启用和禁用鼠标移动报告的控制序列:

  • 9 -> X10 鼠标报告,为了与 X10 的 xterm 兼容,报告按钮按下情况。

  • 1000 -> X11 鼠标报告,报告按钮按下和释放。

  • 1001 -> 突出显示报告,对于报告鼠标突出显示有用。

  • 1002 -> 按钮移动报告,按下按钮时报告移动。

  • 1003 -> 所有运动报告,报告所有运动。

控制序列CSI ? number h用于启用和CSI ? number l禁用。CSI 是ESC [或 字符0x9b。因此,您可以按如下方式使用它们:

echo -e "e[?1000h"

然后,按下按钮时您将获得一堆字符,有关详细信息,请参阅ctlseqsconsole_codes(4)。然后,您可以使用以下命令禁用鼠标跟踪:

echo -e "e[?1000l"

不幸的是,以前的鼠标报告模式只能处理最大 223 (255 - 32) 的坐标,或者在某些情况下处理 95 (127 - 32) 的坐标。因此,有一些新的开关可以更改报告鼠标坐标的格式:

  • 1006 -> 以十进制值形式报告(xterm,许多其他终端仿真器,但不是 urxvt)

  • 1015 -> 以十进制值形式报告(urxvt、xterm、其他终端仿真器、某些应用程序发现解析起来很复杂)

  • 1005 -> 报告编码为 utf-8 (xterm, urxvt, 多种方式损坏)

对于应用程序来说,一个好的策略是启用鼠标报告,然后(可选请求 urxvt 1015 模式,然后)请求 SGR 1006 模式。应用程序应该处理新旧鼠标报告响应,以便在不支持新模式的情况下继续在终端仿真器上工作。

有关新报告模式的更多信息,请访问:

  • 午夜指挥官票#2956

  • tmux 票证 #26

  • 午夜指挥官票#2662

解决方案 2:

根据这里提供的宝贵信息,并经过一番挖掘。

我们可以捕捉鼠标按下和释放、滚轮移动和侧移、鼠标中键单击(滚轮单击)和位置。没有右键单击。

以下只是php 中的一个示例,用作 cli。它隐藏了终端上打印的动作,并在退出时将其正确设置回来。

它足够详细,可以适应任何能够读取STDIN并打印到STDOUT的编程语言,所以肯定有一个很大的列表!

#!/usr/bin/php
<?php
system("stty -icanon");                                  // Enable shell input
system("stty -echo");                                    // Disable characters printing
echo "e[?1003he[?1015he[?1006h";                      // Mouse trap all, urxvt, SGR1006  

function shutdown(){                                     // Cleaning before quiting
    echo "e[?1000l";                                    // Disable mouse trap
    system("stty echo");                                 // Enable back characters printing
    exit;                                                // Cleaned, quit
}
register_shutdown_function("shutdown");                  // Handle regular END of script

declare(ticks = 1);                                      // Allow posix signal handling
pcntl_signal(SIGINT,"shutdown");                         // Catch SIGINT (CTRL+C)   

$KEY = "";
while ($KEY = fread(STDIN,16)) {
  $e = explode(";",explode("<",$KEY)[1]);
  if ($e[0] === "0" && substr($e[2],-1) === "M"){
     echo "BUTTON DOWN, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."
"; 
  }
  if ($e[0] === "0" && substr($e[2],-1) === "m"){
     echo "BUTTON UP, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."
"; 
  }
  if ($e[0] === "64"){
     echo "WHEEL SCROLL UP, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."
"; 
  }
  if ($e[0] === "65"){
     echo "WHEEL SCROLL DOWN, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."
"; 
  }
  if ($e[0] === "1" && substr($e[2],-1) === "M"){
     echo "WHEEL BUTTON DOWN, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."
"; 
  }
  if ($e[0] === "1" && substr($e[2],-1) === "m"){
     echo "WHEEL BUTTON UP, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."
"; 
  }
  if ($e[0] === "35"){
     echo "MOUSE MOVE, LINE ".substr($e[2],0,-1)." COLUMN ".$e[1]."
"; 
  }
}

在此处输入图片描述

解决方案 3:

捷径

  1. 启用 xterm 鼠标跟踪报告

  2. 设置 readline 绑定以使用点击生成的转义序列

路还很长

Xterm 具有鼠标跟踪功能

echo -e "e[?1000;1006;1015h" # Enable tracking
echo -e "e[?1000;1006;1015l" # Disable tracking
  • 鼠标单击看起来像e[<0;3;21M并释放e[<0;3;21m。其中3x 是 ,21y 是,从左上角 1 开始。(请注意,它是 xy 而不是 row-col)。

  • 鼠标向上滚动:e[<64;3;21M

  • 鼠标向下滑动:e[<65;3;21M

  • 启用鼠标跟踪后按Ctrl + v或 Enter 键read即可看到

Readline 可以触发 bash 回调

bind -x '"e[<64;": mouse_void_cb' # Cannot be put in .inputrc
bind    '"C-h"   : "$(date) eC-eefefefefef"' #Can be put in .inputrc

Readline可以调用多个函数

# Mouse cursor to begining-of-line before calling click callback
bind    '"C-98" : beginning-of-line'
bind -x '"C-99" : mouse_0_cb'
bind    '"e[<0;": "C-98C-99"'

Readline 回调可以使用READLINE_POINT环境变量改变光标(点)的位置

bind -x '"C-h"  : xterm_test'
function xterm_test {
    echo "line is $READLINE_LINE and point $READLINE_POINT"
    READLINE_POINT=24    # The cursor position (0 for begining of command)
    READLINE_LINE='coco' # The command line current content
}

链接

  • 用于鼠标跟踪的 bash 脚本:免责声明,我是该脚本的作者

  • 用于鼠标跟踪的 zsh 脚本:相同,但在 zsh 中(不是 bash)

  • Ctrl 键与 vim 源代码中使用的一样

  • Invisible-Island:Xterm 控制序列的参考(vim /usr/share/doc/xterm/ctlseqs.txt.gz

解决方案 4:

bash 对鼠标或鼠标点击一无所知。默认情况下没有光标或类似的东西。

您可以安装“通用鼠标服务器”。例如,查看:http://www.linuxfromscratch.org/blfs/view/6.3/general/gpm.html
,以便在控制台内使用复制和粘贴。也许您可以使用这些工具来处理您的 bash 脚本。

...但根本没有:bash-shell 没有原生的鼠标支持

解决方案 5:

您可以使用包“xautomation”中的命令“xte”。

apt-get install xautomation

例如,可以记下以下命令:

xte 'mousemove 200 300'

因此,鼠标指针移动到屏幕的宽度 200 和高度 300。作为另一个示例,我们有:

xte 'mouseclick 3'

单击鼠标右键(1:单击左键,2:单击中键,3:单击右键)。此外,您还可以通过 shell 按键盘上的键:

xte 'keydown Control_L' 'key c' 'keyup Control_L'

此示例将 ctrl+c 发送到 shell。

解决方案 6:

我希望你能理解GoLang :)

根据这条评论。<3

package main

import (
  &quot;fmt&quot;
  &quot;strings&quot;
  &quot;strconv&quot;

  &quot;github.com/pandasoli/goterm&quot;
)

func main() {
  termios, _ := goterm.SetRawMode()
  defer goterm.RestoreMode(termios)

  fmt.Print(&quot;[?1003h[?1015h[?1006h&quot;) // Mouse trap all, urxvt, SGR1006
  fmt.Print(&quot;[?1002h&quot;) // Enable mouse motion reporting

  defer fmt.Print(&quot;[?1002l&quot;) // Disable mouse trap
  defer fmt.Print(&quot;[?1003l[?1015l[?1006l&quot;) // Restore mouse mode and SGR1006

  for {
    key, _ := goterm.Getch()

    if key == &quot;q&quot; { break }

    if strings.HasPrefix(key, &quot;[&lt;&quot;) {
      list := strings.Split(key[3:], &quot;;&quot;)

      ev := list[0]
      x, _ := strconv.Atoi(list[1])
      y, _ := strconv.Atoi(list[2][:len(list[2]) - 1])
      kind := list[2][len(list[2]) - 1]

      switch ev {
      case &quot;0&quot;:
        if kind == &#039;M&#039; {
          fmt.Printf(&quot;(%d, %d) Left mouse down
&quot;, x, y)
        } else if kind == &#039;m&#039; {
          fmt.Printf(&quot;(%d, %d) Left mouse up
&quot;, x, y)
        }
      case &quot;1&quot;:
        if kind == &#039;M&#039; {
          fmt.Printf(&quot;(%d, %d) Wheel button down
&quot;, x, y)
        } else if kind == &#039;m&#039; {
          fmt.Printf(&quot;(%d, %d) Wheel button up
&quot;, x, y)
        }
      case &quot;2&quot;:
        if kind == &#039;M&#039; {
          fmt.Printf(&quot;(%d, %d) Right mouse down
&quot;, x, y)
        } else if kind == &#039;m&#039; {
          fmt.Printf(&quot;(%d, %d) Right mouse up
&quot;, x, y)
        }
      case &quot;32&quot;:
        if kind == &#039;M&#039; {
          fmt.Printf(&quot;(%d, %d) Left mouse pressed move
&quot;, x, y)
        }
      case &quot;34&quot;:
        if kind == &#039;M&#039; {
          fmt.Printf(&quot;(%d, %d) Right mouse pressed move
&quot;, x, y)
        }
      case &quot;35&quot;:
        fmt.Printf(&quot;(%d, %d) Mouse move
&quot;, x, y)
      case &quot;64&quot;:
        fmt.Printf(&quot;(%d, %d) Wheel scroll up
&quot;, x, y)
      case &quot;65&quot;:
        fmt.Printf(&quot;(%d, %d) Wheel scroll down
&quot;, x, y)
      default:
        code := strings.ReplaceAll(key, &quot;&quot;, &quot;\\033&quot;)
        panic(fmt.Errorf(&quot;Could not understand mouse input: \&quot;%s\&quot;.&quot;, code))
      }
    } else {
      result := key
      codes := [][]string {
        { &quot;&quot;, &quot;\\033&quot; },
        { &quot;&quot;, &quot;\\b&quot; },
        { &quot;
&quot;, &quot;\\n&quot; },
        { &quot;x7f&quot;, &quot;\&quot; },
      }

      for _, code := range codes {
        result = strings.ReplaceAll(result, code[0], code[1])
      }

      fmt.Printf(&quot;Pressed key \&quot;%s\&quot; %v
&quot;, result, []byte(key))
    }
  }
}

解决方案 7:

您可以使用 xdotool 来处理鼠标移动和鼠标单击事件。xdotool 是一个模拟键盘和鼠标的工具。通过输入 sudo apt-get install xdotool 来安装它。通过使用 xdotool,您可以自动执行几乎所有使用键盘和鼠标进行的操作。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用