ref(ags): type stuff
This commit is contained in:
parent
ae615b08f5
commit
c7558cd6ef
4 changed files with 94 additions and 50 deletions
|
@ -9,17 +9,25 @@ import { Box, Entry, Icon, Label, ListBox, Revealer, Scrollable } from 'resource
|
||||||
import PopupWindow from '../misc/popup.js';
|
import PopupWindow from '../misc/popup.js';
|
||||||
import AppItem from './app-item.js';
|
import AppItem from './app-item.js';
|
||||||
|
|
||||||
|
/** @typedef {import('types/service/applications.js').Application} App */
|
||||||
|
|
||||||
|
|
||||||
const Applauncher = ({ window_name = 'applauncher' } = {}) => {
|
const Applauncher = ({ window_name = 'applauncher' } = {}) => {
|
||||||
|
/** @type Array<any> */
|
||||||
let fzfResults;
|
let fzfResults;
|
||||||
const list = ListBox();
|
const list = ListBox();
|
||||||
|
|
||||||
/** @param {String} text */
|
/** @param {String} text */
|
||||||
const setSort = (text) => {
|
const setSort = (text) => {
|
||||||
const fzf = new Fzf(Applications.list, {
|
const fzf = new Fzf(Applications.list, {
|
||||||
selector: (app) => app.name,
|
selector: /** @param {App} app */ (app) => app.name,
|
||||||
tiebreakers: [(a, b) => b.frequency -
|
tiebreakers: [
|
||||||
a.frequency],
|
/**
|
||||||
|
* @param {App} a
|
||||||
|
* @param {App} b
|
||||||
|
*/
|
||||||
|
(a, b) => b.frequency - a.frequency,
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
fzfResults = fzf.find(text);
|
fzfResults = fzf.find(text);
|
||||||
|
@ -38,8 +46,11 @@ const Applauncher = ({ window_name = 'applauncher' } = {}) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const makeNewChildren = () => {
|
const makeNewChildren = () => {
|
||||||
|
/** @type Array<typeof imports.gi.Gtk.ListBoxRow> */
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
Array.from(list.get_children()).forEach((ch) => {
|
const rows = list.get_children();
|
||||||
|
|
||||||
|
rows.forEach((ch) => {
|
||||||
ch.destroy();
|
ch.destroy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -85,14 +96,17 @@ const Applauncher = ({ window_name = 'applauncher' } = {}) => {
|
||||||
setSort(text);
|
setSort(text);
|
||||||
let visibleApps = 0;
|
let visibleApps = 0;
|
||||||
|
|
||||||
|
/** @type Array<typeof imports.gi.Gtk.ListBoxRow> */
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
Array.from(list.get_children()).forEach((row) => {
|
const rows = list.get_children();
|
||||||
|
|
||||||
|
rows.forEach((row) => {
|
||||||
row.changed();
|
row.changed();
|
||||||
|
|
||||||
const item = row.get_children()[0];
|
const item = row.get_children()[0];
|
||||||
|
|
||||||
if (item?.attribute.app) {
|
if (item?.attribute.app) {
|
||||||
const isMatching = Array.from(fzfResults).find((r) => {
|
const isMatching = fzfResults.find((r) => {
|
||||||
return r.item.name === item.attribute.app.name;
|
return r.item.name === item.attribute.app.name;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@ import CursorBox from '../../misc/cursorbox.js';
|
||||||
|
|
||||||
const URGENT_DURATION = 1000;
|
const URGENT_DURATION = 1000;
|
||||||
|
|
||||||
|
/** @typedef {import('types/widgets/revealer.js').default} Revealer */
|
||||||
|
|
||||||
|
|
||||||
/** @property {number} id */
|
/** @property {number} id */
|
||||||
const Workspace = ({ id }) => {
|
const Workspace = ({ id }) => {
|
||||||
|
@ -32,7 +34,7 @@ const Workspace = ({ id }) => {
|
||||||
*/
|
*/
|
||||||
const update = (_, addr) => {
|
const update = (_, addr) => {
|
||||||
const workspace = Hyprland.getWorkspace(id);
|
const workspace = Hyprland.getWorkspace(id);
|
||||||
const occupied = workspace && workspace['windows'] > 0;
|
const occupied = workspace && workspace.windows > 0;
|
||||||
|
|
||||||
self.toggleClassName('occupied', occupied);
|
self.toggleClassName('occupied', occupied);
|
||||||
|
|
||||||
|
@ -43,7 +45,7 @@ const Workspace = ({ id }) => {
|
||||||
// Deal with urgent windows
|
// Deal with urgent windows
|
||||||
const client = Hyprland.getClient(addr);
|
const client = Hyprland.getClient(addr);
|
||||||
const isThisUrgent = client &&
|
const isThisUrgent = client &&
|
||||||
client['workspace']['id'] === id;
|
client.workspace.id === id;
|
||||||
|
|
||||||
if (isThisUrgent) {
|
if (isThisUrgent) {
|
||||||
self.toggleClassName('urgent', true);
|
self.toggleClassName('urgent', true);
|
||||||
|
@ -81,9 +83,12 @@ export default () => {
|
||||||
/** @param {import('types/widgets/box').default} self */
|
/** @param {import('types/widgets/box').default} self */
|
||||||
const updateHighlight = (self) => {
|
const updateHighlight = (self) => {
|
||||||
const currentId = Hyprland.active.workspace.id;
|
const currentId = Hyprland.active.workspace.id;
|
||||||
|
|
||||||
|
/** @type Array<Revealer> */
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
const indicators = self?.get_parent()?.child.child.child.children;
|
const indicators = self?.get_parent()?.child.child.child.children;
|
||||||
const currentIndex = Array.from(indicators)
|
|
||||||
|
const currentIndex = indicators
|
||||||
.findIndex((w) => w.attribute.id === currentId);
|
.findIndex((w) => w.attribute.id === currentId);
|
||||||
|
|
||||||
if (currentIndex < 0) {
|
if (currentIndex < 0) {
|
||||||
|
@ -107,36 +112,45 @@ export default () => {
|
||||||
child: Box({
|
child: Box({
|
||||||
class_name: 'workspaces',
|
class_name: 'workspaces',
|
||||||
|
|
||||||
attribute: { workspaces: [] },
|
attribute: {
|
||||||
|
/** @type Array<Revealer> */
|
||||||
|
workspaces: [],
|
||||||
|
},
|
||||||
|
|
||||||
setup: (self) => {
|
setup: (self) => {
|
||||||
|
/** @type function(void):Array<Revealer> */
|
||||||
|
const workspaces = () => self.attribute.workspaces;
|
||||||
|
|
||||||
const refresh = () => {
|
const refresh = () => {
|
||||||
Array.from(self.children).forEach((rev) => {
|
self.children.forEach((rev) => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error they are in fact revealers
|
||||||
rev.reveal_child = false;
|
rev.reveal_child = false;
|
||||||
});
|
});
|
||||||
Array.from(self.attribute.workspaces).forEach((ws) => {
|
|
||||||
|
workspaces().forEach((ws) => {
|
||||||
ws.reveal_child = true;
|
ws.reveal_child = true;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const updateWorkspaces = () => {
|
const updateWorkspaces = () => {
|
||||||
Hyprland.workspaces.forEach((ws) => {
|
Hyprland.workspaces.forEach((ws) => {
|
||||||
const currentWs = Array.from(self.children)
|
const currentWs = self.children.find((ch) => {
|
||||||
// @ts-expect-error
|
return ch.attribute.id === ws.id;
|
||||||
.find((ch) => ch.attribute.id === ws['id']);
|
});
|
||||||
|
|
||||||
if (!currentWs && ws['id'] > 0) {
|
if (!currentWs && ws.id > 0) {
|
||||||
self.add(Workspace({ id: ws['id'] }));
|
self.add(Workspace({ id: ws.id }));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
self.show_all();
|
self.show_all();
|
||||||
|
|
||||||
// Make sure the order is correct
|
// Make sure the order is correct
|
||||||
Array.from(self.attribute.workspaces)
|
workspaces().forEach((workspace, i) => {
|
||||||
.forEach((workspace, i) => {
|
// @ts-expect-error
|
||||||
workspace.get_parent()
|
workspace?.get_parent()?.reorder_child(
|
||||||
.reorder_child(workspace, i);
|
workspace,
|
||||||
|
i,
|
||||||
|
);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,7 +159,7 @@ export default () => {
|
||||||
self.children.filter((ch) => {
|
self.children.filter((ch) => {
|
||||||
return Hyprland.workspaces.find((ws) => {
|
return Hyprland.workspaces.find((ws) => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
return ws['id'] === ch.attribute.id;
|
return ws.id === ch.attribute.id;
|
||||||
});
|
});
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
}).sort((a, b) => a.attribute.id - b.attribute.id);
|
}).sort((a, b) => a.attribute.id - b.attribute.id);
|
||||||
|
|
|
@ -6,7 +6,7 @@ import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
||||||
import { Box, Icon, Label, Button } from 'resource:///com/github/Aylur/ags/widget.js';
|
import { Box, Icon, Label, Button } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
import { lookUpIcon } from 'resource:///com/github/Aylur/ags/utils.js';
|
import { lookUpIcon } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
|
|
||||||
import GLib from 'gi://GLib';
|
const { GLib } = imports.gi;
|
||||||
|
|
||||||
const setTime = (time) => {
|
const setTime = (time) => {
|
||||||
return GLib.DateTime
|
return GLib.DateTime
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import App from 'resource:///com/github/Aylur/ags/app.js';
|
import App from 'resource:///com/github/Aylur/ags/app.js';
|
||||||
|
// @ts-expect-error
|
||||||
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
|
import Bluetooth from 'resource:///com/github/Aylur/ags/service/bluetooth.js';
|
||||||
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
|
import Network from 'resource:///com/github/Aylur/ags/service/network.js';
|
||||||
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
import Variable from 'resource:///com/github/Aylur/ags/variable.js';
|
||||||
|
@ -14,17 +15,29 @@ import { NetworkMenu } from './network.js';
|
||||||
import { BluetoothMenu } from './bluetooth.js';
|
import { BluetoothMenu } from './bluetooth.js';
|
||||||
|
|
||||||
const SPACING = 28;
|
const SPACING = 28;
|
||||||
|
|
||||||
|
|
||||||
const ButtonStates = [];
|
const ButtonStates = [];
|
||||||
|
|
||||||
|
/** @typedef {import('types/widgets/widget').default} Widget */
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{
|
||||||
|
* command?: function
|
||||||
|
* secondary_command?: function
|
||||||
|
* onOpen?: function(Widget):void
|
||||||
|
* icon: any
|
||||||
|
* indicator?: any
|
||||||
|
* menu?: any
|
||||||
|
* }} o
|
||||||
|
*/
|
||||||
const GridButton = ({
|
const GridButton = ({
|
||||||
command = () => { /**/ },
|
command = () => {/**/},
|
||||||
secondaryCommand = () => { /**/ },
|
secondary_command = () => {/**/},
|
||||||
onOpen = () => { /**/ },
|
onOpen = () => {/**/},
|
||||||
icon,
|
icon,
|
||||||
indicator,
|
indicator,
|
||||||
menu,
|
menu,
|
||||||
} = {}) => {
|
}) => {
|
||||||
const Activated = Variable(false);
|
const Activated = Variable(false);
|
||||||
|
|
||||||
ButtonStates.push(Activated);
|
ButtonStates.push(Activated);
|
||||||
|
@ -32,7 +45,7 @@ const GridButton = ({
|
||||||
// Allow setting icon dynamically or statically
|
// Allow setting icon dynamically or statically
|
||||||
if (typeof icon === 'string') {
|
if (typeof icon === 'string') {
|
||||||
icon = Icon({
|
icon = Icon({
|
||||||
className: 'grid-label',
|
class_name: 'grid-label',
|
||||||
icon,
|
icon,
|
||||||
setup: (self) => {
|
setup: (self) => {
|
||||||
self.hook(Activated, () => {
|
self.hook(Activated, () => {
|
||||||
|
@ -45,7 +58,7 @@ const GridButton = ({
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
icon = Icon({
|
icon = Icon({
|
||||||
className: 'grid-label',
|
class_name: 'grid-label',
|
||||||
setup: (self) => {
|
setup: (self) => {
|
||||||
self
|
self
|
||||||
.hook(...icon)
|
.hook(...icon)
|
||||||
|
@ -60,7 +73,7 @@ const GridButton = ({
|
||||||
|
|
||||||
if (indicator) {
|
if (indicator) {
|
||||||
indicator = Label({
|
indicator = Label({
|
||||||
className: 'sub-label',
|
class_name: 'sub-label',
|
||||||
justification: 'left',
|
justification: 'left',
|
||||||
truncate: 'end',
|
truncate: 'end',
|
||||||
maxWidthChars: 12,
|
maxWidthChars: 12,
|
||||||
|
@ -82,15 +95,15 @@ const GridButton = ({
|
||||||
vertical: true,
|
vertical: true,
|
||||||
children: [
|
children: [
|
||||||
Box({
|
Box({
|
||||||
className: 'grid-button',
|
class_name: 'grid-button',
|
||||||
children: [
|
children: [
|
||||||
|
|
||||||
CursorBox({
|
CursorBox({
|
||||||
className: 'left-part',
|
class_name: 'left-part',
|
||||||
|
|
||||||
on_primary_click_release: () => {
|
on_primary_click_release: () => {
|
||||||
if (Activated.value) {
|
if (Activated.value) {
|
||||||
secondaryCommand();
|
secondary_command();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
command();
|
command();
|
||||||
|
@ -101,7 +114,7 @@ const GridButton = ({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
CursorBox({
|
CursorBox({
|
||||||
className: 'right-part',
|
class_name: 'right-part',
|
||||||
|
|
||||||
on_primary_click_release: () => {
|
on_primary_click_release: () => {
|
||||||
ButtonStates.forEach((state) => {
|
ButtonStates.forEach((state) => {
|
||||||
|
@ -112,10 +125,13 @@ const GridButton = ({
|
||||||
Activated.value = !Activated.value;
|
Activated.value = !Activated.value;
|
||||||
},
|
},
|
||||||
|
|
||||||
onHover: (self) => {
|
on_hover: (self) => {
|
||||||
if (menu) {
|
if (menu) {
|
||||||
const rowMenu = self.get_parent().get_parent()
|
const rowMenu =
|
||||||
.get_parent().get_parent().children[1];
|
self.get_parent()
|
||||||
|
?.get_parent()?.get_parent()
|
||||||
|
?.get_parent()?.get_parent()
|
||||||
|
?.children[1];
|
||||||
|
|
||||||
const isSetup = rowMenu.get_children()
|
const isSetup = rowMenu.get_children()
|
||||||
.find((ch) => ch === menu);
|
.find((ch) => ch === menu);
|
||||||
|
@ -129,7 +145,7 @@ const GridButton = ({
|
||||||
|
|
||||||
child: Icon({
|
child: Icon({
|
||||||
icon: `${App.configDir }/icons/down-large.svg`,
|
icon: `${App.configDir }/icons/down-large.svg`,
|
||||||
className: 'grid-chev',
|
class_name: 'grid-chev',
|
||||||
|
|
||||||
setup: (self) => {
|
setup: (self) => {
|
||||||
self.hook(Activated, () => {
|
self.hook(Activated, () => {
|
||||||
|
@ -162,7 +178,7 @@ const Row = ({ buttons } = {}) => {
|
||||||
|
|
||||||
children: [
|
children: [
|
||||||
Box({
|
Box({
|
||||||
className: 'button-row',
|
class_name: 'button-row',
|
||||||
hpack: 'center',
|
hpack: 'center',
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
@ -189,7 +205,7 @@ const FirstRow = () => Row({
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => Network.toggleWifi(),
|
command: () => Network.toggleWifi(),
|
||||||
|
|
||||||
secondaryCommand: () => {
|
secondary_command: () => {
|
||||||
// TODO: connection editor
|
// TODO: connection editor
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -211,7 +227,7 @@ const FirstRow = () => Row({
|
||||||
//
|
//
|
||||||
},
|
},
|
||||||
|
|
||||||
secondaryCommand: () => {
|
secondary_command: () => {
|
||||||
//
|
//
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -221,7 +237,7 @@ const FirstRow = () => Row({
|
||||||
GridButton({
|
GridButton({
|
||||||
command: () => Bluetooth.toggle(),
|
command: () => Bluetooth.toggle(),
|
||||||
|
|
||||||
secondaryCommand: () => {
|
secondary_command: () => {
|
||||||
// TODO: bluetooth connection editor
|
// TODO: bluetooth connection editor
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -261,7 +277,7 @@ const SecondRow = () => Row({
|
||||||
'@DEFAULT_SINK@', 'toggle']).catch(print);
|
'@DEFAULT_SINK@', 'toggle']).catch(print);
|
||||||
},
|
},
|
||||||
|
|
||||||
secondaryCommand: () => {
|
secondary_command: () => {
|
||||||
execAsync(['bash', '-c', 'pavucontrol'])
|
execAsync(['bash', '-c', 'pavucontrol'])
|
||||||
.catch(print);
|
.catch(print);
|
||||||
},
|
},
|
||||||
|
@ -277,7 +293,7 @@ const SecondRow = () => Row({
|
||||||
'@DEFAULT_SOURCE@', 'toggle']).catch(print);
|
'@DEFAULT_SOURCE@', 'toggle']).catch(print);
|
||||||
},
|
},
|
||||||
|
|
||||||
secondaryCommand: () => {
|
secondary_command: () => {
|
||||||
execAsync(['bash', '-c', 'pavucontrol'])
|
execAsync(['bash', '-c', 'pavucontrol'])
|
||||||
.catch(print);
|
.catch(print);
|
||||||
},
|
},
|
||||||
|
@ -291,14 +307,14 @@ const SecondRow = () => Row({
|
||||||
command: () => {
|
command: () => {
|
||||||
execAsync(['lock']).catch(print);
|
execAsync(['lock']).catch(print);
|
||||||
},
|
},
|
||||||
secondaryCommand: () => App.openWindow('powermenu'),
|
secondary_command: () => App.openWindow('powermenu'),
|
||||||
icon: 'system-lock-screen-symbolic',
|
icon: 'system-lock-screen-symbolic',
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
export default () => Box({
|
export default () => Box({
|
||||||
className: 'button-grid',
|
class_name: 'button-grid',
|
||||||
vertical: true,
|
vertical: true,
|
||||||
hpack: 'center',
|
hpack: 'center',
|
||||||
children: [
|
children: [
|
||||||
|
|
Loading…
Reference in a new issue