something-x-dev 1.9.0.dev29__py3-none-any.whl → 1.9.0.dev30__py3-none-any.whl
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.
- nothing_app/_version.py +2 -2
- nothing_app/pages/device.py +10 -3
- nothing_app/pages/theme.py +8 -16
- nothing_app/profiles.py +1 -1
- nothing_app/protocol.py +35 -3
- nothing_app/tray.py +1 -1
- {something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/METADATA +1 -1
- {something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/RECORD +12 -12
- {something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/WHEEL +0 -0
- {something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/entry_points.txt +0 -0
- {something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/licenses/LICENSE +0 -0
- {something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/top_level.txt +0 -0
nothing_app/_version.py
CHANGED
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.9.0.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 9, 0, '
|
|
21
|
+
__version__ = version = '1.9.0.dev30'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 9, 0, 'dev30')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
nothing_app/pages/device.py
CHANGED
|
@@ -9,7 +9,7 @@ import gi
|
|
|
9
9
|
gi.require_version("Gtk", "4.0")
|
|
10
10
|
gi.require_version("Pango", "1.0")
|
|
11
11
|
gi.require_version("PangoCairo", "1.0")
|
|
12
|
-
from gi.repository import Gtk, GLib, PangoCairo
|
|
12
|
+
from gi.repository import Gtk, GLib, PangoCairo
|
|
13
13
|
|
|
14
14
|
from ..bluetooth import BluetoothDevice, BluetoothManager
|
|
15
15
|
from ..protocol import NothingDevice, ANCMode, EQ_PRESETS
|
|
@@ -477,12 +477,15 @@ class DevicePage(Gtk.Box):
|
|
|
477
477
|
)
|
|
478
478
|
|
|
479
479
|
self._auto_pause_switch = Gtk.Switch()
|
|
480
|
-
self._auto_pause_switch.set_active(
|
|
480
|
+
self._auto_pause_switch.set_active(
|
|
481
|
+
profiles.get_notify_prefs(self._bt_device.address).get("wear_mpris", False)
|
|
482
|
+
)
|
|
481
483
|
self._auto_pause_switch.set_valign(Gtk.Align.CENTER)
|
|
484
|
+
self._auto_pause_switch.connect("state-set", self._on_auto_pause_toggled)
|
|
482
485
|
settings_group.append(
|
|
483
486
|
_settings_row(
|
|
484
487
|
"Auto-Pause",
|
|
485
|
-
"Pause media
|
|
488
|
+
"Pause/resume media with wear detection",
|
|
486
489
|
self._auto_pause_switch,
|
|
487
490
|
)
|
|
488
491
|
)
|
|
@@ -712,6 +715,10 @@ class DevicePage(Gtk.Box):
|
|
|
712
715
|
if not entry.has_focus():
|
|
713
716
|
self._save_nickname()
|
|
714
717
|
|
|
718
|
+
def _on_auto_pause_toggled(self, _switch, state: bool):
|
|
719
|
+
profiles.set_notify_prefs(self._bt_device.address, {"wear_mpris": state})
|
|
720
|
+
return False
|
|
721
|
+
|
|
715
722
|
def _on_notif_battery_toggled(self, _switch, state: bool):
|
|
716
723
|
profiles.set_notify_prefs(self._bt_device.address, {"battery_low": state})
|
|
717
724
|
return False
|
nothing_app/pages/theme.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import math
|
|
2
|
-
from
|
|
2
|
+
from collections.abc import Callable
|
|
3
3
|
|
|
4
4
|
import gi
|
|
5
5
|
|
|
6
6
|
gi.require_version("Gtk", "4.0")
|
|
7
|
-
from gi.repository import Gdk,
|
|
7
|
+
from gi.repository import Gdk, Gtk
|
|
8
8
|
|
|
9
9
|
from ..theme import ACCENT_PRESETS, BG_PRESETS, FONT_PRESETS, TEXTURES, Theme, hex_to_rgb
|
|
10
10
|
|
|
@@ -345,11 +345,8 @@ class ThemePage(Gtk.Box):
|
|
|
345
345
|
|
|
346
346
|
def _on_accent_color_set(self, btn: Gtk.ColorButton):
|
|
347
347
|
rgba = btn.get_rgba()
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
int(rgba.green * 255),
|
|
351
|
-
int(rgba.blue * 255),
|
|
352
|
-
)
|
|
348
|
+
r, g, b = int(rgba.red * 255), int(rgba.green * 255), int(rgba.blue * 255)
|
|
349
|
+
self._theme.accent = f"#{r:02x}{g:02x}{b:02x}"
|
|
353
350
|
self._update_accent_swatches()
|
|
354
351
|
self._emit()
|
|
355
352
|
|
|
@@ -368,11 +365,8 @@ class ThemePage(Gtk.Box):
|
|
|
368
365
|
|
|
369
366
|
def _on_bg_color_set(self, btn: Gtk.ColorButton):
|
|
370
367
|
rgba = btn.get_rgba()
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
int(rgba.green * 255),
|
|
374
|
-
int(rgba.blue * 255),
|
|
375
|
-
)
|
|
368
|
+
r, g, b = int(rgba.red * 255), int(rgba.green * 255), int(rgba.blue * 255)
|
|
369
|
+
self._theme.bg_color = f"#{r:02x}{g:02x}{b:02x}"
|
|
376
370
|
self._update_bg_swatches()
|
|
377
371
|
self._emit()
|
|
378
372
|
|
|
@@ -419,8 +413,6 @@ class ThemePage(Gtk.Box):
|
|
|
419
413
|
self._emit()
|
|
420
414
|
|
|
421
415
|
def _on_reset(self, _btn):
|
|
422
|
-
import dataclasses
|
|
423
|
-
|
|
424
416
|
self._theme = Theme()
|
|
425
417
|
self._reload_controls()
|
|
426
418
|
self._emit()
|
|
@@ -428,11 +420,11 @@ class ThemePage(Gtk.Box):
|
|
|
428
420
|
# ── Internal helpers ──────────────────────────────────────────────────────
|
|
429
421
|
|
|
430
422
|
def _update_accent_swatches(self):
|
|
431
|
-
for sw, (color, _) in zip(self._accent_swatches, ACCENT_PRESETS):
|
|
423
|
+
for sw, (color, _) in zip(self._accent_swatches, ACCENT_PRESETS, strict=False):
|
|
432
424
|
sw.set_active(color.lower() == self._theme.accent.lower())
|
|
433
425
|
|
|
434
426
|
def _update_bg_swatches(self):
|
|
435
|
-
for sw, (color, _) in zip(self._bg_swatches, BG_PRESETS):
|
|
427
|
+
for sw, (color, _) in zip(self._bg_swatches, BG_PRESETS, strict=False):
|
|
436
428
|
sw.set_active(color.lower() == self._theme.bg_color.lower())
|
|
437
429
|
|
|
438
430
|
def _reload_controls(self):
|
nothing_app/profiles.py
CHANGED
|
@@ -5,7 +5,7 @@ _DIR = os.path.expanduser("~/.config/something-x")
|
|
|
5
5
|
_PROFILES_FILE = os.path.join(_DIR, "profiles.json")
|
|
6
6
|
_LAST_DEV_FILE = os.path.join(_DIR, "last_device")
|
|
7
7
|
|
|
8
|
-
_NOTIFY_DEFAULTS: dict = {"battery_low": True, "connect": True, "disconnect": True}
|
|
8
|
+
_NOTIFY_DEFAULTS: dict = {"battery_low": True, "connect": True, "disconnect": True, "wear_mpris": False}
|
|
9
9
|
_ALLOWED_IMPORT_KEYS = frozenset({"anc", "eq", "nickname", "notify"})
|
|
10
10
|
|
|
11
11
|
|
nothing_app/protocol.py
CHANGED
|
@@ -152,6 +152,8 @@ class NothingDevice(GObject.Object):
|
|
|
152
152
|
self._thread: threading.Thread | None = None
|
|
153
153
|
self._low_bat_notified: dict[str, set[int]] = {}
|
|
154
154
|
self._low_bat_seen: set[str] = set()
|
|
155
|
+
self._wear_both_removed: bool = False
|
|
156
|
+
self._wear_paused: bool = False
|
|
155
157
|
|
|
156
158
|
# ── Public API ────────────────────────────────────────────────────────────
|
|
157
159
|
|
|
@@ -545,9 +547,8 @@ class NothingDevice(GObject.Object):
|
|
|
545
547
|
else:
|
|
546
548
|
modes = frozenset([ANCMode.OFF, ANCMode.TRANSPARENCY])
|
|
547
549
|
self.state.supported_anc_modes = modes
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
)
|
|
550
|
+
labels = [ANCMode.LABELS.get(m, m) for m in sorted(modes)]
|
|
551
|
+
_log(f"[protocol] supported ANC modes detected: {labels}")
|
|
551
552
|
changed = True
|
|
552
553
|
|
|
553
554
|
return changed
|
|
@@ -579,6 +580,7 @@ class NothingDevice(GObject.Object):
|
|
|
579
580
|
changed = True
|
|
580
581
|
if changed:
|
|
581
582
|
_log(f"[protocol] wearing L={self.state.left_wearing} R={self.state.right_wearing}")
|
|
583
|
+
self._check_wear_mpris()
|
|
582
584
|
return changed
|
|
583
585
|
|
|
584
586
|
# ── Legacy 0x03 frame handling (status-only fallback) ────────────────────
|
|
@@ -681,6 +683,36 @@ class NothingDevice(GObject.Object):
|
|
|
681
683
|
).start()
|
|
682
684
|
break
|
|
683
685
|
|
|
686
|
+
def _check_wear_mpris(self):
|
|
687
|
+
from . import profiles
|
|
688
|
+
|
|
689
|
+
if not profiles.get_notify_prefs(self.address).get("wear_mpris", False):
|
|
690
|
+
self._wear_both_removed = False
|
|
691
|
+
self._wear_paused = False
|
|
692
|
+
return
|
|
693
|
+
|
|
694
|
+
both_removed = not self.state.left_wearing and not self.state.right_wearing
|
|
695
|
+
|
|
696
|
+
if both_removed and not self._wear_both_removed:
|
|
697
|
+
self._wear_both_removed = True
|
|
698
|
+
self._wear_paused = True
|
|
699
|
+
threading.Thread(
|
|
700
|
+
target=subprocess.run,
|
|
701
|
+
args=(["playerctl", "pause"],),
|
|
702
|
+
kwargs={"capture_output": True},
|
|
703
|
+
daemon=True,
|
|
704
|
+
).start()
|
|
705
|
+
elif not both_removed and self._wear_both_removed:
|
|
706
|
+
self._wear_both_removed = False
|
|
707
|
+
if self._wear_paused:
|
|
708
|
+
self._wear_paused = False
|
|
709
|
+
threading.Thread(
|
|
710
|
+
target=subprocess.run,
|
|
711
|
+
args=(["playerctl", "play"],),
|
|
712
|
+
kwargs={"capture_output": True},
|
|
713
|
+
daemon=True,
|
|
714
|
+
).start()
|
|
715
|
+
|
|
684
716
|
def _poll_earphone_status(self):
|
|
685
717
|
# The firmware only computes a fresh per-bud snapshot when asked; the
|
|
686
718
|
# pushed EVT frames carry stale placeholder entries for the bud that
|
nothing_app/tray.py
CHANGED
|
@@ -4,7 +4,7 @@ import dbus.service
|
|
|
4
4
|
import dbus.mainloop.glib
|
|
5
5
|
from gi.repository import GLib, GObject
|
|
6
6
|
|
|
7
|
-
from .bluetooth import BluetoothManager,
|
|
7
|
+
from .bluetooth import BluetoothManager, device_icon_name
|
|
8
8
|
|
|
9
9
|
_ITEM_IFACE = "org.kde.StatusNotifierItem"
|
|
10
10
|
_WATCHER_IFACE = "org.kde.StatusNotifierWatcher"
|
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
nothing_app/__init__.py,sha256=zN7vSxhfKFzKNDhoeRzP638S46sET39MWhlljtk0vP0,540
|
|
2
|
-
nothing_app/_version.py,sha256=
|
|
2
|
+
nothing_app/_version.py,sha256=PPLVrnyxRQnpFwUz0909dcjj-Haq3TqcfQACTaT8k20,535
|
|
3
3
|
nothing_app/application.py,sha256=c6B0raU5gBPu5la1v01w6oH7c6lmYpCwTY57ISZOY3Y,9599
|
|
4
4
|
nothing_app/bluetooth.py,sha256=MQeF0u_13SZ1GAY2UeadW4bMvGpu5UbgIR912M81dBs,12824
|
|
5
|
-
nothing_app/profiles.py,sha256=
|
|
6
|
-
nothing_app/protocol.py,sha256=
|
|
5
|
+
nothing_app/profiles.py,sha256=LrTgYdDICLA0dlmyftD3hNVmiruDrGz5DDumPk5M5NQ,4385
|
|
6
|
+
nothing_app/protocol.py,sha256=IgkRAArMlAiw2EXFFb1IyAySaRBwYmNBQOnn95AWRNg,30387
|
|
7
7
|
nothing_app/splash.py,sha256=8GhwQ4F2B9tsxu23VpragjLgxdMKVsg3ZQIlzRC2dY8,6811
|
|
8
8
|
nothing_app/theme.py,sha256=UwGO2LYuBdA9_3o3EwhI7D90wIUEpGw6RQ-4RKQO2QM,9727
|
|
9
|
-
nothing_app/tray.py,sha256=
|
|
9
|
+
nothing_app/tray.py,sha256=VqerKxC9SqvbzRdqAIRJo-rJT_h-2_ASxoDdSHNyhlI,5901
|
|
10
10
|
nothing_app/window.py,sha256=VijJo-wcLVNkeiWQZaofQ51qX3C2Z5IkxTACc1OPB5s,6911
|
|
11
11
|
nothing_app/data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
12
|
nothing_app/data/com.something.x.omarchy.desktop,sha256=Uet1FGwgMDvHlejxNuhR8cTWNrYEqnJlTvipl2ztFp8,362
|
|
13
13
|
nothing_app/data/style.css,sha256=OPbBi_kkCSZhCr0pMcRzdbMzVV46jOJtCuEz0wLHkNI,21535
|
|
14
14
|
nothing_app/pages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
nothing_app/pages/device.py,sha256=
|
|
15
|
+
nothing_app/pages/device.py,sha256=wlUDfo3In2wS2jtL-yTAtrQd-2NnCRtl_yoaFjY0UNA,31187
|
|
16
16
|
nothing_app/pages/home.py,sha256=LvARz9Gcwcn_jEV75NwYnhL9EoKYs_bKghjdtLmP21I,8600
|
|
17
|
-
nothing_app/pages/theme.py,sha256=
|
|
18
|
-
something_x_dev-1.9.0.
|
|
19
|
-
something_x_dev-1.9.0.
|
|
20
|
-
something_x_dev-1.9.0.
|
|
21
|
-
something_x_dev-1.9.0.
|
|
22
|
-
something_x_dev-1.9.0.
|
|
23
|
-
something_x_dev-1.9.0.
|
|
17
|
+
nothing_app/pages/theme.py,sha256=2mDj80unCvNxpJpRy3xl8hc1JjCSovZHSlTwKSI_ACM,18837
|
|
18
|
+
something_x_dev-1.9.0.dev30.dist-info/licenses/LICENSE,sha256=f82aGY-Qd4Huw5T9EsynF6CJhVPdcnsTSuuaskxc1ak,1064
|
|
19
|
+
something_x_dev-1.9.0.dev30.dist-info/METADATA,sha256=Q8VRauVr1adb1enM8QsL_jicd4LnnOisIe3VCwa3IZ0,7576
|
|
20
|
+
something_x_dev-1.9.0.dev30.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
21
|
+
something_x_dev-1.9.0.dev30.dist-info/entry_points.txt,sha256=HpMQVOiNSmzNKoa2Fb65XtbK7NWTfxMDBrBNlk9WHi8,65
|
|
22
|
+
something_x_dev-1.9.0.dev30.dist-info/top_level.txt,sha256=yERYCJXvIBXR40iWxixVVZI3z-B4gNYXEdXFiiWa7KI,12
|
|
23
|
+
something_x_dev-1.9.0.dev30.dist-info/RECORD,,
|
|
File without changes
|
{something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{something_x_dev-1.9.0.dev29.dist-info → something_x_dev-1.9.0.dev30.dist-info}/top_level.txt
RENAMED
|
File without changes
|