From 684dedeb1a527a74de31cb405168ad39ec802a51 Mon Sep 17 00:00:00 2001 From: Mora Unie Youer Date: Sun, 2 Mar 2025 14:16:48 +0300 Subject: feat: basic topbar features --- app.ts | 12 ++++-- style.scss | 48 ++++++++++++++++------ widget/Bar.tsx | 124 ++++++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 136 insertions(+), 48 deletions(-) diff --git a/app.ts b/app.ts index 7e8cc7c..b6bf451 100644 --- a/app.ts +++ b/app.ts @@ -2,9 +2,13 @@ import { App } from "astal/gtk4" import style from "./style.scss" import Bar from "./widget/Bar" +const windows = [ + Bar, +] + App.start({ - css: style, - main() { - App.get_monitors().map(Bar) - }, + css: style, + main() { + windows.forEach(window => App.get_monitors().map(window)) + }, }) diff --git a/style.scss b/style.scss index 1d0d3a9..08bcbbf 100644 --- a/style.scss +++ b/style.scss @@ -1,20 +1,42 @@ // https://gitlab.gnome.org/GNOME/gtk/-/blob/gtk-3-24/gtk/theme/Adwaita/_colors-public.scss -$fg-color: #{"@theme_fg_color"}; -$bg-color: #{"@theme_bg_color"}; +// $fg-color: #{"@theme_fg_color"}; +// $bg-color: #{"@theme_bg_color"}; window.Bar { - background: transparent; - color: $fg-color; - font-weight: bold; - - >centerbox { - background: $bg-color; - border-radius: 10px; - margin: 8px; + border: none; + box-shadow: none; + background-color: #000; + color: #fff; + + >box { + padding: 4px 0; + } +} + +box.Workspaces { + padding-left: 3px; + + >button { + min-width: 10px; + min-height: 10px; + border-radius: 5px; + + border: none; + margin: 2px 4px; + padding: 0; + background: #ccc; + + transition: min-width 2s ease-in-out; + // transition-property: min-width; + // transition-duration: 2s; + // transition-timing-function: ease-out; + + &.active { + min-width: 25px; } - button { - border-radius: 8px; - margin: 2px; + &.focused { + background: #AD49E1; } + } } diff --git a/widget/Bar.tsx b/widget/Bar.tsx index c2db8c5..02aa3ba 100644 --- a/widget/Bar.tsx +++ b/widget/Bar.tsx @@ -1,36 +1,98 @@ import { App, Astal, Gtk, Gdk } from "astal/gtk4" -import { Variable } from "astal" +import { exec, GLib, Variable } from "astal" + +type NiriWorkspace = { + id: number, + idx: number, + name: string | null, + output: string, + is_active: boolean, + is_focused: boolean, + active_window_id: number | null, +}; + +function getWorkspaces(): NiriWorkspace[] { + // NOTE: this works only in non-systemd environment on NixOS + // TODO: try to use Niri socket if it is documented + return JSON.parse(exec("niri msg -j workspaces")); +} + +function getWorkspacesByOutput(output: string): NiriWorkspace[] { + return getWorkspaces().filter(workspace => workspace.output == output).sort((a, b) => a.idx - b.idx); +} + +function focusWorkspace(idx: number) { + // NOTE: this works only in non-systemd environment on NixOS + // TODO: try to use Niri socket if it is documented + exec(`niri msg action focus-workspace ${idx}`); +} + +type WorkspaceButtonArguments = { + idx: number, + isActive: boolean, + isFocused: boolean, +}; + +function WorkspaceButton(args: WorkspaceButtonArguments) { + const classes: string[] = []; + args.isActive && classes.push("active"); + args.isFocused && classes.push("focused"); + return - - - - - + const { TOP, LEFT, RIGHT } = Astal.WindowAnchor + + return + + + + + + + + + + + + } -- cgit v1.2.3-70-g09d2