-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Navigation with TAB does not work well in wxOSX/Cocoa #17341
Comments
2016-01-20 18:44:39: paulclinger (Paul K) commentedThis is a good summary. I've opened a similar defect (#17064), but mine is specifically about Ctrl-(Shift-)TAB navigation, although I suspect the underlying cause may be the same. In my case the biggest issue is that none of the workarounds I tried work; not even using EVT_CHAR_HOOK (I don't get Ctrl-TAB event in my handlers no matter what I try) and because I'm using wxwidgets through another layer, I'm limited to using only the public API. EVT_KEY_UP is the only place where Ctrl-TAB shows up, but by that time all the navigation is already done by the internal wxwidgets logic; I'm still hunting for where exactly it happens... |
2016-01-20 19:29:34: @JulianSmart commentedJust to second/third this problem with looping and navigation failure when panels are embedded in dialogs; one of the major issues remaining in my OSX application beta, along with the focus issue. Thanks for describing it in detail. Sorry I don't have the technical know-how to solve it but I'd be very happy to help pay for consultancy to smooth out these issues should that be appropriate and possible. |
2016-01-20 21:17:47: paulclinger (Paul K) commentedI'd chip in as well, if this directly or indirectly fixes #17064. ("directly" would fix Ctrl-(Shift-)TAB to navigate wxAuiNotebook tabs as it does on Windows and "indirectly" would at least fix EVT_CHAR_HOOK to intercept Ctrl-(Shift-)TAB.) |
2016-04-19 19:29:51: scrawford1968 (Scott Crawford) commentedChanging the Full keyboard access setting in System Preferences to "All controls" and using the sample code "dialogs", replacing the MyFrame::DlgCenteredScreen function with the sample code below reproduces the issue. Steps:
TAB key navigation works in this sample between the four buttons but after pressing TAB while on the "Button 4" does not loop back to "Button 1" as it should. If the "green" panel and its child buttons are removed the navigation appears to work. When I last looked into this the wxTextCtrl processes the TAB and does its own widgets navigation calls. It worked in wxWidgets 2.8 because all navigation used to be handled by widgets. Sample Code:
|
2016-05-03 11:07:28: ikamakj uploaded file
|
2016-05-03 11:07:39: ikamakj uploaded file
|
2016-05-03 11:15:07: ikamakj commentedI am now submitting a patch that makes the Cocoa build follow wxWidgets navigation logic in a way that is satisfactory at least as a temporary solution. This does not fix Ctrl(+Shift)+Tab for controls other than wxTextCtrl, and with some specific types of controls there are still problems due to deficiencies in their implementation. Details below. The fix is based on the fact that, according to wxWidgets API, any control wanting to handle navigation keys itself must tell this to wxWidgets by setting flag wxWANTS_CHARS. Surprisingly, this flag has presently an effect on wxMSW only, but the documentation does not mention any platform restrictions. Therefore, when receiving a Tab press from a field with this flag on, the framework can safely treat it as a navigation key and need not send keydown or char events to the control at all. This is just the wxMSW logic in wxWindowMSW::MSWProcessMessage(). In the patch, a function HandleNavigationByTab(), called from wxWidgetCocoaImpl::DoHandleKeyEvent(), checks the flag and if it is not set, Tab is treated as a navigation key and no further processing is done. Notes:
Remaining problems with specific control types:
bool wxRadioBox::AcceptsFocusFromKeyboard() const
Perhaps someone with better Cocoa knowledge can suggest better solutions, but I would like to mention that if there is no other way of making Ctrl(+Shift)+Tab work generally, the last resort is to intercept Tab in WX_filterSendEvent, similarly to the mouse event processing that handles capture. This approach would also make it possible to get keydown and char events from password controls, solving #17185. |
2016-05-03 15:57:45: @vadz changed status from new to confirmed2016-05-03 15:57:45: @vadz commentedThanks a lot for working on this! I just wanted to give a brief explanation about Concerning the patch itself, could we override Other than that, this patch clearly seems to be a big improvement and I'd like to apply it, thanks again! |
2016-05-06 08:41:02: ikamakj commentedTo Vadim: I don't know why you mention
|
2017-06-05 07:49:10: sbrowne (Steve) commentedI created a PR for this with some of the requested changes: |
2017-07-16 16:03:49: @vadz commentedI've finally applied the patch, sorry again for the delay. And big thanks to both of you! |
Issue migrated from trac ticket # 17341
component: wxOSX | priority: normal | resolution: fixed | keywords: Cocoa TAB navigation
2016-01-20 09:34:17: ikamakj created the issue
In the Carbon version, navigation between dialog or panel fields follows the logic in wxControlContainer regardless of where Tab is pressed. This is implemented in wxApp::MacSendCharEvent, in case the container has wxTAB_TRAVERSAL flag. The Cocoa version does not contain similar code but relies on native Cocoa navigation. I don't know the Cocoa logic exactly, but it is clearly different from the wxWidgets navigation order, which corresponds to the child window order. The Cocoa navigation seems to depend on geometrical positions rather than child order. As a result, the navigation does not always work in the way the programmer intended.
The situation is particularly bad if the Full keyboard access setting in System Preferences is set to "All controls", because then the successor or predecessor field is chosen by the wxWidgets logic for some controls and by the Cocoa logic for others. In other words, there is no unique ordering relation for all the controls. Often the result is that some controls cannot be reached by Tab at all. The navigation may also get stuck in a local loop, because if field B is after A from A's viewpoint, A may still be after B from B's viewpoint. The visiting order in backward navigation is not always the opposite of that in forward navigation, because if B is the successor of A from A's viewpoint, A is not necessarily the predecessor of B from B's viewpoint.
If the full keyboard access setting is "Text boxes and lists only", problems are less likely, but one problem that occurs even in this case is navigation into and out of a book control if the dialog contains both a book control and controls outside it. (My observations are from wxAuiNotebook, I have not tested other book controls.) Pressing Tab in the last focusable control before the notebook should always move the focus to the first control inside the notebook, but this actually happens only if the former control is one that generates navigation events itself (i.e., lets the wxControlContainer code to determine the successor), such as a wxTextCtrl. (wxComboBox is an example of a class that participates in native navigation regardless of the setting but does not generate navigation events.) Pressing Tab in the last control of the current notebook page should move focus to the first control after the notebook, but actually the focus goes to a control on the next notebook page, unless the focused control generates navigation events itself. There are similar problems in backward navigation with Shift+Tab.
The fact that there is no global Tab-processing code like MacSendCharEvent also has the consequence that Tab navigation does not work at all from controls that are not native Cocoa controls but do not have their own processing for Tab. One example is wxTreeCtrl.
I have also observed these navigation problems with individual control classes:
The version with which I have tested is based on 3.0.2, but I have modified it with all the recent keyboard and focus related changes in window.mm, nonownedwnd.mm, combobox.mm, textctrl.mm, plus the necessary header files.
Is there some technical problem in making Tab navigation follow the wxControlContainer logic for all controls? If somebody prefers the Cocoa logic, could this at least be made an option via wxSystemOptions? Let me finally note that for those who want to use the Cocoa logic, it should be done consistently for every control to ensure unique ordering, i.e., no control class should send a wxWidgets navigation event on a Tab press. (For me the wxControlContainer logic would be fine, so this last issue is irrelevant.)
The text was updated successfully, but these errors were encountered: