#!/usr/bin/env bash # Keybindings # https://mylinuxforwork.github.io/dotfiles/usage/keybindings # Debian dependencies handled in separated script. Current calls hyprland_deps.sh # which has the corresponding depends in debian that reflects the ml4w deps found # here: https://mylinuxforwork.github.io/dotfiles/getting-started/dependencies # On debian it's best to avoid their userspace python packages # Thet appear to have hijacked pip for their own usw and # none of the automated packaging tools remaom om sync for # installing from pypi. pipx install qtile pipx inject qtile qtile-extras psutil dbus-fast iwlib # Pywal is a tool that generates a color palette from the dominant colors in an image. # It then applies the colors system-wide and on-the-fly in all of your favourite programs. pipx install pywal pywalfox pipx install waypaper # fontend to X and wayland wallpaper backends. DEST=${1:-/etc/skel} CONFIG_HOME=${DEST}/.config ROFI_HOME=${CONFIG_HOME}/rofi QTILE_HOME=${CONFIG_HOME}/qtile QTILE_SCRIPTS=${QTILE_HOME}/scripts QTILE_SETTINGS_HOME=${CONFIG_HOME}/ml4w QTILE_SETTINGS=${QTILE_SETTINGS_HOME}/settings QTILE_THEME_CACHE=${QTILE_SETTINGS_HOME}/cache mkdir -p ${ROFI_HOME} mkdir -p ${QTILE_HOME} mkdir -p ${QTILE_SCRIPTS} mkdir -p ${QTILE_SETTINGS} mkdir -p ${QTILE_THEME_CACHE} # x11-utils DEBIAN_XPROP_PATH="/usr/bin/xprop" xprop=${DEBIAN_XPROP_PATH} # Put ml4w config files in place # These are the conf files replicated in these heredocs # git clone --depth 1 https://github.com/mylinuxforwork/qtile /var/tmp/ml4w_qtile/ # Other settings git clone --depth 1 https://github.com/mylinuxforwork/dotfiles /var/tmp/ml4w_dotfiles/ cp -a /var/tmp/ml4w_dotfiles/.config/ml4w/ ${QTILE_SETTINGS_HOME} # Add the rofi configuration # https://davatorium.github.io/rofi/CONFIG/ cp -a /var/tmp/ml4w_dotfiles/.config/rofi/* ${ROFI_HOME} # Create the wallpaper directory and copy in the ml4w wallpapers # The ensure-wal sscript below will copy in just the default background if the # wallpaper directory is empty so you can comment this out. mkdir -p ${DEST}/wallpaper cp -a /var/tmp/ml4w_dotfiles/dotfiles/.config/ml4w/wallpapers/* ${DEST}/wallpaper # START: nested displays for configuration testing in X and Wayland # Test qtile in a xephyr nested server. if [ -d "/usr/bin/Xephyr" ]; then sudo apt install -y xserver-xephyr fi # https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/scripts/wephyr conf_print_wephyr() { cat <<-'EOF' #!/usr/bin/env python # # The Wayland backend's equivalent to the xephyr script # # The QTILE_XEPHYR environmental variable is set to 2 in this script, which can # be used by configs to detect when they are run via this script. # import os import signal import subprocess import sys import time from pathlib import Path BASE_DIR = Path(__file__).parent.parent.resolve() sys.path.insert(0, BASE_DIR) from libqtile.utils import get_cache_dir, guess_terminal # noqa: E402 CACHE_DIR = Path(get_cache_dir()) QTILE = BASE_DIR / "libqtile" / "scripts" / "main.py" # This script can be configured with environmental variables and arguments: outputs = os.environ.get("OUTPUTS", 1) app = os.environ.get("APP", guess_terminal()) log_level = os.environ.get("LOG_LEVEL", "INFO") cmd = [sys.executable, QTILE.as_posix(), "start", "-b", "wayland", "-l", log_level] cmd.extend(sys.argv[1:]) # Find the display that the app needs display = os.environ.get("WAYLAND_DISPLAY", "") if display: display = display[:-1] + str(int(display[-1]) + 1) else: display = "wayland-0" os.environ["QTILE_XEPHYR"] = "2" os.environ["WLR_X11_OUTPUTS"] = str(outputs) os.environ["WLR_WL_OUTPUTS"] = str(outputs) proc = subprocess.Popen(cmd) time.sleep(1) os.environ["WAYLAND_DISPLAY"] = display app_proc = subprocess.Popen(app) # Suppress KeyboardInterrupt messages def noop(signal, frame): pass signal.signal(signal.SIGINT, noop) proc.wait() EOF } conf_print_xephyr | tee ${HOME}/.local/bin/qtile-start_wnested.sh chmod +x ${HOME}/.local/bin/qtile-start_wnested.sh # https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/scripts/xephyr conf_print_xephyr_official() { cat <<-'EOF' #!/usr/bin/env bash HERE=$(dirname $(readlink -f $0)) SCREEN_SIZE=${SCREEN_SIZE:-800x600} XDISPLAY=${XDISPLAY:-:1} LOG_LEVEL=${LOG_LEVEL:-INFO} APP=${APP:-$(python -c "from libqtile.utils import guess_terminal; print(guess_terminal())")} if [[ -z $PYTHON ]]; then PYTHON=python3 fi Xephyr +extension RANDR -screen ${SCREEN_SIZE} ${XDISPLAY} -ac & XEPHYR_PID=$! ( sleep 1 # env DISPLAY=${XDISPLAY} QTILE_XEPHYR=1 ${PYTHON} "${HERE}"/../libqtile/scripts/main.py start -l ${LOG_LEVEL} $@ & env DISPLAY=${XDISPLAY} QTILE_XEPHYR=1 qtile start -l ${LOG_LEVEL} $@ & QTILE_PID=$! env DISPLAY=${XDISPLAY} ${APP} & wait $QTILE_PID kill $XEPHYR_PID ) EOF } conf_print_xephyr_official | sudo tee ${HOME}/.local/bin/qtile-start_xnested_official.sh # Working - two screens conf_print_xephyr() { cat <<-'EOF' Xephyr +extension RANDR -screen 1280x720 -screen 1280x720+1280+0 :1 -ac & export DISPLAY=:1 qtile start EOF } conf_print_xephyr | tee ${HOME}/.local/bin/qtile-start_xnested.sh chmod +x ${HOME}/.local/bin/qtile-start_xnested.sh # Add XDG path if [ -d "$HOME/.local/bin" ]; then PATH="$HOME/.local/bin:$PATH" fi # END: nested displays for configuration testing in X and Wayland # START:Debian files (will be overridden by qtile debian package) conf_print_start() { cat <<-'EOF' #!/bin/bash # /usr/bin/qtile start /home/default/.local/bin/qtile start EOF } conf_print_start | sudo tee /usr/bin/qtile-start conf_print_desktop() { cat <<-EOF [Desktop Entry] Name=Qtile Comment=Qtile Session Exec=dbus-run-session -- ${DEST}/.local/bin/qtile start Type=Application Keywords=wm;tiling EOF } # conf_print_desktop | sudo tee /usr/share/xsessions/qtile.desktop # This is to set a default session in the $HOME directory rather than # using /usr/share to run $HOME/.local/bin programs. Also this session # will not be available to other users. conf_print_xsession() { cat <<-EOF #!/bin/sh exec dbus-run-session -- ${DEST}/.local/bin/qtile start EOF } conf_print_xsession | tee ${DEST}/.xsession chmod +x ${DEST}/.xsession # The default session for lightdm: named system sessions # xfce, qtile, or default etc from /usr/share/xsessions and # /usr/share/wayland-sessions # default points to $HOME/.xsession conf_print_dmrc() { cat <<-'EOF' [Desktop] Language=en_GB.UTF-8 Session=default EOF } conf_print_dmrc | tee ${DEST}/.dmrc chmod 644 ~/.dmrc conf_print_wayland_desktop() { cat <<-EOF [Desktop Entry] Name=Qtile Comment=Qtile Session Exec=dbus-run-session -- ${DEST}/.local/bin/qtile -b start Type=Application Keywords=wm;tiling EOF } # conf_print_wayland_desktop | sudo tee /usr/share/wayland-sessions/qtile-wayland.desktop # https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/resources/qtile.desktop # conf_print_desktop() { # cat <<-'EOF' # [Desktop Entry] # Name=Qtile # Comment=Qtile Session # Exec=qtile start # Type=Application # Keywords=wm;tiling # EOF # } # conf_print_desktop | sudo tee /usr/share/xsessions/qtile.desktop # https://raw.githubusercontent.com/qtile/qtile/refs/heads/master/resources/qtile-wayland.desktop # conf_print_wayland_desktop() { # cat <<-'EOF' # [Desktop Entry] # Name=Qtile (Wayland) # Comment=Qtile Session # Exec=qtile start -b wayland # Type=Application # Keywords=wm;tiling # EOF # } # conf_print_wayland_desktop | sudo tee /usr/share/xsessions/qtile-wayland.desktop # https://github.com/qtile/qtile/raw/refs/heads/master/resources/99-qtile.rules conf_print_rules() { cat <<-'EOF' # for controlling LCD backlight ACTION=="add", SUBSYSTEM=="backlight", RUN+="/usr/bin/chmod o+w /sys/class/backlight/%k/brightness" OPTIONS="log_level=debug" # keyboard backlight ACTION=="add", SUBSYSTEM=="leds", RUN+="/usr/bin/chmod o+w /sys/class/leds/%k/brightness" # fancy battery charge control, needs to be per ACPI implementation, so we need # to periodically check the kernel for more of these: # # $ ~/packages/linux/drivers/platform/x86 master git grep -l charge_control_end_threshold # asus-wmi.c # dell/dell-laptop.c # fujitsu-laptop.c # huawei-wmi.c # lg-laptop.c # msi-ec.c # samsung-galaxybook.c # system76_acpi.c # thinkpad_acpi.c # toshiba_acpi.c # # Last checked as of 6.16. # # This is a bit annoying: if we use stuff like BAT0 matching we get: # BAT0: Process '/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold' failed with exit code 1 # because charge_control_start_threshold is created by the driver loading, not # the battery being identified. but then we don't have a device name when the # driver loads, so we hardcode BAT0... if you have more than one battery, you # can just copypasta a BAT1 rule too (obviously only for your hardware, though # :). ACTION=="add" KERNEL=="asus-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="asus-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="dell-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="dell-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="huawei-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="huawei-wmi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="lg-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="lg-laptop" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="msi-ec" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="msi-ec" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="samsung-galaxybook" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="samsung-galaxybook" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="system76_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="system76_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="thinkpad_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="thinkpad_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" ACTION=="add" KERNEL=="toshiba_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_start_threshold" ACTION=="add" KERNEL=="toshiba_acpi" RUN+="/usr/bin/chmod o+w /sys/class/power_supply/BAT0/charge_control_end_threshold" EOF } # conf_print_rules | sudo tee /etc/udev/rules.d/99-qtile.rules conf_print_rules | sudo tee /usr/lib/rules.d/99-qtile.rules sudo udevadm control --reload-rules # END:Debian files (will be overridden by qtile debian package) # START: ml4w configuration of qtile conf_print_config() { cat </dev/null)" ]; then echo "[ensure_wal.sh] Wallpaper folder empty → copying a default" cp /usr/share/backgrounds/archlinux/simple.png "$WALLPAPER_DIR/default.png" 2>/dev/null || \ cp /usr/share/backgrounds/gnome/adwaita-day.jpg "$WALLPAPER_DIR/default.jpg" 2>/dev/null || \ cp /usr/share/pixmaps/archlinux-logo.png "$WALLPAPER_DIR/default.png" 2>/dev/null || \ cp /var/tmp/ml4w_dotfiles/dotfiles/wallpaper/default.png "$WALLPAPER_DIR/default.png" 2>/dev/null || \ echo "[ensure_wal.sh] No system wallpaper found — using solid color fallback" fi # 4. Force pywal to generate colors (quietly) wal -q -i "$WALLPAPER_DIR" >/dev/null 2>&1 echo "[ensure_wal.sh] Pywal initialized → Qtile can start safely" EOF } conf_print_ensure_wal | tee ${QTILE_HOME}/scripts/ensure_wal.sh chmod +x ${QTILE_HOME}/scripts/ensure_wal.sh # autostart conf_print_autostart() { cat <<-'EOF' #!/bin/bash # by Stephan Raabe (2023) # ----------------------------------------------------- # === ENSURE PYWAL IS INITIALIZED (critical!) === $HOME/.config/qtile/scripts/ensure_wal.sh # My screen resolution # xrandr --rate 120 # For Virtual Machine # xrandr --output Virtual-1 --mode 1920x1080 # Keyboard layout setxkbmap gb # Load picom # picom & # Load power manager xfce4-power-manager & # Load notification service dunst & # Setup Wallpaper and update colors $HOME/.config/qtile/scripts/wallpaper.sh init EOF } conf_print_autostart | tee ${QTILE_HOME}/autostart.sh # qtile scripts conf_print_diagnosis() { cat <<-'EOF' #!/bin/bash clear sleep 0.5 figlet "Diagnosis" echo echo "This script will check that essential packages and " echo "execution commands are available on your system." echo _commandExists() { package="$1"; if ! type $package > /dev/null 2>&1; then echo ":: ERROR: $package doesn't exists. Please install it with yay -S $2" else echo ":: OK: $package found." fi } _folderExists() { folder="$1"; if [ ! -d $folder ]; then echo ":: ERROR: $folder doesn't exists." else echo ":: OK: $folder found." fi } _commandExists "rofi" "rofi-wayland" _commandExists "dunst" "dunst" _commandExists "wal" "python-pywal" _commandExists "gum" "gum" _commandExists "magick" "imagemagick" _commandExists "figlet" "figlet" echo echo "Press return to exit" read EOF } conf_print_diagnosis | tee ${QTILE_HOME}/scripts/diagnosis.sh conf_print_loadbar() { cat <<-'EOF' # Loadbar # by Stephan Raabe (2023) # ----------------------------------------------------- """ echo "Loading Qtile status bar..." EOF } conf_print_loadbar | tee ${QTILE_HOME}/scripts/loadbar.sh conf_print_powermenu() { cat <<-'EOF' #!/bin/bash # Powermenu # by Stephan Raabe (2023) # ----------------------------------------------------- echo $XDG_SESSION_TYPE lockapp=slock echo "Using $lockapp to lock the screen." option1=" lock" option2=" logout" option3=" reboot" option4=" power off" options="$option1\n" options="$options$option2\n" options="$options$option3\n$option4" choice=$(echo -e "$options" | rofi -dmenu -replace -config ~/.config/rofi/config-power.rasi -i -no-show-icons -l 4 -width 30 -p "Powermenu") case $choice in $option1) $lockapp ;; $option2) qtile cmd-obj -o cmd -f shutdown ;; $option3) systemctl reboot ;; $option4) systemctl poweroff ;; esac EOF } conf_print_powermenu | tee ${QTILE_HOME}/scripts/powermenu.sh conf_print_screenshot() { cat <<-'EOF' #!/bin/bash # Screenshot # by Stephan Raabe (2023) # ----------------------------------------------------- DIR="$HOME/Pictures/screenshots/" NAME="screenshot_$(date +%d%m%Y_%H%M%S).png" option1="Selected window (delay 3 sec)" option2="Selected area" option3="Fullscreen (delay 3 sec)" options="$option2\n$option3\n$option1" choice=$(echo -e "$options" | rofi -i -dmenu -replace -config ~/.config/rofi/config-screenshot.rasi -width 30 -l 3 -p "Take Screenshot") case $choice in $option1) scrot $DIR$NAME -d 3 -e 'xclip -selection clipboard -t image/png -i $f' -c -z -u notify-send "Screenshot created" "Mode: Selected window" ;; $option2) scrot $DIR$NAME -s -e 'xclip -selection clipboard -t image/png -i $f' notify-send "Screenshot created" "Mode: Selected area" ;; $option3) scrot $DIR$NAME -d 3 -e 'xclip -selection clipboard -t image/png -i $f' notify-send "Screenshot created" "Mode: Fullscreen" ;; esac EOF } conf_print_screenshot | tee ${QTILE_HOME}/scripts/screenshot.sh conf_print_wallpaper() { cat < "\$cache_file" fi # Create rasi file if not exists if [ ! -f \$rasi_file ] ;then touch \$rasi_file echo "* { current-image: url(\"\$wallpaper_folder/default.jpg\", height); }" > "\$rasi_file" fi current_wallpaper=\$(cat "\$cache_file") case $1 in # Load wallpaper from .cache of last session "init") if [ -f \$cache_file ]; then wal -q -i \$current_wallpaper else wal -q -i \$wallpaper_folder fi ;; # Select wallpaper with rofi "select") selected=\$(find "\$wallpaper_folder" -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" \) -exec basename {} \; | sort -R | while read rfile; do echo -en "\$rfile\x00icon\x1f\$wallpaper_folder/\${rfile}\n" done | rofi -dmenu -replace -l 6 -config ~/.config/rofi/config-wallpaper.rasi) if [ ! "\$selected" ]; then echo "No wallpaper selected" exit fi wal -q -i \$wallpaper_folder/\$selected ;; # Randomly select wallpaper *) wal -q -i \$wallpaper_folder/ ;; esac # ----------------------------------------------------- # Reload qtile to color bar # ----------------------------------------------------- qtile cmd-obj -o cmd -f reload_config # ----------------------------------------------------- # Get new theme # ----------------------------------------------------- source "\$HOME/.cache/wal/colors.sh" echo "Wallpaper: \$wallpaper" newwall=\$(echo \$wallpaper | sed "s|\$HOME/wallpaper/||g") # ----------------------------------------------------- # Created blurred wallpaper # ----------------------------------------------------- magick \$wallpaper -resize 50% \$blurred echo ":: Resized to 50%" magick \$blurred -blur 50x30 \$blurred echo ":: Blurred" # ----------------------------------------------------- # Write selected wallpaper into .cache files # ----------------------------------------------------- echo "\$wallpaper" > "\$cache_file" echo "* { current-image: url(\"\$blurred\", height); }" > "\$rasi_file" sleep 1 # ----------------------------------------------------- # Send notification # ----------------------------------------------------- notify-send "Colors and Wallpaper updated" "with image \$newwall" echo "Done." EOF } conf_print_wallpaper | tee ${QTILE_HOME}/scripts/wallpaper.sh chmod +x ${QTILE_HOME}/scripts/wallpaper.sh conf_print_browser() { cat <<-'EOF' EOF } conf_print_wallpaper | tee ${QTILE_SCRIPTS}/browser.sh chmod +x ${QTILE_SCRIPTS}/browser.sh # END: ml4w_dotfiles # START: extensions # If you're using a tiling window manager, you probably want to do something like this: # $ wezterm connect wuake --class org.wezfurlong.wezterm.wuake # # Now you can add org.wezfurlong.wezterm.wuake to your floating window exceptions and # still use a normal tiled window when you open wezterm normally. # END: extensions # START: supporting app dotfiles # dmenu-ish notification-daemon conf_print_dunstrc() { cat <<-'EOF' # See dunst(5) for all configuration options [global] ### Display ### # Which monitor should the notifications be displayed on. monitor = 0 # Display notification on focused monitor. Possible modes are: # mouse: follow mouse pointer # keyboard: follow window with keyboard focus # none: don't follow anything # # "keyboard" needs a window manager that exports the # _NET_ACTIVE_WINDOW property. # This should be the case for almost all modern window managers. # # If this option is set to mouse or keyboard, the monitor option # will be ignored. follow = mouse ### Geometry ### # dynamic width from 0 to 300 # width = (0, 300) # constant width of 300 width = (0, 400) # The maximum height of a single notification, excluding the frame. height = (0, 200) # Position the notification in the top right corner origin = top-right # Offset from the origin offset = (15, 65) # Scale factor. It is auto-detected if value is 0. scale = 0 # Maximum number of notification (0 means no limit) notification_limit = 0 ### Progress bar ### # Turn on the progess bar. It appears when a progress hint is passed with # for example dunstify -h int:value:12 progress_bar = true # Set the progress bar height. This includes the frame, so make sure # it's at least twice as big as the frame width. progress_bar_height = 10 # Set the frame width of the progress bar progress_bar_frame_width = 0 # Set the minimum width for the progress bar progress_bar_min_width = 350 # Set the maximum width for the progress bar progress_bar_max_width = 400 # Show how many messages are currently hidden (because of # notification_limit). indicate_hidden = yes # The transparency of the window. Range: [0; 100]. # This option will only work if a compositing window manager is # present (e.g. xcompmgr, compiz, etc.). (X11 only) transparency = 0 # Draw a line of "separator_height" pixel height between two # notifications. # Set to 0 to disable. # If gapsize is greater than 0, this setting will be ignored. separator_height = 2 # Padding between text and separator. padding = 12 # Horizontal padding. horizontal_padding = 15 # Padding between text and icon. text_icon_padding = 0 # Defines width in pixels of frame around the notification window. # Set to 0 to disable. frame_width = 2 # Defines color of the frame around the notification window. frame_color = "#1bd5ab" # Size of gap to display between notifications - requires a compositor. # If value is greater than 0, separator_height will be ignored and a border # of size frame_width will be drawn around each notification instead. # Click events on gaps do not currently propagate to applications below. # WARNING: doesn't exist? gap_size = 5 # Define a color for the separator. # possible values are: # * auto: dunst tries to find a color fitting to the background; # * foreground: use the same color as the foreground; # * frame: use the same color as the frame; # * anything else will be interpreted as a X color. separator_color = auto # or: "#1bd5ab" # Sort messages by urgency. sort = yes # Don't remove messages, if the user is idle (no mouse or keyboard input) # for longer than idle_threshold seconds. # Set to 0 to disable. # A client can set the 'transient' hint to bypass this. See the rules # section for how to disable this if necessary # idle_threshold = 120 ### Text ### font = mononoki Nerd Font 16 # The spacing between lines. If the height is smaller than the # font height, it will get raised to the font height. line_height = 0 # Possible values are: # full: Allow a small subset of html markup in notifications: # bold # italic # strikethrough # underline # # For a complete reference see # . # # strip: This setting is provided for compatibility with some broken # clients that send markup even though it's not enabled on the # server. Dunst will try to strip the markup but the parsing is # simplistic so using this option outside of matching rules for # specific applications *IS GREATLY DISCOURAGED*. # # no: Disable markup parsing, incoming notifications will be treated as # plain text. Dunst will not advertise that it has the body-markup # capability if this is set as a global setting. # # It's important to note that markup inside the format option will be parsed # regardless of what this is set to. markup = full # The format of the message. Possible variables are: # %a appname # %s summary # %b body # %i iconname (including its path) # %I iconname (without its path) # %p progress value if set ([ 0%] to [100%]) or nothing # %n progress value if set without any extra characters # %% Literal % # Markup is allowed # format = "%s\n%b" # (default) format = "%s\n%b" # Alignment of message text. # Possible values are "left", "center" and "right". alignment = center # Vertical alignment of message text and icon. # Possible values are "top", "center" and "bottom". vertical_alignment = center # Show age of message if message is older than show_age_threshold # seconds. # Set to -1 to disable. show_age_threshold = 60 # Specify where to make an ellipsis in long lines. # Possible values are "start", "middle" and "end". ellipsize = "end" # Ignore newlines '\n' in notifications. ignore_newline = no # Stack together notifications with the same content stack_duplicates = true # Hide the count of stacked notifications with the same content hide_duplicate_count = false # Display indicators for URLs (U) and actions (A). show_indicators = yes ### Icons ### # Align icons left/right/top/off icon_position = left # Scale small icons up to this size, set to 0 to disable. Helpful # for e.g. small files or high-dpi screens. In case of conflict, # max_icon_size takes precedence over this. min_icon_size = 32 # Scale larger icons down to this size, set to 0 to disable max_icon_size = 64 # Paths to default icons. icon_path = /usr/share/icons/gnome/256x256/status/:/usr/share/icons/gnome/256x256/devices/ icon_theme = "Papirus" enable_recursive_icon_lookup = true # always_run_scripts = true ### History ### # Should a notification popped up from history be sticky or timeout # as if it would normally do. sticky_history = yes # Maximum amount of notifications kept in history history_length = 20 ### Misc/Advanced ### # dmenu path. dmenu = wofi --show dmenu -p dunst: # Browser for opening urls in context menu. browser = /usr/bin/xdg-open # Always run rule-defined scripts, even if the notification is suppressed always_run_script = true # Define the title of the windows spawned by dunst title = Dunst # Define the class of the windows spawned by dunst class = Dunst # Define the corner of the notification window # in pixel size. If the radius is 0, you have no rounded # corners. # The radius will be automatically lowered if it exceeds half of the # notification height to avoid clipping text and/or icons. corner_radius = 10 # Ignore the dbus closeNotification message. # Useful to enforce the timeout set by dunst configuration. Without this # parameter, an application may close the notification sent before the # user defined timeout. ignore_dbusclose = false ### Wayland ### # These settings are Wayland-specific. They have no effect when using X11 # Uncomment this if you want to let notications appear under fullscreen # applications (default: overlay) layer = top # Set this to true to use X11 output on Wayland. force_xwayland = false ### Legacy # Use the Xinerama extension instead of RandR for multi-monitor support. # This setting is provided for compatibility with older nVidia drivers that # do not support RandR and using it on systems that support RandR is highly # discouraged. # # By enabling this setting dunst will not be able to detect when a monitor # is connected or disconnected which might break follow mode if the screen # layout changes. force_xinerama = false ### mouse # Defines list of actions for each mouse event # Possible values are: # * none: Don't do anything. # * do_action: Invoke the action determined by the action_name rule. If there is no # such action, open the context menu. # * open_url: If the notification has exactly one url, open it. If there are multiple # ones, open the context menu. # * close_current: Close current notification. # * close_all: Close all notifications. # * context: Open context menu for the notification. # * context_all: Open context menu for all notifications. # These values can be strung together for each mouse event, and # will be executed in sequence. mouse_left_click = close_current mouse_middle_click = context mouse_right_click = do_action # Experimental features that may or may not work correctly. Do not expect them # to have a consistent behaviour across releases. [experimental] # Calculate the dpi to use on a per-monitor basis. # If this setting is enabled the Xft.dpi value will be ignored and instead # dunst will attempt to calculate an appropriate dpi value for each monitor # using the resolution and physical size. This might be useful in setups # where there are multiple screens with very different dpi values. per_monitor_dpi = false [urgency_low] # IMPORTANT: colors have to be defined in quotation marks. # Otherwise the "#" and following would be interpreted as a comment. background = "#111019" # "#0f0f0f" foreground = "#F1F0F5" # "#89b4fa" frame_color = "#0B0A10" # "#89b4fa" timeout = 3 highlight = "#AAC5A0" # script = ~/.scripts/dunst/sound-normal.sh # Icon for notifications with low urgency, uncomment to enable #default_icon = /path/to/icon [urgency_normal] background = "#111019" # "#0f0f0f" foreground = "#F1F0F5" # "#a6e3a1" frame_color = "#0B0A10" # "#a6e3a1" timeout = 5 highlight = "#A8C5E6" # script = ~/.scripts/dunst/sound-normal.sh # Icon for notifications with normal urgency, uncomment to enable # default_icon = /path/to/icon [urgency_critical] background = "#111019" # "#0f0f0f" foreground = "#E97193" # "#f38ba8" frame_color = "#0B0A10" # "#f38ba8" timeout = 10 highlight = "#E97193" # script = ~/.scripts/dunst/sound-critical.sh # Icon for notifications with critical urgency, uncomment to enable #default_icon = /path/to/icon # Every section that isn't one of the above is interpreted as a rules to # override settings for certain messages. # # Messages can be matched by # appname (discouraged, see desktop_entry) # body # category # desktop_entry # icon # match_transient # msg_urgency # stack_tag # summary # # and you can override the # background # foreground # format # frame_color # fullscreen # new_icon # set_stack_tag # set_transient # set_category # timeout # urgency # icon_position # skip_display # history_ignore # action_name # word_wrap # ellipsize # alignment # hide_text # # Shell-like globbing will get expanded. # # Instead of the appname filter, it's recommended to use the desktop_entry filter. # GLib based applications export their desktop-entry name. In comparison to the appname, # the desktop-entry won't get localized. # # SCRIPTING # You can specify a script that gets run when the rule matches by # setting the "script" option. # The script will be called as follows: # script appname summary body icon urgency # where urgency can be "LOW", "NORMAL" or "CRITICAL". # # NOTE: It might be helpful to run dunst -print in a terminal in order # to find fitting options for rules. # Disable the transient hint so that idle_threshold cannot be bypassed from the # client #[transient_disable] # match_transient = yes # set_transient = no # # Make the handling of transient notifications more strict by making them not # be placed in history. #[transient_history_ignore] # match_transient = yes # history_ignore = yes # fullscreen values # show: show the notifications, regardless if there is a fullscreen window opened # delay: displays the new notification, if there is no fullscreen window active # If the notification is already drawn, it won't get undrawn. # pushback: same as delay, but when switching into fullscreen, the notification will get # withdrawn from screen again and will get delayed like a new notification #[fullscreen_delay_everything] # fullscreen = delay #[fullscreen_show_critical] # msg_urgency = critical # fullscreen = show #[espeak] # summary = "*" # script = dunst_espeak.sh #[script-test] # summary = "*script*" # script = dunst_test.sh #[ignore] # # This notification will not be displayed # summary = "foobar" # skip_display = true #[history-ignore] # # This notification will not be saved in history # summary = "foobar" # history_ignore = yes #[skip-display] # # This notification will not be displayed, but will be included in the history # summary = "foobar" # skip_display = yes #[signed_on] # appname = Pidgin # summary = "*signed on*" # urgency = low # #[signed_off] # appname = Pidgin # summary = *signed off* # urgency = low # #[says] # appname = Pidgin # summary = *says* # urgency = critical # #[twitter] # appname = Pidgin # summary = *twitter.com* # urgency = normal # #[stack-volumes] # appname = "some_volume_notifiers" # set_stack_tag = "volume" # # [redirect] # summary = "*" # script = "~/.config/hypr/scripts/default/tools/notif" # [logger] # summary = "*" # script = "~/.config/hypr/scripts/default/tools/notif" # [spotify] # summary = "*" # script = "~/.scripts/music-art" # rounded corners forced ? # [Spotify] # appname = "Spotify" # script = "~/.config/dunst/scripts/round_image.sh" # new_icon = "~/.config/dunst/assets/album_cover.png" # */ EOF } conf_print_config | tee ${DEST}/.config/dunst/dunstrc # END: supporting app dotfiles # START settings files (ml4w) output of /var/tmp/automate/conf_print_gen.sh conf_print_ai() { cat <<'EOF_ai_EOF' $(cat ~/.config/ml4w/settings/browser.sh) --new-window https://chat.openai.com EOF_ai_EOF } conf_print_ai | tee "${QTILE_SETTINGS}/ai.sh" conf_print_aur() { cat <<'EOF_aur_EOF' yay EOF_aur_EOF } conf_print_aur | tee "${QTILE_SETTINGS}/aur.sh" conf_print_bluetooth() { cat <<'EOF_bluetooth_EOF' blueman-manager EOF_bluetooth_EOF } conf_print_bluetooth | tee "${QTILE_SETTINGS}/bluetooth.sh" conf_print_blur() { cat <<'EOF_blur_EOF' 50x30 EOF_blur_EOF } conf_print_blur | tee "${QTILE_SETTINGS}/blur.sh" conf_print_browser() { cat <<'EOF_browser_EOF' firefox EOF_browser_EOF } conf_print_browser | tee "${QTILE_SETTINGS}/browser.sh" conf_print_calculator() { cat <<'EOF_calculator_EOF' gnome-calculator EOF_calculator_EOF } conf_print_calculator | tee "${QTILE_SETTINGS}/calculator.sh" conf_print_dock_border() { cat <<'EOF_dock_border_EOF' window { border-width: 2px; } EOF_dock_border_EOF } conf_print_dock_border | tee "${QTILE_SETTINGS}/dock-border.css" conf_print_dock_theme() { cat <<'EOF_dock_theme_EOF' glass EOF_dock_theme_EOF } conf_print_dock_theme | tee "${QTILE_SETTINGS}/dock-theme" conf_print_dotfiles_folder() { cat <<'EOF_dotfiles_folder_EOF' dotfiles EOF_dotfiles_folder_EOF } conf_print_dotfiles_folder | tee "${QTILE_SETTINGS}/dotfiles-folder.sh" conf_print_editor() { cat <<'EOF_editor_EOF' gnome-text-editor EOF_editor_EOF } conf_print_editor | tee "${QTILE_SETTINGS}/editor.sh" conf_print_email() { cat <<'EOF_email_EOF' evolution EOF_email_EOF } conf_print_email | tee "${QTILE_SETTINGS}/email.sh" conf_print_emojipicker() { cat <<'EOF_emojipicker_EOF' flatpak run com.ml4w.sidebar EOF_emojipicker_EOF } conf_print_emojipicker | tee "${QTILE_SETTINGS}/emojipicker.sh" conf_print_filemanager() { cat <<'EOF_filemanager_EOF' yazi EOF_filemanager_EOF } conf_print_filemanager | tee "${QTILE_SETTINGS}/filemanager" conf_print_filemanager() { cat <<'EOF_filemanager_EOF' # #nautilus --new-window rox EOF_filemanager_EOF } conf_print_filemanager | tee "${QTILE_SETTINGS}/filemanager.sh" conf_print_hyprpaper() { cat <<'EOF_hyprpaper_EOF' # Preload Wallpapers preload = WALLPAPER # Set Wallpapers wallpaper = ,WALLPAPER # Disable Splash splash = false EOF_hyprpaper_EOF } conf_print_hyprpaper | tee "${QTILE_SETTINGS}/hyprpaper.tpl" conf_print_hyprpicker() { cat <<'EOF_hyprpicker_EOF' hyprpicker -a -f hex EOF_hyprpicker_EOF } conf_print_hyprpicker | tee "${QTILE_SETTINGS}/hyprpicker.sh" conf_print_hyprshade() { cat <<'EOF_hyprshade_EOF' hyprshade_filter="blue-light-filter-50" EOF_hyprshade_EOF } conf_print_hyprshade | tee "${QTILE_SETTINGS}/hyprshade.sh" conf_print_installupdates() { cat <<'EOF_installupdates_EOF' $(cat ~/.config/ml4w/settings/terminal.sh) --class dotfiles-floating -e ~/.config/ml4w/scripts/installupdates.sh EOF_installupdates_EOF } conf_print_installupdates | tee "${QTILE_SETTINGS}/installupdates.sh" conf_print_kitty_cursor_trail() { cat <<'EOF_kitty_cursor_trail_EOF' cursor_trail 1 EOF_kitty_cursor_trail_EOF } conf_print_kitty_cursor_trail | tee "${QTILE_SETTINGS}/kitty-cursor-trail.conf" conf_print_launcher() { cat <<'EOF_launcher_EOF' rofi EOF_launcher_EOF } conf_print_launcher | tee "${QTILE_SETTINGS}/launcher" conf_print_networkmanager() { cat <<'EOF_networkmanager_EOF' $(cat ~/.config/ml4w/settings/terminal.sh) --class dotfiles-floating -e nmtui EOF_networkmanager_EOF } conf_print_networkmanager | tee "${QTILE_SETTINGS}/networkmanager.sh" conf_print_printer_drivers() { cat <<'EOF_printer_drivers_EOF' #!/usr/bin/env bash # Installation of Printer Drivers # Please add your drivers to the package list # Example: # yay -S brother-hll2360dw-lpr-bin brother-hll2360dw-cups-bin brother-mfc-l3770cdw brscan-skey brscan4 skanpage EOF_printer_drivers_EOF } conf_print_printer_drivers | tee "${QTILE_SETTINGS}/printer-drivers.sh" conf_print_rofi_border_radius() { cat <<'EOF_rofi_border_radius_EOF' * { border-radius: 2em; } EOF_rofi_border_radius_EOF } conf_print_rofi_border_radius | tee "${QTILE_SETTINGS}/rofi-border-radius.rasi" conf_print_rofi_border() { cat <<'EOF_rofi_border_EOF' * { border-width: 2px; } EOF_rofi_border_EOF } conf_print_rofi_border | tee "${QTILE_SETTINGS}/rofi-border.rasi" conf_print_rofi_font() { cat <<'EOF_rofi_font_EOF' configuration { font: "Fira Sans 11"; } EOF_rofi_font_EOF } conf_print_rofi_font | tee "${QTILE_SETTINGS}/rofi-font.rasi" conf_print_screenshot_editor() { cat <<'EOF_screenshot_editor_EOF' pinta EOF_screenshot_editor_EOF } conf_print_screenshot_editor | tee "${QTILE_SETTINGS}/screenshot-editor" conf_print_screenshot_filename() { cat <<'EOF_screenshot_filename_EOF' screenshot_$(date +%Y%m%d_%H%M%S).jpg EOF_screenshot_filename_EOF } conf_print_screenshot_filename | tee "${QTILE_SETTINGS}/screenshot-filename" conf_print_screenshot_folder() { cat <<'EOF_screenshot_folder_EOF' ~/Pictures EOF_screenshot_folder_EOF } conf_print_screenshot_folder | tee "${QTILE_SETTINGS}/screenshot-folder" conf_print_sidepad_active() { cat <<'EOF_sidepad_active_EOF' ml4w-kitty EOF_sidepad_active_EOF } conf_print_sidepad_active | tee "${QTILE_SETTINGS}/sidepad-active" conf_print_systemmonitor() { cat <<'EOF_systemmonitor_EOF' btop EOF_systemmonitor_EOF } conf_print_systemmonitor | tee "${QTILE_SETTINGS}/systemmonitor" conf_print_system_monitor() { cat <<'EOF_system_monitor_EOF' $(cat ~/.config/ml4w/settings/terminal.sh) --class dotfiles-floating -e btop EOF_system_monitor_EOF } conf_print_system_monitor | tee "${QTILE_SETTINGS}/system-monitor.sh" conf_print_terminal() { cat <<'EOF_terminal_EOF' kitty EOF_terminal_EOF } conf_print_terminal | tee "${QTILE_SETTINGS}/terminal.sh" conf_print_walker_theme() { cat <<'EOF_walker_theme_EOF' modern EOF_walker_theme_EOF } conf_print_walker_theme | tee "${QTILE_SETTINGS}/walker-theme" conf_print_wallpaper_automation() { cat <<'EOF_wallpaper_automation_EOF' 60 EOF_wallpaper_automation_EOF } conf_print_wallpaper_automation | tee "${QTILE_SETTINGS}/wallpaper-automation.sh" conf_print_wallpaper_effect() { cat <<'EOF_wallpaper_effect_EOF' off EOF_wallpaper_effect_EOF } conf_print_wallpaper_effect | tee "${QTILE_SETTINGS}/wallpaper-effect.sh" conf_print_wallpaper_engine() { cat <<'EOF_wallpaper_engine_EOF' hyprpaper EOF_wallpaper_engine_EOF } conf_print_wallpaper_engine | tee "${QTILE_SETTINGS}/wallpaper-engine.sh" conf_print_wallpaper_folder() { cat <<'EOF_wallpaper_folder_EOF' $HOME/wallpaper EOF_wallpaper_folder_EOF } conf_print_wallpaper_folder | tee "${QTILE_SETTINGS}/wallpaper-folder" conf_print_waybar_appmenu() { cat <<'EOF_waybar_appmenu_EOF' True EOF_waybar_appmenu_EOF } conf_print_waybar_appmenu | tee "${QTILE_SETTINGS}/waybar_appmenu.sh" conf_print_waybar_backlight() { cat <<'EOF_waybar_backlight_EOF' False EOF_waybar_backlight_EOF } conf_print_waybar_backlight | tee "${QTILE_SETTINGS}/waybar_backlight.sh" conf_print_waybar_chatgpt() { cat <<'EOF_waybar_chatgpt_EOF' True EOF_waybar_chatgpt_EOF } conf_print_waybar_chatgpt | tee "${QTILE_SETTINGS}/waybar_chatgpt.sh" conf_print_waybar_dateformat() { cat <<'EOF_waybar_dateformat_EOF' %a EOF_waybar_dateformat_EOF } conf_print_waybar_dateformat | tee "${QTILE_SETTINGS}/waybar_dateformat.sh" conf_print_waybar_network() { cat <<'EOF_waybar_network_EOF' True EOF_waybar_network_EOF } conf_print_waybar_network | tee "${QTILE_SETTINGS}/waybar_network.sh" conf_print_waybar_quicklinks() { cat <<'EOF_waybar_quicklinks_EOF' /* Define your quick links for the statusbar here. YOu can use icons from here https://fontawesome.com/search?ic=free You can reload waybar with SUPER + SHIFT + B */ { "custom/quicklink_browser": { "format": "", "on-click": "~/.config/ml4w/settings/browser.sh", "tooltip-format": "Open Browser" }, "custom/quicklink_filemanager": { "format": "", "on-click": "~/.config/ml4w/settings/filemanager.sh", "tooltip-format": "Open Filemanager" }, "custom/quicklink_email": { "format": "", "on-click": "~/.config/ml4w/settings/email.sh", "tooltip-format": "Open Email Client" }, "custom/quicklink_chromium": { "format": "", "on-click": "chromium", "tooltip-format": "Open Chromium" }, "custom/quicklink_edge": { "format": "", "on-click": "edge", "tooltip-format": "Open Edge" }, "custom/quicklink_firefox": { "format": "", "on-click": "firefox", "tooltip-format": "Open Firefox" }, "custom/quicklink_thunderbird": { "format": "", "on-click": "thunderbird", "tooltip-format": "Open Thunderbird" }, "custom/quicklink_calculator": { "format": "", "on-click": "~/.config/ml4w/settings/calculator.sh", "tooltip-format": "Open calculator" }, /* Don't remove the quicklinkempty */ "custom/quicklinkempty": { }, /* Add your quicklinks in your desired order to the status bar */ "group/quicklinks": { "orientation": "horizontal", "modules": [ "custom/quicklink_browser", "custom/quicklink_email", "custom/quicklink_filemanager", /* Don't remove the quicklinkempty */ "custom/quicklinkempty" ] } } EOF_waybar_quicklinks_EOF } conf_print_waybar_quicklinks | tee "${QTILE_SETTINGS}/waybar-quicklinks.json" conf_print_waybar_quicklinks() { cat <<'EOF_waybar_quicklinks_EOF' False EOF_waybar_quicklinks_EOF } conf_print_waybar_quicklinks | tee "${QTILE_SETTINGS}/waybar_quicklinks.sh" conf_print_waybar_screenlock() { cat <<'EOF_waybar_screenlock_EOF' True EOF_waybar_screenlock_EOF } conf_print_waybar_screenlock | tee "${QTILE_SETTINGS}/waybar_screenlock.sh" conf_print_waybar_settings() { cat <<'EOF_waybar_settings_EOF' True EOF_waybar_settings_EOF } conf_print_waybar_settings | tee "${QTILE_SETTINGS}/waybar_settings.sh" conf_print_waybar_systray() { cat <<'EOF_waybar_systray_EOF' True EOF_waybar_systray_EOF } conf_print_waybar_systray | tee "${QTILE_SETTINGS}/waybar_systray.sh" conf_print_waybar_taskbar() { cat <<'EOF_waybar_taskbar_EOF' False EOF_waybar_taskbar_EOF } conf_print_waybar_taskbar | tee "${QTILE_SETTINGS}/waybar_taskbar.sh" conf_print_waybar_theme() { cat <<'EOF_waybar_theme_EOF' /ml4w-glass;/ml4w-glass/default EOF_waybar_theme_EOF } conf_print_waybar_theme | tee "${QTILE_SETTINGS}/waybar-theme.sh" conf_print_waybar_timeformat() { cat <<'EOF_waybar_timeformat_EOF' %H:%M EOF_waybar_timeformat_EOF } conf_print_waybar_timeformat | tee "${QTILE_SETTINGS}/waybar_timeformat.sh" conf_print_waybar_toggle() { cat <<'EOF_waybar_toggle_EOF' True EOF_waybar_toggle_EOF } conf_print_waybar_toggle | tee "${QTILE_SETTINGS}/waybar_toggle.sh" conf_print_waybar_window() { cat <<'EOF_waybar_window_EOF' True EOF_waybar_window_EOF } conf_print_waybar_window | tee "${QTILE_SETTINGS}/waybar_window.sh" conf_print_wlogout_parameters() { cat <<'EOF_wlogout_parameters_EOF' -b 3 EOF_wlogout_parameters_EOF } conf_print_wlogout_parameters | tee "${QTILE_SETTINGS}/wlogout-parameters.sh"