Skip to content

Commit

Permalink
Merge pull request #6779 from AvaloniaUI/dbus-tray-icon-fix
Browse files Browse the repository at this point in the history
Graceful error handling of Linux Tray icons
  • Loading branch information
Takoooooo authored and danwalmsley committed Oct 26, 2021
1 parent 015f1ac commit 6dbf015
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 52 deletions.
3 changes: 1 addition & 2 deletions src/Avalonia.Controls/NativeMenuItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class NativeMenuItem : NativeMenuItemBase, INativeMenuItemExporterEventsI
private bool _isChecked = false;
private NativeMenuItemToggleType _toggleType;
private IBitmap _icon;
private readonly CanExecuteChangedSubscriber _canExecuteChangedSubscriber;

private NativeMenu _menu;

Expand Down Expand Up @@ -47,8 +48,6 @@ public void OnEvent(object sender, EventArgs e)
}
}

private readonly CanExecuteChangedSubscriber _canExecuteChangedSubscriber;


public NativeMenuItem()
{
Expand Down
49 changes: 48 additions & 1 deletion src/Avalonia.Controls/TrayIcon.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Input;
using Avalonia.Collections;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Platform;
using Avalonia.Platform;
using Avalonia.Utilities;

#nullable enable

Expand All @@ -13,10 +15,13 @@ namespace Avalonia.Controls
public sealed class TrayIcons : AvaloniaList<TrayIcon>
{
}



public class TrayIcon : AvaloniaObject, INativeMenuExporterProvider, IDisposable
{
private readonly ITrayIconImpl? _impl;
private ICommand? _command;

private TrayIcon(ITrayIconImpl? impl)
{
Expand All @@ -26,7 +31,15 @@ private TrayIcon(ITrayIconImpl? impl)

_impl.SetIsVisible(IsVisible);

_impl.OnClicked = () => Clicked?.Invoke(this, EventArgs.Empty);
_impl.OnClicked = () =>
{
Clicked?.Invoke(this, EventArgs.Empty);

if (Command?.CanExecute(CommandParameter) == true)
{
Command.Execute(CommandParameter);
}
};
}
}

Expand Down Expand Up @@ -64,6 +77,21 @@ static TrayIcon()
/// on OSX this event is not raised.
/// </summary>
public event EventHandler? Clicked;

/// <summary>
/// Defines the <see cref="Command"/> property.
/// </summary>
public static readonly DirectProperty<TrayIcon, ICommand?> CommandProperty =
Button.CommandProperty.AddOwner<TrayIcon>(
trayIcon => trayIcon.Command,
(trayIcon, command) => trayIcon.Command = command,
enableDataValidation: true);

/// <summary>
/// Defines the <see cref="CommandParameter"/> property.
/// </summary>
public static readonly StyledProperty<object?> CommandParameterProperty =
Button.CommandParameterProperty.AddOwner<MenuItem>();

/// <summary>
/// Defines the <see cref="TrayIcons"/> attached property.
Expand Down Expand Up @@ -98,6 +126,25 @@ public static readonly StyledProperty<NativeMenu?> MenuProperty
public static void SetIcons(AvaloniaObject o, TrayIcons trayIcons) => o.SetValue(IconsProperty, trayIcons);

public static TrayIcons GetIcons(AvaloniaObject o) => o.GetValue(IconsProperty);

/// <summary>
/// Gets or sets the <see cref="Command"/> property of a TrayIcon.
/// </summary>
public ICommand? Command
{
get => _command;
set => SetAndRaise(CommandProperty, ref _command, value);
}

/// <summary>
/// Gets or sets the parameter to pass to the <see cref="Command"/> property of a
/// <see cref="TrayIcon"/>.
/// </summary>
public object CommandParameter
{
get { return GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}

/// <summary>
/// Gets or sets the Menu of the TrayIcon.
Expand Down
6 changes: 3 additions & 3 deletions src/Avalonia.FreeDesktop/DBusHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class DBusHelper
/// This class uses synchronous execution at DBus connection establishment stage
/// then switches to using AvaloniaSynchronizationContext
/// </summary>
class DBusSyncContext : SynchronizationContext
private class DBusSyncContext : SynchronizationContext
{
private SynchronizationContext _ctx;
private object _lock = new object();
Expand Down Expand Up @@ -51,10 +51,10 @@ public void Initialized()

public static Connection TryInitialize(string dbusAddress = null)
{
return Connection ?? TryGetConnection(dbusAddress);
return Connection ?? TryCreateNewConnection(dbusAddress);
}

public static Connection TryGetConnection(string dbusAddress = null)
public static Connection TryCreateNewConnection(string dbusAddress = null)
{
var oldContext = SynchronizationContext.Current;
try
Expand Down
Loading

0 comments on commit 6dbf015

Please sign in to comment.