Fix: extract the actual battery icon
This commit is contained in:
parent
353fbd99ec
commit
0b6cc49cec
|
|
@ -9,6 +9,7 @@ import { getIconName } from "./utils";
|
|||
import Wp from "gi://AstalWp";
|
||||
import Battery from "gi://AstalBattery";
|
||||
import GLib from "gi://GLib";
|
||||
import Gio from "gi://Gio";
|
||||
|
||||
const battery = Battery.get_default();
|
||||
const sensorsAvailable = await execAsync(["sensors"])
|
||||
|
|
@ -182,34 +183,53 @@ function Right() {
|
|||
);
|
||||
}
|
||||
|
||||
// Papirus encodes the battery level as a 35%-opacity overlay inside its
|
||||
// *-symbolic icons. GTK4's symbolic recoloring flattens that opacity, so every
|
||||
// level renders as a solid, full battery. The Papirus *-symbolic icons are just
|
||||
// symlinks to non-symbolic panel SVGs which keep the opacity when rendered
|
||||
// normally — so we resolve each name to that underlying file and load it
|
||||
// directly (as a non-symbolic file icon), which renders the correct level.
|
||||
function batteryGicon(): Gio.Icon {
|
||||
const percentage = battery.percentage;
|
||||
const thresholds = [...Array(11).keys()].map((i) => i * 10);
|
||||
const icon = thresholds.find((threshold) => threshold >= percentage * 100);
|
||||
const name = battery.charging
|
||||
? `battery-level-${icon}-${percentage >= 0.99 ? "charged" : "charging"}-symbolic`
|
||||
: `battery-level-${icon}-symbolic`;
|
||||
const symbolic = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()!)
|
||||
.lookup_icon(name, null, 16, 1, Gtk.TextDirection.NONE, 0)
|
||||
.get_file();
|
||||
if (!symbolic) return Gio.ThemedIcon.new(name);
|
||||
try {
|
||||
const target = symbolic
|
||||
.query_info(
|
||||
"standard::symlink-target",
|
||||
Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS,
|
||||
null,
|
||||
)
|
||||
.get_symlink_target();
|
||||
if (target) {
|
||||
return new Gio.FileIcon({
|
||||
file: symbolic.get_parent()!.resolve_relative_path(target),
|
||||
});
|
||||
}
|
||||
} catch (e) {}
|
||||
return new Gio.FileIcon({ file: symbolic });
|
||||
}
|
||||
|
||||
function BatteryIcon(): JSX.Element {
|
||||
if (battery.get_state() == 0) return <box />;
|
||||
let batteryPercentage = createBinding(battery, "percentage");
|
||||
// AstalBattery does not emit notify::percentage/charging/state on this
|
||||
// system, so a signal binding stays frozen at its initial value (e.g.
|
||||
// showing "charged" forever). Poll the live values instead.
|
||||
const gicon = createPoll<Gio.Icon>(batteryGicon(), 10000, batteryGicon);
|
||||
return (
|
||||
<button
|
||||
class="battery-item"
|
||||
onClicked={() => execAsync(["gnome-power-statistics"])}
|
||||
>
|
||||
<box>
|
||||
<With value={batteryPercentage}>
|
||||
{(percentage) => {
|
||||
const thresholds = [...Array(11).keys()].map((i) => i * 10);
|
||||
const icon = thresholds.find(
|
||||
(threshold) => threshold >= percentage * 100,
|
||||
);
|
||||
const charging_name =
|
||||
battery.percentage >= 0.99 ? "charged" : "charging";
|
||||
return (
|
||||
<image
|
||||
iconName={
|
||||
battery.charging
|
||||
? `battery-level-${icon}-${charging_name}-symbolic`
|
||||
: `battery-level-${icon}-symbolic`
|
||||
}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
</With>
|
||||
<image gicon={gicon} />
|
||||
</box>
|
||||
</button>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue