Git Product home page Git Product logo

Comments (16)

ocornut avatar ocornut commented on June 26, 2024 1

I am going to investigate this.

Please note that I have just started making some of this public API, and before doing so I have pushed various breaking changes:

  • b4f564c Renamed ImGuiInputFlags_RouteGlobalLow -> ImGuiInputFlags_RouteGlobal, ImGuiInputFlags_RouteGlobal -> ImGuiInputFlags_RouteGlobalOverFocused, ImGuiInputFlags_RouteGlobalHigh -> ImGuiInputFlags_RouteGlobalHighest
  • 55748cd Renamed ImGuiKeyOwner_None to ImGuiKeyOwner_NoOwner.
  • 900b290 Swapped two last default parameters of Shortcut().
  • 85513de Swapped two last default parameters for owner-aware versions of IsKeyPressed(), IsKeyChordPressed(), IsMouseClicked().

from imgui.

nikitablack avatar nikitablack commented on June 26, 2024 1

I have a list of global actions to perform - a dozen of tasks bound to different single letter keys (I'm porting a legacy app to imgui, the functionality should stay the same). Obviously, I don't want to fire any of the actions when typing in the text input. Also, some windows should intercept single key presses and use them on their own, like 3D navigation with WASD.

The solution you posted kinda work, but requires to abbreviate all occurrences of InputText with all existing shortcuts, which is annoying and will break in the future when new global shortcuts will be introduced. Also, some windows I'm planning to make as plugins, i.e. give the possibility to users bring functionality which does not present in the base application. Obviously, they don't know which keys are bound to global actions.

from imgui.

ocornut avatar ocornut commented on June 26, 2024 1

Ah indeed the mixed key<>char filtering without mods should have been applied for global routes as well, my mistake: 7832e6a

I'm writing new sets of tests right now.

from imgui.

ocornut avatar ocornut commented on June 26, 2024 1

I have amended the inputs_routing_char_filter test to include global route:
ocornut/imgui_test_engine@dffee6a
inputs_routing_char_filter

When you have time could you update to latest and make sure everything works as expected?

Thanks for your help and feedback!

from imgui.

ocornut avatar ocornut commented on June 26, 2024

ImGui::Shortcut(ImGuiKey_M, ImGui::GetID("##Address"), ImGuiInputFlags_RouteFocused);
While preventing to fire a global shortcut during text input usage, it also intercepts the shortcut when the text not in focus, but > the window where this text is a child is in focus. In other words, the line ImGui::SetShortcutRouting(ImGuiKey_M, ImGui::GetID("##Address"), ImGuiInputFlags_RouteFocused) returns true even when the text input not focused, but the parent window is.

I realize it may be confusing but this is correct as you are using the ImGuiInputFlags_RouteFocused route.
If you passed an arbitrary id (not associated to an item) it would still allow registering itself into focus route.

I believe you would want to do:

if (ImGui::IsItemActive() && ImGui::Shortcut(ImGuiKey_M, ImGuiInputFlags_RouteFocused, ImGui::GetItemID()))
...

Which is effectively essentially what widget code are doing themselves.

But I realize it could make sense to add a helper ImGuiInputFlags_RouteActivated to shorten this?

from imgui.

ocornut avatar ocornut commented on June 26, 2024

I added ImGuiInputFlags_RouteActiveItem to do this check:

if (ImGui::Shortcut(ImGuiKey_M, ImGuiInputFlags_RouteGlobal))
    IMGUI_DEBUG_LOG("Global\n");
....
static char buf[32];
ImGui::InputText("##Address", buf, 32);
if (ImGui::Shortcut(ImGuiKey_M, ImGuiInputFlags_RouteActiveItem, ImGui::GetItemID()))
    IMGUI_DEBUG_LOG("InputText shortcut\n");

from imgui.

nikitablack avatar nikitablack commented on June 26, 2024

I believe the changes you posted will not help me. Here's the minimal reproducible example of my problem:

if (ImGui::Shortcut(ImGuiKey_M, 0, ImGuiInputFlags_RouteGlobalLow)) {
    logger::Logger::log("Global M");
}

ImGui::Begin("AAA");
static char str[256];
ImGui::InputText("ABC", str, 256);
ImGui::Shortcut(ImGuiKey_M, ImGui::GetItemID(), ImGuiInputFlags_RouteFocused);
ImGui::End();

Here, the Global M only printed when the window AAA is not in focus, which is not what I want. If I change the global shortcut from ImGuiInputFlags_RouteGlobalLow to ImGuiInputFlags_RouteGlobal, as you suggested, then adding the second window breaks the flow:

if (ImGui::Shortcut(ImGuiKey_M, 0, ImGuiInputFlags_RouteGlobal)) {
    logger::Logger::log("Global M");
}

ImGui::Begin("AAA");
static char str[256];
ImGui::InputText("ABC", str, 256);
ImGui::Shortcut(ImGuiKey_M, ImGui::GetItemID(), ImGuiInputFlags_RouteFocused);
ImGui::End();

ImGui::Begin("BBB");
if (ImGui::Shortcut(ImGuiKey_M, 0, ImGuiInputFlags_RouteFocused)) {
    logger::Logger::log("BBB M");
}
ImGui::End();

In this case:

  • the Global M is not printed when the text input is active, which is good
  • the Global M is printed when the AAA is in focus, but the text input not, which is good
  • the Global M is printed when the BBB is in focus, which is bad, since I'm expecting BBB M to be printed.

The last point happens because Global > Focused (when focused window).

from imgui.

ocornut avatar ocornut commented on June 26, 2024

If I change the global shortcut from ImGuiInputFlags_RouteGlobalLow to ImGuiInputFlags_RouteGlobal, as you suggested,

I didn't, it is because last week ImGuiInputFlags_RouteGlobalLow got renamed to ImGuiInputFlags_RouteGlobal as pointed in my earlier post. So you ImGuiInputFlags_RouteGlobalLow is currently ImGuiInputFlags_RouteGlobal.
That's where the main confusion is.

My point is this is incorrect (or at least not what you actually want):

ImGui::InputText(...);
ImGui::Shortcut(ImGuiKey_M, ImGui::GetItemID(), ImGuiInputFlags_RouteFocused);

This in latest works as expected:

if (ImGui::Shortcut(ImGuiKey_M, ImGuiInputFlags_RouteGlobal))
    IMGUI_DEBUG_LOG("Global\n");

ImGui::Begin("AAA");
static char buf[32];
ImGui::InputText("##Address", buf, 32);
if (ImGui::Shortcut(ImGuiKey_M, ImGuiInputFlags_RouteActive, ImGui::GetItemID()))
    IMGUI_DEBUG_LOG("AAA\n");
ImGui::End();

ImGui::Begin("BBB");
if (ImGui::Shortcut(ImGuiKey_M))
    IMGUI_DEBUG_LOG("BBB\n");
ImGui::End();

from imgui.

ocornut avatar ocornut commented on June 26, 2024

And in your older version, instead of:

if (ImGui::Shortcut(ImGuiKey_M, ImGuiInputFlags_RouteGlobal))
    IMGUI_DEBUG_LOG("Global\n");

You can write:

if (ImGui::Shortcut(ImGuiKey_M, 0, ImGuiInputFlags_RouteGlobalLow))
    IMGUI_DEBUG_LOG("Global\n");

And instead of:

if (ImGui::Shortcut(ImGuiKey_M, ImGuiInputFlags_RouteActive, ImGui::GetItemID()))
    IMGUI_DEBUG_LOG("AAA\n");

You can write:

if (ImGui::IsItemActive() && ImGui::Shortcut(ImGuiKey_M, ImGui::GetItemID(), ImGuiInputFlags_RouteFocused))
    IMGUI_DEBUG_LOG("AAA\n");

For the same effect.

from imgui.

nikitablack avatar nikitablack commented on June 26, 2024

Thank you, @ocornut. Your suggested code works. The new changes (ImGuiInputFlags_RouteActive) are much better, than

if (ImGui::IsItemActive()){
    ImGui::Shortcut(ImGuiKey_M, ImGui::GetItemID(), ImGuiInputFlags_RouteFocused)
}

but still looks strange - after all, when using an InputText it is implied that I don't want any shorcuts to fire (except for the widget itself, of course).

from imgui.

ocornut avatar ocornut commented on June 26, 2024

but still looks strange - after all, when using an InputText it is implied that I don't want any shorcuts to fire (except for the widget itself, of course).

Not exactly: people want other shortcuts such as Ctrl+S to work.

But here.... just realized there is bug, it shouldn't do it with M only, because key emitting characters should normally automatically be filtered out by the active InputText(), something here got broken.

from imgui.

ocornut avatar ocornut commented on June 26, 2024

Actually I think this debatable, here by passing GetItemID() you are pretending to be the InputText(), you can receive the shortcut. Things normally work because InputText() doesn't use keys that would typically emit characters.

Can you clarify what you actual use case is, with this M shortcut you want to activate when InputText() is active?

from imgui.

ocornut avatar ocornut commented on June 26, 2024

The culling logic for keys that maps to characters only apply if you are NOT the active item:

// Specific culling when there's an active item.
if (g.ActiveId != 0 && g.ActiveId != owner_id)
{
    // Cull shortcuts with no modifiers when it could generate a character.
    // e.g. Shortcut(ImGuiKey_G) also generates 'g' character, should not trigger when InputText() is active.
    // but  Shortcut(Ctrl+G) should generally trigger when InputText() is active.
    // TL;DR: lettered shortcut with no mods or with only Alt mod will not trigger while an item reading text input is active.
    // (We cannot filter based on io.InputQueueCharacters[] contents because of trickling and key<>chars submission order are undefined)
    if ((flags & ImGuiInputFlags_RouteFocused) && g.IO.WantTextInput && IsKeyChordPotentiallyCharInput(key_chord))
    {
        IMGUI_DEBUG_LOG_INPUTROUTING("SetShortcutRouting(%s, flags=%04X, owner_id=0x%08X) -> filtered as potential char input\n", GetKeyChordName(key_chord), flags, owner_id);
        return false;
    }

Which IMHO makes sense.

I think sensible answer and design can only come if I understand what you are trying to achieve in the first place with this M shortcut on an active InputText().

from imgui.

nikitablack avatar nikitablack commented on June 26, 2024

I updated to latest and everything works now - I don't need to Shortcut an InputText for a single-letter input. Also, with ImGuiInputFlags_RouteActive the code is more clearer. Thank you very much for your support and super fast responses.

from imgui.

ocornut avatar ocornut commented on June 26, 2024

I am curious however when/how you are using ImGuiInputFlags_RouteActive, because semantically it would make sense if you want to extend/add shortcut to the InputText(), and hopefully you don't need to use it as a workaround for another thing?

from imgui.

nikitablack avatar nikitablack commented on June 26, 2024

That's right, I tested it with Ctrl+S shortcut and an InputText(). Atm, I don't need it though, just tested.

from imgui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.