From 9b75840f1d46405997f78504f38aa1251a56436c Mon Sep 17 00:00:00 2001 From: Quadbyte Date: Sun, 17 Aug 2025 12:00:38 -0400 Subject: [PATCH 1/4] Update README.md --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 044801c..fd0e8f9 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,8 @@ A sleek, minimal, and thoughtfully crafted desktop shell for Wayland using **Qui - `matugen` - Material You color scheme generation - `cava` - Audio visualizer component - `gpu-screen-recorder` - Screen recording functionality +- `brightnessctl` - For internal/laptop monitor brightness +- `ddcutil` - For desktop monitor brightness --- @@ -120,6 +122,8 @@ qs ipc call lockScreen toggle ### Configuration Access settings through the side panel (top right button) to configure weather, wallpapers, screen recording, audio, network, and theme options. +Configuration is usually stored in ~/.config/noctalia +If you upgrade from v1, you can delete the old configuration folder at ~/.config/Noctalia (with capital N) ### Application Launcher @@ -218,10 +222,11 @@ Noctalia/ ### Contributing -1. Follow the existing code style and patterns -2. Use the modular architecture for new features -3. Implement proper error handling and logging -4. Test with both Hyprland and Niri compositors (if applicable) +1. All Pull requests should be based on the "dev" branch +2. Follow the existing code style and patterns +3. Use the modular architecture for new features +4. Implement proper error handling and logging +5. Test with both Hyprland and Niri compositors (if applicable) Contributions are welcome! Don't worry about being perfect - every contribution helps! Whether it's fixing a small bug, adding a new feature, or improving documentation, we welcome all contributions. Feel free to open an issue to discuss ideas or ask questions before diving in. For feature requests and ideas, you can also use our discussions page. From 8c95800de3aa4c5fb61fbbacc7c02bbee9dba8dc Mon Sep 17 00:00:00 2001 From: Quadbyte Date: Sun, 17 Aug 2025 12:07:48 -0400 Subject: [PATCH 2/4] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fd0e8f9..73aae67 100644 --- a/README.md +++ b/README.md @@ -121,9 +121,9 @@ qs ipc call lockScreen toggle ### Configuration -Access settings through the side panel (top right button) to configure weather, wallpapers, screen recording, audio, network, and theme options. -Configuration is usually stored in ~/.config/noctalia -If you upgrade from v1, you can delete the old configuration folder at ~/.config/Noctalia (with capital N) +Access settings through the side panel (top right button) to configure weather, wallpapers, screen recording, audio, network, and theme options. +Configuration is usually stored in ~/.config/noctalia +If you upgrade from v1, you can delete the old configuration folder at ~/.config/Noctalia (with capital N) ### Application Launcher From a71cfb76765b62ce36b6bb8e7e877f85ce3830a8 Mon Sep 17 00:00:00 2001 From: Lysec <52084453+Ly-sec@users.noreply.github.com> Date: Sun, 17 Aug 2025 18:13:19 +0200 Subject: [PATCH 3/4] Update release.yml --- .github/workflows/release.yml | 37 ++++++++++++----------------------- 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 094beb6..703a0c1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,30 +27,19 @@ jobs: mv *.tar.gz ${{ github.workspace }}/ - name: Generate release notes - id: release_notes run: | - PREV_TAG=$(git describe --tags --abbrev=0 @^ 2>/dev/null || echo "") - RANGE="${PREV_TAG}..HEAD" - - PR_NOTES="" - COMMIT_NOTES="" - - git log $RANGE --pretty=format:"%H|%s|%an" | while IFS='|' read -r SHA MSG AUTHOR; do - SHORT_MSG=$(echo "$MSG" | cut -c1-80) - if [[ "$MSG" =~ Merge\ pull\ request\ \#([0-9]+) ]]; then - PR_NUM="${BASH_REMATCH[1]}" - PR_TITLE=$(echo "$SHORT_MSG" | sed -E "s/Merge pull request #$PR_NUM //") - PR_NOTES+="- [PR #$PR_NUM](https://github.com/${GITHUB_REPOSITORY}/pull/$PR_NUM): $PR_TITLE by $AUTHOR\n" - else - COMMIT_NOTES+="- [$SHA](https://github.com/${GITHUB_REPOSITORY}/commit/$SHA): $SHORT_MSG by $AUTHOR\n" - fi - done - - NOTES="### Merged PRs\n$PR_NOTES\n### Direct commits\n$COMMIT_NOTES" - - echo "RELEASE_NOTES<> $GITHUB_ENV - echo -e "$NOTES" >> $GITHUB_ENV - echo "EOF" >> $GITHUB_ENV + PREV_TAG=$(git describe --tags --abbrev=0 ${{ github.ref }}^ 2>/dev/null || echo "") + if [ -z "$PREV_TAG" ]; then + RANGE=$(git rev-list --max-parents=0 HEAD)..HEAD + else + RANGE=$PREV_TAG..HEAD + fi + echo "# Release ${{ github.ref_name }}" > release_notes.md + echo "" >> release_notes.md + echo "## Changes since $PREV_TAG" >> release_notes.md + echo "" >> release_notes.md + git log $RANGE --pretty=format:"- %s ([%h](https://github.com/${{ github.repository }}/commit/%H)) by %an" >> release_notes.md + echo "" >> release_notes.md - name: Create GitHub Release uses: softprops/action-gh-release@v1 @@ -58,6 +47,6 @@ jobs: files: | noctalia-${{ github.ref_name }}.tar.gz noctalia-latest.tar.gz - body: ${{ env.RELEASE_NOTES }} + body_path: release_notes.md env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 4c0ab4aec7cbc11ae3e00e708ea5466c28972c7e Mon Sep 17 00:00:00 2001 From: Ly-sec Date: Sun, 17 Aug 2025 21:55:12 +0200 Subject: [PATCH 4/4] Revert to simple math for now, fix LockScreen warnings --- Helpers/MathHelper.js | 120 ---------------------------- Modules/AppLauncher/AppLauncher.qml | 70 ++++++++++------ Modules/LockScreen/LockScreen.qml | 9 +-- 3 files changed, 49 insertions(+), 150 deletions(-) delete mode 100644 Helpers/MathHelper.js diff --git a/Helpers/MathHelper.js b/Helpers/MathHelper.js deleted file mode 100644 index cc86775..0000000 --- a/Helpers/MathHelper.js +++ /dev/null @@ -1,120 +0,0 @@ -// Math helper functions for calculator functionality -var MathHelper = { - // Basic arithmetic operations - add: (a, b) => a + b, - subtract: (a, b) => a - b, - multiply: (a, b) => a * b, - divide: (a, b) => b !== 0 ? a / b : NaN, - - // Power and roots - pow: (base, exponent) => Math.pow(base, exponent), - sqrt: (x) => x >= 0 ? Math.sqrt(x) : NaN, - cbrt: (x) => Math.cbrt(x), - - // Trigonometric functions (in radians) - sin: (x) => Math.sin(x), - cos: (x) => Math.cos(x), - tan: (x) => Math.tan(x), - asin: (x) => Math.asin(x), - acos: (x) => Math.acos(x), - atan: (x) => Math.atan(x), - - // Logarithmic functions - log: (x) => x > 0 ? Math.log(x) : NaN, - log10: (x) => x > 0 ? Math.log10(x) : NaN, - log2: (x) => x > 0 ? Math.log2(x) : NaN, - - // Other mathematical functions - abs: (x) => Math.abs(x), - floor: (x) => Math.floor(x), - ceil: (x) => Math.ceil(x), - round: (x) => Math.round(x), - min: (...args) => Math.min(...args), - max: (...args) => Math.max(...args), - - // Constants - PI: Math.PI, - E: Math.E, - - // Factorial - factorial: (n) => { - if (n < 0 || n !== Math.floor(n)) return NaN; - if (n === 0 || n === 1) return 1; - let result = 1; - for (let i = 2; i <= n; i++) { - result *= i; - } - return result; - }, - - // Percentage - percent: (value, total) => (value / total) * 100, - - // Degrees to radians and vice versa - toRadians: (degrees) => degrees * (Math.PI / 180), - toDegrees: (radians) => radians * (180 / Math.PI), - - // Safe evaluation with math functions - evaluate: (expression) => { - try { - // Replace common math functions with MathHelper equivalents - let processedExpr = expression - .replace(/\bpi\b/gi, 'MathHelper.PI') - .replace(/\be\b/gi, 'MathHelper.E') - .replace(/\bsin\b/gi, 'MathHelper.sin') - .replace(/\bcos\b/gi, 'MathHelper.cos') - .replace(/\btan\b/gi, 'MathHelper.tan') - .replace(/\basin\b/gi, 'MathHelper.asin') - .replace(/\bacos\b/gi, 'MathHelper.acos') - .replace(/\batan\b/gi, 'MathHelper.atan') - .replace(/\blog\b/gi, 'MathHelper.log') - .replace(/\blog10\b/gi, 'MathHelper.log10') - .replace(/\blog2\b/gi, 'MathHelper.log2') - .replace(/\bsqrt\b/gi, 'MathHelper.sqrt') - .replace(/\bcbrt\b/gi, 'MathHelper.cbrt') - .replace(/\bpow\b/gi, 'MathHelper.pow') - .replace(/\babs\b/gi, 'MathHelper.abs') - .replace(/\bfloor\b/gi, 'MathHelper.floor') - .replace(/\bceil\b/gi, 'MathHelper.ceil') - .replace(/\bround\b/gi, 'MathHelper.round') - .replace(/\bmin\b/gi, 'MathHelper.min') - .replace(/\bmax\b/gi, 'MathHelper.max') - .replace(/\bfactorial\b/gi, 'MathHelper.factorial') - .replace(/\bpercent\b/gi, 'MathHelper.percent') - .replace(/\btoRadians\b/gi, 'MathHelper.toRadians') - .replace(/\btoDegrees\b/gi, 'MathHelper.toDegrees'); - - // Evaluate the expression - const result = Function('MathHelper', 'return ' + processedExpr)(MathHelper); - - // Check if result is valid - if (isNaN(result) || !isFinite(result)) { - return null; - } - - return result; - } catch (error) { - return null; - } - }, - - // Format result for display - formatResult: (result) => { - if (result === null || isNaN(result) || !isFinite(result)) { - return "Error"; - } - - // For very large or small numbers, use scientific notation - if (Math.abs(result) >= 1e10 || (Math.abs(result) < 1e-10 && result !== 0)) { - return result.toExponential(6); - } - - // For integers, don't show decimal places - if (Number.isInteger(result)) { - return result.toString(); - } - - // For decimals, limit to 8 significant digits - return parseFloat(result.toPrecision(8)).toString(); - } -}; \ No newline at end of file diff --git a/Modules/AppLauncher/AppLauncher.qml b/Modules/AppLauncher/AppLauncher.qml index d296f62..885aaa3 100644 --- a/Modules/AppLauncher/AppLauncher.qml +++ b/Modules/AppLauncher/AppLauncher.qml @@ -11,7 +11,6 @@ import qs.Services import qs.Widgets import "../../Helpers/FuzzySort.js" as Fuzzysort -import "../../Helpers/MathHelper.js" as MathHelper NLoader { id: appLauncher @@ -188,26 +187,54 @@ NLoader { // Handle calculator if (query.startsWith(">calc")) { var expr = searchText.slice(5).trim() - if (expr && isMathExpression(expr)) { - var value = safeEval(expr) - if (value !== null && value !== undefined && value !== "") { - var formattedResult = MathHelper.MathHelper.formatResult(value) + if (expr && expr !== "") { + try { + // Simple evaluation - only allow basic math operations + var sanitizedExpr = expr.replace(/[^0-9+\-*/().\s]/g, '') + var result = eval(sanitizedExpr) + + if (isFinite(result) && !isNaN(result)) { + var displayResult = Number.isInteger(result) ? result.toString() : result.toFixed(6).replace(/\.?0+$/, '') + results.push({ + "isCalculator": true, + "name": `${expr} = ${displayResult}`, + "result": result, + "expr": expr, + "icon": "calculate", + "execute": function () { + Quickshell.clipboardText = displayResult + copyText(displayResult) + Quickshell.execDetached(["notify-send", "Calculator", `${expr} = ${displayResult} (copied to clipboard)`]) + } + }) + } else { + results.push({ + "isCalculator": true, + "name": "Invalid expression", + "content": "Please enter a valid mathematical expression", + "icon": "calculate", + "execute": function () {} + }) + } + } catch (error) { results.push({ - "isCalculator": true, - "name": `Calculator: ${expr} = ${formattedResult}`, - "result": value, - "expr": expr, - "icon": "calculate", - "execute": function () { - Quickshell.clipboardText = String(formattedResult) - clipboardTextCopyProcess.copyText(String(formattedResult)) - Quickshell.execDetached( - ["notify-send", "Calculator Result", `${expr} = ${formattedResult} (copied to clipboard)`]) - } - }) + "isCalculator": true, + "name": "Invalid expression", + "content": "Please enter a valid mathematical expression", + "icon": "calculate", + "execute": function () {} + }) } + } else { + // Show placeholder when just ">calc" is entered + results.push({ + "isCalculator": true, + "name": "Calculator", + "content": "Enter a mathematical expression (e.g., 5+5, 2*3, 10/2)", + "icon": "calculate", + "execute": function () {} + }) } - return results } @@ -240,14 +267,7 @@ NLoader { updateClipboardHistory() } - function isMathExpression(str) { - // Allow more characters for enhanced math functions - return /^[-+*/().0-9\s\w]+$/.test(str) - } - function safeEval(expr) { - return MathHelper.MathHelper.evaluate(expr) - } // Main content container Rectangle { diff --git a/Modules/LockScreen/LockScreen.qml b/Modules/LockScreen/LockScreen.qml index 6a9bcf7..8c73a40 100644 --- a/Modules/LockScreen/LockScreen.qml +++ b/Modules/LockScreen/LockScreen.qml @@ -551,9 +551,8 @@ WlSessionLock { height: 20 * scaling color: Color.mPrimary visible: passwordInput.activeFocus - anchors.left: asterisksText.right - anchors.leftMargin: Style.marginTiniest * scaling - anchors.verticalCenter: asterisksText.verticalCenter + Layout.leftMargin: asterisksText.width + Style.marginTiniest * scaling + Layout.alignment: Qt.AlignVCenter SequentialAnimation on opacity { loops: Animation.Infinite @@ -619,7 +618,7 @@ WlSessionLock { onClicked: lock.unlockAttempt() SequentialAnimation on scale { - running: containsMouse + running: executeButtonArea.containsMouse NumberAnimation { to: 1.05 duration: Style.animationFast @@ -628,7 +627,7 @@ WlSessionLock { } SequentialAnimation on scale { - running: !containsMouse + running: !executeButtonArea.containsMouse NumberAnimation { to: 1.0 duration: Style.animationFast