mirror of
https://github.com/Theaninova/TheaninovOS.git
synced 2026-01-09 01:02:49 +00:00
refactor: make the whole thing more generic
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js";
|
||||
import App from "resource:///com/github/Aylur/ags/app.js";
|
||||
import { createSurfaceFromWidget, substitute } from "../utils.js";
|
||||
import Gdk from "gi://Gdk";
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
import options from "../options.js";
|
||||
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js";
|
||||
import icons from "../icons.js";
|
||||
|
||||
const SCALE = 0.08;
|
||||
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)];
|
||||
|
||||
/** @param {string} args */
|
||||
const dispatch = (args) => Hyprland.sendMessage(`dispatch ${args}`);
|
||||
|
||||
/** @param {string} str */
|
||||
const icon = (str) => {
|
||||
const icon = substitute(options.substitutions.icons, str);
|
||||
if (Utils.lookUpIcon(icon)) return icon;
|
||||
|
||||
console.warn("no icon", icon);
|
||||
return icons.fallback.executable;
|
||||
};
|
||||
|
||||
export default ({ address, size: [w, h], class: c, title }) =>
|
||||
Widget.Button({
|
||||
class_name: "client",
|
||||
tooltip_text: `${title}`,
|
||||
child: Widget.Icon({
|
||||
css: `
|
||||
min-width: ${w * SCALE}px;
|
||||
min-height: ${h * SCALE}px;
|
||||
`,
|
||||
icon: icon(c),
|
||||
}),
|
||||
on_secondary_click: () => dispatch(`closewindow address:${address}`),
|
||||
on_clicked: () =>
|
||||
dispatch(`focuswindow address:${address}`).then(() =>
|
||||
App.closeWindow("overview"),
|
||||
),
|
||||
|
||||
setup: (btn) =>
|
||||
btn
|
||||
.on("drag-data-get", (_w, _c, data) =>
|
||||
data.set_text(address, address.length),
|
||||
)
|
||||
.on("drag-begin", (_, context) => {
|
||||
Gtk.drag_set_icon_surface(context, createSurfaceFromWidget(btn));
|
||||
btn.toggleClassName("hidden", true);
|
||||
})
|
||||
.on("drag-end", () => btn.toggleClassName("hidden", false))
|
||||
.drag_source_set(
|
||||
Gdk.ModifierType.BUTTON1_MASK,
|
||||
TARGET,
|
||||
Gdk.DragAction.COPY,
|
||||
),
|
||||
});
|
||||
@@ -0,0 +1,52 @@
|
||||
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js";
|
||||
import PopupWindow from "../misc/PopupWindow.js";
|
||||
import Workspace from "./Workspace.js";
|
||||
import options from "../options.js";
|
||||
import { range } from "../utils.js";
|
||||
|
||||
const ws = options.workspaces;
|
||||
|
||||
const Overview = () =>
|
||||
Widget.Box({
|
||||
children: [Workspace(0)], // for type infer
|
||||
setup: (self) =>
|
||||
Utils.idle(() => {
|
||||
self.hook(ws, () => {
|
||||
self.children = range(ws.value).map(Workspace);
|
||||
update(self);
|
||||
children(self);
|
||||
});
|
||||
self.hook(Hyprland, update);
|
||||
self.hook(Hyprland, children, "notify::workspaces");
|
||||
update(self);
|
||||
children(self);
|
||||
}),
|
||||
});
|
||||
|
||||
/** @param {ReturnType<typeof Overview>} box */
|
||||
const update = (box) => {
|
||||
if (!box.get_parent()?.visible) return;
|
||||
|
||||
Hyprland.sendMessage("j/clients")
|
||||
.then((clients) => {
|
||||
box.children.forEach((ws) => {
|
||||
ws.attribute(JSON.parse(clients));
|
||||
});
|
||||
})
|
||||
.catch(console.error);
|
||||
};
|
||||
|
||||
/** @param {import('types/widgets/box').default} box */
|
||||
const children = (box) => {
|
||||
if (ws.value === 0) {
|
||||
box.children = Hyprland.workspaces
|
||||
.sort((ws1, ws2) => ws1.id - ws2.id)
|
||||
.map(({ id }) => Workspace(id));
|
||||
}
|
||||
};
|
||||
|
||||
export default () =>
|
||||
PopupWindow({
|
||||
name: "overview",
|
||||
child: Overview(),
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
import Hyprland from "resource:///com/github/Aylur/ags/service/hyprland.js";
|
||||
import Widget from "resource:///com/github/Aylur/ags/widget.js";
|
||||
import * as Utils from "resource:///com/github/Aylur/ags/utils.js";
|
||||
import Gdk from "gi://Gdk";
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
import Client from "./Client.js";
|
||||
|
||||
const SCALE = 0.08;
|
||||
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)];
|
||||
|
||||
/** @param {string} args */
|
||||
const dispatch = (args) => Utils.execAsync(`hyprctl dispatch ${args}`);
|
||||
|
||||
/** @param {number} index */
|
||||
export default (index) => {
|
||||
const fixed = Gtk.Fixed.new();
|
||||
|
||||
return Widget.Box({
|
||||
class_name: "workspace",
|
||||
vpack: "center",
|
||||
css: `
|
||||
min-width: ${3840 * SCALE}px;
|
||||
min-height: ${2160 * SCALE}px;
|
||||
`,
|
||||
setup: (box) =>
|
||||
box.hook(Hyprland, () => {
|
||||
box.toggleClassName("active", Hyprland.active.workspace.id === index);
|
||||
}),
|
||||
child: Widget.EventBox({
|
||||
hexpand: true,
|
||||
vexpand: true,
|
||||
on_primary_click: () => dispatch(`workspace ${index}`),
|
||||
setup: (eventbox) => {
|
||||
eventbox.drag_dest_set(
|
||||
Gtk.DestDefaults.ALL,
|
||||
TARGET,
|
||||
Gdk.DragAction.COPY,
|
||||
);
|
||||
eventbox.connect("drag-data-received", (_w, _c, _x, _y, data) => {
|
||||
dispatch(`movetoworkspacesilent ${index},address:${data.get_text()}`);
|
||||
});
|
||||
},
|
||||
child: fixed,
|
||||
}),
|
||||
|
||||
/** @param {Array<import('types/service/hyprland').Client>} clients */
|
||||
attribute: (clients) => {
|
||||
fixed.get_children().forEach((ch) => ch.destroy());
|
||||
clients
|
||||
.filter(({ workspace: { id } }) => id === index)
|
||||
.forEach((c) => {
|
||||
c.at[0] -= Hyprland.getMonitor(c.monitor)?.x || 0;
|
||||
c.at[1] -= Hyprland.getMonitor(c.monitor)?.y || 0;
|
||||
c.mapped && fixed.put(Client(c), c.at[0] * SCALE, c.at[1] * SCALE);
|
||||
});
|
||||
|
||||
fixed.show_all();
|
||||
},
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user