notifpopups: fix clicking opening sidebar
This commit is contained in:
parent
c131a0425e
commit
473e5a6b8a
4 changed files with 59 additions and 44 deletions
5
app.tsx
5
app.tsx
|
|
@ -15,6 +15,7 @@ import { execAsync, idle, timeout, writeFileAsync } from "astal";
|
||||||
import { App } from "astal/gtk3";
|
import { App } from "astal/gtk3";
|
||||||
import { style } from "config";
|
import { style } from "config";
|
||||||
import { initConfig, updateConfig } from "config/funcs";
|
import { initConfig, updateConfig } from "config/funcs";
|
||||||
|
import AstalHyprland from "gi://AstalHyprland?version=0.1";
|
||||||
|
|
||||||
const isLayer = (name: string) =>
|
const isLayer = (name: string) =>
|
||||||
["base", "mantle", "crust"].includes(name) || name.startsWith("surface") || name.startsWith("overlay");
|
["base", "mantle", "crust"].includes(name) || name.startsWith("surface") || name.startsWith("overlay");
|
||||||
|
|
@ -75,9 +76,9 @@ App.start({
|
||||||
Palette.get_default().connect("notify::mode", () => loadStyleAsync().catch(console.error));
|
Palette.get_default().connect("notify::mode", () => loadStyleAsync().catch(console.error));
|
||||||
|
|
||||||
<Launcher />;
|
<Launcher />;
|
||||||
<NotifPopups />;
|
|
||||||
<Osds />;
|
<Osds />;
|
||||||
<Session />;
|
<Session />;
|
||||||
|
Monitors.get_default().forEach(m => <NotifPopups monitor={m} />);
|
||||||
Monitors.get_default().forEach(m => <SideBar monitor={m} />);
|
Monitors.get_default().forEach(m => <SideBar monitor={m} />);
|
||||||
Monitors.get_default().forEach(m => <Bar monitor={m} />);
|
Monitors.get_default().forEach(m => <Bar monitor={m} />);
|
||||||
Monitors.get_default().forEach(m => <ScreenCorners monitor={m} />);
|
Monitors.get_default().forEach(m => <ScreenCorners monitor={m} />);
|
||||||
|
|
@ -99,6 +100,8 @@ App.start({
|
||||||
if (request === "reload-css") loadStyleAsync().catch(console.error);
|
if (request === "reload-css") loadStyleAsync().catch(console.error);
|
||||||
else if (request === "reload-config") updateConfig();
|
else if (request === "reload-config") updateConfig();
|
||||||
else if (request.startsWith("show")) App.get_window(request.split(" ")[1])?.show();
|
else if (request.startsWith("show")) App.get_window(request.split(" ")[1])?.show();
|
||||||
|
else if (request.startsWith("toggle"))
|
||||||
|
App.toggle_window(request.split(" ")[1] + AstalHyprland.get_default().focusedMonitor.id);
|
||||||
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();
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,10 @@ interface SpacerClassNameProps {
|
||||||
afterSpacer?: boolean;
|
afterSpacer?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ModuleProps extends SpacerClassNameProps {
|
||||||
|
monitor: Monitor;
|
||||||
|
}
|
||||||
|
|
||||||
const hyprland = AstalHyprland.get_default();
|
const hyprland = AstalHyprland.get_default();
|
||||||
|
|
||||||
const getBatteryIcon = (perc: number) => {
|
const getBatteryIcon = (perc: number) => {
|
||||||
|
|
@ -70,8 +74,8 @@ const hookFocusedClientProp = (
|
||||||
callback(lastClient);
|
callback(lastClient);
|
||||||
};
|
};
|
||||||
|
|
||||||
const switchPane = (name: string) => {
|
const switchPane = (monitor: Monitor, name: string) => {
|
||||||
const sidebar = App.get_window("sidebar") as SideBar | null;
|
const sidebar = App.get_window(`sidebar${monitor.id}`) as SideBar | null;
|
||||||
if (sidebar) {
|
if (sidebar) {
|
||||||
if (sidebar.visible && sidebar.shown.get() === name) sidebar.hide();
|
if (sidebar.visible && sidebar.shown.get() === name) sidebar.hide();
|
||||||
else sidebar.show();
|
else sidebar.show();
|
||||||
|
|
@ -82,17 +86,17 @@ const switchPane = (name: string) => {
|
||||||
const spacerClassName = ({ beforeSpacer, afterSpacer }: SpacerClassNameProps) =>
|
const spacerClassName = ({ beforeSpacer, afterSpacer }: SpacerClassNameProps) =>
|
||||||
`${beforeSpacer ? "before-spacer" : ""} ${afterSpacer ? "after-spacer" : ""}`;
|
`${beforeSpacer ? "before-spacer" : ""} ${afterSpacer ? "after-spacer" : ""}`;
|
||||||
|
|
||||||
const OSIcon = (props: SpacerClassNameProps) => (
|
const OSIcon = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.osIcon.enabled)}
|
visible={bind(config.modules.osIcon.enabled)}
|
||||||
className={`module os-icon ${spacerClassName(props)}`}
|
className={`module os-icon ${spacerClassName(props)}`}
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("dashboard")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "dashboard")}
|
||||||
>
|
>
|
||||||
{osIcon}
|
{osIcon}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const ActiveWindow = (props: SpacerClassNameProps) => (
|
const ActiveWindow = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<box
|
<box
|
||||||
visible={bind(config.modules.activeWindow.enabled)}
|
visible={bind(config.modules.activeWindow.enabled)}
|
||||||
vertical={bind(config.vertical)}
|
vertical={bind(config.vertical)}
|
||||||
|
|
@ -134,7 +138,7 @@ const ActiveWindow = (props: SpacerClassNameProps) => (
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const MediaPlaying = (props: SpacerClassNameProps) => {
|
const MediaPlaying = ({ monitor, ...props }: ModuleProps) => {
|
||||||
const players = Players.get_default();
|
const players = Players.get_default();
|
||||||
const getLabel = (fallback = "") =>
|
const getLabel = (fallback = "") =>
|
||||||
players.lastPlayer ? `${players.lastPlayer.title} - ${players.lastPlayer.artist}` : fallback;
|
players.lastPlayer ? `${players.lastPlayer.title} - ${players.lastPlayer.artist}` : fallback;
|
||||||
|
|
@ -142,7 +146,7 @@ const MediaPlaying = (props: SpacerClassNameProps) => {
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.mediaPlaying.enabled)}
|
visible={bind(config.modules.mediaPlaying.enabled)}
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
if (event.button === Astal.MouseButton.PRIMARY) switchPane("audio");
|
if (event.button === Astal.MouseButton.PRIMARY) switchPane(monitor, "audio");
|
||||||
else if (event.button === Astal.MouseButton.SECONDARY) players.lastPlayer?.play_pause();
|
else if (event.button === Astal.MouseButton.SECONDARY) players.lastPlayer?.play_pause();
|
||||||
else if (event.button === Astal.MouseButton.MIDDLE) players.lastPlayer?.raise();
|
else if (event.button === Astal.MouseButton.MIDDLE) players.lastPlayer?.raise();
|
||||||
}}
|
}}
|
||||||
|
|
@ -222,7 +226,7 @@ const Workspace = ({ idx }: { idx: number }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Workspaces = (props: SpacerClassNameProps) => (
|
const Workspaces = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<eventbox
|
<eventbox
|
||||||
visible={bind(config.modules.workspaces.enabled)}
|
visible={bind(config.modules.workspaces.enabled)}
|
||||||
onScroll={(_, event) => {
|
onScroll={(_, event) => {
|
||||||
|
|
@ -253,7 +257,7 @@ const TrayItem = (item: AstalTray.TrayItem) => (
|
||||||
</menubutton>
|
</menubutton>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Tray = (props: SpacerClassNameProps) => {
|
const Tray = ({ monitor, ...props }: ModuleProps) => {
|
||||||
const visible = Variable.derive(
|
const visible = Variable.derive(
|
||||||
[config.modules.tray.enabled, bind(AstalTray.get_default(), "items")],
|
[config.modules.tray.enabled, bind(AstalTray.get_default(), "items")],
|
||||||
(e, i) => e && i.length > 0
|
(e, i) => e && i.length > 0
|
||||||
|
|
@ -275,7 +279,7 @@ const Network = () => (
|
||||||
<button
|
<button
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
const network = AstalNetwork.get_default();
|
const network = AstalNetwork.get_default();
|
||||||
if (event.button === Astal.MouseButton.PRIMARY) switchPane("connectivity");
|
if (event.button === Astal.MouseButton.PRIMARY) switchPane(monitor, "connectivity");
|
||||||
else if (event.button === Astal.MouseButton.SECONDARY) network.wifi.enabled = !network.wifi.enabled;
|
else if (event.button === Astal.MouseButton.SECONDARY) network.wifi.enabled = !network.wifi.enabled;
|
||||||
else if (event.button === Astal.MouseButton.MIDDLE)
|
else if (event.button === Astal.MouseButton.MIDDLE)
|
||||||
execAsync("uwsm app -- gnome-control-center wifi").catch(() => {
|
execAsync("uwsm app -- gnome-control-center wifi").catch(() => {
|
||||||
|
|
@ -378,7 +382,7 @@ const BluetoothDevice = (device: AstalBluetooth.Device) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(device, "connected")}
|
visible={bind(device, "connected")}
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
if (event.button === Astal.MouseButton.PRIMARY) switchPane("connectivity");
|
if (event.button === Astal.MouseButton.PRIMARY) switchPane(monitor, "connectivity");
|
||||||
else if (event.button === Astal.MouseButton.SECONDARY)
|
else if (event.button === Astal.MouseButton.SECONDARY)
|
||||||
device.disconnect_device((_, res) => device.disconnect_device_finish(res));
|
device.disconnect_device((_, res) => device.disconnect_device_finish(res));
|
||||||
else if (event.button === Astal.MouseButton.MIDDLE)
|
else if (event.button === Astal.MouseButton.MIDDLE)
|
||||||
|
|
@ -398,7 +402,7 @@ const Bluetooth = () => (
|
||||||
<box vertical={bind(config.vertical)} className="bluetooth">
|
<box vertical={bind(config.vertical)} className="bluetooth">
|
||||||
<button
|
<button
|
||||||
onClick={(_, event) => {
|
onClick={(_, event) => {
|
||||||
if (event.button === Astal.MouseButton.PRIMARY) switchPane("connectivity");
|
if (event.button === Astal.MouseButton.PRIMARY) switchPane(monitor, "connectivity");
|
||||||
else if (event.button === Astal.MouseButton.SECONDARY) AstalBluetooth.get_default().toggle();
|
else if (event.button === Astal.MouseButton.SECONDARY) AstalBluetooth.get_default().toggle();
|
||||||
else if (event.button === Astal.MouseButton.MIDDLE)
|
else if (event.button === Astal.MouseButton.MIDDLE)
|
||||||
execAsync("uwsm app -- blueman-manager").catch(console.error);
|
execAsync("uwsm app -- blueman-manager").catch(console.error);
|
||||||
|
|
@ -440,7 +444,7 @@ const Bluetooth = () => (
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const StatusIcons = (props: SpacerClassNameProps) => (
|
const StatusIcons = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<box
|
<box
|
||||||
visible={bind(config.modules.statusIcons.enabled)}
|
visible={bind(config.modules.statusIcons.enabled)}
|
||||||
vertical={bind(config.vertical)}
|
vertical={bind(config.vertical)}
|
||||||
|
|
@ -451,10 +455,10 @@ const StatusIcons = (props: SpacerClassNameProps) => (
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const PkgUpdates = (props: SpacerClassNameProps) => (
|
const PkgUpdates = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.pkgUpdates.enabled)}
|
visible={bind(config.modules.pkgUpdates.enabled)}
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("packages")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "packages")}
|
||||||
setup={self =>
|
setup={self =>
|
||||||
setupCustomTooltip(
|
setupCustomTooltip(
|
||||||
self,
|
self,
|
||||||
|
|
@ -469,10 +473,10 @@ const PkgUpdates = (props: SpacerClassNameProps) => (
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const NotifCount = (props: SpacerClassNameProps) => (
|
const NotifCount = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.notifCount.enabled)}
|
visible={bind(config.modules.notifCount.enabled)}
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("notifpane")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "notifpane")}
|
||||||
setup={self =>
|
setup={self =>
|
||||||
setupCustomTooltip(
|
setupCustomTooltip(
|
||||||
self,
|
self,
|
||||||
|
|
@ -500,7 +504,7 @@ const NotifCount = (props: SpacerClassNameProps) => (
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Battery = (props: SpacerClassNameProps) => {
|
const Battery = ({ monitor, ...props }: ModuleProps) => {
|
||||||
const visible = Variable.derive(
|
const visible = Variable.derive(
|
||||||
[config.modules.battery.enabled, bind(AstalBattery.get_default(), "isBattery")],
|
[config.modules.battery.enabled, bind(AstalBattery.get_default(), "isBattery")],
|
||||||
(e, i) => e && i
|
(e, i) => e && i
|
||||||
|
|
@ -553,10 +557,10 @@ const DateTimeVertical = (props: SpacerClassNameProps) => (
|
||||||
</box>
|
</box>
|
||||||
);
|
);
|
||||||
|
|
||||||
const DateTime = (props: SpacerClassNameProps) => (
|
const DateTime = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.dateTime.enabled)}
|
visible={bind(config.modules.dateTime.enabled)}
|
||||||
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("time")}
|
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane(monitor, "time")}
|
||||||
setup={self =>
|
setup={self =>
|
||||||
setupCustomTooltip(self, bindCurrentTime(bind(config.modules.dateTime.detailedFormat), undefined, self))
|
setupCustomTooltip(self, bindCurrentTime(bind(config.modules.dateTime.detailedFormat), undefined, self))
|
||||||
}
|
}
|
||||||
|
|
@ -565,7 +569,7 @@ const DateTime = (props: SpacerClassNameProps) => (
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
const Power = (props: SpacerClassNameProps) => (
|
const Power = ({ monitor, ...props }: ModuleProps) => (
|
||||||
<button
|
<button
|
||||||
visible={bind(config.modules.power.enabled)}
|
visible={bind(config.modules.power.enabled)}
|
||||||
className={`module power ${spacerClassName(props)}`}
|
className={`module power ${spacerClassName(props)}`}
|
||||||
|
|
@ -609,21 +613,21 @@ const Bar = ({ monitor }: { monitor: Monitor }) => {
|
||||||
return (
|
return (
|
||||||
<centerbox vertical={bind(config.vertical)} className={bind(className)} onDestroy={() => className.drop()}>
|
<centerbox vertical={bind(config.vertical)} className={bind(className)} onDestroy={() => className.drop()}>
|
||||||
<box vertical={bind(config.vertical)}>
|
<box vertical={bind(config.vertical)}>
|
||||||
<OSIcon />
|
<OSIcon monitor={monitor} />
|
||||||
<ActiveWindow />
|
<ActiveWindow monitor={monitor} />
|
||||||
<MediaPlaying beforeSpacer />
|
<MediaPlaying monitor={monitor} beforeSpacer />
|
||||||
<BrightnessSpacer monitor={monitor} />
|
<BrightnessSpacer monitor={monitor} />
|
||||||
</box>
|
</box>
|
||||||
<Workspaces beforeSpacer afterSpacer />
|
<Workspaces monitor={monitor} beforeSpacer afterSpacer />
|
||||||
<box vertical={bind(config.vertical)}>
|
<box vertical={bind(config.vertical)}>
|
||||||
<VolumeSpacer />
|
<VolumeSpacer />
|
||||||
<Tray afterSpacer />
|
<Tray monitor={monitor} afterSpacer />
|
||||||
<StatusIcons />
|
<StatusIcons monitor={monitor} />
|
||||||
<PkgUpdates />
|
<PkgUpdates monitor={monitor} />
|
||||||
<NotifCount />
|
<NotifCount monitor={monitor} />
|
||||||
<Battery />
|
<Battery monitor={monitor} />
|
||||||
<DateTime />
|
<DateTime monitor={monitor} />
|
||||||
<Power />
|
<Power monitor={monitor} />
|
||||||
</box>
|
</box>
|
||||||
</centerbox>
|
</centerbox>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,15 @@
|
||||||
|
import type { Monitor } from "@/services/monitors";
|
||||||
|
import { idle, timeout } from "astal";
|
||||||
import { App, Astal, Gtk } from "astal/gtk3";
|
import { App, Astal, Gtk } from "astal/gtk3";
|
||||||
import { notifpopups as config } from "config";
|
import { notifpopups as config } from "config";
|
||||||
import AstalNotifd from "gi://AstalNotifd";
|
import AstalNotifd from "gi://AstalNotifd";
|
||||||
import { setupChildClickthrough } from "../utils/widgets";
|
import { setupChildClickthrough } from "../utils/widgets";
|
||||||
import Notification from "../widgets/notification";
|
import Notification from "../widgets/notification";
|
||||||
|
import type SideBar from "./sidebar";
|
||||||
|
|
||||||
export default () => (
|
export default ({ monitor }: { monitor: Monitor }) => (
|
||||||
<window
|
<window
|
||||||
|
monitor={monitor.id}
|
||||||
namespace="caelestia-notifpopups"
|
namespace="caelestia-notifpopups"
|
||||||
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM}
|
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM}
|
||||||
>
|
>
|
||||||
|
|
@ -16,10 +20,9 @@ export default () => (
|
||||||
setup={self => {
|
setup={self => {
|
||||||
const notifd = AstalNotifd.get_default();
|
const notifd = AstalNotifd.get_default();
|
||||||
const map = new Map<number, Notification>();
|
const map = new Map<number, Notification>();
|
||||||
let notifsOpen = false;
|
|
||||||
|
|
||||||
self.hook(notifd, "notified", (self, id) => {
|
self.hook(notifd, "notified", (self, id) => {
|
||||||
if (notifsOpen || notifd.dontDisturb) return;
|
if (notifd.dontDisturb) return;
|
||||||
|
|
||||||
const notification = notifd.get_notification(id);
|
const notification = notifd.get_notification(id);
|
||||||
|
|
||||||
|
|
@ -35,7 +38,11 @@ export default () => (
|
||||||
if (event.button === Astal.MouseButton.PRIMARY) {
|
if (event.button === Astal.MouseButton.PRIMARY) {
|
||||||
if (notification.actions.length === 1)
|
if (notification.actions.length === 1)
|
||||||
notification.invoke(notification.actions[0].id);
|
notification.invoke(notification.actions[0].id);
|
||||||
else App.get_window("notifications")?.show();
|
else {
|
||||||
|
sidebar?.shown.set("notifpane");
|
||||||
|
sidebar?.show();
|
||||||
|
popup.destroyWithAnims();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Dismiss on middle click
|
// Dismiss on middle click
|
||||||
else if (event.button === Astal.MouseButton.MIDDLE) notification.dismiss();
|
else if (event.button === Astal.MouseButton.MIDDLE) notification.dismiss();
|
||||||
|
|
@ -54,12 +61,13 @@ export default () => (
|
||||||
});
|
});
|
||||||
self.hook(notifd, "resolved", (_, id) => map.get(id)?.destroyWithAnims());
|
self.hook(notifd, "resolved", (_, id) => map.get(id)?.destroyWithAnims());
|
||||||
|
|
||||||
self.hook(App, "window-toggled", (_, window) => {
|
let sidebar: SideBar | null;
|
||||||
if (window.name === "notifications") {
|
|
||||||
notifsOpen = window.visible;
|
const awaitSidebar = () => {
|
||||||
map.forEach(n => n.destroyWithAnims());
|
sidebar = App.get_window(`sidebar${monitor.id}`) as SideBar | null;
|
||||||
}
|
if (!sidebar) timeout(100, awaitSidebar);
|
||||||
});
|
};
|
||||||
|
idle(awaitSidebar);
|
||||||
|
|
||||||
// Change input region to child region so can click through empty space
|
// Change input region to child region so can click through empty space
|
||||||
setupChildClickthrough(self);
|
setupChildClickthrough(self);
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ export default class SideBar extends Widget.Window {
|
||||||
constructor({ monitor }: { monitor: Monitor }) {
|
constructor({ monitor }: { monitor: Monitor }) {
|
||||||
super({
|
super({
|
||||||
application: App,
|
application: App,
|
||||||
name: "sidebar",
|
name: `sidebar${monitor.id}`,
|
||||||
namespace: "caelestia-sidebar",
|
namespace: "caelestia-sidebar",
|
||||||
monitor: monitor.id,
|
monitor: monitor.id,
|
||||||
anchor: Astal.WindowAnchor.LEFT | Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM,
|
anchor: Astal.WindowAnchor.LEFT | Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM,
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue