add bg, taskbar items

This commit is contained in:
end-4
2025-11-11 20:23:09 +01:00
parent dec65aea17
commit a412688af2
16 changed files with 424 additions and 126 deletions
@@ -0,0 +1,5 @@
The "search" and "task view" icons are from here, with modifications
https://www.figma.com/community/file/1123040825921884189/windows-11
License: CC BY 4.0
@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="63.999989"
height="61.62962"
viewBox="0 0 26.999999 26"
fill="none"
version="1.1"
id="svg3"
sodipodi:docname="task-view-dark.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="6.0349946"
inkscape:cx="29.328941"
inkscape:cy="30.820243"
inkscape:window-width="1403"
inkscape:window-height="734"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g3" />
<g
id="g3"
transform="translate(0.03879728,0.03736111)">
<rect
opacity="0.9"
x="9.4441719"
width="17.938911"
height="15.248073"
rx="0.89694548"
fill="#ffffff"
id="rect1"
y="0.8962484"
style="fill:url(#linearGradient4);fill-opacity:1;stroke:#e2e2e2;stroke-width:0.179719;stroke-dasharray:none;stroke-opacity:1"
transform="translate(-2.3652457,0.93944352)" />
<rect
y="9"
width="20"
height="17"
rx="1"
fill="url(#paint0_linear_505_17)"
id="rect2"
x="0"
style="mix-blend-mode:exclusion;stroke-width:1.00007574;stroke-dasharray:none;fill:url(#paint0_linear_505_17-3)"
transform="matrix(0.89768213,0,0,0.89768213,1.8147076,0.83970922)" />
<g
id="g1"
transform="translate(-2.3652457,0.93944351)">
<g
style="mix-blend-mode:exclusion;stroke-width:1.00007574;stroke-dasharray:none"
id="g2"
transform="matrix(0.89768215,0,0,0.89768215,4.1799533,-0.09973431)" />
</g>
</g>
<defs
id="defs3">
<linearGradient
id="paint0_linear_505_17"
x1="-2.75374e-08"
y1="9.2399397"
x2="18.808399"
y2="26.838499"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#717171"
id="stop2"
offset="0"
style="stop-color:#717171;stop-opacity:0.73333335;" />
<stop
offset="1"
stop-color="#4F4F4F"
id="stop3"
style="stop-color:#4f4f4f;stop-opacity:0.73333335;" />
</linearGradient>
<linearGradient
id="paint0_linear_505_17-3"
x1="-2.75374e-08"
y1="9.2399397"
x2="18.808399"
y2="26.838499"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#717171"
id="stop2-6"
offset="0"
style="stop-color:#717171;stop-opacity:0.60000002;" />
<stop
offset="1"
stop-color="#4F4F4F"
id="stop3-7"
style="stop-color:#565656;stop-opacity:0.60000002;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1"
id="linearGradient4"
x1="7.1907158"
y1="8.3216944"
x2="24.995911"
y2="10.507897"
gradientUnits="userSpaceOnUse"
gradientTransform="translate(2.3203156,-0.89451377)" />
<linearGradient
id="linearGradient1"
inkscape:collect="always">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop1" />
<stop
style="stop-color:#e6e6e6;stop-opacity:1;"
offset="1"
id="stop4" />
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

@@ -0,0 +1,104 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="63.999989"
height="61.62962"
viewBox="0 0 26.999999 26"
fill="none"
version="1.1"
id="svg3"
sodipodi:docname="task-view-light.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="4.7640337"
inkscape:cx="73.677061"
inkscape:cy="43.030762"
inkscape:window-width="1439"
inkscape:window-height="1020"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g3" />
<g
id="g3"
transform="translate(0.03879728,0.03736111)">
<g
style="mix-blend-mode:exclusion;stroke-width:0.999982;stroke-dasharray:none"
id="g2"
transform="matrix(0.89768215,0,0,0.89768215,1.8596377,0.79477946)">
<rect
y="9"
width="20"
height="17"
rx="1"
fill="url(#paint0_linear_505_17)"
id="rect2"
x="0"
style="fill:url(#paint0_linear_505_17);stroke-width:0.999982;stroke-dasharray:none" />
</g>
<rect
opacity="0.9"
x="7.1238561"
width="17.938911"
height="15.248073"
rx="0.89694548"
fill="#ffffff"
id="rect1"
y="1.7907622"
style="fill:url(#linearGradient4);fill-opacity:1;stroke-width:0.17971878;stroke-dasharray:none;stroke:#d4d4d4;stroke-opacity:1" />
</g>
<defs
id="defs3">
<linearGradient
id="linearGradient1"
inkscape:collect="always">
<stop
style="stop-color:#ffffff;stop-opacity:0.80000001;"
offset="0"
id="stop1" />
<stop
style="stop-color:#e6e6e6;stop-opacity:0.80000001;"
offset="1"
id="stop4" />
</linearGradient>
<linearGradient
id="paint0_linear_505_17"
x1="-2.75374e-08"
y1="9.2399397"
x2="18.808399"
y2="26.838499"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#717171"
id="stop2"
offset="0"
style="stop-color:#464543;stop-opacity:1;" />
<stop
offset="1"
stop-color="#4F4F4F"
id="stop3"
style="stop-color:#1f1f1f;stop-opacity:1;" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1"
id="linearGradient4"
x1="7.1729918"
y1="8.4772339"
x2="25.013634"
y2="10.352362"
gradientUnits="userSpaceOnUse" />
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="63.999989"
height="61.62962"
viewBox="0 0 26.999999 26"
fill="none"
version="1.1"
id="svg3"
sodipodi:docname="Group 6.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview3"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="4.7640336"
inkscape:cx="36.628625"
inkscape:cy="33.794892"
inkscape:window-width="1340"
inkscape:window-height="968"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="svg3" />
<g
id="g3"
transform="translate(0.03879728,0.03736111)">
<rect
opacity="0.9"
x="7.8752632"
width="17.187504"
height="14.609377"
rx="0.85937512"
fill="#ffffff"
id="rect1"
y="1.7907622"
style="stroke-width:0.859375" />
<g
style="mix-blend-mode:exclusion"
id="g2"
transform="matrix(0.85937512,0,0,0.85937512,1.8596377,1.7907622)">
<rect
y="9"
width="20"
height="17"
rx="1"
fill="url(#paint0_linear_505_17)"
id="rect2"
x="0"
style="fill:url(#paint0_linear_505_17)" />
</g>
</g>
<defs
id="defs3">
<linearGradient
id="paint0_linear_505_17"
x1="-2.75374e-08"
y1="9.2399397"
x2="18.808399"
y2="26.838499"
gradientUnits="userSpaceOnUse">
<stop
stop-color="#717171"
id="stop2" />
<stop
offset="1"
stop-color="#4F4F4F"
id="stop3" />
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.0 KiB

@@ -389,7 +389,7 @@ Singleton {
property bool darkenScreen: true property bool darkenScreen: true
property real clickthroughOpacity: 0.8 property real clickthroughOpacity: 0.8
property JsonObject floatingImage: JsonObject { property JsonObject floatingImage: JsonObject {
property string imageSource: "https://cdn.discordapp.com/attachments/961693710968557598/1369635662390759434/image.gif?ex=6911cb1c&is=6910799c&hm=4450244066c0a7a6e5d2bdd195f47388eb5e7f9dd53d3931e99ad9642c638a00&" property string imageSource: "https://media.tenor.com/H5U5bJzj3oAAAAAi/kukuru.gif"
property real scale: 0.5 property real scale: 0.5
} }
} }
@@ -561,7 +561,7 @@ Singleton {
property JsonObject waffles: JsonObject { property JsonObject waffles: JsonObject {
property JsonObject bar: JsonObject { property JsonObject bar: JsonObject {
property bool bottom: true property bool bottom: true
property bool leftAlignApps: true property bool leftAlignApps: false
} }
} }
} }
@@ -17,8 +17,8 @@ DockButton {
property real countDotHeight: 4 property real countDotHeight: 4
property bool appIsActive: appToplevel.toplevels.find(t => (t.activated == true)) !== undefined property bool appIsActive: appToplevel.toplevels.find(t => (t.activated == true)) !== undefined
property bool isSeparator: appToplevel.appId === "SEPARATOR" readonly property bool isSeparator: appToplevel.appId === "SEPARATOR"
property var desktopEntry: DesktopEntries.heuristicLookup(appToplevel.appId) readonly property var desktopEntry: DesktopEntries.heuristicLookup(appToplevel.appId)
enabled: !isSeparator enabled: !isSeparator
implicitWidth: isSeparator ? 1 : implicitHeight - topInset - bottomInset implicitWidth: isSeparator ? 1 : implicitHeight - topInset - bottomInset
@@ -1,6 +1,3 @@
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import Qt5Compat.GraphicalEffects import Qt5Compat.GraphicalEffects
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
@@ -8,6 +5,10 @@ import QtQuick.Layouts
import Quickshell import Quickshell
import Quickshell.Widgets import Quickshell.Widgets
import Quickshell.Wayland import Quickshell.Wayland
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
Item { Item {
id: root id: root
@@ -40,44 +41,7 @@ Item {
model: ScriptModel { model: ScriptModel {
objectProp: "appId" objectProp: "appId"
values: { values: TaskbarApps.apps
var map = new Map();
// Pinned apps
const pinnedApps = Config.options?.dock.pinnedApps ?? [];
for (const appId of pinnedApps) {
if (!map.has(appId.toLowerCase())) map.set(appId.toLowerCase(), ({
pinned: true,
toplevels: []
}));
}
// Separator
if (pinnedApps.length > 0) {
map.set("SEPARATOR", { pinned: false, toplevels: [] });
}
// Ignored apps
const ignoredRegexStrings = Config.options?.dock.ignoredAppRegexes ?? [];
const ignoredRegexes = ignoredRegexStrings.map(pattern => new RegExp(pattern, "i"));
// Open windows
for (const toplevel of ToplevelManager.toplevels.values) {
if (ignoredRegexes.some(re => re.test(toplevel.appId))) continue;
if (!map.has(toplevel.appId.toLowerCase())) map.set(toplevel.appId.toLowerCase(), ({
pinned: false,
toplevels: []
}));
map.get(toplevel.appId.toLowerCase()).toplevels.push(toplevel);
}
var values = [];
for (const [key, value] of map) {
values.push({ appId: key, toplevels: value.toplevels, pinned: value.pinned });
}
return values;
}
} }
delegate: DockAppButton { delegate: DockAppButton {
required property var modelData required property var modelData
@@ -0,0 +1,46 @@
pragma ComponentBehavior: Bound
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.widgets.widgetCanvas
import QtQuick
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Hyprland
import qs.modules.ii.background.widgets
import qs.modules.ii.background.widgets.clock
import qs.modules.ii.background.widgets.weather
Variants {
id: root
model: Quickshell.screens
PanelWindow {
id: panelRoot
required property var modelData
screen: modelData
exclusionMode: ExclusionMode.Ignore
WlrLayershell.layer: WlrLayer.Bottom
WlrLayershell.namespace: "quickshell:background"
anchors {
top: true
bottom: true
left: true
right: true
}
color: "transparent"
StyledImage {
anchors.fill: parent
source: Config.options.background.wallpaperPath
fillMode: Image.PreserveAspectCrop
}
}
}
@@ -0,0 +1,17 @@
import QtQuick
import QtQuick.Layouts
import qs.services
import qs.modules.common
import qs.modules.waffle.looks
AppButton {
id: root
required property var toplevel
readonly property bool isSeparator: toplevel.appId === "SEPARATOR"
readonly property var desktopEntry: DesktopEntries.heuristicLookup(toplevel.appId)
Layout.fillHeight: true
iconName: toplevel.appId
}
@@ -10,6 +10,7 @@ AppButton {
id: root id: root
iconName: "task-view" iconName: "task-view"
separateLightDark: true
checked: GlobalStates.overviewOpen checked: GlobalStates.overviewOpen
onClicked: { onClicked: {
@@ -0,0 +1,34 @@
import QtQuick
import QtQuick.Layouts
import Quickshell
import qs.services
import qs.modules.common
import qs.modules.waffle.looks
Item {
id: root
Layout.fillHeight: true
implicitHeight: row.implicitHeight
implicitWidth: row.implicitWidth
// Apps row
RowLayout {
id: row
anchors.fill: parent
spacing: 4
Repeater {
model: ScriptModel {
objectProp: "appId"
values: TaskbarApps.apps.filter(app => app.appId !== "SEPARATOR")
}
delegate: TaskAppButton {
required property var modelData
toplevel: modelData
}
}
}
// TODO: Previews popup
}
@@ -23,7 +23,7 @@ Scope {
screen: modelData screen: modelData
exclusionMode: ExclusionMode.Ignore exclusionMode: ExclusionMode.Ignore
exclusiveZone: implicitHeight exclusiveZone: implicitHeight
WlrLayershell.namespace: "quickshell:wBar" WlrLayershell.namespace: "quickshell:bar"
anchors { anchors {
left: true left: true
@@ -57,6 +57,7 @@ Rectangle {
StartButton {} StartButton {}
SearchButton {} SearchButton {}
TaskViewButton {} TaskViewButton {}
Tasks {}
} }
BarGroupRow { BarGroupRow {
@@ -1,6 +1,7 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import org.kde.kirigami as Kirigami import org.kde.kirigami as Kirigami
import qs
import qs.services import qs.services
import qs.modules.common import qs.modules.common
import qs.modules.waffle.looks import qs.modules.waffle.looks
@@ -13,6 +14,11 @@ AppButton {
implicitWidth: expandedForm ? 148 : (height - topInset - bottomInset + leftInset + rightInset) implicitWidth: expandedForm ? 148 : (height - topInset - bottomInset + leftInset + rightInset)
iconName: "widgets" iconName: "widgets"
checked: GlobalStates.sidebarLeftOpen
onClicked: {
GlobalStates.sidebarLeftOpen = !GlobalStates.sidebarLeftOpen
}
contentItem: Item { contentItem: Item {
anchors { anchors {
verticalCenter: parent.verticalCenter verticalCenter: parent.verticalCenter
@@ -29,11 +35,20 @@ AppButton {
horizontalCenter: root.expandedForm ? undefined : parent.horizontalCenter horizontalCenter: root.expandedForm ? undefined : parent.horizontalCenter
margins: 8 margins: 8
} }
spacing: 6
AppIcon { AppIcon {
id: iconWidget id: iconWidget
anchors.verticalCenter: parent.verticalCenter
iconName: root.iconName iconName: root.iconName
} }
Column {
anchors.verticalCenter: parent.verticalCenter
WText {
text: Translation.tr("Widgets")
}
}
} }
} }
} }
@@ -0,0 +1,60 @@
pragma Singleton
import qs.modules.common
import QtQuick
import Quickshell
import Quickshell.Wayland
Singleton {
id: root
property list<var> apps: {
var map = new Map();
// Pinned apps
const pinnedApps = Config.options?.dock.pinnedApps ?? [];
for (const appId of pinnedApps) {
if (!map.has(appId.toLowerCase())) map.set(appId.toLowerCase(), ({
pinned: true,
toplevels: []
}));
}
// Separator
if (pinnedApps.length > 0) {
map.set("SEPARATOR", { pinned: false, toplevels: [] });
}
// Ignored apps
const ignoredRegexStrings = Config.options?.dock.ignoredAppRegexes ?? [];
const ignoredRegexes = ignoredRegexStrings.map(pattern => new RegExp(pattern, "i"));
// Open windows
for (const toplevel of ToplevelManager.toplevels.values) {
if (ignoredRegexes.some(re => re.test(toplevel.appId))) continue;
if (!map.has(toplevel.appId.toLowerCase())) map.set(toplevel.appId.toLowerCase(), ({
pinned: false,
toplevels: []
}));
map.get(toplevel.appId.toLowerCase()).toplevels.push(toplevel);
}
var values = [];
for (const [key, value] of map) {
values.push(appEntryComp.createObject(null, { appId: key, toplevels: value.toplevels, pinned: value.pinned }));
}
return values;
}
component TaskbarAppEntry: QtObject {
id: wrapper
required property string appId
required property list<var> toplevels
required property bool pinned
}
Component {
id: appEntryComp
TaskbarAppEntry {}
}
}
+3 -1
View File
@@ -28,6 +28,7 @@ import qs.modules.ii.overlay
import qs.modules.ii.verticalBar import qs.modules.ii.verticalBar
import qs.modules.ii.wallpaperSelector import qs.modules.ii.wallpaperSelector
import qs.modules.waffle.background
import qs.modules.waffle.bar import qs.modules.waffle.bar
import QtQuick import QtQuick
@@ -74,6 +75,7 @@ ShellRoot {
PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} } PanelLoader { identifier: "iiVerticalBar"; extraCondition: Config.options.bar.vertical; component: VerticalBar {} }
PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} } PanelLoader { identifier: "iiWallpaperSelector"; component: WallpaperSelector {} }
PanelLoader { identifier: "wBar"; component: WaffleBar {} } PanelLoader { identifier: "wBar"; component: WaffleBar {} }
PanelLoader { identifier: "wBackground"; component: WaffleBackground {} }
component PanelLoader: LazyLoader { component PanelLoader: LazyLoader {
required property string identifier required property string identifier
@@ -85,7 +87,7 @@ ShellRoot {
property list<string> families: ["ii", "waffle"] property list<string> families: ["ii", "waffle"]
property var panelFamilies: ({ property var panelFamilies: ({
"ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"], "ii": ["iiBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiVerticalBar", "iiWallpaperSelector"],
"waffle": ["wBar", "iiBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiWallpaperSelector"], "waffle": ["wBar", "wBackground", "iiCheatsheet", "iiDock", "iiLock", "iiMediaControls", "iiNotificationPopup", "iiOnScreenDisplay", "iiOnScreenKeyboard", "iiOverlay", "iiOverview", "iiPolkit", "iiRegionSelector", "iiReloadPopup", "iiScreenCorners", "iiSessionScreen", "iiSidebarLeft", "iiSidebarRight", "iiWallpaperSelector"],
}) })
function cyclePanelFamily() { function cyclePanelFamily() {
const currentIndex = families.indexOf(Config.options.panelFamily) const currentIndex = families.indexOf(Config.options.panelFamily)