mirror of
https://github.com/netbirdio/netbird.git
synced 2026-08-31 03:51:29 +02:00
Fix watcher registration on wayland (#6320)
* Fix hover label on linux * Fix watcher registration on wayland
This commit is contained in:
@@ -98,9 +98,27 @@ func (w *statusNotifierWatcher) tryStartXembedHost(busName string, objPath dbus.
|
||||
}
|
||||
|
||||
// startStatusNotifierWatcher claims org.kde.StatusNotifierWatcher on the
|
||||
// session bus if it is not already provided by another process.
|
||||
// Safe to call unconditionally — it does nothing when a real watcher is present.
|
||||
// session bus, but ONLY as a bridge to an XEmbed system tray on minimal WMs.
|
||||
//
|
||||
// The in-process watcher is a stub: its RegisterStatusNotifierItem only
|
||||
// tracks items so it can mirror them into an XEmbed tray icon — it does
|
||||
// NOT relay them to any other StatusNotifierHost. So if we claim the name
|
||||
// on a desktop that has a real watcher/host (e.g. Hyprland + Waybar), every
|
||||
// other tray app (Slack, etc.) registers into our dead-end watcher and its
|
||||
// icon never reaches the real host. We won that name purely by starting
|
||||
// first; a GetNameOwner check doesn't help against a login-order race.
|
||||
//
|
||||
// The correct discriminator is whether an XEmbed tray actually exists. If
|
||||
// one does, we are the bridge of last resort and should claim the watcher.
|
||||
// If not (pure Wayland, or any environment already running a real watcher),
|
||||
// we have nothing to bridge and must stay off the bus entirely so the real
|
||||
// watcher owns the name. Safe to call unconditionally.
|
||||
func startStatusNotifierWatcher() {
|
||||
if !xembedTrayAvailable() {
|
||||
log.Debugf("StatusNotifierWatcher: no XEmbed tray present, leaving the watcher to the desktop")
|
||||
return
|
||||
}
|
||||
|
||||
conn, err := dbus.SessionBusPrivate()
|
||||
if err != nil {
|
||||
log.Debugf("StatusNotifierWatcher: cannot open private session bus: %v", err)
|
||||
|
||||
@@ -88,6 +88,25 @@ func goMenuItemClicked(id C.int) {
|
||||
}
|
||||
|
||||
// newXembedHost creates an XEmbed tray icon for the given SNI item.
|
||||
// xembedTrayAvailable reports whether an XEmbed system tray manager
|
||||
// (_NET_SYSTEM_TRAY_S0) currently owns its selection on the default screen.
|
||||
// It is a cheap, side-effect-free probe — it only queries the selection
|
||||
// owner, creating no windows. Used to decide whether the in-process
|
||||
// StatusNotifierWatcher is needed at all: the watcher exists solely to
|
||||
// bridge SNI items into an XEmbed tray on minimal WMs, so when no XEmbed
|
||||
// tray is present (e.g. Wayland compositors with a real SNI host like
|
||||
// Waybar) we must not claim org.kde.StatusNotifierWatcher and shadow the
|
||||
// real one. Returns false when there is no X display (pure Wayland).
|
||||
func xembedTrayAvailable() bool {
|
||||
dpy := C.XOpenDisplay(nil)
|
||||
if dpy == nil {
|
||||
return false
|
||||
}
|
||||
defer C.XCloseDisplay(dpy)
|
||||
screen := C.xembed_default_screen(dpy)
|
||||
return C.xembed_find_tray(dpy, screen) != 0
|
||||
}
|
||||
|
||||
// Returns an error if no XEmbed tray manager is available (graceful fallback).
|
||||
func newXembedHost(conn *dbus.Conn, busName string, objPath dbus.ObjectPath) (*xembedHost, error) {
|
||||
dpy := C.XOpenDisplay(nil)
|
||||
|
||||
Reference in New Issue
Block a user