input-remapper icon indicating copy to clipboard operation
input-remapper copied to clipboard

Macros consisting of multiple devices

Open ghost opened this issue 3 years ago • 10 comments

I want to set the following macro: When I press Ctrl-1, it should:

  1. Double click.
  2. Wait 170ms.
  3. Send Ctrl-` (Control-backtick)

I can do the double click with r(2, k(BTN_LEFT).w(5))

But I don't understand how to do the other commands.

ghost avatar Feb 20 '22 15:02 ghost

If I do

repeat(2, key(BTN_LEFT).wait(5)).wait(200).modify(Control_L, key(KEY_GRAVE))

then either only double click is working or Ctrl-` is working, depending on whether I set "mouse" or "keyboard"

ghost avatar Feb 20 '22 16:02 ghost

@jonasBoss this is a limitation with the global_uinputs system

sezanzeb avatar Feb 22 '22 09:02 sezanzeb

It is down to the fact that a mapping can have only one target, which is sensible for the usual mapping with only one output Action.

I don't think there is any reason to allow multiple targets for a mapping, except for macros. It should be easy to add a new macro function with_target(target, macro). The mapping would then be:

{
    "mapping":{
        "1,<code>,1":[
            "repeat(2, key(BTN_LEFT).wait(5))
            .wait(200)
            .with_target(
                keyboard,
                modify(Control_L, key(KEY_GRAVE))
            )",
            "mouse"
        ]
    }
}

If we change KeycodeMapper.macro_write to

    def macro_write(self, target_uinput):
        def f(ev_type, code, value, target=target_uinput):
            """Handler for macros."""
            logger.debug(
                f"Macro sending %s to %s", (ev_type, code, value), target
            )
            global_uinputs.write((ev_type, code, value), target)

        return f

the macro would be able to override the target specified by the mapping.

jonasBoss avatar Feb 22 '22 19:02 jonasBoss

yeah, something like this is good I think. Propagation of the target to child macros needs to be implemented as well

sezanzeb avatar Feb 22 '22 21:02 sezanzeb

or automatic mode after all (or both automatic mode and with_target)

While

It is totally possible to have multiple devices with the same capabilities

is true, we could alert if the macro is ambiguous. I.e. if two uinputs exist that can both do BTN_A, we display an error.

sezanzeb avatar Feb 23 '22 10:02 sezanzeb

or, since this is only really relevant for macros, we only support automatic mode via with_target and not via the dropdown (and throw an error if it is ambiguous somehow while editing)

with_target(
  "auto",
  repeat(2, key(BTN_LEFT).wait(5)).
  wait(200).
  modify(Control_L, key(KEY_GRAVE))
)

sezanzeb avatar Feb 23 '22 10:02 sezanzeb

yeah, something like this is good I think. Propagation of the target to child macros needs to be implemented as well

I don't think that would be any problem we would have the following add_with_target method:

class Macro:
    def add_with_target(target, macro):
        # validate target and macro
        async def task(handler):
            def new_handler(type_, code, value, target_=target):
                handler(type_, code, value, target_)
        
            await macro.run(new_handler)

        self.tasks.append(task)

I think that should automatically propagate the target at runtime

or, since this is only really relevant for macros, we only support automatic mode via with_target and not via the dropdown (and throw an error if it is ambiguous somehow while editing)

I think as a first measure we can just implement a basic with_target and maybe we can come up with some good ideas for a automatic target later.

jonasBoss avatar Feb 23 '22 16:02 jonasBoss

yeah sure, one by one. I'm still a bit busy right now due to university and other things, but I hope I'll manage to invest some time again later in spring

sezanzeb avatar Feb 23 '22 17:02 sezanzeb

How could I create a macro? If I try

with_target(
  "auto",
  repeat(2, key(BTN_LEFT).wait(5)).
  wait(200).
  modify(Control_L, key(KEY_GRAVE))
)

inside the GUI, it says Unknown function with_target. Should I put it somewhere else, or is it not possible for now?

ghost avatar Feb 28 '22 17:02 ghost

It is not yet implemented. Input-Remapper needs to be modified for that macro to work.

jonasBoss avatar Feb 28 '22 17:02 jonasBoss