2.7 KiB
fix(chatwin): only fire plugins_post_chat_message_display on incoming
Base: master ← fix/plugin-post-display-incoming-only
Create PR: https://git.jabber.space/devs/cproof/pulls/new/fix/plugin-post-display-incoming-only
Problem
Plugins listening on plugins_post_chat_message_display (e.g. sounds.py — plays a notification sound on a new incoming chat message) were firing in places that are not "a remote party sent a chat message and it was displayed":
- Opening a chat — every message loaded from history triggered the hook, so the user heard the notification sound once per historical message.
- Sending a chat message — the outgoing-message path triggered the hook, so sending played the incoming sound.
- Receiving a carbon copy of your own outgoing message from another device — same, played the incoming sound.
Net effect for sounds.py (and any plugin that treats the hook as "a new message arrived"): notification sound on every open / send / carbon, which is essentially constant nuisance.
Root cause
The post-display hook was invoked from four sites in src/ui/chatwin.c:
| Function | Path |
|---|---|
chatwin_incoming_msg |
remote → us (true incoming) |
chatwin_outgoing_msg |
us → remote |
chatwin_outgoing_carbon |
us → remote, mirrored back via XEP-0280 carbons |
_chatwin_history |
history scroll-back |
chatwin_db_history |
DB-backed history load |
Only the first matches the hook's semantic. The other four were spurious — they treated "display happened" as the trigger condition instead of "an incoming message was displayed".
Fix
Remove the plugins_post_chat_message_display(...) call from the four spurious sites. Keep it only in chatwin_incoming_msg. The corresponding pre-display hook (plugins_pre_chat_message_display) and the msg->plain = old_plain swap that bracket it stay in place — those affect how the message is rendered, independent of the post hook.
One file, five deletions.
Verify
- Open a chat that has stored history → expect zero notification sounds from
sounds.pyduring the history render. - Send a message → expect zero notification sound for your own outgoing.
- Receive an outgoing carbon (send from another XMPP client logged into the same account) → expect zero notification sound.
- Receive an actual incoming message from the remote contact → expect the notification sound exactly once.
Note for plugin authors
Plugins relying on the previous (broader) trigger semantics will see the hook only on true incoming displays. If a plugin needs to observe outgoing or history events, it should hook into the corresponding paths instead (plugins_post_chat_message_send for outgoing; no current hook for history — could be added separately).