[AGS] Remove old modules
This commit is contained in:
parent
6c1c9ad8cf
commit
02861efcae
2
config/ags/bar/.gitignore
vendored
2
config/ags/bar/.gitignore
vendored
@ -1,2 +0,0 @@
|
|||||||
node_modules/
|
|
||||||
@girs/
|
|
@ -1,10 +0,0 @@
|
|||||||
import { App } from "astal/gtk4"
|
|
||||||
import style from "./style.scss"
|
|
||||||
import Bar from "./ui/Bar"
|
|
||||||
|
|
||||||
App.start({
|
|
||||||
css: style,
|
|
||||||
main() {
|
|
||||||
App.get_monitors().map(Bar)
|
|
||||||
},
|
|
||||||
})
|
|
@ -1,886 +0,0 @@
|
|||||||
|
|
||||||
import GLib from "gi://GLib";
|
|
||||||
import Astal from "gi://Astal";
|
|
||||||
import AstalHyprland from "gi://AstalHyprland";
|
|
||||||
import Gio from "gi://Gio";
|
|
||||||
import Gtk from "gi://Gtk";
|
|
||||||
import Gdk from "gi://Gdk";
|
|
||||||
import { exec } from "gi://GLib";
|
|
||||||
|
|
||||||
function getSystemStats() {
|
|
||||||
const cpu = exec("sh -c 'top -bn1 | grep \"Cpu(s)\" | sed \"s/.*, *\\([0-9.]*\\)%* id.*/\\1/\" | awk \"{print 100 - $1}\"'");
|
|
||||||
const memory = exec("free | grep Mem | awk '{print $3/$2 * 100.0}'");
|
|
||||||
const brightness = exec("brightnessctl g");
|
|
||||||
const battery = exec("cat /sys/class/power_supply/BAT0/capacity");
|
|
||||||
return { cpu, memory, brightness, battery };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWorkspaceNumber() {
|
|
||||||
return AstalHyprland.get_default().get_active_workspace().get_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWindowTitle() {
|
|
||||||
return exec("xdotool getactivewindow getwindowname");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDateTime() {
|
|
||||||
return GLib.DateTime.new_now_local().format("%a %b %d, %Y %H:%M:%S");
|
|
||||||
}
|
|
||||||
|
|
||||||
function createQuickActionMenu() {
|
|
||||||
const menu = new Gtk.Menu();
|
|
||||||
const volumeItem = new Gtk.MenuItem({ label: "🔊 Volume" });
|
|
||||||
const micItem = new Gtk.MenuItem({ label: "🎙️ Microphone" });
|
|
||||||
const wifiItem = new Gtk.MenuItem({ label: "📶 WiFi" });
|
|
||||||
const powerItem = new Gtk.MenuItem({ label: "🔌 Power" });
|
|
||||||
|
|
||||||
menu.append(volumeItem);
|
|
||||||
menu.append(micItem);
|
|
||||||
menu.append(wifiItem);
|
|
||||||
menu.append(powerItem);
|
|
||||||
|
|
||||||
volumeItem.show();
|
|
||||||
micItem.show();
|
|
||||||
wifiItem.show();
|
|
||||||
powerItem.show();
|
|
||||||
|
|
||||||
return menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
function Bar(gdkmonitor) {
|
|
||||||
const { cpu, memory, brightness, battery } = getSystemStats();
|
|
||||||
const workspaceNumber = getWorkspaceNumber();
|
|
||||||
const windowTitle = getWindowTitle();
|
|
||||||
const dateTime = getDateTime();
|
|
||||||
const quickActionMenu = createQuickActionMenu();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<window gdkmonitor={gdkmonitor}>
|
|
||||||
<box orientation="horizontal" spacing={10}>
|
|
||||||
<box>
|
|
||||||
<label>{dateTime}</label>
|
|
||||||
<label>{`CPU: ${cpu}%`}</label>
|
|
||||||
<label>{`Mem: ${memory}%`}</label>
|
|
||||||
<label>{`Brightness: ${brightness}%`}</label>
|
|
||||||
<label>{`Battery: ${battery}%`}</label>
|
|
||||||
<label>{`Workspace: ${workspaceNumber}`}</label>
|
|
||||||
</box>
|
|
||||||
<label>{windowTitle}</label>
|
|
||||||
<box>
|
|
||||||
<tray />
|
|
||||||
<button icon="quickaction" menu={quickActionMenu} />
|
|
||||||
</box>
|
|
||||||
</box>
|
|
||||||
</window>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
for (const m of AstalHyprland.get_default().get_monitors()) {
|
|
||||||
Bar(m.gdk_monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
App.start({ main });
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import GLib from "gi://GLib";
|
|
||||||
import Astal from "gi://Astal";
|
|
||||||
import AstalHyprland from "gi://AstalHyprland";
|
|
||||||
import Gtk from "gi://Gtk";
|
|
||||||
import { exec } from "gi://GLib";
|
|
||||||
import { createQuickActionsMenu } from "./quickactions.js";
|
|
||||||
|
|
||||||
function getSystemStats() {
|
|
||||||
const cpu = exec("sh -c 'top -bn1 | grep \"Cpu(s)\" | sed \"s/.*, *\\([0-9.]*\\)%* id.*/\\1/\" | awk \"{print 100 - $1}\"'");
|
|
||||||
const memory = exec("free | grep Mem | awk '{print $3/$2 * 100.0}'");
|
|
||||||
const brightness = exec("brightnessctl g");
|
|
||||||
const battery = exec("cat /sys/class/power_supply/BAT0/capacity");
|
|
||||||
return { cpu, memory, brightness, battery };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWorkspaceNumber() {
|
|
||||||
return AstalHyprland.get_default().get_active_workspace().get_id();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWindowTitle() {
|
|
||||||
return exec("xdotool getactivewindow getwindowname");
|
|
||||||
}
|
|
||||||
|
|
||||||
function getDateTime() {
|
|
||||||
return GLib.DateTime.new_now_local().format("%a %b %d, %Y %H:%M:%S");
|
|
||||||
}
|
|
||||||
|
|
||||||
function Bar(gdkmonitor) {
|
|
||||||
const { cpu, memory, brightness, battery } = getSystemStats();
|
|
||||||
const workspaceNumber = getWorkspaceNumber();
|
|
||||||
const windowTitle = getWindowTitle();
|
|
||||||
const dateTime = getDateTime();
|
|
||||||
const quickActionMenu = createQuickActionsMenu();
|
|
||||||
|
|
||||||
return (
|
|
||||||
<window gdkmonitor={gdkmonitor}>
|
|
||||||
<box orientation="horizontal" spacing={10}>
|
|
||||||
<box>
|
|
||||||
<label>{dateTime}</label>
|
|
||||||
<label>{`CPU: ${cpu}%`}</label>
|
|
||||||
<label>{`Mem: ${memory}%`}</label>
|
|
||||||
<label>{`Brightness: ${brightness}%`}</label>
|
|
||||||
<label>{`Battery: ${battery}%`}</label>
|
|
||||||
<label>{`Workspace: ${workspaceNumber}`}</label>
|
|
||||||
</box>
|
|
||||||
<label>{windowTitle}</label>
|
|
||||||
<box>
|
|
||||||
<tray />
|
|
||||||
<button icon="quickaction" menu={quickActionMenu} />
|
|
||||||
</box>
|
|
||||||
</box>
|
|
||||||
</window>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function main() {
|
|
||||||
for (const m of AstalHyprland.get_default().get_monitors()) {
|
|
||||||
Bar(m.gdk_monitor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
App.start({ main });
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import AstalNetwork from "gi://AstalNetwork";
|
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
|
||||||
import Gtk from "gi://Gtk";
|
|
||||||
|
|
||||||
function createQuickActionsMenu() {
|
|
||||||
const menu = new Gtk.Menu();
|
|
||||||
|
|
||||||
const wifiItem = new Gtk.MenuItem({ label: "📶 WiFi" });
|
|
||||||
const bluetoothItem = new Gtk.MenuItem({ label: "🔵 Bluetooth" });
|
|
||||||
const volumeItem = new Gtk.MenuItem({ label: "🔊 Volume" });
|
|
||||||
const micItem = new Gtk.MenuItem({ label: "🎙️ Microphone" });
|
|
||||||
const powerItem = new Gtk.MenuItem({ label: "🔌 Power" });
|
|
||||||
|
|
||||||
menu.append(wifiItem);
|
|
||||||
menu.append(bluetoothItem);
|
|
||||||
menu.append(volumeItem);
|
|
||||||
menu.append(micItem);
|
|
||||||
menu.append(powerItem);
|
|
||||||
|
|
||||||
wifiItem.connect("activate", () => toggleWiFi());
|
|
||||||
bluetoothItem.connect("activate", () => toggleBluetooth());
|
|
||||||
volumeItem.connect("activate", () => adjustVolume());
|
|
||||||
micItem.connect("activate", () => adjustMic());
|
|
||||||
powerItem.connect("activate", () => showPowerMenu());
|
|
||||||
|
|
||||||
wifiItem.show();
|
|
||||||
bluetoothItem.show();
|
|
||||||
volumeItem.show();
|
|
||||||
micItem.show();
|
|
||||||
powerItem.show();
|
|
||||||
|
|
||||||
return menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleBluetooth() {
|
|
||||||
const bluetooth = AstalBluetooth.get_default();
|
|
||||||
const adapter = bluetooth.get_adapter();
|
|
||||||
const powered = adapter.get_powered();
|
|
||||||
|
|
||||||
adapter.set_powered(!powered);
|
|
||||||
}
|
|
||||||
|
|
||||||
function adjustVolume() {
|
|
||||||
exec("pavucontrol");
|
|
||||||
}
|
|
||||||
|
|
||||||
function adjustMic() {
|
|
||||||
exec("pavucontrol");
|
|
||||||
}
|
|
||||||
|
|
||||||
function showPowerMenu() {
|
|
||||||
exec("power-menu");
|
|
||||||
}
|
|
||||||
|
|
||||||
export { createQuickActionsMenu };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// colors.scss
|
|
||||||
$accent: #4a90e2; // Primary accent color (change this)
|
|
||||||
$bg: #1e1e2e; // Background
|
|
||||||
$fg: #f8f8f2; // Foreground/text
|
|
||||||
$hover: lighten($accent, 10%);
|
|
||||||
$border: rgba(255, 255, 255, 0.1);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@import "colors";
|
|
||||||
|
|
||||||
* {
|
|
||||||
all: unset;
|
|
||||||
font-family: "JetBrainsMono Nerd Font", monospace;
|
|
||||||
font-size: 14px;
|
|
||||||
color: $fg;
|
|
||||||
}
|
|
||||||
|
|
||||||
window {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
box {
|
|
||||||
background-color: $bg;
|
|
||||||
border-radius: 16px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
border: 1px solid $border;
|
|
||||||
margin: 8px;
|
|
||||||
box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clickable buttons/icons (e.g. QuickAction, tray items)
|
|
||||||
button {
|
|
||||||
background-color: transparent;
|
|
||||||
border-radius: 12px;
|
|
||||||
padding: 6px;
|
|
||||||
transition: background-color 0.2s ease-in-out;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $hover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// System Tray area
|
|
||||||
tray {
|
|
||||||
padding: 0 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Layout specifics
|
|
||||||
.left-section,
|
|
||||||
.center-section,
|
|
||||||
.right-section {
|
|
||||||
padding: 0 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-section {
|
|
||||||
border-right: 1px solid $border;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right-section {
|
|
||||||
border-left: 1px solid $border;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Icons (you'll replace them with fluentui icons)
|
|
||||||
.icon {
|
|
||||||
font-family: "FluentUI System Icons"; // Ensure this font is loaded
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
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 };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import Gtk from "gi://Gtk";
|
|
||||||
import AstalNetwork from "gi://AstalNetwork";
|
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
|
||||||
import { exec } from "gi://GLib";
|
|
||||||
|
|
||||||
function toggleWiFi() {
|
|
||||||
const network = AstalNetwork.get_default();
|
|
||||||
const wifi = network.get_wifi();
|
|
||||||
wifi.get_state() === AstalNetwork.WifiState.DISCONNECTED
|
|
||||||
? wifi.connect()
|
|
||||||
: wifi.disconnect();
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleBluetooth() {
|
|
||||||
const adapter = AstalBluetooth.get_default().get_adapter();
|
|
||||||
adapter.set_powered(!adapter.get_powered());
|
|
||||||
}
|
|
||||||
|
|
||||||
function adjustVolume() {
|
|
||||||
exec("pavucontrol");
|
|
||||||
}
|
|
||||||
|
|
||||||
function adjustMic() {
|
|
||||||
exec("pavucontrol");
|
|
||||||
}
|
|
||||||
|
|
||||||
function showPowerMenu() {
|
|
||||||
exec("power-menu");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build submenu for WiFi networks
|
|
||||||
function buildWifiMenu() {
|
|
||||||
const wifi = AstalNetwork.get_default().get_wifi();
|
|
||||||
const menu = new Gtk.Menu();
|
|
||||||
|
|
||||||
for (const ap of wifi.get_access_points()) {
|
|
||||||
const ssid = ap.get_ssid();
|
|
||||||
const strength = ap.get_strength();
|
|
||||||
const item = new Gtk.MenuItem({ label: `${ssid} (${strength}%)` });
|
|
||||||
|
|
||||||
item.connect("activate", () => {
|
|
||||||
wifi.connect_access_point(ap);
|
|
||||||
});
|
|
||||||
|
|
||||||
item.show();
|
|
||||||
menu.append(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build submenu for Bluetooth devices
|
|
||||||
function buildBluetoothMenu() {
|
|
||||||
const bluetooth = AstalBluetooth.get_default();
|
|
||||||
const menu = new Gtk.Menu();
|
|
||||||
|
|
||||||
for (const device of bluetooth.get_devices()) {
|
|
||||||
const name = device.get_name();
|
|
||||||
const connected = device.get_connected();
|
|
||||||
const label = connected ? `✔ ${name}` : name;
|
|
||||||
|
|
||||||
const item = new Gtk.MenuItem({ label });
|
|
||||||
|
|
||||||
item.connect("activate", () => {
|
|
||||||
if (!connected) {
|
|
||||||
device.connect_device();
|
|
||||||
} else {
|
|
||||||
device.disconnect_device();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
item.show();
|
|
||||||
menu.append(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return menu;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createQuickActionsMenu() {
|
|
||||||
const wifiPicker = new Gtk.MenuItem({ label: "→ Pick Network ▸" });
|
|
||||||
const btPicker = new Gtk.MenuItem({ label: "→ Pick Device ▸" });
|
|
||||||
|
|
||||||
const wifiSubMenu = new Gtk.Menu();
|
|
||||||
const btSubMenu = new Gtk.Menu();
|
|
||||||
|
|
||||||
// Populate submenus on open
|
|
||||||
wifiPicker.connect("activate", () => {
|
|
||||||
wifiSubMenu.foreach(child => wifiSubMenu.remove(child));
|
|
||||||
const newMenu = buildWifiMenu();
|
|
||||||
newMenu.foreach(child => wifiSubMenu.append(child));
|
|
||||||
wifiSubMenu.show_all();
|
|
||||||
});
|
|
||||||
|
|
||||||
btPicker.connect("activate", () => {
|
|
||||||
btSubMenu.foreach(child => btSubMenu.remove(child));
|
|
||||||
const newMenu = buildBluetoothMenu();
|
|
||||||
newMenu.foreach(child => btSubMenu.append(child));
|
|
||||||
btSubMenu.show_all();
|
|
||||||
});
|
|
||||||
|
|
||||||
wifiPicker.set_submenu(wifiSubMenu);
|
|
||||||
btPicker.set_submenu(btSubMenu);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<menu>
|
|
||||||
<item label="📶 WiFi" onActivate={toggleWiFi} />
|
|
||||||
{wifiPicker}
|
|
||||||
|
|
||||||
<item label="🔵 Bluetooth" onActivate={toggleBluetooth} />
|
|
||||||
{btPicker}
|
|
||||||
|
|
||||||
<item label="🔊 Volume" onActivate={adjustVolume} />
|
|
||||||
<item label="🎙️ Microphone" onActivate={adjustMic} />
|
|
||||||
<item label="🔌 Power" onActivate={showPowerMenu} />
|
|
||||||
</menu>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { createQuickActionsMenu };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import Gtk from "gi://Gtk";
|
|
||||||
import AstalNetwork from "gi://AstalNetwork";
|
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
|
||||||
import { exec } from "gi://GLib";
|
|
||||||
|
|
||||||
function createToggleRow({ label, active, onToggle, onExpand }) {
|
|
||||||
return (
|
|
||||||
<box className="toggle-row" orientation="horizontal">
|
|
||||||
<button className={active ? "toggle active" : "toggle"} onClicked={onToggle}>
|
|
||||||
{label}
|
|
||||||
</button>
|
|
||||||
<button className="arrow" onClicked={onExpand}>
|
|
||||||
>
|
|
||||||
</button>
|
|
||||||
</box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createQuickActionsMenu() {
|
|
||||||
const wifi = AstalNetwork.get_default().get_wifi();
|
|
||||||
const bt = AstalBluetooth.get_default().get_adapter();
|
|
||||||
|
|
||||||
const wifiSub = new Gtk.Menu();
|
|
||||||
const btSub = new Gtk.Menu();
|
|
||||||
|
|
||||||
function refreshWifiMenu() {
|
|
||||||
wifiSub.foreach(c => wifiSub.remove(c));
|
|
||||||
for (const ap of wifi.get_access_points()) {
|
|
||||||
const item = new Gtk.MenuItem({ label: `${ap.get_ssid()} (${ap.get_strength()}%)` });
|
|
||||||
item.connect("activate", () => wifi.connect_access_point(ap));
|
|
||||||
item.show();
|
|
||||||
wifiSub.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshBtMenu() {
|
|
||||||
btSub.foreach(c => btSub.remove(c));
|
|
||||||
for (const dev of AstalBluetooth.get_default().get_devices()) {
|
|
||||||
const name = dev.get_name();
|
|
||||||
const label = dev.get_connected() ? `✔ ${name}` : name;
|
|
||||||
const item = new Gtk.MenuItem({ label });
|
|
||||||
item.connect("activate", () => {
|
|
||||||
dev.get_connected() ? dev.disconnect_device() : dev.connect_device();
|
|
||||||
});
|
|
||||||
item.show();
|
|
||||||
btSub.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<menu className="quickactions-menu">
|
|
||||||
|
|
||||||
<submenu label="">
|
|
||||||
{createToggleRow({
|
|
||||||
label: "📶 WiFi",
|
|
||||||
active: wifi.get_state() !== AstalNetwork.WifiState.DISCONNECTED,
|
|
||||||
onToggle: () => {
|
|
||||||
wifi.get_state() === AstalNetwork.WifiState.DISCONNECTED ? wifi.connect() : wifi.disconnect();
|
|
||||||
},
|
|
||||||
onExpand: () => {
|
|
||||||
refreshWifiMenu();
|
|
||||||
wifiSub.popup();
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</submenu>
|
|
||||||
|
|
||||||
<submenu label="">
|
|
||||||
{createToggleRow({
|
|
||||||
label: "🔵 Bluetooth",
|
|
||||||
active: bt.get_powered(),
|
|
||||||
onToggle: () => bt.set_powered(!bt.get_powered()),
|
|
||||||
onExpand: () => {
|
|
||||||
refreshBtMenu();
|
|
||||||
btSub.popup();
|
|
||||||
}
|
|
||||||
})}
|
|
||||||
</submenu>
|
|
||||||
|
|
||||||
<item label="🔊 Volume" onActivate={() => exec("pavucontrol")} />
|
|
||||||
<item label="🎙️ Microphone" onActivate={() => exec("pavucontrol")} />
|
|
||||||
<item label="🔌 Power" onActivate={() => exec("power-menu")} />
|
|
||||||
</menu>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { createQuickActionsMenu };
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.audio-control {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 8px 12px;
|
|
||||||
gap: 8px;
|
|
||||||
|
|
||||||
label {
|
|
||||||
min-width: 60px;
|
|
||||||
color: $fg;
|
|
||||||
}
|
|
||||||
|
|
||||||
scale {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 6px;
|
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $hover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-control {
|
|
||||||
padding: 12px;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
margin: 0 4px;
|
|
||||||
padding: 6px 10px;
|
|
||||||
border-radius: 6px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: $hover;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import Gtk from "gi://Gtk";
|
|
||||||
import AstalNetwork from "gi://AstalNetwork";
|
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
|
||||||
import AstalAudio from "gi://AstalAudio";
|
|
||||||
import AstalMedia from "gi://AstalMedia";
|
|
||||||
import { exec } from "gi://GLib";
|
|
||||||
|
|
||||||
// Helpers
|
|
||||||
function createToggleRow({ label, active, onToggle, onExpand }) {
|
|
||||||
return (
|
|
||||||
<box className="toggle-row" orientation="horizontal">
|
|
||||||
<button className={active ? "toggle active" : "toggle"} onClicked={onToggle}>
|
|
||||||
{label}
|
|
||||||
</button>
|
|
||||||
<button className="arrow" onClicked={onExpand}>
|
|
||||||
>
|
|
||||||
</button>
|
|
||||||
</box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createPowerRow({ onExpand }) {
|
|
||||||
return (
|
|
||||||
<box className="toggle-row" orientation="horizontal">
|
|
||||||
<button className="toggle" onClicked={() => exec("systemctl suspend")}>
|
|
||||||
🔋 Power
|
|
||||||
</button>
|
|
||||||
<button className="arrow" onClicked={onExpand}>
|
|
||||||
>
|
|
||||||
</button>
|
|
||||||
</box>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function createQuickActionsMenu() {
|
|
||||||
const wifi = AstalNetwork.get_default().get_wifi();
|
|
||||||
const bt = AstalBluetooth.get_default().get_adapter();
|
|
||||||
const audio = AstalAudio.get_default();
|
|
||||||
const media = AstalMedia.get_default();
|
|
||||||
|
|
||||||
// Submenus
|
|
||||||
const wifiSub = new Gtk.Menu();
|
|
||||||
const btSub = new Gtk.Menu();
|
|
||||||
const powerSub = new Gtk.Menu();
|
|
||||||
const outputSub = new Gtk.Menu();
|
|
||||||
const inputSub = new Gtk.Menu();
|
|
||||||
|
|
||||||
function refreshWifiMenu() {
|
|
||||||
wifiSub.foreach(c => wifiSub.remove(c));
|
|
||||||
for (const ap of wifi.get_access_points()) {
|
|
||||||
const item = new Gtk.MenuItem({ label: `${ap.get_ssid()} (${ap.get_strength()}%)` });
|
|
||||||
item.connect("activate", () => wifi.connect_access_point(ap));
|
|
||||||
item.show();
|
|
||||||
wifiSub.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshBtMenu() {
|
|
||||||
btSub.foreach(c => btSub.remove(c));
|
|
||||||
for (const dev of AstalBluetooth.get_default().get_devices()) {
|
|
||||||
const label = dev.get_connected() ? `✔ ${dev.get_name()}` : dev.get_name();
|
|
||||||
const item = new Gtk.MenuItem({ label });
|
|
||||||
item.connect("activate", () =>
|
|
||||||
dev.get_connected() ? dev.disconnect_device() : dev.connect_device()
|
|
||||||
);
|
|
||||||
item.show();
|
|
||||||
btSub.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshPowerMenu() {
|
|
||||||
const entries = [
|
|
||||||
{ label: "⏻ Shutdown", cmd: "systemctl poweroff" },
|
|
||||||
{ label: "🔁 Reboot", cmd: "systemctl reboot" },
|
|
||||||
{ label: "🔒 Lock", cmd: "loginctl lock-session" },
|
|
||||||
{ label: "🚪 Logout", cmd: "hyprctl dispatch exit" },
|
|
||||||
];
|
|
||||||
powerSub.foreach(c => powerSub.remove(c));
|
|
||||||
for (const entry of entries) {
|
|
||||||
const item = new Gtk.MenuItem({ label: entry.label });
|
|
||||||
item.connect("activate", () => exec(entry.cmd));
|
|
||||||
item.show();
|
|
||||||
powerSub.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshOutputDevices() {
|
|
||||||
outputSub.foreach(c => outputSub.remove(c));
|
|
||||||
for (const device of audio.get_outputs()) {
|
|
||||||
const label = device.is_default() ? `✔ ${device.get_description()}` : device.get_description();
|
|
||||||
const item = new Gtk.MenuItem({ label });
|
|
||||||
item.connect("activate", () => audio.set_default_output(device));
|
|
||||||
item.show();
|
|
||||||
outputSub.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function refreshInputDevices() {
|
|
||||||
inputSub.foreach(c => inputSub.remove(c));
|
|
||||||
for (const device of audio.get_inputs()) {
|
|
||||||
const label = device.is_default() ? `✔ ${device.get_description()}` : device.get_description();
|
|
||||||
const item = new Gtk.MenuItem({ label });
|
|
||||||
item.connect("activate", () => audio.set_default_input(device));
|
|
||||||
item.show();
|
|
||||||
inputSub.append(item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<menu className="quickactions-menu">
|
|
||||||
|
|
||||||
{/* WiFi */}
|
|
||||||
<submenu label="">
|
|
||||||
{createToggleRow({
|
|
||||||
label: "📶 WiFi",
|
|
||||||
active: wifi.get_state() !== AstalNetwork.WifiState.DISCONNECTED,
|
|
||||||
onToggle: () =>
|
|
||||||
wifi.get_state() === AstalNetwork.WifiState.DISCONNECTED
|
|
||||||
? wifi.connect()
|
|
||||||
: wifi.disconnect(),
|
|
||||||
onExpand: () => {
|
|
||||||
refreshWifiMenu();
|
|
||||||
wifiSub.popup();
|
|
||||||
},
|
|
||||||
})}
|
|
||||||
</submenu>
|
|
||||||
|
|
||||||
{/* Bluetooth */}
|
|
||||||
<submenu label="">
|
|
||||||
{createToggleRow({
|
|
||||||
label: "🔵 Bluetooth",
|
|
||||||
active: bt.get_powered(),
|
|
||||||
onToggle: () => bt.set_powered(!bt.get_powered()),
|
|
||||||
onExpand: () => {
|
|
||||||
refreshBtMenu();
|
|
||||||
btSub.popup();
|
|
||||||
},
|
|
||||||
})}
|
|
||||||
</submenu>
|
|
||||||
|
|
||||||
{/* Output Volume */}
|
|
||||||
<box className="audio-control">
|
|
||||||
<label>🔊 Output</label>
|
|
||||||
<scale
|
|
||||||
value={audio.get_output_volume()}
|
|
||||||
onChange={v => audio.set_output_volume(v)}
|
|
||||||
drawValue={false}
|
|
||||||
min={0}
|
|
||||||
max={100}
|
|
||||||
/>
|
|
||||||
<button onClicked={() => {
|
|
||||||
refreshOutputDevices();
|
|
||||||
outputSub.popup();
|
|
||||||
}}>⋯</button>
|
|
||||||
</box>
|
|
||||||
|
|
||||||
{/* Input Volume */}
|
|
||||||
<box className="audio-control">
|
|
||||||
<label>🎙️ Mic</label>
|
|
||||||
<scale
|
|
||||||
value={audio.get_input_volume()}
|
|
||||||
onChange={v => audio.set_input_volume(v)}
|
|
||||||
drawValue={false}
|
|
||||||
min={0}
|
|
||||||
max={100}
|
|
||||||
/>
|
|
||||||
<button onClicked={() => {
|
|
||||||
refreshInputDevices();
|
|
||||||
inputSub.popup();
|
|
||||||
}}>⋯</button>
|
|
||||||
</box>
|
|
||||||
|
|
||||||
{/* Media Controls */}
|
|
||||||
{media && (
|
|
||||||
<box className="media-control">
|
|
||||||
<label>{media.get_artist()} – {media.get_title()}</label>
|
|
||||||
<box>
|
|
||||||
<button onClicked={() => media.prev()}>⏮</button>
|
|
||||||
<button onClicked={() => media.play_pause()}>⏯</button>
|
|
||||||
<button onClicked={() => media.next()}>⏭</button>
|
|
||||||
</box>
|
|
||||||
</box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Power */}
|
|
||||||
<submenu label="">
|
|
||||||
{createPowerRow({
|
|
||||||
onExpand: () => {
|
|
||||||
refreshPowerMenu();
|
|
||||||
powerSub.popup();
|
|
||||||
},
|
|
||||||
})}
|
|
||||||
</submenu>
|
|
||||||
</menu>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export { createQuickActionsMenu };
|
|
21
config/ags/bar/env.d.ts
vendored
21
config/ags/bar/env.d.ts
vendored
@ -1,21 +0,0 @@
|
|||||||
declare const SRC: string
|
|
||||||
|
|
||||||
declare module "inline:*" {
|
|
||||||
const content: string
|
|
||||||
export default content
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.scss" {
|
|
||||||
const content: string
|
|
||||||
export default content
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.blp" {
|
|
||||||
const content: string
|
|
||||||
export default content
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module "*.css" {
|
|
||||||
const content: string
|
|
||||||
export default content
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "astal-shell",
|
|
||||||
"dependencies": {
|
|
||||||
"astal": "/usr/share/astal/gjs"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
// 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"};
|
|
||||||
|
|
||||||
window.Bar {
|
|
||||||
background: transparent;
|
|
||||||
color: $fg-color;
|
|
||||||
font-weight: bold;
|
|
||||||
|
|
||||||
>centerbox {
|
|
||||||
background: $bg-color;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
border-radius: 8px;
|
|
||||||
margin: 2px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "https://json.schemastore.org/tsconfig",
|
|
||||||
"compilerOptions": {
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"strict": true,
|
|
||||||
"target": "ES2022",
|
|
||||||
"module": "ES2022",
|
|
||||||
"moduleResolution": "Bundler",
|
|
||||||
// "checkJs": true,
|
|
||||||
// "allowJs": true,
|
|
||||||
"jsx": "react-jsx",
|
|
||||||
"jsxImportSource": "astal/gtk3",
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
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;
|
|
@ -1,76 +0,0 @@
|
|||||||
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 };
|
|
@ -1,57 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
@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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
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
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user