Jump to content

How to customize the keyboard layout on LineageOS 18.1?

Recommended Posts

  • Replies 294
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Popular Posts

tdm added a feature to his keyboard driver that allows the user to specify a custom keyboard map. Unfortunately there is no documentation (other than the source code), but you should be able to remap

I have made a lot of keyboard-related changes on the code, now I will try to summarize them. Also, I have tried to reach a state what probably all of us may find useful and also original working

Yes, this is a 2-in-1 problem. The first one is the different keymap of shifted (QWERTY) and normal (QWERTZ) variants of keyboards we have. It is a bit strange that F(x)tec itself has generated

Posted Images

  • 1 month later...

Is this still an issue? And in that case, what is the issue? 


Running lineage-18.1-20210726-nightly-pro1-signed.zip and just copied /vendor/usr/keychars/Builtin_Keyboard.kcm to /data/system/devices/keychars/Vendor_181d_Product_5018.kcm


Changed letter "A" to "P" as a test and it works flawless

  • Like 1
Link to post
Share on other sites
On 6/17/2021 at 12:44 PM, Sean McCreary said:

If anyone is set up to build LineageOS, I have pushed a potential fix for this problem to https://review.lineageos.org/c/LineageOS/android_frameworks_native/+/312770
It seems to prevent the key remapping problem with AutoInput enabled.

FYI, this change was merged and has been pulled due to problems it can cause with the touchscreen and certain apps. If we can fix the touchscreen issues, it will be resubmitted and merged again.

  • Thanks 1
Link to post
Share on other sites

I trying to understand how this works. 


My intention is to merge the  LinageOS stock Key Character map with the  pro1_qwerty_swe_1.kcm from finqwerty. 


the stock map file has type ALPHA  while finqwerty has type OVERLAY, what does this mean?


Do I need to merge the two files together, meaning replace the entries in the stock file with those from finqwerty?

Or can I load the two files after each other?

Do I need to edit anything in the key layout file?


finqwerty also has the following entries:

map key 111 PLUS

# orig EQUALS
map key 13 FORWARD_DEL

# orig BACK
map key 158 ESCAPE

 shouldn't I add these to the layout file instead? 


I tried yesterday to merge the files, but then the edited /data/system/devices/keychars/Vendor_181d_Product_5018.kcm wasn't loaded. 


attached the untouched stock keymap,  untouched finqwerty key map and two edited. 


the one ending with kcm_merged is the file I did yesterday that wont load. 

the one ending with p.kcm  has letter 'A' replaced with 'p', this one loads just fine, and writes a "p" when I try ti write a capital "A"


pro1_qwerty_swe_1.kcm Vendor_181d_Product_5018.kcm Vendor_181d_Product_5018_p.kcm Vendor_181d_Product_5018.kcm_merged

Link to post
Share on other sites
  • 4 weeks later...

I ran into some problems with slant arrow when I have tried to redefine my keyboard map.

It seems originally it was named as "fn" but it was renamed to "ralt" under LineageOS.
So I have tried to do the same keyboard map for me where national accents should go (for example) to keys '[' and ']'.
I have used a layout where keyboard was QWERTY and I could reach national letters by slant arrow+key combination.

Currently it seems this kind of definition is not possible for all of the keys, but works on others.

If I look of the keycodes in "KeyEvent Display" application, I see the following codes:
- "[" produces scanCode of 26
- "]" produces scanCode of 27

The above are perfect.

...but pressing then together with slant arrow, they have the following codes:
- "[" produces scanCode of 27 (!) and there is also a scanCode of 100 appears
- "]" produces scanCode of 27 and another scanCode of 42 appears

scanCode of 26 is defined as LEFT_BRACKET and scanCode of 27 is defined as RIGHT_BRACKET.

So, in the .kcm file, if I define LEFT_BRACKET and RIGHT_BRACKET correctly,  for slant arrow + '[', I will receive a character defined for RIGHT_BRACKET instead of the correct one.

So this way something is really incorrect.

I don't know how correct is the second generated key event (why is that even there), but also the important event is corrupted and not only for this key.

I also don't know why right alt was used for the slant arrow instead of anything less common, as alt and right alt is a special modifier in a lot of general applications.

If I change the hardware layout from QWERTZ to QWERTY, the following codes will appear for the very same key positions:
- "[" produces scanCode of 25
- "]" produces scanCode of 39

Together with slant arrow:
- "[" produces scanCode of 53
- "]" produces scanCode of 39 and another scanCode of 42 appears

I think changing "fn" to "right alt" was a wrong idea and it would be better to change it back to be usable for keyboard definition. :S
...or is there a way to redefine it to lose alt functionality but bring it back to a usable modifier?

@tdm, are you still visiting here?

  • Like 1
Link to post
Share on other sites
1 hour ago, VaZso said:

- "[" produces scanCode of 25
- "]" produces scanCode of 39

On stock OS, these keys only produce 25 and 39 (respectively) and slant arrow has a scan code of 464 independently of these keys, there are no strange multi scancode generation...

  • Like 1
Link to post
Share on other sites
On 8/23/2021 at 10:59 PM, VaZso said:

I think changing "fn" to "right alt" was a wrong idea and it would be better to change it back to be usable for keyboard definition. :S
...or is there a way to redefine it to lose alt functionality but bring it back to a usable modifier?

@tdm, are you still visiting here?

I'm with you there. The work @tdm¬†did for us is awesome but I would have implemented the keyboard driver differently. I tried multiple times¬†to convince him and other members of the community to notably leave the Fn keys programmable so that they can be taken advantage off notably by international custom layout but I was told I was wrong and they were right sometimes not very friendly if I remember well. Maybe they felt threaten¬†by the truth of my argumentation even though it was going in another direction than what they had in mind.¬†ūüėĀ

Anyway my understanding of what we have is:

  • Fn AKA Slant arrow AKA Yellow arrow are silent keys which main purpose is to enable / and ? to be sent without extra Fn modifier event to the system as some admin tools and terminal application apparently can't deal with that.
  • We have a unique and little tested, read potentially not working, configuration system which I have still to look into. Do you guys have links to docs for that stuff BTW?
  • The layout override system which is standard Android may be broken. Can anyone confirm that?

I do understand that this was done to be inline with classic desktop PC keyboard where the Fn key is silent too and never rich the OS however when it comes to smartphones that was hardly ever implemented that way for good reasons I find. The main one being that you have too few keys and sacrifying two modifiers that could be used for all sorts of international or¬†navigation purposes¬†to please hard core terminal users is not cool¬†ūüėĀ

I fully expect I will have to get my hands dirty to fix our keyboard driver. IMHO:

  • It should have been KISS¬†and compatible with Android instead of implementing a unique configuration system as we simply don't have the resources to fully develop and¬†maintain such a system.
  • Fn keys should be sent to the system so that they can be configured using Android layout override.

Then again there is not one truth here. If you are a hardcore terminal user I guess you want it one way. If you are an international power user you want it another way. If you are an average user you don't really care you probably don't have a keyboard smartphone¬†ūü§£


I'll leave the above rant for the record of my misunderstanding of the state of things as left by @tdm in the LOS keyboard driver. Basically I now understand the primary goal of that driver is to provide scancodes which are compatible with standard Android keyboard layout  definitions for both QWERTY and QWERTZ variant which was never the case on stock Android for neither of them. Since stock was incompatible with standard layout there was a need for FinQwerty and derived work notably for international users. However on LOS thanks to driver compatibility with standard layout the need for custom layout is less obvious.

Edited by Slion
  • Like 1
Link to post
Share on other sites

¬†¬†I am currently very sad as (for me) it seems to be a bug in the kernel driver which prevents me to use my device in full functionality, so currently its keyboard is only half-working or less for me... ūüėě

I am sad because it is unlikely for me to repair it being it is my daily driver and I don't know about other parts which may be related of this scancode modification.

Maybe replacing "KF_ALTGR" with "KF_FN" in qx1000.c file would solve it but it is only a guess without deeper knowledge or more serious interpretation of that code and as if it would need experimenting on my daily driver, I didn't really want to do it on my own. I also don't have experience compiling a kernel for Android and its potential fault sources or intended way of doing it. (Compiling and installing a Linux kernel on a PC is a bit different thing...)

I have a second Pro1 which I have switched on for this test but I was very disappointed in its hardware which lead me to place it on the table to sit there instead of running LineageOS which was my initial plan (and I was very nervous against the manufacturer)... but every time I looked at it I became extremely nervous producing an unacceptable rattling effect for me.
(So I left it on the table as a potential donor in case something dies in my daily driver.)

Anyway, before I have installed LineageOS on my daily driver, I have opened it and tightened some screws inside the base part (they weren't extremely loose as I expected based on loose screws in display unit I had earlier).
What I have found is the third support arm was a bit loose, but I don't think it may really affect rattling (this devices behaves well anyway regarding this).

I have also disassembled the hinge mechanism.
There are two screws holding a hinge cover on both sides and there is the springed hinge mechanism below it. 
They seems to be a bit "unaligned" compared to each other, so it can not be placed in "as is" - as expected.
The arms near hinge covers were designed in a way the screws of right hinge is also accessible when the hinge is closed (the wide black metal part below the display).
However, the left hinge was in a direction where it does not go in directly.
So all in all, I had to place the left side of the hinge in a way to tension the hinge in one direction, then tension the right side of the hinge in opposite direction.

I may be wrong about the actual placing but it had to tensioned a bit for proper working where it started to behave the same way as before (go in and out with appropriate force in both directions).

So based on that experience, my other unit which has higher rattling may have a less accurate spring mechanism, so I think that part should be potentially replaced in my other unit which is the heart of the mechanism...

Opening the base part was a bit more complicated anyway but after assembled everything, it works well - maybe a bit more stable than before... I mean my daily driver, I haven't disassembled the other one yet.

  • Like 1
Link to post
Share on other sites
24 minutes ago, Slion said:

I'm with you there. The work @tdm did for us is awesome but I would have implemented the keyboard driver differently. I tried multiple times to convince him and other members of the community to notably leave the Fn keys programmable so that they can be taken advantage off notably by international custom layout but I was told I was wrong and they were right sometimes not very friendly if I remember well.

Right, @tdm made an awesome work and he worked really hard and could achieve results very quickly.
I have tried to follow the thread about the keyboard driver and basically it seemed to be a good thing. I somewhat remember (but had to find it out again) the fn key was modified which I had a bad feeling about, but I could not test if it causes any problems.

...but apparently it prevents me to define my modified layout where slant arrow would be useful to reach an other layer of the keys just like how the blue arrow worked for me on my N900.

...and it worked for me absolutely perfectly on stock OS, it was simply became slow, old (more than one year without security fixes) and unoptimized, rebooted every time (for hours of loop) during charge in the last year or more and also rebooted (again and again for hours) when it was rebooted... not the kernel but Android, it was some kind of a soft boot-loop.

However, keyboard was perfectly usable for me, but around a month ago the system has started lagging which caused me to feel enough of stock OS.

I miss the usability of its keyboard (as it is the only reason I use it as a daily driver) and would like to have the same experience under LineageOS as otherwise the system works really well... but this way it will not be good for me at all.

Somehow I would like the keyboard to have repaired as I don't want to go back to stock setting everything up and slowing down again... I am really sad of the current state of my keyboard especially because it does not seem to be easy to dig into it (including the setup¬†of a development environment) which means I may not have a working keyboard for a while which is the main and soon the only valuable feature of this phone. ūüėě

I am really, really sad and disappointed partly because it is almost 2 am here, but I would like to repair my phone which does not seem to be easy at this point for me.

Edited by VaZso
  • Like 1
Link to post
Share on other sites
26 minutes ago, VaZso said:

but apparently it prevents me to define my modified layout where slant arrow would be useful to reach an other layer of the keys just like how the blue arrow worked for me on my N900.


Link to post
Share on other sites
28 minutes ago, VaZso said:

am really, really sad and disappointed partly because it is almost 2 am here, but I would like to repair my phone which does not seem to be easy at this point for me

I'm not surprised, it may be that the only way forward is to modify the keyboard driver.

  • Like 1
Link to post
Share on other sites
35 minutes ago, claude0001 said:

Sorry, @VaZso, I probably misunderstood. I'm not pushing anyone to do anything. You and Slion seemed to have quite specific ideas what changes in the keyboard code could be test-implemented to see if that would improve things for you.

I may have some ideas what to do once I have a development environment set up, currently the more serious question is the test device itself - I have also not replaced stock OS for a reason on my daily driver.

37 minutes ago, claude0001 said:

Getting the latest device-specific code for the Pro1 into your build environment is automated by the "breakfast pro1" step of the build instructions -- no need to search around manually.

I saw that - that was I referred to as "config" above. ūüôā
I don't know if (and how) I can do a pull request on it but I have not even looked in what that script really does yet.

40 minutes ago, claude0001 said:

Again, no pressure! All I want to say: It is really not as difficult as it seems at first. ūüôā

The pressure is at my side...
I have no time for it but need to get my phone working and being nervous something which worked perfectly for me got really bad.

It took me the weekend to get my phone working really well and it failed at the very last step where I wanted to setup the very same keyboard layout what I use on my Pro1 since I have received it.

Today I found opening my phone's keyboard, started writing a reply, then found I can not currently enter characters which have accents, so I have closed it and replied on my laptop instead. :S

Anyway, there are .kcm files where one can define layouts under Android.
A potential setting look like this:


key P {
    label:                              'P'
    base:                               'p'
    shift, capslock:                    'P'
    alt:                                '}'
    fn:                                 '\u00f6'
    fn+shift, ctrl+fn, fn+capslock:     '\u00d6'

So, basically if I press that button, it enters "p", if shift or capslock is on, it enters "P", together with alt, it enters "}" (it is less usable due to alt is also used elsewhere), pressing together with fn (used to be the slant arrow key), it displays "√∂" and fn+shift, ctrl+fn or fn+capslock displays "√Ė"

So one can use key combinations what pressed on the keyboard will be entered as input.

So this behaviour became broken as "fn" does not have effect.
...but, I have found if I replace it with ralt, it starts working, but it also has strange behaviour I wrote above like sometimes an additional keyevent occurs and also main keyevent is modified.

So I have defined two keys (code 26 and 27 on QWERTZ) and it mixed the two layouts as 26 becomes 27 while slant arrow is pressed. It is an unexpected behaviour.

What is needed the pressed keys... so if shift, fn, ctrl, capslock or maybe alt is pressed AND the key which was pressed together with one of these modifiers... but somehow also the key (so one of the most important identifier) is also modified by slant arrow.

Basically the idea of having a setup of which physical layout a user has (QWERTY or QWERTZ) is a very good idea and it also makes possible to use predefined layouts.
Maybe a right alt idea came here as on international keyboards, the right alt was named as "AltGr" which has additional symbols like reaching "[", "]", "{" and "}" characters on a national keyboard where these characters were replaced.

So the basic idea of using AltGr is also good, but I think it conflicts with something on Android itself what causes the modified characters and multiple key events, which is an unexpected behaviour.

So I think there should be two ways:

- Find out what happens under Android on pressing right alt... it may be also checked on another Android phone (most likely not on one which has an own keyboard). It may reveal if it is a specific issue of Pro1-specific part (even if it exists on Pro1 with an external keyboard) or a general issue of Android, or (if tested on another LineageOS-capable phone) is a Lineage-specific thing.
...then it may be solved without modifying the Pro1-specific code or if there should be solved in another part of Pro1-specific behaviour.

- Modify the Pro1 keyboard driver to use another key instead which I think (without deeper digging into the code) may be possible by modifying KF_ALTGR to KF_FN in the code.

However, that code itself generally looks to be good and also using AltGr is generally should not be a problem, but it definitively conflicts with something and that way it can not fulfill its original aim to become compatible with stock keyboard layouts.

So a real solution would be to find out what does the unexpected behaviour of additional and modified keypresses and it may be even a question on another Android phones or LineageOS builds.

So some testing with an application like "KeyEvent Display" would be good also on other devices to see what right alt does while pressed together with other keys - that may help to understand what (which part of the system) generates the additional keypress / and does some keycode modification.

Link to post
Share on other sites

@VaZso I did not read all that last big chunk of text.

However some of it gave me an idea.
It looks like ATM we have like two profiles QWERTY and QWERTZ.
I wonder if we could modify the driver to add more profiles QWERTY and QWERTZ variant that would be compatibly with stock so that FinQwerty and other mods would work the same. I would probably also add another profile that's improved on stock.

If this is doable I guess we would have good chances to get those changes committed to the official LOS repository.

I'm currently downloading the whole LOS source code to inspect it and maybe do a build later.

  • Thanks 1
Link to post
Share on other sites
2 hours ago, VaZso said:

Today I found opening my phone's keyboard, started writing a reply, then found I can not currently enter characters which have accents

I'm using the "English (US), international style" layout for the physical keyboard (QWERTY), and I've attached what I get from it (made with Softmaker Office for Android on the Pro1) with the help of the Sym key when (as in most if not all browsers) I have no access to the long-press special key selection popup. Unfortunately, while this key map covers much including everything the German language uses, I already can see it does not even remotely cover the French accents. 



Edited by Rob. S.
  • Thanks 2
Link to post
Share on other sites

@Sean McCreary Thanks a lot for your great description of that system.

The actual parsing of the keymap files is done there:


In that aw9523b_store_keymap function. In there you can see that the parsed keymap is put directly in the mapping array. Therefore you can use modifiers for your keys using the following constants:

#define KF_SHIFT        0x8000
#define KF_CTRL            0x4000
#define KF_ALT            0x2000
#define KF_ALTGR        0x1000

I'm just trying to come up with a mapping that would do alt+tab when doing fn+tab.
Looks like that stuff will do:



Edited by Slion
Link to post
Share on other sites

Ok so I tried to enable that keymap thing, the UI sees it cause it is enabled but it looks like it has no effect.


Was first trying to add just the remap I mentioned above then also the space power thing from the code sample.

None are working… Am I missing something?

Edited by Slion
Link to post
Share on other sites

I could get it working by modifying the destination keymap directly: /sys/devices/soc/c17a000.i2c/i2c-6/6-0058/keymap

Somehow that guy gets overwritten with the default mapping whenever I toggle the custom keymap settings option. I wonder if your source keymap should contain all keys?

However that trick with alt+tab just won't work as it then goes in task switcher and just exit it when you release. I'm back thinking how I could improve the driver.

Link to post
Share on other sites
8 minutes ago, Slion said:

wonder if your source keymap should contain all keys?

Nope that won't work either somehow whenever you enable custom keymap the destination keymap is filled with the default driver keymap that's it.

Link to post
Share on other sites
6 hours ago, Slion said:

It looks like ATM we have like two profiles QWERTY and QWERTZ.

Right, we have QWERTY and QWERTZ profiles which remaps the physical keys according to the actual locations of the QWERTZ and shifted QWERTY layout to have their proper scan codes.

If you look at the source of qx100.c which I don't know if it is the latest version, there are qwertz_keys / qwertz_fn_keys array and also their qwerty representation which are seem to be copied into key_array and key_fn_array arrays according to the value set as the physical layout.

There is an aw9523b_check_keys() function which then selects appropriate key presses from the arrays above.
There is a g_physical_modifiers variable which is set in gpio_keys_gpio_report_event() function where it checks for KEY_FN, KEY_RIGHTALT, KEY_RIGHTCTRL and KEY_RIGHTSHIFT codes.

...then back to aw9523b_check_keys() function, the interesting part starts here:

else if (g_physical_modifiers & KF_FN) {
	keycode = KEY_VALUE(key_fn_array[key_nr]);
	force_flags = KEY_FLAGS(key_fn_array[key_nr]);
else {
	keycode = key_array[key_nr];
	force_flags = 0;

KEY_VALUE masks the first four bits (0x0fff) while KEY_FLAGS masks the rest (0xf000), so the first part of the 16-bit variable contains the FLAGS and the rest is the actual key.

So if KF_FN (fn key) was pressed, keycode will contain the last three bytes of key_fn_array while force_flags will contain the first byte.
If fn key was not pressed, then keycode will contain key_array while force_flags will be zero.

pressed[key_nr] will contain keycode then it checks force_flags against KF_SHIFT, KF_CTRL, KF_ALT and KF_ALTGR where the same bits are zero in g_logical_modifiers variable.
The g_logical_modifiers variable is set when force_flags & the above flags like KF_ALTGR is set and it calls the following functions once:

input_report_key(aw9523b_input_dev, KEY_RIGHTALT, 1);

This is where the actual keypress is generated.

...then, if keypress was generated and appropriate bit of g_physical_modifiers is zero, it sends a key release similarly as above.

As of "fn" key, first it was defined as "KF_FN", then at logical modifiers it is a "KF_ALTGR" flag which then sends KEY_RIGHTALT to the system.


So, basically there are two arrays - one for button pressed normally and one for buttons pressed together with "fn".
These arrays are filled according to QWERTY or QWERTZ setup.

The order should represent the order of keys readout.

Honesty, looking at "qwertz_fn_keys" array for example (better because it represents QWERTY keymap as opposite to the other one because of the shifted style) I don't really understand why KF_SHIFT while at other keys KF_ALTGR was used.

Anyway, I have just found a bug related to the key I wrote an example above.

It has, for normal keystrokes:

/* 24..31 */
/* 32..39 */

Then, for fn keystrokes:
/* 24..31 */
KEY_RIGHTALT,            KEY_S,                KEY_102ND | KF_ALTGR,        KEY_RESERVED,
/* 32..39 */
KEY_BACKSPACE,            KEY_F,                KEY_C,                KEY_RESERVED,

So that is the cause of my scancode change from 26 to 27, the upper one should be KEY_LEFTBRACE instead.

I think it also has similar mistakes or at least if I remember well, I ran into it.

So the problem definitively lies in these arrays inside the keyboard driver which should be corrected and not in other parts of the system.

Currently I don't know where the values of KF_SHIFT, KF_ALTGR, etc are defined, but for me, it looks to be a bit strange why these (most likely only one bits) are applied and why it is different for different keys.
Also, most likely these are the bits what are placed in force_flags later.

I am getting a bit tired and this message is getting way too long but the root cause of the problem lies in these arrays which should be checked for errors on both variants.

I don't think we need another variants added into settings, only to repair also other potential typos in the arrays above.

I will run again some tests to see the system's behaviour of keypresses compared to the table above.

Oh, and if I connect a bluetooth keyboard to my Pro1, right alt will have scancode of 100 and can be read independently of other keys pressed.

Sorry for the long story but we are much closer to a solution now. ūüôā

Edited by VaZso
  • Thanks 1
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information