Compare commits

..

2 commits

41 changed files with 266 additions and 174 deletions

View file

@ -2,7 +2,7 @@
tablet() {
gsettings set org.gnome.desktop.a11y.applications screen-keyboard-enabled true
brightnessctl -d tpacpi::kbd_backlight s 0
"$HYPR_PATH"/autorotate.sh &

View file

@ -1,22 +1,25 @@
import { exec, execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
import { Powermenu } from './js/powermenu.js';
import { Bar } from './js/bar/main.js';
import { NotificationCenter } from './js/notifications/center.js';
import { App, Utils } from './imports.js';
import { Powermenu } from './js/powermenu.js';
import { Bar } from './js/bar/main.js';
import { NotificationCenter } from './js/notifications/center.js';
import { NotificationsPopupList } from './js/notifications/popup.js'
import { Calendar } from './js/date.js';
import { QuickSettings } from './js/quick-settings/main.js';
import Overview from './js/overview/main.js';
import AppLauncher from './js/applauncher/main.js';
import { Calendar } from './js/date.js';
import { QuickSettings } from './js/quick-settings/main.js';
import Overview from './js/overview/main.js';
import AppLauncher from './js/applauncher/main.js';
import { Closer, closeAll } from './js/misc/closer.js';
ags.App.closeAll = () => closeAll();
import { Closer, closeAll } from './js/misc/closer.js';
globalThis.closeAll = () => closeAll();
const scss = ags.App.configDir + '/scss/main.scss';
const css = ags.App.configDir + '/style.css';
exec(`sassc ${scss} ${css}`);
const scss = App.configDir + '/scss/main.scss';
const css = App.configDir + '/style.css';
Utils.exec(`sassc ${scss} ${css}`);
Utils.execAsync(['bash', '-c', '$AGS_PATH/startup.sh']).catch(print);
execAsync(['bash', '-c', '$AGS_PATH/startup.sh']).catch(print);
export default {
style: css,

21
config/ags/imports.js Normal file
View file

@ -0,0 +1,21 @@
const resource = file => `resource:///com/github/Aylur/ags/${file}.js`;
const require = async file => (await import(resource(file))).default;
const service = async file => (await require(`service/${file}`)).instance;
export const App = await require('app');
App.connect = (...args) => App.instance.connect(...args);
export const Widget = await require('widget');
export const Service = await require('service');
export const Variable = await require('variable');
export const Utils = await import(resource('utils'));
export const Applications = await service('applications');
export const Audio = await service('audio');
export const Battery = await service('battery');
export const Bluetooth = await service('bluetooth');
export const Hyprland = await service('hyprland');
export const Mpris = await service('mpris');
export const Network = await service('network');
export const Notifications = await service('notifications');
export const SystemTray = await service('systemtray');

View file

@ -1,6 +1,5 @@
const { App } = ags;
const { Applications } = ags.Service;
const { Label, Box, Icon, Button, Scrollable, Entry, Window, EventBox } = ags.Widget;
import { App, Applications, Widget } from '../../imports.js';
const { Label, Box, Icon, Button, Scrollable, Entry, Window, EventBox } = Widget;
import { Separator } from '../misc/separator.js';
import { PopUp } from '../misc/popup.js';
@ -12,6 +11,7 @@ const icons = {
}
};
const AppItem = (app, window) => {
if (app.app.get_string('Icon') == 'Nextcloud')
return;

View file

@ -1,5 +1,5 @@
const { Audio } = ags.Service;
const { Label, Box, Icon, Stack, Button, Slider } = ags.Widget;
import { Audio, Widget } from '../../imports.js';
const { Label, Box, Icon } = Widget;
import { Separator } from '../misc/separator.js';
import { EventBox } from '../misc/cursorbox.js';
@ -12,12 +12,13 @@ const items = {
0: 'audio-volume-muted-symbolic',
};
const SpeakerIndicator = params => Icon({
...params,
icon: '',
connections: [[Audio, icon => {
if (Audio.speaker) {
if (Audio.speaker.isMuted) {
if (Audio.speaker.stream.isMuted) {
icon.icon = items[0];
}
else {

View file

@ -1,5 +1,5 @@
const { Battery } = ags.Service;
const { Label, Icon, Stack, Box } = ags.Widget;
import { Battery, Widget } from '../../imports.js';
const { Label, Icon, Stack, Box } = Widget;
import { Separator } from '../misc/separator.js';
@ -16,6 +16,7 @@ const icons = charging => ([
})],
]);
const Indicators = charging => Stack({
items: icons(charging),
connections: [[Battery, stack => {

View file

@ -1,8 +1,10 @@
const { ProgressBar, Overlay, Box } = ags.Widget;
const { execAsync } = ags.Utils;
import { Utils, Widget } from '../../imports.js';
const { ProgressBar, Overlay, Box } = Widget;
import { Separator } from '../misc/separator.js';
import { Heart } from './heart.js';
export const Brightness = Overlay({
setup: widget => {
widget.set_tooltip_text('Brightness');
@ -11,7 +13,7 @@ export const Brightness = Overlay({
className: 'toggle-off brightness',
connections: [
[200, progress => {
execAsync('brightnessctl get').then(out => {
Utils.execAsync('brightnessctl get').then(out => {
let br = out / 255;
if (br > 0.33) {
progress.value = br;

View file

@ -1,9 +1,13 @@
const { Box, Label } = ags.Widget;
const { toggleWindow } = ags.App;
const { DateTime } = imports.gi.GLib;
import { App, Widget } from '../../imports.js';
const { Box, Label } = Widget;
const { toggleWindow } = App;
import GLib from 'gi://GLib';
const { DateTime } = GLib;
import { EventBox } from '../misc/cursorbox.js';
const ClockModule = ({
interval = 1000,
...params
@ -22,7 +26,7 @@ export const Clock = EventBox({
className: 'toggle-off',
onPrimaryClickRelease: () => toggleWindow('calendar'),
connections: [
[ags.App, (box, windowName, visible) => {
[App, (box, windowName, visible) => {
if (windowName == 'calendar') {
box.toggleClassName('toggle-on', visible);
}

View file

@ -1,6 +1,6 @@
const { Hyprland } = ags.Service;
const { Label } = ags.Widget;
const { Gtk } = imports.gi;
import { Widget, Hyprland } from '../../imports.js';
const { Label } = Widget;
export const CurrentWindow = Label({
style: 'color: #CBA6F7; font-size: 18px',

View file

@ -1,7 +1,9 @@
const { Window, CenterBox, EventBox, Button } = ags.Widget;
const { openWindow } = ags.App;
const { Gtk, Gdk } = imports.gi;
const display = Gdk.Display.get_default();
import { Widget, App } from '../../imports.js';
const { CenterBox, EventBox } = Widget;
const { openWindow } = App;
import Gtk from 'gi://Gtk';
export const Gesture = ({
child,
@ -19,7 +21,7 @@ export const Gesture = ({
],
connections: [
[gesture, box => {
[gesture, _ => {
const velocity = gesture.get_velocity()[1];
if (velocity < -100)
openWindow('quick-settings');

View file

@ -1,10 +1,11 @@
const { Box, Label } = ags.Widget;
const { subprocess, execAsync } = ags.Utils;
const deflisten = subprocess;
import { Utils, Widget } from '../../imports.js';
const { Box, Label } = Widget;
const { subprocess, execAsync } = Utils;
import { EventBox } from '../misc/cursorbox.js';
deflisten(
subprocess(
['bash', '-c', 'tail -f /home/matt/.config/.heart'],
(output) => {
Heart.child.children[0].label = ' ' + output;

View file

@ -1,4 +1,5 @@
const { Window, CenterBox, Box } = ags.Widget;
import { Widget } from '../../imports.js';
const { Window, CenterBox, Box } = Widget;
import { Separator } from '../misc/separator.js';
import { CurrentWindow } from './current-window.js';
@ -14,6 +15,7 @@ import { Brightness } from './brightness.js';
import { AudioIndicator } from './audio.js';
import { Gesture } from './gesture.js';
export const Bar = Window({
name: 'bar',
layer: 'overlay',

View file

@ -1,15 +1,16 @@
const { Box, Label, Icon } = ags.Widget;
const { toggleWindow } = ags.App;
const { Notifications } = ags.Service;
import { App, Notifications, Widget } from '../../imports.js';
const { Box, Label, Icon } = Widget;
const { toggleWindow } = App;
import { Separator } from '../misc/separator.js';
import { EventBox } from '../misc/cursorbox.js';
export const NotifButton = EventBox({
className: 'toggle-off',
onPrimaryClickRelease: () => toggleWindow('notification-center'),
connections: [
[ags.App, (box, windowName, visible) => {
[App, (box, windowName, visible) => {
if (windowName == 'notification-center') {
box.toggleClassName('toggle-on', visible);
}
@ -46,7 +47,7 @@ export const NotifButton = EventBox({
[Notifications, label => {
label.label = String(Notifications.notifications.length);
}],
],
],
}),
],

View file

@ -1,10 +1,11 @@
const { Box, Label } = ags.Widget;
const { subprocess } = ags.Utils;
const deflisten = subprocess;
import { Utils, Widget } from '../../imports.js';
const { Box, Label } = Widget;
const { subprocess } = Utils;
import { EventBox } from '../misc/cursorbox.js';
deflisten(
subprocess(
['bash', '-c', '$AGS_PATH/osk-toggle.sh getState'],
(output) => {
if (output == 'Running') {

View file

@ -1,13 +1,15 @@
const { Box, Label } = ags.Widget;
const { toggleWindow } = ags.App;
import { Widget, App } from '../../imports.js';
const { Box, Label } = Widget;
const { toggleWindow } = App;
import { EventBox } from '../misc/cursorbox.js';
export const QsToggle = EventBox({
className: 'toggle-off',
onPrimaryClickRelease: () => toggleWindow('quick-settings'),
connections: [
[ags.App, (box, windowName, visible) => {
[App, (box, windowName, visible) => {
if (windowName == 'quick-settings') {
box.toggleClassName('toggle-on', visible);
}

View file

@ -1,9 +1,11 @@
const { SystemTray } = ags.Service;
const { Box, Revealer, Icon, MenuItem } = ags.Widget;
const { Gtk } = imports.gi;
import { SystemTray, Widget } from '../../imports.js';
const { Box, Revealer, Icon, MenuItem } = Widget;
import Gtk from 'gi://Gtk';
import { Separator } from '../misc/separator.js';
const SysTrayItem = item => MenuItem({
className: 'tray-item',
child: Icon({
@ -23,7 +25,7 @@ export const SysTray = Revealer({
}]],
child: Box({
children: [
ags.Widget({
Widget({
type: Gtk.MenuBar,
className: 'sys-tray',
properties: [

View file

@ -1,8 +1,10 @@
const { Box, Label } = ags.Widget;
const { subprocess } = ags.Utils;
import { Utils, Widget } from '../../imports.js';
const { Box, Label } = Widget;
const { subprocess } = Utils;
import { EventBox } from '../misc/cursorbox.js';
export const TabletToggle = EventBox({
className: 'toggle-off',
onPrimaryClickRelease: function() {

View file

@ -1,9 +1,10 @@
const { Hyprland, Applications } = ags.Service;
const { execAsync } = ags.Utils;
const { Box, Button, Label, Revealer } = ags.Widget;
import { Hyprland, Utils, Widget } from '../../imports.js';
const { Box, Label, Revealer } = Widget;
const { execAsync } = Utils;
import { EventBox } from '../misc/cursorbox.js';
const Workspace = ({ i } = {}) =>
Revealer({
transition: "slide_right",

View file

@ -1,9 +1,13 @@
const { Box, Label, Window } = ags.Widget;
const { Gtk } = imports.gi;
const { DateTime } = imports.gi.GLib;
import { Widget } from '../imports.js';
const { Box, Label, Window } = Widget;
import Gtk from 'gi://Gtk';
import GLib from 'gi://GLib';
const { DateTime } = GLib;
import { PopUp } from './misc/popup.js';
const Divider = () => Box({
className: 'divider',
vertical: true,
@ -59,7 +63,7 @@ const Time = () => Box({
const CalendarWidget = () => Box({
className: 'cal-box',
child: ags.Widget({
child: Widget({
type: Gtk.Calendar,
showDayNames: true,
showHeading: true,

View file

@ -1,13 +1,15 @@
const { Box, Overlay, EventBox } = ags.Widget;
const { Gtk } = imports.gi;
import { Widget } from '../../imports.js';
const { Box, Overlay, EventBox } = Widget;
import Gtk from 'gi://Gtk';
const MAX_OFFSET = 200;
const OFFSCREEN = 500;
const TRANSITION = 'transition: margin 0.5s ease, opacity 3s ease;';
export default ({ properties, connections, params } = {}) => {
let widget = EventBox();
let gesture = Gtk.GestureDrag.new(widget)
widget.child = Overlay({

View file

@ -1,7 +1,8 @@
const { execAsync, lookUpIcon } = ags.Utils;
const { Mpris } = ags.Service;
const { Button, Icon, Label, Stack, Slider, CenterBox, Box } = ags.Widget;
const { Gdk } = imports.gi;
import { Mpris, Utils, Widget } from '../../imports.js';
const { Button, Icon, Label, Stack, Slider, CenterBox, Box } = Widget;
const { execAsync, lookUpIcon } = Utils;
import Gdk from 'gi://Gdk';
const display = Gdk.Display.get_default();
import { EventBox } from '../misc/cursorbox.js';
@ -27,6 +28,7 @@ const icons = {
},
}
export const CoverArt = (player, params) => CenterBox({
...params,
vertical: true,

View file

@ -1,10 +1,11 @@
const { Mpris } = ags.Service;
const { Box, CenterBox, Label } = ags.Widget;
import { Mpris, Variable, Widget } from '../../imports.js';
const { Box, CenterBox, Label } = Widget;
import * as mpris from './mpris.js';
import PlayerGesture from './gesture.js';
import { Separator } from '../misc/separator.js';
const Top = player => Box({
className: 'top',
halign: 'start',
@ -97,7 +98,7 @@ export default () => Box({
return;
const player = Mpris.getPlayer(busName);
player.colors = ags.Variable();
player.colors = Variable();
overlay._players.set(busName, PlayerBox(player));
let result = [];

View file

@ -1,5 +1,6 @@
const { Window, EventBox } = ags.Widget;
const { closeWindow } = ags.App;
import { App, Widget } from '../../imports.js';
const { Window, EventBox } = Widget;
const { closeWindow } = App;
const ALWAYS_OPEN = [
'closer',
@ -7,11 +8,12 @@ const ALWAYS_OPEN = [
'notifications',
];
// TODO: close on scroll event too?
export const closeAll = () => {
ags.App.windows.forEach(w => {
App.windows.forEach(w => {
if (!ALWAYS_OPEN.some(window => window === w.name))
ags.App.closeWindow(w.name)
closeWindow(w.name)
});
closeWindow('closer');
};
@ -24,8 +26,8 @@ export const Closer = Window({
child: EventBox({
onPrimaryClickRelease: () => closeAll(),
connections: [[ags.App, (_b, _w, _v) => {
if (!Array.from(ags.App.windows).some(w => w[1].visible &&
connections: [[App, (_b, _w, _v) => {
if (!Array.from(App.windows).some(w => w[1].visible &&
!ALWAYS_OPEN.some(window => window === w[0]))) {
closeWindow('closer');
}

View file

@ -1,7 +1,10 @@
import { Widget } from '../../imports.js';
import Gdk from 'gi://Gdk';
const display = Gdk.Display.get_default();
export const EventBox = ({ reset = true, ...params }) => ags.Widget.EventBox({
export const EventBox = ({ reset = true, ...params }) => Widget.EventBox({
...params,
onHover: box => {
if (! box.child.sensitive || ! box.sensitive) {
@ -17,7 +20,7 @@ export const EventBox = ({ reset = true, ...params }) => ags.Widget.EventBox({
},
});
export const Button = ({ reset = true, ...params }) => ags.Widget.Button({
export const Button = ({ reset = true, ...params }) => Widget.Button({
...params,
onHover: box => {
if (! box.child.sensitive || ! box.sensitive) {

View file

@ -1,7 +1,11 @@
const { Box, EventBox } = ags.Widget;
const { Gtk, Gdk } = imports.gi;
import { Widget } from '../../imports.js';
const { Box, EventBox } = Widget;
import Gtk from 'gi://Gtk';
import Gdk from 'gi://Gdk';
const display = Gdk.Display.get_default();
export const Draggable = ({
maxOffset = 150,
startMargin = 0,

View file

@ -1,5 +1,7 @@
const { Revealer, Box } = ags.Widget;
const { openWindow } = ags.App;
import { App, Widget } from '../../imports.js';
const { Revealer, Box } = Widget;
const { openWindow } = App;
export const PopUp = ({name, child, transition = 'slide_down', ...params}) => Box({
style: 'min-height:1px; min-width:1px',
@ -7,7 +9,7 @@ export const PopUp = ({name, child, transition = 'slide_down', ...params}) => Bo
...params,
transition,
transitionDuration: 500,
connections: [[ags.App, (revealer, currentName, visible) => {
connections: [[App, (revealer, currentName, visible) => {
if (currentName === name) {
revealer.reveal_child = visible;

View file

@ -1,3 +1,7 @@
export const Separator = width => ags.Widget.Box({
import { Widget } from '../../imports.js';
const { Box } = Widget;
export const Separator = width => Box({
style: `min-width: ${width}px;`,
});

View file

@ -1,17 +1,19 @@
const { GLib } = imports.gi;
const { Notifications, Applications } = ags.Service;
const { lookUpIcon, exec, execAsync } = ags.Utils;
const { Box, Icon, Label, Button } = ags.Widget;
import { Applications, Utils, Widget } from '../../imports.js';
const { lookUpIcon, execAsync } = Utils;
const { Box, Icon, Label, Button } = Widget;
import GLib from 'gi://GLib';
import { Draggable } from '../misc/drag.js';
import { EventBox } from '../misc/cursorbox.js'
import { closeAll } from '../misc/closer.js';
const NotificationIcon = ({ appEntry, appIcon, image }) => {
const NotificationIcon = notif => {
let iconCmd = () => {};
if (Applications.query(appEntry).length > 0) {
let app = Applications.query(appEntry)[0];
if (Applications.query(notif.appEntry).length > 0) {
let app = Applications.query(notif.appEntry)[0];
if (app.app.get_string('StartupWMClass') != null) {
iconCmd = box => {
@ -32,7 +34,7 @@ const NotificationIcon = ({ appEntry, appIcon, image }) => {
}
}
if (image) {
if (notif.image) {
return EventBox({
onPrimaryClickRelease: iconCmd,
child: Box({
@ -40,7 +42,7 @@ const NotificationIcon = ({ appEntry, appIcon, image }) => {
hexpand: false,
className: 'icon img',
style: `
background-image: url("${image}");
background-image: url("${notif.image}");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
@ -52,12 +54,12 @@ const NotificationIcon = ({ appEntry, appIcon, image }) => {
}
let icon = 'dialog-information-symbolic';
if (lookUpIcon(appIcon)) {
icon = appIcon;
if (lookUpIcon(notif.appIcon)) {
icon = notif.appIcon;
}
if (lookUpIcon(appEntry)) {
icon = appEntry;
if (lookUpIcon(notif.appEntry)) {
icon = notif.appEntry;
}
return EventBox({
@ -81,22 +83,22 @@ const NotificationIcon = ({ appEntry, appIcon, image }) => {
});
};
export default ({ id, summary, body, actions, urgency, time, command = i => {}, ...icon }) => {
export default ({ notif, command = () => {}} = {}) => {
const BlockedApps = [
'Spotify',
];
if (BlockedApps.find(app => app == Notifications.getNotification(id).appName)) {
Notifications.close(id);
if (BlockedApps.find(app => app == notif.appName)) {
notif.close();
return;
}
return Draggable({
maxOffset: 200,
command: () => command(id),
command: () => command(),
properties: [
['hovered', false],
['id', id],
['id', notif.id],
],
onHover: w => {
if (!w._hovered) {
@ -110,7 +112,7 @@ export default ({ id, summary, body, actions, urgency, time, command = i => {},
},
child: Box({
className: `notification ${urgency}`,
className: `notification ${notif.urgency}`,
vexpand: false,
// Notification
child: Box({
@ -119,7 +121,7 @@ export default ({ id, summary, body, actions, urgency, time, command = i => {},
// Content
Box({
children: [
NotificationIcon(icon),
NotificationIcon(notif),
Box({
hexpand: true,
vertical: true,
@ -135,20 +137,20 @@ export default ({ id, summary, body, actions, urgency, time, command = i => {},
maxWidthChars: 24,
truncate: 'end',
wrap: true,
label: summary,
useMarkup: summary.startsWith('<'),
label: notif.summary,
useMarkup: notif.summary.startsWith('<'),
}),
Label({
className: 'time',
valign: 'start',
label: GLib.DateTime.new_from_unix_local(time).format('%H:%M'),
label: GLib.DateTime.new_from_unix_local(notif.time).format('%H:%M'),
}),
EventBox({
reset: false,
child: Button({
className: 'close-button',
valign: 'start',
onClicked: () => Notifications.close(id),
onClicked: () => notif.close(),
child: Icon('window-close-symbolic'),
}),
}),
@ -160,7 +162,7 @@ export default ({ id, summary, body, actions, urgency, time, command = i => {},
useMarkup: true,
xalign: 0,
justification: 'left',
label: body,
label: notif.body,
wrap: true,
}),
],
@ -170,9 +172,9 @@ export default ({ id, summary, body, actions, urgency, time, command = i => {},
// Actions
Box({
className: 'actions',
children: actions.map(action => Button({
children: notif.actions.map(action => Button({
className: 'action-button',
onClicked: () => Notifications.invoke(id, action.id),
onClicked: () => notif.invoke(action.id),
hexpand: true,
child: Label(action.label),
})),

View file

@ -1,12 +1,13 @@
const { Notifications } = ags.Service;
const { Button, Label, Box, Icon, Scrollable, Window, Revealer } = ags.Widget;
const { timeout } = ags.Utils;
const { getWindow } = ags.App;
import { Notifications, App, Utils, Widget } from '../../imports.js';
const { Button, Label, Box, Icon, Scrollable, Window, Revealer } = Widget;
const { timeout } = Utils;
const { getWindow } = App;
import Notification from './base.js';
import { EventBox } from '../misc/cursorbox.js';
import { PopUp } from '../misc/popup.js';
const ClearButton = () => EventBox({
child: Button({
onPrimaryClickRelease: button => {
@ -59,12 +60,14 @@ const NotificationList = Box({
if (box.children.length == 0) {
box.children = Notifications.notifications
.reverse()
.map(n => Notification({ ...n, command: i => Notifications.close(i), }));
.map(n => Notification({ notif: n, command: () => n.close() }));
}
else if (id) {
let notif = Notifications.getNotification(id);
const NewNotif = Notification({
...Notifications.getNotification(id),
command: i => Notifications.close(i),
notif,
command: () => notif.close(),
});
if (NewNotif) {

View file

@ -1,8 +1,12 @@
import { Notifications, Utils, Widget } from '../../imports.js';
const { Box, Revealer, Window } = Widget;
const { timeout, interval } = Utils;
import GLib from 'gi://GLib';
const { source_remove } = GLib;
import Notification from './base.js';
const { Notifications } = ags.Service;
const { Box, Revealer, Window } = ags.Widget;
const { timeout, interval } = ags.Utils;
const { source_remove } = imports.gi.GLib;
const Popups = () => Box({
vertical: true,
@ -36,9 +40,10 @@ const Popups = () => Box({
box._map.delete(id);
let notif = Notifications.getNotification(id);
box._map.set(id, Notification({
...Notifications.getNotification(id),
command: i => Notifications.dismiss(i),
notif,
command: () => notif.dismiss(),
}));
box.children = Array.from(box._map.values()).reverse();

View file

@ -1,17 +1,19 @@
const { Icon, Revealer } = ags.Widget;
const { closeWindow } = ags.App;
const { execAsync } = ags.Utils;
const { Hyprland } = ags.Service;
import { App, Hyprland, Utils, Widget } from '../../imports.js';
const { Icon, Revealer } = Widget;
const { closeWindow } = App;
const { execAsync } = Utils;
import { WindowButton } from './dragndrop.js';
import * as VARS from './variables.js';
Array.prototype.remove = function (el) { this.splice(this.indexOf(el), 1) };
const IconStyle = app => `min-width: ${app.size[0] * VARS.SCALE - VARS.MARGIN}px;
min-height: ${app.size[1] * VARS.SCALE - VARS.MARGIN}px;
font-size: ${Math.min(app.size[0] * VARS.SCALE - VARS.MARGIN,
app.size[1] * VARS.SCALE - VARS.MARGIN) * VARS.ICON_SCALE}px;`;
const Client = (client, active, clients) => Revealer({
transition: 'crossfade',
setup: rev => {
@ -65,7 +67,7 @@ const Client = (client, active, clients) => Revealer({
});
export function updateClients(box) {
ags.Utils.execAsync('hyprctl clients -j')
execAsync('hyprctl clients -j')
.then(result => {
let clients = JSON.parse(result).filter(client => client.class)

View file

@ -1,14 +1,17 @@
const { Gtk, Gdk } = imports.gi;
const { EventBox } = ags.Widget;
const { execAsync } = ags.Utils;
const { getWindow } = ags.App;
import { App, Utils, Widget } from '../../imports.js';
const { EventBox } = Widget;
const { execAsync } = Utils;
const { getWindow } = App;
import Gtk from 'gi://Gtk';
import Gdk from 'gi://Gdk';
import Cairo from 'cairo';
import { Button } from '../misc/cursorbox.js';
const TARGET = [Gtk.TargetEntry.new('text/plain', Gtk.TargetFlags.SAME_APP, 0)];
function createSurfaceFromWidget(widget) {
const alloc = widget.get_allocation();
const surface = new Cairo.ImageSurface(
@ -28,7 +31,6 @@ function createSurfaceFromWidget(widget) {
let hidden = 0;
export const WorkspaceDrop = params => EventBox({
...params,
//tooltipText: `Workspace: ${id}`,
connections: [['drag-data-received', (eventbox, _c, _x, _y, data) => {
let id = eventbox.get_parent()._id;

View file

@ -1,10 +1,11 @@
const { Window, Box } = ags.Widget;
const { Hyprland } = ags.Service;
import { Hyprland, Widget } from '../../imports.js';
const { Window, Box } = Widget;
import { PopUp } from '../misc/popup.js';
import { WorkspaceRow, getWorkspaces, updateWorkspaces } from './workspaces.js';
import { updateClients } from './clients.js';
export default Window({
name: 'overview',
layer: 'overlay',

View file

@ -1,6 +1,7 @@
const { Revealer, CenterBox, Box, EventBox, Label, Overlay } = ags.Widget;
const { Hyprland } = ags.Service;
const { Gtk } = imports.gi;
import { Hyprland, Widget } from '../../imports.js';
const { Revealer, CenterBox, Box, EventBox, Label, Overlay } = Widget;
import Gtk from 'gi://Gtk';
import { WorkspaceDrop } from './dragndrop.js';
import * as VARS from './variables.js';
@ -8,6 +9,7 @@ import * as VARS from './variables.js';
const DEFAULT_STYLE = `min-width: ${VARS.SCREEN.X * VARS.SCALE}px;
min-height: ${VARS.SCREEN.Y * VARS.SCALE}px;`;
export function getWorkspaces(box) {
let children = [];
box.children.forEach(type => {
@ -61,7 +63,7 @@ export const WorkspaceRow = (className, i) => Revealer({
overlays: [Box({
style: DEFAULT_STYLE,
children: [
ags.Widget({
Widget({
type: Gtk.Fixed,
}),
Label({
@ -89,7 +91,7 @@ const Workspace = (id, name) => Revealer({
['wasActive', false],
],
connections: [[Hyprland, box => {
box._timeouts.forEach(clearTimeout);
box._timeouts.forEach(timer => timer.destroy());
let activeId = Hyprland.active.workspace.id;
let active = activeId === box._id;
@ -119,12 +121,12 @@ const Workspace = (id, name) => Revealer({
box._wasActive = true;
}
else if (box._wasActive) {
box._wasActive = false;
box._timeouts.push(setTimeout(() => {
rev.setStyle(`${DEFAULT_STYLE}
transition: margin 0.5s ease-in-out;
opacity: 1; margin-left: ${n ? '' : '-'}300px;
margin-right: ${n ? '-' : ''}300px;`);
box._wasActive = false;
}, 120));
box._timeouts.push(setTimeout(() => {
rev.setStyle(`${DEFAULT_STYLE} opacity: 0;
@ -147,7 +149,7 @@ const Workspace = (id, name) => Revealer({
overlays: [Box({
className: 'workspace',
style: DEFAULT_STYLE,
child: ags.Widget({
child: Widget({
type: Gtk.Fixed,
}),
})],

View file

@ -1,8 +1,10 @@
const { Window, CenterBox, Label } = ags.Widget;
import { Widget } from '../imports.js';
const { Window, CenterBox, Label } = Widget;
import { PopUp } from './misc/popup.js';
import { Button } from './misc/cursorbox.js'
const PowermenuWidget = CenterBox({
className: 'powermenu',
vertical: false,

View file

@ -1,10 +1,11 @@
const { Box, CenterBox, Label, Icon } = ags.Widget;
const { Network, Bluetooth, Audio } = ags.Service;
const { execAsync } = ags.Utils;
const { openWindow } = ags.App;
import { Network, Bluetooth, Audio, App, Utils, Widget } from '../../imports.js';
const { Box, CenterBox, Label, Icon } = Widget;
const { execAsync } = Utils;
const { openWindow } = App;
import { EventBox } from '../misc/cursorbox.js';
const GridButton = ({ command = () => {}, secondaryCommand = () => {}, icon } = {}) => Box({
className: 'grid-button',
children: [
@ -148,7 +149,7 @@ const SecondRow = Box({
className: 'grid-label',
connections: [[Audio, icon => {
if (Audio.speaker) {
if (Audio.speaker.isMuted) {
if (Audio.speaker.stream.isMuted) {
icon.icon = items[0];
}
else {
@ -171,7 +172,7 @@ const SecondRow = Box({
className: 'grid-label',
connections: [[Audio, icon => {
if (Audio.microphone) {
if (Audio.microphone.isMuted) {
if (Audio.microphone.stream.isMuted) {
icon.icon = itemsMic[0];
}
else {

View file

@ -1,6 +1,7 @@
const { Window, Box, Label, Revealer, Icon } = ags.Widget;
const { Mpris } = ags.Service;
const { ToggleButton } = imports.gi.Gtk;
import { Mpris, Widget } from '../../imports.js';
const { Window, Box, Label, Revealer, Icon } = Widget;
import Gtk from 'gi://Gtk';
import { ButtonGrid } from './button-grid.js';
import { SliderBox } from './slider-box.js';
@ -8,6 +9,7 @@ import Player from '../media-player/player.js';
import { EventBox } from '../misc/cursorbox.js';
import { PopUp } from '../misc/popup.js';
const QuickSettingsWidget = Box({
className: 'qs-container',
vertical: true,
@ -30,12 +32,12 @@ const QuickSettingsWidget = Box({
SliderBox,
EventBox({
child: ags.Widget({
type: ToggleButton,
child: Widget({
type: Gtk.ToggleButton,
setup: btn => {
const id = Mpris.instance.connect('changed', () => {
const id = Mpris.connect('changed', () => {
btn.set_active(Mpris.players.length > 0);
Mpris.instance.disconnect(id);
Mpris.disconnect(id);
});
},
connections: [['toggled', button => {

View file

@ -1,6 +1,6 @@
const { Box, Slider, Icon, EventBox } = ags.Widget;
const { Audio } = ags.Service;
const { execAsync } = ags.Utils;
import { Audio, Utils, Widget } from '../../imports.js';
const { Box, Slider, Icon, EventBox } = Widget;
const { execAsync } = Utils;
const items = {
101: 'audio-volume-overamplified-symbolic',
@ -10,6 +10,7 @@ const items = {
0: 'audio-volume-muted-symbolic',
};
export const SliderBox = Box({
className: 'slider-box',
vertical: true,
@ -26,7 +27,7 @@ export const SliderBox = Box({
className: 'slider-label',
connections: [[Audio, icon => {
if (Audio.speaker) {
if (Audio.speaker.isMuted) {
if (Audio.speaker.stream.isMuted) {
icon.icon = items[0];
}
else {

View file

@ -12,8 +12,7 @@ Libinput.instance.connect('device-init', () => {
});
*/
const { Service } = ags;
const { execAsync } = ags.Utils;
const { Service, Utils } = '../imports.js';
import GLib from 'gi://GLib';
import Gio from 'gi://Gio';
import GObject from 'gi://GObject';
@ -123,7 +122,7 @@ class LibinputService extends Service {
constructor() {
super();
this.debugInstances = new Map();
execAsync(['libinput', 'list-devices'])
Utils.execAsync(['libinput', 'list-devices'])
.then(out => this.parseOutput(out))
.catch(console.error);
}

View file

@ -171,7 +171,7 @@ bind = $mainMod, C, killactive,
bind = $mainMod, L, exec, $LOCK_PATH/lock.sh
bind = $mainMod SHIFT, E, exec, ags run-js 'ags.App.openWindow("powermenu")'
bindn =, Escape, exec, ags run-js 'ags.App.closeAll()'
bindn =, Escape, exec, ags run-js 'closeAll()'
bind = $mainMod SHIFT, SPACE, togglefloating,
bind = $mainMod, D, exec, ags -t applauncher
bind = $mainMod, P, pseudo, # dwindle

Binary file not shown.