Skip to content

Commit

Permalink
Merge pull request #815 from dremin/configure-hidden-icons
Browse files Browse the repository at this point in the history
Add more notification area icon options
  • Loading branch information
dremin authored Apr 30, 2024
2 parents badcdad + 4795f2d commit f97fae3
Show file tree
Hide file tree
Showing 12 changed files with 270 additions and 54 deletions.
3 changes: 2 additions & 1 deletion RetroBar/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
using System.Diagnostics;
using System.Reflection;
using ManagedShell.Common.Logging;
using System.Linq;

namespace RetroBar
{
Expand Down Expand Up @@ -110,7 +111,7 @@ private ShellManager SetupManagedShell()
_logger = new ManagedShellLogger();

ShellConfig config = ShellManager.DefaultShellConfig;
config.PinnedNotifyIcons = Settings.Instance.PinnedNotifyIcons;
config.PinnedNotifyIcons = Settings.Instance.NotifyIconBehaviors.Where(setting => setting.Behavior == NotifyIconBehavior.AlwaysShow).Select(setting => setting.Identifier).ToArray();

return new ShellManager(config);
}
Expand Down
9 changes: 7 additions & 2 deletions RetroBar/Controls/NotifyIcon.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public NotifyIcon()

private void applyEffects()
{
if (TrayIcon == null || Settings.Instance.InvertIconsMode == Settings.InvertIconsOption.Never)
if (TrayIcon == null || Settings.Instance.InvertIconsMode == InvertIconsOption.Never)
{
return;
}
Expand All @@ -45,7 +45,7 @@ private void applyEffects()
}

bool invertByTheme = Application.Current.FindResource("InvertSystemNotifyIcons") as bool? ?? false;
bool performInvert = invertByTheme || Settings.Instance.InvertIconsMode == Settings.InvertIconsOption.Always;
bool performInvert = invertByTheme || Settings.Instance.InvertIconsMode == InvertIconsOption.Always;

if (NotifyIconImage.Effect == null != performInvert)
{
Expand Down Expand Up @@ -106,6 +106,11 @@ private void TrayIcon_NotificationBalloonShown(object sender, NotificationBalloo
return;
}

if (TrayIcon == null || TrayIcon.GetBehavior() == NotifyIconBehavior.AlwaysHide || TrayIcon.GetBehavior() == NotifyIconBehavior.Disabled)
{
return;
}

BalloonControl.Show(e.Balloon, NotifyIconBorder);
e.Handled = true;
}
Expand Down
18 changes: 18 additions & 0 deletions RetroBar/Controls/NotifyIconList.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Windows.Data;
using System.Windows.Threading;
using ManagedShell.WindowsTray;
using RetroBar.Extensions;
using RetroBar.Utilities;

namespace RetroBar.Controls
Expand Down Expand Up @@ -75,6 +76,7 @@ private void NotifyIconList_OnLoaded(object sender, RoutedEventArgs e)
allNotifyIcons.Add(new CollectionContainer { Collection = NotificationArea.UnpinnedIcons });
allNotifyIcons.Add(new CollectionContainer { Collection = NotificationArea.PinnedIcons });
allNotifyIconsSource = new CollectionViewSource { Source = allNotifyIcons };
NotificationArea.UnpinnedIcons.Filter = UnpinnedNotifyIcons_Filter;

CompositeCollection pinnedNotifyIcons = new CompositeCollection();
pinnedNotifyIcons.Add(new CollectionContainer { Collection = promotedIcons });
Expand Down Expand Up @@ -105,6 +107,16 @@ private void NotifyIconList_OnLoaded(object sender, RoutedEventArgs e)
}
}

private bool UnpinnedNotifyIcons_Filter(object obj)
{
if (obj is ManagedShell.WindowsTray.NotifyIcon notifyIcon)
{
return !notifyIcon.IsPinned && !notifyIcon.IsHidden && notifyIcon.GetBehavior() != NotifyIconBehavior.Disabled;
}

return true;
}

private void NotificationArea_NotificationBalloonShown(object sender, NotificationBalloonEventArgs e)
{
// This is used to promote unpinned icons to show when the tray is collapsed.
Expand All @@ -122,6 +134,12 @@ private void NotificationArea_NotificationBalloonShown(object sender, Notificati
return;
}

if (notifyIcon.GetBehavior() != NotifyIconBehavior.HideWhenInactive)
{
// Do not promote icons that are always hidden
return;
}

if (promotedIcons.Contains(notifyIcon))
{
// Do not duplicate promoted icons
Expand Down
4 changes: 2 additions & 2 deletions RetroBar/Controls/TaskButton.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,11 @@ private void AppButton_OnMouseUp(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Middle)
{
if (Window == null || Settings.Instance.TaskMiddleClickAction == Settings.TaskMiddleClickOption.DoNothing)
if (Window == null || Settings.Instance.TaskMiddleClickAction == TaskMiddleClickOption.DoNothing)
{
return;
}
if (Settings.Instance.TaskMiddleClickAction == Settings.TaskMiddleClickOption.CloseTask)
if (Settings.Instance.TaskMiddleClickAction == TaskMiddleClickOption.CloseTask)
{
Window?.Close();
}
Expand Down
6 changes: 3 additions & 3 deletions RetroBar/Controls/TaskList.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ private void Settings_PropertyChanged(object sender, PropertyChangedEventArgs e)
}
else if (e.PropertyName == nameof(Settings.ShowMultiMon))
{
if (Settings.Instance.MultiMonMode != Settings.MultiMonOption.AllTaskbars)
if (Settings.Instance.MultiMonMode != MultiMonOption.AllTaskbars)
{
taskbarItems?.Refresh();
}
Expand All @@ -114,12 +114,12 @@ private bool Tasks_Filter(object obj)
return false;
}

if (!Settings.Instance.ShowMultiMon || Settings.Instance.MultiMonMode == Settings.MultiMonOption.AllTaskbars)
if (!Settings.Instance.ShowMultiMon || Settings.Instance.MultiMonMode == MultiMonOption.AllTaskbars)
{
return true;
}

if (Settings.Instance.MultiMonMode == Settings.MultiMonOption.SameAsWindowAndPrimary && Host.Screen.Primary)
if (Settings.Instance.MultiMonMode == MultiMonOption.SameAsWindowAndPrimary && Host.Screen.Primary)
{
return true;
}
Expand Down
26 changes: 26 additions & 0 deletions RetroBar/Converters/NotifyIconBehaviorConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using ManagedShell.WindowsTray;
using RetroBar.Extensions;
using System;
using System.Windows.Data;

namespace RetroBar.Converters
{
[ValueConversion(typeof(NotifyIcon), typeof(int))]
public class NotifyIconBehaviorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is NotifyIcon icon)
{
return (int)icon.GetBehavior();
}

return Binding.DoNothing;
}

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return Binding.DoNothing;
}
}
}
66 changes: 66 additions & 0 deletions RetroBar/Extensions/NotifyIconExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,72 @@ public static string GetInvertIdentifier(this NotifyIcon icon)
else return icon.Path + ":" + icon.UID.ToString();
}

public static NotifyIconBehavior GetBehavior(this NotifyIcon icon)
{
if (icon.IsPinned)
{
return NotifyIconBehavior.AlwaysShow;
}

if (Settings.Instance.NotifyIconBehaviors.Find(setting => setting.Identifier == icon.Identifier) is NotifyIconBehaviorSetting iconSetting)
{
return iconSetting.Behavior;
}

return NotifyIconBehavior.HideWhenInactive;
}

public static void SetBehavior(this NotifyIcon icon, NotifyIconBehavior behavior)
{
var settings = new List<NotifyIconBehaviorSetting>(Settings.Instance.NotifyIconBehaviors);
var currentSettingIndex = settings.FindIndex(setting => setting.Identifier == icon.Identifier);

if (currentSettingIndex >= 0)
{
if (behavior == NotifyIconBehavior.HideWhenInactive)
{
// Switching back to default value; remove from settings
settings.RemoveAt(currentSettingIndex);
}
else
{
settings[currentSettingIndex] = new NotifyIconBehaviorSetting
{
Identifier = icon.Identifier,
Behavior = behavior
};
}
}
else
{
settings.Add(new NotifyIconBehaviorSetting
{
Identifier = icon.Identifier,
Behavior = behavior
});
}

Settings.Instance.NotifyIconBehaviors = settings;

if (icon.IsPinned != (behavior == NotifyIconBehavior.AlwaysShow))
{
// Update pinned values in ManagedShell
if (behavior == NotifyIconBehavior.AlwaysShow)
{
icon.Pin();
}
else
{
icon.Unpin();
}
}
else
{
// Trigger a refresh of the collections
icon.OnPropertyChanged("IsPinned");
}
}

public static bool CanInvert(this NotifyIcon icon) {
return Settings.Instance.InvertNotifyIcons.Contains(icon.GetInvertIdentifier());
}
Expand Down
2 changes: 2 additions & 0 deletions RetroBar/Languages/English.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@
<s:String x:Key="customize_notifications_instruction">Select an item, then choose its notification behavior:</s:String>
<s:String x:Key="hide_when_inactive">Hide when inactive</s:String>
<s:String x:Key="always_show">Always show</s:String>
<s:String x:Key="always_hide">Always hide</s:String>
<s:String x:Key="disabled">Disabled</s:String>
<s:String x:Key="name_heading">Name</s:String>
<s:String x:Key="behavior_heading">Behavior</s:String>
<s:String x:Key="invert_heading">Invert</s:String>
Expand Down
21 changes: 15 additions & 6 deletions RetroBar/NotificationPropertiesWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<converters:BoolToIntConverter x:Key="boolToIntConverter" />
<converters:BoolToVisibilityConverter x:Key="boolToVisibilityConverter" />
<converters:NewLineToSpaceConverter x:Key="newLineToSpaceConverter" />
<converters:NotifyIconBehaviorConverter x:Key="notifyIconBehaviorConverter" />
<converters:NotifyIconCanInvertConverter x:Key="notifyIconCanInvertConverter" />
<Style TargetType="{x:Type ComboBox}">
<Setter Property="HorizontalAlignment"
Expand Down Expand Up @@ -100,22 +101,30 @@
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding IsPinned}" Value="True">
<DataTrigger Binding="{Binding Converter={StaticResource notifyIconBehaviorConverter}}" Value="0">
<Setter Property="Text" Value="{DynamicResource hide_when_inactive}" />
</DataTrigger>
<DataTrigger Binding="{Binding Converter={StaticResource notifyIconBehaviorConverter}}" Value="1">
<Setter Property="Text" Value="{DynamicResource always_hide}" />
</DataTrigger>
<DataTrigger Binding="{Binding Converter={StaticResource notifyIconBehaviorConverter}}" Value="2">
<Setter Property="Text" Value="{DynamicResource always_show}" />
</DataTrigger>
<DataTrigger Binding="{Binding IsPinned}" Value="False">
<Setter Property="Text" Value="{DynamicResource hide_when_inactive}" />
<DataTrigger Binding="{Binding Converter={StaticResource notifyIconBehaviorConverter}}" Value="3">
<Setter Property="Text" Value="{DynamicResource disabled}" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
<ComboBox Name="BehaviorComboBox"
SelectedIndex="{Binding IsPinned, Converter={StaticResource boolToIntConverter}}"
SelectedIndex="{Binding Mode=OneWay, Converter={StaticResource notifyIconBehaviorConverter}}"
SelectionChanged="BehaviorComboBox_SelectionChanged"
Visibility="Collapsed">
<ComboBoxItem Content="{DynamicResource hide_when_inactive}" />
<ComboBoxItem Content="{DynamicResource always_show}" />
<ComboBoxItem Content="{DynamicResource hide_when_inactive}" Tag="{x:Static Settings:NotifyIconBehavior.HideWhenInactive}" />
<ComboBoxItem Content="{DynamicResource always_hide}" Tag="{x:Static Settings:NotifyIconBehavior.AlwaysHide}" />
<ComboBoxItem Content="{DynamicResource always_show}" Tag="{x:Static Settings:NotifyIconBehavior.AlwaysShow}" />
<ComboBoxItem Content="{DynamicResource disabled}" Tag="{x:Static Settings:NotifyIconBehavior.Disabled}" />
</ComboBox>
</StackPanel>
<DataTemplate.Triggers>
Expand Down
16 changes: 14 additions & 2 deletions RetroBar/NotificationPropertiesWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ private NotificationPropertiesWindow(NotificationArea notificationArea)

private void Settings_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "InvertNotifyIcons")
if (e.PropertyName == nameof(Settings.InvertNotifyIcons) || e.PropertyName == nameof(Settings.NotifyIconBehaviors))
{
// Reload icons
DataContext = null;
Expand Down Expand Up @@ -63,7 +63,19 @@ private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs

private void BehaviorComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Settings.Instance.PinnedNotifyIcons = _notificationArea.PinnedNotifyIcons;
if (e.AddedItems.Count > 0 &&
(sender as FrameworkElement).DataContext is NotifyIcon notifyIcon &&
e.AddedItems[0] is ComboBoxItem selected &&
selected.Tag is NotifyIconBehavior behavior)
{
if (notifyIcon.GetBehavior() == behavior)
{
// Same setting selected; do nothing
return;
}

notifyIcon.SetBehavior(behavior);
}
}

private void InvertCheckBox_Checked(object sender, RoutedEventArgs e)
Expand Down
Loading

0 comments on commit f97fae3

Please sign in to comment.