Fix context menu suppression

Restore addon alpha after suppression so normal right-click menus work. Bump version to 1.0.1.
This commit is contained in:
2026-01-25 18:35:58 -05:00
parent 3565bcd7f9
commit 54ff9a0c2b
4 changed files with 50 additions and 15 deletions
+45 -13
View File
@@ -153,8 +153,17 @@ public sealed unsafe class Plugin : IDalamudPlugin
private const string InputNumericAddonName = "InputNumeric"; private const string InputNumericAddonName = "InputNumeric";
private const string ContextMenuAddonName = "ContextMenu"; private const string ContextMenuAddonName = "ContextMenu";
private bool suppressContextMenu; // IMPORTANT:
private bool suppressInputNumeric; // We suppress by forcing alpha to 0 in PreDraw, which can "stick" because the same addon instance is reused.
// Therefore we track suppression windows and also restore alpha when not suppressing.
private long suppressContextMenuUntilMs;
private long suppressInputNumericUntilMs;
private void ArmSuppressContextMenu(long now, int durationMs = 250)
=> suppressContextMenuUntilMs = Math.Max(suppressContextMenuUntilMs, now + durationMs);
private void ArmSuppressInputNumeric(long now, int durationMs = 1500)
=> suppressInputNumericUntilMs = Math.Max(suppressInputNumericUntilMs, now + durationMs);
private FFXIVClientStructs.FFXIV.Client.Game.InventoryType[] GetCompanyChestInventoryTypes() private FFXIVClientStructs.FFXIV.Client.Game.InventoryType[] GetCompanyChestInventoryTypes()
{ {
@@ -376,7 +385,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
{ {
if (TryGetVisibleAddon(InputNumericAddonName, out var inputNumeric)) if (TryGetVisibleAddon(InputNumericAddonName, out var inputNumeric))
{ {
suppressInputNumeric = true; ArmSuppressInputNumeric(now);
// Phase 1: set max (and wait a frame so the component commits the value internally). // Phase 1: set max (and wait a frame so the component commits the value internally).
if (!pendingCompanyChestNumericValueSet) if (!pendingCompanyChestNumericValueSet)
{ {
@@ -386,6 +395,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingCompanyChestNumericConfirmUntilMs = 0; pendingCompanyChestNumericConfirmUntilMs = 0;
pendingCompanyChestNumericArmed = false; pendingCompanyChestNumericArmed = false;
pendingNumericKind = PendingNumericKind.None; pendingNumericKind = PendingNumericKind.None;
suppressInputNumericUntilMs = 0;
} }
else else
{ {
@@ -432,7 +442,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingCompanyChestNumericValueSet = false; pendingCompanyChestNumericValueSet = false;
pendingCompanyChestNumericValueSetAtMs = 0; pendingCompanyChestNumericValueSetAtMs = 0;
pendingCompanyChestNumericDesired = 0; pendingCompanyChestNumericDesired = 0;
suppressInputNumeric = false; suppressInputNumericUntilMs = 0;
} }
else else
{ {
@@ -442,7 +452,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingCompanyChestNumericValueSet = false; pendingCompanyChestNumericValueSet = false;
pendingCompanyChestNumericValueSetAtMs = 0; pendingCompanyChestNumericValueSetAtMs = 0;
pendingCompanyChestNumericDesired = 0; pendingCompanyChestNumericDesired = 0;
suppressInputNumeric = false; suppressInputNumericUntilMs = 0;
} }
} }
catch (Exception ex) catch (Exception ex)
@@ -453,7 +463,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingCompanyChestNumericValueSet = false; pendingCompanyChestNumericValueSet = false;
pendingCompanyChestNumericValueSetAtMs = 0; pendingCompanyChestNumericValueSetAtMs = 0;
pendingCompanyChestNumericDesired = 0; pendingCompanyChestNumericDesired = 0;
suppressInputNumeric = false; suppressInputNumericUntilMs = 0;
Log.Warning(ex, "[QuickTransfer] Failed to auto-confirm InputNumeric."); Log.Warning(ex, "[QuickTransfer] Failed to auto-confirm InputNumeric.");
} }
} }
@@ -466,7 +476,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingCompanyChestNumericValueSet = false; pendingCompanyChestNumericValueSet = false;
pendingCompanyChestNumericValueSetAtMs = 0; pendingCompanyChestNumericValueSetAtMs = 0;
pendingCompanyChestNumericDesired = 0; pendingCompanyChestNumericDesired = 0;
suppressInputNumeric = false; suppressInputNumericUntilMs = 0;
} }
// If we have a pending "move outValue" buffer for InputNumeric-driven moves, free it once the dialog is gone, // If we have a pending "move outValue" buffer for InputNumeric-driven moves, free it once the dialog is gone,
@@ -526,7 +536,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingDefault.Value.AddonName.Equals(FreeCompanyChestAddonName, StringComparison.OrdinalIgnoreCase) && pendingDefault.Value.AddonName.Equals(FreeCompanyChestAddonName, StringComparison.OrdinalIgnoreCase) &&
Configuration.EnableCompanyChest) Configuration.EnableCompanyChest)
{ {
suppressContextMenu = true; ArmSuppressContextMenu(now, 1500);
if (TrySelectRemoveFromCompanyChestContextMenu()) if (TrySelectRemoveFromCompanyChestContextMenu())
{ {
lastActionTickMs = now; lastActionTickMs = now;
@@ -537,6 +547,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingCompanyChestNumericValueSet = false; pendingCompanyChestNumericValueSet = false;
pendingCompanyChestNumericValueSetAtMs = 0; pendingCompanyChestNumericValueSetAtMs = 0;
pendingCompanyChestNumericDesired = 0; pendingCompanyChestNumericDesired = 0;
ArmSuppressInputNumeric(now, 1500);
} }
// Keep suppression on while the remove dialog is being handled. // Keep suppression on while the remove dialog is being handled.
} }
@@ -564,7 +575,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
if (TryAutoSelectAndClose(agent, addon, pending.Value.Mode, out var chosenText, out var chosenIndex)) if (TryAutoSelectAndClose(agent, addon, pending.Value.Mode, out var chosenText, out var chosenIndex))
{ {
lastActionTickMs = now; lastActionTickMs = now;
suppressContextMenu = true; ArmSuppressContextMenu(now, 1500);
if (Configuration.EnableCompanyChest && if (Configuration.EnableCompanyChest &&
pending.Value.Mode == ModifierMode.Shift && pending.Value.Mode == ModifierMode.Shift &&
chosenText.Length > 0 && chosenText.Length > 0 &&
@@ -577,6 +588,7 @@ public sealed unsafe class Plugin : IDalamudPlugin
pendingCompanyChestNumericValueSet = false; pendingCompanyChestNumericValueSet = false;
pendingCompanyChestNumericValueSetAtMs = 0; pendingCompanyChestNumericValueSetAtMs = 0;
pendingCompanyChestNumericDesired = 0; pendingCompanyChestNumericDesired = 0;
ArmSuppressInputNumeric(now, 1500);
} }
if (Configuration.DebugMode) if (Configuration.DebugMode)
Log.Information($"[QuickTransfer] ({pending.Value.Mode} + RClick) Selected context action '{chosenText}' (idx={chosenIndex}) via deferred OnMenuOpened."); Log.Information($"[QuickTransfer] ({pending.Value.Mode} + RClick) Selected context action '{chosenText}' (idx={chosenIndex}) via deferred OnMenuOpened.");
@@ -598,17 +610,24 @@ public sealed unsafe class Plugin : IDalamudPlugin
try try
{ {
var name = args.AddonName ?? string.Empty; var name = args.AddonName ?? string.Empty;
var now = Environment.TickCount64;
if (suppressContextMenu && string.Equals(name, ContextMenuAddonName, StringComparison.OrdinalIgnoreCase)) if (string.Equals(name, ContextMenuAddonName, StringComparison.OrdinalIgnoreCase))
{ {
var addon = (AtkUnitBase*)args.Addon.Address; var addon = (AtkUnitBase*)args.Addon.Address;
MakeAddonInvisible(addon); if (now <= suppressContextMenuUntilMs)
MakeAddonInvisible(addon);
else
MakeAddonVisible(addon);
} }
if (suppressInputNumeric && string.Equals(name, InputNumericAddonName, StringComparison.OrdinalIgnoreCase)) if (string.Equals(name, InputNumericAddonName, StringComparison.OrdinalIgnoreCase))
{ {
var addon = (AtkUnitBase*)args.Addon.Address; var addon = (AtkUnitBase*)args.Addon.Address;
MakeAddonInvisible(addon); if (now <= suppressInputNumericUntilMs)
MakeAddonInvisible(addon);
else
MakeAddonVisible(addon);
} }
} }
catch catch
@@ -630,6 +649,19 @@ public sealed unsafe class Plugin : IDalamudPlugin
root->Alpha_2 = 0; root->Alpha_2 = 0;
} }
private static void MakeAddonVisible(AtkUnitBase* addon)
{
if (addon == null)
return;
var root = addon->RootNode;
if (root == null)
return;
// Restore fully visible alpha; this prevents "stuck invisible" menus after a suppression frame.
root->Color.A = 255;
root->Alpha_2 = 255;
}
private void OnInputNumericPreSetup(AddonEvent type, AddonArgs args) private void OnInputNumericPreSetup(AddonEvent type, AddonArgs args)
{ {
try try
+3
View File
@@ -8,6 +8,9 @@
<RootNamespace>QuickTransfer</RootNamespace> <RootNamespace>QuickTransfer</RootNamespace>
<OutputType>Library</OutputType> <OutputType>Library</OutputType>
<IsPackable>false</IsPackable> <IsPackable>false</IsPackable>
<Version>1.0.1</Version>
<AssemblyVersion>1.0.1.0</AssemblyVersion>
<FileVersion>1.0.1.0</FileVersion>
</PropertyGroup> </PropertyGroup>
<!-- Local builds: some setups have DALAMUD_HOME pointing at the XIVLauncher root, <!-- Local builds: some setups have DALAMUD_HOME pointing at the XIVLauncher root,
+1 -1
View File
@@ -2,7 +2,7 @@
"Author": "flick", "Author": "flick",
"Name": "QuickTransfer", "Name": "QuickTransfer",
"InternalName": "QuickTransfer", "InternalName": "QuickTransfer",
"AssemblyVersion": "1.0.0.0", "AssemblyVersion": "1.0.1.0",
"Description": "Automate inventory transfers with Shift/Ctrl + Right-Click.", "Description": "Automate inventory transfers with Shift/Ctrl + Right-Click.",
"ApplicableVersion": "any", "ApplicableVersion": "any",
"RepoUrl": "https://github.com/Knack117/QuickTransfer", "RepoUrl": "https://github.com/Knack117/QuickTransfer",
+1 -1
View File
@@ -3,7 +3,7 @@
"Author": "flick", "Author": "flick",
"Name": "QuickTransfer", "Name": "QuickTransfer",
"InternalName": "QuickTransfer", "InternalName": "QuickTransfer",
"AssemblyVersion": "1.0.0.0", "AssemblyVersion": "1.0.1.0",
"Description": "Automate inventory transfers with Shift/Ctrl + Right-Click.", "Description": "Automate inventory transfers with Shift/Ctrl + Right-Click.",
"ApplicableVersion": "any", "ApplicableVersion": "any",
"RepoUrl": "https://github.com/Knack117/QuickTransfer", "RepoUrl": "https://github.com/Knack117/QuickTransfer",