Injection panel UX: reachable auto re-attach + explain disabled controls
- The "Auto re-attach this game on relaunch" checkbox (and the Vulkan-layer checkbox) lived inside the connected-only block, so after a disconnect the control vanished while auto_reattach_ could stay enabled -- an active, invisible flag. Move both to render whenever a target is selected, connected or not, so they can be set up pre-launch and toggled off after disconnect. - Explain why controls are greyed out: an inline hint under the subsystem toggles when no live game is connected, and a hover tooltip (AllowWhenDisabled) on the disabled "Inject & Connect" button telling the operator to pick a target. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -561,6 +561,10 @@ void InjectionPanel::draw_hook_status(bool debug_details)
|
||||
ImGui::BeginDisabled(target_state_ != TargetState::Alive);
|
||||
draw_subsystem_controls(status);
|
||||
ImGui::EndDisabled();
|
||||
if (target_state_ != TargetState::Alive)
|
||||
{
|
||||
ImGui::TextDisabled("(connect to a live game to change these)"); // why the toggles are locked
|
||||
}
|
||||
ImGui::TextDisabled("Controller poll rates are in the Controllers panel.");
|
||||
|
||||
draw_hook_list(status);
|
||||
@@ -636,40 +640,41 @@ void InjectionPanel::draw(bool debug_details)
|
||||
ImGui::SameLine();
|
||||
ImGui::TextDisabled("(relaunched %s)", narrow(selected_name_).c_str());
|
||||
}
|
||||
// Session-only auto re-attach: tick it (while attached or terminated), then kill +
|
||||
// relaunch the game and it re-injects itself early -- the kill+relaunch fix for a
|
||||
// wrong audio format, without picking a target again.
|
||||
if (!selected_name_.empty())
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
// Session options for the selected game, shown whether or not we're connected -- so they can be set
|
||||
// up before launching the game, and an enabled auto re-attach is never hidden after a disconnect.
|
||||
if (!selected_name_.empty())
|
||||
{
|
||||
// Session-only auto re-attach: tick it, then kill + relaunch the game and it re-injects itself
|
||||
// early -- the kill+relaunch fix for a wrong audio format, without picking a target again.
|
||||
ImGui::Checkbox("Auto re-attach this game on relaunch", &auto_reattach_);
|
||||
if (auto_reattach_ && target_state_ == TargetState::Terminated)
|
||||
{
|
||||
ImGui::Checkbox("Auto re-attach this game on relaunch", &auto_reattach_);
|
||||
if (auto_reattach_ && target_state_ == TargetState::Terminated)
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(kGrey, "(watching for %s...)", narrow(selected_name_).c_str());
|
||||
}
|
||||
// Opt-in Vulkan capture layer: for Vulkan games that initialize Vulkan immediately (where even
|
||||
// auto-attach injects too late -- see the red banner), register a per-user implicit layer scoped
|
||||
// to this game so the next launch is captured from the first frame. Removed when unticked / exit.
|
||||
if (ImGui::Checkbox("Set up Vulkan layer (for immediate-init Vulkan games)", &vk_layer_enabled_))
|
||||
{
|
||||
if (vk_layer_enabled_)
|
||||
{
|
||||
ImGui::SameLine();
|
||||
ImGui::TextColored(kGrey, "(watching for %s...)", narrow(selected_name_).c_str());
|
||||
vk_layer_enabled_ = register_vk_layer(selected_name_);
|
||||
}
|
||||
// Opt-in Vulkan capture layer: for Vulkan games that initialize Vulkan immediately
|
||||
// (where even auto-attach injects too late -- see the red banner), register a per-user
|
||||
// implicit layer scoped to this game so the next launch is captured from the first frame.
|
||||
// Removed when unticked or the host exits.
|
||||
if (ImGui::Checkbox("Set up Vulkan layer (for immediate-init Vulkan games)", &vk_layer_enabled_))
|
||||
else
|
||||
{
|
||||
if (vk_layer_enabled_)
|
||||
{
|
||||
vk_layer_enabled_ = register_vk_layer(selected_name_);
|
||||
}
|
||||
else
|
||||
{
|
||||
unregister_vk_layer();
|
||||
}
|
||||
}
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Registers a per-user (HKCU, no admin) implicit Vulkan layer scoped to\n"
|
||||
"this game, so a relaunch is captured before Vulkan init. Pair with\n"
|
||||
"Auto re-attach. Removed when you untick it or close the tool.");
|
||||
unregister_vk_layer();
|
||||
}
|
||||
}
|
||||
ImGui::Separator();
|
||||
if (ImGui::IsItemHovered())
|
||||
{
|
||||
ImGui::SetTooltip("Registers a per-user (HKCU, no admin) implicit Vulkan layer scoped to\n"
|
||||
"this game, so a relaunch is captured before Vulkan init. Pair with\n"
|
||||
"Auto re-attach. Removed when you untick it or close the tool.");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::TextUnformatted("Target window");
|
||||
@@ -737,6 +742,12 @@ void InjectionPanel::draw(bool debug_details)
|
||||
inject_selected();
|
||||
}
|
||||
ImGui::EndDisabled();
|
||||
// Explain the disabled state on hover (AllowWhenDisabled, since the button is greyed out).
|
||||
if (!can_inject && ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenDisabled))
|
||||
{
|
||||
ImGui::SetTooltip("Pick a target window or process above first.\n"
|
||||
"If the game already has the DLL (e.g. after a reconnect), this reuses it.");
|
||||
}
|
||||
|
||||
if (!status_.empty())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user