AHK V2版本的原始鼠标手势

原来是用的V1的 MouseGestureL
什么都好
就是看不懂源码,想自己改点什么也太过于复杂

最近翻到一款AHK现在作者早期开发的手势
不愧是作者
源码清晰的一塌糊涂,注释好多…
于是起了心思
花了点时间转成V2的版本了(好久…)

有一个吸引我的点就是
手势1(8方向) ---- 手势2(4方向)
用过的人都知道这类软件不是方向越多越好
我常用的就是那些,多出的来方向误识别比较严重…

东西比较原始,界面没有,菜单都被我转换的头晕删掉了(原本就没有多少…)
第一层压缩包 config\Action.ahk 是手势相关的东西

暂时放这吧,估计也没什么人感兴趣
核心已经有了,想用的话也没什么问题,只不过要自己懂AHK…

LexikosGestures.zip 是原始版本
需要V1 U32打开
需要注意没有托盘图标

链接: https://pan.baidu.com/s/1coctZuGcGcVkVedST63wUg?pwd=15un 提取码: 15un 复制这段内容后打开百度网盘手机App,操作更方便哦

我用MouseGestureL的时候使用快捷键配合鼠标动作设定的延时总是会出问题,要试好几次才成功 :rofl:有时候功能不是越多越好

你得用它专用的函数执行延时动作
不过我没用了不记得具体叫啥了

MouseGestureL在按下鼠标手势触发键和修饰键,然后先松开修饰键(不松开触发键)的时候鼠标会不能点击,必须要再按一次触发键,这种操作3d软件里面用的比较多,好像只能加黑名单了?

不太明白修饰键是什么…
我猜测是手势还没结束…

手势轨迹你懂吧
不知其他软件是怎么样
在MouseGestureL 和 本贴的软件中它其实是一个覆盖全屏背景透明的界面.
轨迹就是在这个界面上画画
然后如果你手势没结束…
这个界面就会一直存在…

修复了点小问题
重写了动作
现在所有动作都是函数了

此版本没有添加原版的LexikosGestures
如需要下载0.1
里面包含了一个可直接运行的exe文件
但是不能修改配置,只能用来演示效果

链接: 百度网盘 请输入提取码 提取码: hufm

在 Action.ahk 中
最上面的g.allGestures是包含的所有手势
"_L", "←", ;_L 是手势, ←无作用,我这里是用来提示方向

新增需要在这里添加一行,再在后面添加一个同名的函数
比方说我新增一个上下的手势 由上 _U 连接 _D 组成
左键,滚轮不能连接,要设置就搜索名称类似 _L
然后在下面找到函数添加条件或动作就行
在g.allGestures中新增一行,并在脚本最下面新增一个同名的函数就可以了

"_U_D", "提示",	;在g.allGestures中新增一行,除了在最后其他的都要保留提示后面的逗号

_U_D()	;在Action.ahk最后面添加这个函数
{
     if g.exe = "chrome"	;用来决定不同窗口不同动作 g.exe 目标文件名称, g.class g.pid g.title g.classNN 这些见名思义, g.path 是目的文件路径
          msgbox(1)
     else if WinActive("ahk_exe Notepad3.exe") ;也可以用标准的AHK表达式, if A_Clipboard  剪贴板包含内容
          msgbox(2)
     else  ;最后的是全局动作,建议最常用的放上面,不常用的放中间,全局动作只能放这,如果只有全局动作,去掉所有 if  else只写动作
          run("notepad")	;打开记事本
}

User.ahk 是用来设置一些东西
editPath := 是托盘菜单编辑的工具 默认是 notepad
具体东西翻 Gestures.ahk 这一行下面的那些东西

* Configuration defaults: Override these in Gestures_User.ahk (in "Gestures:" sub).
    
这中间的部分是具体设置,具体设置什么看后面内容
可以在这直接修改
或者在复制一行到User.ahk中修改
* Basic global init

忘了说了
Action.ahk 里这部分是手势识别修正,哪些手势经常划错在这里改
如果没错建议全删掉,然后自己后期按错误添加

    ;这有个核心概念,分为第一步的方向和后续方向,默认是第一步八方向,后续四方向
    ;这里还有个问题就是只有假如我只要一步的手势为八方向怎么办
    ;这里是个人习惯,所以大概率要删除...
    ;我个人也只用一步+两步的手势,三步及以上的对我来说太复杂误识别率太高了
    if g.gestureLength = 2 ;这就是将两步手势都识别为四方向
        action_name := g.firstZone g.lastZone   
    if action_name = "_L_D" ;手势出来识别的是左下
        action_name := "_L_R" ;在这改在左右
    if action_name = "_R_R"
        action_name := "_DR"
    else if action_name = "_R_D_L" || action_name = "_R_D"
        action_name := "_R_L"

修饰键就是ALT,SHIFT, CTRL 这些,前提是"手势触发键"右键菜单里面不要勾选"忽略修饰键状态",这样按住修饰键就不会触发手势,但是有我上面说的问题 (:з)∠)

在这说个不用MouseGestureL 的原因…
它把大部分AHK自带的函数都换个名字自实现了一遍…
这也是我看不懂它源码的主要原因
几乎相当于一门新语言了加上V1的GOTO特性看的真的头疼死了…

如果你用MouseGestureL且不用它的那些特殊功能比方说激活前一个窗口之类…
比方说特殊的触发方式(屏幕边缘?)
而只是用用 send.^c 这类的基本发送快捷键的功能
可以尝试我发的这个,看看是否也有你说的那种毛病

就是第一次配置的时候麻烦点.
需要手动去写…

虽然原始但是其实最终和MouseGestureL 是达到的一样的效果
MouseGestureL 的配置文件里的是这样的

MG_Gesture_RB_3_:
	if (MG_IsTarget6()) {
		;搜索
		Send, ^{F12}
	} else if (MG_IsTarget14()) {
		;下一文件夹
		Send, d
		
	} else if (MG_IsTarget16()) {
		;下一文件夹
		WinMenuSelectItem, A, ,跳转,到下一个文件夹
	} else if (MG_IsTarget20()) {
		;下一本书
		Send, {F7}
	} else if (!MG_IsExDefault()){
		;搜索
		if WinActive("ahk_group notDrag")
			Send, ^{F12}
		else
			MG_RunAsUser(A_ScriptDir "\..\dragseach.ahk", "", "")
	}
return

其实就和我发的一样,它差不多是一个通用的手势了(很厉害)
如果你稍微懂点AHK的话用我说的这个也能达到同样效果
如果有问题可以在这问,我能帮的就帮
确定不会实现的有配置界面,运行中提示手势

分享一个右键关闭标签的手势吧
其他手势可能也能参考,具体思路是这样的
如果标签的classNN不同则判断当前classNN
比方说 ie, notepad++,Directory Opus

还有一种是classNN不能准确找出标签位置的,只能判断标签坐标了
比方说 chrome,vscode
这种有副作用,因为一般会判断高度,阀值内整个宽度都会响应,即使没有标签
且可能不同用户数值不一样需要自己去量.

然后在当前鼠标所在的坐标发送中键(绝大部分标签都能用此方法关闭)即可
我这有个后续是假如会弹出保存框(比方说notepadd++ vscode这类编辑器 )自动按否

参考代码:

;右键单击,在符合条件的窗口右键关闭标签,否则弹出右键菜单
_RB()
{
    if g.exe = "dopus.exe" && (g.classnn == "dopus.tabctrl1" || g.classnn == "dopus.tabctrl2")
        return CloseTab()

    else if g.exe = "Notepad++.exe" && g.ClassNN = "SysTabControl325"
        return CloseTab(true)

    else if g.exe = "iexplore.exe" && g.classnn = "DirectUIHWND1"
        return CloseTab()

    else if g.classnn = "Intermediate D3D Window1"  ;chrome或VSCode
    {
        CoordMode("Mouse", "Client")
        MouseGetPos(, &y)
        if (g.exe = "Code.exe" && y > 30 && y < 60) ;|| (g.exe = "chrome.exe" && y > 10 && y < 40)  ;注释掉chrome是因为我用百分浏览器自带了此功能
            return CloseTab(g.exe = "Code.exe" ? true : false)
    }

    G_ExitGesture(true)

    CloseTab(hasCancal := false)
    {
        Click("M")
        if hasCancal
            ClickCancel()

    }

    ;延时300秒点击 #32770 的取消按键

    ClickCancel()
    {
        SetTimer(CancelTimer, -200)
        return true
        CancelTimer()
        {
            SetControlDelay(-1)
            if WinActive(title := "ahk_class #32770 ahk_exe " g.exe)
                ControlClick("Button2", title, , , 2, "NA")
        }
    }

}

如图
222

自己为软件添加了个统计功能…

你要是能补全这个软件相对其他手势没有手势学习的缺点就好了
个人感觉在基础的右键上附加一堆else-if,太冗余了,AHK本身性能就低

没有办法呀…右键是手势触发键
这种是我权衡各种办法选择的方法了…

经过各种测试我得出一个结论…各种条件甚至执行动作用的时间并不是很多
不知是我鼠标(无线鼠标)还是AHK性能的原因
单纯的一次右键点击(点击到松开)这部分就要耗时 60-80 ms…
我这有统计
一次手势最短90ms(划得特别快)
最长的有2000ms(无聊时不知是测试还是啥划的?)

此时右键单击有两种解决
一种是按下时判断
    这也有两种办法
        一种是两层判断, 第一次仅判断,第二次判断并执行相关动作 
            相当繁杂且不直观
        一种是一层判断,直接判断并执行
            这有个大问题,如果我并不是想在此区域右键点击而是想作为手势起点怎么办
            此种方法副作用就是此区域不能划手势了
一种是松开时判断
    这种速度就没办法了,起步就要60-80ms
    不能60-80ms的主要是要判断这次右键是点击还是手势
    加上中间部分最终耗时和一次最短手势一样会在90-110左右

至于手势学习…
这只有单纯的角度判断而已…
所以划的线基本没用,50ms判断一次当前坐标与上次坐标的角度
能判断和一次角度阀值不一样就算一次成功手势了…
我为了自己添加了一些修正最终成功还好

看我数据几百次也就误识别一两次而已
哦对了…-_U_L上左应该也算次数
这是最终手段(恢复误关闭的窗口)
除了恢复的浏览器标签,大概有5-6次是用于恢复误关闭的吧

未识别的那个10次也可以不算,这是当时添加手势没弄好弄反了

现在添加手势更加复杂但可能更加直观了…

 _L := Gesture.AddGesture("_L", "←")  ;添加手势动作
 _R := Gesture.AddGesture("_R", "→")

 mpv := Gesture.AddWindow("mpv", (*) => g.exe = "mpv.exe")   ;添加窗口 mpv
 _L(mpv, (*) => Send("{/}"), "上一曲") ;此窗口的动作
 _R(mpv, (*) => Send("{*}"), "下一曲")
 _WU(mpv, (*) => Send("{Left}"), "后退5秒")
 _WD(mpv, (*) => Send("{Right}"), "前进5秒")
 
_global := Gesture.AddWindow("全局", (*) => true) ;全局
_R(_global, (*) => Send("{Browser_Forward}"), "前进") ;全局的动作
U(_global, (*) => Send("{Home}"), "到顶端")
D(_global, (*) => Send("{End}"), "到底部")

从百分暂时转到EDGE了
因习惯百分操作
新增了这些手势
右键关闭标签
右键新标签按钮 粘贴并转到
其他的都是通用动作倒没改太多

        if g.exe = "msedge.exe" && y < 40
        {
            color := PixelGetColor(g.startX, g.startY)
            if color = "0x8F9499" || color = "0x000000" ;新建标签按钮,实现粘贴并转到
                return Send("^+l")
            else
                return CloseTab() ;关闭标签

        }

Lexikos 好熟悉的名字。