diff --git a/applets/kicker/package/contents/ui/ItemListDelegate.qml b/applets/kicker/package/contents/ui/ItemListDelegate.qml index 0216bac18..306cbd56d 100644 --- a/applets/kicker/package/contents/ui/ItemListDelegate.qml +++ b/applets/kicker/package/contents/ui/ItemListDelegate.qml @@ -1,281 +1,284 @@ /*************************************************************************** * Copyright (C) 2013-2015 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import "code/tools.js" as Tools Item { id: item height: isSeparator ? separatorHeight : itemHeight width: ListView.view.width enabled: !isSeparator signal actionTriggered(string actionId, variant actionArgument) signal aboutToShowActionMenu(variant actionMenu) + readonly property real fullTextWidth: Math.ceil(icon.width + label.implicitWidth + arrow.width + row.anchors.leftMargin + row.anchors.rightMargin + row.actualSpacing) property bool isSeparator: (model.isSeparator == true) property bool hasChildren: (model.hasChildren == true) property bool hasActionList: ((model.favoriteId != null) || (("hasActionList" in model) && (model.hasActionList == true))) property QtObject childDialog: null property Item menu: actionMenu Accessible.role: isSeparator ? Accessible.Separator: Accessible.MenuItem Accessible.name: label.text onHasChildrenChanged: { if (!hasChildren && ListView.view.currentItem == item) { ListView.view.currentIndex = -1; } } onAboutToShowActionMenu: { var actionList = hasActionList ? model.actionList : []; Tools.fillActionMenu(i18n, actionMenu, actionList, ListView.view.model.favoritesModel, model.favoriteId); } onActionTriggered: { if (Tools.triggerAction(ListView.view.model, model.index, actionId, actionArgument) === true) { plasmoid.expanded = false; } } function openActionMenu(visualParent, x, y) { aboutToShowActionMenu(actionMenu); actionMenu.visualParent = visualParent; actionMenu.open(x, y); } ActionMenu { id: actionMenu onActionClicked: { actionTriggered(actionId, actionArgument); } } MouseArea { id: mouseArea anchors { left: parent.left right: parent.right verticalCenter: parent.verticalCenter } height: parent.height property int mouseCol property bool pressed: false property int pressX: -1 property int pressY: -1 hoverEnabled: true acceptedButtons: Qt.LeftButton | Qt.RightButton onPressed: { if (mouse.buttons & Qt.RightButton) { if (hasActionList) { openActionMenu(mouseArea, mouse.x, mouse.y); } } else { pressed = true; pressX = mouse.x; pressY = mouse.y; } } onReleased: { if (pressed && !hasChildren) { item.ListView.view.model.trigger(index, "", null); plasmoid.expanded = false; } pressed = false; pressX = -1; pressY = -1; } onPositionChanged: { if (pressX != -1 && model.url && dragHelper.isDrag(pressX, pressY, mouse.x, mouse.y)) { dragHelper.startDrag(kicker, model.url, model.decoration); pressed = false; pressX = -1; pressY = -1; return; } // FIXME: Correct escape angle calc for right screen edge. if (justOpenedTimer.running || !hasChildren) { item.ListView.view.currentIndex = index; } else { mouseCol = mouse.x; if (index == item.ListView.view.currentIndex) { updateCurrentItem(); } else if ((index == item.ListView.view.currentIndex - 1) && mouse.y < (itemHeight - 6) || (index == item.ListView.view.currentIndex + 1) && mouse.y > 5) { if ((childDialog != null && childDialog.facingLeft) ? mouse.x > item.ListView.view.eligibleWidth - 5 : mouse.x < item.ListView.view.eligibleWidth + 5) { updateCurrentItem(); } } else if ((childDialog != null && childDialog.facingLeft) ? mouse.x > item.ListView.view.eligibleWidth : mouse.x < item.ListView.view.eligibleWidth) { updateCurrentItem(); } updateCurrentItemTimer.start(); } } onContainsMouseChanged: { if (!containsMouse) { pressed = false; pressX = -1; pressY = -1; updateCurrentItemTimer.stop(); } } function updateCurrentItem() { item.ListView.view.currentIndex = index; item.ListView.view.eligibleWidth = Math.min(width, mouseCol); } Timer { id: updateCurrentItemTimer interval: 50 repeat: false onTriggered: parent.updateCurrentItem() } } Row { + id: row + anchors.left: parent.left anchors.leftMargin: highlightItemSvg.margins.left anchors.right: parent.right anchors.rightMargin: highlightItemSvg.margins.right height: parent.height spacing: units.smallSpacing * 2 + readonly property real actualSpacing: ((icon.visible ? 1 : 0) * spacing) + ((arrow.visible ? 1 : 0) * spacing) LayoutMirroring.enabled: (Qt.application.layoutDirection == Qt.RightToLeft) PlasmaCore.IconItem { id: icon anchors.verticalCenter: parent.verticalCenter width: visible ? units.iconSizes.small : 0 height: width visible: iconsEnabled animated: false usesPlasmaTheme: false source: model.decoration } PlasmaComponents.Label { id: label enabled: !isParent || (isParent && hasChildren) anchors.verticalCenter: parent.verticalCenter - width: (parent.width - icon.width - arrow.width - - ((icon.visible ? 1 : 0) * parent.spacing) - ((arrow.visible ? 1 : 0) * parent.spacing)) + width: parent.width - icon.width - arrow.width - parent.actualSpacing verticalAlignment: Text.AlignVCenter textFormat: Text.PlainText wrapMode: Text.NoWrap elide: Text.ElideRight text: model.display } PlasmaCore.SvgItem { id: arrow anchors.verticalCenter: parent.verticalCenter width: visible ? units.iconSizes.small : 0 height: width visible: hasChildren opacity: (item.ListView.view.currentIndex == index) ? 1.0 : 0.4 svg: arrows elementId: (Qt.application.layoutDirection == Qt.RightToLeft) ? "left-arrow" : "right-arrow" } } Component { id: separatorComponent PlasmaCore.SvgItem { width: parent.width height: lineSvg.horLineHeight svg: lineSvg elementId: "horizontal-line" } } Loader { id: separatorLoader anchors.left: parent.left anchors.leftMargin: highlightItemSvg.margins.left anchors.right: parent.right anchors.rightMargin: highlightItemSvg.margins.right anchors.verticalCenter: parent.verticalCenter active: isSeparator asynchronous: false sourceComponent: separatorComponent } Keys.onPressed: { if (event.key == Qt.Key_Menu && hasActionList) { event.accepted = true; openActionMenu(mouseArea); } else if ((event.key == Qt.Key_Enter || event.key == Qt.Key_Return) && !hasChildren) { if (!hasChildren) { event.accepted = true; item.ListView.view.model.trigger(index, "", null); plasmoid.expanded = false; } } } } diff --git a/applets/kicker/package/contents/ui/ItemListView.qml b/applets/kicker/package/contents/ui/ItemListView.qml index 6704d050a..4a4b22d35 100644 --- a/applets/kicker/package/contents/ui/ItemListView.qml +++ b/applets/kicker/package/contents/ui/ItemListView.qml @@ -1,258 +1,265 @@ /*************************************************************************** * Copyright (C) 2013-2014 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.0 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents import org.kde.plasma.extras 2.0 as PlasmaExtras import org.kde.kquickcontrolsaddons 2.0 FocusScope { id: itemList - width: units.gridUnit * 14 + property real minimumWidth: units.gridUnit * 14 + property real maximumWidth: minimumWidth * 2 + + width: minimumWidth height: listView.contentHeight signal exited signal keyNavigationAtListEnd signal appendSearchText(string text) property Item focusParent: null property QtObject dialog: null property QtObject childDialog: null property bool iconsEnabled: false property int itemHeight: Math.ceil((Math.max(theme.mSize(theme.defaultFont).height, units.iconSizes.small) + Math.max(highlightItemSvg.margins.top + highlightItemSvg.margins.bottom, listItemSvg.margins.top + listItemSvg.margins.bottom)) / 2) * 2 property int separatorHeight: lineSvg.horLineHeight + (2 * units.smallSpacing) property alias currentIndex: listView.currentIndex property alias currentItem: listView.currentItem property alias keyNavigationWraps: listView.keyNavigationWraps property alias showChildDialogs: listView.showChildDialogs property alias model: listView.model property alias count: listView.count property alias containsMouse: listener.containsMouse property alias resetOnExitDelay: resetIndexTimer.interval onFocusParentChanged: { appendSearchText.connect(focusParent.appendSearchText); } Timer { id: dialogSpawnTimer property bool focusOnSpawn: false interval: 70 repeat: false onTriggered: { if (!plasmoid.expanded || model == undefined || currentIndex == -1) { return; } if (childDialog != null) { childDialog.delayedDestroy(); } // Gets reenabled after the dialog spawn causes a focus-in on the dialog window. plasmoid.hideOnWindowDeactivate = false; childDialog = itemListDialogComponent.createObject(itemList); childDialog.focusParent = itemList; childDialog.visualParent = listView.currentItem; childDialog.model = model.modelForRow(listView.currentIndex); childDialog.visible = true; windowSystem.forceActive(childDialog.mainItem); childDialog.mainItem.focus = true; if (focusOnSpawn) { childDialog.mainItem.showChildDialogs = false; childDialog.mainItem.currentIndex = 0; childDialog.mainItem.showChildDialogs = true; } } } Timer { id: resetIndexTimer interval: (dialog != null) ? 50 : 150 repeat: false onTriggered: { if (focus && (!childDialog || !childDialog.mainItem.containsMouse)) { currentIndex = -1; itemList.exited(); } } } MouseEventListener { id: listener anchors.fill: parent hoverEnabled: true onContainsMouseChanged: { listView.eligibleWidth = listView.width; if (containsMouse) { resetIndexTimer.stop(); itemList.forceActiveFocus(); } else if ((!childDialog || !dialog) && (!currentItem || !currentItem.menu.opened)) { resetIndexTimer.start(); } } PlasmaExtras.ScrollArea { anchors.fill: parent focus: true ListView { id: listView property bool showChildDialogs: true property int eligibleWidth: width currentIndex: -1 boundsBehavior: Flickable.StopAtBounds snapMode: ListView.SnapToItem spacing: 0 keyNavigationWraps: (dialog != null) - delegate: ItemListDelegate {} + delegate: ItemListDelegate { + onFullTextWidthChanged: { + if (fullTextWidth > itemList.width) itemList.width = Math.min(fullTextWidth, itemList.maximumWidth); + } + } highlight: PlasmaComponents.Highlight { visible: listView.currentItem && !listView.currentItem.isSeparator } highlightMoveDuration: 0 onCountChanged: { currentIndex = -1; } onCurrentIndexChanged: { if (currentIndex != -1) { if (childDialog) { if (currentItem && currentItem.hasChildren) { childDialog.model = model.modelForRow(currentIndex); childDialog.visualParent = listView.currentItem; } else { childDialog.delayedDestroy(); } return; } if (currentItem == null || !currentItem.hasChildren || !plasmoid.expanded) { dialogSpawnTimer.stop(); return; } if (showChildDialogs) { dialogSpawnTimer.focusOnSpawn = false; dialogSpawnTimer.restart(); } } else if (childDialog != null) { childDialog.delayedDestroy(); childDialog = null; } } onCurrentItemChanged: { if (currentItem) { currentItem.menu.closed.connect(resetIndexTimer.restart); } } Keys.onPressed: { if (event.key == Qt.Key_Up) { event.accepted = true; if (!keyNavigationWraps && currentIndex == 0) { itemList.keyNavigationAtListEnd(); return; } showChildDialogs = false; decrementCurrentIndex(); if (currentItem.isSeparator) { decrementCurrentIndex(); } showChildDialogs = true; } else if (event.key == Qt.Key_Down) { event.accepted = true; if (!keyNavigationWraps && currentIndex == count - 1) { itemList.keyNavigationAtListEnd(); return; } showChildDialogs = false; incrementCurrentIndex(); if (currentItem.isSeparator) { incrementCurrentIndex(); } showChildDialogs = true; } else if ((event.key == Qt.Key_Right || event.key == Qt.Key_Return || event.key == Qt.Key_Enter) && childDialog != null) { windowSystem.forceActive(childDialog.mainItem); childDialog.mainItem.focus = true; childDialog.mainItem.currentIndex = 0; } else if ((event.key == Qt.Key_Right || event.key == Qt.Key_Return || event.key == Qt.Key_Enter) && childDialog == null && currentItem != null && currentItem.hasChildren) { dialogSpawnTimer.focusOnSpawn = true; dialogSpawnTimer.restart(); } else if (event.key == Qt.Key_Left && dialog != null) { dialog.destroy(); } else if (event.key == Qt.Key_Escape) { plasmoid.expanded = false; } else if (event.key == Qt.Key_Tab) { //do nothing, and skip appending text } else if (event.text != "") { appendSearchText(event.text); } } } } } Component.onCompleted: { windowSystem.monitorWindowFocus(itemList); if (dialog == null) { appendSearchText.connect(root.appendSearchText); } } } diff --git a/applets/kicker/package/contents/ui/MenuRepresentation.qml b/applets/kicker/package/contents/ui/MenuRepresentation.qml index b70b76b2d..f50204e4b 100644 --- a/applets/kicker/package/contents/ui/MenuRepresentation.qml +++ b/applets/kicker/package/contents/ui/MenuRepresentation.qml @@ -1,437 +1,440 @@ /*************************************************************************** * Copyright (C) 2013-2015 by Eike Hein * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * ***************************************************************************/ import QtQuick 2.2 import QtQuick.Layouts 1.1 import org.kde.plasma.core 2.0 as PlasmaCore import org.kde.plasma.components 2.0 as PlasmaComponents FocusScope { id: root focus: true Layout.minimumWidth: (sideBar.width + (sideBar.width ? mainRow.spacing : 0) - + Math.max(units.gridUnit * 14, runnerColumns.width)) - Layout.maximumWidth: Layout.minimumWidth + + Math.max(searchField.defaultWidth, runnerColumns.width)) + Layout.maximumWidth: Math.max(mainRow.width, Layout.minimumWidth); // mainRow.width is constrained by rootList.maximumWidth Layout.minimumHeight: Math.max(((rootModel.count - rootModel.separatorCount) * rootList.itemHeight) + (rootModel.separatorCount * rootList.separatorHeight) + searchField.height + (2 * units.smallSpacing), sideBar.margins.top + sideBar.margins.bottom + favoriteApps.contentHeight + favoriteSystemActions.contentHeight + sidebarSeparator.height + (4 * units.smallSpacing)) Layout.maximumHeight: Layout.minimumHeight signal appendSearchText(string text) function reset() { plasmoid.hideOnWindowDeactivate = true; rootList.currentIndex = -1; searchField.text = ""; searchField.focus = true; } Row { id: mainRow height: parent.height spacing: units.smallSpacing LayoutMirroring.enabled: ((plasmoid.location == PlasmaCore.Types.RightEdge) || (Qt.application.layoutDirection == Qt.RightToLeft && plasmoid.location != PlasmaCore.Types.LeftEdge)) PlasmaCore.FrameSvgItem { id: sideBar visible: width > 0 width: (globalFavorites && systemFavorites && (globalFavorites.count + systemFavorites.count) ? units.iconSizes.medium + margins.left + margins.right : 0) height: parent.height imagePath: "widgets/frame" prefix: "plain" SideBarSection { id: favoriteApps anchors.top: parent.top anchors.topMargin: sideBar.margins.top height: (sideBar.height - sideBar.margins.top - sideBar.margins.bottom - favoriteSystemActions.height - sidebarSeparator.height - (4 * units.smallSpacing)) model: globalFavorites states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: favoriteApps anchors.top: undefined anchors.bottom: parent.bottom } PropertyChanges { target: favoriteApps anchors.topMargin: undefined anchors.bottomMargin: sideBar.margins.bottom } }] Binding { target: globalFavorites property: "iconSize" value: units.iconSizes.medium } } PlasmaCore.SvgItem { id: sidebarSeparator anchors.bottom: favoriteSystemActions.top anchors.bottomMargin: (2 * units.smallSpacing) anchors.horizontalCenter: parent.horizontalCenter width: units.iconSizes.medium height: lineSvg.horLineHeight visible: (favoriteApps.model && favoriteApps.model.count && favoriteSystemActions.model && favoriteSystemActions.model.count) svg: lineSvg elementId: "horizontal-line" states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: sidebarSeparator anchors.top: favoriteSystemActions.bottom anchors.bottom: undefined } PropertyChanges { target: sidebarSeparator anchors.topMargin: (2 * units.smallSpacing) anchors.bottomMargin: undefined } }] } SideBarSection { id: favoriteSystemActions anchors.bottom: parent.bottom anchors.bottomMargin: sideBar.margins.bottom model: systemFavorites usesPlasmaTheme: true states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: favoriteSystemActions anchors.top: parent.top anchors.bottom: undefined } PropertyChanges { target: favoriteSystemActions anchors.topMargin: sideBar.margins.top anchors.bottomMargin: undefined } }] } } ItemListView { id: rootList anchors.top: parent.top - width: root.width - sideBar.width - mainRow.spacing + minimumWidth: root.Layout.minimumWidth - sideBar.width - mainRow.spacing height: ((rootModel.count - rootModel.separatorCount) * itemHeight) + (rootModel.separatorCount * separatorHeight) visible: (searchField.text == "") iconsEnabled: false model: rootModel onKeyNavigationAtListEnd: { searchField.focus = true; } states: [ State { name: "top" when: (plasmoid.location == PlasmaCore.Types.TopEdge) AnchorChanges { target: rootList anchors.top: undefined anchors.bottom: parent.bottom } }] Component.onCompleted: { rootList.exited.connect(root.reset); } } Row { id: runnerColumns height: parent.height signal focusChanged() visible: (searchField.text != "" && runnerModel.count > 0) Repeater { id: runnerColumnsRepeater model: runnerModel delegate: RunnerResultsList { id: runnerMatches onKeyNavigationAtListEnd: { searchField.focus = true; } onContainsMouseChanged: { if (containsMouse) { runnerMatches.focus = true; } } onFocusChanged: { if (focus) { runnerColumns.focusChanged(); } } function focusChanged() { if (!runnerMatches.focus && runnerMatches.currentIndex != -1) { runnerMatches.currentIndex = -1; } } Keys.onPressed: { var target = null; if (event.key == Qt.Key_Right) { var targets = new Array(); for (var i = index + 1; i < runnerModel.count; ++i) { targets[targets.length] = i; } for (var i = 0; i < index; ++i) { targets[targets.length] = i; } for (var i = 0; i < targets.length; ++i) { if (runnerModel.modelForRow(targets[i]).count) { target = runnerColumnsRepeater.itemAt(targets[i]); break; } } } else if (event.key == Qt.Key_Left) { var targets = new Array(); for (var i = index - 1; i >= 0; --i) { targets[targets.length] = i; } for (var i = runnerModel.count - 1; i > index; --i) { targets[targets.length] = i; } for (var i = 0; i < targets.length; ++i) { if (runnerModel.modelForRow(targets[i]).count) { target = runnerColumnsRepeater.itemAt(targets[i]); break; } } } if (target) { event.accepted = true; currentIndex = -1; target.currentIndex = 0; target.focus = true; } } Component.onCompleted: { runnerColumns.focusChanged.connect(focusChanged); } Component.onDestruction: { runnerColumns.focusChanged.disconnect(focusChanged); } } } } } PlasmaComponents.TextField { id: searchField anchors.bottom: mainRow.bottom anchors.left: parent.left anchors.leftMargin: sideBar.width + (sideBar.width ? mainRow.spacing : 0) + units.smallSpacing - width: (units.gridUnit * 14) - (2 * units.smallSpacing) + readonly property real defaultWidth: units.gridUnit * 14 + width: (runnerColumnsRepeater.count != 0 ? runnerColumnsRepeater.itemAt(0).width + : (rootList.visible ? rootList.width : defaultWidth)) + - units.smallSpacing focus: true placeholderText: i18n("Search...") clearButtonShown: true onTextChanged: { runnerModel.query = text; } onFocusChanged: { if (focus) { // FIXME: Cleanup arbitration between rootList/runnerCols here and in Keys. if (rootList.visible) { rootList.currentIndex = -1; } if (runnerColumns.visible) { runnerColumnsRepeater.itemAt(0).currentIndex = -1; } } } states: [ State { name: "top" when: plasmoid.location == PlasmaCore.Types.TopEdge AnchorChanges { target: searchField anchors.top: mainRow.top anchors.bottom: undefined anchors.left: parent.left anchors.right: undefined } PropertyChanges { target: searchField anchors.leftMargin: sideBar.width + mainRow.spacing + units.smallSpacing anchors.rightMargin: undefined } }, State { name: "right" when: (plasmoid.location == PlasmaCore.Types.RightEdge && Qt.application.layoutDirection == Qt.LeftToRight) || (plasmoid.location == PlasmaCore.Types.LeftEdge && Qt.application.layoutDirection == Qt.RightToLeft) AnchorChanges { target: searchField anchors.top: undefined anchors.bottom: mainRow.bottom anchors.left: undefined anchors.right: parent.right } PropertyChanges { target: searchField anchors.leftMargin: undefined anchors.rightMargin: sideBar.width + mainRow.spacing + units.smallSpacing } }] Keys.onPressed: { if (event.key == Qt.Key_Up) { if (rootList.visible) { rootList.showChildDialogs = false; rootList.currentIndex = rootList.model.count - 1; rootList.forceActiveFocus(); rootList.showChildDialogs = true; } if (runnerColumns.visible) { for (var i = 0; i < runnerModel.count; ++i) { if (runnerModel.modelForRow(i).count) { var targetList = runnerColumnsRepeater.itemAt(i); targetList.currentIndex = runnerModel.modelForRow(i).count - 1; targetList.forceActiveFocus(); break; } } } } else if (event.key == Qt.Key_Down) { if (rootList.visible) { rootList.showChildDialogs = false; rootList.currentIndex = 0; rootList.forceActiveFocus(); rootList.showChildDialogs = true; } if (runnerColumns.visible) { for (var i = 0; i < runnerModel.count; ++i) { if (runnerModel.modelForRow(i).count) { var targetList = runnerColumnsRepeater.itemAt(i); targetList.currentIndex = 0; targetList.forceActiveFocus(); break; } } } } else if (event.key == Qt.Key_Enter || event.key == Qt.Key_Return) { if (runnerColumns.visible && runnerModel.modelForRow(0).count) { runnerModel.modelForRow(0).trigger(0, "", null); plasmoid.expanded = false; } } } function appendText(newText) { focus = true; text = text + newText; } } Keys.onPressed: { if (event.key == Qt.Key_Escape) { plasmoid.expanded = false; } } Component.onCompleted: { appendSearchText.connect(searchField.appendText); kicker.reset.connect(reset); windowSystem.hidden.connect(reset); } }