diff --git a/DomainModel/DomainModel.csproj b/DomainModel/DomainModel.csproj
index 591a6a0..6848d72 100644
--- a/DomainModel/DomainModel.csproj
+++ b/DomainModel/DomainModel.csproj
@@ -11,9 +11,9 @@
https://github.com/hawkeye-stan/msfs-popout-panel-manager
MSFSPopoutPanelManager.DomainModel
x64
- 4.1.1.0
- 4.1.1.0
- 4.1.1.0
+ 4.1.2.0
+ 4.1.2.0
+ 4.1.2.0
win-x64
Embedded
Debug;Release;Local
diff --git a/DomainModel/Profile/FloatingPanel.cs b/DomainModel/Profile/FloatingPanel.cs
index 8c91a7a..2a6767e 100644
--- a/DomainModel/Profile/FloatingPanel.cs
+++ b/DomainModel/Profile/FloatingPanel.cs
@@ -8,7 +8,7 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
{
public FloatingPanel()
{
- PropertyChanged += FloatingPanel_PropertyChanged; ;
+ PropertyChanged += FloatingPanel_PropertyChanged;
}
private void FloatingPanel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
diff --git a/DomainModel/Profile/PanelConfig.cs b/DomainModel/Profile/PanelConfig.cs
index 26fe447..d39a010 100644
--- a/DomainModel/Profile/PanelConfig.cs
+++ b/DomainModel/Profile/PanelConfig.cs
@@ -127,5 +127,8 @@ namespace MSFSPopoutPanelManager.DomainModel.Profile
return $"Left: {PanelSource.X} / Top: {PanelSource.Y}";
}
}
+
+ [JsonIgnore]
+ public MonitorInfo FullScreenMonitorInfo { get; set; }
}
}
diff --git a/MainApp/AppUserControl/ProfileCard.xaml b/MainApp/AppUserControl/ProfileCard.xaml
index 954dce7..e7dc75b 100644
--- a/MainApp/AppUserControl/ProfileCard.xaml
+++ b/MainApp/AppUserControl/ProfileCard.xaml
@@ -256,6 +256,7 @@
Include in-game menu bar panels for pop out management and touch screen support
+
{ Topmost = e; };
MouseLeftButtonDown += (_, _) => DragMove();
+
}
private void AppWindow_Loaded(object sender, RoutedEventArgs e)
diff --git a/MainApp/MainApp.csproj b/MainApp/MainApp.csproj
index 4e2fcfc..7e2be53 100644
--- a/MainApp/MainApp.csproj
+++ b/MainApp/MainApp.csproj
@@ -14,9 +14,9 @@
MSFSPopoutPanelManager.MainApp
logo.ico
x64
- 4.1.1.0
- 4.1.1.0
- 4.1.1.0
+ 4.1.2.0
+ 4.1.2.0
+ 4.1.2.0
embedded
en
diff --git a/MainApp/Properties/PublishProfiles/FolderProfile.pubxml b/MainApp/Properties/PublishProfiles/FolderProfile.pubxml
index 118e0a6..18dfaa2 100644
--- a/MainApp/Properties/PublishProfiles/FolderProfile.pubxml
+++ b/MainApp/Properties/PublishProfiles/FolderProfile.pubxml
@@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
-->
- Local
+ Release
x64
..\..\..\publish\master
FileSystem
diff --git a/Orchestration/DynamicLodOrchestrator.cs b/Orchestration/DynamicLodOrchestrator.cs
index ff0c937..f304014 100644
--- a/Orchestration/DynamicLodOrchestrator.cs
+++ b/Orchestration/DynamicLodOrchestrator.cs
@@ -1,7 +1,6 @@
using MSFSPopoutPanelManager.DomainModel.DynamicLod;
using MSFSPopoutPanelManager.DomainModel.Setting;
using MSFSPopoutPanelManager.Shared;
-using MSFSPopoutPanelManager.SimConnectAgent;
using MSFSPopoutPanelManager.WindowsAgent;
using System;
using System.Diagnostics;
@@ -17,12 +16,9 @@ namespace MSFSPopoutPanelManager.Orchestration
private const int PROCESS_VM_WRITE = 0x0020;
private const long OFFSET_MODULE_BASE =0x004B2368;
private const long OFFSET_POINTER_MAIN = 0x3D0;
- private const long OFFSET_POINTER_TLOD_VR = 0x114;
private const long OFFSET_POINTER_TLOD = 0xC;
private const long OFFSET_POINTER_OLOD = 0xC;
- private const long OFFSET_POINTER_CLOUDQ = 0x44;
- private const long OFFSET_POINTER_CLOUDQ_VR = 0x108;
- private const long OFFSET_POINTER_VR_MODE = 0x1C;
+ private const long OFFSET_POINTER_CLOUD_QUALITY = 0x44;
private const long OFFSET_POINTER_FG_MODE = 0x4A;
private const long OFFSET_POINTER_ANSIO_FILTER = -0x18;
private const long OFFSET_POINTER_WATER_WAVES = 0x3C;
@@ -34,19 +30,15 @@ namespace MSFSPopoutPanelManager.Orchestration
private long _addressTlod;
private long _addressOlod;
- private long _addressTlodVr;
- private long _addressOlodVr;
private long _addressCloudQ;
- private long _addressCloudQVr;
- private long _addressVrMode;
private long _addressFgMode;
private DynamicLodSetting DynamicLodSetting => AppSettingData.ApplicationSetting.DynamicLodSetting;
- private DynamicLodSimData SimData => FlightSimData.DynamicLodSimData;
+ private DynamicLodSimData DynamicLodSimData => FlightSimData.DynamicLodSimData;
private DateTime _lastLodUpdateTime = DateTime.Now;
- private bool _isDecreasedCloudQualityActive = false;
+ private bool _isDecreasedCloudQualityActive;
public DynamicLodOrchestrator(SharedStorage sharedStorage) : base(sharedStorage) {}
@@ -70,13 +62,9 @@ namespace MSFSPopoutPanelManager.Orchestration
if (_addressTlod > 0)
{
- _addressTlodVr = ReadMemory(_addressTlod) + OFFSET_POINTER_TLOD_VR;
_addressTlod = ReadMemory(_addressTlod) + OFFSET_POINTER_TLOD;
_addressOlod = _addressTlod + OFFSET_POINTER_OLOD;
- _addressOlodVr = _addressTlodVr + OFFSET_POINTER_OLOD;
- _addressCloudQ = _addressTlod + OFFSET_POINTER_CLOUDQ;
- _addressCloudQVr = _addressCloudQ + OFFSET_POINTER_CLOUDQ_VR;
- _addressVrMode = _addressTlod - OFFSET_POINTER_VR_MODE;
+ _addressCloudQ = _addressTlod + OFFSET_POINTER_CLOUD_QUALITY;
_addressFgMode = _addressTlod - OFFSET_POINTER_FG_MODE;
if (!MemoryBoundaryTest())
@@ -99,9 +87,8 @@ namespace MSFSPopoutPanelManager.Orchestration
if (DynamicLodSetting.ResetEnabled)
{
- var isVr = ReadIsVr();
- WriteMemory(isVr ? _addressTlodVr : _addressTlod, DynamicLodSetting.ResetTlod / 100.0f);
- WriteMemory(isVr ? _addressOlodVr : _addressOlod, DynamicLodSetting.ResetOlod / 100.0f);
+ WriteMemory(_addressTlod, DynamicLodSetting.ResetTlod / 100.0f);
+ WriteMemory(_addressOlod, DynamicLodSetting.ResetOlod / 100.0f);
}
_isActive = false;
@@ -109,19 +96,19 @@ namespace MSFSPopoutPanelManager.Orchestration
Debug.WriteLine($"Reset to custom LOD: TLOD: {DynamicLodSetting.ResetTlod}, OLOD: {DynamicLodSetting.ResetOlod}");
}
- public int ReadTlod(bool isVr = false)
+ public int ReadTlod()
{
- return Convert.ToInt32(ReadMemory(isVr ? _addressTlodVr : _addressTlod) * 100.0f);
+ return Convert.ToInt32(ReadMemory(_addressTlod) * 100.0f);
}
- public int ReadOlod(bool isVr = false)
+ public int ReadOlod()
{
- return Convert.ToInt32(ReadMemory(isVr ? _addressOlodVr : _addressOlod) * 100.0f);
+ return Convert.ToInt32(ReadMemory(_addressOlod) * 100.0f);
}
- public string ReadCloudQuality(bool isVr = false)
+ public string ReadCloudQuality()
{
- return ReadCloudQualitySimValue(isVr) switch
+ return ReadCloudQualitySimValue() switch
{
0 => "Low",
1 => "Medium",
@@ -131,33 +118,25 @@ namespace MSFSPopoutPanelManager.Orchestration
};
}
- public int ReadCloudQualitySimValue(bool isVr = false)
+ public int ReadCloudQualitySimValue()
{
- return Convert.ToInt32(ReadMemory(isVr ? _addressCloudQVr : _addressCloudQ));
+ return Convert.ToInt32(ReadMemory(_addressCloudQ));
}
- public bool ReadIsVr()
+ public bool ReadIsFg()
{
- return ReadMemory(_addressVrMode) == 1;
- }
-
- public bool ReadIsFg(bool isVr)
- {
- if (isVr)
- return false;
-
return ReadMemory(_addressFgMode) == 1;
}
- public void UpdateLod(bool isVr)
+ public void UpdateLod()
{
- if (DateTime.Now - _lastLodUpdateTime <= TimeSpan.FromSeconds(1))
+ if (!FlightSimData.IsFlightStarted || !FlightSimData.IsInCockpit)
+ return;
+
+ if (DateTime.Now - _lastLodUpdateTime <= TimeSpan.FromSeconds(3))
return;
- if (!FlightSimData.IsFlightStarted || !FlightSimData.IsInCockpit || (DynamicLodSetting.PauseOutsideCockpitView && FlightSimData.CameraState != CameraState.Cockpit))
- return;
-
- var deltaFps = SimData.Fps - DynamicLodSetting.TargetedFps;
+ var deltaFps = DynamicLodSimData.Fps - DynamicLodSetting.TargetedFps;
if (Math.Abs(deltaFps) < DynamicLodSetting.TargetedFps * DynamicLodSetting.FpsTolerance / 100.0) // within FPS tolerance
return;
@@ -246,10 +225,9 @@ namespace MSFSPopoutPanelManager.Orchestration
private bool MemoryBoundaryTest()
{
// Boundary check a few known setting memory addresses to see if any fail which likely indicates MSFS memory map has changed
- if (ReadTlod() < 10 || ReadTlod() > 1000 || ReadTlod(true) < 10 || ReadTlod(true) > 1000
- || ReadOlod() < 10 || ReadOlod() > 1000 || ReadOlod(true) < 10 || ReadOlod(true) > 1000
- || ReadCloudQuality() == "N/A" || ReadCloudQuality(true) == "N/A"
- || ReadMemory(_addressVrMode) < 0 || ReadMemory(_addressVrMode) > 1
+ if (ReadTlod() < 10 || ReadTlod() > 1000 || ReadTlod() < 10 || ReadTlod() > 1000
+ || ReadOlod() < 10 || ReadOlod() > 1000 || ReadOlod() < 10 || ReadOlod() > 1000
+ || ReadCloudQuality() == "N/A" || ReadCloudQuality() == "N/A"
|| ReadMemory(_addressTlod + OFFSET_POINTER_ANSIO_FILTER) < 1 || ReadMemory(_addressTlod + OFFSET_POINTER_ANSIO_FILTER) > 16
|| !(ReadMemory(_addressTlod + OFFSET_POINTER_WATER_WAVES) == 128 || ReadMemory(_addressTlod + OFFSET_POINTER_WATER_WAVES) == 256 || ReadMemory(_addressTlod + OFFSET_POINTER_WATER_WAVES) == 512))
{
@@ -259,12 +237,12 @@ namespace MSFSPopoutPanelManager.Orchestration
return true;
}
- private void SetTlod(int deltaFps, bool isVr = false)
+ private void SetTlod(int deltaFps)
{
- var tlodStep = Math.Max(5, Math.Abs(deltaFps / 2));
- var newTlod = SimData.Tlod + Math.Sign(deltaFps) * tlodStep;
+ var tlodStep = Math.Max(10, Math.Abs(deltaFps / 2));
+ var newTlod = DynamicLodSimData.Tlod + Math.Sign(deltaFps) * tlodStep;
- if (DynamicLodSetting.TlodMinOnGround && SimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)
+ if (DynamicLodSetting.TlodMinOnGround && DynamicLodSimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)
{
newTlod = DynamicLodSetting.TlodMin;
}
@@ -277,17 +255,17 @@ namespace MSFSPopoutPanelManager.Orchestration
newTlod = DynamicLodSetting.TlodMax;
}
- if (ReadTlod(isVr) == newTlod)
+ if (ReadTlod() == newTlod)
return;
// Adjust cloud quality if applicable
- if (DynamicLodSetting.DecreaseCloudQuality && (!DynamicLodSetting.TlodMinOnGround && !(SimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)))
+ if (DynamicLodSetting.DecreaseCloudQuality && (!DynamicLodSetting.TlodMinOnGround && !(DynamicLodSimData.AltAboveGround <= DynamicLodSetting.AltTlodBase)))
{
switch (deltaFps)
{
case < 0 when newTlod < DynamicLodSetting.CloudRecoveryTlod && !_isDecreasedCloudQualityActive:
_isDecreasedCloudQualityActive = true;
- WriteMemory(isVr ? _addressCloudQVr : _addressCloudQ, ReadCloudQualitySimValue(isVr) - 1);
+ WriteMemory(_addressCloudQ, ReadCloudQualitySimValue() - 1);
_lastLodUpdateTime =
_lastLodUpdateTime.AddSeconds(2); // Add extra delay for cloud setting to take effect
@@ -296,7 +274,7 @@ namespace MSFSPopoutPanelManager.Orchestration
return;
case > 0 when newTlod >= DynamicLodSetting.CloudRecoveryTlod && _isDecreasedCloudQualityActive:
_isDecreasedCloudQualityActive = false;
- WriteMemory(isVr ? _addressCloudQVr : _addressCloudQ, ReadCloudQualitySimValue(isVr) + 1);
+ WriteMemory(_addressCloudQ, ReadCloudQualitySimValue() + 1);
_lastLodUpdateTime = _lastLodUpdateTime.AddSeconds(2);
Debug.WriteLine("New Cloud Quality written - 3.");
@@ -306,31 +284,31 @@ namespace MSFSPopoutPanelManager.Orchestration
}
Debug.WriteLine($"New TLOD written - {newTlod}.");
- WriteMemory(isVr ? _addressTlodVr : _addressTlod, newTlod / 100.0f);
+ WriteMemory(_addressTlod, newTlod / 100.0f);
}
- private void SetOlod(bool isVr = false)
+ private void SetOlod()
{
int newOlod;
- if (SimData.AltAboveGround < DynamicLodSetting.AltOlodBase)
+ if (DynamicLodSimData.AltAboveGround < DynamicLodSetting.AltOlodBase)
{
newOlod = DynamicLodSetting.OlodBase;
}
- else if (SimData.AltAboveGround > DynamicLodSetting.AltOlodTop)
+ else if (DynamicLodSimData.AltAboveGround > DynamicLodSetting.AltOlodTop)
{
newOlod = DynamicLodSetting.OlodTop;
}
else
{
- newOlod = Convert.ToInt32(DynamicLodSetting.OlodBase - (DynamicLodSetting.OlodBase - DynamicLodSetting.OlodTop) * (SimData.AltAboveGround - DynamicLodSetting.AltOlodBase) / (DynamicLodSetting.AltOlodTop - DynamicLodSetting.AltOlodBase));
+ newOlod = Convert.ToInt32(DynamicLodSetting.OlodBase - (DynamicLodSetting.OlodBase - DynamicLodSetting.OlodTop) * (DynamicLodSimData.AltAboveGround - DynamicLodSetting.AltOlodBase) / (DynamicLodSetting.AltOlodTop - DynamicLodSetting.AltOlodBase));
}
- if (ReadOlod(isVr) == newOlod)
+ if (ReadOlod() == newOlod)
return;
Debug.WriteLine($"New OLOD written - {newOlod}.");
- WriteMemory(isVr ? _addressOlodVr : _addressOlod, newOlod / 100.0f);
+ WriteMemory(_addressOlod, newOlod / 100.0f);
}
}
}
diff --git a/Orchestration/FlightSimOrchestrator.cs b/Orchestration/FlightSimOrchestrator.cs
index b195575..5a977b5 100644
--- a/Orchestration/FlightSimOrchestrator.cs
+++ b/Orchestration/FlightSimOrchestrator.cs
@@ -15,7 +15,7 @@ namespace MSFSPopoutPanelManager.Orchestration
private System.Timers.Timer _msfsGameExitDetectionTimer;
private SimConnectProvider _simConnectProvider;
- private DynamicLodOrchestrator _dynamicLodOrchestrator;
+ private readonly DynamicLodOrchestrator _dynamicLodOrchestrator;
private bool _isTurnedOnPower;
private bool _isTurnedOnAvionics;
@@ -72,22 +72,39 @@ 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)
return;
- var isVr = _dynamicLodOrchestrator.ReadIsVr();
- MapDynamicLodSimConnectData(e, isVr);
-
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;
-
- FlightSimData.DynamicLodSimData.Fps = FpsCalc.GetAverageFps(_dynamicLodOrchestrator.ReadIsFg(isVr) ? _currentFps * 2 : _currentFps);
- _dynamicLodOrchestrator.UpdateLod(isVr);
+ }
+
+ if (DateTime.Now - _lastDyanmicLodUpdatedTime <= TimeSpan.FromSeconds(0.4)) // take FPS sample every 0.4 seconds
+ return;
+
+ _lastDyanmicLodUpdatedTime = DateTime.Now;
+
+ MapDynamicLodSimConnectData(e);
+ _dynamicLodOrchestrator.UpdateLod();
};
_simConnectProvider.OnSimConnectDataEventFrameRefreshed += (_, e) =>
@@ -393,6 +410,7 @@ namespace MSFSPopoutPanelManager.Orchestration
FlightSimData.IsFlightStarted = false;
StopDynamicLod();
+ FpsCalc.Reset();
FlightSimData.DynamicLodSimData.Clear();
}
@@ -492,7 +510,7 @@ namespace MSFSPopoutPanelManager.Orchestration
FlightSimData.HudBarData.SimRate = newValue;
}
- private void MapDynamicLodSimConnectData(List simData, bool isVr)
+ private void MapDynamicLodSimConnectData(List simData)
{
if (CompareSimConnectData(simData, SimDataDefinitions.PropName.PlaneAltAboveGround, FlightSimData.DynamicLodSimData.Agl, out var newValue))
FlightSimData.DynamicLodSimData.Agl = newValue;
@@ -509,17 +527,19 @@ namespace MSFSPopoutPanelManager.Orchestration
if (CompareSimConnectData(simData, SimDataDefinitions.PropName.SimOnGround, 1.0f, out newValue))
FlightSimData.DynamicLodSimData.PlaneOnGround = Convert.ToBoolean(newValue);
- var tlod = _dynamicLodOrchestrator.ReadTlod(isVr);
+ var tlod = _dynamicLodOrchestrator.ReadTlod();
if (FlightSimData.DynamicLodSimData.Tlod != tlod)
FlightSimData.DynamicLodSimData.Tlod = tlod;
- var olod = _dynamicLodOrchestrator.ReadOlod(isVr);
+ var olod = _dynamicLodOrchestrator.ReadOlod();
if (FlightSimData.DynamicLodSimData.Olod != olod)
FlightSimData.DynamicLodSimData.Olod = olod;
- var cloudQuality = _dynamicLodOrchestrator.ReadCloudQuality(isVr);
+ var cloudQuality = _dynamicLodOrchestrator.ReadCloudQuality();
if (FlightSimData.DynamicLodSimData.CloudQuality != cloudQuality)
FlightSimData.DynamicLodSimData.CloudQuality = cloudQuality;
+
+ FlightSimData.DynamicLodSimData.Fps = FpsCalc.GetAverageFps(_dynamicLodOrchestrator.ReadIsFg() ? _currentFps * 2 : _currentFps);
}
private int _currentFps;
diff --git a/Orchestration/Orchestration.csproj b/Orchestration/Orchestration.csproj
index 6cf921a..fac2f5f 100644
--- a/Orchestration/Orchestration.csproj
+++ b/Orchestration/Orchestration.csproj
@@ -11,9 +11,9 @@
https://github.com/hawkeye-stan/msfs-popout-panel-manager
MSFSPopoutPanelManager.Orchestration
x64
- 4.1.1.0
- 4.1.1.0
- 4.1.1.0
+ 4.1.2.0
+ 4.1.2.0
+ 4.1.2.0
win-x64
Embedded
Debug;Release;Local
diff --git a/Orchestration/PanelConfigurationOrchestrator.cs b/Orchestration/PanelConfigurationOrchestrator.cs
index 7589b03..2c554c7 100644
--- a/Orchestration/PanelConfigurationOrchestrator.cs
+++ b/Orchestration/PanelConfigurationOrchestrator.cs
@@ -130,8 +130,15 @@ namespace MSFSPopoutPanelManager.Orchestration
{
InputEmulationManager.ToggleFullScreenPanel(panelConfig.PanelHandle);
- if (!panelConfig.FullScreen)
+ if (panelConfig.FullScreen)
+ {
+ WindowActionManager.SetHostMonitor(panelConfig);
+ }
+ else
+ {
WindowActionManager.MoveWindow(panelConfig.PanelHandle, panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height);
+ panelConfig.FullScreenMonitorInfo = null;
+ }
}
else if (configPropertyName == PanelConfigPropertyName.PanelName)
{
diff --git a/Orchestration/PanelPopOutOrchestrator.cs b/Orchestration/PanelPopOutOrchestrator.cs
index 2dfc340..749890f 100644
--- a/Orchestration/PanelPopOutOrchestrator.cs
+++ b/Orchestration/PanelPopOutOrchestrator.cs
@@ -122,7 +122,7 @@ namespace MSFSPopoutPanelManager.Orchestration
StepAddHudBar();
StepAddNumPad();
-
+
SetupRefocusDisplay();
StepApplyPanelConfig();
@@ -412,12 +412,6 @@ namespace MSFSPopoutPanelManager.Orchestration
foreach (var panelConfig in ActiveProfile.PanelConfigs)
{
ApplyPanelConfig(panelConfig);
-
- // Set title bar color
- if (AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.IsEnabled && !panelConfig.FullScreen)
- {
- WindowActionManager.SetWindowTitleBarColor(panelConfig.PanelHandle, AppSettingData.ApplicationSetting.PopOutSetting.PopOutTitleBarCustomization.HexColor);
- }
}
}
@@ -516,11 +510,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
@@ -529,6 +522,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)
@@ -536,6 +536,9 @@ namespace MSFSPopoutPanelManager.Orchestration
Thread.Sleep(500);
InputEmulationManager.ToggleFullScreenPanel(panel.PanelHandle);
Thread.Sleep(250);
+
+ if (panel.TouchEnabled)
+ WindowActionManager.SetHostMonitor(panel); // Set full screen coordinate for touch
}
if (panel.FloatingPanel.IsEnabled && panel.FloatingPanel.HasKeyboardBinding && panel.FloatingPanel.IsHiddenOnStart)
diff --git a/RELEASENOTES.md b/RELEASENOTES.md
index 5ad2bc7..c0a1df8 100644
--- a/RELEASENOTES.md
+++ b/RELEASENOTES.md
@@ -1,15 +1,7 @@
-## Version 4.1.1
+## Version 4.1.2
-* Added option to store POPM profiles and configuration files in your user's AppData Roaming folder instead of Documents folder. Hopefully, this solved the issue where OneDrive users are having issue with POPM files.
+* Added touch support for pop out when in full screen mode.
-* Fixed POPM inability to close correctly when Keyboard Shortcuts preference is disabled.
+* Fixed pop out always on top issue where it sometimes does not work.
-* Fixed issue where auto start option failed to retain CommandLine arguments in exe.xml file.
-
-* Fixed issue where auto start does not work correctly for Steam version of MSFS since exe.xml file location has been moved by Steam installation.
-
-* Added ability for full screen panel to work as floating panel. An example use case is to show and hide EFB as full screen using keyboard shortcut.
-
-* Added dynamic LOD (my own implementation of AutoFPS) - this is totally experimental and unsupported. If you decide to use this version of dynamic LOD, you don't have to run multiple apps.
-
-* Fixed various smaller bugs.
+* Improved dynamic LOD FPS detection and logic.
diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj
index 08c68ae..1c410bb 100644
--- a/Shared/Shared.csproj
+++ b/Shared/Shared.csproj
@@ -11,9 +11,9 @@
https://github.com/hawkeye-stan/msfs-popout-panel-manager
MSFSPopoutPanelManager.Shared
x64
- 4.1.1.0
- 4.1.1.0
- 4.1.1.0
+ 4.1.2.0
+ 4.1.2.0
+ 4.1.2.0
win-x64
Embedded
Debug;Release;Local
diff --git a/SimconnectAgent/FpsCalc.cs b/SimconnectAgent/FpsCalc.cs
index 6aff9e5..ddee248 100644
--- a/SimconnectAgent/FpsCalc.cs
+++ b/SimconnectAgent/FpsCalc.cs
@@ -5,32 +5,57 @@ namespace MSFSPopoutPanelManager.SimConnectAgent
{
public class FpsCalc
{
- private const int FpsLen = 25;
- private static readonly float[] FpsStatistic = new float[FpsLen];
+ 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)
{
if (_fpsIndex == -1)
{
- for (var i = 0; i < FpsLen; i++)
+ // initialize FpsStatistic array
+ for (var i = 0; i < FPS_LEN; i++)
FpsStatistic[i] = newValue;
-
+
+ _avgFps = Convert.ToInt32(newValue);
_fpsIndex = 1;
}
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%
+ {
+ newValue += Math.Abs(deltaFps) / 2; // Let the new FPS to be only half the delta drop
+ }
+
FpsStatistic[_fpsIndex] = newValue;
_fpsIndex++;
- if (_fpsIndex >= FpsLen)
+ if (_fpsIndex >= FPS_LEN)
_fpsIndex = 0;
+
+ _avgFps = Convert.ToInt32(FpsStatistic.Sum() / FPS_LEN);
}
+
+ return _avgFps;
+ }
- var fps = 0;
- if (_fpsIndex != -1)
- fps = Convert.ToInt32(FpsStatistic.Sum() / FpsLen);
-
- return fps;
+ public static void Reset()
+ {
+ _fpsIndex = -1;
+ _avgFps = 0;
}
}
}
diff --git a/SimconnectAgent/SimconnectAgent.csproj b/SimconnectAgent/SimconnectAgent.csproj
index 818840d..7ca62cf 100644
--- a/SimconnectAgent/SimconnectAgent.csproj
+++ b/SimconnectAgent/SimconnectAgent.csproj
@@ -11,9 +11,9 @@
https://github.com/hawkeye-stan/msfs-popout-panel-manager
MSFSPopoutPanelManager.SimConnectAgent
x64
- 4.1.1.0
- 4.1.1.0
- 4.1.1.0
+ 4.1.2.0
+ 4.1.2.0
+ 4.1.2.0
win-x64
Embedded
Debug;Release;Local
diff --git a/VERSION.md b/VERSION.md
index 1eabd21..ce54ff0 100644
--- a/VERSION.md
+++ b/VERSION.md
@@ -1,6 +1,15 @@
# Version History
+## Version 4.1.2
+
+* Added touch support for pop out when in full screen mode.
+
+* Fixed pop out always on top issue where it sometimes does not work.
+
+* Improved dynamic LOD FPS detection and logic.
+
+
## Version 4.1.1
* Added option to store POPM profiles and configuration files in your user's AppData Roaming folder instead of Documents folder. Hopefully, this solved the issue where OneDrive users are having issue with POPM files.
diff --git a/WindowsAgent/PInvoke.cs b/WindowsAgent/PInvoke.cs
index 97a7909..fb74e56 100644
--- a/WindowsAgent/PInvoke.cs
+++ b/WindowsAgent/PInvoke.cs
@@ -193,6 +193,23 @@ namespace MSFSPopoutPanelManager.WindowsAgent
return new Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top);
}
+
+ public static IntPtr GetWindowHandle(string windowCaption)
+ {
+ IntPtr windowHandle = IntPtr.Zero;
+
+ EnumWindows((hwnd, _) =>
+ {
+ var caption = GetWindowText(hwnd);
+
+ if (caption == windowCaption)
+ windowHandle = hwnd;
+
+ return true;
+ }, 0);
+
+ return windowHandle;
+ }
}
public struct RECT
diff --git a/WindowsAgent/TouchEventManager.cs b/WindowsAgent/TouchEventManager.cs
index 99c7640..8260e40 100644
--- a/WindowsAgent/TouchEventManager.cs
+++ b/WindowsAgent/TouchEventManager.cs
@@ -92,10 +92,8 @@ namespace MSFSPopoutPanelManager.WindowsAgent
// If touch point is within pop out panel boundaries and have touch enabled
var panelConfig = ActiveProfile.PanelConfigs.FirstOrDefault(p => p.TouchEnabled &&
- (info.pt.X > p.Left
- && info.pt.X < p.Left + p.Width
- && info.pt.Y > p.Top + (p.HideTitlebar ? 5 : PANEL_MENUBAR_HEIGHT)
- && info.pt.Y < p.Top + p.Height));
+ ((p.FullScreen && CheckWithinFullScreenCoordinate(p, info)) || CheckWithinWindowCoordinate(p, info)));
+
if (panelConfig == null)
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
@@ -218,5 +216,21 @@ namespace MSFSPopoutPanelManager.WindowsAgent
return PInvoke.CallNextHookEx(_hHook, code, wParam, lParam);
}
+
+ private static bool CheckWithinWindowCoordinate(PanelConfig panelConfig, MSLLHOOKSTRUCT coor)
+ {
+ return coor.pt.X > panelConfig.Left
+ && coor.pt.X < panelConfig.Left + panelConfig.Width
+ && coor.pt.Y > panelConfig.Top + (panelConfig.HideTitlebar ? 5 : PANEL_MENUBAR_HEIGHT)
+ && coor.pt.Y < panelConfig.Top + panelConfig.Height;
+ }
+
+ private static bool CheckWithinFullScreenCoordinate(PanelConfig panelConfig, MSLLHOOKSTRUCT coor)
+ {
+ return coor.pt.X > panelConfig.FullScreenMonitorInfo.X
+ && coor.pt.X < panelConfig.FullScreenMonitorInfo.X + panelConfig.FullScreenMonitorInfo.Width
+ && coor.pt.Y > panelConfig.FullScreenMonitorInfo.Y
+ && coor.pt.Y < panelConfig.FullScreenMonitorInfo.Y + panelConfig.FullScreenMonitorInfo.Height;
+ }
}
}
diff --git a/WindowsAgent/WindowActionManager.cs b/WindowsAgent/WindowActionManager.cs
index ffd5a8c..2a1ffa6 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;
}
@@ -309,5 +311,22 @@ namespace MSFSPopoutPanelManager.WindowsAgent
return text.Substring(0, 26).Equals("Microsoft Flight Simulator", StringComparison.InvariantCultureIgnoreCase);
}
+
+ public static void SetHostMonitor(PanelConfig panelConfig)
+ {
+ foreach (var screen in System.Windows.Forms.Screen.AllScreens)
+ {
+ if (screen.Bounds.IntersectsWith(new Rectangle(panelConfig.Left, panelConfig.Top, panelConfig.Width, panelConfig.Height)))
+ panelConfig.FullScreenMonitorInfo =
+ new MonitorInfo
+ {
+ Name = screen.DeviceName.Substring(screen.DeviceName.LastIndexOf("\\", StringComparison.Ordinal) + 1),
+ X = screen.Bounds.X,
+ Y = screen.Bounds.Y,
+ Width = screen.Bounds.Width,
+ Height = screen.Bounds.Height
+ };
+ }
+ }
}
}
diff --git a/WindowsAgent/WindowsAgent.csproj b/WindowsAgent/WindowsAgent.csproj
index 337f6b8..c8f4d3d 100644
--- a/WindowsAgent/WindowsAgent.csproj
+++ b/WindowsAgent/WindowsAgent.csproj
@@ -11,9 +11,9 @@
https://github.com/hawkeye-stan/msfs-popout-panel-manager
MSFSPopoutPanelManager.WindowsAgent
x64
- 4.1.1.0
- 4.1.1.0
- 4.1.1.0
+ 4.1.2.0
+ 4.1.2.0
+ 4.1.2.0
win-x64
Embedded
Debug;Release;Local