Skip to content

feat: add one-shot sticky modifiers#720

Open
braindefender wants to merge 1 commit intoHaoboGu:mainfrom
braindefender:ossm
Open

feat: add one-shot sticky modifiers#720
braindefender wants to merge 1 commit intoHaoboGu:mainfrom
braindefender:ossm

Conversation

@braindefender
Copy link

Added One-Shot Sticky Modifiers functionality
Moved OSM/OSL logic into oneshot.rs file

Added two boolean config variables:

  • activate_on_keypress: Should modifiers be active from keypress (sticky modifiers)
  • send_on_second_press: Should the second keypress send modifiers and unstick them

Updated behavior.md docs to correspond with the new config structure:

[behavior.one_shot_modifiers]
  timeout = "1s"
  activate_on_keypress = false
  send_on_second_press = false

[behavior.one_shot_layers]
  timeout = "1s"

@github-actions
Copy link

github-actions bot commented Feb 2, 2026

Binary Size Report

use_config/nrf52832_ble

   text	   data	    bss	    dec	    hex	filename
 312168	   5072	  32316	 349556	  55574	rmk-nrf52832
Diff
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.3% +7.51Ki  [ = ]       0    .debug_str
  +0.3% +4.16Ki  [ = ]       0    .debug_info
  +0.4%    +997  [ = ]       0    .debug_line
  +0.1%    +672  [ = ]       0    .debug_loc
  +0.2%    +392  [ = ]       0    .debug_ranges
  +0.1%    +295  [ = ]       0    .strtab
  +0.2%    +176  [ = ]       0    .symtab
  [ = ]       0  +0.5%    +144    .bss
  +0.0%    +136  +0.0%    +136    .text
  +0.3%    +112  +0.3%    +112    .rodata
  +0.2%     +80  [ = ]       0    .debug_frame
  +0.1%     +48  [ = ]       0    .debug_aranges
   +22%     +11  [ = ]       0    [Unmapped]
  +0.1%      +1  [ = ]       0    .defmt
  +0.2% +14.5Ki  +0.1%    +392    TOTAL

use_config/nrf52840_ble

   text	   data	    bss	    dec	    hex	filename
 352936	   5072	  48724	 406732	  634cc	rmk-nrf52840
Diff
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.3% +8.68Ki  [ = ]       0    .debug_str
  +0.2% +4.44Ki  [ = ]       0    .debug_info
  +0.3% +1.05Ki  [ = ]       0    .debug_line
  +0.2%    +648  +0.2%    +648    .text
  +0.3%    +616  [ = ]       0    .debug_ranges
  +0.2%    +437  [ = ]       0    .strtab
  +0.3%    +304  [ = ]       0    .symtab
  +0.4%    +160  [ = ]       0    .debug_frame
  [ = ]       0  +0.3%    +144    .bss
  +0.3%    +120  +0.3%    +120    .rodata
  +0.2%     +88  [ = ]       0    .debug_aranges
  +3.7%      +2  [ = ]       0    [Unmapped]
  +0.1%      +1  [ = ]       0    .defmt
  -0.1%    -685  [ = ]       0    .debug_loc
  +0.2% +15.8Ki  +0.2%    +912    TOTAL

use_config/nrf52840_ble_split

   text	   data	    bss	    dec	    hex	filename
 430452	   6376	  45180	 482008	  75ad8	central

   text	   data	    bss	    dec	    hex	filename
 271376	   5740	  25892	 303008	  49fa0	peripheral
Diff

Central Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.2% +8.04Ki  [ = ]       0    .debug_str
  +0.2% +4.20Ki  [ = ]       0    .debug_info
  +0.2%    +842  [ = ]       0    .debug_line
  +0.2%    +840  +0.2%    +840    .text
  +0.2%    +448  [ = ]       0    .debug_ranges
  +0.1%    +259  [ = ]       0    .strtab
  [ = ]       0  +0.3%    +144    .bss
  +0.3%    +120  +0.3%    +120    .rodata
  +0.1%    +112  [ = ]       0    .symtab
  +0.1%     +48  [ = ]       0    .debug_frame
  +0.1%     +32  [ = ]       0    .debug_aranges
  +0.5%      +4  [ = ]       0    .defmt
  -0.1%    -929  [ = ]       0    .debug_loc
  +0.2% +14.0Ki  +0.2% +1.08Ki    TOTAL

Peripheral Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +679  [ = ]       0    .debug_str
  +0.0%    +584  [ = ]       0    .debug_info
  +0.1%    +312  [ = ]       0    .debug_loc
  +0.0%     +64  [ = ]       0    .debug_ranges
  +0.0%      +3  [ = ]       0    .debug_line
  -0.0%      -8  [ = ]       0    .debug_aranges
 -19.7%     -13  [ = ]       0    [Unmapped]
  -0.1%     -32  [ = ]       0    .debug_frame
  -0.0%     -41  [ = ]       0    .strtab
  -0.1%     -64  [ = ]       0    .symtab
  -0.0%    -112  -0.0%    -112    .text
  +0.0% +1.34Ki  -0.0%    -112    TOTAL

use_rust/nrf52840_ble_split

   text	   data	    bss	    dec	    hex	filename
 435344	   6376	  51660	 493380	  78744	central

   text	   data	    bss	    dec	    hex	filename
 269164	   5196	  24652	 299012	  49004	peripheral
Diff

Central Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.2% +7.50Ki  [ = ]       0    .debug_str
  +0.2% +4.75Ki  [ = ]       0    .debug_info
  +0.4% +2.77Ki  [ = ]       0    .debug_loc
  +0.2%    +873  [ = ]       0    .debug_line
  +0.2%    +792  +0.2%    +792    .text
  +0.1%    +459  [ = ]       0    .strtab
  +0.2%    +456  [ = ]       0    .debug_ranges
  +0.3%    +368  [ = ]       0    .symtab
  +0.4%    +176  [ = ]       0    .debug_frame
  [ = ]       0  +0.3%    +144    .bss
  +0.3%    +120  +0.3%    +120    .rodata
  +0.2%     +96  [ = ]       0    .debug_aranges
   +52%     +21  [ = ]       0    [Unmapped]
  +0.2% +18.3Ki  +0.2% +1.03Ki    TOTAL

Peripheral Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +701  [ = ]       0    .debug_str
  +0.0%    +510  [ = ]       0    .debug_info
  +0.0%     +79  [ = ]       0    .debug_loc
 -12.5%      -8  [ = ]       0    [Unmapped]
  -0.0%     -13  [ = ]       0    .debug_line
  -0.1%     -16  [ = ]       0    .debug_frame
  -0.0%     -17  [ = ]       0    .strtab
  -0.0%     -24  -0.0%     -24    .text
  -0.0%     -32  [ = ]       0    .symtab
  -0.0%     -40  [ = ]       0    .debug_ranges
  +0.0% +1.11Ki  -0.0%     -24    TOTAL

use_config/pi_pico_w_ble

   text	   data	    bss	    dec	    hex	filename
 584668	      0	  53716	 638384	  9bdb0	rmk-pi-pico-w
Diff
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.3% +8.03Ki  [ = ]       0    .debug_str
  +0.2% +3.97Ki  [ = ]       0    .debug_info
  +0.2% +1.68Ki  [ = ]       0    .debug_loc
  +0.3% +1.04Ki  [ = ]       0    .debug_line
  +0.3%    +912  +0.3%    +912    .text
  +0.1%    +248  [ = ]       0    .debug_ranges
  +0.1%    +201  [ = ]       0    .strtab
  [ = ]       0  +0.3%    +144    .bss
  +0.0%    +120  +0.0%    +120    .rodata
  +0.1%     +48  [ = ]       0    .symtab
  +0.0%      +8  [ = ]       0    .debug_aranges
  +0.1%      +1  [ = ]       0    .defmt
  -0.0%      -4  [ = ]       0    .debug_frame
 -15.0%      -9  [ = ]       0    [Unmapped]
  +0.2% +16.2Ki  +0.2% +1.15Ki    TOTAL

use_config/pi_pico_w_ble_split

   text	   data	    bss	    dec	    hex	filename
 622112	      0	  61376	 683488	  a6de0	central

   text	   data	    bss	    dec	    hex	filename
 483020	      0	  41628	 524648	  80168	peripheral
Diff

Central Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.2% +7.75Ki  [ = ]       0    .debug_str
  +0.2% +4.25Ki  [ = ]       0    .debug_info
  +0.2% +2.15Ki  [ = ]       0    .debug_loc
  +0.3%    +924  +0.3%    +924    .text
  +0.2%    +785  [ = ]       0    .debug_line
  +0.2%    +552  [ = ]       0    .debug_ranges
  +0.1%    +219  [ = ]       0    .strtab
  [ = ]       0  +0.2%    +144    .bss
  +0.2%    +144  [ = ]       0    .symtab
  +0.0%    +112  +0.0%    +112    .rodata
  +0.0%      +8  [ = ]       0    .debug_aranges
  +0.1%      +1  [ = ]       0    .defmt
 -24.6%     -16  [ = ]       0    [Unmapped]
  +0.2% +16.8Ki  +0.2% +1.15Ki    TOTAL

Peripheral Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +730  [ = ]       0    .debug_str
  +0.0%    +581  [ = ]       0    .debug_info
  +0.1%    +116  +0.1%    +116    .text
  +0.0%     +81  [ = ]       0    .debug_line
  +0.0%      +8  [ = ]       0    .debug_aranges
  -0.0%      -8  [ = ]       0    .debug_ranges
  -0.0%     -11  [ = ]       0    .strtab
 -30.4%     -17  [ = ]       0    [Unmapped]
  -0.1%     -32  [ = ]       0    .symtab
  -0.0%    -160  [ = ]       0    .debug_loc
  +0.0% +1.26Ki  +0.0%    +116    TOTAL

use_rust/pi_pico_w_ble_split

   text	   data	    bss	    dec	    hex	filename
 622168	      0	  61696	 683864	  a6f58	central

   text	   data	    bss	    dec	    hex	filename
 483460	      0	  41628	 525088	  80320	peripheral
Diff

Central Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.2% +7.58Ki  [ = ]       0    .debug_str
  +0.2% +4.46Ki  [ = ]       0    .debug_info
  +0.2% +1.46Ki  [ = ]       0    .debug_loc
  +0.2%    +911  [ = ]       0    .debug_line
  +0.3%    +908  +0.3%    +908    .text
  +0.1%    +232  [ = ]       0    .debug_ranges
  +0.1%    +213  [ = ]       0    .strtab
  [ = ]       0  +0.2%    +144    .bss
  +0.0%    +120  +0.0%    +120    .rodata
  +0.1%    +112  [ = ]       0    .symtab
  +0.0%      +8  [ = ]       0    .debug_aranges
  +0.1%      +1  [ = ]       0    .defmt
  -6.7%      -4  [ = ]       0    [Unmapped]
  -0.1%     -14  [ = ]       0    .debug_abbrev
  +0.2% +15.9Ki  +0.2% +1.14Ki    TOTAL

Peripheral Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +730  [ = ]       0    .debug_str
  +0.0%    +563  [ = ]       0    .debug_info
  +0.0%     +32  [ = ]       0    .debug_ranges
  +0.1%     +32  [ = ]       0    .symtab
  +0.0%      +9  [ = ]       0    .debug_line
  +0.0%      +8  [ = ]       0    .debug_aranges
  +0.0%      +8  +0.0%      +8    .text
  +0.0%      +1  [ = ]       0    .strtab
 -13.2%      -7  [ = ]       0    [Unmapped]
  -0.0%    -124  [ = ]       0    .debug_loc
  +0.0% +1.22Ki  +0.0%      +8    TOTAL

use_config/rp2040

   text	   data	    bss	    dec	    hex	filename
 129104	      0	  15140	 144244	  23374	rmk-rp2040
Diff
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.6% +7.58Ki  [ = ]       0    .debug_str
  +0.3% +2.62Ki  [ = ]       0    .debug_info
  +0.5%    +889  [ = ]       0    .debug_line
  +0.3%    +789  [ = ]       0    .debug_loc
  +0.7%    +768  +0.7%    +768    .text
  +0.2%    +187  [ = ]       0    .strtab
  +0.2%    +176  [ = ]       0    .debug_ranges
  [ = ]       0  +1.0%    +144    .bss
  +0.7%    +116  +0.7%    +116    .rodata
  +0.4%    +112  [ = ]       0    .symtab
   +20%     +11  [ = ]       0    [Unmapped]
  +0.1%      +8  [ = ]       0    .debug_aranges
  +0.3%      +1  [ = ]       0    .defmt
  -0.0%      -4  [ = ]       0    .debug_frame
  +0.4% +13.2Ki  +0.7% +1.00Ki    TOTAL

use_config/rp2040_split

   text	   data	    bss	    dec	    hex	filename
 146148	      0	  17008	 163156	  27d54	central

   text	   data	    bss	    dec	    hex	filename
  21456	      0	   2364	  23820	   5d0c	peripheral
Diff

Central Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.5% +7.77Ki  [ = ]       0    .debug_str
  +0.4% +4.05Ki  [ = ]       0    .debug_info
  +0.5%    +843  [ = ]       0    .debug_line
  +0.6%    +732  +0.6%    +732    .text
  +0.3%    +232  [ = ]       0    .debug_ranges
  +0.2%    +174  [ = ]       0    .strtab
  [ = ]       0  +0.9%    +144    .bss
  +0.6%    +120  +0.6%    +120    .rodata
  +0.0%      +8  [ = ]       0    .debug_aranges
  +0.3%      +1  [ = ]       0    .defmt
  -0.0%     -16  [ = ]       0    .symtab
 -34.8%     -23  [ = ]       0    [Unmapped]
  -0.0%     -90  [ = ]       0    .debug_loc
  +0.4% +13.8Ki  +0.6%    +996    TOTAL

Peripheral Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +166  [ = ]       0    .debug_str
  +0.0%     +45  [ = ]       0    .debug_info
  +0.0%     +14  [ = ]       0    .debug_line
  +0.1%      +8  [ = ]       0    .debug_aranges
  +0.0%      +3  [ = ]       0    .strtab
  -6.1%      -4  [ = ]       0    [Unmapped]
  +0.0%    +232  [ = ]       0    TOTAL

use_rust/rp2040_split

   text	   data	    bss	    dec	    hex	filename
 145544	      0	  16628	 162172	  2797c	central

   text	   data	    bss	    dec	    hex	filename
  22232	      0	   2628	  24860	   611c	peripheral
Diff

Central Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.5% +7.55Ki  [ = ]       0    .debug_str
  +0.4% +4.29Ki  [ = ]       0    .debug_info
  +0.5%    +904  [ = ]       0    .debug_line
  +0.6%    +716  +0.6%    +716    .text
  +0.2%    +192  [ = ]       0    .strtab
  [ = ]       0  +0.9%    +144    .bss
  +0.1%    +120  [ = ]       0    .debug_ranges
  +0.6%    +116  +0.6%    +116    .rodata
  +0.2%     +80  [ = ]       0    .symtab
  +0.4%     +36  [ = ]       0    .debug_abbrev
  +0.0%      +8  [ = ]       0    .debug_aranges
  +0.3%      +1  [ = ]       0    .defmt
  +2.6%      +1  [ = ]       0    [Unmapped]
  -0.1%    -242  [ = ]       0    .debug_loc
  +0.4% +13.7Ki  +0.6%    +976    TOTAL

Peripheral Diff

    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.0%    +166  [ = ]       0    .debug_str
  +0.0%     +45  [ = ]       0    .debug_info
  +0.0%     +14  [ = ]       0    .debug_line
  +0.1%      +8  [ = ]       0    .debug_aranges
  +7.4%      +4  [ = ]       0    [Unmapped]
  +0.0%      +3  [ = ]       0    .strtab
  +0.0%    +240  [ = ]       0    TOTAL

use_config/stm32f1

   text	   data	    bss	    dec	    hex	filename
  51840	     24	   7440	  59304	   e7a8	rmk-stm32f1
Diff
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +1.2% +7.68Ki  [ = ]       0    .debug_str
  +0.8% +3.75Ki  [ = ]       0    .debug_info
  +0.7%    +776  [ = ]       0    .debug_loc
  +0.9%    +741  [ = ]       0    .debug_line
  +1.5%    +560  [ = ]       0    .debug_ranges
  +0.6%    +308  +0.6%    +308    .text
  [ = ]       0  +2.0%    +144    .bss
  +0.2%     +47  [ = ]       0    .strtab
  +0.2%     +32  [ = ]       0    .symtab
   +28%     +12  [ = ]       0    [Unmapped]
  +1.0% +13.8Ki  +0.8%    +452    TOTAL

use_config/stm32f4

   text	   data	    bss	    dec	    hex	filename
 136016	    320	  16692	 153028	  255c4	rmk-stm32f4
Diff
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.4% +7.65Ki  [ = ]       0    .debug_str
  +0.4% +3.73Ki  [ = ]       0    .debug_info
  +0.6% +1.43Ki  [ = ]       0    .debug_loc
  +0.5%    +846  [ = ]       0    .debug_line
  +0.5%    +532  +0.5%    +532    .text
  +0.4%    +368  [ = ]       0    .debug_ranges
  +0.2%    +257  [ = ]       0    .strtab
  [ = ]       0  +0.9%    +144    .bss
  +0.4%    +144  [ = ]       0    .symtab
  +0.6%    +116  +0.6%    +116    .rodata
  +0.2%     +32  [ = ]       0    .debug_frame
  +0.1%     +24  [ = ]       0    .debug_aranges
   +60%     +24  [ = ]       0    [Unmapped]
  +0.3%      +1  [ = ]       0    .defmt
  +0.4% +15.1Ki  +0.5%    +792    TOTAL

use_config/stm32h7

   text	   data	    bss	    dec	    hex	filename
  97936	    264	  10900	 109100	  1aa2c	rmk-stm32h7
Diff
    FILE SIZE        VM SIZE    
 --------------  -------------- 
  +0.5% +8.24Ki  [ = ]       0    .debug_str
  +0.4% +4.03Ki  [ = ]       0    .debug_info
  +0.8%    +967  [ = ]       0    .debug_line
  +0.5%    +811  [ = ]       0    .debug_loc
  +0.9%    +592  [ = ]       0    .debug_ranges
  +0.7%    +544  +0.7%    +544    .text
  +0.7%    +192  [ = ]       0    .symtab
  [ = ]       0  +1.3%    +144    .bss
  +0.2%    +134  [ = ]       0    .strtab
  +0.8%    +120  +0.8%    +120    .rodata
  +0.3%     +48  [ = ]       0    .debug_frame
  +0.1%     +24  [ = ]       0    .debug_aranges
  +7.8%      +4  [ = ]       0    [Unmapped]
  +0.5% +15.6Ki  +0.7%    +808    TOTAL

@braindefender braindefender force-pushed the ossm branch 3 times, most recently from de53682 to 3f613b6 Compare February 4, 2026 03:35
@braindefender
Copy link
Author

Updated the docs, squashed all WIP commits.
Now, I think, it's ready for review.
@HaoboGu

one_shot_modifiers = {
activate_on_keypress = false,
send_on_second_press = false,
release_modifier_keys = [],
Copy link
Owner

Choose a reason for hiding this comment

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

send_on_second_press indicates that the current modifier is released by pressing the same key, so it's kinda overlapped with release_modifier_keys?

I suggest to remove release_modifier_keys and make send_on_second_press defaults to true.

Copy link
Author

Choose a reason for hiding this comment

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

I think that ability to set explicit keys to cancel/release OSSM is better, because with that you can set one key to release all modifiers. Without that, you'll need to press every OSM to cancel and you can make mistake.

send_on_second_press is primarily for the case where you want to trigger the key tap, for example, bring Windows Start Menu or something like that in other OS.

while release_modifier_keys are for explicit release of all OSM modifiers.

Copy link
Owner

Choose a reason for hiding this comment

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

I don't really understand, IIRC in current implementation, all OSM modifiers are cancelled after a non-letter keys is pressed, I thought it was enough for this case?

Copy link
Author

Choose a reason for hiding this comment

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

OSM is canceled/released when:

  • other non-OSM key is pressed (that will trigger a shortcut ModifierCombination+Key)
  • timeout has passed (ModifierCombination will release alone)

If the timeout is set to a very big number (like minutes), then the second option doesn't suit us.
But we want to release modifiers without triggering unnecessary shortcut.
Therefore, we use third option: release_modifier_keys which release mods without triggering any shortcuts.

Why timeout could be set to very big number: in some apps, there are alternative scroll mode (fast scroll, or side scroll). If you want to trigger that behavior, but you don't want to hold the mod for the whole period, you use OSSM with a big timer and release that modifier when it is not needed anymore.

Copy link
Owner

@HaoboGu HaoboGu Feb 9, 2026

Choose a reason for hiding this comment

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

Why timeout could be set to very big number: in some apps, there are alternative scroll mode (fast scroll, or side scroll). If you want to trigger that behavior, but you don't want to hold the mod for the whole period, you use OSSM with a big timer and release that modifier when it is not needed anymore.

Sorry, maybe I didn't make it clear. I think the "cancelling" behavior can be achieved by tapping the same OSSM key again. My expected behavior is:

  1. Tap OSSM key for the first time: activate OSM immediately
  2. Tap the same OSSM key for the second time within the timeout time: cancel current OSSM
  3. Tap other keys within the timeout time: modifier combination + key

With this behavior, you can open Windows Start menu by pressing OSM twice, and can also use OSSM in the scroll mode.

That simplifies the configuration too and saves lots of ram introduced by release_modifier_keys.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants