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

Hidden widgets (textbox, etc) still show carets & pressing tab key switches focus on invisible(hidden) widgets. #62

Closed
beru opened this issue Jun 11, 2015 · 13 comments

Comments

@beru
Copy link
Contributor

beru commented Jun 11, 2015

I think hidden widgets should not retain focus. If it has a focus, its focus should be lost.

@cnjinhao
Copy link
Owner

Hi, thank you for reporting this issue, a fix has been checked into the hotfix branch. Look forward to your feedback.

@beru
Copy link
Contributor Author

beru commented Jun 21, 2015

Hi Jinhao. I found a problem with the fix.

In
file : source/gui/detail/window_manager.cpp
method : window_manager::tabstop(core_window_t* wd, bool forward) const
If all the widgets are invisible, the while loop in the method never ends.

Please use below code to reproduce the problem.

#include <nana/gui.hpp>
#include <nana/gui/widgets/textbox.hpp>

using namespace nana;

#if 1
#include <Windows.h>
int WINAPI WinMain(
    HINSTANCE hInstance,      // 現在のインスタンスのハンドル
    HINSTANCE hPrevInstance,  // 以前のインスタンスのハンドル
    LPSTR lpCmdLine,          // コマンドライン
    int nCmdShow              // 表示状態
    )
#else
int main()
#endif
{
    using namespace nana;

    form fm(API::make_center(500, 300));
    fm.caption(L"tabstop test");

    textbox txt(fm, rectangle{50, 50, 100, 30});
    txt.multi_lines(false);
    txt.caption(L"aaaa");

    textbox txt2(fm, rectangle(50, 90, 200, 200));
    txt2.caption(L"aaaa\nbbbb\ncccc\n");

    API::eat_tabstop(txt, false);
    API::eat_tabstop(txt2, false);

    txt.hide();
    txt2.hide();

    fm.show();
    exec();
}

@beru
Copy link
Contributor Author

beru commented Jun 21, 2015

Here is a workaround for infinite loop in window_manager::tabstop method.

        window_manager::core_window_t* get_tabstop(window_manager::core_window_t* wd, bool forward)
        {
            auto & tabs = wd->root_widget->other.attribute.root->tabstop;
            if (tabs.size())
            {
                bool visible = false;
                for (auto& i : tabs) {
                    if (i->visible) {
                        visible = true;
                        break;
                    }
                }
                if (!visible) {
                    return nullptr;
                }

                if (forward)    //

@cnjinhao
Copy link
Owner

Thank you for your helpful feedback. I updated the fix.

@beru
Copy link
Contributor Author

beru commented Jun 25, 2015

Thank you for the fix.

Please check below program
Please press tab key several times, then press Alt + Tab keys to switch the window back and forth.

Parent widget hidden case.

#include <nana/gui.hpp>
#include <nana/gui/widgets/textbox.hpp>
#include <nana/gui/widgets/panel.hpp>

using namespace nana;

int main()
{
    using namespace nana;

    form fm(API::make_center(500, 300));
    fm.caption(L"tabstop test");

    panel<true> panel(fm, rectangle(fm.size()));

    textbox txt(panel, rectangle{50, 50, 100, 30});
    txt.multi_lines(false);
    txt.caption(L"aaaa");

    textbox txt2(panel, rectangle(50, 90, 200, 200));
    txt2.caption(L"aaaa\nbbbb\ncccc\n");

    API::eat_tabstop(txt, false);
    API::eat_tabstop(txt2, false);

    panel.hide();

    fm.show();
    exec();
}

@cnjinhao
Copy link
Owner

A new fix has been checked into hotfix branch.

@beru
Copy link
Contributor Author

beru commented Jun 27, 2015

Thank you for the fix.
I confirmed that hiding a panel that contains other widgets in a form works fine.

But some of hidden widgets still rendered after refocusing the window so unfortunately still not perfect.

Please run below program and test below procedures.

  1. Run a program.
  2. Press hide button in a form.
  3. Minimize and restore the window.
  4. Then there's the pressed button image displayed.
#include <nana/gui.hpp>
#include <nana/gui/widgets/textbox.hpp>
#include <nana/gui/widgets/panel.hpp>
#include <nana/gui/widgets/button.hpp>

using namespace nana;

int main()
{
    using namespace nana;

    form fm(API::make_center(500, 300));
    fm.caption(L"tabstop test");

    panel<true> panel(fm, rectangle(fm.size()));

    textbox txt(panel, rectangle{50, 50, 100, 30});
    txt.multi_lines(false);
    txt.caption(L"aaaa");

    textbox txt2(panel, rectangle(50, 90, 200, 200));
    txt2.caption(L"aaaa\nbbbb\ncccc\n");

    API::eat_tabstop(txt, false);
    API::eat_tabstop(txt2, false);

    button btn(panel, rectangle(300, 150, 100, 50));
    btn.caption("hide");
    btn.events().click([&](){
        panel.hide();
    });

    fm.show();
    exec();
}

Losing focus and regaining focus of the window causes the same result.
I guess somewhere in a drawing routine, visible state of a widget is overlooked or reused framebuffer still contains old image. But that is just my guessing without debugging efforts...

With following procedures, not only the button but also a textbox in the panel is still displayed though the panel was hidden.

  1. Run a program.
  2. Click a textbox in a form.
  3. Press tab key to change widget focus to the hide button.
    Stay mouse cursor on the textbox to keep it highlighted and press enter key to click the hide button. (Contrary to expectation, pressing space key does not fire click event.)
  4. Above step hides the panel and children widgets are also hidden.
  5. Double press Alt + Tab keys to lose and regain focus of the window.
  6. Image of the textbox and the button is rendered on the form.

The ghost image is ephemeral but still undesirable.

cnjinhao added a commit that referenced this issue Jul 4, 2015
@cnjinhao
Copy link
Owner

cnjinhao commented Jul 4, 2015

Hi, a fix has been checked into the hotfix branch, Thanks for your feedback

@beru
Copy link
Contributor Author

beru commented Jul 4, 2015

Hi, thank you for the fix. I confirmed that your recent fix has solved the ghost image problem.
But I've found two tiny problems.

One of the problems is though parent widget is hidden, pressing tab key switches widget focus into hidden textbox and its cares is displayed. To reproduce the issue, please test below.

  1. Click "hide panel" button
  2. The panel is invisible now.
  3. Repeat pressing tab key to switch widget focus.
  4. Textbox's caret appears on hidden textboxes. Pressing tab key should pass through hidden widgets including parent widget hidden case.

The other problem is buttons somehow stop responding enter key.
Clicking by mouse still works anyway. To reproduce the issue, please test following operations.

  1. Press tab key to switch widget focus into "hide panel" button and press enter key.
  2. The panel is hidden.
  3. Press tab key to switch focus into "show panel" button and press enter.
  4. The panel is visible now.
  5. Press tab key to switch widget focus into "hide panel" button again and press enter key.
  6. The panel is not hidden, still visible.
#include <nana/gui.hpp>
#include <nana/gui/widgets/textbox.hpp>
#include <nana/gui/widgets/panel.hpp>
#include <nana/gui/widgets/button.hpp>

using namespace nana;

int main()
{
    using namespace nana;

    form fm(API::make_center(500, 410));
    fm.caption(L"tabstop test");

    panel<true> panel(fm, rectangle(point(0,0), size(180,350)));
    color c;
    panel.bgcolor(c.from_rgb(0, 100, 0));

    textbox txt(panel, rectangle{50, 50, 100, 30});
    txt.multi_lines(false);
    txt.caption(L"aaaa");

    textbox txt2(panel, rectangle(50, 90, 100, 200));
    txt2.caption(L"aaaa\nbbbb\ncccc\n");

    button btn_hide_panel(fm, rectangle(200, 150, 100, 50));
    btn_hide_panel.caption("hide panel");
    btn_hide_panel.events().click([&](){
        panel.hide();
    });

    button btn_show_panel(fm, rectangle(200, 210, 100, 50));
    btn_show_panel.caption("show panel");
    btn_show_panel.events().click([&](){
        panel.show();
    });

    button btn_hide(fm, rectangle(310, 150, 100, 50));
    btn_hide.caption("hide");
    btn_hide.events().click([&](){
        txt.hide();
        txt2.hide();
    });

    button btn_show(fm, rectangle(310, 210, 100, 50));
    btn_show.caption("show");
    btn_show.events().click([&](){
        txt.show();
        txt2.show();
    });

    API::eat_tabstop(txt, false);
    API::eat_tabstop(txt2, false);
    API::eat_tabstop(btn_hide_panel, false);
    API::eat_tabstop(btn_show_panel, false);
    API::eat_tabstop(btn_hide, false);
    API::eat_tabstop(btn_show, false);

    fm.show();
    exec();
}

cnjinhao added a commit that referenced this issue Jul 5, 2015
pressing space on a button will trigger click event
@cnjinhao
Copy link
Owner

cnjinhao commented Jul 5, 2015

Any feedback is appreciated

@beru
Copy link
Contributor Author

beru commented Jul 5, 2015

Hi, thank you for the fix. I confirmed that two tiny problems I mentioned in my previous post are resolved now.

However, setting focus to hidden widget by API shows a caret.
I added below control to test it.

    button btn_txt_set_focus(fm, rectangle(310, 270, 100, 50));
    btn_txt_set_focus.caption("txt set focus");
    btn_txt_set_focus.events().click([&](){
        txt.focus();
    });

@cnjinhao
Copy link
Owner

cnjinhao commented Jul 5, 2015

Fix it again, wait for your test

@beru
Copy link
Contributor Author

beru commented Jul 6, 2015

Thank you for the fix. I see no more caret on hidden widget.
Albeit mouse dragging text selection still works on hidden widget, considering it is harmless, I surrender on behalf of not showing further clinginess.

@beru beru closed this as completed Jul 6, 2015
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