Merge branch 'main' into module/wifi
C++ / fmt (pull_request) Successful in 5s
JS/TS / fmt (pull_request) Successful in 17s
JS/TS / lint (pull_request) Successful in 16s
Python / fmt (pull_request) Successful in 31s
Python / lint (pull_request) Successful in 41s
Python / test (pull_request) Successful in 1m5s
Python / typecheck (pull_request) Successful in 1m15s
Rust / clippy (pull_request) Failing after 12m43s
Rust / fmt (pull_request) Failing after 12m57s
Rust / build (pull_request) Failing after 13m33s
Python / buildcheck (pull_request) Failing after 13m45s
C++ / clang-tidy (pull_request) Failing after 14m23s
C++ / build (pull_request) Failing after 14m25s

This commit is contained in:
2026-08-15 20:38:54 +02:00
377 changed files with 7398 additions and 8423 deletions
+8 -7
View File
@@ -2,7 +2,8 @@ pragma Singleton
import Quickshell
import Quickshell.Services.UPower
import qs.Config
import ZShell.Config
import qs.Services
Singleton {
id: root
@@ -10,18 +11,18 @@ Singleton {
readonly property var colors: {
if (deviceState === UPowerDeviceState.Charging || deviceState === UPowerDeviceState.FullyCharged)
return {
fg: DynamicColors.swapRG(DynamicColors.palette.m3error),
bg: DynamicColors.swapRG(DynamicColors.palette.m3onError)
fg: Colors.swapRG(Colors.palette.m3error),
bg: Colors.swapRG(Colors.palette.m3onError)
};
else if (currentPerc <= 0.2)
return {
fg: DynamicColors.palette.m3error,
bg: DynamicColors.palette.m3onError
fg: Colors.palette.m3error,
bg: Colors.palette.m3onError
};
else
return {
fg: DynamicColors.palette.m3onSurface,
bg: DynamicColors.palette.m3surface
fg: Colors.palette.m3onSurface,
bg: Colors.palette.m3surface
};
}
readonly property real currentPerc: UPower.displayDevice.percentage
+1 -1
View File
@@ -4,7 +4,7 @@ pragma ComponentBehavior: Bound
import Quickshell
import Quickshell.Io
import QtQuick
import qs.Config
import ZShell.Config
import qs.Components
Singleton {
+1 -1
View File
@@ -4,7 +4,7 @@ pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Config
import ZShell.Config
import "../scripts/fuzzysort.js" as Fuzzy
Singleton {
+1 -1
View File
@@ -4,7 +4,7 @@ import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.Components
import qs.Config
import ZShell.Config
Singleton {
id: root
+1 -1
View File
@@ -4,7 +4,7 @@ import QtQuick
import Quickshell
import Quickshell.Io
import ZShell
import qs.Config
import ZShell.Config
Singleton {
id: root
+1 -1
View File
@@ -3,7 +3,7 @@ pragma Singleton
import Quickshell
import QtQuick
import ZShell.Services
import qs.Config
import ZShell.Config
Singleton {
id: root
+1 -1
View File
@@ -1,6 +1,6 @@
pragma Singleton
import QtQuick
import ZShell.Config
import Quickshell
import Quickshell.Services.Notifications
+6 -5
View File
@@ -4,8 +4,9 @@ import Quickshell
import QtQuick
import qs.Modules
import qs.Helpers
import qs.Config
import ZShell.Config
import qs.Paths
import qs.Services
Singleton {
id: root
@@ -55,10 +56,10 @@ Singleton {
}
if (isDarkTime) {
if (DynamicColors.light)
if (Colors.light)
root.applyDarkMode();
} else {
if (!DynamicColors.light)
if (!Colors.light)
root.applyLightMode();
}
}
@@ -86,10 +87,10 @@ Singleton {
}
if (isDarkTime) {
if (DynamicColors.light)
if (Colors.light)
root.applyDarkMode();
} else {
if (!DynamicColors.light)
if (!Colors.light)
root.applyLightMode();
}
}
+1 -1
View File
@@ -4,7 +4,7 @@ import QtQuick
import Quickshell
import Quickshell.Io
import ZShell.Internal
import qs.Config
import ZShell.Config
Singleton {
id: root
Regular → Executable
+165 -65
View File
@@ -6,10 +6,12 @@ import Quickshell.Wayland
import QtQuick
import QtQuick.Effects
import qs.Components
import qs.Config
import qs.Helpers
import ZShell.Config
import qs.Helpers.Picker
import qs.Paths
import qs.Services
MouseArea {
Item {
id: root
property list<var> clients: {
@@ -29,9 +31,11 @@ MouseArea {
readonly property int cornerRadius: Hypr.options.decoration.rounding
property real ex: screen.width
property real ey: screen.height
property color inkColor: "#ff3b30"
required property LazyLoader loader
property string mode: "select"
property bool onClient
property real realBorderWidth: onClient ? (Hypr.options.general.border_size ?? 1) : 2
property real realBorderWidth: 2
property real realRounding: onClient ? (Hypr.options.decoration.rounding ?? 0) : 0
property real rsx: Math.min(sx, ex)
property real rsy: Math.min(sy, ey)
@@ -48,6 +52,12 @@ MouseArea {
property real sw: Math.abs(sx - ex)
property real sx: 0
property real sy: 0
property string tool: "move"
function cancel(): void {
annotations.clearAll();
closeAnim.start();
}
function checkClientRects(x: real, y: real): void {
for (const client of clients) {
@@ -71,24 +81,49 @@ MouseArea {
}
}
function save(): void {
const tmpfile = Qt.resolvedUrl(`/tmp/zshell-picker-${Quickshell.processId}-${Date.now()}.png`);
function enterEditMode(): void {
mode = "edit";
tool = "move";
}
function save(copyToClipboard: bool): void {
const rounding = root.cornerRadius > 0;
const shadow_blur = root.shadowRange / root.shadowRenderPower;
const r = Math.floor(root.shadowColor.r * 256);
const g = Math.floor(root.shadowColor.g * 256);
const b = Math.floor(root.shadowColor.b * 256);
const a = Math.floor(root.shadowColor.a * 256);
const tmpfile = Qt.resolvedUrl(`/tmp/zshell-picker-${Quickshell.processId}-${Date.now()}.png`);
const args = Config.screenshot.mode === "auto" ? ["--rounding", `${rounding}`, "--radius", root.cornerRadius, "--shadow", root.shadowEnabled, "--shadow-blur", `${shadow_blur}`, "--shadow-color", `${r},${g},${b},${a}`, "--shadow-offset-x", root.shadowOffset[0], "--shadow-offset-y", root.shadowOffset[1]] : [];
const cmd = Config.screenshot.enable_pp ? ["zshell-img-tools", "--scale", root.scaleRatio, ...args, "--image"] : ["swappy", "-f"];
ZShellIo.saveItem(screencopy, tmpfile, Qt.rect(Math.ceil(rsx), Math.ceil(rsy), Math.floor(sw), Math.floor(sh)), path => Quickshell.execDetached([...cmd, path]));
const postCmd = Config.screenshot.enable_pp ? ["zshell-img-tools", "--scale", root.scaleRatio, ...args, "--image"] : null;
overlay.visible = border.visible = false;
handles.visible = false;
toolbar.visible = false;
ZShellIo.saveItem(captureLayer, tmpfile, Qt.rect(Math.ceil(rsx), Math.ceil(rsy), Math.floor(sw), Math.floor(sh)), path => {
const finalize = finalPath => {
if (copyToClipboard) {
Quickshell.execDetached(["sh", "-c", `wl-copy --type image/png < '${finalPath.replace(/'/g, `'\\''`)}'`]);
}
if (!copyToClipboard || Config.screenshot.saveOnCopy) {
const dest = `${Paths.screenshots}/zshell-${Date.now()}.png`;
Quickshell.execDetached(["sh", "-c", `mkdir -p "$(dirname '${dest}')" && cp '${path.replace(/'/g, `'\\''`)}' '${dest}'`]);
}
};
if (postCmd) {
Quickshell.execDetached(postCmd.concat([path]));
finalize(path);
} else {
finalize(path);
}
});
closeAnim.start();
}
anchors.fill: parent
cursorShape: Qt.CrossCursor
focus: true
hoverEnabled: true
opacity: 0
Behavior on opacity {
@@ -97,25 +132,25 @@ MouseArea {
}
}
Behavior on rsx {
enabled: !root.pressed
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
}
}
Behavior on rsy {
enabled: !root.pressed
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
}
}
Behavior on sh {
enabled: !root.pressed
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
}
}
Behavior on sw {
enabled: !root.pressed
enabled: !selectArea.pressed && root.mode === "select"
ExAnim {
}
@@ -123,8 +158,7 @@ MouseArea {
Component.onCompleted: {
Hypr.extras.refreshOptions();
if (loader.freeze)
clients = clients;
screencopy.active = true;
opacity = 1;
@@ -144,48 +178,49 @@ MouseArea {
ey = screen.height / 2 + 100;
}
}
Keys.onEscapePressed: closeAnim.start()
onClientsChanged: checkClientRects(mouseX, mouseY)
onPositionChanged: event => {
const x = event.x;
const y = event.y;
if (pressed) {
onClient = false;
sx = ssx;
sy = ssy;
ex = x;
ey = y;
} else if (!saveTimer.running) {
checkClientRects(x, y);
Keys.onEscapePressed: root.mode === "edit" ? cancel() : closeAnim.start()
Keys.onPressed: e => {
if ((e.key == Qt.Key_C) && (e.modifiers & Qt.ControlModifier)) {
save(true);
e.accepted = true;
} else if ((e.key == Qt.Key_S) && (e.modifiers & Qt.ControlModifier)) {
save(false);
e.accepted = true;
}
}
onPressed: event => {
ssx = event.x;
ssy = event.y;
onClientsChanged: {
if (root.mode === "select")
checkClientRects(selectArea.mouseX, selectArea.mouseY);
}
onReleased: {
if (closeAnim.running)
return;
if (root.loader.freeze) {
saveTimer.start();
} else {
overlay.visible = border.visible = false;
screencopy.visible = false;
screencopy.active = true;
saveTimer.start();
MouseArea {
id: selectArea
anchors.fill: parent
cursorShape: Qt.CrossCursor
enabled: root.mode === "select"
hoverEnabled: true
visible: root.mode === "select"
onPositionChanged: event => {
const x = event.x;
const y = event.y;
if (pressed) {
root.onClient = false;
root.sx = root.ssx;
root.sy = root.ssy;
root.ex = x;
root.ey = y;
} else {
root.checkClientRects(x, y);
}
}
}
Timer {
id: saveTimer
interval: 25
repeat: false
running: false
onTriggered: root.save()
onPressed: event => {
root.ssx = event.x;
root.ssy = event.y;
}
onReleased: root.enterEditMode()
}
SequentialAnimation {
@@ -231,16 +266,38 @@ MouseArea {
}
}
Loader {
id: screencopy
Item {
id: captureLayer
active: root.loader.freeze
anchors.fill: parent
asynchronous: true
sourceComponent: ScreencopyView {
captureSource: root.screen
paintCursor: false
Loader {
id: screencopy
active: false
anchors.fill: parent
asynchronous: true
sourceComponent: ScreencopyView {
captureSource: root.screen
paintCursor: false
}
}
AnnotationCanvas {
id: annotations
anchors.fill: parent
inkColor: root.inkColor
layer.enabled: true
tool: root.mode === "edit" && root.tool !== "move" ? root.tool : "none"
layer.effect: MultiEffect {
maskEnabled: true
maskSource: selectionWrapper
maskSpreadAtMin: 1
maskThresholdMin: 0.5
}
}
}
@@ -252,7 +309,7 @@ MouseArea {
layer.enabled: true
opacity: 0.3
radius: root.realRounding
visible: screencopy.item.hasContent || !root.loader.freeze
visible: screencopy.item?.hasContent ?? false
layer.effect: MultiEffect {
maskEnabled: true
@@ -284,13 +341,13 @@ MouseArea {
Rectangle {
id: border
border.color: DynamicColors.palette.m3primary
border.color: Colors.palette.m3primary
border.width: root.realBorderWidth
color: "transparent"
implicitHeight: selectionRect.implicitHeight + root.realBorderWidth * 2
implicitWidth: selectionRect.implicitWidth + root.realBorderWidth * 2
radius: root.realRounding > 0 ? root.realRounding + root.realBorderWidth : 0
visible: screencopy.item.hasContent || !root.loader.freeze
visible: screencopy.item?.hasContent ?? false
x: selectionRect.x - root.realBorderWidth
y: selectionRect.y - root.realBorderWidth
@@ -300,8 +357,51 @@ MouseArea {
}
}
SelectionHandles {
id: handles
selH: root.sh
selW: root.sw
selX: root.rsx
selY: root.rsy
visible: root.mode === "edit" && root.tool === "move"
onBoundsChanged: (x, y, w, h) => {
root.sx = x;
root.sy = y;
root.ex = x + w;
root.ey = y + h;
}
onMoveBy: (dx, dy) => {
const w = root.sw, h = root.sh;
let nx = root.rsx + dx, ny = root.rsy + dy;
nx = Math.max(0, Math.min(nx, root.screen.width - w));
ny = Math.max(0, Math.min(ny, root.screen.height - h));
root.sx = nx;
root.sy = ny;
root.ex = nx + w;
root.ey = ny + h;
}
}
AnnotationToolbar {
id: toolbar
inkColor: root.inkColor
tool: root.tool
visible: root.mode === "edit"
x: Math.max(8, Math.min(root.rsx + root.sw / 2 - width / 2, root.screen.width - width - 8))
y: (root.rsy + root.sh + height + Tokens.padding.normal <= root.screen.height) ? root.rsy + root.sh + Tokens.padding.normal : (root.rsy - height - Tokens.padding.normal <= 0) ? root.rsy + root.sh - height - Tokens.padding.normal : root.rsy - height - Tokens.padding.normal
onCancelRequested: root.cancel()
onClearRequested: annotations.clearAll()
onColorSelected: c => root.inkColor = c
onCopyRequested: root.save(true)
onSaveRequested: root.save(false)
onToolSelected: t => root.tool = t
onUndoRequested: annotations.undo()
}
component ExAnim: Anim {
duration: MaterialEasing.expressiveEffectsTime
easing.bezierCurve: MaterialEasing.expressiveEffects
}
}
+143
View File
@@ -0,0 +1,143 @@
pragma ComponentBehavior: Bound
import QtQuick
import ZShell.Internal
Item {
id: root
property color inkColor: "#ff3b30"
property real inkWidth: 4
property string tool: "none"
signal changed
function clearAll() {
committedCanvas.clear();
previewCanvas.clear();
changed();
}
function sampleShape(tool, x1, y1, x2, y2) {
const pts = [];
switch (tool) {
case "line":
pts.push([x1, y1], [x2, y2]);
break;
case "arrow":
{
const angle = Math.atan2(y2 - y1, x2 - x1);
const headLen = 14 + root.inkWidth * 2;
pts.push([x1, y1], [x2, y2]);
pts.push([x2 - headLen * Math.cos(angle - Math.PI / 6), y2 - headLen * Math.sin(angle - Math.PI / 6)]);
pts.push([x2, y2]);
pts.push([x2 - headLen * Math.cos(angle + Math.PI / 6), y2 - headLen * Math.sin(angle + Math.PI / 6)]);
break;
}
case "rect":
pts.push([x1, y1], [x2, y1], [x2, y2], [x1, y2], [x1, y1]);
break;
case "ellipse":
{
const cx = (x1 + x2) / 2, cy = (y1 + y2) / 2;
const rx = Math.abs(x2 - x1) / 2, ry = Math.abs(y2 - y1) / 2;
const perimeter = Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));
const steps = Math.max(48, Math.min(256, Math.ceil(perimeter / 4)));
for (let i = 0; i <= steps; i++) {
const a = (i / steps) * Math.PI * 2;
pts.push([cx + rx * Math.cos(a), cy + ry * Math.sin(a)]);
}
break;
}
}
return pts;
}
function undo() {
committedCanvas.undoLastGroup();
changed();
}
anchors.fill: parent
StrokeCanvas {
id: committedCanvas
anchors.fill: parent
penColor: root.inkColor
penWidth: root.inkWidth
}
StrokeCanvas {
id: previewCanvas
anchors.fill: parent
penColor: root.inkColor
penWidth: root.inkWidth
}
PointHandler {
id: drawHandler
property real startX
property real startY
property bool started: false
acceptedButtons: Qt.LeftButton | Qt.RightButton
enabled: root.tool !== "none"
onActiveChanged: {
if (active)
return;
if (root.tool === "pen") {
committedCanvas.endStroke();
} else if (started) {
const pts = root.sampleShape(root.tool, startX, startY, point.position.x, point.position.y);
if (pts.length > 0) {
committedCanvas.beginStroke(pts[0][0], pts[0][1], true);
for (let i = 1; i < pts.length; i++)
committedCanvas.appendPoint(pts[i][0], pts[i][1]);
committedCanvas.endStroke();
}
previewCanvas.clear();
}
started = false;
root.changed();
}
onPointChanged: {
if (!active)
return;
if (point.pressedButtons & Qt.RightButton) {
root.clearAll();
return;
}
const x = point.position.x;
const y = point.position.y;
if (root.tool === "pen") {
if (!started) {
started = true;
committedCanvas.beginStroke(x, y);
return;
}
committedCanvas.appendPoint(x, y);
return;
}
if (!started) {
started = true;
startX = point.pressPosition.x;
startY = point.pressPosition.y;
}
const pts = root.sampleShape(root.tool, startX, startY, x, y);
if (pts.length > 0) {
previewCanvas.beginStroke(pts[0][0], pts[0][1], true);
for (let i = 1; i < pts.length; i++)
previewCanvas.appendPoint(pts[i][0], pts[i][1]);
}
}
}
}
+185
View File
@@ -0,0 +1,185 @@
pragma ComponentBehavior: Bound
import ZShell.Components
import QtQuick
import QtQuick.Layouts
import qs.Components
import ZShell.Config
import qs.Services
CustomRect {
id: root
readonly property var colorPalette: ["#ff3b30", "#ff9500", "#ffcc00", "#34c759", "#0a84ff", "#af52de", "#ffffff", "#000000"]
property color inkColor: "#ff3b30"
property string tool: "move"
readonly property var toolList: [
{
id: "move",
glyph: "arrows_output"
},
{
id: "pen",
glyph: "draw"
},
{
id: "line",
glyph: "diagonal_line"
},
{
id: "arrow",
glyph: "arrow_outward"
},
{
id: "rect",
glyph: "rectangle"
},
{
id: "ellipse",
glyph: "circle"
}
]
signal cancelRequested
signal clearRequested
signal colorSelected(color c)
signal copyRequested
signal saveRequested
signal toolSelected(string tool)
signal undoRequested
color: Colors.palette.m3surface
height: row.implicitHeight + Tokens.padding.normal * 2
radius: Tokens.rounding.full
width: row.implicitWidth + Tokens.padding.normal * 2
RowLayout {
id: row
anchors.centerIn: parent
spacing: 6
ButtonRow {
id: toolRow
spacing: Tokens.spacing.extraSmall
Repeater {
model: root.toolList
delegate: IconButton {
id: tool
required property var modelData
color: root.tool === modelData.id ? "#3584e4" : "transparent"
icon: tool.modelData.glyph
inactiveColor: root.tool === modelData.id ? Colors.palette.m3primary : "transparent"
inactiveOnColor: root.tool === modelData.id ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface
isRound: true
shapeMorph: true
shapeMorphExpansion: shapeMorph && pressed ? 12 : 0
onClicked: root.toolSelected(tool.modelData.id)
}
}
}
CustomRect {
Layout.fillHeight: true
Layout.preferredWidth: 1
color: Colors.palette.m3outlineVariant
}
ButtonRow {
spacing: Tokens.spacing.extraSmall
Repeater {
model: root.colorPalette
delegate: IconButton {
readonly property real buttonSize: toolRow.implicitHeight - Tokens.padding.normal
required property color modelData
fillWidth: false
font.pointSize: 0
icon: ""
implicitHeight: buttonSize
implicitWidth: buttonSize
inactiveColor: modelData
inactiveOnColor: Colors.on(modelData)
isRound: true
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
onClicked: root.colorSelected(modelData)
}
}
}
CustomRect {
Layout.fillHeight: true
Layout.preferredWidth: 1
color: Colors.palette.m3outlineVariant
}
ButtonRow {
spacing: Tokens.spacing.extraSmall
IconButton {
icon: "undo"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
onClicked: root.undoRequested()
}
IconButton {
icon: "delete_history"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
onClicked: root.clearRequested()
}
IconButton {
icon: "content_copy"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
onClicked: root.copyRequested()
}
IconButton {
icon: "delete_forever"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
onClicked: root.cancelRequested()
}
IconButton {
icon: "check"
inactiveColor: "transparent"
inactiveOnColor: Colors.palette.m3onSurface
isRound: true
shapeMorph: true
shapeMorphExpansion: pressed ? 12 : 0
onClicked: root.saveRequested()
}
}
}
}
+183
View File
@@ -0,0 +1,183 @@
pragma ComponentBehavior: Bound
import QtQuick
Item {
id: root
property color handleBorder: "#3584e4"
property color handleFill: "white"
property real hs: 12
property real minSize: 24
required property real selH
required property real selW
required property real selX
required property real selY
signal boundsChanged(x: real, y: real, w: real, h: real)
signal dragFinished
signal moveBy(dx: real, dy: real)
height: selH
width: selW
x: selX
y: selY
DragHandler {
id: moveHandler
property real accumX: 0
property real accumY: 0
target: null
onActiveChanged: {
accumX = 0;
accumY = 0;
if (!active)
root.dragFinished();
}
onTranslationChanged: {
const t = moveHandler.translation;
root.moveBy(t.x - accumX, t.y - accumY);
accumX = t.x;
accumY = t.y;
}
}
Handle {
edge: "tl"
x: -root.hs / 2
y: -root.hs / 2
}
Handle {
edge: "t"
x: root.width / 2 - root.hs / 2
y: -root.hs / 2
}
Handle {
edge: "tr"
x: root.width - root.hs / 2
y: -root.hs / 2
}
Handle {
edge: "r"
x: root.width - root.hs / 2
y: root.height / 2 - root.hs / 2
}
Handle {
edge: "br"
x: root.width - root.hs / 2
y: root.height - root.hs / 2
}
Handle {
edge: "b"
x: root.width / 2 - root.hs / 2
y: root.height - root.hs / 2
}
Handle {
edge: "bl"
x: -root.hs / 2
y: root.height - root.hs / 2
}
Handle {
edge: "l"
x: -root.hs / 2
y: root.height / 2 - root.hs / 2
}
component Handle: Rectangle {
id: handle
required property string edge
border.color: root.handleBorder
border.width: 2
color: root.handleFill
height: root.hs
radius: root.hs / 2
width: root.hs
z: 10
HoverHandler {
cursorShape: {
switch (handle.edge) {
case "tl":
case "br":
return Qt.SizeFDiagCursor;
case "tr":
case "bl":
return Qt.SizeBDiagCursor;
case "t":
case "b":
return Qt.SizeVerCursor;
default:
return Qt.SizeHorCursor;
}
}
}
DragHandler {
id: dh
property real startH
property real startW
property real startX
property real startY
grabPermissions: PointerHandler.CanTakeOverFromAnything | PointerHandler.TakeOverForbidden
target: null
onActiveChanged: {
if (active) {
startX = root.x;
startY = root.y;
startW = root.width;
startH = root.height;
} else {
root.dragFinished();
}
}
onTranslationChanged: {
const delta = dh.translation;
const e = handle.edge;
let nx = startX, ny = startY, nw = startW, nh = startH;
if (e.includes("l")) {
nx = startX + delta.x;
nw = startW - delta.x;
}
if (e.includes("r")) {
nw = startW + delta.x;
}
if (e.includes("t")) {
ny = startY + delta.y;
nh = startH - delta.y;
}
if (e.includes("b")) {
nh = startH + delta.y;
}
if (nw < root.minSize) {
if (e.includes("l"))
nx = startX + startW - root.minSize;
nw = root.minSize;
}
if (nh < root.minSize) {
if (e.includes("t"))
ny = startY + startH - root.minSize;
nh = root.minSize;
}
root.boundsChanged(nx, ny, nw, nh);
}
}
}
}
+2 -2
View File
@@ -6,7 +6,7 @@ import Quickshell.Io
import Quickshell.Services.Mpris
import ZShell
import qs.Components
import qs.Config
import ZShell.Config
Singleton {
id: root
@@ -33,7 +33,7 @@ Singleton {
function getIdentity(player: MprisPlayer): string {
if (!player)
return "";
const alias = Config.services.playerAliases.find(a => a.from === player.identity);
const alias = Config.services.playerAliases.values.find(a => a.from === player.identity);
return alias?.to ?? player.identity;
}
+1 -1
View File
@@ -3,7 +3,7 @@ pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Config
import ZShell.Config
import qs.Paths
Singleton {
+1 -1
View File
@@ -3,7 +3,7 @@ pragma Singleton
import QtQuick
import Quickshell
import Quickshell.Wayland
import qs.Config
import ZShell.Config
Singleton {
id: root
+14 -2
View File
@@ -2,7 +2,7 @@ pragma Singleton
import Quickshell
import QtQuick
import qs.Config
import ZShell.Config
Singleton {
id: root
@@ -20,7 +20,19 @@ Singleton {
readonly property string timeStr: format("hh:mm:ss")
function format(fmt: string): string {
return Qt.formatDateTime(clock.date, fmt);
return Qt.formatDateTime(clock.date, resolveFormat(fmt));
}
function resolveFormat(fmt: string): string {
if (!Config.services.useTwelveHourClock)
return fmt;
let f = fmt.replace(/hh/g, "h");
if (/h/.test(f) && !/AP|ap/.test(f))
f += " AP";
return f;
}
SystemClock {
+1 -1
View File
@@ -5,7 +5,7 @@ import QtQuick
import Quickshell
import Quickshell.Io
import qs.Paths
import qs.Config
import ZShell.Config
Singleton {
id: root
+1 -1
View File
@@ -5,7 +5,7 @@ import Quickshell
import Quickshell.Io
import QtQuick
import ZShell.Models
import qs.Config
import ZShell.Config
import qs.Modules
import qs.Helpers
import qs.Paths
+1 -1
View File
@@ -3,7 +3,7 @@ pragma Singleton
import QtQuick
import Quickshell
import ZShell
import qs.Config
import ZShell.Config
Singleton {
id: root