1
0
mirror of https://github.com/chylex/TweetDuck.git synced 2025-09-14 10:32:10 +02:00

Compare commits

..

18 Commits
1.25 ... master

Author SHA1 Message Date
293683fbdc Release 1.26 2023-07-17 12:49:49 +02:00
57111212ea Fix warning message about TweetDeck Preview appearing on login screen 2023-07-17 12:49:49 +02:00
a58a1b347a Show a deprecation notice on launch
References #360
2023-07-17 01:04:49 +02:00
37303ddf02 Fix doubled border in Settings dialog 2023-07-17 00:58:50 +02:00
f8417706e1 Update CefSharp to 109 2023-07-16 21:40:55 +02:00
c5a42e74d9 Release 1.25.4 2023-05-09 23:03:38 +02:00
23ebd58da0 Fix video player showing controls when cursor is above a different window
Closes #357
2023-03-18 13:48:29 +01:00
9a6394d079 Release 1.25.3 2023-03-09 20:28:03 +01:00
88a55c8795 Work around NullReferenceException when browser frame load events have a null URL
Closes #354
2023-03-09 20:28:03 +01:00
d406866a02 Hide button that enables the TweetDeck Preview 2023-03-09 20:18:40 +01:00
c2094bd2c0 Show error message if TweetDuck features fail to load, for example due to TweetDeck Preview
Closes #356
2023-03-09 20:17:59 +01:00
065b5a751b Release 1.25.2 2022-11-21 20:24:54 +01:00
0dc454e61f Re-add UCRT DLLs 2022-11-21 20:22:04 +01:00
416a43f0b1 Fix update installer not running as administrator due to breaking change in .NET 2022-11-21 20:07:23 +01:00
7a338076db Release 1.25.1 2022-11-21 08:09:55 +01:00
54bf1c2012 Make update installer delete unused files and folders 2022-11-21 08:09:55 +01:00
32681259f6 Re-add VC++ DLLs 2022-11-21 07:59:20 +01:00
1c1aa5ea44 Fix crash when right-clicking tray icon
Closes #350
2022-11-20 20:52:10 +01:00
73 changed files with 133 additions and 35 deletions

View File

@@ -6,6 +6,6 @@ using TweetDuck;
namespace TweetDuck { namespace TweetDuck {
internal static class Version { internal static class Version {
public const string Tag = "1.25"; public const string Tag = "1.26";
} }
} }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bld/Redist/concrt140.dll Normal file

Binary file not shown.

BIN
bld/Redist/msvcp140.dll Normal file

Binary file not shown.

BIN
bld/Redist/msvcp140_1.dll Normal file

Binary file not shown.

BIN
bld/Redist/msvcp140_2.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
bld/Redist/ucrtbase.dll Normal file

Binary file not shown.

BIN
bld/Redist/vccorlib140.dll Normal file

Binary file not shown.

BIN
bld/Redist/vcruntime140.dll Normal file

Binary file not shown.

View File

@@ -71,16 +71,19 @@ Type: filesandordirs; Name: "{localappdata}\{#MyAppName}\GPUCache"
Type: files; Name: "{app}\CEFSHARP-LICENSE.txt" Type: files; Name: "{app}\CEFSHARP-LICENSE.txt"
Type: files; Name: "{app}\LICENSE.txt" Type: files; Name: "{app}\LICENSE.txt"
Type: files; Name: "{app}\README.txt" Type: files; Name: "{app}\README.txt"
Type: files; Name: "{app}\natives_blob.bin"
Type: files; Name: "{app}\cef.pak" Type: files; Name: "{app}\cef.pak"
Type: files; Name: "{app}\cef_100_percent.pak" Type: files; Name: "{app}\cef_100_percent.pak"
Type: files; Name: "{app}\cef_200_percent.pak" Type: files; Name: "{app}\cef_200_percent.pak"
Type: files; Name: "{app}\cef_extensions.pak" Type: files; Name: "{app}\cef_extensions.pak"
Type: files; Name: "{app}\devtools_resources.pak" Type: files; Name: "{app}\devtools_resources.pak"
Type: files; Name: "{app}\natives_blob.bin"
Type: files; Name: "{app}\dbgshim.dll"
Type: files; Name: "{app}\mscordaccore_x86_x86_6.*.dll"
Type: filesandordirs; Name: "{app}\guide" Type: filesandordirs; Name: "{app}\guide"
Type: filesandordirs; Name: "{app}\plugins\official" Type: filesandordirs; Name: "{app}\plugins\official"
Type: filesandordirs; Name: "{app}\resources" Type: filesandordirs; Name: "{app}\resources"
Type: filesandordirs; Name: "{app}\scripts" Type: filesandordirs; Name: "{app}\scripts"
Type: filesandordirs; Name: "{app}\swiftshader"
[Code] [Code]
function TDIsUninstallable: Boolean; forward; function TDIsUninstallable: Boolean; forward;

View File

@@ -67,6 +67,7 @@ import setup_tweet_context_menu from "./tweetdeck/setup_tweet_context_menu.js";
import setup_tweetduck_account_bamboozle from "./tweetdeck/setup_tweetduck_account_bamboozle.js"; import setup_tweetduck_account_bamboozle from "./tweetdeck/setup_tweetduck_account_bamboozle.js";
import setup_video_player from "./tweetdeck/setup_video_player.js"; import setup_video_player from "./tweetdeck/setup_video_player.js";
import skip_pre_login_page from "./tweetdeck/skip_pre_login_page.js"; import skip_pre_login_page from "./tweetdeck/skip_pre_login_page.js";
import tweetdeck_preview_warning from "./tweetdeck/tweetdeck_preview_warning.js";
import update from "./update/update.js"; import update from "./update/update.js";
const globalFunctions = [ const globalFunctions = [

View File

@@ -133,6 +133,14 @@ button {
bottom: 192px !important; bottom: 192px !important;
} }
/***********************/
/* Hide Preview button */
/***********************/
.js-gryphon-beta-btn {
display: none !important;
}
/*************************************/ /*************************************/
/* Tweak collapsed left panel layout */ /* Tweak collapsed left panel layout */
/*************************************/ /*************************************/

View File

@@ -0,0 +1,7 @@
import { $TD } from "../api/bridge.js";
export default function() {
if (location.pathname === "/" && !("TD" in window)) {
$TD.alert("warning", "Some TweetDuck features failed to load. This might happen if your Twitter account is enrolled into the TweetDeck Preview, which TweetDuck does not support. Try opting out of the TweetDeck Preview to restore TweetDuck's functionality.");
}
}

View File

@@ -32,7 +32,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CefSharp.Common.NETCore" Version="107.1.90" /> <PackageReference Include="CefSharp.Common.NETCore" Version="109.1.110" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -237,7 +237,7 @@ namespace TweetDuck.Video {
int maxWidth = Math.Min(DpiScaled(media.imageSourceWidth), ownerWidth * 3 / 4); int maxWidth = Math.Min(DpiScaled(media.imageSourceWidth), ownerWidth * 3 / 4);
int maxHeight = Math.Min(DpiScaled(media.imageSourceHeight), ownerHeight * 3 / 4); int maxHeight = Math.Min(DpiScaled(media.imageSourceHeight), ownerHeight * 3 / 4);
bool isCursorInside = ClientRectangle.Contains(PointToClient(Cursor.Position)); bool isCursorInside = ClientRectangle.Contains(PointToClient(Cursor.Position)) && Handle == NativeMethods.GetFormHandleAt(Cursor.Position);
Size newSize = new Size(Math.Max(minWidth + 2, maxWidth), Math.Max(minHeight + 2, maxHeight)); Size newSize = new Size(Math.Max(minWidth + 2, maxWidth), Math.Max(minHeight + 2, maxHeight));
Point newLocation = new Point(ownerLeft + (ownerWidth - newSize.Width) / 2, ownerTop + (ownerHeight - newSize.Height + SystemInformation.CaptionHeight) / 2); Point newLocation = new Point(ownerLeft + (ownerWidth - newSize.Width) / 2, ownerTop + (ownerHeight - newSize.Height + SystemInformation.CaptionHeight) / 2);

View File

@@ -1,11 +1,13 @@
#nullable enable #nullable enable
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace TweetDuck.Video { namespace TweetDuck.Video {
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
static class NativeMethods { static class NativeMethods {
private const int GA_ROOT = 2;
private const int GWL_HWNDPARENT = -8; private const int GWL_HWNDPARENT = -8;
[DllImport("user32.dll")] [DllImport("user32.dll")]
@@ -25,6 +27,12 @@ namespace TweetDuck.Video {
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow(); public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr WindowFromPoint(Point point);
[DllImport("user32.dll")]
private static extern IntPtr GetAncestor(IntPtr hwnd, int flags);
[DllImport("user32.dll")] [DllImport("user32.dll")]
public static extern bool SetProcessDPIAware(); public static extern bool SetProcessDPIAware();
@@ -49,5 +57,10 @@ namespace TweetDuck.Video {
* ...so technically, this is following the documentation to the word. * ...so technically, this is following the documentation to the word.
*/ */
} }
public static IntPtr GetFormHandleAt(Point point) {
IntPtr window = WindowFromPoint(point);
return window == IntPtr.Zero ? IntPtr.Zero : GetAncestor(window, GA_ROOT);
}
} }
} }

View File

@@ -9,6 +9,7 @@ namespace TweetDuck.Configuration {
public const string ArgIgnoreGDPR = "-nogdpr"; public const string ArgIgnoreGDPR = "-nogdpr";
public const string ArgHttpVideo = "-httpvideo"; public const string ArgHttpVideo = "-httpvideo";
public const string ArgFreeze = "-freeze"; public const string ArgFreeze = "-freeze";
public const string ArgHideDeprecation = "-hidedeprecation";
// internal args // internal args
public const string ArgRestart = "-restart"; public const string ArgRestart = "-restart";

View File

@@ -0,0 +1,36 @@
using System;
using System.Windows.Forms;
using TweetLib.Core;
namespace TweetDuck.Dialogs;
static class DeprecationNoticeDialog {
public static bool Show() {
const string contents = """
TweetDuck is no longer being maintained:
- Twitter has been constantly breaking TweetDeck and therefore also breaking TweetDuck.
- Twitter will be replacing TweetDeck with a new version that is incompatible with most of the app's features.
- Twitter is planning to put TweetDeck behind a subscription paywall.
There will be no more updates.
Continue at your own risk.
""";
using FormMessage message = new FormMessage("TweetDuck Deprecation Notice", contents, MessageBoxIcon.Warning);
message.AddButton("Exit", DialogResult.Cancel, ControlType.Cancel);
message.AddButton("Continue", DialogResult.OK, ControlType.Accept | ControlType.Focused);
Button btnLearnMore = message.CreateButton("Learn More", x: 9, width: 106);
btnLearnMore.Anchor |= AnchorStyles.Left;
btnLearnMore.Margin = new Padding(0, 0, 48, 0);
btnLearnMore.Click += OnBtnLearnMoreClick;
message.AddActionControl(btnLearnMore);
return message.ShowDialog() == DialogResult.OK;
}
private static void OnBtnLearnMoreClick(object? sender, EventArgs args) {
App.SystemHandler.OpenBrowser(Program.Website + "/deprecation");
}
}

View File

@@ -124,15 +124,7 @@ namespace TweetDuck.Dialogs {
} }
public Button AddButton(string title, DialogResult result = DialogResult.OK, ControlType type = ControlType.None) { public Button AddButton(string title, DialogResult result = DialogResult.OK, ControlType type = ControlType.None) {
Button button = new Button { Button button = CreateButton(title);
Anchor = AnchorStyles.Bottom,
Font = SystemFonts.MessageBoxFont,
Location = new Point(0, 12),
Size = new Size(BrowserUtils.Scale(88, dpiScale), BrowserUtils.Scale(26, dpiScale)),
TabIndex = 256 - buttonCount,
Text = title,
UseVisualStyleBackColor = true
};
button.Click += (_, _) => { button.Click += (_, _) => {
ClickedButton = button; ClickedButton = button;
@@ -162,6 +154,18 @@ namespace TweetDuck.Dialogs {
return button; return button;
} }
public Button CreateButton(string title, int x = 0, int width = 88) {
return new Button {
Anchor = AnchorStyles.Bottom,
Font = SystemFonts.MessageBoxFont,
Location = new Point(x, 12),
Size = new Size(BrowserUtils.Scale(width, dpiScale), BrowserUtils.Scale(26, dpiScale)),
TabIndex = 256 - buttonCount,
Text = title,
UseVisualStyleBackColor = true
};
}
public void AddActionControl(Control control) { public void AddActionControl(Control control) {
panelActions.Controls.Add(control); panelActions.Controls.Add(control);

View File

@@ -50,10 +50,10 @@
| System.Windows.Forms.AnchorStyles.Right))); | System.Windows.Forms.AnchorStyles.Right)));
this.panelContents.AutoScroll = true; this.panelContents.AutoScroll = true;
this.panelContents.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; this.panelContents.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panelContents.Location = new System.Drawing.Point(135, 12); this.panelContents.Location = new System.Drawing.Point(134, 12);
this.panelContents.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3); this.panelContents.Margin = new System.Windows.Forms.Padding(0, 3, 3, 3);
this.panelContents.Name = "panelContents"; this.panelContents.Name = "panelContents";
this.panelContents.Size = new System.Drawing.Size(662, 482); this.panelContents.Size = new System.Drawing.Size(663, 482);
this.panelContents.TabIndex = 1; this.panelContents.TabIndex = 1;
// //
// panelButtons // panelButtons

View File

@@ -45,6 +45,7 @@ namespace TweetDuck {
internal static void SetupWinForms() { internal static void SetupWinForms() {
Win.Application.EnableVisualStyles(); Win.Application.EnableVisualStyles();
Win.Application.SetCompatibleTextRenderingDefault(false); Win.Application.SetCompatibleTextRenderingDefault(false);
Win.LegacyWinForms.EnsureValid();
} }
[STAThread] [STAThread]
@@ -107,6 +108,10 @@ namespace TweetDuck {
if (Config.System.Migrate()) { if (Config.System.Migrate()) {
Config.System.Save(); Config.System.Save();
} }
if (!Arguments.HasFlag(Arguments.ArgHideDeprecation) && !DeprecationNoticeDialog.Show()) {
Environment.Exit(0);
}
} }
public void Launch(ResourceCache resourceCache, PluginManager pluginManager) { public void Launch(ResourceCache resourceCache, PluginManager pluginManager) {

View File

@@ -1,6 +1,5 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms; using System.Windows.Forms;
using TweetDuck.Dialogs; using TweetDuck.Dialogs;
using TweetDuck.Management; using TweetDuck.Management;
@@ -36,16 +35,10 @@ namespace TweetDuck {
btnIgnore.Enabled = canIgnore; btnIgnore.Enabled = canIgnore;
form.ActiveControl = canIgnore ? btnIgnore : btnExit; form.ActiveControl = canIgnore ? btnIgnore : btnExit;
Button btnOpenLog = new Button { Button btnOpenLog = form.CreateButton("Show Error Log", x: 9, width: 106);
Anchor = AnchorStyles.Bottom | AnchorStyles.Left, btnOpenLog.Anchor |= AnchorStyles.Left;
Enabled = loggedSuccessfully, btnOpenLog.Enabled = loggedSuccessfully;
Font = SystemFonts.MessageBoxFont, btnOpenLog.Margin = new Padding(0, 0, 48, 0);
Location = new Point(9, 12),
Margin = new Padding(0, 0, 48, 0),
Size = new Size(106, 26),
Text = "Show Error Log",
UseVisualStyleBackColor = true
};
btnOpenLog.Click += static (_, _) => { btnOpenLog.Click += static (_, _) => {
if (!OpenLogFile()) { if (!OpenLogFile()) {

View File

@@ -36,7 +36,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CefSharp.WinForms.NETCore" Version="107.1.90" /> <PackageReference Include="CefSharp.WinForms.NETCore" Version="109.1.110" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -78,6 +78,7 @@
<ResourcesPlugins Remove="$(SolutionDir)resources\Plugins\.debug\**\*.*" /> <ResourcesPlugins Remove="$(SolutionDir)resources\Plugins\.debug\**\*.*" />
<ResourcesPlugins Remove="$(SolutionDir)resources\Plugins\emoji-keyboard\emoji-instructions.txt" /> <ResourcesPlugins Remove="$(SolutionDir)resources\Plugins\emoji-keyboard\emoji-instructions.txt" />
<ResourcesPluginsDebug Include="$(SolutionDir)resources\Plugins\.debug\**\*.*" Visible="false" /> <ResourcesPluginsDebug Include="$(SolutionDir)resources\Plugins\.debug\**\*.*" Visible="false" />
<Redist Include="$(SolutionDir)bld\Redist\*.*" Visible="false" />
</ItemGroup> </ItemGroup>
<PropertyGroup> <PropertyGroup>
@@ -124,6 +125,7 @@
<Copy SourceFiles="@(ResourcesContent)" DestinationFiles="@(ResourcesContent->'$(TargetDir)\resources\%(RecursiveDir)%(Filename)%(Extension)')" /> <Copy SourceFiles="@(ResourcesContent)" DestinationFiles="@(ResourcesContent->'$(TargetDir)\resources\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(ResourcesGuide)" DestinationFiles="@(ResourcesGuide->'$(TargetDir)\guide\%(RecursiveDir)%(Filename)%(Extension)')" /> <Copy SourceFiles="@(ResourcesGuide)" DestinationFiles="@(ResourcesGuide->'$(TargetDir)\guide\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(ResourcesPlugins)" DestinationFiles="@(ResourcesPlugins->'$(TargetDir)\plugins\official\%(RecursiveDir)%(Filename)%(Extension)')" /> <Copy SourceFiles="@(ResourcesPlugins)" DestinationFiles="@(ResourcesPlugins->'$(TargetDir)\plugins\official\%(RecursiveDir)%(Filename)%(Extension)')" />
<Copy SourceFiles="@(Redist)" DestinationFolder="$(TargetDir)" />
<Exec Command="powershell -NoProfile -ExecutionPolicy Unrestricted -File &quot;$(ProjectDir)Resources\PostBuild.ps1&quot; &quot;$(TargetDir)\&quot;" IgnoreExitCode="false" /> <Exec Command="powershell -NoProfile -ExecutionPolicy Unrestricted -File &quot;$(ProjectDir)Resources\PostBuild.ps1&quot; &quot;$(TargetDir)\&quot;" IgnoreExitCode="false" />
</Target> </Target>

View File

@@ -23,6 +23,7 @@ namespace TweetDuck.Updates {
FileName = Path, FileName = Path,
Arguments = arguments, Arguments = arguments,
Verb = runElevated ? "runas" : string.Empty, Verb = runElevated ? "runas" : string.Empty,
UseShellExecute = true,
ErrorDialog = true ErrorDialog = true
})) { })) {
return true; return true;

View File

@@ -59,11 +59,15 @@ namespace TweetImpl.CefSharp.Component {
} }
private void OnFrameLoadStart(object? sender, FrameLoadStartEventArgs e) { private void OnFrameLoadStart(object? sender, FrameLoadStartEventArgs e) {
if (!string.IsNullOrEmpty(e.Url)) {
base.OnFrameLoadStart(e.Url, e.Frame); base.OnFrameLoadStart(e.Url, e.Frame);
} }
}
private void OnFrameLoadEnd(object? sender, FrameLoadEndEventArgs e) { private void OnFrameLoadEnd(object? sender, FrameLoadEndEventArgs e) {
if (!string.IsNullOrEmpty(e.Url)) {
base.OnFrameLoadEnd(e.Url, e.Frame); base.OnFrameLoadEnd(e.Url, e.Frame);
} }
} }
} }
}

View File

@@ -28,7 +28,7 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="CefSharp.WinForms.NETCore" Version="107.1.90" /> <PackageReference Include="CefSharp.WinForms.NETCore" Version="109.1.110" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@@ -4,9 +4,15 @@ using System.Reflection;
namespace System.Windows.Forms { namespace System.Windows.Forms {
internal sealed class Command2 { internal sealed class Command2 {
private static readonly Type Type = typeof(Form).Assembly.GetType("System.Windows.Forms.Command"); private static readonly Type Type = typeof(Form).Assembly.GetType("System.Windows.Forms.Command");
private static readonly ConstructorInfo Constructor = Type.GetConstructor(new Type[] { typeof(ICommandExecutor) }) ?? throw new NullReferenceException(); private static readonly ConstructorInfo Constructor = Type.GetConstructor(new Type[] { typeof(ICommandExecutor) });
private static readonly MethodInfo DisposeMethod = Type.GetMethod("Dispose", BindingFlags.Instance | BindingFlags.Public) ?? throw new NullReferenceException(); private static readonly MethodInfo DisposeMethod = Type.GetMethod("Dispose", BindingFlags.Instance | BindingFlags.Public);
private static readonly PropertyInfo IDProperty = Type.GetProperty("ID") ?? throw new NullReferenceException(); private static readonly PropertyInfo IDProperty = Type.GetProperty("ID");
internal static void EnsureValid() {
if (Constructor == null || DisposeMethod == null || IDProperty == null) {
throw new InvalidOperationException();
}
}
public int ID { get; } public int ID { get; }

View File

@@ -7,7 +7,13 @@ using System.Runtime.InteropServices;
namespace System.Windows.Forms { namespace System.Windows.Forms {
public sealed class ContextMenu : Menu { public sealed class ContextMenu : Menu {
private static readonly FieldInfo NotifyIconWindowField = typeof(NotifyIcon).GetField("window", BindingFlags.Instance | BindingFlags.NonPublic) ?? throw new InvalidOperationException(); private static readonly FieldInfo NotifyIconWindowField = typeof(NotifyIcon).GetField("_window", BindingFlags.Instance | BindingFlags.NonPublic);
internal static void EnsureValid() {
if (NotifyIconWindowField == null) {
throw new InvalidOperationException();
}
}
public event EventHandler Popup; public event EventHandler Popup;

View File

@@ -0,0 +1,8 @@
namespace System.Windows.Forms;
public static class LegacyWinForms {
public static void EnsureValid() {
Command2.EnsureValid();
ContextMenu.EnsureValid();
}
}