Skip to content

Implement password masking#657

Open
nicoburns wants to merge 1 commit into
linebender:mainfrom
nicoburns:password-masking
Open

Implement password masking#657
nicoburns wants to merge 1 commit into
linebender:mainfrom
nicoburns:password-masking

Conversation

@nicoburns

Copy link
Copy Markdown
Collaborator

Implements password masking in the Parley.

Generated with Opus 4.8 High. Reviewed manually. PR description hand written.
Builds on design work and discussion from #394

Changes made:

  • Add grapheme_replacement: Option<char> style (using char makes this not fully general, but it works for the common case and keeps things simple)
  • In the core pipeline, for each Run (if grapheme_replacement is Some)
    • Lookup the glyph id for the grapheme_replacement char in cmap
    • Lookup the glyph advance
    • Replace every glyph in the run with a the grapheme replacement glyph
  • Add a password: bool field to PlainEditor (+getter/setter methods) that uses this functionality with the bullet character.

Notes

  • This deliberately doesn't cache the replacement glyph, as it is assumed that where this is used in practice there will only be one text run (so it will only be looked up once anyway).
  • This doesn't send the replacement character through a full shaping pipeline, as I figured that isn't necessary for the bullet char (which is probably the only case anyone cares about?). But let me know if this is actually required for some reason

Tested with Blitz

Screen.Recording.2026-06-28.at.21.01.09.mov

Signed-off-by: Nico Burns <nico@nicoburns.com>
@nicoburns nicoburns requested review from DJMcNab, taj-p and tomcur June 28, 2026 20:50
@nicoburns nicoburns added enhancement New feature or request C-parley Relates to the parley crate labels Jun 28, 2026
if self.password {
// Mask the entire text with the bullet character. Pushed last so it overrides any
// grapheme replacement that may have been set on the default styles.
builder.push_default(StyleProperty::GraphemeReplacement(Some('\u{2022}')));

@tronical tronical Jun 29, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

We do something similar in Slint and what we've observed is that sometimes that character isn't present on folks systems (yes, reality is sad :). It might make sense to just build the API around password replacement characters and then have a fallback to * inside parley, let the GraphemeReplacement bit an array of options, or ignore the problem :)

(thanks for bringing this into parley proper, btw!)

@nicoburns nicoburns Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hmm... I wonder if a better option would be to allow the user to override the font. In Blitz we're bundling moz-bullet-font.otf that we got from Mozilla/Firefox which we also use for list item bullets. It's ~5kb (not entirely sure why it's so big - maybe just required metadata?).

@nicoburns

nicoburns commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator Author

I think the replacement may need to go slightly earlier in the pipeline so that it occurs before font-fallback (but still after shaping) and we can fallback with the replaced glyph instead of the original glyph. Otherwise you can get issues (invisible glyphs) in cases such as emoji where the font that matches for the original glyph doesn't have a glyph for the replacement glyph.

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

Labels

C-parley Relates to the parley crate enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants