Control key modifier

I’ve got most of the layout on my keyboard set up how i like it, rearranged the thumb keys,added a capslock plugin and redefined my Any key to send Ctrl-Alt-Delete. I’d now like to get around the lack of a £ character (yes, I’m English). Setting my keyboard to U.S. solved all my shifting issues apart from not being able to type a £. I was thinking Ctrl-3 would be a nice key combination to generate one. How do I trap a Ctrl modified keypress in order to send the £ character? Ctrl doesn’t have a layer, so i’m wondering if its tied up in the OS like shift is.

Any help would be gratefully appreciated.

Rob

Control and Shift are both modifiers that are sent to the computer in the key report, so control + 3 sends those two keycodes to the computer together. If you want that combination to give you a certain character, you’ll have to have the operating system do that in your OS keymap.

More generally, to get the £ character, you’ll need to have your OS involved in some way, so that some key combination or sequence will be treated as that character. Then you can get that combo or sequence to be sent by the keyboard using various different means in Kaleidoscope. The first step is figuring out how to get that character on the OS side.

An interesting way to go about this might be to write your own macro for it. Assign that to the 3 key, and then you can tell if it’s shifted, control, unmodified, etc.

1 Like

Sounds promising. I’m ok with macros, but I’m having difficulty finding documentation on detecting if ctrl or shift is pressed.

The function you want is kaleidoscope::hid::wasModifierKeyActive(). For example:

if (kaleidoscope::hid::wasModifierKeyActive(Key_LeftShift) || 
    kaleidoscope::hid::wasModifierKeyActive(Key_RightShift)  ) {
  // do stuff
}

Hi,
I tried this :

case MACRO_3:

if (kaleidoscope::hid::wasModifierKeyActive(Key_LeftControl) || 
    kaleidoscope::hid::wasModifierKeyActive(Key_RightControl)  ) 
{
  return MACRODOWN(D(NonUsPound));
}
else
{
  return MACRODOWN(D(3));
}
break;

which gives me a 3 as normal, but doesn’t handle shift (I suspect I have to check for that too).
CTRL 3 gives me nothing appearing. I also tried KeypadPoundSign, which doesn’t work either.

I’m pretty sure you’ll also need to send a release of the control keys in order to get the output you want.

Here’s a solution for you using macros that works with a US-qwerty layout under windows. This is a windows-specific solution, but since you bound one key to ctrl+alt+delete, I assume you’re using windows anyways.

Steps:

Define MACRO_THREE in your macros enum

enum { MACRO_VERSION_INFO,
       MACRO_ANY,
       /* ... */
       MACRO_THREE
     };

Update your macros section:

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

  case MACRO_VERSION_INFO:
    versionInfoMacro(keyState);
    break;

  case MACRO_ANY:
    anyKeyMacro(keyState);
    break;

  /* ... */

  case MACRO_THREE:
    macroThree(keyState);
    break;
  }
  
  return MACRO_NONE;
}

Add a definition for “macroThree”

/* Send British pound sign on ctrl+3 for US-QWERTY layout under windows */
static void macroThree(uint8_t key_state) {
  /* Ensure we only fire on initial keypress. Don't handle repeat events */
  if (keyToggledOn(key_state)) {
    if(
      kaleidoscope::hid::wasModifierKeyActive(Key_LeftShift)
      || kaleidoscope::hid::wasModifierKeyActive(Key_RightShift)
    ) {
      /* Send a shifted 3: hash sign */
      Macros.play(MACRO(D(LeftShift),T(3),U(LeftShift)));
    } else if(
      kaleidoscope::hid::wasModifierKeyActive(Key_LeftControl)
      || kaleidoscope::hid::wasModifierKeyActive(Key_RightControl)
    ) {
      /* This is windows-only: type alt+0163 on numpad to get British Pound symbol */
       Macros.play(MACRO(D(LeftAlt),W(25),T(Keypad0),T(Keypad1),T(Keypad6),T(Keypad3),W(25),U(LeftAlt)));
    } else {
      /* Tap the 3 if unshifted and un-controlled */
      Macros.play(MACRO(T(3)));
    }
  }
}

Finally, update your keymap to call the macro:

M(MACRO_THREE)

Thanks for that, i put the code in and it worked for my right ctrl key but not for my left. This is weird, looking at the if statement, it should work the same way…

I will see if I can get it to work. I couldn’t get it working on my left one, either, but I assumed it was because I put it on my function layer for testing, and my left control is mapped to alt on my function layer on my layout.

As an aside to this, I was trying to redefine CTRL-H & CTRL-L as start-of-line and end-of-line respectively. I used the same code structure you supplied for the £ sign issue. Interestingly enough, both left and right controls work ok.

The problem I have now is that instead of sending a Key_Home to put the cursor at the start of the line, it sends a Key_PageUp for some reason, and similarly a Key_PageDown instead of Key_End.

The code is as follows for the H key:

static void macroStartLine(uint8_t key_state) 
{
  /* Ensure we only fire on initial keypress. Don't handle repeat events */
  if (keyToggledOn(key_state)) {
    if  (
          kaleidoscope::hid::wasModifierKeyActive(Key_LeftShift)
          || kaleidoscope::hid::wasModifierKeyActive(Key_RightShift)
        ) 
    {
      /* Send a Capital H */
      Macros.play(MACRO(D(LeftShift),T(H),U(LeftShift)));
    } 
    else if (
              kaleidoscope::hid::wasModifierKeyActive(Key_LeftControl)
              || kaleidoscope::hid::wasModifierKeyActive(Key_RightControl)
            ) 
    {
      /* Send Home Key */
       Macros.play(MACRO(T(Home)));
    } 
    else 
    {
      /* Tap the h if unshifted and un-controlled */
      Macros.play(MACRO(T(H)));
    }
  }
}

Are you sure it’s sending Key_PageUp, and it’s not just that sending control + Key_Home has the same effect?

1 Like

I suspect that what you need to do is have the macro first release both control keycodes, then tap Key_Home.

2 Likes

It definitely seems to me like you should unset the control character before sending and see if that fixes it. I suspect it will.

I also apologize for not getting back to you more quickly on the pound / 3 issue. I’ve been super busy in the middle of a move and don’t have my workstation properly setup yet. Once I get it set back up, I’ll take a look and see if I can get both left and right controls to work as expected.

1 Like

Thanks to merlin and bagels, I finally found time to try your suggestion, and it sorted out the problem. :smile:

1 Like