Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Tests

on:
push:
branches:
- dev
- rc
- master
pull_request:
workflow_dispatch:

permissions:
contents: read

jobs:
test:
name: Configuration and script checks
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false

- name: Install test dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends lua5.4 shellcheck
sudo ln -sf /usr/bin/lua5.4 /usr/local/bin/lua
sudo ln -sf /usr/bin/luac5.4 /usr/local/bin/luac

- name: Report tool versions
run: |
lua -v
shellcheck --version
python3 --version

- name: Run the test suite
run: sh tests/run.sh
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ Scripts/pkg_user.lst
Configs/.config/uwsm/*
./.*
build

# Local agent worktrees, never part of the tree
.claude/
5 changes: 5 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,8 @@ repos:
name: markdownlint-strict
args: [--config, .markdownlint-strict.yaml]
stages: [manual]

- repo: https://github.com/Calinou/pre-commit-luacheck
rev: v1.0.0
hooks:
- id: luacheck
39 changes: 37 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,42 @@ All notable changes to 'HyDE' will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to _Modified_ [CalVer](https://calver.org/). See [Versioning](https://github.com/HyDE-Project/HyDE/blob/master/RELEASE_POLICY.md#versioning-yymq) For more info
-->

## v26.7.28 | End of April Release
## Unreleased

### Added
- Docs: `MIGRATION-LUA.md`, a transition guide for upgrading from the hyprlang configuration — what moved where, the silent failures and their causes, and the files the upgrade leaves behind

### Removed
- Hyprland: dropped the legacy hyprlang dot, the files it deployed no longer exist

### Fixed
- Hyprland: a session started without `XDG_CONFIG_HOME`, such as one launched from a TTY, no longer dies with a Lua error before the first window; the unset variable is treated as unset instead of being pasted into a path
- Hyprland: a home directory containing an apostrophe no longer makes the session load its libraries from the system directory instead of the user's own, and an empty `XDG_RUNTIME_DIR` reads as unset rather than resolving against the working directory
- Waybar: the theme module and the HyDE menu call `theme.switch` again; `themeswitch` was removed and the calls failed outright
- Dolphin: the "Set As Wallpaper" service menu switches the theme again
- Fish: `HYPRLAND_CONFIG` points at the deployed `hypr/hyde.lua` instead of a config the Lua release deleted, so a session started outside uwsm no longer comes up without a config
- Hyprland: the config editor offers the user's `hypr/hyprland.lua` instead of four files nothing reads, which it used to create empty on save
- System monitor: a console monitor no longer launches with no terminal attached, and `[sysmonitor] terminal` is a real setting
- Docs: the keybinding reference describes the Lua configuration instead of the removed `userprefs.conf`, documents binds that were missing from it, corrects four descriptions that no longer matched the code, and explains why an override needs the original bind's flags
- Docs: the shipped `hypr/hyprland.lua` stub shows a working bind instead of pointing at a wiki that does not exist
- Docs: the keybinding links in the German, Arabic, French, Dutch and Turkish readmes resolve again
- Core: every migration that has not been applied yet now runs in version order and is recorded, instead of only the newest one running and retiring the rest unseen
- Core: app launchers no longer show a false error when an unrelated `DEBUG` variable contains a non-boolean value such as `release`
- Desktop: the generated battery notification startup command now launches `batterynotify.lua` instead of the removed shell implementation
- Hyprland: Lua keybinds again match the documented shortcuts for window management, screenshots, wallpapers, Waybar, selectors, workspaces and the scratchpad
- Screenshot: area capture now uses the fixed upstream Grimblast selector instead of prompting for the region twice
- Screenshot: Satty defaults to the compatible GTK GL renderer when no explicit `GSK_RENDERER` is configured
- Screenshot: the "print all monitors" keybind now invokes a full-output capture instead of capturing only the focused monitor
- Waybar `hyprland/workspaces` module adapted to use lua dispatchers
- Hyprland: `Super + Ctrl + arrows` no longer changes the group and the workspace at the same time.
Group navigation uses `Super + Ctrl + H/L`
- Hyprland: the right Control key no longer hides Waybar on its own. Hiding moved to `Super + Ctrl + B`
- Hyprland: workspaces 11-20 on the numpad respond again
- OCR: the language list in the result notification is no longer split across arguments
- Wallpaper: the duplicate check in the kon backend compares against the whole hash list again
- Repo: dropped two stray gitlinks that made `git submodule` fail on a fresh clone

## v26.7.4 | 4th Week of July 2026 Release

**Alright** Looks like hyprland 0.56.1 warns user to use lua so here you go!

Expand Down Expand Up @@ -36,7 +71,7 @@ Life is tight as of the moment. Any help will do. 💓
mangle with QT. But KDE apps uses ~/.config/kdeglobals which might break KDE apps for multi DE. (No fix for now)


## Fixed
### Fixed
- Fix cantarell font
- Some minor bugs

Expand Down
7 changes: 6 additions & 1 deletion Configs/.config/fish/conf.d/hyde.fish
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ set -gx PARALLEL_HOME "$XDG_CONFIG_HOME/parallel"
end

if test -z "$HYPRLAND_CONFIG"
set -gx HYPRLAND_CONFIG "$XDG_DATA_HOME/hypr/hyprland.conf"
for candidate in "$XDG_DATA_HOME/hypr/hyde.lua" /usr/local/share/hypr/hyde.lua /usr/share/hypr/hyde.lua
if test -r "$candidate"
set -gx HYPRLAND_CONFIG "$candidate"
break
end
end
end

fish_add_path $HOME/.local/bin:$PATH
Expand Down
33 changes: 28 additions & 5 deletions Configs/.config/hypr/hyprland.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
-- User Configuration goeas here.
-- Adding keybinding are simple, refer to the wiki and add it here!
-- Duplicated keybinding will always respect the last last added, therefore please override keybindings as you wish.
--- use "require()" to load other lua files, for example:
-- require("keybindings") --- this will load "keybindings.lua"
-- Your Hyprland configuration. HyDE never overwrites this file.
--
-- It loads after HyDE's own binds, so settings here take precedence. Replacing
-- a bind needs more than that: see below. HyDE's defaults live in
-- ~/.local/share/hypr/lua/ and are overwritten on every update, so edits there
-- do not survive.
--
-- Adding a keybind:
--
-- hl.bind("SUPER + SPACE", hl.dsp.exec_cmd(hyde.sh.gamelauncher()), {
-- description = "[Utilities] game launcher",
-- })
--
-- Replacing one of HyDE's: bind the same combination again and yours takes
-- over, but copy its flags across as well. A bind counts as the same one only
-- when its flags match, and `description` is not a flag — miss one and both
-- binds stay live on that combination. Copy the whole options table from
-- ~/.local/share/hypr/lua/key_binds.lua and change only what you need:
--
-- hl.bind("F9", hl.dsp.exec_cmd(hyde.sh.volumecontrol("-o", "m")), {
-- locked = true,
-- description = "[Hardware Controls|Audio] un/mute output",
-- })
--
-- Press SUPER + / to see what is actually loaded, your own binds included.
-- The full reference is KEYBINDINGS.md in the HyDE repository.
--
-- Other Lua files next to this one can be pulled in with require("name").
2 changes: 1 addition & 1 deletion Configs/.config/uwsm/env-hyprland.d/00-hyde.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ if [ -z "$HYDE_ACTIVATED" ]; then
unset _hyde_activate
fi

HYPRLAND_CONFIG="${HYPRLAND_CONFIG:-${XDG_DATA_HOME:-$HOME/.local/share}/hypr/hyprland.lua}"
HYPRLAND_CONFIG="${HYPRLAND_CONFIG:-${XDG_DATA_HOME:-$HOME/.local/share}/hypr/hyde.lua}"
HYPRLAND_NO_SD_NOTIFY=1 # If systemd, disables the sd_notify calls.
HYPRLAND_NO_SD_VARS=1 # Disables management of variables in systemd and dbus activation environments.

Expand Down
2 changes: 2 additions & 0 deletions Configs/.config/uwsm/env.d/01-gpu.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#!/usr/bin/env sh

# 00-gpu.sh - GPU detection
# This env script will detect the presence of various GPUs on the system
# and set environment variables accordingly.
Expand Down
1 change: 0 additions & 1 deletion Configs/.config/zsh/ohmyzsh
Submodule ohmyzsh deleted from 9e2392
8 changes: 5 additions & 3 deletions Configs/.local/bin/hyde-shell
Original file line number Diff line number Diff line change
Expand Up @@ -294,10 +294,10 @@ run_command() {
[[ -d "$dir" ]] && SCRIPT_DIRS+=("$dir")
done

# Lua is resolved before shell, so a script left behind by an older release
# cannot shadow the implementation that replaced it.
for dir in "${SCRIPT_DIRS[@]}"; do
if [[ -f "$dir/${1}.sh" ]]; then
exec bash "$dir/${1}.sh" "${@:2}"
elif [[ -f "$dir/${1}.lua" ]]; then
if [[ -f "$dir/${1}.lua" ]]; then
l_env="${XDG_STATE_HOME:-$HOME/.local/state}/hyde/lua_env"
if [[ ! -d "$l_env" ]]; then
print_log -warn "Lua environment not found!" " Please run 'hyde-shell luainit' to set up the environment."
Expand All @@ -315,6 +315,8 @@ run_command() {
export LUA_PATH="$l_env/share/lua/$lua_ver/?.lua;$l_env/share/lua/$lua_ver/?/init.lua;$LUA_PATH"
export LUA_CPATH="$l_env/lib/lua/$lua_ver/?.so;$LUA_CPATH"
exec lua "$dir/${1}.lua" "${@:2}"
elif [[ -f "$dir/${1}.sh" ]]; then
exec bash "$dir/${1}.sh" "${@:2}"
elif [[ -f "$dir/${1}.py" ]]; then
exec "${XDG_STATE_HOME:-$HOME/.local/state}/hyde/python_env/bin/python" "$dir/${1}.py" "${@:2}"
elif [[ -f "$dir/${1}" && -x "$dir/${1}" ]]; then
Expand Down
8 changes: 8 additions & 0 deletions Configs/.local/lib/hyde/app.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,14 @@
# @cmd: service
# @cmd.desc: Run a script as a systemd service

# app2unit and xdg-terminal-exec fall back to the generic DEBUG variable,
# which may contain non-boolean build modes such as "release".
# Give both helpers an explicit, scoped default while preserving any
# user-provided values on both execution paths.
APP2UNIT_DEBUG=${APP2UNIT_DEBUG:-0}
XTE_DEBUG=${XTE_DEBUG:-0}
export APP2UNIT_DEBUG XTE_DEBUG

if [ -d "/run/systemd/system" ]; then
exec app2unit "$@"
fi
Expand Down
2 changes: 1 addition & 1 deletion Configs/.local/lib/hyde/hyde-launch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

notify-send -a "Deprecation Notice" "hyde-launch.sh is deprecated. Please use hyde-shell open instead." -i dialog-information

"${LIB_DIR}/hyde/open.sh" "$@"
hyde-shell open "$@"
4 changes: 0 additions & 4 deletions Configs/.local/lib/hyde/keybinds_hint.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
#!/usr/bin/env bash
pkill -x rofi && exit
[[ $HYDE_SHELL_INIT -ne 1 ]] && eval "$(hyde-shell init)"
confDir="${XDG_CONFIG_HOME:-$HOME/.config}"
keyconfDir="$confDir/hypr"
kb_hint_conf=("$keyconfDir/hyprland.conf" "$keyconfDir/keybindings.conf" "$keyconfDir/userprefs.conf")
kb_hint_conf+=("${ROFI_KEYBIND_HINT_CONFIG[@]}")
kb_cache="$XDG_RUNTIME_DIR/hyde/keybinds_hint.rofi"

if [[ $1 == "--reload" ]]; then
Expand Down
13 changes: 11 additions & 2 deletions Configs/.local/lib/hyde/luautils/xdg.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
--- @module luautils.xdg
-- XDG Base Directory Specification https://specifications.freedesktop.org/basedir-spec/latest/
local HOME = os.getenv("HOME")
--- Per the spec, a variable that is set but empty is treated as unset.
local function env(var, fallback)
return os.getenv(var) or (HOME and HOME .. fallback)
local value = os.getenv(var)
if value == nil or value == "" then
return HOME and HOME .. fallback
end
return value
end
local function dirs(var, default, home)
local t = {}
for e in (os.getenv(var) or default):gmatch("([^:]+)") do
local value = os.getenv(var)
if value == nil or value == "" then
value = default
end
for e in value:gmatch("([^:]+)") do
t[#t + 1] = e
end
if home then
Expand Down
2 changes: 1 addition & 1 deletion Configs/.local/lib/hyde/pm.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/env sh
#!/usr/bin/env bash
set -eu
export LC_ALL=C
usage() {
Expand Down
4 changes: 2 additions & 2 deletions Configs/.local/lib/hyde/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,14 @@ requires-python = ">=3.11"
dependencies = [
"loguru==0.7.3",
"pulsectl==24.12.0",
"requests==2.33.0",
"requests==2.34.2",
"inotify_simple",
"hererocks>=0.25.1",
"websockets>=16.0",
"xdg-prefs",
"uv>=0.1.0",
"deez-dots",
"pyprland==3.3.1",
"pyprland==3.4.3",
]

[project.optional-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion Configs/.local/lib/hyde/pyutils/lua_env.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"bootstrap_install": [
{"name": "luasec", "version": "1.3.2-1"},
{"name": "argparse", "version": "0.7.2-1"},
{"name": "dkjson", "version": "2.9-1"},
{"name": "dkjson", "version": "2.11-1"},
{"name": "luasocket", "version": "3.1.0-1"},
{"name": "luafilesystem", "version": "1.9.0-1"},
"https://raw.githubusercontent.com/lgi-devs/lgi/master/lgi-scm-1.rockspec"
Expand Down
10 changes: 9 additions & 1 deletion Configs/.local/lib/hyde/screenshot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,14 @@ fi

[[ -n ${SCREENSHOT_ANNOTATION_ARGS[*]} ]] && annotation_args+=("${SCREENSHOT_ANNOTATION_ARGS[@]}")

run_annotation_tool() {
if [[ $annotation_tool == "satty" ]]; then
GSK_RENDERER="${GSK_RENDERER:-gl}" "$annotation_tool" "${annotation_args[@]}"
else
"$annotation_tool" "${annotation_args[@]}"
fi
}

take_screenshot() {
local mode=$1
shift
Expand All @@ -102,7 +110,7 @@ take_screenshot() {
print_log -g "Executing screenshot command: ${command[*]}"
if eval "${command[*]}"; then
[[ ${SCREENSHOT_ANNOTATION_ENABLED} == false ]] && return 0
if ! "$annotation_tool" "${annotation_args[@]}"; then
if ! run_annotation_tool; then
send_notifs -r 9 -a "HyDE Alert" "Screenshot Error" "Failed to open annotation tool"
return 1
fi
Expand Down
32 changes: 31 additions & 1 deletion Configs/.local/lib/hyde/shaders.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,32 @@ local function find_include(base)
return nil
end

-- Falls back to the XDG defaults when a variable is not exported, so a shader
-- referencing "$XDG_CACHE_HOME" still resolves outside of a HyDE session.
local ENV_FALLBACK = {
XDG_DATA_HOME = xdg.data,
XDG_CONFIG_HOME = xdg.config,
XDG_CACHE_HOME = xdg.cache,
XDG_STATE_HOME = xdg.state,
XDG_RUNTIME_DIR = xdg.runtime,
HOME = os.getenv("HOME")
}

-- Expands "$VAR" and "${VAR}" occurrences in a path. A variable that is set but
-- empty counts as unset, so the fallback still applies.
local function expand_env(str)
local function lookup(name)
local value = os.getenv(name)
if value == nil or value == "" then
value = ENV_FALLBACK[name]
end
return value or ""
end
str = str:gsub("%${([%w_]+)}", lookup)
str = str:gsub("%$([%w_]+)", lookup)
return str
end

local function parse_source_include(path)
local source_include
local shader_dir = path:match("^(.*)/") or "."
Expand All @@ -45,6 +71,7 @@ local function parse_source_include(path)
for line in f:lines() do
local source = line:match("^%s*//%s*!source%s*=%s*(.-)%s*$")
if source and source ~= "" then
source = expand_env(source)
if source:sub(1, 1) ~= "/" then
source = shader_dir .. "/" .. source
end
Expand Down Expand Up @@ -89,7 +116,10 @@ local function compile_shader(item)
local source_include = parse_source_include(src)

local files = {}
if source_include and lfs.attributes(source_include, "mode") == "file" then
if source_include then
if lfs.attributes(source_include, "mode") ~= "file" then
return nil, "source include not found: " .. source_include
end
files[#files + 1] = source_include
end
if inc_path then
Expand Down
Loading
Loading