Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
### Added
- Docs: link to Lua migration guide in `README.md` and `MIGRATION-LUA.md`
- Waybar: add VSCodium and Chromium icon rules to window module
- Theme import: the "More Themes" fzf picker (`hydectl theme import`) marks themes already present in `~/.config/hyde/themes` with a "✓ installed" suffix, so browsing the gallery no longer requires cross-checking what's already on disk

### Fixed
- Waybar: honor an optional `$WAYBAR_LAYOUT` in `hypr.theme` during color/theme updates, selecting the layout and matching stylesheet temporarily. Restore the previous layout and independently selected CSS when leaving themes with a preset, preserving them across repeated updates and preset-to-preset switches. Fix theme setting lookup for names containing spaces such as `Mac OS`.
Expand All @@ -29,6 +30,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
- Waybar: `gpuinfo` no longer crashes with a division-by-zero error, leaks a plain-text banner into its JSON output on the first poll after a reboot or a `--reset`, or emits an invalid `"percentage":` with no value when no temperature sensor is available; all three used to break the module's parsing
- Python environment: `uv sync` now targets the HyDE-managed venv at `~/.local/state/hyde/python_env` instead of creating a project-local `.venv`; also forces `--link-mode copy` to avoid silent reflink failures on ext4 that left packages uninstalled
- Hypridle: use Lua DPMS dispatchers so idle screen-off and resume work with the Hyprland Lua config parser
- Theme import: `theme.import.py`'s fzf preview no longer crashes with an `AttributeError` when previewing a theme name that isn't in the cached gallery data

## v26.08.21

Expand Down
60 changes: 54 additions & 6 deletions Configs/.local/lib/hyde/theme.import.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,43 @@
"hyde/gallery-database",
)
JSON_DATA = None
# A leading, colored checkmark -- not a repeated "installed" text label -- so
# the theme name stays the most legible thing in the row (HIG lists-and-tables:
# selection/status state is an accessory image, not label text). Green is
# reserved for this; fzf's own multi-select marker uses a different glyph
# (see --marker in fzf_menu) so the two states can't be confused.
#
# fzf's --ansi (needed to render the color at all) parses and *strips* SGR
# escape codes out of every value it hands back via `{}` -- both the live
# preview substitution and the final selected-line output on stdout. Only
# the glyph survives that round trip, never the color codes around it. So
# INSTALLED_GLYPH (bare, no escapes) is what every strip/compare has to
# match; INSTALLED_PREFIX (with color) exists only to build what fzf displays.
INSTALLED_GLYPH = "✓ "
INSTALLED_PREFIX = f"\033[32m{INSTALLED_GLYPH}\033[0m"
NOT_INSTALLED_PREFIX = " " # same 2-column width, keeps names aligned


def get_installed_themes():
config_home = os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
themes_dir = os.path.join(config_home, "hyde/themes")
if not os.path.exists(themes_dir):
return set()
return {d for d in os.listdir(themes_dir) if os.path.isdir(os.path.join(themes_dir, d))}


def strip_installed_marker(theme):
# Check the colored form first: it starts with the same glyph the
# ansi-stripped form does, so checking the glyph alone first would chop
# only the glyph off a still-colored string and leave the escape codes
# attached to the name.
if theme.startswith(INSTALLED_PREFIX):
return theme[len(INSTALLED_PREFIX) :]
if theme.startswith(INSTALLED_GLYPH):
return theme[len(INSTALLED_GLYPH) :]
if theme.startswith(NOT_INSTALLED_PREFIX):
return theme[len(NOT_INSTALLED_PREFIX) :]
return theme


def fetch_theme_preview_path(theme):
Expand Down Expand Up @@ -89,6 +126,7 @@ def clone_repo():


def get_theme_preview(theme):
theme = strip_installed_marker(theme)
fetch_data()
color1 = "#39b1d6"
color2 = "#c79bf0"
Expand Down Expand Up @@ -121,6 +159,7 @@ def get_opposite_color(hex_color):
" [TAB] to mark a theme\n"
" [Enter] or choose [CONFIRM] to confirm selected themes\n"
" [Esc] to exit/cancel\n\n"
f" {INSTALLED_PREFIX}already installed\n\n"
"Some helpful shortcuts:\n"
" CTRL A : mark all\n"
" CTRL D : un-mark all\n"
Expand All @@ -132,8 +171,11 @@ def get_opposite_color(hex_color):
preview_text += bar_bottom + "\n"
image = CLONE_DIR + "/preview.png"
else:
theme_data = next((t for t in JSON_DATA if t["THEME"] == theme), None)
if theme_data and theme_data.get("PREVIEW"):
theme_data = next((t for t in (JSON_DATA or []) if t["THEME"] == theme), None)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
if theme_data is None:
logger.debug(f"Theme not found in gallery data: {theme}")
return f"Image preview not found for {theme}"
if theme_data.get("PREVIEW"):
image = random.choice(theme_data["PREVIEW"])
else:
image = None
Expand Down Expand Up @@ -237,10 +279,15 @@ def fzf_menu():
try:
fetch_data()
if JSON_DATA:
themes = [theme["THEME"] for theme in JSON_DATA]
themes.sort(reverse=True)
themes = ["[CONFIRM]"] + themes
installed = get_installed_themes()
theme_names = sorted((theme["THEME"] for theme in JSON_DATA), reverse=True)
themes = [
(INSTALLED_PREFIX if name in installed else NOT_INSTALLED_PREFIX) + name
for name in theme_names
]
themes = [NOT_INSTALLED_PREFIX + "[CONFIRM]"] + themes
fzf_options = [
"--ansi",
"--input-label-pos=center",
"--cycle",
"-m",
Expand All @@ -253,6 +300,7 @@ def fzf_menu():
"--preview-window=right::70%",
]
SELECTED_THEMES = fzf.prompt(themes, fzf_options)
SELECTED_THEMES = [strip_installed_marker(t) for t in SELECTED_THEMES]
logger.debug(f"Selected themes: {SELECTED_THEMES}")
else:
logger.debug("No JSON data available to display themes.")
Expand Down Expand Up @@ -353,7 +401,7 @@ def main():
logger.debug("LoadedPreview text: " + args.preview)
preview_text = args.preview_text
print(preview_text)
get_theme_preview(args.preview)
print(get_theme_preview(args.preview))
if args.fetch:
fetch_theme(args.fetch)
except KeyboardInterrupt:
Expand Down
Loading