new wallpaper + waybar & mako -> ags

This commit is contained in:
Soph :3 2024-05-20 18:07:58 +03:00
parent 38a04865ed
commit e881630989
Signed by: sophie
GPG key ID: EDA5D222A0C270F2
13 changed files with 455 additions and 253 deletions

23
apps.md
View file

@ -15,26 +15,25 @@ ansible-playbook -K play.yml
Deps: `pkgconfig patch flex bison which` Deps: `pkgconfig patch flex bison which`
1. Audio - `pipewire wireplumber pipewire-pulse pipewire-alsa pipewire-jack qpwgraph` 1. Audio - `pipewire wireplumber pipewire-pulse pipewire-alsa pipewire-jack qpwgraph`
2. Wayland compositor - `hyprland xdg-desktop-portal-hyprland polkit-kde-agent` 2. Wayland compositor - `hyprland xdg-desktop-portal-hyprland polkit-kde-agent`
3. Status bar - `waybar` 3. Status bar - `aylurs-gtk-shell`
4. Terminal - `foot` 4. Terminal - `foot`
5. Screenshotting - `wl-clipboard slurp grim` 5. Screenshotting - `wl-clipboard slurp grim`
6. Application picker - `rofi-lbonn-wayland` 6. Application picker - `rofi-lbonn-wayland`
7. Notifications - `mako` 7. Background - `swww`
8. Background - `swww` 8. File manager - `thunar gvfs gvfs-smb`
9. File manager - `thunar gvfs gvfs-smb` 9. File syncing - `syncthing`
10. File syncing - `syncthing` 10. Music - `spotify spicetify-cli`
11. Music - `spotify spicetify-cli`
``` ```
curl -fsSL https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/install.sh | sh curl -fsSL https://raw.githubusercontent.com/spicetify/spicetify-marketplace/main/resources/install.sh | sh
spicetify backup apply spicetify backup apply
``` ```
12. Fonts - `ttf-jebrains-mono-nerd` 11. Fonts - `ttf-jebrains-mono-nerd`
13. Discord - `vencord-desktop-git` 12. Discord - `vencord-desktop-git`
14. Browser - `vivaldi` 13. Browser - `vivaldi`
``` ```
(credit: Archwiki) (credit: Archwiki)
Go to chrome://flags page, then search wayland. You will see the Preferred Ozone platform setting. Set it to auto. The default one is "X11". "Auto" selects Wayland if possible, X11 otherwise. Go to chrome://flags page, then search wayland. You will see the Preferred Ozone platform setting. Set it to auto. The default one is "X11". "Auto" selects Wayland if possible, X11 otherwise.
``` ```
15. Documents - `wps-office ttf-wps-fonts` 14. Documents - `wps-office ttf-wps-fonts`
16. Code editor - `visual-studio-code-bin` 15. Code editor - `visual-studio-code-bin`
17. Extras - `pipes.sh fastfetch lemurs nushell` 16. Extras - `pipes.sh fastfetch lemurs nushell catppuccin-gtk-theme-latte`

View file

@ -3,10 +3,10 @@
Make new user Make new user
``` ```
pacman -S sudo pacman -S sudo
useradd -mU yf useradd -mU sophie
echo "yf ALL=(ALL:ALL) ALL" >> /etc/sudoers echo "sophie ALL=(ALL:ALL) ALL" >> /etc/sudoers
passwd yf passwd sophie
su yf su sophie
``` ```
Install yay Install yay
@ -26,14 +26,14 @@ mkdir /etc/systemd/system/getty@tty1.service.d
cat <<- "EOF" > /etc/systemd/system/getty@tty1.service.d/skip-username.conf cat <<- "EOF" > /etc/systemd/system/getty@tty1.service.d/skip-username.conf
[Service] [Service]
ExecStart= ExecStart=
ExecStart=-/sbin/agetty -o '-p -- yf' --noclear --skip-login - $TERM ExecStart=-/sbin/agetty -o '-p -- sophie' --noclear --skip-login - $TERM
Environment=XDG_SESSION_TYPE=wayland Environment=XDG_SESSION_TYPE=wayland
EOF EOF
``` ```
Remove password Remove password
``` ```
sudo sed -i 's/yf:[^:]*/yf:/' /etc/shadow sudo sed -i 's/sophie:[^:]*/sophie:/' /etc/shadow
``` ```
Install stow Install stow
@ -50,7 +50,7 @@ stow src
Automatically log into Hyprland Automatically log into Hyprland
``` ```
cat <<- "EOF" > /home/yf/.bash_profile cat <<- "EOF" > /home/sophie/.bash_profile
if [[ "$(tty)" == "/dev/tty1" ]] if [[ "$(tty)" == "/dev/tty1" ]]
then then
Hyprland Hyprland

BIN
old_wallpaper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

View file

@ -25,15 +25,15 @@
- name: Create user group - name: Create user group
ansible.builtin.group: ansible.builtin.group:
name: yf name: sophie
state: present state: present
become: yes become: yes
- name: Create user - name: Create user
ansible.builtin.user: ansible.builtin.user:
name: yf name: sophie
create_home: yes create_home: yes
groups: yf groups: sophie
append: yes append: yes
state: present state: present
become: yes become: yes
@ -45,11 +45,11 @@
state: present state: present
become: yes become: yes
- name: Give user yf max sudoers - name: Give user sophie max sudoers
community.general.sudoers: community.general.sudoers:
name: main-user name: main-user
state: present state: present
user: yf user: sophie
runas: ALL runas: ALL
commands: ALL commands: ALL
become: yes become: yes
@ -69,7 +69,7 @@
use: makepkg use: makepkg
state: present state: present
become: yes become: yes
become_user: yf become_user: sophie
- name: Install stow - name: Install stow
community.general.pacman: community.general.pacman:
@ -80,26 +80,25 @@
- name: Clone my dotfiles - name: Clone my dotfiles
ansible.builtin.git: ansible.builtin.git:
repo: 'https://github.com/fucksophie/dots.git' repo: 'https://git.sad.ovh/sophie/dots.git'
dest: /home/yf/.shell dest: /home/sophie/.shell
become: yes become: yes
become_user: yf become_user: sophie
- name: Upgrade the system using yay - name: Upgrade the system using yay
kewlfft.aur.aur: kewlfft.aur.aur:
upgrade: yes upgrade: yes
use: yay use: yay
become: yes become: yes
become_user: yf become_user: sophie
- name: Run stow - name: Run stow
ansible.builtin.shell: "stow . --target=/home/yf/ --verbose=2" ansible.builtin.shell: "stow . --target=/home/sophie/ --verbose=2"
args: args:
chdir: /home/yf/.shell/src chdir: /home/sophie/.shell/src
register: result register: result
changed_when: 'result.stderr is search("LINK: ")' changed_when: 'result.stderr is search("LINK: ")'
become: yes become: yes
become_user: yf become_user: sophie
- name: Install everything - name: Install everything
kewlfft.aur.aur: kewlfft.aur.aur:
use: yay use: yay
@ -123,14 +122,14 @@
- hyprland - hyprland
- xdg-desktop-portal-hyprland-git - xdg-desktop-portal-hyprland-git
- polkit-kde-agent - polkit-kde-agent
- waybar - aylurs-gtk-shell
- catppuccin-gtk-theme-latte
- foot - foot
- nushell - nushell
- wl-clipboard - wl-clipboard
- slurp - slurp
- grim - grim
- rofi-lbonn-wayland-git - rofi-lbonn-wayland-git
- mako
- swww - swww
- thunar - thunar
- gvfs - gvfs
@ -149,16 +148,16 @@
- lemurs - lemurs
- syncthing - syncthing
become: yes become: yes
become_user: yf become_user: sophie
- name: Create .bash_profile - name: Create .bash_profile
ansible.builtin.file: ansible.builtin.file:
path: /home/yf/.bash_profile path: /home/sophie/.bash_profile
state: touch state: touch
modification_time: preserve modification_time: preserve
access_time: preserve access_time: preserve
become: yes become: yes
become_user: yf become_user: sophie
- name: Enable lemurs - name: Enable lemurs
ansible.builtin.systemd: ansible.builtin.systemd:
@ -188,4 +187,7 @@
#! /bin/sh #! /bin/sh
exec Hyprland exec Hyprland
become: yes become: yes
- name: Set GTK interface theme
ansible.builtin.shell: "gsettings set org.gnome.desktop.interface gtk-theme 'Catppuccin-Latte-Standard-Pink-Light'"
become: yes
become_user: sophie

198
src/.config/ags/config.js Normal file
View file

@ -0,0 +1,198 @@
import { NotificationPopups } from "./notificationPopups.js";
const hyprland = await Service.import("hyprland");
const notifications = await Service.import("notifications");
const mpris = await Service.import("mpris");
const audio = await Service.import("audio");
const battery = await Service.import("battery");
const systemtray = await Service.import("systemtray");
const date = Variable("", {
poll: [1000, 'date "+%H:%M:%S %b %e."'],
});
// widgets can be only assigned as a child in one container
// so to make a reuseable widget, make it a function
// then you can simply instantiate one by calling it
function Workspaces(monitor) {
const activeId = hyprland.active.workspace.bind("id");
const workspaces = hyprland
.bind("workspaces")
.as((ws) =>
ws
.filter((z) => z.monitorID == monitor)
.map(({ id }) =>
Widget.Button({
on_clicked: () => hyprland.messageAsync(`dispatch workspace ${id}`),
child: Widget.Label(`${id}`),
class_name: activeId.as((i) => `${i === id ? "focused" : ""}`),
})
)
);
return Widget.Box({
class_name: "workspaces",
children: workspaces,
});
}
function ClientTitle() {
return Widget.Label({
class_name: "client-title",
label: hyprland.active.client.bind("title"),
});
}
function Clock() {
return Widget.Label({
class_name: "clock",
label: date.bind(),
});
}
function Media() {
const label = Utils.watch("", mpris, "player-changed", () => {
const player = mpris.players.find(z => z.entry == "spotify");
if (player) {
const ms = player.metadata["mpris:length"]/1000;
const minutes = Math.floor((ms/1000)/60)
const seconds = Math.floor((ms/1000)%60)
return `${player.track_artists.join(", ")} - ${player.track_title} [${minutes}:${seconds}]`;
} else {
return "Nothing is playing";
}
});
return Widget.Button({
class_name: "media",
on_primary_click: () => mpris.getPlayer("")?.playPause(),
on_scroll_up: () => mpris.getPlayer("")?.next(),
on_scroll_down: () => mpris.getPlayer("")?.previous(),
child: Widget.Label({ label }),
});
}
function Volume() {
const icons = {
101: "overamplified",
67: "high",
34: "medium",
1: "low",
0: "muted",
};
function getIcon() {
const icon = audio.speaker.is_muted
? 0
: [101, 67, 34, 1, 0].find(
(threshold) => threshold <= audio.speaker.volume * 100
);
return `audio-volume-${icons[icon]}-symbolic`;
}
const icon = Widget.Icon({
icon: Utils.watch(getIcon(), audio.speaker, getIcon),
});
const slider = Widget.Slider({
hexpand: true,
draw_value: false,
on_change: ({ value }) => (audio.speaker.volume = value),
setup: (self) =>
self.hook(audio.speaker, () => {
self.value = audio.speaker.volume || 0;
}),
});
return Widget.Box({
class_name: "volume",
css: "min-width: 180px",
children: [icon, slider],
});
}
function BatteryLabel() {
const value = battery.bind("percent").as((p) => (p > 0 ? p / 100 : 0));
const icon = battery
.bind("percent")
.as((p) => `battery-level-${Math.floor(p / 10) * 10}-symbolic`);
return Widget.Box({
class_name: "battery",
visible: battery.bind("available"),
children: [
Widget.Icon({ icon }),
Widget.LevelBar({
widthRequest: 140,
vpack: "center",
value,
}),
],
});
}
function SysTray() {
const items = systemtray.bind("items").as((items) =>
items.map((item) =>
Widget.Button({
child: Widget.Icon({ icon: item.bind("icon") }),
on_primary_click: (_, event) => item.activate(event),
on_secondary_click: (_, event) => item.openMenu(event),
tooltip_markup: item.bind("tooltip_markup"),
})
)
);
return Widget.Box({
children: items,
});
}
// layout of the bar
function Left(monitor) {
return Widget.Box({
spacing: 8,
children: [Workspaces(monitor), ClientTitle()],
});
}
function Center() {
return Widget.Box({
spacing: 8,
children: [Media()],
});
}
function Right() {
return Widget.Box({
hpack: "end",
spacing: 8,
children: [Volume(), BatteryLabel(), Clock(), SysTray()],
});
}
function Bar(monitor = 0) {
return Widget.Window({
name: `bar-${monitor}`, // name has to be unique
class_name: "bar",
monitor,
anchor: ["top", "left", "right"],
exclusivity: "exclusive",
child: Widget.CenterBox({
start_widget: Left(monitor),
center_widget: Center(),
end_widget: Right(),
}),
});
}
App.config({
style: "./style.css",
windows: [Bar(0), Bar(1), NotificationPopups(0), NotificationPopups(1)],
});
export {};

View file

@ -0,0 +1,130 @@
const notifications = await Service.import("notifications")
/** @param {import('resource:///com/github/Aylur/ags/service/notifications.js').Notification} n */
function NotificationIcon({ app_entry, app_icon, image }) {
if (image) {
return Widget.Box({
css: `background-image: url("${image}");`
+ "background-size: contain;"
+ "background-repeat: no-repeat;"
+ "background-position: center;",
})
}
let icon = "dialog-information-symbolic"
if (Utils.lookUpIcon(app_icon))
icon = app_icon
if (app_entry && Utils.lookUpIcon(app_entry))
icon = app_entry
return Widget.Box({
child: Widget.Icon(icon),
})
}
/** @param {import('resource:///com/github/Aylur/ags/service/notifications.js').Notification} n */
function Notification(n) {
const icon = Widget.Box({
vpack: "start",
class_name: "icon",
child: NotificationIcon(n),
})
const title = Widget.Label({
class_name: "title",
xalign: 0,
justification: "left",
hexpand: true,
max_width_chars: 24,
truncate: "end",
wrap: true,
label: n.summary,
use_markup: true,
})
const body = Widget.Label({
class_name: "body",
hexpand: true,
use_markup: true,
xalign: 0,
justification: "left",
label: n.body,
wrap: true,
})
const actions = Widget.Box({
class_name: "actions",
children: n.actions.map(({ id, label }) => Widget.Button({
class_name: "action-button",
on_clicked: () => {
n.invoke(id)
n.dismiss()
},
hexpand: true,
child: Widget.Label(label),
})),
})
return Widget.EventBox(
{
attribute: { id: n.id },
on_primary_click: n.dismiss,
},
Widget.Box(
{
class_name: `notification ${n.urgency}`,
vertical: true,
},
Widget.Box([
icon,
Widget.Box(
{ vertical: true },
title,
body,
),
]),
actions,
),
)
}
export function NotificationPopups(monitor = 0) {
const list = Widget.Box({
vertical: true,
children: notifications.popups.map(Notification),
})
function onNotified(_, /** @type {number} */ id) {
const n = notifications.getNotification(id)
if (n)
list.children = [Notification(n), ...list.children]
}
function onDismissed(_, /** @type {number} */ id) {
list.children.find(n => n.attribute.id === id)?.destroy()
}
list.hook(notifications, onNotified, "notified")
.hook(notifications, onDismissed, "dismissed")
return Widget.Window({
monitor,
name: `notifications${monitor}`,
class_name: "notification-popups",
anchor: ["top", "right"],
child: Widget.Box({
css: "min-width: 2px; min-height: 2px;",
class_name: "notifications",
vertical: true,
child: list,
/** this is a simple one liner that could be used instead of
hooking into the 'notified' and 'dismissed' signals.
but its not very optimized becuase it will recreate
the whole list everytime a notification is added or dismissed */
// children: notifications.bind('popups')
// .as(popups => popups.map(Notification))
}),
})
}

85
src/.config/ags/style.css Normal file
View file

@ -0,0 +1,85 @@
window.bar {
background-color: @theme_bg_color;
color: @theme_fg_color;
}
button {
min-width: 0;
padding-top: 0;
padding-bottom: 0;
background-color: transparent;
}
button:active {
background-color: @theme_selected_bg_color;
}
button:hover {
border-bottom: 3px solid @theme_fg_color;
}
label {
font-weight: bold;
}
window.notification-popups box.notifications {
padding: .5em;
}
.body {
color: @theme_unfocused_fg_color;
}
.actions .action-button {
margin: 0 .4em;
margin-top: .8em;
}
.actions .action-button:first-child {
margin-left: 0;
}
.actions .action-button:last-child {
margin-right: 0;
}
.icon {
min-width: 68px;
min-height: 68px;
margin-right: 1em;
}
.icon image {
font-size: 58px;
/* to center the icon */
margin: 5px;
color: @theme_fg_color;
}
.icon box {
min-width: 68px;
min-height: 68px;
border-radius: 7px;
}
.workspaces button.focused {
border-bottom: 3px solid @theme_selected_bg_color;
}
.notification {
min-width: 350px;
border-radius: 11px;
padding: 1em;
margin: .5em;
border: 1px solid @wm_borders_edge;
background-color: @theme_bg_color;
}
.client-title {
color: @theme_selected_bg_color;
}
levelbar block,
highlight {
min-height: 10px;
}

View file

@ -16,8 +16,7 @@ exec-once=dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRE
exec-once=~/.config/hypr/portal.sh exec-once=~/.config/hypr/portal.sh
exec-once=swww init && swww img ~/wallpaper.jpg exec-once=swww init && swww img ~/wallpaper.jpg
exec-once=nm-applet exec-once=nm-applet
exec-once=waybar exec-once=ags
exec-once=mako
exec=~/.config/hypr/import-gsettings.sh exec=~/.config/hypr/import-gsettings.sh
env = XCURSOR_SIZE,24 env = XCURSOR_SIZE,24
@ -95,7 +94,7 @@ $mainMod = ALT
bind = $mainMod, Q, killactive, bind = $mainMod, Q, killactive,
bind = $mainMod, M, exit, bind = $mainMod, M, exit,
bind = $mainMod, Z, exec, alacritty --class floating bind = $mainMod, Z, exec, foot -a floating
bind = $mainMod, E, exec, thunar bind = $mainMod, E, exec, thunar
bind = $mainMod, O, exec, swaylock -i ~/wallpaper.png bind = $mainMod, O, exec, swaylock -i ~/wallpaper.png
bind = $mainMod, V, togglefloating, bind = $mainMod, V, togglefloating,

View file

@ -1,9 +0,0 @@
# Colors
background-color=#eff1f5
text-color=#4c4f69
border-color=#1e66f5
progress-color=over #ccd0da
[urgency=high]
border-color=#fe640b

View file

@ -1,78 +0,0 @@
{
"layer": "top",
"position": "top",
"height": 24,
"spacing": 4,
"modules-left": [
"hyprland/workspaces",
"wlr/taskbar",
],
"modules-center": [
"hyprland/window"
],
"modules-right": [
"mpris",
"pulseaudio",
"battery",
"tray",
"clock"
],
"wlr/taskbar": {
"on-click": "activate",
"on-click-middle": "close",
"ignore-list": [
"foot"
]
},
"hyprland/workspaces": {
"on-click": "activate",
"on-scroll-up": "hyprctl dispatch workspace e-1",
"on-scroll-down": "hyprctl dispatch workspace e+1"
},
"hyprland/window": {
"max-length": 128
},
"clock": {
"format": "{:%H:%M}",
"tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>"
},
"mpris": {
"format": "{player_icon} {dynamic}",
"format-paused": "{status_icon} <i>{dynamic}</i>",
"player-icons": {
"default": "🎵"
},
"status-icons": {
"paused": "⏸"
},
},
"pulseaudio": {
"format": "{volume}% {icon}",
"format-bluetooth": "{volume}% {icon} ",
"format-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", ""]
},
"scroll-step": 1,
"on-click": "qpwgraph",
},
"battery": {
"interval": 60,
"states": {
"warning": 30,
"critical": 15
},
"format": "{capacity}% {icon}",
"format-icons": ["", "", "", "", ""],
"max-length": 25
},
"tray": {
"spacing": 4
}
}

View file

@ -1,98 +0,0 @@
@import "theme.css";
* {
font-family: FantasqueSansMono Nerd Font;
font-size: 17px;
min-height: 0;
}
#waybar {
background: @surface1;
color: @text;
margin: 1px 1px;
}
#workspaces {
border-radius: 1rem;
margin: 5px;
background-color: @surface0;
margin-left: 1rem;
}
#workspaces button {
color: @lavender;
border-radius: 1rem;
padding: 0.4rem;
}
#workspaces button.active {
color: @sky;
border-radius: 1rem;
}
#workspaces button:hover {
color: @sapphire;
border-radius: 1rem;
}
#custom-music,
#backlight,
#tray,
#clock,
#battery,
#pulseaudio,
#custom-lock,
#custom-power {
background-color: @surface0;
padding: 0.5rem 1rem;
margin: 5px 0;
}
#clock {
color: @blue;
border-radius: 0px 1rem 1rem 0px;
margin-right: 1rem;
}
#battery {
color: @green;
}
#battery.charging {
color: @green;
}
#battery.warning:not(.charging) {
color: @red;
}
#backlight {
color: @yellow;
}
#backlight,
#battery {
border-radius: 0;
}
#pulseaudio {
color: @maroon;
border-radius: 1rem 0px 0px 1rem;
margin-left: 1rem;
}
#custom-music {
color: @mauve;
border-radius: 1rem;
}
#custom-lock {
border-radius: 1rem 0px 0px 1rem;
color: @lavender;
}
#custom-power {
margin-right: 1rem;
border-radius: 0px 1rem 1rem 0px;
color: @red;
}

View file

@ -1,26 +0,0 @@
@define-color rosewater #dc8a78;
@define-color flamingo #dd7878;
@define-color pink #ea76cb;
@define-color mauve #8839ef;
@define-color red #d20f39;
@define-color maroon #e64553;
@define-color peach #fe640b;
@define-color yellow #df8e1d;
@define-color green #40a02b;
@define-color teal #179299;
@define-color sky #04a5e5;
@define-color sapphire #209fb5;
@define-color blue #1e66f5;
@define-color lavender #7287fd;
@define-color text #4c4f69;
@define-color subtext1 #5c5f77;
@define-color subtext0 #6c6f85;
@define-color overlay2 #7c7f93;
@define-color overlay1 #8c8fa1;
@define-color overlay0 #9ca0b0;
@define-color surface2 #acb0be;
@define-color surface1 #bcc0cc;
@define-color surface0 #ccd0da;
@define-color base #eff1f5;
@define-color mantle #e6e9ef;
@define-color crust #dce0e8;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

After

Width:  |  Height:  |  Size: 1.9 MiB