🔧 chore(modules/utils, osd): use secureBaseBinding() for osd modes
This commit is contained in:
+2
-2
@@ -291,7 +291,7 @@ you should use the socket in the XDG_RUNTIME_DIR/colorshell.sock for a faster re
|
||||
this.#connections.set(Wireplumber.getDefault(),
|
||||
Wireplumber.getDefault().getDefaultSink().connect("notify::volume", () =>
|
||||
!Windows.getDefault().isOpen("control-center") &&
|
||||
triggerOSD(OSDModes.SINK)
|
||||
triggerOSD(OSDModes.sink)
|
||||
)
|
||||
);
|
||||
|
||||
@@ -311,7 +311,7 @@ you should use the socket in the XDG_RUNTIME_DIR/colorshell.sock for a faster re
|
||||
|
||||
this.#connections.set(defaultBk, defaultBk.connect("brightness-changed", () =>
|
||||
!Windows.getDefault().isOpen("control-center") &&
|
||||
triggerOSD(OSDModes.BRIGHTNESS)
|
||||
triggerOSD(OSDModes.brightness)
|
||||
));
|
||||
})
|
||||
);
|
||||
|
||||
+59
-1
@@ -6,7 +6,7 @@ import { getSymbolicIcon } from "./apps";
|
||||
|
||||
import GLib from "gi://GLib?version=2.0";
|
||||
import Gio from "gi://Gio?version=2.0";
|
||||
import GObject from "ags/gobject";
|
||||
import GObject from "gi://GObject?version=2.0";
|
||||
|
||||
|
||||
/** gnim doesn't export this, so we need to do it again */
|
||||
@@ -301,3 +301,61 @@ export function secureBinding<
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/** securely bind to a property of a gobject accessor
|
||||
* use this to securely bind to a property of a constantly
|
||||
* updated variable that points to a gobject.
|
||||
*
|
||||
* It follows the same idea from secureBinding, it allows setting
|
||||
* a default value to return when the base gobject is null.
|
||||
*
|
||||
* @param baseObject a binding to the constantly updated property
|
||||
* that points to the gobject
|
||||
* @param prop the property to bind
|
||||
* @param defaultValue the value to return when the baseObject is
|
||||
* null/undefined
|
||||
*
|
||||
* @returns a bind to the specified property of the constantly-updated
|
||||
* object or the default value.
|
||||
* */
|
||||
export function secureBaseBinding<
|
||||
T extends GObject.Object = GObject.Object,
|
||||
Prop extends keyof T = keyof T,
|
||||
Default = any
|
||||
>(
|
||||
baseObject: Accessor<T>,
|
||||
prop: Prop,
|
||||
defaultValue: Default
|
||||
): Accessor<T[Prop]|Default> {
|
||||
let gobj: T|undefined = baseObject.get();
|
||||
let notify: () => void;
|
||||
|
||||
const baseSub = baseObject.subscribe(() => {
|
||||
const newBase = baseObject.get();
|
||||
|
||||
if(!newBase) {
|
||||
gobj = undefined;
|
||||
notify!();
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
const accessor = new Accessor<T[Prop]|Default>(
|
||||
() => gobj ? gobj[prop] : defaultValue,
|
||||
(notifyFun) => {
|
||||
notify = notifyFun;
|
||||
|
||||
const id = gobj?.connect(
|
||||
`notify::${(prop as string).replace(/[A-Z]/g, (s) => `-${s.toLowerCase()}`)}`,
|
||||
() => notify()
|
||||
);
|
||||
|
||||
return () => {
|
||||
id && gobj?.disconnect(id);
|
||||
baseSub();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
return accessor;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { createBinding, createState, With } from "ags";
|
||||
import { Wireplumber } from "../../modules/volume";
|
||||
import { Windows } from "../../windows";
|
||||
import { Backlights } from "../../modules/backlight";
|
||||
import { secureBinding, variableToBoolean } from "../../modules/utils";
|
||||
import { secureBaseBinding, secureBinding, variableToBoolean } from "../../modules/utils";
|
||||
|
||||
import Pango from "gi://Pango?version=1.0";
|
||||
import GLib from "gi://GLib?version=2.0";
|
||||
@@ -13,18 +13,42 @@ import OSDMode from "./modules/osdmode";
|
||||
|
||||
export const OSDModes = {
|
||||
sink: new OSDMode({
|
||||
icon: secureBinding(AstalWp.get_default().defaultSpeaker, "volumeIcon",
|
||||
"audio-volume-high-symbolic"),
|
||||
value: secureBinding(Wireplumber.getWireplumber().defaultSpeaker, "volume", 50),
|
||||
text: secureBinding(Wireplumber.getWireplumber().defaultSpeaker, "description",
|
||||
"Unknown Speaker"),
|
||||
available: secureBinding(AstalWp.get_default(), "defaultSpeaker", false).as((sink) =>
|
||||
Boolean(sink)),
|
||||
icon: secureBaseBinding<AstalWp.Endpoint>(
|
||||
createBinding(AstalWp.get_default(), "defaultSpeaker"),
|
||||
"volumeIcon",
|
||||
"audio-volume-high-symbolic"
|
||||
),
|
||||
value: secureBaseBinding<AstalWp.Endpoint>(
|
||||
createBinding(AstalWp.get_default(), "defaultSpeaker"),
|
||||
"volume",
|
||||
.5
|
||||
),
|
||||
text: secureBaseBinding<AstalWp.Endpoint>(
|
||||
createBinding(AstalWp.get_default(), "defaultSpeaker"),
|
||||
"description",
|
||||
"Unknown Speaker"
|
||||
),
|
||||
max: Wireplumber.getDefault().getMaxSinkVolume() / 100
|
||||
}),
|
||||
brightness: new OSDMode({
|
||||
icon: "display-brightness-symbolic",
|
||||
value: secureBinding(Backlights.getDefault().default, "brightness", 100),
|
||||
max: secureBinding(Backlights.getDefault().default, "maxBrightness", 100),
|
||||
text: secureBinding(Backlights.getDefault().default, "name", "Unknown Backlight"),
|
||||
value: secureBaseBinding<Backlights.Backlight>(
|
||||
createBinding(Backlights.getDefault(), "default"),
|
||||
"brightness",
|
||||
100
|
||||
),
|
||||
max: secureBaseBinding<Backlights.Backlight>(
|
||||
createBinding(Backlights.getDefault(), "default"),
|
||||
"maxBrightness",
|
||||
100
|
||||
),
|
||||
text: secureBaseBinding<Backlights.Backlight>(
|
||||
createBinding(Backlights.getDefault(), "default"),
|
||||
"name",
|
||||
"Unknown Backlight"
|
||||
),
|
||||
available: createBinding(Backlights.getDefault(), "available")
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user