.\" Automatically generated by Pandoc 2.17.1.1 .\" .\" Define V font for inline verbatim, using C font in formats .\" that render this, and otherwise B font. .ie "\f[CB]x\f[]"x" \{\ . ftr V B . ftr VI BI . ftr VB B . ftr VBI BI .\} .el \{\ . ftr V CR . ftr VI CI . ftr VB CB . ftr VBI CBI .\} .TH "DUAL-FUNCTION-KEYS" "1" "2020/12/25" "Dual Function Keys" "User Manuals" .hy .SH "نام (NAME)" .PP interception \- کلیدهای دوکاره (dual function keys) .SH "توضیحات (DESCRIPTION)" .PP ضربه زدن برای یک کلید، نگه داشتن برای کلیدی دیگر. .PP بسیار کاربردی برای کلیدهای تبدیل‌گر (modifier) مانند: نگه داشتن برای ctrl، ضربه زدن برای delete. .PP نجات‌دهنده‌ی دست برای افرادی با محدودیت حرکتی انگشتان. .PP پلاگینی برای ابزارهای interception (). .SH "شروع سریع (QUICK START)" .IP "1." 3 چند نگاشت در \f[V]/etc/interception/dual-function-keys/my-mappings.yaml\f[R] ایجاد کنید. نمونه‌های زیادی در () وجود دارد. .IP "2." 3 پیکربندی udevmon مربوط به ابزارهای interception () خود را بسازید: \f[V]/etc/interception/udevmon.d/my-keyboards.yaml\f[R]. برای شروع می‌توانید از پیکربندی من استفاده کنید. .IP "3." 3 فعال‌سازی udevmon: \f[V]sudo systemctl enable udevmon\f[R] .IP "4." 3 راه‌اندازی (مجدد) udevmon: \f[V]sudo systemctl restart udevmon\f[R] .IP "5." 3 بررسی مشکلات: \f[V]journalctl -u udevmon\f[R]. بی‌خبری خوش‌خبری است (عدم نمایش پیام نشان‌دهنده عملکرد صحیح است). می‌توانید با خیال راحت از پیام‌های \f[V]ignoring /etc/interception/udevmon.yaml, reason: bad file: /etc/interception/udevmon.yaml\f[R] صرف‌نظر کنید. .SH "عملکرد (FUNCTIONALITY)" .PP در این مثال‌ها از کلید شیفت چپ (LS) استفاده خواهیم کرد. .PP این کلید به‌گونه‌ای پیکربندی شده است که ضربه زدن به آن عمل delete (DE) و نگه داشتن آن عمل LS را انجام می‌دهد. .IP .nf \f[C] - KEY: KEY_LEFTSHIFT TAP: KEY_DELETE HOLD: KEY_LEFTSHIFT \f[R] .fi .SS "ضربه زدن (Tap)" .PP فشردن و رها کردن کلید LS در بازه زمانی \f[V]TAP_MILLIS\f[R] (پیش‌فرض ۲۰۰ میلی‌ثانیه) برای عمل DE. .PP به‌طور پیش‌فرض، تا زمان کامل شدن ضربه، LS دریافت می‌شود. برای مشاهده سایر گزینه‌ها به بخش‌های زیر مراجعه کنید. .IP .nf \f[C] <---------200ms---------> <---------200ms---------> keyboard: LS\[da] LS\[ua] LS\[da] LS\[ua] computer sees: LS\[da] LS\[ua] DE\[da] DE\[ua] LS\[da] LS\[ua] \f[R] .fi .SS "دو بار ضربه زدن (Double Tap)" .PP ضربه بزنید و سپس مجدداً در بازه \f[V]DOUBLE_TAP_MILLIS\f[R] (پیش‌فرض ۱۵۰ میلی‌ثانیه) فشار دهید تا DE نگه داشته شود. .IP .nf \f[C] <-------150ms-------> <---------200ms---------> keyboard: LS\[da] LS\[ua] LS\[da] LS\[ua] computer sees: LS\[da] LS\[ua] DE\[da] DE\[ua] DE\[da] ..(repeats).. DE\[ua] \f[R] .fi .PP تا زمانی که در بازه زمانی \f[V]DOUBLE_TAP_MILLIS\f[R] باشید، می‌توانید به زدن ضربه‌های دوتایی ادامه دهید. .SS "مصرف شدن (Consumption)" .PP اگر کلید دیگری را در بازه زمانی \f[V]TAP_MILLIS\f[R] فشار داده یا رها کنید، عمل ضربه زدن (tap) انجام نخواهد شد. .PP این قابلیت به‌ویژه برای کلیدهای تبدیل‌گر بسیار مفید است، برای مثال اجرای سریع ctrl-C. در این مثال، کلید a را در طول این بازه زمانی فشار می‌دهیم. .PP ضربه دوتایی پس از مصرف شدن عمل نمی‌کند؛ ابتدا باید یک ضربه ساده بزنید. .PP رویدادهای ماوس و تاچ‌پد (\f[V]EV_REL\f[R] و \f[V]EV_ABS\f[R]) نیز می‌توانند ضربه‌ها را مصرف کنند، با این حال باید از یک پیکربندی چنددستگاهی (Multiple Devices) استفاده کنید. .IP .nf \f[C] <-------150ms-------> <---------200ms---------> <-------150ms-------> <---------200ms---------> keyboard: LS\[da] a\[da] a\[ua] LS\[ua] LS\[da] LS\[ua] LS\[da] computer sees: LS\[da] a\[da] a\[ua] LS\[ua] LS\[da] LS\[ua] DE\[da] DE\[ua] DE\[da] ..(repeats).. \f[R] .fi .SH "نصب (INSTALLATION)" .SS "مدیر بسته (Package Manager)" .PP [تصویر: وضعیت بسته‌بندی ()] () .SS "از کد منبع (From Source)" .PP وابستگی‌های زمان اجرا را ببینید (). .PP ابتدا ابزارهای Interception Tools () را نصب کنید. .IP .nf \f[C] git clone https://gitlab.com/interception/linux/plugins/dual-function-keys.git cd dual-function-keys make && sudo make install \f[R] .fi .PP پیشوند نصب به‌طور پیش‌فرض \f[V]/usr/local\f[R] است. این مقدار را می‌توان در \f[V]config.mk\f[R] بازنویسی کرد..SH "پیکربندی (CONFIGURATION)" .PP دو بخش برای پیکربندی وجود دارد: dual-function-keys و udevmon، که dual-function-keys را اجرا می‌کند. .PP به مثال‌ها (https://gitlab.com/interception/linux/plugins/dual-function-keys/-/tree/master/doc/examples.md) که شامل پیکربندی‌های dual-function-keys و udevmon.yaml است مراجعه کنید. .SS dual-function-keys .PP این فایل yaml به طور معمول در \f[V]/etc/interception/dual-function-keys\f[R] قرار دارد. .PP می‌توانید از کدهای کلید خام (عدد صحیح) استفاده کنید، با این حال استفاده از رشته‌های \f[V]#define\f[R] شده از input-event-codes.h (https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h) آسان‌تر است. .IP .nf \f[C] # optional TIMING: TAP_MILLISEC: DOUBLE_TAP_MILLISEC: SYNTHETIC_KEYS_PAUSE_MILLISEC: # necessary MAPPINGS: - KEY: TAP: [ , ... ] HOLD: [ , ... ] # optional HOLD_START: [ AFTER_PRESS | AFTER_RELEASE | BEFORE_CONSUME | BEFORE_CONSUME_OR_RELEASE ] - KEY: ... \f[R] .fi .PP مثال ما از بخش پیشین به این صورت است: .IP .nf \f[C] TIMING: TAP_MILLISEC: 200 DOUBLE_TAP_MILLISEC: 150 MAPPINGS: - KEY: KEY_LEFTSHIFT TAP: KEY_DELETE HOLD: KEY_LEFTSHIFT \f[R] .fi .SS کلیدهای ترکیبی (Combo Keys) .PP می‌توانید \f[V]TAP\f[R] را به عنوان یک \[lq]ترکیب (combo)\[rq] پیکربندی کنید، که چندین کلید را به ترتیب فشرده و سپس رها می‌کند، برای نمونه\ space cadet \f[V](\f[R]: .IP .nf \f[C] MAPPINGS: - KEY: KEY_LEFTSHIFT TAP: [ KEY_LEFTSHIFT, KEY_9, ] HOLD: KEY_LEFTSHIFT \f[R] .fi .PP می‌توانید \f[V]HOLD\f[R] را به عنوان یک \[lq]ترکیب (combo)\[rq] پیکربندی کنید، که چندین کلید را به ترتیب فشرده و سپس رها می‌کند، برای نمونه\ کلید تبدیل‌کننده هایپر (hyper modifier): .IP .nf \f[C] MAPPINGS: - KEY: KEY_TAB TAP: KEY_TAB HOLD: [ KEY_LEFTCTRL, KEY_LEFTMETA, KEY_LEFTALT, ] \f[R] .fi .PP به‌طور پیش‌فرض، یک مکث ۲۰ میلی‌ثانیه‌ای بین کلیدها در \[lq]ترکیب\[rq] وجود خواهد داشت. این مقدار قابل تغییر است: .IP .nf \f[C] TIMING: SYNTHETIC_KEYS_PAUSE_MILLISEC: 10 \f[R] .fi .SS تغییر رفتار کلیدهای \f[V]HOLD\f[R] .PP می‌توانید به صورت اختیاری از \f[V]HOLD_START\f[R] برای پیکربندی رفتار کلیدهای \f[V]HOLD\f[R] استفاده کنید. .SS \f[V]HOLD_START: AFTER_PRESS\f[R] .PP اگر \f[V]HOLD_START\f[R] مشخص نشده باشد، برابر \f[V]AFTER_PRESS\f[R] یا یک مقدار ناشناخته باشد، رفتار پیش‌فرض اعمال خواهد شد. .SS \f[V]HOLD_START: BEFORE_CONSUME\f[R] .PP کلیدهای \f[V]HOLD\f[R] پیش از مصرف شدن \f[V]KEY\f[R] فشرده می‌شوند، و هنگامی که \f[V]KEY\f[R] رها شود، رها می‌شوند. بنابراین هنگامی که روی \f[V]KEY\f[R] ضربه زده (tap) می‌شود، هیچ کلید اضافه‌ای به جز کلیدهای \f[V]TAP\f[R] ارسال نمی‌شود، در حالی که کلیدهای \f[V]HOLD\f[R] همچنان می‌توانند به عنوان کلیدهای تبدیل‌کننده (modifiers) استفاده شوند. .IP .nf \f[C] MAPPINGS: - KEY: KEY_LEFTSHIFT TAP: KEY_DELETE HOLD: KEY_LEFTSHIFT HOLD_START: BEFORE_CONSUME \f[R] .fi .IP .nf \f[C] <---------200ms---------> <---------200ms---------> keyboard: LS\[da] LS\[ua] LS\[da] LS\[ua] computer sees: DE\[da] DE\[ua] \f[R] .fi .IP .nf \f[C] <-------150ms-------> <---------200ms---------> <-------150ms-------> <---------200ms---------> keyboard: LS\[da] a\[da] a\[ua] LS\[ua] LS\[da] LS\[ua] LS\[da] computer sees: LS\[da] a\[da] a\[ua] LS\[ua] DE\[da] DE\[ua] DE\[da] ..(repeats).. \f[R] .fi .SS \f[V]HOLD_START: BEFORE_CONSUME_OR_RELEASE\f[R] .PP رفتار مشابه \f[V]BEFORE_CONSUME\f[R] است، با این تفاوت که وقتی \f[V]KEY\f[R] رها می‌شود و پیش از آن نه ضربه خورده و نه مصرف شده است، کلیدهای \f[V]HOLD\f[R] به ترتیب فشرده شده و سپس به ترتیب رها می‌شوند. .IP .nf \f[C] MAPPINGS: - KEY: KEY_LEFTSHIFT TAP: KEY_DELETE HOLD: KEY_LEFTSHIFT HOLD_START: BEFORE_CONSUME_OR_RELEASE \f[R] .fi .IP .nf \f[C] <---------200ms---------> <---------200ms---------> keyboard: LS\[da] LS\[ua] LS\[da] LS\[ua] computer sees: DE\[da] DE\[ua] LS\[da] LS\[ua] \f[R] .fi.SS \f[V]HOLD_START: AFTER_RELEASE\f[R] .PP حالت نگه‌داشتن (Hold) تنها پس از رها شدن کلید آغاز می‌شود، به شرطی که زمان TAP_MILLISEC سپری شده باشد. این نوع شروع نگه‌داشتن تحت تأثیر هیچ نوع مصرف‌شدنی (consumption) قرار نمی‌گیرد. .IP .nf \f[C] MAPPINGS: - KEY: KEY_A TAP: KEY_A HOLD: [KEY_LEFTSHIFT, KEY_A] HOLD_START: AFTER_RELEASE \f[R] .fi .IP .nf \f[C] <---------200ms---------> <---------200ms---------> keyboard: a\[da] a\[ua] a\[da] a\[ua] computer sees: a\[da] a\[ua] A\[da] A\[ua] \f[R] .fi .SS هشدار (Warning) .PP یک کلید تبدیل‌گر (modifier) یکسان را به دو کلیدی که قصد دارید هم‌زمان فشار دهید اختصاص ندهید، چرا که با یکدیگر تداخل خواهند داشت. از نسخه‌های چپ و راست تبدیل‌گرها استفاده کنید؛ به عنوان مثال alt-tab با space-caps: .IP .nf \f[C] MAPPINGS: - KEY: KEY_CAPSLOCK TAP: KEY_TAB HOLD: KEY_LEFTALT - KEY: KEY_SPACE TAP: KEY_SPACE HOLD: KEY_RIGHTALT \f[R] .fi .PP در غیر این صورت، می‌توانید از \f[V]HOLD_START: BEFORE_CONSUME\f[R] یا \f[V]HOLD_START: BEFORE_CONSUME_OR_RELEASE\f[R] استفاده کنید و سپس اختصاص تبدیل‌گر یکسان بلامانع خواهد بود: .IP .nf \f[C] MAPPINGS: - KEY: KEY_CAPSLOCK TAP: KEY_TAB HOLD: KEY_LEFTALT HOLD_START: BEFORE_CONSUME_OR_RELEASE - KEY: KEY_SPACE TAP: KEY_SPACE HOLD: KEY_LEFTALT HOLD_START: BEFORE_CONSUME_OR_RELEASE \f[R] .fi .SS udevmon .PP باید به udevmon اطلاع داده شود که می‌خواهیم از کلیدهای دوکاره (Dual Function Keys) استفاده کنیم. برای شرح کامل، بخش نحوه کار (https://gitlab.com/interception/linux/tools#how-it-works) را ببینید. .IP .nf \f[C] - JOB: \[dq]intercept -g $DEVNODE | dual-function-keys -c | uinput -d $DEVNODE\[dq] DEVICE: NAME: \f[R] .fi .PP نام دستگاه را می‌توان با اجرای دستور زیر مشخص کرد: .IP .nf \f[C] sudo uinput -p -d /dev/input/by-id/X \f[R] .fi .PP که در آن X دستگاهی است که نامی شبیه به صفحه‌کلید شما دارد. اطمینان حاصل کنید که تمام \f[V]EV_KEY\f[R]ها در زیر بخش \f[V]EVENTS\f[R] وجود داشته باشند. اگر نمی‌توانید صفحه‌کلید خود را در \f[V]/dev/input/by-id\f[R] بیابید، دستگاه‌های موجود در \f[V]/dev/input\f[R] را مستقیماً بررسی کنید. .PP برای اطلاعات بیشتر دربارهٔ \f[V]uinput -p\f[R]، به Interception Tools: How It Works (https://gitlab.com/interception/linux/tools#how-it-works) مراجعه کنید. .PP معمولاً این نام برای شناسایی یکتای صفحه‌کلید کافی است، با این حال برخی صفحه‌کلیدها چندین دستگاه مانند یک ماوس مجازی را ثبت می‌کنند. می‌توانید dual-function-keys را برای همهٔ دستگاه‌ها اجرا کنید، اما ترجیح من اجرای آن صرفاً برای صفحه‌کلید واقعی است. .PP فایل \f[V]/etc/interception/udevmon.d/my-keyboards.yaml\f[R] من: .IP .nf \f[C] - JOB: \[dq]intercept -g $DEVNODE | dual-function-keys -c /etc/interception/dual-function-keys/home-row-modifiers.yaml | uinput -d $DEVNODE\[dq] DEVICE: NAME: \[dq]Minimalist Keyboard ABC\[dq] EVENTS: EV_KEY: [ KEY_LEFTSHIFT ] - JOB: \[dq]intercept -g $DEVNODE | dual-function-keys -c /etc/interception/dual-function-keys/thumb-cluster.yaml | uinput -d $DEVNODE\[dq] DEVICE: NAME: \[dq]Split Keyboard XYZ\[dq] EVENTS: EV_KEY: [ KEY_LEFTSHIFT ] \f[R] .fi .SS چندین دستگاه (Multiple Devices) .PP هنگام استفاده از ورودی‌های چند دستگاه مختلف، مثلاً ctrl-scroll، ممکن است برای اینکه dual-function-keys بین این دستگاه‌ها کار کند (مثلاً اسکرول، ctrl را مصرف کند)، تسهیم کردن (mux) دستگاه‌ها با یکدیگر (https://gitlab.com/interception/linux/tools#mux) لازم باشد. .PP پیکربندی نمونه udevmon برای ماوس و صفحه‌کلید: .IP .nf \f[C] - CMD: mux -c dfk -c my-keyboard -c my-mouse - JOB: - mux -i dfk | dual-function-keys -c /etc/interception/dual-function-keys/my-cfg.yaml | mux -o my-keyboard -o my-mouse - mux -i my-keyboard | uinput -c /etc/interception/udevmon.d/my-keyboard.yaml - mux -i my-mouse | uinput -c /etc/interception/udevmon.d/my-mouse.yaml - JOB: intercept -g $DEVNODE | mux -o dfk DEVICE: NAME: AT Translated Set 2 keyboard EVENTS: EV_KEY: [ KEY_LEFTCTRL ] - JOB: intercept -g $DEVNODE | mux -o dfk DEVICE: NAME: Razer Razer Naga Trinity EVENTS: EV_REL: [REL_WHEEL] EV_KEY: [BTN_LEFT] \f[R] .fi .PP در مثال بالا، \f[V]my-keyboard.yaml\f[R] و \f[V]my-mouse.yaml\f[R] نمایانگر دستگاه‌های مجازی هستند که udevmon برای خروجی دادن رویدادها ایجاد خواهد کرد. آن‌ها یک‌بار از خود دستگاه تولید می‌شوند؛ به عنوان مثال: .IP .nf \f[C] sudo uinput -p -d /dev/input/by-id/usb-my-keyboard-kbd > my-keyboard.yaml \f[R] .fi .PP یک راهکار جایگزین، در صورتی که ریسک آن را می‌پذیرید (https://gitlab.com/interception/linux/plugins/dual-function-keys/-/issues/31#note_725722450)، این است که پیکربندی دستگاه مجازی را بی‌درنگ و در حین کار (on the fly) تولید کنید؛ به عنوان مثال: .IP .nf \f[C] - CMD: mux -c dfk -c my-keyboard -c my-mouse - JOB: - mux -i dfk | dual-function-keys -c /etc/interception/dual-function-keys/my-cfg.yaml | mux -o my-keyboard -o my-mouse - mux -i my-keyboard | uinput -d /dev/input/by-path/my-keyboard-event-kbd - mux -i my-mouse | uinput -d /dev/input/by-id/usb-my-mouse-event-mouse - JOB: intercept -g $DEVNODE | mux -o dfk DEVICE: LINK: /dev/input/by-path/my-keyboard-event-kbd - JOB: intercept -g $DEVNODE | mux -o dfk DEVICE: LINK: /dev/input/by-id/usb-my-mouse-event-mouse \f[R] .fi.SH "هشدارها (CAVEATS)" .PP همانند همیشه یک نکته وجود دارد: dual-function-keys بر روی \f[I]keycodes\f[R] خام عمل می‌کند، نه \f[I]keysyms\f[R]، آن‌گونه که توسط X11 یا Wayland دیده می‌شوند. .PP اگر هر چیزی دارید که نگاشت keycode->keysym را دستکاری می‌کند، مانند XKB (https://www.x.org/wiki/XKB) یا xmodmap (https://wiki.archlinux.org/index.php/Xmodmap)، توجه داشته باشید که dual-function-keys پیش از آن‌ها اعمال می‌شود. .PP برخی از کاربردهای رایج XKB که ممکن است در پیکربندی X11 شما یافت شوند: .IP .nf \f[C] Option \[dq]XkbModel\[dq] \[dq]pc105\[dq] Option \[dq]XKbLayout\[dq] \[dq]us\[dq] Option \[dq]XkbVariant\[dq] \[dq]dvp\[dq] Option \[dq]XkbOptions\[dq] \[dq]caps:escape\[dq] \f[R] .fi .SH "پرسش‌های متداول (FAQ)" .SS موردی جدید برای استفاده دارم. آیا می‌توانید از آن پشتیبانی کنید؟ .PP لطفاً یک issue ثبت کنید. .PP dual-function-keys برای برطرف‌کردن نیازهای من ساخته شده است. بسیار علاقه‌مندم ایده‌های شما را بشنوم و به عملی‌شدن آن‌ها کمک کنم. .PP مثل همیشه، از ارسال PR به‌گرمی استقبال می‌شود. .SS می‌بینم که در udevmon خود از صفحه‌کلید اصلاح‌شدهٔ q.m.k HHKB استفاده می‌کنید. این صفحه‌کلید از QMK Firmware (https://qmk.fm) بهره می‌برد. چرا مستقیماً از Tap-Hold (https://docs.qmk.fm/#/tap_hold) استفاده نمی‌کنید؟ .PP نکته‌سنجی خوبی بود! آن قابلیت در واقع عملکرد مشابهی با dual-function-keys ارائه می‌دهد. متأسفانه معایبی وجود دارد: .IP "1." 3 صفحه‌کلیدهای اندکی از QMK Firmware استفاده می‌کنند. .IP "2." 3 مشکلاتی در آن قابلیت وجود دارد، همان‌طور که در مستندات Tap-Hold (https://docs.qmk.fm) ذکر شده است. .IP "3." 3 این قابلیت نیازمند پردازنده‌ای سریع در صفحه‌کلید است. آزمایش‌های غیرعلمی من با یک Ergodox (\[ti]800 اسکن در ثانیه) و HHKB (\[ti]140) نشان داد که صفحه‌کلید کندتر، اسفنجی شده و دقت آن تا حد بلااستفاده بودن کاهش می‌یابد. .SS چرا از xcape (https://github.com/alols/xcape) استفاده نمی‌کنید؟ .PP برنامه xcape تنها قابلیت ساده tap/hold را ارائه می‌دهد. به نظر می‌رسد افزودن باقی قابلیت‌ها با استفاده از سازوکارهای XTestFakeKeyEvent آن بسیار دشوار (شاید غیرممکن؟) باشد. .SS ترکیب کلیدهای من کار نمی‌کند .PP اطمینان حاصل کنید که مدیر پنجره (window manager) شما این ترکیب کلید را رهگیری و مسدود نمی‌کند. .SS من قابلیت دو بار فشردن (Double Tap) را نمی‌خواهم .PP مقدار DOUBLE_TAP_MILLISEC را برابر با 0 قرار دهید. بخش Key Combinations, No Double Tap (https://gitlab.com/interception/linux/plugins/dual-function-keys/-/blob/master/doc/examples.md#key-combinations-no-double-tap) را ببینید. .SH "مشارکت‌کنندگان (CONTRIBUTORS)" .PP لطفاً این مخزن را فورک کرده و یک PR ارسال کنید. .PP اگر در حال ایجاد تغییرات در مستندات هستید، لطفاً فایل pandoc با نام \f[V]dual-function-keys.md\f[R] را ویرایش کرده و دستور \f[V]make doc\f[R] را اجرا کنید. .PP لطفاً مطمئن شوید که این \f[V]README.md\f[R] و صفحه راهنما \f[V]dual-function-keys.1\f[R] دارای تغییرات شما هستند و هر سه را کامیت کنید. .PP می‌توانید صفحه راهنمای تولیدشده را با دستور \f[V]man -l dual-function-keys.1\f[R] آزمایش کنید. .PP همانند همیشه، لطفاً قواعد \f[V].editorconfig\f[R] را رعایت فرمایید. .SH "مجوز (LICENSE)" .PP .PP کپی‌رایت \[co] 2020 Alexander Courtis .SH "نویسندگان (AUTHORS)" Alexander Courtis.