# MouseKeys Plugin - separate keys for press and release?

**URL:** <https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877>\
**Category:** Programming\
**Created:** [December 19, 2017, 6:44am UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877 "2017-12-19T06:44:33Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [December 19, 2017, 6:44am UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/1 "2017-12-19T06:44:33Z")

</div>

Is there a way to have separate “press” and “release” keys for the MouseKeys plugin?

Right now it looks like there is just Key\_mouseBtnL, Key\_mouseBtnM, and Key\_mouseBtnR.

I’d like to have Key\_mouseBtnLpress and Key\_mouseBtnLrelease (and same for middle and right).

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [December 19, 2017, 7:11am UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/2 "2017-12-19T07:11:11Z")

</div>

You can do it with a pair of macros, something along these lines:

```auto
// Add MBL_P, MBL_R, etc to the macro enum
// MBL_P/_R stand for Mouse Button Left Press / Release

static struct {
 bool left, middle, right;
} mouse_buttons;

static void mousePressMacro(uint8_t macro_index, uint8_t key_state) {
  if (keyToggledOn(key_state)) {
    switch (macro_index) {
      case MBL_P:
        mouse_buttons.left = true;
        break;
      case MBM_P:
        mouse_buttons.middle = true;
        break;
      case MBR_P:
        mouse_buttons.right = true;
        break;
    }
  }

  switch (macro_index) {
    case MBL_P:
      if (mouse_buttons.left)
        kaleidoscope::hid::pressMouseButtons(KEY_MOUSE_BTN_L);
      break;
    case MBM_P:
      if (mouse_buttons.middle)
        kaleidoscope::hid::pressMouseButtons(KEY_MOUSE_BTN_M);
      break;
    case MBR_P:
      if (mouse_buttons.right)
        kaleidoscope::hid::pressMouseButtons(KEY_MOUSE_BTN_R);
      break;
  }
}

static void mouseReleaseMacro(uint8_t mouse_index, uint8_t key_state) {
  if (keyToggledOn(key_state)) {
    switch (macro_index) {
      case MBL_P:
        mouse_buttons.left = false;
        break;
      case MBM_P:
        mouse_buttons.middle = false;
        break;
      case MBR_P:
        mouse_buttons.right = false;
        break;
    }
  }

  // No need to explicitly release, we clear the report each cycle. 
  // Just mark the buttons released so the other macro doesn't re-add 
  // them to the report.
}

// Use M(MBL_P), M(MBL_R), etc on the keymap.

// And something like this in macroAction:
case MBL_P:
case MBM_P:
case MBR_P:
  mousePressMacro(macroIndex, keyState);
  break;
case MBL_R:
case MBM_R:
case MBR_R:
  mouseReleaseMacro(macroIndex, keyState);
  break;

```

And now some explanation: the `mouse_buttons` struct will be used to keep track of what state each button should be at. The `mousePressMacro` will set the appropriate button’s state to true whenever the key toggles on. As long as the state is true, this macro will add the button press to the report that gets sent to the host, thus, keep the button pressed. As macros are executed every cycle, even when there were no key events, this will keep the button pressed. The `mouseReleaseMacro` simply turns the state off. It does not release the button, because we clear the report every cycle. Therefore, if we do not re-add the press, it will get released.

Hope this helps.

---

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [December 19, 2017, 7:56am UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/3 "2017-12-19T07:56:31Z")

</div>

I’ll try it out, thanks!

---

<div class="post-metadata">

**Author:** ![fire](https://avatars.discourse-cdn.com/v4/letter/f/67e7ee/32.png) [@fire](https://community.keyboard.io/u/fire)\
**Post date:** [December 21, 2017, 3:08am UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/4 "2017-12-21T03:08:08Z")

</div>

algernon, I tried this and I had to add in a call to releaseMouseButtons to get the mouse buttons to release. Otherwise, even after fixing the typo where you used P instead of R in mouseReleaseMacro, the buttons wouldn’t release.

So it looks like the mouse buttons don’t get cleared each cycle the way the keys do.

Here’s the working code:

```
static struct {
 bool left, middle, right;
} mouse_buttons;

const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
  switch (macroIndex) {

  case MBL_P:
  case MBM_P:
  case MBR_P:
    mousePressMacro(macroIndex, keyState);
  break;

  case MBL_R:
  case MBM_R:
  case MBR_R:
    mouseReleaseMacro(macroIndex, keyState);
  break;

static void mousePressMacro(uint8_t macro_index, uint8_t key_state) {
  if (keyToggledOn(key_state)) {
    switch (macro_index) {
      case MBL_P:
        mouse_buttons.left = true;
        break;
      case MBM_P:
        mouse_buttons.middle = true;
        break;
      case MBR_P:
        mouse_buttons.right = true;
        break;
    }
  }

  switch (macro_index) {
    case MBL_P:
      if (mouse_buttons.left)
        kaleidoscope::hid::pressMouseButtons(KEY_MOUSE_BTN_L);
      break;
    case MBM_P:
      if (mouse_buttons.middle)
        kaleidoscope::hid::pressMouseButtons(KEY_MOUSE_BTN_M);
      break;
    case MBR_P:
      if (mouse_buttons.right)
        kaleidoscope::hid::pressMouseButtons(KEY_MOUSE_BTN_R);
      break;
  }
}

static void mouseReleaseMacro(uint8_t mouse_index, uint8_t key_state) {
  
 switch (mouse_index) {
    case MBL_R:
      if (mouse_buttons.left)
        kaleidoscope::hid::releaseMouseButtons(KEY_MOUSE_BTN_L);
      break;
    case MBM_R:
      if (mouse_buttons.middle)
        kaleidoscope::hid::releaseMouseButtons(KEY_MOUSE_BTN_M);
      break;
    case MBR_R:
      if (mouse_buttons.right)
        kaleidoscope::hid::releaseMouseButtons(KEY_MOUSE_BTN_R);
      break;
  }
 if (keyToggledOn(key_state)) {
        switch (mouse_index) {
          case MBL_R:
            mouse_buttons.left = false;
            break;
          case MBM_R:
            mouse_buttons.middle = false;
            break;
          case MBR_R:
            mouse_buttons.right = false;
            break;
        }
      }
    }
```

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [December 21, 2017, 8:25am UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/5 "2017-12-21T08:25:44Z")

</div>

> [@fire](#):
>
> So it looks like the mouse buttons don’t get cleared each cycle the way the keys do.

Oh. Did you install the libraries via the Arduino IDE, or via the [Arduino-Boards](https://github.com/keyboardio/Arduino-Boards) git repo? If the former, then the libraries may be out of date. In the past, MouseKeys did not clear the report like keys do, but as of recently, they do. The updated code will work with both versions, mind you, and I’m happy to hear you got it working!

---

<div class="post-metadata">

**Author:** ![pcurry](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/pcurry/32/63_2.png) [@pcurry](https://community.keyboard.io/u/pcurry)\
**Post date:** [May 21, 2018, 3:52pm UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/6 "2018-05-21T15:52:46Z")

</div>

This may explain the problem I’ve been having. I think I’m in the 3rd manufacturing run - would that have the pre-mousekeys fix code?

---

<div class="post-metadata">

**Author:** ![jamadagni](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jamadagni/32/2030_2.png) [@jamadagni](https://community.keyboard.io/u/jamadagni)\
**Post date:** [July 18, 2018, 3:21pm UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/7 "2018-07-18T15:21:01Z")

</div>

> [@algernon](#):
>
> As macros are executed every cycle, even when there were no key events, this will keep the button pressed.

Hello. Can you explain why this is so? I mean in my mind a macro is something that gets executed when you _do_ something, not even when you _don’t_ do something?

Is there any utility to that behaviour apart from this usecase (which would otherwise have required a plugin that is called upon each cycle)?

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [July 18, 2018, 3:24pm UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/8 "2018-07-18T15:24:20Z")

</div>

> [@jamadagni](#):
>
> Hello. Can you explain why this is so? I mean in my mind a macro is something that gets executed when you _do_ something, not even when you _don’t_ do something?

It’s not like that anymore. =)

It was like that because that was easy, and we had a few use-cases that were easier this way. But in the end, we opted to optimize out the idle case, and for the few cases that relied on it, we went with different solutions.

---

<div class="post-metadata">

**Author:** ![jamadagni](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jamadagni/32/2030_2.png) [@jamadagni](https://community.keyboard.io/u/jamadagni)\
**Post date:** [July 18, 2018, 3:32pm UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/9 "2018-07-18T15:32:07Z")

</div>

OK so does this mean that this macro you “prescribed” earlier will work as desired or not? I am looking for something like one-shot double tap stickiness to be released by a third tap or such for my mouse button (left will do) since I have much (diagrammatic) graphical work to do and a Kensington trackball for it but am now trying to use my KbdIO’s mouse abilities to avoid moving my hands around and wondering if it will suffice. (Only starting to get the hang of the warp drive today!) Obviously drag-drop is an important mouse usecase…

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [July 18, 2018, 3:38pm UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/10 "2018-07-18T15:38:29Z")

</div>

No, it will not work anymore, not as is. The [AppSwitcher](https://github.com/keyboardio/Kaleidoscope/tree/master/examples/AppSwitcher) example in the Kaleidoscope repo may be useful to see how to keep a key pressed nowadays.

As for one-shot double-tap sticky for a mouse key… hm. Should be doable with a thin, specialised plugin. On `onKeyswitchEvent`, it’d record the last pressed key. If that’s the left mouse button - again - flip a flag, and keep it pressed in `beforeReportingState`. If the flag is flipped, and the pressed key is the mouse button, unflip the flag.

That should be the gist of it, I think. If you need further help, please open a new thread, and I’ll try to help more.

---

<div class="post-metadata">

**Author:** ![jamadagni](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/jamadagni/32/2030_2.png) [@jamadagni](https://community.keyboard.io/u/jamadagni)\
**Post date:** [July 18, 2018, 3:44pm UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/11 "2018-07-18T15:44:47Z")

</div>

> [@algernon](#):
>
> The [AppSwitcher](https://github.com/keyboardio/Kaleidoscope/tree/master/examples/AppSwitcher) example in the Kaleidoscope repo may be useful to see how to keep a key pressed nowadays.

Specifically [this line in `Macros.cpp`](https://github.com/keyboardio/Kaleidoscope/blob/d945cba325765df669eed4e770d9aed68b2e1be3/examples/AppSwitcher/Macros.cpp#L62) and [this one in the sketch’s `loop` function](https://github.com/keyboardio/Kaleidoscope/blob/d945cba325765df669eed4e770d9aed68b2e1be3/examples/AppSwitcher/AppSwitcher.ino#L67)?

---

<div class="post-metadata">

**Author:** ![algernon](https://yyz1.discourse-cdn.com/flex031/user_avatar/community.keyboard.io/algernon/32/4404_2.png) [@algernon](https://community.keyboard.io/u/algernon)\
**Post date:** [July 18, 2018, 6:43pm UTC](https://community.keyboard.io/t/mousekeys-plugin-separate-keys-for-press-and-release/877/12 "2018-07-18T18:43:00Z")

</div>

Yep, exactly those two lines.
