Found a weird behavior that I'm not sure if it's my bad or an upstream bug.
Sending "shift+h" to type "H" on Sway using their virtual input protocol:
* GTK app receives "shift" key, then "h" key - produces "h" (lowercase, incorrect).
* xterm app, via XWayland, receives "shift" then "h" key produces "H" (uppercase, correct).
* QT app (waycheck) behaves the same as GTK.
Same exact codes get sent by my app to Sway. Fascinating. I wonder if this is some input method related issue - the key ‘state’ in gtk remains zero but it should be 1 when shift is active.
Update: Found a workaround(?). The "virtual input" protocol has a method to tell the compositor about the current modifier state. Calling that to say "I pressed shift, so now the shift modifier is active" is a find workaround for now.
It's unclear why Sway(?) doesn't track this itself, or what I might be doing wrong to cause this.