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 { style } from "config";
|
||||
import { initConfig, updateConfig } from "config/funcs";
|
||||
import AstalHyprland from "gi://AstalHyprland?version=0.1";
|
||||
|
||||
const isLayer = (name: string) =>
|
||||
["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));
|
||||
|
||||
<Launcher />;
|
||||
<NotifPopups />;
|
||||
<Osds />;
|
||||
<Session />;
|
||||
Monitors.get_default().forEach(m => <NotifPopups monitor={m} />);
|
||||
Monitors.get_default().forEach(m => <SideBar monitor={m} />);
|
||||
Monitors.get_default().forEach(m => <Bar monitor={m} />);
|
||||
Monitors.get_default().forEach(m => <ScreenCorners monitor={m} />);
|
||||
|
|
@ -99,6 +100,8 @@ App.start({
|
|||
if (request === "reload-css") loadStyleAsync().catch(console.error);
|
||||
else if (request === "reload-config") updateConfig();
|
||||
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 next") Players.get_default().lastPlayer?.next();
|
||||
else if (request === "media previous") Players.get_default().lastPlayer?.previous();
|
||||
|
|
|
|||
|
|
@ -25,6 +25,10 @@ interface SpacerClassNameProps {
|
|||
afterSpacer?: boolean;
|
||||
}
|
||||
|
||||
interface ModuleProps extends SpacerClassNameProps {
|
||||
monitor: Monitor;
|
||||
}
|
||||
|
||||
const hyprland = AstalHyprland.get_default();
|
||||
|
||||
const getBatteryIcon = (perc: number) => {
|
||||
|
|
@ -70,8 +74,8 @@ const hookFocusedClientProp = (
|
|||
callback(lastClient);
|
||||
};
|
||||
|
||||
const switchPane = (name: string) => {
|
||||
const sidebar = App.get_window("sidebar") as SideBar | null;
|
||||
const switchPane = (monitor: Monitor, name: string) => {
|
||||
const sidebar = App.get_window(`sidebar${monitor.id}`) as SideBar | null;
|
||||
if (sidebar) {
|
||||
if (sidebar.visible && sidebar.shown.get() === name) sidebar.hide();
|
||||
else sidebar.show();
|
||||
|
|
@ -82,17 +86,17 @@ const switchPane = (name: string) => {
|
|||
const spacerClassName = ({ beforeSpacer, afterSpacer }: SpacerClassNameProps) =>
|
||||
`${beforeSpacer ? "before-spacer" : ""} ${afterSpacer ? "after-spacer" : ""}`;
|
||||
|
||||
const OSIcon = (props: SpacerClassNameProps) => (
|
||||
const OSIcon = ({ monitor, ...props }: ModuleProps) => (
|
||||
<button
|
||||
visible={bind(config.modules.osIcon.enabled)}
|
||||
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}
|
||||
</button>
|
||||
);
|
||||
|
||||
const ActiveWindow = (props: SpacerClassNameProps) => (
|
||||
const ActiveWindow = ({ monitor, ...props }: ModuleProps) => (
|
||||
<box
|
||||
visible={bind(config.modules.activeWindow.enabled)}
|
||||
vertical={bind(config.vertical)}
|
||||
|
|
@ -134,7 +138,7 @@ const ActiveWindow = (props: SpacerClassNameProps) => (
|
|||
</box>
|
||||
);
|
||||
|
||||
const MediaPlaying = (props: SpacerClassNameProps) => {
|
||||
const MediaPlaying = ({ monitor, ...props }: ModuleProps) => {
|
||||
const players = Players.get_default();
|
||||
const getLabel = (fallback = "") =>
|
||||
players.lastPlayer ? `${players.lastPlayer.title} - ${players.lastPlayer.artist}` : fallback;
|
||||
|
|
@ -142,7 +146,7 @@ const MediaPlaying = (props: SpacerClassNameProps) => {
|
|||
<button
|
||||
visible={bind(config.modules.mediaPlaying.enabled)}
|
||||
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.MIDDLE) players.lastPlayer?.raise();
|
||||
}}
|
||||
|
|
@ -222,7 +226,7 @@ const Workspace = ({ idx }: { idx: number }) => {
|
|||
);
|
||||
};
|
||||
|
||||
const Workspaces = (props: SpacerClassNameProps) => (
|
||||
const Workspaces = ({ monitor, ...props }: ModuleProps) => (
|
||||
<eventbox
|
||||
visible={bind(config.modules.workspaces.enabled)}
|
||||
onScroll={(_, event) => {
|
||||
|
|
@ -253,7 +257,7 @@ const TrayItem = (item: AstalTray.TrayItem) => (
|
|||
</menubutton>
|
||||
);
|
||||
|
||||
const Tray = (props: SpacerClassNameProps) => {
|
||||
const Tray = ({ monitor, ...props }: ModuleProps) => {
|
||||
const visible = Variable.derive(
|
||||
[config.modules.tray.enabled, bind(AstalTray.get_default(), "items")],
|
||||
(e, i) => e && i.length > 0
|
||||
|
|
@ -275,7 +279,7 @@ const Network = () => (
|
|||
<button
|
||||
onClick={(_, event) => {
|
||||
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.MIDDLE)
|
||||
execAsync("uwsm app -- gnome-control-center wifi").catch(() => {
|
||||
|
|
@ -378,7 +382,7 @@ const BluetoothDevice = (device: AstalBluetooth.Device) => (
|
|||
<button
|
||||
visible={bind(device, "connected")}
|
||||
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)
|
||||
device.disconnect_device((_, res) => device.disconnect_device_finish(res));
|
||||
else if (event.button === Astal.MouseButton.MIDDLE)
|
||||
|
|
@ -398,7 +402,7 @@ const Bluetooth = () => (
|
|||
<box vertical={bind(config.vertical)} className="bluetooth">
|
||||
<button
|
||||
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.MIDDLE)
|
||||
execAsync("uwsm app -- blueman-manager").catch(console.error);
|
||||
|
|
@ -440,7 +444,7 @@ const Bluetooth = () => (
|
|||
</box>
|
||||
);
|
||||
|
||||
const StatusIcons = (props: SpacerClassNameProps) => (
|
||||
const StatusIcons = ({ monitor, ...props }: ModuleProps) => (
|
||||
<box
|
||||
visible={bind(config.modules.statusIcons.enabled)}
|
||||
vertical={bind(config.vertical)}
|
||||
|
|
@ -451,10 +455,10 @@ const StatusIcons = (props: SpacerClassNameProps) => (
|
|||
</box>
|
||||
);
|
||||
|
||||
const PkgUpdates = (props: SpacerClassNameProps) => (
|
||||
const PkgUpdates = ({ monitor, ...props }: ModuleProps) => (
|
||||
<button
|
||||
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 =>
|
||||
setupCustomTooltip(
|
||||
self,
|
||||
|
|
@ -469,10 +473,10 @@ const PkgUpdates = (props: SpacerClassNameProps) => (
|
|||
</button>
|
||||
);
|
||||
|
||||
const NotifCount = (props: SpacerClassNameProps) => (
|
||||
const NotifCount = ({ monitor, ...props }: ModuleProps) => (
|
||||
<button
|
||||
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 =>
|
||||
setupCustomTooltip(
|
||||
self,
|
||||
|
|
@ -500,7 +504,7 @@ const NotifCount = (props: SpacerClassNameProps) => (
|
|||
</button>
|
||||
);
|
||||
|
||||
const Battery = (props: SpacerClassNameProps) => {
|
||||
const Battery = ({ monitor, ...props }: ModuleProps) => {
|
||||
const visible = Variable.derive(
|
||||
[config.modules.battery.enabled, bind(AstalBattery.get_default(), "isBattery")],
|
||||
(e, i) => e && i
|
||||
|
|
@ -553,10 +557,10 @@ const DateTimeVertical = (props: SpacerClassNameProps) => (
|
|||
</box>
|
||||
);
|
||||
|
||||
const DateTime = (props: SpacerClassNameProps) => (
|
||||
const DateTime = ({ monitor, ...props }: ModuleProps) => (
|
||||
<button
|
||||
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 =>
|
||||
setupCustomTooltip(self, bindCurrentTime(bind(config.modules.dateTime.detailedFormat), undefined, self))
|
||||
}
|
||||
|
|
@ -565,7 +569,7 @@ const DateTime = (props: SpacerClassNameProps) => (
|
|||
</button>
|
||||
);
|
||||
|
||||
const Power = (props: SpacerClassNameProps) => (
|
||||
const Power = ({ monitor, ...props }: ModuleProps) => (
|
||||
<button
|
||||
visible={bind(config.modules.power.enabled)}
|
||||
className={`module power ${spacerClassName(props)}`}
|
||||
|
|
@ -609,21 +613,21 @@ const Bar = ({ monitor }: { monitor: Monitor }) => {
|
|||
return (
|
||||
<centerbox vertical={bind(config.vertical)} className={bind(className)} onDestroy={() => className.drop()}>
|
||||
<box vertical={bind(config.vertical)}>
|
||||
<OSIcon />
|
||||
<ActiveWindow />
|
||||
<MediaPlaying beforeSpacer />
|
||||
<OSIcon monitor={monitor} />
|
||||
<ActiveWindow monitor={monitor} />
|
||||
<MediaPlaying monitor={monitor} beforeSpacer />
|
||||
<BrightnessSpacer monitor={monitor} />
|
||||
</box>
|
||||
<Workspaces beforeSpacer afterSpacer />
|
||||
<Workspaces monitor={monitor} beforeSpacer afterSpacer />
|
||||
<box vertical={bind(config.vertical)}>
|
||||
<VolumeSpacer />
|
||||
<Tray afterSpacer />
|
||||
<StatusIcons />
|
||||
<PkgUpdates />
|
||||
<NotifCount />
|
||||
<Battery />
|
||||
<DateTime />
|
||||
<Power />
|
||||
<Tray monitor={monitor} afterSpacer />
|
||||
<StatusIcons monitor={monitor} />
|
||||
<PkgUpdates monitor={monitor} />
|
||||
<NotifCount monitor={monitor} />
|
||||
<Battery monitor={monitor} />
|
||||
<DateTime monitor={monitor} />
|
||||
<Power monitor={monitor} />
|
||||
</box>
|
||||
</centerbox>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
import type { Monitor } from "@/services/monitors";
|
||||
import { idle, timeout } from "astal";
|
||||
import { App, Astal, Gtk } from "astal/gtk3";
|
||||
import { notifpopups as config } from "config";
|
||||
import AstalNotifd from "gi://AstalNotifd";
|
||||
import { setupChildClickthrough } from "../utils/widgets";
|
||||
import Notification from "../widgets/notification";
|
||||
import type SideBar from "./sidebar";
|
||||
|
||||
export default () => (
|
||||
export default ({ monitor }: { monitor: Monitor }) => (
|
||||
<window
|
||||
monitor={monitor.id}
|
||||
namespace="caelestia-notifpopups"
|
||||
anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT | Astal.WindowAnchor.BOTTOM}
|
||||
>
|
||||
|
|
@ -16,10 +20,9 @@ export default () => (
|
|||
setup={self => {
|
||||
const notifd = AstalNotifd.get_default();
|
||||
const map = new Map<number, Notification>();
|
||||
let notifsOpen = false;
|
||||
|
||||
self.hook(notifd, "notified", (self, id) => {
|
||||
if (notifsOpen || notifd.dontDisturb) return;
|
||||
if (notifd.dontDisturb) return;
|
||||
|
||||
const notification = notifd.get_notification(id);
|
||||
|
||||
|
|
@ -35,7 +38,11 @@ export default () => (
|
|||
if (event.button === Astal.MouseButton.PRIMARY) {
|
||||
if (notification.actions.length === 1)
|
||||
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
|
||||
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(App, "window-toggled", (_, window) => {
|
||||
if (window.name === "notifications") {
|
||||
notifsOpen = window.visible;
|
||||
map.forEach(n => n.destroyWithAnims());
|
||||
}
|
||||
});
|
||||
let sidebar: SideBar | null;
|
||||
|
||||
const awaitSidebar = () => {
|
||||
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
|
||||
setupChildClickthrough(self);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export default class SideBar extends Widget.Window {
|
|||
constructor({ monitor }: { monitor: Monitor }) {
|
||||
super({
|
||||
application: App,
|
||||
name: "sidebar",
|
||||
name: `sidebar${monitor.id}`,
|
||||
namespace: "caelestia-sidebar",
|
||||
monitor: monitor.id,
|
||||
anchor: Astal.WindowAnchor.LEFT | Astal.WindowAnchor.TOP | Astal.WindowAnchor.BOTTOM,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue