✨ feat(control-center/page): restore bottom buttons for pages
it was accidentally removed previously, but now it's backgit add .git add .
This commit is contained in:
+1
-3
@@ -13,9 +13,7 @@
|
|||||||
"sync-config": "sh ./scripts/sync-config.sh"
|
"sync-config": "sh ./scripts/sync-config.sh"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"ags": "link:../../../../usr/share/ags/js"
|
"ags": "link:../../../../usr/share/ags/js",
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"gnim-utils": "github:retrozinndev/gnim-utils"
|
"gnim-utils": "github:retrozinndev/gnim-utils"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -203,7 +203,7 @@
|
|||||||
$radius: 18px;
|
$radius: 18px;
|
||||||
$padding: 4px;
|
$padding: 4px;
|
||||||
|
|
||||||
background: rgba(colors.$bg-primary, .5);
|
background: color.scale($color: colors.$bg-primary, $lightness: -25%);
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
padding: $padding;
|
padding: $padding;
|
||||||
min-height: 40px;
|
min-height: 40px;
|
||||||
|
|||||||
+23
-26
@@ -4,6 +4,7 @@ import { userData } from "../config";
|
|||||||
import GObject, { getter, gtype, property, register, setter } from "ags/gobject";
|
import GObject, { getter, gtype, property, register, setter } from "ags/gobject";
|
||||||
|
|
||||||
import AstalBluetooth from "gi://AstalBluetooth";
|
import AstalBluetooth from "gi://AstalBluetooth";
|
||||||
|
import { createScopedConnection } from "gnim-utils";
|
||||||
|
|
||||||
|
|
||||||
/** AstalBluetooth helper (implements the default adapter feature) */
|
/** AstalBluetooth helper (implements the default adapter feature) */
|
||||||
@@ -62,7 +63,7 @@ export class Bluetooth extends GObject.Object {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
createRoot((_) => {
|
createRoot(async () => {
|
||||||
this.#scope = getScope();
|
this.#scope = getScope();
|
||||||
|
|
||||||
if(this.astalBl.adapters.length > 0) {
|
if(this.astalBl.adapters.length > 0) {
|
||||||
@@ -77,36 +78,32 @@ export class Bluetooth extends GObject.Object {
|
|||||||
if(dataDefaultAdapter !== undefined && foundAdapter !== undefined)
|
if(dataDefaultAdapter !== undefined && foundAdapter !== undefined)
|
||||||
this.adapter = foundAdapter;
|
this.adapter = foundAdapter;
|
||||||
|
|
||||||
this.#connections.set(
|
createScopedConnection(AstalBluetooth.get_default(), "adapter-added", (adapter) => {
|
||||||
AstalBluetooth.get_default(), [
|
if(this.astalBl.adapters.length === 1) // adapter was just added
|
||||||
AstalBluetooth.get_default().connect("adapter-added", (self, adapter) => {
|
this.adapter = adapter;
|
||||||
if(self.adapters.length === 1) // adapter was just added
|
});
|
||||||
this.adapter = adapter;
|
createScopedConnection(AstalBluetooth.get_default(), "adapter-removed", (adapter) => {
|
||||||
}),
|
if(this.astalBl.adapters.length < 1) {
|
||||||
AstalBluetooth.get_default().connect("adapter-removed", (self, adapter) => {
|
this.adapter = null;
|
||||||
if(self.adapters.length < 1) {
|
this.#isAvailable = false;
|
||||||
this.adapter = null;
|
this.notify("is-available");
|
||||||
this.#isAvailable = false;
|
}
|
||||||
this.notify("is-available");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(this.#adapter?.address !== adapter.address)
|
if(this.#adapter?.address !== adapter.address)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// the removed adapter was the default
|
// the removed adapter was the default
|
||||||
|
|
||||||
if(self.adapters.length < 1) {
|
if(this.astalBl.adapters.length < 1) {
|
||||||
this.adapter = null;
|
this.adapter = null;
|
||||||
this.#isAvailable = false;
|
this.#isAvailable = false;
|
||||||
this.notify("is-available");
|
this.notify("is-available");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.#adapter = self.adapters[0];
|
this.#adapter = this.astalBl.adapters[0];
|
||||||
})
|
});
|
||||||
]
|
|
||||||
);
|
|
||||||
|
|
||||||
// async to prevent slow start
|
// async to prevent slow start
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
|||||||
@@ -2,12 +2,7 @@ import { createPoll } from "ags/time";
|
|||||||
import { exec, execAsync } from "ags/process";
|
import { exec, execAsync } from "ags/process";
|
||||||
import { Astal, Gtk } from "ags/gtk4";
|
import { Astal, Gtk } from "ags/gtk4";
|
||||||
import { getSymbolicIcon } from "./apps";
|
import { getSymbolicIcon } from "./apps";
|
||||||
|
|
||||||
import GLib from "gi://GLib?version=2.0";
|
|
||||||
import Gio from "gi://Gio?version=2.0";
|
|
||||||
|
|
||||||
export {
|
export {
|
||||||
type JSXNode as WidgetNodeType,
|
|
||||||
toBoolean as variableToBoolean,
|
toBoolean as variableToBoolean,
|
||||||
construct,
|
construct,
|
||||||
transform,
|
transform,
|
||||||
@@ -19,6 +14,9 @@ export {
|
|||||||
createSecureAccessorBinding as secureBaseBinding,
|
createSecureAccessorBinding as secureBaseBinding,
|
||||||
} from "gnim-utils";
|
} from "gnim-utils";
|
||||||
|
|
||||||
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
export const decoder = new TextDecoder("utf-8"),
|
export const decoder = new TextDecoder("utf-8"),
|
||||||
encoder = new TextEncoder();
|
encoder = new TextEncoder();
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import { Windows } from "../windows";
|
|||||||
import { getPopupWindowContainer, PopupWindow } from "./PopupWindow";
|
import { getPopupWindowContainer, PopupWindow } from "./PopupWindow";
|
||||||
import { Separator } from "./Separator";
|
import { Separator } from "./Separator";
|
||||||
import { tr } from "../i18n/intl";
|
import { tr } from "../i18n/intl";
|
||||||
import { Accessor } from "ags";
|
import { Accessor, Node } from "ags";
|
||||||
import { transformWidget, variableToBoolean, WidgetNodeType } from "../modules/utils";
|
import { transformWidget, variableToBoolean } from "../modules/utils";
|
||||||
|
|
||||||
|
|
||||||
export type CustomDialogProps = {
|
export type CustomDialogProps = {
|
||||||
@@ -16,7 +16,7 @@ export type CustomDialogProps = {
|
|||||||
heightRequest?: number | Accessor<number>;
|
heightRequest?: number | Accessor<number>;
|
||||||
widthRequest?: number | Accessor<number>;
|
widthRequest?: number | Accessor<number>;
|
||||||
childOrientation?: Gtk.Orientation | Accessor<Gtk.Orientation>;
|
childOrientation?: Gtk.Orientation | Accessor<Gtk.Orientation>;
|
||||||
children?: WidgetNodeType;
|
children?: Node;
|
||||||
onFinish?: () => void;
|
onFinish?: () => void;
|
||||||
options?: Array<CustomDialogOption> | Accessor<Array<CustomDialogOption>>;
|
options?: Array<CustomDialogOption> | Accessor<Array<CustomDialogOption>>;
|
||||||
optionsOrientation?: Gtk.Orientation | Accessor<Gtk.Orientation>;
|
optionsOrientation?: Gtk.Orientation | Accessor<Gtk.Orientation>;
|
||||||
|
|||||||
@@ -8,12 +8,7 @@ import { generalConfig } from "../../../config";
|
|||||||
export const Clock = () =>
|
export const Clock = () =>
|
||||||
<Gtk.Button class={createBinding(Windows.getDefault(), "openWindows").as((wins) =>
|
<Gtk.Button class={createBinding(Windows.getDefault(), "openWindows").as((wins) =>
|
||||||
`clock ${wins.includes("center-window") ? "open" : ""}`)}
|
`clock ${wins.includes("center-window") ? "open" : ""}`)}
|
||||||
$={(self) => {
|
onClicked={() => Windows.getDefault().toggle("center-window")}
|
||||||
const conns: Array<number> = [
|
|
||||||
self.connect("clicked", (_) => Windows.getDefault().toggle("center-window")),
|
|
||||||
self.connect("destroy", (_) => conns.forEach(id => self.disconnect(id)))
|
|
||||||
];
|
|
||||||
}}
|
|
||||||
label={time((dt) => dt.format(
|
label={time((dt) => dt.format(
|
||||||
generalConfig.getProperty("clock.date_format", "string"))
|
generalConfig.getProperty("clock.date_format", "string"))
|
||||||
?? "An error occurred"
|
?? "An error occurred"
|
||||||
|
|||||||
@@ -1,24 +1,13 @@
|
|||||||
import { Gtk } from "ags/gtk4";
|
import { Gtk } from "ags/gtk4";
|
||||||
import { Separator } from "../../../widget/Separator";
|
import { Separator } from "../../../widget/Separator";
|
||||||
import { Accessor, createRoot } from "ags";
|
import { Accessor, createBinding, createRoot, For, Node } from "ags";
|
||||||
import { transformWidget, variableToBoolean, WidgetNodeType } from "../../../modules/utils";
|
import { gtype, property, register } from "ags/gobject";
|
||||||
|
import { variableToBoolean } from "../../../modules/utils";
|
||||||
|
|
||||||
import Pango from "gi://Pango?version=1.0";
|
import Pango from "gi://Pango?version=1.0";
|
||||||
|
import GObject from "gi://GObject?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
export type PageProps = {
|
|
||||||
id: string;
|
|
||||||
title: string;
|
|
||||||
description?: string;
|
|
||||||
$?: (self: Gtk.Box) => void;
|
|
||||||
headerButtons?: Array<HeaderButton> | Accessor<Array<HeaderButton>>;
|
|
||||||
bottomButtons?: Array<BottomButton> | Accessor<Array<BottomButton>>;
|
|
||||||
orientation?: Gtk.Orientation | Accessor<Gtk.Orientation>;
|
|
||||||
spacing?: number | Accessor<number>;
|
|
||||||
content: () => WidgetNodeType;
|
|
||||||
actionClosed?: () => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BottomButton = {
|
export type BottomButton = {
|
||||||
title: string | Accessor<string>;
|
title: string | Accessor<string>;
|
||||||
description?: string | Accessor<string>;
|
description?: string | Accessor<string>;
|
||||||
@@ -35,93 +24,129 @@ export type HeaderButton = {
|
|||||||
actionClicked?: () => void;
|
actionClicked?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Page {
|
@register({ GTypeName: "Page" })
|
||||||
#title: string;
|
export class Page extends GObject.Object {
|
||||||
#description?: string;
|
readonly #id: string;
|
||||||
#orientation: Gtk.Orientation|Accessor<
|
readonly #create: () => Node;
|
||||||
Gtk.Orientation> = Gtk.Orientation.VERTICAL;
|
|
||||||
#spacing: number|Accessor<number> = 4;
|
|
||||||
#headerButtons?: Array<HeaderButton>|Accessor<Array<HeaderButton>>;
|
|
||||||
#bottomButtons?: Array<BottomButton>|Accessor<Array<BottomButton>>;
|
|
||||||
#setup?: (self: Gtk.Box) => void;
|
|
||||||
readonly #id?: string;
|
|
||||||
readonly #create: () => WidgetNodeType;
|
|
||||||
|
|
||||||
public get id() { return this.#id; }
|
|
||||||
public get title() { return this.#title; }
|
|
||||||
public get description() { return this.#description; }
|
|
||||||
public get headerButtons() { return this.#headerButtons; }
|
|
||||||
public get bottomButtons() { return this.#bottomButtons; }
|
|
||||||
public readonly actionClosed?: () => void;
|
public readonly actionClosed?: () => void;
|
||||||
|
public readonly actionOpen?: () => void;
|
||||||
|
public get id() { return this.#id; }
|
||||||
|
|
||||||
|
@property(String)
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@property(gtype<string|null>(String))
|
||||||
|
description: string|null = null;
|
||||||
|
|
||||||
|
@property(gtype<Gtk.Orientation>(Number))
|
||||||
|
orientation: Gtk.Orientation = Gtk.Orientation.VERTICAL;
|
||||||
|
|
||||||
|
@property(Number)
|
||||||
|
spacing: number = 4;
|
||||||
|
|
||||||
|
@property(Array<HeaderButton>)
|
||||||
|
headerButtons: Array<HeaderButton> = [];
|
||||||
|
@property(Array<BottomButton>)
|
||||||
|
bottomButtons: Array<BottomButton> = [];
|
||||||
|
|
||||||
|
|
||||||
|
constructor(props: {
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
description?: string;
|
||||||
|
headerButtons?: Array<HeaderButton>;
|
||||||
|
bottomButtons?: Array<BottomButton>;
|
||||||
|
orientation?: Gtk.Orientation;
|
||||||
|
spacing?: number;
|
||||||
|
content: () => Node;
|
||||||
|
actionOpen?: () => void;
|
||||||
|
actionClosed?: () => void;
|
||||||
|
}) {
|
||||||
|
super();
|
||||||
|
|
||||||
constructor(props: PageProps) {
|
|
||||||
this.#id = props.id;
|
this.#id = props.id;
|
||||||
this.#title = props.title;
|
|
||||||
this.#description = props.description;
|
|
||||||
this.#create = props.content;
|
this.#create = props.content;
|
||||||
|
|
||||||
|
this.title = props.title;
|
||||||
this.actionClosed = props.actionClosed;
|
this.actionClosed = props.actionClosed;
|
||||||
|
this.actionOpen = props.actionOpen;
|
||||||
|
|
||||||
if(props.orientation != null)
|
if(props.orientation != null)
|
||||||
this.#orientation = props.orientation;
|
this.orientation = props.orientation;
|
||||||
|
|
||||||
|
if(props.description != null)
|
||||||
|
this.description = props.description;
|
||||||
|
|
||||||
if(props.spacing != null)
|
if(props.spacing != null)
|
||||||
this.#spacing = props.spacing;
|
this.spacing = props.spacing;
|
||||||
|
|
||||||
if(props.headerButtons != null)
|
if(props.headerButtons != null)
|
||||||
this.#headerButtons = props.headerButtons;
|
this.headerButtons = props.headerButtons;
|
||||||
|
|
||||||
if(props.$ != null)
|
if(props.bottomButtons != null)
|
||||||
this.#setup = props.$;
|
this.bottomButtons = props.bottomButtons;
|
||||||
|
|
||||||
|
if(props.actionOpen != null)
|
||||||
|
this.actionOpen = props.actionOpen;
|
||||||
|
|
||||||
|
if(props.actionClosed != null)
|
||||||
|
this.actionClosed = props.actionClosed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public create(): Gtk.Box {
|
public create(): Gtk.Box {
|
||||||
return createRoot((dispose) =>
|
return createRoot((dispose) =>
|
||||||
<Gtk.Box hexpand class={`page container ${this.#id ?? ""}`} cssName={"page"} name={"page"}
|
<Gtk.Box hexpand class={`page container ${this.#id ?? ""}`} cssName={"page"} name={"page"}
|
||||||
orientation={Gtk.Orientation.VERTICAL} onUnmap={() => dispose()}
|
orientation={Gtk.Orientation.VERTICAL}
|
||||||
$={this.#setup}>
|
onDestroy={() => dispose()}>
|
||||||
|
|
||||||
<Gtk.Box class={"header"} orientation={Gtk.Orientation.VERTICAL}>
|
<Gtk.Box class={"header"} orientation={Gtk.Orientation.VERTICAL}>
|
||||||
<Gtk.Box class={"top"} hexpand>
|
<Gtk.Box class={"top"} hexpand>
|
||||||
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} hexpand>
|
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} hexpand>
|
||||||
<Gtk.Label class={"title"} label={this.#title} xalign={0}
|
<Gtk.Label class={"title"} label={createBinding(this, "title")} xalign={0}
|
||||||
ellipsize={Pango.EllipsizeMode.END} />
|
ellipsize={Pango.EllipsizeMode.END} />
|
||||||
|
|
||||||
<Gtk.Label class={"description"} label={this.#description}
|
<Gtk.Label class={"description"} label={createBinding(this, "description").as(desc =>
|
||||||
xalign={0} ellipsize={Pango.EllipsizeMode.END}
|
desc ?? ""
|
||||||
visible={variableToBoolean(this.#description)} />
|
)} xalign={0} ellipsize={Pango.EllipsizeMode.END}
|
||||||
|
visible={variableToBoolean(createBinding(this, "description"))} />
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
<Gtk.Box class={"button-row"} visible={variableToBoolean(this.#headerButtons)}
|
<Gtk.Box class={"button-row"} visible={variableToBoolean(
|
||||||
hexpand={false}>
|
createBinding(this, "headerButtons")
|
||||||
|
)} hexpand={false}>
|
||||||
|
|
||||||
{this.#headerButtons && transformWidget(this.#headerButtons, (button) =>
|
<For each={createBinding(this, "headerButtons")}>
|
||||||
<Gtk.Button class={"header-button"} label={button.label}
|
{(button: HeaderButton) =>
|
||||||
iconName={button.icon} onClicked={() => button.actionClicked?.()}
|
<Gtk.Button class={"header-button"} label={button.label}
|
||||||
tooltipText={button.tooltipText} tooltipMarkup={button.tooltipMarkup}
|
iconName={button.icon} onClicked={() => button.actionClicked?.()}
|
||||||
/>
|
tooltipText={button.tooltipText} tooltipMarkup={button.tooltipMarkup}
|
||||||
)}
|
/>
|
||||||
|
}
|
||||||
|
</For>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
<Gtk.Box class={"content"} hexpand={false} orientation={this.#orientation}
|
<Gtk.Box class={"content"} hexpand={false} orientation={createBinding(this, "orientation")}
|
||||||
spacing={this.#spacing}>
|
spacing={createBinding(this, "spacing")}>
|
||||||
|
|
||||||
{this.#create()}
|
{this.#create()}
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
<Separator alpha={.2} spacing={6} orientation={Gtk.Orientation.VERTICAL}
|
<Separator alpha={.2} spacing={6} orientation={Gtk.Orientation.VERTICAL}
|
||||||
visible={variableToBoolean(this.#bottomButtons)}
|
visible={variableToBoolean(createBinding(this, "bottomButtons"))}
|
||||||
/>
|
/>
|
||||||
<Gtk.Box class={"bottom-buttons"} orientation={Gtk.Orientation.VERTICAL}
|
<Gtk.Box class={"bottom-buttons"} orientation={Gtk.Orientation.VERTICAL}
|
||||||
visible={variableToBoolean(this.#bottomButtons)} spacing={2}>
|
visible={variableToBoolean(createBinding(this, "bottomButtons"))} spacing={2}>
|
||||||
|
|
||||||
{this.#bottomButtons && transformWidget(this.#bottomButtons, (button) =>
|
<For each={createBinding(this, "bottomButtons")}>
|
||||||
<Gtk.Button onClicked={() => button?.actionClicked?.()} tooltipText={button?.tooltipText}
|
{(button: BottomButton) =>
|
||||||
tooltipMarkup={button?.tooltipMarkup}>
|
<PageButton actionClicked={() => button.actionClicked?.()}
|
||||||
|
tooltipText={button.tooltipText}
|
||||||
<Gtk.Label class={"title"} label={button?.title} xalign={0} />
|
tooltipMarkup={button.tooltipMarkup}
|
||||||
<Gtk.Label class={"description"} label={button?.description}
|
title={button.title}
|
||||||
xalign={0} visible={variableToBoolean(button?.description)} />
|
description={button.description}
|
||||||
</Gtk.Button>
|
/>
|
||||||
)}
|
}
|
||||||
|
</For>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
</Gtk.Box> as Gtk.Box
|
</Gtk.Box> as Gtk.Box
|
||||||
);
|
);
|
||||||
@@ -136,9 +161,9 @@ export function PageButton({ onUnmap, ...props }: {
|
|||||||
class?: string | Accessor<string>;
|
class?: string | Accessor<string>;
|
||||||
icon?: string | Accessor<string>;
|
icon?: string | Accessor<string>;
|
||||||
title: string | Accessor<string>;
|
title: string | Accessor<string>;
|
||||||
endWidget?: WidgetNodeType;
|
endWidget?: Node;
|
||||||
description?: string | Accessor<string>;
|
description?: string | Accessor<string>;
|
||||||
extraButtons?: Array<WidgetNodeType> | WidgetNodeType;
|
extraButtons?: Node;
|
||||||
maxWidthChars?: number | Accessor<number>;
|
maxWidthChars?: number | Accessor<number>;
|
||||||
onUnmap?: (self: Gtk.Box) => void;
|
onUnmap?: (self: Gtk.Box) => void;
|
||||||
actionClicked?: (self: Gtk.Button) => void;
|
actionClicked?: (self: Gtk.Button) => void;
|
||||||
@@ -170,7 +195,7 @@ export function PageButton({ onUnmap, ...props }: {
|
|||||||
</Gtk.Button>
|
</Gtk.Button>
|
||||||
|
|
||||||
<Gtk.Box class={"extra-buttons"} visible={variableToBoolean(props.extraButtons)}>
|
<Gtk.Box class={"extra-buttons"} visible={variableToBoolean(props.extraButtons)}>
|
||||||
{props.extraButtons}
|
{props.extraButtons as Node}
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
</Gtk.Box> as Gtk.Box;
|
</Gtk.Box> as Gtk.Box;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ import { addSliderMarksFromMinMax } from "../../../../modules/utils";
|
|||||||
import { userData } from "../../../../config";
|
import { userData } from "../../../../config";
|
||||||
|
|
||||||
|
|
||||||
export const PageBacklight = new Page({
|
export const PageBacklight = <Page
|
||||||
id: "backlight",
|
id={"backlight"}
|
||||||
title: tr("control_center.pages.backlight.title"),
|
title={tr("control_center.pages.backlight.title")}
|
||||||
description: tr("control_center.pages.backlight.description"),
|
description={tr("control_center.pages.backlight.description")}
|
||||||
$: () => {
|
actionOpen={() => {
|
||||||
const dataDefaultBacklight = userData.getProperty("control_center.default_backlight", "any");
|
const dataDefaultBacklight = userData.getProperty("control_center.default_backlight", "any");
|
||||||
if(typeof dataDefaultBacklight === "string" &&
|
if(typeof dataDefaultBacklight === "string" &&
|
||||||
Backlights.getDefault().default?.name !== dataDefaultBacklight) {
|
Backlights.getDefault().default?.name !== dataDefaultBacklight) {
|
||||||
@@ -21,8 +21,8 @@ export const PageBacklight = new Page({
|
|||||||
|
|
||||||
Backlights.getDefault().setDefault(bk);
|
Backlights.getDefault().setDefault(bk);
|
||||||
}
|
}
|
||||||
},
|
}}
|
||||||
content: () => (
|
content={() => (
|
||||||
<With value={createBinding(Backlights.getDefault(), "backlights")}>
|
<With value={createBinding(Backlights.getDefault(), "backlights")}>
|
||||||
{(bklights: Array<Backlights.Backlight>) => bklights.length > 0 &&
|
{(bklights: Array<Backlights.Backlight>) => bklights.length > 0 &&
|
||||||
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} spacing={4}>
|
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} spacing={4}>
|
||||||
@@ -75,10 +75,10 @@ export const PageBacklight = new Page({
|
|||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
}
|
}
|
||||||
</With>
|
</With>
|
||||||
),
|
)}
|
||||||
headerButtons: [{
|
headerButtons={[{
|
||||||
icon: "arrow-circular-top-right",
|
icon: "arrow-circular-top-right",
|
||||||
tooltipText: tr("control_center.pages.backlight.refresh"),
|
tooltipText: tr("control_center.pages.backlight.refresh"),
|
||||||
actionClicked: () => Backlights.getDefault().scan()
|
actionClicked: () => Backlights.getDefault().scan()
|
||||||
}]
|
}]}
|
||||||
});
|
/> as Page;
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Windows } from "../../../../windows";
|
|||||||
import { Notifications } from "../../../../modules/notifications";
|
import { Notifications } from "../../../../modules/notifications";
|
||||||
import { execApp } from "../../../../modules/apps";
|
import { execApp } from "../../../../modules/apps";
|
||||||
import { createBinding, createComputed, For, With } from "ags";
|
import { createBinding, createComputed, For, With } from "ags";
|
||||||
|
import { variableToBoolean } from "../../../../modules/utils";
|
||||||
import { Bluetooth } from "../../../../modules/bluetooth";
|
import { Bluetooth } from "../../../../modules/bluetooth";
|
||||||
|
|
||||||
import AstalNotifd from "gi://AstalNotifd";
|
import AstalNotifd from "gi://AstalNotifd";
|
||||||
@@ -13,12 +14,12 @@ import Adw from "gi://Adw?version=1";
|
|||||||
import Gio from "gi://Gio?version=2.0";
|
import Gio from "gi://Gio?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
export const BluetoothPage = new Page({
|
export const BluetoothPage = <Page
|
||||||
id: "bluetooth",
|
id={"bluetooth"}
|
||||||
title: tr("control_center.pages.bluetooth.title"),
|
title={tr("control_center.pages.bluetooth.title")}
|
||||||
spacing: 6,
|
spacing={6}
|
||||||
description: tr("control_center.pages.bluetooth.description"),
|
description={tr("control_center.pages.bluetooth.description")}
|
||||||
headerButtons: createBinding(Bluetooth.getDefault(), "adapter").as(adapter => adapter ? [{
|
headerButtons={createBinding(Bluetooth.getDefault(), "adapter").as(adapter => adapter ? [{
|
||||||
icon: createBinding(adapter, "discovering")
|
icon: createBinding(adapter, "discovering")
|
||||||
.as(discovering => !discovering ?
|
.as(discovering => !discovering ?
|
||||||
"arrow-circular-top-right-symbolic"
|
"arrow-circular-top-right-symbolic"
|
||||||
@@ -36,20 +37,25 @@ export const BluetoothPage = new Page({
|
|||||||
|
|
||||||
adapter.start_discovery();
|
adapter.start_discovery();
|
||||||
}
|
}
|
||||||
}]: []),
|
}]: [])}
|
||||||
actionClosed: () => Bluetooth.getDefault().adapter?.discovering &&
|
actionClosed={() => Bluetooth.getDefault().adapter?.discovering &&
|
||||||
Bluetooth.getDefault().adapter?.stop_discovery(),
|
Bluetooth.getDefault().adapter?.stop_discovery()}
|
||||||
bottomButtons: [{
|
bottomButtons={[{
|
||||||
title: tr("control_center.pages.more_settings"),
|
title: tr("control_center.pages.more_settings"),
|
||||||
actionClicked: () => {
|
actionClicked: () => {
|
||||||
Windows.getDefault().close("control-center");
|
Windows.getDefault().close("control-center");
|
||||||
execApp("overskride", "[float; animation slide right]");
|
execApp("overskride", "[float; animation slide right]");
|
||||||
}
|
}
|
||||||
}],
|
}]}
|
||||||
content: () => {
|
content={() => {
|
||||||
const adapter = createBinding(Bluetooth.getDefault(), "adapter");
|
|
||||||
const adapters = createBinding(AstalBluetooth.get_default(), "adapters");
|
const adapters = createBinding(AstalBluetooth.get_default(), "adapters");
|
||||||
const devices = createBinding(AstalBluetooth.get_default(), "devices");
|
const devices = createBinding(AstalBluetooth.get_default(), "devices");
|
||||||
|
const knownDevices = devices.as(devs => devs.filter(dev =>
|
||||||
|
dev.trusted || dev.paired || dev.connected
|
||||||
|
).sort(dev => dev.connected ? 1 : 0));
|
||||||
|
const discoveredDevices = devices.as(devs => devs.filter(dev =>
|
||||||
|
!dev.trusted && !dev.paired && !dev.connected)
|
||||||
|
);
|
||||||
|
|
||||||
return [
|
return [
|
||||||
<Gtk.Box class={"adapters"} visible={adapters.as(adptrs => adptrs.length > 1)
|
<Gtk.Box class={"adapters"} visible={adapters.as(adptrs => adptrs.length > 1)
|
||||||
@@ -86,40 +92,26 @@ export const BluetoothPage = new Page({
|
|||||||
spacing={2}>
|
spacing={2}>
|
||||||
|
|
||||||
<Gtk.Box class={"paired"} orientation={Gtk.Orientation.VERTICAL} spacing={4}
|
<Gtk.Box class={"paired"} orientation={Gtk.Orientation.VERTICAL} spacing={4}
|
||||||
visible={devices.as(devs => devs.filter(dev =>
|
visible={variableToBoolean(knownDevices)}>
|
||||||
(dev.adapter as AstalBluetooth.Adapter).address === adapter.get()?.address &&
|
|
||||||
dev.paired || dev.connected || dev.trusted).length > 0)
|
|
||||||
}>
|
|
||||||
|
|
||||||
<Gtk.Label class={"sub-header"} label={tr("devices")} xalign={0} />
|
<Gtk.Label class={"sub-header"} label={tr("devices")} xalign={0} />
|
||||||
<For each={devices.as(devs => devs.filter(dev =>
|
<For each={knownDevices}>
|
||||||
(dev.adapter as AstalBluetooth.Adapter).address === adapter.get()?.address &&
|
|
||||||
dev.paired || dev.connected || dev.trusted))
|
|
||||||
}>
|
|
||||||
|
|
||||||
{(dev: AstalBluetooth.Device) => <DeviceWidget device={dev} />}
|
{(dev: AstalBluetooth.Device) => <DeviceWidget device={dev} />}
|
||||||
</For>
|
</For>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
<Gtk.Box class={"discovered"} orientation={Gtk.Orientation.VERTICAL} spacing={4}
|
<Gtk.Box class={"discovered"} orientation={Gtk.Orientation.VERTICAL} spacing={4}
|
||||||
visible={devices.as(devs => devs.filter(dev =>
|
visible={variableToBoolean(discoveredDevices)}>
|
||||||
(dev.adapter as AstalBluetooth.Adapter).address === adapter.get()?.address &&
|
|
||||||
!dev.connected && !dev.paired && !dev.trusted).length > 0)
|
|
||||||
}>
|
|
||||||
|
|
||||||
<Gtk.Label class={"sub-header"} label={tr("control_center.pages.bluetooth.new_devices")}
|
<Gtk.Label class={"sub-header"} label={tr("control_center.pages.bluetooth.new_devices")}
|
||||||
xalign={0} />
|
xalign={0} />
|
||||||
<For each={devices.as(devs => devs.filter(dev =>
|
<For each={discoveredDevices}>
|
||||||
(dev.adapter as AstalBluetooth.Adapter).address === adapter.get()?.address &&
|
|
||||||
!dev.connected && !dev.paired && !dev.trusted))
|
|
||||||
}>
|
|
||||||
|
|
||||||
{(dev: AstalBluetooth.Device) => <DeviceWidget device={dev} />}
|
{(dev: AstalBluetooth.Device) => <DeviceWidget device={dev} />}
|
||||||
</For>
|
</For>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
];
|
];
|
||||||
}
|
}}
|
||||||
});
|
/> as Page;
|
||||||
|
|
||||||
function DeviceWidget({ device }: { device: AstalBluetooth.Device }): Gtk.Widget {
|
function DeviceWidget({ device }: { device: AstalBluetooth.Device }): Gtk.Widget {
|
||||||
const pair = async () => {
|
const pair = async () => {
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import { lookupIcon } from "../../../../modules/apps";
|
|||||||
import AstalWp from "gi://AstalWp?version=0.1";
|
import AstalWp from "gi://AstalWp?version=0.1";
|
||||||
|
|
||||||
|
|
||||||
export const PageMicrophone = new Page({
|
export const PageMicrophone = <Page
|
||||||
id: "microphone",
|
id={"microphone"}
|
||||||
title: tr("control_center.pages.microphone.title"),
|
title={tr("control_center.pages.microphone.title")}
|
||||||
description: tr("control_center.pages.microphone.description"),
|
description={tr("control_center.pages.microphone.description")}
|
||||||
content: () => [
|
content={() => [
|
||||||
<Gtk.Label class={"sub-header"} label={tr("devices")} xalign={0} />,
|
<Gtk.Label class={"sub-header"} label={tr("devices")} xalign={0} />,
|
||||||
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} spacing={4}>
|
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} spacing={4}>
|
||||||
<For each={createBinding(Wireplumber.getWireplumber().get_audio()!, "microphones")}>
|
<For each={createBinding(Wireplumber.getWireplumber().get_audio()!, "microphones")}>
|
||||||
@@ -30,5 +30,5 @@ export const PageMicrophone = new Page({
|
|||||||
/>}
|
/>}
|
||||||
</For>
|
</For>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
]
|
]}
|
||||||
});
|
/> as Page;
|
||||||
|
|||||||
@@ -13,24 +13,24 @@ import NM from "gi://NM";
|
|||||||
import AstalNetwork from "gi://AstalNetwork";
|
import AstalNetwork from "gi://AstalNetwork";
|
||||||
|
|
||||||
|
|
||||||
export const PageNetwork = new Page({
|
export const PageNetwork = <Page
|
||||||
id: "network",
|
id={"network"}
|
||||||
title: tr("control_center.pages.network.title"),
|
title={tr("control_center.pages.network.title")}
|
||||||
headerButtons: createBinding(AstalNetwork.get_default(), "primary").as(primary =>
|
headerButtons={createBinding(AstalNetwork.get_default(), "primary").as(primary =>
|
||||||
primary === AstalNetwork.Primary.WIFI ? [{
|
primary === AstalNetwork.Primary.WIFI ? [{
|
||||||
icon: "arrow-circular-top-right-symbolic",
|
icon: "arrow-circular-top-right-symbolic",
|
||||||
tooltipText: "Re-scan networks",
|
tooltipText: "Re-scan networks",
|
||||||
actionClicked: () => AstalNetwork.get_default().wifi.scan()
|
actionClicked: () => AstalNetwork.get_default().wifi.scan()
|
||||||
}] : []
|
}] : []
|
||||||
),
|
)}
|
||||||
bottomButtons: [{
|
bottomButtons={[{
|
||||||
title: tr("control_center.pages.more_settings"),
|
title: tr("control_center.pages.more_settings"),
|
||||||
actionClicked: () => {
|
actionClicked: () => {
|
||||||
Windows.getDefault().close("control-center");
|
Windows.getDefault().close("control-center");
|
||||||
execApp("nm-connection-editor", "[animationstyle gnomed]");
|
execApp("nm-connection-editor", "[animationstyle gnomed]");
|
||||||
}
|
}
|
||||||
}],
|
}]}
|
||||||
content: () => [
|
content={() => [
|
||||||
<Gtk.Box class={"devices"} hexpand orientation={Gtk.Orientation.VERTICAL}
|
<Gtk.Box class={"devices"} hexpand orientation={Gtk.Orientation.VERTICAL}
|
||||||
visible={variableToBoolean(createBinding(AstalNetwork.get_default().client, "devices"))}
|
visible={variableToBoolean(createBinding(AstalNetwork.get_default().client, "devices"))}
|
||||||
spacing={4}>
|
spacing={4}>
|
||||||
@@ -130,8 +130,8 @@ export const PageNetwork = new Page({
|
|||||||
</For>
|
</For>
|
||||||
</Gtk.Box>}
|
</Gtk.Box>}
|
||||||
</With>
|
</With>
|
||||||
]
|
]}
|
||||||
});
|
/> as Page;
|
||||||
|
|
||||||
function activateWirelessConnection(connection: NM.RemoteConnection, ssid: string): void {
|
function activateWirelessConnection(connection: NM.RemoteConnection, ssid: string): void {
|
||||||
AstalNetwork.get_default().get_client().activate_connection_async(
|
AstalNetwork.get_default().get_client().activate_connection_async(
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ import { Astal, Gtk } from "ags/gtk4";
|
|||||||
import { addSliderMarksFromMinMax } from "../../../../modules/utils";
|
import { addSliderMarksFromMinMax } from "../../../../modules/utils";
|
||||||
import { createBinding } from "ags";
|
import { createBinding } from "ags";
|
||||||
|
|
||||||
export const PageNightLight = new Page({
|
|
||||||
id: "night-light",
|
export const PageNightLight = <Page
|
||||||
title: tr("control_center.pages.night_light.title"),
|
id={"night-light"}
|
||||||
description: tr("control_center.pages.night_light.description"),
|
title={tr("control_center.pages.night_light.title")}
|
||||||
content: () => [
|
description={tr("control_center.pages.night_light.description")}
|
||||||
|
content={() => [
|
||||||
<Gtk.Label class={"sub-header"} label={tr(
|
<Gtk.Label class={"sub-header"} label={tr(
|
||||||
"control_center.pages.night_light.temperature"
|
"control_center.pages.night_light.temperature"
|
||||||
)} xalign={0} />,
|
)} xalign={0} />,
|
||||||
@@ -39,5 +40,5 @@ export const PageNightLight = new Page({
|
|||||||
NightLight.getDefault().gamma = Math.floor(value)
|
NightLight.getDefault().gamma = Math.floor(value)
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
]
|
]}
|
||||||
});
|
/> as Page;
|
||||||
|
|||||||
@@ -4,18 +4,18 @@ import { getAppIcon, lookupIcon } from "../../../../modules/apps";
|
|||||||
import { Wireplumber } from "../../../../modules/volume";
|
import { Wireplumber } from "../../../../modules/volume";
|
||||||
import { tr } from "../../../../i18n/intl";
|
import { tr } from "../../../../i18n/intl";
|
||||||
import { createBinding, For } from "ags";
|
import { createBinding, For } from "ags";
|
||||||
import { variableToBoolean } from "../../../../modules/utils";
|
import { createScopedConnection, variableToBoolean } from "../../../../modules/utils";
|
||||||
|
|
||||||
import AstalWp from "gi://AstalWp";
|
import AstalWp from "gi://AstalWp";
|
||||||
import GObject from "gi://GObject?version=2.0";
|
import GObject from "gi://GObject?version=2.0";
|
||||||
import Pango from "gi://Pango?version=1.0";
|
import Pango from "gi://Pango?version=1.0";
|
||||||
|
|
||||||
|
|
||||||
export const PageSound = new Page({
|
export const PageSound = <Page
|
||||||
id: "sound",
|
id={"sound"}
|
||||||
title: tr("control_center.pages.sound.title"),
|
title={tr("control_center.pages.sound.title")}
|
||||||
description: tr("control_center.pages.sound.description"),
|
description={tr("control_center.pages.sound.description")}
|
||||||
content: () => [
|
content={() => [
|
||||||
<Gtk.Label class={"sub-header"} label={tr("devices")} xalign={0} />,
|
<Gtk.Label class={"sub-header"} label={tr("devices")} xalign={0} />,
|
||||||
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} spacing={4}>
|
<Gtk.Box orientation={Gtk.Orientation.VERTICAL} spacing={4}>
|
||||||
<For each={createBinding(Wireplumber.getWireplumber().audio!, "speakers")}>
|
<For each={createBinding(Wireplumber.getWireplumber().audio!, "speakers")}>
|
||||||
@@ -45,27 +45,17 @@ export const PageSound = new Page({
|
|||||||
<For each={createBinding(Wireplumber.getWireplumber().audio!, "streams")}>
|
<For each={createBinding(Wireplumber.getWireplumber().audio!, "streams")}>
|
||||||
{(stream: AstalWp.Stream) =>
|
{(stream: AstalWp.Stream) =>
|
||||||
<Gtk.Box hexpand $={(self) => {
|
<Gtk.Box hexpand $={(self) => {
|
||||||
const conns: Map<GObject.Object, Array<number>> = new Map();
|
|
||||||
const controllerMotion = Gtk.EventControllerMotion.new();
|
const controllerMotion = Gtk.EventControllerMotion.new();
|
||||||
|
|
||||||
self.add_controller(controllerMotion);
|
self.add_controller(controllerMotion);
|
||||||
|
createScopedConnection(controllerMotion, "enter", () => {
|
||||||
conns.set(controllerMotion, [
|
const revealer = self.get_last_child()!.get_first_child() as Gtk.Revealer;
|
||||||
controllerMotion.connect("enter", () => {
|
revealer.set_reveal_child(true);
|
||||||
const revealer = self.get_last_child()!.get_first_child() as Gtk.Revealer;
|
});
|
||||||
revealer.set_reveal_child(true);
|
createScopedConnection(controllerMotion, "leave", () => {
|
||||||
}),
|
const revealer = self.get_last_child()!.get_first_child() as Gtk.Revealer;
|
||||||
controllerMotion.connect("leave", () => {
|
revealer.set_reveal_child(false);
|
||||||
const revealer = self.get_last_child()!.get_first_child() as Gtk.Revealer;
|
});
|
||||||
revealer.set_reveal_child(false);
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
|
|
||||||
conns.set(self, [
|
|
||||||
self.connect("destroy", () => conns.forEach((ids, obj) =>
|
|
||||||
ids.forEach(id => obj.disconnect(id))
|
|
||||||
))
|
|
||||||
]);
|
|
||||||
}}>
|
}}>
|
||||||
<Gtk.Image iconName={createBinding(stream, "name").as(name =>
|
<Gtk.Image iconName={createBinding(stream, "name").as(name =>
|
||||||
getAppIcon(name.split(' ')[0]) ?? "application-x-executable-symbolic")}
|
getAppIcon(name.split(' ')[0]) ?? "application-x-executable-symbolic")}
|
||||||
@@ -92,5 +82,5 @@ export const PageSound = new Page({
|
|||||||
}
|
}
|
||||||
</For>
|
</For>
|
||||||
</Gtk.Box>
|
</Gtk.Box>
|
||||||
]
|
]}
|
||||||
});
|
/> as Page;
|
||||||
|
|||||||
@@ -1,26 +1,27 @@
|
|||||||
import { register } from "ags/gobject";
|
import GObject, { getter, gtype, register } from "ags/gobject";
|
||||||
import { Gtk } from "ags/gtk4";
|
import { Gtk } from "ags/gtk4";
|
||||||
import { Page } from "../Page";
|
import { Page } from "../Page";
|
||||||
|
|
||||||
import GLib from "gi://GLib?version=2.0";
|
import GLib from "gi://GLib?version=2.0";
|
||||||
|
|
||||||
|
|
||||||
export type PagesProps = {
|
|
||||||
initialPage?: Page;
|
|
||||||
transitionDuration?: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
@register({ GTypeName: "Pages" })
|
@register({ GTypeName: "Pages" })
|
||||||
export class Pages extends Gtk.Box {
|
export class Pages extends Gtk.Box {
|
||||||
#timeouts: Array<[GLib.Source, (() => void)|undefined]> = [];
|
#timeouts: Array<[GLib.Source, (() => void)|undefined]> = [];
|
||||||
#page: (Page|undefined);
|
#page: Page|undefined;
|
||||||
#transDuration: number;
|
#transDuration: number;
|
||||||
#transType: Gtk.RevealerTransitionType = Gtk.RevealerTransitionType.SLIDE_DOWN;
|
#transType: Gtk.RevealerTransitionType = Gtk.RevealerTransitionType.SLIDE_DOWN;
|
||||||
|
|
||||||
|
@getter(Boolean)
|
||||||
get isOpen() { return Boolean(this.#page); }
|
get isOpen() { return Boolean(this.#page); }
|
||||||
|
|
||||||
|
@getter(gtype<Page|undefined>(Page))
|
||||||
get page() { return this.#page; }
|
get page() { return this.#page; }
|
||||||
|
|
||||||
constructor(props?: PagesProps) {
|
constructor(props?: {
|
||||||
|
initialPage?: Page;
|
||||||
|
transitionDuration?: number;
|
||||||
|
}) {
|
||||||
super({
|
super({
|
||||||
orientation: Gtk.Orientation.VERTICAL,
|
orientation: Gtk.Orientation.VERTICAL,
|
||||||
cssName: "pages",
|
cssName: "pages",
|
||||||
@@ -36,7 +37,9 @@ export class Pages extends Gtk.Box {
|
|||||||
|
|
||||||
|
|
||||||
const destroyId = this.connect("destroy", () => {
|
const destroyId = this.connect("destroy", () => {
|
||||||
this.disconnect(destroyId);
|
GObject.signal_handler_is_connected(this, destroyId) &&
|
||||||
|
this.disconnect(destroyId);
|
||||||
|
|
||||||
this.#timeouts.forEach((tmout) => {
|
this.#timeouts.forEach((tmout) => {
|
||||||
tmout[0].destroy();
|
tmout[0].destroy();
|
||||||
(async () => tmout[1]?.())().catch((err: Error) => {
|
(async () => tmout[1]?.())().catch((err: Error) => {
|
||||||
|
|||||||
@@ -9,12 +9,16 @@ import AstalBluetooth from "gi://AstalBluetooth";
|
|||||||
|
|
||||||
export const TileBluetooth = () =>
|
export const TileBluetooth = () =>
|
||||||
<Tile title={"Bluetooth"} visible={createBinding(Bluetooth.getDefault(), "isAvailable")}
|
<Tile title={"Bluetooth"} visible={createBinding(Bluetooth.getDefault(), "isAvailable")}
|
||||||
description={createBinding(AstalBluetooth.get_default(), "adapters").as((connected) => {
|
description={createComputed([
|
||||||
if(!connected) return "";
|
createBinding(Bluetooth.getDefault(), "adapter"),
|
||||||
|
createBinding(AstalBluetooth.get_default(), "devices")
|
||||||
|
], (adapter, devices) => {
|
||||||
|
const lastConnectedDevice = devices.filter(d => d.connected)[devices.length - 1];
|
||||||
|
|
||||||
const connectedDevs = AstalBluetooth.get_default().devices.filter(dev => dev.connected);
|
if(!adapter || !lastConnectedDevice)
|
||||||
const connectedDev = connectedDevs[connectedDevs.length - 1]; // last connected device is on display
|
return "";
|
||||||
return connectedDev ? connectedDev.get_alias() : ""
|
|
||||||
|
return lastConnectedDevice.alias;
|
||||||
})}
|
})}
|
||||||
onEnabled={() => Bluetooth.getDefault().adapter?.set_powered(true)}
|
onEnabled={() => Bluetooth.getDefault().adapter?.set_powered(true)}
|
||||||
onDisabled={() => Bluetooth.getDefault().adapter?.set_powered(false)}
|
onDisabled={() => Bluetooth.getDefault().adapter?.set_powered(false)}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { TileDND } from "./DoNotDisturb";
|
|||||||
import { TileRecording } from "./Recording";
|
import { TileRecording } from "./Recording";
|
||||||
import { TileNightLight } from "./NightLight";
|
import { TileNightLight } from "./NightLight";
|
||||||
import { Pages } from "../pages";
|
import { Pages } from "../pages";
|
||||||
|
import { createRoot, getScope } from "ags";
|
||||||
|
|
||||||
|
|
||||||
export let TilesPages: Pages|undefined;
|
export let TilesPages: Pages|undefined;
|
||||||
@@ -17,16 +18,20 @@ export const tileList: Array<() => JSX.Element|Gtk.Widget> = [
|
|||||||
] as Array<() => Gtk.Widget>;
|
] as Array<() => Gtk.Widget>;
|
||||||
|
|
||||||
export function Tiles(): Gtk.Widget {
|
export function Tiles(): Gtk.Widget {
|
||||||
return <Gtk.Box class={"tiles-container"} orientation={Gtk.Orientation.VERTICAL}
|
return createRoot((dispose) => {
|
||||||
onUnmap={() => TilesPages = undefined}>
|
getScope().onCleanup(() => TilesPages = undefined);
|
||||||
|
|
||||||
<Gtk.FlowBox orientation={Gtk.Orientation.HORIZONTAL} rowSpacing={6}
|
return <Gtk.Box class={"tiles-container"} orientation={Gtk.Orientation.VERTICAL}
|
||||||
columnSpacing={6} minChildrenPerLine={2} activateOnSingleClick
|
onDestroy={() => dispose()}>
|
||||||
maxChildrenPerLine={2} hexpand homogeneous>
|
|
||||||
|
|
||||||
{tileList.map(t => t())}
|
<Gtk.FlowBox orientation={Gtk.Orientation.HORIZONTAL} rowSpacing={6}
|
||||||
</Gtk.FlowBox>
|
columnSpacing={6} minChildrenPerLine={2} activateOnSingleClick
|
||||||
|
maxChildrenPerLine={2} hexpand homogeneous>
|
||||||
|
|
||||||
<Pages class={"tile-pages"} $={(self) => TilesPages = self} />
|
{tileList.map(t => t())}
|
||||||
</Gtk.Box> as Gtk.Box;
|
</Gtk.FlowBox>
|
||||||
|
|
||||||
|
<Pages class={"tile-pages"} $={(self) => TilesPages = self} />
|
||||||
|
</Gtk.Box> as Gtk.Box;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-2
@@ -203,7 +203,10 @@ export class Windows extends GObject.Object {
|
|||||||
|
|
||||||
this.#scope.onMount(scope.dispose);
|
this.#scope.onMount(scope.dispose);
|
||||||
|
|
||||||
scope.onCleanup(() => instance.disconnect(connection));
|
scope.onCleanup(() =>
|
||||||
|
GObject.signal_handler_is_connected(instance, connection) &&
|
||||||
|
instance.disconnect(connection)
|
||||||
|
);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
})
|
})
|
||||||
@@ -231,7 +234,10 @@ export class Windows extends GObject.Object {
|
|||||||
const connection = instance.connect("close-request", () => dispose());
|
const connection = instance.connect("close-request", () => dispose());
|
||||||
|
|
||||||
this.#scope.onMount(dispose)
|
this.#scope.onMount(dispose)
|
||||||
scope.onCleanup(() => instance.disconnect(connection));
|
scope.onCleanup(() =>
|
||||||
|
GObject.signal_handler_is_connected(instance, connection) &&
|
||||||
|
instance.disconnect(connection)
|
||||||
|
);
|
||||||
|
|
||||||
return instance;
|
return instance;
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user