Skip to content

Commit

Permalink
fix(TrayIcon::Tooltip): Fix issue where the trayIcon tooltip kept bei…
Browse files Browse the repository at this point in the history
…ng rebuilt.

Fixes SOUNDSWITCH-1J
  • Loading branch information
Belphemur committed May 9, 2021
1 parent e5a4140 commit ca188bd
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public CachedAudioDeviceLister(DeviceState state)

private void DeviceChanged(object sender, DeviceChangedEventBase e)
{
_dispatcher.Debounce(100, o => Refresh());
_dispatcher.Debounce<object>(TimeSpan.FromMilliseconds(100), _ => Refresh());
}

public void Refresh()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ namespace SoundSwitch.Framework.TrayIcon.TooltipInfoManager
{
public class TooltipInfoManager
{

private static class Fixes
{
public static void SetNotifyIconText(NotifyIcon ni, string text)
Expand All @@ -30,22 +31,20 @@ public static void SetNotifyIconText(NotifyIcon ni, string text)
Type t = typeof(NotifyIcon);
BindingFlags hidden = BindingFlags.NonPublic | BindingFlags.Instance;
t.GetField("text", hidden).SetValue(ni, text);
if ((bool)t.GetField("added", hidden).GetValue(ni))
t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] { true });
if ((bool) t.GetField("added", hidden).GetValue(ni))
t.GetMethod("UpdateIcon", hidden).Invoke(ni, new object[] {true});
}
}

private readonly NotifyIcon _icon;
private readonly TooltipInfoFactory _tooltipInfoFactory;
public bool IsBallontipVisible { get; set; }

public TooltipInfoManager(NotifyIcon icon)
{
_icon = icon;
_tooltipInfoFactory = new TooltipInfoFactory();
_icon.BalloonTipShown += IconOnBalloonTipShown;
_icon.BalloonTipClosed += IconOnBalloonTipClosed;
}

/// <summary>
/// Currently active tooltip info
/// </summary>
Expand All @@ -62,41 +61,18 @@ public static TooltipInfoTypeEnum CurrentTooltipInfo
}
}

private void IconOnBalloonTipClosed(object sender, EventArgs eventArgs)
{
IsBallontipVisible = false;
}

private void IconOnBalloonTipShown(object sender, EventArgs eventArgs)
{
IsBallontipVisible = true;
}


/// <summary>
/// Show the tooltip with the TrayIcon
/// </summary>
public void ShowTooltipInfo()
public void SetIconText()
{
if (IsBallontipVisible)
return;

var tooltipInfo = _tooltipInfoFactory.Get(CurrentTooltipInfo);
var text = tooltipInfo.TextToDisplay();

if (text == null)
return;
Fixes.SetNotifyIconText(_icon, $"{Application.ProductName}\n{text}");

//_icon.ShowBalloonTip(1000, $"{Application.ProductName}: {TooltipInfo.titleTooltip}", text, ToolTipIcon.Info)

}

~TooltipInfoManager()
{
_icon.BalloonTipClosed -= IconOnBalloonTipClosed;
_icon.BalloonTipShown -= IconOnBalloonTipShown;
}
}

}
6 changes: 3 additions & 3 deletions SoundSwitch/Model/AppModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ private AppModel()
_deviceCyclerManager = new DeviceCyclerManager();
MMNotificationClient.Instance.DefaultDeviceChanged += (sender, @event) =>
{
_dispatcher.Debounce(250, o =>
_dispatcher.Debounce(TimeSpan.FromMilliseconds(200), defaultDeviceChanged =>
{
Log.Information(@"[WINAPI] Default device changed to {device}:{role}", @event.Device, @event.Role);
DefaultDeviceChanged?.Invoke(sender, @event);
});
defaultDeviceChanged?.Invoke(sender, @event);
}, DefaultDeviceChanged);
};
_microphoneMuteToggler = new MicrophoneMuteToggler(AudioSwitcher.Instance, _notificationManager);
}
Expand Down
25 changes: 5 additions & 20 deletions SoundSwitch/UI/Component/TrayIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,11 @@ public TrayIcon()
PopulateSettingsMenu();

_selectionMenu.Items.Add(TrayIconStrings.noDevicesSelected, RessourceSettingsSmallBitmap, (sender, e) => ShowSettings());

//NotifyIcon.MouseDoubleClick += (sender, args) => { AppModel.Instance.CycleActiveDevice(DataFlow.Render); };

NotifyIcon.MouseDown += (sender, e) =>
{
Log.Debug("Click on systray icon: {times} {button}", e.Clicks, e.Button);
if (e.Clicks == 2)
{
NotifyIcon.ContextMenuStrip.Close();
AppModel.Instance.CycleActiveDevice(DataFlow.Render);
return;
}
Expand All @@ -119,24 +115,9 @@ public TrayIcon()

NotifyIcon.ContextMenuStrip = _settingsMenu;
};

NotifyIcon.MouseMove += (sender, args) =>
{
try
{
if (!NotifyIcon.Visible)
return;
_tooltipInfoManager.ShowTooltipInfo();
}
catch (Exception)
{
//ignored
}
};
_selectionMenu.Closed += (sender, args) => _tooltipInfoManager.IsBallontipVisible = false;
_settingsMenu.Closed += (sender, args) => _tooltipInfoManager.IsBallontipVisible = false;
SetEventHandlers();
_updateDownloadForm = new UpdateDownloadForm();
_tooltipInfoManager.SetIconText();
}

public void Dispose()
Expand Down Expand Up @@ -246,6 +227,10 @@ private void SetEventHandlers()
if (@event.UpdateMode == UpdateMode.Notify)
_context.Send(s => { NewReleaseAvailable(sender, @event); }, null);
};
AppModel.Instance.DefaultDeviceChanged += (_, _) =>
{
_tooltipInfoManager.SetIconText();
};
}

private void NewReleaseAvailable(object sender, UpdateChecker.NewReleaseEvent newReleaseEvent)
Expand Down
9 changes: 4 additions & 5 deletions SoundSwitch/Util/Timer/DebounceDispatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@ public class DebounceDispatcher
/// <param name="param">optional parameter</param>
/// <param name="priority">optional priorty for the dispatcher</param>
/// <param name="disp">optional dispatcher. If not passed or null CurrentDispatcher is used.</param>
public void Debounce(int interval, Action<object> action,
object param = null)
public void Debounce<T>(TimeSpan interval, Action<T> action, T param = default)
{
lock (_lockDebounce)
{
Expand All @@ -50,7 +49,7 @@ public void Debounce(int interval, Action<object> action,
// timer is recreated for each event and effectively
// resets the timeout. Action only fires after timeout has fully
// elapsed without other events firing in between
_timer = new System.Timers.Timer(interval) {AutoReset = false};
_timer = new System.Timers.Timer(interval.TotalMilliseconds) {AutoReset = false};
_timer.Elapsed += (sender, args) =>
{
if (_timer == null)
Expand All @@ -76,8 +75,7 @@ public void Debounce(int interval, Action<object> action,
/// <param name="param">optional parameter</param>
/// <param name="priority">optional priorty for the dispatcher</param>
/// <param name="disp">optional dispatcher. If not passed or null CurrentDispatcher is used.</param>
public void Throttle(int interval, Action<object> action,
object param = null)
public void Throttle<T>(TimeSpan delay, Action<T> action, T param = default)
{
lock (_lockThrottle)
{
Expand All @@ -87,6 +85,7 @@ public void Throttle(int interval, Action<object> action,


var curTime = DateTime.UtcNow;
var interval = delay.TotalMilliseconds;

// if timeout is not up yet - adjust timeout to fire
// with potentially new Action parameters
Expand Down

0 comments on commit ca188bd

Please sign in to comment.