Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regain focus on canvas after dialog/popup closes #741

Closed
inflex opened this issue Jul 18, 2016 · 13 comments
Closed

Regain focus on canvas after dialog/popup closes #741

inflex opened this issue Jul 18, 2016 · 13 comments

Comments

@inflex
Copy link

inflex commented Jul 18, 2016

I have a situation where my main canvas/app loses mouse-focus after I open a dialog or menu selection and then close it, requiring me to click the main canvas for it to apply again (only has to be a click-down, the return/up isn't required). I'm using the mouse wheel to zoom in/out on the content and that doesn't work until I first click the mouse somewhere on the main canvas.

The keyboard inputs still work.

Is there something I can do to set the focus back to the canvas after I've done the ImGui::CloseCurrentPopup(); call?

@ocornut
Copy link
Owner

ocornut commented Jul 18, 2016

Hello,
I have just committed 19d02be
Which might fix your issue (unless using the BeginManuMenuBar, see #727)

Let me know if it does, otherwise please post a small repro or just the functions/flags you are using to get to this situation. How are you testing whether you apply the mouse wheel for zooming your canvas?

@inflex
Copy link
Author

inflex commented Jul 18, 2016

Here's the part that handles the scroll wheel -> zooming. You'll notice at the bottom that I've put in a debug dump fprintf(stderr,"x"); that just lets me know when the main canvas is focused or not, and that appears to be the crucial aspect - when the x's appear there's no scroll activity, and vice-versa.

This also happens immediately when the program is first loaded.

const ImGuiIO &io = ImGui::GetIO();
if (ImGui::IsWindowFocused()) {

    // Zoom:
    float mwheel = io.MouseWheel;
    if (mwheel != 0.0f) {
        mwheel *= 0.5f;

        // Ctrl slows down the zoom speed:
        if ( ImGui::IsKeyDown(KM(SDL_SCANCODE_LCTRL)) 
|| ImGui::IsKeyDown(KM(SDL_SCANCODE_RCTRL)) ) {
            mwheel *= 0.1f;
        }
        Zoom(io.MousePos.x, io.MousePos.y, mwheel);
    }
} else {
    fprintf(stderr,"x");
}

@ocornut
Copy link
Owner

ocornut commented Jul 18, 2016

Does it still happen with the fix just posted above?

@ocornut
Copy link
Owner

ocornut commented Jul 18, 2016

PS: for
if ( ImGui::IsKeyDown(KM(SDL_SCANCODE_LCTRL)) || ImGui::IsKeyDown(KM(SDL_SCANCODE_RCTRL)) )
You can use
if (io.KeyCtrl) as a convenience.

@inflex
Copy link
Author

inflex commented Jul 18, 2016

I'm thinking that maybe I haven't been able to pull the latest from the repo, unfortunately my git-fu is weak; best I can report is this -

WorkstationTT:~/development/OpenBoardView/src/imgui$ git status
HEAD detached at adb85d8

... which makes me think it's not actually using your latest updates ( and when I check the imgui.cpp code it doesn't even come close to matching, so I think I'll go sort that out first. Apologies for wasting your time.

@ocornut
Copy link
Owner

ocornut commented Jul 18, 2016

Git is a mystery to everyone it seems.. Yeah it looks like you are running an old version, and that fix is literally the last commit in the repo that I pushed this morning.

@inflex
Copy link
Author

inflex commented Jul 18, 2016

I'll check with a couple of the other participants as a couple of them are more imbued with git-fu than I am. I suspect the detached HEAD option might be something to do with avoiding a moving API target.

I'll report back later as soon as I have an answer. Thankyou.

@inflex
Copy link
Author

inflex commented Jul 18, 2016

Managed to update the submodule.

WorkstationTT:~/development/OpenBoardView$ git submodule
19d02be src/imgui (v1.49-40-g19d02be)

Recompiled, still the same behaviour, so I'm thinking there's a bug in my code.

I'll do some more digging around and see what I find and again, I'll report back 👍

@ocornut
Copy link
Owner

ocornut commented Jul 18, 2016

Thanks! Please build a simplified repro. There's possibly a bug in the code but it's hard to guess anything without seeing much of your code.

@inflex
Copy link
Author

inflex commented Jul 18, 2016

I added a bit of debugging code in my program and found essentially what the crux of the issue is;

   ImGuiContext& g = *GImGui;
   fprintf(stderr,"%s =? %s\n", g.CurrentWindow->Name, g.FocusedWindow->Name);

Which, when running, provides the following;

(when not 'focused') surface =? status

(when focused, and scroll zoom working) surface =? surface

For what ever reason, when my program starts up, and when the menu is selected or a dialog used, the focused window becomes "status", and when I click on the draw surface, it finally goes back to 'surface'.

So, I suppose my question is, how do I forcibly make ImGui give focus back to 'surface' when I close the popups or finish the menu handling?

@inflex
Copy link
Author

inflex commented Jul 18, 2016

I think I found the problem, if I comment out my status bar code, things magically work nice again :)

ImGuiWindowFlags flags =
        ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize |
        ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar |
        ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings;
    ImGuiWindowFlags draw_surface_flags = flags |
        ImGuiWindowFlags_NoFocusOnAppearing |
        ImGuiWindowFlags_NoBringToFrontOnFocus;
    ImGui::SetNextWindowPos(ImVec2{0, 0});
    const ImGuiIO &io = ImGui::GetIO();
    if (io.DisplaySize.x != m_lastWidth || io.DisplaySize.y != m_lastHeight) {
        m_lastWidth   = io.DisplaySize.x;
        m_lastHeight  = io.DisplaySize.y;
        m_needsRedraw = true;
    }
    ImGui::SetNextWindowSize(io.DisplaySize);
    ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
    ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.0f, 0.0f, 0.0f, 0.0f));
    if (m_firstFrame) {
        ImGui::SetNextWindowFocus();
        m_firstFrame = false;
    }
    ImGui::Begin("surface", nullptr, draw_surface_flags);
    HandleInput();
    DrawBoard();
    ImGui::End();
    ImGui::PopStyleColor();

    // Overlay
    RenderOverlay();

    // Status Footer
    float status_height = (10.0f + ImGui::GetFontSize());

    ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(4.0f, 3.0f));
    ImGui::SetNextWindowPos(ImVec2{0, io.DisplaySize.y - status_height});
    ImGui::SetNextWindowSize(ImVec2(io.DisplaySize.x, status_height));
    ImGui::Begin("status", nullptr, flags);
    if (m_file && m_board && m_pinSelected) {
        auto pin = m_pinSelected;
        ImGui::Text("Part: %s   Pin: %s   Net: %s   Probe: %d   (%s.)",
                pin->component->name.c_str(), pin->number.c_str(), pin->net->name.c_str(),
                pin->net->number, pin->component->mount_type_str().c_str());
    } else {
        ImVec2 spos = ImGui::GetMousePos();
        ImVec2 pos  = ScreenToCoord(spos.x, spos.y);
        if (showFPS == true) ImGui::Text("FPS: %0.0f Position: %0.3f\", %0.3f\" (%0.2f, %0.2fmm)", ImGui::GetIO().Framerate, pos.x/1000, pos.y/1000, pos.x *0.0254, pos.y *0.0254 );
        else ImGui::Text("Position: %0.3f\", %0.3f\" (%0.2f, %0.2fmm)", pos.x/1000, pos.y/1000, pos.x *0.0254, pos.y *0.0254 );
    }
    ImGui::End();
    ImGui::PopStyleVar();
    ImGui::PopStyleVar();

@ocornut
Copy link
Owner

ocornut commented Jul 18, 2016

So your Status bar window is taking the focus, but you still haven't provided a repro that shows all the related code, aka how is focus taken away from your surface in the first place (dialogs/menus), so it is hard to tell what's wrong. When possible also try to strip down your repro to the useful bits (aka remove the styling bits) and test it as a standalone piece of code.

When a window appears the first time is automatically takes focus, so that's unnecessary:

    if (m_firstFrame) {
        ImGui::SetNextWindowFocus();
        m_firstFrame = false;
    }

And the fact that you are passing ``ImGuiWindowFlags_NoFocusOnAppearing` to that same window requests the exact contrary here.

And conversely, the status bar will take focus on the first frame as well, unless you pass it the ImGuiWindowFlags_NoFocusOnAppearing flag so that is probably what you want.

@inflex
Copy link
Author

inflex commented Jul 18, 2016

Once again @ocornut , many thanks for you time. I have restructured things in the program and changed from IsWindowFocused() to ...IsWindowHovered() which now has resolved all my current issues.

Sorry I couldn't really provide a repro, as I'm not yet fully up to speed with how this program has been written I can't be sure where all the various attributes are being set (until I start reading more, which is usually when I learn where the fault(s) are).

@inflex inflex closed this as completed Jul 18, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants