Skip to content

osd: parse custom message FIFO by newline and render multi-line popups#124

Merged
henkwiedig merged 1 commit into
OpenIPC:masterfrom
evanofficial:feat-multiline-custom-msg
May 20, 2026
Merged

osd: parse custom message FIFO by newline and render multi-line popups#124
henkwiedig merged 1 commit into
OpenIPC:masterfrom
evanofficial:feat-multiline-custom-msg

Conversation

@evanofficial

Copy link
Copy Markdown
Contributor

Fixes #98.

/run/pixelpilot.msg was read once per second and whatever fit in a single non-blocking read() became one fact, so concurrent writers got glued together and a literal \n in the message rendered as a tofu square in the popup widget.

Changes

src/main.cppCustomMsgManager

  • Reads now accumulate into a std::string buffer instead of being published verbatim.
  • Each \n-terminated chunk in the buffer is emitted as its own osd.custom_message fact, so multiple messages written during a single 1-second tick no longer collide.
  • If a writer never sends a newline, the buffer is flushed once it reaches MAX_MSG_LEN (512 bytes) so we cannot grow unboundedly.
  • Before publishing, the message is unescaped: a literal \n becomes a real newline. This lets writers that cannot emit raw newlines (e.g. plain echo, shell printf without -e, some scripting hosts) still produce multi-line messages.

src/osd.cppPopupWidget::draw

  • The widget uses cairo_show_text, which doesn't honour \n — embedded newlines used to render as a tofu glyph. Each message is now split on \n and drawn as separate lines.
  • The background box is sized to the longest line and the total stacked height, so the box still wraps the whole message rather than just the first line.

Testing

  • Verified the parser logic (escape unescape, buffer split across reads, multi-message split, escaped-newline -> split) locally with a small standalone harness.
  • Did not run a full build on this host — the project cross-compiles for Rockchip ARM and requires librockchip-mpp-dev, libdrm-dev, etc., which I don't have set up locally. The changed code only uses <string> / <vector> and existing cairo calls that were already in the file, so it should compile on the target.

Notes

  • MAX_MSG_LEN is 512 (well above the previous 119-byte single-read cap, but small enough to stay safe). Happy to bump it if you'd prefer a different ceiling.
  • The split-then-render approach in the popup keeps line spacing at 2 px, matching the existing inter-message spacing.

Closes OpenIPC#98

- CustomMsgManager now buffers partial reads and emits one fact per
  `\n`-terminated message instead of whatever happens to fit in a single
  read() call. If a writer never sends a newline the buffer is flushed
  after 512 bytes so the process cannot grow unboundedly.
- Each message is unescaped before publishing: `\n` becomes a literal
  newline, letting writers that cannot produce a raw newline (e.g.
  plain `echo`) still build multi-line messages.
- PopupWidget splits the message on `\n` and draws each line on its own
  row with a single background box sized to the longest line, so cairo
  no longer renders embedded newlines as a tofu glyph.
@henkwiedig henkwiedig merged commit 24ffd95 into OpenIPC:master May 20, 2026
10 checks passed
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.

Break custom messages by newline

2 participants