Skip to content

feat(desktop): make libxdo opt-in on Linux via linux-libxdo - #5749

Merged
nicoburns merged 1 commit into
DioxusLabs:mainfrom
nabbisen:linux-libxdo-opt-in
Aug 10, 2026
Merged

feat(desktop): make libxdo opt-in on Linux via linux-libxdo#5749
nicoburns merged 1 commit into
DioxusLabs:mainfrom
nabbisen:linux-libxdo-opt-in

Conversation

@nabbisen

Copy link
Copy Markdown
Contributor

Problem

libxdo is a default feature of both muda and tray-icon, so dioxus-desktop links libxdo.so into every Linux desktop app. muda documents the feature's entire purpose:

libxdo is used to make the predefined Copy, Cut, Paste and SelectAll menu items work.

An app that never uses those items — including any app that calls .with_menu(None) — still hard-links the library.

That is normally just an extra build prerequisite, which is how it usually gets reported (#5090, #2219). The sharper consequence is at distribution time, and I haven't found it written down anywhere:

The soname is recorded at link time, so a release binary built on ubuntu-latest records libxdo.so.3. Ubuntu ships soname 3; Arch and other rolling distros ship 4. The dynamic loader will not substitute one for the other, so:

$ ./myapp
./myapp: error while loading shared libraries: libxdo.so.3: cannot open shared object file

Installing xdotool does not fix this — the user already has libxdo.so.4. There is no supported way to get soname 3 on those distros, so a prebuilt Linux artifact simply cannot run there, over a library the app never calls.

I hit this shipping a Dioxus app: of the binary's 146 dynamic dependencies, exactly one was unresolvable. GTK 3 and WebKitGTK 4.1 record identical sonames on both distro families and are fine; libxdo is the only one that skews.

Change

Mirrors what Tauri already does — tauri/Cargo.toml declares muda and tray-icon with default-features = false and exposes linux-libxdo as opt-in, since v2.0.0-alpha.11. Same crates, same maintainers, same reasoning.

  • muda and tray-icon are declared with default-features = false
  • gtk is kept explicitly on both — that is what actually renders menus and tray icons on Linux
  • a new linux-libxdo feature restores the old behaviour for apps that use the predefined menu items

Verification

In this branch's own workspace:

$ cargo tree --manifest-path packages/desktop/Cargo.toml -e normal | grep -c libxdo
0

$ cargo tree --manifest-path packages/desktop/Cargo.toml -e normal --features linux-libxdo | grep libxdo
│   ├── libxdo v0.6.0
│   │   └── libxdo-sys v0.11.0

I also applied the equivalent change to dioxus-desktop 0.7.9 via [patch.crates-io] and rebuilt a real application against it:

  • readelf -d shows no libxdo entry, where the unpatched build recorded libxdo.so.3
  • libxdo-sys leaves the dependency graph entirely
  • GTK 3 and WebKitGTK 4.1 are still linked
  • the app launches and renders normally on a machine with no libxdo.so.3 present

Notes

This is a breaking change only for apps that rely on the predefined Copy/Cut/Paste/SelectAll menu items on Linux; they need features = ["linux-libxdo"]. Apps already passing default-features = false to dioxus-desktop pick up the fix with no change. Happy to add a CHANGELOG entry or adjust the feature name if you'd prefer it match something else.

`libxdo` is a default feature of both `muda` and `tray-icon`, so every
Dioxus desktop app links `libxdo.so` whether or not it uses menus. muda
documents the feature as existing solely to make the predefined Copy,
Cut, Paste and SelectAll menu items work on Linux.

Because the soname is recorded at link time, a binary built on Ubuntu
(libxdo.so.3) will not start on a distro shipping libxdo 4, even with
xdotool installed. That makes prebuilt Linux artifacts non-portable for
a library most apps never call.

Disables default features on both crates, keeps `gtk` (which is what
renders menus and tray icons on Linux), and adds an opt-in
`linux-libxdo` feature for apps that do use the predefined items.
Mirrors tauri's `linux-libxdo`, which resolves this the same way.

Verified: libxdo is absent from the dependency graph by default and
restored by `--features linux-libxdo`.

@nicoburns nicoburns left a comment

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.

Makes sense - thanks!

@nicoburns
nicoburns merged commit b6c258b into DioxusLabs:main Aug 10, 2026
23 checks passed
@nabbisen
nabbisen deleted the linux-libxdo-opt-in branch August 11, 2026 01:08
nabbisen added a commit to forskscope/forskscope that referenced this pull request Aug 11, 2026
DioxusLabs/dioxus#5749 merged 2026-08-10 (b6c258b): muda and tray-icon
now take default-features = false with gtk kept, and libxdo is opt-in
behind linux-libxdo, mirroring Tauri.

Not yet released, so F44 stays open and 0.166.1 is gated on a
dioxus-desktop release. We already pass default-features = false, so the
fix arrives with a version bump alone.
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.

2 participants