Skip to content

Comments

feat(web): implement doModifierPress ✨ 🎼#15343

Merged
ermshiperete merged 7 commits intoepic/web-corefrom
feat/web/15287_doModifierPress
Jan 22, 2026
Merged

feat(web): implement doModifierPress ✨ 🎼#15343
ermshiperete merged 7 commits intoepic/web-corefrom
feat/web/15287_doModifierPress

Conversation

@ermshiperete
Copy link
Contributor

Fixes: #15287
Test-bot: skip

@keymanapp-test-bot
Copy link

keymanapp-test-bot bot commented Dec 11, 2025

User Test Results

Test specification and instructions

User tests are not required

@keymanapp-test-bot keymanapp-test-bot bot changed the title feat(web): implement doModifierPress feat(web): implement doModifierPress 🎼 Dec 11, 2025
@keymanapp-test-bot keymanapp-test-bot bot added this to the A19S18 milestone Dec 11, 2025
@ermshiperete ermshiperete changed the base branch from refactor/web/cleanup to refactor/web/constants December 11, 2025 18:01
@ermshiperete ermshiperete force-pushed the feat/web/15287_doModifierPress branch from 1bd3aa5 to 283f43f Compare December 11, 2025 18:05
@ermshiperete ermshiperete marked this pull request as ready for review December 11, 2025 18:06
@ermshiperete ermshiperete force-pushed the refactor/web/constants branch from 5b3ea22 to 878b8ab Compare December 11, 2025 18:28
@ermshiperete ermshiperete force-pushed the feat/web/15287_doModifierPress branch from 283f43f to 68de61a Compare December 11, 2025 18:29
@ermshiperete ermshiperete changed the title feat(web): implement doModifierPress 🎼 feat(web): implement doModifierPress ✨ 🎼 Dec 15, 2025
@keyman-server keyman-server modified the milestones: A19S18, A19S19 Dec 21, 2025
Copy link
Member

@mcdurdin mcdurdin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure about some of the modifier-related changes here, we should discuss

Comment on lines +398 to +404
if (this.activeKeyboard.isMnemonic && this.stateKeys['K_CAPS'] && (!e || !e.isModifier)) {
// Modifier keypresses don't trigger mnemonic manipulation of modifier state.
// Only an output key does; active use of Caps will also flip the SHIFT flag.
// Mnemonic keystrokes manipulate the SHIFT property based on CAPS state.
// We need to unflip them when tracking the OSK layer.
keyShiftState ^= ModifierKeyConstants.K_SHIFTFLAG;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this straight from jsKeyboardProcessor? I just don't quite understand the rationale - shift and caps have different effects on keys (e.g. 1 --> ! / 1 vs a --> A / A for shift and caps respectively)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's from jsKeyboardProcessor:

if(this.activeKeyboard.isMnemonic && this.stateKeys['K_CAPS']) {

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth reading through the PR and comments that originally added this: #5456

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like that code might not be correct - see #15439.

case Codes.keyCodes.K_RCTRL:
case Codes.keyCodes.K_LALT:
case Codes.keyCodes.K_RALT:
case Codes.keyCodes.K_ALTGR:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a real AltGr. It's a pseudo AltGr that probably should never be used. See its keyCodes value of 50010. May need some further investigation!

Suggested change
case Codes.keyCodes.K_ALTGR:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this apply to all keycodes > 50000? If so, what are those? And we should probably add a comment to https://github.com/keymanapp/keyman/blob/feat/web/15287_doModifierPress/common/web/types/src/consts/virtual-key-constants.ts#L130

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, all the keycodes > 50000 are special key codes used only in touch layouts; called TKeymanWebTouchStandardKey in keymanweb-key-codes.ts (in the kmw compiler, translated from Delphi, hence the initial T):

export const enum
TKeymanWebTouchStandardKey {
K_LOPT = 50001,
K_ROPT = 50002,
K_NUMERALS = 50003,
K_SYMBOLS = 50004,
K_CURRENCIES = 50005,
K_UPPER = 50006,
K_LOWER = 50007,
K_ALPHA = 50008,
K_SHIFTED = 50009,
K_ALTGR = 50010,
K_TABBACK = 50011,
K_TABFWD = 50012
};

These are predefined to have specific behaviours on a touch layout but no effect on a standard layout. The documentation could be improved; see:

As noted above, some `K_xxxx` codes emit characters, if no rule is defined.
There are also some codes which have special functions:
<table class="display">
<thead>
<tr>
<th>Identifier</th>
<th>Meaning</th>
</tr>
</thead>
<tbody>
<tr>
<td markdown="1">`K_ENTER`</td>
<td>Submit a form, or add a new line (multi-line); the key action may vary depending on the situation.</td>
</tr>
<tr>
<td markdown="1">`K_BKSP`</td>
<td>Delete back a single character. This key, if held down, will repeat. It is the only key code which triggers
repeat behavior.</td>
</tr>
<tr>
<td markdown="1">`K_LOPT`</td>
<td>Open the language menu (aka Globe key).</td>
</tr>
<tr>
<td markdown="1">`K_ROPT`</td>
<td>Hide the on screen keyboard.</td>
</tr>
<tr>
<td markdown="1">`K_TAB`, `K_TABBACK`, `K_TABFWD`</td>
<td markdown="1">Move to next or previous element in a form. Note that these key functions are normally
implemented outside the touch layout, so should not typically be used. `K_TAB` will go to previous
element if used with the `shift` modifier.</td>
</tr>
</tbody>
</table>

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a comment to virtual-key-constants.ts

Comment on lines 144 to 149
case Codes.keyCodes.K_LSHIFT:
case Codes.keyCodes.K_RSHIFT:
case Codes.keyCodes.K_LCTRL:
case Codes.keyCodes.K_RCTRL:
case Codes.keyCodes.K_LALT:
case Codes.keyCodes.K_RALT:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These do not currently return true, so this is a functional change which would need extensive testing. I suggest we do not add them here unless we actually have a need for them, or else we audit all uses to ensure that adding these does not break anything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

{ code: Codes.keyCodes.K_NUMLOCK, name: 'NumLock' },
{ code: Codes.keyCodes.K_SCROLL, name: 'ScrollLock' },
// TODO-web-core: should LSHIFT/RSHIFT etc also be detected as modifier?
// Currently .js keyboards don't don't support distinguishing
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.js keyboards do support L/R alt and ctrl, but not L/R shift. We don't support L/R shift anywhere in Keyman.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed.

Base automatically changed from refactor/web/constants to epic/web-core December 22, 2025 13:33
@keyman-server keyman-server modified the milestones: A19S19, A19S20 Jan 3, 2026
@ermshiperete ermshiperete requested a review from mcdurdin January 6, 2026 17:44
Comment on lines 368 to 370
const lockNames = ['CAPS', 'NUM_LOCK', 'SCROLL_LOCK'] as const;
const lockKeys = ['K_CAPS', 'K_NUMLOCK', 'K_SCROLL'] as const;
const lockModifiers = [ModifierKeyConstants.CAPITALFLAG, ModifierKeyConstants.NUMLOCKFLAG, ModifierKeyConstants.SCROLLFLAG] as const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These, together with LL417-419, should be grouped together at the top of the module rather than declared at the top of the function

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@ermshiperete ermshiperete merged commit c8c20b7 into epic/web-core Jan 22, 2026
6 checks passed
@ermshiperete ermshiperete deleted the feat/web/15287_doModifierPress branch January 22, 2026 16:18
@github-project-automation github-project-automation bot moved this from Todo to Done in Keyman Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

3 participants