Skip to content

fix: return correctly-typed D-Bus values for all standard SNI properties#141

Open
hexpwn wants to merge 1 commit intoProtonVPN:stablefrom
hexpwn:fix/sni-property-types
Open

fix: return correctly-typed D-Bus values for all standard SNI properties#141
hexpwn wants to merge 1 commit intoProtonVPN:stablefrom
hexpwn:fix/sni-property-types

Conversation

@hexpwn
Copy link

@hexpwn hexpwn commented Feb 6, 2026

The tray icon fails to display on desktop environments and window managers that rely on a StatusNotifierHost bridge (e.g. snixembed on i3wm + polybar, or any setup using an SNI-to-XEmbed proxy). The bridge crashes immediately when it tries to read the tray icon's properties.

The StatusNotifierItem specification defines strict D-Bus types for properties like IconPixmap (a(iiay)), ToolTip ((sa(iiay)ss)), and WindowId (u). Previously, Get() returned a plain string ("") for any unknown or unimplemented SNI property, and GetAll() omitted them entirely. When a StatusNotifierHost queries these properties and attempts to deserialize the response using the spec-defined type, it crashes with:

GLib:ERROR:g_variant_serialised_n_children: code should not be reached

This happens because GLib's GVariant deserializer receives a string variant where it expects a complex type like a(iiay).

This commit:

  • Adds a _get_sni_properties() helper that includes all standard SNI spec properties with their correct empty D-Bus-typed defaults
  • Uses it in both Get() and GetAll() to ensure type-correct responses
  • Eliminates the duplicated property dict between Get() and GetAll()

This issue was diagnosed, and the code patched and tested by Claude Opus 4.6. This PR is 100% vibecoded, so I apologize for any nonsense.

Ref: https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/

The tray icon fails to display on desktop environments and window
managers that rely on a StatusNotifierHost bridge (e.g. snixembed on
i3wm + polybar, or any setup using an SNI-to-XEmbed proxy). The bridge
crashes immediately when it tries to read the tray icon's properties.

The StatusNotifierItem specification defines strict D-Bus types for
properties like IconPixmap (a(iiay)), ToolTip ((sa(iiay)ss)), and
WindowId (u). Previously, Get() returned a plain string ("") for any
unknown or unimplemented SNI property, and GetAll() omitted them
entirely. When a StatusNotifierHost queries these properties and
attempts to deserialize the response using the spec-defined type, it
crashes with:

  GLib:ERROR:g_variant_serialised_n_children: code should not be reached

This happens because GLib's GVariant deserializer receives a string
variant where it expects a complex type like a(iiay).

This commit:
- Adds a _get_sni_properties() helper that includes all standard SNI
  spec properties with their correct empty D-Bus-typed defaults
- Uses it in both Get() and GetAll() to ensure type-correct responses
- Eliminates the duplicated property dict between Get() and GetAll()

This issue was diagnosed, patched and tested by Claude Opus 4.6.
This PR is 100% vibecoded.

Ref: https://www.freedesktop.org/wiki/Specifications/StatusNotifierItem/StatusNotifierItem/
@hexpwn hexpwn mentioned this pull request Mar 13, 2026
3 tasks
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.

1 participant