on xenial help sign in
Fixed a race condition causing search history popup to show up when it shouldn't. Fixes: https://bugs.launchpad.net/bugs/1249369.
677390cNick Dedekind
Components/PageHeader.qml+25−6
@@ -44,8 +44,8 @@ Item {
44 if (!searchHistory) return;
44 if (!searchHistory) return;
45
45
46 searchHistory.addQuery(searchField.text);
46 searchHistory.addQuery(searchField.text);
47+ unfocus();
47 searchField.text = "";
48 searchField.text = "";
48− searchField.focus = false;
49 }
49 }
50
50
51 function unfocus() {
51 function unfocus() {
@@ -112,6 +112,8 @@ Item {
112 objectName: "searchContainer"
112 objectName: "searchContainer"
113
113
114 visible: searchEntryEnabled
114 visible: searchEntryEnabled
115+ property bool popoverShouldOpen: false
116+ property bool popoverShouldClose: false
115
117
116 property bool narrowMode: parent.width < label.contentWidth + units.gu(50)
118 property bool narrowMode: parent.width < label.contentWidth + units.gu(50)
117
119
@@ -127,6 +129,16 @@ Item {
127 else if (active && !narrowMode) "active"
129 else if (active && !narrowMode) "active"
128 else if (!active && !narrowMode) "inactive"
130 else if (!active && !narrowMode) "inactive"
129
131
132+ onStateChanged: {
133+ if (state == "active" || state == "narrowActive") {
134+ popoverShouldOpen = true;
135+ popoverShouldClose = false;
136+ } else {
137+ popoverShouldOpen = false;
138+ popoverShouldClose = true;
139+ }
140+ }
141+
130 function openPopover() {
142 function openPopover() {
131 if (searchHistory.count > 0) {
143 if (searchHistory.count > 0) {
132 searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
144 searchContainer.popover = PopupUtils.open(popoverComponent, searchField,
@@ -137,10 +149,17 @@ Item {
137 }
149 }
138 )
150 )
139 }
151 }
152+ popoverShouldOpen = false;
153+ popoverShouldClose = false;
140 }
154 }
141
155
142 function closePopover() {
156 function closePopover() {
157+ if (searchContainer.popover) {
143− if (searchContainer.popover) PopupUtils.close(searchContainer.popover)
158+ PopupUtils.close(searchContainer.popover);
159+ searchContainer.popover = null;
160+ }
161+ popoverShouldOpen = false;
162+ popoverShouldClose = false;
144 }
163 }
145
164
146 onActiveFocusChanged: if (!activeFocus) { searchHistory.addQuery(searchField.text) }
165 onActiveFocusChanged: if (!activeFocus) { searchHistory.addQuery(searchField.text) }
@@ -283,12 +302,12 @@ Item {
283 PropertyAction { target: primaryImage; property: "source" }
302 PropertyAction { target: primaryImage; property: "source" }
284 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
303 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
285 }
304 }
286− ScriptAction { script: searchContainer.openPopover() }
305+ ScriptAction { script: if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
287 }
306 }
288 },
307 },
289 Transition {
308 Transition {
290 to: "inactive"
309 to: "inactive"
291− ScriptAction { script: searchContainer.closePopover() }
310+ ScriptAction { script: if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
292 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
311 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.InOutQuad }
293 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
312 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
294 },
313 },
@@ -299,12 +318,12 @@ Item {
299 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
318 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
300 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
319 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
301 }
320 }
302− ScriptAction { script: searchContainer.openPopover() }
321+ ScriptAction { script: if (searchContainer.popoverShouldOpen) { searchContainer.openPopover(); } }
303 }
322 }
304 },
323 },
305 Transition {
324 Transition {
306 to: "narrowInactive"
325 to: "narrowInactive"
307− ScriptAction { script: searchContainer.closePopover() }
326+ ScriptAction { script: if (searchContainer.popoverShouldClose) { searchContainer.closePopover(); } }
308 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
327 NumberAnimation { targets: [searchContainer, searchField] ; property: "width"; duration: 200; easing.type: Easing.OutQuad }
309 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
328 AnchorAnimation { targets: [searchContainer, textContainer]; duration: 200; easing.type: Easing.InOutQuad }
310 }
329 }
tests/qmltests/Components/tst_PageHeader.qml+43−3
@@ -37,6 +37,10 @@ Item {
37 property alias searchEnabled : pageHeader.searchEntryEnabled
37 property alias searchEnabled : pageHeader.searchEntryEnabled
38 property alias searchQuery : pageHeader.searchQuery
38 property alias searchQuery : pageHeader.searchQuery
39
39
40+ function init() {
41+ searchEnabled = true;
42+ }
43+
40 function test_search_disabled() {
44 function test_search_disabled() {
41 searchEnabled = false
45 searchEnabled = false
42 pageHeader.resetSearch()
46 pageHeader.resetSearch()
@@ -151,12 +155,48 @@ Item {
151 scopeMock.searchInProgress = true
155 scopeMock.searchInProgress = true
152 compare(searchIndicator.running, true, "Search indicator isn't running.")
156 compare(searchIndicator.running, true, "Search indicator isn't running.")
153 tryCompare(primaryImage, "visible", false)
157 tryCompare(primaryImage, "visible", false)
154−
155− pageHeader.resetSearch()
156 }
158 }
157
159
158 function cleanup() {
160 function cleanup() {
159− scopeMock.searchInProgress = false
161+ scopeMock.searchInProgress = false;
162+ pageHeader.resetSearch();
163+ }
164+
165+ function test_popover() {
166+ searchEnabled = true;
167+ pageHeader.searchHistory.clear();
168+
169+ pageHeader.searchHistory.addQuery("Search1");
170+ pageHeader.searchHistory.addQuery("Search2");
171+
172+ pageHeader.triggerSearch();
173+
174+ var searchContainer = findChild(pageHeader, "searchContainer");
175+ verify(searchContainer !== undefined, "searchContainer != undefined");
176+ tryCompareFunction(function() { return searchContainer.popover !== null; }, true);
177+
178+ tryCompare(searchContainer.popover, "visible", true);
179+ }
180+
181+ function test_resetSearch_onPopupClose() {
182+ searchEnabled = true;
183+ pageHeader.searchHistory.clear();
184+
185+ pageHeader.searchHistory.addQuery("Search1");
186+ pageHeader.searchHistory.addQuery("Search2");
187+
188+ pageHeader.triggerSearch();
189+
190+ var searchContainer = findChild(pageHeader, "searchContainer");
191+ verify(searchContainer !== undefined, "searchContainer != undefined");
192+ tryCompareFunction(function() { return searchContainer.popover !== null; }, true);
193+ compare(searchContainer.popover.visible, true);
194+
195+ pageHeader.searchQuery = "test";
196+ tryCompareFunction( function() { return (searchContainer.popover===null || !searchContainer.popover.visible) }, true);
197+
198+ pageHeader.resetSearch();
199+ compare((searchContainer.popover===null || !searchContainer.popover.visible), true);
160 }
200 }
161 }
201 }
162
202