diff --git a/MainApp/AppWindow/AppMainWindow.xaml.cs b/MainApp/AppWindow/AppMainWindow.xaml.cs index 64860a3..6d412b5 100644 --- a/MainApp/AppWindow/AppMainWindow.xaml.cs +++ b/MainApp/AppWindow/AppMainWindow.xaml.cs @@ -1,5 +1,6 @@ using System; using System.ComponentModel; +using System.Diagnostics; using System.Windows; using System.Windows.Interop; using Microsoft.Extensions.DependencyInjection; @@ -27,11 +28,6 @@ namespace MSFSPopoutPanelManager.MainApp.AppWindow WindowActionManager.OnPopOutManagerAlwaysOnTopChanged += (_, e) => { Topmost = e; }; MouseLeftButtonDown += (_, _) => DragMove(); - GotFocus += (_, _) => - { - if (_viewModel.AppSettingData.ApplicationSetting.GeneralSetting.AlwaysOnTop) - WindowActionManager.ApplyAlwaysOnTop(_viewModel.ApplicationHandle, PanelType.PopOutManager, true); - }; } private void AppWindow_Loaded(object sender, RoutedEventArgs e) diff --git a/Orchestration/FlightSimOrchestrator.cs b/Orchestration/FlightSimOrchestrator.cs index d80a2c4..5a977b5 100644 --- a/Orchestration/FlightSimOrchestrator.cs +++ b/Orchestration/FlightSimOrchestrator.cs @@ -72,6 +72,10 @@ namespace MSFSPopoutPanelManager.Orchestration MapHudBarSimConnectData(e); }; + var _lastDynamicLodPause = DateTime.Now; + var _isDynamicLodPausePrevously = true; + var _lastDyanmicLodUpdatedTime = DateTime.Now; + _simConnectProvider.OnSimConnectDataDynamicLodRefreshed += (_, e) => { if (!AppSettingData.ApplicationSetting.DynamicLodSetting.IsEnabled || !FlightSimData.IsFlightStarted) @@ -80,9 +84,25 @@ namespace MSFSPopoutPanelManager.Orchestration var isPaused = (AppSettingData.ApplicationSetting.DynamicLodSetting.PauseWhenMsfsLoseFocus && !WindowActionManager.IsMsfsInFocus()) || (AppSettingData.ApplicationSetting.DynamicLodSetting.PauseOutsideCockpitView && FlightSimData.CameraState != CameraState.Cockpit); - if (isPaused) + if (_isDynamicLodPausePrevously && !isPaused) + { + if (DateTime.Now - _lastDynamicLodPause <= TimeSpan.FromSeconds(3)) + return; + + _lastDynamicLodPause = DateTime.Now; + _isDynamicLodPausePrevously = false; + } + else if (isPaused) + { + _isDynamicLodPausePrevously = true; return; - + } + + if (DateTime.Now - _lastDyanmicLodUpdatedTime <= TimeSpan.FromSeconds(0.4)) // take FPS sample every 0.4 seconds + return; + + _lastDyanmicLodUpdatedTime = DateTime.Now; + MapDynamicLodSimConnectData(e); _dynamicLodOrchestrator.UpdateLod(); }; diff --git a/Orchestration/PanelPopOutOrchestrator.cs b/Orchestration/PanelPopOutOrchestrator.cs index 015d779..27d02da 100644 --- a/Orchestration/PanelPopOutOrchestrator.cs +++ b/Orchestration/PanelPopOutOrchestrator.cs @@ -429,14 +429,14 @@ namespace MSFSPopoutPanelManager.Orchestration ApplyPanelConfig(panelConfig); // Set title bar color - if (AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.IsEnabled && !panelConfig.FullScreen) - { - WindowActionManager.SetWindowTitleBarColor(panelConfig.PanelHandle, AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.HexColor); - } + //if (AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.IsEnabled && !panelConfig.FullScreen) + //{ + // WindowActionManager.SetWindowTitleBarColor(panelConfig.PanelHandle, AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.HexColor); + //} } - if(ActiveProfile.PanelConfigs.Any(p => p.AlwaysOnTop)) - WindowActionManager.ApplyAlwaysOnTop(WindowProcessManager.SimulatorProcess.Handle, PanelType.FlightSimMainWindow, true); + //if(ActiveProfile.PanelConfigs.Any(p => p.AlwaysOnTop)) + // WindowActionManager.ApplyAlwaysOnTop(WindowProcessManager.SimulatorProcess.Handle, PanelType.FlightSimMainWindow, true); } private async Task StepPostPopout() @@ -534,11 +534,10 @@ namespace MSFSPopoutPanelManager.Orchestration if (!panel.FullScreen) { - // Apply always on top - if (panel.AlwaysOnTop) + // Set title bar color + if (AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.IsEnabled) { - WindowActionManager.ApplyAlwaysOnTop(panel.PanelHandle, panel.PanelType, panel.AlwaysOnTop); - Thread.Sleep(250); + WindowActionManager.SetWindowTitleBarColor(panel.PanelHandle, AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.HexColor); } // Apply hide title bar @@ -547,6 +546,13 @@ namespace MSFSPopoutPanelManager.Orchestration WindowActionManager.ApplyHidePanelTitleBar(panel.PanelHandle, true); Thread.Sleep(250); } + + // Apply always on top (must apply this last) + if (panel.AlwaysOnTop) + { + WindowActionManager.ApplyAlwaysOnTop(panel.PanelHandle, panel.PanelType, panel.AlwaysOnTop); + Thread.Sleep(250); + } } if (panel.FullScreen && !panel.AlwaysOnTop && !panel.HideTitlebar) diff --git a/SimconnectAgent/FpsCalc.cs b/SimconnectAgent/FpsCalc.cs index c4baff4..ddee248 100644 --- a/SimconnectAgent/FpsCalc.cs +++ b/SimconnectAgent/FpsCalc.cs @@ -5,10 +5,11 @@ namespace MSFSPopoutPanelManager.SimConnectAgent { public class FpsCalc { - private const int FPS_LEN = 20; + private const int FPS_LEN = 5; private static readonly float[] FpsStatistic = new float[FPS_LEN]; private static int _fpsIndex = -1; private static int _avgFps; + private static int _ignoreFpsSpikeCount = 0; public static int GetAverageFps(int newValue) { @@ -23,6 +24,16 @@ namespace MSFSPopoutPanelManager.SimConnectAgent } else { + var isSpike = Math.Abs(newValue - _avgFps) / (_avgFps * 1.0) > 0.1; + + if (_ignoreFpsSpikeCount != 3 && isSpike) // if new FPS spikes more than 10%, ignore the value + { + _ignoreFpsSpikeCount++; + return _avgFps; + } + + _ignoreFpsSpikeCount = 0; + var deltaFps = newValue - _avgFps; if (deltaFps < 0 && Math.Abs(deltaFps) > _avgFps * 0.1) // FPS suddenly drops more than 10% diff --git a/WindowsAgent/WindowActionManager.cs b/WindowsAgent/WindowActionManager.cs index 9ea692d..7c33d57 100644 --- a/WindowsAgent/WindowActionManager.cs +++ b/WindowsAgent/WindowActionManager.cs @@ -49,6 +49,8 @@ namespace MSFSPopoutPanelManager.WindowsAgent if (panelType == PanelType.PopOutManager) { OnPopOutManagerAlwaysOnTopChanged?.Invoke(null, alwaysOnTop); + if(alwaysOnTop) + PInvoke.SetWindowPos(hwnd, new IntPtr(PInvokeConstant.HWND_TOPMOST), 0, 0, 0, 0, PInvokeConstant.SWP_ALWAYS_ON_TOP); return; }