This commit is contained in:
Nico
2024-10-31 10:33:46 +01:00
commit ad6d893cb0
237 changed files with 19793 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
import PopupWindow from "../PopupWindow.js"
import Workspace from "./Workspace.js"
import options from "../../options.js"
import { range } from "../../lib/utils.js"
const hyprland = await Service.import("hyprland")
const Overview = (ws) => Widget.Box({
class_name: "overview horizontal",
// spacing: 10,
children: ws > 0
? range(ws).map(Workspace)
: hyprland.workspaces
.map(({ id }) => Workspace(id))
.sort((a, b) => a.attribute.id - b.attribute.id),
setup: w => {
if (ws > 0)
return
w.hook(hyprland, (w, id) => {
if (id === undefined)
return
w.children = w.children
.filter(ch => ch.attribute.id !== Number(id))
}, "workspace-removed")
w.hook(hyprland, (w, id) => {
if (id === undefined)
return
w.children = [...w.children, Workspace(Number(id))]
.sort((a, b) => a.attribute.id - b.attribute.id)
}, "workspace-added")
},
})
export default () => PopupWindow({
name: "overview",
layout: "center",
transition: "slide_down",
child: Overview(options.overview.workspaces),
})

View File

@@ -0,0 +1,51 @@
import { createSurfaceFromWidget, icon } from "../../lib/utils.js"
import Gdk from "gi://Gdk"
import Gtk from "gi://Gtk?version=3.0"
import options from "../../options.js"
import icons from "../../lib/icons.js"
const monochrome = options.overview.monochromeIcon
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)]
const scale = (size) => (options.overview.scale / 100) * size
const hyprland = await Service.import("hyprland")
const apps = await Service.import("applications")
const dispatch = (args) => hyprland.messageAsync(`dispatch ${args}`)
const Icon = (m, c) => {
const app = apps.list.find(app => app.match(c))
if (!app)
return icons.fallback.executable
return icon(
app.icon_name + (m ? "-symbolic" : ""),
icons.fallback.executable,
)
}
export default ({ address, size: [w, h], class: c, title }) => Widget.Button({
class_name: "client",
attribute: { address },
tooltip_text: `${title}`,
child: Widget.Icon({
class_name: "overview-icon",
css: `
min-width: ${scale(w)}px;
min-height: ${scale(h)}px;
`,
icon: Icon(monochrome, c),
}),
on_secondary_click: () => dispatch(`closewindow address:${address}`),
on_clicked: () => {
dispatch(`focuswindow address:${address}`)
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),
})

View File

@@ -0,0 +1,59 @@
import Window from "./Window.js"
import Gdk from "gi://Gdk"
import Gtk from "gi://Gtk?version=3.0"
import options from "../../options.js"
const TARGET = [Gtk.TargetEntry.new("text/plain", Gtk.TargetFlags.SAME_APP, 0)]
const scale = (size) => (options.overview.scale / 100) * size
const hyprland = await Service.import("hyprland")
const dispatch = (args) => hyprland.messageAsync(`dispatch ${args}`)
const size = (id) => {
const def = { h: 1080, w: 1920 }
const ws = hyprland.getWorkspace(id)
if (!ws)
return def
const mon = hyprland.getMonitor(ws.monitorID)
return mon ? { h: mon.height, w: mon.width } : def
}
export default (id) => Widget.Box({
attribute: { id },
tooltipText: `${id}`,
class_name: "workspace",
vpack: "center",
css: `
min-width: ${scale(size(id).w)}px;
min-height: ${scale(size(id).h)}px;
`,
setup: box => box.hook(hyprland, () => {
box.toggleClassName("active", hyprland.active.workspace.id === id)
}),
child: Widget.EventBox({
expand: true,
on_primary_click: () => {
App.closeWindow("overview")
dispatch(`workspace ${id}`)
},
setup: eventbox => {
eventbox.drag_dest_set(Gtk.DestDefaults.ALL, TARGET, Gdk.DragAction.COPY)
eventbox.connect("drag-data-received", (_w, _c, _x, _y, data) => {
const address = new TextDecoder().decode(data.get_data())
dispatch(`movetoworkspacesilent ${id},address:${address}`)
})
},
child: Widget.Fixed().hook(hyprland, fixed => {
fixed.get_children().forEach(ch => ch.destroy())
hyprland.clients
.filter(({ workspace }) => workspace.id === id)
.forEach(c => {
const x = c.at[0] - (hyprland.getMonitor(c.monitor)?.x || 0)
const y = c.at[1] - (hyprland.getMonitor(c.monitor)?.y || 0)
c.mapped && fixed.put(Window(c), scale(x), scale(y))
})
fixed.show_all()
}, "notify::clients"),
}),
})