Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug] broken IPC in multi window app on Linux #11171

Closed
Ynng opened this issue Sep 28, 2024 · 9 comments · Fixed by #11268
Closed

[bug] broken IPC in multi window app on Linux #11171

Ynng opened this issue Sep 28, 2024 · 9 comments · Fixed by #11268
Assignees
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug

Comments

@Ynng
Copy link

Ynng commented Sep 28, 2024

Describe the bug

In a multi-window Tauri app on Linux, only the first window ever created can receive events and have its listen callbacks triggered. All subsequent windows do not receive any events.

In this video, the same Tauri app runs on Windows on the left and Linux on the right.

Every window ran listen("reply", (event) => {alert(event.payload})}).
When the button is pressed, a Rust Tauri command is invoked, which emits the reply event.

On Windows, the app behaves correctly and every window receives the reply event.

On Linux, only the first window ever receives any events.

Screencast.from.2024-09-27.23-42-14.mp4

Reproduction

The example shown in the video: https://github.com/Ynng/tauri-listen-test

Or:

  • Clone the tauri repo on an Ubuntu 24 machine
  • Run cargo run --example multiwindow
  • Try to send a message to the second/third window

Expected behavior

All windows should receive events that are "emitted to all targets".

Full tauri info output

[✔] Environment
    - OS: Fedora 40.0.0 x86_64 (X64)
    ✔ webkit2gtk-4.1: 2.44.3
    ✔ rsvg2: 2.57.1
    ✔ rustc: 1.80.1 (3f5fd8dd4 2024-08-06)
    ✔ cargo: 1.80.1 (376290515 2024-07-16)
    ✔ rustup: 1.27.1 (54dd3d00f 2024-04-24)
    ✔ Rust toolchain: stable-x86_64-unknown-linux-gnu (environment override by RUSTUP_TOOLCHAIN)
    - node: 21.7.2
    - pnpm: 9.7.1
    - npm: 10.5.0

[-] Packages
    - tauri 🦀: 2.0.0-rc.11
    - tauri-build 🦀: 2.0.0-rc.13
    - wry 🦀: 0.44.1
    - tao 🦀: 0.30.2
    - tauri-cli 🦀: 2.0.0-rc.10

[-] Plugins
    - tauri-plugin-shell 🦀: 2.0.0-rc.0

[-] App
    - build-type: bundle
    - CSP: unset
    - frontendDist: ../dist
    - devUrl: http://localhost:1420/

Stack trace

No response

Additional context

Undoing #11043 fixes this problem, but re-introduces #10981

@Ynng Ynng added status: needs triage This issue needs to triage, applied to new issues type: bug labels Sep 28, 2024
@Ynng Ynng changed the title [bug] only the first created window receives events on Linux [bug] only the first window receives tauri events on Linux Sep 28, 2024
@Ynng
Copy link
Author

Ynng commented Sep 29, 2024

It appears that this bug was introduced in tauri version 2.0.0-rc.16.

I tested with tauri pinned to version =2.0.0-rc.15 and tauri-utils pinned to version =2.0.0-rc.12, and the bug does not occur

@Ynng Ynng changed the title [bug] only the first window receives tauri events on Linux [bug] borked event handling for multiple windows on Linux in Tauri v2.0.0-rc.16 Sep 29, 2024
@Ynng
Copy link
Author

Ynng commented Sep 29, 2024

My guess is #11043 might be related

@Ynng
Copy link
Author

Ynng commented Oct 2, 2024

The problem still exists on Tauri 2.0.0 stable

@Ynng Ynng changed the title [bug] borked event handling for multiple windows on Linux in Tauri v2.0.0-rc.16 [bug] broken event listening in multi window app on Linux Oct 2, 2024
@gschier
Copy link

gschier commented Oct 2, 2024

I just ran into this today too.

One other thing I noticed is that the injected window in the #[command] is always the main window, too.

For example, this prints main on Linux, when it prints settings on macOS

#[tauri::command]
async fn cmd_update_settings(settings: Settings, w: WebviewWindow) -> Result<Settings, String> {
    println!("UPDATE SETTINGS {}", w.label());
    update_settings(&w, settings)
        .await
        .map_err(|e| e.to_string())
}

@gschier
Copy link

gschier commented Oct 2, 2024

Perhaps the same root cause, but it seems like data-tauri-drag-region="true" is also broken in additional windows on Linux

@Ynng
Copy link
Author

Ynng commented Oct 3, 2024

Manually reverting the changes made in #11043 solved the problem, but re-introduced #10981.

@Ynng
Copy link
Author

Ynng commented Oct 5, 2024

I just ran into this today too.

One other thing I noticed is that the injected window in the #[command] is always the main window, too.

For example, this prints main on Linux, when it prints settings on macOS

#[tauri::command]
async fn cmd_update_settings(settings: Settings, w: WebviewWindow) -> Result<Settings, String> {
    println!("UPDATE SETTINGS {}", w.label());
    update_settings(&w, settings)
        .await
        .map_err(|e| e.to_string())
}

I'm fairly certain this is the cause of the "event listening issue" I described.
The listen command is getting the wrong webview object.

@Ynng
Copy link
Author

Ynng commented Oct 5, 2024

I think I figured out the problem:

for (scheme, protocol) in uri_scheme_protocols {
// on Linux the custom protocols are associated with the web context
// and you cannot register a scheme more than once
if cfg!(any(
target_os = "linux",
target_os = "dragonfly",
target_os = "freebsd",
target_os = "netbsd",
target_os = "openbsd"
)) {
if web_context.registered_custom_protocols.contains(&scheme) {
continue;
}
web_context
.registered_custom_protocols
.insert(scheme.clone());
}
webview_builder =
webview_builder.with_asynchronous_custom_protocol(scheme, move |request, responder| {
protocol(
request,
Box::new(move |response| responder.respond(response)),
)
});
}

As documented, on Linux, custom protocols are associated with the web context and thus we can't register a scheme more than once.

However, every webview want its own tauri, ipc and asset handlers.

On Linux, only the first window's handlers are registered.
Secondary windows' handlers are simply ignored.

@Ynng
Copy link
Author

Ynng commented Oct 5, 2024

Some ideas for potential fix:

On the short term, we can:
Use separate web context (revert #11043) and accept desyned local storage (reopen #10981) for now.

To completely fix the problem,
we need to include the window label in InvokeRequest and update the ipc handler to route requests based on that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage This issue needs to triage, applied to new issues type: bug
Projects
None yet
3 participants