something-x-dev 1.7.0.dev15__tar.gz → 1.7.1.dev15__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. something_x_dev-1.7.1.dev15/.github/CODEOWNERS +1 -0
  2. something_x_dev-1.7.1.dev15/.github/workflows/ci.yml +64 -0
  3. something_x_dev-1.7.1.dev15/.github/workflows/release-dev.yml +97 -0
  4. something_x_dev-1.7.1.dev15/.github/workflows/release.yml +190 -0
  5. something_x_dev-1.7.1.dev15/.gitignore +46 -0
  6. something_x_dev-1.7.1.dev15/DEVICES.md +37 -0
  7. {something_x_dev-1.7.0.dev15/something_x_dev.egg-info → something_x_dev-1.7.1.dev15}/PKG-INFO +1 -1
  8. something_x_dev-1.7.1.dev15/PKGBUILD +24 -0
  9. something_x_dev-1.7.1.dev15/ROADMAP.md +69 -0
  10. something_x_dev-1.7.1.dev15/cliff.toml +41 -0
  11. something_x_dev-1.7.1.dev15/data/style.css +355 -0
  12. something_x_dev-1.7.1.dev15/docs/RELEASING.md +192 -0
  13. something_x_dev-1.7.1.dev15/docs/docs.html +802 -0
  14. something_x_dev-1.7.1.dev15/docs/index.html +588 -0
  15. something_x_dev-1.7.1.dev15/flake.nix +66 -0
  16. something_x_dev-1.7.1.dev15/main.py +10 -0
  17. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/__init__.py +4 -5
  18. something_x_dev-1.7.1.dev15/nothing_app/_version.py +24 -0
  19. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/pyproject.toml +10 -2
  20. something_x_dev-1.7.1.dev15/requirements.txt +3 -0
  21. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15/something_x_dev.egg-info}/PKG-INFO +1 -1
  22. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/something_x_dev.egg-info/SOURCES.txt +20 -0
  23. something_x_dev-1.7.1.dev15/somethingx +3 -0
  24. something_x_dev-1.7.1.dev15/tests/__init__.py +0 -0
  25. something_x_dev-1.7.1.dev15/tests/conftest.py +40 -0
  26. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/LICENSE +0 -0
  27. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/README.md +0 -0
  28. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/application.py +0 -0
  29. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/bluetooth.py +0 -0
  30. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/data/__init__.py +0 -0
  31. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/data/com.something.x.omarchy.desktop +0 -0
  32. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/data/style.css +0 -0
  33. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/pages/__init__.py +0 -0
  34. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/pages/device.py +0 -0
  35. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/pages/home.py +0 -0
  36. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/profiles.py +0 -0
  37. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/protocol.py +0 -0
  38. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/splash.py +0 -0
  39. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/tray.py +0 -0
  40. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/nothing_app/window.py +0 -0
  41. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/setup.cfg +0 -0
  42. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/something_x_dev.egg-info/dependency_links.txt +0 -0
  43. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/something_x_dev.egg-info/entry_points.txt +0 -0
  44. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/something_x_dev.egg-info/requires.txt +0 -0
  45. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/something_x_dev.egg-info/top_level.txt +0 -0
  46. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/tests/test_bluetooth.py +0 -0
  47. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/tests/test_crc.py +0 -0
  48. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/tests/test_profiles.py +0 -0
  49. {something_x_dev-1.7.0.dev15 → something_x_dev-1.7.1.dev15}/tests/test_protocol.py +0 -0
@@ -0,0 +1 @@
1
+ * @SoaOaoS
@@ -0,0 +1,64 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches-ignore: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: read
11
+ pull-requests: write # needed for reviewdog to post inline comments
12
+
13
+ jobs:
14
+ lint:
15
+ name: Lint & format
16
+ runs-on: ubuntu-latest
17
+
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: "3.11"
24
+
25
+ - name: Install ruff
26
+ run: pip install ruff
27
+
28
+ - name: Setup reviewdog
29
+ uses: reviewdog/action-setup@v1
30
+ with:
31
+ reviewdog_version: latest
32
+
33
+ # Posts inline review comments on the PR diff for every ruff finding
34
+ - name: Lint with reviewdog
35
+ run: ruff check --output-format rdjson nothing_app/ | reviewdog -f=rdjson -reporter=github-pr-review -fail-on-error
36
+ env:
37
+ REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
38
+
39
+ # Still fail the job if formatting is wrong
40
+ - name: Check formatting
41
+ run: ruff format --check nothing_app/
42
+
43
+ test:
44
+ name: Unit tests
45
+ runs-on: ubuntu-latest
46
+
47
+ steps:
48
+ - uses: actions/checkout@v4
49
+
50
+ - name: Install system dependencies
51
+ run: |
52
+ sudo apt-get update -q
53
+ sudo apt-get install -y python3-gi python3-gi-cairo gir1.2-gtk-4.0 libgirepository1.0-dev
54
+
55
+ # Use a venv that inherits system site-packages so apt-installed gi is visible.
56
+ # PyGObject cannot be pip-built without Cairo/GLib headers; use the distro package.
57
+ - name: Create venv with system site-packages
58
+ run: python3 -m venv --system-site-packages .venv
59
+
60
+ - name: Install test dependencies
61
+ run: .venv/bin/pip install pytest pytest-cov
62
+
63
+ - name: Run tests
64
+ run: .venv/bin/pytest --tb=short --cov=nothing_app --cov-report=term-missing
@@ -0,0 +1,97 @@
1
+ name: Release Dev
2
+
3
+ on:
4
+ push:
5
+ branches: [develop]
6
+
7
+ permissions:
8
+ contents: write
9
+ id-token: write # for PyPI OIDC trusted publishing
10
+
11
+ jobs:
12
+ release-dev:
13
+ runs-on: ubuntu-latest
14
+ if: "!contains(github.event.head_commit.message, '[skip ci]')"
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+
21
+ # ── Get version from setuptools-scm ────────────────────────────────
22
+ # After tag v1.7.0, develop automatically produces 1.7.1.devN
23
+ - name: Get dev version
24
+ id: version
25
+ run: |
26
+ pip install setuptools-scm
27
+ DEV_VERSION=$(python3 -m setuptools_scm)
28
+ SHORT_SHA=$(git rev-parse --short HEAD)
29
+ echo "dev_version=$DEV_VERSION" >> $GITHUB_OUTPUT
30
+ echo "short_sha=$SHORT_SHA" >> $GITHUB_OUTPUT
31
+ echo "Dev version: $DEV_VERSION (sha: $SHORT_SHA)"
32
+
33
+ # ── Patch package name for dev channel ─────────────────────────────
34
+ - name: Patch package name
35
+ run: |
36
+ sed -i 's/^name\s*=\s*"something-x"/name = "something-x-dev"/' pyproject.toml
37
+ sed -i 's/^something-x = /something-x-dev = /' pyproject.toml
38
+ grep -E "^name|something-x" pyproject.toml
39
+
40
+ # ── Build wheel + sdist ─────────────────────────────────────────────
41
+ - name: Set up Python
42
+ uses: actions/setup-python@v5
43
+ with:
44
+ python-version: "3.11"
45
+
46
+ - name: Build distribution
47
+ run: |
48
+ pip install build
49
+ python -m build
50
+ ls dist/
51
+
52
+ # ── Generate changelog with git-cliff ──────────────────────────────
53
+ - name: Install git-cliff
54
+ run: pip install git-cliff
55
+
56
+ - name: Generate pre-release notes
57
+ run: |
58
+ git cliff --unreleased --strip all 2>/dev/null > /tmp/cliff_body.md
59
+ if [ ! -s /tmp/cliff_body.md ]; then
60
+ echo "No user-facing changes since last release." > /tmp/cliff_body.md
61
+ fi
62
+
63
+ cat > /tmp/release_notes.md <<HEADER
64
+ ## something-x-dev ${{ steps.version.outputs.dev_version }}
65
+
66
+ > Pre-release build from \`develop\` — not for production use.
67
+
68
+ **Commit**: \`${{ steps.version.outputs.short_sha }}\`
69
+
70
+ ### Changes since last stable release
71
+
72
+ HEADER
73
+ cat /tmp/cliff_body.md >> /tmp/release_notes.md
74
+ cat >> /tmp/release_notes.md <<'FOOTER'
75
+
76
+ ### Install
77
+
78
+ ```bash
79
+ pip install something-x-dev==${{ steps.version.outputs.dev_version }}
80
+
81
+ # Or download the wheel below
82
+ pip install something_x_dev-${{ steps.version.outputs.dev_version }}-py3-none-any.whl
83
+ ```
84
+ FOOTER
85
+
86
+ # ── GitHub pre-release ──────────────────────────────────────────────
87
+ - name: Create GitHub pre-release
88
+ uses: softprops/action-gh-release@v2
89
+ with:
90
+ tag_name: "dev-${{ steps.version.outputs.short_sha }}"
91
+ prerelease: true
92
+ body_path: /tmp/release_notes.md
93
+ files: dist/*
94
+
95
+ # ── Publish to PyPI (OIDC — requires trusted publisher configured) ──
96
+ - name: Publish to PyPI
97
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,190 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+
7
+ permissions:
8
+ contents: write
9
+ id-token: write # for PyPI OIDC trusted publishing
10
+
11
+ jobs:
12
+ release:
13
+ runs-on: ubuntu-latest
14
+ if: "!contains(github.event.head_commit.message, '[skip ci]')"
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0
20
+ token: ${{ secrets.RELEASE_PAT }}
21
+
22
+ # ── Determine version bump from conventional commit ─────────────────
23
+ - name: Parse commit and bump version
24
+ id: version
25
+ run: |
26
+ COMMIT_MSG=$(git log -1 --pretty=%B)
27
+ echo "Commit: $COMMIT_MSG"
28
+
29
+ # Read current version from last vX.Y.Z tag (not pyproject.toml)
30
+ CURRENT=$(git describe --tags --abbrev=0 --match "v[0-9]*.[0-9]*.[0-9]*" 2>/dev/null | sed 's/^v//')
31
+ if [ -z "$CURRENT" ]; then
32
+ CURRENT="0.0.0"
33
+ fi
34
+ echo "Current version (last tag): $CURRENT"
35
+
36
+ MAJOR=$(echo $CURRENT | cut -d. -f1)
37
+ MINOR=$(echo $CURRENT | cut -d. -f2)
38
+ PATCH=$(echo $CURRENT | cut -d. -f3)
39
+
40
+ if echo "$COMMIT_MSG" | grep -qE "(^(feat|fix|refactor|perf)!:)|(BREAKING CHANGE:)"; then
41
+ BUMP=major
42
+ MAJOR=$((MAJOR + 1)); MINOR=0; PATCH=0
43
+ elif echo "$COMMIT_MSG" | grep -qE "^feat(\([^)]+\))?:"; then
44
+ BUMP=minor
45
+ MINOR=$((MINOR + 1)); PATCH=0
46
+ elif echo "$COMMIT_MSG" | grep -qE "^(fix|perf|refactor)(\([^)]+\))?:"; then
47
+ BUMP=patch
48
+ PATCH=$((PATCH + 1))
49
+ else
50
+ echo "Commit type does not trigger a release (docs/chore/style/ci/test). Skipping."
51
+ echo "skip=true" >> $GITHUB_OUTPUT
52
+ exit 0
53
+ fi
54
+
55
+ NEW="$MAJOR.$MINOR.$PATCH"
56
+ echo "Bump: $BUMP → $CURRENT → $NEW"
57
+ echo "current=$CURRENT" >> $GITHUB_OUTPUT
58
+ echo "new=$NEW" >> $GITHUB_OUTPUT
59
+ echo "bump=$BUMP" >> $GITHUB_OUTPUT
60
+ echo "skip=false" >> $GITHUB_OUTPUT
61
+
62
+ # ── Tag and push (no pyproject.toml commit needed) ──────────────────
63
+ - name: Create and push release tag
64
+ if: steps.version.outputs.skip != 'true'
65
+ run: |
66
+ git config user.name "github-actions[bot]"
67
+ git config user.email "github-actions[bot]@users.noreply.github.com"
68
+ git tag "v${{ steps.version.outputs.new }}"
69
+ git push origin "v${{ steps.version.outputs.new }}"
70
+
71
+ # ── Generate changelog with git-cliff ──────────────────────────────
72
+ - name: Install git-cliff
73
+ if: steps.version.outputs.skip != 'true'
74
+ run: pip install git-cliff
75
+
76
+ - name: Generate release notes
77
+ if: steps.version.outputs.skip != 'true'
78
+ run: |
79
+ # --latest: commits from the previous vX.Y.Z tag up to the tag we just pushed
80
+ # cliff.toml: skips merge commits, ignores dev-* tags, filters to conventional commits
81
+ git cliff --latest --strip all 2>/dev/null > /tmp/cliff_body.md
82
+ if [ ! -s /tmp/cliff_body.md ]; then
83
+ echo "No user-facing changes in this release." > /tmp/cliff_body.md
84
+ fi
85
+
86
+ # Prepend the header + install block; cliff body goes in the middle
87
+ cat > /tmp/release_notes.md <<HEADER
88
+ ## Something X v${{ steps.version.outputs.new }}
89
+
90
+ HEADER
91
+ cat /tmp/cliff_body.md >> /tmp/release_notes.md
92
+ cat >> /tmp/release_notes.md <<'FOOTER'
93
+
94
+ ### Install
95
+
96
+ ```bash
97
+ # Arch / Omarchy (recommended)
98
+ sudo pacman -S python-gobject python-dbus python-cairo gtk4 libadwaita
99
+ pip install something-x==${{ steps.version.outputs.new }}
100
+
101
+ # Or download the wheel below
102
+ pip install something_x-${{ steps.version.outputs.new }}-py3-none-any.whl
103
+ ```
104
+ FOOTER
105
+
106
+ echo "--- Release notes preview ---"
107
+ cat /tmp/release_notes.md
108
+
109
+ # ── Build wheel + sdist ─────────────────────────────────────────────
110
+ - name: Set up Python
111
+ if: steps.version.outputs.skip != 'true'
112
+ uses: actions/setup-python@v5
113
+ with:
114
+ python-version: "3.11"
115
+
116
+ - name: Build distribution
117
+ if: steps.version.outputs.skip != 'true'
118
+ run: |
119
+ pip install build
120
+ python -m build
121
+ ls dist/
122
+
123
+ # ── Generate changelog with git-cliff ──────────────────────────────
124
+ - name: Install git-cliff
125
+ if: steps.version.outputs.skip != 'true'
126
+ run: pip install git-cliff
127
+
128
+ - name: Generate release notes
129
+ if: steps.version.outputs.skip != 'true'
130
+ run: |
131
+ git cliff --latest --strip all 2>/dev/null > /tmp/cliff_body.md
132
+ if [ ! -s /tmp/cliff_body.md ]; then
133
+ echo "No user-facing changes in this release." > /tmp/cliff_body.md
134
+ fi
135
+
136
+ cat > /tmp/release_notes.md <<HEADER
137
+ ## Something X v${{ steps.version.outputs.new }}
138
+
139
+ HEADER
140
+ cat /tmp/cliff_body.md >> /tmp/release_notes.md
141
+ cat >> /tmp/release_notes.md <<'FOOTER'
142
+
143
+ ### Install
144
+
145
+ ```bash
146
+ # Arch / Omarchy (recommended)
147
+ sudo pacman -S python-gobject python-cairo gtk4 libadwaita
148
+ pip install something-x==${{ steps.version.outputs.new }}
149
+
150
+ # Or download the wheel below
151
+ pip install something_x-${{ steps.version.outputs.new }}-py3-none-any.whl
152
+ ```
153
+ FOOTER
154
+
155
+ # ── GitHub Release ──────────────────────────────────────────────────
156
+ - name: Create GitHub Release
157
+ if: steps.version.outputs.skip != 'true'
158
+ uses: softprops/action-gh-release@v2
159
+ with:
160
+ tag_name: "v${{ steps.version.outputs.new }}"
161
+ body_path: /tmp/release_notes.md
162
+ files: dist/*
163
+
164
+ # ── Publish to PyPI (OIDC trusted publisher) ────────────────────────
165
+ - name: Publish to PyPI
166
+ if: steps.version.outputs.skip != 'true'
167
+ uses: pypa/gh-action-pypi-publish@release/v1
168
+
169
+ # ── Update AUR package ──────────────────────────────────────────────
170
+ - name: Update PKGBUILD and push to AUR
171
+ if: steps.version.outputs.skip != 'true'
172
+ env:
173
+ NEW_VERSION: ${{ steps.version.outputs.new }}
174
+ run: |
175
+ SHA256=$(sha256sum dist/something_x-${NEW_VERSION}.tar.gz | awk '{print $1}')
176
+ sed -i "s/^pkgver=.*/pkgver=${NEW_VERSION}/" PKGBUILD
177
+ sed -i "s/^pkgrel=.*/pkgrel=1/" PKGBUILD
178
+ sed -i "s/sha256sums=('[^']*')/sha256sums=('${SHA256}')/" PKGBUILD
179
+
180
+ - name: Deploy to AUR
181
+ if: steps.version.outputs.skip != 'true'
182
+ uses: KSXGitHub/github-actions-deploy-aur@v3.0.1
183
+ with:
184
+ pkgname: something-x
185
+ pkgbuild: ./PKGBUILD
186
+ commit_username: github-actions[bot]
187
+ commit_email: github-actions[bot]@users.noreply.github.com
188
+ ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
189
+ commit_message: "Update to ${{ steps.version.outputs.new }}"
190
+ allow_empty_commits: false
@@ -0,0 +1,46 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.pyo
5
+ *.pyd
6
+ *.so
7
+ *.egg
8
+ *.egg-info/
9
+ .eggs/
10
+ MANIFEST
11
+
12
+ # Build / distribution
13
+ dist/
14
+ build/
15
+ *.whl
16
+ *.tar.gz
17
+
18
+ # Virtualenvs
19
+ .venv/
20
+ venv/
21
+ env/
22
+ .env
23
+ ENV/
24
+
25
+ # Tools
26
+ .cache/
27
+ .mypy_cache/
28
+ .ruff_cache/
29
+ .pytest_cache/
30
+ .vscode/
31
+ .idea/
32
+ *.swp
33
+ *.swo
34
+ *~
35
+
36
+ # OS
37
+ .DS_Store
38
+ Thumbs.db
39
+
40
+ # setuptools-scm generated version file (written at install/build time)
41
+ nothing_app/_version.py
42
+
43
+ # APK reverse-engineering artifacts (local research only)
44
+ *apkm*
45
+ apkm_decompiled/
46
+ apkm_extracted/
@@ -0,0 +1,37 @@
1
+ # Something X — Device & Platform Compatibility
2
+
3
+ ---
4
+
5
+ ## Supported devices
6
+
7
+ The RFCOMM `0x55` protocol is shared across the entire Nothing Ear lineup. Confirmed working on **Nothing Ear (2)**; the same activation sequence, ANC wire values, and EQ command IDs are present in the APK for all models listed below.
8
+
9
+ | Device | Protocol confirmed | Community reports |
10
+ |---|---|---|
11
+ | Nothing Ear (2) | ✅ reverse-engineered from APK | ✅ |
12
+ | Nothing Ear (1) | ✅ same APK protocol class | needs field testing |
13
+ | Nothing Ear (a) | ✅ same APK protocol class | needs field testing |
14
+ | Nothing Ear (stick) | ✅ (no ANC cmd) | needs field testing |
15
+ | CMF Buds / Buds Pro | ⚠️ likely same, different cmd IDs possible | needs field testing |
16
+ | Nothing Ear (open) | ❓ ANC not applicable | not yet tested |
17
+ | CMF Watch | ❓ different protocol expected | not started |
18
+
19
+ **If your device doesn't work:** open an issue with the raw RFCOMM dump (run with `SOMETHING_X_DEBUG=1 ./somethingx`).
20
+
21
+ ---
22
+
23
+ ## Linux distros
24
+
25
+ The app runs on any Linux system with BlueZ. System package names vary:
26
+
27
+ | Distro | Install command |
28
+ |---|---|
29
+ | Arch / Omarchy | `sudo pacman -S python-gobject python-dbus python-cairo gtk4 libadwaita` |
30
+ | Ubuntu 24.04+ | `sudo apt install python3-gi python3-dbus python3-cairo gir1.2-gtk-4.0 gir1.2-adw-1` |
31
+ | Fedora 39+ | `sudo dnf install python3-gobject python3-dbus python3-cairo gtk4 libadwaita` |
32
+ | openSUSE | `sudo zypper install python3-gobject python3-dbus python3-cairo gtk4 libadwaita` |
33
+ | NixOS | see `flake.nix` |
34
+
35
+ Requirements: `bluetoothd` running, BlueZ ≥ 5.6, GTK4 ≥ 4.6, libadwaita ≥ 1.2.
36
+
37
+ Volume control requires `pactl` — available on any PulseAudio or PipeWire system.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: something-x-dev
3
- Version: 1.7.0.dev15
3
+ Version: 1.7.1.dev15
4
4
  Summary: Something X device manager for Omarchy / Linux
5
5
  Author: Raphael
6
6
  License: MIT
@@ -0,0 +1,24 @@
1
+ # Maintainer: Raphael <raphael.girard.iut@gmail.com>
2
+ pkgname=something-x
3
+ pkgver=1.0.0
4
+ pkgrel=1
5
+ pkgdesc="GTK4 device manager for Nothing earbuds on Linux"
6
+ arch=('any')
7
+ url="https://github.com/SoaOaoS/nothingonmarchy"
8
+ license=('MIT')
9
+ depends=('python' 'python-gobject' 'python-dbus' 'gtk4' 'libadwaita')
10
+ makedepends=('python-build' 'python-installer' 'python-wheel' 'python-setuptools')
11
+ optdepends=('libpulse: volume control via pactl')
12
+ source=("https://files.pythonhosted.org/packages/source/s/something-x/something_x-${pkgver}.tar.gz")
13
+ sha256sums=('SKIP')
14
+
15
+ build() {
16
+ cd "something_x-${pkgver}"
17
+ python -m build --wheel --no-isolation
18
+ }
19
+
20
+ package() {
21
+ cd "something_x-${pkgver}"
22
+ python -m installer --destdir="$pkgdir" dist/*.whl
23
+ install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
24
+ }
@@ -0,0 +1,69 @@
1
+ # Something X — Roadmap
2
+
3
+ ---
4
+
5
+ ## Known Issues
6
+
7
+ - Window control buttons (close/minimize/maximize) in the headerbar had a double-hover effect on non-tiling desktops due to app CSS overriding the system theme — fixed on `feat/fix-headerbar-window-controls`.
8
+
9
+ ---
10
+
11
+ ## v1.x — Near term
12
+
13
+ ### Docs
14
+ - [x] **GitHub Pages** — project landing page + full documentation site (`docs/`)
15
+
16
+ ### Distribution
17
+ - [x] AUR package — AUR package for Arch users to replace pip
18
+ - [x] **NixOS flake** — `flake.nix` for Nix users
19
+ - [x] **`.desktop` file** — ships and auto-installs so the app appears in Walker/Rofi/GNOME launcher
20
+
21
+ ### Features
22
+ - [x] **Low battery desktop notification** — `notify-send` when any bud drops below 20 %
23
+ - [x] **Background mode** — closing the window hides it; relaunch shows it again (Gio single-instance)
24
+ - [x] **Per-device profiles** — ANC + EQ saved per device address to `~/.config/something-x/profiles.json`, restored automatically on reconnect
25
+ - [x] **CLI quick-toggle** — `something-x --anc off|on|transparency`, `something-x --eq bass`, `something-x --battery`
26
+ - [x] **System tray icon** — show battery on hover via StatusNotifierItem (Waybar/SNI)
27
+ - [x] **Wearing detection display** — show L/R in-ear status on the earbud visual
28
+ - [x] **Auto-connect RFCOMM** — connect as soon as BlueZ reports the device connected, no tap needed
29
+
30
+ ### Fixes
31
+ - [x] **Headerbar button hover** — window controls now respect the system theme on all desktops
32
+
33
+ ### Protocol
34
+ - [x] **Debug mode** — `SOMETHING_X_DEBUG=1` env var dumps raw RFCOMM frames for contributors
35
+ - [x] **Graceful ANC mode detection** — infer supported modes from RFCOMM level response; hide unsupported buttons
36
+
37
+ ---
38
+
39
+ ## v2.x — Medium term
40
+
41
+ ### Features
42
+ - [ ] **Multiple devices simultaneously** — open two device pages, manage both at once
43
+ - [ ] **Quick-settings panel** — small floating overlay triggered by keybind
44
+ - [ ] **Touch controls remapping** — if the protocol exposes it (found in APK, not yet implemented)
45
+ - [ ] **Equalizer graph** — visual EQ curve instead of preset pills; custom presets with sliders
46
+ - [ ] **Firmware update check** — compare device firmware against latest known version, show badge
47
+
48
+ ### Tech
49
+ - [ ] **Async BlueZ** — replace `dbus-python` with `dbus-fast` for non-blocking I/O
50
+ - [ ] **Unit tests** — protocol encode/decode, CRC, ANC mode mapping
51
+
52
+ ---
53
+
54
+ ## v3.x — Long term / ideas
55
+
56
+ - [ ] **CMF Watch support** — different protocol; would need fresh APK reverse-engineering
57
+ - [ ] **Nothing Phone integration** — glyph control, notification mirroring
58
+ - [ ] **GNOME Shell extension** — battery indicator in the top bar
59
+ - [ ] **KDE Plasma widget** — same idea for KDE users
60
+ - [ ] **macOS port** — replace BlueZ D-Bus with CoreBluetooth via `pyobjc` (long shot)
61
+
62
+ ---
63
+
64
+ ## Won't do
65
+
66
+ - **Windows** — no BlueZ, RFCOMM access requires a different stack entirely
67
+ - **Wayland screenshot / screen capture control** — out of scope
68
+ - **Streaming / media playback control** — MPRIS already handles this system-wide
69
+
@@ -0,0 +1,41 @@
1
+ [changelog]
2
+ header = ""
3
+ body = """
4
+ {% for group, commits in commits | group_by(attribute="group") %}
5
+ ### {{ group }}
6
+ {% for commit in commits | sort(attribute="message") %}
7
+ - {% if commit.scope %}**{{ commit.scope }}**: {% endif %}\
8
+ {{ commit.message | upper_first }}\
9
+ {% endfor %}
10
+ {% endfor %}
11
+ """
12
+ footer = ""
13
+ trim = true
14
+
15
+ [git]
16
+ conventional_commits = true
17
+ filter_unconventional = true
18
+ split_commits = false
19
+ commit_parsers = [
20
+ { message = "^feat", group = "Features" },
21
+ { message = "^fix", group = "Bug Fixes" },
22
+ { message = "^perf", group = "Performance" },
23
+ { message = "^refactor", group = "Refactoring" },
24
+ { message = "^docs", group = "Documentation" },
25
+ { message = "^style", group = "Styling" },
26
+ { message = "^test", group = "Testing" },
27
+ # skip anything that isn't useful in a user-facing changelog
28
+ { message = "^chore: release", skip = true },
29
+ { message = "^chore", skip = true },
30
+ { message = "^ci", skip = true },
31
+ { message = "^build", skip = true },
32
+ # skip all merge commits regardless of how they are worded
33
+ { message = "^[Mm]erge[ /]", skip = true },
34
+ { message = "^Merged", skip = true },
35
+ ]
36
+ filter_commits = false
37
+ # semver release tags only; dev-* tags are ignored for "previous release" calculation
38
+ tag_pattern = "v[0-9]+\\.[0-9]+\\.[0-9]+"
39
+ ignore_tags = "dev-.*"
40
+ topo_order = false
41
+ sort_commits = "oldest"