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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Symlinks created by preview/lint scripts at runtime
preview/components
preview/assets
10 changes: 6 additions & 4 deletions preview/Preview.qml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import QtQuick.Window
import QtQuick.Layouts
import QtQuick.Controls

import "../components"
import "components"

/*
* Preview.qml - Development harness for the SDDM theme.
Expand All @@ -15,8 +15,10 @@ import "../components"
* Components receive their dependencies as explicit properties, so they
* work identically whether driven by SDDM or by this preview.
*
* Usage: qml6 preview/Preview.qml
* or: qmlscene6 preview/Preview.qml
* The preview script symlinks components/ and assets/ into preview/
* so that relative imports and asset paths resolve to the selected theme.
*
* Usage: ./scripts/preview.sh [-theme <name>]
*/

Window {
Expand All @@ -34,7 +36,7 @@ Window {
id: mockConfig
// Set to "" to use the solid fallback color, or provide a path
// to an image (e.g. drop your own into assets/background.jpg).
property string background: Qt.resolvedUrl("../assets/background.jpg")
property string background: Qt.resolvedUrl("assets/background.jpg")
property string type: "image"
property string color: "#1a1a2e"
property string primaryColor: "#ffffff"
Expand Down
54 changes: 51 additions & 3 deletions scripts/lint-qml.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
# Runs qmllint (static) on all QML source files, then launches the preview
# under xvfb for a few seconds to catch runtime type-assignment warnings.
#
# Usage: ./scripts/lint-qml.sh
# Usage: ./scripts/lint-qml.sh [-theme <name>]
#
# Options:
# -theme <name> Lint a specific theme (default: lint all themes)
#
# Exit codes:
# 0 All checks passed
Expand All @@ -18,6 +21,30 @@ PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

cd "$PROJECT_DIR"

# ── Parse arguments ─────────────────────────────────────────────
THEME_NAME=""

while [[ $# -gt 0 ]]; do
case "$1" in
-theme)
THEME_NAME="${2:?Error: -theme requires a name}"
shift 2
;;
-h|--help)
echo "Usage: $0 [-theme <name>]"
echo ""
echo "Options:"
echo " -theme <name> Lint a specific theme (default: lint all themes)"
exit 0
;;
*)
echo "Unknown option: $1" >&2
echo "Usage: $0 [-theme <name>]" >&2
exit 1
;;
esac
done

# ── Locate Qt 6 tools ────────────────────────────────────────────
# Binary names and paths vary across distros:
# Arch: qmllint, qml6 (on PATH)
Expand All @@ -41,13 +68,27 @@ QML_RUNTIME=$(find_tool qml6 qml)

FAILED=0

# Build list of theme directories to check.
if [[ -n "$THEME_NAME" ]]; then
THEME_DIRS=("themes/$THEME_NAME")
if [[ ! -d "${THEME_DIRS[0]}" ]]; then
echo "Error: theme directory not found: ${THEME_DIRS[0]}" >&2
exit 1
fi
else
THEME_DIRS=()
for d in themes/*/; do
[[ -d "$d" ]] && THEME_DIRS+=("${d%/}")
done
fi

# ── Static analysis with qmllint ──────────────────────────────────
echo "=== qmllint: static analysis ==="

if [[ -z "$QMLLINT" ]]; then
echo "SKIP: qmllint not found."
else
QML_FILES=$(find . -name '*.qml' -not -path './.git/*')
QML_FILES=$(find "${THEME_DIRS[@]}" preview -name '*.qml' -not -path './.git/*')
echo "Checking: $QML_FILES"
echo ""

Expand Down Expand Up @@ -81,7 +122,14 @@ fi
export QT_QUICK_CONTROLS_STYLE=Basic

STDERR_LOG=$(mktemp)
trap 'rm -f "$STDERR_LOG"' EXIT
trap 'rm -f "$STDERR_LOG" "$PROJECT_DIR/preview/components" "$PROJECT_DIR/preview/assets"' EXIT

# Test with the default theme (or the specified one).
RUNTIME_THEME="${THEME_DIRS[0]}"
RUNTIME_THEME_DIR="$PROJECT_DIR/$RUNTIME_THEME"
# Symlink the theme's components and assets into preview/ so QML resolves them.
ln -sfn "$RUNTIME_THEME_DIR/components" "$PROJECT_DIR/preview/components"
ln -sfn "$RUNTIME_THEME_DIR/assets" "$PROJECT_DIR/preview/assets"

# Run preview for 3 seconds under a virtual framebuffer, capture stderr.
if command -v xvfb-run &>/dev/null; then
Expand Down
49 changes: 48 additions & 1 deletion scripts/preview.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,60 @@
# Watches all QML, conf, and image files. On any change, kills the
# running qml6 process and relaunches the Preview.qml harness.
#
# Usage: ./scripts/preview.sh
# Usage: ./scripts/preview.sh [-theme <name>]
#
# Options:
# -theme <name> Preview the theme in themes/<name>/ (default: "default")
#

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

# ── Parse arguments ─────────────────────────────────────────────
THEME_NAME="default"

while [[ $# -gt 0 ]]; do
case "$1" in
-theme)
THEME_NAME="${2:?Error: -theme requires a name}"
shift 2
;;
-h|--help)
echo "Usage: $0 [-theme <name>]"
echo ""
echo "Options:"
echo " -theme <name> Preview the theme in themes/<name>/ (default: \"default\")"
exit 0
;;
*)
echo "Unknown option: $1" >&2
echo "Usage: $0 [-theme <name>]" >&2
exit 1
;;
esac
done

THEME_DIR="$PROJECT_DIR/themes/$THEME_NAME"

if [[ ! -d "$THEME_DIR" ]]; then
echo "Error: theme directory not found: $THEME_DIR" >&2
echo "" >&2
echo "Available themes:" >&2
for d in "$PROJECT_DIR"/themes/*/; do
[[ -d "$d" ]] && echo " $(basename "$d")" >&2
done
exit 1
fi

# ── Setup ───────────────────────────────────────────────────────
ENTR_PID=""

cleanup() {
trap - SIGINT SIGTERM # prevent re-entry
[[ -n "$ENTR_PID" ]] && kill "$ENTR_PID" 2>/dev/null && wait "$ENTR_PID" 2>/dev/null
rm -f "$PROJECT_DIR/preview/components" "$PROJECT_DIR/preview/assets"
echo ""
echo "Preview stopped."
exit 0
Expand All @@ -29,8 +70,14 @@ trap cleanup SIGINT SIGTERM
# unavailable outside a full Plasma session.
export QT_QUICK_CONTROLS_STYLE=Basic

# Symlink the theme's components and assets into preview/ so QML's
# relative imports and asset paths resolve to the selected theme.
ln -sfn "$THEME_DIR/components" "$PROJECT_DIR/preview/components"
ln -sfn "$THEME_DIR/assets" "$PROJECT_DIR/preview/assets"

echo "=== KDE Lockscreen Builder — Live Preview ==="
echo "Project: $PROJECT_DIR"
echo "Theme: $THEME_NAME ($THEME_DIR)"
echo "Press Ctrl+C to stop"
echo ""

Expand Down
45 changes: 42 additions & 3 deletions scripts/test-sddm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,55 @@
# project directory. Shows real user list, session list, and keyboard
# state. Login/power actions won't actually execute in test mode.
#
# Usage: ./scripts/test-sddm.sh
# Usage: ./scripts/test-sddm.sh [-theme <name>]
#
# Options:
# -theme <name> Test the theme in themes/<name>/ (default: "default")
#

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"

# ── Parse arguments ─────────────────────────────────────────────
THEME_NAME="default"

while [[ $# -gt 0 ]]; do
case "$1" in
-theme)
THEME_NAME="${2:?Error: -theme requires a name}"
shift 2
;;
-h|--help)
echo "Usage: $0 [-theme <name>]"
echo ""
echo "Options:"
echo " -theme <name> Test the theme in themes/<name>/ (default: \"default\")"
exit 0
;;
*)
echo "Unknown option: $1" >&2
echo "Usage: $0 [-theme <name>]" >&2
exit 1
;;
esac
done

THEME_DIR="$PROJECT_DIR/themes/$THEME_NAME"

if [[ ! -d "$THEME_DIR" ]]; then
echo "Error: theme directory not found: $THEME_DIR" >&2
echo "" >&2
echo "Available themes:" >&2
for d in "$PROJECT_DIR"/themes/*/; do
[[ -d "$d" ]] && echo " $(basename "$d")" >&2
done
exit 1
fi

echo "=== KDE Lockscreen Builder — SDDM Test Mode ==="
echo "Theme: $PROJECT_DIR"
echo "Theme: $THEME_NAME ($THEME_DIR)"
echo ""

sddm-greeter-qt6 --test-mode --theme "$PROJECT_DIR"
sddm-greeter-qt6 --test-mode --theme "$THEME_DIR"
File renamed without changes.
File renamed without changes
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.