[AGS] Redo basic setup
This commit is contained in:
		
							
								
								
									
										23
									
								
								config/astal/components/bar/ui/Bar.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								config/astal/components/bar/ui/Bar.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,23 @@ | ||||
| import { createQuickActionsMenu } from "./QuickActions"; | ||||
| import { GLib } from "astal"; | ||||
| import { Astal, Gdk, Gtk } from "astal/gtk3"; | ||||
|  | ||||
| const Bar = (gdkmonitor: Gdk.Monitor) => { | ||||
|  | ||||
|     return ( | ||||
|         <window gdkmonitor={gdkmonitor} | ||||
|             cssClasses={["Bar"]}> | ||||
|             <box orientation={Gtk.Orientation.HORIZONTAL} spacing={10}> | ||||
|                 <box> | ||||
|                 </box> | ||||
|                 <label>{windowTitle}</label> | ||||
|                 <box> | ||||
|                     <tray /> | ||||
|                     <button icon="quickaction" menu={quickActionMenu} /> | ||||
|                 </box> | ||||
|             </box> | ||||
|         </window> | ||||
|     ); | ||||
| } | ||||
|  | ||||
| export default Bar; | ||||
							
								
								
									
										76
									
								
								config/astal/components/bar/ui/QuickActions.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								config/astal/components/bar/ui/QuickActions.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| import Gtk from "gi://Gtk"; | ||||
| import AstalNetwork from "gi://AstalNetwork"; | ||||
| import AstalBluetooth from "gi://AstalBluetooth"; | ||||
| import { exec } from "gi://GLib"; | ||||
|  | ||||
| let quickActionsMenu; | ||||
|  | ||||
| // Toggle WiFi connection | ||||
| function toggleWiFi() { | ||||
|     const network = AstalNetwork.get_default(); | ||||
|     const wifi = network.get_wifi()!; | ||||
|     const state = wifi.get_state(); | ||||
|  | ||||
|     if (state === AstalNetwork.WifiState.DISCONNECTED) { | ||||
|         wifi.connect(); | ||||
|     } else { | ||||
|         wifi.disconnect(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| // Toggle Bluetooth power state | ||||
| function toggleBluetooth() { | ||||
|     const bluetooth = AstalBluetooth.get_default(); | ||||
|     const adapter = bluetooth.get_adapter(); | ||||
|     const powered = adapter?.get_powered(); | ||||
|  | ||||
|     adapter?.set_powered(!powered); | ||||
| } | ||||
|  | ||||
| // Adjust volume or microphone (opens pavucontrol) | ||||
| function adjustVolume() { | ||||
|     exec("pavucontrol"); | ||||
| } | ||||
|  | ||||
| function adjustMic() { | ||||
|     exec("pavucontrol"); | ||||
| } | ||||
|  | ||||
| // Power menu | ||||
| function showPowerMenu() { | ||||
|     exec("power-menu"); | ||||
| } | ||||
|  | ||||
| // Show WiFi network picker | ||||
| function pickWiFi() { | ||||
|     const wifi = AstalNetwork.get_default().get_wifi(); | ||||
|     wifi.show_picker(); | ||||
| } | ||||
|  | ||||
| // Show Bluetooth device picker | ||||
| function pickBluetooth() { | ||||
|     const bluetooth = AstalBluetooth.get_default(); | ||||
|     bluetooth.show_picker(); | ||||
| } | ||||
|  | ||||
| // Create menu using JSX | ||||
| function createQuickActionsMenu() { | ||||
|     quickActionsMenu = ( | ||||
|         <menu> | ||||
|             <item label="📶 WiFi" onActivate={toggleWiFi} /> | ||||
|             <item label="→ Pick Network" onActivate={pickWiFi} /> | ||||
|  | ||||
|             <item label="🔵 Bluetooth" onActivate={toggleBluetooth} /> | ||||
|             <item label="→ Pick Device" onActivate={pickBluetooth} /> | ||||
|  | ||||
|             <item label="🔊 Volume" onActivate={adjustVolume} /> | ||||
|             <item label="🎙️ Microphone" onActivate={adjustMic} /> | ||||
|             <item label="🔌 Power" onActivate={showPowerMenu} /> | ||||
|         </menu> | ||||
|     ); | ||||
|  | ||||
|     return quickActionsMenu; | ||||
| } | ||||
|  | ||||
| // Export the function | ||||
| export { createQuickActionsMenu }; | ||||
							
								
								
									
										0
									
								
								config/astal/components/bar/ui/modules/Calendar.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								config/astal/components/bar/ui/modules/Calendar.tsx
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										57
									
								
								config/astal/components/bar/ui/modules/Hyprland.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								config/astal/components/bar/ui/modules/Hyprland.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| import AstalTray from "gi://AstalTray"; | ||||
| import { bind } from "astal"; | ||||
| import AstalHyprland from "gi://AstalHyprland"; | ||||
|  | ||||
| const SysTray = () => { | ||||
|     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 HyprlandWorkspace = () => { | ||||
|     const hypr = AstalHyprland.get_default() | ||||
|  | ||||
|     return <box className={"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} | ||||
|                 </button> | ||||
|             )) | ||||
|         )} | ||||
|     </box> | ||||
| } | ||||
|  | ||||
|  | ||||
| const HyprlandActiveWindow = () => { | ||||
|     const hypr = AstalHyprland.get_default(); | ||||
|     const focused = bind( hypr, "focusedClient" ); | ||||
|  | ||||
|     return <box className={"HyprlandFocusedClients"} visible={focused.as(Boolean)}> | ||||
|         {focused.as( client => ( | ||||
|             client && <label label={bind( client, "title" ).as( String )} /> | ||||
|         ))} | ||||
|     </box> | ||||
| } | ||||
|  | ||||
| export default { | ||||
|     HyprlandWorkspace,  | ||||
|     HyprlandActiveWindow, | ||||
|     SysTray | ||||
| } | ||||
							
								
								
									
										37
									
								
								config/astal/components/bar/ui/quickactions.scss
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								config/astal/components/bar/ui/quickactions.scss
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| @import "colors"; | ||||
|  | ||||
| .toggle-row { | ||||
|   background-color: $bg; | ||||
|   border-radius: 12px; | ||||
|   margin: 6px 0; | ||||
|   overflow: hidden; | ||||
|   border: 1px solid $border; | ||||
|  | ||||
|   button { | ||||
|     padding: 10px 16px; | ||||
|     font-size: 14px; | ||||
|     transition: background 0.2s ease; | ||||
|     border: none; | ||||
|     background: transparent; | ||||
|  | ||||
|     &:hover { | ||||
|       background-color: $hover; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .toggle { | ||||
|     flex: 1; | ||||
|     background-color: transparent; | ||||
|     text-align: left; | ||||
|     &.active { | ||||
|       background-color: $accent; | ||||
|       color: white; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   .arrow { | ||||
|     width: 40px; | ||||
|     background-color: transparent; | ||||
|     text-align: center; | ||||
|   } | ||||
| } | ||||
							
								
								
									
										68
									
								
								config/astal/components/bar/util/hyprland.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								config/astal/components/bar/util/hyprland.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | ||||
| import AstalHyprland from "gi://AstalHyprland"; | ||||
|  | ||||
| const getAvailableWorkspaces = (): number[] => { | ||||
|     const workspaces: number[] = []; | ||||
|     AstalHyprland.get_default().get_workspaces().forEach( val => { | ||||
|         workspaces.push( val.get_id() ); | ||||
|     } ) | ||||
|     return workspaces; | ||||
| } | ||||
|  | ||||
| const getCurrentWorkspaceID = (): number => { | ||||
|     return AstalHyprland.get_default().get_focused_workspace().get_id(); | ||||
| } | ||||
|  | ||||
| const getCurrentWindowTitle = (): string => { | ||||
|     return AstalHyprland.get_default().get_focused_client().get_title(); | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Get the workspace ID of a window by its address | ||||
|  * @param address - The address of the window | ||||
|  * @returns The workspace ID | ||||
|  */ | ||||
| const getWorkspaceIDOfWindowByAddress = ( address: string ): number => { | ||||
|     AstalHyprland.get_default().get_clients().forEach( client => { | ||||
|         if ( client.get_address() === address ) { | ||||
|             return client.get_workspace().get_id(); | ||||
|         } | ||||
|     } ); | ||||
|  | ||||
|     return -1; | ||||
| } | ||||
|  | ||||
|  | ||||
| interface HyprlandSubscriptions { | ||||
|     [key: string]: ( data: string ) => void; | ||||
| } | ||||
| const hooks: HyprlandSubscriptions = {}; | ||||
|  | ||||
| /** | ||||
|  * Add an event listener for Hyprland events. | ||||
|  * @param event - A hyprland IPC event. See https://wiki.hyprland.org/IPC/. Useful events include: urgent, windowtitlev2, workspace, createworkspacev2, destroyworkspacev2, activewindowv2 | ||||
|  * @param cb - The callback function | ||||
|  */ | ||||
| const subscribeToUpdates = ( event: string, cb: ( data: string ) => void ): void => { | ||||
|     hooks[ event ] = cb; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Listen to events. Must be called at some point if events are to be listened for | ||||
|  */ | ||||
| const listen = () => { | ||||
|     AstalHyprland.get_default().connect( "event", ( name: string, data: string ) => { | ||||
|         if ( hooks[ name ] ) { | ||||
|             hooks[ name ]( data ); | ||||
|         } | ||||
|     } ); | ||||
| } | ||||
|  | ||||
|  | ||||
| export default { | ||||
|     getAvailableWorkspaces, | ||||
|     getCurrentWorkspaceID, | ||||
|     getCurrentWindowTitle, | ||||
|     getWorkspaceIDOfWindowByAddress, | ||||
|     subscribeToUpdates, | ||||
|     listen | ||||
| } | ||||
							
								
								
									
										0
									
								
								config/astal/components/bar/util/sysinfo.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								config/astal/components/bar/util/sysinfo.ts
									
									
									
									
									
										Normal file
									
								
							
		Reference in New Issue
	
	Block a user