ags: lot of stuff lmao
This commit is contained in:
@@ -3,7 +3,7 @@ import { Connectable } from "astal/binding";
|
|||||||
|
|
||||||
|
|
||||||
/** !!TODO!! Needs more work and testing
|
/** !!TODO!! Needs more work and testing
|
||||||
* I(retrozinndev) don't have a monitor that has software-controlled brightness
|
* I(retrozinndev) don't have a monitor that has software-controlled brightness :(
|
||||||
*/
|
*/
|
||||||
@register({ GTypeName: "Brightness" })
|
@register({ GTypeName: "Brightness" })
|
||||||
class Brightness extends GObject.Object implements Connectable {
|
class Brightness extends GObject.Object implements Connectable {
|
||||||
@@ -16,7 +16,7 @@ class Brightness extends GObject.Object implements Connectable {
|
|||||||
|
|
||||||
constructor(backlightDevice?: string) {
|
constructor(backlightDevice?: string) {
|
||||||
super();
|
super();
|
||||||
this.backlight = backlightDevice || "";
|
this.backlight = backlightDevice || "intel_backlight";
|
||||||
this.max = Number.parseInt(exec(`brightnessctl -d ${backlightDevice} max`))
|
this.max = Number.parseInt(exec(`brightnessctl -d ${backlightDevice} max`))
|
||||||
this.brightness = Number.parseInt(exec(`brightnessctl -d ${backlightDevice} get`))
|
this.brightness = Number.parseInt(exec(`brightnessctl -d ${backlightDevice} get`))
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Subscribable } from "astal/binding";
|
|||||||
import { GObject, property, register, Variable } from "astal";
|
import { GObject, property, register, Variable } from "astal";
|
||||||
import { Windows } from "../windows";
|
import { Windows } from "../windows";
|
||||||
import { FloatingNotifications } from "../window/FloatingNotifications";
|
import { FloatingNotifications } from "../window/FloatingNotifications";
|
||||||
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
|
||||||
@register({ GTypeName: "Notifications" })
|
@register({ GTypeName: "Notifications" })
|
||||||
class NotificationsClass extends GObject.Object implements Subscribable {
|
class NotificationsClass extends GObject.Object implements Subscribable {
|
||||||
@@ -74,7 +75,6 @@ class NotificationsClass extends GObject.Object implements Subscribable {
|
|||||||
|
|
||||||
notification.urgency !== AstalNotifd.Urgency.CRITICAL &&
|
notification.urgency !== AstalNotifd.Urgency.CRITICAL &&
|
||||||
timeout(notificationTimeout, () => {
|
timeout(notificationTimeout, () => {
|
||||||
notification.dismiss();
|
|
||||||
this.notifications.set(this.notifications.get().filter((item) => item.id !== notification.id));
|
this.notifications.set(this.notifications.get().filter((item) => item.id !== notification.id));
|
||||||
this.addHistory(notification);
|
this.addHistory(notification);
|
||||||
});
|
});
|
||||||
@@ -106,4 +106,67 @@ class NotificationsClass extends GObject.Object implements Subscribable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function NotificationWidget(notification: AstalNotifd.Notification): Gtk.Widget {
|
||||||
|
return new Widget.Box({
|
||||||
|
className: "notification",
|
||||||
|
homogeneous: false,
|
||||||
|
expand: false,
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
children: [
|
||||||
|
new Widget.Box({
|
||||||
|
className: "top",
|
||||||
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
hexpand: true,
|
||||||
|
vexpand: false,
|
||||||
|
children: [
|
||||||
|
new Widget.Icon({
|
||||||
|
className: "icon",
|
||||||
|
visible: notification.appIcon !== "",
|
||||||
|
icon: notification.appIcon || "image-missing",
|
||||||
|
iconSize: Gtk.IconSize.DND,
|
||||||
|
css: ".icon { font-size: 24px; }"
|
||||||
|
}),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "app-name",
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
label: notification.appName || "Unknown Application"
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Button({
|
||||||
|
className: "close nf",
|
||||||
|
onClick: () => notification.dismiss(),
|
||||||
|
label: ""
|
||||||
|
} as Widget.ButtonProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps),
|
||||||
|
new Widget.Box({
|
||||||
|
className: "content",
|
||||||
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
children: [
|
||||||
|
new Widget.Box({
|
||||||
|
className: "image",
|
||||||
|
visible: notification.image !== "",
|
||||||
|
css: `box.image { background-image: url('${notification.image}'); }`
|
||||||
|
} as Widget.BoxProps),
|
||||||
|
new Widget.Box({
|
||||||
|
className: "text",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
children: [
|
||||||
|
new Widget.Label({
|
||||||
|
className: "summary",
|
||||||
|
useMarkup: true,
|
||||||
|
label: notification.summary
|
||||||
|
}),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "body",
|
||||||
|
useMarkup: true,
|
||||||
|
label: notification.body
|
||||||
|
} as Widget.LabelProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps);
|
||||||
|
}
|
||||||
|
|
||||||
export const Notifications = new NotificationsClass();
|
export const Notifications = new NotificationsClass();
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ function watch(): void {
|
|||||||
`${path}`,
|
`${path}`,
|
||||||
(file: string) => {
|
(file: string) => {
|
||||||
// Ignore tmp files
|
// Ignore tmp files
|
||||||
if(!file.endsWith('~')) {
|
if(!file.endsWith('~') && !Number.isNaN(file)) {
|
||||||
console.log(`[LOG] Stylesheet ${file} file updated`)
|
console.log(`[LOG] Stylesheet ${file} file updated`)
|
||||||
compileStyle();
|
compileStyle();
|
||||||
applyStyle();
|
applyStyle();
|
||||||
|
|||||||
+19
-1
@@ -13,7 +13,7 @@
|
|||||||
@include mixins.reset-props;
|
@include mixins.reset-props;
|
||||||
|
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 500;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Style widget groups
|
// Style widget groups
|
||||||
@@ -194,4 +194,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.logo {
|
||||||
|
& > box {
|
||||||
|
border-radius: 12px;
|
||||||
|
transition: 100ms linear;
|
||||||
|
padding: 0 8px;
|
||||||
|
|
||||||
|
& > label {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-right: 1px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
& > box {
|
||||||
|
background: colors.$bg-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,11 @@
|
|||||||
@use "./wal";
|
@use "./wal";
|
||||||
@use "./functions" as funs;
|
@use "./functions" as funs;
|
||||||
|
|
||||||
$bg-primary: funs.toRGB(color.adjust($color: wal.$color1, $lightness: -35%));
|
$bg-primary: funs.toRGB(color.adjust($color: wal.$color1, $lightness: -34%));
|
||||||
$bg-secondary: funs.toRGB(color.adjust($color: wal.$color1, $lightness: -16%));
|
$bg-secondary: funs.toRGB(color.adjust($color: wal.$color1, $lightness: -16%));
|
||||||
$bg-tertiary: funs.toRGB(color.adjust($color: $bg-secondary, $lightness: 10%));
|
$bg-tertiary: funs.toRGB(color.adjust($color: $bg-secondary, $lightness: 10%));
|
||||||
$bg-light: wal.$foreground;
|
$bg-light: wal.$foreground;
|
||||||
$bg-translucent: funs.toRGB(color.change($color: $bg-primary, $alpha: 72%));
|
$bg-translucent: funs.toRGB(color.change($color: $bg-primary, $alpha: 75%));
|
||||||
$fg-primary: wal.$foreground;
|
$fg-primary: wal.$foreground;
|
||||||
$fg-light: $bg-primary;
|
$fg-light: $bg-primary;
|
||||||
$fg-disabled: funs.toRGB(color.adjust($color: wal.$foreground, $lightness: -11%));
|
$fg-disabled: funs.toRGB(color.adjust($color: wal.$foreground, $lightness: -11%));
|
||||||
|
|||||||
@@ -65,3 +65,61 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tiles-container {
|
||||||
|
@include mixins.reset-props;
|
||||||
|
|
||||||
|
& > flowbox {
|
||||||
|
& > flowboxchild .tile-eventbox {
|
||||||
|
&:hover:not(.toggled) > .tile {
|
||||||
|
background: colors.$bg-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.toggled:hover > .tile {
|
||||||
|
box-shadow: inset 0 0 0 100px rgba($color: colors.$fg-primary, $alpha: .2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.toggled > .tile {
|
||||||
|
background: colors.$bg-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .tile {
|
||||||
|
background: colors.$bg-primary;
|
||||||
|
border-radius: 16px;
|
||||||
|
|
||||||
|
& > .content {
|
||||||
|
padding: 8px;
|
||||||
|
padding-right: 0;
|
||||||
|
& > .icon {
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .text {
|
||||||
|
& > .title {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 15.1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .description {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .more {
|
||||||
|
border-top-right-radius: inherit;
|
||||||
|
border-bottom-right-radius: inherit;
|
||||||
|
|
||||||
|
& label {
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
box-shadow: inset 0 0 0 100px rgba($color: colors.$fg-disabled, $alpha: .4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+20
-20
@@ -1,26 +1,26 @@
|
|||||||
// SCSS Variables
|
// SCSS Variables
|
||||||
// Generated by 'wal'
|
// Generated by 'wal'
|
||||||
$wallpaper: "/home/joaov/wallpapers/Miku Bush.jpg";
|
$wallpaper: "/home/joaov/wallpapers/Bocchi The Rock!.png";
|
||||||
|
|
||||||
// Special
|
// Special
|
||||||
$background: #0f1b06;
|
$background: #0a0a0c;
|
||||||
$foreground: #c3c6c0;
|
$foreground: #c1c1c2;
|
||||||
$cursor: #c3c6c0;
|
$cursor: #c1c1c2;
|
||||||
|
|
||||||
// Colors
|
// Colors
|
||||||
$color0: #0f1b06;
|
$color0: #0a0a0c;
|
||||||
$color1: #4e7278;
|
$color1: #935d6d;
|
||||||
$color2: #5b7b94;
|
$color2: #967e84;
|
||||||
$color3: #71807c;
|
$color3: #ac8486;
|
||||||
$color4: #7b9882;
|
$color4: #bcae7a;
|
||||||
$color5: #a3a881;
|
$color5: #a49c9c;
|
||||||
$color6: #778591;
|
$color6: #bcb79c;
|
||||||
$color7: #93988d;
|
$color7: #8a8a96;
|
||||||
$color8: #626d59;
|
$color8: #565669;
|
||||||
$color9: #6898A1;
|
$color9: #C57C92;
|
||||||
$color10: #7AA5C6;
|
$color10: #C9A9B0;
|
||||||
$color11: #97ABA6;
|
$color11: #E6B1B3;
|
||||||
$color12: #A5CBAE;
|
$color12: #FBE8A3;
|
||||||
$color13: #DAE0AC;
|
$color13: #DBD1D0;
|
||||||
$color14: #9FB2C2;
|
$color14: #FBF5D1;
|
||||||
$color15: #c3c6c0;
|
$color15: #c1c1c2;
|
||||||
|
|||||||
+23
-1
@@ -1 +1,23 @@
|
|||||||
//TODO
|
//TODO Needs more work
|
||||||
|
|
||||||
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
|
||||||
|
type CalendarProps = Pick<Widget.BoxProps,
|
||||||
|
"name"
|
||||||
|
| "className"
|
||||||
|
| "css"
|
||||||
|
| "expand"
|
||||||
|
| "halign"
|
||||||
|
| "valign"> & {
|
||||||
|
|
||||||
|
showWeekDays: boolean;
|
||||||
|
showHeader: boolean;
|
||||||
|
fillGrid: boolean; // I need a better name for this LMAOOO
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Calendar(props?: Partial<CalendarProps>): Gtk.Widget {
|
||||||
|
return new Widget.Box({
|
||||||
|
...props,
|
||||||
|
children: []
|
||||||
|
} as Widget.BoxProps);
|
||||||
|
}
|
||||||
|
|||||||
+65
-11
@@ -1,18 +1,72 @@
|
|||||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
import { Binding } from "astal";
|
||||||
|
import { Astal, Gdk, Gtk, Widget } from "astal/gtk3";
|
||||||
|
|
||||||
|
|
||||||
const { TOP, BOTTOM, LEFT, RIGHT }: typeof Astal.WindowAnchor = Astal.WindowAnchor;
|
const { TOP, BOTTOM, LEFT, RIGHT }: typeof Astal.WindowAnchor = Astal.WindowAnchor;
|
||||||
|
|
||||||
/**
|
export interface PopupWindowProps {
|
||||||
* Creates a screen-size window and opens the provided window after it.
|
className?: string | Binding<string | undefined>;
|
||||||
* When clicking in the transparent background window, it closes(hides)
|
namespace: string | Binding<string | undefined>;
|
||||||
* the provided window.
|
visible?: boolean | Binding<boolean | undefined>;
|
||||||
* @param window the window to be rendered and closed when clicking outside of it
|
halign?: Gtk.Align | Binding<Gtk.Align | undefined>;
|
||||||
*/
|
valign?: Gtk.Align | Binding<Gtk.Align | undefined>;
|
||||||
export function PopupWindow(window: Gtk.Window) {
|
hexpand?: boolean | Binding<boolean | undefined>;
|
||||||
const bgWindow: Gtk.Window = new Widget.Window({
|
vexpand?: boolean | Binding<boolean | undefined>;
|
||||||
namespace: "popup-bg-window",
|
expand?: boolean | Binding<boolean | undefined>;
|
||||||
|
monitor?: number | Binding<number | undefined>;
|
||||||
|
marginTop?: number | Binding<number | undefined>;
|
||||||
|
marginBottom?: number | Binding<number | undefined>;
|
||||||
|
marginLeft?: number | Binding<number | undefined>;
|
||||||
|
marginRight?: number | Binding<number | undefined>;
|
||||||
|
widthRequest?: number | Binding<number | undefined>;
|
||||||
|
heightRequest?: number | Binding<number | undefined>;
|
||||||
|
layer?: Astal.Layer | Binding<Astal.Layer | undefined>;
|
||||||
|
onClose?: () => void;
|
||||||
|
child: Gtk.Widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function PopupWindow(props: PopupWindowProps): Widget.Window {
|
||||||
|
return new Widget.Window({
|
||||||
|
namespace: props?.namespace || "popup-window",
|
||||||
|
className: "popup-window",
|
||||||
anchor: TOP | BOTTOM | LEFT | RIGHT,
|
anchor: TOP | BOTTOM | LEFT | RIGHT,
|
||||||
|
exclusivity: Astal.Exclusivity.NORMAL,
|
||||||
|
keymode: Astal.Keymode.EXCLUSIVE,
|
||||||
|
layer: props?.layer || Astal.Layer.OVERLAY,
|
||||||
|
focusOnMap: true,
|
||||||
|
visible: props?.visible,
|
||||||
|
acceptFocus: true,
|
||||||
|
monitor: props?.monitor || 0,
|
||||||
|
onButtonPressEvent: (_, event: Gdk.Event) => {
|
||||||
|
const [, posX, posY] = event.get_coords();
|
||||||
|
const childAllocation = _.get_child()!.get_allocation();
|
||||||
|
|
||||||
} as Widget.WindowProps);
|
if((posX < childAllocation.x || posX > (childAllocation.x + childAllocation.width)) ||
|
||||||
|
(posY < childAllocation.y || posY > (childAllocation.y + childAllocation.height))) {
|
||||||
|
_.hide();
|
||||||
|
props?.onClose && props.onClose();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onKeyPressEvent: (_, event: Gdk.Event) =>
|
||||||
|
event.get_keyval()[1] === Gdk.KEY_Escape && _.hide(),
|
||||||
|
child: new Widget.Box({
|
||||||
|
className: (props?.className instanceof Binding) ?
|
||||||
|
props.className.as((clsName: string|undefined) =>
|
||||||
|
`popup ${clsName || ""}`)
|
||||||
|
: `popup ${props?.className || ""}`,
|
||||||
|
halign: props?.halign || Gtk.Align.CENTER,
|
||||||
|
valign: props?.valign || Gtk.Align.CENTER,
|
||||||
|
expand: props?.expand || false,
|
||||||
|
widthRequest: props?.widthRequest,
|
||||||
|
heightRequest: props?.heightRequest,
|
||||||
|
hexpand: props?.hexpand || false,
|
||||||
|
visible: true,
|
||||||
|
vexpand: props?.vexpand || false,
|
||||||
|
marginTop: props?.marginTop || 0,
|
||||||
|
marginBottom: props?.marginBottom || 0,
|
||||||
|
marginLeft: props?.marginLeft || 0,
|
||||||
|
marginRight: props?.marginRight || 0,
|
||||||
|
child: props.child
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
} as Widget.WindowProps);;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,11 @@ export function Separator(props: SeparatorProps) {
|
|||||||
}
|
}
|
||||||
.separator-horizontal {
|
.separator-horizontal {
|
||||||
padding-bottom: ${props.size || 1 }px;
|
padding-bottom: ${props.size || 1 }px;
|
||||||
margin: 7px 4px;
|
margin: 4px 4px;
|
||||||
}
|
}
|
||||||
.separator-vertical {
|
.separator-vertical {
|
||||||
padding-right: ${props.size || 1 }px;
|
padding-right: ${props.size || 1 }px;
|
||||||
margin: 4px 7px;
|
margin: 7px 7px;
|
||||||
}`,
|
}`,
|
||||||
} as Widget.BoxProps);
|
} as Widget.BoxProps);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import { bind, Process } from "astal";
|
import { bind, Process } from "astal";
|
||||||
import { Widget } from "astal/gtk3";
|
import { Widget } from "astal/gtk3";
|
||||||
import AstalWp from "gi://AstalWp";
|
|
||||||
import { Wireplumber } from "../../scripts/volume";
|
import { Wireplumber } from "../../scripts/volume";
|
||||||
import { ControlCenter } from "../../window/ControlCenter";
|
import { ControlCenter } from "../../window/ControlCenter";
|
||||||
|
|
||||||
const wp = AstalWp.get_default();
|
|
||||||
|
|
||||||
export function Audio() {
|
export function Audio() {
|
||||||
return wp && new Widget.EventBox({
|
return new Widget.EventBox({
|
||||||
className: bind(ControlCenter, "visible").as((visible: boolean) =>
|
className: bind(ControlCenter, "visible").as((visible: boolean) =>
|
||||||
visible ? "audio open" : "audio"),
|
visible ? "audio open" : "audio"),
|
||||||
onClick: () => Process.exec_async("astal toggle control-center", () => {}),
|
onClick: () => Process.exec_async("astal toggle control-center", () => {}),
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ export function FocusedClient() {
|
|||||||
children: [
|
children: [
|
||||||
new Widget.Icon({
|
new Widget.Icon({
|
||||||
className: "icon",
|
className: "icon",
|
||||||
|
vexpand: true,
|
||||||
|
css: ".icon { font-size: 18px; }",
|
||||||
icon: bind(hyprland, "focusedClient").as((client: AstalHyprland.Client) =>
|
icon: bind(hyprland, "focusedClient").as((client: AstalHyprland.Client) =>
|
||||||
client ?
|
client ?
|
||||||
(getAppIcon(client.initialClass) || client.initialClass)
|
(getAppIcon(client.initialClass) || client.initialClass)
|
||||||
@@ -29,15 +31,15 @@ export function FocusedClient() {
|
|||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "class",
|
className: "class",
|
||||||
xalign: 0,
|
xalign: 0,
|
||||||
max_width_chars: 65,
|
maxWidthChars: 50,
|
||||||
truncate: false,
|
truncate: true,
|
||||||
label: bind(focusedClient, "class")
|
label: bind(focusedClient, "class")
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "title",
|
className: "title",
|
||||||
xalign: 0,
|
xalign: 0,
|
||||||
max_width_chars: 48,
|
maxWidthChars: 45,
|
||||||
truncate: false,
|
truncate: true,
|
||||||
label: bind(focusedClient, "title")
|
label: bind(focusedClient, "title")
|
||||||
} as Widget.LabelProps)
|
} as Widget.LabelProps)
|
||||||
] : []
|
] : []
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ import { Widget } from "astal/gtk3";
|
|||||||
import AstalHyprland from "gi://AstalHyprland";
|
import AstalHyprland from "gi://AstalHyprland";
|
||||||
|
|
||||||
export function Logo() {
|
export function Logo() {
|
||||||
return new Widget.Box({
|
return new Widget.EventBox({
|
||||||
|
onClickRelease: () => AstalHyprland.get_default().dispatch("exec", "anyrun"),
|
||||||
className: "logo",
|
className: "logo",
|
||||||
//tooltipText: tr("bar.logo.tooltip"),
|
child: new Widget.Box({
|
||||||
child: new Widget.Button({
|
child: new Widget.Label({
|
||||||
onClick: () => AstalHyprland.get_default().dispatch("exec", "anyrun"),
|
className: "nf",
|
||||||
className: "nf",
|
label: "",
|
||||||
label: "",
|
} as Widget.LabelProps)
|
||||||
} as Widget.ButtonProps)
|
} as Widget.BoxProps)
|
||||||
} as Widget.BoxProps);
|
} as Widget.EventBoxProps);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,12 +82,14 @@ export function Media(): Gtk.Widget {
|
|||||||
className: "player-icon nf",
|
className: "player-icon nf",
|
||||||
label: bind(players[0], "busName").as((busName: string) => {
|
label: bind(players[0], "busName").as((busName: string) => {
|
||||||
const playerName: string = busName.split('.')[busName.split('.').length-1];
|
const playerName: string = busName.split('.')[busName.split('.').length-1];
|
||||||
return playerIcons[playerName as keyof typeof playerIcons] || "";
|
return playerIcons[playerName.toLowerCase() as keyof typeof playerIcons] || "";
|
||||||
})
|
})
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "title",
|
className: "title",
|
||||||
label: bind(players[0], "title").as((title: string) => title || "No Title")
|
label: bind(players[0], "title").as((title: string) => title || "No Title"),
|
||||||
|
maxWidthChars: 20,
|
||||||
|
truncate: true
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
Separator({
|
Separator({
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
@@ -97,7 +99,9 @@ export function Media(): Gtk.Widget {
|
|||||||
} as SeparatorProps),
|
} as SeparatorProps),
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "artist",
|
className: "artist",
|
||||||
label: bind(players[0], "artist").as((artist: string) => artist || "No Artist")
|
label: bind(players[0], "artist").as((artist: string) => artist || "No Artist"),
|
||||||
|
maxWidthChars: 18,
|
||||||
|
truncate: true
|
||||||
} as Widget.LabelProps)
|
} as Widget.LabelProps)
|
||||||
] : new Widget.Label({
|
] : new Widget.Label({
|
||||||
label: "Crazy to think this widget haven't disappeared yet!"
|
label: "Crazy to think this widget haven't disappeared yet!"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { AstalIO, bind, GLib, Process, timeout } from "astal";
|
import { AstalIO, bind, Binding, GLib, Process, timeout } from "astal";
|
||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
import AstalMpris from "gi://AstalMpris";
|
import AstalMpris from "gi://AstalMpris";
|
||||||
|
|
||||||
@@ -19,10 +19,9 @@ export const BigMedia: Gtk.Widget = new Widget.Box({
|
|||||||
className: "image",
|
className: "image",
|
||||||
hexpand: false,
|
hexpand: false,
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
visible: bind(players[0], "coverArt").as((coverArt: string) =>
|
visible: getAlbumArt(players[0]).as(Boolean),
|
||||||
coverArt !== ""),
|
css: getAlbumArt(players[0]).as((artUrl: string|undefined) =>
|
||||||
css: bind(players[0], "coverArt").as((coverArt: string) =>
|
artUrl ? `.image { background-image: url('${artUrl}'); }` : undefined),
|
||||||
`.image { background-image: url('${coverArt}'); }`),
|
|
||||||
width_request: 132,
|
width_request: 132,
|
||||||
height_request: 128
|
height_request: 128
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
@@ -35,13 +34,15 @@ export const BigMedia: Gtk.Widget = new Widget.Box({
|
|||||||
className: "title",
|
className: "title",
|
||||||
tooltipText: bind(players[0], "title").as((title: string) => !title ? "No Title" : title),
|
tooltipText: bind(players[0], "title").as((title: string) => !title ? "No Title" : title),
|
||||||
label: bind(players[0], "title").as((title: string) => !title ? "No Title" : title),
|
label: bind(players[0], "title").as((title: string) => !title ? "No Title" : title),
|
||||||
truncate: true
|
truncate: true,
|
||||||
|
maxWidthChars: 25,
|
||||||
} as Widget.LabelProps),
|
} as Widget.LabelProps),
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "artist",
|
className: "artist",
|
||||||
tooltipText: bind(players[0], "artist").as((artist: string) => !artist ? "No Artist" : artist),
|
tooltipText: bind(players[0], "artist").as((artist: string) => !artist ? "No Artist" : artist),
|
||||||
label: bind(players[0], "artist").as((artist: string) => !artist ? "No Artist" : artist),
|
label: bind(players[0], "artist").as((artist: string) => !artist ? "No Artist" : artist),
|
||||||
truncate: true
|
maxWidthChars: 28,
|
||||||
|
truncate: true,
|
||||||
} as Widget.LabelProps)
|
} as Widget.LabelProps)
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps),
|
} as Widget.BoxProps),
|
||||||
@@ -101,6 +102,15 @@ export const BigMedia: Gtk.Widget = new Widget.Box({
|
|||||||
players[0].get_meta("xesam:url") === null),
|
players[0].get_meta("xesam:url") === null),
|
||||||
onClick: () => Process.exec(`wl-copy ${players[0].get_meta("xesam:url")?.get_string()[0]}`)
|
onClick: () => Process.exec(`wl-copy ${players[0].get_meta("xesam:url")?.get_string()[0]}`)
|
||||||
} as Widget.ButtonProps),
|
} as Widget.ButtonProps),
|
||||||
|
new Widget.Button({
|
||||||
|
className: "shuffle nf",
|
||||||
|
visible: bind(players[0], "shuffleStatus").as((shuffleStatus: AstalMpris.Shuffle) =>
|
||||||
|
shuffleStatus !== AstalMpris.Shuffle.UNSUPPORTED),
|
||||||
|
label: bind(players[0], "shuffleStatus").as((shuffleStatus: AstalMpris.Shuffle) =>
|
||||||
|
shuffleStatus === AstalMpris.Shuffle.ON ? "" : ""),
|
||||||
|
tooltipText: "Toggle Shuffle",
|
||||||
|
onClick: () => players[0].shuffle()
|
||||||
|
} as Widget.ButtonProps),
|
||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "previous nf",
|
className: "previous nf",
|
||||||
label: "",
|
label: "",
|
||||||
@@ -125,6 +135,20 @@ export const BigMedia: Gtk.Widget = new Widget.Box({
|
|||||||
label: "",
|
label: "",
|
||||||
tooltipText: "Next",
|
tooltipText: "Next",
|
||||||
onClick: () => players[0].canGoNext && players[0].next()
|
onClick: () => players[0].canGoNext && players[0].next()
|
||||||
|
} as Widget.ButtonProps),
|
||||||
|
new Widget.Button({
|
||||||
|
className: "repeat nf",
|
||||||
|
visible: bind(players[0], "loopStatus").as((loopStatus: AstalMpris.Loop) =>
|
||||||
|
loopStatus !== AstalMpris.Loop.UNSUPPORTED),
|
||||||
|
label: bind(players[0], "loopStatus").as((loopStatus: AstalMpris.Loop) => {
|
||||||
|
switch(loopStatus) {
|
||||||
|
case AstalMpris.Loop.TRACK: return "";
|
||||||
|
case AstalMpris.Loop.PLAYLIST: return "";
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
tooltipText: "Toggle Loop",
|
||||||
|
onClick: () => players[0].loop()
|
||||||
} as Widget.ButtonProps)
|
} as Widget.ButtonProps)
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps),
|
} as Widget.BoxProps),
|
||||||
@@ -142,3 +166,24 @@ export const BigMedia: Gtk.Widget = new Widget.Box({
|
|||||||
})
|
})
|
||||||
])
|
])
|
||||||
} as Widget.BoxProps);
|
} as Widget.BoxProps);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function handles album art/cover of playing media. If a file is provided
|
||||||
|
* by the player, it adds the "file://" uri as a prefix, so you can use it in css.
|
||||||
|
*
|
||||||
|
* @param player the player you want to pull album art from
|
||||||
|
* @returns Binding to player.artUrl containing the album art uri, or an undefined binding ig none was found.
|
||||||
|
* */
|
||||||
|
function getAlbumArt(player: AstalMpris.Player): Binding<string|undefined> {
|
||||||
|
return bind(player, "artUrl").as((artUrl: string) => {
|
||||||
|
const finalUrl: string = artUrl;
|
||||||
|
|
||||||
|
if(/^(https|http)$/.test(finalUrl.split("://")[0]))
|
||||||
|
return artUrl;
|
||||||
|
else if(artUrl.startsWith("/"))
|
||||||
|
return "file://" + artUrl;
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import { timeout, Variable } from "astal";
|
||||||
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
|
||||||
|
const empty = new Widget.Box();
|
||||||
|
const page = new Variable<Gtk.Widget>(empty);
|
||||||
|
let connectionId: (number|undefined);
|
||||||
|
|
||||||
|
export const PagesWidget: Widget.Revealer = new Widget.Revealer({
|
||||||
|
revealChild: false,
|
||||||
|
transitionType: Gtk.RevealerTransitionType.SLIDE_DOWN,
|
||||||
|
transitionDuration: 250,
|
||||||
|
child: page()
|
||||||
|
} as Widget.RevealerProps);
|
||||||
|
|
||||||
|
export function showPages(child: Gtk.Widget, onShow?: (self: Widget.Revealer) => void): void {
|
||||||
|
page.set(child);
|
||||||
|
PagesWidget.set_reveal_child(true);
|
||||||
|
connectionId !== undefined && PagesWidget.disconnect(connectionId);
|
||||||
|
connectionId = PagesWidget.connect("show", (_) =>
|
||||||
|
onShow && onShow(_));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getPage(): (Gtk.Widget|null) {
|
||||||
|
return page.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function togglePage(page: Gtk.Widget): void {
|
||||||
|
PagesWidget.revealChild ?
|
||||||
|
hidePages()
|
||||||
|
: showPages(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function hidePages(onHide?: () => void) {
|
||||||
|
PagesWidget.set_reveal_child(false);
|
||||||
|
console.log("heyyyyy");
|
||||||
|
timeout(300, () => {
|
||||||
|
page.set(empty);
|
||||||
|
onHide && onHide();
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Process, Variable } from "astal";
|
import { execAsync, Process, Variable } from "astal";
|
||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
import AstalHyprland from "gi://AstalHyprland";
|
import AstalHyprland from "gi://AstalHyprland";
|
||||||
|
|
||||||
@@ -53,10 +53,7 @@ function LogoutButton(): Widget.Button {
|
|||||||
return new Widget.Button({
|
return new Widget.Button({
|
||||||
className: "nf",
|
className: "nf",
|
||||||
label: "",
|
label: "",
|
||||||
onClick: () => Process.exec_async(
|
onClick: () => execAsync("astal open logout-menu")
|
||||||
"bash -c 'wlogout -b 5'",
|
|
||||||
() => {}
|
|
||||||
)
|
|
||||||
} as Widget.ButtonProps);
|
} as Widget.ButtonProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,30 @@
|
|||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
import { TileInternet } from "./tiles/Internet";
|
||||||
|
import { TileBluetooth } from "./tiles/Bluetooth";
|
||||||
|
|
||||||
export const tileList: Array<Gtk.Widget> = [];
|
export const tileList: Array<any> = [
|
||||||
|
TileInternet,
|
||||||
|
TileBluetooth
|
||||||
|
];
|
||||||
|
|
||||||
export function TilesWidget(): Gtk.Widget {
|
export function TilesWidget(): Gtk.Widget {
|
||||||
const tilesFlowBox: Gtk.FlowBox = new Gtk.FlowBox({
|
const tilesFlowBox: Gtk.FlowBox = new Gtk.FlowBox({
|
||||||
visible: true,
|
visible: true,
|
||||||
noShowAll: false,
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
orientation: Gtk.Orientation.HORIZONTAL
|
rowSpacing: 6,
|
||||||
} as Gtk.Grid.ConstructorProps);
|
columnSpacing: 6,
|
||||||
|
minChildrenPerLine: 2,
|
||||||
|
maxChildrenPerLine: 2,
|
||||||
|
expand: true,
|
||||||
|
homogeneous: true,
|
||||||
|
} as Gtk.FlowBox.ConstructorProps);
|
||||||
|
|
||||||
tileList.map((item: Gtk.Widget) =>
|
tileList.map((item: Gtk.Widget) =>
|
||||||
tilesFlowBox.insert(item, -1));
|
tilesFlowBox.insert(item, -1));
|
||||||
|
|
||||||
return new Widget.Box({
|
return new Widget.Box({
|
||||||
children: [
|
className: "tiles-container",
|
||||||
tilesFlowBox
|
child: tilesFlowBox
|
||||||
]
|
|
||||||
} as Widget.BoxProps);
|
} as Widget.BoxProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
import { bind, timeout } from "astal";
|
||||||
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
import AstalBluetooth from "gi://AstalBluetooth?version=0.1";
|
||||||
|
|
||||||
|
let watchingDevices: boolean = false;
|
||||||
|
|
||||||
|
export function BluetoothPage() {
|
||||||
|
watchNewDevices();
|
||||||
|
|
||||||
|
return new Widget.Box({
|
||||||
|
className: "page bluetooth container",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
hexpand: true,
|
||||||
|
children: [
|
||||||
|
new Widget.Box({
|
||||||
|
className: "header",
|
||||||
|
children: [
|
||||||
|
new Widget.Label({
|
||||||
|
hexpand: true,
|
||||||
|
className: "title",
|
||||||
|
label: "Bluetooth",
|
||||||
|
halign: Gtk.Align.START
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps),
|
||||||
|
new Widget.Box({
|
||||||
|
className: "connections",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
expand: true,
|
||||||
|
children: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) =>
|
||||||
|
devices.filter((device: AstalBluetooth.Device) => device.connected
|
||||||
|
).map((dev: AstalBluetooth.Device) =>
|
||||||
|
new Widget.Button({
|
||||||
|
onClick: () => dev.connected ? dev.disconnect_device(null) : dev.connect_device(null),
|
||||||
|
child: new Widget.Box({
|
||||||
|
className: "device",
|
||||||
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
expand: true,
|
||||||
|
children: [
|
||||||
|
new Widget.Label({
|
||||||
|
className: "alias",
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
label: bind(dev, "alias")
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "battery",
|
||||||
|
halign: Gtk.Align.END,
|
||||||
|
label: bind(dev, "batteryPercentage").as(String)
|
||||||
|
} as Widget.LabelProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
} as Widget.ButtonProps)).concat(
|
||||||
|
devices.filter((device: AstalBluetooth.Device) => !device.connected
|
||||||
|
).map((dev: AstalBluetooth.Device) =>
|
||||||
|
new Widget.Button({
|
||||||
|
onClick: () => dev.connect_device(() => {}),
|
||||||
|
child: new Widget.Box({
|
||||||
|
className: "device",
|
||||||
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
expand: true,
|
||||||
|
children: [
|
||||||
|
new Widget.Label({
|
||||||
|
className: "alias",
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
label: bind(dev, "alias")
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "battery",
|
||||||
|
halign: Gtk.Align.END,
|
||||||
|
label: bind(dev, "batteryPercentage").as(String)
|
||||||
|
} as Widget.LabelProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
} as Widget.ButtonProps))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
}
|
||||||
|
|
||||||
|
function watchNewDevices(): void {
|
||||||
|
if(watchingDevices) {
|
||||||
|
timeout(10000, () => {
|
||||||
|
reloadDevicesList();
|
||||||
|
watchNewDevices();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopDeviceWatch(): void {
|
||||||
|
watchingDevices = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function reloadDevicesList(): void {
|
||||||
|
AstalBluetooth.get_default().adapter.start_discovery();
|
||||||
|
timeout(5000, () => AstalBluetooth.get_default().adapter.stop_discovery());
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
import { bind } from "astal";
|
||||||
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
import AstalBluetooth from "gi://AstalBluetooth";
|
||||||
|
|
||||||
|
export function WifiPage() {
|
||||||
|
return new Widget.Box({
|
||||||
|
className: "page bluetooth container",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
hexpand: true,
|
||||||
|
children: [
|
||||||
|
new Widget.Box({
|
||||||
|
className: "connections",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
expand: true,
|
||||||
|
children: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) =>
|
||||||
|
devices && devices.filter((device: AstalBluetooth.Device) => device.connected
|
||||||
|
).map((dev: AstalBluetooth.Device) =>
|
||||||
|
new Widget.Box({
|
||||||
|
className: "device",
|
||||||
|
orientation: Gtk.Orientation.HORIZONTAL,
|
||||||
|
expand: true,
|
||||||
|
children: [
|
||||||
|
new Widget.Label({
|
||||||
|
className: "alias",
|
||||||
|
halign: Gtk.Align.START,
|
||||||
|
label: bind(dev, "alias")
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "battery",
|
||||||
|
halign: Gtk.Align.END,
|
||||||
|
} as Widget.LabelProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
))
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import { bind } from "astal";
|
||||||
|
import { Tile, TileProps } from "./Tile";
|
||||||
|
import AstalBluetooth from "gi://AstalBluetooth";
|
||||||
|
import { togglePage } from "../Pages";
|
||||||
|
import { BluetoothPage } from "../pages/Bluetooth";
|
||||||
|
|
||||||
|
export const TileBluetooth = Tile({
|
||||||
|
title: "Bluetooth",
|
||||||
|
description: bind(AstalBluetooth.get_default(), "devices").as((devices: Array<AstalBluetooth.Device>) => {
|
||||||
|
const connected: Array<AstalBluetooth.Device> = devices.filter(
|
||||||
|
(dev: AstalBluetooth.Device) => dev.connected);
|
||||||
|
|
||||||
|
return connected[0] ? connected[0].get_alias() : undefined;
|
||||||
|
}),
|
||||||
|
onToggledOn: () => AstalBluetooth.get_default().adapter.set_powered(true),
|
||||||
|
onToggledOff: () => AstalBluetooth.get_default().adapter.set_powered(false),
|
||||||
|
onClickMore: () => togglePage(BluetoothPage()),
|
||||||
|
icon: "",
|
||||||
|
iconSize: 16,
|
||||||
|
toggleState: bind(AstalBluetooth.get_default().adapter, "powered")
|
||||||
|
} as TileProps);
|
||||||
@@ -1,8 +1,26 @@
|
|||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { bind, execAsync } from "astal";
|
||||||
|
import { Tile, TileProps } from "./Tile";
|
||||||
|
import AstalNetwork from "gi://AstalNetwork";
|
||||||
|
import { Widget } from "astal/gtk3";
|
||||||
|
|
||||||
export const TileInternet = new Widget.Box({
|
export const TileInternet = new Widget.Box({
|
||||||
className: "tile more internet",
|
child: bind(AstalNetwork.get_default(), "wired").as((wired: AstalNetwork.Wired) => Tile({
|
||||||
children: [
|
title: "Wired",
|
||||||
toggleButton
|
description: bind(wired, "internet").as((internet: AstalNetwork.Internet) => {
|
||||||
]
|
switch(internet) {
|
||||||
|
case AstalNetwork.Internet.CONNECTED:
|
||||||
|
return "Connected";
|
||||||
|
case AstalNetwork.Internet.DISCONNECTED:
|
||||||
|
return "Disconnected";
|
||||||
|
case AstalNetwork.Internet.CONNECTING:
|
||||||
|
return "Connecting...";
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
onToggledOn: () => execAsync("nmcli n on"),
|
||||||
|
onToggledOff: () => execAsync("nmcli n off"),
|
||||||
|
icon: "",
|
||||||
|
iconSize: 16,
|
||||||
|
toggleState: bind(wired, "internet").as((internet: AstalNetwork.Internet) =>
|
||||||
|
internet === AstalNetwork.Internet.CONNECTING || internet === AstalNetwork.Internet.CONNECTED)
|
||||||
|
} as TileProps))
|
||||||
} as Widget.BoxProps);
|
} as Widget.BoxProps);
|
||||||
|
|||||||
@@ -1,39 +1,94 @@
|
|||||||
import { Binding } from "astal";
|
import { Binding, Variable } from "astal";
|
||||||
import { Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
|
|
||||||
export type TileProps = {
|
export type TileProps = {
|
||||||
className?: string | Binding<string | undefined>;
|
className?: string | Binding<string | undefined>;
|
||||||
iconName?: string | Binding<string | undefined>;
|
icon?: string | Binding<string | undefined>;
|
||||||
visible?: boolean | Binding<boolean | undefined>;
|
visible?: boolean | Binding<boolean | undefined>;
|
||||||
iconSize?: number | Binding<number | undefined>;
|
iconSize?: number | Binding<number | undefined>;
|
||||||
title: string | Binding<string>;
|
title: string | Binding<string | undefined>;
|
||||||
description?: string | Binding<string | undefined>;
|
description?: string | Binding<string | undefined>;
|
||||||
defaultToggleState?: boolean;
|
toggleState?: boolean | Binding<boolean | undefined>;
|
||||||
onToggledOn: () => void;
|
onToggledOn: () => void;
|
||||||
onToggledOff: () => void;
|
onToggledOff: () => void;
|
||||||
onClickMore?: () => void;
|
onClickMore?: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function Tile(props: TileProps): Widget.Box {
|
export function Tile(props: TileProps): Widget.EventBox {
|
||||||
|
const toggled = new Variable<boolean>(props.toggleState instanceof Binding ?
|
||||||
|
(props.toggleState.get() || false) : (props.toggleState || false));
|
||||||
|
|
||||||
const toggleButton = new Gtk.ToggleButton();
|
if(props?.toggleState instanceof Binding)
|
||||||
toggleButton.set_active(props.defaultToggleState || false);
|
props.toggleState.subscribe(val => toggled.set(val || false))();
|
||||||
|
|
||||||
const moreButton = new Widget.Button({
|
return new Widget.EventBox({
|
||||||
className: "more",
|
className: toggled().as((state: boolean) =>
|
||||||
visible: props.onClickMore
|
state ? "tile-eventbox toggled" : "tile-eventbox"),
|
||||||
});
|
expand: true,
|
||||||
|
onClick: () => {
|
||||||
|
if(toggled.get()) {
|
||||||
|
toggled.set(false);
|
||||||
|
console.log(toggled.get());
|
||||||
|
props.onToggledOff && props.onToggledOff();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return new Widget.Box({
|
toggled.set(true);
|
||||||
className: (typeof Binding<string | undefined>) === (typeof props.className) ?
|
props.onToggledOn && props.onToggledOn();
|
||||||
(props.className as Binding<string | undefined>).as((clsName: (string|undefined)) =>
|
},
|
||||||
`tile ${clsName || ""}`)
|
child: new Widget.Box({
|
||||||
:
|
className: (props.className instanceof Binding) ?
|
||||||
props.className,
|
props.className.as((clsName: (string|undefined)) =>
|
||||||
visible: props.visible,
|
`tile ${clsName || ""}`)
|
||||||
children: [
|
: `tile ${props.className || ""}`,
|
||||||
toggleButton,
|
visible: props.visible,
|
||||||
moreButton
|
expand: true,
|
||||||
]
|
hexpand: true,
|
||||||
})
|
children: [
|
||||||
|
new Widget.Box({
|
||||||
|
className: "content",
|
||||||
|
expand: true,
|
||||||
|
children: [
|
||||||
|
new Widget.Label({
|
||||||
|
className: "icon nf",
|
||||||
|
label: props.icon || "icon",
|
||||||
|
css: `.icon { font-size: ${props.iconSize || "12px"} }`
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Box({
|
||||||
|
className: "text",
|
||||||
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
vexpand: true,
|
||||||
|
valign: Gtk.Align.CENTER,
|
||||||
|
children: [
|
||||||
|
new Widget.Label({
|
||||||
|
className: "title",
|
||||||
|
xalign: 0,
|
||||||
|
truncate: true,
|
||||||
|
label: props.title
|
||||||
|
} as Widget.LabelProps),
|
||||||
|
new Widget.Label({
|
||||||
|
className: "description",
|
||||||
|
visible: props.description,
|
||||||
|
truncate: true,
|
||||||
|
xalign: 0,
|
||||||
|
label: props.description
|
||||||
|
} as Widget.LabelProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps)
|
||||||
|
]
|
||||||
|
} as Widget.BoxProps),
|
||||||
|
new Widget.Button({
|
||||||
|
className: "more icon",
|
||||||
|
visible: props.onClickMore !== undefined,
|
||||||
|
halign: Gtk.Align.END,
|
||||||
|
image: new Widget.Icon({
|
||||||
|
icon: "go-next-symbolic",
|
||||||
|
css: "icon { font-size: 16px; }"
|
||||||
|
}),
|
||||||
|
onClick: () => props.onClickMore && props?.onClickMore(),
|
||||||
|
widthRequest: 32
|
||||||
|
})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
} as Widget.EventBoxProps)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,19 @@
|
|||||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
import { bind, GLib } from "astal";
|
import { bind, GLib } from "astal";
|
||||||
|
|
||||||
import { getDateTime } from "../scripts/time";
|
import { getDateTime } from "../scripts/time";
|
||||||
import { BigMedia } from "../widget/center-window/BigMedia";
|
import { BigMedia } from "../widget/center-window/BigMedia";
|
||||||
import { Separator, SeparatorProps } from "../widget/Separator";
|
import { Separator, SeparatorProps } from "../widget/Separator";
|
||||||
|
import { PopupWindow, PopupWindowProps } from "../widget/PopupWindow";
|
||||||
|
|
||||||
export const CenterWindow: Widget.Window = new Widget.Window({
|
export const CenterWindow: Widget.Window = PopupWindow({
|
||||||
className: "center-window",
|
className: "center-window",
|
||||||
namespace: "center-window",
|
namespace: "center-window",
|
||||||
canFocus: true,
|
|
||||||
monitor: 0,
|
monitor: 0,
|
||||||
layer: Astal.Layer.OVERLAY,
|
|
||||||
exclusivity: Astal.Exclusivity.NORMAL,
|
|
||||||
visible: false,
|
visible: false,
|
||||||
margin_top: 10,
|
marginTop: 10,
|
||||||
anchor: Astal.WindowAnchor.TOP,
|
valign: Gtk.Align.START,
|
||||||
|
halign: Gtk.Align.CENTER,
|
||||||
child: new Widget.Box({
|
child: new Widget.Box({
|
||||||
className: "center-window-container",
|
className: "center-window-container",
|
||||||
children: [
|
children: [
|
||||||
@@ -69,4 +68,4 @@ export const CenterWindow: Widget.Window = new Widget.Window({
|
|||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
} as Widget.WindowProps);
|
} as PopupWindowProps);
|
||||||
|
|||||||
+15
-12
@@ -1,26 +1,29 @@
|
|||||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
import { Gtk, Widget } from "astal/gtk3";
|
||||||
import { QuickActions } from "../widget/control-center/QuickActions";
|
import { QuickActions } from "../widget/control-center/QuickActions";
|
||||||
import { Tiles } from "../widget/control-center/Tiles";
|
import { Tiles } from "../widget/control-center/Tiles";
|
||||||
import { Sliders } from "../widget/control-center/Sliders";
|
import { Sliders } from "../widget/control-center/Sliders";
|
||||||
|
import { PopupWindow, PopupWindowProps } from "../widget/PopupWindow";
|
||||||
|
import { hidePages, PagesWidget } from "../widget/control-center/Pages";
|
||||||
|
|
||||||
const widgetsContainer: Widget.Box = new Widget.Box({
|
const widgetsContainer: Widget.Box = new Widget.Box({
|
||||||
className: "control-center-container",
|
className: "control-center-container",
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
widthRequest: 400,
|
||||||
} as Widget.BoxProps,
|
} as Widget.BoxProps,
|
||||||
QuickActions,
|
QuickActions,
|
||||||
Sliders,
|
Sliders,
|
||||||
Tiles);
|
Tiles,
|
||||||
|
PagesWidget);
|
||||||
|
|
||||||
export const ControlCenter: Widget.Window = new Widget.Window({
|
export const ControlCenter: Widget.Window = PopupWindow({
|
||||||
className: "control-center",
|
className: "control-center",
|
||||||
namespace: "control-center",
|
namespace: "control-center",
|
||||||
canFocus: true,
|
marginTop: 10,
|
||||||
exclusivity: Astal.Exclusivity.NORMAL,
|
marginRight: 10,
|
||||||
anchor: Astal.WindowAnchor.TOP | Astal.WindowAnchor.RIGHT,
|
|
||||||
layer: Astal.Layer.OVERLAY,
|
|
||||||
margin_top: 10,
|
|
||||||
margin_right: 10,
|
|
||||||
width_request: 400,
|
|
||||||
monitor: 0,
|
monitor: 0,
|
||||||
visible: false
|
onClose: () => hidePages(),
|
||||||
} as Widget.WindowProps, widgetsContainer);
|
halign: Gtk.Align.END,
|
||||||
|
valign: Gtk.Align.START,
|
||||||
|
visible: false,
|
||||||
|
child: widgetsContainer
|
||||||
|
} as PopupWindowProps);
|
||||||
|
|||||||
@@ -1,71 +1,7 @@
|
|||||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
import { Astal, Gtk, Widget } from "astal/gtk3";
|
||||||
import AstalNotifd from "gi://AstalNotifd";
|
import AstalNotifd from "gi://AstalNotifd";
|
||||||
import { bind } from "astal";
|
|
||||||
import { Notifications } from "../scripts/notification-handler";
|
import { Notifications } from "../scripts/notification-handler";
|
||||||
|
|
||||||
function NotificationWidget(notification: AstalNotifd.Notification): Gtk.Widget {
|
|
||||||
return new Widget.Box({
|
|
||||||
className: "notification",
|
|
||||||
homogeneous: false,
|
|
||||||
expand: false,
|
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
|
||||||
children: [
|
|
||||||
new Widget.Box({
|
|
||||||
className: "top",
|
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
|
||||||
hexpand: true,
|
|
||||||
vexpand: false,
|
|
||||||
children: [
|
|
||||||
new Widget.Icon({
|
|
||||||
className: "icon",
|
|
||||||
visible: notification.appIcon !== "",
|
|
||||||
icon: notification.appIcon || "image-missing",
|
|
||||||
iconSize: Gtk.IconSize.DND,
|
|
||||||
css: ".icon { font-size: 24px; }"
|
|
||||||
}),
|
|
||||||
new Widget.Label({
|
|
||||||
className: "app-name",
|
|
||||||
halign: Gtk.Align.START,
|
|
||||||
label: notification.appName || "Unknown Application"
|
|
||||||
} as Widget.LabelProps),
|
|
||||||
new Widget.Button({
|
|
||||||
className: "close nf",
|
|
||||||
onClick: () => notification.dismiss(),
|
|
||||||
label: ""
|
|
||||||
} as Widget.ButtonProps)
|
|
||||||
]
|
|
||||||
} as Widget.BoxProps),
|
|
||||||
new Widget.Box({
|
|
||||||
className: "content",
|
|
||||||
orientation: Gtk.Orientation.HORIZONTAL,
|
|
||||||
children: [
|
|
||||||
new Widget.Box({
|
|
||||||
className: "image",
|
|
||||||
visible: notification.image !== "",
|
|
||||||
css: `box.image { background-image: url('${notification.image}'); }`
|
|
||||||
} as Widget.BoxProps),
|
|
||||||
new Widget.Box({
|
|
||||||
className: "text",
|
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
|
||||||
children: [
|
|
||||||
new Widget.Label({
|
|
||||||
className: "summary",
|
|
||||||
useMarkup: true,
|
|
||||||
label: notification.summary
|
|
||||||
}),
|
|
||||||
new Widget.Label({
|
|
||||||
className: "body",
|
|
||||||
useMarkup: true,
|
|
||||||
label: notification.body
|
|
||||||
} as Widget.LabelProps)
|
|
||||||
]
|
|
||||||
} as Widget.BoxProps)
|
|
||||||
]
|
|
||||||
} as Widget.BoxProps)
|
|
||||||
]
|
|
||||||
} as Widget.BoxProps);
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FloatingNotifications: Widget.Window = new Widget.Window({
|
export const FloatingNotifications: Widget.Window = new Widget.Window({
|
||||||
namespace: "floating-notifications",
|
namespace: "floating-notifications",
|
||||||
canFocus: false,
|
canFocus: false,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Astal, Gdk, Gtk, Widget } from "astal/gtk3";
|
import { Astal, Gdk, Gtk, Widget } from "astal/gtk3";
|
||||||
import { getDateTime } from "../scripts/time";
|
import { getDateTime } from "../scripts/time";
|
||||||
import { execAsync, GLib, Process } from "astal";
|
import { execAsync, GLib } from "astal";
|
||||||
|
|
||||||
|
|
||||||
const { TOP, LEFT, RIGHT, BOTTOM } = Astal.WindowAnchor;
|
const { TOP, LEFT, RIGHT, BOTTOM } = Astal.WindowAnchor;
|
||||||
@@ -10,19 +10,25 @@ export const LogoutMenu: Widget.Window = new Widget.Window({
|
|||||||
anchor: TOP | LEFT | RIGHT | BOTTOM,
|
anchor: TOP | LEFT | RIGHT | BOTTOM,
|
||||||
layer: Astal.Layer.OVERLAY,
|
layer: Astal.Layer.OVERLAY,
|
||||||
exclusivity: Astal.Exclusivity.IGNORE,
|
exclusivity: Astal.Exclusivity.IGNORE,
|
||||||
|
keymode: Astal.Keymode.EXCLUSIVE,
|
||||||
monitor: 0,
|
monitor: 0,
|
||||||
visible: false,
|
visible: false,
|
||||||
|
onKeyPressEvent: (_, event: Gdk.Event) => {
|
||||||
|
event.get_keyval()[1] === Gdk.KEY_Escape &&
|
||||||
|
execAsync("astal close logout-menu")
|
||||||
|
},
|
||||||
child: new Widget.EventBox({
|
child: new Widget.EventBox({
|
||||||
className: "logout-menu",
|
className: "logout-menu",
|
||||||
onClick: () => Process.exec_async("astal close logout-menu", () => {}),
|
onClick: () => execAsync("astal close logout-menu"),
|
||||||
child: new Widget.Box({
|
child: new Widget.Box({
|
||||||
homogeneous: false,
|
expand: true,
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
children: [
|
children: [
|
||||||
new Widget.Box({
|
new Widget.Box({
|
||||||
className: "top",
|
className: "top",
|
||||||
expand: true,
|
expand: false,
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
|
valign: Gtk.Align.START,
|
||||||
children: [
|
children: [
|
||||||
new Widget.Label({
|
new Widget.Label({
|
||||||
className: "time",
|
className: "time",
|
||||||
@@ -45,17 +51,17 @@ export const LogoutMenu: Widget.Window = new Widget.Window({
|
|||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "poweroff nf",
|
className: "poweroff nf",
|
||||||
label: "",
|
label: "",
|
||||||
onClick: "ask user if it's fr!"
|
onClick: () => execAsync("systemctl poweroff")
|
||||||
} as Widget.ButtonProps),
|
} as Widget.ButtonProps),
|
||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "reboot nf",
|
className: "reboot nf",
|
||||||
label: "",
|
label: "",
|
||||||
onClick: "ask user if it's fr!"
|
onClick: () => execAsync("systemctl reboot")
|
||||||
} as Widget.ButtonProps),
|
} as Widget.ButtonProps),
|
||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "suspend nf",
|
className: "suspend nf",
|
||||||
label: "",
|
label: "",
|
||||||
onClick: "ask user if it's fr!"
|
onClick: () => execAsync("systemctl suspend")
|
||||||
} as Widget.ButtonProps),
|
} as Widget.ButtonProps),
|
||||||
new Widget.Button({
|
new Widget.Button({
|
||||||
className: "logout nf",
|
className: "logout nf",
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import { Variable } from "astal";
|
import { Variable } from "astal";
|
||||||
import { Astal, Gtk, Widget } from "astal/gtk3";
|
import { Astal, Gtk, Widget } from "astal/gtk3";
|
||||||
|
import { PopupWindow, PopupWindowProps } from "../widget/PopupWindow";
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
export interface RunnerProps {
|
export interface RunnerProps {
|
||||||
anchor?: Astal.WindowAnchor;
|
halign?: Gtk.Align;
|
||||||
|
valign?: Gtk.Align;
|
||||||
width?: number;
|
width?: number;
|
||||||
height?: number;
|
height?: number;
|
||||||
entryPlaceHolder?: string;
|
entryPlaceHolder?: string;
|
||||||
@@ -20,8 +22,10 @@ export function Runner(props?: RunnerProps) {
|
|||||||
|
|
||||||
} as Widget.BoxProps);
|
} as Widget.BoxProps);
|
||||||
|
|
||||||
return new Widget.Window({
|
return PopupWindow({
|
||||||
namespace: "runner",
|
namespace: "runner",
|
||||||
|
halign: props?.halign || Gtk.Align.CENTER,
|
||||||
|
valign: props?.valign || Gtk.Align.CENTER,
|
||||||
widthRequest: props?.width || 600,
|
widthRequest: props?.width || 600,
|
||||||
heightRequest: props?.height || 500,
|
heightRequest: props?.height || 500,
|
||||||
child: new Widget.Box({
|
child: new Widget.Box({
|
||||||
@@ -33,5 +37,5 @@ export function Runner(props?: RunnerProps) {
|
|||||||
} as Widget.EntryProps),
|
} as Widget.EntryProps),
|
||||||
]
|
]
|
||||||
} as Widget.BoxProps)
|
} as Widget.BoxProps)
|
||||||
} as Widget.WindowProps);
|
} as PopupWindowProps);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
import { Variable } from "astal";
|
||||||
|
import { Astal, Gdk, Gtk, Widget } from "astal/gtk3";
|
||||||
|
import { restartInstance } from "../scripts/reload-handler";
|
||||||
|
|
||||||
|
const { LEFT, RIGHT, TOP, BOTTOM } = Astal.WindowAnchor;
|
||||||
|
const wallpaper: Variable<string|undefined> = new Variable<string|undefined>(undefined);
|
||||||
|
|
||||||
|
const changeWallpaperButton = new Gtk.MenuItem();
|
||||||
|
changeWallpaperButton.set_label("Change wallpaper");
|
||||||
|
|
||||||
|
const reloadShellButton = new Gtk.MenuItem();
|
||||||
|
reloadShellButton.set_label("Reload Shell");
|
||||||
|
reloadShellButton.connect("activate", (_) => restartInstance());
|
||||||
|
|
||||||
|
const desktopMenuButtons: Array<Gtk.MenuItem> = [
|
||||||
|
changeWallpaperButton,
|
||||||
|
reloadShellButton
|
||||||
|
];
|
||||||
|
|
||||||
|
export const Wallpaper: Widget.Window = new Widget.Window({
|
||||||
|
namespace: "wallpaper",
|
||||||
|
layer: Astal.Layer.BACKGROUND,
|
||||||
|
anchor: LEFT | RIGHT | TOP | BOTTOM,
|
||||||
|
exclusivity: Astal.Exclusivity.IGNORE,
|
||||||
|
keymode: Astal.Keymode.NONE,
|
||||||
|
visible: true,
|
||||||
|
monitor: 0, //Needs rework for all monitors
|
||||||
|
child: new Widget.Box({
|
||||||
|
className: "wallpaper",
|
||||||
|
} as Widget.BoxProps),
|
||||||
|
onButtonPressEvent: (_, event: Gdk.Event) => {
|
||||||
|
const [ , x, y ] = event.get_coords();
|
||||||
|
if(event.get_button()[1] === Gdk.BUTTON_SECONDARY)
|
||||||
|
desktopMenu.popup_at_pointer(Gdk.Event.peek());
|
||||||
|
}
|
||||||
|
} as Widget.WindowProps);
|
||||||
|
|
||||||
|
const desktopMenu: Gtk.Menu = new Gtk.Menu({
|
||||||
|
visible: true,
|
||||||
|
monitor: Wallpaper.monitor || 0
|
||||||
|
} as Gtk.Menu.ConstructorProps);
|
||||||
|
|
||||||
|
desktopMenuButtons.map((item: Gtk.MenuItem) =>
|
||||||
|
desktopMenu.insert(item, -1))
|
||||||
+14
-15
@@ -5,28 +5,25 @@ import { OSD } from "./window/OSD";
|
|||||||
import { ControlCenter } from "./window/ControlCenter";
|
import { ControlCenter } from "./window/ControlCenter";
|
||||||
import { CenterWindow } from "./window/CenterWindow";
|
import { CenterWindow } from "./window/CenterWindow";
|
||||||
import { FloatingNotifications } from "./window/FloatingNotifications";
|
import { FloatingNotifications } from "./window/FloatingNotifications";
|
||||||
import { GObject } from "astal";
|
import { GObject, register } from "astal";
|
||||||
import { LogoutMenu } from "./window/LogoutMenu";
|
import { LogoutMenu } from "./window/LogoutMenu";
|
||||||
|
import { Wallpaper } from "./window/Wallpaper";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get open windows / interact with windows(e.g.: close, open or toggle)
|
* get open windows / interact with windows(e.g.: close, open or toggle)
|
||||||
*/
|
*/
|
||||||
export const Windows = GObject.registerClass({
|
@register({ GTypeName: "Windows" })
|
||||||
GTypeName: "Windows"
|
class WindowsClass extends GObject.Object {
|
||||||
}, class WindowsClass extends GObject.Object {
|
|
||||||
private static windowsMap: Map<string, Gtk.Window> = new Map<string, Gtk.Window>();
|
private static windowsMap: Map<string, Gtk.Window> = new Map<string, Gtk.Window>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
WindowsClass.windowsMap.set("bar", Bar);
|
this.setWindow("bar", Bar);
|
||||||
WindowsClass.windowsMap.set("osd", OSD);
|
this.setWindow("osd", OSD);
|
||||||
WindowsClass.windowsMap.set("control-center", ControlCenter);
|
this.setWindow("control-center", ControlCenter);
|
||||||
WindowsClass.windowsMap.set("center-window", CenterWindow);
|
this.setWindow("center-window", CenterWindow);
|
||||||
WindowsClass.windowsMap.set("logout-menu", LogoutMenu);
|
this.setWindow("logout-menu", LogoutMenu);
|
||||||
WindowsClass.windowsMap.set("floating-notifications", FloatingNotifications);
|
this.setWindow("floating-notifications", FloatingNotifications);
|
||||||
}
|
this.setWindow("wallpaper", Wallpaper);
|
||||||
|
|
||||||
public _init(...args: any[]) {
|
|
||||||
super._init(args);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static setWindow(name: string, window: Gtk.Window): void {
|
public static setWindow(name: string, window: Gtk.Window): void {
|
||||||
@@ -56,4 +53,6 @@ export const Windows = GObject.registerClass({
|
|||||||
public static toggle(window: Gtk.Window): void {
|
public static toggle(window: Gtk.Window): void {
|
||||||
window.is_visible() ? WindowsClass.close(window) : WindowsClass.open(window);
|
window.is_visible() ? WindowsClass.close(window) : WindowsClass.open(window);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
export { WindowsClass as Windows };
|
||||||
|
|||||||
Reference in New Issue
Block a user