using hyprland now; can recommend

This commit is contained in:
Ludwig Lehnert 2024-09-25 23:59:46 +02:00
parent 4d882968f9
commit b75a72bc07
13 changed files with 849 additions and 1 deletions

2
hypr-colors.conf Normal file
View File

@ -0,0 +1,2 @@
$foreground = rgba(180, 180, 120, 1)
$background = rgba(30, 30, 30, 0.15)

27
hypr-hypridle.conf Normal file
View File

@ -0,0 +1,27 @@
general {
lock_cmd = pidof hyprlock || hyprlock # avoid starting multiple hyprlock instances.
before_sleep_cmd = loginctl lock-session # lock before suspend.
after_sleep_cmd = hyprctl dispatch dpms on # to avoid having to press a key twice to turn on the display.
}
listener {
timeout = 60 # 1 min.
on-timeout = light -O && light -S 1 # set monitor backlight to minimum, avoid 0 on OLED monitor.
on-resume = light -I # monitor backlight restore.
}
listener {
timeout = 90 # 1.5 min
on-timeout = loginctl lock-session # lock screen when timeout has passed
}
listener {
timeout = 120 # 2 min
on-timeout = hyprctl dispatch dpms off # screen off when timeout has passed
on-resume = hyprctl dispatch dpms on # screen on when activity is detected after timeout has fired.
}
listener {
timeout = 180 # 3 min
on-timeout = systemctl suspend # suspend pc
}

205
hypr-hyprland.conf Normal file
View File

@ -0,0 +1,205 @@
# #######################################################################################
# AUTOGENERATED HYPR CONFIG.
# PLEASE USE THE CONFIG PROVIDED IN THE GIT REPO /examples/hypr.conf AND EDIT IT,
# OR EDIT THIS ONE ACCORDING TO THE WIKI INSTRUCTIONS.
# #######################################################################################
#
# Please note not all available settings / options are set here.
# For a full list, see the wiki
#
autogenerated = 0 # remove this line to remove the warning
# See https://wiki.hyprland.org/Configuring/Monitors/
monitor=,preferred,auto,auto
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
# Execute your favorite apps at launch
# exec-once = waybar & hyprpaper & firefox
# Source a file (multi-file configs)
# source = ~/.config/hypr/myColors.conf
# Set programs that you use
$terminal = kitty
$fileManager = nautilus
$menu = wofi -S drun -i -I -s .config/wofi/style.css
exec-once = waybar
exec-once = hypridle
# Some default env vars.
env = XCURSOR_SIZE,24
env = QT_QPA_PLATFORMTHEME,qt5ct # change to qt6ct if you have that
# For all categories, see https://wiki.hyprland.org/Configuring/Variables/
input {
kb_layout = us
kb_variant =
kb_model =
kb_options =
kb_rules =
follow_mouse = 1
touchpad {
natural_scroll = no
}
sensitivity = 0 # -1.0 to 1.0, 0 means no modification.
}
general {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
gaps_in = 5
gaps_out = 20
border_size = 2
col.active_border = rgba(33ccffee) rgba(00ff99ee) 45deg
col.inactive_border = rgba(595959aa)
layout = dwindle
# Please see https://wiki.hyprland.org/Configuring/Tearing/ before you turn this on
allow_tearing = false
}
decoration {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
rounding = 10
blur {
enabled = false
size = 3
passes = 1
}
drop_shadow = yes
shadow_range = 4
shadow_render_power = 3
col.shadow = rgba(1a1a1aee)
}
animations {
enabled = yes
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
animation = windows, 1, 2, myBezier
animation = windowsOut, 1, 2, default, popin 80%
animation = border, 1, 2, default
animation = borderangle, 1, 2, default
animation = fade, 1, 2, default
animation = workspaces, 1, 2, myBezier
}
dwindle {
# See https://wiki.hyprland.org/Configuring/Dwindle-Layout/ for more
pseudotile = yes # master switch for pseudotiling. Enabling is bound to mainMod + P in the keybinds section below
preserve_split = yes # you probably want this
}
master {
# See https://wiki.hyprland.org/Configuring/Master-Layout/ for more
new_is_master = true
}
gestures {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
workspace_swipe = true
}
misc {
# See https://wiki.hyprland.org/Configuring/Variables/ for more
force_default_wallpaper = -1 # Set to 0 or 1 to disable the anime mascot wallpapers
}
# Example per-device config
# See https://wiki.hyprland.org/Configuring/Keywords/#per-device-input-configs for more
device {
name = epic-mouse-v1
sensitivity = -0.5
}
xwayland {
force_zero_scaling = true
}
# Example windowrule v1
# windowrule = float, ^(kitty)$
# Example windowrule v2
# windowrulev2 = float,class:^(kitty)$,title:^(kitty)$
# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more
windowrulev2 = suppressevent maximize, class:.* # You'll probably like this.
# See https://wiki.hyprland.org/Configuring/Keywords/ for more
$mainMod = SUPER
# Example binds, see https://wiki.hyprland.org/Configuring/Binds/ for more
bind = $mainMod, RETURN, exec, $terminal
bind = $mainMod, Q, killactive,
bind = $mainMod, E, exit,
bind = $mainMod, F, exec, $fileManager
bind = $mainMod, SPACE, togglefloating,
bind = $mainMod, D, exec, $menu
bind = $mainMod, P, pseudo, # dwindle
bind = $mainMod, J, togglesplit, # dwindle
bind = $mainMod, L, exec, hyprlock
# Move focus with mainMod + arrow keys
bind = $mainMod, left, movefocus, l
bind = $mainMod, right, movefocus, r
bind = $mainMod, up, movefocus, u
bind = $mainMod, down, movefocus, d
# Switch workspaces with mainMod + [0-9]
bind = $mainMod, 1, workspace, 1
bind = $mainMod, 2, workspace, 2
bind = $mainMod, 3, workspace, 3
bind = $mainMod, 4, workspace, 4
bind = $mainMod, 5, workspace, 5
bind = $mainMod, 6, workspace, 6
bind = $mainMod, 7, workspace, 7
bind = $mainMod, 8, workspace, 8
bind = $mainMod, 9, workspace, 9
bind = $mainMod, 0, workspace, 10
# Move active window to a workspace with mainMod + SHIFT + [0-9]
bind = $mainMod SHIFT, 1, movetoworkspace, 1
bind = $mainMod SHIFT, 2, movetoworkspace, 2
bind = $mainMod SHIFT, 3, movetoworkspace, 3
bind = $mainMod SHIFT, 4, movetoworkspace, 4
bind = $mainMod SHIFT, 5, movetoworkspace, 5
bind = $mainMod SHIFT, 6, movetoworkspace, 6
bind = $mainMod SHIFT, 7, movetoworkspace, 7
bind = $mainMod SHIFT, 8, movetoworkspace, 8
bind = $mainMod SHIFT, 9, movetoworkspace, 9
bind = $mainMod SHIFT, 0, movetoworkspace, 10
# Example special workspace (scratchpad)
bind = $mainMod, S, togglespecialworkspace, magic
bind = $mainMod SHIFT, S, movetoworkspace, special:magic
# Scroll through existing workspaces with mainMod + scroll
bind = $mainMod, mouse_down, workspace, e+1
bind = $mainMod, mouse_up, workspace, e-1
# Move/resize windows with mainMod + LMB/RMB and dragging
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow
bind = , XF86AudioRaiseVolume, exec, pactl -- set-sink-volume @DEFAULT_SINK@ +5%
bind = , XF86AudioLowerVolume, exec, pactl -- set-sink-volume @DEFAULT_SINK@ -5%
bind = , XF86AudioMute, exec, pactl -- set-sink-mute @DEFAULT_SINK@ toggle
bind = , XF86MonBrightnessUp, exec, light -A 5
bind = , XF86MonBrightnessDown, exec, light -U 5

138
hypr-hyprlock.conf Normal file
View File

@ -0,0 +1,138 @@
source = ~/.config/hypr/colors.conf
# BACKGROUND
background {
monitor =
path = ~/.config/hypr/lockbg.jpg
blur_passes = 2
contrast = 1
brightness = 0.5
vibrancy = 0.2
vibrancy_darkness = 0.2
}
# GENERAL
general {
no_fade_in = true
no_fade_out = true
hide_cursor = false
grace = 0
disable_loading_bar = true
}
# INPUT FIELD
input-field {
monitor =
size = 250, 60
outline_thickness = 2
dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8
dots_spacing = 0.35 # Scale of dots' absolute size, 0.0 - 1.0
dots_center = true
outer_color = rgba(0, 0, 0, 0)
inner_color = rgba(0, 0, 0, 0.2)
font_color = $foreground
fade_on_empty = false
rounding = -1
check_color = rgb(204, 136, 34)
placeholder_text = <i><span foreground="##cdd6f4">Input Password...</span></i>
hide_input = false
position = 0, -200
halign = center
valign = center
}
# DATE
label {
monitor =
text = cmd[update:1000] echo "$(date +"%A, %B %d")"
color = rgba(242, 243, 244, 0.75)
font_size = 22
font_family = JetBrains Mono
position = 0, 300
halign = center
valign = center
}
# TIME
label {
monitor =
text = cmd[update:1000] echo "$(date +"%-I:%M")"
color = rgba(242, 243, 244, 0.75)
font_size = 95
font_family = JetBrains Mono Extrabold
position = 0, 200
halign = center
valign = center
}
# Profile Picture
# image {
# monitor =
# path = /home/justin/Pictures/profile_pictures/justin_square.png
# size = 100
# border_size = 2
# border_color = $foreground
# position = 0, -100
# halign = center
# valign = center
# }
# Desktop Environment
# image {
# monitor =
# path = /home/justin/Pictures/profile_pictures/hypr.png
# size = 75
# border_size = 2
# border_color = $foreground
# position = -50, 50
# halign = right
# valign = bottom
# }
# CURRENT SONG
# label {
# monitor =
# text = cmd[update:1000] echo "$(/home/justin/Documents/Scripts/whatsong.sh)"
# color = $foreground
# #color = rgba(255, 255, 255, 0.6)
# font_size = 18
# font_family = Metropolis Light, Font Awesome 6 Free Solid
# position = 0, 50
# halign = center
# valign = bottom
# }
label {
monitor =
text = cmd[update:1000] whoami
color = $foreground
font_size = 14
font_family = JetBrains Mono
position = 0, -10
halign = center
valign = top
}
label {
monitor =
text = cmd[update:1000] ~/.config/waybar/battery.sh once
color = $foreground
font_size = 24
font_family = JetBrains Mono
position = -10, -10
halign = right
valign = top
}
# label {
# monitor =
# text = cmd[update:1000] echo "$(/home/justin/Documents/Scripts/network-status.sh)"
# color = $foreground
# font_size = 24
# font_family = JetBrains Mono
# position = -20, -10
# halign = right
# valign = top
# }

BIN
hypr-lockbg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

View File

@ -13,10 +13,11 @@ if [[ -f /etc/os-release && $1 == "packages" ]]; then
sudo apt-get update && sudo apt-get -y install --no-install-recommends wget curl
# install pfetch
curl -s https://raw.githubusercontent.com/dylanaraps/pfetch/master/pfetch > "$HOME/.local/bin/pfetch"
chmod +x "$HOME/.local/bin/pfetch"
# TODO: further setup
# add google chrome repository

31
kitty-kitty.conf Normal file
View File

@ -0,0 +1,31 @@
font_size 12
cursor_shape underline
window_margin_width 0
background #323232
foreground #ffffff
cursor #d6d6d6
selection_background #5b5b5b
selection_foreground #323232
color0 #353535
color8 #535353
color1 #d25252
color9 #f00c0c
color2 #a4c161
color10 #c1df74
color3 #ffc56d
color11 #e1e48a
color4 #6c99ba
color12 #8ab6d9
color5 #d096d9
color13 #efb5f7
color6 #bdd6ff
color14 #dbf4ff
color7 #ededec
color15 #ffffff
active_tab_foreground #ffffff
active_tab_background #535353
inactive_tab_foreground #ffffff
inactive_tab_background #353535

15
waybar-battery.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
print_status() {
echo $(upower -i /org/freedesktop/UPower/devices/battery_BAT0 | grep percentage | sed 's/percentage://g') " "
}
print_status
if [ -z "$1" ] || [ "$1" -ne "once" ]; then
while sleep 1; do
print_status
done
fi

15
waybar-brightness.sh Executable file
View File

@ -0,0 +1,15 @@
#!/bin/bash
print_status() {
echo "$(light -G | xargs printf %.0f)%" " "
}
print_status
if [ -z "$1" ] || [ "$1" -ne "once" ]; then
while sleep 0.1; do
print_status
done
fi

82
waybar-config Normal file
View File

@ -0,0 +1,82 @@
{
"modules-left": ["hyprland/workspaces", "hyprland/window"],
"modules-center": ["clock", "custom/lock"],
"modules-right": ["tray", "custom/spotify", "pulseaudio", "custom/brightness", "battery"],
"network": {
"format-wifi": "{essid} ({signalStrength}%) ",
"format-ethernet": "{ifname} ",
"format-disconnected": "",
"max-length": 50,
"on-click": "kitty -e 'nmtui'"
},
// "tray": {
// "icon-size": 15,
// "spacing": 10
// },
"clock": {
// "tooltip-format": "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>",
// "format-alt": "{:%Y-%m-%d}",
"on-click": "gnome-calendar"
},
"pulseaudio": {
"format": "{volume}% {icon} ",
"format-bluetooth": "{volume}% {icon} {format_source}",
"format-bluetooth-muted": " {icon} {format_source}",
"format-muted": "0% {icon} ",
"format-source": "{volume}% ",
"format-source-muted": "",
"format-icons": {
"headphone": "",
"hands-free": "",
"headset": "",
"phone": "",
"portable": "",
"car": "",
"default": ["", "", ""]
},
"on-click": "pavucontrol"
},
"custom/lock": {
"format": " ",
"on-click": "hyprlock"
},
"battery": {
"states": {
"warning": 30,
"critical": 15
},
"interval": 3,
"format": "{capacity}% {icon}",
"format-charging": "{capacity}%  ",
"format-plugged": "{capacity}%  ",
"format-alt": "{time} {icon}",
"format-full": "{capacity}%  ",
"format-icons": [" ", " ", " "]
},
// "custom/battery": {
// "return-type": "text",
// "exec": "~/.config/waybar/battery.sh"
// },
"custom/brightness": {
"return-type": "text",
"exec": "~/.config/waybar/brightness.sh",
"on-click": "light -S 1"
},
"custom/spotify": {
"return-type": "json",
"exec": "~/.config/waybar/media.py --player spotify",
"on-click": "playerctl play-pause",
"on-scroll-up": "playerctl next",
"on-scroll-down": "playerctl previous",
"escape": true
}
}

203
waybar-media.py Executable file
View File

@ -0,0 +1,203 @@
#!/usr/bin/env python3
import gi
gi.require_version("Playerctl", "2.0")
from gi.repository import Playerctl, GLib
from gi.repository.Playerctl import Player
import argparse
import logging
import sys
import signal
import gi
import json
import os
import io
import json
from typing import List
logger = logging.getLogger(__name__)
def signal_handler(sig, frame):
logger.info("Received signal to stop, exiting")
sys.stdout.write("\n")
sys.stdout.flush()
# loop.quit()
sys.exit(0)
class PlayerManager:
def __init__(self, selected_player=None, excluded_player=[], limit=35):
self.manager = Playerctl.PlayerManager()
self.loop = GLib.MainLoop()
self.manager.connect(
"name-appeared", lambda *args: self.on_player_appeared(*args))
self.manager.connect(
"player-vanished", lambda *args: self.on_player_vanished(*args))
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
self.selected_player = selected_player
self.excluded_player = excluded_player.split(',') if excluded_player else []
self.limit = limit
self.init_players()
def init_players(self):
for player in self.manager.props.player_names:
if player.name in self.excluded_player:
continue
if self.selected_player is not None and self.selected_player != player.name:
logger.debug(f"{player.name} is not the filtered player, skipping it")
continue
self.init_player(player)
def run(self):
logger.info("Starting main loop")
self.loop.run()
def init_player(self, player):
logger.info(f"Initialize new player: {player.name}")
player = Playerctl.Player.new_from_name(player)
player.connect("playback-status",
self.on_playback_status_changed, None)
player.connect("metadata", self.on_metadata_changed, None)
self.manager.manage_player(player)
self.on_metadata_changed(player, player.props.metadata)
def get_players(self) -> List[Player]:
return self.manager.props.players
def write_output(self, text, player):
logger.debug(f"Writing output: {text}")
if len(text) > self.limit:
text = text[:self.limit] + ''
output = {"text": text,
"class": "custom-" + player.props.player_name,
"alt": player.props.player_name}
sys.stdout.write(json.dumps(output) + "\n")
sys.stdout.flush()
def clear_output(self):
sys.stdout.write("\n")
sys.stdout.flush()
def on_playback_status_changed(self, player, status, _=None):
logger.debug(f"Playback status changed for player {player.props.player_name}: {status}")
self.on_metadata_changed(player, player.props.metadata)
def get_first_playing_player(self):
players = self.get_players()
logger.debug(f"Getting first playing player from {len(players)} players")
if len(players) > 0:
# if any are playing, show the first one that is playing
# reverse order, so that the most recently added ones are preferred
for player in players[::-1]:
if player.props.status == "Playing":
return player
# if none are playing, show the first one
return players[0]
else:
logger.debug("No players found")
return None
def show_most_important_player(self):
logger.debug("Showing most important player")
# show the currently playing player
# or else show the first paused player
# or else show nothing
current_player = self.get_first_playing_player()
if current_player is not None:
self.on_metadata_changed(current_player, current_player.props.metadata)
else:
self.clear_output()
def on_metadata_changed(self, player, metadata, _=None):
logger.debug(f"Metadata changed for player {player.props.player_name}")
player_name = player.props.player_name
artist = player.get_artist()
title = player.get_title()
title = title.replace("&", "&amp;")
track_info = ""
if player_name == "spotify" and "mpris:trackid" in metadata.keys() and ":ad:" in player.props.metadata["mpris:trackid"]:
track_info = "Advertisement"
elif artist is not None and title is not None:
track_info = f"{title}{artist}"
else:
track_info = title
if track_info:
if player.props.status == "Playing":
track_info = "" + track_info
else:
track_info = "" + track_info
# only print output if no other player is playing
current_playing = self.get_first_playing_player()
if current_playing is None or current_playing.props.player_name == player.props.player_name:
self.write_output(track_info, player)
else:
logger.debug(f"Other player {current_playing.props.player_name} is playing, skipping")
def on_player_appeared(self, _, player):
logger.info(f"Player has appeared: {player.name}")
if player.name in self.excluded_player:
logger.debug(
"New player appeared, but it's in exclude player list, skipping")
return
if player is not None and (self.selected_player is None or player.name == self.selected_player):
self.init_player(player)
else:
logger.debug(
"New player appeared, but it's not the selected player, skipping")
def on_player_vanished(self, _, player):
logger.info(f"Player {player.props.player_name} has vanished")
self.show_most_important_player()
def parse_arguments():
parser = argparse.ArgumentParser()
# Increase verbosity with every occurrence of -v
parser.add_argument("-v", "--verbose", action="count", default=0)
parser.add_argument("-x", "--exclude", "- Comma-separated list of excluded player")
parser.add_argument("-l", "--limit", "- Limit resulting text length", default=25, type=int)
# Define for which player we"re listening
parser.add_argument("--player")
parser.add_argument("--enable-logging", action="store_true")
return parser.parse_args()
def main():
arguments = parse_arguments()
# Initialize logging
if arguments.enable_logging:
logfile = os.path.join(os.path.dirname(
os.path.realpath(__file__)), "media-player.log")
logging.basicConfig(filename=logfile, level=logging.DEBUG,
format="%(asctime)s %(name)s %(levelname)s:%(lineno)d %(message)s")
# Logging is set by default to WARN and higher.
# With every occurrence of -v it's lowered by one
logger.setLevel(max((3 - arguments.verbose) * 10, 0))
logger.info("Creating player manager")
if arguments.player:
logger.info(f"Filtering for player: {arguments.player}")
if arguments.exclude:
logger.info(f"Exclude player {arguments.exclude}")
player = PlayerManager(arguments.player, arguments.exclude, arguments.limit)
player.run()
if __name__ == "__main__":
main()

78
waybar-style.css Normal file
View File

@ -0,0 +1,78 @@
* {
border: none;
font-family: Font Awesome, Roboto, Arial, sans-serif;
font-size: 13px;
color: #ffffff;
border-radius: 20px;
}
window {
/*font-weight: bold;*/
}
window#waybar {
background: rgba(0, 0, 0, 0);
}
/*-----module groups----*/
.modules-right {
background-color: rgba(0,43,51,0.85);
margin: 2px 10px 0 0;
padding: 0 5px;
}
.modules-center {
background-color: rgba(0,43,51,0.85);
margin: 2px 5px 0 5px;
padding: 0 5px;
}
.modules-left {
margin: 2px 0 0 5px;
background-color: rgba(0,119,179,0.6);
}
/*-----modules indv----*/
#workspaces button {
padding: 1px 6px;
background-color: transparent;
}
#workspaces button:hover {
box-shadow: inherit;
background-color: rgba(0,153,153,1);
}
#workspaces button.active {
background-color: rgba(0,43,51,0.85);
}
#window {
font-family: 'Go Mono', 'JetBrains Mono', 'Ubuntu Mono', 'Droid Sans Mono', 'monospace', monospace;
font-weight: bold;
padding: 0 10px;
}
#clock,
#battery,
#pulseaudio,
#custom-lock,
#custom-media,
#custom-spotify,
#custom-brightness {
padding: 0 6px;
}
#pulseaudio.muted {
color: #cc3436;
}
#battery.charging {
color: #2dcc36;
}
#battery.warning:not(.charging) {
color: #e6e600;
}
#battery.critical:not(.charging) {
color: #cc3436;
}
/*-----Colors----*/
/*
*rgba(0,85,102,1),#005566 --> Indigo(dye)
*rgba(0,43,51,1),#002B33 --> Dark Green
*rgba(0,153,153,1),#009999 --> Persian Green
*
*/

51
wofi-style.css Normal file
View File

@ -0,0 +1,51 @@
window {
font-family: "DejaVu Sans", "Font Awesome 5 Free";
margin: 0px;
border: 1px solid rgba(0, 0, 0, 0.9);
background-color: rgba(29, 31, 33, 0.95);
border-radius: 10px;
}
#input {
margin: 5px;
border: none;
color: #f8f8f2;
background-color: rgba(55, 59, 65, 0.95);
}
#inner-box {
margin: 5px;
border: none;
background-color: transparent;
}
#outer-box {
margin: 5px;
border: none;
background-color: transparent;
}
#scroll {
margin: 0px;
border: none;
}
#text {
margin: 5px;
border: none;
color: #c5c8c6;
}
#entry {
border: none;
}
#entry:focus {
border: none;
}
#entry:selected {
background-color: rgba(55, 59, 65, 0.95);
border-radius: 5px;
border: none;
}