Glypher

Insert any Unicode character into any app with a single button press.
Tap, double-tap, or long-press for three independent characters per key.
macOS 12+ & Windows 10+ • Stream Deck SDK 2
Glypher — Stream Deck Unicode inserter overview

Glypher buttons on a Stream Deck. Each keycap shows its assigned character(s) and updates dynamically — no static images involved.

Origin

Glypher started from two recurring frustrations:

  1. Slack removes blank lines. Always. The only workaround is a Unicode line-separator character (U+2028), which Slack accepts but which has no keyboard shortcut.
  2. Business symbols aren't on keyboards. µ, €, £, →, em-dashes, and similar characters require memorising obscure key combinations or reaching for a character picker every single time.

Both problems are solvable with a Stream Deck button. Glypher was written solely to solve them.

Why a separate plugin? Glypher is intentionally separate from Mac-A-Tron. Mac-A-Tron does OS-specific things (mouse control, window management) that only make sense on macOS. Glypher works the same way on macOS and Windows — because a Microsoft Surface is also in the bag.

Features

Three characters per button

Each button can hold a primary, secondary, and tertiary character reached via tap, double-tap, and long-press gestures.

Works everywhere

Pastes into any focused application — browsers, terminals, chat clients, document editors, creative tools.

Invisible character labels

Characters like the line separator or zero-width space show a short custom label on the keycap so the button isn't blank.

Quick Insert palette

A built-in scrollable character picker organised by category so you don't need to look up code points.

Dynamic SVG button graphics

Button images are generated as SVG at runtime, with font sizes that scale automatically to the character count and zone size.

macOS & Windows

Uses the most reliable paste mechanism on each platform to avoid encoding corruption.

Tap / Double-Tap / Long-Press

Each Glypher button supports three independent character assignments through gesture timing:

GestureTimingSlot
Single tapPress and releasePrimary character
Double tapTwo presses within 300 msSecondary character
Long pressHold for 600 msTertiary character

When only a primary character is configured, it fills the entire keycap. As secondary and tertiary slots are populated, the button automatically switches to a split-zone layout:

┌──────────────────────┐ │ PRIMARY (tap) │ ← top half ├───────────┬──────────┤ │ DOUBLE-TAP│LONG-PRESS│ ← bottom quarters └───────────┴──────────┘
Glypher gesture showcase — tap, double-tap, long-press zones visible on Stream Deck keys

Buttons automatically adapt their layout to show primary, double-tap, and long-press zones.

Special Invisible Characters

Glypher has first-class support for characters that are invisible or have specialised semantics:

SlackLF — Line Separator U+2028

Slack parses this character as a real blank line without collapsing it. It's invisible in the message box but preserved in the formatted output. Glypher shows the label SLF on the keycap.

This is the character that started it all. Slack's formatter strips ordinary blank lines, but U+2028 sneaks through. Press the button, get a blank line.

Zero-Width Space U+200B — label ZW-Sp

An invisible character that hints to text-layout engines that line-wrapping is allowed at this point. Useful for breaking automatic URL linkification in apps that linkify everything they see.

Non-Breaking Space U+00A0 — label NB-Sp

A visible space that prevents line-wrapping between two words — for example between a title and a name: Mr. Smith.

Quick Insert Palette

The Property Inspector (the configuration panel in Stream Deck) includes a scrollable character palette organised by category. Clicking any character pre-fills it into the active slot and automatically sets an appropriate display label for invisible characters.

Glypher Quick Insert character palette in the Property Inspector

The Quick Insert palette makes it easy to find and assign characters without needing to know Unicode code points.

Palette categories

Invisible

Line Separator, Zero-Width Space, Non-Breaking Space — all pre-labelled for keycap display.

Punctuation & Symbols

Em dash, en dash, ellipsis, bullet, section, pilcrow, quotes, copyright, registered, trademark.

Arrows

→ ← ↑ ↓ ↔ ⇒ ⇐ ↩ ➜ and more directional arrows.

Math

× ÷ √ ≈ ≠ ∞ ≤ ≥ ± ∑ degree, micro sign.

Currency

€ £ ¥ ¢ ₿ ₹ — major world currencies at your fingertips.

Greek

π Ω Δ and other Greek letters commonly used in technical writing.

Dynamic Button Images

Glypher generates every button graphic as an SVG at runtime inside the plugin — no static icon files are involved. This means:

Platform Support

PlatformMinimum versionPaste mechanism
macOS12 (Monterey)osascript — AppleScript via stdin
Windows10powershell.exe -EncodedCommand

How pasting works — macOS

The plugin spawns a single osascript process that both sets the clipboard and fires Cmd+V in one atomic step:

set the clipboard to (character id 181)   -- µ
tell application "System Events" to keystroke "v" using command down

Using character id N (where N is the Unicode code point) sidesteps every encoding conversion in the shell pipeline. An earlier implementation used pbcopy followed by a separate osascript keystroke; this suffered from a clipboard race condition where clipboard-monitoring software would re-encode UTF-8 as Mac Roman before the paste could fire, producing garbled output such as Œº instead of µ. The single-process atomic approach eliminates that race window entirely.

Accessibility permission required

Glypher uses System Events for keystroke injection, which requires Accessibility access. Grant it in System Settings → Privacy & Security → Accessibility.

How pasting works — Windows

The plugin spawns powershell.exe with an -EncodedCommand argument (Base64 of UTF-16LE) that loads System.Windows.Forms and pastes atomically:

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Clipboard]::SetText([System.Char]::ConvertFromUtf32(181))
[System.Windows.Forms.SendKeys]::SendWait("^v")

ConvertFromUtf32 correctly handles every Unicode code point, including characters above U+FFFF that require surrogate pairs in .NET's UTF-16 strings. Base64 encoding avoids command-line quoting issues with multi-byte characters.

Supplementary-plane characters (above U+FFFF): JavaScript strings are UTF-16. Glypher iterates characters with the spread operator ([...char]), which yields full Unicode code points — not UTF-16 code units — so surrogate pairs are handled correctly on both platforms.

Starter Profile

Glypher ships with a 15-button starter profile (5 columns × 3 rows) pre-configured with the most commonly useful Unicode characters. Each button holds three characters via tap / double-tap / long-press.

Col 0 Col 1 Col 2 Col 3 Col 4 ┌──────────────┬────────────┬─────────┬──────────┬─────────┐ Row 0 │ Invisible │ Dashes │ IP │ Marks │ Quotes │ │ tap: SLF │ tap: — │ tap: © │ tap: • │ tap: " │ │ dbl: ZW-Sp │ dbl: – │ dbl: ® │ dbl: § │ dbl: " │ │ hold: NB-Sp │ hold: … │ hold: ™ │ hold: ¶ │ hold: ' │ ├──────────────┼────────────┼─────────┼──────────┼─────────┤ Row 1 │ Right arrows │ Left arrows│ Vert │ Relations│ Compare │ │ tap: → │ tap: ← │ tap: ↑ │ tap: ≈ │ tap: ≤ │ │ dbl: ⇒ │ dbl: ⇐ │ dbl: ↓ │ dbl: ≠ │ dbl: ≥ │ │ hold: ➜ │ hold: ↩ │ hold: ↔ │ hold: ∞ │ hold: ± │ ├──────────────┼────────────┼─────────┼──────────┼─────────┤ Row 2 │ Arithmetic │ Science │ Major $ │ Minor $ │ Greek │ │ tap: × │ tap: µ │ tap: € │ tap: ¢ │ tap: π │ │ dbl: ÷ │ dbl: ° │ dbl: £ │ dbl: ₿ │ dbl: Ω │ │ hold: √ │ hold: ∑ │ hold: ¥ │ hold: ₹ │ hold: Δ │ └──────────────┴────────────┴─────────┴──────────┴─────────┘

Full character reference

ButtonTapDouble-tapLong-press
InvisibleLINE SEPARATOR U+2028SLFZERO-WIDTH SPACE U+200BZW-SpNO-BREAK SPACE U+00A0NB-Sp
DashesEM DASH — U+2014EN DASH – U+2013ELLIPSIS … U+2026
IP (marks)COPYRIGHT © U+00A9REGISTERED ® U+00AETRADE MARK ™ U+2122
MarksBULLET • U+2022SECTION § U+00A7PILCROW ¶ U+00B6
QuotesLEFT DBL QUOTE " U+201CRIGHT DBL QUOTE " U+201DRIGHT SINGLE ' U+2019
Right arrowsU+2192U+21D2U+279C
Left arrowsU+2190U+21D0U+21A9
Vertical arrowsU+2191U+2193U+2194
RelationsU+2248U+2260U+221E
CompareU+2264U+2265± U+00B1
Arithmetic× U+00D7÷ U+00F7U+221A
Scienceµ U+00B5° U+00B0U+2211
Major currencyU+20AC£ U+00A3¥ U+00A5
Minor currency¢ U+00A2U+20BFU+20B9
Greekπ U+03C0Ω U+03A9Δ U+0394
Note on µ: The micro sign at the Science button is U+00B5 (Micro Sign), not U+03BC (Greek small letter mu). They look identical but are distinct code points. U+00B5 is what Option+M types on macOS.

Setup

macOS: Accessibility permission required

Glypher uses System Events to fire Cmd+V. Grant access in System Settings → Privacy & Security → Accessibility and enable the Stream Deck entry (or the helper process) once prompted.

1) Install the plugin

Download and double-click the .streamDeckPlugin file. Stream Deck will import it automatically.

2) Add a button

From the Stream Deck app, drag a Glypher action onto any button. Open its Property Inspector to configure characters.

3) Pick your characters

  1. Type a character directly into the Primary, Secondary, or Tertiary field, or
  2. Open the Quick Insert palette, browse by category, and click to insert.
  3. For invisible characters the label is filled in automatically — you can customise it.

4) (Optional) Install the Starter Profile

The starter profile installs 15 pre-configured buttons covering the most useful Unicode characters. From the glypher/ directory:

node docs/install-profile.mjs

After Stream Deck restarts, select the Glypher profile from the profile picker (top-left in the Stream Deck app).

# Preview without writing anything:
node docs/install-profile.mjs --dry-run