feat: do not close addons when any Window is still open

This commit is contained in:
goat 2021-09-01 19:50:23 +02:00
parent 647d095fcc
commit 412a335b93
No known key found for this signature in database
GPG key ID: F18F057873895461
6 changed files with 68 additions and 28 deletions

View file

@ -216,7 +216,7 @@ namespace Dalamud
clientState.Enable();
Log.Information("[T2] CS ENABLE!");
Service<DalamudSystemMenu>.Set().Enable();
Service<DalamudAtkTweaks>.Set().Enable();
this.IsReady = true;
}
@ -339,7 +339,7 @@ namespace Dalamud
Service<WinSockHandlers>.GetNullable()?.Dispose();
Service<DataManager>.GetNullable()?.Dispose();
Service<AntiDebug>.GetNullable()?.Dispose();
Service<DalamudSystemMenu>.GetNullable()?.Dispose();
Service<DalamudAtkTweaks>.GetNullable()?.Dispose();
Service<HookManager>.GetNullable()?.Dispose();
Service<SigScanner>.GetNullable()?.Dispose();

View file

@ -7,6 +7,7 @@ using Dalamud.Configuration.Internal;
using Dalamud.Hooking;
using Dalamud.Interface.Internal;
using FFXIVClientStructs.FFXIV.Component.GUI;
using Serilog;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
@ -15,7 +16,7 @@ namespace Dalamud.Game.Internal
/// <summary>
/// This class implements in-game Dalamud options in the in-game System menu.
/// </summary>
internal sealed unsafe partial class DalamudSystemMenu
internal sealed unsafe partial class DalamudAtkTweaks
{
private readonly AtkValueChangeType atkValueChangeType;
private readonly AtkValueSetString atkValueSetString;
@ -24,10 +25,12 @@ namespace Dalamud.Game.Internal
// TODO: Make this into events in Framework.Gui
private readonly Hook<UiModuleRequestMainCommand> hookUiModuleRequestMainCommand;
private readonly Hook<AtkUnitBaseReceiveGlobalEvent> hookAtkUnitBaseReceiveGlobalEvent;
/// <summary>
/// Initializes a new instance of the <see cref="DalamudSystemMenu"/> class.
/// Initializes a new instance of the <see cref="DalamudAtkTweaks"/> class.
/// </summary>
public DalamudSystemMenu()
public DalamudAtkTweaks()
{
var sigScanner = Service<SigScanner>.Get();
@ -43,6 +46,11 @@ namespace Dalamud.Game.Internal
var uiModuleRequestMainCommandAddress = sigScanner.ScanText("40 53 56 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 48 8B 01 8B DA 48 8B F1 FF 90 ?? ?? ?? ??");
this.hookUiModuleRequestMainCommand = new Hook<UiModuleRequestMainCommand>(uiModuleRequestMainCommandAddress, this.UiModuleRequestMainCommandDetour);
var atkUnitBaseReceiveGlobalEventAddress =
sigScanner.ScanText("48 89 5C 24 ?? 48 89 7C 24 ?? 55 41 56 41 57 48 8B EC 48 83 EC 50 44 0F B7 F2 ");
this.hookAtkUnitBaseReceiveGlobalEvent =
new Hook<AtkUnitBaseReceiveGlobalEvent>(atkUnitBaseReceiveGlobalEventAddress, this.AtkUnitBaseReceiveGlobalEventDetour);
}
private delegate void AgentHudOpenSystemMenuPrototype(void* thisPtr, AtkValue* atkValueArgs, uint menuSize);
@ -53,13 +61,28 @@ namespace Dalamud.Game.Internal
private delegate void UiModuleRequestMainCommand(void* thisPtr, int commandId);
private delegate IntPtr AtkUnitBaseReceiveGlobalEvent(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5);
/// <summary>
/// Enables the <see cref="DalamudSystemMenu"/>.
/// Enables the <see cref="DalamudAtkTweaks"/>.
/// </summary>
public void Enable()
{
this.hookAgentHudOpenSystemMenu.Enable();
this.hookUiModuleRequestMainCommand.Enable();
this.hookAtkUnitBaseReceiveGlobalEvent.Enable();
}
private IntPtr AtkUnitBaseReceiveGlobalEventDetour(AtkUnitBase* thisPtr, ushort cmd, uint a3, IntPtr a4, uint* a5)
{
Log.Information($"cmd:{cmd} a3:{a3} a4:{a4:x} a5:{*a5}");
var di = Service<DalamudInterface>.Get();
// "Close Addon"
if (cmd == 12 && di.WindowSystem.HasAnyFocus)
return IntPtr.Zero;
return this.hookAtkUnitBaseReceiveGlobalEvent.Original(thisPtr, cmd, a3, a4, a5);
}
private void AgentHudOpenSystemMenuDetour(void* thisPtr, AtkValue* atkValueArgs, uint menuSize)
@ -157,14 +180,14 @@ namespace Dalamud.Game.Internal
/// <summary>
/// Implements IDisposable.
/// </summary>
internal sealed partial class DalamudSystemMenu : IDisposable
internal sealed partial class DalamudAtkTweaks : IDisposable
{
private bool disposed = false;
/// <summary>
/// Finalizes an instance of the <see cref="DalamudSystemMenu"/> class.
/// Finalizes an instance of the <see cref="DalamudAtkTweaks"/> class.
/// </summary>
~DalamudSystemMenu() => this.Dispose(false);
~DalamudAtkTweaks() => this.Dispose(false);
/// <summary>
/// Dispose of managed and unmanaged resources.
@ -187,6 +210,7 @@ namespace Dalamud.Game.Internal
{
this.hookAgentHudOpenSystemMenu.Dispose();
this.hookUiModuleRequestMainCommand.Dispose();
this.hookAtkUnitBaseReceiveGlobalEvent.Dispose();
}
this.disposed = true;

View file

@ -28,8 +28,6 @@ namespace Dalamud.Interface.Internal
{
private static readonly ModuleLog Log = new("DUI");
private readonly WindowSystem windowSystem;
private readonly ChangelogWindow changelogWindow;
private readonly ColorDemoWindow colorDemoWindow;
private readonly ComponentDemoWindow componentDemoWindow;
@ -61,7 +59,7 @@ namespace Dalamud.Interface.Internal
{
var configuration = Service<DalamudConfiguration>.Get();
this.windowSystem = new WindowSystem("DalamudCore");
this.WindowSystem = new WindowSystem("DalamudCore");
this.changelogWindow = new ChangelogWindow() { IsOpen = false };
this.colorDemoWindow = new ColorDemoWindow() { IsOpen = false };
@ -77,19 +75,19 @@ namespace Dalamud.Interface.Internal
this.settingsWindow = new SettingsWindow() { IsOpen = false };
this.selfTestWindow = new SelfTestWindow() { IsOpen = false };
this.windowSystem.AddWindow(this.changelogWindow);
this.windowSystem.AddWindow(this.colorDemoWindow);
this.windowSystem.AddWindow(this.componentDemoWindow);
this.windowSystem.AddWindow(this.creditsWindow);
this.windowSystem.AddWindow(this.dataWindow);
this.windowSystem.AddWindow(this.gamepadModeNotifierWindow);
this.windowSystem.AddWindow(this.imeWindow);
this.windowSystem.AddWindow(this.consoleWindow);
this.windowSystem.AddWindow(this.pluginStatWindow);
this.windowSystem.AddWindow(this.pluginWindow);
this.windowSystem.AddWindow(this.scratchpadWindow);
this.windowSystem.AddWindow(this.settingsWindow);
this.windowSystem.AddWindow(this.selfTestWindow);
this.WindowSystem.AddWindow(this.changelogWindow);
this.WindowSystem.AddWindow(this.colorDemoWindow);
this.WindowSystem.AddWindow(this.componentDemoWindow);
this.WindowSystem.AddWindow(this.creditsWindow);
this.WindowSystem.AddWindow(this.dataWindow);
this.WindowSystem.AddWindow(this.gamepadModeNotifierWindow);
this.WindowSystem.AddWindow(this.imeWindow);
this.WindowSystem.AddWindow(this.consoleWindow);
this.WindowSystem.AddWindow(this.pluginStatWindow);
this.WindowSystem.AddWindow(this.pluginWindow);
this.WindowSystem.AddWindow(this.scratchpadWindow);
this.WindowSystem.AddWindow(this.settingsWindow);
this.WindowSystem.AddWindow(this.selfTestWindow);
ImGuiManagedAsserts.EnableAsserts = true;
@ -98,6 +96,11 @@ namespace Dalamud.Interface.Internal
Log.Information("Windows added");
}
/// <summary>
/// Gets the <see cref="WindowSystem"/> controlling all Dalamud-internal windows.
/// </summary>
public WindowSystem WindowSystem { get; init; }
/// <summary>
/// Gets or sets a value indicating whether the /xldev menu is open.
/// </summary>
@ -117,7 +120,7 @@ namespace Dalamud.Interface.Internal
{
Service<InterfaceManager>.Get().Draw -= this.OnDraw;
this.windowSystem.RemoveAllWindows();
this.WindowSystem.RemoveAllWindows();
this.creditsWindow.Dispose();
this.consoleWindow.Dispose();
@ -309,7 +312,7 @@ namespace Dalamud.Interface.Internal
if (Service<GameGui>.Get().GameUiHidden)
return;
this.windowSystem.Draw();
this.WindowSystem.Draw();
if (this.isImGuiDrawDemoWindow)
ImGui.ShowDemoWindow();

View file

@ -57,6 +57,8 @@ namespace Dalamud.Interface.Internal.Windows
this.Size = new Vector2(500, 400);
this.SizeCondition = ImGuiCond.FirstUseEver;
this.RespectCloseHotkey = false;
}
private List<LogEntry> LogEntries => this.isFiltered ? this.filteredLogText : this.logText;

View file

@ -49,7 +49,7 @@ namespace Dalamud.Interface.Windowing
public bool IsFocused { get; private set; }
/// <summary>
/// Allow this window to be closed with a hotkey, like Escape, and keep game addons open in turn if it is closed.
/// Gets or sets a value indicating whether this window is to be closed with a hotkey, like Escape, and keep game addons open in turn if it is closed.
/// </summary>
public bool RespectCloseHotkey { get; set; } = true;
@ -112,6 +112,9 @@ namespace Dalamud.Interface.Windowing
set
{
this.internalIsOpen = value;
if (value == false)
this.IsFocused = false;
}
}

View file

@ -22,6 +22,12 @@ namespace Dalamud.Interface.Windowing
this.Namespace = imNamespace;
}
/// <summary>
/// Gets a value indicating whether any window in this <see cref="WindowSystem"/> has focus and is
/// not marked to be excluded from consideration.
/// </summary>
public bool HasAnyFocus { get; private set; }
/// <summary>
/// Gets or sets the name/ID-space of this <see cref="WindowSystem"/>.
/// </summary>
@ -75,6 +81,8 @@ namespace Dalamud.Interface.Windowing
window.DrawInternal();
}
this.HasAnyFocus = this.windows.Any(x => x.IsFocused && x.RespectCloseHotkey);
if (hasNamespace)
ImGui.PopID();
}