From ca188bdff5ca89b78ef7dc3d1fcb1be24be47d7e Mon Sep 17 00:00:00 2001 From: Antoine Aflalo Date: Sun, 9 May 2021 19:00:48 -0400 Subject: [PATCH] fix(TrayIcon::Tooltip): Fix issue where the trayIcon tooltip kept being rebuilt. Fixes SOUNDSWITCH-1J --- .../Audio/Lister/CachedAudioDeviceLister.cs | 2 +- .../TooltipInfoManager/TooltipInfoManager.cs | 34 +++---------------- SoundSwitch/Model/AppModel.cs | 6 ++-- SoundSwitch/UI/Component/TrayIcon.cs | 25 +++----------- SoundSwitch/Util/Timer/DebounceDispatcher.cs | 9 +++-- 5 files changed, 18 insertions(+), 58 deletions(-) diff --git a/SoundSwitch/Framework/Audio/Lister/CachedAudioDeviceLister.cs b/SoundSwitch/Framework/Audio/Lister/CachedAudioDeviceLister.cs index d1fec1977a..794a5822de 100644 --- a/SoundSwitch/Framework/Audio/Lister/CachedAudioDeviceLister.cs +++ b/SoundSwitch/Framework/Audio/Lister/CachedAudioDeviceLister.cs @@ -45,7 +45,7 @@ public CachedAudioDeviceLister(DeviceState state) private void DeviceChanged(object sender, DeviceChangedEventBase e) { - _dispatcher.Debounce(100, o => Refresh()); + _dispatcher.Debounce(TimeSpan.FromMilliseconds(100), _ => Refresh()); } public void Refresh() diff --git a/SoundSwitch/Framework/TrayIcon/TooltipInfoManager/TooltipInfoManager.cs b/SoundSwitch/Framework/TrayIcon/TooltipInfoManager/TooltipInfoManager.cs index 1084b96730..5b3e96bd2e 100644 --- a/SoundSwitch/Framework/TrayIcon/TooltipInfoManager/TooltipInfoManager.cs +++ b/SoundSwitch/Framework/TrayIcon/TooltipInfoManager/TooltipInfoManager.cs @@ -22,6 +22,7 @@ namespace SoundSwitch.Framework.TrayIcon.TooltipInfoManager { public class TooltipInfoManager { + private static class Fixes { public static void SetNotifyIconText(NotifyIcon ni, string text) @@ -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; } + /// /// Currently active tooltip info /// @@ -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; - } - /// /// Show the tooltip with the TrayIcon /// - 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; } } - } \ No newline at end of file diff --git a/SoundSwitch/Model/AppModel.cs b/SoundSwitch/Model/AppModel.cs index 65d61146da..ad518b1173 100644 --- a/SoundSwitch/Model/AppModel.cs +++ b/SoundSwitch/Model/AppModel.cs @@ -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); } diff --git a/SoundSwitch/UI/Component/TrayIcon.cs b/SoundSwitch/UI/Component/TrayIcon.cs index 1c83a90775..5d5e7e759a 100644 --- a/SoundSwitch/UI/Component/TrayIcon.cs +++ b/SoundSwitch/UI/Component/TrayIcon.cs @@ -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; } @@ -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() @@ -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) diff --git a/SoundSwitch/Util/Timer/DebounceDispatcher.cs b/SoundSwitch/Util/Timer/DebounceDispatcher.cs index 9a96d61b17..76a021226a 100644 --- a/SoundSwitch/Util/Timer/DebounceDispatcher.cs +++ b/SoundSwitch/Util/Timer/DebounceDispatcher.cs @@ -39,8 +39,7 @@ public class DebounceDispatcher /// optional parameter /// optional priorty for the dispatcher /// optional dispatcher. If not passed or null CurrentDispatcher is used. - public void Debounce(int interval, Action action, - object param = null) + public void Debounce(TimeSpan interval, Action action, T param = default) { lock (_lockDebounce) { @@ -50,7 +49,7 @@ public void Debounce(int interval, Action 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) @@ -76,8 +75,7 @@ public void Debounce(int interval, Action action, /// optional parameter /// optional priorty for the dispatcher /// optional dispatcher. If not passed or null CurrentDispatcher is used. - public void Throttle(int interval, Action action, - object param = null) + public void Throttle(TimeSpan delay, Action action, T param = default) { lock (_lockThrottle) { @@ -87,6 +85,7 @@ public void Throttle(int interval, Action action, var curTime = DateTime.UtcNow; + var interval = delay.TotalMilliseconds; // if timeout is not up yet - adjust timeout to fire // with potentially new Action parameters