Can I edit mapping for Caps Lock + Control?

In keymap, I duplicated and modified “Apple Aluminium Extended International” in order to make the mapping exactly as the keyboard I’m using.

However, I noticed that no matter which keyboard layout I choose, I get in trouble when having Caps Lock enabled and holding down Control. It’s easiest to observe in the Terminal running nano:

Open the terminal, type ‘nano’

Press Caps Lock, so it’s on, now hold down Control and press ‘x’.

Instead of exiting nano, an ‘x’ is going to the file.

-No matter which keyboard layout I use, I get this problem, is there a way to fix it, or should I file a bug-report ?

(Bug 20052 seems to touch the problem, but I’m not sure it’s the exact same problem)

1 Like

Yes, file a bug report.

1 Like

Filed as bug #20175

It is indeed the same problem as 20052. Some (but not all) keymaps do not define the right values for shift+control (and caps+control which is the same).

I didn’t have time to go over all keymaps and replace the shift+control layer with the control characters from the base control layer.

2 Likes

OK, so it’s fixable in the keyboard layouts, that’s good news (I think). :wink:

-I’ll probably try and see if I can fix my customized danish Apple Alu Extended Int. layout. :slight_smile:

Thank you for diving into this.

If I do a …

keymap -d >myKeymap

… then I get 9 columns, but none of them contains control+shift.

So how do I define the layout for that ?

-Do you have a working keymap file, which I can try out ?

Non-working:

  • All Apple Aluminium
  • Thinkpad
  • Fizzbook
  • Generic 104
  • Generic 105

(I tried danish and US versions of the above, but none of them are handling the control key correctly)

You are mixing up keymaps and keyboard layout definitions. These do absolutely nothing except change how the keys are shown in keymap preferences.

The keymaps are for different languages.

But other than that, you’re right, the problem is not solvable at the keymap level as I thought. It’s rather a matter of priorities between modifiers: control should override caps lock, but currently the opposite happens. So that will need a change in the code, apparently.

2 Likes

I completely agree; control needs highest priority.

I think it’s great, that we’re able to assign our own control-codes to each key; especially in case a key has a unicode code point, we’d still be able to output 0x01 on that key (or even special symbols).

Sorry about the mixup; Yes, keymapping is ‘what’ a key does, layout is ‘where’ the key is located (and is completely unrelated.

Well, I guess it’s due to src/kits/shared/keymap.cpp , in BKeymap::Offset() which support only these modifiers combinaison:

  • shift
  • caps lock
  • shift + caps lock
  • control
  • option
  • option + shift
  • option + caps lock
  • option + caps lock + shift
  • default mapping

Control + caps lock is not explicitly catched, therefore when Control + x is pressed while caps lock is also on, it fall on default mapping => “x” (lowercase).

Maybe we need to add something like:

int32
BKeymap::Offset(uint32 keyCode, uint32 modifiers, uint32* _table) const
{
    [...]

	switch (modifiers & kModifierKeys) {
		case B_SHIFT_KEY:
			offset = fKeys.shift_map[keyCode];
			table = B_SHIFT_TABLE;
			break;
		case B_CAPS_LOCK:
			offset = fKeys.caps_map[keyCode];
			table = B_CAPS_TABLE;
			break;
		case B_CAPS_LOCK | B_SHIFT_KEY:
			offset = fKeys.caps_shift_map[keyCode];
			table = B_CAPS_SHIFT_TABLE;
			break;
++      case B_CONTROL_KEY | B_CAPS_LOCK:
		case B_CONTROL_KEY:
			offset = fKeys.control_map[keyCode];
			table = B_CONTROL_TABLE;
			break;
  		case B_OPTION_KEY:
			offset = fKeys.option_map[keyCode];
			table = B_OPTION_TABLE;
			break;
		case B_OPTION_KEY | B_SHIFT_KEY:
			offset = fKeys.option_shift_map[keyCode];
			table = B_OPTION_SHIFT_TABLE;
			break;
		case B_OPTION_KEY | B_CAPS_LOCK:
			offset = fKeys.option_caps_map[keyCode];
			table = B_OPTION_CAPS_TABLE;
			break;
		case B_OPTION_KEY | B_SHIFT_KEY | B_CAPS_LOCK:
			offset = fKeys.option_caps_shift_map[keyCode];
			table = B_OPTION_CAPS_SHIFT_TABLE;
			break;
		default:
			offset = fKeys.normal_map[keyCode];
			table = B_NORMAL_TABLE;
			break;
        } 

    [...]
}

Edit: I posted this to #20052 ticket, which is a better place.

4 Likes

Fix pending review…

2 Likes

Fix merged in hrev59846

4 Likes

Confirmed fixed. Thank you so much; it may seem like a small thing, but it means so much to me! :slight_smile:

2 Likes

We all face similar “small but important/annoying to me” edge-cases from time to time :slight_smile:

I remember hitting an issue with mount_server (where it incorrectly remembered previously mounted partitions… if you happened to have to very similar ones). Annoyed me enough to fix it myself, send a patch, and then, as my solution was subpar… pester @waddlesplash into writing an acceptable solution (sorry, and thanks again there Augustin!).

2 Likes

Thanks you for taking the time to report the issue, opening a ticket (even if it was a duplicate), because in the end it is what bring this issue again in the spotlight and triggered the curiosity of someone to try to find its root cause.

Low hanging fruits are tasty :face_savoring_food:

3 Likes

You’re so welcome. Thank you for all the hard work you’re doing. :slight_smile:

I hope that with time, I’ll be able to improve on my bug-reporting and maybe even be able to send suggestions for solutions.

(That reminds me; I need to file a bug-report on “setvolume -d” not unmuting; the fix should be quick and easy. Done: #20185)

1 Like