libratbag / libratbag

A DBus daemon to configure input devices, mainly high-end and gaming mice
MIT License
2.1k stars 257 forks source link

Logitech G600 G-Key Can't be set to CTRL, SHIFT, or ALT #710

Open ghost opened 5 years ago

ghost commented 5 years ago

https://github.com/libratbag/piper/issues/342

terencode commented 5 years ago

Also affects G502

guppy42 commented 5 years ago

Any chance support for this will be added ?

FFY00 commented 5 years ago

Any chance support for this will be added ?

Yes, but it will be awhile. Right now we have more pressing matters.

AtomToast commented 5 years ago

I noticed that using keybindings such as Shift + A do work. It only gives an error when it's only the modifier key

guppy42 commented 5 years ago

I noticed that using keybindings such as Shift + A do work. It only gives an error when it's only the modifier key

The 'only modifier' case is also where it's interesting, using a standard WASD setup reaching ALT and CTRL can be quite anoying / requires extensive finger gymnastics. Having them on the mouse would be very, very helpfull for games such as MMOs with lots of keybinds.

Hope the feature gets added in the foreseeable future, currently researching virtual HID devices but it seems like a very hacky way to do it

gerardlouw commented 4 years ago

I have a workaround for this:

ratbagctl singing-gundi profile 0 button 5 action set macro +KEY_LEFTALT KEY_RESERVED -KEY_LEFTALT

I'm not sure what KEY_RESERVED is, but it doesn't seem to do anything for me. If this actually triggers some unwanted action for you, looking at input.h, some other options might be KEY_UNKNOWN, KEY_F24, or similar.

So far I've tested using the G-Key as Alt both for my KDE shortcuts (e.g. G-Key + F2 now opens KRunner, G-Key + left-click drags the window) and in World of Warcraft (I am able to to self-cast by pressing G-Key with another shortcut).

guppy42 commented 4 years ago

@gerardlouw can't make that work at all

also it seems that it would just press left alt 'unkown' and release it really quickly ? Where as what we are trying to achive is to have say mouse 3 behave as ALT - so while it's being pressed +KEY_LEFTALT is being sendt, and when released it will send -KEY_LEFTALT (once)

Tried with both ALT and CTRL and neigther ALT+F2 or CTRL-W would trigger in cinnamon when using the mouse :(

gerardlouw commented 4 years ago

Here is a demo of what xev reports when I press down my G-Key with the above settings. I did both quick and slow press-and-release for demonstration purposes.

animation

guppy42 commented 4 years ago

wierd ran the same xev as you triggering mouse 3 which I bound the macro to I get all 0.

It's a G502 Hero but I dont see why that should make a difference

Cincidial commented 4 years ago

I found the workaround using KEY_RESERVED would not be accepted by the device, however, if you change KEY_RESERVED to instead be an existing key that you never use you can get modifiers like ctrl to work.

For example, I bound the macro ctrl down + numlock (down and up) + ctrl up to a button. Now when I press that button numlock is of course triggered, but I don't really care as my keyboard doesnt have a numpad. When the button is being held though I can input another key, like A and I get a select all command.

I also tried F1, but there were some cases were things like menus were triggered.

tldr; Find a key that isn't a modifier and won't do anything to your workflow when pressed/held and put it between the press and release of the modifier key in the macro. Now use the modifier macro as originally intended

ghost commented 4 years ago

Nice temp solution seems to work for now

I found the workaround using KEY_RESERVED would not be accepted by the device, however, if you change KEY_RESERVED to instead be an existing key that you never use you can get modifiers like ctrl to work.

For example, I bound the macro ctrl down + numlock (down and up) + ctrl up to a button. Now when I press that button numlock is of course triggered, but I don't really care as my keyboard doesnt have a numpad. When the button is being held though I can input another key, like A and I get a select all command.

I also tried F1, but there were some cases were things like menus were triggered.

tldr; Find a key that isn't a modifier and won't do anything to your workflow when pressed/held and put it between the press and release of the modifier key in the macro. Now use the modifier macro as originally intended

ghost commented 4 years ago

I have currently a differen issue on ratbagd (Is already open), but if it finally works, I would like to do exactly the same. So I push this, even though there is a workaround. In the Logitech gaming software on windows I was able to put CTRL, ALT and SHIFT to the three thumb buttons of my G500s

mlabarca commented 4 years ago

Hi! Just came in here to mention that workaround with numlock is still working well for using the gshift with ffxiv and getting the ctrl key recognized. At first try in game when mapping keybinds it gets recognized with numlock, but strangely it detects the ctrl key second time around.

sam-goode commented 4 years ago

Out of interest, if the second mode function were to be addressed would that effectively solve this? https://github.com/libratbag/libratbag/issues/598

If you have a button to hold for second mode, and could then assign each of the other buttons to modifier + whatever, then it seems like that would give even more flexibility by allowing different modifiers (at the relatively minor cost of having to configure them for each button)

e.g.

guppy42 commented 4 years ago

No the idea is so effectively move the modifier button to the mouse ( eg. having mouse 7 trigger ctrl ) that way while it's held down any keyboard press would behave as if you pressed ctrl+ it.

sam-goode commented 4 years ago

Ah good point I hadn't considered keyboard presses as well

bluemner commented 4 years ago

With the latest build from master I ran the following commands and they all worked as modifiers, while you press the button it acts like you are holder down shift, ctrl or alt

ratbagctl -v "Logitech Gaming Mouse G600" button 8 action set macro +KEY_LEFTSHIFT KEY_RESERVED -KEY_LEFTSHIFT && echo "worked $?" || echo "failed $?"
ratbagctl -v "Logitech Gaming Mouse G600" button 9 action set macro +KEY_LEFTALT KEY_RESERVED -KEY_LEFTALT && echo $? || echo $?
ratbagctl -v "Logitech Gaming Mouse G600" button 9 action set macro +KEY_LEFTCTRL KEY_RESERVED -KEY_LEFTCTRL && echo $? || echo $

However I did encounter an issue where you have to run the command twice sometimes for it to be sent to the device. That is not an issue with the command but is tied to this #1036.

guppy42 commented 4 years ago

It's a valiant attempt @bluemner but the problem with that solution is that its basically equivalent to repeatedly smashing the modifier autofire style - there is a good risk that you would hit the key without the modifier ( triggering another ability ). or in the case were you need to keep the combination pressed for x time the timer will reset constantly.

ZTerminator77 commented 4 years ago

I found the workaround using KEY_RESERVED would not be accepted by the device, however, if you change KEY_RESERVED to instead be an existing key that you never use you can get modifiers like ctrl to work.

For example, I bound the macro ctrl down + numlock (down and up) + ctrl up to a button. Now when I press that button numlock is of course triggered, but I don't really care as my keyboard doesnt have a numpad. When the button is being held though I can input another key, like A and I get a select all command.

I also tried F1, but there were some cases were things like menus were triggered.

tldr; Find a key that isn't a modifier and won't do anything to your workflow when pressed/held and put it between the press and release of the modifier key in the macro. Now use the modifier macro as originally intended

This is my first time scripting but I would really like to implement this workaround so my G600 can have a modifier key. Creating the macro makes complete sense but I'm not sure how to "change KEY_RESERVED to... an existing key." I've messed around with variations on the scripts previously mentioned with no luck. Would someone mind helping this code noob out and posting the exact code that I can paste into GHub script? This is my own sad attempt:

function OnEvent(PROFILE_ACTIVATED) --KEY_NUMLOCK KEY_RESERVED -KEY_NUMLOCK end

bluemner commented 4 years ago

Based @guppy42 comments and some of my testing the built in macro system sends out a repeat of the macro every ~500-1000ms. I have not yet found a way to change this in the mouses profile and am unsure if its possible to change this behavior as the windows software produces the same results except when in running in application mode. As of now Ratbagd doesn't have an application mode so another method will have to be used.

@ZTerminator77 As a work around you could

example map: key_down button 18 --> +LEFT_SHIFT key_up button 18 --> -LEFT_SHIFT

For 3rd party options

Note both of these options will add a few seconds of delay as it will go from kernel -> program -> virtual key press.

ghost commented 4 years ago

Hello some additional information from my G604: The KEY_RESERVED does not work here. On my old G500s the Logitech Gaming Software but a Makro up like explained from @bluemner with KEY_RESERVED in between. This is not possible for the G604. The other workaround with using a unused key like NUMLOCK or in my case the deviding button right from NUMLOCK in between still works as a charm. It can easily be applied with piper

Gargarvore commented 3 years ago

So i had the same issue and resolved it with quite a simple method, after questioning my intelligence and almost burning my computer science degree. what i did was: start menu > settings > Easy of Access > Interaction Keyboard > Turned off "use filter keys"

bluemner commented 3 years ago

@Gargarvore this project is for Linux kernel not NT (windows). The issue out lined is with how the Logitech implements the firmware for the device.

When running Linux: 3 events are registered

2 called "Logitech Gaming Mouse G600"

The other is "Logitech Gaming Mouse G600 Keyboard" this has information to emulate keyboard presses

when running a command like sudo evtest you get the following support keys

Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 1 (KEY_ESC)
    Event code 2 (KEY_1)
    Event code 3 (KEY_2)
    Event code 4 (KEY_3)
    Event code 5 (KEY_4)
    Event code 6 (KEY_5)
    Event code 7 (KEY_6)
    Event code 8 (KEY_7)
    Event code 9 (KEY_8)
    Event code 10 (KEY_9)
    Event code 11 (KEY_0)
    Event code 12 (KEY_MINUS)
    Event code 13 (KEY_EQUAL)
    Event code 14 (KEY_BACKSPACE)
    Event code 15 (KEY_TAB)
    Event code 16 (KEY_Q)
    Event code 17 (KEY_W)
    Event code 18 (KEY_E)
    Event code 19 (KEY_R)
    Event code 20 (KEY_T)
    Event code 21 (KEY_Y)
    Event code 22 (KEY_U)
    Event code 23 (KEY_I)
    Event code 24 (KEY_O)
    Event code 25 (KEY_P)
    Event code 26 (KEY_LEFTBRACE)
    Event code 27 (KEY_RIGHTBRACE)
    Event code 28 (KEY_ENTER)
    Event code 29 (KEY_LEFTCTRL)
    Event code 30 (KEY_A)
    Event code 31 (KEY_S)
    Event code 32 (KEY_D)
    Event code 33 (KEY_F)
    Event code 34 (KEY_G)
    Event code 35 (KEY_H)
    Event code 36 (KEY_J)
    Event code 37 (KEY_K)
    Event code 38 (KEY_L)
    Event code 39 (KEY_SEMICOLON)
    Event code 40 (KEY_APOSTROPHE)
    Event code 41 (KEY_GRAVE)
    Event code 42 (KEY_LEFTSHIFT)
    Event code 43 (KEY_BACKSLASH)
    Event code 44 (KEY_Z)
    Event code 45 (KEY_X)
    Event code 46 (KEY_C)
    Event code 47 (KEY_V)
    Event code 48 (KEY_B)
    Event code 49 (KEY_N)
    Event code 50 (KEY_M)
    Event code 51 (KEY_COMMA)
    Event code 52 (KEY_DOT)
    Event code 53 (KEY_SLASH)
    Event code 54 (KEY_RIGHTSHIFT)
    Event code 55 (KEY_KPASTERISK)
    Event code 56 (KEY_LEFTALT)
    Event code 57 (KEY_SPACE)
    Event code 58 (KEY_CAPSLOCK)
    Event code 59 (KEY_F1)
    Event code 60 (KEY_F2)
    Event code 61 (KEY_F3)
    Event code 62 (KEY_F4)
    Event code 63 (KEY_F5)
    Event code 64 (KEY_F6)
    Event code 65 (KEY_F7)
    Event code 66 (KEY_F8)
    Event code 67 (KEY_F9)
    Event code 68 (KEY_F10)
    Event code 69 (KEY_NUMLOCK)
    Event code 70 (KEY_SCROLLLOCK)
    Event code 71 (KEY_KP7)
    Event code 72 (KEY_KP8)
    Event code 73 (KEY_KP9)
    Event code 74 (KEY_KPMINUS)
    Event code 75 (KEY_KP4)
    Event code 76 (KEY_KP5)
    Event code 77 (KEY_KP6)
    Event code 78 (KEY_KPPLUS)
    Event code 79 (KEY_KP1)
    Event code 80 (KEY_KP2)
    Event code 81 (KEY_KP3)
    Event code 82 (KEY_KP0)
    Event code 83 (KEY_KPDOT)
    Event code 85 (KEY_ZENKAKUHANKAKU)
    Event code 86 (KEY_102ND)
    Event code 87 (KEY_F11)
    Event code 88 (KEY_F12)
    Event code 89 (KEY_RO)
    Event code 90 (KEY_KATAKANA)
    Event code 91 (KEY_HIRAGANA)
    Event code 92 (KEY_HENKAN)
    Event code 93 (KEY_KATAKANAHIRAGANA)
    Event code 94 (KEY_MUHENKAN)
    Event code 95 (KEY_KPJPCOMMA)
    Event code 96 (KEY_KPENTER)
    Event code 97 (KEY_RIGHTCTRL)
    Event code 98 (KEY_KPSLASH)
    Event code 99 (KEY_SYSRQ)
    Event code 100 (KEY_RIGHTALT)
    Event code 102 (KEY_HOME)
    Event code 103 (KEY_UP)
    Event code 104 (KEY_PAGEUP)
    Event code 105 (KEY_LEFT)
    Event code 106 (KEY_RIGHT)
    Event code 107 (KEY_END)
    Event code 108 (KEY_DOWN)
    Event code 109 (KEY_PAGEDOWN)
    Event code 110 (KEY_INSERT)
    Event code 111 (KEY_DELETE)
    Event code 113 (KEY_MUTE)
    Event code 114 (KEY_VOLUMEDOWN)
    Event code 115 (KEY_VOLUMEUP)
    Event code 116 (KEY_POWER)
    Event code 117 (KEY_KPEQUAL)
    Event code 119 (KEY_PAUSE)
    Event code 121 (KEY_KPCOMMA)
    Event code 122 (KEY_HANGUEL)
    Event code 123 (KEY_HANJA)
    Event code 124 (KEY_YEN)
    Event code 125 (KEY_LEFTMETA)
    Event code 126 (KEY_RIGHTMETA)
    Event code 127 (KEY_COMPOSE)
    Event code 128 (KEY_STOP)
    Event code 129 (KEY_AGAIN)
    Event code 130 (KEY_PROPS)
    Event code 131 (KEY_UNDO)
    Event code 132 (KEY_FRONT)
    Event code 133 (KEY_COPY)
    Event code 134 (KEY_OPEN)
    Event code 135 (KEY_PASTE)
    Event code 136 (KEY_FIND)
    Event code 137 (KEY_CUT)
    Event code 138 (KEY_HELP)
    Event code 183 (KEY_F13)
    Event code 184 (KEY_F14)
    Event code 185 (KEY_F15)
    Event code 186 (KEY_F16)
    Event code 187 (KEY_F17)
    Event code 188 (KEY_F18)
    Event code 189 (KEY_F19)
    Event code 190 (KEY_F20)
    Event code 191 (KEY_F21)
    Event code 192 (KEY_F22)
    Event code 193 (KEY_F23)
    Event code 194 (KEY_F24)
    Event code 240 (KEY_UNKNOWN)
  Event type 4 (EV_MSC)
    Event code 4 (MSC_SCAN)
Key repeat handling:
  Repeat type 20 (EV_REP)
    Repeat code 0 (REP_DELAY)
      Value    250
    Repeat code 1 (REP_PERIOD)
      Value     33

The problem is REP_PERIOD and REP_DELAY which effects the repeat per cycle. Also the fact that the mouse emulates key press stokes with KEY DOWN and KEY_UP Action.

SO KEY_LEFTSHIFT↓ + KEY_A↕ + KEY_LEFTSHIFT↑ is needed. With out a KEY_DOWN and KEY_UP pair the profile gets corrupted and the key event is pulled from the next register in memory.

What the issue above is they want BUTTON_DOWN to map to KEY_LEFTSHIFT↓ and BUTTON_UP to map to KEY_LEFTSHIFT↑ which doesn't seem possible with how the on board controller is written even on windows the issues is present.

So @Gargarvore what you did on windows was change the value similar to REP_DELAY on Linux which changed the delay.

One solution for this is to map keys using a software that loads a pre-configured profile into the G600 and maps the pre-configured profile to a config file that the user wants. That way in Linux you can capture the BUTTON_DOWN and BUTTON_UP events. The only problem is the need to find a way to save non-persistent profiles to the device so when you unplug the G600 it should have the 3 profiles that where on the device originally not the pre-configured one.

Gargarvore commented 3 years ago

@bluemner oh I did not notice. I'm so sorry, google send me here, and I just assumed it was a windows issue, my bad.

Rettokid commented 3 years ago

I found the workaround using KEY_RESERVED would not be accepted by the device, however, if you change KEY_RESERVED to instead be an existing key that you never use you can get modifiers like ctrl to work. For example, I bound the macro ctrl down + numlock (down and up) + ctrl up to a button. Now when I press that button numlock is of course triggered, but I don't really care as my keyboard doesnt have a numpad. When the button is being held though I can input another key, like A and I get a select all command. I also tried F1, but there were some cases were things like menus were triggered. tldr; Find a key that isn't a modifier and won't do anything to your workflow when pressed/held and put it between the press and release of the modifier key in the macro. Now use the modifier macro as originally intended

This is my first time scripting but I would really like to implement this workaround so my G600 can have a modifier key. Creating the macro makes complete sense but I'm not sure how to "change KEY_RESERVED to... an existing key." I've messed around with variations on the scripts previously mentioned with no luck. Would someone mind helping this code noob out and posting the exact code that I can paste into GHub script? This is my own sad attempt:

function OnEvent(PROFILE_ACTIVATED) --KEY_NUMLOCK KEY_RESERVED -KEY_NUMLOCK end

I'm in the same situation. Could please someone help us/me? I'm new to this and I'm not sure how to do it. Thanks

bluemner commented 3 years ago

@Rettokid Option 1 use Piper

Option 2 use ratbagctl:

Below is how to use ratbagctl, use at your own risk.

kei2e commented 3 years ago

When I tried doing this in Piper, I couldn't: G-key cannot be set to Shift on my G600.

Here's the weird thing: I could assign it via ratbagctl:

ratbagctl -v "Logitech Gaming Mouse G600" button 5 action set macro +KEY_LEFTSHIFT KEY_RESERVED -KEY_LEFTSHIFT

It is working just fine, it appears!

ExperiBass commented 3 years ago

@Rettokid Option 1 use Piper

Option 2 use ratbagctl:

Below is how to use ratbagctl, use at your own risk.

* Step 1: Get device name
  ```shell
   ratbagctl
  ```

  > hooting-chinchilla:  Logitech Gaming Mouse G600

* Step 2: get info
  ```shell
  ratbagctl "Logitech Gaming Mouse G600" info
  ```

  Take note of how many buttons you have if you have `Number of Buttons: 20`.

  * Step 2.5:
    If you have `20` then you don't have the patch yet for the the g-shift and will have to   compile from source to get that fix (optional).

* Step 3: Get the button info
  Get button info to check that it is the correct button. in command below replace `$N` with the button you want. [G600 button index](https://github.com/libratbag/libratbag/blob/master/src/driver-logitech-g600.c#L106-L146) take note of the comments on the right of the code and the number to the left  add example `   { 6, RATBAG_BUTTON_TYPE_PROFILE_CYCLE_UP }, // G07` in code means  `6` maps to `G07`.
    ratbagctl "Logitech Gaming Mouse G600" button $N action get
* Step 4: Set button
  > DON'T USE NUMBERS GRATER THAN N-1 WHERE N IS `Number of Buttons: 20` FROM THE PREVIOUS STEP 2!!!!
  > ALSO DON'T USE BUTTON 20 as this is where color information is located for G-SHIFT.

  ```shell
  ratbagctl "Logitech Gaming Mouse G600" button $N action set macro +KEY_LEFTSHIFT KEY_RESERVED -KEY_LEFTSHIFT && echo "worked $?" || echo "failed $?"
  ```

  Change the macro to the key combination you want. You must have a matching `-` at the end to every `+` plus used or else you will have issues
  > You May have apply Step 4 two times as there is sometimes an issue with the command being sent in Ubuntu

* Step 5: Verify
  Re Run Step 3 value should have changed

This doesnt work for my g502 E: changing KEY_RESERVED to a key that doesnt exist on my keyboard worked

Riven-Spell commented 2 years ago

On a G502 Lightspeed, I've been able to successfully bind just a modifier with + and - macros, but the lone modifier does not work. This additionally bugs piper out somewhat in that piper thinks something has gone wrong when profile-switching. That said, the buttons work fine when switching profiles for me.

ratbagctl screaming-chipmunk button 3 action set macro +KEY_LEFTCTRL -KEY_LEFTCTRL ratbagctl screaming-chipmunk button 4 action set macro +KEY_LEFTALT -KEY_LEFTALT

BioBox commented 2 years ago

So does this macro actually work? Because it seems like @guppy42's comment still applies:

It's a valiant attempt @bluemner but the problem with that solution is that its basically equivalent to repeatedly smashing the modifier autofire style - there is a good risk that you would hit the key without the modifier ( triggering another ability ). or in the case were you need to keep the combination pressed for x time the timer will reset constantly.

Is anybody having issues with this? I don't see how this would properly work because you'd be hitting a key when the modifer isn't held down - because your macro is rapid-firing it.

foresto commented 2 years ago

@BioBox I tested mapping one of the numbered side buttons to Control, Shift, and Alt. The command I used looked like this:

ratbagctl device-foo profile 0 button 17 action set macro +KEY_LEFTSHIFT KEY_RESERVED -KEY_LEFTSHIFT

It worked consistently, both as stand-alone key taps and in combination with other keys and mouse clicks. xev showed a single event when I pressed the button, and another when I released it. Holding it produced no additional events.

I guess it's possible that this behavior might vary with different G600 firmware versions or input driver versions, but I don't have a convenient way to test those.

bluemner commented 2 years ago

The firmware on the G600 mouse will prevent CTRL, SHIFT, ALT from working the way some people would like. On the windows side I believe this is fixed in the software rather than firmware. So in order to get the same functionality a program would need to grab the device and override the default functionality.

As such I have have been working on a sample test program that will override input from G600 and allows user to map keys via yaml configuration file. https://github.com/bluemner/hid-mapper-sample#g600-linux-driver. I tried to implement both modifier and toggle key support. so you can set G9 be shift down and G10 be shift up if you so wish.

This code attempts to mimic capabilities of the "software mode" by grabbing the G600 input and sending overrides to a virtual keyboard (This virtual keyboard should support 5.x Linux Kernel Input keys) . Not sure how anti cheat will behave with this method, use at your own risk....

Note: right now only the g600 is working as I hard coded the device memory address in the c code.

Need to figure out how to load a HID descriptor and grab the correct input paths / addresses from device to support all HID devices.

FlatCapElectronics commented 1 month ago

My case: Linux Mint 21.2 Victoria (Ubuntu 22.04 jammy base) ratbag device: "Logitech G203 Prodigy Gaming Mouse"

My goal was to use the forward/back buttons as 'press to apply shift' and 'press to apply control' modifiers in an application running under Wine.

After reading the above and fighting with ratbag/piper for a while I looked for a different solution. There's an application called 'Input Remapper' available that accomplishes my goal in software, and after testing it and finding it to work I thought I'd leave this here for anyone that might be struggling to solve the same problem.

avstoyanov commented 3 weeks ago

It has been a while since I did it and I thought I wrote a comment here, but the solution with mapping a key that doesn't do anything along with the modifier works perfectly.

I have a G502, and I mapped one of the buttons to shift down, (one of the media buttons i can't remember), shift up and it works.

It even works in combination with some of the other keybindings, meaning I can ctrl+shift+c/v for when I want to copy or paste from a terminal, and can use the shift functionally almost like a g-shift through keyboard shortcuts.

I used a similar solution to the KEY_RESERVED ones above but instead of KEY_RESERVED I just did one of the media buttons up and down. It didn't actually function as a media button for some reason so I just rolled with it...