diff options
| author | Donald Williams <129223418+dwilliam62@users.noreply.github.com> | 2025-10-13 20:31:53 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-13 20:31:53 -0400 |
| commit | e4be12e23fa8d6f8a73dde974ea6adf242885bc1 (patch) | |
| tree | b879abcf54989120a0931443bfb8203c885c2b20 | |
| parent | 0e52d19b894e3cfd2c87cfbcc35ae087d48f5485 (diff) | |
| parent | 9d26c191c1071a542e816d1bc2b0b3f96ebfa74d (diff) | |
Merge pull request #841 from JaKooLit/ddubs-hyprsunset
Merge ddubs-hyprsunset into main fixes for wallust, sddm and weather
42 files changed, 868 insertions, 1113 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..d20a9670 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +WARP.md +.warp.md +result diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..cd0effc4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,42 @@ +# Changelog — JAK's Hyprland Dotfiles + +## October 2025 + +### 🐛 Fixes + +- Correct `windowrule` syntax error. +- Ensure wallpaper selector applies wallpaper to SDDM. +- Update theme colors when a new wallpaper is selected. + +### 🌦️ Weather.py + +- ♻️ Substantial rewrite. +- ✅ Launches properly in Waybar. +- 📍 Improved location detection; overridable variables exposed. +- 🌐 Switched to Open-Meteo for weather data with fallback providers. + +### 🖥️ Support for debian and ubuntu installs + +- Providing they are using Hyprland 0.51.1 or greater + +### 🖥️ Drop-down terminal + +- 🔧 Start on login via `TerminalDropDown.sh` so first invocation works. +- 🐱 Use Kitty explicitly instead of `$TERM` for consistent behavior. + +### 🌇 HyprSunset + +- 🔧 Availble from waybar or`SUPER + N` + +### 🖱️ Gestures + +- 🔧 Updated to accommodate Hyprland 0.5x changes. + +### 👥 Contributors + +- [CharlyMH](https://github.com/CharlyMH) +- [ndeekshith](https://github.com/ndeekshith) +- [SherLock707](https://github.com/SherLock707) +- [SVIGHNESH](https://github.com/SVIGHNESH) + +If you have any questions, feel free to contact via [GitHub Discussions](https://github.com/JaKooLit/Hyprland-Dots/discussions) or [Through Discord Server](https://discord.gg/kool-tech-world) @@ -42,14 +42,18 @@ https://github.com/user-attachments/assets/49bc12b2-abaf-45de-a21c-67aacd9bb872 </div> ### 📹 A video walkthroughs + - at the bottom </details> --- + [](https://git.io/typing-svg) + ### 🚩 🏁 Auto Distro-Hyprland install scripts cloning and starting 🇵🇭 -> [!CAUTION] + +> [!CAUTION] > If you are using FISH SHELL, DO NOT use this function. Clone the Distro-Hyprland and ran install.sh instead - NOTE: you need package `curl` for this to work @@ -61,8 +65,8 @@ sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distr - you can now use above command to automatically clone the Distro-Hyprland install scripts below - it will clone the install scripts and start the `install.sh` 😎 - ### 👁️🗨️ My Hyprland install Scripts 👁️🗨️ + - Automated Hyprland Scripts for Distro of choice which will pull this dotfiles if opted to install these configurations - [Arch-Linux](https://github.com/JaKooLit/Arch-Hyprland) @@ -77,117 +81,136 @@ sh <(curl -L https://raw.githubusercontent.com/JaKooLit/Hyprland-Dots/main/Distr - [Ubuntu 24.04 LTS](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.04) - [Ubuntu 24.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/24.10) -- [Ubuntu 25.04 - (ALPHA STAGE)](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) +- [Ubuntu 25.04](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.04) +- [Ubuntu 25.10](https://github.com/JaKooLit/Ubuntu-Hyprland/tree/25.10) + --- ### 🪧 Attention 🪧 + - This repo does NOT contain or will NOT install any packages. These are only pre-configured-hyprland configs or dotfiles - refer to install scripts what packages needed to install... but atleast, Hyprland packages is needed 😏😏😏 duh!! - This repo will be pulled by the Distro-Hyprland install scripts above if you opt to download pre-configured dots ### 👀 Screenshots 👀 + - All screenshots are collected here [Screenshots](https://github.com/JaKooLit/screenshots/tree/main/Hyprland-ScreenShots) ### 📦 Whats new? -- To easily track changes, I will be updating the [CHANGELOGS](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) Screenshots will be included if worth mentioning the changes! + +- To easily track changes, I will be updating the [CHANGELOGS](https://github.com/JaKooLit/Hyprland-Dots/wiki/Changelogs) Screenshots will be included if worth mentioning the changes! > [!NOTE] -> Kindly note that by defeault, Kools Dots are adjusted / configured for 2k (1440p) display without scaling. +> Kindly note that by defeault, Kools Dots are adjusted / configured for 2k (1440p) display without scaling. ### 💥 Copying / Installation / Update instructions 💥 -- [`MORE INFO HERE`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) -> [!Note] -> The auto copy script "copy.sh" will create backups of intended directories to be copied. However, still a good idea to manually backup just incase script failed to backup! + +- [`MORE INFO HERE`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) + > [!Note] + > The auto copy script "copy.sh" will create backups of intended directories to be copied. However, still a good idea to manually backup just incase script failed to backup! - clone this repo by using git. Change directory, make executable and run the script > to download from Master branch + ```bash git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git cd Hyprland-Dots ``` > to download from Development branch (development and testing) + ```bash git clone --depth=1 https://github.com/JaKooLit/Hyprland-Dots.git -b development cd Hyprland-Dots ``` - automatic copy/install of pre-configured dots (recommended for updating) + ```bash chmod +x copy.sh ./copy.sh ``` - to copy/install from releases (stable) (note this is 1 version older than in main) + ```bash chmod +x release.sh ./release.sh ``` - UPGRADE.sh function -> [!IMPORTANT] -> You need rsync for it to work -> you should have already up and running KooL's Hyprland before using this function + > [!IMPORTANT] + > You need rsync for it to work + > you should have already up and running KooL's Hyprland before using this function + ```bash chmod +x upgrade.sh ./upgrade.sh ``` -## ❗❗❗ DEBIAN AND UBUNTU HEADS UP! -- I am getting ridiculously amount of messages for updating your KooL Hyprland dotfiles. I have made a BIG note on [`WIKI`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Install_&_Update) +## ❗❗❗ DEBIAN AND UBUNTU! +- Debian 13 and ubuntu 25.10 +- You can now build Hyprland 0.51.1 from source using the `install.sh` script +- So the current version of Hyprland-Dots is compatible only in those cases. #### ⚠️⚠️⚠️ ATTENTION - BACKUPS CREATED by SCRIPT + > [!CAUTION] > copy.sh, release.sh and even upgrade.sh creates a backup! > Kindly investigate manually contents on your $HOME/.config > Delete manually all the backups which you dont need #### 🛎️ a small note on wallpapers + - by default, only few wallpapers will be copied (1 each dark and light plus 3 more). You will be offered to download more wallpapers. You can preview/check the additional wallpapers from [`THIS`](https://github.com/JaKooLit/Wallpaper-Bank/tree/main/wallpapers) Link +#### ⚠️⚠️⚠️ A MUST! after copying / Installing these dots -#### ⚠️⚠️⚠️ A MUST! after copying / Installing these dots -+ Press SUPER W and set a wallpaper. This is also to initiate wallust for waybar, kitty (tty) and rofi themes. However, If you use the copy.sh or the release.sh, there will be a preset initial Wallpaper and you dont have to do this +- Press SUPER W and set a wallpaper. This is also to initiate wallust for waybar, kitty (tty) and rofi themes. However, If you use the copy.sh or the release.sh, there will be a preset initial Wallpaper and you dont have to do this -+ Nvidia Owners. Make sure to edit your `~/.config/hypr/UserConfigs/ENVariables.conf` (highly recommended). -- NVIDIA users / owners, after installation, check [`THIS`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) +- Nvidia Owners. Make sure to edit your `~/.config/hypr/UserConfigs/ENVariables.conf` (highly recommended). -+ If you have already set your own keybinds, monitors, etc.... Just copy over from backup created before log-out or reboot. (recommended) +* NVIDIA users / owners, after installation, check [`THIS`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Notes_to_remember#--for-nvidia-gpu-users) +- If you have already set your own keybinds, monitors, etc.... Just copy over from backup created before log-out or reboot. (recommended) #### 📖 Known issues and possible solutions -- check out this page [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) and [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) +- check out this page [FAQ](https://github.com/JaKooLit/Hyprland-Dots/wiki/FAQ) and [UNSOLVED ISSUES](https://github.com/JaKooLit/Hyprland-Dots/wiki/Known_Issues) #### 🙋 QUESTIONS ?!?! ⁉️ + - FAQ! Yes you can use these dotfiles to other distro! Just ensure to install proper packages first! If it makes you feel better, I use same config on my Gentoo:) - QUICK HINT! Click the HINT! Waybar module (note only available in Waybar default and Simple-L [TOP] layout). Can be launched by Keybind `SUPER H` - More question? click here browse through this [WIKI](https://github.com/JaKooLit/Hyprland-Dots/wiki/) - If you want the old configs, it is collected on my "Archive" repo. See [HERE](https://github.com/JaKooLit/Hyprland-Dots-releases-Archive) #### ⌨ Keybinds + - Keybinds [`CLICK`](https://github.com/JaKooLit/Hyprland-Dots/wiki/Keybinds) #### 🙏 Special request -- If you have improvements on the dotfiles or configuration, feel free to submit a PR for improvement. I always welcome improvements as I am also just learning just like you guys! +- If you have improvements on the dotfiles or configuration, feel free to submit a PR for improvement. I always welcome improvements as I am also just learning just like you guys! #### ✍️ Contributing -- Want to contribute? Click [`HERE`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) for a guide how to contribute +- Want to contribute? Click [`HERE`](https://github.com/JaKooLit/Hyprland-Dots/blob/main/CONTRIBUTING.md) for a guide how to contribute #### 🤷♂️ TO DO! -- [ ] Tweak dots - 🚧 in constant progress + +- [ ] Tweak dots - 🚧 in constant progress #### 🔮 Discord Server -- kindly join my [Discord](https://discord.com/invite/kool-tech-world) +- kindly join my [Discord](https://discord.com/invite/kool-tech-world) #### 💖 Support + - a Star on my Github repos would be nice 🌟 -- Subscribe to my Youtube Channel [YouTube](https://www.youtube.com/@Ja.KooLit) +- Subscribe to my Youtube Channel [YouTube](https://www.youtube.com/@Ja.KooLit) - you can also give support through coffee's or btc 😊 @@ -197,12 +220,12 @@ or [](https://www.buymeacoffee.com/JaKooLit) -Or you can donate cryto on my btc wallet :) +Or you can donate cryto on my btc wallet :) + > 1N3MeV2dsX6gQB42HXU6MF2hAix1mqjo8i  +## 🫰 Thank you for the stars 🩷 - -## 🫰 Thank you for the stars 🩷 [](https://starchart.cc/JaKooLit/Hyprland-Dots) diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf index f8af55e4..7b668b77 100644 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ b/config/hypr/UserConfigs/Startup_Apps.conf @@ -20,6 +20,10 @@ exec-once = swww-daemon --format xrgb exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP +# Initialize Drop Down terminal - See Bug#810 https://github.com/JaKooLit/Hyprland-Dots/issues/810#issuecomment-3351947644 +exec-once = $HOME/.config/hypr/scripts/Dropterminal.sh kitty & + + # Polkit (Polkit Gnome / KDE) exec-once = $scriptsDir/Polkit.sh diff --git a/config/hypr/UserConfigs/UserKeybinds.conf b/config/hypr/UserConfigs/UserKeybinds.conf index 2f0e808f..4d35a9c9 100644 --- a/config/hypr/UserConfigs/UserKeybinds.conf +++ b/config/hypr/UserConfigs/UserKeybinds.conf @@ -29,6 +29,7 @@ bind = $mainMod, H, exec, $scriptsDir/KeyHints.sh # help / cheat sheet bind = $mainMod ALT, R, exec, $scriptsDir/Refresh.sh # Refresh waybar, swaync, rofi bind = $mainMod ALT, E, exec, $scriptsDir/RofiEmoji.sh # emoji menu bind = $mainMod, S, exec, $scriptsDir/RofiSearch.sh # Google search using rofi +bind = $mainMod SHIFT, S, exec, rofi -show windows # list/switch apps using rofi bind = $mainMod ALT, O, exec, $scriptsDir/ChangeBlur.sh # Toggle blur settings bind = $mainMod SHIFT, G, exec, $scriptsDir/GameMode.sh # Toggle animations ON/OFF bind = $mainMod ALT, L, exec, $scriptsDir/ChangeLayout.sh # Toggle Master or Dwindle Layout @@ -55,6 +56,9 @@ bind = $mainMod CTRL ALT, B, exec, pkill -SIGUSR1 waybar # Toggle hide/show wayb bind = $mainMod CTRL, B, exec, $scriptsDir/WaybarStyles.sh # Waybar Styles Menu bind = $mainMod ALT, B, exec, $scriptsDir/WaybarLayout.sh # Waybar Layout Menu +# Night light toggle (Hyprsunset) +bind = $mainMod, N, exec, $scriptsDir/Hyprsunset.sh toggle + # FEATURES / EXTRAS (UserScripts) bind = $mainMod SHIFT, M, exec, $UserScripts/RofiBeats.sh # online music using rofi bind = $mainMod, W, exec, $UserScripts/WallpaperSelect.sh # Select wallpaper to apply @@ -74,6 +78,7 @@ bind = $mainMod CTRL, F10, movecurrentworkspacetomonitor, r #move current worksp bind = $mainMod CTRL, F11, movecurrentworkspacetomonitor, u #move current workspace to UP monitor bind = $mainMod CTRL, F12, movecurrentworkspacetomonitor, d #move current workspace to DOWN monitor + # For passthrough keyboard into a VM # bind = $mainMod ALT, P, submap, passthru #submap = passthru diff --git a/config/hypr/UserConfigs/UserSettings.conf b/config/hypr/UserConfigs/UserSettings.conf index 325d24f7..f81ccc6a 100644 --- a/config/hypr/UserConfigs/UserSettings.conf +++ b/config/hypr/UserConfigs/UserSettings.conf @@ -63,6 +63,7 @@ input { } } + gestures { gesture = 3, horizontal, workspace workspace_swipe_distance = 500 diff --git a/config/hypr/UserConfigs/WindowRules.conf b/config/hypr/UserConfigs/WindowRules.conf index 16dc48a5..d6959dc4 100644 --- a/config/hypr/UserConfigs/WindowRules.conf +++ b/config/hypr/UserConfigs/WindowRules.conf @@ -180,6 +180,7 @@ windowrule = opacity 0.8 0.7, class:^(gedit|org.gnome.TextEditor|mousepad)$ windowrule = opacity 0.9 0.8, class:^(deluge)$ windowrule = opacity 0.9 0.8, class:^(seahorse)$ # gnome-keyring gui windowrule = opacity 0.95 0.75, title:^(Picture-in-Picture)$ +windowrule = opacity 0.9,class:^(code)$ # SIZE windowrule = size 65% 90%, tag:KooL_Cheat* diff --git a/config/hypr/UserScripts/WallpaperEffects.sh b/config/hypr/UserScripts/WallpaperEffects.sh index 2ba58d0c..ac8fc0e8 100755 --- a/config/hypr/UserScripts/WallpaperEffects.sh +++ b/config/hypr/UserScripts/WallpaperEffects.sh @@ -108,31 +108,41 @@ main sleep 1 if [[ -n "$choice" ]]; then - sddm_simple="/usr/share/sddm/themes/simple_sddm_2" - if [ -d "$sddm_simple" ]; then - - # Check if yad is running to avoid multiple yad notification - if pidof yad > /dev/null; then - killall yad - fi - - if yad --info --text="Set current wallpaper as SDDM background?\n\nNOTE: This only applies to SIMPLE SDDM v2 Theme" \ - --text-align=left \ - --title="SDDM Background" \ - --timeout=5 \ - --timeout-indicator=right \ - --button="yad-yes:0" \ - --button="yad-no:1" \ - ; then + # Resolve SDDM themes directory (standard and NixOS path) + sddm_themes_dir="" + if [ -d "/usr/share/sddm/themes" ]; then + sddm_themes_dir="/usr/share/sddm/themes" + elif [ -d "/run/current-system/sw/share/sddm/themes" ]; then + sddm_themes_dir="/run/current-system/sw/share/sddm/themes" + fi - # Check if terminal exists - if ! command -v "$terminal" &>/dev/null; then - notify-send -i "$iDIR/ja.png" "Missing $terminal" "Install $terminal to enable setting of wallpaper background" - exit 1 - fi + if [ -n "$sddm_themes_dir" ]; then + sddm_simple="$sddm_themes_dir/simple_sddm_2" + + # Only prompt if theme exists and its Backgrounds directory is writable + if [ -d "$sddm_simple" ] && [ -w "$sddm_simple/Backgrounds" ]; then + # Check if yad is running to avoid multiple yad notification + if pidof yad > /dev/null; then + killall yad + fi - exec $SCRIPTSDIR/sddm_wallpaper.sh --effects - + if yad --info --text="Set current wallpaper as SDDM background?\n\nNOTE: This only applies to SIMPLE SDDM v2 Theme" \ + --text-align=left \ + --title="SDDM Background" \ + --timeout=5 \ + --timeout-indicator=right \ + --button="yad-yes:0" \ + --button="yad-no:1" \ + ; then + + # Check if terminal exists + if ! command -v "$terminal" &>/dev/null; then + notify-send -i "$iDIR/ja.png" "Missing $terminal" "Install $terminal to enable setting of wallpaper background" + exit 1 + fi + + exec "$SCRIPTSDIR/sddm_wallpaper.sh" --effects + fi fi fi -fi
\ No newline at end of file +fi diff --git a/config/hypr/UserScripts/WallpaperSelect.sh b/config/hypr/UserScripts/WallpaperSelect.sh index a08b53ce..466832ba 100755 --- a/config/hypr/UserScripts/WallpaperSelect.sh +++ b/config/hypr/UserScripts/WallpaperSelect.sh @@ -101,9 +101,21 @@ menu() { # Offer SDDM Simple Wallpaper Option (only for non-video wallpapers) set_sddm_wallpaper() { sleep 1 - sddm_simple="/usr/share/sddm/themes/simple_sddm_2" - if [ -d "$sddm_simple" ]; then + # Resolve SDDM themes directory (standard and NixOS path) + local sddm_themes_dir="" + if [ -d "/usr/share/sddm/themes" ]; then + sddm_themes_dir="/usr/share/sddm/themes" + elif [ -d "/run/current-system/sw/share/sddm/themes" ]; then + sddm_themes_dir="/run/current-system/sw/share/sddm/themes" + fi + + [ -z "$sddm_themes_dir" ] && return 0 + + local sddm_simple="$sddm_themes_dir/simple_sddm_2" + + # Only prompt if theme exists and its Backgrounds directory is writable + if [ -d "$sddm_simple" ] && [ -w "$sddm_simple/Backgrounds" ]; then # Check if yad is running to avoid multiple notifications if pidof yad >/dev/null; then @@ -123,9 +135,9 @@ set_sddm_wallpaper() { notify-send -i "$iDIR/error.png" "Missing $terminal" "Install $terminal to enable setting of wallpaper background" exit 1 fi - - exec $SCRIPTSDIR/sddm_wallpaper.sh --normal - + + exec "$SCRIPTSDIR/sddm_wallpaper.sh" --normal + fi fi } diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index a71fe8ca..ca1d5281 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -9,7 +9,6 @@ import sys import time import html from typing import Any, Dict, List, Optional, Tuple -from datetime import datetime import requests @@ -18,7 +17,7 @@ import requests # Examples (zsh): # # One-off run # # WEATHER_UNITS can be "metric" or "imperial" -# WEATHER_UNITS=imperial WEATHER_PLACE="Concord, NH" python3 ~/.config/hypr/UserScripts/Weather.py +# WEATHER_UNITS=imperial WEATHER_PLACE="Concord, NH" python3 /home/dwilliams/Projects/Weather.py # # # Persist in current shell session # export WEATHER_UNITS=imperial @@ -277,594 +276,6 @@ def fetch_open_meteo(lat: float, lon: float) -> Dict[str, Any]: "latitude": lat, "longitude": lon, "current": "temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_direction_10m,weather_code,visibility,precipitation,pressure_msl,is_day", - "hourly": "precipitation_probability,weather_code", - "daily": "temperature_2m_max,temperature_2m_min", - "timezone": "auto", - } - params.update(units_params(UNITS)) - resp = SESSION.get(base, params=params, timeout=TIMEOUT) - resp.raise_for_status() - return resp.json() - - -def fetch_aqi(lat: float, lon: float) -> Optional[Dict[str, Any]]: - try: - base = "https://air-quality-api.open-meteo.com/v1/air-quality" - params = { - "latitude": lat, - "longitude": lon, - "current": "european_aqi", - "timezone": "auto", - } - resp = SESSION.get(base, params=params, timeout=TIMEOUT) - resp.raise_for_status() - return resp.json() - except Exception as e: - print(f"AQI fetch failed: {e}", file=sys.stderr) - return None - - -def fetch_place(lat: float, lon: float) -> Optional[str]: - """Reverse geocode lat/lon to an approximate place. Tries Nominatim first, then Open-Meteo.""" - lang = os.getenv("WEATHER_LANG", "en") - - # 1) Nominatim (OpenStreetMap) - try: - base = "https://nominatim.openstreetmap.org/reverse" - params = { - "lat": lat, - "lon": lon, - "format": "jsonv2", - "accept-language": lang, - } - headers = {"User-Agent": UA + " Weather.py/1.0"} - resp = SESSION.get(base, params=params, headers=headers, timeout=TIMEOUT) - resp.raise_for_status() - data = resp.json() - address = data.get("address", {}) - name = data.get("name") or address.get("city") or address.get("town") or address.get("village") or address.get("hamlet") - admin1 = address.get("state") - country = address.get("country") - parts = [part for part in [name, admin1, country] if part] - if parts: - return ", ".join(parts) - except Exception as e: - log_debug(f"Reverse geocoding (Nominatim) failed: {e}") - - # 2) Open-Meteo reverse (fallback) - try: - base = "https://geocoding-api.open-meteo.com/v1/reverse" - params = { - "latitude": lat, - "longitude": lon, - "language": lang, - "format": "json", - } - resp = SESSION.get(base, params=params, timeout=TIMEOUT) - resp.raise_for_status() - data = resp.json() - results = data.get("results") or [] - if results: - p = results[0] - name = p.get("name") - admin1 = p.get("admin1") - country = p.get("country") - parts = [part for part in [name, admin1, country] if part] - if parts: - return ", ".join(parts) - except Exception as e: - log_debug(f"Reverse geocoding (Open-Meteo) failed: {e}") - - return None - - -# =============== Build Output =============== - -def safe_get(dct: Dict[str, Any], *keys, default=None): - cur: Any = dct - for k in keys: - if isinstance(cur, dict): - if k not in cur: - return default - cur = cur[k] - elif isinstance(cur, list): - try: - cur = cur[k] # type: ignore[index] - except Exception: - return default - else: - return default - return cur - - -def build_hourly_precip(forecast: Dict[str, Any]) -> str: - try: - times: List[str] = safe_get(forecast, "hourly", "time", default=[]) or [] - probs: List[Optional[float]] = safe_get( - forecast, "hourly", "precipitation_probability", default=[] - ) or [] - cur_time: Optional[str] = safe_get(forecast, "current", "time") - idx = times.index(cur_time) if cur_time in times else 0 - window = probs[idx : idx + 6] - if not window: - return "" - parts = [f"{int(p)}%" if p is not None else "-" for p in window] - return " (next 6h) " + " ".join(parts) - except Exception: - return "" - - -def build_output(lat: float, lon: float, forecast: Dict[str, Any], aqi: Optional[Dict[str, Any]], place: Optional[str] = None) -> Tuple[Dict[str, Any], str]: - cur = forecast.get("current", {}) - cur_units = forecast.get("current_units", {}) - daily = forecast.get("daily", {}) - daily_units = forecast.get("daily_units", {}) - - temp_val = cur.get("temperature_2m") - temp_unit = cur_units.get("temperature_2m", "") - temp_str = f"{int(round(temp_val))}{temp_unit}" if isinstance(temp_val, (int, float)) else "N/A" - - feels_val = cur.get("apparent_temperature") - feels_unit = cur_units.get("apparent_temperature", "") - feels_str = f"Feels like {int(round(feels_val))}{feels_unit}" if isinstance(feels_val, (int, float)) else "" - - is_day = int(cur.get("is_day", 1) or 1) - code = int(cur.get("weather_code", -1) or -1) - - unavailable = False - if code == -1: - try: - times: List[str] = safe_get(forecast, "hourly", "time", default=[]) or [] - codes: List[Optional[int]] = safe_get(forecast, "hourly", "weather_code", default=[]) or [] - cur_time: Optional[str] = safe_get(forecast, "current", "time") - - idx = 0 - if cur_time and times: - try: - ct = datetime.fromisoformat(cur_time) - diffs = [] - for t in times: - try: - diffs.append(abs((datetime.fromisoformat(t) - ct).total_seconds())) - except Exception: - diffs.append(float("inf")) - idx = min(range(len(diffs)), key=lambda i: diffs[i]) if diffs else 0 - except Exception: - idx = times.index(cur_time) if cur_time in times else 0 - - hcode = None - if isinstance(codes, list) and codes: - if idx < len(codes) and isinstance(codes[idx], (int, float)): - hcode = int(codes[idx]) - else: - for c in codes: - if isinstance(c, (int, float)): - hcode = int(c) - break - if isinstance(hcode, int): - code = hcode - log_debug(f"Fallback hourly weather_code used: code={code} idx={idx} cur_time={cur_time}") - except Exception as e: - log_debug(f"Hourly code fallback failed: {e}") - - if not isinstance(code, int) or code < 0: - unavailable = True - log_debug("Weather code invalid; setting status to 'Condition Unavailable'") - - if unavailable: - icon = WEATHER_ICONS["default"] - status = "Condition Unavailable" - code_for_class = "unavailable" - else: - icon = wmo_to_icon(code, is_day) - status = wmo_to_status(code) - code_for_class = f"wmo-{code} {'day' if is_day else 'night'}" - - # min/max today (index 0) - tmin_val = safe_get(daily, "temperature_2m_min", 0) - tmax_val = safe_get(daily, "temperature_2m_max", 0) - dtemp_unit = daily_units.get("temperature_2m_min", temp_unit) - tmin_str = f"{int(round(tmin_val))}{dtemp_unit}" if isinstance(tmin_val, (int, float)) else "" - tmax_str = f"{int(round(tmax_val))}{dtemp_unit}" if isinstance(tmax_val, (int, float)) else "" - min_max = f" {tmin_str}\t\t {tmax_str}" if tmin_str and tmax_str else "" - - wind_val = cur.get("wind_speed_10m") - wind_unit = cur_units.get("wind_speed_10m", "") - wind_text = f" {int(round(wind_val))}{wind_unit}" if isinstance(wind_val, (int, float)) else "" - - hum_val = cur.get("relative_humidity_2m") - humidity_text = f" {int(hum_val)}%" if isinstance(hum_val, (int, float)) else "" - - vis_val = cur.get("visibility") - visibility_text = f" {format_visibility(vis_val)}" if isinstance(vis_val, (int, float)) else "" - - aqi_val = safe_get(aqi or {}, "current", "european_aqi") - aqi_text = f"AQI {int(aqi_val)}" if isinstance(aqi_val, (int, float)) else "AQI N/A" - - hourly_precip = build_hourly_precip(forecast) - prediction = f"\n\n{hourly_precip}" if hourly_precip else "" - - # Build place string (priority: MANUAL_PLACE > ENV_PLACE > reverse geocode > lat,lon) - place_str = (MANUAL_PLACE or ENV_PLACE or place or f"{lat:.3f}, {lon:.3f}") - location_text = f"{LOC_ICON} {place_str}" - - # Build tooltip (markup or plain) - if TOOLTIP_MARKUP: - # Escape dynamic text to avoid breaking Pango markup - tooltip_text = str.format( - "\t\t{}\t\t\n{}\n{}\n{}\n{}\n\n{}\n{}\n{}{}", - f'<span size="xx-large">{esc(temp_str)}</span>', - f"<big> {icon}</big>", - f"<b>{esc(status)}</b>", - esc(location_text), - f"<small>{esc(feels_str)}</small>" if feels_str else "", - f"<b>{esc(min_max)}</b>" if min_max else "", - f"{esc(wind_text)}\t{esc(humidity_text)}", - f"{esc(visibility_text)}\t{esc(aqi_text)}", - f"<i> {esc(prediction)}</i>" if prediction else "", - ) - else: - lines = [ - f"{icon} {temp_str}", - status, - location_text, - ] - if feels_str: - lines.append(feels_str) - if min_max: - lines.append(min_max) - lines.append(f"{wind_text} {humidity_text}".strip()) - lines.append(f"{visibility_text} {aqi_text}".strip()) - if prediction: - lines.append(hourly_precip) - tooltip_text = "\n".join([ln for ln in lines if ln]) - - out_data = { - "text": f"{icon} {temp_str}", - "alt": status, - "tooltip": tooltip_text, - "class": code_for_class, - } - - simple_weather = ( - f"{icon} {status}\n" - + f" {temp_str} ({feels_str})\n" - + (f"{wind_text} \n" if wind_text else "") - + (f"{humidity_text} \n" if humidity_text else "") - + f"{visibility_text} {aqi_text}\n" - ) - - return out_data, simple_weather - - -def main() -> None: - lat, lon = get_coords() - - # Try cache first - cached = read_api_cache() - if cached and isinstance(cached, dict): - forecast = cached.get("forecast") - aqi = cached.get("aqi") - cached_place = cached.get("place") if isinstance(cached.get("place"), str) else None - place_effective = MANUAL_PLACE or ENV_PLACE or cached_place - try: - out, simple = build_output(lat, lon, forecast, aqi, place_effective) - print(json.dumps(out, ensure_ascii=False)) - write_simple_text_cache(simple) - return - except Exception as e: - print(f"Cached data build failed, refetching: {e}", file=sys.stderr) - - # Fetch fresh - try: - forecast = fetch_open_meteo(lat, lon) - aqi = fetch_aqi(lat, lon) - # Use manual/env place if provided; otherwise reverse geocode - place_effective = MANUAL_PLACE or ENV_PLACE or fetch_place(lat, lon) - write_api_cache({"forecast": forecast, "aqi": aqi, "place": place_effective}) - out, simple = build_output(lat, lon, forecast, aqi, place_effective) - print(json.dumps(out, ensure_ascii=False)) - write_simple_text_cache(simple) - except Exception as e: - print(f"Open-Meteo fetch failed: {e}", file=sys.stderr) - # Last resort: try stale cache without TTL - try: - if os.path.exists(API_CACHE_PATH): - with open(API_CACHE_PATH, "r", encoding="utf-8") as f: - stale = json.load(f) - out, simple = build_output(lat, lon, stale.get("forecast", {}), stale.get("aqi"), stale.get("place") if isinstance(stale.get("place"), str) else None) - print(json.dumps(out, ensure_ascii=False)) - write_simple_text_cache(simple) - return - except Exception as e2: - print(f"Failed to use stale cache: {e2}", file=sys.stderr) - # Fallback minimal output - fallback = { - "text": f"{WEATHER_ICONS['default']} N/A", - "alt": "Unavailable", - "tooltip": "Weather unavailable", - "class": "unavailable", - } - print(json.dumps(fallback, ensure_ascii=False)) - - -if __name__ == "__main__": - main() -status = html_data("div[data-testid='wxPhrase']").text() -status = f"{status[:16]}.." if len(status) > 17 else status - -# status code -status_code = html_data("#regionHeader").attr("class").split(" ")[2].split("-")[2] - -# status icon -icon = ( - weather_icons[status_code] - if status_code in weather_icons - else weather_icons["default"] -) - -# temperature feels like -temp_feel = html_data( - "div[data-testid='FeelsLikeSection'] > span > span[data-testid='TemperatureValue']" -).text() -temp_feel_text = f"Feels like {temp_feel}c" - -# min-max temperature -temp_min = ( - html_data("div[data-testid='wxData'] > span[data-testid='TemperatureValue']") - .eq(1) - .text() -) -temp_max = ( - html_data("div[data-testid='wxData'] > span[data-testid='TemperatureValue']") - .eq(0) - .text() -) -temp_min_max = f" {temp_min}\t\t {temp_max}" - -# wind speed -wind_speed = html_data("span[data-testid='Wind']").text().split("\n")[1] -wind_text = f" {wind_speed}" - -# humidity -humidity = html_data("span[data-testid='PercentageValue']").text() -humidity_text = f" {humidity}" - -# visibility -visibility = html_data("span[data-testid='VisibilityValue']").text() -visibility_text = f" {visibility}" - -# air quality index -air_quality_index = html_data("text[data-testid='DonutChartValue']").text() - -# hourly rain prediction -prediction = html_data("section[aria-label='Hourly Forecast']")( - "div[data-testid='SegmentPrecipPercentage'] > span" -).text() -prediction = prediction.replace("Chance of Rain", "") -prediction = f"\n\n (hourly) {prediction}" if len(prediction) > 0 else prediction - -# tooltip text -tooltip_text = str.format( - "\t\t{}\t\t\n{}\n{}\n{}\n\n{}\n{}\n{}{}", - f'<span size="xx-large">{temp}</span>', - f"<big> {icon}</big>", - f"<b>{status}</b>", - f"<small>{temp_feel_text}</small>", - f"<b>{temp_min_max}</b>", - f"{wind_text}\t{humidity_text}", - f"{visibility_text}\tAQI {air_quality_index}", - f"<i> {prediction}</i>", -) - -# print waybar module data -out_data = { - "text": f"{icon} {temp}", - "alt": status, - "tooltip": tooltip_text, - "class": status_code, -======= -WMO_STATUS = { - 0: "Clear sky", - 1: "Mainly clear", - 2: "Partly cloudy", - 3: "Overcast", - 45: "Fog", - 48: "Depositing rime fog", - 51: "Light drizzle", - 53: "Moderate drizzle", - 55: "Dense drizzle", - 56: "Freezing drizzle", - 57: "Freezing drizzle", - 61: "Light rain", - 63: "Moderate rain", - 65: "Heavy rain", - 66: "Freezing rain", - 67: "Freezing rain", - 71: "Slight snow", - 73: "Moderate snow", - 75: "Heavy snow", - 77: "Snow grains", - 80: "Rain showers", - 81: "Rain showers", - 82: "Violent rain showers", - 85: "Snow showers", - 86: "Heavy snow showers", - 95: "Thunderstorm", - 96: "Thunderstorm w/ hail", - 99: "Thunderstorm w/ hail", ->>>>>>> 2a5a7c5 (Weather.py: switch to Open-Meteo; add caching, reverse geocoding, robust geolocation, and config options) -} - - -def wmo_to_icon(code: int, is_day: int) -> str: - day = bool(is_day) - if code == 0: - return WEATHER_ICONS["sunnyDay" if day else "clearNight"] - if code in (1, 2, 3, 45, 48): - return WEATHER_ICONS["cloudyFoggyDay" if day else "cloudyFoggyNight"] - if code in (51, 53, 55, 61, 63, 65, 80, 81, 82): - return WEATHER_ICONS["rainyDay" if day else "rainyNight"] - if code in (56, 57, 66, 67, 71, 73, 75, 77, 85, 86): - return WEATHER_ICONS["snowyIcyDay" if day else "snowyIcyNight"] - if code in (95, 96, 99): - return WEATHER_ICONS["severe"] - return WEATHER_ICONS["default"] - - -def wmo_to_status(code: int) -> str: - return WMO_STATUS.get(code, "Unknown") - - -# =============== Utilities =============== - -def esc(s: Optional[str]) -> str: - return html.escape(s, quote=False) if s else "" - -def log_debug(msg: str) -> None: - if DEBUG: - print(msg, file=sys.stderr) - -def ensure_cache_dir() -> None: - try: - os.makedirs(CACHE_DIR, exist_ok=True) - except Exception as e: - print(f"Error creating cache dir: {e}", file=sys.stderr) - - -def read_api_cache() -> Optional[Dict[str, Any]]: - try: - if not os.path.exists(API_CACHE_PATH): - return None - with open(API_CACHE_PATH, "r", encoding="utf-8") as f: - data = json.load(f) - if (time.time() - data.get("timestamp", 0)) <= CACHE_TTL_SECONDS: - return data - return None - except Exception as e: - print(f"Error reading cache: {e}", file=sys.stderr) - return None - - -def write_api_cache(payload: Dict[str, Any]) -> None: - try: - ensure_cache_dir() - payload["timestamp"] = time.time() - with open(API_CACHE_PATH, "w", encoding="utf-8") as f: - json.dump(payload, f) - except Exception as e: - print(f"Error writing API cache: {e}", file=sys.stderr) - - -def write_simple_text_cache(text: str) -> None: - try: - ensure_cache_dir() - with open(SIMPLE_TEXT_CACHE_PATH, "w", encoding="utf-8") as f: - f.write(text) - except Exception as e: - print(f"Error writing simple cache: {e}", file=sys.stderr) - - -def get_coords() -> Tuple[float, float]: - # 1) Explicit env - if ENV_LAT and ENV_LON: - try: - return float(ENV_LAT), float(ENV_LON) - except ValueError: - print("Invalid WEATHER_LAT/WEATHER_LON; falling back to IP geolocation", file=sys.stderr) - - # 2) Try cached coordinates from last successful forecast - try: - cached = read_api_cache() - if cached and isinstance(cached, dict): - fc = cached.get("forecast") or {} - lat = fc.get("latitude") - lon = fc.get("longitude") - if isinstance(lat, (int, float)) and isinstance(lon, (int, float)): - return float(lat), float(lon) - except Exception as e: - print(f"Reading cached coords failed: {e}", file=sys.stderr) - - # 3) IP-based geolocation with multiple providers (prefer ipwho.is, ipapi.co; ipinfo.io as fallback) - # ipwho.is - try: - resp = SESSION.get("https://ipwho.is/", timeout=TIMEOUT) - resp.raise_for_status() - data = resp.json() - if data.get("success"): - lat = data.get("latitude") - lon = data.get("longitude") - if isinstance(lat, (int, float)) and isinstance(lon, (int, float)): - return float(lat), float(lon) - except Exception as e: - print(f"ipwho.is failed: {e}", file=sys.stderr) - - # ipapi.co - try: - resp = SESSION.get("https://ipapi.co/json", timeout=TIMEOUT) - resp.raise_for_status() - data = resp.json() - lat = data.get("latitude") - lon = data.get("longitude") - if isinstance(lat, (int, float)) and isinstance(lon, (int, float)): - return float(lat), float(lon) - except Exception as e: - print(f"ipapi.co failed: {e}", file=sys.stderr) - - # ipinfo.io (fallback) - try: - resp = SESSION.get("https://ipinfo.io/json", timeout=TIMEOUT) - resp.raise_for_status() - data = resp.json() - loc = data.get("loc") - if loc and "," in loc: - lat_s, lon_s = loc.split(",", 1) - return float(lat_s), float(lon_s) - except Exception as e: - print(f"ipinfo.io failed: {e}", file=sys.stderr) - - # 4) Last resort - print("IP geolocation failed: no providers succeeded", file=sys.stderr) - return 0.0, 0.0 - - -def units_params(units: str) -> Dict[str, str]: - if units == "imperial": - return { - "temperature_unit": "fahrenheit", - "wind_speed_unit": "mph", - "precipitation_unit": "inch", - } - # default metric - return { - "temperature_unit": "celsius", - "wind_speed_unit": "kmh", - "precipitation_unit": "mm", - } - - -def format_visibility(meters: Optional[float]) -> str: - if meters is None: - return "" - try: - if UNITS == "imperial": - miles = meters / 1609.344 - return f"{miles:.1f} mi" - else: - km = meters / 1000.0 - return f"{km:.1f} km" - except Exception: - return "" - - -# =============== API Fetching =============== - -def fetch_open_meteo(lat: float, lon: float) -> Dict[str, Any]: - base = "https://api.open-meteo.com/v1/forecast" - params = { - "latitude": lat, - "longitude": lon, - "current": "temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_direction_10m,weather_code,visibility,precipitation,pressure_msl,is_day", "hourly": "precipitation_probability", "daily": "temperature_2m_max,temperature_2m_min", "timezone": "auto", diff --git a/config/hypr/scripts/Hyprsunset.sh b/config/hypr/scripts/Hyprsunset.sh new file mode 100755 index 00000000..c7c4b395 --- /dev/null +++ b/config/hypr/scripts/Hyprsunset.sh @@ -0,0 +1,99 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Hyprsunset toggle + Waybar status helper +# Phase 1: manual toggle only (no scheduling) +# Icons: +# - Off: bright sun +# - On: sunset icon if available, otherwise a blue sun +# +# Customize via env vars: +# HYPERSUNSET_TEMP default 4500 (K) +# HYPERSUNSET_ICON_MODE sunset|blue (default: sunset) + +STATE_FILE="$HOME/.cache/.hyprsunset_state" +TARGET_TEMP="${HYPERSUNSET_TEMP:-4500}" +ICON_MODE="${HYPERSUNSET_ICON_MODE:-sunset}" + +ensure_state() { + [[ -f "$STATE_FILE" ]] || echo "off" > "$STATE_FILE" +} + +# Render icons using pango markup to allow colorization +icon_off() { + # universally available sun symbol + printf "☀" +} + +icon_on() { + case "$ICON_MODE" in + sunset) + # sunset emoji (falls back to tofu if no emoji font) + printf "🌇" + ;; + blue) + # no color in text; rely on CSS .on to style if desired + printf "☀" + ;; + *) + printf "☀" + ;; + esac +} + +cmd_toggle() { + ensure_state + state="$(cat "$STATE_FILE" || echo off)" + + # Always stop any running hyprsunset first to avoid CTM manager conflicts + if pgrep -x hyprsunset >/dev/null 2>&1; then + pkill -x hyprsunset || true + # give it a moment to release the CTM manager + sleep 0.2 + fi + +if [[ "$state" == "on" ]]; then + # Turning OFF: set identity and exit + if command -v hyprsunset >/dev/null 2>&1; then + nohup hyprsunset -i >/dev/null 2>&1 & + # if hyprsunset persists, stop it shortly after applying identity + sleep 0.3 && pkill -x hyprsunset || true + fi + echo off > "$STATE_FILE" + notify-send -u low "Hyprsunset: Disabled" || true + else + # Turning ON: start hyprsunset at target temp in background + if command -v hyprsunset >/dev/null 2>&1; then + nohup hyprsunset -t "$TARGET_TEMP" >/dev/null 2>&1 & + fi + echo on > "$STATE_FILE" + notify-send -u low "Hyprsunset: Enabled" "${TARGET_TEMP}K" || true + fi +} + +cmd_status() { + ensure_state + # Prefer live process detection; fall back to state file + if pgrep -x hyprsunset >/dev/null 2>&1; then + onoff="on" + else + onoff="$(cat "$STATE_FILE" || echo off)" + fi + + if [[ "$onoff" == "on" ]]; then + txt="<span size='18pt'>$(icon_on)</span>" + cls="on" + tip="Night light on @ ${TARGET_TEMP}K" + else + txt="<span size='16pt'>$(icon_off)</span>" + cls="off" + tip="Night light off" + fi + printf '{"text":"%s","class":"%s","tooltip":"%s"}\n' "$txt" "$cls" "$tip" +} + +case "${1:-}" in + toggle) cmd_toggle ;; + status) cmd_status ;; + *) echo "usage: $0 [toggle|status]" >&2; exit 2 ;; + esac diff --git a/config/hypr/scripts/MediaCtrl.sh b/config/hypr/scripts/MediaCtrl.sh index 2cbeccf3..000c3ade 100755 --- a/config/hypr/scripts/MediaCtrl.sh +++ b/config/hypr/scripts/MediaCtrl.sh @@ -6,56 +6,57 @@ music_icon="$HOME/.config/swaync/icons/music.png" # Play the next track play_next() { - playerctl next - show_music_notification + playerctl next + show_music_notification } # Play the previous track play_previous() { - playerctl previous - show_music_notification + playerctl previous + show_music_notification } # Toggle play/pause toggle_play_pause() { - playerctl play-pause - show_music_notification + playerctl play-pause + sleep 0.1 + show_music_notification } # Stop playback stop_playback() { - playerctl stop - notify-send -e -u low -i $music_icon " Playback:" " Stopped" + playerctl stop + notify-send -e -u low -i $music_icon " Playback:" " Stopped" } # Display notification with song information show_music_notification() { - status=$(playerctl status) - if [[ "$status" == "Playing" ]]; then - song_title=$(playerctl metadata title) - song_artist=$(playerctl metadata artist) - notify-send -e -u low -i $music_icon "Now Playing:" "$song_title by $song_artist" - elif [[ "$status" == "Paused" ]]; then - notify-send -e -u low -i $music_icon " Playback:" " Paused" - fi + status=$(playerctl status) + if [[ "$status" == "Playing" ]]; then + song_title=$(playerctl metadata title) + song_artist=$(playerctl metadata artist) + notify-send -e -u low -i $music_icon "Now Playing:" "$song_title by $song_artist" + elif [[ "$status" == "Paused" ]]; then + notify-send -e -u low -i $music_icon " Playback:" " Paused" + fi } # Get media control action from command line argument case "$1" in - "--nxt") - play_next - ;; - "--prv") - play_previous - ;; - "--pause") - toggle_play_pause - ;; - "--stop") - stop_playback - ;; - *) - echo "Usage: $0 [--nxt|--prv|--pause|--stop]" - exit 1 - ;; +"--nxt") + play_next + ;; +"--prv") + play_previous + ;; +"--pause") + toggle_play_pause + ;; +"--stop") + stop_playback + ;; +*) + echo "Usage: $0 [--nxt|--prv|--pause|--stop]" + exit 1 + ;; esac diff --git a/config/hypr/scripts/sddm_wallpaper.sh b/config/hypr/scripts/sddm_wallpaper.sh index a781156e..9487188c 100644 --- a/config/hypr/scripts/sddm_wallpaper.sh +++ b/config/hypr/scripts/sddm_wallpaper.sh @@ -10,7 +10,12 @@ wallDIR="$HOME/Pictures/wallpapers" SCRIPTSDIR="$HOME/.config/hypr/scripts" wallpaper_current="$HOME/.config/hypr/wallpaper_effects/.wallpaper_current" wallpaper_modified="$HOME/.config/hypr/wallpaper_effects/.wallpaper_modified" -sddm_simple="/usr/share/sddm/themes/simple_sddm_2" +# Resolve SDDM themes directory (standard paths and NixOS path) +sddm_themes_dir="/usr/share/sddm/themes" +if [ ! -d "$sddm_themes_dir" ] && [ -d "/run/current-system/sw/share/sddm/themes" ]; then + sddm_themes_dir="/run/current-system/sw/share/sddm/themes" +fi +sddm_simple="$sddm_themes_dir/simple_sddm_2" # rofi-wallust-sddm colors path rofi_wallust="$HOME/.config/rofi/wallust/colors-rofi.rasi" @@ -46,6 +51,12 @@ else wallpaper_path="$wallpaper_modified" fi +# Abort on NixOS where this repo doesn't manage SDDM and themes are typically read-only +if hostnamectl 2>/dev/null | grep -q 'Operating System: NixOS'; then + notify-send -i "$iDIR/error.png" "SDDM" "NixOS detected: skipping SDDM background change." + exit 0 +fi + # Launch terminal and apply changes $terminal -e bash -c " echo 'Enter your password to update SDDM wallpapers and colors'; @@ -70,7 +81,15 @@ sudo sed -i \"s/UserIconColor=\\\"#.*\\\"/UserIconColor=\\\"$color7\\\"/\" \"$sd sudo sed -i \"s/PasswordIconColor=\\\"#.*\\\"/PasswordIconColor=\\\"$color7\\\"/\" \"$sddm_theme_conf\" # Copy wallpaper to SDDM theme -sudo cp \"$wallpaper_path\" \"$sddm_simple/Backgrounds/default\" +# Primary: set Backgrounds/default (no extension) for simple_sddm_2 +sudo cp -f \"$wallpaper_path\" \"$sddm_simple/Backgrounds/default\" || true +# Fallbacks: if theme ships default.jpg or default.png, update those too +if [ -e \"$sddm_simple/Backgrounds/default.jpg\" ]; then + sudo cp -f \"$wallpaper_path\" \"$sddm_simple/Backgrounds/default.jpg\" +fi +if [ -e \"$sddm_simple/Backgrounds/default.png\" ]; then + sudo cp -f \"$wallpaper_path\" \"$sddm_simple/Backgrounds/default.png\" +fi notify-send -i \"$iDIR/ja.png\" \"SDDM\" \"Background SET\" "
\ No newline at end of file diff --git a/config/hypr/v2.3.16 b/config/hypr/v2.3.16 deleted file mode 100644 index 31b3414d..00000000 --- a/config/hypr/v2.3.16 +++ /dev/null @@ -1,5 +0,0 @@ -### https://github.com/JaKooLit ### -## https://github.com/JaKooLit/Hyprland-Dots -## This is to have a reference of which version would be - -## note that this will always be higher than the released versions
\ No newline at end of file diff --git a/config/quickshell/modules/common/ConfigOptions.qml b/config/quickshell/modules/common/ConfigOptions.qml index 25f0de05..3a9fa194 100644 --- a/config/quickshell/modules/common/ConfigOptions.qml +++ b/config/quickshell/modules/common/ConfigOptions.qml @@ -17,6 +17,7 @@ Singleton { property real windowPadding: 6 property real position: 1 // 0: top | 1: middle | 2: bottom property real workspaceNumberSize: 120 // Set 0, dynamic calculation based on monitor size + property bool showAllMonitors: true // Show windows from all monitors } property QtObject resources: QtObject { diff --git a/config/quickshell/modules/overview/Overview.qml b/config/quickshell/modules/overview/Overview.qml index ef5a49c3..08a3b0d3 100644 --- a/config/quickshell/modules/overview/Overview.qml +++ b/config/quickshell/modules/overview/Overview.qml @@ -17,7 +17,7 @@ Scope { Variants { id: overviewVariants - model: Quickshell.screens + model: Quickshell.screens.filter(s => Hyprland.monitorFor(s).id === Hyprland.focusedMonitor?.id) PanelWindow { id: root required property var modelData diff --git a/config/quickshell/modules/overview/OverviewWidget.qml b/config/quickshell/modules/overview/OverviewWidget.qml index 93e90967..05a15e10 100644 --- a/config/quickshell/modules/overview/OverviewWidget.qml +++ b/config/quickshell/modules/overview/OverviewWidget.qml @@ -46,6 +46,33 @@ Item { property int draggingFromWorkspace: -1 property int draggingTargetWorkspace: -1 + // Debug logging function + function debugMultiMonitorInfo() { + console.log("=== Multi-Monitor Debug Info ===") + console.log("Current monitor ID:", root.monitor.id) + console.log("Current monitor name:", root.monitor.name) + console.log("Current monitor scale:", root.monitor.scale) + console.log("Current monitor position:", root.monitor.x, root.monitor.y) + console.log("Total monitors:", HyprlandData.monitors.length) + + HyprlandData.monitors.forEach((mon, idx) => { + console.log(`Monitor ${idx}: ID=${mon.id}, Name=${mon.name}, Scale=${mon.scale}, Pos=(${mon.x},${mon.y}), Size=${mon.width}x${mon.height}, Reserved=[${mon.reserved.join(",")}]`) + }) + + console.log("Total windows:", windowAddresses.length) + windowAddresses.forEach((address, idx) => { + const win = windowByAddress[address] + if (win) { + console.log(`Window ${idx}: ${win.class} on monitor ${win.monitor}, workspace ${win.workspace?.id}, pos=(${win.at[0]},${win.at[1]})`) + } + }) + console.log("=== End Debug Info ===") + } + + Component.onCompleted: { + debugMultiMonitorInfo() + } + implicitWidth: overviewBackground.implicitWidth + Appearance.sizes.elevationMargin * 2 implicitHeight: overviewBackground.implicitHeight + Appearance.sizes.elevationMargin * 2 @@ -233,14 +260,21 @@ Item { model: ScriptModel { values: windowAddresses.filter((address) => { var win = windowByAddress[address] - return (root.workspaceGroup * root.workspacesShown < win?.workspace?.id && win?.workspace?.id <= (root.workspaceGroup + 1) * root.workspacesShown) + if (!win) return false + + // Filter by workspace group AND monitor if configured + const inWorkspaceGroup = (root.workspaceGroup * root.workspacesShown < win?.workspace?.id && + win?.workspace?.id <= (root.workspaceGroup + 1) * root.workspacesShown) + const inMonitor = ConfigOptions.overview.showAllMonitors || win.monitor === root.monitor.id + + return inWorkspaceGroup && inMonitor }) } delegate: OverviewWindow { id: window windowData: windowByAddress[modelData] - monitorData: HyprlandData.monitors.find(m => m.id === windowData?.monitor) // use monitorData of the monitor the window is on - scale: root.scale * (monitorData?.scale / root.monitor?.scale) // adjust window scale to the monitor where the overview is displayed + monitorData: root.monitorData + scale: root.scale availableWorkspaceWidth: root.workspaceImplicitWidth availableWorkspaceHeight: root.workspaceImplicitHeight diff --git a/config/quickshell/modules/overview/OverviewWindow.qml b/config/quickshell/modules/overview/OverviewWindow.qml index 93ea06f9..b28a5bf6 100644 --- a/config/quickshell/modules/overview/OverviewWindow.qml +++ b/config/quickshell/modules/overview/OverviewWindow.qml @@ -17,14 +17,31 @@ Rectangle { // Window property var scale property var availableWorkspaceWidth property var availableWorkspaceHeight - property bool restrictToWorkspace: true - property real initX: Math.max((windowData?.at[0] - monitorData?.reserved[0] - monitorData?.x) * root.scale, 0) + xOffset - property real initY: Math.max((windowData?.at[1] - monitorData?.reserved[1] - monitorData?.y) * root.scale, 0) + yOffset + property bool restrictToWorkspace: true`` + property var sourceMonitor: HyprlandData.monitors.find(m => m.id === windowData?.monitor) || HyprlandData.monitors[0] || { scale: 1.0, x: 0, y: 0, reserved: [0,0,0,0] } + property real monitorScaleFactor: sourceMonitor?.scale || 1.0 + property real targetScaleFactor: monitorData?.scale || monitorScaleFactor || 1.0 + property var focusedMonitor: Hyprland.focusedMonitor + property real focusedMonitorScale: focusedMonitor?.scale || 1.0 + property real effectiveScale: root.scale * ( + ConfigOptions.overview.showAllMonitors + ? (focusedMonitorScale / monitorScaleFactor) // Scale relative to focused monitor when showing all + : (targetScaleFactor / monitorScaleFactor) // Scale relative to target monitor normally + ) + + // Calculate position relative to source monitor + property real relativeX: (windowData?.at[0] - sourceMonitor?.x - sourceMonitor?.reserved[0]) || 0 + property real relativeY: (windowData?.at[1] - sourceMonitor?.y - sourceMonitor?.reserved[1]) || 0 + + // Scale position based on monitor differences + property real initX: Math.max(relativeX * effectiveScale, 0) + xOffset + property real initY: Math.max(relativeY * effectiveScale, 0) + yOffset property real xOffset: 0 property real yOffset: 0 - property var targetWindowWidth: windowData?.size[0] * scale - property var targetWindowHeight: windowData?.size[1] * scale + // Scale window size based on monitor differences + property var targetWindowWidth: (windowData?.size[0] || 0) * effectiveScale + property var targetWindowHeight: (windowData?.size[1] || 0) * effectiveScale property bool hovered: false property bool pressed: false diff --git a/config/waybar/ModulesCustom b/config/waybar/ModulesCustom index dddc5ccc..146ec275 100644 --- a/config/waybar/ModulesCustom +++ b/config/waybar/ModulesCustom @@ -104,6 +104,19 @@ "tooltip-format": "Left Click: Switch Dark-Light Themes\nMiddle Click: Wallpaper Menu\nRight Click: Waybar Styles Menu", }, +// Night light (Hyprsunset) +"custom/nightlight": { + "return-type": "json", + "exec": "$HOME/.config/hypr/scripts/Hyprsunset.sh status", + "interval": 3, + "format": "{text}", + "min-length": 2, + "on-click": "$HOME/.config/hypr/scripts/Hyprsunset.sh toggle", + "tooltip": true, + "tooltip-format": "Night light toggle", + "escape": false +}, + "custom/lock": { "format": "", "on-click": "$HOME/.config/hypr/scripts/LockScreen.sh", diff --git a/config/waybar/ModulesGroups b/config/waybar/ModulesGroups index 30e47f16..8d4453a2 100644 --- a/config/waybar/ModulesGroups +++ b/config/waybar/ModulesGroups @@ -89,6 +89,7 @@ }, "modules": [ "custom/power", + "custom/nightlight", "custom/lock", "keyboard-state", "custom/keyboard", @@ -131,6 +132,7 @@ }, "modules": [ "custom/power", + "custom/nightlight", "custom/lock", "custom/logout", "custom/reboot" diff --git a/config/waybar/configs/[BOT & Left] SouthWest b/config/waybar/configs/[BOT & Left] SouthWest index a039f040..594b46d3 100644 --- a/config/waybar/configs/[BOT & Left] SouthWest +++ b/config/waybar/configs/[BOT & Left] SouthWest @@ -46,6 +46,7 @@ "power-profiles-daemon", "pulseaudio#microphone", "keyboard-state", + "custom/nightlight", "custom/power", ], }, diff --git a/config/waybar/configs/[BOT & Right] SouthEast b/config/waybar/configs/[BOT & Right] SouthEast index 9a58e952..03cdb06c 100644 --- a/config/waybar/configs/[BOT & Right] SouthEast +++ b/config/waybar/configs/[BOT & Right] SouthEast @@ -46,6 +46,7 @@ "power-profiles-daemon", "pulseaudio#microphone", "keyboard-state", + "custom/nightlight", "custom/power", ], }, diff --git a/config/waybar/configs/[LEFT] WestWing b/config/waybar/configs/[LEFT] WestWing index e3f25d1a..28e5dbec 100644 --- a/config/waybar/configs/[LEFT] WestWing +++ b/config/waybar/configs/[LEFT] WestWing @@ -39,6 +39,7 @@ "backlight#vertical", "pulseaudio#microphone_vertical", "pulseaudio#vertical", + "custom/nightlight", "custom/power_vertical", "custom/menu", ], diff --git a/config/waybar/configs/[LEFT] WestWing v2 b/config/waybar/configs/[LEFT] WestWing v2 index f1ed69c3..906f83d6 100644 --- a/config/waybar/configs/[LEFT] WestWing v2 +++ b/config/waybar/configs/[LEFT] WestWing v2 @@ -40,6 +40,7 @@ "backlight#vertical", "pulseaudio/slider", "pulseaudio#microphone_vertical", + "custom/nightlight", "group/power#vert", ], diff --git a/config/waybar/configs/[RIGHT] EastWing b/config/waybar/configs/[RIGHT] EastWing index b64fe5f8..a5ce6756 100644 --- a/config/waybar/configs/[RIGHT] EastWing +++ b/config/waybar/configs/[RIGHT] EastWing @@ -39,6 +39,7 @@ "backlight#vertical", "pulseaudio#microphone_vertical", "pulseaudio#vertical", + "custom/nightlight", "custom/power_vertical", "custom/menu", ], diff --git a/config/waybar/configs/[RIGHT] EastWing v2 b/config/waybar/configs/[RIGHT] EastWing v2 index f9991bd6..28dd1e43 100644 --- a/config/waybar/configs/[RIGHT] EastWing v2 +++ b/config/waybar/configs/[RIGHT] EastWing v2 @@ -40,6 +40,7 @@ "backlight#vertical", "pulseaudio/slider", "pulseaudio#microphone_vertical", + "custom/nightlight", "group/power#vert", ], diff --git a/config/waybar/configs/[TOP & BOT] SummitSplit b/config/waybar/configs/[TOP & BOT] SummitSplit index 03c8e81b..516e9834 100644 --- a/config/waybar/configs/[TOP & BOT] SummitSplit +++ b/config/waybar/configs/[TOP & BOT] SummitSplit @@ -44,6 +44,7 @@ "network", "custom/updater", "custom/cycle_wall", + "custom/nightlight", "custom/lock", ], }, @@ -88,6 +89,7 @@ "pulseaudio", //"wireplumber", "pulseaudio#microphone", + "custom/nightlight", "custom/power", ], }], diff --git a/config/waybar/configs/[TOP & BOT] SummitSplit v2 b/config/waybar/configs/[TOP & BOT] SummitSplit v2 index 1425f657..4d576aef 100644 --- a/config/waybar/configs/[TOP & BOT] SummitSplit v2 +++ b/config/waybar/configs/[TOP & BOT] SummitSplit v2 @@ -28,13 +28,14 @@ "network", ], "modules-center": ["hyprland/window"], - "modules-right": [ +"modules-right": [ "mpris", "battery", "backlight", "pulseaudio", "group/mobo_drawer", "idle_inhibitor", + "custom/nightlight", "group/power" ], diff --git a/config/waybar/configs/[TOP] 0-Ja-0 b/config/waybar/configs/[TOP] 0-Ja-0 index c4cb0a65..6e7fc9aa 100644 --- a/config/waybar/configs/[TOP] 0-Ja-0 +++ b/config/waybar/configs/[TOP] 0-Ja-0 @@ -48,6 +48,7 @@ "custom/separator#dot-line", "mpris", "custom/separator#blank", + "custom/nightlight", "group/status", ], }
\ No newline at end of file diff --git a/config/waybar/configs/[TOP] Arrow b/config/waybar/configs/[TOP] Arrow index 8001d8fb..7fc55f60 100644 --- a/config/waybar/configs/[TOP] Arrow +++ b/config/waybar/configs/[TOP] Arrow @@ -36,7 +36,8 @@ "battery", "custom/arrow2", "tray", - "custom/arrow1", +"custom/arrow1", + "custom/nightlight", "clock#2" ], } diff --git a/config/waybar/configs/[TOP] Camellia b/config/waybar/configs/[TOP] Camellia index c93e9079..efaf6e20 100644 --- a/config/waybar/configs/[TOP] Camellia +++ b/config/waybar/configs/[TOP] Camellia @@ -44,7 +44,8 @@ "power-profiles-daemon", "battery", "clock#3", - "network"], + "network", + "custom/nightlight"], // Additional modules // "pulseaudio/slider": { diff --git a/config/waybar/configs/[TOP] Chrysanthemum b/config/waybar/configs/[TOP] Chrysanthemum index ebaa0ca4..d12f73e3 100644 --- a/config/waybar/configs/[TOP] Chrysanthemum +++ b/config/waybar/configs/[TOP] Chrysanthemum @@ -36,6 +36,7 @@ "modules-right": [ "pulseaudio#1", "backlight#2", - "battery"], + "battery", + "custom/nightlight"], }
\ No newline at end of file diff --git a/config/waybar/configs/[TOP] Default Laptop b/config/waybar/configs/[TOP] Default Laptop index b9722b89..0b264c6b 100644 --- a/config/waybar/configs/[TOP] Default Laptop +++ b/config/waybar/configs/[TOP] Default Laptop @@ -54,6 +54,7 @@ "custom/separator#line", "group/audio", "custom/separator#dot-line", + "custom/nightlight", "group/status", ], }
\ No newline at end of file diff --git a/config/waybar/configs/[TOP] Everforest b/config/waybar/configs/[TOP] Everforest index a66763ed..7b007f78 100644 --- a/config/waybar/configs/[TOP] Everforest +++ b/config/waybar/configs/[TOP] Everforest @@ -45,6 +45,7 @@ "battery#forest", "custom/separator#blank_2", "group/audio", + "custom/nightlight", ], // Additional / Edited Waybar Modules // diff --git a/config/waybar/configs/[TOP] Gardenia b/config/waybar/configs/[TOP] Gardenia index 77e86bae..073ff46e 100644 --- a/config/waybar/configs/[TOP] Gardenia +++ b/config/waybar/configs/[TOP] Gardenia @@ -37,7 +37,8 @@ "modules-right": [ "pulseaudio#1", "backlight#2", - "battery" + "battery", + "custom/nightlight" ], }
\ No newline at end of file diff --git a/config/waybar/configs/[TOP] Minimal - Long b/config/waybar/configs/[TOP] Minimal - Long index b57cf3a3..a5be4bd7 100644 --- a/config/waybar/configs/[TOP] Minimal - Long +++ b/config/waybar/configs/[TOP] Minimal - Long @@ -42,6 +42,7 @@ "custom/separator#blank_2", "group/audio", "custom/separator#blank_2", + "custom/nightlight", "custom/power", ], diff --git a/config/waybar/configs/[TOP] Minimal - Short b/config/waybar/configs/[TOP] Minimal - Short index 57abd3d3..7b9a1929 100644 --- a/config/waybar/configs/[TOP] Minimal - Short +++ b/config/waybar/configs/[TOP] Minimal - Short @@ -34,5 +34,6 @@ "backlight", "pulseaudio", "battery", + "custom/nightlight", "custom/power"], } diff --git a/config/waybar/configs/[TOP] Peony b/config/waybar/configs/[TOP] Peony index 2fd1dfe3..a1ef02e8 100644 --- a/config/waybar/configs/[TOP] Peony +++ b/config/waybar/configs/[TOP] Peony @@ -44,6 +44,7 @@ "temperature", "custom/separator#blank", "group/mobo_drawer", - "network"], + "network", + "custom/nightlight"], }
\ No newline at end of file diff --git a/config/waybar/configs/[TOP] Sleek b/config/waybar/configs/[TOP] Sleek index fe0f41ba..f591f472 100644 --- a/config/waybar/configs/[TOP] Sleek +++ b/config/waybar/configs/[TOP] Sleek @@ -39,6 +39,7 @@ "pulseaudio", "custom/separator#blank", "group/mobo_drawer", + "custom/nightlight", "custom/power", ], } @@ -5,7 +5,7 @@ clear wallpaper=$HOME/.config/hypr/wallpaper_effects/.wallpaper_current waybar_style="$HOME/.config/waybar/style/[Extra] Neon Circuit.css" waybar_config="$HOME/.config/waybar/configs/[TOP] Default" -waybar_config_laptop="$HOME/.config/waybar/configs/[TOP] Default Laptop" +waybar_config_laptop="$HOME/.config/waybar/configs/[TOP] Default Laptop" # Set some colors for output messages OK="$(tput setaf 2)[OK]$(tput sgr0)" @@ -23,44 +23,51 @@ BLUE="$(tput setaf 4)" SKY_BLUE="$(tput setaf 6)" RESET="$(tput sgr0)" - # Check if running as root. If root, script will exit if [[ $EUID -eq 0 ]]; then - echo "${ERROR} This script should ${WARNING}NOT${RESET} be executed as root!! Exiting......." - printf "\n%.0s" {1..2} - exit 1 + echo "${ERROR} This script should ${WARNING}NOT${RESET} be executed as root!! Exiting......." + printf "\n%.0s" {1..2} + exit 1 fi # Function to print colorful text print_color() { - printf "%b%s%b\n" "$1" "$2" "$RESET" + printf "%b%s%b\n" "$1" "$2" "$RESET" } -# Check /etc/os-release to see if this is an Ubuntu or Debian based distro -if grep -iq '^\(ID_LIKE\|ID\)=.*\(debian\|ubuntu\)' /etc/os-release >/dev/null 2>&1; then - printf "\n%.0s" {1..1} - print_color $WARNING " - █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ - KOOL DOTS version INCOMPATIBLE - █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ - - Debian / Ubuntu detected. Refer to Hyprland-Dots README - For instruction on how to update your KooL Hyprland Dots - - exiting .... - " - printf "\n%.0s" {1..3} - exit 1 +# Check /etc/os-release for Ubuntu or Debian and warn about Hyprland version requirement +if grep -iqE '^(ID_LIKE|ID)=.*(ubuntu|debian)' /etc/os-release >/dev/null 2>&1; then + printf "\n%.0s" {1..1} + print_color $WARNING "\nThese Dotfiles are only supported on Hyprland 0.51.1 or greater. Do not install on older revisions.\n" + while true; do + echo -n "${CAT} Do you want to continue anyway? (y/N): " + read _continue + _continue=$(echo "${_continue}" | tr '[:upper:]' '[:lower:]') + case "${_continue}" in + y|yes) + echo "${NOTE} Proceeding on Ubuntu/Debian by user confirmation." + break + ;; + n|no|"") + printf "\n%.0s" {1..1} + echo "${INFO} Aborting per user choice. No changes made." + printf "\n%.0s" {1..1} + exit 1 + ;; + *) + echo "${WARN} Please answer 'y' or 'n'." + ;; + esac + done fi - -printf "\n%.0s" {1..1} +printf "\n%.0s" {1..1} echo -e "\e[35m ╦╔═┌─┐┌─┐╦ ╔╦╗┌─┐┌┬┐┌─┐ ╠╩╗│ ││ │║ ║║│ │ │ └─┐ 2025 ╩ ╩└─┘└─┘╩═╝ ═╩╝└─┘ ┴ └─┘ \e[0m" -printf "\n%.0s" {1..1} +printf "\n%.0s" {1..1} ####### Announcement echo "${WARNING}A T T E N T I O N !${RESET}" @@ -69,7 +76,7 @@ printf "\n%.0s" {1..1} # Create Directory for Copy Logs if [ ! -d Copy-Logs ]; then - mkdir Copy-Logs + mkdir Copy-Logs fi # Set the name of the log file to include the current date and time @@ -86,8 +93,8 @@ if lspci -k | grep -A 2 -E "(VGA|3D)" | grep -iq nvidia; then sed -i '/env = NVD_BACKEND,direct/s/^#//' config/hypr/UserConfigs/ENVariables.conf sed -i '/env = GSK_RENDERER,ngl/s/^#//' config/hypr/UserConfigs/ENVariables.conf - # no hardware cursors if nvidia detected - sed -i 's/^\([[:space:]]*no_hardware_cursors[[:space:]]*=[[:space:]]*\)2/\1 1/' config/hypr/UserConfigs/UserSettings.conf + # no hardware cursors if nvidia detected + sed -i 's/^\([[:space:]]*no_hardware_cursors[[:space:]]*=[[:space:]]*\)2/\1 1/' config/hypr/UserConfigs/UserSettings.conf #sed -i 's/^\([[:space:]]*explicit_sync[[:space:]]*=[[:space:]]*\)2/\1 0/' config/hypr/UserConfigs/UserSettings.conf fi @@ -110,13 +117,13 @@ fi # activating hyprcursor on env by checking if the directory ~/.icons/Bibata-Modern-Ice/hyprcursors exists if [ -d "$HOME/.icons/Bibata-Modern-Ice/hyprcursors" ]; then - HYPRCURSOR_ENV_FILE="config/hypr/UserConfigs/ENVariables.conf" - echo "${INFO} Bibata-Hyprcursor directory detected. Activating Hyprcursor...." 2>&1 | tee -a "$LOG" || true - sed -i 's/^#env = HYPRCURSOR_THEME,Bibata-Modern-Ice/env = HYPRCURSOR_THEME,Bibata-Modern-Ice/' "$HYPRCURSOR_ENV_FILE" - sed -i 's/^#env = HYPRCURSOR_SIZE,24/env = HYPRCURSOR_SIZE,24/' "$HYPRCURSOR_ENV_FILE" + HYPRCURSOR_ENV_FILE="config/hypr/UserConfigs/ENVariables.conf" + echo "${INFO} Bibata-Hyprcursor directory detected. Activating Hyprcursor...." 2>&1 | tee -a "$LOG" || true + sed -i 's/^#env = HYPRCURSOR_THEME,Bibata-Modern-Ice/env = HYPRCURSOR_THEME,Bibata-Modern-Ice/' "$HYPRCURSOR_ENV_FILE" + sed -i 's/^#env = HYPRCURSOR_SIZE,24/env = HYPRCURSOR_SIZE,24/' "$HYPRCURSOR_ENV_FILE" fi -printf "\n%.0s" {1..1} +printf "\n%.0s" {1..1} # Function to detect keyboard layout using localectl or setxkbmap detect_layout() { @@ -160,15 +167,15 @@ ${MAGENTA} NOTE:${RESET} • For example: ${YELLOW}us, kr, gb, ru${RESET} " printf "\n%.0s" {1..1} - + echo -n "${CAT} - Please enter the correct keyboard layout: " read new_layout if [ -n "$new_layout" ]; then - layout="$new_layout" - break + layout="$new_layout" + break else - echo "${CAT} Please enter a keyboard layout." + echo "${CAT} Please enter a keyboard layout." fi done fi @@ -182,15 +189,16 @@ while true; do read keyboard_layout case $keyboard_layout in - [yY]) - awk -v layout="$layout" '/kb_layout/ {$0 = " kb_layout = " layout} 1' config/hypr/UserConfigs/UserSettings.conf > temp.conf - mv temp.conf config/hypr/UserConfigs/UserSettings.conf - - echo "${NOTE} kb_layout ${MAGENTA}$layout${RESET} configured in settings." 2>&1 | tee -a "$LOG" - break ;; - [nN]) - printf "\n%.0s" {1..2} - print_color $WARNING " + [yY]) + awk -v layout="$layout" '/kb_layout/ {$0 = " kb_layout = " layout} 1' config/hypr/UserConfigs/UserSettings.conf >temp.conf + mv temp.conf config/hypr/UserConfigs/UserSettings.conf + + echo "${NOTE} kb_layout ${MAGENTA}$layout${RESET} configured in settings." 2>&1 | tee -a "$LOG" + break + ;; + [nN]) + printf "\n%.0s" {1..2} + print_color $WARNING " █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ STOP AND READ █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ @@ -210,54 +218,56 @@ ${MAGENTA} NOTE:${RESET} • You can also set more than 2 keyboard layouts • For example: ${YELLOW}us, kr, gb, ru${RESET} " - printf "\n%.0s" {1..1} - - echo -n "${CAT} - Please enter the correct keyboard layout: " - read new_layout + printf "\n%.0s" {1..1} - awk -v new_layout="$new_layout" '/kb_layout/ {$0 = " kb_layout = " new_layout} 1' config/hypr/UserConfigs/UserSettings.conf > temp.conf - mv temp.conf config/hypr/UserConfigs/UserSettings.conf - echo "${OK} kb_layout $new_layout configured in settings." 2>&1 | tee -a "$LOG" - break ;; - *) - echo "${ERROR} Please enter either 'y' or 'n'." ;; + echo -n "${CAT} - Please enter the correct keyboard layout: " + read new_layout + + awk -v new_layout="$new_layout" '/kb_layout/ {$0 = " kb_layout = " new_layout} 1' config/hypr/UserConfigs/UserSettings.conf >temp.conf + mv temp.conf config/hypr/UserConfigs/UserSettings.conf + echo "${OK} kb_layout $new_layout configured in settings." 2>&1 | tee -a "$LOG" + break + ;; + *) + echo "${ERROR} Please enter either 'y' or 'n'." + ;; esac done # Check if asusctl is installed and add rog-control-center on Startup if command -v asusctl >/dev/null 2>&1; then - sed -i '/^\s*#exec-once = rog-control-center/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf + sed -i '/^\s*#exec-once = rog-control-center/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf fi # Check if blueman-applet is installed and add blueman-applet on Startup if command -v blueman-applet >/dev/null 2>&1; then - sed -i '/^\s*#exec-once = blueman-applet/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf + sed -i '/^\s*#exec-once = blueman-applet/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf fi # Check if ags is installed edit ags behaviour on configs if command -v ags >/dev/null 2>&1; then - sed -i '/^\s*#exec-once = ags/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf - sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh - sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/Refresh.sh + sed -i '/^\s*#exec-once = ags/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf + sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh + sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/Refresh.sh - # Uncomment the ags overview keybind - sed -i '/^#bind = \$mainMod, A, exec, pkill rofi || true && ags -t '\''overview'\''/s/^#//' config/hypr/UserConfigs/UserKeybinds.conf + # Uncomment the ags overview keybind + sed -i '/^#bind = \$mainMod, A, exec, pkill rofi || true && ags -t '\''overview'\''/s/^#//' config/hypr/UserConfigs/UserKeybinds.conf - # Comment the quickshell line if not already commented - sed -i '/^\s*bind\s*=\s*\$mainMod,\s*A,\s*global,\s*quickshell:overviewToggle/{s/^\s*/#/}' config/hypr/UserConfigs/UserKeybinds.conf + # Comment the quickshell line if not already commented + sed -i '/^\s*bind\s*=\s*\$mainMod,\s*A,\s*global,\s*quickshell:overviewToggle/{s/^\s*/#/}' config/hypr/UserConfigs/UserKeybinds.conf fi # Check if quickshell is installed; edit quickshell behaviour on configs if command -v qs >/dev/null 2>&1; then - sed -i '/^\s*#exec-once = qs/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf - sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh - sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh + sed -i '/^\s*#exec-once = qs/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf + sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh + sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh - # Uncomment the quickshell keybind line - sed -i "/^#bind = \$mainMod, A, global, quickshell:overviewToggle/s/^#//" config/hypr/UserConfigs/UserKeybinds.conf + # Uncomment the quickshell keybind line + sed -i "/^#bind = \$mainMod, A, global, quickshell:overviewToggle/s/^#//" config/hypr/UserConfigs/UserKeybinds.conf - # Ensure the ags overview keybind is commented - sed -i "/^\s*bind\s*=\s*\\\$mainMod,\s*A,\s*exec,\s*pkill rofi\s*||\s*true\s*&&\s*ags\s*-t\s*'overview'/{s/^\s*/#/}" config/hypr/UserConfigs/UserKeybinds.conf + # Ensure the ags overview keybind is commented + sed -i "/^\s*bind\s*=\s*\\\$mainMod,\s*A,\s*exec,\s*pkill rofi\s*||\s*true\s*&&\s*ags\s*-t\s*'overview'/{s/^\s*/#/}" config/hypr/UserConfigs/UserKeybinds.conf fi printf "\n%.0s" {1..1} @@ -265,34 +275,34 @@ printf "\n%.0s" {1..1} # Checking if neovim or vim is installed and offer user if they want to make as default editor # Function to modify the ENVariables.conf file update_editor() { - local editor=$1 - sed -i "s/#env = EDITOR,.*/env = EDITOR,$editor #default editor/" config/hypr/UserConfigs/01-UserDefaults.conf - echo "${OK} Default editor set to ${MAGENTA}$editor${RESET}." 2>&1 | tee -a "$LOG" + local editor=$1 + sed -i "s/#env = EDITOR,.*/env = EDITOR,$editor #default editor/" config/hypr/UserConfigs/01-UserDefaults.conf + echo "${OK} Default editor set to ${MAGENTA}$editor${RESET}." 2>&1 | tee -a "$LOG" } EDITOR_SET=0 # Check for neovim if installed -if command -v nvim &> /dev/null; then - printf "${INFO} ${MAGENTA}neovim${RESET} is detected as installed\n" - echo -n "${CAT} Do you want to make ${MAGENTA}neovim${RESET} the default editor? (y/N): " - read EDITOR_CHOICE - if [[ "$EDITOR_CHOICE" == "y" || "$EDITOR_CHOICE" == "Y" ]]; then - update_editor "nvim" - EDITOR_SET=1 - fi +if command -v nvim &>/dev/null; then + printf "${INFO} ${MAGENTA}neovim${RESET} is detected as installed\n" + echo -n "${CAT} Do you want to make ${MAGENTA}neovim${RESET} the default editor? (y/N): " + read EDITOR_CHOICE + if [[ "$EDITOR_CHOICE" == "y" || "$EDITOR_CHOICE" == "Y" ]]; then + update_editor "nvim" + EDITOR_SET=1 + fi fi printf "\n" # Check for vim if installed, but only if neovim wasn't chosen -if [[ "$EDITOR_SET" -eq 0 ]] && command -v vim &> /dev/null; then - printf "${INFO} ${MAGENTA}vim${RESET} is detected as installed\n" - echo -n "${CAT} Do you want to make ${MAGENTA}vim${RESET} the default editor? (y/N): " - read EDITOR_CHOICE - if [[ "$EDITOR_CHOICE" == "y" || "$EDITOR_CHOICE" == "Y" ]]; then - update_editor "vim" - EDITOR_SET=1 - fi +if [[ "$EDITOR_SET" -eq 0 ]] && command -v vim &>/dev/null; then + printf "${INFO} ${MAGENTA}vim${RESET} is detected as installed\n" + echo -n "${CAT} Do you want to make ${MAGENTA}vim${RESET} the default editor? (y/N): " + read EDITOR_CHOICE + if [[ "$EDITOR_CHOICE" == "y" || "$EDITOR_CHOICE" == "Y" ]]; then + update_editor "vim" + EDITOR_SET=1 + fi fi printf "\n" @@ -305,22 +315,22 @@ while true; do echo "${MAGENTA}Select monitor resolution to properly configure appearance and fonts:" echo "$YELLOW -- Enter 1. for monitor resolution less than 1440p (< 1440p)" echo "$YELLOW -- Enter 2. for monitor resolution equal to or higher than 1440p (≥ 1440p)" - + echo -n "$CAT Enter the number of your choice (1 or 2): " read res_choice case $res_choice in - 1) - resolution="< 1440p" - break - ;; - 2) - resolution="≥ 1440p" - break - ;; - *) - echo "${ERROR} Invalid choice. Please enter 1 for < 1440p or 2 for ≥ 1440p." - ;; + 1) + resolution="< 1440p" + break + ;; + 2) + resolution="≥ 1440p" + break + ;; + *) + echo "${ERROR} Invalid choice. Please enter 1 for < 1440p or 2 for ≥ 1440p." + ;; esac done @@ -343,8 +353,8 @@ if [ "$resolution" == "< 1440p" ]; then # rofi fonts reduction rofi_config_file="config/rofi/0-shared-fonts.rasi" if [ -f "$rofi_config_file" ]; then - sed -i '/element-text {/,/}/s/[[:space:]]*font: "JetBrainsMono Nerd Font SemiBold 13"/font: "JetBrainsMono Nerd Font SemiBold 11"/' "$rofi_config_file" 2>&1 | tee -a "$LOG" - sed -i '/configuration {/,/}/s/[[:space:]]*font: "JetBrainsMono Nerd Font SemiBold 15"/font: "JetBrainsMono Nerd Font SemiBold 13"/' "$rofi_config_file" 2>&1 | tee -a "$LOG" + sed -i '/element-text {/,/}/s/[[:space:]]*font: "JetBrainsMono Nerd Font SemiBold 13"/font: "JetBrainsMono Nerd Font SemiBold 11"/' "$rofi_config_file" 2>&1 | tee -a "$LOG" + sed -i '/configuration {/,/}/s/[[:space:]]*font: "JetBrainsMono Nerd Font SemiBold 15"/font: "JetBrainsMono Nerd Font SemiBold 13"/' "$rofi_config_file" 2>&1 | tee -a "$LOG" fi fi @@ -352,46 +362,46 @@ printf "\n%.0s" {1..1} # Ask whether to change to 12hr format while true; do - echo -e "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured in 24H clock format." - echo -n "$CAT Do you want to change to 12H (AM/PM) clock format? (y/n): " - read answer + echo -e "${NOTE} ${SKY_BLUE} By default, KooL's Dots are configured in 24H clock format." + echo -n "$CAT Do you want to change to 12H (AM/PM) clock format? (y/n): " + read answer - # Convert the answer to lowercase for comparison - answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]') + # Convert the answer to lowercase for comparison + answer=$(echo "$answer" | tr '[:upper:]' '[:lower:]') - # Check if the answer is valid - if [[ "$answer" == "y" ]]; then - # Modify waybar clock modules if 12hr is selected - # Clock 1 - sed -i 's#^\(\s*\)//\("format": " {:%I:%M %p}",\) #\1\2 #g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": " {:%H:%M:%S}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # Clock 2 - sed -i 's#^\(\s*\)\("format": " {:%H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # Clock 3 - sed -i 's#^\(\s*\)//\("format": "{:%I:%M %p - %d/%b}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": "{:%H:%M - %d/%b}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # Clock 4 - sed -i 's#^\(\s*\)//\("format": "{:%B | %a %d, %Y | %I:%M %p}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": "{:%B | %a %d, %Y | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" + # Check if the answer is valid + if [[ "$answer" == "y" ]]; then + # Modify waybar clock modules if 12hr is selected + # Clock 1 + sed -i 's#^\(\s*\)//\("format": " {:%I:%M %p}",\) #\1\2 #g' config/waybar/Modules 2>&1 | tee -a "$LOG" + sed -i 's#^\(\s*\)\("format": " {:%H:%M:%S}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - # Clock 5 - sed -i 's#^\(\s*\)//\("format": "{:%A, %I:%M %P}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's#^\(\s*\)\("format": "{:%a %d | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - - # for hyprlock - sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%H")"/# &/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" - sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo "\$(date +"%I")" #AM\/PM/\1 text = cmd\[update:1000\] echo "\$(date +"%I")" #AM\/PM/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" + # Clock 2 + sed -i 's#^\(\s*\)\("format": " {:%H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%S")"/# &/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" - sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo "\$(date +"%S %p")" #AM\/PM/\1 text = cmd\[update:1000\] echo "\$(date +"%S %p")" #AM\/PM/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" - - echo "${OK} 12H format set on waybar clocks succesfully." 2>&1 | tee -a "$LOG" + # Clock 3 + sed -i 's#^\(\s*\)//\("format": "{:%I:%M %p - %d/%b}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" + sed -i 's#^\(\s*\)\("format": "{:%H:%M - %d/%b}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" - # Function to apply 12H format to SDDM themes - apply_sddm_12h_format() { + # Clock 4 + sed -i 's#^\(\s*\)//\("format": "{:%B | %a %d, %Y | %I:%M %p}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" + sed -i 's#^\(\s*\)\("format": "{:%B | %a %d, %Y | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" + + # Clock 5 + sed -i 's#^\(\s*\)//\("format": "{:%A, %I:%M %P}",\) #\1\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" + sed -i 's#^\(\s*\)\("format": "{:%a %d | %H:%M}",\) #\1//\2#g' config/waybar/Modules 2>&1 | tee -a "$LOG" + + # for hyprlock + sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%H")"/# &/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" + sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo "\$(date +"%I")" #AM\/PM/\1 text = cmd\[update:1000\] echo "\$(date +"%I")" #AM\/PM/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" + + sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%S")"/# &/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" + sed -i 's/^\(\s*\)# *text = cmd\[update:1000\] echo "\$(date +"%S %p")" #AM\/PM/\1 text = cmd\[update:1000\] echo "\$(date +"%S %p")" #AM\/PM/' config/hypr/hyprlock.conf 2>&1 | tee -a "$LOG" + + echo "${OK} 12H format set on waybar clocks succesfully." 2>&1 | tee -a "$LOG" + + # Function to apply 12H format to SDDM themes + apply_sddm_12h_format() { local sddm_directory=$1 # Check if the directory exists @@ -401,36 +411,36 @@ while true; do sudo sed -i 's|^## HourFormat="hh:mm AP"|HourFormat="hh:mm AP"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$LOG" || true sudo sed -i 's|^HourFormat="HH:mm"|## HourFormat="HH:mm"|' "$sddm_directory/theme.conf" 2>&1 | tee -a "$LOG" || true fi - } + } - # Applying to different SDDM themes - apply_sddm_12h_format "/usr/share/sddm/themes/simple-sddm" - apply_sddm_12h_format "/usr/share/sddm/themes/simple_sddm_2" + # Applying to different SDDM themes + apply_sddm_12h_format "/usr/share/sddm/themes/simple-sddm" + apply_sddm_12h_format "/usr/share/sddm/themes/simple_sddm_2" - # For SDDM (sequoia_2) - sddm_directory_3="/usr/share/sddm/themes/sequoia_2" - if [ -d "$sddm_directory_3" ]; then - echo "${YELLOW}sddm sequoia_2${RESET} theme exists. Editing to 12H format" 2>&1 | tee -a "$LOG" + # For SDDM (sequoia_2) + sddm_directory_3="/usr/share/sddm/themes/sequoia_2" + if [ -d "$sddm_directory_3" ]; then + echo "${YELLOW}sddm sequoia_2${RESET} theme exists. Editing to 12H format" 2>&1 | tee -a "$LOG" - # Comment out the existing clockFormat="HH:mm" line - sudo sed -i 's|^clockFormat="HH:mm"|## clockFormat="HH:mm"|' "$sddm_directory_3/theme.conf" 2>&1 | tee -a "$LOG" || true + # Comment out the existing clockFormat="HH:mm" line + sudo sed -i 's|^clockFormat="HH:mm"|## clockFormat="HH:mm"|' "$sddm_directory_3/theme.conf" 2>&1 | tee -a "$LOG" || true - # Insert the new clockFormat="hh:mm AP" line if it's not already present - if ! grep -q 'clockFormat="hh:mm AP"' "$sddm_directory_3/theme.conf"; then - sudo sed -i '/^clockFormat=/a clockFormat="hh:mm AP"' "$sddm_directory_3/theme.conf" 2>&1 | tee -a "$LOG" || true - fi - - echo "${OK} 12H format set to SDDM successfully." 2>&1 | tee -a "$LOG" + # Insert the new clockFormat="hh:mm AP" line if it's not already present + if ! grep -q 'clockFormat="hh:mm AP"' "$sddm_directory_3/theme.conf"; then + sudo sed -i '/^clockFormat=/a clockFormat="hh:mm AP"' "$sddm_directory_3/theme.conf" 2>&1 | tee -a "$LOG" || true fi - break - - elif [[ "$answer" == "n" ]]; then - echo "${NOTE} You chose not to change to 12H format." 2>&1 | tee -a "$LOG" - break # Exit the loop if the user chooses "n" - else - echo "${ERROR} Invalid choice. Please enter y for yes or n for no." + echo "${OK} 12H format set to SDDM successfully." 2>&1 | tee -a "$LOG" fi + + break + + elif [[ "$answer" == "n" ]]; then + echo "${NOTE} You chose not to change to 12H format." 2>&1 | tee -a "$LOG" + break # Exit the loop if the user chooses "n" + else + echo "${ERROR} Invalid choice. Please enter y for yes or n for no." + fi done printf "\n%.0s" {1..1} @@ -444,16 +454,16 @@ read border_choice # Check user's choice if [[ "$border_choice" =~ ^[Yy]$ ]]; then - # Disable Rainbow Borders - mv config/hypr/UserScripts/RainbowBorders.sh config/hypr/UserScripts/RainbowBorders.bak.sh - - # Comment out the exec-once and animation lines - sed -i '/exec-once = \$UserScripts\/RainbowBorders.sh/s/^/#/' config/hypr/UserConfigs/Startup_Apps.conf - sed -i '/^[[:space:]]*animation = borderangle, 1, 180, liner, loop/s/^/#/' config/hypr/UserConfigs/UserAnimations.conf - - echo "${OK} Rainbow borders are now disabled." 2>&1 | tee -a "$LOG" + # Disable Rainbow Borders + mv config/hypr/UserScripts/RainbowBorders.sh config/hypr/UserScripts/RainbowBorders.bak.sh + + # Comment out the exec-once and animation lines + sed -i '/exec-once = \$UserScripts\/RainbowBorders.sh/s/^/#/' config/hypr/UserConfigs/Startup_Apps.conf + sed -i '/^[[:space:]]*animation = borderangle, 1, 180, liner, loop/s/^/#/' config/hypr/UserConfigs/UserAnimations.conf + + echo "${OK} Rainbow borders are now disabled." 2>&1 | tee -a "$LOG" else - echo "${NOTE} No changes made. Rainbow borders remain enabled." 2>&1 | tee -a "$LOG" + echo "${NOTE} No changes made. Rainbow borders remain enabled." 2>&1 | tee -a "$LOG" fi printf "\n%.0s" {1..1} @@ -478,7 +488,7 @@ DIRS="fastfetch kitty rofi swaync" for DIR2 in $DIRS; do DIRPATH="$HOME/.config/$DIR2" - + if [ -d "$DIRPATH" ]; then while true; do printf "\n${INFO} Found ${YELLOW}$DIR2${RESET} config found in ~/.config/\n" @@ -486,43 +496,43 @@ for DIR2 in $DIRS; do read DIR1_CHOICE case "$DIR1_CHOICE" in - [Yy]* ) - BACKUP_DIR=$(get_backup_dirname) - # Backup the existing directory - mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" - echo -e "${NOTE} - Backed up $DIR2 to $DIRPATH-backup-$BACKUP_DIR." 2>&1 | tee -a "$LOG" + [Yy]*) + BACKUP_DIR=$(get_backup_dirname) + # Backup the existing directory + mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" + echo -e "${NOTE} - Backed up $DIR2 to $DIRPATH-backup-$BACKUP_DIR." 2>&1 | tee -a "$LOG" - # Copy the new config - cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$LOG" - echo -e "${OK} - Replaced $DIR2 with new configuration." 2>&1 | tee -a "$LOG" - - # Restoring rofi themes directory unique themes - if [ "$DIR2" = "rofi" ]; then - if [ -d "$DIRPATH-backup-$BACKUP_DIR/themes" ]; then - for file in "$DIRPATH-backup-$BACKUP_DIR/themes"/*; do - [ -e "$file" ] || continue # Skip if no files are found - echo "Copying $file to $HOME/.config/rofi/themes/" >> "$LOG" - cp -n "$file" "$HOME/.config/rofi/themes/" >> "$LOG" 2>&1 - done || true - fi - - # restoring global 0-shared-fonts.rasi - if [ -f "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" ]; then - echo "Restoring $DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi to $HOME/.config/rofi/" >> "$LOG" - cp "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" "$HOME/.config/rofi/0-shared-fonts.rasi" >> "$LOG" 2>&1 - fi + # Copy the new config + cp -r "config/$DIR2" "$HOME/.config/$DIR2" 2>&1 | tee -a "$LOG" + echo -e "${OK} - Replaced $DIR2 with new configuration." 2>&1 | tee -a "$LOG" + # Restoring rofi themes directory unique themes + if [ "$DIR2" = "rofi" ]; then + if [ -d "$DIRPATH-backup-$BACKUP_DIR/themes" ]; then + for file in "$DIRPATH-backup-$BACKUP_DIR/themes"/*; do + [ -e "$file" ] || continue # Skip if no files are found + echo "Copying $file to $HOME/.config/rofi/themes/" >>"$LOG" + cp -n "$file" "$HOME/.config/rofi/themes/" >>"$LOG" 2>&1 + done || true fi - break - ;; - [Nn]* ) - echo -e "${NOTE} - Skipping ${YELLOW}$DIR2${RESET}" 2>&1 | tee -a "$LOG" - break - ;; - * ) - echo -e "${WARN} - Invalid choice. Please enter Y or N." - ;; + # restoring global 0-shared-fonts.rasi + if [ -f "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" ]; then + echo "Restoring $DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi to $HOME/.config/rofi/" >>"$LOG" + cp "$DIRPATH-backup-$BACKUP_DIR/0-shared-fonts.rasi" "$HOME/.config/rofi/0-shared-fonts.rasi" >>"$LOG" 2>&1 + fi + + fi + + break + ;; + [Nn]*) + echo -e "${NOTE} - Skipping ${YELLOW}$DIR2${RESET}" 2>&1 | tee -a "$LOG" + break + ;; + *) + echo -e "${WARN} - Invalid choice. Please enter Y or N." + ;; esac done else @@ -538,103 +548,103 @@ printf "\n%.0s" {1..1} DIRW="waybar" DIRPATHw="$HOME/.config/$DIRW" if [ -d "$DIRPATHw" ]; then - while true; do - echo -n "${CAT} Do you want to replace ${YELLOW}$DIRW${RESET} config? (y/n): " - read DIR1_CHOICE + while true; do + echo -n "${CAT} Do you want to replace ${YELLOW}$DIRW${RESET} config? (y/n): " + read DIR1_CHOICE - case "$DIR1_CHOICE" in - [Yy]* ) - BACKUP_DIR=$(get_backup_dirname) - cp -r "$DIRPATHw" "$DIRPATHw-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" - echo -e "${NOTE} - Backed up $DIRW to $DIRPATHw-backup-$BACKUP_DIR." 2>&1 | tee -a "$LOG" - - # Remove the old $DIRPATHw and copy the new one - rm -rf "$DIRPATHw" && cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$LOG" - - # Step 1: Handle waybar symlinks - for file in "config" "style.css"; do - symlink="$DIRPATHw-backup-$BACKUP_DIR/$file" - target_file="$DIRPATHw/$file" - - if [ -L "$symlink" ]; then - symlink_target=$(readlink "$symlink") - if [ -f "$symlink_target" ]; then - rm -f "$target_file" && cp -f "$symlink_target" "$target_file" - echo -e "${NOTE} - Copied $file as a regular file." - else - echo -e "${WARN} - Symlink target for $file does not exist." - fi - fi - done - - # Step 2: Copy non-existing directories and files under waybar/configs - for dir in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do - [ -e "$dir" ] || continue # Skip if no files are found - if [ -d "$dir" ]; then - target_dir="$HOME/.config/waybar/configs/$(basename "$dir")" - if [ ! -d "$target_dir" ]; then - echo "Copying directory $dir to $HOME/.config/waybar/configs/" >> "$LOG" - cp -r "$dir" "$HOME/.config/waybar/configs/" - else - echo "Directory $target_dir already exists. Skipping." >> "$LOG" - fi - fi - done + case "$DIR1_CHOICE" in + [Yy]*) + BACKUP_DIR=$(get_backup_dirname) + cp -r "$DIRPATHw" "$DIRPATHw-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" + echo -e "${NOTE} - Backed up $DIRW to $DIRPATHw-backup-$BACKUP_DIR." 2>&1 | tee -a "$LOG" - for file in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do - [ -e "$file" ] || continue - target_file="$HOME/.config/waybar/configs/$(basename "$file")" - if [ ! -e "$target_file" ]; then - echo "Copying $file to $HOME/.config/waybar/configs/" >> "$LOG" - cp "$file" "$HOME/.config/waybar/configs/" - else - echo "File $target_file already exists. Skipping." >> "$LOG" - fi - done || true - - # Step 3: Copy unique files in waybar/style - for file in "$DIRPATHw-backup-$BACKUP_DIR/style"/*; do - [ -e "$file" ] || continue - - if [ -d "$file" ]; then - target_dir="$HOME/.config/waybar/style/$(basename "$file")" - if [ ! -d "$target_dir" ]; then - echo "Copying directory $file to $HOME/.config/waybar/style/" >> "$LOG" - cp -r "$file" "$HOME/.config/waybar/style/" - else - echo "Directory $target_dir already exists. Skipping." >> "$LOG" - fi - else - target_file="$HOME/.config/waybar/style/$(basename "$file")" - if [ ! -e "$target_file" ]; then - echo "Copying file $file to $HOME/.config/waybar/style/" >> "$LOG" - cp "$file" "$HOME/.config/waybar/style/" - else - echo "File $target_file already exists. Skipping." >> "$LOG" - fi - fi - done || true + # Remove the old $DIRPATHw and copy the new one + rm -rf "$DIRPATHw" && cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$LOG" - # Step 4: restore Modules_Extras - BACKUP_FILEw="$DIRPATHw-backup-$BACKUP_DIR/UserModules" - if [ -f "$BACKUP_FILEw" ]; then - cp -f "$BACKUP_FILEw" "$DIRPATHw/UserModules" - fi + # Step 1: Handle waybar symlinks + for file in "config" "style.css"; do + symlink="$DIRPATHw-backup-$BACKUP_DIR/$file" + target_file="$DIRPATHw/$file" - break - ;; - [Nn]* ) - echo -e "${NOTE} - Skipping ${YELLOW}$DIRW${RESET} config replacement." 2>&1 | tee -a "$LOG" - break - ;; - * ) - echo -e "${WARN} - Invalid choice. Please enter Y or N." - ;; - esac - done + if [ -L "$symlink" ]; then + symlink_target=$(readlink "$symlink") + if [ -f "$symlink_target" ]; then + rm -f "$target_file" && cp -f "$symlink_target" "$target_file" + echo -e "${NOTE} - Copied $file as a regular file." + else + echo -e "${WARN} - Symlink target for $file does not exist." + fi + fi + done + + # Step 2: Copy non-existing directories and files under waybar/configs + for dir in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do + [ -e "$dir" ] || continue # Skip if no files are found + if [ -d "$dir" ]; then + target_dir="$HOME/.config/waybar/configs/$(basename "$dir")" + if [ ! -d "$target_dir" ]; then + echo "Copying directory $dir to $HOME/.config/waybar/configs/" >>"$LOG" + cp -r "$dir" "$HOME/.config/waybar/configs/" + else + echo "Directory $target_dir already exists. Skipping." >>"$LOG" + fi + fi + done + + for file in "$DIRPATHw-backup-$BACKUP_DIR/configs"/*; do + [ -e "$file" ] || continue + target_file="$HOME/.config/waybar/configs/$(basename "$file")" + if [ ! -e "$target_file" ]; then + echo "Copying $file to $HOME/.config/waybar/configs/" >>"$LOG" + cp "$file" "$HOME/.config/waybar/configs/" + else + echo "File $target_file already exists. Skipping." >>"$LOG" + fi + done || true + + # Step 3: Copy unique files in waybar/style + for file in "$DIRPATHw-backup-$BACKUP_DIR/style"/*; do + [ -e "$file" ] || continue + + if [ -d "$file" ]; then + target_dir="$HOME/.config/waybar/style/$(basename "$file")" + if [ ! -d "$target_dir" ]; then + echo "Copying directory $file to $HOME/.config/waybar/style/" >>"$LOG" + cp -r "$file" "$HOME/.config/waybar/style/" + else + echo "Directory $target_dir already exists. Skipping." >>"$LOG" + fi + else + target_file="$HOME/.config/waybar/style/$(basename "$file")" + if [ ! -e "$target_file" ]; then + echo "Copying file $file to $HOME/.config/waybar/style/" >>"$LOG" + cp "$file" "$HOME/.config/waybar/style/" + else + echo "File $target_file already exists. Skipping." >>"$LOG" + fi + fi + done || true + + # Step 4: restore Modules_Extras + BACKUP_FILEw="$DIRPATHw-backup-$BACKUP_DIR/UserModules" + if [ -f "$BACKUP_FILEw" ]; then + cp -f "$BACKUP_FILEw" "$DIRPATHw/UserModules" + fi + + break + ;; + [Nn]*) + echo -e "${NOTE} - Skipping ${YELLOW}$DIRW${RESET} config replacement." 2>&1 | tee -a "$LOG" + break + ;; + *) + echo -e "${WARN} - Invalid choice. Please enter Y or N." + ;; + esac + done else - cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$LOG" - echo -e "${OK} - Copy completed for ${YELLOW}$DIRW${RESET}" 2>&1 | tee -a "$LOG" + cp -r "config/$DIRW" "$DIRPATHw" 2>&1 | tee -a "$LOG" + echo -e "${OK} - Copy completed for ${YELLOW}$DIRW${RESET}" 2>&1 | tee -a "$LOG" fi printf "\n%.0s" {1..1} @@ -651,12 +661,12 @@ DIR="btop cava hypr Kvantum qt5ct qt6ct swappy wallust wlogout" for DIR_NAME in $DIR; do DIRPATH="$HOME/.config/$DIR_NAME" - + # Backup the existing directory if it exists if [ -d "$DIRPATH" ]; then echo -e "\n${NOTE} - Config for ${YELLOW}$DIR_NAME${RESET} found, attempting to back up." BACKUP_DIR=$(get_backup_dirname) - + # Backup the existing directory mv "$DIRPATH" "$DIRPATH-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" if [ $? -eq 0 ]; then @@ -666,7 +676,7 @@ for DIR_NAME in $DIR; do exit 1 fi fi - + # Copy the new config if [ -d "config/$DIR_NAME" ]; then cp -r "config/$DIR_NAME/" "$HOME/.config/$DIR_NAME" 2>&1 | tee -a "$LOG" @@ -698,21 +708,21 @@ if command -v ags >/dev/null 2>&1; then else read -p "${CAT} Do you want to overwrite your existing ${YELLOW}ags${RESET} config? [y/N] " answer_ags case "$answer_ags" in - [Yy]* ) - BACKUP_DIR=$(get_backup_dirname) - mv "$DIRPATH_AGS" "$DIRPATH_AGS-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" - echo -e "${NOTE} - Backed up ags config to $DIRPATH_AGS-backup-$BACKUP_DIR" - - if cp -r "config/ags/" "$DIRPATH_AGS" 2>&1 | tee -a "$LOG"; then - echo "${OK} - ${YELLOW}ags configs${RESET} overwritten successfully." - else - echo "${ERROR} - Failed to copy ${YELLOW}ags${RESET} config." - exit 1 - fi - ;; - * ) - echo "${NOTE} - Skipping overwrite of ags config." - ;; + [Yy]*) + BACKUP_DIR=$(get_backup_dirname) + mv "$DIRPATH_AGS" "$DIRPATH_AGS-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" + echo -e "${NOTE} - Backed up ags config to $DIRPATH_AGS-backup-$BACKUP_DIR" + + if cp -r "config/ags/" "$DIRPATH_AGS" 2>&1 | tee -a "$LOG"; then + echo "${OK} - ${YELLOW}ags configs${RESET} overwritten successfully." + else + echo "${ERROR} - Failed to copy ${YELLOW}ags${RESET} config." + exit 1 + fi + ;; + *) + echo "${NOTE} - Skipping overwrite of ags config." + ;; esac fi fi @@ -734,28 +744,27 @@ if command -v qs >/dev/null 2>&1; then else read -p "${CAT} Do you want to overwrite your existing ${YELLOW}quickshell${RESET} config? [y/N] " answer_qs case "$answer_qs" in - [Yy]* ) - BACKUP_DIR=$(get_backup_dirname) - mv "$DIRPATH_QS" "$DIRPATH_QS-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" - echo -e "${NOTE} - Backed up quickshell to $DIRPATH_QS-backup-$BACKUP_DIR" - - cp -r "config/quickshell/" "$DIRPATH_QS" 2>&1 | tee -a "$LOG" - if [ $? -eq 0 ]; then - echo "${OK} - ${YELLOW}quickshell${RESET} overwritten successfully." - else - echo "${ERROR} - Failed to copy ${YELLOW}quickshell${RESET} config." - exit 1 - fi - ;; - * ) - echo "${NOTE} - Skipping overwrite of quickshell config." - ;; + [Yy]*) + BACKUP_DIR=$(get_backup_dirname) + mv "$DIRPATH_QS" "$DIRPATH_QS-backup-$BACKUP_DIR" 2>&1 | tee -a "$LOG" + echo -e "${NOTE} - Backed up quickshell to $DIRPATH_QS-backup-$BACKUP_DIR" + + cp -r "config/quickshell/" "$DIRPATH_QS" 2>&1 | tee -a "$LOG" + if [ $? -eq 0 ]; then + echo "${OK} - ${YELLOW}quickshell${RESET} overwritten successfully." + else + echo "${ERROR} - Failed to copy ${YELLOW}quickshell${RESET} config." + exit 1 + fi + ;; + *) + echo "${NOTE} - Skipping overwrite of quickshell config." + ;; esac fi fi printf "\n%.0s" {1..1} - # Restore automatically Animations and Monitor-Profiles # including monitors.conf and workspaces.conf HYPR_DIR="$HOME/.config/hypr" @@ -764,14 +773,14 @@ BACKUP_HYPR_PATH="$HYPR_DIR-backup-$BACKUP_DIR" if [ -d "$BACKUP_HYPR_PATH" ]; then echo -e "\n${NOTE} Restoring ${SKY_BLUE}Animations & Monitor Profiles${RESET} directories into ${YELLOW}$HYPR_DIR${RESET}..." - + DIR_B=("Monitor_Profiles" "animations" "wallpaper_effects") - # Restore directories automatically + # Restore directories automatically for DIR_RESTORE in "${DIR_B[@]}"; do BACKUP_SUBDIR="$BACKUP_HYPR_PATH/$DIR_RESTORE" - + if [ -d "$BACKUP_SUBDIR" ]; then - cp -r "$BACKUP_SUBDIR" "$HYPR_DIR/" + cp -r "$BACKUP_SUBDIR" "$HYPR_DIR/" echo "${OK} - Restored directory: ${MAGENTA}$DIR_RESTORE${RESET}" 2>&1 | tee -a "$LOG" fi done @@ -782,7 +791,7 @@ if [ -d "$BACKUP_HYPR_PATH" ]; then BACKUP_FILE="$BACKUP_HYPR_PATH/$FILE_RESTORE" if [ -f "$BACKUP_FILE" ]; then - cp "$BACKUP_FILE" "$HYPR_DIR/$FILE_RESTORE" + cp "$BACKUP_FILE" "$HYPR_DIR/$FILE_RESTORE" echo "${OK} - Restored file: ${MAGENTA}$FILE_RESTORE${RESET}" 2>&1 | tee -a "$LOG" fi done @@ -815,8 +824,8 @@ if [ -z "$BACKUP_DIR" ]; then fi if [ -d "$BACKUP_DIR_PATH" ]; then - echo -e "${NOTE} Restoring previous ${MAGENTA}User-Configs${RESET}... " - print_color $WARNING " + echo -e "${NOTE} Restoring previous ${MAGENTA}User-Configs${RESET}... " + print_color $WARNING " █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ NOTES for RESTORING PREVIOUS CONFIGS █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ @@ -824,8 +833,7 @@ if [ -d "$BACKUP_DIR_PATH" ]; then If you decide to restore your old configs, make sure to handle the updates or changes manually !!! " - echo -e "${MAGENTA}Kindly Visit and check KooL's Hyprland-Dots GitHub page for the history of commits.${RESET}" - + echo -e "${MAGENTA}Kindly Visit and check KooL's Hyprland-Dots GitHub page for the history of commits.${RESET}" for FILE_NAME in "${FILES_TO_RESTORE[@]}"; do BACKUP_FILE="$BACKUP_DIR_PATH/$FILE_NAME" @@ -870,7 +878,7 @@ if [ -d "$BACKUP_DIR_PATH_S" ]; then printf "\n${INFO} Found ${YELLOW}$SCRIPT_NAME${RESET} in hypr backup...\n" echo -n "${CAT} Do you want to restore ${YELLOW}$SCRIPT_NAME${RESET} from backup? (y/N): " read script_restore - + if [[ "$script_restore" == [Yy]* ]]; then if cp "$BACKUP_SCRIPT" "$DIRSHPATH/UserScripts/$SCRIPT_NAME"; then echo "${OK} - $SCRIPT_NAME restored!" 2>&1 | tee -a "$LOG" @@ -902,7 +910,7 @@ if [ -d "$BACKUP_DIR_PATH_F" ]; then for FILE_RESTORE in "${FILES_2_RESTORE[@]}"; do BACKUP_FILE="$BACKUP_DIR_PATH_F/$FILE_RESTORE" - + if [ -f "$BACKUP_FILE" ]; then echo -e "\n${INFO} Found ${YELLOW}$FILE_RESTORE${RESET} in hypr backup..." echo -n "${CAT} Do you want to restore ${YELLOW}$FILE_RESTORE${RESET} from backup? (y/N): " @@ -933,7 +941,7 @@ if [ ! -d "$rofi_DIR" ]; then fi if [ -d "$HOME/.config/rofi/themes" ]; then if [ -z "$(ls -A $HOME/.config/rofi/themes)" ]; then - echo '/* Dummy Rofi theme */' > "$HOME/.config/rofi/themes/dummy.rasi" + echo '/* Dummy Rofi theme */' >"$HOME/.config/rofi/themes/dummy.rasi" fi ln -snf "$HOME/.config/rofi/themes/"* "$HOME/.local/share/rofi/themes/" # Delete the dummy file if it was created @@ -951,7 +959,7 @@ if cp -r wallpapers $HOME/Pictures/; then else echo "${ERROR} Failed to copy some ${YELLOW}wallpapers${RESET}" | tee -a "$LOG" fi - + # Set some files as executable chmod +x "$HOME/.config/hypr/scripts/"* 2>&1 | tee -a "$LOG" chmod +x "$HOME/.config/hypr/UserScripts/"* 2>&1 | tee -a "$LOG" @@ -960,26 +968,25 @@ chmod +x "$HOME/.config/hypr/initial-boot.sh" 2>&1 | tee -a "$LOG" # Waybar config to symlink & retain based on machine type if hostnamectl | grep -q 'Chassis: desktop'; then - config_file="$waybar_config" - config_remove=" Laptop" + config_file="$waybar_config" + config_remove=" Laptop" else - config_file="$waybar_config_laptop" - config_remove="" + config_file="$waybar_config_laptop" + config_remove="" fi # Check if ~/.config/waybar/config does not exist or is a symlink if [ ! -e "$HOME/.config/waybar/config" ] || [ -L "$HOME/.config/waybar/config" ]; then - ln -sf "$config_file" "$HOME/.config/waybar/config" 2>&1 | tee -a "$LOG" + ln -sf "$config_file" "$HOME/.config/waybar/config" 2>&1 | tee -a "$LOG" fi - # Remove inappropriate waybar configs rm -rf "$HOME/.config/waybar/configs/[TOP] Default$config_remove" \ - "$HOME/.config/waybar/configs/[BOT] Default$config_remove" \ - "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v1)" \ - "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v2)" \ - "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v3)" \ - "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v4)" 2>&1 | tee -a "$LOG" || true + "$HOME/.config/waybar/configs/[BOT] Default$config_remove" \ + "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v1)" \ + "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v2)" \ + "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v3)" \ + "$HOME/.config/waybar/configs/[TOP] Default$config_remove (old v4)" 2>&1 | tee -a "$LOG" || true printf "\n%.0s" {1..1} @@ -989,24 +996,24 @@ if [ -d "$sddm_simple_sddm_2" ]; then while true; do echo -n "${CAT} SDDM simple_sddm_2 theme detected! Apply current wallpaper as SDDM background? (y/n): " read SDDM_WALL - + # Remove any leading/trailing whitespace or newlines from input SDDM_WALL=$(echo "$SDDM_WALL" | tr -d '\n' | tr -d ' ') case $SDDM_WALL in - [Yy]) - # Copy the wallpaper, ignore errors if the file exists or fails - sudo cp -r "config/hypr/wallpaper_effects/.wallpaper_current" "/usr/share/sddm/themes/simple_sddm_2/Backgrounds/default" || true - echo "${NOTE} Current wallpaper applied as default SDDM background" 2>&1 | tee -a "$LOG" - break - ;; - [Nn]) - echo "${NOTE} You chose not to apply the current wallpaper to SDDM." 2>&1 | tee -a "$LOG" - break - ;; - *) - echo "Please enter 'y' or 'n' to proceed." - ;; + [Yy]) + # Copy the wallpaper, ignore errors if the file exists or fails + sudo cp -r "config/hypr/wallpaper_effects/.wallpaper_current" "/usr/share/sddm/themes/simple_sddm_2/Backgrounds/default" || true + echo "${NOTE} Current wallpaper applied as default SDDM background" 2>&1 | tee -a "$LOG" + break + ;; + [Nn]) + echo "${NOTE} You chose not to apply the current wallpaper to SDDM." 2>&1 | tee -a "$LOG" + break + ;; + *) + echo "Please enter 'y' or 'n' to proceed." + ;; esac done fi @@ -1018,37 +1025,37 @@ echo "${MAGENTA}By default only a few wallpapers are copied${RESET}..." while true; do echo -n "${CAT} Would you like to download additional wallpapers? ${WARN} This is 1GB in size (y/n): " read WALL - + case $WALL in - [Yy]) - echo "${NOTE} Downloading additional wallpapers..." - if git clone "https://github.com/JaKooLit/Wallpaper-Bank.git"; then - echo "${OK} Wallpapers downloaded successfully." 2>&1 | tee -a "$LOG" + [Yy]) + echo "${NOTE} Downloading additional wallpapers..." + if git clone "https://github.com/JaKooLit/Wallpaper-Bank.git"; then + echo "${OK} Wallpapers downloaded successfully." 2>&1 | tee -a "$LOG" - # Check if wallpapers directory exists and create it if not - if [ ! -d "$HOME/Pictures/wallpapers" ]; then - mkdir -p "$HOME/Pictures/wallpapers" - echo "${OK} Created wallpapers directory." 2>&1 | tee -a "$LOG" - fi + # Check if wallpapers directory exists and create it if not + if [ ! -d "$HOME/Pictures/wallpapers" ]; then + mkdir -p "$HOME/Pictures/wallpapers" + echo "${OK} Created wallpapers directory." 2>&1 | tee -a "$LOG" + fi - if cp -R Wallpaper-Bank/wallpapers/* "$HOME/Pictures/wallpapers/" >> "$LOG" 2>&1; then - echo "${OK} Wallpapers copied successfully." 2>&1 | tee -a "$LOG" - rm -rf Wallpaper-Bank 2>&1 # Remove cloned repository after copying wallpapers - break - else - echo "${ERROR} Copying wallpapers failed" 2>&1 | tee -a "$LOG" - fi + if cp -R Wallpaper-Bank/wallpapers/* "$HOME/Pictures/wallpapers/" >>"$LOG" 2>&1; then + echo "${OK} Wallpapers copied successfully." 2>&1 | tee -a "$LOG" + rm -rf Wallpaper-Bank 2>&1 # Remove cloned repository after copying wallpapers + break else - echo "${ERROR} Downloading additional wallpapers failed" 2>&1 | tee -a "$LOG" + echo "${ERROR} Copying wallpapers failed" 2>&1 | tee -a "$LOG" fi - ;; + else + echo "${ERROR} Downloading additional wallpapers failed" 2>&1 | tee -a "$LOG" + fi + ;; [Nn]) - echo "${NOTE} You chose not to download additional wallpapers." 2>&1 | tee -a "$LOG" - break - ;; + echo "${NOTE} You chose not to download additional wallpapers." 2>&1 | tee -a "$LOG" + break + ;; *) - echo "Please enter 'y' or 'n' to proceed." - ;; + echo "Please enter 'y' or 'n' to proceed." + ;; esac done @@ -1068,10 +1075,10 @@ cleanup_backups() { BACKUP_DIRS+=("$BACKUP") fi done - + # If more than one backup found if [ ${#BACKUP_DIRS[@]} -gt 1 ]; then - printf "\n%.0s" {1..2} + printf "\n%.0s" {1..2} echo -e "${INFO} Found ${MAGENTA}multiple backups${RESET} for: ${YELLOW}${DIR##*/}${RESET}" echo "${YELLOW}Backups: ${RESET}" @@ -1109,7 +1116,7 @@ cleanup_backups # Check if ~/.config/waybar/style.css does not exist or is a symlink if [ ! -e "$HOME/.config/waybar/style.css" ] || [ -L "$HOME/.config/waybar/style.css" ]; then - ln -sf "$waybar_style" "$HOME/.config/waybar/style.css" 2>&1 | tee -a "$LOG" + ln -sf "$waybar_style" "$HOME/.config/waybar/style.css" 2>&1 | tee -a "$LOG" fi printf "\n%.0s" {1..1} @@ -1123,4 +1130,5 @@ printf "\n%.0s" {1..1} printf "${INFO} However, it is ${MAGENTA}HIGHLY SUGGESTED${RESET} to logout and re-login or better reboot to avoid any issues" printf "\n%.0s" {1..1} printf "${SKY_BLUE}Thank you${RESET} for using ${MAGENTA}KooL's Hyprland Configuration${RESET}... ${YELLOW}ENJOY!!!${RESET}" -printf "\n%.0s" {1..3}
\ No newline at end of file +printf "\n%.0s" {1..3} + @@ -18,21 +18,30 @@ BLUE="$(tput setaf 4)" SKY_BLUE="$(tput setaf 6)" RESET="$(tput sgr0)" -# Check /etc/os-release to see if this is an Ubuntu or Debian based distro -if grep -iq '^\(ID_LIKE\|ID\)=.*\(debian\|ubuntu\)' /etc/os-release >/dev/null 2>&1; then - printf "\n%.0s" {1..1} - print_color $WARNING " - █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█ - KOOL DOTS version INCOMPATIBLE - █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█ - - Debian / Ubuntu detected. Refer to Hyprland-Dots README - For instruction on how to update your KooL Hyprland Dots - - exiting .... - " - printf "\n%.0s" {1..3} - exit 1 +# Check /etc/os-release for Ubuntu or Debian and warn about Hyprland version requirement +if grep -iqE '^(ID_LIKE|ID)=.*(ubuntu|debian)' /etc/os-release >/dev/null 2>&1; then + printf "\n%.0s" {1..1} + echo "${WARNING} These Dotfiles are only supported on Hyprland 0.51.1 or greater. Do not install on older revisions.${RESET}" + while true; do + echo -n "${CAT} Do you want to continue anyway? (y/N): ${RESET}" + read _continue + _continue=$(echo "${_continue}" | tr '[:upper:]' '[:lower:]') + case "${_continue}" in + y|yes) + echo "${NOTE} Proceeding on Ubuntu/Debian by user confirmation." + break + ;; + n|no|"") + printf "\n%.0s" {1..1} + echo "${INFO} Aborting per user choice. No changes made." + printf "\n%.0s" {1..1} + exit 1 + ;; + *) + echo "${WARN} Please answer 'y' or 'n'." + ;; + esac + done fi @@ -27,6 +27,31 @@ echo -e "\e[35m \e[0m" printf "\n%.0s" {1..1} +# On Ubuntu/Debian, warn about required Hyprland version and prompt to continue +if grep -iqE '^(ID_LIKE|ID)=.*(ubuntu|debian)' /etc/os-release >/dev/null 2>&1; then + echo "${WARNING} These Dotfiles are only supported on Hyprland 0.51.1 or greater. Do not install on older revisions.${RESET}" + while true; do + echo -n "${CAT} Do you want to continue anyway? (y/N): ${RESET}" + read _continue + _continue=$(echo "${_continue}" | tr '[:upper:]' '[:lower:]') + case "${_continue}" in + y|yes) + echo "${NOTE} Proceeding on Ubuntu/Debian by user confirmation." + break + ;; + n|no|"") + printf "\n%.0s" {1..1} + echo "${INFO} Aborting per user choice. No changes made." + printf "\n%.0s" {1..1} + exit 1 + ;; + *) + echo "${WARN} Please answer 'y' or 'n'." + ;; + esac + done +fi + echo "${WARNING}A T T E N T I O N !${RESET}" echo "${SKY_BLUE}This script is meant to manually upgrade your KooL Hyprland Dots${RESET}" echo "${YELLOW}NOTE that you should edit this script and assign an Directory or Files exclusion${RESET}" |
