diff --git a/nixosModules/ags/config/configurations/wim.ts b/nixosModules/ags/config/configurations/wim.ts
index 67567a91..c4be9d55 100644
--- a/nixosModules/ags/config/configurations/wim.ts
+++ b/nixosModules/ags/config/configurations/wim.ts
@@ -6,6 +6,7 @@ import style from '../style/main.scss';
import AppLauncher from '../widgets/applauncher/main';
import Bar from '../widgets/bar/wim';
import BgLayer from '../widgets/bg-layer/main';
+import BluetoothWindow from '../widgets/bluetooth/wim';
import Calendar from '../widgets/date/wim';
import Clipboard from '../widgets/clipboard/main';
import Corners from '../widgets/corners/main';
@@ -55,6 +56,7 @@ export default () => {
AppLauncher();
Bar();
+ BluetoothWindow();
Calendar();
Clipboard();
Corners();
diff --git a/nixosModules/ags/config/style/main.scss b/nixosModules/ags/config/style/main.scss
index 0c9a5fd5..d31e20cd 100644
--- a/nixosModules/ags/config/style/main.scss
+++ b/nixosModules/ags/config/style/main.scss
@@ -2,6 +2,7 @@
@use '../widgets/applauncher';
@use '../widgets/bar';
+@use '../widgets/bluetooth';
@use '../widgets/clipboard';
@use '../widgets/date';
@use '../widgets/icon-browser';
diff --git a/nixosModules/ags/config/widgets/bar/_index.scss b/nixosModules/ags/config/widgets/bar/_index.scss
index 0234b762..68f4308f 100644
--- a/nixosModules/ags/config/widgets/bar/_index.scss
+++ b/nixosModules/ags/config/widgets/bar/_index.scss
@@ -19,7 +19,8 @@
background-color: color.adjust(colors.$window_bg_color, $lightness: 3%);
}
- &.network icon {
+ &.network icon,
+ &.bluetooth icon {
min-width: 30px;
}
diff --git a/nixosModules/ags/config/widgets/bar/items/bluetooth.tsx b/nixosModules/ags/config/widgets/bar/items/bluetooth.tsx
new file mode 100644
index 00000000..58b85db3
--- /dev/null
+++ b/nixosModules/ags/config/widgets/bar/items/bluetooth.tsx
@@ -0,0 +1,67 @@
+import { bind, Variable } from 'astal';
+import { App, Gtk } from 'astal/gtk3';
+
+import AstalBluetooth from 'gi://AstalBluetooth';
+
+import PopupWindow from '../../misc/popup-window';
+
+
+export default () => {
+ const bluetooth = AstalBluetooth.get_default();
+
+ const Hovered = Variable(false);
+
+ return (
+
+ );
+};
diff --git a/nixosModules/ags/config/widgets/bar/wim.tsx b/nixosModules/ags/config/widgets/bar/wim.tsx
index e9c4edcc..869c1759 100644
--- a/nixosModules/ags/config/widgets/bar/wim.tsx
+++ b/nixosModules/ags/config/widgets/bar/wim.tsx
@@ -2,6 +2,7 @@ import { Astal, Gtk } from 'astal/gtk3';
import Audio from './items/audio';
import Battery from './items/battery';
+import Bluetooth from './items/bluetooth';
import Brightness from './items/brightness';
import Clock from './items/clock';
import CurrentClient from './items/current-client';
@@ -48,6 +49,10 @@ export default () => (
+
+
+
+
diff --git a/nixosModules/ags/config/widgets/bluetooth/_index.scss b/nixosModules/ags/config/widgets/bluetooth/_index.scss
new file mode 100644
index 00000000..b747edd1
--- /dev/null
+++ b/nixosModules/ags/config/widgets/bluetooth/_index.scss
@@ -0,0 +1,24 @@
+@use 'sass:color';
+@use '../../style/colors';
+
+.bluetooth {
+ margin-top: 0;
+
+ .toggle-button {
+ background-color: colors.$window_bg_color;
+
+ transition: background-color 0.2s ease-in-out, border-color 0.2s ease-in-out;
+
+ box-shadow: 2px 1px 2px colors.$accent-color;
+
+ padding: 4px;
+
+ margin: 4px 4px 4px 4px;
+
+ &.active {
+ box-shadow: 0 0 0 white;
+ margin: 6px 4px 2px 4px;
+ background-color: color.adjust(colors.$window_bg_color, $lightness: -3%);
+ }
+ }
+}
diff --git a/nixosModules/ags/config/widgets/bluetooth/device.tsx b/nixosModules/ags/config/widgets/bluetooth/device.tsx
new file mode 100644
index 00000000..62c11d17
--- /dev/null
+++ b/nixosModules/ags/config/widgets/bluetooth/device.tsx
@@ -0,0 +1,57 @@
+import { bind } from 'astal';
+import { Gtk, Widget } from 'astal/gtk3';
+
+import AstalBluetooth from 'gi://AstalBluetooth';
+
+import Separator from '../misc/separator';
+
+
+export default (dev: AstalBluetooth.Device) => {
+ const rev = (
+
+
+ TODO: add buttons here
+
+
+ ) as Widget.Revealer;
+
+ const button = (
+
+ );
+
+ return (
+
+ {button}
+ {rev}
+
+ );
+};
diff --git a/nixosModules/ags/config/widgets/bluetooth/main.tsx b/nixosModules/ags/config/widgets/bluetooth/main.tsx
new file mode 100644
index 00000000..e8d6c8aa
--- /dev/null
+++ b/nixosModules/ags/config/widgets/bluetooth/main.tsx
@@ -0,0 +1,67 @@
+import { bind } from 'astal';
+import { Gtk } from 'astal/gtk3';
+
+import AstalBluetooth from 'gi://AstalBluetooth';
+
+import { ToggleButton } from '../misc/subclasses';
+import Separator from '../misc/separator';
+
+import DeviceWidget from './device';
+
+
+export default () => {
+ const bluetooth = AstalBluetooth.get_default();
+
+ return (
+
+
+ {
+ self.connect('notify::active', () => {
+ bluetooth.adapter?.set_powered(self.active);
+ });
+ }}
+ />
+
+
+
+ {
+ self.toggleClassName('active', self.active);
+
+ if (self.active) {
+ bluetooth.adapter?.start_discovery();
+ }
+ else {
+ bluetooth.adapter?.stop_discovery();
+ }
+ }}
+ >
+
+
+
+
+
+
+ {bind(bluetooth, 'devices').as((devices) => devices
+ .filter((dev) => dev.name)
+ .map((dev) => DeviceWidget(dev)))}
+
+ );
+};
diff --git a/nixosModules/ags/config/widgets/bluetooth/wim.tsx b/nixosModules/ags/config/widgets/bluetooth/wim.tsx
new file mode 100644
index 00000000..3f618638
--- /dev/null
+++ b/nixosModules/ags/config/widgets/bluetooth/wim.tsx
@@ -0,0 +1,15 @@
+import { Astal } from 'astal/gtk3';
+
+import PopupWindow from '../misc/popup-window';
+
+import BluetoothWidget from './main';
+
+
+export default () => (
+
+
+
+);
diff --git a/nixosModules/ags/config/widgets/misc/subclasses.tsx b/nixosModules/ags/config/widgets/misc/subclasses.tsx
new file mode 100644
index 00000000..ed69a521
--- /dev/null
+++ b/nixosModules/ags/config/widgets/misc/subclasses.tsx
@@ -0,0 +1,14 @@
+import { astalify, Gtk, type ConstructProps } from 'astal/gtk3';
+import { register } from 'astal/gobject';
+
+
+@register()
+export class ToggleButton extends astalify(Gtk.ToggleButton) {
+ constructor(props: ConstructProps<
+ ToggleButton,
+ Gtk.ToggleButton.ConstructorProps
+ >) {
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ super(props as any);
+ }
+}
diff --git a/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx b/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx
index a1a7b801..e990b26e 100644
--- a/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx
+++ b/nixosModules/ags/config/widgets/on-screen-keyboard/keyboard.tsx
@@ -1,7 +1,7 @@
import { bind, idle, Variable } from 'astal';
-import { Astal, astalify, Gtk, type ConstructProps, Widget } from 'astal/gtk3';
-import { register } from 'astal/gobject';
+import { Astal, Gtk, Widget } from 'astal/gtk3';
+import { ToggleButton } from '../misc/subclasses';
import Separator from '../misc/separator';
import Arc from './arcs';
@@ -13,17 +13,6 @@ import { defaultOskLayout, oskLayouts } from './keyboard-layouts';
const keyboardLayout = defaultOskLayout;
const keyboardJson = oskLayouts[keyboardLayout];
-@register()
-class ToggleButton extends astalify(Gtk.ToggleButton) {
- constructor(props: ConstructProps<
- ToggleButton,
- Gtk.ToggleButton.ConstructorProps
- >) {
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
- super(props as any);
- }
-}
-
const L_KEY_PER_ROW = [8, 7, 6, 6, 6, 4];
const SPACING = 4;
const COLOR = 'rgba(0, 0, 0, 0.5)';