waffles: context menus for app buttons

This commit is contained in:
end-4
2025-12-07 00:04:24 +01:00
parent 13968db31c
commit 6c460b209c
13 changed files with 155 additions and 20 deletions
@@ -0,0 +1,4 @@
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#000000">
<path d="M13.7045 4.28377C13.3111 3.89615 12.678 3.90084 12.2904 4.29424C11.9027 4.68765 11.9074 5.3208 12.3008 5.70842L17.6712 10.9998H4C3.44771 10.9998 3 11.4475 3 11.9998C3 12.5521 3.44772 12.9998 4 12.9998H17.6646L12.3008 18.2847C11.9074 18.6723 11.9027 19.3055 12.2904 19.6989C12.678 20.0923 13.3111 20.097 13.7045 19.7094L20.6287 12.887C21.1256 12.3974 21.1256 11.5958 20.6287 11.1062L13.7045 4.28377Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 570 B

@@ -0,0 +1,4 @@
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#000000">
<path d="M13.2673 4.20889C12.9674 3.9232 12.4926 3.93475 12.2069 4.23467C11.9212 4.5346 11.9328 5.00933 12.2327 5.29502L18.4841 11.2496H3.75C3.33579 11.2496 3 11.5854 3 11.9996C3 12.4138 3.33579 12.7496 3.75 12.7496H18.4842L12.2327 18.7043C11.9328 18.99 11.9212 19.4648 12.2069 19.7647C12.4926 20.0646 12.9674 20.0762 13.2673 19.7905L20.6862 12.7238C20.8551 12.5629 20.9551 12.3576 20.9861 12.1443C20.9952 12.0975 21 12.0491 21 11.9996C21 11.9501 20.9952 11.9016 20.986 11.8547C20.955 11.6415 20.855 11.4364 20.6862 11.2756L13.2673 4.20889Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 703 B

@@ -0,0 +1,4 @@
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#000000">
<path d="M13 3C13.5523 3 14 3.44772 14 4C14 4.55228 13.5523 5 13 5H6.41435L20.7071 19.2928C21.0976 19.6833 21.0976 20.3164 20.7071 20.707C20.3166 21.0975 19.6834 21.0975 19.2929 20.707L5 6.41408V13C5 13.5523 4.55228 14 4 14C3.44772 14 3 13.5523 3 13V4C3 3.44772 3.44772 3 4 3H13Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 442 B

@@ -0,0 +1,4 @@
<?xml version="1.0" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#000000">
<path d="M13.2461 3C13.6603 3 13.9961 3.33579 13.9961 3.75C13.9961 4.16421 13.6603 4.5 13.2461 4.5H5.57699L20.7768 19.6998C21.0753 19.9983 21.0753 20.4824 20.7768 20.781C20.4782 21.0796 19.9941 21.0796 19.6955 20.781L4.49609 5.58158V13.25C4.49609 13.6642 4.16031 14 3.74609 14C3.33188 14 2.99609 13.6642 2.99609 13.25V3.75C2.99609 3.33579 3.33188 3 3.74609 3H13.2461Z" fill="#000000"/>
</svg>

After

Width:  |  Height:  |  Size: 530 B

@@ -95,6 +95,5 @@ Menu {
delegate: WMenuItem {
id: menuItemDelegate
width: ListView.view?.width
}
}
@@ -55,6 +55,9 @@ MenuItem {
rightInset: inset
horizontalPadding: 11
width: ListView.view?.width
height: visible ? implicitHeight : 0
background: Rectangle {
id: backgroundRect
radius: Looks.radius.medium
@@ -57,7 +57,6 @@ Scope {
Item {
anchors.fill: parent
focus: true
Keys.onPressed: (event) => {
if (event.key === Qt.Key_Escape) {
sessionRoot.hide();
@@ -200,6 +200,16 @@ RowLayout {
resultPreview.entry.execute();
}
}),
...(isAppEntry ? [
searchResultComp.createObject(null, {
name: startPinned ? Translation.tr("Unpin from Start") : Translation.tr("Pin to Start"),
iconName: startPinned ? "keep_off" : "keep",
iconType: LauncherSearchResult.IconType.Material,
execute: () => {
LauncherApps.togglePin(appId);
}
})
] : []),
...(isAppEntry ? [
searchResultComp.createObject(null, {
name: pinned ? Translation.tr("Unpin from taskbar") : Translation.tr("Pin to taskbar"),
@@ -210,20 +220,6 @@ RowLayout {
}
})
] : []),
...(isAppEntry ? [
searchResultComp.createObject(null, {
name: startPinned ? Translation.tr("Unpin from start") : Translation.tr("Pin to start"),
iconName: startPinned ? "keep_off" : "keep",
iconType: LauncherSearchResult.IconType.Material,
execute: () => {
if (Config.options.launcher.pinnedApps.indexOf(appId) !== -1) {
Config.options.launcher.pinnedApps = Config.options.launcher.pinnedApps.filter(id => id !== appId)
} else {
Config.options.launcher.pinnedApps = Config.options.launcher.pinnedApps.concat([appId])
}
}
})
] : [])
];
result = result.concat(resultPreview.entry.actions);
return result;
@@ -274,6 +274,9 @@ Rectangle {
id: smallGridAppButton
property DesktopEntry desktopEntry
property bool pinnedStart: LauncherApps.isPinned(smallGridAppButton.desktopEntry.id);
property bool pinnedTaskbar: TaskbarApps.isPinned(smallGridAppButton.desktopEntry.id);
onClicked: {
GlobalStates.searchOpen = false;
desktopEntry.execute();
@@ -298,6 +301,30 @@ Rectangle {
WToolTip {
text: smallGridAppButton.desktopEntry.name
}
altAction: () => {
appMenu.popup();
}
WMenu {
id: appMenu
downDirection: true
WMenuItem {
icon.name: smallGridAppButton.pinnedStart ? "pin-off" : "pin"
text: smallGridAppButton.pinnedStart ? Translation.tr("Unpin from Start") : Translation.tr("Pin to Start")
onTriggered: {
LauncherApps.togglePin(smallGridAppButton.desktopEntry.id);
}
}
WMenuItem {
icon.name: smallGridAppButton.pinnedTaskbar ? "pin-off" : "pin"
text: smallGridAppButton.pinnedTaskbar ? Translation.tr("Unpin from taskbar") : Translation.tr("Pin to taskbar")
onTriggered: {
TaskbarApps.togglePin(smallGridAppButton.desktopEntry.id);
}
}
}
}
component SmallGridButton: WButton {
@@ -23,9 +23,7 @@ GridLayout {
uniformCellWidths: true
Repeater {
model: ScriptModel {
values: root.desktopEntries
}
model: root.desktopEntries
delegate: StartAppButton {
id: pinnedAppButton
required property var modelData
@@ -14,6 +14,10 @@ import qs.modules.waffle.looks
WButton {
id: root
required property DesktopEntry desktopEntry
property bool pinnedStart: LauncherApps.isPinned(root.desktopEntry.id);
property bool pinnedTaskbar: TaskbarApps.isPinned(root.desktopEntry.id);
implicitWidth: 96
implicitHeight: 84
horizontalPadding: 0
@@ -43,4 +47,52 @@ WButton {
WToolTip {
text: root.desktopEntry.name
}
altAction: () => {
appMenu.popup()
}
WMenu {
id: appMenu
downDirection: true
WMenuItem {
visible: root.pinnedStart
icon.name: "arrow-up-left"
text: Translation.tr("Move to front")
onTriggered: {
LauncherApps.moveToFront(root.desktopEntry.id);
}
}
WMenuItem {
visible: root.pinnedStart
icon.name: "arrow-left"
text: Translation.tr("Move left")
onTriggered: {
LauncherApps.moveLeft(root.desktopEntry.id);
}
}
WMenuItem {
visible: root.pinnedStart
icon.name: "arrow-right"
text: Translation.tr("Move right")
onTriggered: {
LauncherApps.moveRight(root.desktopEntry.id);
}
}
WMenuItem {
icon.name: root.pinnedStart ? "pin-off" : "pin"
text: root.pinnedStart ? Translation.tr("Unpin from Start") : Translation.tr("Pin to Start")
onTriggered: {
LauncherApps.togglePin(root.desktopEntry.id);
}
}
WMenuItem {
icon.name: root.pinnedTaskbar ? "pin-off" : "pin"
text: root.pinnedTaskbar ? Translation.tr("Unpin from taskbar") : Translation.tr("Pin to taskbar")
onTriggered: {
TaskbarApps.togglePin(root.desktopEntry.id);
}
}
}
}
@@ -0,0 +1,41 @@
pragma Singleton
import qs.modules.common
import QtQuick
import Quickshell
Singleton {
id: root
function isPinned(appId) {
return Config.options.launcher.pinnedApps.indexOf(appId) !== -1;
}
function togglePin(appId) {
if (root.isPinned(appId)) {
Config.options.launcher.pinnedApps = Config.options.launcher.pinnedApps.filter(id => id !== appId)
} else {
Config.options.launcher.pinnedApps = Config.options.launcher.pinnedApps.concat([appId])
}
}
function moveToFront(appId) {
if (!root.isPinned(appId)) return;
const pinnedApps = Config.options.launcher.pinnedApps;
Config.options.launcher.pinnedApps = [appId].concat(pinnedApps.filter(id => id !== appId));
}
function moveLeft(appId) {
const pinnedApps = Config.options.launcher.pinnedApps;
const index = pinnedApps.indexOf(appId);
if (index === -1 || index === 0) return;
Config.options.launcher.pinnedApps = pinnedApps.slice(0, index - 1).concat([appId]).concat(pinnedApps[index - 1]).concat(pinnedApps.slice(index + 1));
}
function moveRight(appId) {
const pinnedApps = Config.options.launcher.pinnedApps;
const index = pinnedApps.indexOf(appId);
if (index === -1 || index === pinnedApps.length - 1) return;
Config.options.launcher.pinnedApps = pinnedApps.slice(0, index).concat(pinnedApps[index + 1]).concat([appId]).concat(pinnedApps.slice(index + 2));
}
}
@@ -8,8 +8,12 @@ import Quickshell.Wayland
Singleton {
id: root
function isPinned(appId) {
return Config.options.dock.pinnedApps.indexOf(appId) !== -1;
}
function togglePin(appId) {
if (Config.options.dock.pinnedApps.indexOf(appId) !== -1) {
if (root.isPinned(appId)) {
Config.options.dock.pinnedApps = Config.options.dock.pinnedApps.filter(id => id !== appId)
} else {
Config.options.dock.pinnedApps = Config.options.dock.pinnedApps.concat([appId])