From d20745840e43bfabef2a60190071d78016ddb658 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 5 Oct 2025 20:50:47 -0400 Subject: Updated Weather.py to correct version On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/UserScripts/Weather.py --- config/hypr/UserScripts/Weather.py | 627 ++++++++++++++++++++++++++++++------- 1 file changed, 512 insertions(+), 115 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index a8b70417..ca1d5281 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -1,15 +1,69 @@ #!/usr/bin/env python3 # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # -# original code https://gist.github.com/Surendrajat/ff3876fd2166dd86fb71180f4e9342d7 -# weather using python +# Rewritten to use Open-Meteo APIs (worldwide, no API key) for robust weather data. +# Outputs Waybar-compatible JSON and a simple text cache. -import requests import json import os -from pyquery import PyQuery # install using `pip install pyquery` +import sys +import time +import html +from typing import Any, Dict, List, Optional, Tuple + +import requests + +# =============== Configuration =============== +# You can configure behavior via environment variables OR the constants below. +# Examples (zsh): +# # One-off run +# # WEATHER_UNITS can be "metric" or "imperial" +# WEATHER_UNITS=imperial WEATHER_PLACE="Concord, NH" python3 /home/dwilliams/Projects/Weather.py +# +# # Persist in current shell session +# export WEATHER_UNITS=imperial +# export WEATHER_LAT=43.2229 +# export WEATHER_LON=-71.332 +# export WEATHER_PLACE="Concord, NH" +# export WEATHER_TOOLTIP_MARKUP=1 # 1 to enable Pango markup, 0 to disable +# export WEATHER_LOC_ICON="๐Ÿ“" # or "*" for ASCII-only +# +CACHE_DIR = os.path.expanduser("~/.cache") +API_CACHE_PATH = os.path.join(CACHE_DIR, "open_meteo_cache.json") +SIMPLE_TEXT_CACHE_PATH = os.path.join(CACHE_DIR, ".weather_cache") +CACHE_TTL_SECONDS = int(os.getenv("WEATHER_CACHE_TTL", "600")) # default 10 minutes + +# Units: metric or imperial (default metric) +UNITS = os.getenv("WEATHER_UNITS", "metric").strip().lower() # metric|imperial + +# Optional manual coordinates +ENV_LAT = os.getenv("WEATHER_LAT") +ENV_LON = os.getenv("WEATHER_LON") +# Optional manual place override for tooltip +ENV_PLACE = os.getenv("WEATHER_PLACE") +# Manual place name set inside this file. If set (non-empty), this takes top priority. +# Example: MANUAL_PLACE = "Concord, NH, US" +MANUAL_PLACE: Optional[str] = None + +# Location icon in tooltip (default to a standard emoji to avoid missing glyphs) +LOC_ICON = os.getenv("WEATHER_LOC_ICON", "๐Ÿ“") +# Enable/disable Pango markup in tooltip (1/0, true/false) +TOOLTIP_MARKUP = os.getenv("WEATHER_TOOLTIP_MARKUP", "1").lower() not in ("0", "false", "no") +# Optional debug logging to stderr (set WEATHER_DEBUG=1 to enable) +DEBUG = os.getenv("WEATHER_DEBUG", "0").lower() not in ("0", "false", "no") + +# HTTP settings +UA = ( + "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 " + "(KHTML, like Gecko) Chrome/128.0 Safari/537.36" +) +TIMEOUT = 8 -# weather icons -weather_icons = { +SESSION = requests.Session() +SESSION.headers.update({"User-Agent": UA}) + +# =============== Icon and status mapping =============== +# Reuse prior icon set for continuity +WEATHER_ICONS = { "sunnyDay": "๓ฐ–™", "clearNight": "๓ฐ–”", "cloudyFoggyDay": "๎Œƒ", @@ -22,126 +76,469 @@ weather_icons = { "default": "๎Œ‚", } +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", +} -# Get current location based on IP address -def get_location(): - response = requests.get("https://ipinfo.io") - data = response.json() - loc = data["loc"].split(",") - return float(loc[0]), float(loc[1]) +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"] -# Get latitude and longitude -latitude, longitude = get_location() -# Open-Meteo API endpoint -url = f"https://weather.com/en-PH/weather/today/l/{latitude},{longitude}" +def wmo_to_status(code: int) -> str: + return WMO_STATUS.get(code, "Unknown") -# manual location_id -# NOTE: if you want to add manually, make sure you disable def get_location above -# to get your own location_id, go to https://weather.com & search your location. -# once you choose your location, you can see the location_id in the URL(64 chars long hex string) -# like this: https://weather.com/en-PH/weather/today/l/bca47d1099e762a012b9a139c36f30a0b1e647f69c0c4ac28b537e7ae9c1c200 -# location_id = "bca47d1099e762a012b9a139c36f30a0b1e647f69c0c4ac28b537e7ae9c1c200" # TODO -# NOTE to change to deg F, change the URL to your preffered location after weather.com -# Default is English-Philippines with Busan, South Korea as location_id -# get html page -# url = "https://weather.com/en-PH/weather/today/l/" + location_id +# =============== Utilities =============== -html_data = PyQuery(url=url) +def esc(s: Optional[str]) -> str: + return html.escape(s, quote=False) if s else "" -# current temperature -temp = html_data("span[data-testid='TemperatureValue']").eq(0).text() +def log_debug(msg: str) -> None: + if DEBUG: + print(msg, file=sys.stderr) -# current status phrase -status = html_data("div[data-testid='wxPhrase']").text() -status = f"{status[:16]}.." if len(status) > 17 else status +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) -# status code -# Fix provided by mio-dokuhaki -status_code = html_data("#regionHeader").attr("class").split(" ")[1].split("-")[0] -# status icon -icon = ( - weather_icons[status_code] - if status_code in weather_icons - else weather_icons["default"] -) +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 -# 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 = str(html_data("span[data-testid='Wind'] > span").text()) -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'{temp}', - f" {icon}", - f"{status}", - f"{temp_feel_text}", - f"{temp_min_max}", - f"{wind_text}\t{humidity_text}", - f"{visibility_text}\tAQI {air_quality_index}", - f" {prediction}", -) -# print waybar module data -out_data = { - "text": f"{icon} {temp}", - "alt": status, - "tooltip": tooltip_text, - "class": status_code, -} -print(json.dumps(out_data)) - -simple_weather = ( - f"{icon} {status}\n" - + f"๏‹‰ {temp} ({temp_feel_text})\n" - + f"{wind_text} \n" - + f"{humidity_text} \n" - + f"{visibility_text} AQI{air_quality_index}\n" -) +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", + } + 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) + icon = wmo_to_icon(code, is_day) + status = wmo_to_status(code) + + # 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'{esc(temp_str)}', + f" {icon}", + f"{esc(status)}", + esc(location_text), + f"{esc(feels_str)}" if feels_str else "", + f"{esc(min_max)}" if min_max else "", + f"{esc(wind_text)}\t{esc(humidity_text)}", + f"{esc(visibility_text)}\t{esc(aqi_text)}", + f" {esc(prediction)}" 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": f"wmo-{code} {'day' if is_day else 'night'}", + } + + 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)) + -try: - with open(os.path.expanduser("~/.cache/.weather_cache"), "w") as file: - file.write(simple_weather) -except Exception as e: - print(f"Error writing to cache: {e}") +if __name__ == "__main__": + main() -- cgit v1.2.3 From f4a9ba41e25b4e40b6b7154aa7f48e9fbeb0b859 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sat, 18 Oct 2025 22:59:07 -0400 Subject: disabled workspace rules adj dropdown term size Added nm-tray startup for ubuntu users On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/UserConfigs/Startup_Apps.conf modified: config/hypr/UserConfigs/WindowRules.conf modified: config/hypr/scripts/Dropterminal.sh --- config/hypr/UserConfigs/Startup_Apps.conf | 1 + config/hypr/UserConfigs/WindowRules.conf | 24 +- config/hypr/scripts/Dropterminal.sh | 590 +++++++++++++++--------------- 3 files changed, 308 insertions(+), 307 deletions(-) diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf index 7b668b77..738eb2da 100644 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ b/config/hypr/UserConfigs/Startup_Apps.conf @@ -29,6 +29,7 @@ exec-once = $scriptsDir/Polkit.sh # starup apps exec-once = nm-applet --indicator +exec-once = nm-tray # For ubuntu exec-once = swaync #exec-once = ags #exec-once = blueman-applet diff --git a/config/hypr/UserConfigs/WindowRules.conf b/config/hypr/UserConfigs/WindowRules.conf index d6959dc4..2c24dafc 100644 --- a/config/hypr/UserConfigs/WindowRules.conf +++ b/config/hypr/UserConfigs/WindowRules.conf @@ -113,20 +113,20 @@ windowrule = move 72% 7%,title:^(Picture-in-Picture)$ windowrule = idleinhibit fullscreen, fullscreen:1 # windowrule move to workspace -windowrule = workspace 1, tag:email* -windowrule = workspace 2, tag:browser* +#windowrule = workspace 1, tag:email* +#windowrule = workspace 2, tag:browser* #windowrule = workspace 3, class:^([Tt]hunar)$ #windowrule = workspace 3, tag:projects* -windowrule = workspace 5, tag:gamestore* -windowrule = workspace 7, tag:im* -windowrule = workspace 8, tag:games* +#windowrule = workspace 5, tag:gamestore* +#windowrule = workspace 7, tag:im* +#windowrule = workspace 8, tag:games* # windowrule move to workspace (silent) -windowrule = workspace 4 silent, tag:screenshare* -windowrule = workspace 6 silent, class:^(virt-manager)$ -windowrule = workspace 6 silent, class:^(.virt-manager-wrapped)$ -windowrule = workspace 9 silent, tag:multimedia* - +#windowrule = workspace 4 silent, tag:screenshare* +#windowrule = workspace 6 silent, class:^(virt-manager)$ +#windowrule = workspace 6 silent, class:^(.virt-manager-wrapped)$ +#windowrule = workspace 9 silent, tag:multimedia* +# # FLOAT windowrule = float, tag:KooL_Cheat* windowrule = float, tag:wallpaper* @@ -167,12 +167,12 @@ windowrule = size 16% 12%, title:^(SDDM Background)$ #KooL's Dots YAD for settin # END of float popups and dialogue ####### # OPACITY -windowrule = opacity 0.9 0.7, tag:browser* +windowrule = opacity 0.99 0.8, tag:browser* windowrule = opacity 0.9 0.8, tag:projects* windowrule = opacity 0.94 0.86, tag:im* windowrule = opacity 0.94 0.86, tag:multimedia* windowrule = opacity 0.9 0.8, tag:file-manager* -windowrule = opacity 0.8 0.7, tag:terminal* +windowrule = opacity 0.9 0.7, tag:terminal* windowrule = opacity 0.8 0.7, tag:settings* windowrule = opacity 0.82 0.75, tag:viewer* windowrule = opacity 0.9 0.7, tag:wallpaper* diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index 4833545c..1c17fbb4 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -3,7 +3,7 @@ # # Made and brought to by Kiran George # /* -- โœจ https://github.com/SherLock707 โœจ -- */ ## -# Dropdown Terminal +# Dropdown Terminal # Usage: ./Dropdown.sh [-d] # Example: ./Dropdown.sh foot # ./Dropdown.sh -d foot (with debug output) @@ -15,186 +15,186 @@ SPECIAL_WS="special:scratchpad" ADDR_FILE="/tmp/dropdown_terminal_addr" # Dropdown size and position configuration (percentages) -WIDTH_PERCENT=50 # Width as percentage of screen width -HEIGHT_PERCENT=50 # Height as percentage of screen height -Y_PERCENT=5 # Y position as percentage from top (X is auto-centered) +WIDTH_PERCENT=65 # Width as percentage of screen width +HEIGHT_PERCENT=65 # Height as percentage of screen height +Y_PERCENT=10 # Y position as percentage from top (X is auto-centered) # Animation settings -ANIMATION_DURATION=100 # milliseconds +ANIMATION_DURATION=100 # milliseconds SLIDE_STEPS=5 -SLIDE_DELAY=5 # milliseconds between steps +SLIDE_DELAY=5 # milliseconds between steps # Parse arguments if [ "$1" = "-d" ]; then - DEBUG=true - shift + DEBUG=true + shift fi TERMINAL_CMD="$1" # Debug echo function debug_echo() { - if [ "$DEBUG" = true ]; then - echo "$@" - fi + if [ "$DEBUG" = true ]; then + echo "$@" + fi } # Validate input if [ -z "$TERMINAL_CMD" ]; then - echo "Missing terminal command. Usage: $0 [-d] " - echo "Examples:" - echo " $0 foot" - echo " $0 -d foot (with debug output)" - echo " $0 'kitty -e zsh'" - echo " $0 'alacritty --working-directory /home/user'" - echo "" - echo "Edit the script to modify size and position:" - echo " WIDTH_PERCENT - Width as percentage of screen (default: 50)" - echo " HEIGHT_PERCENT - Height as percentage of screen (default: 50)" - echo " Y_PERCENT - Y position from top as percentage (default: 5)" - echo " Note: X position is automatically centered" - exit 1 + echo "Missing terminal command. Usage: $0 [-d] " + echo "Examples:" + echo " $0 foot" + echo " $0 -d foot (with debug output)" + echo " $0 'kitty -e zsh'" + echo " $0 'alacritty --working-directory /home/user'" + echo "" + echo "Edit the script to modify size and position:" + echo " WIDTH_PERCENT - Width as percentage of screen (default: 50)" + echo " HEIGHT_PERCENT - Height as percentage of screen (default: 50)" + echo " Y_PERCENT - Y position from top as percentage (default: 5)" + echo " Note: X position is automatically centered" + exit 1 fi # Function to get window geometry get_window_geometry() { - local addr="$1" - hyprctl clients -j | jq -r --arg ADDR "$addr" '.[] | select(.address == $ADDR) | "\(.at[0]) \(.at[1]) \(.size[0]) \(.size[1])"' + local addr="$1" + hyprctl clients -j | jq -r --arg ADDR "$addr" '.[] | select(.address == $ADDR) | "\(.at[0]) \(.at[1]) \(.size[0]) \(.size[1])"' } # Function to animate window slide down (show) animate_slide_down() { - local addr="$1" - local target_x="$2" - local target_y="$3" - local width="$4" - local height="$5" - - debug_echo "Animating slide down for window $addr to position $target_x,$target_y" - - # Start position (above screen) - local start_y=$((target_y - height - 50)) - - # Calculate step size - local step_y=$(((target_y - start_y) / SLIDE_STEPS)) - - # Move window to start position instantly (off-screen) - hyprctl dispatch movewindowpixel "exact $target_x $start_y,address:$addr" >/dev/null 2>&1 - sleep 0.05 - - # Animate slide down - for i in $(seq 1 $SLIDE_STEPS); do - local current_y=$((start_y + (step_y * i))) - hyprctl dispatch movewindowpixel "exact $target_x $current_y,address:$addr" >/dev/null 2>&1 - sleep 0.03 - done - - # Ensure final position is exact - hyprctl dispatch movewindowpixel "exact $target_x $target_y,address:$addr" >/dev/null 2>&1 + local addr="$1" + local target_x="$2" + local target_y="$3" + local width="$4" + local height="$5" + + debug_echo "Animating slide down for window $addr to position $target_x,$target_y" + + # Start position (above screen) + local start_y=$((target_y - height - 50)) + + # Calculate step size + local step_y=$(((target_y - start_y) / SLIDE_STEPS)) + + # Move window to start position instantly (off-screen) + hyprctl dispatch movewindowpixel "exact $target_x $start_y,address:$addr" >/dev/null 2>&1 + sleep 0.05 + + # Animate slide down + for i in $(seq 1 $SLIDE_STEPS); do + local current_y=$((start_y + (step_y * i))) + hyprctl dispatch movewindowpixel "exact $target_x $current_y,address:$addr" >/dev/null 2>&1 + sleep 0.03 + done + + # Ensure final position is exact + hyprctl dispatch movewindowpixel "exact $target_x $target_y,address:$addr" >/dev/null 2>&1 } # Function to animate window slide up (hide) animate_slide_up() { - local addr="$1" - local start_x="$2" - local start_y="$3" - local width="$4" - local height="$5" - - debug_echo "Animating slide up for window $addr from position $start_x,$start_y" - - # End position (above screen) - local end_y=$((start_y - height - 50)) - - # Calculate step size - local step_y=$(((start_y - end_y) / SLIDE_STEPS)) - - # Animate slide up - for i in $(seq 1 $SLIDE_STEPS); do - local current_y=$((start_y - (step_y * i))) - hyprctl dispatch movewindowpixel "exact $start_x $current_y,address:$addr" >/dev/null 2>&1 - sleep 0.03 - done - - debug_echo "Slide up animation completed" + local addr="$1" + local start_x="$2" + local start_y="$3" + local width="$4" + local height="$5" + + debug_echo "Animating slide up for window $addr from position $start_x,$start_y" + + # End position (above screen) + local end_y=$((start_y - height - 50)) + + # Calculate step size + local step_y=$(((start_y - end_y) / SLIDE_STEPS)) + + # Animate slide up + for i in $(seq 1 $SLIDE_STEPS); do + local current_y=$((start_y - (step_y * i))) + hyprctl dispatch movewindowpixel "exact $start_x $current_y,address:$addr" >/dev/null 2>&1 + sleep 0.03 + done + + debug_echo "Slide up animation completed" } # Function to get monitor info including scale and name of focused monitor get_monitor_info() { - local monitor_data=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x) \(.y) \(.width) \(.height) \(.scale) \(.name)"') - if [ -z "$monitor_data" ] || [[ "$monitor_data" =~ ^null ]]; then - debug_echo "Error: Could not get focused monitor information" - return 1 - fi - echo "$monitor_data" + local monitor_data=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | "\(.x) \(.y) \(.width) \(.height) \(.scale) \(.name)"') + if [ -z "$monitor_data" ] || [[ "$monitor_data" =~ ^null ]]; then + debug_echo "Error: Could not get focused monitor information" + return 1 + fi + echo "$monitor_data" } # Function to calculate dropdown position with proper scaling and centering calculate_dropdown_position() { - local monitor_info=$(get_monitor_info) - - if [ $? -ne 0 ] || [ -z "$monitor_info" ]; then - debug_echo "Error: Failed to get monitor info, using fallback values" - echo "100 100 800 600 fallback-monitor" - return 1 - fi - - local mon_x=$(echo $monitor_info | cut -d' ' -f1) - local mon_y=$(echo $monitor_info | cut -d' ' -f2) - local mon_width=$(echo $monitor_info | cut -d' ' -f3) - local mon_height=$(echo $monitor_info | cut -d' ' -f4) - local mon_scale=$(echo $monitor_info | cut -d' ' -f5) - local mon_name=$(echo $monitor_info | cut -d' ' -f6) - - debug_echo "Monitor info: x=$mon_x, y=$mon_y, width=$mon_width, height=$mon_height, scale=$mon_scale" - - # Validate scale value and provide fallback - if [ -z "$mon_scale" ] || [ "$mon_scale" = "null" ] || [ "$mon_scale" = "0" ]; then - debug_echo "Invalid scale value, using 1.0 as fallback" - mon_scale="1.0" - fi - - # Calculate logical dimensions by dividing physical dimensions by scale - local logical_width logical_height - if command -v bc >/dev/null 2>&1; then - # Use bc for precise floating point calculation - logical_width=$(echo "scale=0; $mon_width / $mon_scale" | bc | cut -d'.' -f1) - logical_height=$(echo "scale=0; $mon_height / $mon_scale" | bc | cut -d'.' -f1) - else - # Fallback to integer math (multiply by 100 for precision, then divide) - local scale_int=$(echo "$mon_scale" | sed 's/\.//' | sed 's/^0*//') - if [ -z "$scale_int" ]; then scale_int=100; fi - - logical_width=$(((mon_width * 100) / scale_int)) - logical_height=$(((mon_height * 100) / scale_int)) - fi - - # Ensure we have valid integer values - if ! [[ "$logical_width" =~ ^-?[0-9]+$ ]]; then logical_width=$mon_width; fi - if ! [[ "$logical_height" =~ ^-?[0-9]+$ ]]; then logical_height=$mon_height; fi - - debug_echo "Physical resolution: ${mon_width}x${mon_height}" - debug_echo "Logical resolution: ${logical_width}x${logical_height} (physical รท scale)" - - # Calculate window dimensions based on LOGICAL space percentages - local width=$((logical_width * WIDTH_PERCENT / 100)) - local height=$((logical_height * HEIGHT_PERCENT / 100)) - - # Calculate Y position from top based on percentage of LOGICAL height - local y_offset=$((logical_height * Y_PERCENT / 100)) - - # Calculate centered X position in LOGICAL space - local x_offset=$(((logical_width - width) / 2)) - - # Apply monitor offset to get final positions in logical coordinates - local final_x=$((mon_x + x_offset)) - local final_y=$((mon_y + y_offset)) - - debug_echo "Window size: ${width}x${height} (logical pixels)" - debug_echo "Final position: x=$final_x, y=$final_y (logical coordinates)" - debug_echo "Hyprland will scale these to physical coordinates automatically" - - echo "$final_x $final_y $width $height $mon_name" + local monitor_info=$(get_monitor_info) + + if [ $? -ne 0 ] || [ -z "$monitor_info" ]; then + debug_echo "Error: Failed to get monitor info, using fallback values" + echo "100 100 800 600 fallback-monitor" + return 1 + fi + + local mon_x=$(echo $monitor_info | cut -d' ' -f1) + local mon_y=$(echo $monitor_info | cut -d' ' -f2) + local mon_width=$(echo $monitor_info | cut -d' ' -f3) + local mon_height=$(echo $monitor_info | cut -d' ' -f4) + local mon_scale=$(echo $monitor_info | cut -d' ' -f5) + local mon_name=$(echo $monitor_info | cut -d' ' -f6) + + debug_echo "Monitor info: x=$mon_x, y=$mon_y, width=$mon_width, height=$mon_height, scale=$mon_scale" + + # Validate scale value and provide fallback + if [ -z "$mon_scale" ] || [ "$mon_scale" = "null" ] || [ "$mon_scale" = "0" ]; then + debug_echo "Invalid scale value, using 1.0 as fallback" + mon_scale="1.0" + fi + + # Calculate logical dimensions by dividing physical dimensions by scale + local logical_width logical_height + if command -v bc >/dev/null 2>&1; then + # Use bc for precise floating point calculation + logical_width=$(echo "scale=0; $mon_width / $mon_scale" | bc | cut -d'.' -f1) + logical_height=$(echo "scale=0; $mon_height / $mon_scale" | bc | cut -d'.' -f1) + else + # Fallback to integer math (multiply by 100 for precision, then divide) + local scale_int=$(echo "$mon_scale" | sed 's/\.//' | sed 's/^0*//') + if [ -z "$scale_int" ]; then scale_int=100; fi + + logical_width=$(((mon_width * 100) / scale_int)) + logical_height=$(((mon_height * 100) / scale_int)) + fi + + # Ensure we have valid integer values + if ! [[ "$logical_width" =~ ^-?[0-9]+$ ]]; then logical_width=$mon_width; fi + if ! [[ "$logical_height" =~ ^-?[0-9]+$ ]]; then logical_height=$mon_height; fi + + debug_echo "Physical resolution: ${mon_width}x${mon_height}" + debug_echo "Logical resolution: ${logical_width}x${logical_height} (physical รท scale)" + + # Calculate window dimensions based on LOGICAL space percentages + local width=$((logical_width * WIDTH_PERCENT / 100)) + local height=$((logical_height * HEIGHT_PERCENT / 100)) + + # Calculate Y position from top based on percentage of LOGICAL height + local y_offset=$((logical_height * Y_PERCENT / 100)) + + # Calculate centered X position in LOGICAL space + local x_offset=$(((logical_width - width) / 2)) + + # Apply monitor offset to get final positions in logical coordinates + local final_x=$((mon_x + x_offset)) + local final_y=$((mon_y + y_offset)) + + debug_echo "Window size: ${width}x${height} (logical pixels)" + debug_echo "Final position: x=$final_x, y=$final_y (logical coordinates)" + debug_echo "Hyprland will scale these to physical coordinates automatically" + + echo "$final_x $final_y $width $height $mon_name" } # Get the current workspace @@ -202,179 +202,179 @@ CURRENT_WS=$(hyprctl activeworkspace -j | jq -r '.id') # Function to get stored terminal address get_terminal_address() { - if [ -f "$ADDR_FILE" ] && [ -s "$ADDR_FILE" ]; then - cut -d' ' -f1 "$ADDR_FILE" - fi + if [ -f "$ADDR_FILE" ] && [ -s "$ADDR_FILE" ]; then + cut -d' ' -f1 "$ADDR_FILE" + fi } # Function to get stored monitor name get_terminal_monitor() { - if [ -f "$ADDR_FILE" ] && [ -s "$ADDR_FILE" ]; then - cut -d' ' -f2- "$ADDR_FILE" - fi + if [ -f "$ADDR_FILE" ] && [ -s "$ADDR_FILE" ]; then + cut -d' ' -f2- "$ADDR_FILE" + fi } # Function to check if terminal exists terminal_exists() { - local addr=$(get_terminal_address) - if [ -n "$addr" ]; then - hyprctl clients -j | jq -e --arg ADDR "$addr" 'any(.[]; .address == $ADDR)' >/dev/null 2>&1 - else - return 1 - fi + local addr=$(get_terminal_address) + if [ -n "$addr" ]; then + hyprctl clients -j | jq -e --arg ADDR "$addr" 'any(.[]; .address == $ADDR)' >/dev/null 2>&1 + else + return 1 + fi } # Function to check if terminal is in special workspace terminal_in_special() { - local addr=$(get_terminal_address) - if [ -n "$addr" ]; then - hyprctl clients -j | jq -e --arg ADDR "$addr" 'any(.[]; .address == $ADDR and .workspace.name == "special:scratchpad")' >/dev/null 2>&1 - else - return 1 - fi + local addr=$(get_terminal_address) + if [ -n "$addr" ]; then + hyprctl clients -j | jq -e --arg ADDR "$addr" 'any(.[]; .address == $ADDR and .workspace.name == "special:scratchpad")' >/dev/null 2>&1 + else + return 1 + fi } # Function to spawn terminal and capture its address spawn_terminal() { - debug_echo "Creating new dropdown terminal with command: $TERMINAL_CMD" - - # Calculate dropdown position for later use - local pos_info=$(calculate_dropdown_position) - if [ $? -ne 0 ]; then - debug_echo "Warning: Using fallback positioning" - fi - - local target_x=$(echo $pos_info | cut -d' ' -f1) - local target_y=$(echo $pos_info | cut -d' ' -f2) - local width=$(echo $pos_info | cut -d' ' -f3) - local height=$(echo $pos_info | cut -d' ' -f4) - local monitor_name=$(echo $pos_info | cut -d' ' -f5) - - debug_echo "Target position: ${target_x},${target_y}, size: ${width}x${height}" - - # Get window count before spawning - local windows_before=$(hyprctl clients -j) - local count_before=$(echo "$windows_before" | jq 'length') - - # Launch terminal directly in special workspace to avoid visible spawn - hyprctl dispatch exec "[float; size $width $height; workspace special:scratchpad silent] $TERMINAL_CMD" - - # Wait for window to appear - sleep 0.1 - - # Get windows after spawning - local windows_after=$(hyprctl clients -j) - local count_after=$(echo "$windows_after" | jq 'length') - - local new_addr="" - - if [ "$count_after" -gt "$count_before" ]; then - # Find the new window by comparing before/after lists - new_addr=$(comm -13 \ - <(echo "$windows_before" | jq -r '.[].address' | sort) \ - <(echo "$windows_after" | jq -r '.[].address' | sort) \ - | head -1) - fi - - # Fallback: try to find by the most recently mapped window - if [ -z "$new_addr" ] || [ "$new_addr" = "null" ]; then - new_addr=$(hyprctl clients -j | jq -r 'sort_by(.focusHistoryID) | .[-1] | .address') - fi - - if [ -n "$new_addr" ] && [ "$new_addr" != "null" ]; then - # Store the address and monitor name - echo "$new_addr $monitor_name" > "$ADDR_FILE" - debug_echo "Terminal created with address: $new_addr in special workspace on monitor $monitor_name" - - # Small delay to ensure it's properly in special workspace - sleep 0.2 - - # Now bring it back with the same animation as subsequent shows - # Use movetoworkspacesilent to avoid affecting workspace history - hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$new_addr" - hyprctl dispatch pin "address:$new_addr" - animate_slide_down "$new_addr" "$target_x" "$target_y" "$width" "$height" - - return 0 - fi - - debug_echo "Failed to get terminal address" - return 1 + debug_echo "Creating new dropdown terminal with command: $TERMINAL_CMD" + + # Calculate dropdown position for later use + local pos_info=$(calculate_dropdown_position) + if [ $? -ne 0 ]; then + debug_echo "Warning: Using fallback positioning" + fi + + local target_x=$(echo $pos_info | cut -d' ' -f1) + local target_y=$(echo $pos_info | cut -d' ' -f2) + local width=$(echo $pos_info | cut -d' ' -f3) + local height=$(echo $pos_info | cut -d' ' -f4) + local monitor_name=$(echo $pos_info | cut -d' ' -f5) + + debug_echo "Target position: ${target_x},${target_y}, size: ${width}x${height}" + + # Get window count before spawning + local windows_before=$(hyprctl clients -j) + local count_before=$(echo "$windows_before" | jq 'length') + + # Launch terminal directly in special workspace to avoid visible spawn + hyprctl dispatch exec "[float; size $width $height; workspace special:scratchpad silent] $TERMINAL_CMD" + + # Wait for window to appear + sleep 0.1 + + # Get windows after spawning + local windows_after=$(hyprctl clients -j) + local count_after=$(echo "$windows_after" | jq 'length') + + local new_addr="" + + if [ "$count_after" -gt "$count_before" ]; then + # Find the new window by comparing before/after lists + new_addr=$(comm -13 \ + <(echo "$windows_before" | jq -r '.[].address' | sort) \ + <(echo "$windows_after" | jq -r '.[].address' | sort) | + head -1) + fi + + # Fallback: try to find by the most recently mapped window + if [ -z "$new_addr" ] || [ "$new_addr" = "null" ]; then + new_addr=$(hyprctl clients -j | jq -r 'sort_by(.focusHistoryID) | .[-1] | .address') + fi + + if [ -n "$new_addr" ] && [ "$new_addr" != "null" ]; then + # Store the address and monitor name + echo "$new_addr $monitor_name" >"$ADDR_FILE" + debug_echo "Terminal created with address: $new_addr in special workspace on monitor $monitor_name" + + # Small delay to ensure it's properly in special workspace + sleep 0.2 + + # Now bring it back with the same animation as subsequent shows + # Use movetoworkspacesilent to avoid affecting workspace history + hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$new_addr" + hyprctl dispatch pin "address:$new_addr" + animate_slide_down "$new_addr" "$target_x" "$target_y" "$width" "$height" + + return 0 + fi + + debug_echo "Failed to get terminal address" + return 1 } # Main logic if terminal_exists; then - TERMINAL_ADDR=$(get_terminal_address) - debug_echo "Found existing terminal: $TERMINAL_ADDR" - focused_monitor=$(get_monitor_info | awk '{print $6}') - dropdown_monitor=$(get_terminal_monitor) - if [ "$focused_monitor" != "$dropdown_monitor" ]; then - debug_echo "Monitor focus changed: moving dropdown to $focused_monitor" - # Calculate new position for focused monitor - pos_info=$(calculate_dropdown_position) - target_x=$(echo $pos_info | cut -d' ' -f1) - target_y=$(echo $pos_info | cut -d' ' -f2) - width=$(echo $pos_info | cut -d' ' -f3) - height=$(echo $pos_info | cut -d' ' -f4) - monitor_name=$(echo $pos_info | cut -d' ' -f5) - # Move and resize window - hyprctl dispatch movewindowpixel "exact $target_x $target_y,address:$TERMINAL_ADDR" - hyprctl dispatch resizewindowpixel "exact $width $height,address:$TERMINAL_ADDR" - # Update ADDR_FILE - echo "$TERMINAL_ADDR $monitor_name" > "$ADDR_FILE" - fi + TERMINAL_ADDR=$(get_terminal_address) + debug_echo "Found existing terminal: $TERMINAL_ADDR" + focused_monitor=$(get_monitor_info | awk '{print $6}') + dropdown_monitor=$(get_terminal_monitor) + if [ "$focused_monitor" != "$dropdown_monitor" ]; then + debug_echo "Monitor focus changed: moving dropdown to $focused_monitor" + # Calculate new position for focused monitor + pos_info=$(calculate_dropdown_position) + target_x=$(echo $pos_info | cut -d' ' -f1) + target_y=$(echo $pos_info | cut -d' ' -f2) + width=$(echo $pos_info | cut -d' ' -f3) + height=$(echo $pos_info | cut -d' ' -f4) + monitor_name=$(echo $pos_info | cut -d' ' -f5) + # Move and resize window + hyprctl dispatch movewindowpixel "exact $target_x $target_y,address:$TERMINAL_ADDR" + hyprctl dispatch resizewindowpixel "exact $width $height,address:$TERMINAL_ADDR" + # Update ADDR_FILE + echo "$TERMINAL_ADDR $monitor_name" >"$ADDR_FILE" + fi - if terminal_in_special; then - debug_echo "Bringing terminal from scratchpad with slide down animation" - - # Calculate target position - pos_info=$(calculate_dropdown_position) - target_x=$(echo $pos_info | cut -d' ' -f1) - target_y=$(echo $pos_info | cut -d' ' -f2) - width=$(echo $pos_info | cut -d' ' -f3) - height=$(echo $pos_info | cut -d' ' -f4) - - # Use movetoworkspacesilent to avoid affecting workspace history - hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$TERMINAL_ADDR" - hyprctl dispatch pin "address:$TERMINAL_ADDR" - - # Set size and animate slide down - hyprctl dispatch resizewindowpixel "exact $width $height,address:$TERMINAL_ADDR" - animate_slide_down "$TERMINAL_ADDR" "$target_x" "$target_y" "$width" "$height" - - hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" + if terminal_in_special; then + debug_echo "Bringing terminal from scratchpad with slide down animation" + + # Calculate target position + pos_info=$(calculate_dropdown_position) + target_x=$(echo $pos_info | cut -d' ' -f1) + target_y=$(echo $pos_info | cut -d' ' -f2) + width=$(echo $pos_info | cut -d' ' -f3) + height=$(echo $pos_info | cut -d' ' -f4) + + # Use movetoworkspacesilent to avoid affecting workspace history + hyprctl dispatch movetoworkspacesilent "$CURRENT_WS,address:$TERMINAL_ADDR" + hyprctl dispatch pin "address:$TERMINAL_ADDR" + + # Set size and animate slide down + hyprctl dispatch resizewindowpixel "exact $width $height,address:$TERMINAL_ADDR" + animate_slide_down "$TERMINAL_ADDR" "$target_x" "$target_y" "$width" "$height" + + hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" + else + debug_echo "Hiding terminal to scratchpad with slide up animation" + + # Get current geometry for animation + geometry=$(get_window_geometry "$TERMINAL_ADDR") + if [ -n "$geometry" ]; then + curr_x=$(echo $geometry | cut -d' ' -f1) + curr_y=$(echo $geometry | cut -d' ' -f2) + curr_width=$(echo $geometry | cut -d' ' -f3) + curr_height=$(echo $geometry | cut -d' ' -f4) + + debug_echo "Current geometry: ${curr_x},${curr_y} ${curr_width}x${curr_height}" + + # Animate slide up first + animate_slide_up "$TERMINAL_ADDR" "$curr_x" "$curr_y" "$curr_width" "$curr_height" + + # Small delay then move to special workspace and unpin + sleep 0.1 + hyprctl dispatch pin "address:$TERMINAL_ADDR" # Unpin (toggle) + hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" else - debug_echo "Hiding terminal to scratchpad with slide up animation" - - # Get current geometry for animation - geometry=$(get_window_geometry "$TERMINAL_ADDR") - if [ -n "$geometry" ]; then - curr_x=$(echo $geometry | cut -d' ' -f1) - curr_y=$(echo $geometry | cut -d' ' -f2) - curr_width=$(echo $geometry | cut -d' ' -f3) - curr_height=$(echo $geometry | cut -d' ' -f4) - - debug_echo "Current geometry: ${curr_x},${curr_y} ${curr_width}x${curr_height}" - - # Animate slide up first - animate_slide_up "$TERMINAL_ADDR" "$curr_x" "$curr_y" "$curr_width" "$curr_height" - - # Small delay then move to special workspace and unpin - sleep 0.1 - hyprctl dispatch pin "address:$TERMINAL_ADDR" # Unpin (toggle) - hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" - else - debug_echo "Could not get window geometry, moving to scratchpad without animation" - hyprctl dispatch pin "address:$TERMINAL_ADDR" - hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" - fi + debug_echo "Could not get window geometry, moving to scratchpad without animation" + hyprctl dispatch pin "address:$TERMINAL_ADDR" + hyprctl dispatch movetoworkspacesilent "$SPECIAL_WS,address:$TERMINAL_ADDR" fi + fi else - debug_echo "No existing terminal found, creating new one" - if spawn_terminal; then - TERMINAL_ADDR=$(get_terminal_address) - if [ -n "$TERMINAL_ADDR" ]; then - hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" - fi + debug_echo "No existing terminal found, creating new one" + if spawn_terminal; then + TERMINAL_ADDR=$(get_terminal_address) + if [ -n "$TERMINAL_ADDR" ]; then + hyprctl dispatch focuswindow "address:$TERMINAL_ADDR" fi + fi fi -- cgit v1.2.3 From 1195ecd49921dc4e243454450440de24f5ab4d76 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Mon, 20 Oct 2025 14:23:03 -0400 Subject: Waybar: fix rofi selection marker stripping; prevent embedding ๐Ÿ‘‰ in symlink names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: reselecting the current style/layout left the '๐Ÿ‘‰ ' prefix in the choice, so the symlink target included it (e.g., style.css -> .../๐Ÿ‘‰ [0 VERTICAL] [Catpuccin] Mocha.css). Cause: options are annotated as "๐Ÿ‘‰ ${name}", but the code used: choice=${choice# $MARKER} (matches ' ๐Ÿ‘‰'), not the actual prefix '๐Ÿ‘‰ '. Fix: use choice=${choice#"$MARKER "} in WaybarStyles.sh and WaybarLayout.sh. Result: selecting the same item no longer pollutes the symlink target. --- config/hypr/scripts/WaybarLayout.sh | 2 +- config/hypr/scripts/WaybarStyles.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/hypr/scripts/WaybarLayout.sh b/config/hypr/scripts/WaybarLayout.sh index b4d9c493..f65c9c00 100755 --- a/config/hypr/scripts/WaybarLayout.sh +++ b/config/hypr/scripts/WaybarLayout.sh @@ -50,7 +50,7 @@ main() { [[ -z "$choice" ]] && { echo "No option selected. Exiting."; exit 0; } # Strip marker before applying - choice=${choice# $MARKER} + choice=${choice#"$MARKER "} case "$choice" in "no panel") diff --git a/config/hypr/scripts/WaybarStyles.sh b/config/hypr/scripts/WaybarStyles.sh index a439f8eb..15767c2a 100755 --- a/config/hypr/scripts/WaybarStyles.sh +++ b/config/hypr/scripts/WaybarStyles.sh @@ -51,7 +51,7 @@ main() { [[ -z "$choice" ]] && { echo "No option selected. Exiting."; exit 0; } # remove annotation and apply - choice=${choice# $MARKER} + choice=${choice#"$MARKER "} apply_style "$choice" } -- cgit v1.2.3 From 2da2474592577766136b11847b22ade05cd5ac58 Mon Sep 17 00:00:00 2001 From: brockar Date: Mon, 20 Oct 2025 17:12:57 -0300 Subject: config: add env var for dots version --- config/hypr/UserConfigs/ENVariables.conf | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/hypr/UserConfigs/ENVariables.conf b/config/hypr/UserConfigs/ENVariables.conf index f24cc306..d82fc2a6 100644 --- a/config/hypr/UserConfigs/ENVariables.conf +++ b/config/hypr/UserConfigs/ENVariables.conf @@ -4,6 +4,9 @@ # Set your defaults editor through ENV in ~/.config/hypr/UserConfigs/01-UserDefaults.conf # environment-variables +# Current Version of JakooLit Dotfiles: +env = DOTS_VERSION,2.3.17 + # Toolkit Backend Variables env = GDK_BACKEND,wayland,x11,* env = QT_QPA_PLATFORM,wayland;xcb -- cgit v1.2.3 From 88a5a701937ae0a91ab0919c59d595a198b440e5 Mon Sep 17 00:00:00 2001 From: brockar Date: Mon, 20 Oct 2025 17:13:24 -0300 Subject: config: fastfetch: add the dots version on every fastfetch --- config/fastfetch/config-compact.jsonc | 10 +++++++-- config/fastfetch/config-pokemon.jsonc | 8 ++++++- config/fastfetch/config-v2.jsonc | 42 ++++++++++++++++++++--------------- config/fastfetch/config.jsonc | 13 ++++++++--- 4 files changed, 49 insertions(+), 24 deletions(-) diff --git a/config/fastfetch/config-compact.jsonc b/config/fastfetch/config-compact.jsonc index fc2c4884..d3d94d26 100644 --- a/config/fastfetch/config-compact.jsonc +++ b/config/fastfetch/config-compact.jsonc @@ -21,12 +21,18 @@ { "type": "custom", "format": " โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€๏†’โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ " - }, + }, { "type": "kernel", "key": "๎œ’ ", "keyColor": "yellow" }, + { + "type": "custom", + "key": "๎ฏ† ", + "format": "JaKooLit: {$DOTS_VERSION}", + "keyColor": "magenta" + }, { "type": "wm", "key": "๏’ˆ ", @@ -69,6 +75,6 @@ "type": "custom", "format": " \u001b[31m๏†’ \u001b[32m๏†’ \u001b[33m๏†’ \u001b[34m๏†’ \u001b[35m๏†’ \u001b[36m๏†’ \u001b[37m๏†’ \u001b[90m๏†’ " }, - "break", + "break" ] } diff --git a/config/fastfetch/config-pokemon.jsonc b/config/fastfetch/config-pokemon.jsonc index 2b4522f4..a5cf6280 100644 --- a/config/fastfetch/config-pokemon.jsonc +++ b/config/fastfetch/config-pokemon.jsonc @@ -26,6 +26,12 @@ "key": "๎œ’ ", "keyColor": "yellow" }, + { + "type": "custom", + "key": "๎œ’ ", + "keyColor": "red", + "format": "JaKooLit Version: {$DOTS_VERSION}" + }, { "type": "wm", "key": "๏’ˆ ", @@ -68,6 +74,6 @@ "type": "custom", "format": " \u001b[31m๏†’ \u001b[32m๏†’ \u001b[33m๏†’ \u001b[34m๏†’ \u001b[35m๏†’ \u001b[36m๏†’ \u001b[37m๏†’ \u001b[90m๏†’ " }, - "break", + "break" ] } diff --git a/config/fastfetch/config-v2.jsonc b/config/fastfetch/config-v2.jsonc index 59509fe7..57cc9c65 100644 --- a/config/fastfetch/config-v2.jsonc +++ b/config/fastfetch/config-v2.jsonc @@ -20,95 +20,101 @@ { "type": "os", "key": "๎ฏ† DISTRO", - "keyColor": "31", + "keyColor": "31" }, { "type": "kernel", "key": " โ”œ ๏€“ ", - "keyColor": "31", + "keyColor": "31" + }, + { + "type": "custom", + "key": " โ”œ ๎ฏ† ", + "format": "JaKooLit Version: {$DOTS_VERSION}", + "keyColor": "31" }, { "type": "packages", "key": " โ”œ ๓ฐ– ", - "keyColor": "31", + "keyColor": "31" }, { "type": "shell", "key": " โ”” ๏’‰ ", - "keyColor": "31", + "keyColor": "31" }, "break", { "type": "wm", "key": "๏’ˆ DE/WM", - "keyColor": "32", + "keyColor": "32" }, { "type": "wmtheme", "key": " โ”œ ๓ฐ‰ผ ", - "keyColor": "32", + "keyColor": "32" }, { "type": "icons", "key": " โ”œ ๓ฐ€ป ", - "keyColor": "32", + "keyColor": "32" }, { "type": "cursor", "key": " โ”œ ๎˜ฃ ", - "keyColor": "32", + "keyColor": "32" }, { "type": "terminal", "key": " โ”œ ๎ž• ", - "keyColor": "32", + "keyColor": "32" }, { "type": "terminalfont", "key": " โ”” ๏€ฑ ", - "keyColor": "32", + "keyColor": "32" }, "break", { "type": "host", "format": "{2}", "key": "๓ฐŒข SYSTEM", - "keyColor": "33", + "keyColor": "33" }, { "type": "cpu", "format": "{1} ({3}) @ {7} GHz", "key": " โ”œ ๏’ผ ", - "keyColor": "33", + "keyColor": "33" }, { "type": "gpu", "format": "{2}", "key": " โ”œ ๓ฐขฎ ", - "keyColor": "33", + "keyColor": "33" }, { "type": "memory", "key": " โ”œ ๏‹› ", - "keyColor": "33", + "keyColor": "33" }, { "type": "swap", "key": " โ”œ ๓ฐ“ก ", - "keyColor": "33", + "keyColor": "33" }, { "type": "disk", "key": " โ”œ ๓ฐ‹Š ", - "keyColor": "33", + "keyColor": "33" }, { "type": "display", "key": " โ”” ๏„ˆ ", "compactType": "original-with-refresh-rate", - "keyColor": "33", + "keyColor": "33" }, "break", - "break", + "break" ] } diff --git a/config/fastfetch/config.jsonc b/config/fastfetch/config.jsonc index e3f8c3c6..fab0068c 100644 --- a/config/fastfetch/config.jsonc +++ b/config/fastfetch/config.jsonc @@ -17,10 +17,17 @@ "key": "๎ฏ† DISTRO", "keyColor": "yellow" }, + { "type": "kernel", "key": "โ”‚ โ”œ๏€“", "keyColor": "yellow" + }, + { + "type": "custom", + "key": "โ”‚ โ”œ๎ฏ†", + "format": "JaKooLit Version: {$DOTS_VERSION}", + "keyColor": "yellow" }, { "type": "packages", @@ -50,12 +57,12 @@ { "type": "cursor", "key": "โ”‚ โ”œ๎˜ฃ", - "keyColor": "blue", + "keyColor": "blue" }, { "type": "terminalfont", "key": "โ”‚ โ”œ๏€ฑ", - "keyColor": "blue", + "keyColor": "blue" }, { "type": "terminal", @@ -124,6 +131,6 @@ "type": "custom", "format": "\u001b[90m๏†’ \u001b[31m๏†’ \u001b[32m๏†’ \u001b[33m๏†’ \u001b[34m๏†’ \u001b[35m๏†’ \u001b[36m๏†’ \u001b[37m๏†’ \u001b[38m๏†’ \u001b[39m๏†’ \u001b[39m๏†’ ๏†’ \u001b[38m๏†’ \u001b[37m๏†’ \u001b[36m๏†’ \u001b[35m๏†’ \u001b[34m๏†’ \u001b[33m๏†’ \u001b[32m๏†’ \u001b[31m๏†’ \u001b[90m๏†’ " }, - "break", + "break" ] } -- cgit v1.2.3 From 53fe242ffdddf74bf13e32999027053ee4614b20 Mon Sep 17 00:00:00 2001 From: brockar Date: Mon, 20 Oct 2025 17:40:50 -0300 Subject: config: update icon from linux to hyprland for fastfetch --- config/fastfetch/config-compact.jsonc | 6 +++--- config/fastfetch/config-pokemon.jsonc | 6 +++--- config/fastfetch/config-v2.jsonc | 2 +- config/fastfetch/config.jsonc | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/config/fastfetch/config-compact.jsonc b/config/fastfetch/config-compact.jsonc index d3d94d26..962b6bb3 100644 --- a/config/fastfetch/config-compact.jsonc +++ b/config/fastfetch/config-compact.jsonc @@ -29,14 +29,14 @@ }, { "type": "custom", - "key": "๎ฏ† ", + "key": "๏™ ", "format": "JaKooLit: {$DOTS_VERSION}", - "keyColor": "magenta" + "keyColor": "blue" }, { "type": "wm", "key": "๏’ˆ ", - "keyColor": "blue" + "keyColor": "magenta" }, { "type": "shell", diff --git a/config/fastfetch/config-pokemon.jsonc b/config/fastfetch/config-pokemon.jsonc index a5cf6280..0435033c 100644 --- a/config/fastfetch/config-pokemon.jsonc +++ b/config/fastfetch/config-pokemon.jsonc @@ -28,14 +28,14 @@ }, { "type": "custom", - "key": "๎œ’ ", - "keyColor": "red", + "key": "๏™ ", + "keyColor": "blue", "format": "JaKooLit Version: {$DOTS_VERSION}" }, { "type": "wm", "key": "๏’ˆ ", - "keyColor": "blue" + "keyColor": "magenta" }, { "type": "shell", diff --git a/config/fastfetch/config-v2.jsonc b/config/fastfetch/config-v2.jsonc index 57cc9c65..6d20c695 100644 --- a/config/fastfetch/config-v2.jsonc +++ b/config/fastfetch/config-v2.jsonc @@ -29,7 +29,7 @@ }, { "type": "custom", - "key": " โ”œ ๎ฏ† ", + "key": " โ”œ ๏™ ", "format": "JaKooLit Version: {$DOTS_VERSION}", "keyColor": "31" }, diff --git a/config/fastfetch/config.jsonc b/config/fastfetch/config.jsonc index fab0068c..dce06d78 100644 --- a/config/fastfetch/config.jsonc +++ b/config/fastfetch/config.jsonc @@ -25,7 +25,7 @@ }, { "type": "custom", - "key": "โ”‚ โ”œ๎ฏ†", + "key": "โ”‚ โ”œ๏™", "format": "JaKooLit Version: {$DOTS_VERSION}", "keyColor": "yellow" }, -- cgit v1.2.3 From f86f0e7c7819bc7dd970353e81e51985b3267a34 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Sun, 26 Oct 2025 19:34:56 +0545 Subject: gitignore: add ignores for Python artifacts, virtualenvs, test/coverage, lint caches and editor files --- .gitignore | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.gitignore b/.gitignore index d20a9670..f85a9570 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,43 @@ WARP.md .warp.md result + +# Python artifacts +__pycache__/ +*.py[cod] +*.pyo +*.pyd +*.so +*.egg +*.egg-info/ +.eggs/ +dist/ +build/ +eggs/ +pip-wheel-metadata/ + +# Virtual environments +.venv/ +venv/ +env/ +ENV/ +.env + +# Testing and coverage +.pytest_cache/ +.coverage +.cache/ +.tox/ +htmlcov/ + +# Type checking and linting +.mypy_cache/ +.pytype/ +.flake8 +.ruff_cache/ + +# IDE and editor directories +.idea/ +.vscode/ +*.swp +*.swo -- cgit v1.2.3 From 7a147c0da9fb515cdb751014b737a33701063a74 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Sun, 26 Oct 2025 19:35:33 +0545 Subject: config(hypr): refactor Weather.py โ€” pathlib, typing, safer parsing & modular flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert to dataclasses (Location, WeatherData) and add richer typing/casts - Replace os.path with pathlib for cache paths and file I/O - Add robust numeric coercion helpers (coerce_int/float/number) and unit-safe parsing - Introduce ensure_dict/ensure_list and improved safe_get for resilient JSON traversal - Split geolocation into env/cache/ip providers and modular reverse-geocoding helpers - Modularize cache/fetch logic (try_cached, fetch_fresh, try_stale) and unify output builder - Safer handling of API cache timestamp/TTL and stale-cache fallback - Add simple tests for coercion functions --- config/hypr/UserScripts/Weather.py | 682 +++++++++++++++++++++++++++---------- 1 file changed, 502 insertions(+), 180 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index ca1d5281..d76fb8db 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -3,15 +3,42 @@ # Rewritten to use Open-Meteo APIs (worldwide, no API key) for robust weather data. # Outputs Waybar-compatible JSON and a simple text cache. +from __future__ import annotations + import json import os import sys import time import html -from typing import Any, Dict, List, Optional, Tuple - +from pathlib import Path +from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union, cast +from typing import NamedTuple import requests +from dataclasses import dataclass + +@dataclass +class Location: + lat: float + lon: float + place: Optional[str] = None + + +@dataclass +class WeatherData: + temp_str: str + feels_str: str + icon: str + status: str + min_max: str + wind_text: str + humidity_text: str + visibility_text: str + aqi_text: str + hourly_precip: str + is_day: int + code: int + # =============== Configuration =============== # You can configure behavior via environment variables OR the constants below. # Examples (zsh): @@ -27,9 +54,9 @@ import requests # export WEATHER_TOOLTIP_MARKUP=1 # 1 to enable Pango markup, 0 to disable # export WEATHER_LOC_ICON="๐Ÿ“" # or "*" for ASCII-only # -CACHE_DIR = os.path.expanduser("~/.cache") -API_CACHE_PATH = os.path.join(CACHE_DIR, "open_meteo_cache.json") -SIMPLE_TEXT_CACHE_PATH = os.path.join(CACHE_DIR, ".weather_cache") +CACHE_DIR: Path = Path.home() / ".cache" +API_CACHE_PATH: Path = CACHE_DIR / "open_meteo_cache.json" +SIMPLE_TEXT_CACHE_PATH: Path = CACHE_DIR / ".weather_cache" CACHE_TTL_SECONDS = int(os.getenv("WEATHER_CACHE_TTL", "600")) # default 10 minutes # Units: metric or imperial (default metric) @@ -138,19 +165,68 @@ def log_debug(msg: str) -> None: def ensure_cache_dir() -> None: try: - os.makedirs(CACHE_DIR, exist_ok=True) + # CACHE_DIR is a Path + CACHE_DIR.mkdir(parents=True, exist_ok=True) except Exception as e: print(f"Error creating cache dir: {e}", file=sys.stderr) +def _coerce_numeric(value: Any, to_int: bool) -> Optional[Union[int, float]]: + if to_int: + if isinstance(value, int): + return value + if isinstance(value, (float, str)): + try: + return int(float(value)) + except (ValueError, TypeError): + return None + return None + else: + if isinstance(value, float): + return value + if isinstance(value, int): + return float(value) + if isinstance(value, str): + try: + return float(value) + except (ValueError, TypeError): + return None + return None + + +def coerce_int(value: Any) -> Optional[int]: + return cast(Optional[int], _coerce_numeric(value, True)) + + +def coerce_float(value: Any) -> Optional[float]: + return cast(Optional[float], _coerce_numeric(value, False)) + + +def coerce_number(value: Any) -> Union[int, float, None]: + if isinstance(value, (int, float)): + return value + if isinstance(value, str): + try: + # Try float first, then int if no decimal + f = float(value) + return f if '.' in value or 'e' in value.lower() else int(f) + except (ValueError, TypeError): + return None + return None + + def read_api_cache() -> Optional[Dict[str, Any]]: try: - if not os.path.exists(API_CACHE_PATH): + if not API_CACHE_PATH.exists(): return None - with open(API_CACHE_PATH, "r", encoding="utf-8") as f: + with API_CACHE_PATH.open("r", encoding="utf-8") as f: data = json.load(f) - if (time.time() - data.get("timestamp", 0)) <= CACHE_TTL_SECONDS: - return data + # Use ensure_dict for safety + data_dict = ensure_dict(data) + timestamp_val = data_dict.get("timestamp", 0) + timestamp = coerce_float(timestamp_val) or 0 + if (time.time() - timestamp) <= CACHE_TTL_SECONDS: + return data_dict return None except Exception as e: print(f"Error reading cache: {e}", file=sys.stderr) @@ -161,7 +237,7 @@ 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: + with API_CACHE_PATH.open("w", encoding="utf-8") as f: json.dump(payload, f) except Exception as e: print(f"Error writing API cache: {e}", file=sys.stderr) @@ -170,34 +246,42 @@ def write_api_cache(payload: Dict[str, Any]) -> None: def write_simple_text_cache(text: str) -> None: try: ensure_cache_dir() - with open(SIMPLE_TEXT_CACHE_PATH, "w", encoding="utf-8") as f: + with SIMPLE_TEXT_CACHE_PATH.open("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 +def get_coords_from_env() -> Optional[Tuple[float, float]]: 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) + return None + - # 2) Try cached coordinates from last successful forecast +def get_coords_from_cache() -> Optional[Tuple[float, float]]: 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) + if cached: + fc = ensure_dict(cached.get("forecast")) + lat_raw = safe_get(fc, "latitude") + lon_raw = safe_get(fc, "longitude") + lat = coerce_float(lat_raw) + lon = coerce_float(lon_raw) + if lat is None: + log_debug(f"Unexpected type for cached latitude: {type(lat_raw)}") + if lon is None: + log_debug(f"Unexpected type for cached longitude: {type(lon_raw)}") + if lat is not None and lon is not None: + return lat, lon except Exception as e: print(f"Reading cached coords failed: {e}", file=sys.stderr) + return None + - # 3) IP-based geolocation with multiple providers (prefer ipwho.is, ipapi.co; ipinfo.io as fallback) - # ipwho.is +def get_coords_from_ipwho() -> Optional[Tuple[float, float]]: try: resp = SESSION.get("https://ipwho.is/", timeout=TIMEOUT) resp.raise_for_status() @@ -209,8 +293,10 @@ def get_coords() -> Tuple[float, float]: return float(lat), float(lon) except Exception as e: print(f"ipwho.is failed: {e}", file=sys.stderr) + return None + - # ipapi.co +def get_coords_from_ipapi() -> Optional[Tuple[float, float]]: try: resp = SESSION.get("https://ipapi.co/json", timeout=TIMEOUT) resp.raise_for_status() @@ -221,8 +307,10 @@ def get_coords() -> Tuple[float, float]: return float(lat), float(lon) except Exception as e: print(f"ipapi.co failed: {e}", file=sys.stderr) + return None - # ipinfo.io (fallback) + +def get_coords_from_ipinfo() -> Optional[Tuple[float, float]]: try: resp = SESSION.get("https://ipinfo.io/json", timeout=TIMEOUT) resp.raise_for_status() @@ -233,6 +321,24 @@ def get_coords() -> Tuple[float, float]: return float(lat_s), float(lon_s) except Exception as e: print(f"ipinfo.io failed: {e}", file=sys.stderr) + return None + + +def get_coords() -> Tuple[float, float]: + # 1) Explicit env + coords = get_coords_from_env() + if coords: + return coords + + # 2) Try cached coordinates + coords = get_coords_from_cache() + if coords: + return coords + + # 3) IP-based geolocation + coords = get_coords_from_ipwho() or get_coords_from_ipapi() or get_coords_from_ipinfo() + if coords: + return coords # 4) Last resort print("IP geolocation failed: no providers succeeded", file=sys.stderr) @@ -272,7 +378,7 @@ def format_visibility(meters: Optional[float]) -> str: def fetch_open_meteo(lat: float, lon: float) -> Dict[str, Any]: base = "https://api.open-meteo.com/v1/forecast" - params = { + params: Dict[str, Union[str, float]] = { "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", @@ -289,7 +395,7 @@ def fetch_open_meteo(lat: float, lon: float) -> Dict[str, Any]: def fetch_aqi(lat: float, lon: float) -> Optional[Dict[str, Any]]: try: base = "https://air-quality-api.open-meteo.com/v1/air-quality" - params = { + params: Dict[str, Union[str, float]] = { "latitude": lat, "longitude": lon, "current": "european_aqi", @@ -303,37 +409,51 @@ def fetch_aqi(lat: float, lon: float) -> Optional[Dict[str, Any]]: 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) +def extract_place_parts_nominatim(data_dict: JSONDict) -> List[str]: + address = ensure_dict(data_dict.get("address")) + candidates = [data_dict.get("name"), address.get("city"), address.get("town"), address.get("village"), address.get("hamlet")] + name = cast(Optional[str], next((c for c in candidates if c is not None), None)) + admin1 = cast(Optional[str], address.get("state")) + country = cast(Optional[str], address.get("country")) + parts: List[str] = [] + if name is not None: + parts.append(name) + if admin1 is not None: + parts.append(admin1) + if country is not None: + parts.append(country) + return parts + + +def extract_place_parts_open_meteo(p: JSONDict) -> List[str]: + name = cast(Optional[str], p.get("name")) + admin1 = cast(Optional[str], p.get("admin1")) + country = cast(Optional[str], p.get("country")) + parts: List[str] = [] + for part in [name, admin1, country]: + if part is not None: + parts.append(part) + return parts + + +def reverse_geocode(base: str, params: Dict[str, Union[str, float]], headers: Optional[Dict[str, str]] = None) -> Optional[str]: 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] + data_dict = ensure_dict(data) + parts = extract_place_parts_nominatim(data_dict) if parts: return ", ".join(parts) except Exception as e: - log_debug(f"Reverse geocoding (Nominatim) failed: {e}") + log_debug(f"Reverse geocoding failed: {e}") + return None - # 2) Open-Meteo reverse (fallback) + +def reverse_geocode_open_meteo(lat: float, lon: float, lang: str) -> Optional[str]: try: base = "https://geocoding-api.open-meteo.com/v1/reverse" - params = { + params: Dict[str, Union[str, float]] = { "latitude": lat, "longitude": lon, "language": lang, @@ -342,48 +462,107 @@ def fetch_place(lat: float, lon: float) -> Optional[str]: resp = SESSION.get(base, params=params, timeout=TIMEOUT) resp.raise_for_status() data = resp.json() - results = data.get("results") or [] + data_dict = ensure_dict(data) + results = ensure_list(data_dict.get("results")) 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] + p = ensure_dict(results[0]) + parts = extract_place_parts_open_meteo(p) if parts: return ", ".join(parts) except Exception as e: log_debug(f"Reverse geocoding (Open-Meteo) failed: {e}") - 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) + base = "https://nominatim.openstreetmap.org/reverse" + params: Dict[str, Union[str, float]] = { + "lat": lat, + "lon": lon, + "format": "jsonv2", + "accept-language": lang, + } + headers = {"User-Agent": UA + " Weather.py/1.0"} + place = reverse_geocode(base, params, headers) + if place: + return place + + # 2) Open-Meteo reverse (fallback) + return reverse_geocode_open_meteo(lat, lon, lang) + + # =============== Build Output =============== -def safe_get(dct: Dict[str, Any], *keys, default=None): - cur: Any = dct - for k in keys: +_T = TypeVar("_T") + +JSONValue = Union[str, int, float, bool, None, "JSONDict", "JSONList"] +JSONDict = Dict[str, JSONValue] +JSONList = List[JSONValue] + + +def ensure_dict(value: Any) -> JSONDict: + """Return a JSON-like dict when the incoming value looks like one.""" + if isinstance(value, dict): + return cast(JSONDict, value) + return cast(JSONDict, {}) + + +def ensure_list(value: Any) -> JSONList: + """Return a JSON-like list when the incoming value looks like one.""" + if isinstance(value, list): + return cast(JSONList, value) + return cast(JSONList, []) + + +def safe_get( + obj: JSONValue | None, + *keys: Union[str, int], + default: _T | None = None, +) -> _T | JSONValue | None: + """Safely traverse nested dict/list structures. + + Keys may be strings (for mapping lookups) or ints (for list indices). + Returns ``default`` if any lookup fails. + """ + + cur: JSONValue | None = obj + for key in keys: if isinstance(cur, dict): - if k not in cur: + if not isinstance(key, str) or key not in cur: return default - cur = cur[k] + cur = cur[key] elif isinstance(cur, list): - try: - cur = cur[k] # type: ignore[index] - except Exception: + if not isinstance(key, int) or key < 0 or key >= len(cur): return default + cur = cur[key] else: return default - return cur + return cast(_T | JSONValue | None, cur) -def build_hourly_precip(forecast: Dict[str, Any]) -> str: +def get_precipitation_probabilities(forecast: JSONDict) -> List[Optional[float]]: + probs_raw = safe_get(forecast, "hourly", "precipitation_probability") + probs_raw_list = ensure_list(probs_raw) + return [coerce_float(p) if p is not None else None for p in probs_raw_list] + + +def find_current_index(times: List[str], cur_time: Optional[str]) -> int: + if cur_time is not None and cur_time in times: + return times.index(cur_time) + return 0 + + +def build_hourly_precip(forecast: JSONDict) -> 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 + times_raw = safe_get(forecast, "hourly", "time") + times: List[str] = cast(List[str], ensure_list(times_raw)) + probs = get_precipitation_probabilities(forecast) + cur_time: Optional[str] = cast(Optional[str], safe_get(forecast, "current", "time")) + idx = find_current_index(times, cur_time) window = probs[idx : idx + 6] if not window: return "" @@ -393,152 +572,295 @@ def build_hourly_precip(forecast: Dict[str, Any]) -> str: 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", {}) +def build_weather_strings(cur: JSONDict, cur_units: JSONDict, daily: JSONDict, daily_units: JSONDict, temp_unit: str) -> Tuple[str, str, int, int, str, str, str]: + temp_val = coerce_float(cur.get("temperature_2m")) + temp_unit_str = cast(str, cur_units.get("temperature_2m", "")) + temp_str = f"{int(round(temp_val))}{temp_unit_str}" if temp_val is not None else "N/A" - 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 = coerce_float(cur.get("apparent_temperature")) + feels_unit = cast(str, cur_units.get("apparent_temperature", "")) + feels_str = f"Feels like {int(round(feels_val))}{feels_unit}" if feels_val is not None else "" - 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) + is_day_val = cur.get("is_day") + is_day = coerce_int(is_day_val) or 1 + weather_code_val = cur.get("weather_code") + code = coerce_int(weather_code_val) or -1 icon = wmo_to_icon(code, is_day) status = wmo_to_status(code) - # 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 "" + tmin_val = coerce_float(safe_get(daily, "temperature_2m_min", 0)) + tmax_val = coerce_float(safe_get(daily, "temperature_2m_max", 0)) + dtemp_unit = cast(str, daily_units.get("temperature_2m_min", temp_unit)) + tmin_str = f"{int(round(tmin_val))}{dtemp_unit}" if tmin_val is not None else "" + tmax_str = f"{int(round(tmax_val))}{dtemp_unit}" if tmax_val is not None 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 "" + return temp_str, feels_str, is_day, code, icon, status, min_max + + +def build_weather_details(cur: JSONDict, cur_units: JSONDict) -> Tuple[str, str, str]: + wind_val_raw = cur.get("wind_speed_10m") + wind_val = coerce_float(wind_val_raw) + wind_unit = cast(str, cur_units.get("wind_speed_10m", "")) + if wind_val is None: + log_debug(f"Unexpected type for wind_speed_10m: {type(wind_val_raw)}") + wind_text = f" {int(round(wind_val))}{wind_unit}" if wind_val is not None else "" + + hum_val_raw = cur.get("relative_humidity_2m") + hum_val = coerce_float(hum_val_raw) + if hum_val is None: + log_debug(f"Unexpected type for relative_humidity_2m: {type(hum_val_raw)}") + humidity_text = f" {int(hum_val)}%" if hum_val is not None else "" + + vis_val_raw = cur.get("visibility") + vis_val = coerce_float(vis_val_raw) + if vis_val is None: + log_debug(f"Unexpected type for visibility: {type(vis_val_raw)}") + visibility_text = f" {format_visibility(vis_val)}" if vis_val is not None else "" + + return wind_text, humidity_text, visibility_text + + +def build_aqi_info(aqi: Optional[Dict[str, Any]]) -> str: + aqi_dict = ensure_dict(aqi) + aqi_val_raw = safe_get(aqi_dict, "current", "european_aqi") + aqi_val = coerce_float(aqi_val_raw) + if aqi_val is None: + log_debug(f"Unexpected type for european_aqi: {type(aqi_val_raw)}") + return f"AQI {int(aqi_val)}" if aqi_val is not None else "AQI N/A" + + +def build_place_str(lat: float, lon: float, place: Optional[str]) -> str: + return MANUAL_PLACE or ENV_PLACE or place or f"{lat:.3f}, {lon:.3f}" + + + + +class TooltipParams(NamedTuple): + temp_str: str + icon: str + status: str + location_text: str + feels_str: str + min_max: str + wind_text: str + humidity_text: str + visibility_text: str + aqi_text: str + hourly_precip: str + + +def build_tooltip_markup(params: TooltipParams) -> str: + return str.format( + "\t\t{}\t\t\n{}\n{}\n{}\n{}\n\n{}\n{}\n{}{}", + f'{esc(params.temp_str)}', + f" {params.icon}", + f"{esc(params.status)}", + esc(params.location_text), + f"{esc(params.feels_str)}" if params.feels_str else "", + f"{esc(params.min_max)}" if params.min_max else "", + f"{esc(params.wind_text)}\t{esc(params.humidity_text)}", + f"{esc(params.visibility_text)}\t{esc(params.aqi_text)}", + f" {esc(params.hourly_precip)}" if params.hourly_precip 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 "" +def build_tooltip_plain(params: TooltipParams) -> str: + lines = [ + f"{params.icon} {params.temp_str}", + params.status, + params.location_text, + ] + if params.feels_str: + lines.append(params.feels_str) + if params.min_max: + lines.append(params.min_max) + combined_wind = f"{params.wind_text} {params.humidity_text}".strip() + if combined_wind: + lines.append(combined_wind) + combined_visibility = f"{params.visibility_text} {params.aqi_text}".strip() + if combined_visibility: + lines.append(combined_visibility) + if params.hourly_precip: + lines.append(params.hourly_precip) + return "\n".join([ln for ln in lines if ln]) + + +def build_tooltip_text(params: TooltipParams) -> str: + if TOOLTIP_MARKUP: + return build_tooltip_markup(params) + else: + return build_tooltip_plain(params) + + +def gather_weather_data(forecast: Optional[Dict[str, Any]], aqi: Optional[Dict[str, Any]]) -> WeatherData: + forecast_dict = ensure_dict(forecast) + cur = ensure_dict(forecast_dict.get("current")) + cur_units = ensure_dict(forecast_dict.get("current_units")) + daily = ensure_dict(forecast_dict.get("daily")) + daily_units = ensure_dict(forecast_dict.get("daily_units")) + + temp_str, feels_str, is_day, code, icon, status, min_max = build_weather_strings(cur, cur_units, daily, daily_units, cast(str, cur_units.get("temperature_2m", ""))) + wind_text, humidity_text, visibility_text = build_weather_details(cur, cur_units) + aqi_text = build_aqi_info(aqi) + hourly_precip = build_hourly_precip(forecast_dict) + + return WeatherData( + temp_str=temp_str, + feels_str=feels_str, + icon=icon, + status=status, + min_max=min_max, + wind_text=wind_text, + humidity_text=humidity_text, + visibility_text=visibility_text, + aqi_text=aqi_text, + hourly_precip=hourly_precip, + is_day=is_day, + code=code, + ) - 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 "" +def build_output(loc: Location, forecast: Optional[Dict[str, Any]], aqi: Optional[Dict[str, Any]]) -> Tuple[Dict[str, str], str]: + data = gather_weather_data(forecast, aqi) - # 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}") + place_str = build_place_str(loc.lat, loc.lon, loc.place) 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'{esc(temp_str)}', - f" {icon}", - f"{esc(status)}", - esc(location_text), - f"{esc(feels_str)}" if feels_str else "", - f"{esc(min_max)}" if min_max else "", - f"{esc(wind_text)}\t{esc(humidity_text)}", - f"{esc(visibility_text)}\t{esc(aqi_text)}", - f" {esc(prediction)}" if prediction else "", + tooltip_text = build_tooltip_text( + TooltipParams( + data.temp_str, data.icon, data.status, location_text, data.feels_str, data.min_max, + data.wind_text, data.humidity_text, data.visibility_text, data.aqi_text, data.hourly_precip ) - 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, + ) + + out_data: Dict[str, str] = { + "text": f"{data.icon} {data.temp_str}", + "alt": data.status, "tooltip": tooltip_text, - "class": f"wmo-{code} {'day' if is_day else 'night'}", + "class": f"wmo-{data.code} {'day' if data.is_day else 'night'}", } 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" + f"{data.icon} {data.status}\n" + + f"๏‹‰ {data.temp_str} ({data.feels_str})\n" + + (f"{data.wind_text} \n" if data.wind_text else "") + + (f"{data.humidity_text} \n" if data.humidity_text else "") + + f"{data.visibility_text} {data.aqi_text}\n" ) return out_data, simple_weather -def main() -> None: - lat, lon = get_coords() - - # Try cache first +def try_cached_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], str]]: 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 + if cached: + forecast = cast(Optional[Dict[str, Any]], cached.get("forecast")) + aqi = cast(Optional[Dict[str, Any]], cached.get("aqi")) + place_val = cached.get("place") + cached_place = place_val if isinstance(place_val, 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 + return build_output(Location(lat, lon, place_effective), forecast, aqi) except Exception as e: print(f"Cached data build failed, refetching: {e}", file=sys.stderr) + return None - # Fetch fresh + +def fetch_fresh_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], str]]: 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) + return build_output(Location(lat, lon, place_effective), forecast, aqi) 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)) + return None + + +def try_stale_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], str]]: + try: + if API_CACHE_PATH.exists(): + with API_CACHE_PATH.open("r", encoding="utf-8") as f: + stale = json.load(f) + stale_dict = ensure_dict(stale) + place_val = stale_dict.get("place") + place = place_val if isinstance(place_val, str) else None + forecast = cast(Optional[Dict[str, Any]], stale_dict.get("forecast")) + aqi = cast(Optional[Dict[str, Any]], stale_dict.get("aqi")) + return build_output(Location(lat, lon, place), forecast, aqi) + except Exception as e2: + print(f"Failed to use stale cache: {e2}", file=sys.stderr) + return None + + +def main() -> None: + lat, lon = get_coords() + + # Try cache first + result = try_cached_weather(lat, lon) + if result: + out, simple = result + print(json.dumps(out, ensure_ascii=False)) + write_simple_text_cache(simple) + return + + # Fetch fresh + result = fetch_fresh_weather(lat, lon) + if result: + out, simple = result + print(json.dumps(out, ensure_ascii=False)) + write_simple_text_cache(simple) + return + + # Last resort: try stale cache + result = try_stale_weather(lat, lon) + if result: + out, simple = result + print(json.dumps(out, ensure_ascii=False)) + write_simple_text_cache(simple) + return + + # 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)) + + +def test_coerce_functions(): + """Manual testing for coerce functions.""" + # Test coerce_int + assert coerce_int(5) == 5 + assert coerce_int(5.5) == 5 + assert coerce_int("5") == 5 + assert coerce_int("5.7") == 5 + assert coerce_int("abc") is None + assert coerce_int(None) is None + + # Test coerce_float + assert coerce_float(5.5) == 5.5 + assert coerce_float(5) == 5.0 + assert coerce_float("5.5") == 5.5 + assert coerce_float("abc") is None + assert coerce_float(None) is None + + # Test coerce_number + assert coerce_number(5) == 5 + assert coerce_number(5.5) == 5.5 + assert coerce_number("5") == 5 + assert coerce_number("5.5") == 5.5 + assert coerce_number("abc") is None + + print("All coerce function tests passed.", file=sys.stderr) if __name__ == "__main__": - main() + if len(sys.argv) > 1 and sys.argv[1] == "--test": + test_coerce_functions() + else: + main() -- cgit v1.2.3 From 30839413484f72343d66035bbd77af700059d0a3 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Sun, 26 Oct 2025 19:42:36 +0545 Subject: config(hypr): improve numeric coercion and add ensure_* warnings - Parse numeric strings more robustly in coerce_number: convert to float then return int when the float has no fractional part (handles scientific notation and avoids brittle '.'/'e' checks). - Add diagnostic warnings to ensure_dict and ensure_list that print the unexpected type and a truncated repr to stderr to help detect API shape mismatches. --- config/hypr/UserScripts/Weather.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index d76fb8db..a566d5ec 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -207,9 +207,9 @@ def coerce_number(value: Any) -> Union[int, float, None]: return value if isinstance(value, str): try: - # Try float first, then int if no decimal + # Parse to float, then return int if it has no fractional part f = float(value) - return f if '.' in value or 'e' in value.lower() else int(f) + return int(f) if f.is_integer() else f except (ValueError, TypeError): return None return None @@ -508,6 +508,11 @@ def ensure_dict(value: Any) -> JSONDict: """Return a JSON-like dict when the incoming value looks like one.""" if isinstance(value, dict): return cast(JSONDict, value) + # Warn about unexpected type to catch API shape mismatches + val_repr = repr(value) if value is not None else "None" + if len(val_repr) > 100: + val_repr = val_repr[:100] + "..." + print(f"Warning: ensure_dict received {type(value).__name__} instead of dict: {val_repr}", file=sys.stderr) return cast(JSONDict, {}) @@ -515,6 +520,11 @@ def ensure_list(value: Any) -> JSONList: """Return a JSON-like list when the incoming value looks like one.""" if isinstance(value, list): return cast(JSONList, value) + # Warn about unexpected type to catch API shape mismatches + val_repr = repr(value) if value is not None else "None" + if len(val_repr) > 100: + val_repr = val_repr[:100] + "..." + print(f"Warning: ensure_list received {type(value).__name__} instead of list: {val_repr}", file=sys.stderr) return cast(JSONList, []) -- cgit v1.2.3 From f876fc42308b949e791e6f685fa9c6f32605667e Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Sun, 26 Oct 2025 19:53:08 +0545 Subject: config(hypr): relax out_data typing in Weather.py to Dict[str, Any] Change out_data annotation from Dict[str, str] to Dict[str, Any] so the output can include non-string values (tooltip, class, etc.) and avoid type mismatches. --- config/hypr/UserScripts/Weather.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index a566d5ec..3c5d58f9 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -744,7 +744,7 @@ def build_output(loc: Location, forecast: Optional[Dict[str, Any]], aqi: Optiona ) ) - out_data: Dict[str, str] = { + out_data: Dict[str, Any] = { "text": f"{data.icon} {data.temp_str}", "alt": data.status, "tooltip": tooltip_text, -- cgit v1.2.3 From 95b85dd6c59620d660ff320a07bdf7b3c42bdc46 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 10:32:36 +0545 Subject: config(hypr): disable tooltip markup by default, refine place handling & simple output; replace wttr wrapper - Set TOOLTIP_MARKUP default to off (ENV-driven still supported). - Use truthy checks in place extraction helpers and simplify extraction logic. - Change place formatting to show resolved place with coordinates or coordinates-only. - Prepend place to simple text cache and add icons for wind, humidity and visibility. - Replace legacy wttr-based Weather.sh with a direct Python Weather.py invocation. --- config/hypr/UserScripts/Weather.py | 28 ++++++++----- config/hypr/UserScripts/Weather.sh | 86 +------------------------------------- 2 files changed, 19 insertions(+), 95 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 3c5d58f9..3b58d8ff 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -74,7 +74,7 @@ MANUAL_PLACE: Optional[str] = None # Location icon in tooltip (default to a standard emoji to avoid missing glyphs) LOC_ICON = os.getenv("WEATHER_LOC_ICON", "๐Ÿ“") # Enable/disable Pango markup in tooltip (1/0, true/false) -TOOLTIP_MARKUP = os.getenv("WEATHER_TOOLTIP_MARKUP", "1").lower() not in ("0", "false", "no") +TOOLTIP_MARKUP = os.getenv("WEATHER_TOOLTIP_MARKUP", "0").lower() not in ("0", "false", "no") # Optional debug logging to stderr (set WEATHER_DEBUG=1 to enable) DEBUG = os.getenv("WEATHER_DEBUG", "0").lower() not in ("0", "false", "no") @@ -416,11 +416,11 @@ def extract_place_parts_nominatim(data_dict: JSONDict) -> List[str]: admin1 = cast(Optional[str], address.get("state")) country = cast(Optional[str], address.get("country")) parts: List[str] = [] - if name is not None: + if name: parts.append(name) - if admin1 is not None: + if admin1: parts.append(admin1) - if country is not None: + if country: parts.append(country) return parts @@ -430,9 +430,12 @@ def extract_place_parts_open_meteo(p: JSONDict) -> List[str]: admin1 = cast(Optional[str], p.get("admin1")) country = cast(Optional[str], p.get("country")) parts: List[str] = [] - for part in [name, admin1, country]: - if part is not None: - parts.append(part) + if name: + parts.append(name) + if admin1: + parts.append(admin1) + if country: + parts.append(country) return parts @@ -641,7 +644,9 @@ def build_aqi_info(aqi: Optional[Dict[str, Any]]) -> str: def build_place_str(lat: float, lon: float, place: Optional[str]) -> str: - return MANUAL_PLACE or ENV_PLACE or place or f"{lat:.3f}, {lon:.3f}" + if place: + return f"{place} ({lat:.3f}, {lon:.3f})" + return f"{lat:.3f}, {lon:.3f}" @@ -752,11 +757,12 @@ def build_output(loc: Location, forecast: Optional[Dict[str, Any]], aqi: Optiona } simple_weather = ( + f"{place_str}\n" f"{data.icon} {data.status}\n" + f"๏‹‰ {data.temp_str} ({data.feels_str})\n" - + (f"{data.wind_text} \n" if data.wind_text else "") - + (f"{data.humidity_text} \n" if data.humidity_text else "") - + f"{data.visibility_text} {data.aqi_text}\n" + + (f"๎‰พ {data.wind_text} \n" if data.wind_text else "") + + (f"๎ณ {data.humidity_text} \n" if data.humidity_text else "") + + f"๏ฎ {data.visibility_text} {data.aqi_text}\n" ) return out_data, simple_weather diff --git a/config/hypr/UserScripts/Weather.sh b/config/hypr/UserScripts/Weather.sh index 9bdaff4a..744878a9 100755 --- a/config/hypr/UserScripts/Weather.sh +++ b/config/hypr/UserScripts/Weather.sh @@ -1,87 +1,5 @@ #!/bin/bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## -# weather info from wttr. https://github.com/chubin/wttr.in -# Remember to add city +# weather info using Python script with Open-Meteo APIs -city= -cachedir="$HOME/.cache/rbn" -cachefile=${0##*/}-$1 - -if [ ! -d $cachedir ]; then - mkdir -p $cachedir -fi - -if [ ! -f $cachedir/$cachefile ]; then - touch $cachedir/$cachefile -fi - -# Save current IFS -SAVEIFS=$IFS -# Change IFS to new line. -IFS=$'\n' - -cacheage=$(($(date +%s) - $(stat -c '%Y' "$cachedir/$cachefile"))) -if [ $cacheage -gt 1740 ] || [ ! -s $cachedir/$cachefile ]; then - data=($(curl -s https://en.wttr.in/"$city"$1\?0qnT 2>&1)) - echo ${data[0]} | cut -f1 -d, > $cachedir/$cachefile - echo ${data[1]} | sed -E 's/^.{15}//' >> $cachedir/$cachefile - echo ${data[2]} | sed -E 's/^.{15}//' >> $cachedir/$cachefile -fi - -weather=($(cat $cachedir/$cachefile)) - -# Restore IFSClear -IFS=$SAVEIFS - -temperature=$(echo ${weather[2]} | sed -E 's/([[:digit:]]+)\.\./\1 to /g') - -#echo ${weather[1]##*,} - -# https://fontawesome.com/icons?s=solid&c=weather -case $(echo ${weather[1]##*,} | tr '[:upper:]' '[:lower:]') in -"clear" | "sunny") - condition="๎Œ" - ;; -"partly cloudy") - condition="๓ฐ–•" - ;; -"cloudy") - condition="๎Œ’" - ;; -"overcast") - condition="๎ŒŒ" - ;; -"fog" | "freezing fog") - condition="๎Œ“" - ;; -"patchy rain possible" | "patchy light drizzle" | "light drizzle" | "patchy light rain" | "light rain" | "light rain shower" | "mist" | "rain") - condition="๓ฐผณ" - ;; -"moderate rain at times" | "moderate rain" | "heavy rain at times" | "heavy rain" | "moderate or heavy rain shower" | "torrential rain shower" | "rain shower") - condition="๎ˆน" - ;; -"patchy snow possible" | "patchy sleet possible" | "patchy freezing drizzle possible" | "freezing drizzle" | "heavy freezing drizzle" | "light freezing rain" | "moderate or heavy freezing rain" | "light sleet" | "ice pellets" | "light sleet showers" | "moderate or heavy sleet showers") - condition="๓ฐผด" - ;; -"blowing snow" | "moderate or heavy sleet" | "patchy light snow" | "light snow" | "light snow showers") - condition="๓ฐ™ฟ" - ;; -"blizzard" | "patchy moderate snow" | "moderate snow" | "patchy heavy snow" | "heavy snow" | "moderate or heavy snow with thunder" | "moderate or heavy snow showers") - condition="๎ž" - ;; -"thundery outbreaks possible" | "patchy light rain with thunder" | "moderate or heavy rain with thunder" | "patchy light snow with thunder") - condition="๎Œ" - ;; -*) - condition="๏ช" - echo -e "{\"text\":\""$condition"\", \"alt\":\""${weather[0]}"\", \"tooltip\":\""${weather[0]}: $temperature ${weather[1]}"\"}" - ;; -esac - -#echo $temp $condition - -echo -e "{\"text\":\""$temperature $condition"\", \"alt\":\""${weather[0]}"\", \"tooltip\":\""${weather[0]}: $temperature ${weather[1]}"\"}" - -cached_weather="๏‹‰ $temperature \n$condition ${weather[1]}" - -echo -e $cached_weather > "$HOME/.cache/.weather_cache" \ No newline at end of file +python3 "$(dirname "$0")/Weather.py" \ No newline at end of file -- cgit v1.2.3 From 7275b5f73ff6c1164cba645a5f41ac088a10e7cc Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 10:35:13 +0545 Subject: config(hypr): run Weather.sh at startup; lower weather cache TTL to 5 minutes --- config/hypr/UserConfigs/Startup_Apps.conf | 3 +++ config/hypr/UserScripts/Weather.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf index 738eb2da..976208e9 100644 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ b/config/hypr/UserConfigs/Startup_Apps.conf @@ -47,6 +47,9 @@ exec-once = $UserScripts/RainbowBorders.sh # Starting hypridle to start hyprlock exec-once = hypridle +# Weather script to populate cache on startup +exec-once = $UserScripts/Weather.sh + # Here are list of features available but disabled by default # exec-once = swww-daemon --format xrgb && swww img $HOME/Pictures/wallpapers/mecha-nostalgia.png # persistent wallpaper diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 3b58d8ff..47c88d1f 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -57,7 +57,7 @@ class WeatherData: CACHE_DIR: Path = Path.home() / ".cache" API_CACHE_PATH: Path = CACHE_DIR / "open_meteo_cache.json" SIMPLE_TEXT_CACHE_PATH: Path = CACHE_DIR / ".weather_cache" -CACHE_TTL_SECONDS = int(os.getenv("WEATHER_CACHE_TTL", "600")) # default 10 minutes +CACHE_TTL_SECONDS = int(os.getenv("WEATHER_CACHE_TTL", "300")) # default 5 minutes # Units: metric or imperial (default metric) UNITS = os.getenv("WEATHER_UNITS", "metric").strip().lower() # metric|imperial -- cgit v1.2.3 From a37147a7c3f236028f1f44ebdc6fbb915cf2d5f0 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 10:44:54 +0545 Subject: config(hypr): add python3 availability check, forward args and propagate exit status in Weather.sh --- config/hypr/UserScripts/Weather.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/config/hypr/UserScripts/Weather.sh b/config/hypr/UserScripts/Weather.sh index 744878a9..0540e51d 100755 --- a/config/hypr/UserScripts/Weather.sh +++ b/config/hypr/UserScripts/Weather.sh @@ -2,4 +2,14 @@ # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # weather info using Python script with Open-Meteo APIs -python3 "$(dirname "$0")/Weather.py" \ No newline at end of file +if ! command -v python3 >/dev/null 2>&1; then + echo "python3 not found in PATH" >&2 + exit 127 +fi + +python3 "$(dirname "$0")/Weather.py" "$@" +exit_code=$? +if [ "$exit_code" -ne 0 ]; then + echo "Failed to run Weather.py" >&2 +fi +exit "$exit_code" \ No newline at end of file -- cgit v1.2.3 From d299040a6826be545e18a892994226a58ad0c10a Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 10:57:46 +0545 Subject: config(hypr): preserve empty place strings and use explicit None checks Use `is not None` when extracting open-meteo place parts so empty strings aren't discarded. Replace truthy `or` chains for selecting the effective place with explicit None-aware conditionals so MANUAL_PLACE/ENV_PLACE empty values are honored instead of being treated as false. --- config/hypr/UserScripts/Weather.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 47c88d1f..6189c647 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -430,11 +430,11 @@ def extract_place_parts_open_meteo(p: JSONDict) -> List[str]: admin1 = cast(Optional[str], p.get("admin1")) country = cast(Optional[str], p.get("country")) parts: List[str] = [] - if name: + if name is not None: parts.append(name) - if admin1: + if admin1 is not None: parts.append(admin1) - if country: + if country is not None: parts.append(country) return parts @@ -775,7 +775,7 @@ def try_cached_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], aqi = cast(Optional[Dict[str, Any]], cached.get("aqi")) place_val = cached.get("place") cached_place = place_val if isinstance(place_val, str) else None - place_effective = MANUAL_PLACE or ENV_PLACE or cached_place + place_effective = MANUAL_PLACE if MANUAL_PLACE is not None else (ENV_PLACE if ENV_PLACE is not None else cached_place) try: return build_output(Location(lat, lon, place_effective), forecast, aqi) except Exception as e: @@ -787,7 +787,7 @@ def fetch_fresh_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str] try: forecast = fetch_open_meteo(lat, lon) aqi = fetch_aqi(lat, lon) - place_effective = MANUAL_PLACE or ENV_PLACE or fetch_place(lat, lon) + place_effective = MANUAL_PLACE if MANUAL_PLACE is not None else (ENV_PLACE if ENV_PLACE is not None else fetch_place(lat, lon)) write_api_cache({"forecast": forecast, "aqi": aqi, "place": place_effective}) return build_output(Location(lat, lon, place_effective), forecast, aqi) except Exception as e: @@ -803,9 +803,10 @@ def try_stale_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], stale_dict = ensure_dict(stale) place_val = stale_dict.get("place") place = place_val if isinstance(place_val, str) else None + place_effective = MANUAL_PLACE if MANUAL_PLACE is not None else (ENV_PLACE if ENV_PLACE is not None else place) forecast = cast(Optional[Dict[str, Any]], stale_dict.get("forecast")) aqi = cast(Optional[Dict[str, Any]], stale_dict.get("aqi")) - return build_output(Location(lat, lon, place), forecast, aqi) + return build_output(Location(lat, lon, place_effective), forecast, aqi) except Exception as e2: print(f"Failed to use stale cache: {e2}", file=sys.stderr) return None -- cgit v1.2.3 From f930ca046894ab12bb5907ffc9b4e5cbd3a5a2e4 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 11:05:44 +0545 Subject: config(hypr): skip empty place parts and simplify place selection using or-chaining Use truthy checks when building Open-Meteo place parts (ignore empty strings) and replace verbose None-check ternaries with `or` chains when resolving the effective place (prefer MANUAL_PLACE, then ENV_PLACE, then cached/fetched place). --- config/hypr/UserScripts/Weather.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 6189c647..7e350c30 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -430,11 +430,11 @@ def extract_place_parts_open_meteo(p: JSONDict) -> List[str]: admin1 = cast(Optional[str], p.get("admin1")) country = cast(Optional[str], p.get("country")) parts: List[str] = [] - if name is not None: + if name: parts.append(name) - if admin1 is not None: + if admin1: parts.append(admin1) - if country is not None: + if country: parts.append(country) return parts @@ -775,7 +775,7 @@ def try_cached_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], aqi = cast(Optional[Dict[str, Any]], cached.get("aqi")) place_val = cached.get("place") cached_place = place_val if isinstance(place_val, str) else None - place_effective = MANUAL_PLACE if MANUAL_PLACE is not None else (ENV_PLACE if ENV_PLACE is not None else cached_place) + place_effective = MANUAL_PLACE or ENV_PLACE or cached_place try: return build_output(Location(lat, lon, place_effective), forecast, aqi) except Exception as e: @@ -787,7 +787,7 @@ def fetch_fresh_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str] try: forecast = fetch_open_meteo(lat, lon) aqi = fetch_aqi(lat, lon) - place_effective = MANUAL_PLACE if MANUAL_PLACE is not None else (ENV_PLACE if ENV_PLACE is not None else fetch_place(lat, lon)) + place_effective = MANUAL_PLACE or ENV_PLACE or fetch_place(lat, lon) write_api_cache({"forecast": forecast, "aqi": aqi, "place": place_effective}) return build_output(Location(lat, lon, place_effective), forecast, aqi) except Exception as e: @@ -803,7 +803,7 @@ def try_stale_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], stale_dict = ensure_dict(stale) place_val = stale_dict.get("place") place = place_val if isinstance(place_val, str) else None - place_effective = MANUAL_PLACE if MANUAL_PLACE is not None else (ENV_PLACE if ENV_PLACE is not None else place) + place_effective = MANUAL_PLACE or ENV_PLACE or place forecast = cast(Optional[Dict[str, Any]], stale_dict.get("forecast")) aqi = cast(Optional[Dict[str, Any]], stale_dict.get("aqi")) return build_output(Location(lat, lon, place_effective), forecast, aqi) -- cgit v1.2.3 From c47eadb340dcdea51587537f4237f347653cb675 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 11:16:58 +0545 Subject: config(hypr): preserve empty place strings & prefer MANUAL/ENV place; use explicit None checks - Use explicit "is not None" checks when building place parts so empty strings are kept instead of being treated as falsy. - Build place string from MANUAL_PLACE or ENV_PLACE before reverse-geocoded place, preserving explicit overrides and empty place values. --- config/hypr/UserScripts/Weather.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 7e350c30..2a3e0ad2 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -416,11 +416,11 @@ def extract_place_parts_nominatim(data_dict: JSONDict) -> List[str]: admin1 = cast(Optional[str], address.get("state")) country = cast(Optional[str], address.get("country")) parts: List[str] = [] - if name: + if name is not None: parts.append(name) - if admin1: + if admin1 is not None: parts.append(admin1) - if country: + if country is not None: parts.append(country) return parts @@ -430,11 +430,11 @@ def extract_place_parts_open_meteo(p: JSONDict) -> List[str]: admin1 = cast(Optional[str], p.get("admin1")) country = cast(Optional[str], p.get("country")) parts: List[str] = [] - if name: + if name is not None: parts.append(name) - if admin1: + if admin1 is not None: parts.append(admin1) - if country: + if country is not None: parts.append(country) return parts @@ -644,8 +644,9 @@ def build_aqi_info(aqi: Optional[Dict[str, Any]]) -> str: def build_place_str(lat: float, lon: float, place: Optional[str]) -> str: - if place: - return f"{place} ({lat:.3f}, {lon:.3f})" + effective_place = MANUAL_PLACE or ENV_PLACE or place + if effective_place: + return f"{effective_place} ({lat:.3f}, {lon:.3f})" return f"{lat:.3f}, {lon:.3f}" -- cgit v1.2.3 From a8b355b490d6f0d4e5e5e219426ddffd26ca19f1 Mon Sep 17 00:00:00 2001 From: Prabin Panta Date: Mon, 27 Oct 2025 11:46:38 +0545 Subject: Update config/hypr/UserScripts/Weather.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- config/hypr/UserScripts/Weather.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 2a3e0ad2..ee861ebb 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -74,7 +74,7 @@ MANUAL_PLACE: Optional[str] = None # Location icon in tooltip (default to a standard emoji to avoid missing glyphs) LOC_ICON = os.getenv("WEATHER_LOC_ICON", "๐Ÿ“") # Enable/disable Pango markup in tooltip (1/0, true/false) -TOOLTIP_MARKUP = os.getenv("WEATHER_TOOLTIP_MARKUP", "0").lower() not in ("0", "false", "no") +TOOLTIP_MARKUP = os.getenv("WEATHER_TOOLTIP_MARKUP", "0").lower() in ("1", "true", "yes") # Optional debug logging to stderr (set WEATHER_DEBUG=1 to enable) DEBUG = os.getenv("WEATHER_DEBUG", "0").lower() not in ("0", "false", "no") -- cgit v1.2.3 From 94e1d96814cdaf41da1f4129f6a01447bd771af6 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 11:52:04 +0545 Subject: config(hypr): preserve fetched/cached place and stop preemptive MANUAL/ENV override Use the exact place value returned from fetch_place or stored in the API cache when writing/reading and when building output. Remove the early coalescing with MANUAL_PLACE/ENV_PLACE so cached/fetched place strings (including empty/None) are preserved and final selection is handled centrally by build_place_str. --- config/hypr/UserScripts/Weather.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index ee861ebb..c7638599 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -776,9 +776,8 @@ def try_cached_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], aqi = cast(Optional[Dict[str, Any]], cached.get("aqi")) place_val = cached.get("place") cached_place = place_val if isinstance(place_val, str) else None - place_effective = MANUAL_PLACE or ENV_PLACE or cached_place try: - return build_output(Location(lat, lon, place_effective), forecast, aqi) + return build_output(Location(lat, lon, cached_place), forecast, aqi) except Exception as e: print(f"Cached data build failed, refetching: {e}", file=sys.stderr) return None @@ -788,9 +787,9 @@ def fetch_fresh_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str] try: forecast = fetch_open_meteo(lat, lon) aqi = fetch_aqi(lat, lon) - place_effective = MANUAL_PLACE or ENV_PLACE or fetch_place(lat, lon) - write_api_cache({"forecast": forecast, "aqi": aqi, "place": place_effective}) - return build_output(Location(lat, lon, place_effective), forecast, aqi) + place = fetch_place(lat, lon) + write_api_cache({"forecast": forecast, "aqi": aqi, "place": place}) + return build_output(Location(lat, lon, place), forecast, aqi) except Exception as e: print(f"Open-Meteo fetch failed: {e}", file=sys.stderr) return None @@ -804,10 +803,9 @@ def try_stale_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], stale_dict = ensure_dict(stale) place_val = stale_dict.get("place") place = place_val if isinstance(place_val, str) else None - place_effective = MANUAL_PLACE or ENV_PLACE or place forecast = cast(Optional[Dict[str, Any]], stale_dict.get("forecast")) aqi = cast(Optional[Dict[str, Any]], stale_dict.get("aqi")) - return build_output(Location(lat, lon, place_effective), forecast, aqi) + return build_output(Location(lat, lon, place), forecast, aqi) except Exception as e2: print(f"Failed to use stale cache: {e2}", file=sys.stderr) return None -- cgit v1.2.3 From 2d4f945c6ffb850e21d3f2d24dc25087a207068d Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Mon, 27 Oct 2025 12:22:12 +0545 Subject: config(hypr): preserve valid zero values for is_day and weather_code by using explicit None checks --- config/hypr/UserScripts/Weather.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index c7638599..4c64221f 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -595,9 +595,11 @@ def build_weather_strings(cur: JSONDict, cur_units: JSONDict, daily: JSONDict, d feels_str = f"Feels like {int(round(feels_val))}{feels_unit}" if feels_val is not None else "" is_day_val = cur.get("is_day") - is_day = coerce_int(is_day_val) or 1 + is_day_int = coerce_int(is_day_val) + is_day = is_day_int if is_day_int is not None else 1 weather_code_val = cur.get("weather_code") - code = coerce_int(weather_code_val) or -1 + code_int = coerce_int(weather_code_val) + code = code_int if code_int is not None else -1 icon = wmo_to_icon(code, is_day) status = wmo_to_status(code) -- cgit v1.2.3 From 1ecc4dd6201aba5c0b0575c7b2d89bf9ff95d6af Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 16:36:20 +0545 Subject: feat(weather): prefer structured wttr.in format, harden cache and icons - Use wttr.in structured format first (%l, %C, %t) for stable 3-line parsing - Fallback to individual field requests when combined output omits temperature - Keep ASCII fallback as last resort; best-effort extraction of loc/cond/temp - Read/write cache via mapfile to avoid word splitting; validate temp line - Normalize condition string; extend mapping and add substring icon heuristics - Remove accidental double JSON print in default-case; ensure single output --- config/hypr/UserScripts/Weather.sh | 185 +++++++++++++++++++++++++++++++++++-- 1 file changed, 176 insertions(+), 9 deletions(-) diff --git a/config/hypr/UserScripts/Weather.sh b/config/hypr/UserScripts/Weather.sh index 0540e51d..deba2d41 100755 --- a/config/hypr/UserScripts/Weather.sh +++ b/config/hypr/UserScripts/Weather.sh @@ -1,15 +1,182 @@ #!/bin/bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## -# weather info using Python script with Open-Meteo APIs +# weather info from wttr. https://github.com/chubin/wttr.in +# Remember to add city -if ! command -v python3 >/dev/null 2>&1; then - echo "python3 not found in PATH" >&2 - exit 127 +city="" + + +# if city is blank, use https://ipapi.co/json to get location from IP +if [ -z "$city" ]; then + city=$(curl -fsS https://ipapi.co/json | grep city | cut -f4 -d'"') +fi + + +cachedir="$HOME/.cache/rbn" +# Include city and arg in cache key so changing city invalidates old cache +cache_key="${city}_${1}" +# Sanitize cache key to avoid problematic characters in filename +safe_key=$(printf '%s' "$cache_key" | tr -c '[:alnum:]_-' '_') +cachefile=${0##*/}-$safe_key + +if [ ! -d $cachedir ]; then + mkdir -p $cachedir +fi + +if [ ! -f $cachedir/$cachefile ]; then + touch $cachedir/$cachefile +fi + +# Save current IFS +SAVEIFS=$IFS +# Change IFS to new line. +IFS=$'\n' + +cacheage=$(($(date +%s) - $(stat -c '%Y' "$cachedir/$cachefile"))) +if [ $cacheage -gt 1740 ] || [ ! -s "$cachedir/$cachefile" ]; then + # Prefer structured format for reliable parsing (3 lines: location, condition, temperature) + mapfile -t sdata < <(curl -fsS "https://wttr.in/${city}?format=%25l%0A%25C%0A%25t&lang=en" 2>/dev/null || true) + if [ ${#sdata[@]} -ge 3 ]; then + printf "%s\n" "${sdata[0]}" > "$cachedir/$cachefile" + printf "%s\n" "${sdata[1]}" >> "$cachedir/$cachefile" + printf "%s\n" "${sdata[2]}" >> "$cachedir/$cachefile" + else + # Try fetching each field separately if combined format is flaky + loc=$(curl -fsS "https://wttr.in/${city}?format=%25l&lang=en" 2>/dev/null || true) + cond_only=$(curl -fsS "https://wttr.in/${city}?format=%25C&lang=en" 2>/dev/null || true) + temp_only=$(curl -fsS "https://wttr.in/${city}?format=%25t" 2>/dev/null || true) + if [ -n "$loc" ] && [ -n "$cond_only" ] && [ -n "$temp_only" ]; then + printf "%s\n" "$loc" > "$cachedir/$cachefile" + printf "%s\n" "$cond_only" >> "$cachedir/$cachefile" + printf "%s\n" "$temp_only" >> "$cachedir/$cachefile" + else + # Fallback: try ASCII output and extract best-effort fields + url="https://en.wttr.in/${city}?1" + mapfile -t data < <(curl -fsS "$url" 2>/dev/null || true) + if [ ${#data[@]} -ge 3 ] && ! echo "${data[0]}" | grep -qi 'not found\|unknown location'; then + loc=$(echo "${data[0]}" | sed -E 's/^.*: *//') + # Attempt to pull condition and temperature hints from nearby lines + cond=$(echo "${data[2]}" | sed -E 's/^.{0,15}//; s/^\s+//') + temp=$(printf "%s\n" "${data[@]}" | grep -Eo '\+?-?[0-9]+(\([^)]+\))? ?ยฐ?[CF]' | head -n1) + # Only write if we have at least location and something else meaningful + if [ -n "$loc" ] && { [ -n "$cond" ] || [ -n "$temp" ]; }; then + printf "%s\n" "$loc" > "$cachedir/$cachefile" + printf "%s\n" "${cond:-Unknown}" >> "$cachedir/$cachefile" + printf "%s\n" "${temp:-N/A}" >> "$cachedir/$cachefile" + fi + fi + fi + fi +fi + +# Read cache robustly (line-wise) +mapfile -t weather < "$cachedir/$cachefile" + +# If cache is still empty or invalid, emit a single error JSON and exit to avoid double-prints +if [ ${#weather[@]} -lt 3 ] || ! echo "${weather[2]}" | grep -qE '[-+0-9].*ยฐ'; then + # Last-chance: try live structured fetch and populate cache and runtime weather + mapfile -t sdata < <(curl -fsS "https://wttr.in/${city}?format=%25l%0A%25C%0A%25t&lang=en" 2>/dev/null || true) + if [ ${#sdata[@]} -ge 3 ]; then + weather=("${sdata[@]}") + printf "%s\n" "${sdata[0]}" > "$cachedir/$cachefile" + printf "%s\n" "${sdata[1]}" >> "$cachedir/$cachefile" + printf "%s\n" "${sdata[2]}" >> "$cachedir/$cachefile" + else + loc=$(curl -fsS "https://wttr.in/${city}?format=%25l&lang=en" 2>/dev/null || true) + cond_only=$(curl -fsS "https://wttr.in/${city}?format=%25C&lang=en" 2>/dev/null || true) + temp_only=$(curl -fsS "https://wttr.in/${city}?format=%25t" 2>/dev/null || true) + if [ -n "$loc" ] && [ -n "$cond_only" ] && [ -n "$temp_only" ]; then + weather=("$loc" "$cond_only" "$temp_only") + printf "%s\n" "$loc" > "$cachedir/$cachefile" + printf "%s\n" "$cond_only" >> "$cachedir/$cachefile" + printf "%s\n" "$temp_only" >> "$cachedir/$cachefile" + else + echo -e "{\"text\":\"\uf06a\", \"alt\":\"\", \"tooltip\":\": \"}" + exit 1 + fi + fi +fi + +# Restore IFSClear +IFS=$SAVEIFS + +temperature=$(echo "${weather[2]}" | sed -E 's/([[:digit:]]+)\.\./\1 to /g') + +#echo ${weather[1]##*,} + +# https://fontawesome.com/icons?s=solid&c=weather +# Normalize condition string for matching +cond_key=$(echo "${weather[1]##*,}" | tr '[:upper:]' '[:lower:]' | sed -E 's/^\s+//; s/\s+$//') +case "$cond_key" in +"clear" | "sunny") + condition="๎Œ" + ;; +"partly cloudy") + condition="๓ฐ–•" + ;; +"cloudy") + condition="๎Œ’" + ;; +"overcast") + condition="๎ŒŒ" + ;; +"fog" | "freezing fog") + condition="๎Œ“" + ;; +"patchy rain possible" | "patchy light drizzle" | "light drizzle" | "patchy light rain" | "light rain" | "light rain shower" | "mist" | "rain" | "patchy rain nearby") + condition="๓ฐผณ" + ;; +"moderate rain at times" | "moderate rain" | "heavy rain at times" | "heavy rain" | "moderate or heavy rain shower" | "torrential rain shower" | "rain shower") + condition="๎ˆน" + ;; +"patchy snow possible" | "patchy sleet possible" | "patchy freezing drizzle possible" | "freezing drizzle" | "heavy freezing drizzle" | "light freezing rain" | "moderate or heavy freezing rain" | "light sleet" | "ice pellets" | "light sleet showers" | "moderate or heavy sleet showers") + condition="๓ฐผด" + ;; +"blowing snow" | "moderate or heavy sleet" | "patchy light snow" | "light snow" | "light snow showers") + condition="๓ฐ™ฟ" + ;; +"blizzard" | "patchy moderate snow" | "moderate snow" | "patchy heavy snow" | "heavy snow" | "moderate or heavy snow with thunder" | "moderate or heavy snow showers") + condition="๎ž" + ;; +"thundery outbreaks possible" | "patchy light rain with thunder" | "moderate or heavy rain with thunder" | "patchy light snow with thunder") + condition="๎Œ" + ;; +*) + condition="๏ช" + ;; +esac + +# If still unknown, try substring heuristics to pick a reasonable icon +if [ "$condition" = "๏ช" ]; then + if echo "$cond_key" | grep -q "rain\|drizzle\|shower"; then + condition="๓ฐผณ" + elif echo "$cond_key" | grep -q "heavy rain\|torrential"; then + condition="๎ˆน" + elif echo "$cond_key" | grep -q "snow"; then + condition="๓ฐ™ฟ" + elif echo "$cond_key" | grep -q "sleet\|freezing\|ice"; then + condition="๓ฐผด" + elif echo "$cond_key" | grep -q "thunder"; then + condition="๎Œ" + elif echo "$cond_key" | grep -q "overcast"; then + condition="๎ŒŒ" + elif echo "$cond_key" | grep -q "cloud"; then + condition="๎Œ’" + elif echo "$cond_key" | grep -q "sunny\|clear"; then + condition="๎Œ" + fi fi -python3 "$(dirname "$0")/Weather.py" "$@" -exit_code=$? -if [ "$exit_code" -ne 0 ]; then - echo "Failed to run Weather.py" >&2 +#echo $temp $condition + +# Ensure temperature has a value; if empty, keep whatever is in weather[2] or N/A +if [ -z "$temperature" ]; then + temperature="${weather[2]:-N/A}" fi -exit "$exit_code" \ No newline at end of file + +cond_disp=$(echo "${weather[1]}" | sed -E 's/^\s+//; s/\s+$//') +echo -e "{\"text\":\""$temperature" "$condition"\", \"alt\":\""${weather[0]}"\", \"tooltip\":\""${weather[0]}: $temperature $cond_disp"\"}" + +cached_weather="๏‹‰ $temperature \n$condition ${weather[1]}" + +echo -e $cached_weather > "$HOME/.cache/.weather_cache" \ No newline at end of file -- cgit v1.2.3 From c93aba52fb00e23b6902581c0837525334cbe837 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 16:36:50 +0545 Subject: feat(weather): forward geocode MANUAL_PLACE/WEATHER_PLACE to lat/lon MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Openโ€‘Meteo geocoding for place names; use when env coords arenโ€™t set - Adjust get_coords precedence: env coords > manual/env place > cache > IP - Guard cache reuse by verifying cached forecast lat/lon matches requested - Preserve tooltip place display; no changes to JSON schema/output fields --- config/hypr/UserScripts/Weather.py | 57 +++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 4c64221f..1a7380cf 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -65,11 +65,12 @@ UNITS = os.getenv("WEATHER_UNITS", "metric").strip().lower() # metric|imperial # Optional manual coordinates ENV_LAT = os.getenv("WEATHER_LAT") ENV_LON = os.getenv("WEATHER_LON") -# Optional manual place override for tooltip +# Optional manual place override for tooltip (and optional forward geocoding) ENV_PLACE = os.getenv("WEATHER_PLACE") -# Manual place name set inside this file. If set (non-empty), this takes top priority. +# Manual place name set inside this file. If set (non-empty), this takes top priority for display +# and, if coordinates are not provided, will be used to geocode latitude/longitude. # Example: MANUAL_PLACE = "Concord, NH, US" -MANUAL_PLACE: Optional[str] = None +MANUAL_PLACE: Optional[str] = "" #Set your city HERE # Location icon in tooltip (default to a standard emoji to avoid missing glyphs) LOC_ICON = os.getenv("WEATHER_LOC_ICON", "๐Ÿ“") @@ -324,23 +325,58 @@ def get_coords_from_ipinfo() -> Optional[Tuple[float, float]]: return None +def get_coords_from_place_name(name: str) -> Optional[Tuple[float, float]]: + """Forward geocode a place name to coordinates using Open-Meteo Geocoding API. + + Returns (lat, lon) if found, else None. + """ + try: + base = "https://geocoding-api.open-meteo.com/v1/search" + params: Dict[str, Union[str, float]] = { + "name": name, + "count": 1, + "language": os.getenv("WEATHER_LANG", "en"), + "format": "json", + } + resp = SESSION.get(base, params=params, timeout=TIMEOUT) + resp.raise_for_status() + data = ensure_dict(resp.json()) + results = ensure_list(data.get("results")) + if results: + p = ensure_dict(results[0]) + lat = coerce_float(p.get("latitude")) + lon = coerce_float(p.get("longitude")) + if lat is not None and lon is not None: + return float(lat), float(lon) + except Exception as e: + print(f"Place geocoding failed: {e}", file=sys.stderr) + return None + + def get_coords() -> Tuple[float, float]: - # 1) Explicit env + # 1) Explicit env coordinates coords = get_coords_from_env() if coords: return coords - # 2) Try cached coordinates + # 2) Forward geocode from a specified place name (manual takes precedence over env) + place_name = (MANUAL_PLACE or "").strip() or (ENV_PLACE or "").strip() + if place_name: + coords = get_coords_from_place_name(place_name) + if coords: + return coords + + # 3) Try cached coordinates coords = get_coords_from_cache() if coords: return coords - # 3) IP-based geolocation + # 4) IP-based geolocation coords = get_coords_from_ipwho() or get_coords_from_ipapi() or get_coords_from_ipinfo() if coords: return coords - # 4) Last resort + # 5) Last resort print("IP geolocation failed: no providers succeeded", file=sys.stderr) return 0.0, 0.0 @@ -778,6 +814,13 @@ def try_cached_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str], aqi = cast(Optional[Dict[str, Any]], cached.get("aqi")) place_val = cached.get("place") cached_place = place_val if isinstance(place_val, str) else None + # Ensure the cached forecast corresponds to the requested lat/lon + fc = ensure_dict(cached.get("forecast")) + c_lat = coerce_float(safe_get(fc, "latitude")) + c_lon = coerce_float(safe_get(fc, "longitude")) + if c_lat is not None and c_lon is not None: + if abs(c_lat - lat) > 0.1 or abs(c_lon - lon) > 0.1: + return None # force fresh fetch for new location try: return build_output(Location(lat, lon, cached_place), forecast, aqi) except Exception as e: -- cgit v1.2.3 From d409213ae1e98bd80eca432a70a158d4c7c24b71 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 16:38:00 +0545 Subject: chore(hypridle): refresh weather cache synchronously on lock - Run weatherWrap.sh before launching hyprlock so ~/.cache/.weather_cache exists - Switch from background to blocking call to avoid race with lockscreen draw - Keep existing idle listeners and comments unchanged --- config/hypr/hypridle.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/hypridle.conf b/config/hypr/hypridle.conf index 4b8cd7e2..c931419a 100644 --- a/config/hypr/hypridle.conf +++ b/config/hypr/hypridle.conf @@ -5,7 +5,7 @@ $iDIR="$HOME/.config/swaync/images/ja.png" general { - lock_cmd = pidof hyprlock || hyprlock # runs hyprlock if it is not already running (this is always run when "loginctl lock-session" is called) + lock_cmd = sh -lc 'bash "$HOME/.secret/Hyprland-Dots/config/hypr/UserScripts/weatherWrap.sh" >/dev/null 2>&1; pidof hyprlock || hyprlock' # refresh weather cache synchronously via weatherWrap.sh, then run hyprlock # unlock_cmd = killall hyprlock # kills hyprlock when unlocking (this is always run when "loginctl unlock-session" is called) before_sleep_cmd = loginctl lock-session # ensures that the session is locked before going to sleep after_sleep_cmd = hyprctl dispatch dpms on # turn of screen after sleep (not strictly necessary, but just in case) -- cgit v1.2.3 From 05ca56247aae6cbc4e36cbf8bb8b39507d26dd64 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 16:38:45 +0545 Subject: chore(lock): prime weather cache before locking session - Call weatherWrap.sh synchronously, then loginctl lock-session - Ensures lockscreen/waybar can read an up-to-date ~/.cache/.weather_cache --- config/hypr/scripts/LockScreen.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config/hypr/scripts/LockScreen.sh b/config/hypr/scripts/LockScreen.sh index 5e799181..17239406 100755 --- a/config/hypr/scripts/LockScreen.sh +++ b/config/hypr/scripts/LockScreen.sh @@ -4,4 +4,7 @@ # For Hyprlock #pidof hyprlock || hyprlock -q +# Ensure weather cache is up-to-date before locking (Waybar/lockscreen readers) +bash "$HOME/.secret/Hyprland-Dots/config/hypr/UserScripts/weatherWrap.sh" >/dev/null 2>&1 + loginctl lock-session \ No newline at end of file -- cgit v1.2.3 From 2b750637da39e4418132c70c2b53c4070a813a84 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 16:41:43 +0545 Subject: feat(weatherWrap): add Pythonโ€‘first entrypoint with Bash fallback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Prefer Weather.py (Openโ€‘Meteo) for reliable data and caching - Fallback to Weather.sh if Python is missing or Weather.py exits nonโ€‘zero - Pass through all CLI args; invoke Bash explicitly for consistent execution - Helps external callers (e.g., lock hooks) refresh ~/.cache/.weather_cache robustly --- config/hypr/UserConfigs/Startup_Apps.conf | 2 +- config/hypr/UserScripts/weatherWrap.sh | 33 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100755 config/hypr/UserScripts/weatherWrap.sh diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf index 976208e9..c40d0b0a 100644 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ b/config/hypr/UserConfigs/Startup_Apps.conf @@ -48,7 +48,7 @@ exec-once = $UserScripts/RainbowBorders.sh exec-once = hypridle # Weather script to populate cache on startup -exec-once = $UserScripts/Weather.sh +exec-once = $UserScripts/weatherWrap.sh # Here are list of features available but disabled by default diff --git a/config/hypr/UserScripts/weatherWrap.sh b/config/hypr/UserScripts/weatherWrap.sh new file mode 100755 index 00000000..4c9a16dc --- /dev/null +++ b/config/hypr/UserScripts/weatherWrap.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## +# Weather entrypoint: prefer Python (Openโ€‘Meteo), fallback to legacy Bash (wttr.in) + +SCRIPT_DIR="$(dirname "$0")" +PY_SCRIPT="$SCRIPT_DIR/Weather.py" +BASH_FALLBACK="$SCRIPT_DIR/Weather.sh" + +run_fallback() { + if [ -f "$BASH_FALLBACK" ]; then + # Invoke via bash to avoid requiring +x and ensure consistent shell + bash "$BASH_FALLBACK" "$@" + return $? + else + echo "Weather fallback not found: $BASH_FALLBACK" >&2 + return 127 + fi +} + +if command -v python3 >/dev/null 2>&1; then + python3 "$PY_SCRIPT" "$@" + exit_code=$? + if [ "$exit_code" -eq 0 ]; then + exit 0 + fi + echo "Weather.py failed with code $exit_code โ€” falling back to Weather.sh" >&2 + run_fallback "$@" + exit $? +else + echo "python3 not found in PATH โ€” falling back to Weather.sh" >&2 + run_fallback "$@" + exit $? +fi \ No newline at end of file -- cgit v1.2.3 From 2847467b4427a02c8b92346e9916186e05e42a41 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 16:55:42 +0545 Subject: chore(hypridle): remove synchronous weatherWrap invocation from lock_cmd and restore simple hyprlock call (revert back to original) --- config/hypr/hypridle.conf | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/config/hypr/hypridle.conf b/config/hypr/hypridle.conf index c931419a..c1343926 100644 --- a/config/hypr/hypridle.conf +++ b/config/hypr/hypridle.conf @@ -1,11 +1,9 @@ -# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # # Hypridle -# Original config submitted by https://github.com/SherLock707 - + $iDIR="$HOME/.config/swaync/images/ja.png" general { - lock_cmd = sh -lc 'bash "$HOME/.secret/Hyprland-Dots/config/hypr/UserScripts/weatherWrap.sh" >/dev/null 2>&1; pidof hyprlock || hyprlock' # refresh weather cache synchronously via weatherWrap.sh, then run hyprlock + lock_cmd = pidof hyprlock || hyprlock # runs hyprlock if it is not already running (this is always run when "loginctl lock-session" is called) # unlock_cmd = killall hyprlock # kills hyprlock when unlocking (this is always run when "loginctl unlock-session" is called) before_sleep_cmd = loginctl lock-session # ensures that the session is locked before going to sleep after_sleep_cmd = hyprctl dispatch dpms on # turn of screen after sleep (not strictly necessary, but just in case) -- cgit v1.2.3 From 2c32d1cc6ca9397db2db94bb50ad5238fa75d0c9 Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 17:13:29 +0545 Subject: feat(weather): URL-encode city, harden file handling, and produce safe JSON/cache output - URL-encode city (python3 / jq / minimal sed fallback) and use encoded_city for all wttr.in calls - Quote cachedir/cachefile usages and introduce a file variable for clarity - Use portable stat (GNU/BSD fallback) and compute cache age robustly - Replace brittle echo JSON with json_escape + printf to safely escape output - Ensure .weather_cache is written as a two-line file with a proper trailing newline --- config/hypr/UserScripts/Weather.sh | 61 +++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/config/hypr/UserScripts/Weather.sh b/config/hypr/UserScripts/Weather.sh index deba2d41..b69662e6 100755 --- a/config/hypr/UserScripts/Weather.sh +++ b/config/hypr/UserScripts/Weather.sh @@ -12,6 +12,18 @@ if [ -z "$city" ]; then fi +# URL-encode city for safe use in URLs +encoded_city="$city" +if command -v python3 >/dev/null 2>&1; then + encoded_city=$(python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))' "$city") +elif command -v jq >/dev/null 2>&1; then + encoded_city=$(printf '%s' "$city" | jq -sRr @uri) +else + # Minimal fallback: encode a few common special characters + encoded_city=$(printf '%s' "$city" | sed -e 's/ /%20/g' -e 's/&/%26/g' -e 's/?/%3F/g' -e 's/#/%23/g') +fi + + cachedir="$HOME/.cache/rbn" # Include city and arg in cache key so changing city invalidates old cache cache_key="${city}_${1}" @@ -19,12 +31,12 @@ cache_key="${city}_${1}" safe_key=$(printf '%s' "$cache_key" | tr -c '[:alnum:]_-' '_') cachefile=${0##*/}-$safe_key -if [ ! -d $cachedir ]; then - mkdir -p $cachedir +if [ ! -d "$cachedir" ]; then + mkdir -p "$cachedir" fi -if [ ! -f $cachedir/$cachefile ]; then - touch $cachedir/$cachefile +if [ ! -f "$cachedir/$cachefile" ]; then + touch "$cachedir/$cachefile" fi # Save current IFS @@ -32,26 +44,32 @@ SAVEIFS=$IFS # Change IFS to new line. IFS=$'\n' -cacheage=$(($(date +%s) - $(stat -c '%Y' "$cachedir/$cachefile"))) +file="$cachedir/$cachefile" +# Portable file mtime retrieval (GNU/BSD): +# - GNU: stat -c %Y +# - BSD/macOS: stat -f %m +mtime=$(stat -c %Y "$file" 2>/dev/null || stat -f %m "$file" 2>/dev/null || echo 0) +now=$(date +%s) +cacheage=$(( now - mtime )) if [ $cacheage -gt 1740 ] || [ ! -s "$cachedir/$cachefile" ]; then # Prefer structured format for reliable parsing (3 lines: location, condition, temperature) - mapfile -t sdata < <(curl -fsS "https://wttr.in/${city}?format=%25l%0A%25C%0A%25t&lang=en" 2>/dev/null || true) + mapfile -t sdata < <(curl -fsS "https://wttr.in/${encoded_city}?format=%25l%0A%25C%0A%25t&lang=en" 2>/dev/null || true) if [ ${#sdata[@]} -ge 3 ]; then printf "%s\n" "${sdata[0]}" > "$cachedir/$cachefile" printf "%s\n" "${sdata[1]}" >> "$cachedir/$cachefile" printf "%s\n" "${sdata[2]}" >> "$cachedir/$cachefile" else # Try fetching each field separately if combined format is flaky - loc=$(curl -fsS "https://wttr.in/${city}?format=%25l&lang=en" 2>/dev/null || true) - cond_only=$(curl -fsS "https://wttr.in/${city}?format=%25C&lang=en" 2>/dev/null || true) - temp_only=$(curl -fsS "https://wttr.in/${city}?format=%25t" 2>/dev/null || true) + loc=$(curl -fsS "https://wttr.in/${encoded_city}?format=%25l&lang=en" 2>/dev/null || true) + cond_only=$(curl -fsS "https://wttr.in/${encoded_city}?format=%25C&lang=en" 2>/dev/null || true) + temp_only=$(curl -fsS "https://wttr.in/${encoded_city}?format=%25t" 2>/dev/null || true) if [ -n "$loc" ] && [ -n "$cond_only" ] && [ -n "$temp_only" ]; then printf "%s\n" "$loc" > "$cachedir/$cachefile" printf "%s\n" "$cond_only" >> "$cachedir/$cachefile" printf "%s\n" "$temp_only" >> "$cachedir/$cachefile" else # Fallback: try ASCII output and extract best-effort fields - url="https://en.wttr.in/${city}?1" + url="https://en.wttr.in/${encoded_city}?1" mapfile -t data < <(curl -fsS "$url" 2>/dev/null || true) if [ ${#data[@]} -ge 3 ] && ! echo "${data[0]}" | grep -qi 'not found\|unknown location'; then loc=$(echo "${data[0]}" | sed -E 's/^.*: *//') @@ -75,16 +93,16 @@ mapfile -t weather < "$cachedir/$cachefile" # If cache is still empty or invalid, emit a single error JSON and exit to avoid double-prints if [ ${#weather[@]} -lt 3 ] || ! echo "${weather[2]}" | grep -qE '[-+0-9].*ยฐ'; then # Last-chance: try live structured fetch and populate cache and runtime weather - mapfile -t sdata < <(curl -fsS "https://wttr.in/${city}?format=%25l%0A%25C%0A%25t&lang=en" 2>/dev/null || true) + mapfile -t sdata < <(curl -fsS "https://wttr.in/${encoded_city}?format=%25l%0A%25C%0A%25t&lang=en" 2>/dev/null || true) if [ ${#sdata[@]} -ge 3 ]; then weather=("${sdata[@]}") printf "%s\n" "${sdata[0]}" > "$cachedir/$cachefile" printf "%s\n" "${sdata[1]}" >> "$cachedir/$cachefile" printf "%s\n" "${sdata[2]}" >> "$cachedir/$cachefile" else - loc=$(curl -fsS "https://wttr.in/${city}?format=%25l&lang=en" 2>/dev/null || true) - cond_only=$(curl -fsS "https://wttr.in/${city}?format=%25C&lang=en" 2>/dev/null || true) - temp_only=$(curl -fsS "https://wttr.in/${city}?format=%25t" 2>/dev/null || true) + loc=$(curl -fsS "https://wttr.in/${encoded_city}?format=%25l&lang=en" 2>/dev/null || true) + cond_only=$(curl -fsS "https://wttr.in/${encoded_city}?format=%25C&lang=en" 2>/dev/null || true) + temp_only=$(curl -fsS "https://wttr.in/${encoded_city}?format=%25t" 2>/dev/null || true) if [ -n "$loc" ] && [ -n "$cond_only" ] && [ -n "$temp_only" ]; then weather=("$loc" "$cond_only" "$temp_only") printf "%s\n" "$loc" > "$cachedir/$cachefile" @@ -175,8 +193,17 @@ if [ -z "$temperature" ]; then fi cond_disp=$(echo "${weather[1]}" | sed -E 's/^\s+//; s/\s+$//') -echo -e "{\"text\":\""$temperature" "$condition"\", \"alt\":\""${weather[0]}"\", \"tooltip\":\""${weather[0]}: $temperature $cond_disp"\"}" -cached_weather="๏‹‰ $temperature \n$condition ${weather[1]}" +# Escape strings for safe JSON embedding (escape backslashes and double quotes) +json_escape() { + printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/\"/\\\"/g' +} + +text_json=$(json_escape "$temperature $condition") +alt_json=$(json_escape "${weather[0]}") +tooltip_json=$(json_escape "${weather[0]}: $temperature $cond_disp") + +printf '{"text":"%s", "alt":"%s", "tooltip":"%s"}\n' "$text_json" "$alt_json" "$tooltip_json" -echo -e $cached_weather > "$HOME/.cache/.weather_cache" \ No newline at end of file +# Write a two-line cache with an actual newline between lines +printf '๏‹‰ %s \n%s %s\n' "$temperature" "$condition" "${weather[1]}" > "$HOME/.cache/.weather_cache" \ No newline at end of file -- cgit v1.2.3 From 8f53face681abe37b93d9278dcc9d1caaeb78ffa Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 17:29:23 +0545 Subject: revert back to original --- config/hypr/hypridle.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/hypr/hypridle.conf b/config/hypr/hypridle.conf index c1343926..4b8cd7e2 100644 --- a/config/hypr/hypridle.conf +++ b/config/hypr/hypridle.conf @@ -1,5 +1,7 @@ +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # # Hypridle - +# Original config submitted by https://github.com/SherLock707 + $iDIR="$HOME/.config/swaync/images/ja.png" general { -- cgit v1.2.3 From 0914a7105188ae2f606f6056d4584f85b951599d Mon Sep 17 00:00:00 2001 From: prabinpanta0 Date: Tue, 28 Oct 2025 18:08:17 +0545 Subject: feat(weather): prioritize MANUAL_PLACE for geocoding and skip reverse lookup when set - Treat MANUAL_PLACE as highest priority: forward-geocode it first and return coords if found - Make ENV_PLACE a separate forward-geocode step (after explicit env coords) - When fetching fresh weather, use MANUAL_PLACE directly as the place string to avoid an unnecessary reverse geocode call - Update comment numbering to reflect the new priority order --- config/hypr/UserScripts/Weather.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index 1a7380cf..a9a826e1 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -354,29 +354,36 @@ def get_coords_from_place_name(name: str) -> Optional[Tuple[float, float]]: def get_coords() -> Tuple[float, float]: - # 1) Explicit env coordinates + # 1) Forward geocode from MANUAL_PLACE first (highest priority) + if MANUAL_PLACE: + place_name = MANUAL_PLACE.strip() + coords = get_coords_from_place_name(place_name) + if coords: + return coords + + # 2) Explicit env coordinates coords = get_coords_from_env() if coords: return coords - # 2) Forward geocode from a specified place name (manual takes precedence over env) - place_name = (MANUAL_PLACE or "").strip() or (ENV_PLACE or "").strip() - if place_name: + # 3) Forward geocode from ENV_PLACE + if ENV_PLACE: + place_name = ENV_PLACE.strip() coords = get_coords_from_place_name(place_name) if coords: return coords - # 3) Try cached coordinates + # 4) Try cached coordinates coords = get_coords_from_cache() if coords: return coords - # 4) IP-based geolocation + # 5) IP-based geolocation coords = get_coords_from_ipwho() or get_coords_from_ipapi() or get_coords_from_ipinfo() if coords: return coords - # 5) Last resort + # 6) Last resort print("IP geolocation failed: no providers succeeded", file=sys.stderr) return 0.0, 0.0 @@ -832,7 +839,8 @@ def fetch_fresh_weather(lat: float, lon: float) -> Optional[Tuple[Dict[str, str] try: forecast = fetch_open_meteo(lat, lon) aqi = fetch_aqi(lat, lon) - place = fetch_place(lat, lon) + # If MANUAL_PLACE is set, don't reverse geocode - use the manual place instead + place = MANUAL_PLACE if MANUAL_PLACE else fetch_place(lat, lon) write_api_cache({"forecast": forecast, "aqi": aqi, "place": place}) return build_output(Location(lat, lon, place), forecast, aqi) except Exception as e: -- cgit v1.2.3 From 2c1ce157c97ae690e1dfb8087a3bfa808ac57c18 Mon Sep 17 00:00:00 2001 From: brockar Date: Tue, 28 Oct 2025 18:08:12 -0300 Subject: weatherWrap.sh -> WeatherWrap.sh --- config/hypr/UserConfigs/Startup_Apps.conf | 2 +- config/hypr/UserScripts/WeatherWrap.sh | 33 +++++++++++++++++++++++++++++++ config/hypr/UserScripts/weatherWrap.sh | 33 ------------------------------- config/hypr/scripts/LockScreen.sh | 7 ++++--- 4 files changed, 38 insertions(+), 37 deletions(-) create mode 100755 config/hypr/UserScripts/WeatherWrap.sh delete mode 100755 config/hypr/UserScripts/weatherWrap.sh diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf index c40d0b0a..2f5c7ae7 100644 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ b/config/hypr/UserConfigs/Startup_Apps.conf @@ -48,7 +48,7 @@ exec-once = $UserScripts/RainbowBorders.sh exec-once = hypridle # Weather script to populate cache on startup -exec-once = $UserScripts/weatherWrap.sh +exec-once = $UserScripts/WeatherWrap.sh # Here are list of features available but disabled by default diff --git a/config/hypr/UserScripts/WeatherWrap.sh b/config/hypr/UserScripts/WeatherWrap.sh new file mode 100755 index 00000000..4c9a16dc --- /dev/null +++ b/config/hypr/UserScripts/WeatherWrap.sh @@ -0,0 +1,33 @@ +#!/bin/bash +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## +# Weather entrypoint: prefer Python (Openโ€‘Meteo), fallback to legacy Bash (wttr.in) + +SCRIPT_DIR="$(dirname "$0")" +PY_SCRIPT="$SCRIPT_DIR/Weather.py" +BASH_FALLBACK="$SCRIPT_DIR/Weather.sh" + +run_fallback() { + if [ -f "$BASH_FALLBACK" ]; then + # Invoke via bash to avoid requiring +x and ensure consistent shell + bash "$BASH_FALLBACK" "$@" + return $? + else + echo "Weather fallback not found: $BASH_FALLBACK" >&2 + return 127 + fi +} + +if command -v python3 >/dev/null 2>&1; then + python3 "$PY_SCRIPT" "$@" + exit_code=$? + if [ "$exit_code" -eq 0 ]; then + exit 0 + fi + echo "Weather.py failed with code $exit_code โ€” falling back to Weather.sh" >&2 + run_fallback "$@" + exit $? +else + echo "python3 not found in PATH โ€” falling back to Weather.sh" >&2 + run_fallback "$@" + exit $? +fi \ No newline at end of file diff --git a/config/hypr/UserScripts/weatherWrap.sh b/config/hypr/UserScripts/weatherWrap.sh deleted file mode 100755 index 4c9a16dc..00000000 --- a/config/hypr/UserScripts/weatherWrap.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/bash -# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## -# Weather entrypoint: prefer Python (Openโ€‘Meteo), fallback to legacy Bash (wttr.in) - -SCRIPT_DIR="$(dirname "$0")" -PY_SCRIPT="$SCRIPT_DIR/Weather.py" -BASH_FALLBACK="$SCRIPT_DIR/Weather.sh" - -run_fallback() { - if [ -f "$BASH_FALLBACK" ]; then - # Invoke via bash to avoid requiring +x and ensure consistent shell - bash "$BASH_FALLBACK" "$@" - return $? - else - echo "Weather fallback not found: $BASH_FALLBACK" >&2 - return 127 - fi -} - -if command -v python3 >/dev/null 2>&1; then - python3 "$PY_SCRIPT" "$@" - exit_code=$? - if [ "$exit_code" -eq 0 ]; then - exit 0 - fi - echo "Weather.py failed with code $exit_code โ€” falling back to Weather.sh" >&2 - run_fallback "$@" - exit $? -else - echo "python3 not found in PATH โ€” falling back to Weather.sh" >&2 - run_fallback "$@" - exit $? -fi \ No newline at end of file diff --git a/config/hypr/scripts/LockScreen.sh b/config/hypr/scripts/LockScreen.sh index 17239406..e61490cd 100755 --- a/config/hypr/scripts/LockScreen.sh +++ b/config/hypr/scripts/LockScreen.sh @@ -2,9 +2,10 @@ # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For Hyprlock -#pidof hyprlock || hyprlock -q +#pidof hyprlock || hyprlock -q # Ensure weather cache is up-to-date before locking (Waybar/lockscreen readers) -bash "$HOME/.secret/Hyprland-Dots/config/hypr/UserScripts/weatherWrap.sh" >/dev/null 2>&1 +bash "$HOME/.config/hypr/UserScripts/WeatherWrap.sh" >/dev/null 2>&1 + +loginctl lock-session -loginctl lock-session \ No newline at end of file -- cgit v1.2.3 From 0536a3a6f61cf24ac46ff74b49dc27d816a898e4 Mon Sep 17 00:00:00 2001 From: brockar Date: Tue, 28 Oct 2025 18:13:12 -0300 Subject: fix: waybar: now use WeatherWrap.sh --- config/waybar/ModulesCustom | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/waybar/ModulesCustom b/config/waybar/ModulesCustom index 146ec275..f4c871f7 100644 --- a/config/waybar/ModulesCustom +++ b/config/waybar/ModulesCustom @@ -11,8 +11,9 @@ "format-alt-click": "click", "interval": 3600, "return-type": "json", - "exec": "$HOME/.config/hypr/UserScripts/Weather.py", + //"exec": "$HOME/.config/hypr/UserScripts/Weather.py", //"exec": "$HOME/.config/hypr/UserScripts/Weather.sh", + "exec": "$HOME/.config/hypr/UserScripts/WeatherWrap.sh", //"exec-if": "ping wttr.in -c1", "tooltip": true, }, @@ -286,4 +287,4 @@ "format": "๎‚ฐ", "tooltip": false } -} \ No newline at end of file +} -- cgit v1.2.3 From 758b466c5f2030188d46511b20ad39c6d8b46a0d Mon Sep 17 00:00:00 2001 From: Don Williams Date: Tue, 28 Oct 2025 17:30:59 -0400 Subject: Changed /usr/bin/bash to /usr/bin/env bash On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: Distro-Hyprland.sh modified: config/hypr/UserScripts/RainbowBorders.sh modified: config/hypr/UserScripts/RofiBeats.sh modified: config/hypr/UserScripts/RofiCalc.sh modified: config/hypr/UserScripts/Tak0-Autodispatch.sh modified: config/hypr/UserScripts/WallpaperAutoChange.sh modified: config/hypr/UserScripts/WallpaperEffects.sh modified: config/hypr/UserScripts/WallpaperRandom.sh modified: config/hypr/UserScripts/WallpaperSelect.sh modified: config/hypr/UserScripts/Weather.sh modified: config/hypr/UserScripts/WeatherWrap.sh modified: config/hypr/UserScripts/ZshChangeTheme.sh new file: config/hypr/configs/Startup_Apps.conf new file: config/hypr/configs/WindowRules.conf modified: config/hypr/hyprland.conf modified: config/hypr/initial-boot.sh modified: config/hypr/scripts/AirplaneMode.sh modified: config/hypr/scripts/Animations.sh modified: config/hypr/scripts/Battery.sh modified: config/hypr/scripts/Brightness.sh modified: config/hypr/scripts/BrightnessKbd.sh modified: config/hypr/scripts/ChangeBlur.sh modified: config/hypr/scripts/ChangeLayout.sh modified: config/hypr/scripts/ClipManager.sh new file: config/hypr/scripts/ComposeHyprConfigs.sh modified: config/hypr/scripts/DarkLight.sh modified: config/hypr/scripts/Distro_update.sh modified: config/hypr/scripts/Dropterminal.sh modified: config/hypr/scripts/GameMode.sh modified: config/hypr/scripts/Hypridle.sh modified: config/hypr/scripts/KeyBinds.sh modified: config/hypr/scripts/KeyHints.sh modified: config/hypr/scripts/KillActiveProcess.sh modified: config/hypr/scripts/Kitty_themes.sh modified: config/hypr/scripts/KooLsDotsUpdate.sh modified: config/hypr/scripts/Kool_Quick_Settings.sh modified: config/hypr/scripts/LockScreen.sh modified: config/hypr/scripts/MediaCtrl.sh modified: config/hypr/scripts/MonitorProfiles.sh modified: config/hypr/scripts/Polkit-NixOS.sh modified: config/hypr/scripts/Polkit.sh modified: config/hypr/scripts/PortalHyprland.sh modified: config/hypr/scripts/Refresh.sh modified: config/hypr/scripts/RefreshNoWaybar.sh modified: config/hypr/scripts/RofiEmoji.sh modified: config/hypr/scripts/RofiSearch.sh modified: config/hypr/scripts/RofiThemeSelector-modified.sh modified: config/hypr/scripts/RofiThemeSelector.sh modified: config/hypr/scripts/ScreenShot.sh modified: config/hypr/scripts/Sounds.sh modified: config/hypr/scripts/SwitchKeyboardLayout.sh modified: config/hypr/scripts/Tak0-Autodispatch.sh modified: config/hypr/scripts/TouchPad.sh modified: config/hypr/scripts/Volume.sh modified: config/hypr/scripts/WallustSwww.sh modified: config/hypr/scripts/WaybarLayout.sh modified: config/hypr/scripts/WaybarScripts.sh modified: config/hypr/scripts/WaybarStyles.sh modified: config/hypr/scripts/Wlogout.sh modified: config/hypr/scripts/sddm_wallpaper.sh modified: copy.sh modified: release.sh modified: upgrade.sh --- Distro-Hyprland.sh | 2 +- config/hypr/UserScripts/RainbowBorders.sh | 2 +- config/hypr/UserScripts/RofiBeats.sh | 2 +- config/hypr/UserScripts/RofiCalc.sh | 2 +- config/hypr/UserScripts/Tak0-Autodispatch.sh | 2 +- config/hypr/UserScripts/WallpaperAutoChange.sh | 2 +- config/hypr/UserScripts/WallpaperEffects.sh | 2 +- config/hypr/UserScripts/WallpaperRandom.sh | 2 +- config/hypr/UserScripts/WallpaperSelect.sh | 2 +- config/hypr/UserScripts/Weather.sh | 2 +- config/hypr/UserScripts/WeatherWrap.sh | 2 +- config/hypr/UserScripts/ZshChangeTheme.sh | 2 +- config/hypr/configs/Startup_Apps.conf | 58 ++++++ config/hypr/configs/WindowRules.conf | 235 ++++++++++++++++++++++ config/hypr/hyprland.conf | 4 +- config/hypr/initial-boot.sh | 2 +- config/hypr/scripts/AirplaneMode.sh | 2 +- config/hypr/scripts/Animations.sh | 2 +- config/hypr/scripts/Battery.sh | 2 +- config/hypr/scripts/Brightness.sh | 2 +- config/hypr/scripts/BrightnessKbd.sh | 2 +- config/hypr/scripts/ChangeBlur.sh | 2 +- config/hypr/scripts/ChangeLayout.sh | 2 +- config/hypr/scripts/ClipManager.sh | 2 +- config/hypr/scripts/ComposeHyprConfigs.sh | 109 ++++++++++ config/hypr/scripts/DarkLight.sh | 2 +- config/hypr/scripts/Distro_update.sh | 2 +- config/hypr/scripts/Dropterminal.sh | 2 +- config/hypr/scripts/GameMode.sh | 2 +- config/hypr/scripts/Hypridle.sh | 2 +- config/hypr/scripts/KeyBinds.sh | 2 +- config/hypr/scripts/KeyHints.sh | 2 +- config/hypr/scripts/KillActiveProcess.sh | 2 +- config/hypr/scripts/Kitty_themes.sh | 2 +- config/hypr/scripts/KooLsDotsUpdate.sh | 2 +- config/hypr/scripts/Kool_Quick_Settings.sh | 2 +- config/hypr/scripts/LockScreen.sh | 2 +- config/hypr/scripts/MediaCtrl.sh | 2 +- config/hypr/scripts/MonitorProfiles.sh | 2 +- config/hypr/scripts/Polkit-NixOS.sh | 2 +- config/hypr/scripts/Polkit.sh | 2 +- config/hypr/scripts/PortalHyprland.sh | 2 +- config/hypr/scripts/Refresh.sh | 2 +- config/hypr/scripts/RefreshNoWaybar.sh | 2 +- config/hypr/scripts/RofiEmoji.sh | 2 +- config/hypr/scripts/RofiSearch.sh | 2 +- config/hypr/scripts/RofiThemeSelector-modified.sh | 2 +- config/hypr/scripts/RofiThemeSelector.sh | 2 +- config/hypr/scripts/ScreenShot.sh | 2 +- config/hypr/scripts/Sounds.sh | 2 +- config/hypr/scripts/SwitchKeyboardLayout.sh | 2 +- config/hypr/scripts/Tak0-Autodispatch.sh | 2 +- config/hypr/scripts/TouchPad.sh | 2 +- config/hypr/scripts/Volume.sh | 2 +- config/hypr/scripts/WallustSwww.sh | 2 +- config/hypr/scripts/WaybarLayout.sh | 2 +- config/hypr/scripts/WaybarScripts.sh | 2 +- config/hypr/scripts/WaybarStyles.sh | 2 +- config/hypr/scripts/Wlogout.sh | 2 +- config/hypr/scripts/sddm_wallpaper.sh | 2 +- copy.sh | 84 +++++++- release.sh | 2 +- upgrade.sh | 9 +- 63 files changed, 544 insertions(+), 69 deletions(-) create mode 100644 config/hypr/configs/Startup_Apps.conf create mode 100644 config/hypr/configs/WindowRules.conf create mode 100644 config/hypr/scripts/ComposeHyprConfigs.sh diff --git a/Distro-Hyprland.sh b/Distro-Hyprland.sh index ff88325f..99a1fc34 100755 --- a/Distro-Hyprland.sh +++ b/Distro-Hyprland.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # https://github.com/JaKooLit # Script design to clone the Distro-Hyprland install scripts diff --git a/config/hypr/UserScripts/RainbowBorders.sh b/config/hypr/UserScripts/RainbowBorders.sh index cc1419fb..0a7fd721 100755 --- a/config/hypr/UserScripts/RainbowBorders.sh +++ b/config/hypr/UserScripts/RainbowBorders.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # for rainbow borders animation diff --git a/config/hypr/UserScripts/RofiBeats.sh b/config/hypr/UserScripts/RofiBeats.sh index 1cddce09..ca566019 100755 --- a/config/hypr/UserScripts/RofiBeats.sh +++ b/config/hypr/UserScripts/RofiBeats.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For Rofi Beats to play online Music or Locally saved media files diff --git a/config/hypr/UserScripts/RofiCalc.sh b/config/hypr/UserScripts/RofiCalc.sh index 4b3b8b69..b72d5f3e 100755 --- a/config/hypr/UserScripts/RofiCalc.sh +++ b/config/hypr/UserScripts/RofiCalc.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # /* Calculator (using qalculate) and rofi */ # /* Submitted by: https://github.com/JosephArmas */ diff --git a/config/hypr/UserScripts/Tak0-Autodispatch.sh b/config/hypr/UserScripts/Tak0-Autodispatch.sh index a1f72129..114a3e8e 100755 --- a/config/hypr/UserScripts/Tak0-Autodispatch.sh +++ b/config/hypr/UserScripts/Tak0-Autodispatch.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # USAGE / ะ†ะะกะขะ ะฃะšะฆะ†ะฏ: # 1) Run from terminal: # ./dispatch.sh diff --git a/config/hypr/UserScripts/WallpaperAutoChange.sh b/config/hypr/UserScripts/WallpaperAutoChange.sh index a6d2cedd..6d8e8735 100755 --- a/config/hypr/UserScripts/WallpaperAutoChange.sh +++ b/config/hypr/UserScripts/WallpaperAutoChange.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # source https://wiki.archlinux.org/title/Hyprland#Using_a_script_to_change_wallpaper_every_X_minutes diff --git a/config/hypr/UserScripts/WallpaperEffects.sh b/config/hypr/UserScripts/WallpaperEffects.sh index ac8fc0e8..89577efa 100755 --- a/config/hypr/UserScripts/WallpaperEffects.sh +++ b/config/hypr/UserScripts/WallpaperEffects.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # # Wallpaper Effects using ImageMagick (SUPER SHIFT W) diff --git a/config/hypr/UserScripts/WallpaperRandom.sh b/config/hypr/UserScripts/WallpaperRandom.sh index 79396508..654d4bd3 100755 --- a/config/hypr/UserScripts/WallpaperRandom.sh +++ b/config/hypr/UserScripts/WallpaperRandom.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Script for Random Wallpaper ( CTRL ALT W) diff --git a/config/hypr/UserScripts/WallpaperSelect.sh b/config/hypr/UserScripts/WallpaperSelect.sh index 466832ba..9e51125f 100755 --- a/config/hypr/UserScripts/WallpaperSelect.sh +++ b/config/hypr/UserScripts/WallpaperSelect.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # This script for selecting wallpapers (SUPER W) diff --git a/config/hypr/UserScripts/Weather.sh b/config/hypr/UserScripts/Weather.sh index b69662e6..ac9abc13 100755 --- a/config/hypr/UserScripts/Weather.sh +++ b/config/hypr/UserScripts/Weather.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # weather info from wttr. https://github.com/chubin/wttr.in # Remember to add city diff --git a/config/hypr/UserScripts/WeatherWrap.sh b/config/hypr/UserScripts/WeatherWrap.sh index 4c9a16dc..10c125dc 100755 --- a/config/hypr/UserScripts/WeatherWrap.sh +++ b/config/hypr/UserScripts/WeatherWrap.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Weather entrypoint: prefer Python (Openโ€‘Meteo), fallback to legacy Bash (wttr.in) diff --git a/config/hypr/UserScripts/ZshChangeTheme.sh b/config/hypr/UserScripts/ZshChangeTheme.sh index cffaf5cb..690f0f13 100755 --- a/config/hypr/UserScripts/ZshChangeTheme.sh +++ b/config/hypr/UserScripts/ZshChangeTheme.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Script for Oh my ZSH theme ( CTRL SHIFT O) diff --git a/config/hypr/configs/Startup_Apps.conf b/config/hypr/configs/Startup_Apps.conf new file mode 100644 index 00000000..d952e65b --- /dev/null +++ b/config/hypr/configs/Startup_Apps.conf @@ -0,0 +1,58 @@ +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # +# Commands and Apps to be executed at launch (vendor defaults) + +$scriptsDir = $HOME/.config/hypr/scripts +$UserScripts = $HOME/.config/hypr/UserScripts + +$wallDIR=$HOME/Pictures/wallpapers +$lock = $scriptsDir/LockScreen.sh +$SwwwRandom = $UserScripts/WallpaperAutoChange.sh +$livewallpaper="" + +# wallpaper stuff +exec-once = swww-daemon --format xrgb +#exec-once = mpvpaper '*' -o "load-scripts=no no-audio --loop" $livewallpaper + +# wallpaper random +#exec-once = $SwwwRandom $wallDIR # random wallpaper switcher every 30 minutes + +# Startup +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 + +# starup apps +exec-once = nm-applet --indicator +exec-once = nm-tray # For ubuntu +exec-once = swaync +#exec-once = ags +#exec-once = blueman-applet +#exec-once = rog-control-center +exec-once = waybar +exec-once = qs # quickshell AGS Desktop Overview alternative + +#clipboard manager +exec-once = wl-paste --type text --watch cliphist store +exec-once = wl-paste --type image --watch cliphist store + +# Rainbow borders +exec-once = $UserScripts/RainbowBorders.sh + +# Starting hypridle to start hyprlock +exec-once = hypridle + + +# Here are list of features available but disabled by default +# exec-once = swww-daemon --format xrgb && swww img $HOME/Pictures/wallpapers/mecha-nostalgia.png # persistent wallpaper + +#gnome polkit for nixos +#exec-once = $scriptsDir/Polkit-NixOS.sh + +# xdg-desktop-portal-hyprland (should be auto starting. However, you can force to start) +#exec-once = $scriptsDir/PortalHyprland.sh \ No newline at end of file diff --git a/config/hypr/configs/WindowRules.conf b/config/hypr/configs/WindowRules.conf new file mode 100644 index 00000000..f02c5d29 --- /dev/null +++ b/config/hypr/configs/WindowRules.conf @@ -0,0 +1,235 @@ +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # +# Vendor defaults for window rules and layerrules +# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more + +# NOTES: This is only for Hyprland > 0.48 + +# note for ja: This should NOT be implemented on Debian and Ubuntu + +# windowrule - tags - add apps under appropriate tag to use the same settings +# browser tags +windowrule = tag +browser, class:^([Ff]irefox|org.mozilla.firefox|[Ff]irefox-esr|[Ff]irefox-bin)$ +windowrule = tag +browser, class:^([Gg]oogle-chrome(-beta|-dev|-unstable)?)$ +windowrule = tag +browser, class:^(chrome-.+-Default)$ # Chrome PWAs +windowrule = tag +browser, class:^([Cc]hromium)$ +windowrule = tag +browser, class:^([Mm]icrosoft-edge(-stable|-beta|-dev|-unstable))$ +windowrule = tag +browser, class:^(Brave-browser(-beta|-dev|-unstable)?)$ +windowrule = tag +browser, class:^([Tt]horium-browser|[Cc]achy-browser)$ +windowrule = tag +browser, class:^(zen-alpha|zen)$ + +# notif tags +windowrule = tag +notif, class:^(swaync-control-center|swaync-notification-window|swaync-client|class)$ + +# KooL settings tag +windowrule = tag +KooL_Cheat, title:^(KooL Quick Cheat Sheet)$ +windowrule = tag +KooL_Settings, title:^(KooL Hyprland Settings)$ +windowrule = tag +KooL-Settings, class:^(nwg-displays|nwg-look)$ + +# terminal tags +windowrule = tag +terminal, class:^(Alacritty|kitty|kitty-dropterm)$ + +# email tags +windowrule = tag +email, class:^([Tt]hunderbird|org.gnome.Evolution)$ +windowrule = tag +email, class:^(eu.betterbird.Betterbird)$ + +# project tags +windowrule = tag +projects, class:^(codium|codium-url-handler|VSCodium)$ +windowrule = tag +projects, class:^(VSCode|code-url-handler)$ +windowrule = tag +projects, class:^(jetbrains-.+)$ # JetBrains IDEs + +# screenshare tags +windowrule = tag +screenshare, class:^(com.obsproject.Studio)$ + +# IM tags +windowrule = tag +im, class:^([Dd]iscord|[Ww]ebCord|[Vv]esktop)$ +windowrule = tag +im, class:^([Ff]erdium)$ +windowrule = tag +im, class:^([Ww]hatsapp-for-linux)$ +windowrule = tag +im, class:^(ZapZap|com.rtosta.zapzap)$ +windowrule = tag +im, class:^(org.telegram.desktop|io.github.tdesktop_x64.TDesktop)$ +windowrule = tag +im, class:^(teams-for-linux)$ +windowrule = tag +im, class:^(im.riot.Riot|Element)$ # Element Matrix client + +# game tags +windowrule = tag +games, class:^(gamescope)$ +windowrule = tag +games, class:^(steam_app_\d+)$ + +# gamestore tags +windowrule = tag +gamestore, class:^([Ss]team)$ +windowrule = tag +gamestore, title:^([Ll]utris)$ +windowrule = tag +gamestore, class:^(com.heroicgameslauncher.hgl)$ + +# file-manager tags +windowrule = tag +file-manager, class:^([Tt]hunar|org.gnome.Nautilus|[Pp]cmanfm-qt)$ +windowrule = tag +file-manager, class:^(app.drey.Warp)$ + +# wallpaper tags +windowrule = tag +wallpaper, class:^([Ww]aytrogen)$ + +# multimedia tags +windowrule = tag +multimedia, class:^([Aa]udacious)$ + +# multimedia-video tags +windowrule = tag +multimedia_video, class:^([Mm]pv|vlc)$ + +# settings tags +windowrule = tag +settings, title:^(ROG Control)$ +windowrule = tag +settings, class:^(wihotspot(-gui)?)$ # wifi hotspot +windowrule = tag +settings, class:^([Bb]aobab|org.gnome.[Bb]aobab)$ # Disk usage analyzer +windowrule = tag +settings, class:^(gnome-disks|wihotspot(-gui)?)$ +windowrule = tag +settings, title:(Kvantum Manager) +windowrule = tag +settings, class:^(file-roller|org.gnome.FileRoller)$ # archive manager +windowrule = tag +settings, class:^(nm-applet|nm-connection-editor|blueman-manager)$ +windowrule = tag +settings, class:^(pavucontrol|org.pulseaudio.pavucontrol|com.saivert.pwvucontrol)$ +windowrule = tag +settings, class:^(qt5ct|qt6ct|[Yy]ad)$ +windowrule = tag +settings, class:(xdg-desktop-portal-gtk) +windowrule = tag +settings, class:^(org.kde.polkit-kde-authentication-agent-1)$ +windowrule = tag +settings, class:^([Rr]ofi)$ + +# viewer tags +windowrule = tag +viewer, class:^(gnome-system-monitor|org.gnome.SystemMonitor|io.missioncenter.MissionCenter)$ # system monitor +windowrule = tag +viewer, class:^(evince)$ # document viewer +windowrule = tag +viewer, class:^(eog|org.gnome.Loupe)$ # image viewer + +# Some special override rules +windowrule = noblur, tag:multimedia_video* +windowrule = opacity 1.0, tag:multimedia_video* + +# POSITION +# windowrule = center,floating:1 # warning, it cause even the menu to float and center. +windowrule = center, tag:KooL_Cheat* +windowrule = center, class:([Tt]hunar), title:negative:(.*[Tt]hunar.*) +windowrule = center, title:^(ROG Control)$ +windowrule = center, tag:KooL-Settings* +windowrule = center, title:^(Keybindings)$ +windowrule = center, class:^(pavucontrol|org.pulseaudio.pavucontrol|com.saivert.pwvucontrol)$ +windowrule = center, class:^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ +windowrule = center, class:^([Ff]erdium)$ +windowrule = move 72% 7%,title:^(Picture-in-Picture)$ +#windowrule = move 72% 7%,title:^(Firefox)$ + +# windowrule to avoid idle for fullscreen apps +#windowrule = idleinhibit fullscreen, class:^(*)$ +#windowrule = idleinhibit fullscreen, title:^(*)$ +windowrule = idleinhibit fullscreen, fullscreen:1 + +# windowrule move to workspace +#windowrule = workspace 1, tag:email* +#windowrule = workspace 2, tag:browser* +#windowrule = workspace 3, class:^([Tt]hunar)$ +#windowrule = workspace 3, tag:projects* +#windowrule = workspace 5, tag:gamestore* +#windowrule = workspace 7, tag:im* +#windowrule = workspace 8, tag:games* + +# windowrule move to workspace (silent) +#windowrule = workspace 4 silent, tag:screenshare* +#windowrule = workspace 6 silent, class:^(virt-manager)$ +#windowrule = workspace 6 silent, class:^(.virt-manager-wrapped)$ +#windowrule = workspace 9 silent, tag:multimedia* +# +# FLOAT +windowrule = float, tag:KooL_Cheat* +windowrule = float, tag:wallpaper* +windowrule = float, tag:settings* +windowrule = float, tag:viewer* +windowrule = float, tag:KooL-Settings* +windowrule = float, class:([Zz]oom|onedriver|onedriver-launcher)$ +windowrule = float, class:(org.gnome.Calculator), title:(Calculator) +windowrule = float, class:^(mpv|com.github.rafostar.Clapper)$ +windowrule = float, class:^([Qq]alculate-gtk)$ +#windowrule = float, class:^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ +windowrule = float, class:^([Ff]erdium)$ +windowrule = float, title:^(Picture-in-Picture)$ +#windowrule = float, title:^(Firefox)$ + +# windowrule - ######### float popups and dialogue ####### +windowrule = float, title:^(Authentication Required)$ +windowrule = center, title:^(Authentication Required)$ +windowrule = float, class:(codium|codium-url-handler|VSCodium), title:negative:(.*codium.*|.*VSCodium.*) +windowrule = float, class:^(com.heroicgameslauncher.hgl)$, title:negative:(Heroic Games Launcher) +windowrule = float, class:^([Ss]team)$, title:negative:^([Ss]team)$ +windowrule = float, class:([Tt]hunar), title:negative:(.*[Tt]hunar.*) + +windowrule = float, title:^(Add Folder to Workspace)$ +windowrule = size 70% 60%, title:^(Add Folder to Workspace)$ +windowrule = center, title:^(Add Folder to Workspace)$ + +windowrule = float, title:^(Save As)$ +windowrule = size 70% 60%, title:^(Save As)$ +windowrule = center, title:^(Save As)$ + +windowrule = float, initialTitle:(Open Files) +windowrule = size 70% 60%, initialTitle:(Open Files) + +windowrule = float, title:^(SDDM Background)$ #KooL's Dots YAD for setting SDDM background +windowrule = center, title:^(SDDM Background)$ #KooL's Dots YAD for setting SDDM background +windowrule = size 16% 12%, title:^(SDDM Background)$ #KooL's Dots YAD for setting SDDM background +# END of float popups and dialogue ####### + +# OPACITY +windowrule = opacity 0.99 0.8, tag:browser* +windowrule = opacity 0.9 0.8, tag:projects* +windowrule = opacity 0.94 0.86, tag:im* +windowrule = opacity 0.94 0.86, tag:multimedia* +windowrule = opacity 0.9 0.8, tag:file-manager* +windowrule = opacity 0.9 0.7, tag:terminal* +windowrule = opacity 0.8 0.7, tag:settings* +windowrule = opacity 0.82 0.75, tag:viewer* +windowrule = opacity 0.9 0.7, tag:wallpaper* +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* +windowrule = size 70% 70%, tag:wallpaper* +windowrule = size 70% 70%, tag:settings* +windowrule = size 60% 70%, class:^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ +windowrule = size 60% 70%, class:^([Ff]erdium)$ + +#windowrule = size 25% 25%, title:^(Picture-in-Picture)$ +#windowrule = size 25% 25%, title:^(Firefox)$ + +# PINNING +windowrule = pin, title:^(Picture-in-Picture)$ +#windowrule = pin,title:^(Firefox)$ + +# windowrule - extras +windowrule = keepaspectratio, title:^(Picture-in-Picture)$ + +# BLUR & FULLSCREEN +windowrule = noblur, tag:games* +windowrule = fullscreen, tag:games* + + +#This not gonna take the focus to the window that appears when hovering over some of the parts of the IntelliJ Products +windowrule = noinitialfocus, class:^(jetbrains-*) +windowrule = noinitialfocus, title:^(wind.*)$ + +#This will gonna make the VS Code bluer like other apps +windowrule = opacity 0.8,class:^(code)$ + +#windowrule = bordercolor rgb(EE4B55) rgb(880808), fullscreen:1 +#windowrule = bordercolor rgb(282737) rgb(1E1D2D), floating:1 +#windowrule = opacity 0.8 0.8, pinned:1 + +# LAYER RULES +layerrule = blur, rofi +layerrule = ignorezero, rofi +layerrule = blur, notifications +layerrule = ignorezero, notifications +layerrule = blur, quickshell:overview +layerrule = ignorezero, quickshell:overview +layerrule = ignorealpha 0.5, quickshell:overview + +#layerrule = ignorealpha 0.5, tag:notif* + +#layerrule = ignorezero, class:^([Rr]ofi)$ +#layerrule = blur, class:^([Rr]ofi)$ +#layerrule = unset,class:^([Rr]ofi)$ +#layerrule = ignorezero, + +#layerrule = ignorezero, overview +#layerrule = blur, overview \ No newline at end of file diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index 71f243e7..cd9fed2d 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -15,7 +15,9 @@ source=$configs/Keybinds.conf # Pre-configured keybinds # ## This is where you want to start tinkering $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path -source= $UserConfigs/Startup_Apps.conf # put your start-up packages on this file +# Generated merges (vendor + user overlay with dedupe/disable) +source= $HOME/.config/hypr/generated/Startup_Apps.conf +source= $HOME/.config/hypr/generated/WindowRules.conf source= $UserConfigs/ENVariables.conf # Environment variables to load diff --git a/config/hypr/initial-boot.sh b/config/hypr/initial-boot.sh index 5b49cb6d..1313f104 100755 --- a/config/hypr/initial-boot.sh +++ b/config/hypr/initial-boot.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # # A bash script designed to run only once dotfiles installed diff --git a/config/hypr/scripts/AirplaneMode.sh b/config/hypr/scripts/AirplaneMode.sh index 4379935d..548b9d6b 100755 --- a/config/hypr/scripts/AirplaneMode.sh +++ b/config/hypr/scripts/AirplaneMode.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Airplane Mode. Turning on or off all wifi using rfkill. diff --git a/config/hypr/scripts/Animations.sh b/config/hypr/scripts/Animations.sh index 477e5cd3..4bbe050f 100755 --- a/config/hypr/scripts/Animations.sh +++ b/config/hypr/scripts/Animations.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For applying Animations from different users diff --git a/config/hypr/scripts/Battery.sh b/config/hypr/scripts/Battery.sh index d7830058..2baed6ca 100644 --- a/config/hypr/scripts/Battery.sh +++ b/config/hypr/scripts/Battery.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash for i in {0..3}; do if [ -f /sys/class/power_supply/BAT$i/capacity ]; then diff --git a/config/hypr/scripts/Brightness.sh b/config/hypr/scripts/Brightness.sh index 63fd02f3..ce443ef2 100755 --- a/config/hypr/scripts/Brightness.sh +++ b/config/hypr/scripts/Brightness.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Script for Monitor backlights (if supported) using brightnessctl diff --git a/config/hypr/scripts/BrightnessKbd.sh b/config/hypr/scripts/BrightnessKbd.sh index 24737b73..93e09d86 100755 --- a/config/hypr/scripts/BrightnessKbd.sh +++ b/config/hypr/scripts/BrightnessKbd.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Script for keyboard backlights (if supported) using brightnessctl diff --git a/config/hypr/scripts/ChangeBlur.sh b/config/hypr/scripts/ChangeBlur.sh index 895987a4..0060285b 100755 --- a/config/hypr/scripts/ChangeBlur.sh +++ b/config/hypr/scripts/ChangeBlur.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Script for changing blurs on the fly diff --git a/config/hypr/scripts/ChangeLayout.sh b/config/hypr/scripts/ChangeLayout.sh index b083fcdc..78428188 100755 --- a/config/hypr/scripts/ChangeLayout.sh +++ b/config/hypr/scripts/ChangeLayout.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # for changing Hyprland Layouts (Master or Dwindle) on the fly diff --git a/config/hypr/scripts/ClipManager.sh b/config/hypr/scripts/ClipManager.sh index 9937b6f4..3ba5d91a 100755 --- a/config/hypr/scripts/ClipManager.sh +++ b/config/hypr/scripts/ClipManager.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Clipboard Manager. This script uses cliphist, rofi, and wl-copy. diff --git a/config/hypr/scripts/ComposeHyprConfigs.sh b/config/hypr/scripts/ComposeHyprConfigs.sh new file mode 100644 index 00000000..55bc3c5c --- /dev/null +++ b/config/hypr/scripts/ComposeHyprConfigs.sh @@ -0,0 +1,109 @@ +#!/usr/bin/env bash +# Compose merged Hyprland configs for Startup_Apps and WindowRules +set -euo pipefail + +BASE_DIR="$HOME/.config/hypr" +BASE_CFG_DIR="$BASE_DIR/configs" +USER_DIR="$BASE_DIR/UserConfigs" +GEN_DIR="$BASE_DIR/generated" + +mkdir -p "$GEN_DIR" + +log() { printf "[compose] %s\n" "$*"; } + +# Trim leading/trailing whitespace +trim() { sed -E 's/^\s+//;s/\s+$//'; } + +# Normalize spaces in a directive line +normalize() { awk '{$1=$1;print}'; } + +# Build merged Startup_Apps.conf +compose_startup_apps() { + local base_file="$BASE_CFG_DIR/Startup_Apps.conf" + local user_file="$USER_DIR/Startup_Apps.conf" + local disable_file="$USER_DIR/Startup_Apps.disable" + local out_file="$GEN_DIR/Startup_Apps.conf" + + : >"$out_file" + + # Header and variable lines come from base + if [[ -f "$base_file" ]]; then + # Copy all non exec-once lines (comments, blanks, variables, etc.) + grep -Ev '^\s*exec-once\s*=' "$base_file" || true >>"$out_file" + fi + + # Collect exec-once commands (the right side of '=') + declare -A cmds=() + + if [[ -f "$base_file" ]]; then + while IFS= read -r line; do + [[ "$line" =~ ^\s*exec-once\s*= ]] || continue + cmd="${line#*=}" + cmd="$(echo "$cmd" | trim)" + cmds["$cmd"]=1 + done <"$base_file" + fi + + if [[ -f "$user_file" ]]; then + while IFS= read -r line; do + [[ "$line" =~ ^\s*exec-once\s*= ]] || continue + cmd="${line#*=}" + cmd="$(echo "$cmd" | trim)" + cmds["$cmd"]=1 + done <"$user_file" + fi + + # Apply disables (exact match of command string) + if [[ -f "$disable_file" ]]; then + while IFS= read -r d; do + d="$(echo "$d" | trim)" + [[ -z "$d" || "$d" =~ ^# ]] && continue + unset 'cmds[$d]' + done <"$disable_file" + fi + + # Emit combined exec-once (stable sort) + for k in "${!cmds[@]}"; do echo "$k"; done | sort -u | while IFS= read -r cmd; do + [[ -z "$cmd" ]] && continue + printf "exec-once = %s\n" "$cmd" >>"$out_file" + done + + log "Wrote $out_file" +} + +# Build merged WindowRules.conf +compose_window_rules() { + local base_file="$BASE_CFG_DIR/WindowRules.conf" + local user_file="$USER_DIR/WindowRules.conf" + local disable_file="$USER_DIR/WindowRules.disable" + local out_file="$GEN_DIR/WindowRules.conf" + + : >"$out_file" + echo "# Generated merged WindowRules" >>"$out_file" + + declare -A rules=() + add_rules() { + local f="$1" + [[ -f "$f" ]] || return 0 + grep -E '^(windowrule|layerrule)\s*=' "$f" | trim | while IFS= read -r r; do + rules["$r"]=1 + done + } + + add_rules "$base_file" + add_rules "$user_file" + + if [[ -f "$disable_file" ]]; then + while IFS= read -r d; do + d="$(echo "$d" | trim)" + [[ -z "$d" || "$d" =~ ^# ]] && continue + unset 'rules[$d]' + done <"$disable_file" + fi + + for r in "${!rules[@]}"; do echo "$r"; done | sort -u >>"$out_file" + log "Wrote $out_file" +} + +compose_startup_apps +compose_window_rules \ No newline at end of file diff --git a/config/hypr/scripts/DarkLight.sh b/config/hypr/scripts/DarkLight.sh index 1bc1602f..e473efb2 100755 --- a/config/hypr/scripts/DarkLight.sh +++ b/config/hypr/scripts/DarkLight.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash ## /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For Dark and Light switching # Note: Scripts are looking for keywords Light or Dark except for wallpapers as the are in a separate directories diff --git a/config/hypr/scripts/Distro_update.sh b/config/hypr/scripts/Distro_update.sh index b0b1446b..2b3376e3 100755 --- a/config/hypr/scripts/Distro_update.sh +++ b/config/hypr/scripts/Distro_update.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Simple bash script to check and will try to update your system diff --git a/config/hypr/scripts/Dropterminal.sh b/config/hypr/scripts/Dropterminal.sh index 1c17fbb4..9b2eeecb 100755 --- a/config/hypr/scripts/Dropterminal.sh +++ b/config/hypr/scripts/Dropterminal.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # # Made and brought to by Kiran George diff --git a/config/hypr/scripts/GameMode.sh b/config/hypr/scripts/GameMode.sh index 7a39da3d..ec1e541e 100755 --- a/config/hypr/scripts/GameMode.sh +++ b/config/hypr/scripts/GameMode.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Game Mode. Turning off all animations diff --git a/config/hypr/scripts/Hypridle.sh b/config/hypr/scripts/Hypridle.sh index 56176716..6acff434 100755 --- a/config/hypr/scripts/Hypridle.sh +++ b/config/hypr/scripts/Hypridle.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # This is for custom version of waybar idle_inhibitor which activates / deactivates hypridle instead diff --git a/config/hypr/scripts/KeyBinds.sh b/config/hypr/scripts/KeyBinds.sh index 9c6b5ab7..3a19390f 100755 --- a/config/hypr/scripts/KeyBinds.sh +++ b/config/hypr/scripts/KeyBinds.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # searchable enabled keybinds using rofi diff --git a/config/hypr/scripts/KeyHints.sh b/config/hypr/scripts/KeyHints.sh index 7917ae3a..8a478039 100755 --- a/config/hypr/scripts/KeyHints.sh +++ b/config/hypr/scripts/KeyHints.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # GDK BACKEND. Change to either wayland or x11 if having issues diff --git a/config/hypr/scripts/KillActiveProcess.sh b/config/hypr/scripts/KillActiveProcess.sh index bee146d7..2bc108f2 100755 --- a/config/hypr/scripts/KillActiveProcess.sh +++ b/config/hypr/scripts/KillActiveProcess.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Copied from Discord post. Thanks to @Zorg diff --git a/config/hypr/scripts/Kitty_themes.sh b/config/hypr/scripts/Kitty_themes.sh index 48bfa99f..55da7e44 100755 --- a/config/hypr/scripts/Kitty_themes.sh +++ b/config/hypr/scripts/Kitty_themes.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ย  # # Kitty Themes Source https://github.com/dexpota/kitty-themes # diff --git a/config/hypr/scripts/KooLsDotsUpdate.sh b/config/hypr/scripts/KooLsDotsUpdate.sh index f4b8814a..51277ab1 100755 --- a/config/hypr/scripts/KooLsDotsUpdate.sh +++ b/config/hypr/scripts/KooLsDotsUpdate.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # simple bash script to check if update is available by comparing local version and github version diff --git a/config/hypr/scripts/Kool_Quick_Settings.sh b/config/hypr/scripts/Kool_Quick_Settings.sh index e43749bf..79ddc163 100755 --- a/config/hypr/scripts/Kool_Quick_Settings.sh +++ b/config/hypr/scripts/Kool_Quick_Settings.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Rofi menu for KooL Hyprland Quick Settings (SUPER SHIFT E) diff --git a/config/hypr/scripts/LockScreen.sh b/config/hypr/scripts/LockScreen.sh index e61490cd..d58f5c21 100755 --- a/config/hypr/scripts/LockScreen.sh +++ b/config/hypr/scripts/LockScreen.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For Hyprlock diff --git a/config/hypr/scripts/MediaCtrl.sh b/config/hypr/scripts/MediaCtrl.sh index 000c3ade..9dc3571d 100755 --- a/config/hypr/scripts/MediaCtrl.sh +++ b/config/hypr/scripts/MediaCtrl.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Playerctl diff --git a/config/hypr/scripts/MonitorProfiles.sh b/config/hypr/scripts/MonitorProfiles.sh index 67316c09..1176a46a 100755 --- a/config/hypr/scripts/MonitorProfiles.sh +++ b/config/hypr/scripts/MonitorProfiles.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For applying Pre-configured Monitor Profiles diff --git a/config/hypr/scripts/Polkit-NixOS.sh b/config/hypr/scripts/Polkit-NixOS.sh index 51675eff..28642d19 100755 --- a/config/hypr/scripts/Polkit-NixOS.sh +++ b/config/hypr/scripts/Polkit-NixOS.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For NixOS starting of polkit-gnome. Dec 2023, the settings stated in NixOS wiki does not work so have to manual start it diff --git a/config/hypr/scripts/Polkit.sh b/config/hypr/scripts/Polkit.sh index dcea7653..1af8fd1b 100755 --- a/config/hypr/scripts/Polkit.sh +++ b/config/hypr/scripts/Polkit.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # This script starts the first available Polkit agent from a list of possible locations diff --git a/config/hypr/scripts/PortalHyprland.sh b/config/hypr/scripts/PortalHyprland.sh index 9bdf4b8c..21cb7db4 100755 --- a/config/hypr/scripts/PortalHyprland.sh +++ b/config/hypr/scripts/PortalHyprland.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For manually starting xdg-desktop-portal-hyprland diff --git a/config/hypr/scripts/Refresh.sh b/config/hypr/scripts/Refresh.sh index 719c368d..2e772aa9 100755 --- a/config/hypr/scripts/Refresh.sh +++ b/config/hypr/scripts/Refresh.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Scripts for refreshing ags, waybar, rofi, swaync, wallust diff --git a/config/hypr/scripts/RefreshNoWaybar.sh b/config/hypr/scripts/RefreshNoWaybar.sh index 8454124e..54c760bd 100755 --- a/config/hypr/scripts/RefreshNoWaybar.sh +++ b/config/hypr/scripts/RefreshNoWaybar.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Modified version of Refresh.sh but waybar wont refresh diff --git a/config/hypr/scripts/RofiEmoji.sh b/config/hypr/scripts/RofiEmoji.sh index 4570831e..7e3ef0f3 100755 --- a/config/hypr/scripts/RofiEmoji.sh +++ b/config/hypr/scripts/RofiEmoji.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Variables diff --git a/config/hypr/scripts/RofiSearch.sh b/config/hypr/scripts/RofiSearch.sh index 4218bed3..8ef12c46 100755 --- a/config/hypr/scripts/RofiSearch.sh +++ b/config/hypr/scripts/RofiSearch.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For Searching via web browsers diff --git a/config/hypr/scripts/RofiThemeSelector-modified.sh b/config/hypr/scripts/RofiThemeSelector-modified.sh index 2cfc2d24..d6a353c0 100755 --- a/config/hypr/scripts/RofiThemeSelector-modified.sh +++ b/config/hypr/scripts/RofiThemeSelector-modified.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # A modified version of Rofi-Theme-Selector, concentrating only on ~/.local and also, applying only 10 @themes in ~/.config/rofi/config.rasi # as opposed to continous adding of //@theme diff --git a/config/hypr/scripts/RofiThemeSelector.sh b/config/hypr/scripts/RofiThemeSelector.sh index 8b2fcb71..b7236e8f 100755 --- a/config/hypr/scripts/RofiThemeSelector.sh +++ b/config/hypr/scripts/RofiThemeSelector.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ย  # # Rofi Themes - Script to preview and apply themes by live-reloading the config. diff --git a/config/hypr/scripts/ScreenShot.sh b/config/hypr/scripts/ScreenShot.sh index 0a37c7e4..0ef70964 100755 --- a/config/hypr/scripts/ScreenShot.sh +++ b/config/hypr/scripts/ScreenShot.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Screenshots scripts diff --git a/config/hypr/scripts/Sounds.sh b/config/hypr/scripts/Sounds.sh index 8b2cc76e..b372d714 100755 --- a/config/hypr/scripts/Sounds.sh +++ b/config/hypr/scripts/Sounds.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # This script is used to play system sounds. # Script is used by Volume.Sh and ScreenShots.sh diff --git a/config/hypr/scripts/SwitchKeyboardLayout.sh b/config/hypr/scripts/SwitchKeyboardLayout.sh index f505fa6c..18a9517e 100755 --- a/config/hypr/scripts/SwitchKeyboardLayout.sh +++ b/config/hypr/scripts/SwitchKeyboardLayout.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # This is for changing kb_layouts. Set kb_layouts in $settings_file diff --git a/config/hypr/scripts/Tak0-Autodispatch.sh b/config/hypr/scripts/Tak0-Autodispatch.sh index a1f72129..114a3e8e 100755 --- a/config/hypr/scripts/Tak0-Autodispatch.sh +++ b/config/hypr/scripts/Tak0-Autodispatch.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # USAGE / ะ†ะะกะขะ ะฃะšะฆะ†ะฏ: # 1) Run from terminal: # ./dispatch.sh diff --git a/config/hypr/scripts/TouchPad.sh b/config/hypr/scripts/TouchPad.sh index 8509d79f..030c36de 100755 --- a/config/hypr/scripts/TouchPad.sh +++ b/config/hypr/scripts/TouchPad.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # For disabling touchpad. # Edit the Touchpad_Device on ~/.config/hypr/UserConfigs/Laptops.conf according to your system diff --git a/config/hypr/scripts/Volume.sh b/config/hypr/scripts/Volume.sh index 8efdb55c..4c82f543 100755 --- a/config/hypr/scripts/Volume.sh +++ b/config/hypr/scripts/Volume.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Scripts for volume controls for audio and mic diff --git a/config/hypr/scripts/WallustSwww.sh b/config/hypr/scripts/WallustSwww.sh index 5e0148ee..657f41ab 100755 --- a/config/hypr/scripts/WallustSwww.sh +++ b/config/hypr/scripts/WallustSwww.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Wallust: derive colors from the current wallpaper and update templates # Usage: WallustSwww.sh [absolute_path_to_wallpaper] diff --git a/config/hypr/scripts/WaybarLayout.sh b/config/hypr/scripts/WaybarLayout.sh index f65c9c00..d3725a91 100755 --- a/config/hypr/scripts/WaybarLayout.sh +++ b/config/hypr/scripts/WaybarLayout.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Script for waybar layout or configs diff --git a/config/hypr/scripts/WaybarScripts.sh b/config/hypr/scripts/WaybarScripts.sh index 7b3aaba2..d2205c42 100755 --- a/config/hypr/scripts/WaybarScripts.sh +++ b/config/hypr/scripts/WaybarScripts.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # # This file used on waybar modules sourcing defaults set in $HOME/.config/hypr/UserConfigs/01-UserDefaults.conf diff --git a/config/hypr/scripts/WaybarStyles.sh b/config/hypr/scripts/WaybarStyles.sh index 15767c2a..8ebfed92 100755 --- a/config/hypr/scripts/WaybarStyles.sh +++ b/config/hypr/scripts/WaybarStyles.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Script for waybar styles diff --git a/config/hypr/scripts/Wlogout.sh b/config/hypr/scripts/Wlogout.sh index f552b83d..8879858c 100755 --- a/config/hypr/scripts/Wlogout.sh +++ b/config/hypr/scripts/Wlogout.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # wlogout (Power, Screen Lock, Suspend, etc) diff --git a/config/hypr/scripts/sddm_wallpaper.sh b/config/hypr/scripts/sddm_wallpaper.sh index 9487188c..9dca2f72 100644 --- a/config/hypr/scripts/sddm_wallpaper.sh +++ b/config/hypr/scripts/sddm_wallpaper.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # SDDM Wallpaper and Wallust Colors Setter diff --git a/copy.sh b/copy.sh index d54402f3..496811d8 100755 --- a/copy.sh +++ b/copy.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # clear @@ -111,8 +111,17 @@ fi # Proper Polkit for NixOS if hostnamectl | grep -q 'Operating System: NixOS'; then echo "${INFO} NixOS Distro Detected. Setting up proper env's and configs." 2>&1 | tee -a "$LOG" || true - sed -i -E '/^#?exec-once = \$scriptsDir\/Polkit-NixOS\.sh/s/^#//' config/hypr/UserConfigs/Startup_Apps.conf - sed -i '/^exec-once = \$scriptsDir\/Polkit\.sh$/ s/^#*/#/' config/hypr/UserConfigs/Startup_Apps.conf + # Ensure NixOS polkit is enabled via overlay and default polkit is disabled via disable list + OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" + DISABLE_SA="config/hypr/UserConfigs/Startup_Apps.disable" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" "$DISABLE_SA" + if ! grep -qx 'exec-once = $scriptsDir/Polkit-NixOS.sh' "$OVERLAY_SA"; then + echo 'exec-once = $scriptsDir/Polkit-NixOS.sh' >> "$OVERLAY_SA" + fi + if ! grep -qx '\$scriptsDir/Polkit.sh' "$DISABLE_SA"; then + echo '$scriptsDir/Polkit.sh' >> "$DISABLE_SA" + fi fi # activating hyprcursor on env by checking if the directory ~/.icons/Bibata-Modern-Ice/hyprcursors exists @@ -236,17 +245,23 @@ 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 + OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" + grep -qx 'exec-once = rog-control-center' "$OVERLAY_SA" || echo 'exec-once = rog-control-center' >> "$OVERLAY_SA" 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 + OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" + grep -qx 'exec-once = blueman-applet' "$OVERLAY_SA" || echo 'exec-once = blueman-applet' >> "$OVERLAY_SA" 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 + OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" + grep -qx 'exec-once = ags' "$OVERLAY_SA" || echo 'exec-once = ags' >> "$OVERLAY_SA" sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/Refresh.sh @@ -259,7 +274,9 @@ 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 + OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" + mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" + grep -qx 'exec-once = qs' "$OVERLAY_SA" || echo 'exec-once = qs' >> "$OVERLAY_SA" sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh @@ -814,6 +831,37 @@ FILES_TO_RESTORE=( "WindowRules.conf" ) +# Helper to extract overlay (additions) and optional disables from a previous user file compared to vendor base +compose_overlay_from_backup() { + local type="$1" # startup|windowrules + local base_file="$2" + local old_user_file="$3" + local new_user_file="$4" + local disable_file="$5" + + mkdir -p "$(dirname "$new_user_file")" + : >"$new_user_file" + : >"$disable_file" + + if [ "$type" = "startup" ]; then + # additions: exec-once lines present in old user but not in base + grep -E '^\s*exec-once\s*=' "$old_user_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$old_user_file.tmp.exec" + grep -E '^\s*exec-once\s*=' "$base_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$base_file.tmp.exec" + comm -23 "$old_user_file.tmp.exec" "$base_file.tmp.exec" >"$new_user_file" + # treat commented exec-once in old user as disables + grep -E '^\s*#\s*exec-once\s*=' "$old_user_file" | sed -E 's/^\s*#\s*exec-once\s*=\s*//' | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$disable_file" + rm -f "$old_user_file.tmp.exec" "$base_file.tmp.exec" + elif [ "$type" = "windowrules" ]; then + # additions + grep -E '^(windowrule|layerrule)\s*=' "$old_user_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$old_user_file.tmp.rules" + grep -E '^(windowrule|layerrule)\s*=' "$base_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$base_file.tmp.rules" + comm -23 "$old_user_file.tmp.rules" "$base_file.tmp.rules" >"$new_user_file" + # disables: lines commented in old user + grep -E '^\s*#\s*(windowrule|layerrule)\s*=' "$old_user_file" | sed -E 's/^\s*#\s*//' | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$disable_file" + rm -f "$old_user_file.tmp.rules" "$base_file.tmp.rules" + fi +} + DIRPATH="$HOME/.config/$DIRH" BACKUP_DIR=$(get_backup_dirname) BACKUP_DIR_PATH="$DIRPATH-backup-$BACKUP_DIR/UserConfigs" @@ -830,14 +878,27 @@ if [ -d "$BACKUP_DIR_PATH" ]; then NOTES for RESTORING PREVIOUS CONFIGS โ–ˆโ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–„โ–ˆ - If you decide to restore your old configs, make sure to - handle the updates or changes manually !!! + We now auto-migrate Startup_Apps and WindowRules by extracting + your additions into overlay files and optional disable lists. + This keeps new defaults while preserving your custom changes. " 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" if [ -f "$BACKUP_FILE" ]; then + # Special handling for Startup_Apps.conf and WindowRules.conf + if [ "$FILE_NAME" = "Startup_Apps.conf" ]; then + compose_overlay_from_backup "startup" "$DIRPATH/configs/Startup_Apps.conf" "$BACKUP_FILE" "$DIRPATH/UserConfigs/Startup_Apps.conf" "$DIRPATH/UserConfigs/Startup_Apps.disable" + echo "${OK} - Migrated overlay for ${YELLOW}$FILE_NAME${RESET}" 2>&1 | tee -a "$LOG" + continue + fi + if [ "$FILE_NAME" = "WindowRules.conf" ]; then + compose_overlay_from_backup "windowrules" "$DIRPATH/configs/WindowRules.conf" "$BACKUP_FILE" "$DIRPATH/UserConfigs/WindowRules.conf" "$DIRPATH/UserConfigs/WindowRules.disable" + echo "${OK} - Migrated overlay for ${YELLOW}$FILE_NAME${RESET}" 2>&1 | tee -a "$LOG" + continue + fi + printf "\n${INFO} Found ${YELLOW}$FILE_NAME${RESET} in hypr backup...\n" echo -n "${CAT} Do you want to restore ${YELLOW}$FILE_NAME${RESET} from backup? (y/N): " read file_restore @@ -855,6 +916,11 @@ if [ -d "$BACKUP_DIR_PATH" ]; then done fi +# Compose merged configs (Startup_Apps and WindowRules) +if [ -x "$DIRPATH/scripts/ComposeHyprConfigs.sh" ]; then + "$DIRPATH/scripts/ComposeHyprConfigs.sh" 2>&1 | tee -a "$LOG" || true +fi + printf "\n%.0s" {1..1} # Restoring previous UserScripts diff --git a/release.sh b/release.sh index 78063ee1..e29eaa79 100755 --- a/release.sh +++ b/release.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # # For downloading dots from releases diff --git a/upgrade.sh b/upgrade.sh index a47bd48b..9aee3c2c 100755 --- a/upgrade.sh +++ b/upgrade.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # # for Semi-Manual upgrading your system. # NOTE: requires rsync @@ -196,7 +196,12 @@ if version_gt "$latest_version" "$stored_version"; then chmod +x "$HOME/.config/hypr/scripts/"* 2>&1 | tee -a "$LOG" chmod +x "$HOME/.config/hypr/UserScripts/"* 2>&1 | tee -a "$LOG" # Set executable for initial-boot.sh - chmod +x "$HOME/.config/hypr/initial-boot.sh" 2>&1 | tee -a "$LOG" + chmod +x "$HOME/.config/hypr/initial-boot.sh" 2>&1 | tee -a "$LOG" + + # Compose merged configs (Startup_Apps and WindowRules) + if [ -x "$HOME/.config/hypr/scripts/ComposeHyprConfigs.sh" ]; then + "$HOME/.config/hypr/scripts/ComposeHyprConfigs.sh" 2>&1 | tee -a "$LOG" || true + fi else echo "$MAGENTA Upgrade declined. No files or directories changed" 2>&1 | tee -a "$LOG" fi -- cgit v1.2.3 From 396bf3fa59ded1c41c9484ec8696db856b046b2f Mon Sep 17 00:00:00 2001 From: Don Williams Date: Tue, 28 Oct 2025 19:17:33 -0400 Subject: Fixed path issue on Startup and Window Rules On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: hyprland.conf --- config/hypr/hyprland.conf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index cd9fed2d..27003ac9 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -16,8 +16,8 @@ source=$configs/Keybinds.conf # Pre-configured keybinds $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path # Generated merges (vendor + user overlay with dedupe/disable) -source= $HOME/.config/hypr/generated/Startup_Apps.conf -source= $HOME/.config/hypr/generated/WindowRules.conf +source= $HOME/.config/hypr/UserConfigs/Startup_Apps.conf +source= $HOME/.config/hypr/UserConfigs/WindowRules.conf source= $UserConfigs/ENVariables.conf # Environment variables to load @@ -42,4 +42,4 @@ source= $UserConfigs/01-UserDefaults.conf # settings for User defaults apps # nwg-displays source= $HOME/.config/hypr/monitors.conf -source= $HOME/.config/hypr/workspaces.conf \ No newline at end of file +source= $HOME/.config/hypr/workspaces.conf -- cgit v1.2.3 From 8eef1819d5c509eab56b482e9c3b093910a3bf74 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Tue, 28 Oct 2025 19:23:29 -0400 Subject: The variable for UserConfig dir was hard coded Should be varible $USerConfig On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: hyprland.conf --- config/hypr/hyprland.conf | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index 27003ac9..fa8435dc 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -15,9 +15,7 @@ source=$configs/Keybinds.conf # Pre-configured keybinds # ## This is where you want to start tinkering $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path -# Generated merges (vendor + user overlay with dedupe/disable) -source= $HOME/.config/hypr/UserConfigs/Startup_Apps.conf -source= $HOME/.config/hypr/UserConfigs/WindowRules.conf +source= $UserConfigs/Startup_Apps.conf source= $UserConfigs/ENVariables.conf # Environment variables to load -- cgit v1.2.3 From 313a350c997835a199ab737a46229e22289648e0 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Tue, 28 Oct 2025 19:52:13 -0400 Subject: Updated CHANGELOG.md --- CHANGELOG.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd0effc4..623e697c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,26 @@ ### ๐Ÿ› Fixes +- Updated `/bin/bash` to `/usr/bin/env bash` - Correct `windowrule` syntax error. - Ensure wallpaper selector applies wallpaper to SDDM. - Update theme colors when a new wallpaper is selected. +### ๐Ÿ–ฅ๏ธ Jak dotfiles version now in `fastfetch` output. + ### ๐ŸŒฆ๏ธ Weather.py +Key Changes: + +- 2nd Weather.py Update by prabinpanta0 - โ™ป๏ธ Substantial rewrite. -- โœ… Launches properly in Waybar. -- ๐Ÿ“ Improved location detection; overridable variables exposed. -- ๐ŸŒ Switched to Open-Meteo for weather data with fallback providers. +- โœจ New unified weather entrypoint (weatherWrap.sh) + - With Python-first execution +- ๐Ÿ”’ Automatic weather updates before screen lock +- ๐Ÿš€ Weather cache initialization at session startup +- ๐Ÿ›ก๏ธ Enhanced error handling and fallback mechanisms +- ๐Ÿ“ Automatic location detection via IP geolocation +- ๐ŸŽจ Improved weather condition mapping and JSON output ### ๐Ÿ–ฅ๏ธ Support for debian and ubuntu installs @@ -34,6 +44,7 @@ ### ๐Ÿ‘ฅ Contributors +- [prabinpanta0](https://github.com/prabinpanta0) - [CharlyMH](https://github.com/CharlyMH) - [ndeekshith](https://github.com/ndeekshith) - [SherLock707](https://github.com/SherLock707) -- cgit v1.2.3 From cc12a1f43d2d35d86a299f456ada1bc1cddd2000 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 29 Oct 2025 09:50:12 -0400 Subject: Added message about AI wallpaper download allows user to not install wallpapers On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: copy.sh --- copy.sh | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/copy.sh b/copy.sh index 496811d8..762af601 100755 --- a/copy.sh +++ b/copy.sh @@ -38,25 +38,25 @@ print_color() { # 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" + print_color $WARNING "\nThese Dotfiles are only supported on Hyprland v0.50 or greater. Do not install on older versions of Hyprland.\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'." - ;; + 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 @@ -117,10 +117,10 @@ if hostnamectl | grep -q 'Operating System: NixOS'; then mkdir -p "$(dirname "$OVERLAY_SA")" touch "$OVERLAY_SA" "$DISABLE_SA" if ! grep -qx 'exec-once = $scriptsDir/Polkit-NixOS.sh' "$OVERLAY_SA"; then - echo 'exec-once = $scriptsDir/Polkit-NixOS.sh' >> "$OVERLAY_SA" + echo 'exec-once = $scriptsDir/Polkit-NixOS.sh' >>"$OVERLAY_SA" fi if ! grep -qx '\$scriptsDir/Polkit.sh' "$DISABLE_SA"; then - echo '$scriptsDir/Polkit.sh' >> "$DISABLE_SA" + echo '$scriptsDir/Polkit.sh' >>"$DISABLE_SA" fi fi @@ -246,22 +246,25 @@ done # Check if asusctl is installed and add rog-control-center on Startup if command -v asusctl >/dev/null 2>&1; then OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" - grep -qx 'exec-once = rog-control-center' "$OVERLAY_SA" || echo 'exec-once = rog-control-center' >> "$OVERLAY_SA" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = rog-control-center' "$OVERLAY_SA" || echo 'exec-once = rog-control-center' >>"$OVERLAY_SA" fi # Check if blueman-applet is installed and add blueman-applet on Startup if command -v blueman-applet >/dev/null 2>&1; then OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" - grep -qx 'exec-once = blueman-applet' "$OVERLAY_SA" || echo 'exec-once = blueman-applet' >> "$OVERLAY_SA" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = blueman-applet' "$OVERLAY_SA" || echo 'exec-once = blueman-applet' >>"$OVERLAY_SA" fi # Check if ags is installed edit ags behaviour on configs if command -v ags >/dev/null 2>&1; then OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" - grep -qx 'exec-once = ags' "$OVERLAY_SA" || echo 'exec-once = ags' >> "$OVERLAY_SA" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = ags' "$OVERLAY_SA" || echo 'exec-once = ags' >>"$OVERLAY_SA" sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh sed -i '/#ags -q && ags &/s/^#//' config/hypr/scripts/Refresh.sh @@ -275,8 +278,9 @@ fi # Check if quickshell is installed; edit quickshell behaviour on configs if command -v qs >/dev/null 2>&1; then OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" - mkdir -p "$(dirname "$OVERLAY_SA")"; touch "$OVERLAY_SA" - grep -qx 'exec-once = qs' "$OVERLAY_SA" || echo 'exec-once = qs' >> "$OVERLAY_SA" + mkdir -p "$(dirname "$OVERLAY_SA")" + touch "$OVERLAY_SA" + grep -qx 'exec-once = qs' "$OVERLAY_SA" || echo 'exec-once = qs' >>"$OVERLAY_SA" sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/RefreshNoWaybar.sh sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh @@ -1089,6 +1093,7 @@ printf "\n%.0s" {1..1} echo "${MAGENTA}By default only a few wallpapers are copied${RESET}..." while true; do + echo "${NOTE} A number of these wallpapers are AI generated or enhanced. Select (N/n) if this is an issue for you. " echo -n "${CAT} Would you like to download additional wallpapers? ${WARN} This is 1GB in size (y/n): " read WALL @@ -1197,4 +1202,3 @@ printf "${INFO} However, it is ${MAGENTA}HIGHLY SUGGESTED${RESET} to logout and 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} - -- cgit v1.2.3 From dedbe6bcfacd9dfb4c6f7e1dee409d9f4765bbdf Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 29 Oct 2025 11:20:28 -0400 Subject: Added more appl icons for waybars that use them On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/waybar/ModulesWorkspaces --- config/waybar/ModulesWorkspaces | 38 +++++++++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/config/waybar/ModulesWorkspaces b/config/waybar/ModulesWorkspaces index 82a82869..ab4b2b02 100644 --- a/config/waybar/ModulesWorkspaces +++ b/config/waybar/ModulesWorkspaces @@ -198,19 +198,21 @@ "class": "๏„  ", "class": " ๎ž•", "class": " ๎ช…", + "class": "๓ฐฐญ ", "class<[Tt]hunderbird|[Tt]hunderbird-esr>": "๏ฐ ", "class": "๏ฐ ", "title<.*gmail.*>": "๓ฐŠซ ", "class<[Tt]elegram-desktop|org.telegram.desktop|io.github.tdesktop_x64.TDesktop>": "๎ˆ— ", - "class": "๏‡ฟ ", + "class": "๏‡ฟ ", + "class<[Ss]ignal|signal-desktop|org.signal.Signal>": "๓ฐฉ ", + "title<.*Signal.*>": "๓ฐฉ ", "title<.*whatsapp.*>": "๏ˆฒ ", "title<.*zapzap.*>": "๏ˆฒ ", "title<.*messenger.*>": "๏‰Ÿ ", "title<.*facebook.*>": "๏‚š ", - "title<.*reddit.*>": "๏Ё ", - + "title<.*Discord.*>": "๏‡ฟ ", "title<.*ChatGPT.*>": "๓ฐšฉ ", "title<.*deepseek.*>": "๓ฐšฉ ", @@ -224,17 +226,20 @@ "title<.*Picture-in-Picture.*>": "๏”ฌ ", "title<.*youtube.*>": "๏…ช ", "class": "๓ฐ•ผ ", + "class<[Kk]denlive|org.kde.kdenlive>": "๐ŸŽฌ ", + "title<.*Kdenlive.*>": "๐ŸŽฌ ", "title<.*cmus.*>": "๏€ ", "class<[Ss]potify>": "๏†ผ ", "class": "๓ฐšบ ", "class": "๎ญป ", "class<.virt-manager-wrapped>": "๎ญป ", + "class": "๎ญป ", "class": "๐Ÿ’ฝ ", "title": "๐Ÿ’ฝ ", - "class": "๐Ÿ–ฅ๏ธ ", + "class": "๐Ÿ–ฅ๏ธ ", - "class": "๓ฐจž ", + "class": "๓ฐจž ", "class": "๓ฐต", "class": "๓ฐ…ฉ ", "title<.*github.*>": "๏„“ ", @@ -263,6 +268,29 @@ "class": "๓ฐ“ƒ", "class":"๏‡ ", "class": "๓ฐน›", + + "class": "๏Š‘ ", + "title<^Bazaar$>": "๏Š‘ ", + + "class": "๏€ฐ ", + "title<^satty$>": "๏€ฐ ", + + "class<[Bb]ox[Bb]uddy|io.github.dvlv.boxbuddy|io.github.dvlv.BoxBuddy>": "๏†ฒ ", + "title<.*BoxBuddy.*>": "๏†ฒ ", + + "title": "๏„œ ", + "title": "๏„œ ", + "title": "๏„œ ", + "title": "๏„œ ", + "title": "๏„œ ", + "title": "๏„œ ", + "title": "๏„œ ", + "title": "๏„œ ", + "title": "๏€ญ ", + "title": "๏ƒถ ", + "title<^Wallpapers$>": "๏€พ ", + "title<^Video Wallpapers$>": "๏€ฝ ", + "title<^qs-wlogout$>": "๏‚‹ ", } }, } \ No newline at end of file -- cgit v1.2.3 From 9fcc463fd035c3c48c28430d7504c0f1870f9a30 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 29 Oct 2025 13:38:00 -0400 Subject: Added icons for alacritty and nwg-displays On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/waybar/ModulesWorkspaces --- config/waybar/ModulesWorkspaces | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/waybar/ModulesWorkspaces b/config/waybar/ModulesWorkspaces index ab4b2b02..5bdccb91 100644 --- a/config/waybar/ModulesWorkspaces +++ b/config/waybar/ModulesWorkspaces @@ -194,7 +194,7 @@ "class": "๏ฑ ", "class": "๐ŸฆŠ ", - "class": "๎ฏ† ", + "class": "๎ฏ† ", "class": "๏„  ", "class": " ๎ž•", "class": " ๎ช…", @@ -258,6 +258,7 @@ "class": "๓ฐ’ƒ ", "class": "๎ญ’ ", + "class": "๏‰ฌ ", "class<[Pp]avucontrol|org.pulseaudio.pavucontrol>": "๓ฑกซ ", "class": "๏†ถ ", "class": "๓ฐฐ ", -- cgit v1.2.3 From 70cb1f313d04558da9ab4e4f9ca5eecd373acb45 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 30 Oct 2025 22:39:02 -0400 Subject: refactor(keybinds): use bindd with descriptions across configs - Convert binds to description form (bindd/bindld/binded/bindmd/bindlnd) - Keep naming as powermenu for shutdown/reboot/logout/suspend - Update KeyBinds.sh to parse and display descriptions - Update CHANGELOG --- CHANGELOG.md | 8 ++ config/hypr/UserConfigs/UserKeybinds.conf | 82 ++++++------- config/hypr/configs/Keybinds.conf | 196 +++++++++++++++--------------- config/hypr/scripts/KeyBinds.sh | 69 +++++++++-- 4 files changed, 203 insertions(+), 152 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 623e697c..dd01997b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ## October 2025 +### โŒจ๏ธ Keybinds + +- Convert Hyprland keybinds to description form (`bindd`, `bindld`, `binded`, + `bindmd`, `bindlnd`) in `config/hypr/...`. +- Add concise descriptions for each keybind; keep the name "powermenu". +- Update `config/hypr/scripts/KeyBinds.sh` to parse and display descriptions + as: MODS+KEY โ€” DESCRIPTION โ€” DISPATCHER [PARAMS]. + ### ๐Ÿ› Fixes - Updated `/bin/bash` to `/usr/bin/env bash` diff --git a/config/hypr/UserConfigs/UserKeybinds.conf b/config/hypr/UserConfigs/UserKeybinds.conf index 338bf0d1..5b257b33 100644 --- a/config/hypr/UserConfigs/UserKeybinds.conf +++ b/config/hypr/UserConfigs/UserKeybinds.conf @@ -16,67 +16,67 @@ source= $UserConfigs/01-UserDefaults.conf # common shortcuts #bindr = $mainMod, $mainMod_L, exec, pkill rofi || rofi -show drun -modi drun,filebrowser,run,window # Super Key to Launch rofi menu -bind = $mainMod, D, exec, pkill rofi || true && rofi -show drun -modi drun,filebrowser,run,window # Main Menu (APP Launcher) -bind = $mainMod, B, exec, xdg-open "https://" # default browser +bindd = $mainMod, D, app launcher, exec, pkill rofi || true && rofi -show drun -modi drun,filebrowser,run,window +bindd = $mainMod, B, open default browser, exec, xdg-open "https://" #bind = $mainMod, A, exec, pkill rofi || true && ags -t 'overview' # desktop overview (if installed) #bind = $mainMod, A, global, quickshell:overviewToggle # desktop overview (if installed) -bind = $mainMod, Return, exec, $term #terminal -bind = $mainMod, E, exec, $files #file manager +bindd = $mainMod, Return, terminal, exec, $term +bindd = $mainMod, E, file manager, exec, $files # FEATURES / EXTRAS -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 CTRL, S, exec, rofi -show window # 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 -bind = $mainMod ALT, V, exec, $scriptsDir/ClipManager.sh # Clipboard Manager -bind = $mainMod CTRL, R, exec, $scriptsDir/RofiThemeSelector.sh # KooL Rofi Menu Theme Selector -bind = $mainMod CTRL SHIFT, R, exec, pkill rofi || true && $scriptsDir/RofiThemeSelector-modified.sh # modified Rofi Theme Selector +bindd = $mainMod, H, help / cheat sheet, exec, $scriptsDir/KeyHints.sh +bindd = $mainMod ALT, R, refresh bar and menus, exec, $scriptsDir/Refresh.sh +bindd = $mainMod ALT, E, emoji menu, exec, $scriptsDir/RofiEmoji.sh +bindd = $mainMod, S, web search, exec, $scriptsDir/RofiSearch.sh +bindd = $mainMod CTRL, S, window switcher, exec, rofi -show window +bindd = $mainMod ALT, O, toggle blur, exec, $scriptsDir/ChangeBlur.sh +bindd = $mainMod SHIFT, G, toggle game mode, exec, $scriptsDir/GameMode.sh +bindd = $mainMod ALT, L, toggle master/dwindle layout, exec, $scriptsDir/ChangeLayout.sh +bindd = $mainMod ALT, V, clipboard manager, exec, $scriptsDir/ClipManager.sh +bindd = $mainMod CTRL, R, rofi theme selector, exec, $scriptsDir/RofiThemeSelector.sh +bindd = $mainMod CTRL SHIFT, R, rofi theme selector (modified), exec, pkill rofi || true && $scriptsDir/RofiThemeSelector-modified.sh -bind = $mainMod SHIFT, F, fullscreen # whole full screen -bind = $mainMod CTRL, F, fullscreen, 1 # fake full screen -bind = $mainMod, SPACE, togglefloating, #Float Mode -bind = $mainMod ALT, SPACE, exec, hyprctl dispatch workspaceopt allfloat #All Float Mode -bind = $mainMod SHIFT, Return, exec, $scriptsDir/Dropterminal.sh $term # Dropdown terminal +bindd = $mainMod SHIFT, F, fullscreen, fullscreen +bindd = $mainMod CTRL, F, fake fullscreen, fullscreen, 1 +bindd = $mainMod, SPACE, toggle floating, togglefloating, +bindd = $mainMod ALT, SPACE, all float mode, exec, hyprctl dispatch workspaceopt allfloat +bindd = $mainMod SHIFT, Return, dropdown terminal, exec, $scriptsDir/Dropterminal.sh $term # Desktop zooming or magnifier -bind = $mainMod ALT, mouse_down, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor * 2.0}')" -bind = $mainMod ALT, mouse_up, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor / 2.0}')" +bindd = $mainMod ALT, mouse_down, zoom in, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor * 2.0}')" +bindd = $mainMod ALT, mouse_up, zoom out, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor / 2.0}')" ## NOTES for ja (Hyprland version 0.39 (Ubuntu 24.04)) #bind = $mainMod ALT, mouse_down, exec, hyprctl keyword misc:cursor_zoom_factor "$(hyprctl getoption misc:cursor_zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor * 2.0}')" #bind = $mainMod ALT, mouse_up, exec, hyprctl keyword misc:cursor_zoom_factor "$(hyprctl getoption misc:cursor_zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor / 2.0}')" # Waybar / Bar related -bind = $mainMod CTRL ALT, B, exec, pkill -SIGUSR1 waybar # Toggle hide/show waybar -bind = $mainMod CTRL, B, exec, $scriptsDir/WaybarStyles.sh # Waybar Styles Menu -bind = $mainMod ALT, B, exec, $scriptsDir/WaybarLayout.sh # Waybar Layout Menu +bindd = $mainMod CTRL ALT, B, toggle waybar, exec, pkill -SIGUSR1 waybar +bindd = $mainMod CTRL, B, waybar styles menu, exec, $scriptsDir/WaybarStyles.sh +bindd = $mainMod ALT, B, waybar layout menu, exec, $scriptsDir/WaybarLayout.sh # Night light toggle (Hyprsunset) -bind = $mainMod, N, exec, $scriptsDir/Hyprsunset.sh toggle +bindd = $mainMod, N, toggle night light, 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 -bind = $mainMod SHIFT, W, exec, $UserScripts/WallpaperEffects.sh # Wallpaper Effects by imagemagick -bind = CTRL ALT, W, exec, $UserScripts/WallpaperRandom.sh # Random wallpapers -bind = $mainMod CTRL, O, exec, hyprctl setprop active opaque toggle # disable opacity on active window -bind = $mainMod SHIFT, K, exec, $scriptsDir/KeyBinds.sh # search keybinds via rofi -bind = $mainMod SHIFT, A, exec, $scriptsDir/Animations.sh #hyprland animations menu -bind = $mainMod SHIFT, O, exec, $UserScripts/ZshChangeTheme.sh # Change oh-my-zsh theme -bindln = ALT_L, SHIFT_L, exec, $scriptsDir/SwitchKeyboardLayout.sh # Change keyboard layout globally -bindln = SHIFT_L, ALT_L, exec, $scriptsDir/Tak0-Per-Window-Switch.sh # Change keyboard layout locally for each window -bind = $mainMod ALT, C, exec, $UserScripts/RofiCalc.sh # calculator (qalculate) +bindd = $mainMod SHIFT, M, online music, exec, $UserScripts/RofiBeats.sh +bindd = $mainMod, W, select wallpaper, exec, $UserScripts/WallpaperSelect.sh +bindd = $mainMod SHIFT, W, wallpaper effects, exec, $UserScripts/WallpaperEffects.sh +bindd = CTRL ALT, W, random wallpaper, exec, $UserScripts/WallpaperRandom.sh +bindd = $mainMod CTRL, O, toggle active window opacity, exec, hyprctl setprop active opaque toggle +bindd = $mainMod SHIFT, K, search keybinds, exec, $scriptsDir/KeyBinds.sh +bindd = $mainMod SHIFT, A, animations menu, exec, $scriptsDir/Animations.sh +bindd = $mainMod SHIFT, O, change oh-my-zsh theme, exec, $UserScripts/ZshChangeTheme.sh +bindlnd = ALT_L, SHIFT_L, switch keyboard layout globally, exec, $scriptsDir/SwitchKeyboardLayout.sh +bindlnd = SHIFT_L, ALT_L, switch keyboard layout per-window, exec, $scriptsDir/Tak0-Per-Window-Switch.sh +bindd = $mainMod ALT, C, calculator, exec, $UserScripts/RofiCalc.sh # Move current workspaces to monitors (left right up or down) -bind = $mainMod CTRL, F9, movecurrentworkspacetomonitor, l #move current workspace to LEFT monitor -bind = $mainMod CTRL, F10, movecurrentworkspacetomonitor, r #move current workspace to RIGHT monitor -bind = $mainMod CTRL, F11, movecurrentworkspacetomonitor, u #move current workspace to UP monitor -bind = $mainMod CTRL, F12, movecurrentworkspacetomonitor, d #move current workspace to DOWN monitor +bindd = $mainMod CTRL, F9, move workspace to left monitor, movecurrentworkspacetomonitor, l +bindd = $mainMod CTRL, F10, move workspace to right monitor, movecurrentworkspacetomonitor, r +bindd = $mainMod CTRL, F11, move workspace to up monitor, movecurrentworkspacetomonitor, u +bindd = $mainMod CTRL, F12, move workspace to down monitor, movecurrentworkspacetomonitor, d # For passthrough keyboard into a VM diff --git a/config/hypr/configs/Keybinds.conf b/config/hypr/configs/Keybinds.conf index c2ba9681..0fa250b7 100644 --- a/config/hypr/configs/Keybinds.conf +++ b/config/hypr/configs/Keybinds.conf @@ -8,142 +8,142 @@ $scriptsDir = $HOME/.config/hypr/scripts $UserConfigs = $HOME/.config/hypr/UserConfigs $UserScripts = $HOME/.config/hypr/UserScripts -bind = CTRL ALT, Delete, exec, hyprctl dispatch exit 0 # exit Hyprland -bind = $mainMod, Q, killactive, # close active (not kill) -bind = $mainMod SHIFT, Q, exec, $scriptsDir/KillActiveProcess.sh # Kill active process -bind = CTRL ALT, L, exec, $scriptsDir/LockScreen.sh # screen lock -bind = CTRL ALT, P, exec, $scriptsDir/Wlogout.sh # power menu -bind = $mainMod SHIFT, N, exec, swaync-client -t -sw # swayNC notification panel -bind = $mainMod SHIFT, E, exec, $scriptsDir/Kool_Quick_Settings.sh # Settings Menu KooL Hyprland Settings +bindd = CTRL ALT, Delete, exit Hyprland, exec, hyprctl dispatch exit 0 +bindd = $mainMod, Q, close active window, killactive, +bindd = $mainMod SHIFT, Q, kill active process, exec, $scriptsDir/KillActiveProcess.sh +bindd = CTRL ALT, L, lock screen, exec, $scriptsDir/LockScreen.sh +bindd = CTRL ALT, P, powermenu, exec, $scriptsDir/Wlogout.sh +bindd = $mainMod SHIFT, N, notification panel, exec, swaync-client -t -sw +bindd = $mainMod SHIFT, E, settings menu, exec, $scriptsDir/Kool_Quick_Settings.sh # Master Layout -bind = $mainMod CTRL, D, layoutmsg, removemaster -bind = $mainMod, I, layoutmsg, addmaster -bind = $mainMod, J, layoutmsg, cyclenext -bind = $mainMod, K, layoutmsg, cycleprev -bind = $mainMod CTRL, Return, layoutmsg, swapwithmaster +bindd = $mainMod CTRL, D, remove master, layoutmsg, removemaster +bindd = $mainMod, I, add master, layoutmsg, addmaster +bindd = $mainMod, J, cycle next, layoutmsg, cyclenext +bindd = $mainMod, K, cycle previous, layoutmsg, cycleprev +bindd = $mainMod CTRL, Return, swap with master, layoutmsg, swapwithmaster # Dwindle Layout -bind = $mainMod SHIFT, I, togglesplit # only works on dwindle layout -bind = $mainMod, P, pseudo, # dwindle +bindd = $mainMod SHIFT, I, toggle split (dwindle), togglesplit +bindd = $mainMod, P, toggle pseudo (dwindle), pseudo, # Works on either layout (Master or Dwindle) -bind = $mainMod, M, exec, hyprctl dispatch splitratio 0.3 +bindd = $mainMod, M, set split ratio 0.3, exec, hyprctl dispatch splitratio 0.3 # group -bind = $mainMod, G, togglegroup # toggle group -bind = $mainMod CTRL, tab, changegroupactive # change focus to another window +bindd = $mainMod, G, toggle group, togglegroup +bindd = $mainMod CTRL, tab, change active in group, changegroupactive - # Cycle windows if floating bring to top -bind = ALT, tab, cyclenext -bind = ALT, tab, bringactivetotop +# Cycle windows; if floating bring to top +bindd = ALT, tab, cycle next window, cyclenext +bindd = ALT, tab, bring active to top, bringactivetotop # Special Keys / Hot Keys -bindel = , xf86audioraisevolume, exec, $scriptsDir/Volume.sh --inc # volume up -bindel = , xf86audiolowervolume, exec, $scriptsDir/Volume.sh --dec # volume down -bindl = , xf86AudioMicMute, exec, $scriptsDir/Volume.sh --toggle-mic # mic mute -bindl = , xf86audiomute, exec, $scriptsDir/Volume.sh --toggle # mute -bindl = , xf86Sleep, exec, systemctl suspend # sleep button -bindl = , xf86Rfkill, exec, $scriptsDir/AirplaneMode.sh # Airplane mode +bindeld = , xf86audioraisevolume, volume up, exec, $scriptsDir/Volume.sh --inc +bindeld = , xf86audiolowervolume, volume down, exec, $scriptsDir/Volume.sh --dec +bindld = , xf86AudioMicMute, toggle mic mute, exec, $scriptsDir/Volume.sh --toggle-mic +bindld = , xf86audiomute, toggle mute, exec, $scriptsDir/Volume.sh --toggle +bindld = , xf86Sleep, sleep, exec, systemctl suspend +bindld = , xf86Rfkill, airplane mode, exec, $scriptsDir/AirplaneMode.sh # media controls using keyboards -bindl = , xf86AudioPlayPause, exec, $scriptsDir/MediaCtrl.sh --pause -bindl = , xf86AudioPause, exec, $scriptsDir/MediaCtrl.sh --pause -bindl = , xf86AudioPlay, exec, $scriptsDir/MediaCtrl.sh --pause -bindl = , xf86AudioNext, exec, $scriptsDir/MediaCtrl.sh --nxt -bindl = , xf86AudioPrev, exec, $scriptsDir/MediaCtrl.sh --prv -bindl = , xf86audiostop, exec, $scriptsDir/MediaCtrl.sh --stop +bindld = , xf86AudioPlayPause, play/pause, exec, $scriptsDir/MediaCtrl.sh --pause +bindld = , xf86AudioPause, pause, exec, $scriptsDir/MediaCtrl.sh --pause +bindld = , xf86AudioPlay, play, exec, $scriptsDir/MediaCtrl.sh --pause +bindld = , xf86AudioNext, next track, exec, $scriptsDir/MediaCtrl.sh --nxt +bindld = , xf86AudioPrev, previous track, exec, $scriptsDir/MediaCtrl.sh --prv +bindld = , xf86audiostop, stop, exec, $scriptsDir/MediaCtrl.sh --stop # Screenshot keybindings NOTE: You may need to press Fn key as well -bind = $mainMod, Print, exec, $scriptsDir/ScreenShot.sh --now # screenshot -bind = $mainMod SHIFT, Print, exec, $scriptsDir/ScreenShot.sh --area # screenshot (area) -bind = $mainMod CTRL, Print, exec, $scriptsDir/ScreenShot.sh --in5 # screenshot (5 secs delay) -bind = $mainMod CTRL SHIFT, Print, exec, $scriptsDir/ScreenShot.sh --in10 # screenshot (10 secs delay) -bind = ALT, Print, exec, $scriptsDir/ScreenShot.sh --active # screenshot (active window only) +bindd = $mainMod, Print, screenshot now, exec, $scriptsDir/ScreenShot.sh --now +bindd = $mainMod SHIFT, Print, screenshot (area), exec, $scriptsDir/ScreenShot.sh --area +bindd = $mainMod CTRL, Print, screenshot in 5s, exec, $scriptsDir/ScreenShot.sh --in5 +bindd = $mainMod CTRL SHIFT, Print, screenshot in 10s, exec, $scriptsDir/ScreenShot.sh --in10 +bindd = ALT, Print, screenshot active window, exec, $scriptsDir/ScreenShot.sh --active # screenshot with swappy (another screenshot tool) -bind = $mainMod SHIFT, S, exec, $scriptsDir/ScreenShot.sh --swappy #screenshot (swappy) +bindd = $mainMod SHIFT, S, screenshot (swappy), exec, $scriptsDir/ScreenShot.sh --swappy # Resize windows -binde = $mainMod SHIFT, left, resizeactive,-50 0 -binde = $mainMod SHIFT, right, resizeactive,50 0 -binde = $mainMod SHIFT, up, resizeactive,0 -50 -binde = $mainMod SHIFT, down, resizeactive,0 50 +binded = $mainMod SHIFT, left, resize left (-50), resizeactive, -50 0 +binded = $mainMod SHIFT, right, resize right (+50), resizeactive, 50 0 +binded = $mainMod SHIFT, up, resize up (-50), resizeactive, 0 -50 +binded = $mainMod SHIFT, down, resize down (+50), resizeactive, 0 50 # Move windows -bind = $mainMod CTRL, left, movewindow, l -bind = $mainMod CTRL, right, movewindow, r -bind = $mainMod CTRL, up, movewindow, u -bind = $mainMod CTRL, down, movewindow, d +bindd = $mainMod CTRL, left, move window left, movewindow, l +bindd = $mainMod CTRL, right, move window right, movewindow, r +bindd = $mainMod CTRL, up, move window up, movewindow, u +bindd = $mainMod CTRL, down, move window down, movewindow, d # Swap windows -bind = $mainMod ALT, left, swapwindow, l -bind = $mainMod ALT, right, swapwindow, r -bind = $mainMod ALT, up, swapwindow, u -bind = $mainMod ALT, down, swapwindow, d +bindd = $mainMod ALT, left, swap window left, swapwindow, l +bindd = $mainMod ALT, right, swap window right, swapwindow, r +bindd = $mainMod ALT, up, swap window up, swapwindow, u +bindd = $mainMod ALT, down, swap window down, swapwindow, d # Move focus with mainMod + arrow keys -bind = $mainMod, left, movefocus, l -bind = $mainMod, right, movefocus, r -bind = $mainMod, up, movefocus, u -bind = $mainMod, down, movefocus, d +bindd = $mainMod, left, focus left, movefocus, l +bindd = $mainMod, right, focus right, movefocus, r +bindd = $mainMod, up, focus up, movefocus, u +bindd = $mainMod, down, focus down, movefocus, d # Workspaces related -bind = $mainMod, tab, workspace, m+1 -bind = $mainMod SHIFT, tab, workspace, m-1 +bindd = $mainMod, tab, next workspace, workspace, m+1 +bindd = $mainMod SHIFT, tab, previous workspace, workspace, m-1 # Special workspace -bind = $mainMod SHIFT, U, movetoworkspace, special -bind = $mainMod, U, togglespecialworkspace, +bindd = $mainMod SHIFT, U, move to special workspace, movetoworkspace, special +bindd = $mainMod, U, toggle special workspace, togglespecialworkspace, # The following mappings use the key codes to better support various keyboard layouts # 1 is code:10, 2 is code 11, etc # Switch workspaces with mainMod + [0-9] -bind = $mainMod, code:10, workspace, 1 # NOTE: code:10 = key 1 -bind = $mainMod, code:11, workspace, 2 # NOTE: code:11 = key 2 -bind = $mainMod, code:12, workspace, 3 # NOTE: code:12 = key 3 -bind = $mainMod, code:13, workspace, 4 # NOTE: code:13 = key 4 -bind = $mainMod, code:14, workspace, 5 # NOTE: code:14 = key 5 -bind = $mainMod, code:15, workspace, 6 # NOTE: code:15 = key 6 -bind = $mainMod, code:16, workspace, 7 # NOTE: code:16 = key 7 -bind = $mainMod, code:17, workspace, 8 # NOTE: code:17 = key 8 -bind = $mainMod, code:18, workspace, 9 # NOTE: code:18 = key 9 -bind = $mainMod, code:19, workspace, 10 # NOTE: code:19 = key 0 +bindd = $mainMod, code:10, workspace 1, workspace, 1 # NOTE: code:10 = key 1 +bindd = $mainMod, code:11, workspace 2, workspace, 2 # NOTE: code:11 = key 2 +bindd = $mainMod, code:12, workspace 3, workspace, 3 # NOTE: code:12 = key 3 +bindd = $mainMod, code:13, workspace 4, workspace, 4 # NOTE: code:13 = key 4 +bindd = $mainMod, code:14, workspace 5, workspace, 5 # NOTE: code:14 = key 5 +bindd = $mainMod, code:15, workspace 6, workspace, 6 # NOTE: code:15 = key 6 +bindd = $mainMod, code:16, workspace 7, workspace, 7 # NOTE: code:16 = key 7 +bindd = $mainMod, code:17, workspace 8, workspace, 8 # NOTE: code:17 = key 8 +bindd = $mainMod, code:18, workspace 9, workspace, 9 # NOTE: code:18 = key 9 +bindd = $mainMod, code:19, workspace 10, workspace, 10 # NOTE: code:19 = key 0 # Move active window and follow to workspace mainMod + SHIFT [0-9] -bind = $mainMod SHIFT, code:10, movetoworkspace, 1 # NOTE: code:10 = key 1 -bind = $mainMod SHIFT, code:11, movetoworkspace, 2 # NOTE: code:11 = key 2 -bind = $mainMod SHIFT, code:12, movetoworkspace, 3 # NOTE: code:12 = key 3 -bind = $mainMod SHIFT, code:13, movetoworkspace, 4 # NOTE: code:13 = key 4 -bind = $mainMod SHIFT, code:14, movetoworkspace, 5 # NOTE: code:14 = key 5 -bind = $mainMod SHIFT, code:15, movetoworkspace, 6 # NOTE: code:15 = key 6 -bind = $mainMod SHIFT, code:16, movetoworkspace, 7 # NOTE: code:16 = key 7 -bind = $mainMod SHIFT, code:17, movetoworkspace, 8 # NOTE: code:17 = key 8 -bind = $mainMod SHIFT, code:18, movetoworkspace, 9 # NOTE: code:18 = key 9 -bind = $mainMod SHIFT, code:19, movetoworkspace, 10 # NOTE: code:19 = key 0 -bind = $mainMod SHIFT, bracketleft, movetoworkspace, -1 # brackets [ -bind = $mainMod SHIFT, bracketright, movetoworkspace, +1 # brackets ] +bindd = $mainMod SHIFT, code:10, move to workspace 1, movetoworkspace, 1 # NOTE: code:10 = key 1 +bindd = $mainMod SHIFT, code:11, move to workspace 2, movetoworkspace, 2 # NOTE: code:11 = key 2 +bindd = $mainMod SHIFT, code:12, move to workspace 3, movetoworkspace, 3 # NOTE: code:12 = key 3 +bindd = $mainMod SHIFT, code:13, move to workspace 4, movetoworkspace, 4 # NOTE: code:13 = key 4 +bindd = $mainMod SHIFT, code:14, move to workspace 5, movetoworkspace, 5 # NOTE: code:14 = key 5 +bindd = $mainMod SHIFT, code:15, move to workspace 6, movetoworkspace, 6 # NOTE: code:15 = key 6 +bindd = $mainMod SHIFT, code:16, move to workspace 7, movetoworkspace, 7 # NOTE: code:16 = key 7 +bindd = $mainMod SHIFT, code:17, move to workspace 8, movetoworkspace, 8 # NOTE: code:17 = key 8 +bindd = $mainMod SHIFT, code:18, move to workspace 9, movetoworkspace, 9 # NOTE: code:18 = key 9 +bindd = $mainMod SHIFT, code:19, move to workspace 10, movetoworkspace, 10 # NOTE: code:19 = key 0 +bindd = $mainMod SHIFT, bracketleft, move to previous workspace, movetoworkspace, -1 # brackets [ +bindd = $mainMod SHIFT, bracketright, move to next workspace, movetoworkspace, +1 # brackets ] # Move active window to a workspace silently mainMod + CTRL [0-9] -bind = $mainMod CTRL, code:10, movetoworkspacesilent, 1 # NOTE: code:10 = key 1 -bind = $mainMod CTRL, code:11, movetoworkspacesilent, 2 # NOTE: code:11 = key 2 -bind = $mainMod CTRL, code:12, movetoworkspacesilent, 3 # NOTE: code:12 = key 3 -bind = $mainMod CTRL, code:13, movetoworkspacesilent, 4 # NOTE: code:13 = key 4 -bind = $mainMod CTRL, code:14, movetoworkspacesilent, 5 # NOTE: code:14 = key 5 -bind = $mainMod CTRL, code:15, movetoworkspacesilent, 6 # NOTE: code:15 = key 6 -bind = $mainMod CTRL, code:16, movetoworkspacesilent, 7 # NOTE: code:16 = key 7 -bind = $mainMod CTRL, code:17, movetoworkspacesilent, 8 # NOTE: code:17 = key 8 -bind = $mainMod CTRL, code:18, movetoworkspacesilent, 9 # NOTE: code:18 = key 9 -bind = $mainMod CTRL, code:19, movetoworkspacesilent, 10 # NOTE: code:19 = key 0 -bind = $mainMod CTRL, bracketleft, movetoworkspacesilent, -1 # brackets [ -bind = $mainMod CTRL, bracketright, movetoworkspacesilent, +1 # brackets ] +bindd = $mainMod CTRL, code:10, move silently to workspace 1, movetoworkspacesilent, 1 # NOTE: code:10 = key 1 +bindd = $mainMod CTRL, code:11, move silently to workspace 2, movetoworkspacesilent, 2 # NOTE: code:11 = key 2 +bindd = $mainMod CTRL, code:12, move silently to workspace 3, movetoworkspacesilent, 3 # NOTE: code:12 = key 3 +bindd = $mainMod CTRL, code:13, move silently to workspace 4, movetoworkspacesilent, 4 # NOTE: code:13 = key 4 +bindd = $mainMod CTRL, code:14, move silently to workspace 5, movetoworkspacesilent, 5 # NOTE: code:14 = key 5 +bindd = $mainMod CTRL, code:15, move silently to workspace 6, movetoworkspacesilent, 6 # NOTE: code:15 = key 6 +bindd = $mainMod CTRL, code:16, move silently to workspace 7, movetoworkspacesilent, 7 # NOTE: code:16 = key 7 +bindd = $mainMod CTRL, code:17, move silently to workspace 8, movetoworkspacesilent, 8 # NOTE: code:17 = key 8 +bindd = $mainMod CTRL, code:18, move silently to workspace 9, movetoworkspacesilent, 9 # NOTE: code:18 = key 9 +bindd = $mainMod CTRL, code:19, move silently to workspace 10, movetoworkspacesilent, 10 # NOTE: code:19 = key 0 +bindd = $mainMod CTRL, bracketleft, move silently to previous workspace, movetoworkspacesilent, -1 # brackets [ +bindd = $mainMod CTRL, bracketright, move silently to next workspace, movetoworkspacesilent, +1 # brackets ] # Scroll through existing workspaces with mainMod + scroll -bind = $mainMod, mouse_down, workspace, e+1 -bind = $mainMod, mouse_up, workspace, e-1 -bind = $mainMod, period, workspace, e+1 -bind = $mainMod, comma, workspace, e-1 +bindd = $mainMod, mouse_down, next workspace, workspace, e+1 +bindd = $mainMod, mouse_up, previous workspace, workspace, e-1 +bindd = $mainMod, period, next workspace, workspace, e+1 +bindd = $mainMod, comma, previous workspace, workspace, e-1 # Move/resize windows with mainMod + LMB/RMB and dragging -bindm = $mainMod, mouse:272, movewindow # NOTE: mouse:272 = left click -bindm = $mainMod, mouse:273, resizewindow # NOTE: mouse:272 = right click \ No newline at end of file +bindmd = $mainMod, mouse:272, move window, movewindow # NOTE: mouse:272 = left click +bindmd = $mainMod, mouse:273, resize window, resizewindow # NOTE: mouse:272 = right click diff --git a/config/hypr/scripts/KeyBinds.sh b/config/hypr/scripts/KeyBinds.sh index 3a19390f..46953cc5 100755 --- a/config/hypr/scripts/KeyBinds.sh +++ b/config/hypr/scripts/KeyBinds.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## -# searchable enabled keybinds using rofi +# searchable enabled keybinds using rofi (supports bindd descriptions) # kill yad to not interfere with this binds pkill yad || true @@ -17,23 +17,66 @@ laptop_conf="$HOME/.config/hypr/UserConfigs/Laptops.conf" rofi_theme="$HOME/.config/rofi/config-keybinds.rasi" msg='โ˜ฃ๏ธ NOTE โ˜ฃ๏ธ: Clicking with Mouse or Pressing ENTER will have NO function' -# combine the contents of the keybinds files and filter for keybinds -keybinds=$(cat "$keybinds_conf" "$user_keybinds_conf" | grep -E '^bind') +# collect raw bind lines (strip end-of-line comments) from available files +files=("$keybinds_conf" "$user_keybinds_conf") +[[ -f "$laptop_conf" ]] && files+=("$laptop_conf") -# check if laptop.conf exists and add its keybinds if present -if [[ -f "$laptop_conf" ]]; then - laptop_binds=$(grep -E '^bind' "$laptop_conf") - keybinds+=$'\n'"$laptop_binds" -fi +raw_keybinds=$(cat "${files[@]}" 2>/dev/null \ + | grep -E '^[[:space:]]*bind' \ + | sed -E 's/[[:space:]]+#.*$//') # check for any keybinds to display -if [[ -z "$keybinds" ]]; then +if [[ -z "$raw_keybinds" ]]; then echo "no keybinds found." exit 1 fi -# replace $mainmod with super in the displayed keybinds for rofi -display_keybinds=$(echo "$keybinds" | sed 's/\$mainMod/SUPER/g') +# transform into a readable list: MODS+KEY โ€” DESCRIPTION โ€” DISPATCHER [PARAMS] +display_keybinds=$(echo "$raw_keybinds" | awk -F'=' ' + function trim(s){ gsub(/^[ \t]+|[ \t]+$/,"",s); return s } + /^[[:space:]]*bind/ { + binder=$1; gsub(/[ \t]/, "", binder); + hasdesc = (index(binder, "d")>0); + + rhs=$2; rhs=trim(rhs); + n=split(rhs, a, /[ \t]*,[ \t]*/); + + mods=trim(a[1]); key=(n>=2?trim(a[2]):""); + desc=""; dispatcher=""; params=""; + + if (hasdesc) { + desc=(n>=3?trim(a[3]):""); + dispatcher=(n>=4?trim(a[4]):""); + start=5; + } else { + dispatcher=(n>=3?trim(a[3]):""); + start=4; + } + + for(i=start;i<=n;i++){ if(length(a[i])){ p=trim(a[i]); if(p!="") params = (params?params", ":"") p } } + + gsub(/\$mainMod/,"SUPER",mods); + gsub(/[ \t]+/,"+",mods); + + combo = (mods && key) ? mods "+" key : (key?key:mods); + + if (desc != "") { + if (dispatcher != "" && params != "") + print combo, " โ€” ", desc, " โ€” ", dispatcher, " ", params; + else if (dispatcher != "") + print combo, " โ€” ", desc, " โ€” ", dispatcher; + else + print combo, " โ€” ", desc; + } else { + if (dispatcher != "" && params != "") + print combo, " โ€” ", dispatcher, " ", params; + else if (dispatcher != "") + print combo, " โ€” ", dispatcher; + else + print combo; + } + } +') -# use rofi to display the keybinds with the modified content -echo "$display_keybinds" | rofi -dmenu -i -config "$rofi_theme" -mesg "$msg" \ No newline at end of file +# use rofi to display the keybinds +printf '%s\n' "$display_keybinds" | rofi -dmenu -i -config "$rofi_theme" -mesg "$msg" -- cgit v1.2.3 From f26ef7141a88801b62702df5f2c78b4915111e29 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 30 Oct 2025 22:46:07 -0400 Subject: Small decription changes On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/UserConfigs/UserKeybinds.conf modified: config/hypr/configs/Keybinds.conf --- config/hypr/UserConfigs/UserKeybinds.conf | 16 ++++++++-------- config/hypr/configs/Keybinds.conf | 4 ++-- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/config/hypr/UserConfigs/UserKeybinds.conf b/config/hypr/UserConfigs/UserKeybinds.conf index 5b257b33..4bebe342 100644 --- a/config/hypr/UserConfigs/UserKeybinds.conf +++ b/config/hypr/UserConfigs/UserKeybinds.conf @@ -18,9 +18,9 @@ source= $UserConfigs/01-UserDefaults.conf #bindr = $mainMod, $mainMod_L, exec, pkill rofi || rofi -show drun -modi drun,filebrowser,run,window # Super Key to Launch rofi menu bindd = $mainMod, D, app launcher, exec, pkill rofi || true && rofi -show drun -modi drun,filebrowser,run,window bindd = $mainMod, B, open default browser, exec, xdg-open "https://" -#bind = $mainMod, A, exec, pkill rofi || true && ags -t 'overview' # desktop overview (if installed) -#bind = $mainMod, A, global, quickshell:overviewToggle # desktop overview (if installed) -bindd = $mainMod, Return, terminal, exec, $term +#bindd = $mainMod, A, ags overview, exec, pkill rofi || true && ags -t 'overview' # desktop overview (if installed) +#bindd = $mainMod, A, Quickshell overview, global, quickshell:overviewToggle # desktop overview (if installed) +bindd = $mainMod, Return, Open terminal, exec, $term bindd = $mainMod, E, file manager, exec, $files @@ -38,10 +38,10 @@ bindd = $mainMod CTRL, R, rofi theme selector, exec, $scriptsDir/RofiThemeSelect bindd = $mainMod CTRL SHIFT, R, rofi theme selector (modified), exec, pkill rofi || true && $scriptsDir/RofiThemeSelector-modified.sh bindd = $mainMod SHIFT, F, fullscreen, fullscreen -bindd = $mainMod CTRL, F, fake fullscreen, fullscreen, 1 -bindd = $mainMod, SPACE, toggle floating, togglefloating, -bindd = $mainMod ALT, SPACE, all float mode, exec, hyprctl dispatch workspaceopt allfloat -bindd = $mainMod SHIFT, Return, dropdown terminal, exec, $scriptsDir/Dropterminal.sh $term +bindd = $mainMod CTRL, F, maximize window, fullscreen, 1 +bindd = $mainMod, SPACE, Float current window, togglefloating, +bindd = $mainMod ALT, SPACE, Float all windows, exec, hyprctl dispatch workspaceopt allfloat +bindd = $mainMod SHIFT, Return, DropDown terminal, exec, $scriptsDir/Dropterminal.sh $term # Desktop zooming or magnifier bindd = $mainMod ALT, mouse_down, zoom in, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor * 2.0}')" @@ -52,7 +52,7 @@ bindd = $mainMod ALT, mouse_up, zoom out, exec, hyprctl keyword cursor:zoom_fact #bind = $mainMod ALT, mouse_up, exec, hyprctl keyword misc:cursor_zoom_factor "$(hyprctl getoption misc:cursor_zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor / 2.0}')" # Waybar / Bar related -bindd = $mainMod CTRL ALT, B, toggle waybar, exec, pkill -SIGUSR1 waybar +bindd = $mainMod CTRL ALT, B, toggle waybar on/off, exec, pkill -SIGUSR1 waybar bindd = $mainMod CTRL, B, waybar styles menu, exec, $scriptsDir/WaybarStyles.sh bindd = $mainMod ALT, B, waybar layout menu, exec, $scriptsDir/WaybarLayout.sh diff --git a/config/hypr/configs/Keybinds.conf b/config/hypr/configs/Keybinds.conf index 0fa250b7..ebaee30a 100644 --- a/config/hypr/configs/Keybinds.conf +++ b/config/hypr/configs/Keybinds.conf @@ -10,11 +10,11 @@ $UserScripts = $HOME/.config/hypr/UserScripts bindd = CTRL ALT, Delete, exit Hyprland, exec, hyprctl dispatch exit 0 bindd = $mainMod, Q, close active window, killactive, -bindd = $mainMod SHIFT, Q, kill active process, exec, $scriptsDir/KillActiveProcess.sh +bindd = $mainMod SHIFT, Q, Terminate active process, exec, $scriptsDir/KillActiveProcess.sh bindd = CTRL ALT, L, lock screen, exec, $scriptsDir/LockScreen.sh bindd = CTRL ALT, P, powermenu, exec, $scriptsDir/Wlogout.sh bindd = $mainMod SHIFT, N, notification panel, exec, swaync-client -t -sw -bindd = $mainMod SHIFT, E, settings menu, exec, $scriptsDir/Kool_Quick_Settings.sh +bindd = $mainMod SHIFT, E, Quick settings menu, exec, $scriptsDir/Kool_Quick_Settings.sh # Master Layout bindd = $mainMod CTRL, D, remove master, layoutmsg, removemaster -- cgit v1.2.3 From 4687cfc8c6786ebaae169e19219f1cf9f3be982d Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 31 Oct 2025 19:22:24 -0400 Subject: SWWW v0.11.2 uses swww-daemon --format argb now Changed the flag for updated SWWW On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/UserConfigs/Startup_Apps.conf --- config/hypr/UserConfigs/Startup_Apps.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf index 2f5c7ae7..4f4fbd22 100644 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ b/config/hypr/UserConfigs/Startup_Apps.conf @@ -10,7 +10,8 @@ $SwwwRandom = $UserScripts/WallpaperAutoChange.sh $livewallpaper="" # wallpaper stuff -exec-once = swww-daemon --format xrgb +exec-once = swww-daemon --format argb # New flag for v0.11.2 +#exec-once = swww-daemon --format xrgb # old 0.9.5 option #exec-once = mpvpaper '*' -o "load-scripts=no no-audio --loop" $livewallpaper # wallpaper random -- cgit v1.2.3 From 7441f2cb05b6916ff7cb08a8c0f14b7ff865a1b1 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Sun, 2 Nov 2025 17:23:53 -0500 Subject: feat: Add smart AGS/Quickshell fallback with OverviewToggle wrapper Implements a robust fallback mechanism for desktop overview functionality that handles both AGS and Quickshell installations gracefully. Changes: - Add OverviewToggle.sh wrapper script that tries Quickshell first, falls back to AGS if unavailable or broken - Update UserKeybinds.conf with new SUPER+A binding to OverviewToggle.sh - Preserve original AGS and Quickshell keybinds as commented references - Simplify copy.sh logic to enable both AGS and QS simultaneously - Remove conflicting keybind toggle logic from copy.sh Benefits: - Users can have both AGS and Quickshell installed simultaneously - Automatic fallback when one tool is broken or unavailable - Quickshell preferred (tried first) as it's more performant - Graceful degradation with user notification if neither available - Auto-starts AGS if installed but not running - Compatible with existing upgrade.sh and ComposeHyprConfigs.sh workflow Technical details: - OverviewToggle.sh checks for running processes before attempting toggle - Uses hyprctl dispatch for Quickshell's global dispatcher - Falls back to ags -t 'overview' with rofi cleanup for AGS - Shows desktop notification if neither tool is available - Script auto-made executable via existing chmod in copy.sh (line 1027) Addresses: Issue where AGS and Quickshell have had recent stability problems, requiring manual keybind switching between them --- config/hypr/UserConfigs/UserKeybinds.conf | 1 + config/hypr/scripts/OverviewToggle.sh | 28 ++++++++++++++++++++++++++++ copy.sh | 21 +++++++-------------- 3 files changed, 36 insertions(+), 14 deletions(-) create mode 100644 config/hypr/scripts/OverviewToggle.sh diff --git a/config/hypr/UserConfigs/UserKeybinds.conf b/config/hypr/UserConfigs/UserKeybinds.conf index 4bebe342..17711559 100644 --- a/config/hypr/UserConfigs/UserKeybinds.conf +++ b/config/hypr/UserConfigs/UserKeybinds.conf @@ -18,6 +18,7 @@ source= $UserConfigs/01-UserDefaults.conf #bindr = $mainMod, $mainMod_L, exec, pkill rofi || rofi -show drun -modi drun,filebrowser,run,window # Super Key to Launch rofi menu bindd = $mainMod, D, app launcher, exec, pkill rofi || true && rofi -show drun -modi drun,filebrowser,run,window bindd = $mainMod, B, open default browser, exec, xdg-open "https://" +bindd = $mainMod, A, desktop overview, exec, $scriptsDir/OverviewToggle.sh # toggles quickshell or ags overview (tries QS first, falls back to AGS) #bindd = $mainMod, A, ags overview, exec, pkill rofi || true && ags -t 'overview' # desktop overview (if installed) #bindd = $mainMod, A, Quickshell overview, global, quickshell:overviewToggle # desktop overview (if installed) bindd = $mainMod, Return, Open terminal, exec, $term diff --git a/config/hypr/scripts/OverviewToggle.sh b/config/hypr/scripts/OverviewToggle.sh new file mode 100644 index 00000000..18683984 --- /dev/null +++ b/config/hypr/scripts/OverviewToggle.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # +# Overview toggle wrapper - tries quickshell first, falls back to AGS + +# Try quickshell first if installed +if command -v qs >/dev/null 2>&1; then + # Check if quickshell is running + if pgrep -x qs >/dev/null 2>&1; then + # Try to toggle quickshell overview + hyprctl dispatch global quickshell:overviewToggle 2>/dev/null && exit 0 + fi +fi + +# Fall back to AGS if quickshell failed or isn't available +if command -v ags >/dev/null 2>&1; then + # Check if AGS is running, start it if not + if ! pgrep -x ags >/dev/null 2>&1; then + ags & + sleep 0.5 + fi + # Toggle AGS overview + pkill rofi || true + ags -t 'overview' 2>/dev/null && exit 0 +fi + +# If we get here, neither worked +notify-send "Overview" "Neither Quickshell nor AGS is available" -u low 2>/dev/null || true +exit 1 diff --git a/copy.sh b/copy.sh index 762af601..b4e958a9 100755 --- a/copy.sh +++ b/copy.sh @@ -259,38 +259,31 @@ if command -v blueman-applet >/dev/null 2>&1; then grep -qx 'exec-once = blueman-applet' "$OVERLAY_SA" || echo 'exec-once = blueman-applet' >>"$OVERLAY_SA" fi -# Check if ags is installed edit ags behaviour on configs +# Check if ags is installed and enable it if command -v ags >/dev/null 2>&1; then + echo "${INFO} AGS detected - enabling in startup and refresh scripts" 2>&1 | tee -a "$LOG" OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" mkdir -p "$(dirname "$OVERLAY_SA")" touch "$OVERLAY_SA" grep -qx 'exec-once = ags' "$OVERLAY_SA" || echo 'exec-once = ags' >>"$OVERLAY_SA" 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 - - # 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 +# Check if quickshell is installed and enable it if command -v qs >/dev/null 2>&1; then + echo "${INFO} Quickshell detected - enabling in startup and refresh scripts" 2>&1 | tee -a "$LOG" OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" mkdir -p "$(dirname "$OVERLAY_SA")" touch "$OVERLAY_SA" grep -qx 'exec-once = qs' "$OVERLAY_SA" || echo 'exec-once = qs' >>"$OVERLAY_SA" 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 - - # 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 +# Note: The SUPER+A keybind now uses OverviewToggle.sh which automatically +# tries quickshell first and falls back to AGS, so both can be installed + printf "\n%.0s" {1..1} # Checking if neovim or vim is installed and offer user if they want to make as default editor -- cgit v1.2.3 From c97e7c0e636ab0f1cd053c3228fa4b8f3c0cd388 Mon Sep 17 00:00:00 2001 From: Alberson Miranda Date: Sun, 2 Nov 2025 21:19:10 -0300 Subject: hotfix: remove hypersunset from status group. --- config/waybar/ModulesGroups | 2 -- 1 file changed, 2 deletions(-) diff --git a/config/waybar/ModulesGroups b/config/waybar/ModulesGroups index 8d4453a2..30e47f16 100644 --- a/config/waybar/ModulesGroups +++ b/config/waybar/ModulesGroups @@ -89,7 +89,6 @@ }, "modules": [ "custom/power", - "custom/nightlight", "custom/lock", "keyboard-state", "custom/keyboard", @@ -132,7 +131,6 @@ }, "modules": [ "custom/power", - "custom/nightlight", "custom/lock", "custom/logout", "custom/reboot" -- cgit v1.2.3 From f992b375bfaf76e82df939ac16502755984db53e Mon Sep 17 00:00:00 2001 From: Don Williams Date: Mon, 3 Nov 2025 22:27:24 -0500 Subject: scripts is config/hypr/scripts weren't executable On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: scripts/Battery.sh modified: scripts/ComposeHyprConfigs.sh modified: scripts/OverviewToggle.sh modified: scripts/sddm_wallpaper.sh --- config/hypr/scripts/Battery.sh | 0 config/hypr/scripts/ComposeHyprConfigs.sh | 0 config/hypr/scripts/OverviewToggle.sh | 37 +++++++++++++++++++------------ config/hypr/scripts/sddm_wallpaper.sh | 0 4 files changed, 23 insertions(+), 14 deletions(-) mode change 100644 => 100755 config/hypr/scripts/Battery.sh mode change 100644 => 100755 config/hypr/scripts/ComposeHyprConfigs.sh mode change 100644 => 100755 config/hypr/scripts/OverviewToggle.sh mode change 100644 => 100755 config/hypr/scripts/sddm_wallpaper.sh diff --git a/config/hypr/scripts/Battery.sh b/config/hypr/scripts/Battery.sh old mode 100644 new mode 100755 diff --git a/config/hypr/scripts/ComposeHyprConfigs.sh b/config/hypr/scripts/ComposeHyprConfigs.sh old mode 100644 new mode 100755 diff --git a/config/hypr/scripts/OverviewToggle.sh b/config/hypr/scripts/OverviewToggle.sh old mode 100644 new mode 100755 index 18683984..21c2da34 --- a/config/hypr/scripts/OverviewToggle.sh +++ b/config/hypr/scripts/OverviewToggle.sh @@ -1,26 +1,35 @@ #!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # -# Overview toggle wrapper - tries quickshell first, falls back to AGS +# Overview toggle wrapper - tries Quickshell first, falls back to AGS -# Try quickshell first if installed +set -euo pipefail + +# 1) Try Quickshell via Hyprland global dispatch (works if QS is running and listening) +if hyprctl dispatch global quickshell:overviewToggle >/dev/null 2>&1; then + exit 0 +fi + +# If QS isn't running, try starting it and retry once if command -v qs >/dev/null 2>&1; then - # Check if quickshell is running - if pgrep -x qs >/dev/null 2>&1; then - # Try to toggle quickshell overview - hyprctl dispatch global quickshell:overviewToggle 2>/dev/null && exit 0 + qs >/dev/null 2>&1 & + sleep 0.6 + if hyprctl dispatch global quickshell:overviewToggle >/dev/null 2>&1; then + exit 0 fi fi -# Fall back to AGS if quickshell failed or isn't available +# 2) Fall back to AGS template if command -v ags >/dev/null 2>&1; then - # Check if AGS is running, start it if not - if ! pgrep -x ags >/dev/null 2>&1; then - ags & - sleep 0.5 - fi - # Toggle AGS overview pkill rofi || true - ags -t 'overview' 2>/dev/null && exit 0 + if ags -t 'overview' >/dev/null 2>&1; then + exit 0 + fi + # If it failed, try starting AGS daemon then call the template + ags >/dev/null 2>&1 & + sleep 0.6 + if ags -t 'overview' >/dev/null 2>&1; then + exit 0 + fi fi # If we get here, neither worked diff --git a/config/hypr/scripts/sddm_wallpaper.sh b/config/hypr/scripts/sddm_wallpaper.sh old mode 100644 new mode 100755 -- cgit v1.2.3 From c9c54016a8675448eba7accdea9978f8d780725c Mon Sep 17 00:00:00 2001 From: mio-dokuhaki Date: Wed, 5 Nov 2025 02:24:25 +0900 Subject: feat(rofi): merge RofiBeats dynamic music system into development --- config/hypr/UserScripts/RofiBeats.sh | 205 ++++++++++++++++------------------- config/rofi/online_music.list | 17 +++ 2 files changed, 111 insertions(+), 111 deletions(-) create mode 100644 config/rofi/online_music.list diff --git a/config/hypr/UserScripts/RofiBeats.sh b/config/hypr/UserScripts/RofiBeats.sh index ca566019..adb5aa2c 100755 --- a/config/hypr/UserScripts/RofiBeats.sh +++ b/config/hypr/UserScripts/RofiBeats.sh @@ -1,35 +1,39 @@ -#!/usr/bin/env bash +#!/bin/bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## -# For Rofi Beats to play online Music or Locally saved media files +# RofiBeats - unified, dynamic UI (add, remove, manage, play) -# Variables mDIR="$HOME/Music/" iDIR="$HOME/.config/swaync/icons" rofi_theme="$HOME/.config/rofi/config-rofi-Beats.rasi" -rofi_theme_1="$HOME/.config/rofi/config-rofi-Beats-menu.rasi" +rofi_theme_menu="$HOME/.config/rofi/config-rofi-Beats-menu.rasi" +music_list="$HOME/.config/rofi/online_music.list" -# Online Stations. Edit as required -declare -A online_music=( - ["FM - Easy Rock 96.3 ๐Ÿ“ป๐ŸŽถ"]="https://radio-stations-philippines.com/easy-rock" - ["FM - Easy Rock - Baguio 91.9 ๐Ÿ“ป๐ŸŽถ"]="https://radio-stations-philippines.com/easy-rock-baguio" - ["FM - Love Radio 90.7 ๐Ÿ“ป๐ŸŽถ"]="https://radio-stations-philippines.com/love" - ["FM - WRock - CEBU 96.3 ๐Ÿ“ป๐ŸŽถ"]="https://onlineradio.ph/126-96-3-wrock.html" - ["FM - Fresh Philippines ๐Ÿ“ป๐ŸŽถ"]="https://onlineradio.ph/553-fresh-fm.html" - ["Radio - Lofi Girl ๐ŸŽง๐ŸŽถ"]="https://play.streamafrica.net/lofiradio" - ["Radio - Chillhop ๐ŸŽง๐ŸŽถ"]="http://stream.zeno.fm/fyn8eh3h5f8uv" - ["Radio - Ibiza Global ๐ŸŽง๐ŸŽถ"]="https://filtermusic.net/ibiza-global" - ["Radio - Metal Music ๐ŸŽง๐ŸŽถ"]="https://tunein.com/radio/mETaLmuSicRaDio-s119867/" - ["YT - Wish 107.5 YT Pinoy HipHop ๐Ÿ“ป๐ŸŽถ"]="https://youtube.com/playlist?list=PLkrzfEDjeYJnmgMYwCKid4XIFqUKBVWEs&si=vahW_noh4UDJ5d37" - ["YT - Youtube Top 100 Songs Global ๐Ÿ“น๐ŸŽถ"]="https://youtube.com/playlist?list=PL4fGSI1pDJn6puJdseH2Rt9sMvt9E2M4i&si=5jsyfqcoUXBCSLeu" - ["YT - Wish 107.5 YT Wishclusives ๐Ÿ“น๐ŸŽถ"]="https://youtube.com/playlist?list=PLkrzfEDjeYJn5B22H9HOWP3Kxxs-DkPSM&si=d_Ld2OKhGvpH48WO" - ["YT - Relaxing Piano Music ๐ŸŽน๐ŸŽถ"]="https://youtu.be/6H7hXzjFoVU?si=nZTPREC9lnK1JJUG" - ["YT - Youtube Remix ๐Ÿ“น๐ŸŽถ"]="https://youtube.com/playlist?list=PLeqTkIUlrZXlSNn3tcXAa-zbo95j0iN-0" - ["YT - Korean Drama OST ๐Ÿ“น๐ŸŽถ"]="https://youtube.com/playlist?list=PLUge_o9AIFp4HuA-A3e3ZqENh63LuRRlQ" - ["YT - lofi hip hop radio beats ๐Ÿ“น๐ŸŽถ"]="https://www.youtube.com/live/jfKfPfyJRdk?si=PnJIA9ErQIAw6-qd" - ["YT - Relaxing Piano Jazz Music ๐ŸŽน๐ŸŽถ"]="https://youtu.be/85UEqRat6E4?si=jXQL1Yp2VP_G6NSn" -) +mkdir -p "$(dirname "$music_list")" +[[ -f "$music_list" ]] || touch "$music_list" -# Populate local_music array with files from music directory and subdirectories +# Send notification +notification() { + notify-send -u normal -i "$iDIR/music.png" "$@" +} + +# Check if mpv is currently playing +music_playing() { pgrep -x "mpv" >/dev/null; } + +# Stop all mpv processes except mpvpaper +stop_music() { + mpv_pids=$(pgrep -x mpv) + if [ -n "$mpv_pids" ]; then + mpvpaper_pid=$(ps aux | grep -- 'unique-wallpaper-process' | grep -v 'grep' | awk '{print $2}') + for pid in $mpv_pids; do + if ! echo "$mpvpaper_pid" | grep -q "$pid"; then + kill -9 $pid || true + fi + done + notification "Music stopped" + fi +} + +# Populate local music file list populate_local_music() { local_music=() filenames=() @@ -39,115 +43,94 @@ populate_local_music() { done < <(find -L "$mDIR" -type f \( -iname "*.mp3" -o -iname "*.flac" -o -iname "*.wav" -o -iname "*.ogg" -o -iname "*.mp4" \)) } -# Function for displaying notifications -notification() { - notify-send -u normal -i "$iDIR/music.png" "Now Playing:" "$@" -} - -# Main function for playing local music +# Play selected local music file play_local_music() { populate_local_music - - # Prompt the user to select a song - choice=$(printf "%s\n" "${filenames[@]}" | rofi -i -dmenu -config $rofi_theme) - - if [ -z "$choice" ]; then - exit 1 - fi - - # Find the corresponding file path based on user's choice and set that to play the song then continue on the list - for (( i=0; i<"${#filenames[@]}"; ++i )); do + choice=$(printf "%s\n" "${filenames[@]}" | rofi -i -dmenu -config "$rofi_theme" \ + -theme-str 'entry { placeholder: "๐ŸŽต Choose Local Music"; }') + [[ -z "$choice" ]] && exit 1 + for ((i = 0; i < "${#filenames[@]}"; ++i)); do if [ "${filenames[$i]}" = "$choice" ]; then - - if music_playing; then - stop_music - fi - notification "$choice" - mpv --playlist-start="$i" --loop-playlist --vid=no "${local_music[@]}" - + music_playing && stop_music + notification "Now Playing:" "$choice" + mpv --no-video --playlist-start="$i" --loop-playlist "${local_music[@]}" break fi done } -# Main function for shuffling local music +# Shuffle and play all local music shuffle_local_music() { - if music_playing; then - stop_music - fi + music_playing && stop_music notification "Shuffle Play local music" - - # Play music in $mDIR on shuffle - mpv --shuffle --loop-playlist --vid=no "$mDIR" + mpv --no-video --shuffle --loop-playlist "$mDIR" } -# Main function for playing online music +# Play selected online music play_online_music() { - choice=$(for online in "${!online_music[@]}"; do - echo "$online" - done | sort | rofi -i -dmenu -config "$rofi_theme") - - if [ -z "$choice" ]; then - exit 1 - fi - - link="${online_music[$choice]}" - - if music_playing; then - stop_music + if [ ! -s "$music_list" ]; then + notify-send -u low -i "$iDIR/music.png" "No online music found" "Add some with Manage Music" + exit 0 fi - notification "$choice" - - # Play the selected online music using mpv - mpv --shuffle --vid=no "$link" -} - -# Function to check if music is already playing -music_playing() { - pgrep -x "mpv" > /dev/null + choice=$(awk -F'|' '{print $1}' "$music_list" | sort | rofi -i -dmenu -config "$rofi_theme" \ + -theme-str 'entry { placeholder: "๐ŸŒ Choose Online Station"; }') + [[ -z "$choice" ]] && exit 1 + link=$(awk -F'|' -v name="$choice" '$1 == name {print $2; exit}' "$music_list") + [[ -z "$link" ]] && { + notify-send -u low -i "$iDIR/music.png" "URL not found for" "$choice" + exit 1 + } + music_playing && stop_music + notification "Now Playing:" "$choice" + mpv --no-video --shuffle "$link" } -# Function to stop music and kill mpv processes -stop_music() { - mpv_pids=$(pgrep -x mpv) - - if [ -n "$mpv_pids" ]; then - # Get the PID of the mpv process used by mpvpaper (using the unique argument added) - mpvpaper_pid=$(ps aux | grep -- 'unique-wallpaper-process' | grep -v 'grep' | awk '{print $2}') - - for pid in $mpv_pids; do - if ! echo "$mpvpaper_pid" | grep -q "$pid"; then - kill -9 $pid || true - fi - done - notify-send -u low -i "$iDIR/music.png" "Music stopped" || true - fi +# Manage online music list (add, remove, view) +manage_music() { + sub_choice=$(printf "Add Music\nRemove Music\nView List" | rofi -dmenu \ + -config "$rofi_theme_menu" \ + -theme-str 'entry { placeholder: "๐Ÿ› ๏ธ Manage Music List"; }') + + case "$sub_choice" in + "Add Music") + name=$(rofi -dmenu -lines 0 -config "$rofi_theme_menu" \ + -theme-str 'entry { placeholder: "๐ŸŽผ Enter Music Title"; }') + [[ -z "$name" ]] && return + url=$(rofi -dmenu -lines 0 -config "$rofi_theme_menu" \ + -theme-str 'entry { placeholder: "๐Ÿ”— Enter Music URL"; }') + [[ -z "$url" ]] && return + echo "$name|$url" >>"$music_list" + notification "Added" "$name" + ;; + "Remove Music") + entry=$(awk -F'|' '{print $1}' "$music_list" | rofi -dmenu -config "$rofi_theme_menu" \ + -theme-str 'entry { placeholder: "๐Ÿ—‘๏ธ Select Music to Remove"; }') + [[ -z "$entry" ]] && return + grep -vF "$entry" "$music_list" >"$music_list.tmp" && mv "$music_list.tmp" "$music_list" + notification "Removed" "$entry" + ;; + "View List") + # Show only titles, not URLs + awk -F'|' '{print $1}' "$music_list" | rofi -dmenu -config "$rofi_theme_menu" \ + -theme-str 'entry { placeholder: "๐Ÿ“œ Online Music List"; }' >/dev/null + ;; + esac } +# Main menu user_choice=$(printf "%s\n" \ "Play from Online Stations" \ "Play from Music directory" \ "Shuffle Play from Music directory" \ "Stop RofiBeats" \ - | rofi -dmenu -config $rofi_theme_1) - -echo "User choice: $user_choice" + "Manage Music List" | + rofi -dmenu -config "$rofi_theme_menu" \ + -theme-str 'entry { placeholder: "๐ŸŽง RofiBeats Menu"; }') case "$user_choice" in - "Play from Online Stations") - play_online_music - ;; - "Play from Music directory") - play_local_music - ;; - "Shuffle Play from Music directory") - shuffle_local_music - ;; - "Stop RofiBeats") - if music_playing; then - stop_music - fi - ;; - *) - ;; +"Play from Online Stations") play_online_music ;; +"Play from Music directory") play_local_music ;; +"Shuffle Play from Music directory") shuffle_local_music ;; +"Stop RofiBeats") music_playing && stop_music ;; +"Manage Music List") manage_music ;; esac diff --git a/config/rofi/online_music.list b/config/rofi/online_music.list new file mode 100644 index 00000000..bb21b9d4 --- /dev/null +++ b/config/rofi/online_music.list @@ -0,0 +1,17 @@ +FM - Easy Rock 96.3 ๐Ÿ“ป๐ŸŽถ|https://radio-stations-philippines.com/easy-rock +FM - Easy Rock - Baguio 91.9 ๐Ÿ“ป๐ŸŽถ|https://radio-stations-philippines.com/easy-rock-baguio +FM - Love Radio 90.7 ๐Ÿ“ป๐ŸŽถ|https://radio-stations-philippines.com/love +FM - WRock - CEBU 96.3 ๐Ÿ“ป๐ŸŽถ|https://onlineradio.ph/126-96-3-wrock.html +FM - Fresh Philippines ๐Ÿ“ป๐ŸŽถ|https://onlineradio.ph/553-fresh-fm.html +Radio - Lofi Girl ๐ŸŽง๐ŸŽถ|https://play.streamafrica.net/lofiradio +Radio - Chillhop ๐ŸŽง๐ŸŽถ|http://stream.zeno.fm/fyn8eh3h5f8uv +Radio - Ibiza Global ๐ŸŽง๐ŸŽถ|https://filtermusic.net/ibiza-global +Radio - Metal Music ๐ŸŽง๐ŸŽถ|https://tunein.com/radio/mETaLmuSicRaDio-s119867/ +YT - Wish 107.5 YT Pinoy HipHop ๐Ÿ“ป๐ŸŽถ|https://youtube.com/playlist?list=PLkrzfEDjeYJnmgMYwCKid4XIFqUKBVWEs&si=vahW_noh4UDJ5d37 +YT - Youtube Top 100 Songs Global ๐Ÿ“น๐ŸŽถ|https://youtube.com/playlist?list=PL4fGSI1pDJn6puJdseH2Rt9sMvt9E2M4i&si=5jsyfqcoUXBCSLeu +YT - Wish 107.5 YT Wishclusives ๐Ÿ“น๐ŸŽถ|https://youtube.com/playlist?list=PLkrzfEDjeYJn5B22H9HOWP3Kxxs-DkPSM&si=d_Ld2OKhGvpH48WO +YT - Relaxing Piano Music ๐ŸŽน๐ŸŽถ|https://youtu.be/6H7hXzjFoVU?si=nZTPREC9lnK1JJUG +YT - Youtube Remix ๐Ÿ“น๐ŸŽถ|https://youtube.com/playlist?list=PLeqTkIUlrZXlSNn3tcXAa-zbo95j0iN-0 +YT - Korean Drama OST ๐Ÿ“น๐ŸŽถ|https://youtube.com/playlist?list=PLUge_o9AIFp4HuA-A3e3ZqENh63LuRRlQ +YT - lofi hip hop radio beats ๐Ÿ“น๐ŸŽถ|https://www.youtube.com/live/jfKfPfyJRdk?si=PnJIA9ErQIAw6-qd +YT - Relaxing Piano Jazz Music ๐ŸŽน๐ŸŽถ|https://youtu.be/85UEqRat6E4?si=jXQL1Yp2VP_G6NSn -- cgit v1.2.3 From 073fc0fb287777e39e6b9089a5db7a7cf010f24f Mon Sep 17 00:00:00 2001 From: mio-dokuhaki Date: Wed, 5 Nov 2025 02:43:32 +0900 Subject: fix(rofi): update RofiBeats shebang to /usr/bin/env bash --- config/hypr/UserScripts/RofiBeats.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/UserScripts/RofiBeats.sh b/config/hypr/UserScripts/RofiBeats.sh index adb5aa2c..a002a518 100755 --- a/config/hypr/UserScripts/RofiBeats.sh +++ b/config/hypr/UserScripts/RofiBeats.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # RofiBeats - unified, dynamic UI (add, remove, manage, play) -- cgit v1.2.3 From ebae2be8c6cc37fd6e66baaac18368789ee97851 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 00:50:08 -0500 Subject: feat(hypr): align SUPER+J/K binds to current layout on startup\n\n- Add scripts/KeybindsLayoutInit.sh to set J/K (and O for togglesplit) based on general:layout\n- Wire via Startup_Apps.conf (exec-once) so default dwindle or master both get correct binds\n- Complements scripts/ChangeLayout.sh dynamic rebinds --- config/hypr/configs/Startup_Apps.conf | 1 + config/hypr/scripts/KeybindsLayoutInit.sh | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100755 config/hypr/scripts/KeybindsLayoutInit.sh diff --git a/config/hypr/configs/Startup_Apps.conf b/config/hypr/configs/Startup_Apps.conf index d952e65b..07a92a3f 100644 --- a/config/hypr/configs/Startup_Apps.conf +++ b/config/hypr/configs/Startup_Apps.conf @@ -19,6 +19,7 @@ exec-once = swww-daemon --format xrgb # Startup exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP +exec-once = $scriptsDir/KeybindsLayoutInit.sh # 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 & diff --git a/config/hypr/scripts/KeybindsLayoutInit.sh b/config/hypr/scripts/KeybindsLayoutInit.sh new file mode 100755 index 00000000..7e328cde --- /dev/null +++ b/config/hypr/scripts/KeybindsLayoutInit.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## +# Initialize J/K keybinds to match the current default layout at startup + +# Query current layout (master|dwindle) +LAYOUT=$(hyprctl -j getoption general:layout | jq -r '.str') + +case "$LAYOUT" in + master) + # Ensure master layout-style binds + hyprctl keyword unbind SUPER,J + hyprctl keyword unbind SUPER,K + hyprctl keyword unbind SUPER,O + hyprctl keyword bind SUPER,J,layoutmsg,cyclenext + hyprctl keyword bind SUPER,K,layoutmsg,cycleprev + ;; + dwindle) + # Ensure dwindle layout-style binds + hyprctl keyword unbind SUPER,J + hyprctl keyword unbind SUPER,K + hyprctl keyword unbind SUPER,O + hyprctl keyword bind SUPER,J,cyclenext + hyprctl keyword bind SUPER,K,cyclenext,prev + hyprctl keyword bind SUPER,O,togglesplit + ;; + *) + # Do nothing for unexpected values + : + ;; + esac -- cgit v1.2.3 From 3665ebd0f02a04e44d382d4cc9f306525e02279d Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 02:11:21 -0500 Subject: feat(hypr): source composed generated/Startup_Apps.conf and WindowRules.conf\n\n- Hypr now loads ~/.config/hypr/generated outputs from ComposeHyprConfigs.sh\n- Avoids confusion when UserConfigs/Startup_Apps.conf is only an overlay --- config/hypr/hyprland.conf | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index fa8435dc..1cf7bd31 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -9,13 +9,15 @@ exec-once = $HOME/.config/hypr/initial-boot.sh # Sourcing external config files $configs = $HOME/.config/hypr/configs # Default Configs directory path +$Generated = $HOME/.config/hypr/generated # Composed configs (base + user overlays) source=$configs/Keybinds.conf # Pre-configured keybinds # ## This is where you want to start tinkering $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path -source= $UserConfigs/Startup_Apps.conf +# Use composed Startup_Apps (base + user overlay + disables) +source= $Generated/Startup_Apps.conf source= $UserConfigs/ENVariables.conf # Environment variables to load @@ -26,7 +28,8 @@ source= $UserConfigs/Laptops.conf # For laptop related source= $UserConfigs/LaptopDisplay.conf # Laptop display related. You need to read the comment on this file -source= $UserConfigs/WindowRules.conf # all about Hyprland Window Rules and Layer Rules +# Use composed WindowRules (base + user overlay + disables) +source= $Generated/WindowRules.conf # all about Hyprland Window Rules and Layer Rules source= $UserConfigs/UserDecorations.conf # Decorations config file -- cgit v1.2.3 From 5fc91179274f7dceed62e24aad274a600d082f22 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 02:25:14 -0500 Subject: fix(copy): always add KeybindsLayoutInit.sh to UserConfigs/Startup_Apps overlay\n\n- Ensures the layout-aware J/K init survives composition and user updates\n- Prevents cases where generated/Startup_Apps.conf misses the init entry --- copy.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/copy.sh b/copy.sh index b4e958a9..1addda84 100755 --- a/copy.sh +++ b/copy.sh @@ -281,6 +281,14 @@ if command -v qs >/dev/null 2>&1; then sed -i '/#pkill qs && qs &/s/^#//' config/hypr/scripts/Refresh.sh fi +# Ensure layout-aware keybinds init runs on startup (adds to user overlay so it survives composes) +OVERLAY_SA="config/hypr/UserConfigs/Startup_Apps.conf" +mkdir -p "$(dirname "$OVERLAY_SA")" +if ! grep -qx 'exec-once = \$scriptsDir/KeybindsLayoutInit.sh' "$OVERLAY_SA"; then + echo 'exec-once = $scriptsDir/KeybindsLayoutInit.sh' >>"$OVERLAY_SA" + echo "${INFO} Added KeybindsLayoutInit.sh to user Startup_Apps overlay" 2>&1 | tee -a "$LOG" +fi + # Note: The SUPER+A keybind now uses OverviewToggle.sh which automatically # tries quickshell first and falls back to AGS, so both can be installed -- cgit v1.2.3 From a35eb612dda901c5d14d559e55e64c0b1e93eae4 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 02:32:31 -0500 Subject: fix(startup): preserve KeybindsLayoutInit in composed Startup_Apps; harden hyprlock 12h edits\n\n- ComposeHyprConfigs.sh: ignore disabling /KeybindsLayoutInit.sh\n- copy.sh migration: filter KeybindsLayoutInit from Startup_Apps.disable\n- copy.sh: target existing hyprlock template, avoid sed errors --- config/hypr/scripts/ComposeHyprConfigs.sh | 4 ++++ copy.sh | 22 +++++++++++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/config/hypr/scripts/ComposeHyprConfigs.sh b/config/hypr/scripts/ComposeHyprConfigs.sh index 55bc3c5c..f0928a24 100755 --- a/config/hypr/scripts/ComposeHyprConfigs.sh +++ b/config/hypr/scripts/ComposeHyprConfigs.sh @@ -58,6 +58,10 @@ compose_startup_apps() { while IFS= read -r d; do d="$(echo "$d" | trim)" [[ -z "$d" || "$d" =~ ^# ]] && continue + # Never disable our layout-aware keybind init unless user re-enables via explicit edit here + if [[ "$d" == "\$scriptsDir/KeybindsLayoutInit.sh" ]]; then + continue + fi unset 'cmds[$d]' done <"$disable_file" fi diff --git a/copy.sh b/copy.sh index 1addda84..cd5f5212 100755 --- a/copy.sh +++ b/copy.sh @@ -414,11 +414,19 @@ while true; do 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" + HYPRLOCK_FILE="config/hypr/hyprlock.conf" + if [ ! -f "$HYPRLOCK_FILE" ] && [ -f "config/hypr/hyprlock-1080p.conf" ]; then + HYPRLOCK_FILE="config/hypr/hyprlock-1080p.conf" + fi + if [ -f "$HYPRLOCK_FILE" ]; then + sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%H")"/# &/' "$HYPRLOCK_FILE" 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/' "$HYPRLOCK_FILE" 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" + sed -i 's/^\s*text = cmd\[update:1000\] echo "\$(date +"%S")"/# &/' "$HYPRLOCK_FILE" 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/' "$HYPRLOCK_FILE" 2>&1 | tee -a "$LOG" + else + echo "${WARN} hyprlock template not found; skipping 12H lock format edits" 2>&1 | tee -a "$LOG" + fi echo "${OK} 12H format set on waybar clocks succesfully." 2>&1 | tee -a "$LOG" @@ -854,7 +862,11 @@ compose_overlay_from_backup() { grep -E '^\s*exec-once\s*=' "$base_file" | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$base_file.tmp.exec" comm -23 "$old_user_file.tmp.exec" "$base_file.tmp.exec" >"$new_user_file" # treat commented exec-once in old user as disables - grep -E '^\s*#\s*exec-once\s*=' "$old_user_file" | sed -E 's/^\s*#\s*exec-once\s*=\s*//' | sed -E 's/^\s+//;s/\s+$//' | sort -u >"$disable_file" + grep -E '^\s*#\s*exec-once\s*=' "$old_user_file" \ + | sed -E 's/^\s*#\s*exec-once\s*=\s*//' \ + | sed -E 's/^\s+//;s/\s+$//' \ + | grep -Ev '^\$scriptsDir/KeybindsLayoutInit\.sh$' \ + | sort -u >"$disable_file" rm -f "$old_user_file.tmp.exec" "$base_file.tmp.exec" elif [ "$type" = "windowrules" ]; then # additions -- cgit v1.2.3 From 67cc7cdab26ad7dc0f9c0aa691a1efc3a200518a Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 02:45:53 -0500 Subject: fix(qs): Edit Startup Apps opens full vendor defaults (configs/Startup_Apps.conf)\n\n- Restores prior behavior where users edit the complete startup config\n- Composition still merges overlay+vendor at runtime --- config/hypr/scripts/Kool_Quick_Settings.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/scripts/Kool_Quick_Settings.sh b/config/hypr/scripts/Kool_Quick_Settings.sh index 79ddc163..d6e1b089 100755 --- a/config/hypr/scripts/Kool_Quick_Settings.sh +++ b/config/hypr/scripts/Kool_Quick_Settings.sh @@ -58,7 +58,7 @@ main() { "view/edit Window Rules") file="$UserConfigs/WindowRules.conf" ;; "view/edit User Keybinds") file="$UserConfigs/UserKeybinds.conf" ;; "view/edit User Settings") file="$UserConfigs/UserSettings.conf" ;; - "view/edit Startup Apps") file="$UserConfigs/Startup_Apps.conf" ;; + "view/edit Startup Apps") file="$configs/Startup_Apps.conf" ;; "view/edit Decorations") file="$UserConfigs/UserDecorations.conf" ;; "view/edit Animations") file="$UserConfigs/UserAnimations.conf" ;; "view/edit Laptop Keybinds") file="$UserConfigs/Laptops.conf" ;; -- cgit v1.2.3 From 109a4b1ab03ef16b20c00aeb2775f515fc56ff07 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 02:50:39 -0500 Subject: fix(hypr): source UserConfigs/Startup_Apps.conf and WindowRules.conf again\n\n- Revert to runtime includes that always exist to restore startup apps\n- Keep KeybindsLayoutInit in vendor configs/Startup_Apps.conf so it runs --- config/hypr/hyprland.conf | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index 1cf7bd31..fa8435dc 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -9,15 +9,13 @@ exec-once = $HOME/.config/hypr/initial-boot.sh # Sourcing external config files $configs = $HOME/.config/hypr/configs # Default Configs directory path -$Generated = $HOME/.config/hypr/generated # Composed configs (base + user overlays) source=$configs/Keybinds.conf # Pre-configured keybinds # ## This is where you want to start tinkering $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path -# Use composed Startup_Apps (base + user overlay + disables) -source= $Generated/Startup_Apps.conf +source= $UserConfigs/Startup_Apps.conf source= $UserConfigs/ENVariables.conf # Environment variables to load @@ -28,8 +26,7 @@ source= $UserConfigs/Laptops.conf # For laptop related source= $UserConfigs/LaptopDisplay.conf # Laptop display related. You need to read the comment on this file -# Use composed WindowRules (base + user overlay + disables) -source= $Generated/WindowRules.conf # all about Hyprland Window Rules and Layer Rules +source= $UserConfigs/WindowRules.conf # all about Hyprland Window Rules and Layer Rules source= $UserConfigs/UserDecorations.conf # Decorations config file -- cgit v1.2.3 From f8e7eb13f48aa5576674318bcd7b3ab920e72846 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 02:53:52 -0500 Subject: fix(startup): load vendor Startup_Apps/WindowRules then user overlay\n\n- Restores baseline autostarts (waybar, swaync, etc.) while allowing user additions\n- Keeps SUPER+SHIFT+E editing vendor Startup_Apps for full view --- config/hypr/hyprland.conf | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index fa8435dc..8f0fc1e5 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -15,6 +15,8 @@ source=$configs/Keybinds.conf # Pre-configured keybinds # ## This is where you want to start tinkering $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path +# Load vendor defaults, then user additions/overrides +source= $configs/Startup_Apps.conf source= $UserConfigs/Startup_Apps.conf source= $UserConfigs/ENVariables.conf # Environment variables to load @@ -26,7 +28,9 @@ source= $UserConfigs/Laptops.conf # For laptop related source= $UserConfigs/LaptopDisplay.conf # Laptop display related. You need to read the comment on this file -source= $UserConfigs/WindowRules.conf # all about Hyprland Window Rules and Layer Rules +# Load vendor defaults, then user additions +source= $configs/WindowRules.conf # all about Hyprland Window Rules and Layer Rules (defaults) +source= $UserConfigs/WindowRules.conf # user rules and layer rules source= $UserConfigs/UserDecorations.conf # Decorations config file -- cgit v1.2.3 From 8361dcc058fb41225630934d37bae65dd9b76e43 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 03:05:23 -0500 Subject: chore(release): v2.3.18\n\nKeybinds\n- Initialize SUPER+J/K to match default layout at login via scripts/KeybindsLayoutInit.sh\n- Keep ChangeLayout.sh dynamic rebinds on layout toggle\n- Credit: Suresh Thagunna (https://github.com/suresh466)\n\nStartup\n- Source vendor Startup_Apps/WindowRules first, then UserConfigs overlay to restore baseline autostarts while honoring user additions\n- Quick Settings: Edit Startup Apps opens full vendor defaults\n\nMeta\n- Version marker: config/hypr/v2.3.18 --- CHANGELOG.md | 9 +++++++++ config/hypr/UserConfigs/ENVariables.conf | 2 +- config/hypr/v2.3.17 | 5 ----- config/hypr/v2.3.18 | 5 +++++ 4 files changed, 15 insertions(+), 6 deletions(-) delete mode 100644 config/hypr/v2.3.17 create mode 100644 config/hypr/v2.3.18 diff --git a/CHANGELOG.md b/CHANGELOG.md index dd01997b..f6623708 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Changelog โ€” JAK's Hyprland Dotfiles +## v2.3.18 โ€” 2025-11-05 + +- Keybinds: initialize SUPER+J/K at login to match the default layout (master or dwindle). + - Adds scripts/KeybindsLayoutInit.sh and wires it to Startup_Apps so J/K and O (togglesplit) are correct on first session. + - ChangeLayout.sh continues to rebind dynamically when layouts are toggled. + - Credits: [Suresh Thagunna](https://github.com/suresh466) for identifying the mismatch and proposing an auto-alignment approach. +- Startup config sourcing: load vendor Startup_Apps and WindowRules first, then user overlays, restoring baseline autostarts while keeping user additions. +- Quick Settings: โ€œEdit Startup Appsโ€ opens the full vendor defaults for clarity. + ## October 2025 ### โŒจ๏ธ Keybinds diff --git a/config/hypr/UserConfigs/ENVariables.conf b/config/hypr/UserConfigs/ENVariables.conf index d82fc2a6..4e736dc3 100644 --- a/config/hypr/UserConfigs/ENVariables.conf +++ b/config/hypr/UserConfigs/ENVariables.conf @@ -5,7 +5,7 @@ # environment-variables # Current Version of JakooLit Dotfiles: -env = DOTS_VERSION,2.3.17 +env = DOTS_VERSION,2.3.18 # Toolkit Backend Variables env = GDK_BACKEND,wayland,x11,* diff --git a/config/hypr/v2.3.17 b/config/hypr/v2.3.17 deleted file mode 100644 index 31b3414d..00000000 --- a/config/hypr/v2.3.17 +++ /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/hypr/v2.3.18 b/config/hypr/v2.3.18 new file mode 100644 index 00000000..31b3414d --- /dev/null +++ b/config/hypr/v2.3.18 @@ -0,0 +1,5 @@ +### 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 -- cgit v1.2.3 From 74b5fe09f3a0b04093ff1442b1dfc683f40d3eca Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 21:59:55 -0500 Subject: Dropped duplicate startup_apps.sh script Removed the ComposeHyprConfitg.sh script Your branch is up to date with 'origin/development'. Changes to be committed: deleted: config/hypr/UserConfigs/Startup_Apps.conf modified: config/hypr/hyprland.conf deleted: config/hypr/scripts/ComposeHyprConfigs.sh modified: config/hypr/scripts/Kool_Quick_Settings.sh modified: copy.sh modified: upgrade.sh --- config/hypr/UserConfigs/Startup_Apps.conf | 62 ---------------- config/hypr/hyprland.conf | 2 - config/hypr/scripts/ComposeHyprConfigs.sh | 113 ----------------------------- config/hypr/scripts/Kool_Quick_Settings.sh | 2 +- copy.sh | 4 - upgrade.sh | 4 - 6 files changed, 1 insertion(+), 186 deletions(-) delete mode 100644 config/hypr/UserConfigs/Startup_Apps.conf delete mode 100755 config/hypr/scripts/ComposeHyprConfigs.sh diff --git a/config/hypr/UserConfigs/Startup_Apps.conf b/config/hypr/UserConfigs/Startup_Apps.conf deleted file mode 100644 index 4f4fbd22..00000000 --- a/config/hypr/UserConfigs/Startup_Apps.conf +++ /dev/null @@ -1,62 +0,0 @@ -# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # -# Commands and Apps to be executed at launch - -$scriptsDir = $HOME/.config/hypr/scripts -$UserScripts = $HOME/.config/hypr/UserScripts - -$wallDIR=$HOME/Pictures/wallpapers -$lock = $scriptsDir/LockScreen.sh -$SwwwRandom = $UserScripts/WallpaperAutoChange.sh -$livewallpaper="" - -# wallpaper stuff -exec-once = swww-daemon --format argb # New flag for v0.11.2 -#exec-once = swww-daemon --format xrgb # old 0.9.5 option -#exec-once = mpvpaper '*' -o "load-scripts=no no-audio --loop" $livewallpaper - -# wallpaper random -#exec-once = $SwwwRandom $wallDIR # random wallpaper switcher every 30 minutes - -# Startup -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 - -# starup apps -exec-once = nm-applet --indicator -exec-once = nm-tray # For ubuntu -exec-once = swaync -#exec-once = ags -#exec-once = blueman-applet -#exec-once = rog-control-center -exec-once = waybar -exec-once = qs # quickshell AGS Desktop Overview alternative - -#clipboard manager -exec-once = wl-paste --type text --watch cliphist store -exec-once = wl-paste --type image --watch cliphist store - -# Rainbow borders -exec-once = $UserScripts/RainbowBorders.sh - -# Starting hypridle to start hyprlock -exec-once = hypridle - -# Weather script to populate cache on startup -exec-once = $UserScripts/WeatherWrap.sh - - -# Here are list of features available but disabled by default -# exec-once = swww-daemon --format xrgb && swww img $HOME/Pictures/wallpapers/mecha-nostalgia.png # persistent wallpaper - -#gnome polkit for nixos -#exec-once = $scriptsDir/Polkit-NixOS.sh - -# xdg-desktop-portal-hyprland (should be auto starting. However, you can force to start) -#exec-once = $scriptsDir/PortalHyprland.sh diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index 8f0fc1e5..8eb91df7 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -17,7 +17,6 @@ $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path # Load vendor defaults, then user additions/overrides source= $configs/Startup_Apps.conf -source= $UserConfigs/Startup_Apps.conf source= $UserConfigs/ENVariables.conf # Environment variables to load @@ -30,7 +29,6 @@ source= $UserConfigs/LaptopDisplay.conf # Laptop display related. You need to re # Load vendor defaults, then user additions source= $configs/WindowRules.conf # all about Hyprland Window Rules and Layer Rules (defaults) -source= $UserConfigs/WindowRules.conf # user rules and layer rules source= $UserConfigs/UserDecorations.conf # Decorations config file diff --git a/config/hypr/scripts/ComposeHyprConfigs.sh b/config/hypr/scripts/ComposeHyprConfigs.sh deleted file mode 100755 index f0928a24..00000000 --- a/config/hypr/scripts/ComposeHyprConfigs.sh +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/env bash -# Compose merged Hyprland configs for Startup_Apps and WindowRules -set -euo pipefail - -BASE_DIR="$HOME/.config/hypr" -BASE_CFG_DIR="$BASE_DIR/configs" -USER_DIR="$BASE_DIR/UserConfigs" -GEN_DIR="$BASE_DIR/generated" - -mkdir -p "$GEN_DIR" - -log() { printf "[compose] %s\n" "$*"; } - -# Trim leading/trailing whitespace -trim() { sed -E 's/^\s+//;s/\s+$//'; } - -# Normalize spaces in a directive line -normalize() { awk '{$1=$1;print}'; } - -# Build merged Startup_Apps.conf -compose_startup_apps() { - local base_file="$BASE_CFG_DIR/Startup_Apps.conf" - local user_file="$USER_DIR/Startup_Apps.conf" - local disable_file="$USER_DIR/Startup_Apps.disable" - local out_file="$GEN_DIR/Startup_Apps.conf" - - : >"$out_file" - - # Header and variable lines come from base - if [[ -f "$base_file" ]]; then - # Copy all non exec-once lines (comments, blanks, variables, etc.) - grep -Ev '^\s*exec-once\s*=' "$base_file" || true >>"$out_file" - fi - - # Collect exec-once commands (the right side of '=') - declare -A cmds=() - - if [[ -f "$base_file" ]]; then - while IFS= read -r line; do - [[ "$line" =~ ^\s*exec-once\s*= ]] || continue - cmd="${line#*=}" - cmd="$(echo "$cmd" | trim)" - cmds["$cmd"]=1 - done <"$base_file" - fi - - if [[ -f "$user_file" ]]; then - while IFS= read -r line; do - [[ "$line" =~ ^\s*exec-once\s*= ]] || continue - cmd="${line#*=}" - cmd="$(echo "$cmd" | trim)" - cmds["$cmd"]=1 - done <"$user_file" - fi - - # Apply disables (exact match of command string) - if [[ -f "$disable_file" ]]; then - while IFS= read -r d; do - d="$(echo "$d" | trim)" - [[ -z "$d" || "$d" =~ ^# ]] && continue - # Never disable our layout-aware keybind init unless user re-enables via explicit edit here - if [[ "$d" == "\$scriptsDir/KeybindsLayoutInit.sh" ]]; then - continue - fi - unset 'cmds[$d]' - done <"$disable_file" - fi - - # Emit combined exec-once (stable sort) - for k in "${!cmds[@]}"; do echo "$k"; done | sort -u | while IFS= read -r cmd; do - [[ -z "$cmd" ]] && continue - printf "exec-once = %s\n" "$cmd" >>"$out_file" - done - - log "Wrote $out_file" -} - -# Build merged WindowRules.conf -compose_window_rules() { - local base_file="$BASE_CFG_DIR/WindowRules.conf" - local user_file="$USER_DIR/WindowRules.conf" - local disable_file="$USER_DIR/WindowRules.disable" - local out_file="$GEN_DIR/WindowRules.conf" - - : >"$out_file" - echo "# Generated merged WindowRules" >>"$out_file" - - declare -A rules=() - add_rules() { - local f="$1" - [[ -f "$f" ]] || return 0 - grep -E '^(windowrule|layerrule)\s*=' "$f" | trim | while IFS= read -r r; do - rules["$r"]=1 - done - } - - add_rules "$base_file" - add_rules "$user_file" - - if [[ -f "$disable_file" ]]; then - while IFS= read -r d; do - d="$(echo "$d" | trim)" - [[ -z "$d" || "$d" =~ ^# ]] && continue - unset 'rules[$d]' - done <"$disable_file" - fi - - for r in "${!rules[@]}"; do echo "$r"; done | sort -u >>"$out_file" - log "Wrote $out_file" -} - -compose_startup_apps -compose_window_rules \ No newline at end of file diff --git a/config/hypr/scripts/Kool_Quick_Settings.sh b/config/hypr/scripts/Kool_Quick_Settings.sh index d6e1b089..16742492 100755 --- a/config/hypr/scripts/Kool_Quick_Settings.sh +++ b/config/hypr/scripts/Kool_Quick_Settings.sh @@ -55,7 +55,7 @@ main() { case "$choice" in "view/edit User Defaults") file="$UserConfigs/01-UserDefaults.conf" ;; "view/edit ENV variables") file="$UserConfigs/ENVariables.conf" ;; - "view/edit Window Rules") file="$UserConfigs/WindowRules.conf" ;; + "view/edit Window Rules") file="$configs/WindowRules.conf" ;; "view/edit User Keybinds") file="$UserConfigs/UserKeybinds.conf" ;; "view/edit User Settings") file="$UserConfigs/UserSettings.conf" ;; "view/edit Startup Apps") file="$configs/Startup_Apps.conf" ;; diff --git a/copy.sh b/copy.sh index cd5f5212..b1cc6e1a 100755 --- a/copy.sh +++ b/copy.sh @@ -933,10 +933,6 @@ if [ -d "$BACKUP_DIR_PATH" ]; then done fi -# Compose merged configs (Startup_Apps and WindowRules) -if [ -x "$DIRPATH/scripts/ComposeHyprConfigs.sh" ]; then - "$DIRPATH/scripts/ComposeHyprConfigs.sh" 2>&1 | tee -a "$LOG" || true -fi printf "\n%.0s" {1..1} diff --git a/upgrade.sh b/upgrade.sh index 9aee3c2c..07ee1f8b 100755 --- a/upgrade.sh +++ b/upgrade.sh @@ -198,10 +198,6 @@ if version_gt "$latest_version" "$stored_version"; then # Set executable for initial-boot.sh chmod +x "$HOME/.config/hypr/initial-boot.sh" 2>&1 | tee -a "$LOG" - # Compose merged configs (Startup_Apps and WindowRules) - if [ -x "$HOME/.config/hypr/scripts/ComposeHyprConfigs.sh" ]; then - "$HOME/.config/hypr/scripts/ComposeHyprConfigs.sh" 2>&1 | tee -a "$LOG" || true - fi else echo "$MAGENTA Upgrade declined. No files or directories changed" 2>&1 | tee -a "$LOG" fi -- cgit v1.2.3 From 206f51d28f8f0cb17289c573991eea5eedae2eec Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 5 Nov 2025 22:07:57 -0500 Subject: Fixing layout aware SUPER J/K cycle next/prev On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/configs/Keybinds.conf modified: config/hypr/scripts/KeybindsLayoutInit.sh --- config/hypr/configs/Keybinds.conf | 6 ++++-- config/hypr/scripts/KeybindsLayoutInit.sh | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/config/hypr/configs/Keybinds.conf b/config/hypr/configs/Keybinds.conf index ebaee30a..fbe3bfe5 100644 --- a/config/hypr/configs/Keybinds.conf +++ b/config/hypr/configs/Keybinds.conf @@ -19,8 +19,10 @@ bindd = $mainMod SHIFT, E, Quick settings menu, exec, $scriptsDir/Kool_Quick_Set # Master Layout bindd = $mainMod CTRL, D, remove master, layoutmsg, removemaster bindd = $mainMod, I, add master, layoutmsg, addmaster -bindd = $mainMod, J, cycle next, layoutmsg, cyclenext -bindd = $mainMod, K, cycle previous, layoutmsg, cycleprev +# NOTE: J/K bindings are set dynamically by scripts/KeybindsLayoutInit.sh and scripts/ChangeLayout.sh +# (we intentionally do not bind them statically here to avoid conflicts across layouts) +# bindd = $mainMod, J, cycle next, layoutmsg, cyclenext +# bindd = $mainMod, K, cycle previous, layoutmsg, cycleprev bindd = $mainMod CTRL, Return, swap with master, layoutmsg, swapwithmaster # Dwindle Layout diff --git a/config/hypr/scripts/KeybindsLayoutInit.sh b/config/hypr/scripts/KeybindsLayoutInit.sh index 7e328cde..af81f62e 100755 --- a/config/hypr/scripts/KeybindsLayoutInit.sh +++ b/config/hypr/scripts/KeybindsLayoutInit.sh @@ -20,7 +20,8 @@ case "$LAYOUT" in hyprctl keyword unbind SUPER,K hyprctl keyword unbind SUPER,O hyprctl keyword bind SUPER,J,cyclenext - hyprctl keyword bind SUPER,K,cyclenext,prev +hyprctl keyword bind SUPER,K,cyclenext,prev +# ensure SUPER+O togglesplit is available on dwindle hyprctl keyword bind SUPER,O,togglesplit ;; *) -- cgit v1.2.3 From 1788691d242abe607add69d211478e306a154cc6 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 7 Nov 2025 12:26:05 -0500 Subject: Fixing Super J/K cycle next/prev for auto layout Cycle next/prev is different for dwindle vs. master Oringinal code only worked in master. This script detects which and rebunds SUPER J/K accordingly On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/scripts/KeybindsLayoutInit.sh --- config/hypr/scripts/KeybindsLayoutInit.sh | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/config/hypr/scripts/KeybindsLayoutInit.sh b/config/hypr/scripts/KeybindsLayoutInit.sh index af81f62e..fd34f90e 100755 --- a/config/hypr/scripts/KeybindsLayoutInit.sh +++ b/config/hypr/scripts/KeybindsLayoutInit.sh @@ -2,8 +2,15 @@ # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## # Initialize J/K keybinds to match the current default layout at startup -# Query current layout (master|dwindle) -LAYOUT=$(hyprctl -j getoption general:layout | jq -r '.str') +set -euo pipefail + +# Determine current layout (master|dwindle); be robust to null at startup +LAYOUT=$(hyprctl -j getoption general:layout | jq -r '.str // empty' 2>/dev/null || true) +if [ -z "${LAYOUT:-}" ]; then + # Fallback: parse non-JSON output (e.g., "str: dwindle") + LAYOUT=$(hyprctl getoption general:layout 2>/dev/null | awk -F'str:' 'NF>1 {gsub(/^ +| +$/,"",$2); print $2}') +fi +[ -z "${LAYOUT:-}" ] && exit 0 case "$LAYOUT" in master) @@ -20,8 +27,8 @@ case "$LAYOUT" in hyprctl keyword unbind SUPER,K hyprctl keyword unbind SUPER,O hyprctl keyword bind SUPER,J,cyclenext -hyprctl keyword bind SUPER,K,cyclenext,prev -# ensure SUPER+O togglesplit is available on dwindle + hyprctl keyword bind SUPER,K,cyclenext,prev + # ensure SUPER+O togglesplit is available on dwindle hyprctl keyword bind SUPER,O,togglesplit ;; *) -- cgit v1.2.3 From 672aaf336df2a4897c086d84da6fea8611a5ec54 Mon Sep 17 00:00:00 2001 From: Alberson Miranda <45690517+albersonmiranda@users.noreply.github.com> Date: Sat, 8 Nov 2025 00:17:21 -0300 Subject: feat: resume hyprsunset (#862) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Looks good! Merging this into development branch ๐Ÿ‘ --- config/hypr/configs/Startup_Apps.conf | 2 ++ config/hypr/scripts/Hyprsunset.sh | 22 +++++++++++++++++----- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/config/hypr/configs/Startup_Apps.conf b/config/hypr/configs/Startup_Apps.conf index 07a92a3f..c1670595 100644 --- a/config/hypr/configs/Startup_Apps.conf +++ b/config/hypr/configs/Startup_Apps.conf @@ -48,6 +48,8 @@ exec-once = $UserScripts/RainbowBorders.sh # Starting hypridle to start hyprlock exec-once = hypridle +# Resume Hyprsunset if state is "on" from previous session +exec-once = $scriptsDir/Hyprsunset.sh init # Here are list of features available but disabled by default # exec-once = swww-daemon --format xrgb && swww img $HOME/Pictures/wallpapers/mecha-nostalgia.png # persistent wallpaper diff --git a/config/hypr/scripts/Hyprsunset.sh b/config/hypr/scripts/Hyprsunset.sh index c7c4b395..4a2b52f4 100755 --- a/config/hypr/scripts/Hyprsunset.sh +++ b/config/hypr/scripts/Hyprsunset.sh @@ -8,12 +8,12 @@ set -euo pipefail # - 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) +# HYPRSUNSET_TEMP default 4500 (K) +# HYPRSUNSET_ICON_MODE sunset|blue (default: sunset) STATE_FILE="$HOME/.cache/.hyprsunset_state" -TARGET_TEMP="${HYPERSUNSET_TEMP:-4500}" -ICON_MODE="${HYPERSUNSET_ICON_MODE:-sunset}" +TARGET_TEMP="${HYPRSUNSET_TEMP:-4500}" +ICON_MODE="${HYPRSUNSET_ICON_MODE:-sunset}" ensure_state() { [[ -f "$STATE_FILE" ]] || echo "off" > "$STATE_FILE" @@ -92,8 +92,20 @@ cmd_status() { printf '{"text":"%s","class":"%s","tooltip":"%s"}\n' "$txt" "$cls" "$tip" } +cmd_init() { + ensure_state + state="$(cat "$STATE_FILE" || echo off)" + + if [[ "$state" == "on" ]]; then + if command -v hyprsunset >/dev/null 2>&1; then + nohup hyprsunset -t "$TARGET_TEMP" >/dev/null 2>&1 & + fi + fi +} + case "${1:-}" in toggle) cmd_toggle ;; status) cmd_status ;; - *) echo "usage: $0 [toggle|status]" >&2; exit 2 ;; + init) cmd_init ;; + *) echo "usage: $0 [toggle|status|init]" >&2; exit 2 ;; esac -- cgit v1.2.3 From 0cda1d47c8ff9344ea62bc3741911b3da9367f86 Mon Sep 17 00:00:00 2001 From: brockar Date: Sun, 9 Nov 2025 10:05:45 -0300 Subject: fix: Weather.py one-off run --- config/hypr/UserScripts/Weather.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/hypr/UserScripts/Weather.py b/config/hypr/UserScripts/Weather.py index a9a826e1..a6483777 100755 --- a/config/hypr/UserScripts/Weather.py +++ b/config/hypr/UserScripts/Weather.py @@ -44,7 +44,7 @@ class WeatherData: # Examples (zsh): # # One-off run # # WEATHER_UNITS can be "metric" or "imperial" -# WEATHER_UNITS=imperial WEATHER_PLACE="Concord, NH" python3 /home/dwilliams/Projects/Weather.py +# WEATHER_UNITS=imperial WEATHER_PLACE="Concord, NH" python3 ~/.config/hypr/UserScripts/Weather.py # # # Persist in current shell session # export WEATHER_UNITS=imperial -- cgit v1.2.3 From e90d57835b9596c83dec0e468e666af4c209a63a Mon Sep 17 00:00:00 2001 From: brockar Date: Wed, 12 Nov 2025 22:53:59 -0300 Subject: fix: add UserConfigs/Startup_App.conf to hyprland.conf and clean a bit --- config/hypr/hyprland.conf | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index 8eb91df7..a85c235f 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -9,35 +9,27 @@ exec-once = $HOME/.config/hypr/initial-boot.sh # Sourcing external config files $configs = $HOME/.config/hypr/configs # Default Configs directory path - -source=$configs/Keybinds.conf # Pre-configured keybinds - # ## This is where you want to start tinkering $UserConfigs = $HOME/.config/hypr/UserConfigs # User Configs directory path +source=$configs/Keybinds.conf # Pre-configured keybinds + # Load vendor defaults, then user additions/overrides source= $configs/Startup_Apps.conf +source= $UserConfigs/Startup_Apps.conf source= $UserConfigs/ENVariables.conf # Environment variables to load -#source= $UserConfigs/Monitors.conf # Its all about your monitor config (old dots) will remove on push to main -#source= $UserConfigs/WorkspaceRules.conf # Hyprland workspaces (old dots) will remove on push to main - source= $UserConfigs/Laptops.conf # For laptop related - source= $UserConfigs/LaptopDisplay.conf # Laptop display related. You need to read the comment on this file # Load vendor defaults, then user additions source= $configs/WindowRules.conf # all about Hyprland Window Rules and Layer Rules (defaults) source= $UserConfigs/UserDecorations.conf # Decorations config file - source= $UserConfigs/UserAnimations.conf # Animation config file - source= $UserConfigs/UserKeybinds.conf # Put your own keybinds here - source= $UserConfigs/UserSettings.conf # Main Hyprland Settings. - source= $UserConfigs/01-UserDefaults.conf # settings for User defaults apps # nwg-displays -- cgit v1.2.3 From 4693e56583f81e10de500ad701ba57175113e969 Mon Sep 17 00:00:00 2001 From: brockar Date: Wed, 12 Nov 2025 23:04:02 -0300 Subject: fix: hyprland.conf user windowrules --- config/hypr/hyprland.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/config/hypr/hyprland.conf b/config/hypr/hyprland.conf index a85c235f..f509a76d 100644 --- a/config/hypr/hyprland.conf +++ b/config/hypr/hyprland.conf @@ -25,6 +25,7 @@ source= $UserConfigs/LaptopDisplay.conf # Laptop display related. You need to re # Load vendor defaults, then user additions source= $configs/WindowRules.conf # all about Hyprland Window Rules and Layer Rules (defaults) +source= $UserConfigs/WindowRules.conf # Window Rules and Layer Rules user configs source= $UserConfigs/UserDecorations.conf # Decorations config file source= $UserConfigs/UserAnimations.conf # Animation config file -- cgit v1.2.3 From ad3b7656f223f380e3f60cf77bb125a09ab28559 Mon Sep 17 00:00:00 2001 From: installer Date: Thu, 13 Nov 2025 12:47:11 -0500 Subject: Upd std resolution lockscreen to horizontal layout Reduced the font size and colors Going to convert the 2k lockscreen next On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/hyprlock.conf --- config/hypr/hyprlock.conf | 99 +++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 50 deletions(-) diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index b67bba51..4251ac68 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -1,5 +1,5 @@ # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # -# Hyprlock config for => 2k monitor resolutions +# Hyprlock config for < 1080p monitor resolutions # Original config submitted by https://github.com/SherLock707 # Sourcing colors generated by wallust @@ -37,9 +37,9 @@ label { monitor = text = cmd[update:18000000] echo " "$(date +'%A, %-d %B')" " color = $color13 - font_size = 18 + font_size = 48 font_family = Victor Mono Bold Italic - position = 0, -120 + position = 0, -60 halign = center valign = center } @@ -47,66 +47,66 @@ label { # Hour-Time label { monitor = - text = cmd[update:1000] echo "$(date +"%H")" -# text = cmd[update:1000] echo "$(date +"%I")" #AM/PM +# text = cmd[update:1000] echo "$(date +"%H")" + text = cmd[update:1000] echo "$(date +"%I:%M %p")" #AM/PM #color = rgba(255, 185, 0, .8) - color = $color13 - font_size = 240 + color = $color8 + font_size = 130 font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -100 + position = 0, -250 halign = center valign = top } # Minute-Time -label { - monitor = - text = cmd[update:1000] echo "$(date +"%M")" - #color = rgba(15, 10, 222, .8) - color = $color12 - font_size = 240 - font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -450 - halign = center - valign = top -} +# label { +# monitor = +# text = cmd[update:1000] echo "$(date +"%M")" +# #color = rgba(15, 10, 222, .8) +# color = $color12 +# font_size = 150 +# font_family = JetBrainsMono Nerd Font ExtraBold +# position = 0, -340 +# halign = center + # valign = top +# } # Seconds-Time -label { - monitor = - text = cmd[update:1000] echo "$(date +"%S")" +#label { +# monitor = +## text = cmd[update:1000] echo "$(date +"%S")" # text = cmd[update:1000] echo "$(date +"%S %p")" #AM/PM - color = $color11 - font_size = 50 - font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -450 - halign = center - valign = top -} +# color = $color11 +# font_size = 32 +# font_family = JetBrainsMono Nerd Font ExtraBold +# position = 0, -350 +# halign = center +# valign = top +#} # Put a picture of choice here. Default is the current wallpaper #image { # monitor = -# #path = $HOME/.config/hypr/wallpaper_effects/.wallpaper_current +# path = $HOME/.config/hypr/wallpaper_effects/.wallpaper_current # size = 160 # rounding = -1 # border_size = 0 # border_color = $color11 # rotate = 0 # reload_time = -1 -# position = 0, 400 +# position = 0, 280 # halign = center # valign = bottom -#} +} # USER label { monitor = text = ๏Šพ $USER - color = $color13 - font_size = 24 + color = $color9 + font_size = 36 font_family = Victor Mono Bold Oblique - position = 0, 280 + position = 0, 275 halign = center valign = bottom } @@ -114,33 +114,32 @@ label { # INPUT FIELD input-field { monitor = - size = 300, 60 + size = 230, 70 outline_thickness = 2 dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8 dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0 dots_center = true - outer_color = $color11 + outer_color = $color8 inner_color = rgba(255, 255, 255, 0.1) + capslock_color = rgb(255,255,255) font_color = $color13 - capslock_color = rgb(255,255,255) fade_on_empty = false font_family = Victor Mono Bold Oblique placeholder_text = ๐Ÿ”’ Type Password hide_input = false - position = 0, 120 + position = 0, 100 halign = center valign = bottom } - # Keyboard LAYOUT label { monitor = text = $LAYOUT - color = $color13 - font_size = 12 + color = $color8 + font_size = 14 font_family = Victor Mono Bold Oblique - position = 0, 80 + position = 0, 70 halign = center valign = bottom } @@ -149,8 +148,8 @@ label { label { monitor = text = cmd[update:60000] echo " "$(uptime -p || $Scripts/UptimeNixOS.sh)" " - color = $color13 - font_size = 18 + color = $color8 + font_size = 24 font_family = Victor Mono Bold Oblique position = 0, 0 halign = right @@ -161,8 +160,8 @@ label { label { monitor = text = cmd[update:1000] echo " "$($Scripts/Battery.sh)" " - color = $color13 - font_size = 18 + color = $color8 + font_size = 16 font_family = Victor Mono Bold Oblique position = 0, 30 halign = right @@ -174,9 +173,9 @@ label { # see https://github.com/JaKooLit/Hyprland-Dots/wiki/TIPS#%EF%B8%8F-weather-app-related-for-waybar-and-hyprlock label { monitor = - text = cmd[update:3600000] [ -f "$HOME/.cache/.weather_cache" ] && cat "$HOME/.cache/.weather_cache" - color = $color13 - font_size = 18 + text = cmd[update:3600000] [ -f "$HOME/.cache/.weather_cache" ] && cat "$HOME/.cache/.weather_cache" + color = $color8 + font_size = 14 font_family = Victor Mono Bold Oblique position = 50, 0 halign = left -- cgit v1.2.3 From 6bb250c58fbdda05140f5e197c25106d3ba27c57 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 13 Nov 2025 13:02:34 -0500 Subject: Reverting 2K hyprlock to original Editing 1080 hyprlock screen overwrote 2K by mistake On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: hyprlock.conf --- config/hypr/hyprlock.conf | 99 ++++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index 4251ac68..b67bba51 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -1,5 +1,5 @@ # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # -# Hyprlock config for < 1080p monitor resolutions +# Hyprlock config for => 2k monitor resolutions # Original config submitted by https://github.com/SherLock707 # Sourcing colors generated by wallust @@ -37,9 +37,9 @@ label { monitor = text = cmd[update:18000000] echo " "$(date +'%A, %-d %B')" " color = $color13 - font_size = 48 + font_size = 18 font_family = Victor Mono Bold Italic - position = 0, -60 + position = 0, -120 halign = center valign = center } @@ -47,66 +47,66 @@ label { # Hour-Time label { monitor = -# text = cmd[update:1000] echo "$(date +"%H")" - text = cmd[update:1000] echo "$(date +"%I:%M %p")" #AM/PM + text = cmd[update:1000] echo "$(date +"%H")" +# text = cmd[update:1000] echo "$(date +"%I")" #AM/PM #color = rgba(255, 185, 0, .8) - color = $color8 - font_size = 130 + color = $color13 + font_size = 240 font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -250 + position = 0, -100 halign = center valign = top } # Minute-Time -# label { -# monitor = -# text = cmd[update:1000] echo "$(date +"%M")" -# #color = rgba(15, 10, 222, .8) -# color = $color12 -# font_size = 150 -# font_family = JetBrainsMono Nerd Font ExtraBold -# position = 0, -340 -# halign = center - # valign = top -# } +label { + monitor = + text = cmd[update:1000] echo "$(date +"%M")" + #color = rgba(15, 10, 222, .8) + color = $color12 + font_size = 240 + font_family = JetBrainsMono Nerd Font ExtraBold + position = 0, -450 + halign = center + valign = top +} # Seconds-Time -#label { -# monitor = -## text = cmd[update:1000] echo "$(date +"%S")" +label { + monitor = + text = cmd[update:1000] echo "$(date +"%S")" # text = cmd[update:1000] echo "$(date +"%S %p")" #AM/PM -# color = $color11 -# font_size = 32 -# font_family = JetBrainsMono Nerd Font ExtraBold -# position = 0, -350 -# halign = center -# valign = top -#} + color = $color11 + font_size = 50 + font_family = JetBrainsMono Nerd Font ExtraBold + position = 0, -450 + halign = center + valign = top +} # Put a picture of choice here. Default is the current wallpaper #image { # monitor = -# path = $HOME/.config/hypr/wallpaper_effects/.wallpaper_current +# #path = $HOME/.config/hypr/wallpaper_effects/.wallpaper_current # size = 160 # rounding = -1 # border_size = 0 # border_color = $color11 # rotate = 0 # reload_time = -1 -# position = 0, 280 +# position = 0, 400 # halign = center # valign = bottom -} +#} # USER label { monitor = text = ๏Šพ $USER - color = $color9 - font_size = 36 + color = $color13 + font_size = 24 font_family = Victor Mono Bold Oblique - position = 0, 275 + position = 0, 280 halign = center valign = bottom } @@ -114,32 +114,33 @@ label { # INPUT FIELD input-field { monitor = - size = 230, 70 + size = 300, 60 outline_thickness = 2 dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8 dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0 dots_center = true - outer_color = $color8 + outer_color = $color11 inner_color = rgba(255, 255, 255, 0.1) - capslock_color = rgb(255,255,255) font_color = $color13 + capslock_color = rgb(255,255,255) fade_on_empty = false font_family = Victor Mono Bold Oblique placeholder_text = ๐Ÿ”’ Type Password hide_input = false - position = 0, 100 + position = 0, 120 halign = center valign = bottom } + # Keyboard LAYOUT label { monitor = text = $LAYOUT - color = $color8 - font_size = 14 + color = $color13 + font_size = 12 font_family = Victor Mono Bold Oblique - position = 0, 70 + position = 0, 80 halign = center valign = bottom } @@ -148,8 +149,8 @@ label { label { monitor = text = cmd[update:60000] echo " "$(uptime -p || $Scripts/UptimeNixOS.sh)" " - color = $color8 - font_size = 24 + color = $color13 + font_size = 18 font_family = Victor Mono Bold Oblique position = 0, 0 halign = right @@ -160,8 +161,8 @@ label { label { monitor = text = cmd[update:1000] echo " "$($Scripts/Battery.sh)" " - color = $color8 - font_size = 16 + color = $color13 + font_size = 18 font_family = Victor Mono Bold Oblique position = 0, 30 halign = right @@ -173,9 +174,9 @@ label { # see https://github.com/JaKooLit/Hyprland-Dots/wiki/TIPS#%EF%B8%8F-weather-app-related-for-waybar-and-hyprlock label { monitor = - text = cmd[update:3600000] [ -f "$HOME/.cache/.weather_cache" ] && cat "$HOME/.cache/.weather_cache" - color = $color8 - font_size = 14 + text = cmd[update:3600000] [ -f "$HOME/.cache/.weather_cache" ] && cat "$HOME/.cache/.weather_cache" + color = $color13 + font_size = 18 font_family = Victor Mono Bold Oblique position = 50, 0 halign = left -- cgit v1.2.3 From fbcaa735e0e39ff3c2c018e9955f8eca7a295854 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 13 Nov 2025 13:05:20 -0500 Subject: Updated hyprlock 1080 to horizontal layout Adjust fontsize and colors On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: hyprlock-1080p.conf --- config/hypr/hyprlock-1080p.conf | 80 ++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/config/hypr/hyprlock-1080p.conf b/config/hypr/hyprlock-1080p.conf index 14f2f35e..4251ac68 100644 --- a/config/hypr/hyprlock-1080p.conf +++ b/config/hypr/hyprlock-1080p.conf @@ -37,9 +37,9 @@ label { monitor = text = cmd[update:18000000] echo " "$(date +'%A, %-d %B')" " color = $color13 - font_size = 16 + font_size = 48 font_family = Victor Mono Bold Italic - position = 0, -120 + position = 0, -60 halign = center valign = center } @@ -47,42 +47,42 @@ label { # Hour-Time label { monitor = - text = cmd[update:1000] echo "$(date +"%H")" -# text = cmd[update:1000] echo "$(date +"%I")" #AM/PM +# text = cmd[update:1000] echo "$(date +"%H")" + text = cmd[update:1000] echo "$(date +"%I:%M %p")" #AM/PM #color = rgba(255, 185, 0, .8) - color = $color13 - font_size = 200 + color = $color8 + font_size = 130 font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -60 + position = 0, -250 halign = center valign = top } # Minute-Time -label { - monitor = - text = cmd[update:1000] echo "$(date +"%M")" - #color = rgba(15, 10, 222, .8) - color = $color12 - font_size = 200 - font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -340 - halign = center - valign = top -} +# label { +# monitor = +# text = cmd[update:1000] echo "$(date +"%M")" +# #color = rgba(15, 10, 222, .8) +# color = $color12 +# font_size = 150 +# font_family = JetBrainsMono Nerd Font ExtraBold +# position = 0, -340 +# halign = center + # valign = top +# } # Seconds-Time -label { - monitor = - text = cmd[update:1000] echo "$(date +"%S")" +#label { +# monitor = +## text = cmd[update:1000] echo "$(date +"%S")" # text = cmd[update:1000] echo "$(date +"%S %p")" #AM/PM - color = $color11 - font_size = 35 - font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -350 - halign = center - valign = top -} +# color = $color11 +# font_size = 32 +# font_family = JetBrainsMono Nerd Font ExtraBold +# position = 0, -350 +# halign = center +# valign = top +#} # Put a picture of choice here. Default is the current wallpaper #image { @@ -103,10 +103,10 @@ label { label { monitor = text = ๏Šพ $USER - color = $color13 - font_size = 24 + color = $color9 + font_size = 36 font_family = Victor Mono Bold Oblique - position = 0, 220 + position = 0, 275 halign = center valign = bottom } @@ -114,12 +114,12 @@ label { # INPUT FIELD input-field { monitor = - size = 200, 60 + size = 230, 70 outline_thickness = 2 dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8 dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0 dots_center = true - outer_color = $color11 + outer_color = $color8 inner_color = rgba(255, 255, 255, 0.1) capslock_color = rgb(255,255,255) font_color = $color13 @@ -136,8 +136,8 @@ input-field { label { monitor = text = $LAYOUT - color = $color13 - font_size = 10 + color = $color8 + font_size = 14 font_family = Victor Mono Bold Oblique position = 0, 70 halign = center @@ -148,8 +148,8 @@ label { label { monitor = text = cmd[update:60000] echo " "$(uptime -p || $Scripts/UptimeNixOS.sh)" " - color = $color13 - font_size = 16 + color = $color8 + font_size = 24 font_family = Victor Mono Bold Oblique position = 0, 0 halign = right @@ -160,7 +160,7 @@ label { label { monitor = text = cmd[update:1000] echo " "$($Scripts/Battery.sh)" " - color = $color13 + color = $color8 font_size = 16 font_family = Victor Mono Bold Oblique position = 0, 30 @@ -174,8 +174,8 @@ label { label { monitor = text = cmd[update:3600000] [ -f "$HOME/.cache/.weather_cache" ] && cat "$HOME/.cache/.weather_cache" - color = $color13 - font_size = 16 + color = $color8 + font_size = 14 font_family = Victor Mono Bold Oblique position = 50, 0 halign = left -- cgit v1.2.3 From 54901ac4859fe53398da51bee4126f51adf78e2b Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 13 Nov 2025 14:11:29 -0500 Subject: Adj 2k+ res hyprlock.conf to horizontal layout On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: hyprlock.conf --- config/hypr/hyprlock.conf | 101 +++++++++++++++++++++++----------------------- 1 file changed, 50 insertions(+), 51 deletions(-) diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index b67bba51..5aa66adc 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -37,52 +37,52 @@ label { monitor = text = cmd[update:18000000] echo " "$(date +'%A, %-d %B')" " color = $color13 - font_size = 18 + font_size = 64 font_family = Victor Mono Bold Italic - position = 0, -120 + position = 0, -80 halign = center valign = center } -# Hour-Time +# Hour-Time (single horizontal time like 1080p variant) label { monitor = - text = cmd[update:1000] echo "$(date +"%H")" -# text = cmd[update:1000] echo "$(date +"%I")" #AM/PM +# text = cmd[update:1000] echo "$(date +"%H:%M")" # 24h option + text = cmd[update:1000] echo "$(date +"%I:%M %p")" # AM/PM #color = rgba(255, 185, 0, .8) - color = $color13 - font_size = 240 + color = $color8 + font_size = 173 font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -100 + position = 0, -333 halign = center valign = top } -# Minute-Time -label { - monitor = - text = cmd[update:1000] echo "$(date +"%M")" - #color = rgba(15, 10, 222, .8) - color = $color12 - font_size = 240 - font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -450 - halign = center - valign = top -} - -# Seconds-Time -label { - monitor = - text = cmd[update:1000] echo "$(date +"%S")" -# text = cmd[update:1000] echo "$(date +"%S %p")" #AM/PM - color = $color11 - font_size = 50 - font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -450 - halign = center - valign = top -} +# Minute-Time (disabled; kept for reference) +# label { +# monitor = +# text = cmd[update:1000] echo "$(date +"%M")" +# #color = rgba(15, 10, 222, .8) +# color = $color12 +# font_size = 240 +# font_family = JetBrainsMono Nerd Font ExtraBold +# position = 0, -450 +# halign = center +# valign = top +# } + +# Seconds-Time (disabled; kept for reference) +# label { +# monitor = +# text = cmd[update:1000] echo "$(date +"%S")" +# # text = cmd[update:1000] echo "$(date +"%S %p")" #AM/PM +# color = $color11 +# font_size = 50 +# font_family = JetBrainsMono Nerd Font ExtraBold +# position = 0, -450 +# halign = center +# valign = top +# } # Put a picture of choice here. Default is the current wallpaper #image { @@ -103,10 +103,10 @@ label { label { monitor = text = ๏Šพ $USER - color = $color13 - font_size = 24 + color = $color9 + font_size = 48 font_family = Victor Mono Bold Oblique - position = 0, 280 + position = 0, 366 halign = center valign = bottom } @@ -114,33 +114,32 @@ label { # INPUT FIELD input-field { monitor = - size = 300, 60 + size = 306, 93 outline_thickness = 2 dots_size = 0.2 # Scale of input-field height, 0.2 - 0.8 dots_spacing = 0.2 # Scale of dots' absolute size, 0.0 - 1.0 dots_center = true - outer_color = $color11 + outer_color = $color8 inner_color = rgba(255, 255, 255, 0.1) + capslock_color = rgb(255,255,255) font_color = $color13 - capslock_color = rgb(255,255,255) fade_on_empty = false font_family = Victor Mono Bold Oblique placeholder_text = ๐Ÿ”’ Type Password hide_input = false - position = 0, 120 + position = 0, 133 halign = center valign = bottom } - # Keyboard LAYOUT label { monitor = text = $LAYOUT - color = $color13 - font_size = 12 + color = $color8 + font_size = 19 font_family = Victor Mono Bold Oblique - position = 0, 80 + position = 0, 93 halign = center valign = bottom } @@ -149,8 +148,8 @@ label { label { monitor = text = cmd[update:60000] echo " "$(uptime -p || $Scripts/UptimeNixOS.sh)" " - color = $color13 - font_size = 18 + color = $color8 + font_size = 32 font_family = Victor Mono Bold Oblique position = 0, 0 halign = right @@ -161,10 +160,10 @@ label { label { monitor = text = cmd[update:1000] echo " "$($Scripts/Battery.sh)" " - color = $color13 - font_size = 18 + color = $color8 + font_size = 21 font_family = Victor Mono Bold Oblique - position = 0, 30 + position = 0, 40 halign = right valign = bottom } @@ -175,8 +174,8 @@ label { label { monitor = text = cmd[update:3600000] [ -f "$HOME/.cache/.weather_cache" ] && cat "$HOME/.cache/.weather_cache" - color = $color13 - font_size = 18 + color = $color8 + font_size = 19 font_family = Victor Mono Bold Oblique position = 50, 0 halign = left -- cgit v1.2.3 From 872b09fa88825ec5631ba3cdc21e0e717ec241ee Mon Sep 17 00:00:00 2001 From: Don Williams Date: Thu, 13 Nov 2025 14:26:34 -0500 Subject: Adj layout for 2k+ monitors On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: hyprlock.conf --- config/hypr/hyprlock.conf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/config/hypr/hyprlock.conf b/config/hypr/hyprlock.conf index 5aa66adc..f359357f 100644 --- a/config/hypr/hyprlock.conf +++ b/config/hypr/hyprlock.conf @@ -39,7 +39,7 @@ label { color = $color13 font_size = 64 font_family = Victor Mono Bold Italic - position = 0, -80 + position = 0, -20 halign = center valign = center } @@ -53,7 +53,7 @@ label { color = $color8 font_size = 173 font_family = JetBrainsMono Nerd Font ExtraBold - position = 0, -333 + position = 0, -133 halign = center valign = top } @@ -106,7 +106,7 @@ label { color = $color9 font_size = 48 font_family = Victor Mono Bold Oblique - position = 0, 366 + position = 0, 300 halign = center valign = bottom } @@ -127,7 +127,7 @@ input-field { font_family = Victor Mono Bold Oblique placeholder_text = ๐Ÿ”’ Type Password hide_input = false - position = 0, 133 + position = 0, 100 halign = center valign = bottom } @@ -139,7 +139,7 @@ label { color = $color8 font_size = 19 font_family = Victor Mono Bold Oblique - position = 0, 93 + position = 0, 53 halign = center valign = bottom } -- cgit v1.2.3 From f9e882782d23b2869cd272841af12f7e0ce2ad37 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 14 Nov 2025 12:10:46 -0500 Subject: hyprctl dispatch returned success w/o QS installed On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/scripts/OverviewToggle.sh --- config/hypr/scripts/OverviewToggle.sh | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/config/hypr/scripts/OverviewToggle.sh b/config/hypr/scripts/OverviewToggle.sh index 21c2da34..2737234c 100755 --- a/config/hypr/scripts/OverviewToggle.sh +++ b/config/hypr/scripts/OverviewToggle.sh @@ -5,11 +5,15 @@ set -euo pipefail # 1) Try Quickshell via Hyprland global dispatch (works if QS is running and listening) -if hyprctl dispatch global quickshell:overviewToggle >/dev/null 2>&1; then - exit 0 +# Only attempt this if a Quickshell process is running; otherwise Hyprland will +# still return success for the dispatch and we'll never fall back to AGS. +if pgrep -x quickshell >/dev/null 2>&1; then + if hyprctl dispatch global quickshell:overviewToggle >/dev/null 2>&1; then + exit 0 + fi fi -# If QS isn't running, try starting it and retry once +# If QS isn't running, but the CLI exists, try starting it and retry once if command -v qs >/dev/null 2>&1; then qs >/dev/null 2>&1 & sleep 0.6 -- cgit v1.2.3 From 0a9484f35e7726c697e1e64b27355a5f9ebc53b0 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 14 Nov 2025 12:27:19 -0500 Subject: Fixed SUPER J/K ping ponging On branch development Your branch is up to date with 'origin/development'. Changes to be committed: new file: CHANGES-v2.3.18.md modified: config/hypr/scripts/ChangeLayout.sh modified: config/hypr/scripts/KeybindsLayoutInit.sh --- CHANGES-v2.3.18.md | 19 +++++++++++++++ config/hypr/scripts/ChangeLayout.sh | 10 ++------ config/hypr/scripts/KeybindsLayoutInit.sh | 40 +++++++------------------------ 3 files changed, 29 insertions(+), 40 deletions(-) create mode 100644 CHANGES-v2.3.18.md diff --git a/CHANGES-v2.3.18.md b/CHANGES-v2.3.18.md new file mode 100644 index 00000000..97af5183 --- /dev/null +++ b/CHANGES-v2.3.18.md @@ -0,0 +1,19 @@ +# CHANGES: Hyprland-Dots v2.3.18 + +## FIXES: + +- Changed to Hyprland (only) Packages from SID + - No longer build from source + - Hyprland Version @ v0.51.1 + - If/When SID it updated, updates will be done as normal process +- Overview Toggle keyind SUPER + A now properly detects QS +- If QS fails, or not installed AGS will be started instead +- Fixed Super J/K cycle next/prev being activated switch + +## CHANGES: + +- Lock screen + - Clock now horizontal and smaller + - Adjust spacing margines of the various fields + - Small changes to color variabbles Trying to balance colors + - Fixed both 1080 and 2K+ configurations diff --git a/config/hypr/scripts/ChangeLayout.sh b/config/hypr/scripts/ChangeLayout.sh index 78428188..e2436b79 100755 --- a/config/hypr/scripts/ChangeLayout.sh +++ b/config/hypr/scripts/ChangeLayout.sh @@ -9,20 +9,14 @@ LAYOUT=$(hyprctl -j getoption general:layout | jq '.str' | sed 's/"//g') case $LAYOUT in "master") hyprctl keyword general:layout dwindle - hyprctl keyword unbind SUPER,J - hyprctl keyword unbind SUPER,K - hyprctl keyword bind SUPER,J,cyclenext - hyprctl keyword bind SUPER,K,cyclenext,prev + # SUPER+J/K are global and managed by KeybindsLayoutInit.sh; only manage SUPER+O here hyprctl keyword bind SUPER,O,togglesplit notify-send -e -u low -i "$notif" " Dwindle Layout" ;; "dwindle") hyprctl keyword general:layout master - hyprctl keyword unbind SUPER,J - hyprctl keyword unbind SUPER,K + # Drop togglesplit binding on SUPER+O when switching back to master hyprctl keyword unbind SUPER,O - hyprctl keyword bind SUPER,J,layoutmsg,cyclenext - hyprctl keyword bind SUPER,K,layoutmsg,cycleprev notify-send -e -u low -i "$notif" " Master Layout" ;; *) ;; diff --git a/config/hypr/scripts/KeybindsLayoutInit.sh b/config/hypr/scripts/KeybindsLayoutInit.sh index fd34f90e..0a53eaaf 100755 --- a/config/hypr/scripts/KeybindsLayoutInit.sh +++ b/config/hypr/scripts/KeybindsLayoutInit.sh @@ -1,38 +1,14 @@ #!/usr/bin/env bash # /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ ## -# Initialize J/K keybinds to match the current default layout at startup +# Initialize J/K keybinds so they always cycle windows globally (no layout-specific behavior) +# This avoids double-actions when layouts change. set -euo pipefail -# Determine current layout (master|dwindle); be robust to null at startup -LAYOUT=$(hyprctl -j getoption general:layout | jq -r '.str // empty' 2>/dev/null || true) -if [ -z "${LAYOUT:-}" ]; then - # Fallback: parse non-JSON output (e.g., "str: dwindle") - LAYOUT=$(hyprctl getoption general:layout 2>/dev/null | awk -F'str:' 'NF>1 {gsub(/^ +| +$/,"",$2); print $2}') -fi -[ -z "${LAYOUT:-}" ] && exit 0 +# Always reset and bind SUPER+J/K the same way on startup +hyprctl keyword unbind SUPER,J || true +hyprctl keyword unbind SUPER,K || true -case "$LAYOUT" in - master) - # Ensure master layout-style binds - hyprctl keyword unbind SUPER,J - hyprctl keyword unbind SUPER,K - hyprctl keyword unbind SUPER,O - hyprctl keyword bind SUPER,J,layoutmsg,cyclenext - hyprctl keyword bind SUPER,K,layoutmsg,cycleprev - ;; - dwindle) - # Ensure dwindle layout-style binds - hyprctl keyword unbind SUPER,J - hyprctl keyword unbind SUPER,K - hyprctl keyword unbind SUPER,O - hyprctl keyword bind SUPER,J,cyclenext - hyprctl keyword bind SUPER,K,cyclenext,prev - # ensure SUPER+O togglesplit is available on dwindle - hyprctl keyword bind SUPER,O,togglesplit - ;; - *) - # Do nothing for unexpected values - : - ;; - esac +# Cycle windows globally: J = next, K = previous +hyprctl keyword bind SUPER,J,cyclenext +hyprctl keyword bind SUPER,K,cyclenext,prev -- cgit v1.2.3 From 7741755ccff931fe8eb93903093a12199fae78fb Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 14 Nov 2025 16:44:40 -0500 Subject: Updated Changelog On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: CHANGES-v2.3.18.md --- CHANGES-v2.3.18.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/CHANGES-v2.3.18.md b/CHANGES-v2.3.18.md index 97af5183..ba169c1f 100644 --- a/CHANGES-v2.3.18.md +++ b/CHANGES-v2.3.18.md @@ -3,12 +3,24 @@ ## FIXES: - Changed to Hyprland (only) Packages from SID - - No longer build from source + - No longer built from source - Hyprland Version @ v0.51.1 - If/When SID it updated, updates will be done as normal process -- Overview Toggle keyind SUPER + A now properly detects QS +- Overview Toggle keyind SUPER + A now properly detects QuickShell - If QS fails, or not installed AGS will be started instead -- Fixed Super J/K cycle next/prev being activated switch +- Fixed Super J/K cycle next/prev weren't working in both master / dwindle +- Fixed Weather.py one-off run +- Removed Hyprsunt from status group. -- Credit: Alberson Miranda +- Added more application icons for waybars +- Weather.py basically rewritten to improve look and functionality +- Credit: Prabin Panta + The Jak team also heavily contributed to the rewrite +- Waybar fixed + - Changing the waybar config would sometimes require it to be done twice + - Cause: options were incorrect annotated with "๐Ÿ‘‰ ${name}" +- `GameMode.sh` fixed to function consistently +- Updated `WalllustSwww.sh` wallpaper path +- Corrected typo in Show Open Apps ## CHANGES: @@ -17,3 +29,36 @@ - Adjust spacing margines of the various fields - Small changes to color variabbles Trying to balance colors - Fixed both 1080 and 2K+ configurations +- `UserConfigs/Startup_App.conf` is now sourced in `hyprland.conf` +- It was being sourced twice +- Some scripts weren't executable + - `scripts/Battery.sh` + - `scripts/ComposeHyprConfigs.sh` + - `scripts/OverviewToggle.sh` + - `scripts/sddm_wallpaper.sh` +- SWWW updated to v0.11.2 +- Fixes numerous issues +- Portrait monitors especially +- SWWW isn't being maintained In future will switch to AWWWW +- Added a message before installing wallpapers that some are AI generated or enhanced +- Changed `/usr/bin/bash` to `/usr/bin/evn bash` for better portability +- Small adjustment to `DropDownterminal.sh` +- Increased top margin % to center it more +- Widdened it. +- These options are settable in the script. + +## FEATURES: + +- Hyprsunet retains last state on/off + - Credit: Alberson Miranda +- Fastfetch now displays the version of the Jak Dotfiles +- ChangeLayout.sh + - Dynamically binds SUPER J/K based on current layout + - Previously only worked in Master Layout + - Credit: Suresh Thagunna + - Along with that KeybindsLayoutInit script reads current default layout + - Then it adjusts the SUPER J/K keybindings appropriately +- RofiBeats dynamic music system added +- Binds now included descriptions. +- Switched from `bind` to `bindd` +- Improves usability of keybind search -- cgit v1.2.3 From 58361c13b62f264049e2ad5703628a010a0c6574 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 14 Nov 2025 16:52:29 -0500 Subject: Text cleanup of Changelog --- CHANGES-v2.3.18.md | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/CHANGES-v2.3.18.md b/CHANGES-v2.3.18.md index ba169c1f..f6f9ecd9 100644 --- a/CHANGES-v2.3.18.md +++ b/CHANGES-v2.3.18.md @@ -2,11 +2,7 @@ ## FIXES: -- Changed to Hyprland (only) Packages from SID - - No longer built from source - - Hyprland Version @ v0.51.1 - - If/When SID it updated, updates will be done as normal process -- Overview Toggle keyind SUPER + A now properly detects QuickShell +- Fixed: Overview Toggle keyind SUPER + A now properly detects QuickShell - If QS fails, or not installed AGS will be started instead - Fixed Super J/K cycle next/prev weren't working in both master / dwindle - Fixed Weather.py one-off run @@ -24,28 +20,32 @@ ## CHANGES: +- Changed: Hyprland Packages from SID + - No longer built from source + - Hyprland Version @ v0.51.1 + - If/When SID it updated, updates will be done as normal process - Lock screen - Clock now horizontal and smaller - Adjust spacing margines of the various fields - Small changes to color variabbles Trying to balance colors - Fixed both 1080 and 2K+ configurations - `UserConfigs/Startup_App.conf` is now sourced in `hyprland.conf` -- It was being sourced twice + - It was being sourced twice - Some scripts weren't executable - `scripts/Battery.sh` - `scripts/ComposeHyprConfigs.sh` - `scripts/OverviewToggle.sh` - `scripts/sddm_wallpaper.sh` -- SWWW updated to v0.11.2 -- Fixes numerous issues -- Portrait monitors especially -- SWWW isn't being maintained In future will switch to AWWWW -- Added a message before installing wallpapers that some are AI generated or enhanced -- Changed `/usr/bin/bash` to `/usr/bin/evn bash` for better portability -- Small adjustment to `DropDownterminal.sh` -- Increased top margin % to center it more -- Widdened it. -- These options are settable in the script. +- Updated: SWWW to v0.11.2 + - Fixes numerous issues + - Portrait monitors especially + - SWWW isn't being maintained In future will switch to AWWWW +- Added: A message before installing wallpapers that some are AI generated or enhanced +- Changed: `/usr/bin/bash` to `/usr/bin/evn bash` for better portability +- Adjusted: Small change to `DropDownterminal.sh` + - Increased top margin % to center it more + - Widdened it. + - These options are settable in the script. ## FEATURES: @@ -59,6 +59,8 @@ - Along with that KeybindsLayoutInit script reads current default layout - Then it adjusts the SUPER J/K keybindings appropriately - RofiBeats dynamic music system added -- Binds now included descriptions. -- Switched from `bind` to `bindd` -- Improves usability of keybind search +- Binds now include descriptions. + - Switched from `bind` to `bindd` + - Improves usability of keybind search + +Thanks to everyone that contributed, or reported issues. -- cgit v1.2.3 From 1f3ef992bf1afffc70636493ec40309a78ae0f3a Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 14 Nov 2025 16:54:41 -0500 Subject: Text cleanup of Changelog --- CHANGES-v2.3.18.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGES-v2.3.18.md b/CHANGES-v2.3.18.md index f6f9ecd9..d7aebe06 100644 --- a/CHANGES-v2.3.18.md +++ b/CHANGES-v2.3.18.md @@ -6,11 +6,12 @@ - If QS fails, or not installed AGS will be started instead - Fixed Super J/K cycle next/prev weren't working in both master / dwindle - Fixed Weather.py one-off run -- Removed Hyprsunt from status group. -- Credit: Alberson Miranda +- Removed Hyprsunt from status group. + - Credit: Alberson Miranda - Added more application icons for waybars - Weather.py basically rewritten to improve look and functionality -- Credit: Prabin Panta - The Jak team also heavily contributed to the rewrite + - Credit: Prabin Panta + - The Jak team also heavily contributed to the rewrite - Waybar fixed - Changing the waybar config would sometimes require it to be done twice - Cause: options were incorrect annotated with "๐Ÿ‘‰ ${name}" @@ -44,7 +45,7 @@ - Changed: `/usr/bin/bash` to `/usr/bin/evn bash` for better portability - Adjusted: Small change to `DropDownterminal.sh` - Increased top margin % to center it more - - Widdened it. + - Widened it. - These options are settable in the script. ## FEATURES: -- cgit v1.2.3 From 78d15254ee56be6013af754714eaf14c44535b53 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 14 Nov 2025 16:57:56 -0500 Subject: Text cleanup of Changelog --- CHANGES-v2.3.18.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGES-v2.3.18.md b/CHANGES-v2.3.18.md index d7aebe06..4f76a5d0 100644 --- a/CHANGES-v2.3.18.md +++ b/CHANGES-v2.3.18.md @@ -3,21 +3,21 @@ ## FIXES: - Fixed: Overview Toggle keyind SUPER + A now properly detects QuickShell -- If QS fails, or not installed AGS will be started instead -- Fixed Super J/K cycle next/prev weren't working in both master / dwindle -- Fixed Weather.py one-off run -- Removed Hyprsunt from status group. + - If QS fails, or not installed AGS will be started instead +- Fixed: Super J/K cycle next/prev weren't working in both master / dwindle +- Fixed: Weather.py one-off run +- Removed: Hyprsunt from status group. - Credit: Alberson Miranda -- Added more application icons for waybars +- Added: more application icons for waybars - Weather.py basically rewritten to improve look and functionality - Credit: Prabin Panta - The Jak team also heavily contributed to the rewrite -- Waybar fixed - - Changing the waybar config would sometimes require it to be done twice +- Fixed: Waybar + - Changing the waybar config `SUPERALT + B` would sometimes need to be done twice - Cause: options were incorrect annotated with "๐Ÿ‘‰ ${name}" -- `GameMode.sh` fixed to function consistently -- Updated `WalllustSwww.sh` wallpaper path -- Corrected typo in Show Open Apps +- Fixed: `GameMode.sh` to function consistently +- Updated: `WalllustSwww.sh` wallpaper path +- Corrected: Typo in Show Open Apps ## CHANGES: @@ -25,7 +25,7 @@ - No longer built from source - Hyprland Version @ v0.51.1 - If/When SID it updated, updates will be done as normal process -- Lock screen +- Lock screen: - Clock now horizontal and smaller - Adjust spacing margines of the various fields - Small changes to color variabbles Trying to balance colors -- cgit v1.2.3 From 4015eea740904baca74a7e6c772e866128ac2a2f Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 19 Nov 2025 17:39:16 -0500 Subject: Added 1st pass at WindowsRules v3 On branch development Your branch is up to date with 'origin/development'. Changes to be committed: new file: config/hypr/UserConfigs/WindowRules.conf-v3.conf --- config/hypr/UserConfigs/WindowRules.conf-v3.conf | 692 +++++++++++++++++++++++ 1 file changed, 692 insertions(+) create mode 100644 config/hypr/UserConfigs/WindowRules.conf-v3.conf diff --git a/config/hypr/UserConfigs/WindowRules.conf-v3.conf b/config/hypr/UserConfigs/WindowRules.conf-v3.conf new file mode 100644 index 00000000..a35504f1 --- /dev/null +++ b/config/hypr/UserConfigs/WindowRules.conf-v3.conf @@ -0,0 +1,692 @@ +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # +# For window rules and layerrules +# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more + +# NOTES: This is only for Hyprland > 0.48 + +# note for ja: This should NOT be implemented on Debian and Ubuntu + +# windowrule - tags - add apps under appropriate tag to use the same settings +# browser tags + +# notif tags + +# KooL settings tag + +# terminal tags + +# email tags + +# project tags + +# screenshare tags + +# IM tags + +# game tags + +# gamestore tags + +# file-manager tags + +# wallpaper tags + +# multimedia tags + +# multimedia-video tags + +# settings tags + +# viewer tags + +# Some special override rules + +# POSITION +# windowrule = center,floating:1 # warning, it cause even the menu to float and center. +#windowrule = move 72% 7%,title:^(Firefox)$ + +# windowrule to avoid idle for fullscreen apps +#windowrule = idleinhibit fullscreen, class:^(*)$ +#windowrule = idleinhibit fullscreen, title:^(*)$ + +# windowrule move to workspace +#windowrule = workspace 1, tag:email* +#windowrule = workspace 2, tag:browser* +#windowrule = workspace 3, class:^([Tt]hunar)$ +#windowrule = workspace 3, tag:projects* +#windowrule = workspace 5, tag:gamestore* +#windowrule = workspace 7, tag:im* +#windowrule = workspace 8, tag:games* + +# windowrule move to workspace (silent) +#windowrule = workspace 4 silent, tag:screenshare* +#windowrule = workspace 6 silent, class:^(virt-manager)$ +#windowrule = workspace 6 silent, class:^(.virt-manager-wrapped)$ +#windowrule = workspace 9 silent, tag:multimedia* +# +# FLOAT +#windowrule = float, class:^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ +#windowrule = float, title:^(Firefox)$ + +# windowrule - ######### float popups and dialogue ####### + + + + +# END of float popups and dialogue ####### + +# OPACITY + +# SIZE + +#windowrule = size 25% 25%, title:^(Picture-in-Picture)$ +#windowrule = size 25% 25%, title:^(Firefox)$ + +# PINNING +#windowrule = pin,title:^(Firefox)$ + +# windowrule - extras + +# BLUR & FULLSCREEN + + +#This not gonna take the focus to the window that appears when hovering over some of the parts of the IntelliJ Products + +#This will gonna make the VS Code bluer like other apps + +#windowrule = bordercolor rgb(EE4B55) rgb(880808), fullscreen:1 +#windowrule = bordercolor rgb(282737) rgb(1E1D2D), floating:1 +#windowrule = opacity 0.8 0.8, pinned:1 + +# LAYER RULES + +#layerrule = ignorealpha 0.5, tag:notif* + +#layerrule = ignorezero, class:^([Rr]ofi)$ +#layerrule = blur, class:^([Rr]ofi)$ +#layerrule = unset,class:^([Rr]ofi)$ +#layerrule = ignorezero, + +#layerrule = ignorezero, overview +#layerrule = blur, overview + +# --- Auto-generated window rules --- +windowrule { + name = windowrule-1 + match:class = ^([Ff]irefox|org.mozilla.firefox|[Ff]irefox-esr|[Ff]irefox-bin)$ + tag = +browser +} + +windowrule { + name = windowrule-2 + match:class = ^([Gg]oogle-chrome(-beta|-dev|-unstable)?)$ + tag = +browser +} + +windowrule { + name = windowrule-3 + match:class = ^(chrome-.+-Default)$ # Chrome PWAs + tag = +browser +} + +windowrule { + name = windowrule-4 + match:class = ^([Cc]hromium)$ + tag = +browser +} + +windowrule { + name = windowrule-5 + match:class = ^([Mm]icrosoft-edge(-stable|-beta|-dev|-unstable))$ + tag = +browser +} + +windowrule { + name = windowrule-6 + match:class = ^(Brave-browser(-beta|-dev|-unstable)?)$ + tag = +browser +} + +windowrule { + name = windowrule-7 + match:class = ^([Tt]horium-browser|[Cc]achy-browser)$ + tag = +browser +} + +windowrule { + name = windowrule-8 + match:class = ^(zen-alpha|zen)$ + tag = +browser +} + +windowrule { + name = windowrule-9 + match:class = ^(swaync-control-center|swaync-notification-window|swaync-client|class)$ + tag = +notif +} + +windowrule { + name = windowrule-10 + match:title = ^(KooL Quick Cheat Sheet)$ + tag = +KooL_Cheat +} + +windowrule { + name = windowrule-11 + match:title = ^(KooL Hyprland Settings)$ + tag = +KooL_Settings +} + +windowrule { + name = windowrule-12 + match:class = ^(nwg-displays|nwg-look)$ + tag = +KooL-Settings +} + +windowrule { + name = windowrule-13 + match:class = ^(Alacritty|kitty|kitty-dropterm)$ + tag = +terminal +} + +windowrule { + name = windowrule-14 + match:class = ^([Tt]hunderbird|org.gnome.Evolution)$ + tag = +email +} + +windowrule { + name = windowrule-15 + match:class = ^(eu.betterbird.Betterbird)$ + tag = +email +} + +windowrule { + name = windowrule-16 + match:class = ^(codium|codium-url-handler|VSCodium)$ + tag = +projects +} + +windowrule { + name = windowrule-17 + match:class = ^(VSCode|code-url-handler)$ + tag = +projects +} + +windowrule { + name = windowrule-18 + match:class = ^(jetbrains-.+)$ # JetBrains IDEs + tag = +projects +} + +windowrule { + name = windowrule-19 + match:class = ^(com.obsproject.Studio)$ + tag = +screenshare +} + +windowrule { + name = windowrule-20 + match:class = ^([Dd]iscord|[Ww]ebCord|[Vv]esktop)$ + tag = +im +} + +windowrule { + name = windowrule-21 + match:class = ^([Ff]erdium)$ + center = on + float = on + size = 60% = 70% + tag = +im +} + +windowrule { + name = windowrule-22 + match:class = ^([Ww]hatsapp-for-linux)$ + tag = +im +} + +windowrule { + name = windowrule-23 + match:class = ^(ZapZap|com.rtosta.zapzap)$ + tag = +im +} + +windowrule { + name = windowrule-24 + match:class = ^(org.telegram.desktop|io.github.tdesktop_x64.TDesktop)$ + tag = +im +} + +windowrule { + name = windowrule-25 + match:class = ^(teams-for-linux)$ + tag = +im +} + +windowrule { + name = windowrule-26 + match:class = ^(im.riot.Riot|Element)$ # Element Matrix client + tag = +im +} + +windowrule { + name = windowrule-27 + match:class = ^(gamescope)$ + tag = +games +} + +windowrule { + name = windowrule-28 + match:class = ^(steam_app_\d+)$ + tag = +games +} + +windowrule { + name = windowrule-29 + match:class = ^([Ss]team)$ + tag = +gamestore +} + +windowrule { + name = windowrule-30 + match:title = ^([Ll]utris)$ + tag = +gamestore +} + +windowrule { + name = windowrule-31 + match:class = ^(com.heroicgameslauncher.hgl)$ + tag = +gamestore +} + +windowrule { + name = windowrule-32 + match:class = ^([Tt]hunar|org.gnome.Nautilus|[Pp]cmanfm-qt)$ + tag = +file-manager +} + +windowrule { + name = windowrule-33 + match:class = ^(app.drey.Warp)$ + tag = +file-manager +} + +windowrule { + name = windowrule-34 + match:class = ^([Ww]aytrogen)$ + tag = +wallpaper +} + +windowrule { + name = windowrule-35 + match:class = ^([Aa]udacious)$ + tag = +multimedia +} + +windowrule { + name = windowrule-36 + match:class = ^([Mm]pv|vlc)$ + tag = +multimedia_video +} + +windowrule { + name = windowrule-37 + match:title = ^(ROG Control)$ + center = on + tag = +settings +} + +windowrule { + name = windowrule-38 + match:class = ^(wihotspot(-gui)?)$ # wifi hotspot + tag = +settings +} + +windowrule { + name = windowrule-39 + match:class = ^([Bb]aobab|org.gnome.[Bb]aobab)$ # Disk usage analyzer + tag = +settings +} + +windowrule { + name = windowrule-40 + match:class = ^(gnome-disks|wihotspot(-gui)?)$ + tag = +settings +} + +windowrule { + name = windowrule-41 + match:title = (Kvantum Manager) + tag = +settings +} + +windowrule { + name = windowrule-42 + match:class = ^(file-roller|org.gnome.FileRoller)$ # archive manager + tag = +settings +} + +windowrule { + name = windowrule-43 + match:class = ^(nm-applet|nm-connection-editor|blueman-manager)$ + tag = +settings +} + +windowrule { + name = windowrule-44 + match:class = ^(pavucontrol|org.pulseaudio.pavucontrol|com.saivert.pwvucontrol)$ + center = on + tag = +settings +} + +windowrule { + name = windowrule-45 + match:class = ^(qt5ct|qt6ct|[Yy]ad)$ + tag = +settings +} + +windowrule { + name = windowrule-46 + match:class = (xdg-desktop-portal-gtk) + tag = +settings +} + +windowrule { + name = windowrule-47 + match:class = ^(org.kde.polkit-kde-authentication-agent-1)$ + tag = +settings +} + +windowrule { + name = windowrule-48 + match:class = ^([Rr]ofi)$ + tag = +settings +} + +windowrule { + name = windowrule-49 + match:class = ^(gnome-system-monitor|org.gnome.SystemMonitor|io.missioncenter.MissionCenter)$ # system monitor + tag = +viewer +} + +windowrule { + name = windowrule-50 + match:class = ^(evince)$ # document viewer + tag = +viewer +} + +windowrule { + name = windowrule-51 + match:class = ^(eog|org.gnome.Loupe)$ # image viewer + tag = +viewer +} + +windowrule { + name = windowrule-52 + match:tag = multimedia_video* + no_blur = on + opacity = 1.0 +} + +windowrule { + name = windowrule-53 + match:tag = KooL_Cheat* + center = on + float = on + size = 65% = 90% +} + +windowrule { + name = windowrule-54 + match:class = ([Tt]hunar) + match:title = negative:(.*[Tt]hunar.*) + center = on + float = on +} + +windowrule { + name = windowrule-55 + match:tag = KooL-Settings* + center = on + float = on +} + +windowrule { + name = windowrule-56 + match:title = ^(Keybindings)$ + center = on +} + +windowrule { + name = windowrule-57 + match:class = ^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ + center = on + size = 60% = 70% +} + +windowrule { + name = windowrule-58 + match:title = ^(Picture-in-Picture)$ + float = on + keepaspectratio = 1 + move = 72% = 7% + opacity = 0.95 = 0.75 + pin = 0 +} + +windowrule { + name = windowrule-59 + match:fullscreen = 1 + idle_inhibit = fullscreen +} + +windowrule { + name = windowrule-60 + match:tag = wallpaper* + float = on + opacity = 0.9 = 0.7 + size = 70% = 70% +} + +windowrule { + name = windowrule-61 + match:tag = settings* + float = on + opacity = 0.8 = 0.7 + size = 70% = 70% +} + +windowrule { + name = windowrule-62 + match:tag = viewer* + float = on + opacity = 0.82 = 0.75 +} + +windowrule { + name = windowrule-63 + match:class = ([Zz]oom|onedriver|onedriver-launcher)$ + float = on +} + +windowrule { + name = windowrule-64 + match:class = (org.gnome.Calculator) + match:title = (Calculator) + float = on +} + +windowrule { + name = windowrule-65 + match:class = ^(mpv|com.github.rafostar.Clapper)$ + float = on +} + +windowrule { + name = windowrule-66 + match:class = ^([Qq]alculate-gtk)$ + float = on +} + +windowrule { + name = windowrule-67 + match:title = ^(Authentication Required)$ + center = on + float = on +} + +windowrule { + name = windowrule-68 + match:class = (codium|codium-url-handler|VSCodium) + match:title = negative:(.*codium.*|.*VSCodium.*) + float = on +} + +windowrule { + name = windowrule-69 + match:class = ^(com.heroicgameslauncher.hgl)$ + match:title = negative:(Heroic Games Launcher) + float = on +} + +windowrule { + name = windowrule-70 + match:class = ^([Ss]team)$ + match:title = negative:^([Ss]team)$ + float = on +} + +windowrule { + name = windowrule-71 + match:title = ^(Add Folder to Workspace)$ + center = on + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-72 + match:title = ^(Save As)$ + center = on + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-73 + match:initial_title = (Open Files) + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-74 + match:title = ^(SDDM Background)$ #KooL's Dots YAD for setting SDDM background + center = on + float = on + size = 16% = 12% +} + +windowrule { + name = windowrule-75 + match:tag = browser* + opacity = 0.99 = 0.8 +} + +windowrule { + name = windowrule-76 + match:tag = projects* + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-77 + match:tag = im* + opacity = 0.94 = 0.86 +} + +windowrule { + name = windowrule-78 + match:tag = multimedia* + opacity = 0.94 = 0.86 +} + +windowrule { + name = windowrule-79 + match:tag = file-manager* + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-80 + match:tag = terminal* + opacity = 0.9 = 0.7 +} + +windowrule { + name = windowrule-81 + match:class = ^(gedit|org.gnome.TextEditor|mousepad)$ + opacity = 0.8 = 0.7 +} + +windowrule { + name = windowrule-82 + match:class = ^(deluge)$ + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-83 + match:class = ^(seahorse)$ # gnome-keyring gui + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-84 + match:class = ^(code)$ + opacity = 0.8 + opacity = 0.9 +} + +windowrule { + name = windowrule-85 + match:tag = games* + fullscreen = 0 + no_blur = on +} + +windowrule { + name = windowrule-86 + match:class = ^(jetbrains-*) + no_initial_focus = on +} + +windowrule { + name = windowrule-87 + match:title = ^(wind.*)$ + no_initial_focus = on +} + +# --- Auto-generated layer rules --- +layerrule { + name = layerrule-1 + match:namespace = rofi + blur = on + ignore_alpha = 0 +} + +layerrule { + name = layerrule-2 + match:namespace = notifications + blur = on + ignore_alpha = 0 +} + +layerrule { + name = layerrule-3 + match:namespace = quickshell:overview + blur = on + ignore_alpha = 0 + ignore_alpha = 0.5 +} -- cgit v1.2.3 From 7cb667e732602e36762c31abefc1bfbb6f01c7b3 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 19 Nov 2025 18:36:51 -0500 Subject: Fixing v3 WindowRules b4 testings Tested the basic changes in NixOS. Found a couple rules here that were wrong. On branch development Your branch is up to date with 'origin/development'. Changes to be committed: renamed: config/hypr/UserConfigs/WindowRules.conf-v3.conf -> config/hypr/UserConfigs/WindowRules-v3.conf --- config/hypr/UserConfigs/WindowRules-v3.conf | 671 ++++++++++++++++++++++ config/hypr/UserConfigs/WindowRules.conf-v3.conf | 692 ----------------------- 2 files changed, 671 insertions(+), 692 deletions(-) create mode 100644 config/hypr/UserConfigs/WindowRules-v3.conf delete mode 100644 config/hypr/UserConfigs/WindowRules.conf-v3.conf diff --git a/config/hypr/UserConfigs/WindowRules-v3.conf b/config/hypr/UserConfigs/WindowRules-v3.conf new file mode 100644 index 00000000..f093faf6 --- /dev/null +++ b/config/hypr/UserConfigs/WindowRules-v3.conf @@ -0,0 +1,671 @@ +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # +# For window rules and layerrules +# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more + +# NOTES: This is only for Hyprland > 0.52 + +# note for ja: This should NOT be implemented on Debian and Ubuntu + +# windowrule - tags - add apps under appropriate tag to use the same settings +# browser tags +# notif tags +# KooL settings tag +# terminal tags +# email tags +# project tags +# screenshare tags +# IM tags +# game tags +# gamestore tags +# file-manager tags +# wallpaper tags +# multimedia tags +# multimedia-video tags +# settings tags +# viewer tags +# Some special override rules + +# POSITION +# windowrule = center,floating:1 # warning, it cause even the menu to float and center. +#windowrule = move 72% 7%,title:^(Firefox)$ + +# windowrule to avoid idle for fullscreen apps +#windowrule = idleinhibit fullscreen, class:^(*)$ +#windowrule = idleinhibit fullscreen, title:^(*)$ + +# windowrule move to workspace +#windowrule = workspace 1, tag:email* +#windowrule = workspace 2, tag:browser* +#windowrule = workspace 3, class:^([Tt]hunar)$ +#windowrule = workspace 3, tag:projects* +#windowrule = workspace 5, tag:gamestore* +#windowrule = workspace 7, tag:im* +#windowrule = workspace 8, tag:games* + +# windowrule move to workspace (silent) +#windowrule = workspace 4 silent, tag:screenshare* +#windowrule = workspace 6 silent, class:^(virt-manager)$ +#windowrule = workspace 6 silent, class:^(.virt-manager-wrapped)$ +#windowrule = workspace 9 silent, tag:multimedia* +# +# FLOAT +#windowrule = float, class:^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ +#windowrule = float, title:^(Firefox)$ + +# windowrule - ######### float popups and dialogue ####### + + +# OPACITY + +# SIZE + +#windowrule = size 25% 25%, title:^(Picture-in-Picture)$ +#windowrule = size 25% 25%, title:^(Firefox)$ + +# PINNING +#windowrule = pin,title:^(Firefox)$ + +# windowrule - extras + +# BLUR & FULLSCREEN + + +#This not gonna take the focus to the window that appears when hovering over some of the parts of the IntelliJ Products + +#This will gonna make the VS Code bluer like other apps + +#windowrule = bordercolor rgb(EE4B55) rgb(880808), fullscreen:1 +#windowrule = bordercolor rgb(282737) rgb(1E1D2D), floating:1 +#windowrule = opacity 0.8 0.8, pinned:1 + +# LAYER RULES + +#layerrule = ignorealpha 0.5, tag:notif* + +#layerrule = ignorezero, class:^([Rr]ofi)$ +#layerrule = blur, class:^([Rr]ofi)$ +#layerrule = unset,class:^([Rr]ofi)$ +#layerrule = ignorezero, + +#layerrule = ignorezero, overview +#layerrule = blur, overview + +# --- Auto-generated window rules --- +windowrule { + name = windowrule-1 + match:class = ^([Ff]irefox|org.mozilla.firefox|[Ff]irefox-esr|[Ff]irefox-bin)$ + tag = +browser +} + +windowrule { + name = windowrule-2 + match:class = ^([Gg]oogle-chrome(-beta|-dev|-unstable)?)$ + tag = +browser +} + +windowrule { + name = windowrule-3 + match:class = ^(chrome-.+-Default)$ # Chrome PWAs + tag = +browser +} + +windowrule { + name = windowrule-4 + match:class = ^([Cc]hromium)$ + tag = +browser +} + +windowrule { + name = windowrule-5 + match:class = ^([Mm]icrosoft-edge(-stable|-beta|-dev|-unstable))$ + tag = +browser +} + +windowrule { + name = windowrule-6 + match:class = ^(Brave-browser(-beta|-dev|-unstable)?)$ + tag = +browser +} + +windowrule { + name = windowrule-7 + match:class = ^([Tt]horium-browser|[Cc]achy-browser)$ + tag = +browser +} + +windowrule { + name = windowrule-8 + match:class = ^(zen-alpha|zen)$ + tag = +browser +} + +windowrule { + name = windowrule-9 + match:class = ^(swaync-control-center|swaync-notification-window|swaync-client|class)$ + tag = +notif +} + +windowrule { + name = windowrule-10 + match:title = ^(KooL Quick Cheat Sheet)$ + tag = +KooL_Cheat +} + +windowrule { + name = windowrule-11 + match:title = ^(KooL Hyprland Settings)$ + tag = +KooL_Settings +} + +windowrule { + name = windowrule-12 + match:class = ^(nwg-displays|nwg-look)$ + tag = +KooL-Settings +} + +windowrule { + name = windowrule-13 + match:class = ^(Alacritty|kitty|kitty-dropterm)$ + tag = +terminal +} + +windowrule { + name = windowrule-14 + match:class = ^([Tt]hunderbird|org.gnome.Evolution)$ + tag = +email +} + +windowrule { + name = windowrule-15 + match:class = ^(eu.betterbird.Betterbird)$ + tag = +email +} + +windowrule { + name = windowrule-16 + match:class = ^(codium|codium-url-handler|VSCodium)$ + tag = +projects +} + +windowrule { + name = windowrule-17 + match:class = ^(VSCode|code-url-handler)$ + tag = +projects +} + +windowrule { + name = windowrule-18 + match:class = ^(jetbrains-.+)$ # JetBrains IDEs + tag = +projects +} + +windowrule { + name = windowrule-19 + match:class = ^(com.obsproject.Studio)$ + tag = +screenshare +} + +windowrule { + name = windowrule-20 + match:class = ^([Dd]iscord|[Ww]ebCord|[Vv]esktop)$ + tag = +im +} + +windowrule { + name = windowrule-21 + match:class = ^([Ff]erdium)$ + center = on + float = on + size = 60% = 70% + tag = +im +} + +windowrule { + name = windowrule-22 + match:class = ^([Ww]hatsapp-for-linux)$ + tag = +im +} + +windowrule { + name = windowrule-23 + match:class = ^(ZapZap|com.rtosta.zapzap)$ + tag = +im +} + +windowrule { + name = windowrule-24 + match:class = ^(org.telegram.desktop|io.github.tdesktop_x64.TDesktop)$ + tag = +im +} + +windowrule { + name = windowrule-25 + match:class = ^(teams-for-linux)$ + tag = +im +} + +windowrule { + name = windowrule-26 + match:class = ^(im.riot.Riot|Element)$ # Element Matrix client + tag = +im +} + +windowrule { + name = windowrule-27 + match:class = ^(gamescope)$ + tag = +games +} + +windowrule { + name = windowrule-28 + match:class = ^(steam_app_\d+)$ + tag = +games +} + +windowrule { + name = windowrule-29 + match:class = ^([Ss]team)$ + tag = +gamestore +} + +windowrule { + name = windowrule-30 + match:title = ^([Ll]utris)$ + tag = +gamestore +} + +windowrule { + name = windowrule-31 + match:class = ^(com.heroicgameslauncher.hgl)$ + tag = +gamestore +} + +windowrule { + name = windowrule-32 + match:class = ^([Tt]hunar|org.gnome.Nautilus|[Pp]cmanfm-qt)$ + tag = +file-manager +} + +windowrule { + name = windowrule-33 + match:class = ^(app.drey.Warp)$ + tag = +file-manager +} + +windowrule { + name = windowrule-34 + match:class = ^([Ww]aytrogen)$ + tag = +wallpaper +} + +windowrule { + name = windowrule-35 + match:class = ^([Aa]udacious)$ + tag = +multimedia +} + +windowrule { + name = windowrule-36 + match:class = ^([Mm]pv|vlc)$ + tag = +multimedia_video +} + +windowrule { + name = windowrule-37 + match:title = ^(ROG Control)$ + center = on + tag = +settings +} + +windowrule { + name = windowrule-38 + match:class = ^(wihotspot(-gui)?)$ # wifi hotspot + tag = +settings +} + +windowrule { + name = windowrule-39 + match:class = ^([Bb]aobab|org.gnome.[Bb]aobab)$ # Disk usage analyzer + tag = +settings +} + +windowrule { + name = windowrule-40 + match:class = ^(gnome-disks|wihotspot(-gui)?)$ + tag = +settings +} + +windowrule { + name = windowrule-41 + match:title = (Kvantum Manager) + tag = +settings +} + +windowrule { + name = windowrule-42 + match:class = ^(file-roller|org.gnome.FileRoller)$ # archive manager + tag = +settings +} + +windowrule { + name = windowrule-43 + match:class = ^(nm-applet|nm-connection-editor|blueman-manager)$ + tag = +settings +} + +windowrule { + name = windowrule-44 + match:class = ^(pavucontrol|org.pulseaudio.pavucontrol|com.saivert.pwvucontrol)$ + center = on + tag = +settings +} + +windowrule { + name = windowrule-45 + match:class = ^(qt5ct|qt6ct|[Yy]ad)$ + tag = +settings +} + +windowrule { + name = windowrule-46 + match:class = (xdg-desktop-portal-gtk) + tag = +settings +} + +windowrule { + name = windowrule-47 + match:class = ^(org.kde.polkit-kde-authentication-agent-1)$ + tag = +settings +} + +windowrule { + name = windowrule-48 + match:class = ^([Rr]ofi)$ + tag = +settings +} + +windowrule { + name = windowrule-49 + match:class = ^(gnome-system-monitor|org.gnome.SystemMonitor|io.missioncenter.MissionCenter)$ # system monitor + tag = +viewer +} + +windowrule { + name = windowrule-50 + match:class = ^(evince)$ # document viewer + tag = +viewer +} + +windowrule { + name = windowrule-51 + match:class = ^(eog|org.gnome.Loupe)$ # image viewer + tag = +viewer +} + +windowrule { + name = windowrule-52 + match:tag = multimedia_video* + no_blur = on + opacity = 1.0 +} + +windowrule { + name = windowrule-53 + match:tag = KooL_Cheat* + center = on + float = on + size = 65% = 90% +} + +windowrule { + name = windowrule-54 + match:class = ([Tt]hunar) + match:title = negative:(.*[Tt]hunar.*) + center = on + float = on +} + +windowrule { + name = windowrule-55 + match:tag = KooL-Settings* + center = on + float = on +} + +windowrule { + name = windowrule-56 + match:title = ^(Keybindings)$ + center = on +} + +windowrule { + name = windowrule-57 + match:class = ^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ + center = on + size = 60% = 70% +} + +windowrule { + name = windowrule-58 + match:title = ^(Picture-in-Picture)$ + float = on + move = 72% = 7% + opacity = 0.95 = 0.75 + pin = 0 +} + +windowrule { + name = windowrule-59 + match:fullscreen = 1 + idle_inhibit = fullscreen +} + +windowrule { + name = windowrule-60 + match:tag = wallpaper* + float = on + opacity = 0.9 = 0.7 + size = 70% = 70% +} + +windowrule { + name = windowrule-61 + match:tag = settings* + float = on + opacity = 0.8 = 0.7 + size = 70% = 70% +} + +windowrule { + name = windowrule-62 + match:tag = viewer* + float = on + opacity = 0.82 = 0.75 +} + +windowrule { + name = windowrule-63 + match:class = ([Zz]oom|onedriver|onedriver-launcher)$ + float = on +} + +windowrule { + name = windowrule-64 + match:class = (org.gnome.Calculator) + match:title = (Calculator) + float = on +} + +windowrule { + name = windowrule-65 + match:class = ^(mpv|com.github.rafostar.Clapper)$ + float = on +} + +windowrule { + name = windowrule-66 + match:class = ^([Qq]alculate-gtk)$ + float = on +} + +windowrule { + name = windowrule-67 + match:title = ^(Authentication Required)$ + center = on + float = on +} + +windowrule { + name = windowrule-68 + match:class = (codium|codium-url-handler|VSCodium) + match:title = negative:(.*codium.*|.*VSCodium.*) + float = on +} + +windowrule { + name = windowrule-69 + match:class = ^(com.heroicgameslauncher.hgl)$ + match:title = negative:(Heroic Games Launcher) + float = on +} + +windowrule { + name = windowrule-70 + match:class = ^([Ss]team)$ + match:title = negative:^([Ss]team)$ + float = on +} + +windowrule { + name = windowrule-71 + match:title = ^(Add Folder to Workspace)$ + center = on + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-72 + match:title = ^(Save As)$ + center = on + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-73 + match:initial_title = (Open Files) + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-74 + match:title = ^(SDDM Background)$ #KooL's Dots YAD for setting SDDM background + center = on + float = on + size = 16% = 12% +} + +windowrule { + name = windowrule-75 + match:tag = browser* + opacity = 0.99 = 0.8 +} + +windowrule { + name = windowrule-76 + match:tag = projects* + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-77 + match:tag = im* + opacity = 0.94 = 0.86 +} + +windowrule { + name = windowrule-78 + match:tag = multimedia* + opacity = 0.94 = 0.86 +} + +windowrule { + name = windowrule-79 + match:tag = file-manager* + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-80 + match:tag = terminal* + opacity = 0.9 = 0.7 +} + +windowrule { + name = windowrule-81 + match:class = ^(gedit|org.gnome.TextEditor|mousepad)$ + opacity = 0.8 = 0.7 +} + +windowrule { + name = windowrule-82 + match:class = ^(deluge)$ + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-83 + match:class = ^(seahorse)$ # gnome-keyring gui + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-84 + match:class = ^(code)$ + opacity = 0.8 + opacity = 0.9 +} + +windowrule { + name = windowrule-85 + match:tag = games* + fullscreen = 0 + no_blur = on +} + +windowrule { + name = windowrule-86 + match:class = ^(jetbrains-*) + no_initial_focus = on +} + +windowrule { + name = windowrule-87 + match:title = ^(wind.*)$ + no_initial_focus = on +} + +# --- Auto-generated layer rules --- +layerrule { + name = layerrule-1 + match:namespace = rofi + blur = on + ignore_alpha = 0 +} + +layerrule { + name = layerrule-2 + match:namespace = notifications + blur = on + ignore_alpha = 0 +} + +layerrule { + name = layerrule-3 + match:namespace = quickshell:overview + blur = on + ignore_alpha = 0 + ignore_alpha = 0.5 +} diff --git a/config/hypr/UserConfigs/WindowRules.conf-v3.conf b/config/hypr/UserConfigs/WindowRules.conf-v3.conf deleted file mode 100644 index a35504f1..00000000 --- a/config/hypr/UserConfigs/WindowRules.conf-v3.conf +++ /dev/null @@ -1,692 +0,0 @@ -# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # -# For window rules and layerrules -# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more - -# NOTES: This is only for Hyprland > 0.48 - -# note for ja: This should NOT be implemented on Debian and Ubuntu - -# windowrule - tags - add apps under appropriate tag to use the same settings -# browser tags - -# notif tags - -# KooL settings tag - -# terminal tags - -# email tags - -# project tags - -# screenshare tags - -# IM tags - -# game tags - -# gamestore tags - -# file-manager tags - -# wallpaper tags - -# multimedia tags - -# multimedia-video tags - -# settings tags - -# viewer tags - -# Some special override rules - -# POSITION -# windowrule = center,floating:1 # warning, it cause even the menu to float and center. -#windowrule = move 72% 7%,title:^(Firefox)$ - -# windowrule to avoid idle for fullscreen apps -#windowrule = idleinhibit fullscreen, class:^(*)$ -#windowrule = idleinhibit fullscreen, title:^(*)$ - -# windowrule move to workspace -#windowrule = workspace 1, tag:email* -#windowrule = workspace 2, tag:browser* -#windowrule = workspace 3, class:^([Tt]hunar)$ -#windowrule = workspace 3, tag:projects* -#windowrule = workspace 5, tag:gamestore* -#windowrule = workspace 7, tag:im* -#windowrule = workspace 8, tag:games* - -# windowrule move to workspace (silent) -#windowrule = workspace 4 silent, tag:screenshare* -#windowrule = workspace 6 silent, class:^(virt-manager)$ -#windowrule = workspace 6 silent, class:^(.virt-manager-wrapped)$ -#windowrule = workspace 9 silent, tag:multimedia* -# -# FLOAT -#windowrule = float, class:^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ -#windowrule = float, title:^(Firefox)$ - -# windowrule - ######### float popups and dialogue ####### - - - - -# END of float popups and dialogue ####### - -# OPACITY - -# SIZE - -#windowrule = size 25% 25%, title:^(Picture-in-Picture)$ -#windowrule = size 25% 25%, title:^(Firefox)$ - -# PINNING -#windowrule = pin,title:^(Firefox)$ - -# windowrule - extras - -# BLUR & FULLSCREEN - - -#This not gonna take the focus to the window that appears when hovering over some of the parts of the IntelliJ Products - -#This will gonna make the VS Code bluer like other apps - -#windowrule = bordercolor rgb(EE4B55) rgb(880808), fullscreen:1 -#windowrule = bordercolor rgb(282737) rgb(1E1D2D), floating:1 -#windowrule = opacity 0.8 0.8, pinned:1 - -# LAYER RULES - -#layerrule = ignorealpha 0.5, tag:notif* - -#layerrule = ignorezero, class:^([Rr]ofi)$ -#layerrule = blur, class:^([Rr]ofi)$ -#layerrule = unset,class:^([Rr]ofi)$ -#layerrule = ignorezero, - -#layerrule = ignorezero, overview -#layerrule = blur, overview - -# --- Auto-generated window rules --- -windowrule { - name = windowrule-1 - match:class = ^([Ff]irefox|org.mozilla.firefox|[Ff]irefox-esr|[Ff]irefox-bin)$ - tag = +browser -} - -windowrule { - name = windowrule-2 - match:class = ^([Gg]oogle-chrome(-beta|-dev|-unstable)?)$ - tag = +browser -} - -windowrule { - name = windowrule-3 - match:class = ^(chrome-.+-Default)$ # Chrome PWAs - tag = +browser -} - -windowrule { - name = windowrule-4 - match:class = ^([Cc]hromium)$ - tag = +browser -} - -windowrule { - name = windowrule-5 - match:class = ^([Mm]icrosoft-edge(-stable|-beta|-dev|-unstable))$ - tag = +browser -} - -windowrule { - name = windowrule-6 - match:class = ^(Brave-browser(-beta|-dev|-unstable)?)$ - tag = +browser -} - -windowrule { - name = windowrule-7 - match:class = ^([Tt]horium-browser|[Cc]achy-browser)$ - tag = +browser -} - -windowrule { - name = windowrule-8 - match:class = ^(zen-alpha|zen)$ - tag = +browser -} - -windowrule { - name = windowrule-9 - match:class = ^(swaync-control-center|swaync-notification-window|swaync-client|class)$ - tag = +notif -} - -windowrule { - name = windowrule-10 - match:title = ^(KooL Quick Cheat Sheet)$ - tag = +KooL_Cheat -} - -windowrule { - name = windowrule-11 - match:title = ^(KooL Hyprland Settings)$ - tag = +KooL_Settings -} - -windowrule { - name = windowrule-12 - match:class = ^(nwg-displays|nwg-look)$ - tag = +KooL-Settings -} - -windowrule { - name = windowrule-13 - match:class = ^(Alacritty|kitty|kitty-dropterm)$ - tag = +terminal -} - -windowrule { - name = windowrule-14 - match:class = ^([Tt]hunderbird|org.gnome.Evolution)$ - tag = +email -} - -windowrule { - name = windowrule-15 - match:class = ^(eu.betterbird.Betterbird)$ - tag = +email -} - -windowrule { - name = windowrule-16 - match:class = ^(codium|codium-url-handler|VSCodium)$ - tag = +projects -} - -windowrule { - name = windowrule-17 - match:class = ^(VSCode|code-url-handler)$ - tag = +projects -} - -windowrule { - name = windowrule-18 - match:class = ^(jetbrains-.+)$ # JetBrains IDEs - tag = +projects -} - -windowrule { - name = windowrule-19 - match:class = ^(com.obsproject.Studio)$ - tag = +screenshare -} - -windowrule { - name = windowrule-20 - match:class = ^([Dd]iscord|[Ww]ebCord|[Vv]esktop)$ - tag = +im -} - -windowrule { - name = windowrule-21 - match:class = ^([Ff]erdium)$ - center = on - float = on - size = 60% = 70% - tag = +im -} - -windowrule { - name = windowrule-22 - match:class = ^([Ww]hatsapp-for-linux)$ - tag = +im -} - -windowrule { - name = windowrule-23 - match:class = ^(ZapZap|com.rtosta.zapzap)$ - tag = +im -} - -windowrule { - name = windowrule-24 - match:class = ^(org.telegram.desktop|io.github.tdesktop_x64.TDesktop)$ - tag = +im -} - -windowrule { - name = windowrule-25 - match:class = ^(teams-for-linux)$ - tag = +im -} - -windowrule { - name = windowrule-26 - match:class = ^(im.riot.Riot|Element)$ # Element Matrix client - tag = +im -} - -windowrule { - name = windowrule-27 - match:class = ^(gamescope)$ - tag = +games -} - -windowrule { - name = windowrule-28 - match:class = ^(steam_app_\d+)$ - tag = +games -} - -windowrule { - name = windowrule-29 - match:class = ^([Ss]team)$ - tag = +gamestore -} - -windowrule { - name = windowrule-30 - match:title = ^([Ll]utris)$ - tag = +gamestore -} - -windowrule { - name = windowrule-31 - match:class = ^(com.heroicgameslauncher.hgl)$ - tag = +gamestore -} - -windowrule { - name = windowrule-32 - match:class = ^([Tt]hunar|org.gnome.Nautilus|[Pp]cmanfm-qt)$ - tag = +file-manager -} - -windowrule { - name = windowrule-33 - match:class = ^(app.drey.Warp)$ - tag = +file-manager -} - -windowrule { - name = windowrule-34 - match:class = ^([Ww]aytrogen)$ - tag = +wallpaper -} - -windowrule { - name = windowrule-35 - match:class = ^([Aa]udacious)$ - tag = +multimedia -} - -windowrule { - name = windowrule-36 - match:class = ^([Mm]pv|vlc)$ - tag = +multimedia_video -} - -windowrule { - name = windowrule-37 - match:title = ^(ROG Control)$ - center = on - tag = +settings -} - -windowrule { - name = windowrule-38 - match:class = ^(wihotspot(-gui)?)$ # wifi hotspot - tag = +settings -} - -windowrule { - name = windowrule-39 - match:class = ^([Bb]aobab|org.gnome.[Bb]aobab)$ # Disk usage analyzer - tag = +settings -} - -windowrule { - name = windowrule-40 - match:class = ^(gnome-disks|wihotspot(-gui)?)$ - tag = +settings -} - -windowrule { - name = windowrule-41 - match:title = (Kvantum Manager) - tag = +settings -} - -windowrule { - name = windowrule-42 - match:class = ^(file-roller|org.gnome.FileRoller)$ # archive manager - tag = +settings -} - -windowrule { - name = windowrule-43 - match:class = ^(nm-applet|nm-connection-editor|blueman-manager)$ - tag = +settings -} - -windowrule { - name = windowrule-44 - match:class = ^(pavucontrol|org.pulseaudio.pavucontrol|com.saivert.pwvucontrol)$ - center = on - tag = +settings -} - -windowrule { - name = windowrule-45 - match:class = ^(qt5ct|qt6ct|[Yy]ad)$ - tag = +settings -} - -windowrule { - name = windowrule-46 - match:class = (xdg-desktop-portal-gtk) - tag = +settings -} - -windowrule { - name = windowrule-47 - match:class = ^(org.kde.polkit-kde-authentication-agent-1)$ - tag = +settings -} - -windowrule { - name = windowrule-48 - match:class = ^([Rr]ofi)$ - tag = +settings -} - -windowrule { - name = windowrule-49 - match:class = ^(gnome-system-monitor|org.gnome.SystemMonitor|io.missioncenter.MissionCenter)$ # system monitor - tag = +viewer -} - -windowrule { - name = windowrule-50 - match:class = ^(evince)$ # document viewer - tag = +viewer -} - -windowrule { - name = windowrule-51 - match:class = ^(eog|org.gnome.Loupe)$ # image viewer - tag = +viewer -} - -windowrule { - name = windowrule-52 - match:tag = multimedia_video* - no_blur = on - opacity = 1.0 -} - -windowrule { - name = windowrule-53 - match:tag = KooL_Cheat* - center = on - float = on - size = 65% = 90% -} - -windowrule { - name = windowrule-54 - match:class = ([Tt]hunar) - match:title = negative:(.*[Tt]hunar.*) - center = on - float = on -} - -windowrule { - name = windowrule-55 - match:tag = KooL-Settings* - center = on - float = on -} - -windowrule { - name = windowrule-56 - match:title = ^(Keybindings)$ - center = on -} - -windowrule { - name = windowrule-57 - match:class = ^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ - center = on - size = 60% = 70% -} - -windowrule { - name = windowrule-58 - match:title = ^(Picture-in-Picture)$ - float = on - keepaspectratio = 1 - move = 72% = 7% - opacity = 0.95 = 0.75 - pin = 0 -} - -windowrule { - name = windowrule-59 - match:fullscreen = 1 - idle_inhibit = fullscreen -} - -windowrule { - name = windowrule-60 - match:tag = wallpaper* - float = on - opacity = 0.9 = 0.7 - size = 70% = 70% -} - -windowrule { - name = windowrule-61 - match:tag = settings* - float = on - opacity = 0.8 = 0.7 - size = 70% = 70% -} - -windowrule { - name = windowrule-62 - match:tag = viewer* - float = on - opacity = 0.82 = 0.75 -} - -windowrule { - name = windowrule-63 - match:class = ([Zz]oom|onedriver|onedriver-launcher)$ - float = on -} - -windowrule { - name = windowrule-64 - match:class = (org.gnome.Calculator) - match:title = (Calculator) - float = on -} - -windowrule { - name = windowrule-65 - match:class = ^(mpv|com.github.rafostar.Clapper)$ - float = on -} - -windowrule { - name = windowrule-66 - match:class = ^([Qq]alculate-gtk)$ - float = on -} - -windowrule { - name = windowrule-67 - match:title = ^(Authentication Required)$ - center = on - float = on -} - -windowrule { - name = windowrule-68 - match:class = (codium|codium-url-handler|VSCodium) - match:title = negative:(.*codium.*|.*VSCodium.*) - float = on -} - -windowrule { - name = windowrule-69 - match:class = ^(com.heroicgameslauncher.hgl)$ - match:title = negative:(Heroic Games Launcher) - float = on -} - -windowrule { - name = windowrule-70 - match:class = ^([Ss]team)$ - match:title = negative:^([Ss]team)$ - float = on -} - -windowrule { - name = windowrule-71 - match:title = ^(Add Folder to Workspace)$ - center = on - float = on - size = 70% = 60% -} - -windowrule { - name = windowrule-72 - match:title = ^(Save As)$ - center = on - float = on - size = 70% = 60% -} - -windowrule { - name = windowrule-73 - match:initial_title = (Open Files) - float = on - size = 70% = 60% -} - -windowrule { - name = windowrule-74 - match:title = ^(SDDM Background)$ #KooL's Dots YAD for setting SDDM background - center = on - float = on - size = 16% = 12% -} - -windowrule { - name = windowrule-75 - match:tag = browser* - opacity = 0.99 = 0.8 -} - -windowrule { - name = windowrule-76 - match:tag = projects* - opacity = 0.9 = 0.8 -} - -windowrule { - name = windowrule-77 - match:tag = im* - opacity = 0.94 = 0.86 -} - -windowrule { - name = windowrule-78 - match:tag = multimedia* - opacity = 0.94 = 0.86 -} - -windowrule { - name = windowrule-79 - match:tag = file-manager* - opacity = 0.9 = 0.8 -} - -windowrule { - name = windowrule-80 - match:tag = terminal* - opacity = 0.9 = 0.7 -} - -windowrule { - name = windowrule-81 - match:class = ^(gedit|org.gnome.TextEditor|mousepad)$ - opacity = 0.8 = 0.7 -} - -windowrule { - name = windowrule-82 - match:class = ^(deluge)$ - opacity = 0.9 = 0.8 -} - -windowrule { - name = windowrule-83 - match:class = ^(seahorse)$ # gnome-keyring gui - opacity = 0.9 = 0.8 -} - -windowrule { - name = windowrule-84 - match:class = ^(code)$ - opacity = 0.8 - opacity = 0.9 -} - -windowrule { - name = windowrule-85 - match:tag = games* - fullscreen = 0 - no_blur = on -} - -windowrule { - name = windowrule-86 - match:class = ^(jetbrains-*) - no_initial_focus = on -} - -windowrule { - name = windowrule-87 - match:title = ^(wind.*)$ - no_initial_focus = on -} - -# --- Auto-generated layer rules --- -layerrule { - name = layerrule-1 - match:namespace = rofi - blur = on - ignore_alpha = 0 -} - -layerrule { - name = layerrule-2 - match:namespace = notifications - blur = on - ignore_alpha = 0 -} - -layerrule { - name = layerrule-3 - match:namespace = quickshell:overview - blur = on - ignore_alpha = 0 - ignore_alpha = 0.5 -} -- cgit v1.2.3 From 8d0e5d201c7cb0c0ce81df6861dfa041d2ec5d7f Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 19 Nov 2025 20:42:48 -0500 Subject: Converted config/hypr/configs/WindowsRules.conf On branch development Your branch is up to date with 'origin/development'. Changes to be committed: new file: config/hypr/configs/WindowRules-config-v3.conf --- config/hypr/configs/WindowRules-config-v3.conf | 691 +++++++++++++++++++++++++ 1 file changed, 691 insertions(+) create mode 100644 config/hypr/configs/WindowRules-config-v3.conf diff --git a/config/hypr/configs/WindowRules-config-v3.conf b/config/hypr/configs/WindowRules-config-v3.conf new file mode 100644 index 00000000..7dc60a4f --- /dev/null +++ b/config/hypr/configs/WindowRules-config-v3.conf @@ -0,0 +1,691 @@ +# /* ---- ๐Ÿ’ซ https://github.com/JaKooLit ๐Ÿ’ซ ---- */ # +# Vendor defaults for window rules and layerrules +# See https://wiki.hyprland.org/Configuring/Window-Rules/ for more + +# NOTES: This is only for Hyprland > 0.48 + +# note for ja: This should NOT be implemented on Debian and Ubuntu + +# windowrule - tags - add apps under appropriate tag to use the same settings +# browser tags + +# notif tags + +# KooL settings tag + +# terminal tags + +# email tags + +# project tags + +# screenshare tags + +# IM tags + +# game tags + +# gamestore tags + +# file-manager tags + +# wallpaper tags + +# multimedia tags + +# multimedia-video tags + +# settings tags + +# viewer tags + +# Some special override rules + +# POSITION +# windowrule = center,floating:1 # warning, it cause even the menu to float and center. +#windowrule = move 72% 7%,title:^(Firefox)$ + +# windowrule to avoid idle for fullscreen apps +#windowrule = idleinhibit fullscreen, class:^(*)$ +#windowrule = idleinhibit fullscreen, title:^(*)$ + +# windowrule move to workspace +#windowrule = workspace 1, tag:email* +#windowrule = workspace 2, tag:browser* +#windowrule = workspace 3, class:^([Tt]hunar)$ +#windowrule = workspace 3, tag:projects* +#windowrule = workspace 5, tag:gamestore* +#windowrule = workspace 7, tag:im* +#windowrule = workspace 8, tag:games* + +# windowrule move to workspace (silent) +#windowrule = workspace 4 silent, tag:screenshare* +#windowrule = workspace 6 silent, class:^(virt-manager)$ +#windowrule = workspace 6 silent, class:^(.virt-manager-wrapped)$ +#windowrule = workspace 9 silent, tag:multimedia* +# +# FLOAT +#windowrule = float, class:^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ +#windowrule = float, title:^(Firefox)$ + +# windowrule - ######### float popups and dialogue ####### + + + + +# END of float popups and dialogue ####### + +# OPACITY + +# SIZE + +#windowrule = size 25% 25%, title:^(Picture-in-Picture)$ +#windowrule = size 25% 25%, title:^(Firefox)$ + +# PINNING +#windowrule = pin,title:^(Firefox)$ + +# windowrule - extras + +# BLUR & FULLSCREEN + + +#This not gonna take the focus to the window that appears when hovering over some of the parts of the IntelliJ Products + +#This will gonna make the VS Code bluer like other apps + +#windowrule = bordercolor rgb(EE4B55) rgb(880808), fullscreen:1 +#windowrule = bordercolor rgb(282737) rgb(1E1D2D), floating:1 +#windowrule = opacity 0.8 0.8, pinned:1 + +# LAYER RULES + +#layerrule = ignorealpha 0.5, tag:notif* + +#layerrule = ignorezero, class:^([Rr]ofi)$ +#layerrule = blur, class:^([Rr]ofi)$ +#layerrule = unset,class:^([Rr]ofi)$ +#layerrule = ignorezero, + +#layerrule = ignorezero, overview +#layerrule = blur, overview +# --- Auto-generated window rules --- +windowrule { + name = windowrule-1 + match:class = ^([Ff]irefox|org.mozilla.firefox|[Ff]irefox-esr|[Ff]irefox-bin)$ + tag = +browser +} + +windowrule { + name = windowrule-2 + match:class = ^([Gg]oogle-chrome(-beta|-dev|-unstable)?)$ + tag = +browser +} + +windowrule { + name = windowrule-3 + match:class = ^(chrome-.+-Default)$ # Chrome PWAs + tag = +browser +} + +windowrule { + name = windowrule-4 + match:class = ^([Cc]hromium)$ + tag = +browser +} + +windowrule { + name = windowrule-5 + match:class = ^([Mm]icrosoft-edge(-stable|-beta|-dev|-unstable))$ + tag = +browser +} + +windowrule { + name = windowrule-6 + match:class = ^(Brave-browser(-beta|-dev|-unstable)?)$ + tag = +browser +} + +windowrule { + name = windowrule-7 + match:class = ^([Tt]horium-browser|[Cc]achy-browser)$ + tag = +browser +} + +windowrule { + name = windowrule-8 + match:class = ^(zen-alpha|zen)$ + tag = +browser +} + +windowrule { + name = windowrule-9 + match:class = ^(swaync-control-center|swaync-notification-window|swaync-client|class)$ + tag = +notif +} + +windowrule { + name = windowrule-10 + match:title = ^(KooL Quick Cheat Sheet)$ + tag = +KooL_Cheat +} + +windowrule { + name = windowrule-11 + match:title = ^(KooL Hyprland Settings)$ + tag = +KooL_Settings +} + +windowrule { + name = windowrule-12 + match:class = ^(nwg-displays|nwg-look)$ + tag = +KooL-Settings +} + +windowrule { + name = windowrule-13 + match:class = ^(Alacritty|kitty|kitty-dropterm)$ + tag = +terminal +} + +windowrule { + name = windowrule-14 + match:class = ^([Tt]hunderbird|org.gnome.Evolution)$ + tag = +email +} + +windowrule { + name = windowrule-15 + match:class = ^(eu.betterbird.Betterbird)$ + tag = +email +} + +windowrule { + name = windowrule-16 + match:class = ^(codium|codium-url-handler|VSCodium)$ + tag = +projects +} + +windowrule { + name = windowrule-17 + match:class = ^(VSCode|code-url-handler)$ + tag = +projects +} + +windowrule { + name = windowrule-18 + match:class = ^(jetbrains-.+)$ # JetBrains IDEs + tag = +projects +} + +windowrule { + name = windowrule-19 + match:class = ^(com.obsproject.Studio)$ + tag = +screenshare +} + +windowrule { + name = windowrule-20 + match:class = ^([Dd]iscord|[Ww]ebCord|[Vv]esktop)$ + tag = +im +} + +windowrule { + name = windowrule-21 + match:class = ^([Ff]erdium)$ + center = on + float = on + size = 60% = 70% + tag = +im +} + +windowrule { + name = windowrule-22 + match:class = ^([Ww]hatsapp-for-linux)$ + tag = +im +} + +windowrule { + name = windowrule-23 + match:class = ^(ZapZap|com.rtosta.zapzap)$ + tag = +im +} + +windowrule { + name = windowrule-24 + match:class = ^(org.telegram.desktop|io.github.tdesktop_x64.TDesktop)$ + tag = +im +} + +windowrule { + name = windowrule-25 + match:class = ^(teams-for-linux)$ + tag = +im +} + +windowrule { + name = windowrule-26 + match:class = ^(im.riot.Riot|Element)$ # Element Matrix client + tag = +im +} + +windowrule { + name = windowrule-27 + match:class = ^(gamescope)$ + tag = +games +} + +windowrule { + name = windowrule-28 + match:class = ^(steam_app_\d+)$ + tag = +games +} + +windowrule { + name = windowrule-29 + match:class = ^([Ss]team)$ + tag = +gamestore +} + +windowrule { + name = windowrule-30 + match:title = ^([Ll]utris)$ + tag = +gamestore +} + +windowrule { + name = windowrule-31 + match:class = ^(com.heroicgameslauncher.hgl)$ + tag = +gamestore +} + +windowrule { + name = windowrule-32 + match:class = ^([Tt]hunar|org.gnome.Nautilus|[Pp]cmanfm-qt)$ + tag = +file-manager +} + +windowrule { + name = windowrule-33 + match:class = ^(app.drey.Warp)$ + tag = +file-manager +} + +windowrule { + name = windowrule-34 + match:class = ^([Ww]aytrogen)$ + tag = +wallpaper +} + +windowrule { + name = windowrule-35 + match:class = ^([Aa]udacious)$ + tag = +multimedia +} + +windowrule { + name = windowrule-36 + match:class = ^([Mm]pv|vlc)$ + tag = +multimedia_video +} + +windowrule { + name = windowrule-37 + match:title = ^(ROG Control)$ + center = on + tag = +settings +} + +windowrule { + name = windowrule-38 + match:class = ^(wihotspot(-gui)?)$ # wifi hotspot + tag = +settings +} + +windowrule { + name = windowrule-39 + match:class = ^([Bb]aobab|org.gnome.[Bb]aobab)$ # Disk usage analyzer + tag = +settings +} + +windowrule { + name = windowrule-40 + match:class = ^(gnome-disks|wihotspot(-gui)?)$ + tag = +settings +} + +windowrule { + name = windowrule-41 + match:title = (Kvantum Manager) + tag = +settings +} + +windowrule { + name = windowrule-42 + match:class = ^(file-roller|org.gnome.FileRoller)$ # archive manager + tag = +settings +} + +windowrule { + name = windowrule-43 + match:class = ^(nm-applet|nm-connection-editor|blueman-manager)$ + tag = +settings +} + +windowrule { + name = windowrule-44 + match:class = ^(pavucontrol|org.pulseaudio.pavucontrol|com.saivert.pwvucontrol)$ + center = on + tag = +settings +} + +windowrule { + name = windowrule-45 + match:class = ^(qt5ct|qt6ct|[Yy]ad)$ + tag = +settings +} + +windowrule { + name = windowrule-46 + match:class = (xdg-desktop-portal-gtk) + tag = +settings +} + +windowrule { + name = windowrule-47 + match:class = ^(org.kde.polkit-kde-authentication-agent-1)$ + tag = +settings +} + +windowrule { + name = windowrule-48 + match:class = ^([Rr]ofi)$ + tag = +settings +} + +windowrule { + name = windowrule-49 + match:class = ^(gnome-system-monitor|org.gnome.SystemMonitor|io.missioncenter.MissionCenter)$ # system monitor + tag = +viewer +} + +windowrule { + name = windowrule-50 + match:class = ^(evince)$ # document viewer + tag = +viewer +} + +windowrule { + name = windowrule-51 + match:class = ^(eog|org.gnome.Loupe)$ # image viewer + tag = +viewer +} + +windowrule { + name = windowrule-52 + match:tag = multimedia_video* + no_blur = on + opacity = 1.0 +} + +windowrule { + name = windowrule-53 + match:tag = KooL_Cheat* + center = on + float = on + size = 65% = 90% +} + +windowrule { + name = windowrule-54 + match:class = ([Tt]hunar) + match:title = negative:(.*[Tt]hunar.*) + center = on + float = on +} + +windowrule { + name = windowrule-55 + match:tag = KooL-Settings* + center = on + float = on +} + +windowrule { + name = windowrule-56 + match:title = ^(Keybindings)$ + center = on +} + +windowrule { + name = windowrule-57 + match:class = ^([Ww]hatsapp-for-linux|ZapZap|com.rtosta.zapzap)$ + center = on + size = 60% = 70% +} + +windowrule { + name = windowrule-58 + match:title = ^(Picture-in-Picture)$ + float = on + keepaspectratio = 1 + move = 72% = 7% + opacity = 0.95 = 0.75 + pin = 0 +} + +windowrule { + name = windowrule-59 + match:fullscreen = 1 + idle_inhibit = fullscreen +} + +windowrule { + name = windowrule-60 + match:tag = wallpaper* + float = on + opacity = 0.9 = 0.7 + size = 70% = 70% +} + +windowrule { + name = windowrule-61 + match:tag = settings* + float = on + opacity = 0.8 = 0.7 + size = 70% = 70% +} + +windowrule { + name = windowrule-62 + match:tag = viewer* + float = on + opacity = 0.82 = 0.75 +} + +windowrule { + name = windowrule-63 + match:class = ([Zz]oom|onedriver|onedriver-launcher)$ + float = on +} + +windowrule { + name = windowrule-64 + match:class = (org.gnome.Calculator) + match:title = (Calculator) + float = on +} + +windowrule { + name = windowrule-65 + match:class = ^(mpv|com.github.rafostar.Clapper)$ + float = on +} + +windowrule { + name = windowrule-66 + match:class = ^([Qq]alculate-gtk)$ + float = on +} + +windowrule { + name = windowrule-67 + match:title = ^(Authentication Required)$ + center = on + float = on +} + +windowrule { + name = windowrule-68 + match:class = (codium|codium-url-handler|VSCodium) + match:title = negative:(.*codium.*|.*VSCodium.*) + float = on +} + +windowrule { + name = windowrule-69 + match:class = ^(com.heroicgameslauncher.hgl)$ + match:title = negative:(Heroic Games Launcher) + float = on +} + +windowrule { + name = windowrule-70 + match:class = ^([Ss]team)$ + match:title = negative:^([Ss]team)$ + float = on +} + +windowrule { + name = windowrule-71 + match:title = ^(Add Folder to Workspace)$ + center = on + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-72 + match:title = ^(Save As)$ + center = on + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-73 + match:initial_title = (Open Files) + float = on + size = 70% = 60% +} + +windowrule { + name = windowrule-74 + match:title = ^(SDDM Background)$ #KooL's Dots YAD for setting SDDM background + center = on + float = on + size = 16% = 12% +} + +windowrule { + name = windowrule-75 + match:tag = browser* + opacity = 0.99 = 0.8 +} + +windowrule { + name = windowrule-76 + match:tag = projects* + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-77 + match:tag = im* + opacity = 0.94 = 0.86 +} + +windowrule { + name = windowrule-78 + match:tag = multimedia* + opacity = 0.94 = 0.86 +} + +windowrule { + name = windowrule-79 + match:tag = file-manager* + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-80 + match:tag = terminal* + opacity = 0.9 = 0.7 +} + +windowrule { + name = windowrule-81 + match:class = ^(gedit|org.gnome.TextEditor|mousepad)$ + opacity = 0.8 = 0.7 +} + +windowrule { + name = windowrule-82 + match:class = ^(deluge)$ + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-83 + match:class = ^(seahorse)$ # gnome-keyring gui + opacity = 0.9 = 0.8 +} + +windowrule { + name = windowrule-84 + match:class = ^(code)$ + opacity = 0.8 + opacity = 0.9 +} + +windowrule { + name = windowrule-85 + match:tag = games* + fullscreen = 0 + no_blur = on +} + +windowrule { + name = windowrule-86 + match:class = ^(jetbrains-*) + no_initial_focus = on +} + +windowrule { + name = windowrule-87 + match:title = ^(wind.*)$ + no_initial_focus = on +} + +# --- Auto-generated layer rules --- +layerrule { + name = layerrule-1 + match:namespace = rofi + blur = on + ignore_alpha = 0 +} + +layerrule { + name = layerrule-2 + match:namespace = notifications + blur = on + ignore_alpha = 0 +} + +layerrule { + name = layerrule-3 + match:namespace = quickshell:overview + blur = on + ignore_alpha = 0 + ignore_alpha = 0.5 +} -- cgit v1.2.3 From f69b75530ff70492efd8ce8fd6b5fd5df488dd40 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Wed, 19 Nov 2025 20:46:17 -0500 Subject: Removed keepaspect = 1 On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/configs/WindowRules-config-v3.conf --- config/hypr/configs/WindowRules-config-v3.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/config/hypr/configs/WindowRules-config-v3.conf b/config/hypr/configs/WindowRules-config-v3.conf index 7dc60a4f..b54c6a85 100644 --- a/config/hypr/configs/WindowRules-config-v3.conf +++ b/config/hypr/configs/WindowRules-config-v3.conf @@ -468,7 +468,6 @@ windowrule { name = windowrule-58 match:title = ^(Picture-in-Picture)$ float = on - keepaspectratio = 1 move = 72% = 7% opacity = 0.95 = 0.75 pin = 0 -- cgit v1.2.3 From a151dda103af298fb4af3ed381217e35b8cc97c9 Mon Sep 17 00:00:00 2001 From: Don Williams Date: Fri, 21 Nov 2025 22:28:45 -0500 Subject: Repeated gamemode cycling gets multiple waybars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit You have to hammer on it, to get it to occr Added addtional sleep timer to allow pkill to keep up Resolves: https://github.com/JaKooLit/Hyprland-Dots/issues/870 On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: CHANGES-v2.3.18.md modified: config/hypr/scripts/GameMode.sh modified: config/hypr/scripts/Refresh.sh --- CHANGES-v2.3.18.md | 4 ++++ config/hypr/scripts/GameMode.sh | 1 + config/hypr/scripts/Refresh.sh | 6 +++++- 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGES-v2.3.18.md b/CHANGES-v2.3.18.md index 4f76a5d0..69aabec4 100644 --- a/CHANGES-v2.3.18.md +++ b/CHANGES-v2.3.18.md @@ -18,6 +18,10 @@ - Fixed: `GameMode.sh` to function consistently - Updated: `WalllustSwww.sh` wallpaper path - Corrected: Typo in Show Open Apps +- GameMode.sh / Refresh.sh + - Enabling / Disabling repeatedly would result in multiple waybars + - Added additional `sleep` commands in `GameMode.sh` and `Refresh.sh` + - Resolves [Issue 870](https://github.com/JaKooLit/Hyprland-Dots/issues/870) ## CHANGES: diff --git a/config/hypr/scripts/GameMode.sh b/config/hypr/scripts/GameMode.sh index ec1e541e..59cf7372 100755 --- a/config/hypr/scripts/GameMode.sh +++ b/config/hypr/scripts/GameMode.sh @@ -20,6 +20,7 @@ if [ "$HYPRGAMEMODE" = 1 ] ; then hyprctl keyword "windowrule opacity 1 override 1 override 1 override, ^(.*)$" swww kill notify-send -e -u low -i "$notif" " Gamemode:" " enabled" + sleep 0.1 exit else swww-daemon --format xrgb && swww img "$HOME/.config/rofi/.current_wallpaper" & diff --git a/config/hypr/scripts/Refresh.sh b/config/hypr/scripts/Refresh.sh index 2e772aa9..1dd59752 100755 --- a/config/hypr/scripts/Refresh.sh +++ b/config/hypr/scripts/Refresh.sh @@ -24,6 +24,9 @@ done # added since wallust sometimes not applying killall -SIGUSR2 waybar +# Added sleep for GameMode causing multiple waybar +sleep 0.1 + # quit ags & relaunch ags #ags -q && ags & @@ -34,6 +37,7 @@ killall -SIGUSR2 waybar # some process to kill for pid in $(pidof waybar rofi swaync ags swaybg); do kill -SIGUSR1 "$pid" + sleep 0.3 done #Restart waybar @@ -52,4 +56,4 @@ if file_exists "${UserScripts}/RainbowBorders.sh"; then ${UserScripts}/RainbowBorders.sh & fi -exit 0 \ No newline at end of file +exit 0 -- cgit v1.2.3 From aefafcfdaad27df4d0943c475840a93fdb7b0e82 Mon Sep 17 00:00:00 2001 From: brockar Date: Sat, 22 Nov 2025 11:50:26 -0300 Subject: feat: Add new laptop gesture for zoom --- CHANGES-v2.3.18.md | 1 + config/hypr/UserConfigs/UserSettings.conf | 2 ++ 2 files changed, 3 insertions(+) diff --git a/CHANGES-v2.3.18.md b/CHANGES-v2.3.18.md index 69aabec4..29eb7c41 100644 --- a/CHANGES-v2.3.18.md +++ b/CHANGES-v2.3.18.md @@ -67,5 +67,6 @@ - Binds now include descriptions. - Switched from `bind` to `bindd` - Improves usability of keybind search +- Add new laptop gesture for zoom system. Thanks to everyone that contributed, or reported issues. diff --git a/config/hypr/UserConfigs/UserSettings.conf b/config/hypr/UserConfigs/UserSettings.conf index f81ccc6a..4802e79a 100644 --- a/config/hypr/UserConfigs/UserSettings.conf +++ b/config/hypr/UserConfigs/UserSettings.conf @@ -73,6 +73,8 @@ gestures { workspace_swipe_create_new = true workspace_swipe_forever = true #workspace_swipe_use_r = true #uncomment if wanted a forever create a new workspace with swipe right + gesture = 3, up, dispatcher, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor * 1.5}')" + gesture = 3, down, dispatcher, exec, hyprctl keyword cursor:zoom_factor "$(hyprctl getoption cursor:zoom_factor | awk 'NR==1 {factor = $2; if (factor < 1) {factor = 1}; print factor / 1.5}')" } misc { -- cgit v1.2.3 From 1351220a092414ae593bc006e3a3ebc09523198d Mon Sep 17 00:00:00 2001 From: installer Date: Sat, 22 Nov 2025 11:27:26 -0500 Subject: Adjusted sleep timers, last change was too long Slowed down changes and waybar startup On branch development Your branch is up to date with 'origin/development'. Changes to be committed: modified: config/hypr/scripts/Refresh.sh --- config/hypr/scripts/Refresh.sh | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/config/hypr/scripts/Refresh.sh b/config/hypr/scripts/Refresh.sh index 1dd59752..76757aa4 100755 --- a/config/hypr/scripts/Refresh.sh +++ b/config/hypr/scripts/Refresh.sh @@ -7,27 +7,26 @@ UserScripts=$HOME/.config/hypr/UserScripts # Define file_exists function file_exists() { - if [ -e "$1" ]; then - return 0 # File exists - else - return 1 # File does not exist - fi + if [ -e "$1" ]; then + return 0 # File exists + else + return 1 # File does not exist + fi } # Kill already running processes _ps=(waybar rofi swaync ags) for _prs in "${_ps[@]}"; do - if pidof "${_prs}" >/dev/null; then - pkill "${_prs}" - fi + if pidof "${_prs}" >/dev/null; then + pkill "${_prs}" + fi done # added since wallust sometimes not applying -killall -SIGUSR2 waybar +killall -SIGUSR2 waybar # Added sleep for GameMode causing multiple waybar sleep 0.1 - # quit ags & relaunch ags #ags -q && ags & @@ -36,24 +35,24 @@ sleep 0.1 # some process to kill for pid in $(pidof waybar rofi swaync ags swaybg); do - kill -SIGUSR1 "$pid" - sleep 0.3 + kill -SIGUSR1 "$pid" + sleep 0.1 done #Restart waybar -sleep 1 +sleep 0.1 waybar & # relaunch swaync -sleep 0.5 -swaync > /dev/null 2>&1 & +sleep 0.3 +swaync >/dev/null 2>&1 & # reload swaync swaync-client --reload-config # Relaunching rainbow borders if the script exists sleep 1 if file_exists "${UserScripts}/RainbowBorders.sh"; then - ${UserScripts}/RainbowBorders.sh & + ${UserScripts}/RainbowBorders.sh & fi exit 0 -- cgit v1.2.3