diff options
| author | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-02-18 22:34:13 +1100 |
|---|---|---|
| committer | 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com> | 2025-02-18 22:34:13 +1100 |
| commit | 0b771cbd1bfccdcbf4cbaabfed13eece4a2e8929 (patch) | |
| tree | b425f18696b5e17db585a90c39f1b3e7b1959c5c | |
| parent | bar: transparent + more round (diff) | |
| download | caelestia-shell-0b771cbd1bfccdcbf4cbaabfed13eece4a2e8929.tar.gz caelestia-shell-0b771cbd1bfccdcbf4cbaabfed13eece4a2e8929.tar.bz2 caelestia-shell-0b771cbd1bfccdcbf4cbaabfed13eece4a2e8929.zip | |
bar: vertical mode
| -rw-r--r-- | config.ts | 3 | ||||
| -rw-r--r-- | scss/bar.scss | 147 | ||||
| -rw-r--r-- | src/modules/bar.tsx | 58 | ||||
| -rw-r--r-- | src/utils/widgets.ts | 2 | ||||
| -rw-r--r-- | src/widgets/popupwindow.ts | 22 |
5 files changed, 164 insertions, 68 deletions
@@ -2,7 +2,8 @@ import { Astal } from "astal/gtk3"; // Modules export const bar = { - wsPerGroup: 10, + vertical: true, + wsPerGroup: 5, dateTimeFormat: "%d/%m/%y %R", }; diff --git a/scss/bar.scss b/scss/bar.scss index fb47501..d4dd974 100644 --- a/scss/bar.scss +++ b/scss/bar.scss @@ -6,22 +6,12 @@ .bar { @include font.mono; - margin: 10px 10px 0 10px; font-size: lib.s(14); - @include lib.spacing(10); - - & > * { - @include lib.spacing(10); - } - .module { @include lib.rounded(8); - padding: lib.s(3) lib.s(8); background-color: scheme.$base; - - @include lib.spacing; } label.icon { @@ -33,7 +23,6 @@ color: scheme.$yellow; font-size: lib.s(14); - padding-right: lib.s(12); } .active-window { @@ -43,55 +32,35 @@ .media-playing { color: scheme.$lavender; - @include lib.spacing(8); - icon { font-size: lib.s(16); } } - .workspaces { - padding: lib.s(3) lib.s(18); - - @include lib.spacing(10); - - & > * { - @include lib.rounded(100); - @include lib.element-decel; + .workspaces > * { + @include lib.rounded(100); + @include lib.element-decel; - min-width: lib.s(8); - min-height: lib.s(8); - background-color: scheme.$surface1; + min-width: lib.s(8); + min-height: lib.s(8); + background-color: scheme.$surface1; - &.occupied { - background-color: scheme.$overlay1; - } + &.occupied { + background-color: scheme.$overlay1; + } - &.focused { - min-width: lib.s(30); - background-color: scheme.$mauve; - } + &.focused { + background-color: scheme.$mauve; } } .tray { font-size: lib.s(15); color: scheme.$text; - - @include lib.spacing(10); } .status-icons { color: scheme.$rosewater; - - .bluetooth { - @include lib.spacing(10); - - // The spacing doesn't look right for some reason so this - & > :first-child:not(:last-child) { - margin-right: lib.s(5); - } - } } .pkg-updates { @@ -123,4 +92,98 @@ font-weight: bold; font-size: lib.s(16); } + + &.horizontal { + margin: 10px 10px 0 10px; + + @include lib.spacing(10); + + & > * { + @include lib.spacing(10); + } + + .module { + padding: lib.s(3) lib.s(8); + + @include lib.spacing; + } + + .os-icon { + padding-right: lib.s(12); + } + + .media-playing { + @include lib.spacing(8); + } + + .workspaces { + padding: lib.s(3) lib.s(18); + + @include lib.spacing(10); + + & > .focused { + min-width: lib.s(30); + } + } + + .tray { + @include lib.spacing(10); + } + + .status-icons .bluetooth { + @include lib.spacing(10); + + // The spacing doesn't look right for some reason so this + & > :first-child:not(:last-child) { + margin-right: lib.s(5); + } + } + } + + &.vertical { + margin: 10px 0 10px 10px; + + @include lib.spacing(10, true); + + & > * { + @include lib.spacing(10, true); + } + + .module { + padding: lib.s(8); + + @include lib.spacing($vertical: true); + } + + .os-icon > * { + margin-left: lib.s(-5); + } + + .media-playing { + @include lib.spacing(8, true); + } + + .workspaces { + padding: lib.s(18) lib.s(3); + + @include lib.spacing(10, true); + + & > .focused { + min-height: lib.s(30); + } + } + + .tray { + @include lib.spacing(10, true); + } + + .status-icons .bluetooth { + @include lib.spacing(10, true); + + // The spacing doesn't look right for some reason so this + & > :first-child:not(:last-child) { + margin-bottom: lib.s(5); + } + } + } } diff --git a/src/modules/bar.tsx b/src/modules/bar.tsx index ad11f43..33a5a9b 100644 --- a/src/modules/bar.tsx +++ b/src/modules/bar.tsx @@ -68,14 +68,15 @@ const togglePopup = (self: JSX.Element, event: Astal.ClickEvent, name: string) = const OSIcon = () => ( <button className="module os-icon" - label={osIcon} onClick={(self, event) => event.button === Astal.MouseButton.PRIMARY && togglePopup(self, event, "sideleft")} - /> + > + {osIcon} + </button> ); const ActiveWindow = () => ( <box - hasTooltip + vertical={config.vertical} className="module active-window" setup={self => { const title = Variable(""); @@ -101,8 +102,13 @@ const ActiveWindow = () => ( } /> <label + angle={config.vertical ? 270 : 0} setup={self => - hookFocusedClientProp(self, "title", c => (self.label = c?.title ? ellipsize(c.title) : "Desktop")) + hookFocusedClientProp( + self, + "title", + c => (self.label = c?.title ? ellipsize(c.title, config.vertical ? 30 : 40) : "Desktop") + ) } /> </box> @@ -126,7 +132,7 @@ const MediaPlaying = () => { setupCustomTooltip(self, bind(label)); }} > - <box className="module media-playing"> + <box vertical={config.vertical} className="module media-playing"> <icon setup={self => players.hookLastPlayer(self, "notify::identity", () => { @@ -142,6 +148,7 @@ const MediaPlaying = () => { } /> <label + angle={config.vertical ? 270 : 0} setup={self => players.hookLastPlayer(self, ["notify::title", "notify::artist"], () => { self.label = ellipsize(getLabel("No media")); // TODO: scroll text @@ -195,7 +202,7 @@ const Workspaces = () => ( hyprland.dispatch("workspace", (event.delta_y < 0 ? "-" : "+") + 1); }} > - <box className="module workspaces"> + <box vertical={config.vertical} className="module workspaces"> {Array.from({ length: config.wsPerGroup }).map((_, idx) => ( <Workspace idx={idx + 1} /> // Start from 1 ))} @@ -248,7 +255,11 @@ const TrayItem = (item: AstalTray.TrayItem) => { }; const Tray = () => ( - <box className="module tray" visible={bind(AstalTray.get_default(), "items").as(i => i.length > 0)}> + <box + vertical={config.vertical} + className="module tray" + visible={bind(AstalTray.get_default(), "items").as(i => i.length > 0)} + > {bind(AstalTray.get_default(), "items").as(i => i.map(TrayItem))} </box> ); @@ -378,7 +389,7 @@ const BluetoothDevice = (device: AstalBluetooth.Device) => ( ); const Bluetooth = () => ( - <box className="bluetooth"> + <box vertical={config.vertical} className="bluetooth"> <button onClick={(self, event) => { if (event.button === Astal.MouseButton.PRIMARY) togglePopup(self, event, "bluetooth-devices"); @@ -424,7 +435,7 @@ const Bluetooth = () => ( ); const StatusIcons = () => ( - <box className="module status-icons"> + <box vertical={config.vertical} className="module status-icons"> <Network /> <Bluetooth /> </box> @@ -440,7 +451,7 @@ const PkgUpdates = () => ( ) } > - <box className="module pkg-updates"> + <box vertical={config.vertical} className="module pkg-updates"> <label className="icon" label="download" /> <label label={bind(Updates.get_default(), "numUpdates").as(String)} /> </box> @@ -461,7 +472,7 @@ const NotifCount = () => ( ) } > - <box className="module notif-count"> + <box vertical={config.vertical} className="module notif-count"> <label className="icon" label="info" /> <label label={bind(AstalNotifd.get_default(), "notifications").as(n => String(n.length))} /> </box> @@ -476,6 +487,7 @@ const Battery = () => { return ( <box + vertical={config.vertical} className={bind(className)} setup={self => setupCustomTooltip( @@ -486,7 +498,9 @@ const Battery = () => { onDestroy={() => className.drop()} > <revealer - transitionType={Gtk.RevealerTransitionType.SLIDE_RIGHT} + transitionType={ + config.vertical ? Gtk.RevealerTransitionType.SLIDE_UP : Gtk.RevealerTransitionType.SLIDE_LEFT + } transitionDuration={150} revealChild={bind(AstalBattery.get_default(), "charging")} > @@ -502,9 +516,9 @@ const DateTime = () => ( <button onClick={(self, event) => event.button === Astal.MouseButton.PRIMARY && togglePopup(self, event, "sideright")} > - <box className="module date-time"> + <box vertical={config.vertical} className="module date-time"> <label className="icon" label="calendar_month" /> - <label label={bindCurrentTime(config.dateTimeFormat)} /> + <label angle={config.vertical ? 270 : 0} label={bindCurrentTime(config.dateTimeFormat)} /> </box> </button> ); @@ -521,25 +535,29 @@ export default ({ monitor }: { monitor: Monitor }) => ( <window namespace="caelestia-bar" monitor={monitor.id} - anchor={Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT | Astal.WindowAnchor.RIGHT} + anchor={ + Astal.WindowAnchor.TOP | + Astal.WindowAnchor.LEFT | + (config.vertical ? Astal.WindowAnchor.BOTTOM : Astal.WindowAnchor.RIGHT) + } exclusivity={Astal.Exclusivity.EXCLUSIVE} > - <centerbox className="bar"> - <box> + <centerbox vertical={config.vertical} className={`bar ${config.vertical ? "vertical" : " horizontal"}`}> + <box vertical={config.vertical}> <OSIcon /> <ActiveWindow /> <MediaPlaying /> <button - hexpand + expand onScroll={(_, event) => event.delta_y > 0 ? (monitor.brightness -= 0.1) : (monitor.brightness += 0.1) } /> </box> <Workspaces /> - <box> + <box vertical={config.vertical}> <button - hexpand + expand onScroll={(_, event) => { const speaker = AstalWp01.get_default()?.audio.defaultSpeaker; if (!speaker) return; diff --git a/src/utils/widgets.ts b/src/utils/widgets.ts index c6f0f19..9802263 100644 --- a/src/utils/widgets.ts +++ b/src/utils/widgets.ts @@ -6,6 +6,8 @@ import type { AstalWidget } from "./types"; export const setupCustomTooltip = (self: AstalWidget, text: string | Binding<string>) => { if (!text) return null; + self.set_has_tooltip(true); + const window = new Widget.Window({ visible: false, namespace: "caelestia-tooltip", diff --git a/src/widgets/popupwindow.ts b/src/widgets/popupwindow.ts index ffed396..2ba49fc 100644 --- a/src/widgets/popupwindow.ts +++ b/src/widgets/popupwindow.ts @@ -1,5 +1,6 @@ import { Binding, register } from "astal"; import { App, Astal, Gdk, Widget } from "astal/gtk3"; +import { bar } from "config"; import AstalHyprland from "gi://AstalHyprland?version=0.1"; const extendProp = <T>( @@ -29,19 +30,30 @@ export default class PopupWindow extends Widget.Window { popup_at_widget(widget: JSX.Element, event: Gdk.Event | Astal.ClickEvent) { const { width, height } = widget.get_allocation(); - const mWidth = AstalHyprland.get_default().get_focused_monitor().get_width(); + const { width: mWidth, height: mHeight } = AstalHyprland.get_default().get_focused_monitor(); const pWidth = this.get_preferred_width()[1]; + const pHeight = this.get_preferred_height()[1]; const [, x, y] = event instanceof Gdk.Event ? event.get_coords() : [null, event.x, event.y]; const { x: cx, y: cy } = AstalHyprland.get_default().get_cursor_position(); - let marginLeft = cx + ((width - pWidth) / 2 - x); - if (marginLeft < 0) marginLeft = 0; - else if (marginLeft + pWidth > mWidth) marginLeft = mWidth - pWidth; + let marginLeft = 0; + let marginTop = 0; + if (bar.vertical) { + marginLeft = cx + (width - x); + marginTop = cy + ((height - pHeight) / 2 - y); + if (marginTop < 0) marginTop = 0; + else if (marginTop + pHeight > mHeight) marginTop = mHeight - pHeight; + } else { + marginLeft = cx + ((width - pWidth) / 2 - x); + if (marginLeft < 0) marginLeft = 0; + else if (marginLeft + pWidth > mWidth) marginLeft = mWidth - pWidth; + marginTop = cy + (height - y); + } this.anchor = Astal.WindowAnchor.TOP | Astal.WindowAnchor.LEFT; this.exclusivity = Astal.Exclusivity.IGNORE; this.marginLeft = marginLeft; - this.marginTop = cy + (height - y); + this.marginTop = marginTop; this.show(); } |