[SOLVED] Tab Traversal Woes

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

[SOLVED] Tab Traversal Woes

Post by dcbdbis »

Good Evening All,

CodeBlocks 17:12, wxSmith, wxWidgets 3.0.4, Manjaro x64.

I have redone a GUI for a project of mine twice - fighting the Tab Traversal issue. I do not use sizers, they are a pain in my backsides and are always getting in my way.

I used a panel, and even though Tab_Traversal is turned off - tab traversal still happens. Tab Traversal is unchecked in the Frame, Panel, and on each object on the GUI. The objects on the GUI (there are 20 of them, a variety of different widgets) all have the Tab_Traversal flags unset in them (those that have them).

Tab Traversal still happens.

I dumped the Panel and rebuilt the GUI again from scratch directly on the Frame without a panel....Same issue. Same steps to turn it off. Same failure to turn off tab traversal.

So then I got cute and tried to modify the tab order - only to find that there is no tab order available - so I can't define the tab order.

I came to this forum, and tried pretty much every post I found - except deriving my own class of objects....which defeats the whole point of a RAD environment.

I need:

a) To be able to reorder the tab traversal.

or

b) Or be able to turn it off in a predictable manner so I can write my own handlers to deal with the tab key.

or

c) Be told that this is an issue for which there is no resolution, so I stop beating my head against the doorpost and calling the cat bad names...:-)


Directions will be helpful.

Thank You!

Sincerely and respectfully,

Dave
Last edited by dcbdbis on Tue Jul 30, 2019 12:54 am, edited 1 time in total.
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Tab Traversal Woes

Post by doublemax »

You can change the tab order with wxWindow::MoveAfterInTabOrder / MoveBeforeInTabOrder
https://docs.wxwidgets.org/trunk/classw ... 11bdb6f2b6

I would have expected that not using a wxPanel disables the tab processing.

You could try to use wxEventFilter::FilterEvent() to filter out wxEVT_CHAR events (maybe also wxEVT_KEY_DOWN/UP) with the Tab key. This will get more complicated though if there are places where you actually need it (e.g. in a text field).

https://docs.wxwidgets.org/trunk/classw ... 6a2e3b2c6a
(wxApp derives from wxEventFilter, so you have have to implement the method in your wxApp class)
Use the source, Luke!
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

Re: Tab Traversal Woes

Post by dcbdbis »

Thank you @doublemax for your response. Yes, I had tried this as well before posting.

I tried to use the MoveAfter/BeforeInTab Order. I was getting a runtime error on both that complains that the object is not a window and it crashes.

The documentation states:
Moves this window in the tab navigation order after the specified win.
It doesn't reference an object - rather it talks about a window. I'm trying to move objects around in the tab order. So....I went against the documentation and passed references to my objects. Specifically I called:
ComboBox3->MoveBeforeInTabOrder(TextCtrl2);
...and it worked.

May I recommend that the documentation be clarified? It should probably use language that talks about objects - and not windows. When I did the above - I was able to change the tab order.

But on some of my Windows (Frames and Dialogs) - I will want the Tab_Traversal turned off.

It's a tad disconcerting that the various objects don't follow their respective settings with regard to wxTAB_TRAVERSAL, same thing for the panel.

I will try to intercept the tab key as you mentioned in the post, to shut it down completely - then I will report back my results before tagging this post as solved.

THANK YOU for your response.....

Dave
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

Re: Tab Traversal Woes

Post by dcbdbis »

I've tried some other things. All to no avail.

In the constructor I have done this:
ComboBox1 = new wxComboBox(this, ID_COMBOBOX1, wxEmptyString, wxPoint(210,80), wxSize(300,30), 0, 0, !wxTAB_TRAVERSAL, wxDefaultValidator, _T("ID_COMBOBOX1"));
I've also manually set this in the body of my code:
ComboBox2->SetWindowStyle(!wxTAB_TRAVERSAL);
All to no avail. I've also for a third time, rebuilt the GUI directly on the Frame. No Change in behavior.

It is my opinion that this may indeed be a bug somewhere along the inheritance chain of wxWidgets.

I will try to intercept the keyboard event - but as doublemax explains - I DO have text boxes where the user might want a tab in their text.

I'll report back after I attempt to intercept the keyboard events.


Dave
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: Tab Traversal Woes

Post by PB »

dcbdbis wrote: Mon Jul 29, 2019 3:39 pm I tried to use the MoveAfter/BeforeInTab Order. I was getting a runtime error on both that complains that the object is not a window and it crashes.

The documentation states:
Moves this window in the tab navigation order after the specified win.
It doesn't reference an object - rather it talks about a window. I'm trying to move objects around in the tab order. So....I went against the documentation and passed references to my objects. Specifically I called:
ComboBox3->MoveBeforeInTabOrder(TextCtrl2);
...and it worked.

May I recommend that the documentation be clarified?
Sorry but the documentation for Move{After|Before}InTabOrder() clearly lists the parameter as a pointer to wxWindow?

Code: Select all

void MoveAfterInTabOrder(wxWindow *win)
void MoveBeforeInTabOrder (wxWindow *win)
wxWindow is always used as a new()ed pointer, you never create child windows on the stack. If it worked you must have passed the pointers (wxWindow*), not references (wxWindow&). In case it is not clear, every control is (a descendant of) a wxWindow. They are not called objects, anything can be an object, e.g. a sizer is an object, can be "placed" in a window but it is not a (wx)Window.

Additionally, these obviously cannot work

Code: Select all

ComboBox1 = new wxComboBox(this, ID_COMBOBOX1, wxEmptyString, wxPoint(210,80), wxSize(300,30), 0, 0, !wxTAB_TRAVERSAL, _T("ID_COMBOBOX1")); 
ComboBox2->SetWindowStyle(!wxTAB_TRAVERSAL);
Firstly, wxTAB_TRAVERSAL is to be used for a wxPanel (a container which can have child windows), not for individual controls.
Secondly, the logical not operator (!) cannot be used like this with a bitwise flag.

Anyway, I do not use Linux so I have no idea if <Tab>bing is any different there that on WIndows. Out of curiosity, if you build verbatim the second example code in this post, is the tab order correct? When you hit the plus or minus button there, a three control group gets added after the group with the plus button clicked or removed, while maintaining the proper tab order.

BTW, IME things like "sizers are getting in my way" more often than not indicate an issue with the GUI design that probably needs to be addressed properly.
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

Re: Tab Traversal Woes

Post by dcbdbis »

@PB - thank you for your post.

Here are some answers:

First a cut-n-paste from the documentation:
void wxWindow::MoveBeforeInTabOrder ( wxWindow * win )

Same as MoveAfterInTabOrder() except that it inserts this window just before win instead of putting it right after it.
Regarding sizers - even though I've followed the tutorials and followed the wiki's - sizers continue to cause me grief - so I do not use them. I cannot get my GUI to look properly with sizers.

This is an existing app I wrote under Visual Studio and C# (electrical contractor estimating software), that I am porting to C++ and wxWidgets. The sizers operate like nothing I've used before in QT-Creator, nor in Visual Studio, nor in the older Borland's C++ Builder 6. I'm not a young guy. I'm 63. Sizers simply get in my way, and the basic GUI and grid does not. So I don't use them.

Regarding inability to "!" the wxTAB_TRAVERSAL - the compiler doesn't complain neither does the runtime. I admit that the wxTAB_TRAVERSAL is a long - not a boolean, and it was an inappropriate long shot - I agree. But as the library is not following the configuration no matter how I configured it - I was grasping at inappropriate straws - I acknowledge this.

Yet I STILL cannot shutdown wxTAB_TRAVERSAL.

So I will create a test wxFrame, put a sizer on it, then put a few objects on it and see if the TAB_TRAVERSAL issue goes away - I think not, but in my world over the years, I've seen some crazy illogical things work occassionaly over the years - like "!"'ing a long type.

I'll report back my findings - if I am still unsuccessfull - I think we have a legitimate bug in the wx library to not be able to shutdown the tabs.

<EDIT> I'm working to my client's spec - to clone the existing application to wxWidgets and C++. Clone as in look and feel to include how the user interacts with it.
</EDIT>

Give me a few hours to get back to you....

Again - THANK YOU for your post!


Sincerely and respectfully,


Dave
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Tab Traversal Woes

Post by doublemax »

So I will create a test wxFrame, put a sizer on it, then put a few objects on it and see if the TAB_TRAVERSAL issue goes away - I think not,
Save your time. Using sizers - while recommended - has no effect whatsoever on TAB navigation. Sizers are just a layout tool.
Use the source, Luke!
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

Re: Tab Traversal Woes

Post by dcbdbis »

Unable to shutdown TAB_TRAVERSAL. Giving up under 3.0.4.

But the main page clearly states this:
Fix several bugs related to focus handling and TAB navigation in wxGTK.
Seems like I am going to compile and give 3.1.2 a shot.....I am not worried about incompatibilities at this point - as I am not too deep into the porting process that flushing the 3.0.4 version and starting over - will not hurt me too much regarding labor hours.

So an upgrade of the library is in order.

If that works, then I'll come back and mark this thread solved.

Dave
User avatar
doublemax
Moderator
Moderator
Posts: 19114
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Tab Traversal Woes

Post by doublemax »

After a little browsing through the wx sources, i think i found an easy solution:

In your App class, implement the FilterEvent method.

Example code based on the "minimal" sample:

Code: Select all

class MyApp : public wxApp
{
public:
    // override base class virtuals
    // ----------------------------

    // this one is called on application startup and is a good place for the app
    // initialization (doing it here and not in the ctor allows to have an error
    // return: if OnInit() returns false, the application terminates)
    virtual bool OnInit();
    
    // START NEW CODE
    virtual int FilterEvent(wxEvent &event)
    {
      if(event.GetEventType() == wxEVT_NAVIGATION_KEY )
      {
        // pretend we processed it already
        return Event_Processed;
      }

      return Event_Skip;
    }
    // END NEW CODE
};
Use the source, Luke!
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

Re: Tab Traversal Woes

Post by dcbdbis »

Thank you doublemax....

That was my plan. Clearly 3.0.4 has issues. The bug tracker is full of them, and in the changelog for 3.2.* - it talks about fixing "several bugs related to TAB_TRAVERSAL.

Thank you again - I am going to mark this thread solved.


Dave
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4193
Joined: Sun Jan 03, 2010 5:45 pm

Re: Tab Traversal Woes

Post by PB »

dcbdbis wrote: Tue Jul 30, 2019 12:53 am The changelog for 3.2.* - it talks about fixing "several bugs related to TAB_TRAVERSAL.
JFYI, there is no wxWidgets 3.2 and hence no changelog for it.

Anyway the only issue for tab traversal on GTK I found was this
https://github.com/wxWidgets/wxWidgets/ ... a0e5d2e4af

The fix seems to be included in v3.04:
https://github.com/wxWidgets/wxWidgets/ ... .cpp#L3745

As you did not provide an SSCE showing the issue nor tested the code I provided above, it is difficult to tell if it is a bug your code, a bug in wxWidgets, or an issue with your system.

If you believe there is still a bug, you should:
* Be able to provide a SSCE demonstrating it.
* Submit a bug report.

I do understand that you are not feeling like it, so...
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

Re: [SOLVED] Tab Traversal Woes

Post by dcbdbis »

Thank you all of you for your posts.... I sent a post to the CodeBlocks forums about developing for 3.1.2, in a system based upon 3.0.4. I have been warned of the pitfalls of doing so and have decided to stick with 3.0.4 for my two apps.

The other choice was QT - and they are expensive for commercial apps, and according to their own public records have been running in red ink for the last 6 fiscal quarters - not good - not to mention that they have changed owners several times - another sign of ill-corporate health. When I was developing for Carrier (the A/C people) a license was $250. Now it's somewhere near $5,500. I am not going to ask my two clients to pop for that amount of money on a company that is having financial difficulties.

So I have decided to stick with what I've got - and work out kinks along the way as they/if they crop up. Solutions like what doublemax kindly posted as a class I can use to intercept the tab key was so very much appreciated. CodeBlocks is built on wxWidgets - and it is a damned good IDE. More stable than Visual Studio ever was - an outstanding testimonial to wxWidgets robustness.

With regard to my system having a problem. I have three separate physical workstations - all displaying the same issues. Could it be Manjaro? Possibly, plausible - but it's not significant enough for me too much time on. doublemax gave me a workaround and I have every intention of using it.

But - I will establish a new VM today in a different distro - install code blocks and wxWidgets - and see. Manjaro built wxWidgets against GTK3 - which is quite buggy, so it's plausible that it is part and parcel of my system (Manjaro). I am going to install mxLinux in the VM - and see if I can duplicate the problem there.

I'll report back here to this thread my findings - then I've got to move with the project - I'm under a scheduling and delivery time frame....


THANK YOU!



Dave
dcbdbis
Experienced Solver
Experienced Solver
Posts: 80
Joined: Sun Nov 24, 2013 9:49 pm
Location: Aurora, Colorado

Re: [SOLVED] Tab Traversal Woes

Post by dcbdbis »

Last Post from me:

I created a new VM, put Linux Mint 19.1 xfce in it, installed codeblocks and the required 3.0.4 libraries and dev files, and created a small test app.

I put 4 ComboBoxes on it, no panel, just put the ComboBoxes directly on the Frame. Made sure all TAB_TRAVERSALS were turned off (they were by default), then built the app.

Issue Remains. The TAB_TRAVERSAL remains... Can't be shutdown without deploying doublemax's interventionary event handler class.

So I don't know if this is a GTK3 issue that wxWidgets is built against (GTK3 has plenty of bugs - still), or if it's an issue with wxWidgets itself. I was about to build 3.1.2 and try it - but I have some apps on my system that depend on 3.0.4. In the CodeBlocks forums they strongly recommended against building and installing 3.1.2 due to the potential of hosing my system - so I didn't do it.

doublemax's solution works well - though it doesn't address the bug directly, it allows for a workaround. I suspect that this may be a GTK3 issue - but that is only my gut feeling.....no facts to support the "instinct".

THANK YOU TO ALL, for your responses and your posts. I sincerely appreciate them.

Sincerely and respectfully,


Dave
Post Reply