diff --git a/nixosModules/ags/config/widgets/bluetooth/_index.scss b/nixosModules/ags/config/widgets/bluetooth/_index.scss index 2b66102a..fa1b24a9 100644 --- a/nixosModules/ags/config/widgets/bluetooth/_index.scss +++ b/nixosModules/ags/config/widgets/bluetooth/_index.scss @@ -4,6 +4,14 @@ .bluetooth { margin-top: 0; + * { + font-size: 20px; + } + + row { + all: unset; + } + .toggle-button { padding: 4px; min-width: 30px; diff --git a/nixosModules/ags/config/widgets/bluetooth/main.tsx b/nixosModules/ags/config/widgets/bluetooth/main.tsx index c077e05e..a30df1e6 100644 --- a/nixosModules/ags/config/widgets/bluetooth/main.tsx +++ b/nixosModules/ags/config/widgets/bluetooth/main.tsx @@ -3,12 +3,45 @@ import { Gtk } from 'astal/gtk3'; import AstalBluetooth from 'gi://AstalBluetooth'; -import { ToggleButton } from '../misc/subclasses'; +import { ListBox, ToggleButton } from '../misc/subclasses'; import Separator from '../misc/separator'; import DeviceWidget from './device'; +const calculateDevSort = (dev: AstalBluetooth.Device) => { + let value = 0; + + if (dev.connected) { + value += 1000; + } + if (dev.paired) { + value += 100; + } + if (dev.blocked) { + value += 10; + } + if (dev.icon) { + if (dev.icon === 'audio-headset') { + value += 9; + } + if (dev.icon === 'audio-headphones') { + value += 8; + } + if (dev.icon === 'audio-card') { + value += 7; + } + if (dev.icon === 'computer') { + value += 6; + } + if (dev.icon === 'phone') { + value += 5; + } + } + + return value; +}; + export default () => { const bluetooth = AstalBluetooth.get_default(); @@ -16,38 +49,53 @@ export default () => { - { - self.children = bluetooth.devices + bluetooth.devices .filter((dev) => dev.name) - .map((dev) => ); + .forEach((dev) => { + self.add(); + }); self.hook(bluetooth, 'device-added', (_, dev) => { if (dev.name) { self.add(); + self.invalidate_sort(); } }); self.hook(bluetooth, 'device-removed', (_, dev) => { - const children = self.children as DeviceWidget[]; + const children = self + .get_children() + .map((ch) => ch.get_child()) as DeviceWidget[]; + const devWidget = children.find((ch) => ch.dev === dev); if (devWidget) { devWidget.revealChild = false; setTimeout(() => { - devWidget.destroy(); + devWidget.get_parent()?.destroy(); }, devWidget.transitionDuration + 100); } }); + + self.set_sort_func((a, b) => { + const devA = (a.get_child() as DeviceWidget).dev; + const devB = (b.get_child() as DeviceWidget).dev; + + const sort = calculateDevSort(devB) - calculateDevSort(devA); + + return sort !== 0 ? sort : devA.name.localeCompare(devB.name); + }); }} - > - + /> ); diff --git a/nixosModules/ags/config/widgets/misc/subclasses.tsx b/nixosModules/ags/config/widgets/misc/subclasses.tsx index ed69a521..626448fc 100644 --- a/nixosModules/ags/config/widgets/misc/subclasses.tsx +++ b/nixosModules/ags/config/widgets/misc/subclasses.tsx @@ -12,3 +12,18 @@ export class ToggleButton extends astalify(Gtk.ToggleButton) { super(props as any); } } + +@register() +export class ListBox extends astalify(Gtk.ListBox) { + override get_children() { + return super.get_children() as Gtk.ListBoxRow[]; + } + + constructor(props: ConstructProps< + ListBox, + Gtk.ListBox.ConstructorProps + >) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + super(props as any); + } +}