Code Monkey home page Code Monkey logo

map2's Issues

Does map2 support hotstringing?

By hotstrings I mean what AutoHotkey means, i.e. being able to type abbreviations and the script would replace it with the full form (like FBI -> Federal Bureau of Investigations).

Does map2 support that? If so - could you, please, provide an example?

Release binaries for older machines

Looks very interesting, but it suffers from the common "requires a very recent GLIBC" issue. If you could release binaries that are made on an older machine, it would not affect people with a newer GLIBC, but it would extend your reach. I am on the latest Ubuntu-family LTS (20.04), but last month I was still running 18.04 and I ran into this issue a lot...
Debug output:

map2: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.33' not found (required by map2)
map2: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by map2)

can't get it to work - keep getting device busy errors

issue: i can't get it to work at all; seems like it doesn't like the file descriptors. I saw issue #3 but it wasn't any help.
system: Fedora 34 Cinnamon (and yes, I tried it with SELinux disabled too)
kernel: 5.15.12-100
install type: tried both manual install from releases (/usr/bin/map2 with chmod 755) and building with cargo.
map2 version: 1.0.6 for releases page / source for cargo (map2 --version gives map2 1.0 in both cases)
keyboard/mouse: logitech k400 wireless htpc keyboard via logitech receiver
script: just trying to get the simple example.m2 from the README working for now: a::b;
file descriptors: honestly, I was a bit confused about what is supposed to go in here. will give full details below.


File descriptors

This part was the most confusing for me. The README only says:

To describe which devices should be grabbed it is necessary to provide a list of file descriptor paths, regular expressions are also supported.
...
In order to find out which file descriptor corresponds to which physical device one should examine /dev/input/by-id/ and /dev/input/by-path/

But doesn't actually describe how to identify what the correct file descriptor is (e.g. not sure if it's supposed to be obvious or it is purely a trial-and-error process).

Anyway, I had:

$ ls -acl /dev/input/by-id /dev/input/by-path | grep -Pvi 'Headset|spkr'
/dev/input/by-id:
total 0
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 usb-Logitech_USB_Receiver-if02-event-mouse -> ../event4
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 usb-Logitech_USB_Receiver-if02-mouse -> ../mouse1
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 usb-MOSART_Semi._2.4G_Wireless_Mouse-event-if00 -> ../event7
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 usb-MOSART_Semi._2.4G_Wireless_Mouse-event-mouse -> ../event6
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 usb-MOSART_Semi._2.4G_Wireless_Mouse-mouse -> ../mouse0
 
/dev/input/by-path:
total 0
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 pci-0000:00:12.0-usb-0:2:1.3-event -> ../event3
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 pci-0000:00:13.0-usb-0:4:1.2-event-mouse -> ../event4
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 pci-0000:00:13.0-usb-0:4:1.2-mouse -> ../mouse1
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 pci-0000:00:13.2-usb-0:5.2:1.0-event -> ../event7
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 pci-0000:00:13.2-usb-0:5.2:1.0-event-mouse -> ../event6
lrwxrwxrwx. 1 root root 9 Jan  8 19:58 pci-0000:00:13.2-usb-0:5.2:1.0-mouse -> ../mouse0

Since the example in the README showed 2 entries, I assume that I also need 2 entries: one from /dev/input/by-id and one from /dev/input/by-path. I also made the assumption that I wanted one of the "usb-Logitech_USB_Receiver" ones and that I should probably pair similar events (e.g. the file under /dev/input/by-id that points to ../mouse1 and the file under /dev/input/by-path that points to ../mouse1)... but all guesswork.

Since I had 2 candidates, I made 2 files and figured I just try one and if it didn't work, then try the other.

devices-mouse1.list
/dev/input/by-id/usb-Logitech_USB_Receiver-if02-mouse
/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-mouse
devices-event4.list
/dev/input/by-id/usb-Logitech_USB_Receiver-if02-event-mouse
/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-event-mouse

Errors

Attempting first as regular user then with sudo, using first the precompiled version from releases page then with version built from source with caro.

$ cd /tmp/map2
$ ls -acl
total 1.4M
drwxr-x---. 3 fd fd   60 Jan  9 19:37 map2-1.0.6-x86_64/
-rw-rw----. 1 fd fd  120 Jan  9 19:02 devices-event4.list
-rw-rw----. 1 fd fd  108 Jan  9 19:02 devices-mouse1.list
-rw-rw----. 1 fd fd   25 Jan  9 19:01 example.m2
-rw-r--r--. 1 fd fd 1.4M Jan  9 19:38 map2-1.0.6-x86_64.tar.gz
 
$ sudo -i
# setenforce 0
# getenforce
Permissive
 
# cd /tmp/map2/map2-1.0.6-x86_64
# find . -type f
./usr/bin/map2
./usr/share/man/man1/map2.1.gz
# cp -a -t /usr/bin ./usr/bin/map2
# cp -a -t /usr/share/man/man1 ./usr/share/man/man1/map2.1.gz
# chmod 755 /usr/bin/map2
# exit
 
$ map2 --version
map2 1.0
 
$ map2 -d devices-event4.list example.m2 
thread 'tokio-runtime-worker' panicked at 'failed to open fd '/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-event-mouse': Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', /home/shiro/project/map2/src/device/virtual_input_device.rs:88:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
 $ map2 -d devices-mouse1.list example.m2 
thread 'tokio-runtime-worker' panicked at 'failed to open fd '/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-mouse': Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', /home/shiro/project/map2/src/device/virtual_input_device.rs:88:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
$ sudo map2 -d devices-event4.list example.m2 
failed to grab device '/dev/input/by-id/usb-Logitech_USB_Receiver-if02-event-mouse': Device or resource busy (os error 16)
 
$ sudo map2 -d devices-mouse1.list example.m2 
thread 'tokio-runtime-worker' panicked at 'failed to open fd '/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-mouse': Os { code: 25, kind: Other, message: "Inappropriate ioctl for device" }', /home/shiro/project/map2/src/device/virtual_input_device.rs:91:56
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

From this, I think that my devices-event4.list is the correct file descriptor to use for my logitech k400 but still can't get it to work.

I tried the same thing with the cargo build but got the same error message.

# dnf install -y ncurses ncurses-base ncurses-static ncurses-libs ncurses-devel ncurses-c++-libs \
	libevdev libevdev-devel xorg-x11-drv-evdev xorg-x11-drv-evdev-devel libevdev-utils
# exit
 
$ mkdir /tmp/map2
$ git clone https://github.com/shiro/map2 map2_src
$ cd map2_src/
$ cargo build --release
$ cd target/release/
$ ./map2 --version
map2 1.0
  
$ ./map2 -d ../../../devices-mouse1.list ../../../example.m2
thread 'tokio-runtime-worker' panicked at 'failed to open fd '/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-mouse': Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', /tmp/map2/map2/src/device/virtual_input_device.rs:88:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
$ sudo ./map2 -d ../../../devices-mouse1.list ../../../example.m2
thread 'tokio-runtime-worker' panicked at 'failed to open fd '/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-mouse': Os { code: 25, kind: Uncategorized, message: "Inappropriate ioctl for device" }', /tmp/map2/map2/src/device/virtual_input_device.rs:91:56
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

$ ./map2 -d ../../../devices-event4.list ../../../example.m2
thread 'tokio-runtime-worker' panicked at 'failed to open fd '/dev/input/by-path/pci-0000:00:13.0-usb-0:4:1.2-event-mouse': Os { code: 13, kind: PermissionDenied, message: "Permission denied" }', /tmp/map2/map2/src/device/virtual_input_device.rs:88:10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
 
$ sudo ./map2 -d ../../../devices-event4.list ../../../example.m2
failed to grab device '/dev/input/by-id/usb-Logitech_USB_Receiver-if02-event-mouse': Device or resource busy (os error 16)

I've closed several processes like Solaar that I thought might potentially be responsible but no luck..

Any ideas?

Getting UNSUPPORTED_PLATFORM error in X11

I was testing the window change events on my machine (a fairly standard Arch setup) but, for some reason, I encountered the UNSUPPORTED_PLATFORM error. Upon further investigation, I got to this line:

.map(|info| info.status.success() && String::from_utf8_lossy(&info.stdout) == "x11")

Testing the same code in Rust I found that, in my machine, info.stdout ends up as "x11\n", and that messes up the test.

Adding udev rule to access /dev/uinput as user in Arch Linux

Since I found a way to add the needed udev rule on my system, I figured I'd share it here.

Create file in /etc/udev/rules.d/, for example 01-uinput-permission.rules, with the following content:

SUBSYSTEM=="misc", KERNEL=="uinput", MODE="0660", GROUP="uinput"

Create /etc/modules-load.d/uinput.conf with:

uinput

(trick found here)

and

reboot

NOTE: I also happened to create the uinput usergroup, and adding my user to it beforehand, which could've helped as well.

I can't figure out where this code is failing.

// =================
// APASTRON KEYBINDS
// =================
sleep(2000); // sleep 2s
print("the active window class is: " + active_window_class());
// Main File
on_window_change(||{
if(active_window_class() == "steam_app_1264850"){
print("Apastron mappings loaded: " + active_window_class());
// maps 'esdf' to 'wasd'
e::w;
s::a;
d::s;
f::d;
c::KEY_CAPSLOCK;
v::BTN_THUMB;
BTN_1::z;
BTN_2::BTN_BACK;
BTN_3::BTN_FORWARD;
a::KEY_LEFTSHIFT;
g::b;
}else{
print("Apastron mappings reverted: " + active_window_class());
// maps 'esdf' back to 'esdf'
e::e;
s::s;
d::d;
f::f;
c::c;
v::v;
BTN_1::BTN_1;
BTN_2::BTN_2;
BTN_3::BTN_3;
a::a;
g::g;
}else if({send_modifier("{shift end}")}){
print("exiting apastron.m2 ");
execute("exit(0)");
}
});

Doesn't build

Traceback on cargo build --release:

   Compiling map2 v0.1.0 (/home/pp/git/map2)
error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/lib.rs:1:1
  |
1 | #![feature(type_ascription)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/lib.rs:2:1
  |
2 | #![feature(async_closure)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/lib.rs:3:1
  |
3 | #![feature(unboxed_closures)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/lib.rs:4:1
  |
4 | #![feature(trait_alias)]

  | ^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/lib.rs:5:1
  |
5 | #![feature(label_break_value)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/lib.rs:6:1
  |
6 | #![feature(destructuring_assignment)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0554]: `#![feature]` may not be used on the stable release channel
 --> src/lib.rs:7:1
  |
7 | #![feature(seek_convenience)]
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unused imports: `parse_key_action_with_mods`, `parse_key_sequence`
 --> src/runtime/evaluation.rs:7:30
  |
7 | use crate::parsing::parser::{parse_key_sequence, parse_key_action_with_mods};
  |                              ^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: `evdev_rs::enums::int_to_ev_key`
 --> src/runtime/evaluation.rs:8:5
  |
8 | use evdev_rs::enums::int_to_ev_key;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unused import: `evaluation::*`
 --> src/runtime/mod.rs:4:5
  |
4 | use evaluation::*;
  |     ^^^^^^^^^^^^^

warning: unused imports: `VerboseError`, `context`
  --> src/parsing/mod.rs:12:18
   |
12 | use nom::error::{context, VerboseError, ParseError};
   |                  ^^^^^^^  ^^^^^^^^^^^^

warning: unused import: `crate::runtime::evaluation::*`
  --> src/parsing/mod.rs:36:5
   |
36 | use crate::runtime::evaluation::*;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unused import: `nom::error::convert_error`
 --> src/parsing/parser.rs:2:5
  |
2 | use nom::error::convert_error;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unused import: `InputIter`
 --> src/parsing/custom_combinators.rs:1:40
  |
1 | use nom::{Compare, CompareResult, Err, InputIter, InputLength, InputTake, Parser, Slice, Offset};
  |                                        ^^^^^^^^^

warning: unused import: `nom::combinator::map_res`
 --> src/parsing/key_action.rs:2:5

  |
2 | use nom::combinator::map_res;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^

warning: unused import: `nom::combinator::consumed`
 --> src/parsing/variable.rs:2:5
  |
2 | use nom::combinator::consumed;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unnecessary parentheses around `if` condition
  --> src/parsing/error.rs:36:19
   |
36 |         } else if (other.input.input_len() > self.input.input_len()) {
   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove these parentheses
   |
   = note: `#[warn(unused_parens)]` on by default

warning: unused import: `tokio::sync::oneshot::Sender`
  --> src/device/virtual_input_device.rs:11:5
   |
11 | use tokio::sync::oneshot::Sender;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: unused import: `crate::device::virt_device`
  --> src/device/virtual_input_device.rs:15:5
   |
15 | use crate::device::virt_device;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: variable does not need to be mutable
   --> src/runtime/builtin_functions.rs:172:17
    |

172 |             let mut child_process = cmd.output().await
    |                 ----^^^^^^^^^^^^^
    |                 |
    |                 help: remove this `mut`
    |
    = note: `#[warn(unused_mut)]` on by default

warning: unreachable expression
   --> src/device/virtual_input_device.rs:141:13
    |
124 | /             loop {
125 | |                 match watch_rx.recv() {
126 | |                     Ok(event) => {
127 | |                         use FsWatchEvent::*;
...   |
139 | |                 }
140 | |             }
    | |_____________- any code following this expression is unreachable
141 |               Ok(())
    |               ^^^^^^ unreachable expression
    |
    = note: `#[warn(unreachable_code)]` on by default

warning: unreachable expression
   --> src/device/virtual_input_device.rs:177:9
    |
159 | /         loop {
160 | |             let fs_event = fs_event_rx.recv().await.unwrap();
161 | |             match fs_event {
162 | |                 FsWatchEvent::ADD(path) => {
...   |
175 | |             }
176 | |         }

    | |_________- any code following this expression is unreachable
177 |           Ok::<(), anyhow::Error>(())
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^ unreachable expression

warning: unreachable expression
  --> src/device/virtual_output_device.rs:24:9
   |
16 | /         loop {
17 | |             let msg = reader_rx.recv().await;
18 | |             let ev: InputEvent = match msg {
19 | |                 Some(v) => v,
...  |
22 | |             input_device.write_event(&ev)?;
23 | |         }
   | |_________- any code following this expression is unreachable
24 |           Ok(())
   |           ^^^^^^ unreachable expression

warning: unused import: `futures::StreamExt`
 --> src/parsing/mod.rs:6:5
  |
6 | use futures::StreamExt;
  |     ^^^^^^^^^^^^^^^^^^

error: aborting due to 7 previous errors; 17 warnings emitted

For more information about this error, try `rustc --explain E0554`.
error: could not compile `map2`.

To learn more, run the command again with --verbose.
warning: build failed, waiting for other jobs to finish...
error: build failed

Failing to properly remap capslock to meta/super key

I've been trying to remap CAPSLOCK to Super_L via your method,

{capslock down}::{
  caps_down = true;
  key_pressed = false;
  send("{ctrl down}");
};

{capslock up}::{
  caps_down = false;
  send("{ctrl up}");
  if (key_pressed == false){
    send("{esc}");
  }
};

where I tried replacing ctrl with win, super, hyper, Super_L, and 0xffeb. No success.

Would there be a way to achieve this by default, or should I be looking into modifying the source code itself?

Doesn't work

cat q.m2:

a::b;

RUST_BACKTRACE=1 ./target/release/map2 q.m2:

thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Permission denied (os error 13)', /home/pp/git/map2/src/device/virtual_input_device.rs:110:76
stack backtrace:
   0: rust_begin_unwind
             at /build/rustc-n7HJ8w/rustc-1.47.0+dfsg1+llvm/library/std/src/panicking.rs:475
   1: core::panicking::panic_fmt
             at /build/rustc-n7HJ8w/rustc-1.47.0+dfsg1+llvm/library/core/src/panicking.rs:85
   2: core::result::unwrap_failed
             at /build/rustc-n7HJ8w/rustc-1.47.0+dfsg1+llvm/library/core/src/result.rs:1220
   3: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   4: tokio::runtime::task::core::Core<T,S>::poll
   5: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
   6: tokio::runtime::task::harness::Harness<T,S>::poll
   7: std::thread::local::LocalKey<T>::with
   8: tokio::runtime::thread_pool::worker::Context::run_task
   9: tokio::runtime::thread_pool::worker::Context::run
  10: tokio::macros::scoped_tls::ScopedKey<T>::set
  11: tokio::runtime::thread_pool::worker::run
  12: tokio::runtime::task::core::Core<T,S>::poll
  13: <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
  14: tokio::runtime::task::harness::Harness<T,S>::poll
  15: tokio::runtime::blocking::pool::Inner::run
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.