Skip to content

Instantly share code, notes, and snippets.

@vredesbyyrd
Created August 9, 2025 18:32
Show Gist options
  • Select an option

  • Save vredesbyyrd/f9ce565380e8a8d4897f9ef066aee111 to your computer and use it in GitHub Desktop.

Select an option

Save vredesbyyrd/f9ce565380e8a8d4897f9ef066aee111 to your computer and use it in GitHub Desktop.
rofi blocks image preview debug script
/**
* ROFI Color Theme
*
* Fullscreen theme with switchable PREVIEW option.
*
* User: Dave Davenport
* Copyright: Dave Davenport
*/
* {
background-color: transparent;
text-color: white;
}
window {
fullscreen: true;
background-color: black/80%;
padding: 4em;
children: [ wrap, listview-split];
spacing: 1em;
}
/** We add an extra child to this if PREVIEW=true */
listview-split {
orientation: horizontal;
spacing: 0.4em;
children: [listview];
}
wrap {
expand: false;
orientation: vertical;
children: [ inputbar, message ];
background-image: linear-gradient(white/5%, white/40%);
border-color: lightblue;
border: 3px;
border-radius: 0.4em;
}
icon-ib {
expand: false;
filename: "system-search";
vertical-align: 0.5;
horizontal-align: 0.5;
size: 1em;
}
inputbar {
spacing: 0.4em;
padding: 0.4em;
children: [ icon-ib, entry ];
}
entry {
placeholder: "Search";
placeholder-color: grey;
}
message {
background-color: red/20%;
border-color: lightsalmon;
border: 3px 0px 0px 0px;
padding: 0.4em;
spacing: 0.4em;
}
listview {
flow: horizontal;
fixed-columns: true;
columns: 7;
lines: 5;
spacing: 1.0em;
}
element {
orientation: vertical;
padding: 0.1em;
background-image: linear-gradient(white/5%, white/20%);
border-color: lightblue /15%;
border: 3px;
border-radius: 0.4em;
children: [element-icon, element-text ];
}
element-icon {
size: calc(((100% - 8em) / 7 ));
horizontal-align: 0.5;
vertical-align: 0.5;
}
element-text {
horizontal-align: 0.5;
vertical-align: 0.5;
padding: 0.2em;
}
element selected {
background-image: linear-gradient(white/25%, white/10%);
border-color: lightblue;
border: 3px;
border-radius: 0.4em;
}
/**
* Launching rofi with environment PREVIEW set to true
* will split the screen and show a preview widget.
*/
@media ( enabled: env(PREVIEW, false)) {
/** preview widget */
icon-current-entry {
expand: true;
size: 80%;
}
listview-split {
children: [listview, icon-current-entry];
}
listview {
columns: 4;
}
}
@media ( enabled: env(NO_IMAGE, false)) {
listview {
columns: 1;
spacing: 0.4em;
}
element {
children: [ element-text ];
}
element-text {
horizontal-align: 0.0;
}
}
#!/usr/bin/env python
import sys
import json
from pathlib import Path
# run me like: G_MESSAGES_DEBUG=BlocksMode PREVIEW=true rofi -modi blocks -show blocks -blocks-wrap $HOME/$USER/image_debug_blocks.py -theme fullscreen-preview.rasi
# --- Configuration ---
IMAGE_DIRECTORY = Path("/home/foo/bar") #IMPORTANT: add any dir path with images that are of decent size, height > 600px should suffice
# A tuple of the file suffixes to search for.
IMAGE_SUFFIXES = ('.png', '.jpg')
# -------------------
# A list to hold the individual line entries for rofi.
rofi_entries = []
if IMAGE_DIRECTORY.is_dir():
for item_path in IMAGE_DIRECTORY.iterdir():
# Check if the item is a file and if its name ends with any of the target suffixes.
# Using .lower() makes the check case-insensitive (e.g., matches .JPG, .PNG).
if item_path.is_file() and item_path.name.lower().endswith(IMAGE_SUFFIXES):
entry = {
"text": item_path.name,
"icon": str(item_path.resolve())
}
rofi_entries.append(entry)
# The final JSON object that rofi-blocks expects.
output = {
"prompt": "Jellyfin Images",
"lines": rofi_entries
}
# 1. Print the initial state to standard output.
print(json.dumps(output))
# 2. Flush stdout to ensure rofi receives the data immediately.
sys.stdout.flush()
# 3. Keep the script alive by listening for events from rofi on stdin.
for line in sys.stdin:
# Any event will cause the script to exit.
break
#!/usr/bin/env python
import sys
from pathlib import Path
# run me like: G_MESSAGES_DEBUG=BlocksMode PREVIEW=true rofi -modi blocks -show blocks -blocks-wrap $HOME/$USER/image_debug_modi.py -theme fullscreen-preview.rasi
# --- Configuration ---
# The directory where your images are stored.
IMAGE_DIRECTORY = Path("/home/foo/bar") #IMPORTANT: add any dir path with images that are of decent size, height > 600px should suffice
# A tuple of the file suffixes to search for.
IMAGE_SUFFIXES = ('.png', '.jpg')
# The rofi script protocol uses special characters as separators.
# \0 is the null character, separating the display text from metadata.
# \x1f is the unit separator, separating metadata keys from values.
NULL_SEP = '\0'
INFO_SEP = '\x1f'
# Rofi calls the script with arguments when an entry is selected.
# If no arguments are passed (len(sys.argv) == 1), it's the first run to generate the list.
if len(sys.argv) == 1:
# --- First Run: Generate and print the list for Rofi ---
# Ensure the specified directory actually exists.
if IMAGE_DIRECTORY.is_dir():
# Iterate over all items in the directory.
for item_path in IMAGE_DIRECTORY.iterdir():
# Check if the item is a file and has the correct suffix.
if item_path.is_file() and item_path.name.lower().endswith(IMAGE_SUFFIXES):
# Get the filename for the display text.
display_text = item_path.name
# Get the full, resolved path for the icon.
icon_path = str(item_path.resolve())
# Print the entry in the special format Rofi expects:
# "display_text\0icon\x1ficon_path"
# This tells rofi to use the filename as the text and the full path as the icon.
print(f"{display_text}{NULL_SEP}icon{INFO_SEP}{icon_path}")
else:
# --- Second Run: An item was selected ---
# The selected item's text is passed as the first argument (sys.argv[1]).
# For this simple debugging script, we don't need to do anything with the selection.
# The script will simply exit after being called.
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment