Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-117591

Let QQuick focus chain be independent of the logical hierarchical order

XMLWordPrintable

       
      Today, the focus chain is implicitly defined by the logical hierarchical order of QQuickItems. The focus order can only be changed by reordering items in the hierarchy (e.g. reordering sibling items or reparenting items).

      This means that controls that dynamically create and destroy children (e.g ListView with a delegate) must take care and retain the order (this is already a known bug in ListView and GridView). Untangling the focus chain from the logical hierarchy means that these controls don’t need to take extra care about focus order when manipulating its child order.
      In addition, having a focus chain that is independent of the logical hierarchical order also allows the focus chain to be altered without having to change the logical hierarchy.

       

      Note/Update!

      Even with a focus chain, it is unclear how a delegate in item view can help with retaining an explicit tab order, as these are created and destroyed dynamically.

       

      Suggestion A (complete and separate focus chain)

      The design will follow similar design found in QWidget. The focus chain will by default be initialized to the default logical hierarchical order (same order as today). (Actually, in widgets the focus chain is "...in the order of widget construction" - so not following hierarchical order (but in most cases construction order is very close to hierarchical order)). The focus chain will be a (linked?) list having all focus Items (or maybe absolutely all items), where

      • <Tab> moves from activeFocusItem() to the item after the focus item in the focus chain.
      • <Backtab> moves from activeFocusItem() to the item before the focus item in the focus chain.

      Note that it might skip items because they do not accept focus (or tabFocus).

       
      Focus chain can be implemented with a double linked list, where each QQuickItem will have:

      QQuickItem *focusNext;
      QQuickItem *focusPrev;

      Focus chain can alternatively be implemented with a QVector<QQuickItem*> on e.g. QQuickWindow. This will save some space (e.g. if all items are non-focusable), but there might be startup time penalties (might need to insert items in the middle of the vector etc).
      Order can be customized similar to

      QWidget::setTabOrder(a, c); 
      

       
      In QML, it could also take an array of items, e.g:

      Window.tabOrder: [a,c,b] 

      Today, when moving items in the hierarchy, the focus order will also automatically change (see for yourself: quick-focus-chain.qml

      In order to preserve that behavior, the focus chain needs to be updated when items move around in the hierarchy. (Could maybe question if this is a behavior we want - it currently diverges from QWidget focus tab order behavior)

       

      Suggestion B (Sparse focus chain)

      Hybrid approach of hierarchical order and separate focus chain. The focus chain is sparse, only storing the tab order that diverges from the default hierarchical order.

      finding the next effective focus item will then:

      1. Query the explicit focus chain if it know what should be the next focus item.
      2. If 1) returns nullptr, move to the next focusable item by traversing the hierarchy (as is today)

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

            qt.team.quick.subscriptions Qt Quick and Widgets Team
            smd Jan Arve
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:

                There are no open Gerrit changes