diff --git a/src/Avalonia.FreeDesktop/DBusHelper.cs b/src/Avalonia.FreeDesktop/DBusHelper.cs index da74f15a3e..b733176243 100644 --- a/src/Avalonia.FreeDesktop/DBusHelper.cs +++ b/src/Avalonia.FreeDesktop/DBusHelper.cs @@ -7,37 +7,51 @@ namespace Avalonia.FreeDesktop { internal static class DBusHelper { - public static Connection? Connection { get; private set; } + private static Connection? s_defaultConntection; + private static bool s_defaultConnectionFailed; + public static Connection? DefaultConnection + { + get + { + if (s_defaultConntection == null && !s_defaultConnectionFailed) + { + s_defaultConntection = TryCreateNewConnection(); + if (s_defaultConntection == null) + s_defaultConnectionFailed = true; + } - public static Connection? TryInitialize(string? dbusAddress = null) - => Connection ?? TryCreateNewConnection(dbusAddress); + return s_defaultConntection; + } + } public static Connection? TryCreateNewConnection(string? dbusAddress = null) { var oldContext = SynchronizationContext.Current; + Connection? conn = null; try { - var conn = new Connection(new ClientConnectionOptions(dbusAddress ?? Address.Session!) + SynchronizationContext.SetSynchronizationContext(null); + conn = new Connection(new ClientConnectionOptions(dbusAddress ?? Address.Session!) { - AutoConnect = false + AutoConnect = false, }); // Connect synchronously conn.ConnectAsync().GetAwaiter().GetResult(); - - Connection = conn; + return conn; } catch (Exception e) { Logger.TryGet(LogEventLevel.Error, "DBUS") ?.Log(null, "Unable to connect to DBus: " + e); + conn?.Dispose(); } finally { SynchronizationContext.SetSynchronizationContext(oldContext); } - return Connection; + return null; } } } diff --git a/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs b/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs index 8042d3bff2..babf5cf417 100644 --- a/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs +++ b/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs @@ -37,7 +37,7 @@ namespace Avalonia.FreeDesktop.DBusIme var factory = DetectInputMethod(); if (factory is not null) { - var conn = DBusHelper.TryInitialize(); + var conn = DBusHelper.DefaultConnection; if (conn is not null) { AvaloniaLocator.CurrentMutable.Bind().ToConstant(factory(conn)); diff --git a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs index 931c574edc..2a3d76eaeb 100644 --- a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs +++ b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs @@ -17,7 +17,7 @@ namespace Avalonia.FreeDesktop internal class DBusMenuExporter { public static ITopLevelNativeMenuExporter? TryCreateTopLevelNativeMenu(IntPtr xid) => - DBusHelper.Connection is null ? null : new DBusMenuExporterImpl(DBusHelper.Connection, xid); + DBusHelper.DefaultConnection is {} conn ? new DBusMenuExporterImpl(conn, xid) : null; public static INativeMenuExporter TryCreateDetachedNativeMenu(string path, Connection currentConnection) => new DBusMenuExporterImpl(currentConnection, path); diff --git a/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs b/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs index acfa985e90..affa50a8e0 100644 --- a/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs +++ b/src/Avalonia.FreeDesktop/DBusPlatformSettings.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Avalonia.Media; using Avalonia.Platform; +using Avalonia.Threading; using Tmds.DBus.Protocol; using Tmds.DBus.SourceGenerator; @@ -17,10 +18,11 @@ namespace Avalonia.FreeDesktop public DBusPlatformSettings() { - if (DBusHelper.Connection is null) + if (DBusHelper.DefaultConnection is not {} conn) return; + using var restoreContext = AvaloniaSynchronizationContext.Ensure(DispatcherPriority.Input); - _settings = new OrgFreedesktopPortalSettings(DBusHelper.Connection, "org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop"); + _settings = new OrgFreedesktopPortalSettings(conn, "org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop"); _ = _settings.WatchSettingChangedAsync(SettingsChangedHandler); _ = TryGetInitialValuesAsync(); } diff --git a/src/Avalonia.FreeDesktop/DBusSystemDialog.cs b/src/Avalonia.FreeDesktop/DBusSystemDialog.cs index bd041a044a..c4663878cc 100644 --- a/src/Avalonia.FreeDesktop/DBusSystemDialog.cs +++ b/src/Avalonia.FreeDesktop/DBusSystemDialog.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Avalonia.Platform; using Avalonia.Platform.Storage; using Avalonia.Platform.Storage.FileIO; +using Avalonia.Threading; using Tmds.DBus.Protocol; using Tmds.DBus.SourceGenerator; @@ -16,10 +17,12 @@ namespace Avalonia.FreeDesktop { internal static async Task TryCreateAsync(IPlatformHandle handle) { - if (DBusHelper.Connection is null) + if (DBusHelper.DefaultConnection is not {} conn) return null; - var dbusFileChooser = new OrgFreedesktopPortalFileChooser(DBusHelper.Connection, "org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop"); + using var restoreContext = AvaloniaSynchronizationContext.Ensure(DispatcherPriority.Input); + + var dbusFileChooser = new OrgFreedesktopPortalFileChooser(conn, "org.freedesktop.portal.Desktop", "/org/freedesktop/portal/desktop"); uint version; try { @@ -30,7 +33,7 @@ namespace Avalonia.FreeDesktop return null; } - return new DBusSystemDialog(DBusHelper.Connection, handle, dbusFileChooser, version); + return new DBusSystemDialog(conn, handle, dbusFileChooser, version); } private readonly Connection _connection; diff --git a/src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs b/src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs index 8b3592090d..0d4fb57169 100644 --- a/src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs +++ b/src/Avalonia.FreeDesktop/DBusTrayIconImpl.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Avalonia.Controls.Platform; using Avalonia.Logging; using Avalonia.Platform; +using Avalonia.Threading; using Tmds.DBus.Protocol; using Tmds.DBus.SourceGenerator; @@ -39,6 +40,7 @@ namespace Avalonia.FreeDesktop public DBusTrayIconImpl() { + using var restoreContext = AvaloniaSynchronizationContext.Ensure(DispatcherPriority.Input); _connection = DBusHelper.TryCreateNewConnection(); if (_connection is null) diff --git a/src/Avalonia.X11/X11Platform.cs b/src/Avalonia.X11/X11Platform.cs index e16cb0d98c..905e9e1346 100644 --- a/src/Avalonia.X11/X11Platform.cs +++ b/src/Avalonia.X11/X11Platform.cs @@ -68,9 +68,6 @@ namespace Avalonia.X11 Info = new X11Info(Display, DeferredDisplay, useXim); Globals = new X11Globals(this); Resources = new XResources(this); - //TODO: log - if (options.UseDBusMenu) - DBusHelper.TryInitialize(); IRenderTimer timer = options.ShouldRenderOnUIThread ? new UiThreadRenderTimer(60)