osds: lock keys popups
This commit is contained in:
parent
a2d73b585f
commit
5f2febe534
4 changed files with 103 additions and 15 deletions
7
app.tsx
7
app.tsx
|
|
@ -22,15 +22,14 @@ App.start({
|
||||||
|
|
||||||
<Launcher />;
|
<Launcher />;
|
||||||
<NotifPopups />;
|
<NotifPopups />;
|
||||||
Monitors.get_default().forEach(m => {
|
<Osds />;
|
||||||
<Osds monitor={m} />;
|
Monitors.get_default().forEach(m => <Bar monitor={m} />);
|
||||||
<Bar monitor={m} />;
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log("Caelestia started");
|
console.log("Caelestia started");
|
||||||
},
|
},
|
||||||
requestHandler(request, res) {
|
requestHandler(request, res) {
|
||||||
if (request === "reload css") loadStyleAsync().catch(console.error);
|
if (request === "reload css") loadStyleAsync().catch(console.error);
|
||||||
|
else if (request.startsWith("show")) App.get_window(request.split(" ")[1])?.show();
|
||||||
else if (request === "media play pause") Players.get_default().lastPlayer?.play_pause();
|
else if (request === "media play pause") Players.get_default().lastPlayer?.play_pause();
|
||||||
else if (request === "media next") Players.get_default().lastPlayer?.next();
|
else if (request === "media next") Players.get_default().lastPlayer?.next();
|
||||||
else if (request === "media previous") Players.get_default().lastPlayer?.previous();
|
else if (request === "media previous") Players.get_default().lastPlayer?.previous();
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,14 @@ export const osds = {
|
||||||
hideDelay: 1500,
|
hideDelay: 1500,
|
||||||
showValue: true,
|
showValue: true,
|
||||||
},
|
},
|
||||||
|
lock: {
|
||||||
|
caps: {
|
||||||
|
hideDelay: 1000,
|
||||||
|
},
|
||||||
|
num: {
|
||||||
|
hideDelay: 1000,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Services
|
// Services
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,12 @@
|
||||||
import { timeout, Variable, type Time } from "astal";
|
import { execAsync, register, timeout, Variable, type Time } from "astal";
|
||||||
import { Astal, Gtk, type Widget } from "astal/gtk3";
|
import { App, Astal, Gtk, Widget } from "astal/gtk3";
|
||||||
import cairo from "cairo";
|
import cairo from "cairo";
|
||||||
import AstalWp from "gi://AstalWp";
|
import AstalWp from "gi://AstalWp";
|
||||||
|
import Cairo from "gi://cairo";
|
||||||
import Pango from "gi://Pango";
|
import Pango from "gi://Pango";
|
||||||
import PangoCairo from "gi://PangoCairo";
|
import PangoCairo from "gi://PangoCairo";
|
||||||
import { osds as config } from "../config";
|
import { osds as config } from "../config";
|
||||||
import { type Monitor } from "../services/monitors";
|
import Monitors, { type Monitor } from "../services/monitors";
|
||||||
import { PopupWindow } from "../utils/widgets";
|
import { PopupWindow } from "../utils/widgets";
|
||||||
|
|
||||||
const getStyle = (context: Gtk.StyleContext, prop: string) => context.get_property(prop, Gtk.StateFlags.NORMAL);
|
const getStyle = (context: Gtk.StyleContext, prop: string) => context.get_property(prop, Gtk.StateFlags.NORMAL);
|
||||||
|
|
@ -40,8 +41,8 @@ const SliderOsd = ({
|
||||||
drawAreaSetup,
|
drawAreaSetup,
|
||||||
}: {
|
}: {
|
||||||
fillIcons?: boolean;
|
fillIcons?: boolean;
|
||||||
monitor: Monitor;
|
monitor?: Monitor;
|
||||||
type: keyof typeof config;
|
type: "volume" | "brightness";
|
||||||
windowSetup: (self: Widget.Window, show: () => void) => void;
|
windowSetup: (self: Widget.Window, show: () => void) => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
initValue: number;
|
initValue: number;
|
||||||
|
|
@ -49,7 +50,7 @@ const SliderOsd = ({
|
||||||
}) => (
|
}) => (
|
||||||
<PopupWindow
|
<PopupWindow
|
||||||
name={type}
|
name={type}
|
||||||
monitor={monitor.id}
|
monitor={monitor?.id}
|
||||||
keymode={Astal.Keymode.NONE}
|
keymode={Astal.Keymode.NONE}
|
||||||
anchor={config[type].position}
|
anchor={config[type].position}
|
||||||
margin={config[type].margin}
|
margin={config[type].margin}
|
||||||
|
|
@ -206,10 +207,9 @@ const SliderOsd = ({
|
||||||
</PopupWindow>
|
</PopupWindow>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Volume = ({ monitor, audio }: { monitor: Monitor; audio: AstalWp.Audio }) => (
|
const Volume = ({ audio }: { audio: AstalWp.Audio }) => (
|
||||||
<SliderOsd
|
<SliderOsd
|
||||||
fillIcons
|
fillIcons
|
||||||
monitor={monitor}
|
|
||||||
type="volume"
|
type="volume"
|
||||||
windowSetup={(self, show) => {
|
windowSetup={(self, show) => {
|
||||||
self.hook(audio.defaultSpeaker, "notify::volume", show);
|
self.hook(audio.defaultSpeaker, "notify::volume", show);
|
||||||
|
|
@ -259,9 +259,66 @@ const Brightness = ({ monitor }: { monitor: Monitor }) => (
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default ({ monitor }: { monitor: Monitor }) => {
|
@register()
|
||||||
if (AstalWp.get_default()) <Volume monitor={monitor} audio={AstalWp.get_default()!.audio} />;
|
class LockOsd extends Widget.Window {
|
||||||
<Brightness monitor={monitor} />;
|
readonly lockType: "caps" | "num";
|
||||||
|
|
||||||
|
#timeout: Time | null = null;
|
||||||
|
|
||||||
|
constructor({ type, icon, right }: { type: "caps" | "num"; icon: string; right?: boolean }) {
|
||||||
|
super({
|
||||||
|
visible: false,
|
||||||
|
name: `lock-${type}`,
|
||||||
|
application: App,
|
||||||
|
namespace: `caelestia-lock-${type}`,
|
||||||
|
anchor:
|
||||||
|
Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT | Astal.WindowAnchor.BOTTOM | Astal.WindowAnchor.RIGHT,
|
||||||
|
exclusivity: Astal.Exclusivity.IGNORE,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.lockType = type;
|
||||||
|
this.#update();
|
||||||
|
|
||||||
|
this.add(
|
||||||
|
<box vertical halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER} className={`lock ${type}`}>
|
||||||
|
<label vexpand className="icon" label={icon} />
|
||||||
|
<label vexpand className="text" label={type.slice(0, 1).toUpperCase() + type.slice(1) + "lock"} />
|
||||||
|
</box>
|
||||||
|
);
|
||||||
|
|
||||||
|
// Clickthrough
|
||||||
|
this.connect("size-allocate", () => this.input_shape_combine_region(new Cairo.Region()));
|
||||||
|
|
||||||
|
// Move over when other indicator opens/closes
|
||||||
|
this.hook(App, "window-toggled", (_, window) => {
|
||||||
|
if (window !== this && window instanceof LockOsd) {
|
||||||
|
const child = this.get_child();
|
||||||
|
if (!child) return;
|
||||||
|
this[right ? "marginLeft" : "marginRight"] = window.visible ? child.get_preferred_width()[1] + 5 : 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#update() {
|
||||||
|
execAsync(`fish -c 'cat /sys/class/leds/input*::${this.lockType}lock/brightness'`)
|
||||||
|
.then(out => (this.get_child() as Widget.Box | null)?.toggleClassName("enabled", out.includes("1")))
|
||||||
|
.catch(console.error);
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
super.show();
|
||||||
|
this.#update();
|
||||||
|
this.#timeout?.cancel();
|
||||||
|
this.#timeout = timeout(config.lock[this.lockType].hideDelay, () => this.hide());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
if (AstalWp.get_default()) <Volume audio={AstalWp.get_default()!.audio} />;
|
||||||
|
Monitors.get_default().forEach(monitor => <Brightness monitor={monitor} />);
|
||||||
|
|
||||||
|
<LockOsd type="caps" icon="keyboard_capslock" />;
|
||||||
|
<LockOsd right type="num" icon="filter_1" />;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -25,3 +25,27 @@
|
||||||
.volume .inner.mute {
|
.volume .inner.mute {
|
||||||
background-color: scheme.$overlay0;
|
background-color: scheme.$overlay0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lock {
|
||||||
|
@include lib.rounded(8);
|
||||||
|
@include lib.border(scheme.$overlay0, 0.1);
|
||||||
|
@include lib.shadow;
|
||||||
|
@include lib.element-decel;
|
||||||
|
@include font.mono;
|
||||||
|
|
||||||
|
min-width: lib.s(80);
|
||||||
|
min-height: lib.s(80);
|
||||||
|
padding: lib.s(10);
|
||||||
|
background-color: scheme.$base;
|
||||||
|
color: scheme.$overlay0;
|
||||||
|
font-size: lib.s(16);
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&.enabled {
|
||||||
|
color: scheme.$text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
font-size: lib.s(48);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue