import Quickshell import Quickshell.Io import Quickshell.Wayland import QtQuick import QtQuick.Effects import "../emojis.mjs" as Emojis Item { height: currentItems.length ? 180 : 60 width: 700 property var show: input.text.length property var currentItems: { if (input.text.length === 0 || input.text === ":") { return [] } const searchEmojis = (input.text[0] === ':' || input.text[0] === ';') const items = searchEmojis ? Emojis.emojis : Array.from(DesktopEntries.applications.values) for (let item of items) { item.searchPos = item.name.toLowerCase().search(input.text.slice(searchEmojis)) } return items .filter(item => item.searchPos !== -1) .sort((a, b) => a.searchPos - b.searchPos) } function clear() { input.text = "" } anchors { top: parent.top horizontalCenter: parent.horizontalCenter } Rectangle { anchors { top: parent.top left: parent.left right: parent.right margins: 6 } height: 48 color: "#111" radius: 10 TextInput { id: input anchors.verticalCenter: parent.verticalCenter x: parent.width/2 - this.width/2 Behavior on x {NumberAnimation {duration: 300; easing.type: Easing.OutQuint}} focus: true font.pixelSize: 20 color: "white" cursorDelegate: Item {} onCursorPositionChanged: cursorPosition = text.length Keys.onPressed: (event) => { switch (event.key) { case Qt.Key_Return: list.currentItem.execute(); root.close(); break; case Qt.Key_Right: list.incrementCurrentIndex(); break; case Qt.Key_Left: list.decrementCurrentIndex(); break; case Qt.Key_Backspace: // If control is held when backspace is pressed console.log((event.modifiers & 0x4000000).toString(16)) if (event.modifiers & 0x4000000) { input.text = "" } break; }} } } ListView { id: list anchors { top: input.parent.bottom left: parent.left right: parent.right margins: 6 } height: 114 highlightFollowsCurrentItem: true onCurrentIndexChanged: background.indexChanged() orientation: ListView.Horizontal spacing: 6 add: Transition { NumberAnimation { property: "opacity" from: 0 to: 1 duration: 150 }} remove: Transition { NumberAnimation { property: "opacity" from: 1 to: 0 duration: 150 }} displaced: Transition { NumberAnimation { property: "x" duration: 300 easing.type: Easing.OutQuint } NumberAnimation { property: "opacity" to: 1 duration: 150 } } model: ScriptModel {values: currentItems.slice(0, 5)} delegate: Rectangle { id: item anchors { top: parent?.top bottom: parent?.bottom } width: (700 - 6*6)/5 radius: 10 color: "#20181818" ListView.onIsCurrentItemChanged: ListView.isCurrentItem ? selectAnim.start() : deselectAnim.start() property var selectAnim: ColorAnimation { target: item property: "color" to: "#10ffffff" duration: 200 easing.type: Easing.OutQuint } property var deselectAnim: ColorAnimation { target: item onStarted: selectAnim.stop() property: "color" to: "#00181818" duration: 200 easing.type: Easing.InQuint } function execute() { modelData.emoji ? Quickshell.clipboardText = modelData.emoji : modelData.execute() } Column { anchors { left: parent.left right: parent.right verticalCenter: parent.verticalCenter } Image { visible: !modelData.emoji anchors.horizontalCenter: parent.horizontalCenter width: 64 height: width source: Quickshell.iconPath(modelData.icon, "application-default") } Text { anchors.horizontalCenter: parent.horizontalCenter font.pixelSize: 64 text: modelData.emoji ?? "" } Text { anchors { left: parent.left right: parent.right } width: parent.width - 12 text: modelData.name color: "white" font.pixelSize: 16 horizontalAlignment: Text.AlignHCenter elide: Text.ElideRight } } } } }