mirror of
https://github.com/chylex/TweetDuck.git
synced 2025-04-23 12:15:48 +02:00
Add option for browser throttling w/ default when covered by larger window
This commit is contained in:
parent
0355a5c646
commit
4e52102c5c
Configuration
Core
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using TweetDuck.Core;
|
||||
using TweetDuck.Data.Serialization;
|
||||
|
||||
namespace TweetDuck.Configuration{
|
||||
@ -16,6 +17,8 @@ sealed class SystemConfig{
|
||||
public bool ClearCacheAutomatically { get; set; } = true;
|
||||
public int ClearCacheThreshold { get; set; } = 250;
|
||||
|
||||
public FormBrowser.ThrottleBehavior ThrottleBehavior { get; set; } = FormBrowser.ThrottleBehavior.Covered;
|
||||
|
||||
// SPECIAL PROPERTIES
|
||||
|
||||
public bool HardwareAcceleration{
|
||||
|
7
Core/FormBrowser.Designer.cs
generated
7
Core/FormBrowser.Designer.cs
generated
@ -27,6 +27,7 @@ private void InitializeComponent() {
|
||||
this.trayIcon = new TweetDuck.Core.Other.TrayIcon(this.components);
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.timerResize = new System.Windows.Forms.Timer(this.components);
|
||||
this.timerThrottle = new System.Windows.Forms.Timer(this.components);
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// timerResize
|
||||
@ -34,6 +35,10 @@ private void InitializeComponent() {
|
||||
this.timerResize.Interval = 500;
|
||||
this.timerResize.Tick += new System.EventHandler(this.timerResize_Tick);
|
||||
//
|
||||
// timerThrottle
|
||||
//
|
||||
this.timerThrottle.Tick += new System.EventHandler(this.timerThrottle_Tick);
|
||||
//
|
||||
// FormBrowser
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
@ -46,6 +51,7 @@ private void InitializeComponent() {
|
||||
this.Name = "FormBrowser";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Activated += new System.EventHandler(this.FormBrowser_Activated);
|
||||
this.Deactivate += new System.EventHandler(this.FormBrowser_Deactivate);
|
||||
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FormBrowser_FormClosing);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FormBrowser_FormClosed);
|
||||
this.ResizeEnd += new System.EventHandler(this.FormBrowser_ResizeEnd);
|
||||
@ -60,6 +66,7 @@ private void InitializeComponent() {
|
||||
private TweetDuck.Core.Other.TrayIcon trayIcon;
|
||||
private System.Windows.Forms.ToolTip toolTip;
|
||||
private System.Windows.Forms.Timer timerResize;
|
||||
private System.Windows.Forms.Timer timerThrottle;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
|
||||
namespace TweetDuck.Core{
|
||||
sealed partial class FormBrowser : Form, AnalyticsFile.IProvider{
|
||||
public enum ThrottleBehavior{ // keep order
|
||||
Minimized, Covered, Unfocused
|
||||
}
|
||||
|
||||
private static UserConfig Config => Program.UserConfig;
|
||||
|
||||
public bool IsWaiting{
|
||||
@ -96,7 +100,7 @@ public FormBrowser(){
|
||||
Config.TrayBehaviorChanged += Config_TrayBehaviorChanged;
|
||||
|
||||
UpdateTray();
|
||||
|
||||
|
||||
if (Config.MuteNotifications){
|
||||
UpdateFormIcon();
|
||||
}
|
||||
@ -145,6 +149,34 @@ private void timerResize_Tick(object sender, EventArgs e){
|
||||
FormBrowser_ResizeEnd(this, e); // also stops timer
|
||||
}
|
||||
|
||||
private void timerThrottle_Tick(object sender, EventArgs e){
|
||||
if (!browser.Ready){
|
||||
timerThrottle.Interval = 5000;
|
||||
return;
|
||||
}
|
||||
|
||||
bool shouldThrottle;
|
||||
|
||||
switch(Program.SystemConfig.ThrottleBehavior){
|
||||
case ThrottleBehavior.Covered:
|
||||
shouldThrottle = WindowState != FormWindowState.Minimized && NativeMethods.IsFormCoveredByLargerWindow(this);
|
||||
break;
|
||||
|
||||
case ThrottleBehavior.Unfocused:
|
||||
shouldThrottle = !FormManager.HasAnyDialogs;
|
||||
break;
|
||||
|
||||
default:
|
||||
timerThrottle.Stop();
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldThrottle){
|
||||
browser.SetThrottle(true);
|
||||
timerThrottle.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
private void FormBrowser_Activated(object sender, EventArgs e){
|
||||
if (!isLoaded)return;
|
||||
|
||||
@ -153,6 +185,15 @@ private void FormBrowser_Activated(object sender, EventArgs e){
|
||||
if (!browser.Enabled){ // when taking a screenshot, the window is unfocused and
|
||||
browser.Enabled = true; // the browser is disabled; if the user clicks back into
|
||||
} // the window, enable the browser again
|
||||
|
||||
timerThrottle.Stop();
|
||||
browser.SetThrottle(false);
|
||||
}
|
||||
|
||||
private void FormBrowser_Deactivate(object sender, EventArgs e){
|
||||
timerThrottle.Stop();
|
||||
timerThrottle.Interval = Program.SystemConfig.ThrottleBehavior == ThrottleBehavior.Covered ? 30000 : 1000;
|
||||
timerThrottle.Start();
|
||||
}
|
||||
|
||||
private void FormBrowser_LocationChanged(object sender, EventArgs e){
|
||||
|
40
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
40
Core/Other/Settings/TabSettingsAdvanced.Designer.cs
generated
@ -43,6 +43,8 @@ private void InitializeComponent() {
|
||||
this.panelConfiguration = new System.Windows.Forms.Panel();
|
||||
this.labelConfiguration = new System.Windows.Forms.Label();
|
||||
this.flowPanel = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.labelThrottle = new System.Windows.Forms.Label();
|
||||
this.comboBoxThrottle = new System.Windows.Forms.ComboBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this.numClearCacheThreshold)).BeginInit();
|
||||
this.panelAppButtons.SuspendLayout();
|
||||
this.panelClearCacheAuto.SuspendLayout();
|
||||
@ -209,7 +211,7 @@ private void InitializeComponent() {
|
||||
this.labelPerformance.Location = new System.Drawing.Point(0, 102);
|
||||
this.labelPerformance.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelPerformance.Name = "labelPerformance";
|
||||
this.labelPerformance.Size = new System.Drawing.Size(93, 20);
|
||||
this.labelPerformance.Size = new System.Drawing.Size(92, 20);
|
||||
this.labelPerformance.TabIndex = 2;
|
||||
this.labelPerformance.Text = "Performance";
|
||||
//
|
||||
@ -219,7 +221,7 @@ private void InitializeComponent() {
|
||||
this.panelClearCacheAuto.Controls.Add(this.checkClearCacheAuto);
|
||||
this.panelClearCacheAuto.Controls.Add(this.numClearCacheThreshold);
|
||||
this.panelClearCacheAuto.Location = new System.Drawing.Point(0, 207);
|
||||
this.panelClearCacheAuto.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelClearCacheAuto.Margin = new System.Windows.Forms.Padding(0, 0, 0, 2);
|
||||
this.panelClearCacheAuto.Name = "panelClearCacheAuto";
|
||||
this.panelClearCacheAuto.Size = new System.Drawing.Size(322, 28);
|
||||
this.panelClearCacheAuto.TabIndex = 6;
|
||||
@ -240,7 +242,7 @@ private void InitializeComponent() {
|
||||
this.panelConfiguration.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.panelConfiguration.Controls.Add(this.btnEditCSS);
|
||||
this.panelConfiguration.Controls.Add(this.btnEditCefArgs);
|
||||
this.panelConfiguration.Location = new System.Drawing.Point(0, 275);
|
||||
this.panelConfiguration.Location = new System.Drawing.Point(0, 333);
|
||||
this.panelConfiguration.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.panelConfiguration.Name = "panelConfiguration";
|
||||
this.panelConfiguration.Size = new System.Drawing.Size(322, 31);
|
||||
@ -250,7 +252,7 @@ private void InitializeComponent() {
|
||||
//
|
||||
this.labelConfiguration.AutoSize = true;
|
||||
this.labelConfiguration.Font = new System.Drawing.Font("Segoe UI", 11.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelConfiguration.Location = new System.Drawing.Point(0, 255);
|
||||
this.labelConfiguration.Location = new System.Drawing.Point(0, 313);
|
||||
this.labelConfiguration.Margin = new System.Windows.Forms.Padding(0, 20, 0, 0);
|
||||
this.labelConfiguration.Name = "labelConfiguration";
|
||||
this.labelConfiguration.Size = new System.Drawing.Size(100, 20);
|
||||
@ -269,22 +271,46 @@ private void InitializeComponent() {
|
||||
this.flowPanel.Controls.Add(this.labelCache);
|
||||
this.flowPanel.Controls.Add(this.btnClearCache);
|
||||
this.flowPanel.Controls.Add(this.panelClearCacheAuto);
|
||||
this.flowPanel.Controls.Add(this.labelThrottle);
|
||||
this.flowPanel.Controls.Add(this.comboBoxThrottle);
|
||||
this.flowPanel.Controls.Add(this.labelConfiguration);
|
||||
this.flowPanel.Controls.Add(this.panelConfiguration);
|
||||
this.flowPanel.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
|
||||
this.flowPanel.Location = new System.Drawing.Point(9, 9);
|
||||
this.flowPanel.Name = "flowPanel";
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 307);
|
||||
this.flowPanel.Size = new System.Drawing.Size(322, 364);
|
||||
this.flowPanel.TabIndex = 0;
|
||||
this.flowPanel.WrapContents = false;
|
||||
//
|
||||
// labelThrottle
|
||||
//
|
||||
this.labelThrottle.AutoSize = true;
|
||||
this.labelThrottle.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.labelThrottle.Location = new System.Drawing.Point(3, 249);
|
||||
this.labelThrottle.Margin = new System.Windows.Forms.Padding(3, 12, 3, 0);
|
||||
this.labelThrottle.Name = "labelThrottle";
|
||||
this.labelThrottle.Size = new System.Drawing.Size(92, 15);
|
||||
this.labelThrottle.TabIndex = 9;
|
||||
this.labelThrottle.Text = "Throttle When...";
|
||||
//
|
||||
// comboBoxThrottle
|
||||
//
|
||||
this.comboBoxThrottle.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.comboBoxThrottle.Font = new System.Drawing.Font("Segoe UI", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(238)));
|
||||
this.comboBoxThrottle.FormattingEnabled = true;
|
||||
this.comboBoxThrottle.Location = new System.Drawing.Point(5, 267);
|
||||
this.comboBoxThrottle.Margin = new System.Windows.Forms.Padding(5, 3, 3, 3);
|
||||
this.comboBoxThrottle.Name = "comboBoxThrottle";
|
||||
this.comboBoxThrottle.Size = new System.Drawing.Size(173, 23);
|
||||
this.comboBoxThrottle.TabIndex = 10;
|
||||
//
|
||||
// TabSettingsAdvanced
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.flowPanel);
|
||||
this.Name = "TabSettingsAdvanced";
|
||||
this.Size = new System.Drawing.Size(340, 325);
|
||||
this.Size = new System.Drawing.Size(340, 382);
|
||||
((System.ComponentModel.ISupportInitialize)(this.numClearCacheThreshold)).EndInit();
|
||||
this.panelAppButtons.ResumeLayout(false);
|
||||
this.panelClearCacheAuto.ResumeLayout(false);
|
||||
@ -317,5 +343,7 @@ private void InitializeComponent() {
|
||||
private Controls.NumericUpDownEx numClearCacheThreshold;
|
||||
private System.Windows.Forms.CheckBox checkClearCacheAuto;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowPanel;
|
||||
private System.Windows.Forms.Label labelThrottle;
|
||||
private System.Windows.Forms.ComboBox comboBoxThrottle;
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,8 @@ public TabSettingsAdvanced(Action<string> reinjectBrowserCSS){
|
||||
toolTip.SetToolTip(btnClearCache, "Clearing cache will free up space taken by downloaded images and other resources.");
|
||||
toolTip.SetToolTip(checkClearCacheAuto, "Automatically clears cache when its size exceeds the set threshold. Note that cache can only be cleared when closing TweetDuck.");
|
||||
|
||||
toolTip.SetToolTip(comboBoxThrottle, "Decides when to stop rendering and throttle the browser to improve performance and battery life.");
|
||||
|
||||
toolTip.SetToolTip(btnEditCefArgs, "Set custom command line arguments for Chromium Embedded Framework.");
|
||||
toolTip.SetToolTip(btnEditCSS, "Set custom CSS for browser and notification windows.");
|
||||
|
||||
@ -48,6 +50,11 @@ public TabSettingsAdvanced(Action<string> reinjectBrowserCSS){
|
||||
string text = task.Status == TaskStatus.RanToCompletion ? (int)Math.Ceiling(task.Result/(1024.0*1024.0))+" MB" : "unknown";
|
||||
this.InvokeSafe(() => btnClearCache.Text = $"Clear Cache ({text})");
|
||||
});
|
||||
|
||||
comboBoxThrottle.Items.Add("Minimized (Naive)");
|
||||
comboBoxThrottle.Items.Add("Covered (Smart)");
|
||||
comboBoxThrottle.Items.Add("Unfocused (Aggressive)");
|
||||
comboBoxThrottle.SelectedIndex = Math.Min(Math.Max((int)SysConfig.ThrottleBehavior, 0), comboBoxThrottle.Items.Count-1);
|
||||
}
|
||||
|
||||
public override void OnReady(){
|
||||
@ -60,6 +67,8 @@ public override void OnReady(){
|
||||
|
||||
btnClearCache.Click += btnClearCache_Click;
|
||||
checkClearCacheAuto.CheckedChanged += checkClearCacheAuto_CheckedChanged;
|
||||
|
||||
comboBoxThrottle.SelectedIndexChanged += comboBoxThrottle_SelectedIndexChanged;
|
||||
|
||||
btnEditCefArgs.Click += btnEditCefArgs_Click;
|
||||
btnEditCSS.Click += btnEditCSS_Click;
|
||||
@ -86,6 +95,10 @@ private void checkHardwareAcceleration_CheckedChanged(object sender, EventArgs e
|
||||
PromptRestart(); // calls OnClosing
|
||||
}
|
||||
|
||||
private void comboBoxThrottle_SelectedIndexChanged(object sender, EventArgs e){
|
||||
SysConfig.ThrottleBehavior = (FormBrowser.ThrottleBehavior)comboBoxThrottle.SelectedIndex;
|
||||
}
|
||||
|
||||
private void btnEditCefArgs_Click(object sender, EventArgs e){
|
||||
DialogSettingsCefArgs form = new DialogSettingsCefArgs();
|
||||
|
||||
|
@ -87,6 +87,16 @@ public void Focus(){
|
||||
browser.Focus();
|
||||
}
|
||||
|
||||
public void SetThrottle(bool throttle){
|
||||
if (throttle && browser.Dock == DockStyle.Fill){
|
||||
browser.Dock = DockStyle.None;
|
||||
browser.Size = Size.Empty;
|
||||
}
|
||||
else if (!throttle && browser.Dock == DockStyle.None){
|
||||
browser.Dock = DockStyle.Fill;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose(){
|
||||
Program.UserConfig.MuteToggled -= UserConfig_MuteToggled;
|
||||
Program.UserConfig.ZoomLevelChanged -= UserConfig_ZoomLevelChanged;
|
||||
|
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
@ -14,6 +15,7 @@ static class NativeMethods{
|
||||
public const int HWND_TOPMOST = -1;
|
||||
public const uint SWP_NOACTIVATE = 0x0010;
|
||||
public const int WS_DISABLED = 0x08000000;
|
||||
public const int GW_HWNDPREV = 3;
|
||||
public const int GWL_STYLE = -16;
|
||||
|
||||
public const int SB_HORZ = 0;
|
||||
@ -23,6 +25,7 @@ static class NativeMethods{
|
||||
public const int WM_XBUTTONDOWN = 0x020B;
|
||||
public const int WM_XBUTTONUP = 0x020C;
|
||||
public const int WM_PARENTNOTIFY = 0x0210;
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct LASTINPUTINFO{
|
||||
@ -38,6 +41,14 @@ private struct POINT{
|
||||
public int Y;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct RECT{
|
||||
public int left;
|
||||
public int top;
|
||||
public int right;
|
||||
public int bottom;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct MSLLHOOKSTRUCT{
|
||||
public POINT pt;
|
||||
@ -93,6 +104,17 @@ private struct MSLLHOOKSTRUCT{
|
||||
[DllImport("user32.dll")]
|
||||
private static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
private static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool GetWindowRect(IntPtr hWnd, [Out] out RECT lpRect);
|
||||
|
||||
[DllImport("user32.dll")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
private static extern bool IsWindowVisible(IntPtr hWnd);
|
||||
|
||||
public static void SetFormPos(Form form, int hWndOrder, uint flags){
|
||||
SetWindowPos(form.Handle.ToInt32(), hWndOrder, form.Left, form.Top, form.Width, form.Height, flags);
|
||||
}
|
||||
@ -106,6 +128,30 @@ public static void SetFormDisabled(Form form, bool disabled){
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsFormCoveredByLargerWindow(Form form){
|
||||
IntPtr handle = form.Handle;
|
||||
|
||||
if (!IsWindowVisible(handle)){
|
||||
return false;
|
||||
}
|
||||
|
||||
HashSet<IntPtr> visited = new HashSet<IntPtr>{ handle };
|
||||
GetWindowRect(handle, out RECT thisRect);
|
||||
|
||||
while((handle = GetWindow(handle, GW_HWNDPREV)) != IntPtr.Zero && visited.Add(handle)){
|
||||
if (IsWindowVisible(handle) &&
|
||||
GetWindowRect(handle, out RECT otherRect) &&
|
||||
otherRect.left <= thisRect.left &&
|
||||
otherRect.top <= thisRect.top &&
|
||||
otherRect.right >= thisRect.right &&
|
||||
otherRect.bottom >= thisRect.bottom){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void BroadcastMessage(uint msg, uint wParam, int lParam){
|
||||
PostMessage(HWND_BROADCAST, msg, new UIntPtr(wParam), new IntPtr(lParam));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user