Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add legacy mode option to fix tooltip positioning issues (#398 and #760) #787

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SyncTrayzor/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
</PathConfiguration>
<DefaultUserConfiguration Version="10">
<ShowTrayIconOnlyOnClose>false</ShowTrayIconOnlyOnClose>
<ShowTrayToolTipInLegacyMode>false</ShowTrayToolTipInLegacyMode>
<MinimizeToTray>false</MinimizeToTray>
<CloseToTray>true</CloseToTray>
<ShowDeviceConnectivityBalloons>false</ShowDeviceConnectivityBalloons>
Expand Down
12 changes: 12 additions & 0 deletions src/SyncTrayzor/NotifyIcon/NotifyIconManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ namespace SyncTrayzor.NotifyIcon
public interface INotifyIconManager : IDisposable
{
bool ShowOnlyOnClose { get; set; }
bool ShowInLegacyMode { get; set; }
bool MinimizeToTray { get; set; }
bool CloseToTray { get; set; }
Dictionary<string, bool> FolderNotificationsEnabled { get; set; }
Expand Down Expand Up @@ -59,6 +60,17 @@ public bool ShowOnlyOnClose
}
}

private bool _showInLegacyMode;
public bool ShowInLegacyMode
{
get => this._showInLegacyMode;
set
{
this._showInLegacyMode = value;
Utils.TrayToolTipWorkaround.SetLegacyMode(value, this.taskbarIcon);
}
}

public bool MinimizeToTray { get; set; }

private bool _closeToTray;
Expand Down
1 change: 1 addition & 0 deletions src/SyncTrayzor/Pages/Settings/SettingsView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
<CheckBox DockPanel.Dock="Top" IsChecked="{Binding ShowDeviceConnectivityBalloons.Value}" Content="{l:Loc SettingsView_ShowDeviceConnectivityBalloons}"/>
<CheckBox DockPanel.Dock="Top" IsChecked="{Binding ShowDeviceOrFolderRejectedBalloons.Value}" Content="{l:Loc SettingsView_ShowDeviceOrFolderRejectedBalloons}"/>
<CheckBox DockPanel.Dock="Top" IsChecked="{Binding ShowTrayIconOnlyOnClose.Value}" Content="{l:Loc SettingsView_OnlyShowTrayIconOnClose}"/>
<CheckBox DockPanel.Dock="Top" IsChecked="{Binding ShowTrayToolTipInLegacyMode.Value}" Content="{l:Loc SettingsView_ShowTrayToolTipInLegacyMode}"/>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,5,0,0">
<Label Padding="0,0,5,0" Target="{Binding ElementName=IconAnimationModeSelect}" VerticalAlignment="Center" Content="{l:Loc SettingsView_AnimateTrayIcon}"/>
<ComboBox x:Name="IconAnimationModeSelect" ItemsSource="{Binding IconAnimationModes}" SelectedValuePath="Value" SelectedValue="{Binding IconAnimationMode.Value}"/>
Expand Down
3 changes: 3 additions & 0 deletions src/SyncTrayzor/Pages/Settings/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class SettingsViewModel : Screen
public SettingItem<bool> PauseDevicesOnMeteredNetworks { get; }

public SettingItem<bool> ShowTrayIconOnlyOnClose { get; }

public SettingItem<bool> ShowTrayToolTipInLegacyMode { get; }
public SettingItem<bool> ShowSynchronizedBalloonEvenIfNothingDownloaded { get; }
public SettingItem<bool> ShowDeviceConnectivityBalloons { get; }
public SettingItem<bool> ShowDeviceOrFolderRejectedBalloons { get; }
Expand Down Expand Up @@ -138,6 +140,7 @@ public SettingsViewModel(
this.PauseDevicesOnMeteredNetworksSupported = meteredNetworkManager.IsSupportedByWindows;

this.ShowTrayIconOnlyOnClose = this.CreateBasicSettingItem(x => x.ShowTrayIconOnlyOnClose);
this.ShowTrayToolTipInLegacyMode = this.CreateBasicSettingItem(x => x.ShowTrayToolTipInLegacyMode);
this.ShowSynchronizedBalloonEvenIfNothingDownloaded = this.CreateBasicSettingItem(x => x.ShowSynchronizedBalloonEvenIfNothingDownloaded);
this.ShowDeviceConnectivityBalloons = this.CreateBasicSettingItem(x => x.ShowDeviceConnectivityBalloons);
this.ShowDeviceOrFolderRejectedBalloons = this.CreateBasicSettingItem(x => x.ShowDeviceOrFolderRejectedBalloons);
Expand Down
13 changes: 11 additions & 2 deletions src/SyncTrayzor/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/SyncTrayzor/Properties/Resources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1002,4 +1002,7 @@ Please donate to my charity fundraising campaign.</value>
<data name="BarAlertsView_IntelXeGraphics_DismissLink" xml:space="preserve">
<value>Dismiss</value>
</data>
<data name="SettingsView_ShowTrayToolTipInLegacyMode" xml:space="preserve">
<value>Show TrayToolTip in legacy mode (Experimental): Check this option if the TrayToolTip is displaying in the wrong location to attempt to fix it.</value>
</data>
</root>
5 changes: 4 additions & 1 deletion src/SyncTrayzor/Services/Config/Configuration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public int Version
}

public bool ShowTrayIconOnlyOnClose { get; set; }
public bool ShowTrayToolTipInLegacyMode { get; set; }
public bool MinimizeToTray { get; set; }
public bool CloseToTray { get; set; }
public bool ShowDeviceConnectivityBalloons { get; set; }
Expand Down Expand Up @@ -78,6 +79,7 @@ public Configuration()
// Default configuration is for a portable setup.

this.ShowTrayIconOnlyOnClose = false;
this.ShowTrayToolTipInLegacyMode = false;
this.MinimizeToTray = false;
this.CloseToTray = true;
this.ShowSynchronizedBalloonEvenIfNothingDownloaded = false;
Expand Down Expand Up @@ -116,6 +118,7 @@ public Configuration()
public Configuration(Configuration other)
{
this.ShowTrayIconOnlyOnClose = other.ShowTrayIconOnlyOnClose;
this.ShowTrayToolTipInLegacyMode = other.ShowTrayToolTipInLegacyMode;
this.MinimizeToTray = other.MinimizeToTray;
this.CloseToTray = other.CloseToTray;
this.ShowSynchronizedBalloonEvenIfNothingDownloaded = other.ShowSynchronizedBalloonEvenIfNothingDownloaded;
Expand Down Expand Up @@ -153,7 +156,7 @@ public Configuration(Configuration other)

public override string ToString()
{
return $"<Configuration ShowTrayIconOnlyOnClose={this.ShowTrayIconOnlyOnClose} MinimizeToTray={this.MinimizeToTray} CloseToTray={this.CloseToTray} " +
return $"<Configuration ShowTrayIconOnlyOnClose={this.ShowTrayIconOnlyOnClose} ShowTrayToolTipInLegacyMode={this.ShowTrayToolTipInLegacyMode} MinimizeToTray={this.MinimizeToTray} CloseToTray={this.CloseToTray} " +
$"ShowDeviceConnectivityBalloons={this.ShowDeviceConnectivityBalloons} ShowDeviceOrFolderRejectedBalloons={this.ShowDeviceOrFolderRejectedBalloons} " +
$"SyncthingAddress={this.SyncthingAddress} StartSyncthingAutomatically={this.StartSyncthingAutomatically} " +
$"SyncthingCommandLineFlags=[{String.Join(",", this.SyncthingCommandLineFlags)}] " +
Expand Down
1 change: 1 addition & 0 deletions src/SyncTrayzor/Services/ConfigurationApplicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ private void ApplyNewConfiguration(Configuration configuration)
this.notifyIconManager.MinimizeToTray = configuration.MinimizeToTray;
this.notifyIconManager.CloseToTray = configuration.CloseToTray;
this.notifyIconManager.ShowOnlyOnClose = configuration.ShowTrayIconOnlyOnClose;
this.notifyIconManager.ShowInLegacyMode = configuration.ShowTrayToolTipInLegacyMode;
this.notifyIconManager.FolderNotificationsEnabled = configuration.Folders.ToDictionary(x => x.ID, x => x.NotificationsEnabled);
this.notifyIconManager.ShowSynchronizedBalloonEvenIfNothingDownloaded = configuration.ShowSynchronizedBalloonEvenIfNothingDownloaded;
this.notifyIconManager.ShowDeviceConnectivityBalloons = configuration.ShowDeviceConnectivityBalloons;
Expand Down
7 changes: 4 additions & 3 deletions src/SyncTrayzor/SyncTrayzor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
<WarningLevel>4</WarningLevel>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<IsWebBootstrapper>false</IsWebBootstrapper>
<TargetFrameworkProfile />
<GenerateResourceMSBuildArchitecture>CurrentArchitecture</GenerateResourceMSBuildArchitecture>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
Expand All @@ -27,11 +30,8 @@
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
<GenerateResourceMSBuildArchitecture>CurrentArchitecture</GenerateResourceMSBuildArchitecture>
</PropertyGroup>
<PropertyGroup>
</PropertyGroup>
Expand Down Expand Up @@ -339,6 +339,7 @@
<Compile Include="Utils\StringExtensions.cs" />
<Compile Include="Utils\SynchronizedEventDispatcher.cs" />
<Compile Include="Design\ViewModelLocator.cs" />
<Compile Include="Utils\TrayToolTipWorkaround.cs" />
<Compile Include="Xaml\ActivateBehaviour.cs" />
<Compile Include="Xaml\CultureAwareBinding.cs" />
<Compile Include="Xaml\GridLengthToAbsoluteConverter.cs" />
Expand Down
92 changes: 92 additions & 0 deletions src/SyncTrayzor/Utils/TrayToolTipWorkaround.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.Windows;
using System.Reflection;
using Hardcodet.Wpf.TaskbarNotification;
using Hardcodet.Wpf.TaskbarNotification.Interop;

namespace SyncTrayzor.Utils
{
public static class TrayToolTipWorkaround {
private static bool hasFixed = false;
private static bool legacyMode = false;

private static void setTipTextMode(TaskbarIcon taskbarIcon) {
if (!hasFixed || taskbarIcon == null) {
return;
}

if (taskbarIcon.TrayToolTip == null && taskbarIcon.TrayToolTipResolved != null) {
// icon data
FieldInfo iconDataField = typeof(TaskbarIcon).GetField("iconData", BindingFlags.NonPublic | BindingFlags.Instance);
if (iconDataField == null) {
return;
}

NotifyIconData iconData = (NotifyIconData) iconDataField.GetValue(taskbarIcon);
IconDataMembers flags = IconDataMembers.Tip;
if (legacyMode) {
flags |= IconDataMembers.UseLegacyToolTips;
}
if (iconData.ValidMembers != flags) {
iconData.ValidMembers = flags;

// get util type
Type utilType = typeof(TaskbarIcon).GetTypeInfo().Assembly.GetType("Hardcodet.Wpf.TaskbarNotification.Util");
if (utilType == null)
{
return;
}

// get write method
MethodInfo writeIconDataMethod = utilType.GetMethod("WriteIconData", new Type[] { typeof(NotifyIconData).MakeByRefType(), typeof(NotifyCommand) });
if (writeIconDataMethod == null)
{
return;
}

writeIconDataMethod.Invoke(null, new object[] { iconData, NotifyCommand.Modify });
}
}
}

private static void doFix(TaskbarIcon taskbarIcon) {
// register new DependencyProperty
DependencyProperty newProperty = DependencyProperty.Register("NewToolTipText", typeof(string), typeof(TaskbarIcon),
new FrameworkPropertyMetadata(string.Empty, (d, e) => {
// call the origin callback func
MethodInfo originCbMethod = typeof(TaskbarIcon).GetMethod("ToolTipTextPropertyChanged", BindingFlags.Static | BindingFlags.NonPublic);
originCbMethod?.Invoke(null, new object[] { d, e });

// try to refresh legacy mode
TaskbarIcon t = d as TaskbarIcon;
setTipTextMode(t);
})
);

// back up tip text
string tipTextBackup = string.Empty;
if (taskbarIcon != null && !string.IsNullOrEmpty(taskbarIcon.ToolTipText)) {
tipTextBackup = taskbarIcon.ToolTipText;
}

// set new ToolTipTextProperty, every time update ToolTipText, will run own func
var propertyFieldInfo = typeof(TaskbarIcon).GetField("ToolTipTextProperty", BindingFlags.Static | BindingFlags.Public);
propertyFieldInfo.SetValue(null, newProperty);

// set tip text
if (taskbarIcon != null) {
taskbarIcon.ToolTipText = tipTextBackup;
}
}

public static void SetLegacyMode(bool _legacyMode, TaskbarIcon taskbarIcon)
{
if(_legacyMode && !hasFixed) {
doFix(taskbarIcon);
hasFixed = true;
}
legacyMode = _legacyMode;
setTipTextMode(taskbarIcon);
}
}
}