update
This commit is contained in:
parent
c26c8d4b2d
commit
e51171fca8
|
@ -54,11 +54,6 @@
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
|
||||||
openmw-git = {
|
|
||||||
url = "gitlab:OpenMW/openmw";
|
|
||||||
flake = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
nvim-hmts = {
|
nvim-hmts = {
|
||||||
url = "github:calops/hmts.nvim";
|
url = "github:calops/hmts.nvim";
|
||||||
flake = false;
|
flake = false;
|
||||||
|
@ -89,6 +84,9 @@
|
||||||
config = {
|
config = {
|
||||||
allowUnfree = true;
|
allowUnfree = true;
|
||||||
allowUnsupportedSystem = true;
|
allowUnsupportedSystem = true;
|
||||||
|
permittedInsecurePackages = [
|
||||||
|
"libxls-1.6.2"
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
overlays = [
|
overlays = [
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{pkgs, ...}: {
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./avahi
|
./avahi
|
||||||
./locate
|
./locate
|
||||||
|
@ -11,18 +11,11 @@
|
||||||
services = {
|
services = {
|
||||||
blueman.enable = true;
|
blueman.enable = true;
|
||||||
flatpak.enable = true;
|
flatpak.enable = true;
|
||||||
fwupd.enable = true;
|
|
||||||
gnome.gnome-keyring.enable = true;
|
gnome.gnome-keyring.enable = true;
|
||||||
gvfs.enable = true;
|
gvfs.enable = true;
|
||||||
irqbalance.enable = true;
|
|
||||||
openssh.enable = true;
|
openssh.enable = true;
|
||||||
udisks2.enable = true;
|
udisks2.enable = true;
|
||||||
|
|
||||||
mullvad-vpn = {
|
|
||||||
enable = true;
|
|
||||||
package = pkgs.mullvad-vpn;
|
|
||||||
};
|
|
||||||
|
|
||||||
fstrim = {
|
fstrim = {
|
||||||
enable = true;
|
enable = true;
|
||||||
interval = "weekly";
|
interval = "weekly";
|
||||||
|
|
|
@ -2,6 +2,7 @@ import App from 'resource:///com/github/Aylur/ags/app.js'
|
||||||
import { exec } from 'resource://com/github/Aylur/ags/utils.js'
|
import { exec } from 'resource://com/github/Aylur/ags/utils.js'
|
||||||
|
|
||||||
import Panel from './js/panel/panel.js';
|
import Panel from './js/panel/panel.js';
|
||||||
|
import { NotificationCenter, NotificationsPopupWindow } from './js/notifications/config.js';
|
||||||
import {
|
import {
|
||||||
forMonitors
|
forMonitors
|
||||||
}
|
}
|
||||||
|
@ -15,5 +16,7 @@ export default {
|
||||||
style: css,
|
style: css,
|
||||||
windows: [
|
windows: [
|
||||||
forMonitors(Panel),
|
forMonitors(Panel),
|
||||||
|
NotificationsPopupWindow(),
|
||||||
|
NotificationCenter(),
|
||||||
].flat(2),
|
].flat(2),
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
import {
|
||||||
|
NotificationList, ClearButton, PopupList
|
||||||
|
} from './widgets.js';
|
||||||
|
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
|
import App from 'resource:///com/github/Aylur/ags/app.js';
|
||||||
|
|
||||||
|
const Header = () => Widget.Box({
|
||||||
|
className: 'header',
|
||||||
|
children: [
|
||||||
|
Widget.Box({ hexpand: true }),
|
||||||
|
ClearButton(),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const NotificationCenter = () => Widget.Window({
|
||||||
|
name: 'notification-center',
|
||||||
|
anchor: [ 'right', 'top', 'bottom'],
|
||||||
|
popup: true,
|
||||||
|
focusable: true,
|
||||||
|
child: Widget.Box({
|
||||||
|
children: [
|
||||||
|
Widget.EventBox({
|
||||||
|
hexpand: true,
|
||||||
|
connections: [['button-press-event', () =>
|
||||||
|
App.closeWindow('notification-center')]]
|
||||||
|
}),
|
||||||
|
Widget.Box({
|
||||||
|
vertical: true,
|
||||||
|
children: [
|
||||||
|
Header(),
|
||||||
|
NotificationList(),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const NotificationsPopupWindow = () => Widget.Window({
|
||||||
|
name: 'popup-window',
|
||||||
|
anchor: ['right', 'top'],
|
||||||
|
child: PopupList(),
|
||||||
|
});
|
|
@ -0,0 +1,120 @@
|
||||||
|
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
|
import { lookUpIcon, timeout } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||||
|
|
||||||
|
const NotificationIcon = ({ appEntry, appIcon, image }) => {
|
||||||
|
if (image) {
|
||||||
|
return Widget.Box({
|
||||||
|
valign: 'start',
|
||||||
|
hexpand: false,
|
||||||
|
className: 'icon img',
|
||||||
|
style: `
|
||||||
|
background-image: url("${image}");
|
||||||
|
background-size: contain;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
min-width: 78px;
|
||||||
|
min-height: 78px;
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let icon = 'dialog-information-symbolic';
|
||||||
|
if (lookUpIcon(appIcon))
|
||||||
|
icon = appIcon;
|
||||||
|
|
||||||
|
if (lookUpIcon(appEntry))
|
||||||
|
icon = appEntry;
|
||||||
|
|
||||||
|
return Widget.Box({
|
||||||
|
valign: 'start',
|
||||||
|
hexpand: false,
|
||||||
|
className: 'icon',
|
||||||
|
style: `
|
||||||
|
min-width: 78px;
|
||||||
|
min-height: 78px;
|
||||||
|
`,
|
||||||
|
children: [Widget.Icon({
|
||||||
|
icon, size: 58,
|
||||||
|
halign: 'center', hexpand: true,
|
||||||
|
valign: 'center', vexpand: true,
|
||||||
|
})],
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const Notification = n => Widget.EventBox({
|
||||||
|
className: `notification ${n.urgency}`,
|
||||||
|
onPrimaryClick: () => n.dismiss(),
|
||||||
|
properties: [['hovered', false]],
|
||||||
|
onHover: self => {
|
||||||
|
if (self._hovered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// if there are action buttons and they are hovered
|
||||||
|
// EventBox onHoverLost will fire off immediately,
|
||||||
|
// so to prevent this we delay it
|
||||||
|
timeout(300, () => self._hovered = true);
|
||||||
|
},
|
||||||
|
onHoverLost: self => {
|
||||||
|
if (!self._hovered)
|
||||||
|
return;
|
||||||
|
|
||||||
|
self._hovered = false;
|
||||||
|
n.dismiss();
|
||||||
|
},
|
||||||
|
vexpand: false,
|
||||||
|
child: Widget.Box({
|
||||||
|
vertical: true,
|
||||||
|
children: [
|
||||||
|
Widget.Box({
|
||||||
|
children: [
|
||||||
|
NotificationIcon(n),
|
||||||
|
Widget.Box({
|
||||||
|
hexpand: true,
|
||||||
|
vertical: true,
|
||||||
|
children: [
|
||||||
|
Widget.Box({
|
||||||
|
children: [
|
||||||
|
Widget.Label({
|
||||||
|
className: 'title',
|
||||||
|
xalign: 0,
|
||||||
|
justification: 'left',
|
||||||
|
hexpand: true,
|
||||||
|
maxWidthChars: 24,
|
||||||
|
truncate: 'end',
|
||||||
|
wrap: true,
|
||||||
|
label: n.summary,
|
||||||
|
useMarkup: true,
|
||||||
|
}),
|
||||||
|
Widget.Button({
|
||||||
|
className: 'close-button',
|
||||||
|
valign: 'start',
|
||||||
|
child: Widget.Icon('window-close-symbolic'),
|
||||||
|
onClicked: n.close.bind(n),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
Widget.Label({
|
||||||
|
className: 'description',
|
||||||
|
hexpand: true,
|
||||||
|
useMarkup: true,
|
||||||
|
xalign: 0,
|
||||||
|
justification: 'left',
|
||||||
|
label: n.body,
|
||||||
|
wrap: true,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
Widget.Box({
|
||||||
|
className: 'actions',
|
||||||
|
children: n.actions.map(({ id, label }) => Widget.Button({
|
||||||
|
className: 'action-button',
|
||||||
|
onClicked: () => n.invoke(id),
|
||||||
|
hexpand: true,
|
||||||
|
child: Widget.Label(label),
|
||||||
|
})),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { Notification } from './notification.js';
|
||||||
|
import Notifications from 'resource:///com/github/Aylur/ags/service/notifications.js';
|
||||||
|
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
||||||
|
|
||||||
|
const List = () => Widget.Box({
|
||||||
|
vertical: true,
|
||||||
|
vexpand: true,
|
||||||
|
connections: [[Notifications, self => {
|
||||||
|
self.children = Notifications.notifications
|
||||||
|
.reverse()
|
||||||
|
.map(Notification);
|
||||||
|
|
||||||
|
self.visible = Notifications.notifications.length > 0;
|
||||||
|
}]],
|
||||||
|
});
|
||||||
|
|
||||||
|
const Placeholder = () => Widget.Box({
|
||||||
|
className: 'placeholder',
|
||||||
|
vertical: true,
|
||||||
|
vexpand: true,
|
||||||
|
valign: 'center',
|
||||||
|
children: [
|
||||||
|
Widget.Icon('notifications-disabled-symbolic'),
|
||||||
|
Widget.Label('Your inbox is empty'),
|
||||||
|
],
|
||||||
|
binds: [
|
||||||
|
['visible', Notifications, 'notifications', n => n.length === 0],
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
export const NotificationList = () => Widget.Scrollable({
|
||||||
|
hscroll: 'never',
|
||||||
|
vscroll: 'automatic',
|
||||||
|
child: Widget.Box({
|
||||||
|
className: 'list',
|
||||||
|
vertical: true,
|
||||||
|
children: [
|
||||||
|
List(),
|
||||||
|
Placeholder(),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const ClearButton = () => Widget.Button({
|
||||||
|
onClicked: () => Notifications.clear(),
|
||||||
|
binds: [
|
||||||
|
['sensitive', Notifications, 'notifications', n => n.length > 0],
|
||||||
|
],
|
||||||
|
child: Widget.Box({
|
||||||
|
children: [
|
||||||
|
Widget.Label('Clear'),
|
||||||
|
Widget.Icon({
|
||||||
|
binds: [
|
||||||
|
['icon', Notifications, 'notifications', n =>
|
||||||
|
`user-trash-${n.length > 0 ? 'full-' : ''}symbolic`],
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
export const PopupList = () => Widget.Box({
|
||||||
|
className: 'list',
|
||||||
|
style: 'padding: 1px;', // so it shows up
|
||||||
|
vertical: true,
|
||||||
|
binds: [['children', Notifications, 'popups',
|
||||||
|
popups => popups.map(Notification)]],
|
||||||
|
});
|
|
@ -17,14 +17,16 @@ const Left = monitor => Box({
|
||||||
|
|
||||||
const Center = () => Box({
|
const Center = () => Box({
|
||||||
children: [
|
children: [
|
||||||
Volume(), Mpris('mpd')
|
Volume(),
|
||||||
|
Mpris('mpd'),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const Right = () => Box({
|
const Right = () => Box({
|
||||||
halign: 'end',
|
halign: 'end',
|
||||||
children: [
|
children: [
|
||||||
SysTray(), Clock(),
|
SysTray(),
|
||||||
|
Clock(),
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Box, Button, Icon, Label, Stack } from 'resource:///com/github/Aylur/ag
|
||||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
||||||
|
|
||||||
export default player => Button({
|
export default player => Button({
|
||||||
className: 'media',
|
className: 'mpris',
|
||||||
onPrimaryClick: () => Mpris.getPlayer(player)?.playPause(),
|
onPrimaryClick: () => Mpris.getPlayer(player)?.playPause(),
|
||||||
onScrollUp: () => Mpris.getPlayer(player)?.previous(),
|
onScrollUp: () => Mpris.getPlayer(player)?.previous(),
|
||||||
onScrollDown: () => Mpris.getPlayer(player)?.next(),
|
onScrollDown: () => Mpris.getPlayer(player)?.next(),
|
||||||
|
|
|
@ -7,7 +7,7 @@ export default () => Box({
|
||||||
[SystemTray, box => {
|
[SystemTray, box => {
|
||||||
box.children = SystemTray.items.map(item => Button({
|
box.children = SystemTray.items.map(item => Button({
|
||||||
className: 'tray-icons',
|
className: 'tray-icons',
|
||||||
child: Icon(),
|
child: Icon({ binds: [['icon', item, 'icon']] }),
|
||||||
onPrimaryClick: (_, event) => item.activate(event),
|
onPrimaryClick: (_, event) => item.activate(event),
|
||||||
onSecondaryClick: (_, event) => item.openMenu(event),
|
onSecondaryClick: (_, event) => item.openMenu(event),
|
||||||
connections: [
|
connections: [
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
/* Assuming Adwaita-dark as Gtk theme */
|
||||||
|
|
||||||
|
#popup-window {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#notification-center {
|
||||||
|
background-color: #232323;
|
||||||
|
}
|
||||||
|
|
||||||
|
#popup-window .notification > * {
|
||||||
|
box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#popup-window *,
|
||||||
|
#notification-center *{
|
||||||
|
outline: none;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: none;
|
||||||
|
box-shadow: none;
|
||||||
|
border-radius: 7px;
|
||||||
|
background-color: rgba(255,255,255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: rgba(255,255,255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
background-color: rgba(255,255,255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification > * {
|
||||||
|
margin: 8px;
|
||||||
|
padding: 8px;
|
||||||
|
border-radius: 15px;
|
||||||
|
background-color: #141414;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification .icon {
|
||||||
|
border-radius: 7px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification .close-button {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
min-height: 1.4em;
|
||||||
|
min-width: 1.4em;
|
||||||
|
border-radius: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification .title {
|
||||||
|
font-size: 1.1em;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification .description {
|
||||||
|
color: rgba(255, 255, 255, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
|
.list {
|
||||||
|
margin: 8px;
|
||||||
|
min-width: 380px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button {
|
||||||
|
margin: 0 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:first-child {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-button:last-child:first-child {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 8px;
|
||||||
|
border-bottom: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder image {
|
||||||
|
font-size: 8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.placeholder label {
|
||||||
|
font-size: 1.4em;
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
.media {
|
.mpris {
|
||||||
background-color: $box-bg;
|
background-color: $box-bg;
|
||||||
border-radius: $box-border-radius;
|
border-radius: $box-border-radius;
|
||||||
padding: 0px 10px 0px 10px;
|
padding: 0px 10px 0px 10px;
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
@import './scss/panel/widgets/clock.scss';
|
@import './scss/panel/widgets/clock.scss';
|
||||||
@import './scss/panel/widgets/sysTray.scss';
|
@import './scss/panel/widgets/sysTray.scss';
|
||||||
|
|
||||||
|
@import './notify-test.scss';
|
||||||
|
|
||||||
|
|
||||||
* {
|
* {
|
||||||
min-height: unset;
|
min-height: unset;
|
||||||
|
|
|
@ -67,13 +67,13 @@ in {
|
||||||
monitor=${leftMonitor.display}, ${leftMonitor.res}, ${leftMonitor.pos}, 1
|
monitor=${leftMonitor.display}, ${leftMonitor.res}, ${leftMonitor.pos}, 1
|
||||||
monitor=${rightMonitor.display}, ${rightMonitor.res}, ${rightMonitor.pos}, 1
|
monitor=${rightMonitor.display}, ${rightMonitor.res}, ${rightMonitor.pos}, 1
|
||||||
|
|
||||||
workspace = 1, monitor:${rightMonitor.display}
|
workspace = 1, monitor:${rightMonitor.display}, persistent:true
|
||||||
workspace = 2, monitor:${rightMonitor.display}
|
workspace = 2, monitor:${rightMonitor.display}, persistent:true
|
||||||
workspace = 3, monitor:${rightMonitor.display}
|
workspace = 3, monitor:${rightMonitor.display}, persistent:true
|
||||||
|
|
||||||
workspace = 4, monitor:${leftMonitor.display}
|
workspace = 4, monitor:${leftMonitor.display}, persistent:true
|
||||||
workspace = 5, monitor:${leftMonitor.display}
|
workspace = 5, monitor:${leftMonitor.display}, persistent:true
|
||||||
workspace = 6, monitor:${leftMonitor.display}
|
workspace = 6, monitor:${leftMonitor.display}, persistent:true
|
||||||
|
|
||||||
input {
|
input {
|
||||||
kb_layout = us
|
kb_layout = us
|
||||||
|
@ -119,9 +119,9 @@ in {
|
||||||
}
|
}
|
||||||
|
|
||||||
drop_shadow = yes
|
drop_shadow = yes
|
||||||
shadow_range = 8
|
shadow_range = 30
|
||||||
shadow_render_power = 1
|
shadow_render_power = 3
|
||||||
col.shadow = rgba(282828ff)
|
col.shadow = rgba(1a1a1aee)
|
||||||
}
|
}
|
||||||
|
|
||||||
animations {
|
animations {
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
services.mako = {
|
services.mako = {
|
||||||
enable = true;
|
enable = false;
|
||||||
anchor = "top-right";
|
anchor = "top-right";
|
||||||
defaultTimeout = 5000;
|
defaultTimeout = 5000;
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
pulsemixer
|
pulsemixer
|
||||||
qbittorrent
|
qbittorrent
|
||||||
qt5ct
|
qt5ct
|
||||||
|
ranger
|
||||||
samba
|
samba
|
||||||
sc-im
|
sc-im
|
||||||
signal-desktop
|
signal-desktop
|
||||||
|
|
Reference in New Issue