summaryrefslogtreecommitdiff
path: root/services
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2026-09-02 18:26:45 +0800
committerlittleblack111 <littleblack11111@gmail.com>2026-09-02 18:26:45 +0800
commitf7a43077fe4e139dd7e3f46f448e0951740ec148 (patch)
treef6a68248fe42bd899e99049bab7fdb7e5d26ea60 /services
parent2f7576faf493b4667b02dcb60ddbf3aa0a9f654b (diff)
fix: qmlfmt
IListView: animation
Diffstat (limited to 'services')
-rw-r--r--services/AppSearch.qml230
-rw-r--r--services/Clip.qml494
-rw-r--r--services/Emoji.qml90
-rw-r--r--services/Mpris.qml300
-rw-r--r--services/Network.qml136
-rw-r--r--services/NetworkUsage.qml106
-rw-r--r--services/Persistent.qml38
-rw-r--r--services/Resource.qml198
-rw-r--r--services/TimeDate.qml128
9 files changed, 860 insertions, 860 deletions
diff --git a/services/AppSearch.qml b/services/AppSearch.qml
index d56213f..b8294b6 100644
--- a/services/AppSearch.qml
+++ b/services/AppSearch.qml
@@ -6,119 +6,119 @@ import qs.config
import qs.components
Searchable {
- id: root
-
- list: Array.from(DesktopEntries.applications.values).sort((a, b) => a.name.localeCompare(b.name))
- scoreThreshold: General.appSearchFuzzySearchThreshold
- algorithm: Searchable.SearchAlgorithm.Levendist
- keys: ["name", "genericName", "execString", "keywords", "comment", "categories", "icon"]
-
- property var substitutions: ({
- "code-url-handler": "visual-studio-code",
- "Code": "visual-studio-code",
- "gnome-tweaks": "org.gnome.tweaks",
- "pavucontrol-qt": "pavucontrol",
- "wps": "wps-office2019-kprometheus",
- "wpsoffice": "wps-office2019-kprometheus",
- "footclient": "foot",
- "zen": "zen-browser",
- "brave-browser": "brave-desktop"
- })
-
- property var regexSubstitutions: [
- {
- regex: /^steam_app_(\d+)$/,
- replace: "steam_icon_$1"
- },
- {
- regex: /Minecraft.*/,
- replace: "minecraft"
- },
- {
- regex: /.*polkit.*/,
- replace: "system-lock-screen"
- },
- {
- regex: /gcr.prompter/,
- replace: "system-lock-screen"
- }
- ]
-
- property var iconExistsCache: ({})
- property var guessIconCache: ({})
-
- function iconExists(iconName) {
- if (!iconName || iconName.length === 0) {
- return false;
- }
- if (root.iconExistsCache.hasOwnProperty(iconName)) {
- return root.iconExistsCache[iconName];
- }
- const exists = Quickshell.iconPath(iconName, true).length > 0 && !iconName.includes("image-missing");
- root.iconExistsCache[iconName] = exists;
- return exists;
- }
-
- function guessIcon(str) {
- if (!str || str.length === 0) {
- return "image-missing";
- }
- if (root.guessIconCache[str]) {
- return root.guessIconCache[str];
- }
-
- var result;
-
- if (substitutions[str]) {
- result = substitutions[str];
- } else {
- result = null;
- for (var i = 0; i < regexSubstitutions.length; i++) {
- var {
- regex,
- replace
- } = regexSubstitutions[i];
- var replaced = str.replace(regex, replace);
- if (replaced !== str) {
- result = replaced;
- break;
- }
- }
- }
-
- if (!result && root.iconExists(str)) {
- result = str;
- }
-
- if (!result) {
- var guessStr = str.split(".").slice(-1)[0].toLowerCase();
- if (root.iconExists(guessStr)) {
- result = guessStr;
- }
- }
-
- if (!result) {
- var kebab = str.toLowerCase().replace(/\s+/g, "-");
- if (root.iconExists(kebab)) {
- result = kebab;
- }
- }
-
- if (!result) {
- const matches = root.query(str);
- if (matches.length > 0) {
- const candidate = matches[0].icon;
- if (root.iconExists(candidate)) {
- result = candidate;
- }
- }
- }
-
- if (!result) {
- result = str;
- }
-
- root.guessIconCache[str] = result;
- return result;
- }
+ id: root
+
+ list: Array.from(DesktopEntries.applications.values).sort((a, b) => a.name.localeCompare(b.name))
+ scoreThreshold: General.appSearchFuzzySearchThreshold
+ algorithm: Searchable.SearchAlgorithm.Levendist
+ keys: ["name", "genericName", "execString", "keywords", "comment", "categories", "icon"]
+
+ property var substitutions: ({
+ "code-url-handler": "visual-studio-code",
+ "Code": "visual-studio-code",
+ "gnome-tweaks": "org.gnome.tweaks",
+ "pavucontrol-qt": "pavucontrol",
+ "wps": "wps-office2019-kprometheus",
+ "wpsoffice": "wps-office2019-kprometheus",
+ "footclient": "foot",
+ "zen": "zen-browser",
+ "brave-browser": "brave-desktop"
+ })
+
+ property var regexSubstitutions: [
+ {
+ regex: /^steam_app_(\d+)$/,
+ replace: "steam_icon_$1"
+ },
+ {
+ regex: /Minecraft.*/,
+ replace: "minecraft"
+ },
+ {
+ regex: /.*polkit.*/,
+ replace: "system-lock-screen"
+ },
+ {
+ regex: /gcr.prompter/,
+ replace: "system-lock-screen"
+ }
+ ]
+
+ property var iconExistsCache: ({})
+ property var guessIconCache: ({})
+
+ function iconExists(iconName) {
+ if (!iconName || iconName.length === 0) {
+ return false;
+ }
+ if (root.iconExistsCache.hasOwnProperty(iconName)) {
+ return root.iconExistsCache[iconName];
+ }
+ const exists = Quickshell.iconPath(iconName, true).length > 0 && !iconName.includes("image-missing");
+ root.iconExistsCache[iconName] = exists;
+ return exists;
+ }
+
+ function guessIcon(str) {
+ if (!str || str.length === 0) {
+ return "image-missing";
+ }
+ if (root.guessIconCache[str]) {
+ return root.guessIconCache[str];
+ }
+
+ var result;
+
+ if (substitutions[str]) {
+ result = substitutions[str];
+ } else {
+ result = null;
+ for (var i = 0; i < regexSubstitutions.length; i++) {
+ var {
+ regex,
+ replace
+ } = regexSubstitutions[i];
+ var replaced = str.replace(regex, replace);
+ if (replaced !== str) {
+ result = replaced;
+ break;
+ }
+ }
+ }
+
+ if (!result && root.iconExists(str)) {
+ result = str;
+ }
+
+ if (!result) {
+ var guessStr = str.split(".").slice(-1)[0].toLowerCase();
+ if (root.iconExists(guessStr)) {
+ result = guessStr;
+ }
+ }
+
+ if (!result) {
+ var kebab = str.toLowerCase().replace(/\s+/g, "-");
+ if (root.iconExists(kebab)) {
+ result = kebab;
+ }
+ }
+
+ if (!result) {
+ const matches = root.query(str);
+ if (matches.length > 0) {
+ const candidate = matches[0].icon;
+ if (root.iconExists(candidate)) {
+ result = candidate;
+ }
+ }
+ }
+
+ if (!result) {
+ result = str;
+ }
+
+ root.guessIconCache[str] = result;
+ return result;
+ }
}
diff --git a/services/Clip.qml b/services/Clip.qml
index 2289dd2..4960dd9 100644
--- a/services/Clip.qml
+++ b/services/Clip.qml
@@ -11,251 +11,251 @@ import qs.config
import "../utils/string_utils.js" as StringUtils
Searchable {
- id: root
-
- key: "data"
- algorithm: General.defaultSearchAlgorithm
-
- property list<string> _clipHist: []
- property list<string> _clipImg: []
- property list<string> _clipImgIds: _clipImg.map(p => p.split("/").pop().split(".").shift())
- property var _clipMetadata: ({})
- property var _clipDecoded: ({})
- property int _pendingReorderId: -1
-
- function getType(text: string): string {
- if (!text)
- return;
- if (text.startsWith("http://") || text.startsWith("https://"))
- return "web";
- if (text.startsWith("file://"))
- return "file";
-
- return "text";
- }
-
- list: {
- if (!_clipHist?.length)
- return [];
-
- const imgMap = _clipImgIds.slice(0, Math.min(_clipImg.length, _clipImgIds.length)).reduce((map, id, i) => {
- if (id)
- map[id] = _clipImg[i];
- return map;
- }, {});
-
- return _clipHist.filter(raw => raw).map((raw, idx) => {
- const tab = raw.indexOf("\t");
- let idNum = -1;
- let payload = raw;
-
- if (tab > 0) {
- const n = parseInt(raw.slice(0, tab), 10);
- if (!Number.isNaN(n)) {
- idNum = n;
- payload = raw.slice(tab + 1);
- }
- }
-
- const imgPath = idNum >= 0 ? imgMap[idNum] || "" : "";
- const isImg = !!imgPath;
- const metadata = _clipMetadata[idNum] || {};
-
- return {
- index: idNum,
- type: isImg ? "image" : root.getType(payload),
- data: isImg ? imgPath : payload,
- raw: raw,
- timestamp: metadata.timestamp || "",
- appId: metadata.appId || "",
- appTitle: metadata.appTitle || "",
- appIcon: Quickshell.iconPath(AppSearch.guessIcon(metadata.appId), "image-missing"),
- image: imgPath,
- decoded: root._clipDecoded[idx] || ""
- };
- });
- }
-
- Persistent {
- id: clipMetaStore
- filePath: Directories.clipHistMetaDataPath
- adapter: JsonAdapter {
- property var metadata: ({})
- }
- fileView.onLoaded: {
- const meta = adapter.metadata;
- for (const k in meta) {
- if (meta[k].timestamp && typeof meta[k].timestamp === "string") {
- meta[k].timestamp = new Date(meta[k].timestamp);
- }
- }
- root._clipMetadata = meta;
- }
- }
-
- on_ClipMetadataChanged: {
- clipMetaStore.adapter.metadata = _clipMetadata;
- }
-
- function transformSearch(search) {
- return search.toLowerCase();
- }
-
- function decodeAndCopy(text) {
- const tab = text.indexOf("\t");
- if (tab > 0) {
- const idStr = text.slice(0, tab);
- const n = parseInt(idStr, 10);
- if (!Number.isNaN(n))
- _pendingReorderId = n;
- }
- Quickshell.execDetached(["sh", "-c", `cliphist decode '${StringUtils.shellSingleQuoteEscape(text)}' | wl-copy`]);
- }
-
- function copy(text) {
- _pendingReorderId = -1;
- Quickshell.execDetached(["wl-copy", text]);
- }
-
- function _update() {
- clipProc.running = true;
- clipDecodeProc.running = true;
- imgProc.running = true;
- }
-
- function _captureMetadata() {
- const now = new Date();
- const activeToplevel = ToplevelManager.activeToplevel;
-
- Qt.callLater(() => {
- clipProc.running = true;
- clipProc.stdout.onceFinished = () => {
- const lines = clipProc.stdout.text.split(/\r?\n/);
- const firstLine = lines[0] || "";
- const tab = firstLine.indexOf("\t");
-
- if (tab > 0) {
- const idStr = firstLine.slice(0, tab);
- const n = parseInt(idStr, 10);
- if (!Number.isNaN(n)) {
- if (_clipMetadata[idStr]) {
- _pendingReorderId = -1;
- return;
- }
-
- let newMetadata = {};
- for (var k in _clipMetadata) {
- if (_clipMetadata.hasOwnProperty(k))
- newMetadata[k] = _clipMetadata[k];
- }
-
- if (_pendingReorderId >= 0) {
- if (_clipMetadata[_pendingReorderId]) {
- newMetadata[idStr] = _clipMetadata[_pendingReorderId];
- }
- _pendingReorderId = -1;
- } else {
- if (!newMetadata[idStr]) {
- newMetadata[idStr] = {
- timestamp: now,
- appId: activeToplevel ? activeToplevel.appId : "",
- appTitle: activeToplevel ? activeToplevel.title : ""
- };
- }
- }
- _clipMetadata = newMetadata;
- }
- }
- };
- });
- }
-
- Process {
- id: clipProc
- running: true
- command: ["cliphist", "-preview-width", 9 ** 9, "-max-items", 9 ** 9, "list"]
- stdout: StdioCollector {
- property bool pending: false
- property var onceFinished: null
-
- onStreamFinished: () => {
- pending = true;
- Qt.callLater(() => {
- if (pending) {
- pending = false;
- _clipHist = this.text.split(/\r?\n/);
- if (onceFinished) {
- onceFinished();
- onceFinished = null;
- }
- }
- });
- }
- }
- }
-
- Process {
- id: clipDecodeProc
- property var tmp: ({})
- property int index: 0
- property string separator: "\0\x01\x02CLIP_SEP_7b9a4c8d\x02\x01\0"
- running: true
- command: ["sh", "-c", 'cliphist list | while IFS= read -r line; do\n' + ' cliphist decode "$line"; ' + 'printf "\\0\\x01\\x02CLIP_SEP_7b9a4c8d\\x02\\x01\\0";\n' + 'done']
- onStarted: {
- clipDecodeProc.tmp = [];
- clipDecodeProc.index = 0;
- }
- onExited: {
- if (clipDecodeProc.tmp)
- root._clipDecoded = clipDecodeProc.tmp;
- }
- stdout: SplitParser {
- onRead: data => {
- const parts = data.split(clipDecodeProc.separator);
-
- if (!clipDecodeProc.tmp[clipDecodeProc.index])
- clipDecodeProc.tmp[clipDecodeProc.index] = "";
-
- clipDecodeProc.tmp[clipDecodeProc.index] += parts[0];
-
- for (let i = 1; i < parts.length; i++) {
- clipDecodeProc.index++;
- clipDecodeProc.tmp[clipDecodeProc.index] = parts[i];
- }
- }
- }
- }
-
- Process {
- id: imgProc
- running: true
- command: ["sh", Quickshell.shellDir + "/utils/cliphist-img.sh"]
- stdout: StdioCollector {
- property bool pending: false
- onStreamFinished: () => {
- pending = true;
- Qt.callLater(() => {
- if (pending) {
- pending = false;
- _clipImg = this.text.split(/\r?\n/);
- }
- });
- }
- }
- }
-
- Process {
- id: watchProc
- running: true
- command: ["wl-paste", "-w", "echo"]
- onRunningChanged: if (!running)
- running = true
-
- stdout: SplitParser {
- onRead: line => {
- _captureMetadata();
- _update();
- }
- }
- }
+ id: root
+
+ key: "data"
+ algorithm: General.defaultSearchAlgorithm
+
+ property list<string> _clipHist: []
+ property list<string> _clipImg: []
+ property list<string> _clipImgIds: _clipImg.map(p => p.split("/").pop().split(".").shift())
+ property var _clipMetadata: ({})
+ property var _clipDecoded: ({})
+ property int _pendingReorderId: -1
+
+ function getType(text: string): string {
+ if (!text)
+ return;
+ if (text.startsWith("http://") || text.startsWith("https://"))
+ return "web";
+ if (text.startsWith("file://"))
+ return "file";
+
+ return "text";
+ }
+
+ list: {
+ if (!_clipHist?.length)
+ return [];
+
+ const imgMap = _clipImgIds.slice(0, Math.min(_clipImg.length, _clipImgIds.length)).reduce((map, id, i) => {
+ if (id)
+ map[id] = _clipImg[i];
+ return map;
+ }, {});
+
+ return _clipHist.filter(raw => raw).map((raw, idx) => {
+ const tab = raw.indexOf("\t");
+ let idNum = -1;
+ let payload = raw;
+
+ if (tab > 0) {
+ const n = parseInt(raw.slice(0, tab), 10);
+ if (!Number.isNaN(n)) {
+ idNum = n;
+ payload = raw.slice(tab + 1);
+ }
+ }
+
+ const imgPath = idNum >= 0 ? imgMap[idNum] || "" : "";
+ const isImg = !!imgPath;
+ const metadata = _clipMetadata[idNum] || {};
+
+ return {
+ index: idNum,
+ type: isImg ? "image" : root.getType(payload),
+ data: isImg ? imgPath : payload,
+ raw: raw,
+ timestamp: metadata.timestamp || "",
+ appId: metadata.appId || "",
+ appTitle: metadata.appTitle || "",
+ appIcon: Quickshell.iconPath(AppSearch.guessIcon(metadata.appId), "image-missing"),
+ image: imgPath,
+ decoded: root._clipDecoded[idx] || ""
+ };
+ });
+ }
+
+ Persistent {
+ id: clipMetaStore
+ filePath: Directories.clipHistMetaDataPath
+ adapter: JsonAdapter {
+ property var metadata: ({})
+ }
+ fileView.onLoaded: {
+ const meta = adapter.metadata;
+ for (const k in meta) {
+ if (meta[k].timestamp && typeof meta[k].timestamp === "string") {
+ meta[k].timestamp = new Date(meta[k].timestamp);
+ }
+ }
+ root._clipMetadata = meta;
+ }
+ }
+
+ on_ClipMetadataChanged: {
+ clipMetaStore.adapter.metadata = _clipMetadata;
+ }
+
+ function transformSearch(search) {
+ return search.toLowerCase();
+ }
+
+ function decodeAndCopy(text) {
+ const tab = text.indexOf("\t");
+ if (tab > 0) {
+ const idStr = text.slice(0, tab);
+ const n = parseInt(idStr, 10);
+ if (!Number.isNaN(n))
+ _pendingReorderId = n;
+ }
+ Quickshell.execDetached(["sh", "-c", `cliphist decode '${StringUtils.shellSingleQuoteEscape(text)}' | wl-copy`]);
+ }
+
+ function copy(text) {
+ _pendingReorderId = -1;
+ Quickshell.execDetached(["wl-copy", text]);
+ }
+
+ function _update() {
+ clipProc.running = true;
+ clipDecodeProc.running = true;
+ imgProc.running = true;
+ }
+
+ function _captureMetadata() {
+ const now = new Date();
+ const activeToplevel = ToplevelManager.activeToplevel;
+
+ Qt.callLater(() => {
+ clipProc.running = true;
+ clipProc.stdout.onceFinished = () => {
+ const lines = clipProc.stdout.text.split(/\r?\n/);
+ const firstLine = lines[0] || "";
+ const tab = firstLine.indexOf("\t");
+
+ if (tab > 0) {
+ const idStr = firstLine.slice(0, tab);
+ const n = parseInt(idStr, 10);
+ if (!Number.isNaN(n)) {
+ if (_clipMetadata[idStr]) {
+ _pendingReorderId = -1;
+ return;
+ }
+
+ let newMetadata = {};
+ for (var k in _clipMetadata) {
+ if (_clipMetadata.hasOwnProperty(k))
+ newMetadata[k] = _clipMetadata[k];
+ }
+
+ if (_pendingReorderId >= 0) {
+ if (_clipMetadata[_pendingReorderId]) {
+ newMetadata[idStr] = _clipMetadata[_pendingReorderId];
+ }
+ _pendingReorderId = -1;
+ } else {
+ if (!newMetadata[idStr]) {
+ newMetadata[idStr] = {
+ timestamp: now,
+ appId: activeToplevel ? activeToplevel.appId : "",
+ appTitle: activeToplevel ? activeToplevel.title : ""
+ };
+ }
+ }
+ _clipMetadata = newMetadata;
+ }
+ }
+ };
+ });
+ }
+
+ Process {
+ id: clipProc
+ running: true
+ command: ["cliphist", "-preview-width", 9 ** 9, "-max-items", 9 ** 9, "list"]
+ stdout: StdioCollector {
+ property bool pending: false
+ property var onceFinished: null
+
+ onStreamFinished: () => {
+ pending = true;
+ Qt.callLater(() => {
+ if (pending) {
+ pending = false;
+ _clipHist = this.text.split(/\r?\n/);
+ if (onceFinished) {
+ onceFinished();
+ onceFinished = null;
+ }
+ }
+ });
+ }
+ }
+ }
+
+ Process {
+ id: clipDecodeProc
+ property var tmp: ({})
+ property int index: 0
+ property string separator: "\0\x01\x02CLIP_SEP_7b9a4c8d\x02\x01\0"
+ running: true
+ command: ["sh", "-c", 'cliphist list | while IFS= read -r line; do\n' + ' cliphist decode "$line"; ' + 'printf "\\0\\x01\\x02CLIP_SEP_7b9a4c8d\\x02\\x01\\0";\n' + 'done']
+ onStarted: {
+ clipDecodeProc.tmp = [];
+ clipDecodeProc.index = 0;
+ }
+ onExited: {
+ if (clipDecodeProc.tmp)
+ root._clipDecoded = clipDecodeProc.tmp;
+ }
+ stdout: SplitParser {
+ onRead: data => {
+ const parts = data.split(clipDecodeProc.separator);
+
+ if (!clipDecodeProc.tmp[clipDecodeProc.index])
+ clipDecodeProc.tmp[clipDecodeProc.index] = "";
+
+ clipDecodeProc.tmp[clipDecodeProc.index] += parts[0];
+
+ for (let i = 1; i < parts.length; i++) {
+ clipDecodeProc.index++;
+ clipDecodeProc.tmp[clipDecodeProc.index] = parts[i];
+ }
+ }
+ }
+ }
+
+ Process {
+ id: imgProc
+ running: true
+ command: ["sh", Quickshell.shellDir + "/utils/cliphist-img.sh"]
+ stdout: StdioCollector {
+ property bool pending: false
+ onStreamFinished: () => {
+ pending = true;
+ Qt.callLater(() => {
+ if (pending) {
+ pending = false;
+ _clipImg = this.text.split(/\r?\n/);
+ }
+ });
+ }
+ }
+ }
+
+ Process {
+ id: watchProc
+ running: true
+ command: ["wl-paste", "-w", "echo"]
+ onRunningChanged: if (!running)
+ running = true
+
+ stdout: SplitParser {
+ onRead: line => {
+ _captureMetadata();
+ _update();
+ }
+ }
+ }
}
diff --git a/services/Emoji.qml b/services/Emoji.qml
index 108fbd9..697840b 100644
--- a/services/Emoji.qml
+++ b/services/Emoji.qml
@@ -6,49 +6,49 @@ import QtQuick
import qs.components
Searchable {
- id: root
-
- property var _emojis: []
- property var _emojiFile: FileView {
- path: "/usr/share/rofi-emoji/all_emojis.txt"
- onTextChanged: _parseEmojis()
- }
-
- list: _emojis
- keys: ["name", "keywords", "category", "subcategory", "emoji"]
- algorithm: Searchable.SearchAlgorithm.Include
-
- function transformSearch(search) {
- return search.toLowerCase();
- }
-
- function _parseEmojis() {
- const text = _emojiFile.text();
- if (!text) {
- console.warn("Emoji service: failed to load", _emojiFile.path);
- _emojis = [];
- return;
- }
-
- const lines = text.split("\n").filter(l => l.trim());
- const out = [];
- for (let i = 0; i < lines.length; ++i) {
- const parts = lines[i].split("\t");
- if (parts.length < 5)
- continue;
- const [emoji, category, subcategory, name, keywords] = parts;
- out.push({
- emoji: emoji,
- category: category,
- subcategory: subcategory,
- name: name,
- keywords: keywords
- });
- }
- _emojis = out;
- }
-
- function copy(emoji) {
- Clip.copy(emoji);
- }
+ id: root
+
+ property var _emojis: []
+ property var _emojiFile: FileView {
+ path: "/usr/share/rofi-emoji/all_emojis.txt"
+ onTextChanged: _parseEmojis()
+ }
+
+ list: _emojis
+ keys: ["name", "keywords", "category", "subcategory", "emoji"]
+ algorithm: Searchable.SearchAlgorithm.Include
+
+ function transformSearch(search) {
+ return search.toLowerCase();
+ }
+
+ function _parseEmojis() {
+ const text = _emojiFile.text();
+ if (!text) {
+ console.warn("Emoji service: failed to load", _emojiFile.path);
+ _emojis = [];
+ return;
+ }
+
+ const lines = text.split("\n").filter(l => l.trim());
+ const out = [];
+ for (let i = 0; i < lines.length; ++i) {
+ const parts = lines[i].split("\t");
+ if (parts.length < 5)
+ continue;
+ const [emoji, category, subcategory, name, keywords] = parts;
+ out.push({
+ emoji: emoji,
+ category: category,
+ subcategory: subcategory,
+ name: name,
+ keywords: keywords
+ });
+ }
+ _emojis = out;
+ }
+
+ function copy(emoji) {
+ Clip.copy(emoji);
+ }
}
diff --git a/services/Mpris.qml b/services/Mpris.qml
index dc103f8..c73ed3f 100644
--- a/services/Mpris.qml
+++ b/services/Mpris.qml
@@ -16,154 +16,154 @@ import qs.config
* A service that provides easy access to the active Mpris player.
*/
Singleton {
- id: root
- property MprisPlayer trackedPlayer: null
- property MprisPlayer activePlayer: Mpris.players.values.find(i => i.desktopEntry === Bar.preferedPlayer) ?? trackedPlayer ?? Mpris.players.values[0] ?? null
- signal trackChanged(reverse: bool)
-
- property bool __reverse: false
-
- property var activeTrack
-
- Timer {
- running: root.activePlayer?.playbackState == MprisPlaybackState.Playing && root.activePlayer?.positionSupported
- interval: 1000
- repeat: true
- onTriggered: root.activePlayer.positionChanged()
- }
-
- Instantiator {
- model: Mpris.players
-
- Connections {
- required property MprisPlayer modelData
- target: modelData
-
- Component.onCompleted: {
- if (root.trackedPlayer == null || modelData.isPlaying) {
- root.trackedPlayer = modelData;
- }
- }
-
- Component.onDestruction: {
- if (root.trackedPlayer == null || !root.trackedPlayer.isPlaying) {
- for (const player of Mpris.players.values) {
- if (player.playbackState.isPlaying) {
- root.trackedPlayer = player;
- break;
- }
- }
-
- if (trackedPlayer == null && Mpris.players.values.length != 0) {
- trackedPlayer = Mpris.players.values[0];
- }
- }
- }
-
- function onPlaybackStateChanged() {
- if (root.trackedPlayer !== modelData)
- root.trackedPlayer = modelData;
- }
- }
- }
-
- Connections {
- target: activePlayer
-
- function onPostTrackChanged() {
- root.updateTrack();
- }
-
- function onTrackArtUrlChanged() {
- // console.log("arturl:", activePlayer.trackArtUrl)
- // root.updateTrack();
- if (root.activePlayer.uniqueId == root.activeTrack.uniqueId && root.activePlayer.trackArtUrl != root.activeTrack.artUrl) {
- // cantata likes to send cover updates *BEFORE* updating the track info.
- // as such, art url changes shouldn't be able to break the reverse animation
- const r = root.__reverse;
- root.updateTrack();
- root.__reverse = r;
- }
- }
- // not working https://github.com/quickshell-mirror/quickshell/issues/111
- // function onEntered() {
- // }
- }
-
- onActivePlayerChanged: this.updateTrack()
-
- function updateTrack() {
- // console.log(`update: ${this.activePlayer?.trackTitle ?? ""} : ${this.activePlayer?.trackArtists}`);
- this.activeTrack = {
- uniqueId: this.activePlayer?.uniqueId ?? 0,
- artUrl: this.activePlayer?.trackArtUrl ?? "",
- title: this.activePlayer?.trackTitle || qsTr("Unknown Title"),
- artist: this.activePlayer?.trackArtist || qsTr("Unknown Artist"),
- album: this.activePlayer?.trackAlbum || qsTr("Unknown Album"),
- position: this.activePlayer?.position ?? 0,
- length: this.activePlayer?.length ?? 0
- };
-
- this.trackChanged(__reverse);
- this.__reverse = false;
- }
-
- function updateProgress() {
- this.activePlayer.position;
- }
-
- property bool isPlaying: this.activePlayer && this.activePlayer.isPlaying
- property bool canTogglePlaying: this.activePlayer?.canTogglePlaying ?? false
- function togglePlaying() {
- if (this.canTogglePlaying)
- this.activePlayer.togglePlaying();
- }
-
- property bool canGoPrevious: this.activePlayer?.canGoPrevious ?? false
- function previous() {
- if (this.canGoPrevious) {
- this.__reverse = true;
- this.activePlayer.previous();
- }
- }
-
- property bool canGoNext: this.activePlayer?.canGoNext ?? false
- function next() {
- if (this.canGoNext) {
- this.__reverse = false;
- this.activePlayer.next();
- }
- }
-
- property bool canChangeVolume: this.activePlayer && this.activePlayer.volumeSupported && this.activePlayer.canControl
-
- property bool loopSupported: this.activePlayer && this.activePlayer.loopSupported && this.activePlayer.canControl
- property var loopState: this.activePlayer?.loopState ?? MprisLoopState.None
- function setLoopState(loopState: var) {
- if (this.loopSupported) {
- this.activePlayer.loopState = loopState;
- }
- }
-
- property bool shuffleSupported: this.activePlayer && this.activePlayer.shuffleSupported && this.activePlayer.canControl
- property bool hasShuffle: this.activePlayer?.shuffle ?? false
- function setShuffle(shuffle: bool) {
- if (this.shuffleSupported) {
- this.activePlayer.shuffle = shuffle;
- }
- }
-
- function setActivePlayer(player: MprisPlayer) {
- const targetPlayer = player ?? Mpris.players[0];
- console.log(`[Mpris] Active player ${targetPlayer} << ${activePlayer}`);
-
- if (targetPlayer && this.activePlayer) {
- this.__reverse = Mpris.players.indexOf(targetPlayer) < Mpris.players.indexOf(this.activePlayer);
- } else {
- // always animate forward if going to null
- this.__reverse = false;
- }
-
- this.trackedPlayer = targetPlayer;
- }
+ id: root
+ property MprisPlayer trackedPlayer: null
+ property MprisPlayer activePlayer: Mpris.players.values.find(i => i.desktopEntry === Bar.preferedPlayer) ?? trackedPlayer ?? Mpris.players.values[0] ?? null
+ signal trackChanged(reverse: bool)
+
+ property bool __reverse: false
+
+ property var activeTrack
+
+ Timer {
+ running: root.activePlayer?.playbackState == MprisPlaybackState.Playing && root.activePlayer?.positionSupported
+ interval: 1000
+ repeat: true
+ onTriggered: root.activePlayer.positionChanged()
+ }
+
+ Instantiator {
+ model: Mpris.players
+
+ Connections {
+ required property MprisPlayer modelData
+ target: modelData
+
+ Component.onCompleted: {
+ if (root.trackedPlayer == null || modelData.isPlaying) {
+ root.trackedPlayer = modelData;
+ }
+ }
+
+ Component.onDestruction: {
+ if (root.trackedPlayer == null || !root.trackedPlayer.isPlaying) {
+ for (const player of Mpris.players.values) {
+ if (player.playbackState.isPlaying) {
+ root.trackedPlayer = player;
+ break;
+ }
+ }
+
+ if (trackedPlayer == null && Mpris.players.values.length != 0) {
+ trackedPlayer = Mpris.players.values[0];
+ }
+ }
+ }
+
+ function onPlaybackStateChanged() {
+ if (root.trackedPlayer !== modelData)
+ root.trackedPlayer = modelData;
+ }
+ }
+ }
+
+ Connections {
+ target: activePlayer
+
+ function onPostTrackChanged() {
+ root.updateTrack();
+ }
+
+ function onTrackArtUrlChanged() {
+ // console.log("arturl:", activePlayer.trackArtUrl)
+ // root.updateTrack();
+ if (root.activePlayer.uniqueId == root.activeTrack.uniqueId && root.activePlayer.trackArtUrl != root.activeTrack.artUrl) {
+ // cantata likes to send cover updates *BEFORE* updating the track info.
+ // as such, art url changes shouldn't be able to break the reverse animation
+ const r = root.__reverse;
+ root.updateTrack();
+ root.__reverse = r;
+ }
+ }
+ // not working https://github.com/quickshell-mirror/quickshell/issues/111
+ // function onEntered() {
+ // }
+ }
+
+ onActivePlayerChanged: this.updateTrack()
+
+ function updateTrack() {
+ // console.log(`update: ${this.activePlayer?.trackTitle ?? ""} : ${this.activePlayer?.trackArtists}`);
+ this.activeTrack = {
+ uniqueId: this.activePlayer?.uniqueId ?? 0,
+ artUrl: this.activePlayer?.trackArtUrl ?? "",
+ title: this.activePlayer?.trackTitle || qsTr("Unknown Title"),
+ artist: this.activePlayer?.trackArtist || qsTr("Unknown Artist"),
+ album: this.activePlayer?.trackAlbum || qsTr("Unknown Album"),
+ position: this.activePlayer?.position ?? 0,
+ length: this.activePlayer?.length ?? 0
+ };
+
+ this.trackChanged(__reverse);
+ this.__reverse = false;
+ }
+
+ function updateProgress() {
+ this.activePlayer.position;
+ }
+
+ property bool isPlaying: this.activePlayer && this.activePlayer.isPlaying
+ property bool canTogglePlaying: this.activePlayer?.canTogglePlaying ?? false
+ function togglePlaying() {
+ if (this.canTogglePlaying)
+ this.activePlayer.togglePlaying();
+ }
+
+ property bool canGoPrevious: this.activePlayer?.canGoPrevious ?? false
+ function previous() {
+ if (this.canGoPrevious) {
+ this.__reverse = true;
+ this.activePlayer.previous();
+ }
+ }
+
+ property bool canGoNext: this.activePlayer?.canGoNext ?? false
+ function next() {
+ if (this.canGoNext) {
+ this.__reverse = false;
+ this.activePlayer.next();
+ }
+ }
+
+ property bool canChangeVolume: this.activePlayer && this.activePlayer.volumeSupported && this.activePlayer.canControl
+
+ property bool loopSupported: this.activePlayer && this.activePlayer.loopSupported && this.activePlayer.canControl
+ property var loopState: this.activePlayer?.loopState ?? MprisLoopState.None
+ function setLoopState(loopState: var) {
+ if (this.loopSupported) {
+ this.activePlayer.loopState = loopState;
+ }
+ }
+
+ property bool shuffleSupported: this.activePlayer && this.activePlayer.shuffleSupported && this.activePlayer.canControl
+ property bool hasShuffle: this.activePlayer?.shuffle ?? false
+ function setShuffle(shuffle: bool) {
+ if (this.shuffleSupported) {
+ this.activePlayer.shuffle = shuffle;
+ }
+ }
+
+ function setActivePlayer(player: MprisPlayer) {
+ const targetPlayer = player ?? Mpris.players[0];
+ console.log(`[Mpris] Active player ${targetPlayer} << ${activePlayer}`);
+
+ if (targetPlayer && this.activePlayer) {
+ this.__reverse = Mpris.players.indexOf(targetPlayer) < Mpris.players.indexOf(this.activePlayer);
+ } else {
+ // always animate forward if going to null
+ this.__reverse = false;
+ }
+
+ this.trackedPlayer = targetPlayer;
+ }
}
diff --git a/services/Network.qml b/services/Network.qml
index 231841a..bfe6c12 100644
--- a/services/Network.qml
+++ b/services/Network.qml
@@ -9,78 +9,78 @@ import QtQuick
import qs.config
Singleton {
- id: root
+ id: root
- property bool wifi: true
- property bool ethernet: false
- property string networkName: ""
- property int networkStrength
- property string state: ethernet ? Icons.resource.network.wifi : (networkName.length >= 0 && networkName !== "lo") ? (networkStrength >= 90 ? Icons.resource.network.wifi.max : networkStrength >= 80 ? Icons.resource.network.wifi.high : networkStrength >= 60 ? Icons.resource.network.wifi.mid : networkStrength >= 40 ? Icons.resource.network.wifi.low : networkStrength >= 20 ? Icons.resource.network.wifi.min : Icons.resource.network.disconnected) : Icons.resource.network.disconnected
+ property bool wifi: true
+ property bool ethernet: false
+ property string networkName: ""
+ property int networkStrength
+ property string state: ethernet ? Icons.resource.network.wifi : (networkName.length >= 0 && networkName !== "lo") ? (networkStrength >= 90 ? Icons.resource.network.wifi.max : networkStrength >= 80 ? Icons.resource.network.wifi.high : networkStrength >= 60 ? Icons.resource.network.wifi.mid : networkStrength >= 40 ? Icons.resource.network.wifi.low : networkStrength >= 20 ? Icons.resource.network.wifi.min : Icons.resource.network.disconnected) : Icons.resource.network.disconnected
- function update() {
- updateConnectionType.startCheck();
- updateNetworkName.running = true;
- updateNetworkStrength.running = true;
- }
+ function update() {
+ updateConnectionType.startCheck();
+ updateNetworkName.running = true;
+ updateNetworkStrength.running = true;
+ }
- Timer {
- interval: General.resourceUpdateInterval
- running: true
- repeat: true
- onTriggered: {
- root.update();
- interval = General.resourceUpdateInterval * 1000;
- }
- }
+ Timer {
+ interval: General.resourceUpdateInterval
+ running: true
+ repeat: true
+ onTriggered: {
+ root.update();
+ interval = General.resourceUpdateInterval * 1000;
+ }
+ }
- Process {
- id: updateConnectionType
- property string buffer
- command: ["nmcli", "-t", "-f", "NAME,TYPE,DEVICE", "c", "show", "--active"]
- running: true
- function startCheck() {
- buffer = "";
- updateConnectionType.running = true;
- }
- stdout: SplitParser {
- onRead: data => {
- updateConnectionType.buffer += data + "\n";
- }
- }
- onExited: (exitCode, exitStatus) => {
- const lines = updateConnectionType.buffer.trim().split('\n');
- let hasEthernet = false;
- let hasWifi = false;
- lines.forEach(line => {
- if (line.includes("ethernet"))
- hasEthernet = true;
- else if (line.includes("wireless"))
- hasWifi = true;
- });
- root.ethernet = hasEthernet;
- root.wifi = hasWifi;
- }
- }
+ Process {
+ id: updateConnectionType
+ property string buffer
+ command: ["nmcli", "-t", "-f", "NAME,TYPE,DEVICE", "c", "show", "--active"]
+ running: true
+ function startCheck() {
+ buffer = "";
+ updateConnectionType.running = true;
+ }
+ stdout: SplitParser {
+ onRead: data => {
+ updateConnectionType.buffer += data + "\n";
+ }
+ }
+ onExited: (exitCode, exitStatus) => {
+ const lines = updateConnectionType.buffer.trim().split('\n');
+ let hasEthernet = false;
+ let hasWifi = false;
+ lines.forEach(line => {
+ if (line.includes("ethernet"))
+ hasEthernet = true;
+ else if (line.includes("wireless"))
+ hasWifi = true;
+ });
+ root.ethernet = hasEthernet;
+ root.wifi = hasWifi;
+ }
+ }
- Process {
- id: updateNetworkName
- command: ["sh", "-c", "nmcli -t -f NAME c show --active | head -1"]
- running: true
- stdout: SplitParser {
- onRead: data => {
- root.networkName = data;
- }
- }
- }
+ Process {
+ id: updateNetworkName
+ command: ["sh", "-c", "nmcli -t -f NAME c show --active | head -1"]
+ running: true
+ stdout: SplitParser {
+ onRead: data => {
+ root.networkName = data;
+ }
+ }
+ }
- Process {
- id: updateNetworkStrength
- running: true
- command: ["sh", "-c", "nmcli -f IN-USE,SIGNAL,SSID device wifi | awk '/^\*/{if (NR!=1) {print $2}}'"]
- stdout: SplitParser {
- onRead: data => {
- root.networkStrength = parseInt(data);
- }
- }
- }
+ Process {
+ id: updateNetworkStrength
+ running: true
+ command: ["sh", "-c", "nmcli -f IN-USE,SIGNAL,SSID device wifi | awk '/^\*/{if (NR!=1) {print $2}}'"]
+ stdout: SplitParser {
+ onRead: data => {
+ root.networkStrength = parseInt(data);
+ }
+ }
+ }
}
diff --git a/services/NetworkUsage.qml b/services/NetworkUsage.qml
index c503891..9179e52 100644
--- a/services/NetworkUsage.qml
+++ b/services/NetworkUsage.qml
@@ -8,65 +8,65 @@ import "../utils/networkUsage.js" as Network
import qs.config
Singleton {
- property int up: 0
- property string upUnit: ""
- property int down: 0
- property string downUnit: ""
+ property int up: 0
+ property string upUnit: ""
+ property int down: 0
+ property string downUnit: ""
- property string __iface: ""
- property var __prev: ({
- rx: 0,
- tx: 0
- })
+ property string __iface: ""
+ property var __prev: ({
+ rx: 0,
+ tx: 0
+ })
- Timer {
- interval: General.resourceUpdateInterval * 1000
- running: true
- repeat: true
- onTriggered: update()
- }
+ Timer {
+ interval: General.resourceUpdateInterval * 1000
+ running: true
+ repeat: true
+ onTriggered: update()
+ }
- function update() {
- try {
- __iface = Network.defaultInterface(getRouteProc.stdout.text);
- } catch (e) {
- getRouteProc.running = true;
- }
- const cur = Network.getRxTxBytes(getNetDevProc.stdout.text, __iface);
- const sec = General.resourceUpdateInterval;
- const rawUp = (cur.tx - __prev.tx) / sec;
- const rawDown = (cur.rx - __prev.rx) / sec;
+ function update() {
+ try {
+ __iface = Network.defaultInterface(getRouteProc.stdout.text);
+ } catch (e) {
+ getRouteProc.running = true;
+ }
+ const cur = Network.getRxTxBytes(getNetDevProc.stdout.text, __iface);
+ const sec = General.resourceUpdateInterval;
+ const rawUp = (cur.tx - __prev.tx) / sec;
+ const rawDown = (cur.rx - __prev.rx) / sec;
- up = Network.formatSize(rawUp, false);
- upUnit = Network.formatSize(rawUp, true);
- down = Network.formatSize(rawDown, false);
- downUnit = Network.formatSize(rawDown, true);
+ up = Network.formatSize(rawUp, false);
+ upUnit = Network.formatSize(rawUp, true);
+ down = Network.formatSize(rawDown, false);
+ downUnit = Network.formatSize(rawDown, true);
- __prev = cur;
- getRouteProc.running = true;
- getNetDevProc.running = true;
- }
+ __prev = cur;
+ getRouteProc.running = true;
+ getNetDevProc.running = true;
+ }
- Process {
- id: getRouteProc
- running: true
- command: ["ip", "route"]
- stdout: StdioCollector {}
- }
+ Process {
+ id: getRouteProc
+ running: true
+ command: ["ip", "route"]
+ stdout: StdioCollector {}
+ }
- Process {
- id: getNetDevProc
- running: true
- command: ["cat", "/proc/net/dev"]
- stdout: StdioCollector {}
- }
+ Process {
+ id: getNetDevProc
+ running: true
+ command: ["cat", "/proc/net/dev"]
+ stdout: StdioCollector {}
+ }
- Component.onCompleted: {
- getRouteProc.running = true;
- getNetDevProc.running = true;
- if (getRouteProc.stdout.text)
- __iface = Network.defaultInterface(getRouteProc.stdout.text);
- if (getNetDevProc.stdout.text)
- __prev = Network.getRxTxBytes(getNetDevProc.stdout.text, __iface);
- }
+ Component.onCompleted: {
+ getRouteProc.running = true;
+ getNetDevProc.running = true;
+ if (getRouteProc.stdout.text)
+ __iface = Network.defaultInterface(getRouteProc.stdout.text);
+ if (getNetDevProc.stdout.text)
+ __prev = Network.getRxTxBytes(getNetDevProc.stdout.text, __iface);
+ }
}
diff --git a/services/Persistent.qml b/services/Persistent.qml
index 3a911bf..9077ce9 100644
--- a/services/Persistent.qml
+++ b/services/Persistent.qml
@@ -4,24 +4,24 @@ import Quickshell.Io
import qs.utils
Scope {
- id: root
- property alias adapter: fileView.adapter
- property alias fileView: fileView
- property string fileDir: Directories.state
- property string fileName: "states.json"
- property string filePath: `${root.fileDir}/${root.fileName}`
+ id: root
+ property alias adapter: fileView.adapter
+ property alias fileView: fileView
+ property string fileDir: Directories.state
+ property string fileName: "states.json"
+ property string filePath: `${root.fileDir}/${root.fileName}`
- FileView {
- id: fileView
- path: root.filePath
- watchChanges: true
- onFileChanged: reload()
- onAdapterUpdated: writeAdapter()
- onLoadFailed: error => {
- console.log("Failed to load persistent states file:", error);
- if (error == FileViewError.FileNotFound) {
- writeAdapter();
- }
- }
- }
+ FileView {
+ id: fileView
+ path: root.filePath
+ watchChanges: true
+ onFileChanged: reload()
+ onAdapterUpdated: writeAdapter()
+ onLoadFailed: error => {
+ console.log("Failed to load persistent states file:", error);
+ if (error == FileViewError.FileNotFound) {
+ writeAdapter();
+ }
+ }
+ }
}
diff --git a/services/Resource.qml b/services/Resource.qml
index 3c6c6ea..e94d8c0 100644
--- a/services/Resource.qml
+++ b/services/Resource.qml
@@ -7,114 +7,114 @@ import Quickshell.Io
import qs.config
Singleton {
- id: root
+ id: root
- property double memoryTotal: 1
- property double memoryFree: 1
- property double memoryUsed: memoryTotal - memoryFree
- property double memoryUsedPercentage: memoryUsed / memoryTotal
- property double swapTotal: 1
- property double swapFree: 1
- property double swapUsed: swapTotal - swapFree
- property double swapUsedPercentage: swapTotal > 0 ? (swapUsed / swapTotal) : 0
+ property double memoryTotal: 1
+ property double memoryFree: 1
+ property double memoryUsed: memoryTotal - memoryFree
+ property double memoryUsedPercentage: memoryUsed / memoryTotal
+ property double swapTotal: 1
+ property double swapFree: 1
+ property double swapUsed: swapTotal - swapFree
+ property double swapUsedPercentage: swapTotal > 0 ? (swapUsed / swapTotal) : 0
- property double cpuUsage: 0
- property double cpuTemp: 0
- property double cpuFreq: 0
- property var previousCpuStats
+ property double cpuUsage: 0
+ property double cpuTemp: 0
+ property double cpuFreq: 0
+ property var previousCpuStats
- property int gpuUsage: 0
- property int gpuTemp: 0
+ property int gpuUsage: 0
+ property int gpuTemp: 0
- Timer {
- interval: General.resourceUpdateInterval
- running: true
- repeat: true
- onTriggered: {
- fileMeminfo.reload();
- fileStat.reload();
- fileCpuThermal.reload();
- fileCpuInfo.reload();
+ Timer {
+ interval: General.resourceUpdateInterval
+ running: true
+ repeat: true
+ onTriggered: {
+ fileMeminfo.reload();
+ fileStat.reload();
+ fileCpuThermal.reload();
+ fileCpuInfo.reload();
- const textMeminfo = fileMeminfo.text();
- memoryTotal = Number(textMeminfo.match(/MemTotal:\s*(\d+)/)[1] ?? 1);
- memoryFree = Number(textMeminfo.match(/MemAvailable:\s*(\d+)/)[1] ?? 0);
- memoryUsed = memoryTotal - memoryFree;
- memoryUsedPercentage = memoryUsed / memoryTotal;
- swapTotal = Number(textMeminfo.match(/SwapTotal:\s*(\d+)/)[1] ?? 1);
- swapFree = Number(textMeminfo.match(/SwapFree:\s*(\d+)/)[1] ?? 0);
+ const textMeminfo = fileMeminfo.text();
+ memoryTotal = Number(textMeminfo.match(/MemTotal:\s*(\d+)/)[1] ?? 1);
+ memoryFree = Number(textMeminfo.match(/MemAvailable:\s*(\d+)/)[1] ?? 0);
+ memoryUsed = memoryTotal - memoryFree;
+ memoryUsedPercentage = memoryUsed / memoryTotal;
+ swapTotal = Number(textMeminfo.match(/SwapTotal:\s*(\d+)/)[1] ?? 1);
+ swapFree = Number(textMeminfo.match(/SwapFree:\s*(\d+)/)[1] ?? 0);
- const textStat = fileStat.text();
- const cpuLine = textStat.match(/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/);
- if (cpuLine) {
- const stats = cpuLine.slice(1).map(Number);
- const total = stats.reduce((a, b) => a + b, 0);
- const idle = stats[3];
- if (root.previousCpuStats) {
- const td = total - root.previousCpuStats.total;
- const id = idle - root.previousCpuStats.idle;
- cpuUsage = td > 0 ? (1 - id / td) : 0;
- }
- root.previousCpuStats = {
- total,
- idle
- };
- }
+ const textStat = fileStat.text();
+ const cpuLine = textStat.match(/^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)/);
+ if (cpuLine) {
+ const stats = cpuLine.slice(1).map(Number);
+ const total = stats.reduce((a, b) => a + b, 0);
+ const idle = stats[3];
+ if (root.previousCpuStats) {
+ const td = total - root.previousCpuStats.total;
+ const id = idle - root.previousCpuStats.idle;
+ cpuUsage = td > 0 ? (1 - id / td) : 0;
+ }
+ root.previousCpuStats = {
+ total,
+ idle
+ };
+ }
- const cpuTempText = fileCpuThermal.text();
- cpuTemp = cpuTempText ? parseInt(cpuTempText.trim()) / 100000 : 0;
+ const cpuTempText = fileCpuThermal.text();
+ cpuTemp = cpuTempText ? parseInt(cpuTempText.trim()) / 100000 : 0;
- const textCpuInfo = fileCpuInfo.text();
- let sum = 0, cnt = 0;
- const re = /^cpu MHz\s*:\s*([\d.]+)/mg;
- let m;
- while ((m = re.exec(textCpuInfo)) !== null) {
- sum += Number(m[1]);
- cnt++;
- }
- cpuFreq = cnt ? sum / cnt : 0;
+ const textCpuInfo = fileCpuInfo.text();
+ let sum = 0, cnt = 0;
+ const re = /^cpu MHz\s*:\s*([\d.]+)/mg;
+ let m;
+ while ((m = re.exec(textCpuInfo)) !== null) {
+ sum += Number(m[1]);
+ cnt++;
+ }
+ cpuFreq = cnt ? sum / cnt : 0;
- gpuUsageProc.running = true;
- gpuTempProc.running = true;
- interval = General.resourceUpdateInterval * cpuUsage > 0.7 || memoryUsedPercentage > 0.7 || cpuTemp > 0.7 ? 100 : 1000;
- }
- }
+ gpuUsageProc.running = true;
+ gpuTempProc.running = true;
+ interval = General.resourceUpdateInterval * cpuUsage > 0.7 || memoryUsedPercentage > 0.7 || cpuTemp > 0.7 ? 100 : 1000;
+ }
+ }
- FileView {
- id: fileMeminfo
- path: "/proc/meminfo"
- }
- FileView {
- id: fileStat
- path: "/proc/stat"
- }
- FileView {
- id: fileCpuThermal
- path: General.cpuThermalPath
- }
- FileView {
- id: fileCpuInfo
- path: "/proc/cpuinfo"
- }
+ FileView {
+ id: fileMeminfo
+ path: "/proc/meminfo"
+ }
+ FileView {
+ id: fileStat
+ path: "/proc/stat"
+ }
+ FileView {
+ id: fileCpuThermal
+ path: General.cpuThermalPath
+ }
+ FileView {
+ id: fileCpuInfo
+ path: "/proc/cpuinfo"
+ }
- Process {
- id: gpuUsageProc
- running: true
- command: ["nvidia-smi", "--query-gpu=utilization.gpu", "--format=csv,noheader,nounits"]
- stdout: StdioCollector {
- onStreamFinished: {
- root.gpuUsage = parseInt(this.text.trim());
- }
- }
- }
- Process {
- id: gpuTempProc
- running: true
- command: ["nvidia-smi", "--query-gpu=temperature.gpu", "--format=csv,noheader,nounits"]
- stdout: StdioCollector {
- onStreamFinished: {
- root.gpuTemp = parseInt(this.text.trim());
- }
- }
- }
+ Process {
+ id: gpuUsageProc
+ running: true
+ command: ["nvidia-smi", "--query-gpu=utilization.gpu", "--format=csv,noheader,nounits"]
+ stdout: StdioCollector {
+ onStreamFinished: {
+ root.gpuUsage = parseInt(this.text.trim());
+ }
+ }
+ }
+ Process {
+ id: gpuTempProc
+ running: true
+ command: ["nvidia-smi", "--query-gpu=temperature.gpu", "--format=csv,noheader,nounits"]
+ stdout: StdioCollector {
+ onStreamFinished: {
+ root.gpuTemp = parseInt(this.text.trim());
+ }
+ }
+ }
}
diff --git a/services/TimeDate.qml b/services/TimeDate.qml
index f066f46..ebefbc1 100644
--- a/services/TimeDate.qml
+++ b/services/TimeDate.qml
@@ -4,79 +4,79 @@ import Quickshell
import QtQuick
Singleton {
- id: root
- readonly property string time: {
- // fuck you qt give me my 12 hr time
- var h = clock.date.getHours();
- var m = clock.date.getMinutes();
- var s = clock.date.getSeconds();
- h = h % 12;
- if (h === 0)
- h = 12;
- return (h < 10 ? "0" : "") + h + ":" + (m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s;
- }
- readonly property int hours: {
- var h = clock.date.getHours();
- h = h % 12;
- if (h === 0)
- h = 12;
- return h;
- }
- readonly property int minutes: clock.date.getMinutes()
- readonly property int seconds: clock.date.getSeconds()
+ id: root
+ readonly property string time: {
+ // fuck you qt give me my 12 hr time
+ var h = clock.date.getHours();
+ var m = clock.date.getMinutes();
+ var s = clock.date.getSeconds();
+ h = h % 12;
+ if (h === 0)
+ h = 12;
+ return (h < 10 ? "0" : "") + h + ":" + (m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s;
+ }
+ readonly property int hours: {
+ var h = clock.date.getHours();
+ h = h % 12;
+ if (h === 0)
+ h = 12;
+ return h;
+ }
+ readonly property int minutes: clock.date.getMinutes()
+ readonly property int seconds: clock.date.getSeconds()
- readonly property string date: Qt.formatDateTime(clock.date, "dddd dd/MM")
+ readonly property string date: Qt.formatDateTime(clock.date, "dddd dd/MM")
- function sinceWhen(d) {
- if (typeof d === "string")
- return;
+ function sinceWhen(d) {
+ if (typeof d === "string")
+ return;
- var now = clock.date;
+ var now = clock.date;
- function startOfDay(x) {
- return new Date(x.getFullYear(), x.getMonth(), x.getDate(), 0, 0, 0, 0);
- }
+ function startOfDay(x) {
+ return new Date(x.getFullYear(), x.getMonth(), x.getDate(), 0, 0, 0, 0);
+ }
- function startOfWeek(x) {
- var dow = x.getDay();
- var mondayOffset = (dow + 6) % 7;
- var sod = startOfDay(x);
- sod.setDate(sod.getDate() - mondayOffset);
- return sod;
- }
+ function startOfWeek(x) {
+ var dow = x.getDay();
+ var mondayOffset = (dow + 6) % 7;
+ var sod = startOfDay(x);
+ sod.setDate(sod.getDate() - mondayOffset);
+ return sod;
+ }
- function fmt12h(dateObj) {
- var h24 = dateObj.getHours();
- var m = dateObj.getMinutes();
- var h12 = h24 % 12;
- if (h12 === 0)
- h12 = 12;
- var ampm = h24 < 12 ? "AM" : "PM";
- return ((h12 < 10 ? "0" : "") + h12 + ":" + (m < 10 ? "0" : "") + m + " " + ampm);
- }
+ function fmt12h(dateObj) {
+ var h24 = dateObj.getHours();
+ var m = dateObj.getMinutes();
+ var h12 = h24 % 12;
+ if (h12 === 0)
+ h12 = 12;
+ var ampm = h24 < 12 ? "AM" : "PM";
+ return ((h12 < 10 ? "0" : "") + h12 + ":" + (m < 10 ? "0" : "") + m + " " + ampm);
+ }
- function weekdayName(dateObj) {
- return Qt.formatDateTime(dateObj, "dddd");
- }
+ function weekdayName(dateObj) {
+ return Qt.formatDateTime(dateObj, "dddd");
+ }
- var nowSOD = startOfDay(now).getTime();
- var dSOD = startOfDay(d).getTime();
- if (nowSOD === dSOD) {
- return fmt12h(d);
- }
+ var nowSOD = startOfDay(now).getTime();
+ var dSOD = startOfDay(d).getTime();
+ if (nowSOD === dSOD) {
+ return fmt12h(d);
+ }
- var nowSOW = startOfWeek(now).getTime();
- var dSOW = startOfWeek(d).getTime();
- if (nowSOW === dSOW) {
- return weekdayName(d) + " " + fmt12h(d);
- }
+ var nowSOW = startOfWeek(now).getTime();
+ var dSOW = startOfWeek(d).getTime();
+ if (nowSOW === dSOW) {
+ return weekdayName(d) + " " + fmt12h(d);
+ }
- var ymd = Qt.formatDateTime(d, "yyyy-MM-dd");
- return ymd + " at " + fmt12h(d);
- }
+ var ymd = Qt.formatDateTime(d, "yyyy-MM-dd");
+ return ymd + " at " + fmt12h(d);
+ }
- SystemClock {
- id: clock
- precision: SystemClock.Seconds
- }
+ SystemClock {
+ id: clock
+ precision: SystemClock.Seconds
+ }
}