[Astal] Add mode indicator
This commit is contained in:
@@ -1,19 +1,30 @@
|
||||
import { App, Astal, Gdk, Gtk } from "astal/gtk4";
|
||||
import Hyprland from "./modules/Hyprland";
|
||||
import Calendar from "./modules/Calendar";
|
||||
import QuickView from "./modules/QuickView";
|
||||
import SystemInfo from "./modules/SystemInfo";
|
||||
import { CenterBox } from "astal/gtk4/widget";
|
||||
import {
|
||||
App, Astal, Gdk, Gtk
|
||||
} from 'astal/gtk4';
|
||||
import Calendar from './modules/Calendar';
|
||||
import {
|
||||
CenterBox
|
||||
} from 'astal/gtk4/widget';
|
||||
import Hyprland from './modules/Hyprland';
|
||||
import QuickView from './modules/QuickView';
|
||||
import SystemInfo from './modules/SystemInfo';
|
||||
|
||||
const Bar = ( { gdkmonitor, name }: { gdkmonitor: Gdk.Monitor, name: string } ) => {
|
||||
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor;
|
||||
const Bar = ( {
|
||||
gdkmonitor, name
|
||||
}: {
|
||||
'gdkmonitor': Gdk.Monitor,
|
||||
'name': string
|
||||
} ) => {
|
||||
const {
|
||||
TOP, LEFT, RIGHT
|
||||
} = Astal.WindowAnchor;
|
||||
|
||||
return (
|
||||
<window
|
||||
gdkmonitor={gdkmonitor}
|
||||
cssClasses={["Bar"]}
|
||||
cssClasses={[ 'Bar' ]}
|
||||
name={name}
|
||||
namespace={"bar"}
|
||||
namespace={'bar'}
|
||||
exclusivity={Astal.Exclusivity.EXCLUSIVE}
|
||||
anchor={TOP | LEFT | RIGHT}
|
||||
visible
|
||||
@@ -26,6 +37,7 @@ const Bar = ( { gdkmonitor, name }: { gdkmonitor: Gdk.Monitor, name: string } )
|
||||
hexpand
|
||||
halign={Gtk.Align.START}
|
||||
>
|
||||
<Hyprland.ModeStatus />
|
||||
<Calendar.Time />
|
||||
<SystemInfo.SystemInfo />
|
||||
<Hyprland.Workspace />
|
||||
@@ -36,7 +48,7 @@ const Bar = ( { gdkmonitor, name }: { gdkmonitor: Gdk.Monitor, name: string } )
|
||||
<box
|
||||
hexpand
|
||||
halign={Gtk.Align.END}
|
||||
cssClasses={["BarRight"]}
|
||||
cssClasses={[ 'BarRight' ]}
|
||||
>
|
||||
<Hyprland.SysTray />
|
||||
<QuickView.QuickView />
|
||||
@@ -48,21 +60,24 @@ const Bar = ( { gdkmonitor, name }: { gdkmonitor: Gdk.Monitor, name: string } )
|
||||
);
|
||||
};
|
||||
|
||||
const cliHandler = (args: string[]): string => {
|
||||
return "Not implemented";
|
||||
const cliHandler = ( args: string[] ): string => {
|
||||
console.debug( args );
|
||||
|
||||
return 'Not implemented';
|
||||
};
|
||||
|
||||
const BarLauncher = ( monitor: Gdk.Monitor ) => {
|
||||
const windowName = `bar-${monitor.get_connector()}`
|
||||
const windowName = `bar-${ monitor.get_connector() }`;
|
||||
|
||||
const createBar = () => {
|
||||
return <Bar gdkmonitor={monitor} name={windowName}></Bar>
|
||||
}
|
||||
return <Bar gdkmonitor={monitor} name={windowName}></Bar>;
|
||||
};
|
||||
|
||||
// Actually start the bar
|
||||
createBar();
|
||||
|
||||
return windowName;
|
||||
}
|
||||
};
|
||||
|
||||
export default {
|
||||
BarLauncher,
|
||||
|
||||
@@ -12,6 +12,14 @@ window.Bar {
|
||||
/* margin: 8px; */
|
||||
/* } */
|
||||
.mode-status {
|
||||
color: white;
|
||||
background-color: #00002dff;
|
||||
padding-left: 10px;
|
||||
padding-right: 10px;
|
||||
margin-left: 5px;
|
||||
border-radius: 20px;
|
||||
font-family: $monospace-font;
|
||||
|
||||
&.windowing-mode {
|
||||
background-color: darkslategray;
|
||||
color: white;
|
||||
@@ -85,6 +93,7 @@ window.Bar {
|
||||
.time {
|
||||
min-width: 11rem;
|
||||
padding: 3px;
|
||||
|
||||
& button {
|
||||
box-shadow: none;
|
||||
padding: 0;
|
||||
|
||||
@@ -1,50 +1,59 @@
|
||||
import AstalTray from "gi://AstalTray";
|
||||
import { bind, GObject } from "astal";
|
||||
import AstalHyprland from "gi://AstalHyprland";
|
||||
import { Gtk } from "astal/gtk4";
|
||||
import Pango from "gi://Pango?version=1.0";
|
||||
import {
|
||||
GObject, bind,
|
||||
exec,
|
||||
readFile
|
||||
} from 'astal';
|
||||
import AstalHyprland from 'gi://AstalHyprland';
|
||||
import AstalTray from 'gi://AstalTray';
|
||||
import {
|
||||
Gtk
|
||||
} from 'astal/gtk4';
|
||||
import Pango from 'gi://Pango?version=1.0';
|
||||
|
||||
const hypr = AstalHyprland.get_default();
|
||||
const SYNC = GObject.BindingFlags.SYNC_CREATE;
|
||||
|
||||
const SysTray = () => {
|
||||
const trayBox = new Gtk.Box({ cssClasses: ["bar-button"] });
|
||||
const trayBox = new Gtk.Box( {
|
||||
'cssClasses': [ 'bar-button' ]
|
||||
} );
|
||||
const tray = AstalTray.get_default();
|
||||
|
||||
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 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({
|
||||
const button = new Gtk.MenuButton( {
|
||||
popover,
|
||||
child: icon,
|
||||
cssClasses: ["tray-item"],
|
||||
});
|
||||
'child': icon,
|
||||
'cssClasses': [ 'tray-item' ],
|
||||
} );
|
||||
|
||||
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);
|
||||
});
|
||||
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);
|
||||
});
|
||||
trayItems.set( id, button );
|
||||
trayBox.append( button );
|
||||
} );
|
||||
const trayRemovedHandler = tray.connect( 'item-removed', ( _, id ) => {
|
||||
const button = trayItems.get( id );
|
||||
|
||||
const trayRemovedHandler = tray.connect("item-removed", (_, id) => {
|
||||
const button = trayItems.get(id);
|
||||
if (button) {
|
||||
trayBox.remove(button);
|
||||
if ( button ) {
|
||||
trayBox.remove( button );
|
||||
button.run_dispose();
|
||||
trayItems.delete(id);
|
||||
trayItems.delete( id );
|
||||
}
|
||||
});
|
||||
} );
|
||||
|
||||
trayBox.connect("destroy", () => {
|
||||
tray.disconnect(trayAddedHandler);
|
||||
tray.disconnect(trayRemovedHandler);
|
||||
});
|
||||
trayBox.connect( 'destroy', () => {
|
||||
tray.disconnect( trayAddedHandler );
|
||||
tray.disconnect( trayRemovedHandler );
|
||||
} );
|
||||
|
||||
return trayBox;
|
||||
};
|
||||
@@ -52,25 +61,21 @@ const SysTray = () => {
|
||||
const Workspace = () => {
|
||||
return (
|
||||
<box>
|
||||
{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 => (
|
||||
{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
|
||||
cssClasses={bind(hypr, "focusedWorkspace").as(fw =>
|
||||
ws === fw
|
||||
cssClasses={bind( hypr, 'focusedWorkspace' ).as( fw => ws === fw
|
||||
? [
|
||||
"focused-workspace-button",
|
||||
"workspace-button",
|
||||
'focused-workspace-button',
|
||||
'workspace-button',
|
||||
]
|
||||
: ["workspace-button"],
|
||||
)}
|
||||
: [ 'workspace-button' ], )}
|
||||
onButtonPressed={() => ws.focus()}
|
||||
child={<label label={String(ws.id)}></label>}
|
||||
child={<label label={String( ws.id )}></label>}
|
||||
></button>
|
||||
)),
|
||||
)}
|
||||
) ), )}
|
||||
</box>
|
||||
);
|
||||
};
|
||||
@@ -80,15 +85,15 @@ const Workspace = () => {
|
||||
* displaying all available clients
|
||||
*/
|
||||
const ActiveWindow = () => {
|
||||
const focused = bind(hypr, "focusedClient");
|
||||
const focused = bind( hypr, 'focusedClient' );
|
||||
|
||||
const WindowPopover = (): Gtk.Popover => {
|
||||
// Set up boxes + Popover
|
||||
const popover = new Gtk.Popover();
|
||||
|
||||
const popoverBox = WindowPopoverBox();
|
||||
|
||||
popover.set_child(popoverBox);
|
||||
popover.set_child( popoverBox );
|
||||
|
||||
return popover;
|
||||
};
|
||||
|
||||
@@ -98,65 +103,88 @@ const ActiveWindow = () => {
|
||||
// Return fully assembled HyprlandFocusedClient box
|
||||
// ───────────────────────────────────────────────────────────────────
|
||||
return (
|
||||
<box visible={focused.as(Boolean)}>
|
||||
<box visible={focused.as( Boolean )}>
|
||||
<button
|
||||
onClicked={() => windowPopover.popup()}
|
||||
cssClasses={["bar-button"]}
|
||||
cssClasses={[ 'bar-button' ]}
|
||||
child={
|
||||
focused.as(
|
||||
client =>
|
||||
client && (
|
||||
focused.as( client => client && (
|
||||
<label
|
||||
maxWidthChars={70}
|
||||
ellipsize={Pango.EllipsizeMode.END}
|
||||
label={bind(client, "title").as(String)} />
|
||||
),
|
||||
)
|
||||
label={bind( client, 'title' ).as( String )} />
|
||||
), )
|
||||
}></button>
|
||||
{windowPopover}
|
||||
</box >
|
||||
);
|
||||
};
|
||||
|
||||
type submaps = 'device' | 'launch' | 'workspace' | 'windowing' | 'screenshotting' | 'notifications' | '';
|
||||
|
||||
const ModeStatus = () => {
|
||||
const label = new Gtk.Label();
|
||||
const map = {
|
||||
"device": "D",
|
||||
"launch": "L",
|
||||
"workspace": "W",
|
||||
"windowing": "M",
|
||||
"screenshotting": "S",
|
||||
"notifications": "N",
|
||||
let isUsingHyprmode = false;
|
||||
|
||||
try {
|
||||
const path = exec( 'bash -c "cd ~ && pwd"' ) + '/.config/hyprmode';
|
||||
|
||||
isUsingHyprmode = readFile( path ).trim() === 'y';
|
||||
} catch ( e ) {
|
||||
printerr( 'Failed to read hyprmode config', e );
|
||||
}
|
||||
|
||||
const label = new Gtk.Label();
|
||||
|
||||
if ( !isUsingHyprmode ) return label;
|
||||
|
||||
print( '==> Using hyprmode config' );
|
||||
|
||||
const map = {
|
||||
'device': 'D',
|
||||
'launch': 'L',
|
||||
'workspace': 'W',
|
||||
'windowing': 'M',
|
||||
'screenshotting': 'S',
|
||||
'notifications': 'N',
|
||||
'': 'N'
|
||||
};
|
||||
|
||||
label.label = 'N';
|
||||
label.cssClasses = [ 'mode-status' ];
|
||||
|
||||
// TODO: Possibly add popover to it that lists binds
|
||||
hypr.connect("submap", (name: string) => {
|
||||
hypr.connect( 'submap', ( _, name: submaps ) => {
|
||||
label.label = map[name];
|
||||
label.cssClasses = ["mode-status", name + '-mode']
|
||||
})
|
||||
return
|
||||
}
|
||||
label.cssClasses = [
|
||||
'mode-status',
|
||||
name + '-mode'
|
||||
];
|
||||
} );
|
||||
|
||||
return label;
|
||||
};
|
||||
|
||||
const WindowPopoverBox = () => {
|
||||
return <box vertical>
|
||||
<label label={"Available Windows"} cssClasses={['title-2']}></label>
|
||||
<label label={'Available Windows'} cssClasses={[ 'title-2' ]}></label>
|
||||
<Gtk.Separator marginTop={5} marginBottom={5}></Gtk.Separator>
|
||||
<box vertical>
|
||||
{bind(hypr, 'clients').as(clients => {
|
||||
return clients.map(client => {
|
||||
{bind( hypr, 'clients' ).as( clients => {
|
||||
return clients.map( client => {
|
||||
return <button child={
|
||||
<box>
|
||||
<label label={bind(client, 'workspace').as(w => `(WS ${w.name})`)}></label>
|
||||
<label label={bind(client, 'initialClass').as(c => `[${c}]`)}></label>
|
||||
<label label={bind(client, 'title')}></label>
|
||||
<label label={bind( client, 'workspace' ).as( w => `(WS ${ w.name })` )}></label>
|
||||
<label label={bind( client, 'initialClass' ).as( c => `[${ c }]` )}></label>
|
||||
<label label={bind( client, 'title' )}></label>
|
||||
</box>
|
||||
}
|
||||
onClicked={() => client.focus()}
|
||||
></button>
|
||||
})
|
||||
})}
|
||||
></button>;
|
||||
} );
|
||||
} )}
|
||||
</box>
|
||||
</box>
|
||||
}
|
||||
</box>;
|
||||
};
|
||||
|
||||
export default {
|
||||
Workspace,
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
import { bind } from "astal";
|
||||
import { execAsync } from "astal";
|
||||
import AstalBattery from "gi://AstalBattery";
|
||||
import AstalBluetooth from "gi://AstalBluetooth";
|
||||
import AstalNetwork from "gi://AstalNetwork";
|
||||
import AstalWp from "gi://AstalWp";
|
||||
import { Gtk } from "astal/gtk4";
|
||||
import Brightness from "../../../util/brightness";
|
||||
import QuickActions from "../../QuickActions/QuickActions";
|
||||
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/gtk4';
|
||||
import QuickActions from '../../QuickActions/QuickActions';
|
||||
import {
|
||||
bind
|
||||
} from 'astal';
|
||||
import {
|
||||
execAsync
|
||||
} from 'astal';
|
||||
|
||||
const STATE = AstalNetwork.DeviceState;
|
||||
|
||||
const QuickView = () => {
|
||||
const qa = QuickActions.QuickActions();
|
||||
|
||||
const showQuickActions = () => {
|
||||
qa.popup();
|
||||
};
|
||||
@@ -19,14 +26,14 @@ const QuickView = () => {
|
||||
return (
|
||||
<button
|
||||
onClicked={() => showQuickActions()}
|
||||
cssClasses={["quick-action-button"]}
|
||||
cssClasses={[ 'quick-action-button' ]}
|
||||
child={
|
||||
<box>
|
||||
<BatteryWidget></BatteryWidget>
|
||||
<Audio></Audio>
|
||||
<BluetoothWidget></BluetoothWidget>
|
||||
<NetworkWidget></NetworkWidget>
|
||||
<image iconName={"system-shutdown-symbolic"}></image>
|
||||
<image iconName={'system-shutdown-symbolic'}></image>
|
||||
{qa}
|
||||
</box>
|
||||
}
|
||||
@@ -40,37 +47,39 @@ const NetworkWidget = () => {
|
||||
return (
|
||||
<box>
|
||||
<image
|
||||
iconName={bind(network, "state").as(state => {
|
||||
if (state === AstalNetwork.State.CONNECTING) {
|
||||
return "chronometer-reset-symbolic";
|
||||
iconName={bind( network, 'state' ).as( state => {
|
||||
if ( state === AstalNetwork.State.CONNECTING ) {
|
||||
return 'chronometer-reset-symbolic';
|
||||
} else if (
|
||||
state === AstalNetwork.State.CONNECTED_LOCAL ||
|
||||
state === AstalNetwork.State.CONNECTED_SITE ||
|
||||
state === AstalNetwork.State.CONNECTED_GLOBAL
|
||||
state === AstalNetwork.State.CONNECTED_LOCAL
|
||||
|| state === AstalNetwork.State.CONNECTED_SITE
|
||||
|| state === AstalNetwork.State.CONNECTED_GLOBAL
|
||||
) {
|
||||
return "network-wired-activated-symbolic";
|
||||
return 'network-wired-activated-symbolic';
|
||||
} else {
|
||||
return "paint-unknown-symbolic";
|
||||
return 'paint-unknown-symbolic';
|
||||
}
|
||||
})}
|
||||
cssClasses={["network-widget", "quick-view-symbol"]}
|
||||
visible={bind(network.wifi, "state").as(
|
||||
state => state !== STATE.ACTIVATED,
|
||||
)}
|
||||
} )}
|
||||
cssClasses={[
|
||||
'network-widget',
|
||||
'quick-view-symbol'
|
||||
]}
|
||||
visible={bind( network.wifi, 'state' ).as( state => state !== STATE.ACTIVATED, )}
|
||||
></image>
|
||||
<image
|
||||
iconName={bind(network.wifi, "state").as(state => {
|
||||
if (state === STATE.ACTIVATED) {
|
||||
iconName={bind( network.wifi, 'state' ).as( state => {
|
||||
if ( state === STATE.ACTIVATED ) {
|
||||
return network.wifi.iconName;
|
||||
} else {
|
||||
return "";
|
||||
return '';
|
||||
}
|
||||
})}
|
||||
tooltipText={bind(network.wifi, 'ssid')}
|
||||
cssClasses={["network-widget", "quick-view-symbol"]}
|
||||
visible={bind(network.wifi, "state").as(
|
||||
state => state === STATE.ACTIVATED,
|
||||
)}
|
||||
} )}
|
||||
tooltipText={bind( network.wifi, 'ssid' )}
|
||||
cssClasses={[
|
||||
'network-widget',
|
||||
'quick-view-symbol'
|
||||
]}
|
||||
visible={bind( network.wifi, 'state' ).as( state => state === STATE.ACTIVATED, )}
|
||||
></image>
|
||||
</box>
|
||||
);
|
||||
@@ -78,44 +87,40 @@ const NetworkWidget = () => {
|
||||
|
||||
const BluetoothWidget = () => {
|
||||
const bluetooth = AstalBluetooth.get_default();
|
||||
const enabled = bind(bluetooth, "isPowered");
|
||||
const connected = bind(bluetooth, "isConnected");
|
||||
const enabled = bind( bluetooth, 'isPowered' );
|
||||
const connected = bind( bluetooth, 'isConnected' );
|
||||
|
||||
// For each connected BT device, render status
|
||||
return (
|
||||
<box>
|
||||
<box visible={enabled.as(e => e)}>
|
||||
<box visible={enabled.as( e => e )}>
|
||||
<image
|
||||
iconName={"bluetooth-active-symbolic"}
|
||||
visible={connected.as(c => c)}
|
||||
iconName={'bluetooth-active-symbolic'}
|
||||
visible={connected.as( c => c )}
|
||||
></image>
|
||||
<image
|
||||
iconName={"bluetooth-disconnected-symbolic"}
|
||||
visible={connected.as(c => !c)}
|
||||
iconName={'bluetooth-disconnected-symbolic'}
|
||||
visible={connected.as( c => !c )}
|
||||
></image>
|
||||
</box>
|
||||
<image
|
||||
iconName={"bluetooth-disabled-symbolic"}
|
||||
visible={enabled.as(e => !e)}
|
||||
iconName={'bluetooth-disabled-symbolic'}
|
||||
visible={enabled.as( e => !e )}
|
||||
></image>
|
||||
<box>
|
||||
{bind(bluetooth, "devices").as(devices => {
|
||||
return devices.map(device => {
|
||||
{bind( bluetooth, 'devices' ).as( devices => {
|
||||
return devices.map( device => {
|
||||
return (
|
||||
<image
|
||||
iconName={bind(device, "icon").as(
|
||||
icon => icon,
|
||||
)}
|
||||
visible={bind(device, "connected")}
|
||||
tooltipText={bind(device, "batteryPercentage").as(
|
||||
n => {
|
||||
return device.get_name() + ': ' + n + "%";
|
||||
},
|
||||
)}
|
||||
iconName={bind( device, 'icon' ).as( icon => icon, )}
|
||||
visible={bind( device, 'connected' )}
|
||||
tooltipText={bind( device, 'batteryPercentage' ).as( n => {
|
||||
return device.get_name() + ': ' + n + '%';
|
||||
}, )}
|
||||
></image>
|
||||
);
|
||||
});
|
||||
})}
|
||||
} );
|
||||
} )}
|
||||
</box>
|
||||
</box>
|
||||
);
|
||||
@@ -123,21 +128,25 @@ const BluetoothWidget = () => {
|
||||
|
||||
|
||||
let hasSentNotification = false;
|
||||
|
||||
const BatteryWidget = () => {
|
||||
const battery = AstalBattery.get_default();
|
||||
if (battery.get_is_present()) {
|
||||
|
||||
if ( battery.get_is_present() ) {
|
||||
return (
|
||||
<image
|
||||
iconName={bind(battery, "batteryIconName").as(icon => icon)}
|
||||
cssClasses={["quick-view-symbol"]}
|
||||
tooltipText={bind(battery, 'percentage').as(p => {
|
||||
const level = Math.round(p * 100)
|
||||
iconName={bind( battery, 'batteryIconName' ).as( icon => icon )}
|
||||
cssClasses={[ 'quick-view-symbol' ]}
|
||||
tooltipText={bind( battery, 'percentage' ).as( p => {
|
||||
const level = Math.round( p * 100 );
|
||||
|
||||
if ( level < 20 && !hasSentNotification ) {
|
||||
hasSentNotification = true;
|
||||
execAsync( 'bash -c "notify-send \'Battery level below 20%\'"' );
|
||||
}
|
||||
return `Battery Level: ${level}%`
|
||||
})}
|
||||
|
||||
return `Battery Level: ${ level }%`;
|
||||
} )}
|
||||
></image>
|
||||
);
|
||||
} else {
|
||||
@@ -148,14 +157,14 @@ const BatteryWidget = () => {
|
||||
|
||||
const BrightnessWidget = () => {
|
||||
const brightness = Brightness.get_default();
|
||||
const screen_brightness = bind(brightness, "screen");
|
||||
const screen_brightness = bind( brightness, 'screen' );
|
||||
|
||||
return (
|
||||
<box cssClasses={["quick-view-symbol"]}>
|
||||
<image iconName={"brightness-high-symbolic"}></image>
|
||||
<box cssClasses={[ 'quick-view-symbol' ]}>
|
||||
<image iconName={'brightness-high-symbolic'}></image>
|
||||
<label
|
||||
label={screen_brightness.as(b => '' + Math.round(100 * b))}
|
||||
visible={bind(brightness, "screenAvailable")}
|
||||
label={screen_brightness.as( b => '' + Math.round( 100 * b ) )}
|
||||
visible={bind( brightness, 'screenAvailable' )}
|
||||
></label>
|
||||
</box>
|
||||
);
|
||||
@@ -163,31 +172,27 @@ const BrightnessWidget = () => {
|
||||
|
||||
const Audio = () => {
|
||||
const wireplumber = AstalWp.get_default();
|
||||
if (wireplumber) {
|
||||
|
||||
if ( wireplumber ) {
|
||||
return (
|
||||
<box orientation={Gtk.Orientation.HORIZONTAL}>
|
||||
<image
|
||||
iconName={bind(wireplumber.defaultSpeaker, "volumeIcon").as(
|
||||
icon => icon,
|
||||
)}
|
||||
cssClasses={["quick-view-symbol"]}
|
||||
tooltipText={bind(wireplumber.defaultSpeaker, 'volume').as(v => Math.round(100 * v) + '%')}
|
||||
iconName={bind( wireplumber.defaultSpeaker, 'volumeIcon' ).as( icon => icon, )}
|
||||
cssClasses={[ 'quick-view-symbol' ]}
|
||||
tooltipText={bind( wireplumber.defaultSpeaker, 'volume' ).as( v => Math.round( 100 * v ) + '%' )}
|
||||
></image>
|
||||
<image
|
||||
iconName={bind(
|
||||
wireplumber.defaultMicrophone,
|
||||
"volumeIcon",
|
||||
).as(icon => icon)}
|
||||
cssClasses={["quick-view-symbol"]}
|
||||
tooltipText={bind(wireplumber.defaultMicrophone, 'volume').as(v => Math.round(100 * v) + '%')}
|
||||
iconName={bind( wireplumber.defaultMicrophone,
|
||||
'volumeIcon', ).as( icon => icon )}
|
||||
cssClasses={[ 'quick-view-symbol' ]}
|
||||
tooltipText={bind( wireplumber.defaultMicrophone, 'volume' ).as( v => Math.round( 100 * v ) + '%' )}
|
||||
></image>
|
||||
</box>
|
||||
);
|
||||
} else {
|
||||
print(
|
||||
"[ WirePlumber ] Could not connect, Audio support in bar will be missing",
|
||||
);
|
||||
return <image iconName={"action-unavailable-symbolic"}></image>;
|
||||
print( '[ WirePlumber ] Could not connect, Audio support in bar will be missing', );
|
||||
|
||||
return <image iconName={'action-unavailable-symbolic'}></image>;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -195,4 +200,5 @@ const Audio = () => {
|
||||
|
||||
export default {
|
||||
QuickView,
|
||||
BrightnessWidget
|
||||
};
|
||||
|
||||
@@ -1,35 +1,39 @@
|
||||
import { execAsync } from "astal";
|
||||
import { Gtk } from "astal/gtk4";
|
||||
import sysinfo from "../sysinfo";
|
||||
import {
|
||||
Gtk
|
||||
} from 'astal/gtk4';
|
||||
import {
|
||||
execAsync
|
||||
} from 'astal';
|
||||
import sysinfo from '../sysinfo';
|
||||
|
||||
const info = () => {
|
||||
return (
|
||||
<box vertical>
|
||||
<label
|
||||
label={"System Information"}
|
||||
cssClasses={["title-2"]}
|
||||
label={'System Information'}
|
||||
cssClasses={[ 'title-2' ]}
|
||||
></label>
|
||||
<Gtk.Separator marginTop={5} marginBottom={10}></Gtk.Separator>
|
||||
<label
|
||||
vexpand
|
||||
halign={Gtk.Align.START}
|
||||
hexpand
|
||||
label={sysinfo.ramUsed(used => {
|
||||
return "RAM: " + used + ` (${sysinfo.ramUtil.get()}%)`;
|
||||
})}
|
||||
label={sysinfo.ramUsed( used => {
|
||||
return 'RAM: ' + used + ` (${ sysinfo.ramUtil.get() }%)`;
|
||||
} )}
|
||||
></label>
|
||||
<label
|
||||
label={sysinfo.systemStats(stats => {
|
||||
return `CPU: ${stats.cpuTemp}, ${stats.cpuClk}
|
||||
GPU: ${stats.gpuTemp}, ${stats.gpuClk} (${stats.vram} / ${stats.availableVRAM})
|
||||
Kernel: ${stats.kernel}`;
|
||||
})}
|
||||
label={sysinfo.systemStats( stats => {
|
||||
return `CPU: ${ stats.cpuTemp }, ${ stats.cpuClk }
|
||||
GPU: ${ stats.gpuTemp }, ${ stats.gpuClk } (${ stats.vram } / ${ stats.availableVRAM })
|
||||
Kernel: ${ stats.kernel }`;
|
||||
} )}
|
||||
></label>
|
||||
<Gtk.Separator marginTop={10}></Gtk.Separator>
|
||||
<button
|
||||
onClicked={() => execAsync(`/bin/sh -c "kitty --hold fish -c 'fastfetch'"`)}
|
||||
onClicked={() => execAsync( '/bin/sh -c "kitty --hold fish -c \'fastfetch\'"' )}
|
||||
child={
|
||||
<label label={"View FastFetch"}></label>
|
||||
<label label={'View FastFetch'}></label>
|
||||
}></button>
|
||||
</box>
|
||||
);
|
||||
@@ -38,7 +42,7 @@ Kernel: ${stats.kernel}`;
|
||||
const SystemInformationPanel = () => {
|
||||
const popover = new Gtk.Popover();
|
||||
|
||||
popover.set_child(info());
|
||||
popover.set_child( info() );
|
||||
|
||||
return popover;
|
||||
};
|
||||
@@ -54,44 +58,44 @@ const SystemInfo = () => {
|
||||
sysinfo.refreshStats();
|
||||
};
|
||||
|
||||
if (sysinfo.enabled) {
|
||||
if ( sysinfo.enabled ) {
|
||||
return (
|
||||
<button
|
||||
onClicked={() => openSysInfo()}
|
||||
child={
|
||||
<box tooltipText={sysinfo.ramUsed(v => v)}>
|
||||
<box tooltipText={sysinfo.ramUsed( v => v )}>
|
||||
<box
|
||||
cssClasses={[ 'quick-view-symbol' ]}
|
||||
>
|
||||
<image
|
||||
iconName={"power-profile-performance-symbolic"}
|
||||
iconName={'power-profile-performance-symbolic'}
|
||||
marginEnd={1}
|
||||
></image>
|
||||
<label
|
||||
label={sysinfo.cpuUtil(util => util)}
|
||||
label={sysinfo.cpuUtil( util => util )}
|
||||
marginEnd={5}
|
||||
></label>
|
||||
</box>
|
||||
<box
|
||||
cssClasses={[ 'quick-view-symbol' ]}
|
||||
>
|
||||
<image iconName={"memory"}></image>
|
||||
<label label={sysinfo.ramUtil(util => util)}></label>
|
||||
<image iconName={'memory'}></image>
|
||||
<label label={sysinfo.ramUtil( util => util )}></label>
|
||||
</box>
|
||||
<box
|
||||
cssClasses={[ 'quick-view-symbol' ]}
|
||||
>
|
||||
<image iconName={"show-gpu-effects-symbolic"}></image>
|
||||
<label label={sysinfo.gpuUtil(util => util)}></label>
|
||||
<image iconName={'show-gpu-effects-symbolic'}></image>
|
||||
<label label={sysinfo.gpuUtil( util => util )}></label>
|
||||
</box>
|
||||
{panel}
|
||||
</box>
|
||||
}
|
||||
cssClasses={["bar-button"]}
|
||||
cssClasses={[ 'bar-button' ]}
|
||||
></button>
|
||||
);
|
||||
} else {
|
||||
return <image iconName={"action-unavailable-symbolic"}></image>;
|
||||
return <image iconName={'action-unavailable-symbolic'}></image>;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,3 +3,4 @@ $bg-color: #0A0A0F;
|
||||
$accent-color: #591641;
|
||||
$accent-color-2: #97103A;
|
||||
$shadow-color: rgba(0, 0, 2, 0.3);
|
||||
$monospace-font: Source Code Pro
|
||||
|
||||
Reference in New Issue
Block a user