Skip to content

Commit 2962357

Browse files
authored
feat: 新增「猫咪设置 > 模型设置 > 按键自动释放延迟」配置项 (#725)
1 parent a75c2d6 commit 2962357

7 files changed

Lines changed: 59 additions & 14 deletions

File tree

src/components/pro-list-item/index.vue

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ const hasDescription = computed(() => {
2323
justify="space-between"
2424
:vertical="vertical"
2525
>
26-
<Flex align="center">
26+
<Flex
27+
align="center"
28+
class="flex-1"
29+
>
2730
<Flex vertical>
2831
<div class="text-sm font-medium">
2932
{{ title }}

src/composables/useDevice.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import type { CursorPoint } from '@/utils/monitor'
22

33
import { invoke } from '@tauri-apps/api/core'
4-
import { useDebounceFn } from '@vueuse/core'
54
import { isEqual, mapValues } from 'es-toolkit'
65
import { ref } from 'vue'
76

@@ -10,7 +9,9 @@ import { INVOKE_KEY, LISTEN_KEY } from '../constants'
109
import { useModel } from './useModel'
1110
import { useTauriListen } from './useTauriListen'
1211

12+
import { useCatStore } from '@/stores/cat'
1313
import { useModelStore } from '@/stores/model'
14+
import { isWindows } from '@/utils/platform'
1415

1516
interface MouseButtonEvent {
1617
kind: 'MousePress' | 'MouseRelease'
@@ -32,14 +33,14 @@ type DeviceEvent = MouseButtonEvent | MouseMoveEvent | KeyboardEvent
3233
export function useDevice() {
3334
const modelStore = useModelStore()
3435
const lastCursorPoint = ref<CursorPoint>({ x: 0, y: 0 })
36+
const releaseTimers = new Map<string, NodeJS.Timeout>()
37+
const catStore = useCatStore()
3538
const { handlePress, handleRelease, handleMouseChange, handleMouseMove } = useModel()
3639

3740
const startListening = () => {
3841
invoke(INVOKE_KEY.START_DEVICE_LISTENING)
3942
}
4043

41-
const debouncedRelease = useDebounceFn(handleRelease, 100)
42-
4344
const getSupportedKey = (key: string) => {
4445
let nextKey = key
4546

@@ -69,6 +70,22 @@ export function useDevice() {
6970
return handleMouseMove(point)
7071
}
7172

73+
const handleAutoRelease = (key: string, delay = 100) => {
74+
handlePress(key)
75+
76+
if (releaseTimers.has(key)) {
77+
clearTimeout(releaseTimers.get(key))
78+
}
79+
80+
const timer = setTimeout(() => {
81+
handleRelease(key)
82+
83+
releaseTimers.delete(key)
84+
}, delay)
85+
86+
releaseTimers.set(key, timer)
87+
}
88+
7289
useTauriListen<DeviceEvent>(LISTEN_KEY.DEVICE_CHANGED, ({ payload }) => {
7390
const { kind, value } = payload
7491

@@ -78,12 +95,16 @@ export function useDevice() {
7895
if (!nextValue) return
7996

8097
if (nextValue === 'CapsLock') {
81-
handlePress(nextValue)
82-
83-
return debouncedRelease(nextValue)
98+
return handleAutoRelease(nextValue)
8499
}
85100

86101
if (kind === 'KeyboardPress') {
102+
if (isWindows) {
103+
const delay = catStore.model.autoReleaseDelay * 1000
104+
105+
return handleAutoRelease(nextValue, delay)
106+
}
107+
87108
return handlePress(nextValue)
88109
}
89110

src/locales/en-US.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@
1919
"alwaysOnTop": "Always On Top",
2020
"windowSize": "Window Size",
2121
"windowRadius": "Window Radius",
22-
"opacity": "Opacity"
22+
"opacity": "Opacity",
23+
"autoReleaseDelay": "Auto Release Delay"
2324
},
2425
"hints": {
2526
"mirrorMode": "When enabled, the model will be horizontally flipped.",
2627
"singleMode": "When enabled, only the last key pressed on each hand is displayed (prevents showing multiple hands when pressing multiple keys at once).",
2728
"mouseMirror": "When enabled, the mouse will mirror follow the hand movement.",
2829
"passThrough": "When enabled, the window will not affect operations on other applications.",
2930
"alwaysOnTop": "When enabled, the window will always stay above other applications.",
30-
"windowSize": "Move the mouse to the edge of the window or hold Shift and right-drag to resize."
31+
"windowSize": "Move the mouse to the edge of the window or hold Shift and right-drag to resize.",
32+
"autoReleaseDelay": "Due to Windows not capturing the release events of certain system-level keys, they will be automatically treated as released after a timeout."
3133
}
3234
},
3335
"general": {

src/locales/vi-VN.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@
1919
"alwaysOnTop": "Luôn trên cùng",
2020
"windowSize": "Kích thước",
2121
"windowRadius": "Độ bo tròn cửa sổ",
22-
"opacity": "Độ mờ"
22+
"opacity": "Độ mờ",
23+
"autoReleaseDelay": "Độ trễ tự động nhả phím"
2324
},
2425
"hints": {
2526
"mirrorMode": "Bật để lật ngang mô hình.",
2627
"singleMode": "Khi bật, mỗi tay mèo chỉ hiển thị phím vừa nhấn cuối cùng (tránh hiện nhiều tay khi nhấn nhiều phím cùng lúc).",
2728
"mouseMirror": "Khi bật, chuột của mô hình sẽ phản chiếu theo chuyển động chuột thực tế.",
2829
"passThrough": "Bật để cửa sổ không ảnh hưởng đến thao tác trên ứng dụng khác.",
2930
"alwaysOnTop": "Bật để cửa sổ luôn nằm trên ứng dụng khác.",
30-
"windowSize": "Di chuyển chuột đến mép cửa sổ hoặc giữ Shift và kéo chuột phải để thay đổi kích thước."
31+
"windowSize": "Di chuyển chuột đến mép cửa sổ hoặc giữ Shift và kéo chuột phải để thay đổi kích thước.",
32+
"autoReleaseDelay": "Do Windows không bắt được sự kiện nhả của một số phím hệ thống, các phím đó sẽ được tự động xem như đã nhả sau khi hết thời gian chờ."
3133
}
3234
},
3335
"general": {

src/locales/zh-CN.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,17 @@
1919
"alwaysOnTop": "窗口置顶",
2020
"windowSize": "窗口尺寸",
2121
"windowRadius": "窗口圆角",
22-
"opacity": "不透明度"
22+
"opacity": "不透明度",
23+
"autoReleaseDelay": "按键自动释放延迟"
2324
},
2425
"hints": {
2526
"mirrorMode": "启用后,模型将水平镜像翻转。",
2627
"singleMode": "启用后,每只手只显示最后按下的一个按键。",
2728
"mouseMirror": "启用后,鼠标将镜像跟随手部移动。",
2829
"passThrough": "启用后,窗口不影响对其他应用程序的操作。",
2930
"alwaysOnTop": "启用后,窗口始终显示在其他应用程序上方。",
30-
"windowSize": "将鼠标移至窗口边缘,或按住 Shift 并右键拖动,也可以调整窗口大小。"
31+
"windowSize": "将鼠标移至窗口边缘,或按住 Shift 并右键拖动,也可以调整窗口大小。",
32+
"autoReleaseDelay": "由于 Windows 下部分系统级按键无法捕获释放事件,超时后将自动视为已释放。"
3133
}
3234
},
3335
"general": {

src/pages/preference/components/cat/index.vue

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { InputNumber, Slider, Switch } from 'ant-design-vue'
44
import ProList from '@/components/pro-list/index.vue'
55
import ProListItem from '@/components/pro-list-item/index.vue'
66
import { useCatStore } from '@/stores/cat'
7+
import { isWindows } from '@/utils/platform'
78
89
const catStore = useCatStore()
910
</script>
@@ -30,6 +31,18 @@ const catStore = useCatStore()
3031
>
3132
<Switch v-model:checked="catStore.model.mouseMirror" />
3233
</ProListItem>
34+
35+
<ProListItem
36+
v-if="isWindows"
37+
:description="$t('pages.preference.cat.hints.autoReleaseDelay')"
38+
:title="$t('pages.preference.cat.labels.autoReleaseDelay')"
39+
>
40+
<InputNumber
41+
v-model:value="catStore.model.autoReleaseDelay"
42+
addon-after="s"
43+
class="w-28"
44+
/>
45+
</ProListItem>
3346
</ProList>
3447

3548
<ProList :title="$t('pages.preference.cat.labels.windowSettings')">
@@ -74,7 +87,7 @@ const catStore = useCatStore()
7487
>
7588
<Slider
7689
v-model:value="catStore.window.opacity"
77-
class="m-0!"
90+
class="m-[0]!"
7891
:max="100"
7992
:min="10"
8093
:tip-formatter="(value) => `${value}%`"

src/stores/cat.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export interface CatStore {
66
mirror: boolean
77
single: boolean
88
mouseMirror: boolean
9+
autoReleaseDelay: number
910
}
1011
window: {
1112
visible: boolean
@@ -48,6 +49,7 @@ export const useCatStore = defineStore('cat', () => {
4849
mirror: false,
4950
single: false,
5051
mouseMirror: false,
52+
autoReleaseDelay: 3,
5153
})
5254

5355
const window = reactive<CatStore['window']>({

0 commit comments

Comments
 (0)