[Astal] Finish modes, move tray into quickactions menu
This commit is contained in:
		| @@ -1,44 +1,58 @@ | |||||||
| import { Gtk } from "astal/gtk4"; | import Audio from './modules/Audio/Audio'; | ||||||
| import Power from "./modules/Power"; | import { | ||||||
| import Audio from "./modules/Audio/Audio"; |     BatteryBox | ||||||
| import Bluetooth from "./modules/Bluetooth/Bluetooth"; | } from './modules/Battery'; | ||||||
| import Brightness from "./modules/Brightness/Brightness"; | import Bluetooth from './modules/Bluetooth/Bluetooth'; | ||||||
| import Player from "./modules/Player/Player"; | import Brightness from './modules/Brightness/Brightness'; | ||||||
| import { BatteryBox } from "./modules/Battery"; | import { | ||||||
| import { exec } from "astal"; |     Gtk | ||||||
| import Network from "./modules/Networking/Network"; | } from 'astal/gtk4'; | ||||||
|  | import Network from './modules/Networking/Network'; | ||||||
|  | import Player from './modules/Player/Player'; | ||||||
|  | import Power from './modules/Power'; | ||||||
|  | import SysTray from './modules/SysTray'; | ||||||
|  | import { | ||||||
|  |     exec | ||||||
|  | } from 'astal'; | ||||||
|  |  | ||||||
| const QuickActions = () => { | const QuickActions = () => { | ||||||
|     const popover = new Gtk.Popover({ cssClasses: ["quick-actions-wrapper"] }); |     const popover = new Gtk.Popover( { | ||||||
|  |         'cssClasses': [ 'quick-actions-wrapper' ] | ||||||
|  |     } ); | ||||||
|  |  | ||||||
|     popover.set_child( renderQuickActions() ); |     popover.set_child( renderQuickActions() ); | ||||||
|  |  | ||||||
|     return popover; |     return popover; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const renderQuickActions = () => { | const renderQuickActions = () => { | ||||||
|     const user = exec("/bin/sh -c whoami"); |     const user = exec( '/bin/sh -c whoami' ); | ||||||
|     const profile = exec("/bin/fish -c get-profile-picture"); |     const profile = exec( '/bin/fish -c get-profile-picture' ); | ||||||
|     const cwd = exec("pwd"); |     const cwd = exec( 'pwd' ); | ||||||
|     const um = Power.UserMenu(); |     const um = Power.UserMenu(); | ||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <box visible cssClasses={["quick-actions", "popover-box"]} vertical> |         <box visible cssClasses={[ | ||||||
|  |             'quick-actions', | ||||||
|  |             'popover-box' | ||||||
|  |         ]} vertical> | ||||||
|             <centerbox |             <centerbox | ||||||
|                 startWidget={ |                 startWidget={ | ||||||
|                     <button |                     <button | ||||||
|                         onClicked={() => um.popup()} |                         onClicked={() => um.popup()} | ||||||
|                         cssClasses={["stealthy-button"]} |                         cssClasses={[ 'stealthy-button' ]} | ||||||
|                         child={ |                         child={ | ||||||
|                             <box> |                             <box> | ||||||
|                                 {um} |                                 {um} | ||||||
|                                 <Gtk.Frame |                                 <Gtk.Frame | ||||||
|                                     cssClasses={["avatar-icon"]} |                                     cssClasses={[ 'avatar-icon' ]} | ||||||
|                                     child={ |                                     child={ | ||||||
|                                         <image |                                         <image | ||||||
|                                             file={ |                                             file={ | ||||||
|                                                 profile !== "" |                                                 profile !== '' | ||||||
|                                                     ? profile |                                                     ? profile | ||||||
|                                                     : cwd + |                                                     : cwd | ||||||
|                                                     "/no-avatar-icon.jpg" |                                                     + '/no-avatar-icon.jpg' | ||||||
|                                             } |                                             } | ||||||
|                                         ></image> |                                         ></image> | ||||||
|                                     } |                                     } | ||||||
| @@ -53,6 +67,7 @@ const renderQuickActions = () => { | |||||||
|                         hexpand={false} |                         hexpand={false} | ||||||
|                     > |                     > | ||||||
|                         <BatteryBox></BatteryBox> |                         <BatteryBox></BatteryBox> | ||||||
|  |                         <SysTray.SystemTray></SysTray.SystemTray> | ||||||
|                         <Power.Power></Power.Power> |                         <Power.Power></Power.Power> | ||||||
|                     </box> |                     </box> | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -1,48 +1,56 @@ | |||||||
| import { exec } from "astal"; | import { | ||||||
| import { Gtk } from "astal/gtk4"; |     exec | ||||||
|  | } from 'astal'; | ||||||
|  | import { | ||||||
|  |     Gtk | ||||||
|  | } from 'astal/gtk4'; | ||||||
|  |  | ||||||
| const PowerMenu = (): Gtk.Popover => { | const PowerMenu = (): Gtk.Popover => { | ||||||
|     const popover = new Gtk.Popover({ cssClasses: ["PowerMenu"] }); |     const popover = new Gtk.Popover( { | ||||||
|  |         'cssClasses': [ 'PowerMenu' ] | ||||||
|  |     } ); | ||||||
|  |  | ||||||
|     const powerMenuBox = () => { |     const powerMenuBox = () => { | ||||||
|         return ( |         return ( | ||||||
|             <box> |             <box> | ||||||
|                 <button |                 <button | ||||||
|                     cssClasses={["power-button"]} |                     cssClasses={[ 'power-button' ]} | ||||||
|                     child={ |                     child={ | ||||||
|                         <image iconName={"system-shutdown-symbolic"}></image> |                         <image iconName={'system-shutdown-symbolic'}></image> | ||||||
|                     } |                     } | ||||||
|                     onClicked={() => exec("/bin/sh -c 'shutdown now'")} |                     onClicked={() => exec( '/bin/sh -c \'shutdown now\'' )} | ||||||
|                 ></button> |                 ></button> | ||||||
|                 <button |                 <button | ||||||
|                     cssClasses={["power-button"]} |                     cssClasses={[ 'power-button' ]} | ||||||
|                     child={<image iconName={"system-reboot-symbolic"}></image>} |                     child={<image iconName={'system-reboot-symbolic'}></image>} | ||||||
|                     onClicked={() => exec("/bin/sh -c 'reboot'")} |                     onClicked={() => exec( '/bin/sh -c \'reboot\'' )} | ||||||
|                 ></button> |                 ></button> | ||||||
|                 <button |                 <button | ||||||
|                     cssClasses={["power-button"]} |                     cssClasses={[ 'power-button' ]} | ||||||
|                     child={<image iconName={"system-suspend-symbolic"}></image>} |                     child={<image iconName={'system-suspend-symbolic'}></image>} | ||||||
|                     onClicked={() => exec("/bin/sh -c 'systemctl suspend'")} |                     onClicked={() => exec( '/bin/sh -c \'systemctl suspend\'' )} | ||||||
|                 ></button> |                 ></button> | ||||||
|             </box> |             </box> | ||||||
|         ); |         ); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     popover.set_child( powerMenuBox() ); |     popover.set_child( powerMenuBox() ); | ||||||
|  |  | ||||||
|     return popover; |     return popover; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| const Power = () => { | const Power = () => { | ||||||
|     const pm = PowerMenu(); |     const pm = PowerMenu(); | ||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|         <button |         <button | ||||||
|             widthRequest={0} |             widthRequest={0} | ||||||
|             hexpand={false} |             hexpand={false} | ||||||
|             vexpand={false} |             vexpand={false} | ||||||
|             cssClasses={["power-menu-button"]} |             cssClasses={[ 'power-menu-button' ]} | ||||||
|             child={ |             child={ | ||||||
|                 <box> |                 <box> | ||||||
|                     <image iconName={"system-shutdown-symbolic"}></image> |                     <image iconName={'system-shutdown-symbolic'}></image> | ||||||
|                     {pm} |                     {pm} | ||||||
|                 </box> |                 </box> | ||||||
|             } |             } | ||||||
| @@ -58,17 +66,16 @@ const UserMenu = (): Gtk.Popover => { | |||||||
|         return ( |         return ( | ||||||
|             <box> |             <box> | ||||||
|                 <button |                 <button | ||||||
|                     cssClasses={["power-button"]} |                     cssClasses={[ 'power-button' ]} | ||||||
|                     child={ |                     child={ | ||||||
|                         <image iconName={"system-lock-screen-symbolic"}></image> |                         <image iconName={'system-lock-screen-symbolic'}></image> | ||||||
|                     } |                     } | ||||||
|                     onClicked={() => exec("/bin/sh -c 'hyprlock'")} |                     onClicked={() => exec( '/bin/sh -c \'hyprlock\'' )} | ||||||
|                 ></button> |                 ></button> | ||||||
|                 <button |                 <button | ||||||
|                     cssClasses={["power-button"]} |                     cssClasses={[ 'power-button' ]} | ||||||
|                     child={<image iconName={"system-log-out-symbolic"}></image>} |                     child={<image iconName={'system-log-out-symbolic'}></image>} | ||||||
|                     onClicked={() => |                     onClicked={() => exec( '/bin/sh -c \'hyprctl dispatch exit 0\'' ) | ||||||
|                         exec("/bin/sh -c 'hyprctl dispatch exit 0'") |  | ||||||
|                     } |                     } | ||||||
|                 ></button> |                 ></button> | ||||||
|             </box> |             </box> | ||||||
| @@ -76,6 +83,7 @@ const UserMenu = (): Gtk.Popover => { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     popover.set_child( powerMenuBox() ); |     popover.set_child( powerMenuBox() ); | ||||||
|  |  | ||||||
|     return popover; |     return popover; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										88
									
								
								config/astal/components/QuickActions/modules/SysTray.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								config/astal/components/QuickActions/modules/SysTray.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | |||||||
|  | import AstalTray from 'gi://AstalTray'; | ||||||
|  | import { | ||||||
|  |     GObject | ||||||
|  | } from 'astal'; | ||||||
|  | import { | ||||||
|  |     Gtk | ||||||
|  | } from 'astal/gtk4'; | ||||||
|  |  | ||||||
|  | const SYNC = GObject.BindingFlags.SYNC_CREATE; | ||||||
|  |  | ||||||
|  | const SysTray = () => { | ||||||
|  |     const trayBox = new Gtk.Box( { | ||||||
|  |         'cssClasses': [ '' ] | ||||||
|  |     } ); | ||||||
|  |     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 icon = new Gtk.Image(); | ||||||
|  |         const button = new Gtk.MenuButton( { | ||||||
|  |             popover, | ||||||
|  |             '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 ); | ||||||
|  |         } ); | ||||||
|  |  | ||||||
|  |         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 TrayPopover = () => { | ||||||
|  |     const popover = new Gtk.Popover( { | ||||||
|  |         'cssClasses': [ 'TrayPopover' ] | ||||||
|  |     } ); | ||||||
|  |  | ||||||
|  |     popover.set_child( SysTray() ); | ||||||
|  |  | ||||||
|  |     return popover; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const SystemTray = () => { | ||||||
|  |     const systray = TrayPopover(); | ||||||
|  |  | ||||||
|  |     return ( | ||||||
|  |         <button | ||||||
|  |             widthRequest={0} | ||||||
|  |             hexpand={false} | ||||||
|  |             vexpand={false} | ||||||
|  |             cssClasses={[ 'power-menu-button' ]} | ||||||
|  |             child={ | ||||||
|  |                 <box> | ||||||
|  |                     <image iconName={'systemtray'}></image> | ||||||
|  |                     {systray} | ||||||
|  |                 </box> | ||||||
|  |             } | ||||||
|  |             onClicked={() => systray.popup()} | ||||||
|  |         /> | ||||||
|  |     ); | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | export default { | ||||||
|  |     SystemTray | ||||||
|  | }; | ||||||
| @@ -39,7 +39,6 @@ const Bar = ( { | |||||||
|                         > |                         > | ||||||
|                             <Hyprland.ModeStatus /> |                             <Hyprland.ModeStatus /> | ||||||
|                             <Calendar.Time /> |                             <Calendar.Time /> | ||||||
|                             <SystemInfo.SystemInfo /> |  | ||||||
|                             <Hyprland.Workspace /> |                             <Hyprland.Workspace /> | ||||||
|                         </box> |                         </box> | ||||||
|                     } |                     } | ||||||
| @@ -50,7 +49,7 @@ const Bar = ( { | |||||||
|                             halign={Gtk.Align.END} |                             halign={Gtk.Align.END} | ||||||
|                             cssClasses={[ 'BarRight' ]} |                             cssClasses={[ 'BarRight' ]} | ||||||
|                         > |                         > | ||||||
|                             <Hyprland.SysTray /> |                             <SystemInfo.SystemInfo /> | ||||||
|                             <QuickView.QuickView /> |                             <QuickView.QuickView /> | ||||||
|                         </box> |                         </box> | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -20,6 +20,11 @@ window.Bar { | |||||||
|     border-radius: 20px; |     border-radius: 20px; | ||||||
|     font-family: $monospace-font; |     font-family: $monospace-font; | ||||||
|  |  | ||||||
|  |     &.command-mode { | ||||||
|  |       background-color: darkslategray; | ||||||
|  |       color: white; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     &.windowing-mode { |     &.windowing-mode { | ||||||
|       background-color: darkslategray; |       background-color: darkslategray; | ||||||
|       color: white; |       color: white; | ||||||
|   | |||||||
| @@ -1,62 +1,15 @@ | |||||||
| import { | import { | ||||||
|     GObject, bind, |     bind, | ||||||
|     exec, |     exec, | ||||||
|     readFile |     readFile | ||||||
| } from 'astal'; | } from 'astal'; | ||||||
| import AstalHyprland from 'gi://AstalHyprland'; | import AstalHyprland from 'gi://AstalHyprland'; | ||||||
| import AstalTray from 'gi://AstalTray'; |  | ||||||
| import { | import { | ||||||
|     Gtk |     Gtk | ||||||
| } from 'astal/gtk4'; | } from 'astal/gtk4'; | ||||||
| import Pango from 'gi://Pango?version=1.0'; | import Pango from 'gi://Pango?version=1.0'; | ||||||
|  |  | ||||||
| const hypr = AstalHyprland.get_default(); | const hypr = AstalHyprland.get_default(); | ||||||
| const SYNC = GObject.BindingFlags.SYNC_CREATE; |  | ||||||
|  |  | ||||||
| const SysTray = () => { |  | ||||||
|     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 icon = new Gtk.Image(); |  | ||||||
|         const button = new Gtk.MenuButton( { |  | ||||||
|             popover, |  | ||||||
|             '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 ); |  | ||||||
|         } ); |  | ||||||
|  |  | ||||||
|         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 Workspace = () => { | ||||||
|     return ( |     return ( | ||||||
| @@ -123,33 +76,33 @@ const ActiveWindow = () => { | |||||||
| type submaps = 'device' | 'launch' | 'workspace' | 'windowing' | 'screenshotting' | 'notifications' | ''; | type submaps = 'device' | 'launch' | 'workspace' | 'windowing' | 'screenshotting' | 'notifications' | ''; | ||||||
|  |  | ||||||
| const ModeStatus = () => { | const ModeStatus = () => { | ||||||
|     let isUsingHyprmode = false; |     let isUsingHyprvim = false; | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
|         const path = exec( 'bash -c "cd ~ && pwd"' ) + '/.config/hyprmode'; |         const path = exec( 'bash -c "cd ~ && pwd"' ) + '/.config/hyprvim'; | ||||||
|  |  | ||||||
|         isUsingHyprmode = readFile( path ).trim() === 'y'; |         isUsingHyprvim = readFile( path ).trim() === 'y'; | ||||||
|     } catch ( e ) { |     } catch ( e ) { | ||||||
|         printerr( 'Failed to read hyprmode config', e ); |         printerr( 'Failed to read hyprvim config', e ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     const label = new Gtk.Label(); |     const label = new Gtk.Label(); | ||||||
|  |  | ||||||
|     if ( !isUsingHyprmode ) return label; |     if ( !isUsingHyprvim ) return label; | ||||||
|  |  | ||||||
|     print( '==> Using hyprmode config' ); |     print( '==> Using hyprvim config' ); | ||||||
|  |  | ||||||
|     const map = { |     const map = { | ||||||
|         'device': 'D', |         'device': 'DEV', | ||||||
|         'launch': 'L', |         'launch': 'LNC', | ||||||
|         'workspace': 'W', |         'workspace': 'WSP', | ||||||
|         'windowing': 'M', |         'windowing': 'WIN', | ||||||
|         'screenshotting': 'S', |         'screenshotting': 'SCS', | ||||||
|         'notifications': 'N', |         'notifications': 'NOT', | ||||||
|         '': 'N' |         '': 'NRM' | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     label.label = 'N'; |     label.label = map['']; | ||||||
|     label.cssClasses = [ 'mode-status' ]; |     label.cssClasses = [ 'mode-status' ]; | ||||||
|  |  | ||||||
|     // TODO: Possibly add popover to it that lists binds |     // TODO: Possibly add popover to it that lists binds | ||||||
| @@ -189,6 +142,5 @@ const WindowPopoverBox = () => { | |||||||
| export default { | export default { | ||||||
|     Workspace, |     Workspace, | ||||||
|     ActiveWindow, |     ActiveWindow, | ||||||
|     SysTray, |  | ||||||
|     ModeStatus |     ModeStatus | ||||||
| }; | }; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user