[AGS] GTK 4 Migration: Done, Start adding QuickActions
Probably gonna abandon the QuickActions, as that is just way too much effort for what it does. Will be providing keybinds for doing what I wanted to do there in Hyprland
This commit is contained in:
@@ -1,14 +1,16 @@
|
||||
import { GLib, Variable } from "astal"
|
||||
import { Gtk } from "astal/gtk4"
|
||||
|
||||
const Time = ({ format = "%a, %e.%m %H:%M:%S" }) => {
|
||||
const time = Variable<string>("").poll(1000, () =>
|
||||
GLib.DateTime.new_now_local().format(format)!)
|
||||
|
||||
return <label
|
||||
className="Time"
|
||||
onDestroy={() => time.drop()}
|
||||
label={time()}
|
||||
/>
|
||||
return <menubutton cssClasses={["Time"]} hexpand halign={Gtk.Align.CENTER}>
|
||||
<label onDestroy={() => time.drop()} label={time()}></label>
|
||||
<popover>
|
||||
<Gtk.Calendar />
|
||||
</popover>
|
||||
</menubutton>
|
||||
}
|
||||
|
||||
const Calendar = () => {
|
||||
|
@@ -1,38 +1,62 @@
|
||||
|
||||
import AstalTray from "gi://AstalTray";
|
||||
import { bind, Variable } from "astal";
|
||||
import { bind, GObject } from "astal";
|
||||
import AstalHyprland from "gi://AstalHyprland";
|
||||
import { Gtk } from "astal/gtk4";
|
||||
|
||||
const SYNC = GObject.BindingFlags.SYNC_CREATE;
|
||||
|
||||
const SysTray = () => {
|
||||
const trayBox = new Gtk.Box();
|
||||
const tray = AstalTray.get_default();
|
||||
|
||||
return <box className="SysTray">
|
||||
{bind(tray, "items").as( items => items.map( item => (
|
||||
<button
|
||||
tooltipMarkup={bind(item, "tooltipMarkup")}
|
||||
usePopover={false}
|
||||
actionGroup={bind(item, "actionGroup").as(ag => ["dbusmenu", ag])}
|
||||
menuModel={bind(item, "menuModel")}>
|
||||
<icon gicon={bind(item, "gicon")} />
|
||||
</button>
|
||||
) ) ) }
|
||||
</box>
|
||||
const trayItems = new Map<string, Gtk.MenuButton>();
|
||||
const trayAddedHandler = tray.connect("item-added", (_, id) => {
|
||||
const item = tray.get_item(id);
|
||||
const popover = Gtk.PopoverMenu.new_from_model(item.menu_model);
|
||||
const icon = new Gtk.Image();
|
||||
const button = new Gtk.MenuButton({ popover, child: icon });
|
||||
|
||||
item.bind_property("gicon", icon, "gicon", SYNC);
|
||||
popover.insert_action_group("dbusmenu", item.action_group);
|
||||
item.connect("notify::action-group", () => {
|
||||
popover.insert_action_group("dbusmenu", item.action_group);
|
||||
});
|
||||
|
||||
trayItems.set(id, button);
|
||||
trayBox.append(button);
|
||||
})
|
||||
|
||||
const trayRemovedHandler = tray.connect("item-removed", (_, id) => {
|
||||
const button = trayItems.get(id);
|
||||
if (button) {
|
||||
trayBox.remove(button);
|
||||
button.run_dispose();
|
||||
trayItems.delete(id);
|
||||
}
|
||||
});
|
||||
|
||||
trayBox.connect("destroy", () => {
|
||||
tray.disconnect(trayAddedHandler);
|
||||
tray.disconnect(trayRemovedHandler);
|
||||
});
|
||||
|
||||
return trayBox;
|
||||
}
|
||||
|
||||
|
||||
const Workspace = () => {
|
||||
const hypr = AstalHyprland.get_default()
|
||||
|
||||
return <box className={"HyprlandWorkspaces"}>
|
||||
return <box cssClasses={["HyprlandWorkspaces"]}>
|
||||
{bind(hypr, "workspaces").as(wss => wss
|
||||
.filter(ws => !(ws.id >= -99 && ws.id <= -2)) // filter out special workspaces
|
||||
.sort((a, b) => a.id - b.id)
|
||||
.map(ws => (
|
||||
<button
|
||||
className={bind(hypr, "focusedWorkspace").as(fw =>
|
||||
ws === fw ? "HyprlandFocusedWorkspace" : "")}
|
||||
onClicked={() => ws.focus()}>
|
||||
{ws.id}
|
||||
cssClasses={bind(hypr, "focusedWorkspace").as(fw =>
|
||||
ws === fw ? ["HyprlandFocusedWorkspace"] : [""])}
|
||||
onButtonPressed={() => ws.focus()} child={<label label={String(ws.id)}></label>}>
|
||||
</button>
|
||||
))
|
||||
)}
|
||||
@@ -40,24 +64,88 @@ const Workspace = () => {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Displays the name of the currently active window and provides a popover for
|
||||
* displaying all available clients
|
||||
*/
|
||||
const ActiveWindow = () => {
|
||||
const hypr = AstalHyprland.get_default();
|
||||
const focused = bind( hypr, "focusedClient" );
|
||||
let visible = Variable( false );
|
||||
|
||||
const toggleOverlay = () => {
|
||||
visible.set( !visible.get() );
|
||||
const WindowPopover = (): Gtk.Popover => {
|
||||
// Set up boxes + Popover
|
||||
const clients = new Map<string, Gtk.Box>();
|
||||
const popover = new Gtk.Popover();
|
||||
const popoverBox = new Gtk.Box( { orientation: Gtk.Orientation.VERTICAL } );
|
||||
|
||||
const addClient = ( client: AstalHyprland.Client ) => {
|
||||
const clientBox = new Gtk.Box();
|
||||
|
||||
// Workspace description
|
||||
const descWS = new Gtk.Label( { label: '(WS ' } );
|
||||
|
||||
// Workpsace information
|
||||
const workspace = new Gtk.Label();
|
||||
client.workspace.bind_property( 'name', workspace, 'label', SYNC );
|
||||
|
||||
const windowClassDesc = new Gtk.Label( { label: ') [' } );
|
||||
|
||||
const windowClass = new Gtk.Label();
|
||||
windowClass.label = client.get_initial_class();
|
||||
|
||||
const titleDesc = new Gtk.Label( { label: '] ' } );
|
||||
titleDesc.set_margin_end( 2 );
|
||||
|
||||
const title = new Gtk.Label();
|
||||
client.bind_property( 'title', title, 'label', SYNC );
|
||||
|
||||
clientBox.append( descWS );
|
||||
clientBox.append( workspace );
|
||||
clientBox.append( windowClassDesc );
|
||||
clientBox.append( windowClass );
|
||||
clientBox.append( titleDesc );
|
||||
clientBox.append( title );
|
||||
|
||||
popoverBox.append( clientBox );
|
||||
|
||||
clients.set( client.get_address(), clientBox );
|
||||
}
|
||||
|
||||
// Populate with already added clients
|
||||
const c = hypr.get_clients();
|
||||
for ( let index = 0; index < c.length; index++ ) {
|
||||
addClient( c[ index ] );
|
||||
}
|
||||
|
||||
hypr.connect( 'client-added', ( _, client ) => {
|
||||
addClient( client );
|
||||
} );
|
||||
|
||||
hypr.connect( 'client-removed', ( _, client ) => {
|
||||
const c = clients.get( client );
|
||||
if ( c ) {
|
||||
popoverBox.remove( c );
|
||||
c.run_dispose();
|
||||
clients.delete( client );
|
||||
}
|
||||
} );
|
||||
|
||||
popover.set_child( popoverBox );
|
||||
return popover;
|
||||
}
|
||||
|
||||
const windowPopover = WindowPopover();
|
||||
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
// Return fully assembled HyprlandFocusedClient box
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
return <box cssName={"HyprlandFocusedClients"} visible={focused.as(Boolean)}>
|
||||
<Gtk.Button onClicked={toggleOverlay}>
|
||||
<button onClicked={() => windowPopover.popup()}>
|
||||
{focused.as( client => (
|
||||
client && <label label={bind( client, "title" ).as( String )} />
|
||||
))}
|
||||
</Gtk.Button>
|
||||
<eventbox visible={bind(visible).as( v => v )} name="popover-container">
|
||||
<label label="This is a test"></label>
|
||||
</eventbox>
|
||||
</button>
|
||||
{ windowPopover }
|
||||
</box>
|
||||
}
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
import { bind } from "astal";
|
||||
import AstalBattery from "gi://AstalBattery?version=0.1";
|
||||
import AstalBluetooth from "gi://AstalBluetooth?version=0.1";
|
||||
import AstalNetwork from "gi://AstalNetwork?version=0.1"
|
||||
import AstalWp from "gi://AstalWp?version=0.1";
|
||||
import AstalBattery from "gi://AstalBattery";
|
||||
import AstalBluetooth from "gi://AstalBluetooth";
|
||||
import AstalNetwork from "gi://AstalNetwork"
|
||||
import AstalWp from "gi://AstalWp";
|
||||
import Brightness from "../../util/brightness";
|
||||
import { Gtk } from "astal/gtk3";
|
||||
import { Gtk } from "astal/gtk4";
|
||||
|
||||
const QuickView = () => {
|
||||
return <box>
|
||||
|
@@ -18,7 +18,6 @@ const featureTest = () => {
|
||||
printerr( '[ SysInfo ] Feature Test for CPU info failed. mpstat from the sysstat package missing!' );
|
||||
}
|
||||
|
||||
// Screen brightness... CTL might be available, but no screen controllable
|
||||
// Battery... acpi might be present, but potentially no bat
|
||||
}
|
||||
|
||||
@@ -28,8 +27,6 @@ const availableFeatures = {
|
||||
cpu: true,
|
||||
ram: true,
|
||||
bat: true,
|
||||
net: false,
|
||||
brightness: true,
|
||||
}
|
||||
|
||||
const sysInfoFetcher = () => {
|
||||
@@ -44,17 +41,10 @@ const sysInfoFetcher = () => {
|
||||
const acpi = exec( `acpi -i | grep 'Battery'` );
|
||||
// TODO: Parse acpi output
|
||||
}
|
||||
// if ( availableFeatures.net ) {
|
||||
// // Using ifstat or vnstat probably, get current network de
|
||||
// }
|
||||
if ( availableFeatures.brightness ) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const SystemInfo = () => {
|
||||
|
||||
return <box></box>
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user