activeFocus not being forwarded to TextInput inside TextField
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
| Canonical System Image |
Critical
|
Zoltan Balogh | ||
| ubuntu-ui-toolkit (Ubuntu) |
Critical
|
Christian Dywan | ||
| ubuntu-ui-toolkit (Ubuntu RTM) |
Undecided
|
Unassigned | ||
| webbrowser-app (Ubuntu) |
High
|
Olivier Tilloy |
Bug Description
Haven’t managed to reproduce with a standalone example yet, but I can reliably reproduce the following issue with the browser app on a tablet with a bluetooth keyboard connected (this needs to be on a tablet so that the wide layout of the app is used, for example with a Nexus 7 (flo) in landscape orientation):
1) launch the browser app with a bluetooth keyboard attached and ensure that the current tab is not a new tab
2) press Ctrl+T to open a new tab
Expected result: the address bar gets active focus so that the user can start entering a URL right away
Current result: the address bar gets active focus for a fraction of a second, then looses it. When that happens, pressing Ctrl+L (which forces focus on the address bar) doesn’t fix it.
I added some debugging to the browser (printing Window.
That situation can be remedied by using a bluetooth mouse to click on the address bar, which restores active focus on the QQuickTextInput.
Related branches
- system-apps-ci-bot: Needs Fixing (continuous-integration) on 2016-04-06
- PS Jenkins bot: Needs Fixing (continuous-integration) on 2016-03-29
-
Diff: 1198 lines (+666/-337)12 files modifiedsrc/app/CMakeLists.txt (+3/-1)
src/app/FilteredKeyboardModel.qml (+33/-0)
src/app/browserapplication.cpp (+2/-0)
src/app/qquickshortcut.cpp (+283/-0)
src/app/qquickshortcut_p.h (+109/-0)
src/app/webbrowser/Browser.qml (+200/-258)
src/app/webbrowser/KeyboardShortcut.qml (+0/-25)
src/app/webbrowser/KeyboardShortcuts.qml (+0/-41)
src/app/webbrowser/ListViewHighlight.qml (+2/-3)
src/app/webbrowser/NavigationBar.qml (+10/-7)
tests/autopilot/webbrowser_app/tests/test_keyboard.py (+22/-1)
tests/autopilot/webbrowser_app/tests/test_private.py (+2/-1)
- ubuntu-sdk-build-bot: Approve (continuous-integration) on 2016-05-11
- Ubuntu SDK team: Pending requested 2016-05-09
-
Diff: 97 lines (+52/-4)2 files modifiedsrc/Ubuntu/Components/1.3/InputHandler.qml (+1/-3)
tests/unit_x11/tst_components/tst_textinput_common13.qml (+51/-1)
- PS Jenkins bot: Needs Fixing (continuous-integration) on 2016-05-11
- Ubuntu SDK team: Pending requested 2016-05-09
-
Diff: 122 lines (+69/-5)2 files modifiedsrc/Ubuntu/Components/1.3/InputHandler.qml (+1/-3)
tests/unit_x11/tst_components/tst_textinput_common13.qml (+68/-2)
- PS Jenkins bot: Needs Fixing (continuous-integration) on 2016-05-11
- Ubuntu SDK team: Pending requested 2016-05-11
-
Diff: 98 lines (+53/-4)2 files modifiedsrc/Ubuntu/Components/1.3/InputHandler.qml (+1/-3)
tests/unit_x11/tst_components/tst_textinput_common13.qml (+52/-1)
Olivier Tilloy (osomon) wrote : | #1 |
summary: |
- TextInput inside TextField not being forwarded activeFocus + activeFocus not being forwarded to TextInput inside TextField |
Olivier Tilloy (osomon) wrote : | #2 |
I just tried a very ugly hack to work around the issue:
TextField {
objectName: "addressBarText
onActiveFocus
if (activeFocus) {
var textInput = findChild(
console.
textInput
console.
}
}
}
Where findChild() is copied from UbuntuTestCase to recursively search for a given descendant by objectName.
Well I’m seeing this output:
qml: AFI: QQuickTextInput
qml: address bar got active focus, text input = QQuickTextInput
qml: after forcing active focus on text input QQuickTextInput
qml: AFI: TextField_
So this hack isn’t even working. But it seems to indicate that active focus is removed from the TextInput, but remains on the ancestor TextField. Why that happens remains to be explained.
Olivier Tilloy (osomon) wrote : | #3 |
I added some debugging to TextField13.qml, and I can confirm that when I observe the issue, 'focus' is being set to false on the QQuickTextInput.
Olivier Tilloy (osomon) wrote : | #4 |
I have commented out the definition of the custom primaryItem and secondaryItem in the browser’s AddressBar, and the problem persists. So at least we can rule out those two custom components stealing focus.
Olivier Tilloy (osomon) wrote : | #5 |
I’ve replaced the implementation of the AddressBar component with a simple TextField with no added cruft (only placeholder properties and signals that embedders expect), and the problem persists, so it’s not with the AddressBar implementation.
Olivier Tilloy (osomon) wrote : | #6 |
The problem persists in the latest rc-proposed image.
Olivier Tilloy (osomon) wrote : | #7 |
The same issue affects https:/
Olivier Tilloy (osomon) wrote : | #8 |
I’m still unable to reproduce the issue in a standalone example, however there is clearly a problem with the TextField component in the UITK, if it allows active focus to not be forwarded to its child QQuickTextInput under certain circumstances.
In TextField.qml, the TextInput element (with id 'editor') is inside a Flickable (id 'flicker'), which itself is a child of the top-level ActionItem. ActionItem is a focus scope, but Flickable isn’t. I’m not sure how a focus scope is supposed to behave when the item that has 'focus: true' isn’t a direct child.
Andrea Bernabei (faenil) wrote : | #9 |
That should not make a difference, as far as I know.
FocusScope redirects focus to the last child who requested it.
I believe in this case, the problem might be that something is setting focus:false on the QQuickTextInput. When you do that, the FocusScope does not know whom to redirect the focus to anymore, as far I know.
And that would explain why nothing is happening.
So, in the beginning TextInput has focus true, so when TextField is focused it redirects the focus to QQuickTextInput. Then somehow QQuickTextInput focus is set to false. The next time TextField is focused, it doesn't redirect the focus to QQuickTextInput because it is actually *not* asking for focus (i.e. it's focus property is false).
Hope that helps :)
Olivier Tilloy (osomon) wrote : | #10 |
Yep, that analysis is correct, but I still don’t know what sets focus to false on the QQuickTextInput, and why.
Olivier Tilloy (osomon) wrote : | #11 |
I still haven’t gotten to the bottom of things, but I found a workaround in the browser: in Browser.qml at line 70¹, if I comment out the call to contentsContain
The underlying bug still exists in the UITK.
I’m marking webbrowser-app also affected, and linking a branch that has the workaround.
Changed in webbrowser-app (Ubuntu): | |
assignee: | nobody → Olivier Tilloy (osomon) |
importance: | Undecided → High |
status: | New → In Progress |
Launchpad Janitor (janitor) wrote : | #12 |
This bug was fixed in the package webbrowser-app - 0.23+16.
---------------
webbrowser-app (0.23+16.
[ CI Train Bot ]
* Resync trunk.
[ Loïc Molinari ]
* Made AddressBar height scalable with regards to the grid units
system.
[ Olivier Tilloy ]
* Add dep8 tests and instructions to run them in qemu or on a phone.
Original work by Leo Arias and Vincent Ladeuil. added: debian/tests/
debian/
* Catch ESC key event one level up to ensure that it’s not incorrectly
bubbled up to the outer component. (LP: #1557016)
* Customize the contents of the media permission dialog to avoid
truncated text. (LP: #1554220)
* Do not write the session to a temporary file when no target file is
defined.
* Fix a failing unit test with Qt 5.6. (LP: #1565507)
* Fix broken webapp container autopilot tests. (LP: #1557019)
* Fix issues with item selection in the downloads page: do not allow
selecting multiple files when only one is expected do not allow
entering delete mode (with a long press on an item) while in picker
mode (LP: #1534112, #1561575)
* Fix unit tests when run under an sbuild chroot. (LP: #1567294)
* Import QQuickShortcut from Qt 5.5 to properly handle window-level
keyboard shortcuts. We cannot bump the dependency on Qt to 5.5 as
the stable overlay PPA for devices currently has Qt 5.4.1. (LP:
#1542224, #1545802, #1537782)
* Make the autopilot tests more reliable when dragging the bottom
edge. (LP: #1560109)
* Remove workaround for bug #1526940 that was fixed in the latest
release of the UITK. (LP: #1526940)
* Rename debian packages to follow new QML module naming convention.
(LP: #1342031)
* Simplify the implementation of HistoryViewWide quite a bit, and as a
side effect fix a unit test failure when run against the staging
branch of the UITK. (LP: #1567337)
-- Olivier Tilloy <email address hidden> Fri, 08 Apr 2016 17:07:04 +0000
Changed in webbrowser-app (Ubuntu): | |
status: | In Progress → Fix Released |
Changed in canonical-devices-system-image: | |
status: | New → Fix Committed |
Changed in ubuntu-ui-toolkit (Ubuntu): | |
assignee: | nobody → Christian Dywan (kalikiana) |
Olivier Tilloy (osomon) wrote : | #13 |
Another (simpler) way of reproducing this issue on a touch device (initially reported as bug #1578304), on the latest rc-proposed image:
- ensure that the webview has active focus
- tap once on the address bar
The entire text inside the address bar gets selected, as expected, but the active focus remains on the TextField itself, it is not being passed down to the QQuickTextInput inside it.
Tapping once again on the address bar then correctly focuses the QQuickTextInput.
Changed in ubuntu-ui-toolkit (Ubuntu): | |
importance: | Undecided → Critical |
Launchpad Janitor (janitor) wrote : | #14 |
Status changed to 'Confirmed' because the bug affects multiple users.
Changed in ubuntu-ui-toolkit (Ubuntu): | |
status: | New → Confirmed |
Changed in canonical-devices-system-image: | |
status: | Fix Committed → New |
Olivier Tilloy (osomon) wrote : | #15 |
Another occurrence of the issue just happened when running the QML unit tests for this branch: lp:~osomon/webbrowser-app/browserpage.
That’s with a different TextField (the search field in the history view, not the address bar), but the symptom is similar: at some point the code calls forceActiveFocus() on the field, and the TextField component gets active focus, but it doesn’t forward it to the QQuickTextInput inside it.
Olivier Tilloy (osomon) wrote : | #16 |
The call to forceActiveFocus() that triggers the problem is there: https:/
tags: | added: lt-blocker |
Olivier Tilloy (osomon) wrote : | #17 |
I’m looking at the code in InputHandler.qml (https:/
The following patch seems to fix the regression, although I’m not sure it’s entirely correct, someone familiar with that code should review it and comment:
=== modified file 'src/Ubuntu/
--- src/Ubuntu/
+++ src/Ubuntu/
@@ -291,11 +291,7 @@
Connections {
target: main
- onActiveFocusCh
- if (!main.activeFocus) {
- input.focus = false;
- }
- }
+ onActiveFocusCh
if (main.keyNaviga
Changed in canonical-devices-system-image: | |
assignee: | nobody → Zoltan Balogh (bzoltan) |
importance: | Undecided → Critical |
milestone: | none → 11 |
status: | New → In Progress |
Changed in ubuntu-ui-toolkit (Ubuntu): | |
status: | Confirmed → In Progress |
Changed in canonical-devices-system-image: | |
status: | In Progress → Fix Committed |
Changed in ubuntu-ui-toolkit (Ubuntu): | |
status: | In Progress → Fix Committed |
Oliver Grawert (ogra) wrote : | #18 |
note that the same seems to happen at the login window (waking up the device has the password field auto-focused, enabling a BT keyboard unsets the focus and you have to tap it first)
Changed in canonical-devices-system-image: | |
status: | Fix Committed → Fix Released |
Here’s the additional debug output from the instrumented browser:
[launching the browser, before pressing Ctrl+T] QMLTYPE_ 185(0xb7cc5ae0) e(0xb7d0f8c8) e_QML_174( 0xb80651a8) QMLTYPE_ 122_QML_ 197(0xb80a5398)
qml: AFI: Browser_
qml: AFI: QQuickFocusScop
qml: AFI: QQuickFocusScop
qml: AFI: WebViewImpl_
[after pressing Ctrl+T] (0xb7d844a8, "text_input") QMLTYPE_ 122_QML_ 197(0xb80a5398) 0xb814e608, "foldersList") QMLTYPE_ 134(0xb81266a0, "topSitesList") ate_QMLTYPE_ 132(0xb818f010, "topSiteItem") (0xb7d844a8, "text_input") QMLTYPE_ 71(0xb7d7b970, "addressBarText Field")
qml: AFI: QQuickTextInput
qml: AFI: WebViewImpl_
qml: AFI: QQuickListView(
qml: AFI: UrlPreviewGrid_
qml: AFI: UrlPreviewDeleg
qml: AFI: QQuickTextInput
qml: AFI: TextField_
As can be seen with the last two lines, activeFocus is initially forwarded to the QQuickTextInput inside the TextField, and then for some reason activeFocus switches back to the parent TextField, but is removed from the QQuickTextInput.