peterbrittain / asciimatics

A cross platform package to do curses-like operations, plus higher level APIs and widgets to create text UIs and ASCII art animations
Apache License 2.0
3.61k stars 238 forks source link

Left Mouse Click on a Listbox in Another Layout Only Semi-Focuses the ListBox #339

Closed peterjschroeder closed 2 years ago

peterjschroeder commented 2 years ago

Describe the bug Left mouse click on a Listbox in another layout only semi-focuses the ListBox.

To Reproduce Create a Text widget in layout1, create a ListBox widget in layout2. The ListBox can be clicked with the mouse which doesn't actually focus it completely. Hitting up/down through the ListBox brings it fully into focus.

Also, using the down key to switch to the ListBox does bring it closer into focus, but the Text widget seems to still be in focus somewhat. This can be reproduced by setting a on_focus in the Text widget which for whatever reason is called when the down arrow is used.

Expected behavior Full focus on click

System details (please complete the following information):

peterbrittain commented 2 years ago

Found it! I think the latest build on master should fix your issue now.

peterjschroeder commented 2 years ago

Thank you. Now the left click is focusing correctly and not calling the on_focus from the Text widget. But for whatever reason using the down arrow in the Text widget is still causing on_focus to be called.

peterbrittain commented 2 years ago

Do you also have an on_blur callback? There are a few paths where it can call blur/focus/blur before it successfully moves the focus...

peterjschroeder commented 2 years ago

No. I only have an on_change and an on_focus. It already worked correctly switching focus with tab, and now with your fix it works correctly switching focus with the mouse, but switching focus with the down arrow key calls on_focus for the Text widget.

The ListBox I have updates when something is typed into the TextBox. I added an option to autoclear the TextBox on focus. My code is here. https://github.com/peterjschroeder/bukut

peterbrittain commented 2 years ago

This code is fragile owing to the interaction of Frame, Layout and Widget event processing. I currently use logic that maintains state as it attempts to move the focus (and so triggers callbacks as it progresses). It's possible I can catch some of these transitions, but maybe not all. I'll see what I can do...

In the meantime, the safest fix is to monitor blur events too. You would need to track this on all widgets to track the last blurred widget, then trigger your current on_focus logic only when the last blurred widget is a different widget. Far from ideal, I know, but it will get you going for now.

peterjschroeder commented 2 years ago

Thank You.

If I catch the down key in process_event and add self._list._has_focus = True everything works as expected. Is the down key even suppose to switch focus? Up doesn't if in the ListBox. Left and Right can't as it is used to move through the text.

peterbrittain commented 2 years ago

It's a little complicated... See the details in https://github.com/peterbrittain/asciimatics/issues/316.

In this case, up/down allow you to navigate through the list of options in the listbox and so it handles the events (which means that up will not move you back to the text widget). Similarly, left/right allow you to navigate the text in the Text widget (and so you can't move out of that widget with those keys).

peterjschroeder commented 2 years ago

After reading #316 , it does make sense that it does move layouts. Movement when possible is good design.

peterbrittain commented 2 years ago

Hopefully that covers all your cases now!

peterjschroeder commented 2 years ago

Turns out my temporarily fix didn't even work. But your permanent fix does. Thank you.

peterbrittain commented 2 years ago

NP. Glad I could help!