From 0f90722c1a845d962ec6e8964c930f5475642f15 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Thu, 30 Jul 2026 16:25:34 -0700 Subject: [PATCH] Arm the object launcher by opening its window. The launch key binding was gated behind a checkbox because it stayed active with the plugin window closed. Condition it on the window being open instead: the arming state is visible, so the checkbox is redundant and the press-proof chord can relax to plain Enter. Text fields and dialogs are unaffected: plugin chords are not checked while ImGui captures the keyboard, and built-in shortcuts dispatch first. PiperOrigin-RevId: 956796864 Change-Id: I4e5b2bdcaafbcc1b1ba113dd37ef8314b3ade49e --- .../platform/ux/object_launcher_plugin.cc | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/experimental/platform/ux/object_launcher_plugin.cc b/src/experimental/platform/ux/object_launcher_plugin.cc index b012e957..a19ce75a 100644 --- a/src/experimental/platform/ux/object_launcher_plugin.cc +++ b/src/experimental/platform/ux/object_launcher_plugin.cc @@ -13,6 +13,7 @@ // limitations under the License. #include +#include #include #include #include @@ -24,6 +25,8 @@ namespace mujoco::studio { +inline constexpr char kObjectLauncherName[] = "ObjectLauncher"; + class ObjectLauncher { public: ObjectLauncher() : rng_(std::random_device{}()) {} @@ -31,7 +34,6 @@ class ObjectLauncher { void UpdateGui() { using platform::ImGui_Input; - ImGui::Checkbox("Enable Key Binding (Ctrl+Shift+Enter)", &enabled_); ImGui_Input("Size", &size_, {0.01f, 1.0f, 0.01, 0.1}); ImGui_Input("Speed", &speed_, {0.01f, 100.0f, 0.1, 1.0}); ImGui_Input("Mass", &mass_, {0.01f, 100.0f, 0.01, 0.1}); @@ -42,7 +44,7 @@ class ObjectLauncher { ImGui::Combo("Shape", &shape, names, 2); type_ = shape == 0 ? mjGEOM_BOX : mjGEOM_SPHERE; - if (ImGui::Button("Launch", ImVec2(-1.0f, 0.0f))) { + if (ImGui::Button("Launch (Enter)", ImVec2(-1.0f, 0.0f))) { active_ = true; } @@ -54,7 +56,12 @@ class ObjectLauncher { } void HandleKeyboardEvent() { - if (enabled_) active_ = true; + // The key binding is armed only while the plugin window is open. + platform::ForEachPlugin([this](auto* gui) { + if (gui->active && !std::strcmp(gui->name, kObjectLauncherName)) { + active_ = true; + } + }); } bool UpdateSpecPreCompile(mjSpec* spec, const mjModel* model, @@ -162,7 +169,6 @@ class ObjectLauncher { std::mt19937 rng_; int counter_ = 0; - bool enabled_ = false; bool active_ = false; mjtNum size_ = 0.13365; mjtNum speed_ = 10.0; @@ -182,7 +188,7 @@ mjPLUGIN_LIB_INIT(object_launcher) { mujoco::platform::GuiPlugin gui; gui.data = &plugin; - gui.name = "ObjectLauncher"; + gui.name = mujoco::studio::kObjectLauncherName; gui.update = [](mujoco::platform::GuiPlugin* self) { auto* plugin = static_cast(self->data); plugin->UpdateGui(); @@ -191,8 +197,8 @@ mjPLUGIN_LIB_INIT(object_launcher) { mujoco::platform::KeyHandlerPlugin key_handler; key_handler.data = &plugin; - key_handler.name = "ObjectLauncher"; - key_handler.key_chord = ImGuiKey_Enter | ImGuiMod_Ctrl | ImGuiMod_Shift; + key_handler.name = mujoco::studio::kObjectLauncherName; + key_handler.key_chord = ImGuiKey_Enter; key_handler.on_key_pressed = [](mujoco::platform::KeyHandlerPlugin* self) { auto* plugin = static_cast(self->data); plugin->HandleKeyboardEvent(); @@ -201,7 +207,7 @@ mjPLUGIN_LIB_INIT(object_launcher) { mujoco::platform::SpecEditorPlugin spec_editor; spec_editor.data = &plugin; - spec_editor.name = "ObjectLauncher"; + spec_editor.name = mujoco::studio::kObjectLauncherName; spec_editor.pre_compile = [](mujoco::platform::SpecEditorPlugin* self, mjSpec* spec, const mjModel* model, const mjData* data, const mjvCamera* camera) {