tooltip: ensure fully visible

This commit is contained in:
2 * r + 2 * t 2025-02-09 17:16:53 +11:00
parent d34556dca8
commit 09d4e48108
2 changed files with 31 additions and 5 deletions

View file

@ -1,7 +1,7 @@
import SWeather, { type WeatherData } from "@/services/weather"; import SWeather, { type WeatherData } from "@/services/weather";
import { ellipsize } from "@/utils/strings"; import { ellipsize } from "@/utils/strings";
import { bindCurrentTime } from "@/utils/system"; import { bindCurrentTime } from "@/utils/system";
import { Calendar as WCal } from "@/utils/widgets"; import { setupCustomTooltip, Calendar as WCal } from "@/utils/widgets";
import PopupWindow from "@/widgets/popupwindow"; import PopupWindow from "@/widgets/popupwindow";
import { bind, timeout } from "astal"; import { bind, timeout } from "astal";
import { Astal, Gtk, type Gdk } from "astal/gtk3"; import { Astal, Gtk, type Gdk } from "astal/gtk3";
@ -88,12 +88,22 @@ const Weather = () => {
<label <label
xalign={0} xalign={0}
label={bind(weather, "wind").as(w => `${w}`)} label={bind(weather, "wind").as(w => `${w}`)}
tooltipText={bind(weather, "wind").as(w => `${w} wind speed`)} setup={self =>
setupCustomTooltip(
self,
bind(weather, "wind").as(w => `${w} wind speed`)
)
}
/> />
<label <label
xalign={0} xalign={0}
label={bind(weather, "rainChance").as(r => `${r}`)} label={bind(weather, "rainChance").as(r => `${r}`)}
tooltipText={bind(weather, "rainChance").as(r => `${r} chance of rain`)} setup={self =>
setupCustomTooltip(
self,
bind(weather, "rainChance").as(r => `${r} chance of rain`)
)
}
/> />
</box> </box>
</centerbox> </centerbox>

View file

@ -8,6 +8,7 @@ export const setupCustomTooltip = (self: any, text: string | Binding<string>) =>
const window = new Widget.Window({ const window = new Widget.Window({
visible: false, visible: false,
namespace: "caelestia-tooltip", namespace: "caelestia-tooltip",
layer: Astal.Layer.OVERLAY,
keymode: Astal.Keymode.NONE, keymode: Astal.Keymode.NONE,
exclusivity: Astal.Exclusivity.IGNORE, exclusivity: Astal.Exclusivity.IGNORE,
anchor: Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT, anchor: Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT,
@ -19,7 +20,14 @@ export const setupCustomTooltip = (self: any, text: string | Binding<string>) =>
let lastX = 0; let lastX = 0;
self.connect("size-allocate", () => (dirty = true)); self.connect("size-allocate", () => (dirty = true));
window.connect("size-allocate", () => { window.connect("size-allocate", () => {
window.marginLeft = lastX + (self.get_allocated_width() - window.get_preferred_width()[1]) / 2; const mWidth = AstalHyprland.get_default().get_focused_monitor().get_width();
const pWidth = window.get_preferred_width()[1];
let marginLeft = lastX + (self.get_allocated_width() - pWidth) / 2;
if (marginLeft < 0) marginLeft = 0;
else if (marginLeft + pWidth > mWidth) marginLeft = mWidth - pWidth;
window.marginLeft = marginLeft;
}); });
if (text instanceof Binding) self.hook(text, (_: any, v: string) => !v && window.hide()); if (text instanceof Binding) self.hook(text, (_: any, v: string) => !v && window.hide());
@ -27,10 +35,18 @@ export const setupCustomTooltip = (self: any, text: string | Binding<string>) =>
if (text instanceof Binding && !text.get()) return false; if (text instanceof Binding && !text.get()) return false;
if (dirty) { if (dirty) {
const { width, height } = self.get_allocation(); const { width, height } = self.get_allocation();
const mWidth = AstalHyprland.get_default().get_focused_monitor().get_width();
const pWidth = window.get_preferred_width()[1];
const { x: cx, y: cy } = AstalHyprland.get_default().get_cursor_position(); const { x: cx, y: cy } = AstalHyprland.get_default().get_cursor_position();
window.marginLeft = cx + ((width - window.get_preferred_width()[1]) / 2 - x);
let marginLeft = cx + ((width - pWidth) / 2 - x);
if (marginLeft < 0) marginLeft = 0;
else if (marginLeft + pWidth > mWidth) marginLeft = mWidth - pWidth;
window.marginLeft = marginLeft;
window.marginTop = cy + (height - y); window.marginTop = cy + (height - y);
lastX = cx - x; lastX = cx - x;
dirty = false; dirty = false;
} }
return true; return true;