Skip to content

Add an interface for creating system trays#11234

Merged
expenses merged 31 commits intoslint-ui:feature/systrayfrom
expenses:system-tray
Apr 10, 2026
Merged

Add an interface for creating system trays#11234
expenses merged 31 commits intoslint-ui:feature/systrayfrom
expenses:system-tray

Conversation

@expenses
Copy link
Copy Markdown
Contributor

@expenses expenses commented Apr 2, 2026

Initial work on #6053. The idea is to use the ksni crate on linux and tray-icon everywhere else. I haven't yet added a SystemTray type to slint as getting this hooked up seems to be a little tricky - we make quite a few assumptions that the root exported type is a window and not something else. Icons successfully display in ksni, tooltips etc need more work.

@expenses expenses requested a review from tronical April 2, 2026 11:31
@expenses
Copy link
Copy Markdown
Contributor Author

expenses commented Apr 2, 2026

Todo:

  • Have some kind of integration with slint code via a SystemTray component
  • System tray event handling
  • Properly work out what features we want the system tray to be capable of
  • Ensure that all features are supported across both system tray backends
  • Tests
  • Documentation

@tronical
Copy link
Copy Markdown
Member

tronical commented Apr 2, 2026

Todo looks good. I'd say that in terms of API surface to our users we only want a Slint component. I just realize that we should probably keep track of that in #6053 - that way you can work with multiple PRs.

}

let tray = KsniTray { icon: ksni::Icon { width, height, data } }
.spawn()
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since spawn returns a future and ksni builds on top of smol, I think it's best to poll that future in a slint task (spawn_local), similar to the xdg settings watcher perhaps.

That way you also don't need custom event enums / variants.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Would prefer to do that as part of a later commit

change_tracker: crate::properties::ChangeTracker,
}

impl Item for SystemTray {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I wonder if we really need the SystemTray to be an Item
the Compiler would probably need to generate some special code of it.
But thats fine to have it temporarily as an experiment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

What would the alternative be?

@expenses expenses marked this pull request as ready for review April 9, 2026 12:10
@expenses expenses requested review from ogoffart and tronical April 9, 2026 12:15
Copy link
Copy Markdown
Member

@ogoffart ogoffart left a comment

Choose a reason for hiding this comment

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

Looks like a good start.
I'd be OK to merge this into master if it is gated as experimental.

//-is_internal
}

export component SystemTray {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you make it as experimental so it is only available when using SLINT_ENABLE_EXPERIMENTAL_FEATURES=1 ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done. Where does that leave the example? Should I remove it now?

@expenses expenses requested a review from ogoffart April 9, 2026 13:07
@ogoffart
Copy link
Copy Markdown
Member

ogoffart commented Apr 9, 2026

I see the CI is failling because it needs experimental.

One way to fix this is to add

println!("cargo:rustc-env=SLINT_ENABLE_EXPERIMENTAL_FEATURES=1");

in the build.rs, and use the slint! macro instead of slint-build.

Cargo.lock Outdated
]

[[package]]
name = "gtk"
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This will not make the security check happy :-(

@tronical
Copy link
Copy Markdown
Member

tronical commented Apr 9, 2026

Looks like a good start.
I'd be OK to merge this into master if it is gated as experimental.

Same here. I would however suggest to target a feature/systray branch instead of master as this will I think otherwise immediately trigger a security alert for the slint repo due to the gtk dependency. I have some hope to resolve that before the feature is shipped

@ogoffart ogoffart changed the base branch from master to feature/systray April 9, 2026 14:52
@ogoffart
Copy link
Copy Markdown
Member

ogoffart commented Apr 9, 2026

I would however suggest to target a feature/systray branch instead of master

I agree. I've created the branch and took the liberty to re-target this PR.

@tronical
Copy link
Copy Markdown
Member

tronical commented Apr 9, 2026

After merging this, please move the todo list from #11234 (comment) to the GitHub issue, update it, and work forward with that.

@expenses expenses merged commit 569d022 into slint-ui:feature/systray Apr 10, 2026
45 of 54 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.

3 participants