Compare commits

...

4 commits

Author SHA1 Message Date
2Epik4u
d7bf692ba1 Merge branch 'Plasma/6.7' into 'Plasma/6.7'
Fix aero style highlighted text

See merge request aeroshell/atp/aerothemeplasma!75
2026-09-15 05:57:47 +00:00
wackyideas
ed0037c751 OftenUsedView: fix mismatch on launching applications [skip ci] 2026-09-15 02:58:06 +02:00
wackyideas
458449b1c9 Add type-ahead feature from upstream [skip ci] 2026-09-13 19:15:25 +02:00
2Epik4u
84a8eb8b50 Fix aero style highlighted text 2026-08-18 23:49:54 -04:00
4 changed files with 93 additions and 6 deletions

View file

@ -77,14 +77,27 @@ Item {
baseView.currentIndex = -1;
}
Connections {
target: kicker
target: Plasmoid
function onExpandedChanged() {
if (!kicker.expanded) {
if (!Plasmoid.expanded) {
baseView.currentIndex = -1;
}
}
}
/*
* The KSortFilterProxyModel has a nasty behavior (with this particular
* source model) where only the first row will be updated (twice instantly),
* which invalidates the index list. In that case, we want a full update
* instead of a partial update, so the filtering can update the index map.
*/
Timer {
id: refreshTimer
interval: 50
onTriggered: {
Qt.callLater(() => { recentUsageModel.refresh()});
}
}
KickoffListView {
id: baseView
@ -96,25 +109,43 @@ Item {
interactive: contentHeight > height
//model: recentUsageModel //rootModel.modelForRow(0)
model: KItemModels.KSortFilterProxyModel {
id: sortModel
sourceModel: recentUsageModel
property var favoritesModel: globalFavorites
property int favoritesCount: sourceModel.favoritesModel.count
property int favoritesFound: 0
/*
* Because the trigger function relies on the original model's
* index values, we need a way to map the index values from the filtered
* model to the values from the source model.
*/
property list<int> originalIndexList
onFavoritesCountChanged: Qt.callLater(() => { sourceModel.refresh()});
onCountChanged: Qt.callLater(() => {
if(count > Plasmoid.configuration.numberRows) sourceModel.refresh();
})
function trigger(index, str, ptr) {
sourceModel.trigger(index, str, ptr);
if(typeof originalIndexList[index] !== "undefined") {
sourceModel.trigger(originalIndexList[index], str, ptr);
}
}
filterRowCallback: function(source_row, source_parent) {
if(source_row == 0) favoritesFound = 0;
if(source_row == 0) {
refreshTimer.start();
originalIndexList.length = 0;
favoritesFound = 0;
} else {
refreshTimer.stop();
}
const FavoriteIdRole = sourceModel.KItemModels.KRoleNames.role("favoriteId");
const favoriteId = sourceModel.data(sourceModel.index(source_row, 0, source_parent), FavoriteIdRole);
var hasFavorite = favoritesIds.idList.indexOf(favoriteId) === -1
if(!hasFavorite) favoritesFound++;
return hasFavorite && source_row < (Plasmoid.configuration.numberRows+favoritesFound)// - sourceModel.favoritesModel.count;
var shouldAccept = hasFavorite && source_row < (Plasmoid.configuration.numberRows+favoritesFound);
if(shouldAccept) {
originalIndexList.push(source_row);
}
return shouldAccept;// - sourceModel.favoritesModel.count;
};
}

View file

@ -147,6 +147,10 @@
<label>Use drop shadows for icons on the desktop.</label>
<default>false</default>
</entry>
<entry name="useTypeAhead" type="Bool">
<label>Select icons on the desktop by typing their names.</label>
<default>true</default>
</entry>
</group>
<group name="Watermark">

View file

@ -46,6 +46,7 @@ Item {
property alias cfg_iconShadows: iconShadows.checked
property alias cfg_selectionStyle: selectionStyle.currentIndex
property alias cfg_useTypeAhead: typeAhead.checked
readonly property bool lockedByKiosk: !KAuthorized.authorize("editable_desktop_icons")
@ -314,6 +315,7 @@ Item {
text: i18n("Show selection markers")
}
CheckBox {
id: popups
visible: !isPopup
@ -361,6 +363,11 @@ Item {
i18nc("@item:inlistbox how the selection should be", "Classic"),
]
}
CheckBox {
id: typeAhead
text: i18n("Select items by typing on the desktop")
}
CheckBox {
id: previews

View file

@ -1017,6 +1017,12 @@ FocusScope {
Behavior on contentX { id: smoothX; enabled: false; SmoothedAnimation { velocity: 700 } }
Behavior on contentY { id: smoothY; enabled: false; SmoothedAnimation { velocity: 700 } }
property string searchString: ""
Timer {
id: typeAheadTimer
interval: 500 // Resets search string after 0.5 seconds of inactivity
onTriggered: searchString = ""
}
Keys.onReturnPressed: event => {
if (event.modifiers === Qt.AltModifier) {
dir.openPropertiesDialog();
@ -1099,6 +1105,40 @@ FocusScope {
dir.refresh(true);
} else if (event.matches(StandardKey.SelectAll)) {
positioner.setRangeSelected(0, count - 1);
} else if ( (root.isPopup || Plasmoid.configuration.useTypeAhead) && event.text.length === 1 && event.modifiers === Qt.NoModifier) {
typeAheadTimer.restart();
const charPressed = event.text.toLowerCase();
if (searchString.length >= 1 && searchString.indexOf(charPressed) !== 0) {
searchString += charPressed;
} else if (searchString !== charPressed) {
searchString = charPressed;
}
let matches = [];
for (let i = 0; i < gridView.count; i++) {
const itemData = positioner.data(positioner.index(i, 0), Qt.DisplayRole);
if (itemData && itemData.toLowerCase().indexOf(searchString) === 0) {
matches.push(i);
}
}
if (matches.length > 0) {
let nextIdx = matches[0];
if (searchString.length === 1) {
for (let j = 0; j < matches.length; j++) {
if (matches[j] > gridView.currentIndex) {
nextIdx = matches[j];
break;
}
}
}
currentIndex = nextIdx;
dir.clearSelection();
dir.setSelected(positioner.map(nextIdx));
} else {
searchString = charPressed;
}
} else {
event.accepted = false;
}
@ -1269,6 +1309,11 @@ FocusScope {
previewPlugins: Plasmoid.configuration.previewPlugins
applet: Plasmoid
onSelectionChanged: {
if(gridView.currentIndex === -1) {
gridView.searchString = "";
}
}
onListingCompleted: {
if (!gridView.model && root.expanded) {
gridView.model = positioner;