Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions ags/lib/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ export let config = {
},
},
lockCommand: opt<string | null>(null),
powerMenuEntries: opt<Array<{ label: string; command: string; confirmation?: string }>>([
{
label: "Restart",
command: "reboot",
confirmation: "Are you sure you want to restart the computer?",
},
{
label: "Power Off",
command: "shutdown now",
confirmation: "Are you sure you want to power off the computer?",
},
]),
minWorkspaces: opt<number>(3),
popups: {
volumePopup: {
Expand Down
77 changes: 77 additions & 0 deletions ags/quicksettings/power-menu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import type Gtk from "gi://Gtk?version=3.0";
import { config } from "lib/settings";
import type { Binding } from "types/service.js";
import { PopupWindow, showModal } from "window";

/**
* Power menu that lists multiple power options.
*
* @param reveal - Variable that stores the reveal state of the power menu.
*/
export const PowerMenu = (params: {
reveal?: Binding<any, any, boolean>;
}) => {
const entries = config.powerMenuEntries.map(({ label, command, confirmation }) =>
Widget.Button({
className: "entry",
hexpand: true,
child: Widget.Box({
children: [
Widget.Label({
label: `${label}...`,
}),
],
}),
async onClicked() {
App.closeWindow("quicksettings");

const confirmed = confirmation
? await showModal({
title: label,
description: confirmation,
noOption: "Cancel",
yesOption: label,
emphasize: "no",
})
: true;

if (confirmed) {
await Utils.execAsync(command);
}
},
}),
);

return Widget.Revealer({
hexpand: false,
transition: "slide_down",
transitionDuration: 150,
revealChild: params.reveal,
child: Widget.Box({
className: "power-menu",
hexpand: true,
vexpand: false,
vertical: true,
children: [
Widget.Box({
className: "title",
children: [
Widget.Icon({
className: "icon",
icon: "system-shutdown-symbolic",
size: 20,
}),
Widget.Label({
label: "Power Off",
}),
],
}),
Widget.Box({
className: "entries",
vertical: true,
children: entries,
}),
],
}),
});
};
30 changes: 16 additions & 14 deletions ags/quicksettings/quicksettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { config } from "lib/settings";
import type { Icon } from "lib/types";
import type { Binding } from "types/service";
import { PopupWindow, showModal } from "window";
import { PowerMenu } from "./power-menu";
import { Sliders } from "./sliders";
import { Toggles } from "./toggles";

Expand Down Expand Up @@ -40,6 +41,7 @@ const Button = (props: {
export const Quicksettings = () => {
// Used to take a screenshot without including the quicksettings menu.
const opacity = Variable(1.0);
const revealPowerMenu = Variable(false);

const top_button_battery = Button({
icon: battery.bind("icon_name"),
Expand Down Expand Up @@ -96,24 +98,12 @@ export const Quicksettings = () => {
Button({
icon: "system-shutdown-symbolic",
async onClick() {
App.closeWindow("quicksettings");

const shutdown = await showModal({
title: "Power Off",
description: "Are you sure you want to power off the computer?",
noOption: "Cancel",
yesOption: "Power Off",
emphasize: "no",
});

if (shutdown) {
await Utils.execAsync("shutdown now");
}
revealPowerMenu.value = !revealPowerMenu.value;
},
}),
];

return PopupWindow({
const window = PopupWindow({
name: "quicksettings",
location: "top-right",
child: Widget.Box({
Expand All @@ -138,10 +128,22 @@ export const Quicksettings = () => {
}),
}),

PowerMenu({ reveal: revealPowerMenu.bind() }),

Sliders(),

Toggles(),
],
}),
});

window.hook(
App,
() => {
revealPowerMenu.value = false;
},
"window-toggled",
);

return window;
};
54 changes: 48 additions & 6 deletions ags/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,6 @@ window.darkened {
margin-left: 0.5em;
margin-bottom: 0.5em;

label {
font-weight: bold;
font-size: 14px;
}

.button-row {
@include space-between-x(3em);

Expand Down Expand Up @@ -232,6 +227,48 @@ window.darkened {
}
}

.power-menu {
@include space-between-y(0.625em);

margin-top: 1.25em;
padding: 0.625em;
border-radius: 25px;
background-color: hover-color($background1);

.title {
.icon {
@include rounded-full;
padding: 0.625em;
background-color: hover-color($surface0);
margin-right: 0.625em;
}

label {
font-size: 1.25em;
font-weight: bold;
}
}

.entries {
.entry {
@include rounded-full;
padding: 0.625em;

&:hover {
background-color: hover-color($surface0);
}

&:active {
background-color: $primary;

* {
color: $background1;
}
}
}
}
}

.sliders {
@include space-between-y(1.5em);
}
Expand Down Expand Up @@ -271,6 +308,11 @@ window.darkened {
}

.toggle-buttons {
label {
font-weight: bold;
font-size: 14px;
}

.toggle-button {
border-top-left-radius: 9999px;
border-bottom-left-radius: 9999px;
Expand Down Expand Up @@ -385,4 +427,4 @@ window.darkened {

}
}
}
}
46 changes: 46 additions & 0 deletions modules/mithril-shell.nix
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,52 @@ in
'';
};

powerMenuEntries = mkOption {
type = types.listOf (
types.submodule {
options = {
label = mkOption {
type = types.str;
example = "Power Off";
description = ''
The name of the power menu entry.
'';
};
command = mkOption {
type = types.str;
example = "shutdown now";
description = ''
The command to run when selecting the option.
'';
};
confirmation = mkOption {
type = types.nullOr types.str;
default = null;
example = "Are you sure you want to power off the computer?";
description = ''
An optional confirmation prompt to show before running the command.
'';
};
};
}
);
description = ''
List of entries to show in the power menu.
'';
default = [
{
label = "Restart";
command = "reboot";
confirmation = "Are you sure you want to restart the computer?";
}
{
label = "Power Off";
command = "shutdown now";
confirmation = "Are you sure you want to power off the computer?";
}
];
};

minWorkspaces = mkOption {
type = types.int;
default = 3;
Expand Down
Loading