🔧 chore: use a different approach to compile stylesheets

also fixed promise calls not working(execAsync, subprocess), restored previous control center tile implementation temporarily
This commit is contained in:
retrozinndev
2025-08-12 14:30:47 -03:00
parent eb4b5a847f
commit 0191afef16
9 changed files with 179 additions and 482 deletions
+48 -56
View File
@@ -2,7 +2,7 @@
// import app from "ags/gtk4/app";
// fix can't convert non-null pointer to JS value (thanks Aylur!)
import "/usr/share/ags/js/src/overrides";
import "ags/overrides";
import {
PluginApps,
PluginClipboard,
@@ -24,10 +24,10 @@ import { Gdk, Gtk } from "ags/gtk4";
import { createRoot, getScope } from "ags";
import { triggerOSD } from "./window/OSD";
import { programArgs, programInvocationName } from "system";
import { encoder, decoder } from "./scripts/utils";
import { setConsoleLogDomain } from "console";
import { initPlayer } from "./scripts/media";
import GObject, { register } from "ags/gobject";
import AstalNotifd from "gi://AstalNotifd";
import GLib from "gi://GLib?version=2.0";
import Gio from "gi://Gio?version=2.0";
@@ -50,16 +50,13 @@ Adw.init();
GLib.unsetenv("LD_PRELOAD");
@register({ GTypeName: "Shell", Implements: [Gio.ActionGroup]})
export class Shell extends Gtk.Application implements Gio.ActionMap {
export class Shell extends Adw.Application implements Gio.ActionMap {
private static instance: Shell;
#loop!: GLib.MainLoop;
#scope!: ReturnType<typeof getScope>;
#connections = new Map<GObject.Object, Array<number> | number>();
#stylesheet: Uint8Array|undefined;
#styleProvider: Gtk.CssProvider;
#providers: Array<Gtk.CssProvider> = [];
#gresource: Gio.Resource|null = null;
#icons: Record<string, Gio.BytesIcon> = {};
get scope() { return this.#scope; }
@@ -70,7 +67,8 @@ export class Shell extends Gtk.Application implements Gio.ActionMap {
version: COLORSHELL_VERSION ?? "0.0.0-unknown",
});
this.#styleProvider = Gtk.CssProvider.new();
setConsoleLogDomain("colorshell");
try {
// load gresource from build-defined value + support env variables
this.#gresource = Gio.Resource.load(GRESOURCES_FILE.split('/').filter(s =>
@@ -89,19 +87,8 @@ export class Shell extends Gtk.Application implements Gio.ActionMap {
Gio.resources_register(this.#gresource);
// add icons
Gio.resources_enumerate_children(
"/io/github/retrozinndev/colorshell",
Gio.ResourceLookupFlags.NONE
).filter(name =>
/symbolic$/.test(name) || name.endsWith("svg")
).map(name =>
`/io/github/retrozinndev/colorshell/${name}`
).forEach(path => {
const name = path.split('/')[path.split('/').length - 1];
const iconBytes = Gio.resources_lookup_data(path, null);
this.#icons[name] = Gio.BytesIcon.new(iconBytes);
});
Gtk.IconTheme.get_for_display(Gdk.Display.get_default()!)
.add_resource_path("/io/github/retrozinndev/colorshell/icons")
} catch(_e) {
const e = _e as Error;
console.error(`Error: couldn't load gresource! Stderr: ${e.message}\n${e.stack}`);
@@ -122,37 +109,48 @@ export class Shell extends Gtk.Application implements Gio.ActionMap {
}
public resetStyle(): void {
this.#stylesheet = undefined;
Gtk.StyleContext.remove_provider_for_display(
Gdk.Display.get_default()!,
this.#styleProvider
this.#providers.forEach(provider =>
Gtk.StyleContext.remove_provider_for_display(
Gdk.Display.get_default()!,
provider
)
);
}
public getGIcon(name: string): Gio.BytesIcon {
if(!Object.hasOwn(this.#icons, name))
throw new Error(`Colorshell: No gicon found with name "${name}"`);
public removeProvider(provider: Gtk.CssProvider): void {
if(!this.#providers.includes(provider)) {
console.warn("Colorshell: Couldn't find the provided GtkCssProvider to remove. Was it added before?");
return;
}
return this.#icons[name];
for(let i = 0; i < this.#providers.length; i++) {
const prov = this.#providers[i];
if(prov === provider) {
this.#providers.splice(i, 1);
Gtk.StyleContext.remove_provider_for_display(
Gdk.Display.get_default()!,
provider
);
break;
}
}
}
public applyStyle(stylesheet: string): void {
const previous = this.#stylesheet ? decoder.decode(this.#stylesheet) : undefined;
let final = "";
try {
const provider = Gtk.CssProvider.new();
provider.load_from_string(stylesheet)
this.#providers.push(provider);
if(previous)
final = previous + "\n";
this.#stylesheet = encoder.encode(stylesheet);
final = final.concat(stylesheet);
this.#styleProvider.load_from_string(final);
Gtk.StyleContext.add_provider_for_display(
Gdk.Display.get_default()!,
this.#styleProvider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
Gtk.StyleContext.add_provider_for_display(
Gdk.Display.get_default()!,
provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
);
} catch(e) {
console.error(`Colorshell: Couldn't apply style. Stderr: ${e}`);
return;
}
}
vfunc_command_line(cmd: Gio.ApplicationCommandLine): number {
@@ -186,26 +184,22 @@ export class Shell extends Gtk.Application implements Gio.ActionMap {
vfunc_activate(): void {
super.vfunc_activate();
this.hold();
this.main();
}
private main(): void {
this.#loop = GLib.MainLoop.new(null, false);
createRoot((dispose) => {
console.log(`Colorshell: Initializing things`);
this.#connections.set(this, this.connect("shutdown", () => dispose()));
this.#scope = getScope();
initPlayer();
Stylesheet.getDefault();
// Init clipboard module
Clipboard.getDefault();
console.log("Initializing wallpaper handler");
console.log("Colorshell: Initializing wallpaper & Stylesheet handlers");
Wallpaper.getDefault();
Stylesheet.getDefault();
console.log("Adding runner plugins");
runnerPlugins.forEach(plugin => Runner.addPlugin(plugin));
@@ -233,12 +227,10 @@ export class Shell extends Gtk.Application implements Gio.ActionMap {
ids.forEach(id => obj.disconnect(id))
: obj.disconnect(ids));
});
this.#loop.run();
}
quit(): void {
this.#loop.is_running() && this.#loop.quit();
this.release();
super.quit();
}
}
@@ -284,4 +276,4 @@ export const generalConfig = new Config<keyof typeof generalConfigDefaults,
`${GLib.get_user_config_dir()}/colorshell/config.json`, generalConfigDefaults
);
Shell.getDefault().run([ programInvocationName, ...programArgs ]);
Shell.getDefault().runAsync([ programInvocationName, ...programArgs ]);
-27
View File
@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/io/github/retrozinndev/colorshell">
<!-- Sass -->
<file alias="style">style.scss</file>
<file alias="style-apps-window">style/_apps-window.scss</file>
<file alias="style-bar">style/_bar.scss</file>
<file alias="style-center-window">style/_center-window.scss</file>
<file alias="style-control-center">style/_control-center.scss</file>
<file alias="style-float-notifications">style/_float-notifications.scss</file>
<file alias="style-logout-menu">style/_logout-menu.scss</file>
<file alias="style-mixins">style/_mixins.scss</file>
<file alias="style-osd">style/_osd.scss</file>
<file alias="style-runner">style/_runner.scss</file>
<!-- Icons -->
<file alias="applications-other-symbolic">icons/applications-other-symbolic.svg</file>
<file alias="arrow-circular-top-right-symbolic">icons/arrow-circular-top-right-symbolic.svg</file>
<file alias="circle-filled-symbolic">icons/circle-filled-symbolic.svg</file>
<file alias="hourglass-symbolic">icons/hourglass-symbolic.svg</file>
<file alias="loop-arrow-symbolic">icons/loop-arrow-symbolic.svg</file>
<file alias="minus-circle-filled-symbolic">icons/minus-circle-filled-symbolic.svg</file>
<file alias="shield-danger-symbolic">icons/shield-danger-symbolic.svg</file>
<file alias="shield-safe-symbolic">icons/shield-safe-symbolic.svg</file>
<file alias="user-trash-symbolic">icons/user-trash-symbolic.svg</file>
</gresource>
</gresources>
+1 -3
View File
@@ -7,7 +7,6 @@ import { timeout } from "ags/time";
import AstalHyprland from "gi://AstalHyprland";
import AstalIO from "gi://AstalIO";
import { Shell } from "../app";
export namespace Runner {
@@ -245,8 +244,7 @@ export function openRunner(props: RunnerProps, placeholders?: Array<Result>): As
heightRequest={props.height} exclusivity={Astal.Exclusivity.IGNORE} halign={Gtk.Align.CENTER}
marginTop={(AstalHyprland.get_default().get_monitor(mon)?.height / 2) - (props.height! / 2)}
valign={Gtk.Align.START} hexpand orientation={Gtk.Orientation.VERTICAL}
$={(self) => {
self.set_application(Shell.getDefault());
$={() => {
plugins.forEach(plugin =>
plugin.init?.());
+104 -73
View File
@@ -1,8 +1,8 @@
import { monitorFile, readFile } from "ags/file";
import { monitorFile, readFile, writeFileAsync } from "ags/file";
import { decoder } from "./utils";
import { execAsync } from "ags/process";
import { Wallpaper } from "./wallpaper";
import { Shell } from "../app";
import { exec } from "ags/process";
import Gio from "gi://Gio?version=2.0";
import GLib from "gi://GLib?version=2.0";
@@ -12,20 +12,15 @@ import GLib from "gi://GLib?version=2.0";
export class Stylesheet {
private static instance: Stylesheet;
#outputPath = Gio.File.new_for_path(`${GLib.get_user_cache_dir()}/colorshell/style`);
#sassStyles!: {
colors: string;
general: string;
#stylesPaths: Array<string>;
readonly #sassStyles = {
modules: ["sass:color"].map(mod => `@use "${mod}";`).join('\n'),
colors: "",
mixins: "",
rules: ""
};
public get stylePath() { return this.#outputPath.get_path()!; }
public compileSass(): string {
console.log("Stylesheet: Compiling Sass");
exec(`echo '${this.#sassStyles.colors}\n${this.#sassStyles.general}' \
| sass --stdin --no-source-map -s "${this.stylePath}.css"`);
return readFile(`${this.stylePath}/style.css`);
}
public static getDefault(): Stylesheet {
if(!this.instance)
@@ -34,54 +29,36 @@ export class Stylesheet {
return this.instance;
}
private bundle(): string {
return `${this.#sassStyles.modules}\n\n${this.#sassStyles.colors
}\n${this.#sassStyles.mixins}\n${this.#sassStyles.rules}`.trim();
}
private async compile(): Promise<void> {
const sass = this.bundle();
await writeFileAsync(`${this.stylePath}/sass.scss`, sass).catch(_e => {
const e = _e as Error;
console.error(`Stylesheet: Couldn't write Sass to cache. Stderr: ${
e.message}\n${e.stack}`);
});
await execAsync(
`bash -c "sass ${this.stylePath}/sass.scss ${this.stylePath}/style.css"`
).catch(_e => {
const e = _e as Error;
console.error(`Stylesheet: An error occurred on compile-time! Stderr: ${
e.message}\n${e.stack}`);
});
}
public getStyleSheet(): string {
const stylesNames: Array<string> = Gio.resources_enumerate_children(
"/io/github/retrozinndev/colorshell",
Gio.ResourceLookupFlags.NONE
).filter(name =>
name.startsWith("style")
).map(name =>
`/io/github/retrozinndev/colorshell/${name}`
);
return stylesNames.map(path =>
Gio.resources_lookup_data(path, Gio.ResourceLookupFlags.NONE)
).map(bytes => decoder.decode(bytes.get_data()!)).join('\n');
return readFile(`${this.stylePath}/style.css`);
}
/*
private objectToStyleSheet(colors: object & Record<string, string>): string {
return Object.keys(colors).map(name => {
const isBg = name.toLowerCase().startsWith('bg') || name.toLowerCase() === "background",
color = colors[name as keyof typeof colors];
// this will transform the color name's casing, example: bgPrimary -> bg-primary
return `
.${this.kebabify(name)} {
${isBg ? `background: ${color}` : `color: ${color}`}
}
`.trim();
}).join('\n')
}
private kebabify(str: string) {
return str.replace(/[A-Z]/, (c) => `-${c.toLowerCase()}`);
}
*/
public getColors(): string {
public getColorDefinitions(): string {
const data = Wallpaper.getDefault().getData();
const colors = {
bgPrimary: `color.adjust($color: ${data.colors.color1}, $lightness: -28%)`,
bgSecondary: `color.adjust($color: ${data.colors.color1}, $lightness: -16%)`,
bgTertiary: `color.adjust($color: ${data.colors.color1}, $lightness: -4%)`,
bgLight: data.special.foreground,
bgTranslucent: `rgba(color.adjust($color: ${data.colors.color1}, $lightness: -28%), .7)`,
bgTranslucentPrimary: `rgba(color.adjust($color: ${data.colors.color1}, $lightness: -28%), .7)`,
bgTranslucentSecondary: `rgba(color.adjust($color: ${data.colors.color1}, $lightness: -16%), .7)`,
fgPrimary: data.special.foreground,
fgLight: `color.adjust($color: ${data.colors.color1}, $lightness: -28%)`,
fgDisabled: `color.adjust($color: ${data.special.foreground}, $lightness: -11%)`
...data.special,
...data.colors
};
return Object.keys(colors).map(name =>
@@ -89,28 +66,82 @@ export class Stylesheet {
).join('\n');
}
private updateColors(): void {
this.#sassStyles.colors = this.getColors();
Shell.getDefault().applyStyle(this.compileSass());
private organizeModuleImports(sass: string) {
return sass.replaceAll(
/[@](use|forward|import) ["'](.*)["']?[;]?\n/gi,
(_, impType, imp) => {
imp = (imp as string).replace(/["';]/g, "");
// add sass modules on top
if(!this.#sassStyles.modules.includes(imp) && /^(sass|.*http|.*https)/.test(imp))
this.#sassStyles.modules = this.#sassStyles.modules.concat(`\n@${impType} "${imp}";`);
return "";
}
).replace(/(colors|mixins|wal)\./g, "");
}
public compileApply(): void {
this.compile().then(() => {
Shell.getDefault().resetStyle();
Shell.getDefault().applyStyle(this.getStyleSheet());
}).catch(_e => {
const e = _e as Error;
console.error(`Stylesheet: An error occurred at compile-time. Stderr: ${
e.message}\n${e.stack}`);
});
}
private getStyleData(path: string): string {
return decoder.decode(Gio.resources_lookup_data(path, null).get_data()!);
}
constructor() {
try {
!this.#outputPath.query_exists(null) &&
this.#outputPath.make_directory_with_parents(null);
} catch(_e) {
const e = _e as Error;
console.error(`Stylesheet: couldn't create output path. Stderr: ${e.message}\n${e.stack}`);
}
if(!this.#outputPath.query_exists(null))
this.#outputPath.make_directory_with_parents(null);
this.#sassStyles = {
colors: this.getColors(),
general: this.getStyleSheet().replace(/colors\.[$]/g, "\$")
};
Shell.getDefault().applyStyle(this.compileSass());
this.#stylesPaths = Gio.resources_enumerate_children(
"/io/github/retrozinndev/colorshell/styles", null
).map(name =>
`/io/github/retrozinndev/colorshell/styles/${name}`
);
monitorFile(`${GLib.get_user_cache_dir()}/wal/colors.json`, () => {
this.updateColors();
// Rules won't change at runtime in a common build,
// so no need to worry about this.
// But in a development build, there should be support
// hot-reloading the gresource, this is a TODO
this.#stylesPaths.forEach(path => {
const name = path.split('/')[path.split('/').length - 1];
switch(name) {
case "colors":
this.#sassStyles.colors = `${this.getColorDefinitions()}\n${
this.organizeModuleImports(this.getStyleData(path))
}`;
break;
case "mixins":
this.#sassStyles.mixins = `${this.organizeModuleImports(
this.getStyleData(path)
)}`;
break;
default:
this.#sassStyles.rules = `${this.#sassStyles.rules}\n${
this.organizeModuleImports(this.getStyleData(path))
}`;
break;
}
});
this.compileApply();
monitorFile(`${GLib.get_user_cache_dir()}/wal/colors`, () => {
this.#sassStyles.colors = `${this.getColorDefinitions()}\n${
this.organizeModuleImports(this.getStyleData(
"/io/github/retrozinndev/colorshell/styles/colors"
))
}`;
this.compileApply();
});
}
}
+4 -3
View File
@@ -1,11 +1,12 @@
import { execAsync } from "ags/process";
import { timeout } from "ags/time";
import GObject, { register, getter } from "ags/gobject";
import { monitorFile, readFile } from "ags/file";
import GObject, { register, getter } from "ags/gobject";
import AstalIO from "gi://AstalIO";
import Gio from "gi://Gio?version=2.0";
import GLib from "gi://GLib?version=2.0";
import { decoder, encoder } from "./utils";
export { Wallpaper };
@@ -96,7 +97,7 @@ class Wallpaper extends GObject.Object {
if(!loaded)
console.error("Wallpaper: Couldn't read changes inside the hyprpaper file!");
const content = new TextDecoder().decode(text);
const content = decoder.decode(text);
if(content) {
let setWall: boolean = true;
@@ -147,7 +148,7 @@ class Wallpaper extends GObject.Object {
if(res) {
// success
this.#ignoreWatch = true; // tell monitor to ignore this change
res.write_bytes_async(new TextEncoder().encode(`# This file was automatically generated by color-shell
res.write_bytes_async(encoder.encode(`# This file was automatically generated by color-shell
preload = ${this.#wallpaper}
splash = ${this.#splash}
-314
View File
@@ -1,314 +0,0 @@
@use "sass:color";
@use "./style/wal";
@use "./style/mixins";
@use "./style/functions";
@use "./style/colors";
@use "./style/bar";
@use "./style/osd";
@use "./style/control-center";
@use "./style/center-window";
@use "./style/float-notifications";
@use "./style/logout-menu";
@use "./style/apps-window";
@use "./style/runner";
* {
@include mixins.reset-props;
}
entry {
background: colors.$bg-primary;
padding: 10px 9px;
border-radius: 12px;
&:focus {
box-shadow: inset 0 0 0 2px colors.$bg-secondary;
}
& image.left {
margin-right: 6px;
}
}
.custom-dialog-container {
background: colors.$bg-translucent;
padding: 18px;
border-radius: 24px;
& .title {
font-size: 21px;
font-weight: 700;
margin-bottom: 10px;
}
& .text {
font-size: 16px;
font-weight: 400;
}
& .options {
& button {
@include mixins.button-reactive-primary;
background: colors.$bg-primary;
border-radius: 12px;
padding: 9px 6px;
& label {
font-size: 16px;
font-weight: 600;
}
margin: {
left: 4px;
right: 4px;
};
}
}
&.entry-popup-box entry {
margin-bottom: 10px;
&.password {
font-size: 14px;
font-family: "Adwaita Mono", "Cantarell Mono", "Noto Sans Mono", monospace;
font-weight: 400;
}
}
}
.notification {
background: colors.$bg-translucent-secondary;
border-radius: 16px;
& > .top {
padding: 8px;
padding-bottom: 0;
& .app-icon {
margin-right: 6px;
}
& .app-name {
font-size: 12px;
}
& label.time {
font-size: 11px;
font-weight: 500;
color: colors.$fg-disabled;
margin-right: 6px;
}
& button.close {
padding: 2px;
border-radius: 8px;
&:hover {
background: colors.$bg-secondary;
}
}
& icon.close {
font-size: 16px;
}
}
& .content {
padding: 6px;
padding-top: 0;
& .image {
$size: 78px;
min-width: $size;
min-height: $size;
background-size: cover;
background-position: center;
margin: 6px;
border-radius: 8px;
}
& .summary {
font-size: 17.3px;
font-weight: 700;
margin-bottom: 4px;
}
& .body {
font-size: 14.5px;
font-weight: 400;
}
}
& .actions {
padding: 6px;
& button.action {
border-radius: 4px;
background: colors.$bg-secondary;
padding: 6px;
& label {
font-size: 14px;
font-weight: 600;
}
&:hover {
background: colors.$bg-tertiary;
}
&:first-child {
border-top-left-radius: 12px;
border-bottom-left-radius: 12px;
}
&:last-child {
border-top-right-radius: 12px;
border-bottom-right-radius: 12px;
}
}
}
}
tooltip > box {
padding: 7px 8px;
margin: 12px;
margin-top: 0;
border-radius: 12px;
background: rgba(colors.$bg-primary, .98);
box-shadow: 0 5px 6px 1px colors.$bg-translucent-primary;
& label {
font-size: 13.1px;
font-weight: 500;
color: colors.$fg-primary;
}
}
popover.menu contents {
background: wal.$background;
border-radius: 14px;
padding: 4px;
& viewport > stack > * > * > * {
& > separator {
min-height: .5px;
margin: 3px 2px;
background: rgba(colors.$fg-disabled, .1);
}
& > *:not(separator) > * {
padding: 6px;
border-radius: 10px;
font-size: 12px;
font-weight: 600;
&:hover, &:focus {
background: wal.$color1;
}
}
}
}
.button-row {
& > button {
$active-radius: 8px;
$corner-radius: calc($active-radius + 2px);
background: colors.$bg-secondary;
margin: 0 1px;
padding: 4px 6px;
border-radius: 2px;
transition: 120ms linear;
&:hover {
background: colors.$bg-tertiary;
}
&:active {
border-radius: $active-radius;
}
&:first-child {
margin-left: 0;
&:not(:active) {
border-top-left-radius: $corner-radius;
border-bottom-left-radius: $corner-radius;
}
}
&:last-child {
margin-right: 0;
&:not(:active) {
border-top-right-radius: $corner-radius;
border-bottom-right-radius: $corner-radius;
}
}
}
}
selection {
background: colors.$bg-tertiary;
}
trough {
background: color.adjust($color: colors.$bg-primary, $lightness: -5%);
border-radius: 8px;
margin: 2px 0;
}
trough highlight {
background: wal.$color1;
min-height: .9em;
}
trough slider {
border-radius: 50%;
margin: -4px 0;
background: wal.$foreground;
min-width: 1.2em;
min-height: 1.2em;
}
scrollbar trough {
@include mixins.reset-props;
background: colors.$bg-translucent;
border-radius: 8px;
& slider {
@include mixins.reset-props;
min-width: .45em;
background: colors.$bg-tertiary;
border-radius: 12px;
&:hover, &:active, &:focus {
margin: 2px;
}
}
&:hover, &:active, &:focus {
padding: 2px;
}
}
scale {
& marks mark {
& indicator {
color: colors.$fg-disabled;
min-width: 1px;
min-height: 6px;
}
& label {
font-size: 11px;
font-weight: 400;
color: colors.$fg-disabled;
}
}
}
+1 -2
View File
@@ -10,7 +10,6 @@ import GObject from "ags/gobject";
import AstalBluetooth from "gi://AstalBluetooth";
import AstalNetwork from "gi://AstalNetwork";
import AstalWp from "gi://AstalWp";
import { Shell } from "../../app";
export const Status = () =>
@@ -134,7 +133,7 @@ function StatusIcons() {
: "preferences-system-notifications-symbolic")
}
/>
<Gtk.Image gicon={Shell.getDefault().getGIcon("circle-filled-symbolic")} class={"notification-count"}
<Gtk.Image iconName={"circle-filled-symbolic"} class={"notification-count"}
visible={variableToBoolean(createBinding(Notifications.getDefault(), "history"))}
/>
</Gtk.Box>
+19 -2
View File
@@ -7,8 +7,24 @@ import GObject, { property, register, signal } from "ags/gobject";
import Pango from "gi://Pango?version=1.0";
export { Tile };
export { Tile, TileProps };
type TileProps = {
class?: string | Accessor<string>;
icon?: string | Accessor<string>;
visible?: boolean | Accessor<boolean>;
iconSize?: number | Accessor<number>;
title: string | Accessor<string>;
description?: string | Accessor<string>;
toggleState?: boolean | Accessor<boolean>;
enableOnClickMore?: boolean | Accessor<boolean>;
onUnmap?: () => void;
onToggledOn: () => void;
onToggledOff: () => void;
onClickMore?: () => void;
};
/* TODO: finish the tile class
@register({ GTypeName: "Tile" })
class Tile extends Gtk.Box {
@signal(Boolean) toggled(_state: boolean) {}
@@ -119,8 +135,9 @@ class Tile extends Gtk.Box {
return super.connect(signal, callback);
}
}
*/
export function TileFun(props: TileProps): Gtk.Widget {
function Tile(props: TileProps): Gtk.Widget {
const subs: Array<() => void> = [];
const [toggled, setToggled] = createState(((props.toggleState instanceof Accessor) ?
props.toggleState.get()
+1 -1
View File
@@ -31,7 +31,7 @@ export type WindowData = {
* Also contains util functions to create dynamic windows, opening the window only on focused
* monitor, or all available monitors!
*/
@register()
@register({ GTypeName: "Windows" })
class Windows extends GObject.Object {
private static instance: (Windows | null);