Sushi removes 'Always on Visible Workspace'

Ubuntu Version

Ubuntu 26.04 LTS

Desktop Environment (if applicable)

GNOME

Problem Description

I use gnome-sushi to preview my files in nautilus, and because I have dual monitors I have set nautilus to be displayed on ‘Always on Visible Workspace’. (I have fixed the number of Workspaces to 4). However, when I press space bar to preview the file, the ‘Always on Visible Workspace’ is disabled. Is there a way to ensure that gnome-sushi doesn’t do this ? It seems to work fine for most of the time and then it fails.

I also have the following gnome extension installed: Deja Window

Relevant System Information

Hardware Information:

  • Hardware Model: NOVATECH LTD PC-X003745
  • Memory: 16.0 GiB
  • Processor: Intel® Core™ i5-6500 × 4
  • Graphics: NV106
  • Graphics 1: Intel® HD Graphics 530 (SKL GT2)

Software Information:

  • Firmware Version: 3805
  • OS Name: Ubuntu 26.04.1 LTS
  • OS Build: (null)
  • OS Type: 64-bit
  • GNOME Version: 50
  • Windowing System: Wayland
  • Kernel Version: Linux 7.0.0-31-generic
1 Like

I dug into this one in the Mutter and Sushi sources, and I think I can explain what’s happening — it’s not Sushi touching your Nautilus window directly, it’s the transient-parent link plus the way Mutter propagates workspace changes upwards.

How Sushi attaches to Nautilus

When you hit space, Nautilus exports its Wayland surface handle and passes it to Sushi over D-Bus (ShowFile(uri, windowHandle, ...)). Sushi then calls sushi_window_set_child_of_external(), which does gdk_wayland_toplevel_set_transient_for_exported() — so the preview window is registered as a transient child of your Nautilus window.

Source: src/libsushi/externalwindow.c and src/core/application.js in GNOME/sushi; src/nautilus-previewer.c in GNOME/nautilus.

Why your sticky flag gets clobbered

The relevant part is meta_window_change_workspace() in Mutter’s src/core/window.c:

meta_window_change_workspace_without_transients (window, workspace);
meta_window_foreach_transient (window, change_workspace_foreach, workspace);
meta_window_foreach_ancestor (window, change_workspace_foreach, workspace);

Note the last line — it walks the transient chain upwards to ancestors, not just down to children. And change_workspace_without_transients() starts with:

/* Try to unstick the window if it's stuck. */
if (window->on_all_workspaces_requested)
    meta_window_unstick (window);

So when Sushi’s window is moved to a workspace, that change propagates up the transient chain to Nautilus, and Nautilus gets unstick()ed as a side effect.

Why it’s intermittent: the activation path is only taken when Sushi’s window isn’t already on the active workspace. If you’re previewing while the active workspace matches where things already are, nothing moves and the flag survives — matching your “works fine most of the time and then it fails.” The timing of focus/activation on Wayland means it’s not deterministic.

What you can try

  1. Test whether the transient link is really the culprit. Launch Sushi standalone on a file without Nautilus involved and watch the flag:

    sushi /path/to/some-file.png &
    

    Standalone Sushi has no parent handle, so no transient link. If your Nautilus window’s sticky flag still gets cleared, this analysis is wrong and something else (possibly Deja Window) is responsible.

  2. Deja Window is worth ruling in or out. Since it persists window state, it may be re-applying — or fighting over — the workspace assignment when Sushi appears/disappears. Try disabling it for a session. I couldn’t find its source to confirm, so this is a hypothesis, not a finding.

  3. The workspaces-only-on-primary angle. With a dual-monitor setup, if org.gnome.mutter workspaces-only-on-primary is true, any window on the non-primary monitor is implicitly on_all_workspaces (should_be_on_all_workspaces() returns TRUE for those). Check:

    gsettings get org.gnome.mutter workspaces-only-on-primary
    

    If it’s true, your sticky setting is interacting with a monitor-based override, which would make the flag churn much more likely.

I’m fairly confident in the mechanism, since it’s straight from the Mutter source — but the trigger in your specific setup is the part I can’t verify without your machine. If the standalone-sushi test shows the flag survives, then Sushi’s transient link is exonerated and I’d look at Deja Window next.

1 Like

Hi lechynte-ub

Many thanks for getting back to me with such a comprehensive reply.

Suggestion 1:
I tried using standalone sushi. This had no noticeable effect on nautilus.

Suggestion 2:
I disabled deja-window for a session with no effects on nautilus. This appeared to be the culprit. Re-enabled, and it began occurring again. I then changed some of the settings for nautilus in deja-window (in particular, not using regex when defining the WM Class). This seems to have sorted the issue (though, I am conscious it’s early days).

Suggestions 3:
gsettings get org.gnome.mutter workspaces-only-on-primary returned false.

Thanks for your prompt response.

That’s a clean isolation, and you did the part I couldn’t — I searched for Deja Window’s source and never found it, so the extension’s matching rules stayed a hypothesis in my last reply. Your disable/re-enable toggle is the test I would have wanted to run, and the re-enable reproducing it is what makes it an actual finding rather than a guess.

The WM_CLASS detail slots into the mechanism I traced in the mutter sources in a way that makes sense of the intermittent timing. Nautilus’s own window class is Nautilus with the instance name org.gnome.Nautilus, and Sushi’s is org.gnome.NautilusPreviewer — they share the Nautilus prefix but not the class. A regex pattern loose enough to match one would plausibly match the other, or match the Nautilus file manager itself when the rule was meant for something narrower. Once the regex was hitting the Nautilus window, the extension’s workspace rule applied to it, and that’s where the transient-chain behavior in mutter takes over: activating the Sushi preview triggers meta_window_activate, which moves a transient window to the active workspace, and meta_window_change_workspace walks the ancestor chain via meta_window_foreach_ancestor. The change_workspace_without_transients path unsets the sticky flag at the top. So the extension had quietly put a workspace rule on the Nautilus window, and the Sushi activation is what set it off.

Your exact-match fix is the right permanent one, since it removes the match that put the rule there. The reason I’d still keep an eye on it isn’t that I expect a relapse — it’s that the same loose regex could have been matching other windows you haven’t noticed yet, and a regex that broad on window classes tends to catch things in batches rather than one at a time.

Thanks for reporting back with the specifics. The WM-class-versus-regex distinction is the kind of detail that would never have surfaced from reading mutter alone.

This topic was automatically closed 18 hours after the last reply. New replies are no longer allowed.