diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md
similarity index 100%
rename from CONTRIBUTING.md
rename to .github/CONTRIBUTING.md
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 00000000..07d6479e
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: ['https://github.com/canton7/synctrayzor/blob/develop/DONATING.md#donating']
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 25c333a4..1e7ea0a8 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
Changelog
=========
+v1.1.28
+-------
+
+ - Work around Intel X2 Graphics driver bug which causes Syncthing's UI to appear blank (#606)
+ - Fix chocolatey package (#614)
+
v1.1.27
-------
diff --git a/DONATING.md b/DONATING.md
new file mode 100644
index 00000000..32b61cb7
--- /dev/null
+++ b/DONATING.md
@@ -0,0 +1,38 @@
+Donating
+========
+
+Syncthing and SyncTrayzor are free software, and you don't need to pay a penny to use them.
+However, if you find them useful, please consider giving a small amount to one of the causes below.
+
+Syncthing
+---------
+
+SyncTrayzor is just the wrapper around [Syncthing](https://syncthing.net), which makes it look and behave like a native Windows application.
+The heavy lifting is being done by Syncthing.
+
+While development is done for free by a fantastic team, running the infrastructure which lets your devices find and talk to each other costs money, as does hosting things like the [website](https://syncthing.net) and [forum](https://forum.syncthing.net).
+If you make use of these, I kindly ask that you consider sending a small amount towards funding Syncthing's running costs and future development.
+Donations are handled by the Syncthing Foundation, whose accounts are public.
+
+[Donate to Syncthing](https://syncthing.net/donations/).
+
+
+SyncTrayzor Charity Fundraiser
+------------------------------
+
+I've put a lot of my free time into writing and maintaining SyncTrayzor.
+If you use it and appreciate it, I'd be very grateful if you could show your thanks by
+donating a small amount (the price of a beer) to charity.
+
+I've been running charity fundraisers for many years, and very kind people from all over the world have helped raise thousands for people who really need it, which is absolutely amazing.
+
+Please consider [donating to the current appeal](https://synctrayzor.antonymale.co.uk/fundraiser).
+
+
+Buy me a beer
+-------------
+
+If you want to buy me a coffee (or beer!), you'll absolutely make my day.
+Thank you!
+
+I'm on [Ko-fi](https://ko-fi.com/canton7) or [PayPal](https://www.paypal.com/donate?hosted_button_id=92FADFBYS42MU).
diff --git a/README.md b/README.md
index aa046519..9d13b8df 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Quick Links
- [Download and install SyncTrayzor now](#installation)
- [Something went wrong](#something-went-wrong)
- - [Find SyncTrayzor useful? Please donate!](#find-synctrayzor-useful-please-donate)
+ - [Find Syncthing/SyncTrayzor useful? Please donate!](DONATING.md#donating)
Introduction
@@ -80,15 +80,10 @@ Multi-lingual? SyncTrayzor needs you! Please read [Localization](https://github.
Want to make a contribution? Fantastic, and thank you! Please read [Contributing](https://github.com/canton7/SyncTrayzor/wiki/Contributing) first.
-Find SyncTrayzor useful? Please donate!
----------------------------------------
+Find Syncthing/SyncTrayzor useful? Please donate!
+-------------------------------------------------
-I develop SyncTrayzor in my free time because I enjoy it.
-SyncTrayzor will never become paid-for.
-
-However, if you find SyncTrayzor useful and want to say thanks, please consider [donating to my charity fundraiser](https://synctrayzor.antonymale.co.uk/donate).
-I'm currently raising money for Médecins Sans Frontières (Doctors Without Borders).
-Thanks!
+Please see [DONATING](DONATING.md#donating).
Will SyncTrayzor phone home / give away my secrets / etc?
diff --git a/chocolatey/synctrayzor.nuspec b/chocolatey/synctrayzor.nuspec
index ba956d89..2f3767fb 100644
--- a/chocolatey/synctrayzor.nuspec
+++ b/chocolatey/synctrayzor.nuspec
@@ -44,6 +44,8 @@ Features include:
+
+
https://github.com/canton7/SyncTrayzor/blob/master/CHANGELOG.md
diff --git a/chocolatey/tools/chocolateyinstall.ps1 b/chocolatey/tools/chocolateyinstall.ps1
index cc86fd40..b960eb28 100644
--- a/chocolatey/tools/chocolateyinstall.ps1
+++ b/chocolatey/tools/chocolateyinstall.ps1
@@ -4,7 +4,7 @@ $toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definitio
$packageName= 'SyncTrayzor'
$file = (Join-Path $toolsDir 'SyncTrayzorSetup-x86.exe')
$file64 = (Join-Path $toolsDir 'SyncTrayzorSetup-x64.exe')
-$silentArgs = '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP-'
+$silentArgs = '/VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- /SkipDotNetInstall'
$fileType = 'exe'
$validExitCodes = @(0)
diff --git a/installer/common.iss b/installer/common.iss
index c94e122d..f814315e 100644
--- a/installer/common.iss
+++ b/installer/common.iss
@@ -250,13 +250,27 @@ begin
end
end;
+function CmdLineParamGiven(const Value: String): Boolean;
+var
+ I: Integer;
+begin
+ // Can't use {param}, as it doesn't match flags with no value
+ Result := False;
+ for I := 1 to ParamCount do
+ if CompareText(ParamStr(I), Value) = 0 then
+ begin
+ Result := True;
+ Exit;
+ end;
+end;
+
function PrepareToInstall(var NeedsRestart: Boolean): String;
begin
// 'NeedsRestart' only has an effect if we return a non-empty string, thus aborting the installation.
// If the installers indicate that they want a restart, this should be done at the end of installation.
// Therefore we set the global 'restartRequired' if a restart is needed, and return this from NeedRestart()
- if DotNetIsMissing() then
+ if not CmdLineParamGiven('/SkipDotNetInstall') and DotNetIsMissing() then
begin
Result := InstallDotNet();
end;
@@ -268,19 +282,8 @@ begin
end;
function ShouldStartSyncTrayzor(): Boolean;
-var
- flagPassed: Boolean;
- i: Integer;
begin
- // Can't use {param}, as it doesn't match flags with no value
- flagPassed := False;
- for i := 0 to ParamCount do begin
- if ParamStr(i) = '/StartSyncTrayzor' then begin
- flagPassed := True;
- break;
- end;
- end;
- Result := (not WizardSilent()) or flagPassed;
+ Result := (not WizardSilent()) or CmdLineParamGiven('/StartSyncTrayzor');
end;
function SyncTrayzorStartFlags(param: String): String;
diff --git a/server/version_check.php b/server/version_check.php
index 1460a52b..abceccb9 100644
--- a/server/version_check.php
+++ b/server/version_check.php
@@ -65,7 +65,7 @@ function get_with_wildcard($src, $value, $default = null)
}
$versions = [
- '1.1.27' => [
+ '1.1.28' => [
'base_url' => 'https://github.com/canton7/SyncTrayzor/releases/download',
'installed' => [
'direct_download_url' => [
@@ -82,7 +82,7 @@ function get_with_wildcard($src, $value, $default = null)
'sha1sum_download_url' => "{base_url}/v{version}/sha1sum.txt.asc",
'sha512sum_download_url' => "{base_url}/v{version}/sha512sum.txt.asc",
'release_page_url' => 'https://github.com/canton7/SyncTrayzor/releases/tag/v{version}',
- 'release_notes' => "- Add touch support\n- Minor UI updates (#538, #540, #541, #543)\n- Wrap text on Settings screen (#540)\n- Improve appearance on high-DPI displays (#559)\n- Uninstaller tries to remove autostart registry keys (#586)",
+ 'release_notes' => "Add a workaround for an Intel Xe graphics driver bug which causes Syncthing's UI to appear blank.\n\nIf you are not affected by this, you do not need to upgrade.",
],
'1.1.21' => [
'base_url' => 'https://synctrayzor.antonymale.co.uk/download',
@@ -106,9 +106,10 @@ function get_with_wildcard($src, $value, $default = null)
];
$upgrades = [
- '1.1.26' => ['to' => 'latest', 'formatter' => '5', 'overrides' => ['release_notes' => "- Fix crashes on a small number of machines (#602, #603)\n- Wrap text on Settings screen (#540)\n- Improve appearance on high-DPI displays (#559)"]],
- '1.1.25' => ['to' => 'latest', 'formatter' => '5', 'overrides' => ['release_notes' => "- Fix the problems in v1.1.25 (#594, #595, #596, #597, #602, #603)\n- Wrap text on Settings screen (#540)\n- Improve appearance on high-DPI displays (#559)\n- Uninstaller tries to remove autostart registry keys (#586)"]],
- '1.1.24' => ['to' => 'latest', 'formatter' => '5', 'overrides' => ['release_notes' => "- Add touch support\n- Wrap text on Settings screen (#540)\n- Improve appearance on high-DPI displays (#559)\n- Uninstaller tries to remove autostart registry keys (#586)"]],
+ '1.1.27' => ['to' => 'latest', 'formatter' => '5'],
+ '1.1.26' => ['to' => 'latest', 'formatter' => '5'],
+ '1.1.25' => ['to' => 'latest', 'formatter' => '5'],
+ '1.1.24' => ['to' => 'latest', 'formatter' => '5'],
'1.1.23' => ['to' => 'latest', 'formatter' => '5'],
'1.1.22' => ['to' => 'latest', 'formatter' => '5'],
'1.1.21' => ['to' => 'latest', 'formatter' => '5'],
diff --git a/src/SyncTrayzor/Bootstrapper.cs b/src/SyncTrayzor/Bootstrapper.cs
index 2ef8eab3..fb07af52 100644
--- a/src/SyncTrayzor/Bootstrapper.cs
+++ b/src/SyncTrayzor/Bootstrapper.cs
@@ -27,6 +27,8 @@
using SyncTrayzor.Localization;
using SyncTrayzor.Services.Ipc;
using System.Net;
+using System.Windows.Media;
+using System.Windows.Interop;
namespace SyncTrayzor
{
@@ -195,6 +197,13 @@ protected override void Configure()
MessageBoxViewModel.DefaultFlowDirection = Localizer.FlowDirection;
RecycleBinDeleter.Logger = s => LogManager.GetLogger(typeof(RecycleBinDeleter).FullName).Error(s);
+
+ // Workaround for Intel Xe processors, which mess up CefSharp unless we disable hardware
+ // rendering for WPF. See #606.
+ if (configuration.DisableHardwareRendering)
+ {
+ RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;
+ }
}
protected override void Launch()
diff --git a/src/SyncTrayzor/Pages/BarAlerts/BarAlertsViewModel.cs b/src/SyncTrayzor/Pages/BarAlerts/BarAlertsViewModel.cs
index 16aeed50..c7e02c82 100644
--- a/src/SyncTrayzor/Pages/BarAlerts/BarAlertsViewModel.cs
+++ b/src/SyncTrayzor/Pages/BarAlerts/BarAlertsViewModel.cs
@@ -1,6 +1,7 @@
using Stylet;
using SyncTrayzor.Pages.ConflictResolution;
using SyncTrayzor.Services;
+using SyncTrayzor.Services.Config;
using SyncTrayzor.Syncthing;
using System;
using System.Collections.Generic;
@@ -12,23 +13,33 @@ public class BarAlertsViewModel : Conductor.Collection.AllActive
private readonly IAlertsManager alertsManager;
private readonly ISyncthingManager syncthingManager;
private readonly Func conflictResolutionViewModelFactory;
+ private readonly Func intelXeGraphicsAlertViewModelFactory;
private readonly IWindowManager windowManager;
+ private readonly IConfigurationProvider configurationProvider;
+ private readonly GraphicsCardDetector graphicsCardDetector;
public BarAlertsViewModel(
IAlertsManager alertsManager,
ISyncthingManager syncthingManager,
Func conflictResolutionViewModelFactory,
- IWindowManager windowManager)
+ Func intelXeGraphicsAlertViewModelFactory,
+ IWindowManager windowManager,
+ IConfigurationProvider configurationProvider,
+ GraphicsCardDetector graphicsCardDetector)
{
this.alertsManager = alertsManager;
this.syncthingManager = syncthingManager;
this.conflictResolutionViewModelFactory = conflictResolutionViewModelFactory;
+ this.intelXeGraphicsAlertViewModelFactory = intelXeGraphicsAlertViewModelFactory;
this.windowManager = windowManager;
+ this.configurationProvider = configurationProvider;
+ this.graphicsCardDetector = graphicsCardDetector;
}
protected override void OnInitialActivate()
{
this.alertsManager.AlertsStateChanged += this.AlertsStateChanged;
+ this.configurationProvider.ConfigurationChanged += this.AlertsStateChanged;
this.Load();
}
@@ -69,6 +80,12 @@ private void Load()
var vm = new PausedDevicesFromMeteringViewModel(pausedDeviceNames);
this.Items.Add(vm);
}
+
+ var configuration = this.configurationProvider.Load();
+ if (!configuration.DisableHardwareRendering && !configuration.HideIntelXeWarningMessage && this.graphicsCardDetector.IsIntelXe)
+ {
+ this.Items.Add(this.intelXeGraphicsAlertViewModelFactory());
+ }
}
private void OpenConflictResolver()
@@ -80,6 +97,7 @@ private void OpenConflictResolver()
protected override void OnClose()
{
this.alertsManager.AlertsStateChanged -= this.AlertsStateChanged;
+ this.configurationProvider.ConfigurationChanged -= this.AlertsStateChanged;
}
}
}
diff --git a/src/SyncTrayzor/Pages/BarAlerts/IntelXeGraphicsAlertView.xaml b/src/SyncTrayzor/Pages/BarAlerts/IntelXeGraphicsAlertView.xaml
new file mode 100644
index 00000000..6025b741
--- /dev/null
+++ b/src/SyncTrayzor/Pages/BarAlerts/IntelXeGraphicsAlertView.xaml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/SyncTrayzor/Pages/BarAlerts/IntelXeGraphicsAlertViewModel.cs b/src/SyncTrayzor/Pages/BarAlerts/IntelXeGraphicsAlertViewModel.cs
new file mode 100644
index 00000000..0ab58a72
--- /dev/null
+++ b/src/SyncTrayzor/Pages/BarAlerts/IntelXeGraphicsAlertViewModel.cs
@@ -0,0 +1,22 @@
+using Stylet;
+using SyncTrayzor.Services.Config;
+
+namespace SyncTrayzor.Pages.BarAlerts
+{
+ public class IntelXeGraphicsAlertViewModel : Screen, IBarAlert
+ {
+ private readonly IConfigurationProvider configurationProvider;
+
+ public AlertSeverity Severity => AlertSeverity.Info;
+
+ public IntelXeGraphicsAlertViewModel(IConfigurationProvider configurationProvider)
+ {
+ this.configurationProvider = configurationProvider;
+ }
+
+ public void Dismiss()
+ {
+ this.configurationProvider.AtomicLoadAndSave(config => config.HideIntelXeWarningMessage = true);
+ }
+ }
+}
diff --git a/src/SyncTrayzor/Pages/ViewerViewModel.cs b/src/SyncTrayzor/Pages/ViewerViewModel.cs
index 3fc5d3b5..d86e5b12 100644
--- a/src/SyncTrayzor/Pages/ViewerViewModel.cs
+++ b/src/SyncTrayzor/Pages/ViewerViewModel.cs
@@ -113,9 +113,10 @@ protected override void OnInitialActivate()
if (configuration.DisableHardwareRendering)
{
- settings.CefCommandLineArgs.Add("disable-gpu", "1");
- settings.CefCommandLineArgs.Add("disable-gpu-vsync", "1");
- settings.CefCommandLineArgs.Add("disable-application-cache", "1");
+ settings.CefCommandLineArgs.Add("disable-gpu");
+ settings.CefCommandLineArgs.Add("disable-gpu-vsync");
+ settings.CefCommandLineArgs.Add("disable-gpu-compositing");
+ settings.CefCommandLineArgs.Add("disable-application-cache");
}
Cef.Initialize(settings);
diff --git a/src/SyncTrayzor/Properties/Resources.Designer.cs b/src/SyncTrayzor/Properties/Resources.Designer.cs
index 62a5b1dc..fa430820 100644
--- a/src/SyncTrayzor/Properties/Resources.Designer.cs
+++ b/src/SyncTrayzor/Properties/Resources.Designer.cs
@@ -205,6 +205,24 @@ public static string BarAlertsView_FailedTransfer_Details {
}
}
+ ///
+ /// Looks up a localized string similar to The area below may be blank when using Intel Xe graphics cards. Please disable hardware rendering under File -> Settings if you encounter this..
+ ///
+ public static string BarAlertsView_IntelXeGraphics_AlertText {
+ get {
+ return ResourceManager.GetString("BarAlertsView_IntelXeGraphics_AlertText", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Dismiss.
+ ///
+ public static string BarAlertsView_IntelXeGraphics_DismissLink {
+ get {
+ return ResourceManager.GetString("BarAlertsView_IntelXeGraphics_DismissLink", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The following {0:p:device has|devices have} been paused because {0:p:it|they} connected using a metered network: {0:l:{}|, }..
///
diff --git a/src/SyncTrayzor/Properties/Resources.resx b/src/SyncTrayzor/Properties/Resources.resx
index 415b6c18..5b30fd0e 100644
--- a/src/SyncTrayzor/Properties/Resources.resx
+++ b/src/SyncTrayzor/Properties/Resources.resx
@@ -995,4 +995,11 @@ Please donate to my charity fundraising campaign.
_Rescan All Folders
Menu option available when right-clicking the tray icon. Allows the user to re-scan all folders
+
+ The area below may be blank when using Intel Xe graphics cards. Please disable hardware rendering under File -> Settings if you encounter this.
+ Warning shown at the top of a page if Intel Xe graphics are detected
+
+
+ Dismiss
+
\ No newline at end of file
diff --git a/src/SyncTrayzor/Services/Config/Configuration.cs b/src/SyncTrayzor/Services/Config/Configuration.cs
index 814ec363..e5a8eb62 100644
--- a/src/SyncTrayzor/Services/Config/Configuration.cs
+++ b/src/SyncTrayzor/Services/Config/Configuration.cs
@@ -61,6 +61,7 @@ public string LatestNotifiedVersionRaw
public string SyncthingCustomPath { get; set; }
public string SyncthingCustomHomePath { get; set; }
public bool DisableHardwareRendering { get; set; }
+ public bool HideIntelXeWarningMessage { get; set; }
public bool EnableFailedTransferAlerts { get; set; }
public bool EnableConflictFileMonitoring { get; set; }
@@ -100,6 +101,7 @@ public Configuration()
this.SyncthingCustomPath = null;
this.SyncthingCustomHomePath = null;
this.DisableHardwareRendering = false;
+ this.HideIntelXeWarningMessage = false;
this.EnableFailedTransferAlerts = true;
this.EnableConflictFileMonitoring = true;
this.ConflictResolverDeletesToRecycleBin = true;
@@ -137,6 +139,7 @@ public Configuration(Configuration other)
this.SyncthingCustomPath = other.SyncthingCustomPath;
this.SyncthingCustomHomePath = other.SyncthingCustomHomePath;
this.DisableHardwareRendering = other.DisableHardwareRendering;
+ this.HideIntelXeWarningMessage = other.HideIntelXeWarningMessage;
this.EnableFailedTransferAlerts = other.EnableFailedTransferAlerts;
this.EnableConflictFileMonitoring = other.EnableConflictFileMonitoring;
this.ConflictResolverDeletesToRecycleBin = other.ConflictResolverDeletesToRecycleBin;
@@ -160,7 +163,7 @@ public override string ToString()
$"ObfuscateDeviceIDs={this.ObfuscateDeviceIDs} UseComputerCulture={this.UseComputerCulture} SyncthingConsoleHeight={this.SyncthingConsoleHeight} WindowPlacement={this.WindowPlacement} " +
$"SyncthingWebBrowserZoomLevel={this.SyncthingWebBrowserZoomLevel} LastSeenInstallCount={this.LastSeenInstallCount} SyncthingCustomPath={this.SyncthingCustomPath} " +
$"SyncthingCustomHomePath={this.SyncthingCustomHomePath} ShowSynchronizedBalloonEvenIfNothingDownloaded={this.ShowSynchronizedBalloonEvenIfNothingDownloaded} " +
- $"DisableHardwareRendering={this.DisableHardwareRendering} EnableFailedTransferAlerts={this.EnableFailedTransferAlerts} " +
+ $"DisableHardwareRendering={this.DisableHardwareRendering} HideIntelXeWarningMessage={this.HideIntelXeWarningMessage} EnableFailedTransferAlerts={this.EnableFailedTransferAlerts} " +
$"EnableConflictFileMonitoring={this.EnableConflictFileMonitoring} " +
$"ConflictResolverDeletesToRecycleBin={this.ConflictResolverDeletesToRecycleBin} PauseDevicesOnMeteredNetworks={this.PauseDevicesOnMeteredNetworks} " +
$"HaveDonated={this.HaveDonated} IconAnimationMode={this.IconAnimationMode} OpenFolderCommand={this.OpenFolderCommand} ShowFileInFolderCommand={this.ShowFileInFolderCommand}" +
diff --git a/src/SyncTrayzor/Services/GraphicsCardDetector.cs b/src/SyncTrayzor/Services/GraphicsCardDetector.cs
new file mode 100644
index 00000000..0790ce6c
--- /dev/null
+++ b/src/SyncTrayzor/Services/GraphicsCardDetector.cs
@@ -0,0 +1,42 @@
+using NLog;
+using System;
+using System.Management;
+
+namespace SyncTrayzor.Services
+{
+ public class GraphicsCardDetector
+ {
+ private static readonly Logger logger = LogManager.GetCurrentClassLogger();
+
+ private bool? _isIntelXe;
+ public bool IsIntelXe
+ {
+ get
+ {
+ if (this._isIntelXe == null)
+ this._isIntelXe = GetIsIntelXe();
+ return this._isIntelXe.Value;
+ }
+ }
+
+ private static bool GetIsIntelXe()
+ {
+ var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_VideoController");
+ foreach (ManagementObject obj in searcher.Get())
+ {
+ if (obj["CurrentBitsPerPixel"] != null && obj["CurrentHorizontalResolution"] != null)
+ {
+ string name = obj["Name"]?.ToString();
+ if (name.IndexOf("Intel", StringComparison.OrdinalIgnoreCase) >= 0 &&
+ name.IndexOf(" Xe ", StringComparison.OrdinalIgnoreCase) >= 0)
+ {
+ logger.Info($"Graphics card: {name}");
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/SyncTrayzor/SyncTrayzor.csproj b/src/SyncTrayzor/SyncTrayzor.csproj
index 9859bf15..dee2adca 100644
--- a/src/SyncTrayzor/SyncTrayzor.csproj
+++ b/src/SyncTrayzor/SyncTrayzor.csproj
@@ -101,6 +101,7 @@
+
@@ -140,6 +141,7 @@
+
PausedDevicesFromMeteringView.xaml
@@ -183,6 +185,7 @@
+
@@ -392,6 +395,10 @@
Designer
MSBuild:Compile
+
+ Designer
+ MSBuild:Compile
+
Designer
MSBuild:Compile