mirror of
https://github.com/zoriya/flake.git
synced 2026-06-02 10:45:59 +00:00
Add darkmode toggle
This commit is contained in:
@@ -3,7 +3,7 @@ import * as audio from "../modules/audio.js";
|
||||
import * as brightness from "../modules/brightness.js";
|
||||
import * as network from "../modules/network.js";
|
||||
import * as bluetooth from "../modules/bluetooth.js";
|
||||
// import * as darkmode from "../modules/darkmode.js";
|
||||
import * as darkmode from "../modules/darkmode.js";
|
||||
// import * as nightmode from "../modules/nightmode.js";
|
||||
import * as mpris from "../modules/mpris.js";
|
||||
import PopupWindow from "../misc/popup.js";
|
||||
@@ -20,7 +20,6 @@ const Row = (toggles = [], menus = []) =>
|
||||
children: [
|
||||
Widget.Box({
|
||||
homogeneous: true,
|
||||
class_name: "row horizontal",
|
||||
children: toggles,
|
||||
}),
|
||||
...menus,
|
||||
@@ -45,18 +44,13 @@ export const Quicksettings = () =>
|
||||
[network.Toggle({}), bluetooth.Toggle({})],
|
||||
[network.Selection({}), bluetooth.Selection({})],
|
||||
),
|
||||
// Box({
|
||||
// children: [darkmode.DarkToggle(), nightmode.NightToggle()],
|
||||
// }),
|
||||
Widget.Box({
|
||||
homogeneous: true,
|
||||
children: [darkmode.Toggle(), darkmode.Toggle()],
|
||||
}),
|
||||
// Box({
|
||||
// children: [audio.AppMixerToggle(), audio.MuteToggle()],
|
||||
// }),
|
||||
// Submenu({
|
||||
// menuName: "app-mixer",
|
||||
// icon: FontIcon({ icon: "" }),
|
||||
// title: "App Mixer",
|
||||
// contentType: audio.AppMixer,
|
||||
// }),
|
||||
Widget.Box({
|
||||
children: mprisService
|
||||
.bind("players")
|
||||
|
||||
@@ -88,6 +88,47 @@ export const ArrowToggleButton = ({
|
||||
],
|
||||
});
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* icon: Gtk.Widget,
|
||||
* label: Gtk.Widget,
|
||||
* activate: () => void
|
||||
* deactivate: () => void
|
||||
* connection: [GObject.Object, () => boolean]
|
||||
* } & import("types/widgets/box").BoxProps} SimpleToggleButtonProps
|
||||
* @param {SimpleToggleButtonProps} props
|
||||
*/
|
||||
export const SimpleToggleButton = ({
|
||||
icon,
|
||||
label,
|
||||
activate,
|
||||
deactivate,
|
||||
connection: [service, condition],
|
||||
}) =>
|
||||
Widget.Box({
|
||||
className: "qs-button surface",
|
||||
setup: (self) =>
|
||||
self.hook(service, () => {
|
||||
self.toggleClassName("accent", condition());
|
||||
}),
|
||||
children: [
|
||||
Widget.Button({
|
||||
child: Widget.Box({
|
||||
hexpand: true,
|
||||
children: [icon, label],
|
||||
}),
|
||||
onClicked: () => {
|
||||
if (condition()) {
|
||||
deactivate();
|
||||
} else {
|
||||
activate();
|
||||
}
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* name: string,
|
||||
|
||||
@@ -1,87 +1,51 @@
|
||||
import GLib from 'gi://GLib';
|
||||
import Gio from "gi://Gio";
|
||||
import GLib from "gi://GLib?version=2.0";
|
||||
|
||||
import Service from 'resource:///com/github/Aylur/ags/service.js'
|
||||
import { exec, execAsync } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||
import { Icon, Label, Button, Box, Stack } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
import { SimpleToggleButton } from "../misc/menu.js";
|
||||
|
||||
class ThemeService extends Service {
|
||||
static {
|
||||
Service.register(this);
|
||||
}
|
||||
const theme = Variable(/** @type {"light" | "dark"} */ ("light"));
|
||||
|
||||
_dark = false;
|
||||
|
||||
get dark() {
|
||||
return this._dark;
|
||||
}
|
||||
|
||||
set dark(value) {
|
||||
this._dark = value;
|
||||
execAsync(`gsettings set org.gnome.desktop.interface color-scheme prefer-${this._dark ? "dark" : "light"}`).catch(
|
||||
print
|
||||
);
|
||||
execAsync(`gsettings set org.gnome.desktop.interface gtk-theme adw-gtk3${this._dark ? "-dark" : ""}`).catch(
|
||||
print
|
||||
);
|
||||
const conf = GLib.get_user_config_dir();
|
||||
execAsync(`ln -sf ${conf}/kitty/${this._dark ? "dark" : "light"}.conf ${conf}/kitty/theme.conf`).catch(
|
||||
print
|
||||
);
|
||||
execAsync("pkill -USR1 kitty").catch(print);
|
||||
this.emit("changed");
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.dark = !this.dark;
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._dark = exec(`gsettings get org.gnome.desktop.interface color-scheme`) === "'prefer-dark'";
|
||||
// Ensure that the gtk theme is in sync with the theme.
|
||||
this._dark = this._dark;
|
||||
}
|
||||
}
|
||||
|
||||
const Theme = new ThemeService();
|
||||
|
||||
export const Indicator = ({ ...props } = {}) =>
|
||||
Stack({
|
||||
items: [
|
||||
["light", Icon("weather-clear-symbolic")],
|
||||
["dark", Icon("weather-clear-night-symbolic")],
|
||||
],
|
||||
...props,
|
||||
connections: [
|
||||
[
|
||||
Theme,
|
||||
(stack) => {
|
||||
stack.shown = Theme.dark ? "dark" : "light";
|
||||
},
|
||||
],
|
||||
],
|
||||
});
|
||||
|
||||
export const ThemeLabel = () =>
|
||||
Label({
|
||||
connections: [
|
||||
[
|
||||
Theme,
|
||||
(label) => {
|
||||
label.label = Theme.dark ? "Dark Theme" : "Light Theme";
|
||||
},
|
||||
],
|
||||
],
|
||||
});
|
||||
|
||||
export const DarkToggle = ({ ...props } = {}) =>
|
||||
Button({
|
||||
className: "qs-button surface",
|
||||
hexpand: true,
|
||||
onClicked: () => Theme.toggle(),
|
||||
child: Box({
|
||||
children: [Indicator({ className: "qs-icon" }), ThemeLabel()],
|
||||
/** @param {Partial<import("../misc/menu.js").SimpleToggleButtonProps>} props */
|
||||
export const Toggle = ({ ...props } = {}) =>
|
||||
SimpleToggleButton({
|
||||
icon: Widget.Icon({
|
||||
className: "qs-icon",
|
||||
icon: theme
|
||||
.bind()
|
||||
.as((x) =>
|
||||
x === "light"
|
||||
? "weather-clear-symbolic"
|
||||
: "weather-clear-night-symbolic",
|
||||
),
|
||||
}),
|
||||
connections: [[Theme, (button) => button.toggleClassName("accent", Theme.dark)]],
|
||||
label: Widget.Label({
|
||||
label: theme.bind().as((x) => (x === "light" ? "Light" : "Dark")),
|
||||
}),
|
||||
activate: () => theme.setValue("dark"),
|
||||
deactivate: () => theme.setValue("light"),
|
||||
connection: [theme, () => theme.value === "dark"],
|
||||
...props,
|
||||
});
|
||||
|
||||
function init() {
|
||||
const settings = new Gio.Settings({
|
||||
schema: "org.gnome.desktop.interface",
|
||||
});
|
||||
const initial = /** @type {"prefer-light" | "prefer-dark"}} */ (
|
||||
settings.get_value("color-scheme").get_string()[0]
|
||||
);
|
||||
theme.setValue(/** @type {any}} */ (initial.substring("prefer-".length)));
|
||||
theme.connect("changed", () => {
|
||||
settings.set_string("color-scheme", `prefer-${theme.value}`);
|
||||
settings.set_string(
|
||||
"gtk-theme",
|
||||
`adw-gtk3${theme.value === "dark" ? "-dark" : ""}`,
|
||||
);
|
||||
|
||||
const conf = GLib.get_user_config_dir();
|
||||
Utils.execAsync(
|
||||
`bash -c 'ln -sf ${conf}/kitty/${theme.value}.conf ${conf}/kitty/theme.conf && pkill -USR1 kitty'`,
|
||||
).catch(print);
|
||||
});
|
||||
}
|
||||
init();
|
||||
|
||||
Reference in New Issue
Block a user