31 Commits

Author SHA1 Message Date
f678056c5b Merge pull request #54 from javalsai/actions/update-aur-
[AUR update]: Bump to v1.2.0
2025-07-04 22:53:04 +02:00
3a7bd6f9f5 fix(ci,aur): empty version strings 2025-07-04 22:50:45 +02:00
5207e1e94b Merge branch 'master' into actions/update-aur- 2025-07-04 22:49:01 +02:00
GitHub Actions
69d48d32d6 Update AUR pkgs to v 2025-07-04 20:47:25 +00:00
7f75b8edce fix: allow building without a git repo 2025-07-04 22:40:23 +02:00
75fc3c139b ci: rename release workflow 2025-07-04 22:09:32 +02:00
ec41c6f70e Merge pull request #53 from javalsai/update_rate
feat: add refresh_rate option for clock
2025-07-04 20:58:49 +02:00
65bbb7d1b4 Merge branch 'master' into update_rate 2025-07-04 19:33:43 +02:00
9fe938b96a Merge pull request #52 from grialion/feat-help-version-menu
feat: help, version menu
2025-07-04 19:28:25 +02:00
5f7e412408 Merge branch 'master' into feat-help-version-menu 2025-07-04 19:25:59 +02:00
335459e127 ci: rename push workflow 2025-07-04 19:22:59 +02:00
c05218d30a ci: split check & build 2025-07-04 19:19:44 +02:00
3d6efa448b ci: update make release action 2025-07-04 19:12:45 +02:00
f3ae85bb94 feat|fix: improve all ci behavior 2025-07-04 18:36:47 +02:00
521a7c295e rm: unused Makefile flags 2025-07-04 16:39:29 +02:00
d1b993c32a ci: fix bear 2025-07-04 16:05:14 +02:00
7cd976f916 ci: fix clang-tidy 2025-07-04 16:03:42 +02:00
240bdbede6 ci(9245d38): set-status first of all
and no need to cache libpam for vm build architectures
2025-07-04 15:56:31 +02:00
e4b11f9a30 ci: add clang-tidy to CI 2025-07-04 15:50:37 +02:00
736e816509 style: satisfy clang-tidy 2025-07-04 15:50:18 +02:00
3fb74ece44 style: indent preprocessor directives 2025-07-04 15:23:22 +02:00
19a1355b06 dev: automatic version.h generation
also added compiler information as a feature
2025-07-04 15:22:22 +02:00
9c022c5813 feat(cfg): add ellipsis to config 2025-07-04 04:48:20 +02:00
a316afecb2 fix: possible memory issues 2025-07-04 04:47:32 +02:00
5a6471dd00 feat: utf8 hostname and ellipsis 2025-07-04 04:40:10 +02:00
9084dfdcda fix: wrong default.ini value 2025-07-04 04:12:22 +02:00
5b5adf76b7 feat: support long hostnames
close #49
2025-07-04 03:56:51 +02:00
ba836e5cd4 feat: add refresh_rate option for clock 2025-07-04 03:30:29 +02:00
grialion
3ec1eec56f fix: git describe always (even in CI build)
use --always to make it work on shallow cloned repos (ie. CI build job)
2025-07-04 00:40:10 +02:00
grialion
9245d38ecf ci: fix: install git before checkout action 2025-07-04 00:35:51 +02:00
grialion
afd23657c0 feat: help, version menu 2025-07-04 00:15:14 +02:00
32 changed files with 552 additions and 444 deletions

View File

@@ -6,3 +6,6 @@ AllowShortIfStatementsOnASingleLine: WithoutElse
AlignAfterOpenBracket: Align
BinPackParameters: true
AllowAllParametersOfDeclarationOnNextLine: true
IndentPPDirectives: BeforeHash
IndentGotoLabels: true

130
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,130 @@
name: Build
on:
workflow_call:
jobs:
build-linux-amd64:
name: amd64
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git libpam0g-dev"
version: 1.0
- uses: actions/checkout@v4
- id: build
run: ARCH=amd64 assets/github_scripts/build.sh
- uses: actions/upload-artifact@v4
with:
name: build-amd64
path: lidm-amd64
retention-days: 1
build-linux-i386:
name: i386
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git libpam0g-dev gcc-multilib"
version: 1.0
- uses: actions/checkout@v4
- run: |
sudo dpkg --add-architecture i386
sudo apt-get update -y
sudo apt-get install -y libpam0g-dev:i386
- id: build
run: ARCH=i386 assets/github_scripts/build.sh CFLAGS="-O3 -Wall -m32"
- uses: actions/upload-artifact@v4
with:
name: build-i386
path: lidm-i386
retention-days: 1
build-linux-aarch64:
name: aarch64
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v2
with:
arch: aarch64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: ARCH=aarch64 GITHUB_STEP_SUMMARY=gss.out GITHUB_OUTPUT=go.out assets/github_scripts/build.sh
- run: set +e; cat gss.out >>"$GITHUB_STEP_SUMMARY"; cat go.out >>"$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: build-aarch64
path: lidm-aarch64
retention-days: 1
build-linux-armv7:
name: armv7
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v2
with:
arch: armv7
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: ARCH=armv7 GITHUB_STEP_SUMMARY=gss.out GITHUB_OUTPUT=go.out assets/github_scripts/build.sh
- run: set +e; cat gss.out >>"$GITHUB_STEP_SUMMARY"; cat go.out >>"$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: build-armv7
path: lidm-armv7
retention-days: 1
build-linux-riscv64:
name: riscv64
runs-on: ubuntu-24.04
permissions: write-all
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- uses: uraimo/run-on-arch-action@v2
with:
arch: riscv64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: ARCH=riscv64 GITHUB_STEP_SUMMARY=gss.out GITHUB_OUTPUT=go.out assets/github_scripts/build.sh
- run: set +e; cat gss.out >>"$GITHUB_STEP_SUMMARY"; cat go.out >>"$GITHUB_OUTPUT"
- uses: actions/upload-artifact@v4
with:
name: build-riscv64
path: lidm-riscv64
retention-days: 1

View File

@@ -1,291 +0,0 @@
name: Check and Build
on:
workflow_call:
inputs:
set-statuses:
required: false
default: true
type: boolean
jobs:
spellcheck:
name: Check Grammar
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "codespell"
version: 1.0
- run: codespell
shellcheck:
name: Shell Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "shellcheck"
version: 1.0
- run: find . -type f -name '*.sh' -not -path './assets/pkg/aur/*/src/*' | xargs shellcheck
clangcheck:
name: Clang Check
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "clang-format clang-tidy"
version: 1.0
- run: clang-format -ni src/*.c include/*.h
# TODO: include when the errors/warnings are bearable
#- run: clang-tidy src/*.c include/*.h
build-linux-amd64:
name: Build for amd64
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.build.outputs.DESCR }}
context: Build for amd64
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "libpam0g-dev"
version: 1.0
- id: build
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
HSIZE="$(stat --printf="%s" lidm | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
mv lidm lidm-amd64
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.build.outputs.DESCR }}
context: Build for amd64
- uses: actions/upload-artifact@v4
with:
name: build-amd64
path: lidm-amd64
retention-days: 1
build-linux-i386:
name: Build for i386
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.build.outputs.DESCR }}
context: Build for i386
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "libpam0g-dev gcc-multilib"
version: 1.0
- run: |
sudo dpkg --add-architecture i386
sudo apt-get update -y
sudo apt-get install -y libpam0g-dev:i386
- id: build
run: |
make -j$(nproc) CFLAGS="-O3 -Wall -m32" 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
HSIZE="$(stat --printf="%s" lidm | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
mv lidm lidm-i386
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.build.outputs.DESCR }}
context: Build for i386
- uses: actions/upload-artifact@v4
with:
name: build-i386
path: lidm-i386
retention-days: 1
build-linux-aarch64:
name: Build for aarch64
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.status.outputs.DESCR }}
context: Build for aarch64
- uses: uraimo/run-on-arch-action@v2
with:
arch: aarch64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
mv lidm lidm-aarch64
- if: inputs.set-statuses
id: status
run: |
HSIZE="$(stat --printf="%s" lidm-aarch64 | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.status.outputs.DESCR }}
context: Build for aarch64
- uses: actions/upload-artifact@v4
with:
name: build-aarch64
path: lidm-aarch64
retention-days: 1
build-linux-armv7:
name: Build for armv7
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.status.outputs.DESCR }}
context: Build for armv7
- uses: uraimo/run-on-arch-action@v2
with:
arch: armv7
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
mv lidm lidm-armv7
- if: inputs.set-statuses
id: status
run: |
HSIZE="$(stat --printf="%s" lidm-armv7 | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.status.outputs.DESCR }}
context: Build for armv7
- uses: actions/upload-artifact@v4
with:
name: build-armv7
path: lidm-armv7
retention-days: 1
build-linux-riscv64:
name: Build for riscv64
runs-on: ubuntu-24.04
permissions: write-all
needs: [spellcheck, shellcheck, clangcheck]
steps:
- uses: actions/checkout@v4
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: pending
description: ${{ steps.status.outputs.DESCR }}
context: Build for riscv64
- uses: uraimo/run-on-arch-action@v2
with:
arch: riscv64
distro: ubuntu22.04
githubToken: ${{ github.token }}
install: |
apt-get update && \
apt-get install -y make gcc libpam0g-dev
run: |
make -j$(nproc) 2> /tmp/stderr || (ERR=$?; cat /tmp/stderr >&2; exit $ERR)
cat /tmp/stderr >&2
mv lidm lidm-riscv64
- if: inputs.set-statuses
id: status
run: |
HSIZE="$(stat --printf="%s" lidm-riscv64 | numfmt --to=iec-i)B"
WARNS="$(cat /tmp/stderr | grep '^[^ ]*\.[ch]:' | wc -l)"
echo "DESCR='$HSIZE, $WARNS warnings'" >> "$GITHUB_OUTPUT"
- uses: myrotvorets/set-commit-status-action@master
if: inputs.set-statuses
with:
token: ${{ secrets.GITHUB_TOKEN }}
status: ${{ job.status }}
description: ${{ steps.status.outputs.DESCR }}
context: Build for riscv64
- uses: actions/upload-artifact@v4
with:
name: build-riscv64
path: lidm-riscv64
retention-days: 1

43
.github/workflows/check.yml vendored Normal file
View File

@@ -0,0 +1,43 @@
name: Check
on:
workflow_call:
jobs:
spellcheck:
name: Grammar
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "codespell"
version: 1.0
- run: codespell
shellcheck:
name: Shellcheck
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "shellcheck"
version: 1.0
- run: find . -type f -name '*.sh' -not -path './assets/pkg/aur/*/src/*' | xargs shellcheck
clangcheck:
name: Clang
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "clang-format clang-tidy bear libpam0g-dev"
version: 1.0
- run: bear -- make
- run: clang-format -ni src/*.c include/*.h
- run: clang-tidy -p . src/*.c include/*.h

View File

@@ -1,26 +1,52 @@
name: Check and Build Release
name: Make Release
on:
workflow_dispatch:
inputs:
version:
required: true
default: ''
type: string
jobs:
build:
name: Check and Build
uses: ./.github/workflows/check-and-build.yml
permissions: write-all
with:
set-statuses: false
release:
name: Make Release v${{ inputs.version }}
release-checks:
name: Release Checks
runs-on: ubuntu-24.04
permissions: write-all
needs: build
outputs:
VERSION: ${{ steps.check-ver-changed.outputs.VERSION }}
steps:
- uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: "git"
version: 1.0
- uses: actions/checkout@v4
- name: Check Version Changed
id: check-ver-changed
run: |
GIT_TAG=$(git describe --no-long --abbrev=0 --tags --always)
MAKE_TAG=$(make print-version)
if [[ "$GIT_TAG" == "v$MAKE_TAG" ]]; then
echo "ERR: Git tag matches makefile, did you bump Makefile up?" >&2
exit 1
fi
echo "VERSION=$MAKE_TAG" >> "$GITHUB_OUTPUT"
check:
name: Check
needs: release-checks
uses: ./.github/workflows/check.yml
permissions: write-all
build:
name: Build
needs: release-checks
uses: ./.github/workflows/build.yml
permissions: write-all
release:
name: Make Release v${{ needs.release-checks.outputs.VERSION }}
runs-on: ubuntu-24.04
permissions: write-all
needs: [ release-checks, check, build ]
steps:
- uses: actions/download-artifact@v4
with:
@@ -30,7 +56,7 @@ jobs:
- uses: ncipollo/release-action@v1
with:
tag: v${{ inputs.version }}
tag: v${{ needs.release-checks.outputs.VERSION }}
commit: ${{ github.sha }}
artifacts: builds/lidm-*
artifactErrorsFailBuild: true
@@ -41,7 +67,7 @@ jobs:
runs-on: ubuntu-24.04
container: archlinux:latest
permissions: write-all
needs: release
needs: [ release-checks, release ]
steps:
- run: pacman -Sy --noconfirm git github-cli base-devel pacman-contrib
@@ -53,20 +79,20 @@ jobs:
cd "assets/pkg/aur"
chown nobody:nobody . -R
su - -s /bin/bash nobody -c "$PWD/update-pkgs.sh ${{ inputs.version }}"
su - -s /bin/bash nobody -c "$PWD/update-pkgs.sh ${{ needs.release-checks.outputs.VERSION }}"
su - -s /bin/bash nobody -c "$PWD/test-makepkg.sh" # This will also update -git pkgver
chown $UID:$(id -g) . -R
- run: |
BRANCH=actions/update-aur-${{ inputs.version }}
BRANCH=actions/update-aur-${{ needs.release-checks.outputs.VERSION }}
git config --global --add safe.directory $GITHUB_WORKSPACE
git config user.name "GitHub Actions"
git config user.email "actions@github.com"
git checkout -b $BRANCH
git commit -am "Update AUR pkgs to v${{ inputs.version }}"
git commit -am "Update AUR pkgs to v${{ needs.release-checks.outputs.VERSION }}"
git push -u origin $BRANCH
gh pr create --head $BRANCH \
--title "[AUR update]: Bump to ${{ inputs.version }}" \
--title "[AUR update]: Bump to ${{ needs.release-checks.outputs.VERSION }}" \
--body "*This PR was created automatically*"
env:
GH_TOKEN: ${{ github.token }}

View File

@@ -1,5 +1,4 @@
# Kinda based by https://github.com/myrotvorets/set-commit-status-action/actions/runs/12344741285/workflow
name: Push Checks
name: _
on:
push:
@@ -9,7 +8,11 @@ on:
workflow_dispatch:
jobs:
check-and-build:
name: Check and Build
uses: ./.github/workflows/check-and-build.yml
check:
name: Check
uses: ./.github/workflows/check.yml
permissions: write-all
build:
name: Build
uses: ./.github/workflows/build.yml
permissions: write-all

2
.gitignore vendored
View File

@@ -8,3 +8,5 @@ valgrind-out.txt
# nix build result
result
include/version.h

View File

@@ -1,3 +1,6 @@
VERSION = 1.2.0
.DEFAULT_GOAL := lidm
CDIR=src
LDIR=lib
IDIR=include
@@ -7,17 +10,29 @@ PREFIX=/usr
CC?=gcc
CFLAGS?=-O3 -Wall
_CFLAGS=-I$(DIR)
ALLFLAGS=$(CFLAGS) -I$(IDIR)
LIBS=-lpam
_DEPS = log.h util.h ui.h ui_state.h config.h desktop.h auth.h ofield.h efield.h keys.h users.h sessions.h chvt.h macros.h launch_state.h
_DEPS = version.h log.h util.h ui.h ui_state.h config.h desktop.h auth.h ofield.h efield.h keys.h users.h sessions.h chvt.h macros.h launch_state.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o log.o util.o ui.o ui_state.o config.o desktop.o auth.o ofield.o efield.o users.o sessions.o chvt.o launch_state.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
.git/HEAD:
$(IDIR)/version.h: Makefile .git/HEAD
@tmp=$$(mktemp); \
printf '' > $$tmp; \
echo '#define LIDM_VERSION "'$(VERSION)'"' >> $$tmp; \
echo '#define LIDM_GIT_REV "'$$(git describe --long --tags --always || echo '?')'"' >> $$tmp; \
echo '#define LIDM_BUILD_TS '$$(date +%s) >> $$tmp; \
if ! cmp -s $$tmp $@; then \
mv $$tmp $@; \
fi; \
rm -f $$tmp;
$(ODIR)/%.o: $(CDIR)/%.c $(DEPS)
@mkdir -p $(ODIR)
$(CC) -c -o $@ $< $(ALLFLAGS)
@@ -25,7 +40,6 @@ $(ODIR)/%.o: $(CDIR)/%.c $(DEPS)
lidm: $(OBJ)
$(CC) -o $@ $^ $(ALLFLAGS) $(LIBS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o lidm
@@ -78,3 +92,17 @@ pre-commit:
find . -type f -name '*.sh' -not -path './assets/pkg/aur/*/src/*' | xargs shellcheck
clang-format -i $$(git ls-files "*.c" "*.h")
clang-tidy -p . $$(git ls-files "*.c" "*.h")
print-version:
@echo $(VERSION)
.PHONY: clean \
install uninstall \
install-service \
install-service-s6 \
install-service-dinit \
install-service-runit \
install-service-openrc \
install-service-systemd \
pre-commit \
print-version

47
assets/github_scripts/build.sh Executable file
View File

@@ -0,0 +1,47 @@
#!/usr/bin/env bash
set -euo pipefail
if [ -z "$ARCH" ]; then
echo "\$ARCH not present" >&2
exit 1
fi
ERR=0
# shellcheck disable=SC2034
make -j"$(nproc)" "$@" 2> /tmp/stderr || ERR=$?
BSIZE=$(stat --printf="%s" lidm)
HSIZE=$(numfmt --to=iec-i<<<"$BSIZE")B
WARNS=$(
{ grep -E '^[^ ]+\.[ch]:[0-9]+:[0-9]+: [a-z]+:' /tmp/stderr || :; } \
| sed -E 's/^([^ ]+\.[ch]):([0-9]+):([0-9]+): ([a-z]+): (.*)$/::\4 file=\1,line=\2,col=\3::\5/'
)
WARNS_NUM=$({ [[ "$WARNS" == "" ]] && echo 0; } || wc -l <<<"$WARNS")
echo "$WARNS"
{
echo "# Build for $ARCH"
echo ""
if [ -s "/tmp/stderr" ]; then
echo "<details><summary><code>stderr</code></summary>"
echo ""
echo "\`\`\`"
cat "/tmp/stderr"
echo "\`\`\`"
echo ""
echo "</details>"
else
echo "*no \`stderr\` to show*"
fi
echo ""
echo "## Stats"
echo "* **Filesize:** $HSIZE ($BSIZE B)"
echo "* **Warnings & Errors:** $WARNS_NUM"
} >> "$GITHUB_STEP_SUMMARY"
if [ "$ERR" -ne 0 ]; then exit "$ERR"; fi
mv lidm lidm-"$ARCH"
echo "DESCR='$HSIZE, $WARNS_NUM warnings'" >> "$GITHUB_OUTPUT"

View File

@@ -86,6 +86,9 @@ Text to display as the header for such sessions.
.TP
\fBopts_pre, opts_post\fP
To be used for items with multiple options on the left and right sides \fB"< "\fP and \fB" >"\fP.
.TP
\fBellipsis\fP
Ellipsis to be used in multiple parts such as overflowing hostnames.
.SS behavior
Other miscellaneous behavior strings, of mixed types
@@ -98,6 +101,9 @@ Types \fBSTRING_ARRAY\fP. Specify paths to source on login if they exist, simple
.TP
\fBtimefmt\fP
Specify the time format string to be displayed. Check \fBstrftime (3)\fP to know the possible formatting variables.
.TP
\fBrefresh_rate\fP
Rate (in milliseconds) at which the UI should refresh, affects clock and resize behavior.
.SH "SEE ALSO"

View File

@@ -1,6 +1,6 @@
pkgbase = lidm-bin
pkgdesc = A fully colorful customizable TUI display manager made in C. (release binary)
pkgver = 1.1.1
pkgver = 1.2.0
pkgrel = 1
url = https://github.com/javalsai/lidm
arch = x86_64
@@ -8,13 +8,13 @@ pkgbase = lidm-bin
depends = pam
provides = lidm
conflicts = lidm
source = lidm::https://github.com/javalsai/lidm/releases/download/v1.1.1/lidm-amd64
source = default-theme.ini::https://raw.githubusercontent.com/javalsai/lidm/v1.1.1/themes/default.ini
source = lidm.1::https://raw.githubusercontent.com/javalsai/lidm/v1.1.1/assets/man/lidm.1
source = lidm-config.5::https://raw.githubusercontent.com/javalsai/lidm/v1.1.1/assets/man/lidm-config.5
sha256sums = c4e82ae2c08c223ef417edca50f86f516e3f9154339f67110c87d01855673fcf
sha256sums = a8d29e220c23b48b5cd3aac0c0e395e90a9d6c9ca9c9c35a45ad6f3df5f55542
source = lidm::https://github.com/javalsai/lidm/releases/download/v1.2.0/lidm-amd64
source = default-theme.ini::https://raw.githubusercontent.com/javalsai/lidm/v1.2.0/themes/default.ini
source = lidm.1::https://raw.githubusercontent.com/javalsai/lidm/v1.2.0/assets/man/lidm.1
source = lidm-config.5::https://raw.githubusercontent.com/javalsai/lidm/v1.2.0/assets/man/lidm-config.5
sha256sums = 6bf4403c21bd26607302d99d7bd1a129822e7d2506e949fb483ea445e022eb6d
sha256sums = ffaa5fe2cf5011bf53c90f81bfec8585158d35f72c0666db0bd4d3866ae041ca
sha256sums = 7f2fb91f55088be1a9b1c93ecf5d6c1e437f369b56df2eacc9d10b00c93c39f8
sha256sums = 5dbe088ce29c95a400080190560d4308c10519a953e83d2d5020dfdf47dd830f
sha256sums = 0aa5755bdcc60ea80cd9ee0f89233ffaf22c6cee9db9da277274a62c6ed477d9
pkgname = lidm-bin

View File

@@ -1,7 +1,7 @@
# shellcheck disable=SC2034,SC2148,SC2128,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-bin
pkgver=1.1.1
pkgver=1.2.0
pkgrel=1
depends=('pam')
pkgdesc="A fully colorful customizable TUI display manager made in C. (release binary)"
@@ -16,10 +16,10 @@ source=(
"lidm.1::https://raw.githubusercontent.com/javalsai/lidm/v$pkgver/assets/man/lidm.1"
"lidm-config.5::https://raw.githubusercontent.com/javalsai/lidm/v$pkgver/assets/man/lidm-config.5"
)
sha256sums=('c4e82ae2c08c223ef417edca50f86f516e3f9154339f67110c87d01855673fcf'
'a8d29e220c23b48b5cd3aac0c0e395e90a9d6c9ca9c9c35a45ad6f3df5f55542'
sha256sums=('6bf4403c21bd26607302d99d7bd1a129822e7d2506e949fb483ea445e022eb6d'
'ffaa5fe2cf5011bf53c90f81bfec8585158d35f72c0666db0bd4d3866ae041ca'
'7f2fb91f55088be1a9b1c93ecf5d6c1e437f369b56df2eacc9d10b00c93c39f8'
'5dbe088ce29c95a400080190560d4308c10519a953e83d2d5020dfdf47dd830f')
'0aa5755bdcc60ea80cd9ee0f89233ffaf22c6cee9db9da277274a62c6ed477d9')
package() {
install -Dm755 lidm "${pkgdir}/usr/bin/lidm"

View File

@@ -1,7 +1,7 @@
# shellcheck disable=SC2034,SC2148,SC2128,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm-git
pkgver=1.1.1.r0.g3bfc2f5
pkgver=1.2.0.r0.g7f75b8e
pkgrel=1
depends=('pam')
makedepends=('git' 'make' 'gcc')

View File

@@ -1,6 +1,6 @@
pkgbase = lidm
pkgdesc = A fully colorful customizable TUI display manager made in C. (build latest tag)
pkgver = 1.1.1
pkgver = 1.2.0
pkgrel = 1
url = https://github.com/javalsai/lidm
arch = any
@@ -8,7 +8,7 @@ pkgbase = lidm
makedepends = git
makedepends = gcc
depends = pam
source = tarball.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v1.1.1.tar.gz
sha256sums = 915dc5acce413d5d32bb52c6f9980661a389a0939a49ac31bc250b2d162a5479
source = tarball.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v1.2.0.tar.gz
sha256sums = 0dffded5fcef45cb45fe88358b0cba8de04f614e323a9c6e4162f84b6e3a50b6
pkgname = lidm

View File

@@ -1,7 +1,7 @@
# shellcheck disable=SC2034,SC2148,SC2128,SC2154,SC2164
# Maintainer: javalsai <javalsai@proton.me>
pkgname=lidm
pkgver=1.1.1
pkgver=1.2.0
pkgrel=1
depends=('pam')
makedepends=('git' 'gcc')
@@ -10,7 +10,7 @@ arch=('any')
url="https://github.com/javalsai/lidm"
license=('GPL')
source=("tarball.tar.gz::https://github.com/javalsai/lidm/archive/refs/tags/v$pkgver.tar.gz")
sha256sums=('915dc5acce413d5d32bb52c6f9980661a389a0939a49ac31bc250b2d162a5479')
sha256sums=('0dffded5fcef45cb45fe88358b0cba8de04f614e323a9c6e4162f84b6e3a50b6')
build() {
tar -xzf "tarball.tar.gz"

View File

@@ -11,12 +11,14 @@
enum introspection_type {
STRING,
BOOL,
NUMBER,
KEY,
STRING_ARRAY,
};
static const char* NNULLABLE const INTROS_TYS_NAMES[] = {
[STRING] = "STRING",
[BOOL] = "BOOL",
[NUMBER] = "NUMBER",
[KEY] = "KEY",
[STRING_ARRAY] = "STRING_ARRAY",
};
@@ -104,7 +106,8 @@ BUILD(functions, FUNCTIONS, TABLE_FUNCTIONS);
F(char* NNULLABLE, s_xorg, STRING, "xorg", name) \
F(char* NNULLABLE, s_shell, STRING, "shell", name) \
F(char* NNULLABLE, opts_pre, STRING, "< ", name) \
F(char* NNULLABLE, opts_post, STRING, " >", name)
F(char* NNULLABLE, opts_post, STRING, " >", name) \
F(char* NNULLABLE, ellipsis, STRING, "…", name)
BUILD(strings, STRINGS, TABLE_STRINGS);
@@ -116,7 +119,8 @@ BUILD(strings, STRINGS, TABLE_STRINGS);
F(bool, include_defshell, BOOL, true, name) \
F(struct Vector, source, STRING_ARRAY, NULL_VEC, name) \
F(struct Vector, user_source, STRING_ARRAY, NULL_VEC, name) \
F(char* NNULLABLE, timefmt, STRING, "%X %x", name)
F(char* NNULLABLE, timefmt, STRING, "%X %x", name) \
F(long long, refresh_rate, NUMBER, 100, name)
BUILD(behavior, BEHAVIOR, TABLE_BEHAVIOR);

View File

@@ -3,21 +3,31 @@
// Do we just replace the compiler with clang??
#if defined(__clang__)
#define NULLABLE _Nullable
#define NULLABLE _Nullable
#else
#define NULLABLE
#define NULLABLE
#endif
#if defined(__clang__)
#define NNULLABLE _Nonnull
#define NNULLABLE _Nonnull
#else
#define NNULLABLE
#define NNULLABLE
#endif
#if defined(__clang__)
#define UNULLABLE _Null_unspecified
#define UNULLABLE _Null_unspecified
#else
#define UNULLABLE
#define UNULLABLE
#endif
#if defined(__clang__)
#define COMPILER_VERSION __VERSION__
#elif defined(__GNUC__)
#define xstr(s) str(s)
#define str(s) #s
#define COMPILER_VERSION \
"GCC " xstr(__GNUC__) "." xstr(__GNUC_MINOR__) "." xstr(__GNUC_PATCHLEVEL__)
#endif
#define LEN(X) (sizeof(X) / sizeof((X)[0]))

View File

@@ -13,7 +13,7 @@
int find_keyname(enum keys* at, const char* name);
enum keys find_ansi(const char* seq);
void read_press(u_char* length, char* out);
// non blocking, waits up to tv, returns true if actually read
// non blocking, waits up to tv or interrupt, returns true if actually read
bool read_press_nb(u_char* length, char* out, struct timeval* tv);
bool utf8_iscont(char byte);

View File

@@ -1,10 +1,13 @@
#include <errno.h>
#include <linux/fs.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "config.h"
#include "desktop.h"
@@ -111,6 +114,7 @@ unfinished:
#define NOFAIL return (struct parser_error){NULL, 0}
union typ_ptr {
char** string;
long long* number;
bool* boolean;
enum keys* key;
struct Vector* vec;
@@ -147,6 +151,13 @@ struct parser_error parse_key(enum introspection_type typ, union typ_ptr at,
FAIL("Invalid key value, wasn't 'true' nor 'false'");
}
break;
case NUMBER:
errno = 0;
*at.number = strtol(key, NULL, 10);
if (errno) {
FAIL("strtol failed");
}
break;
case KEY:
// NOLINTNEXTLINE(performance-no-int-to-ptr)
if (find_keyname(at.key, key) != 0) {
@@ -205,6 +216,8 @@ struct status config_line_handler(void* _config, char* table, char* k,
size_t offset = this_intros_table->offset + this_intros_key->offset;
union typ_ptr k_addr = {.ptr = (uintptr_t)config + offset};
log_printf("[I] parsing [%s.%s] as %s\n", table, k,
INTROS_TYS_NAMES[this_intros_key->typ]);
struct parser_error err = parse_key(this_intros_key->typ, k_addr, v, offset);
if (err.msg != NULL) {
log_printf("[E] cfg parser, failed to parse [%s.%s] (%s): %s\n", table, k,
@@ -213,7 +226,9 @@ struct status config_line_handler(void* _config, char* table, char* k,
return ret;
}
if (this_intros_key->typ == STRING)
if (this_intros_key->typ == NUMBER)
log_printf("[I] cfg parsed [%s.%s] (%lld)\n", table, k, *k_addr.number);
else if (this_intros_key->typ == STRING)
log_printf("[I] cfg parsed [%s.%s] (%s)\n", table, k, *k_addr.string);
else
log_printf("[I] cfg parsed [%s.%s]\n", table, k);

View File

@@ -1,18 +1,23 @@
#include <pwd.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "chvt.h"
#include "config.h"
#include "log.h"
#include "macros.h"
#include "sessions.h"
#include "ui.h"
#include "users.h"
#include "util.h"
#include "version.h"
#define DATESTR_MAXBUFSIZE 0x20
int main(int argc, char* argv[]) {
// Logger
char* log_output = getenv("LIDM_LOG");
@@ -27,8 +32,45 @@ int main(int argc, char* argv[]) {
log_init(log_fd);
}
// Chvt
if (argc == 2) chvt_str(argv[1]);
if (argc == 2) {
if (strcmp(argv[1], "-v") == 0 || strcmp(argv[1], "--version") == 0) {
// NOLINTBEGIN(clang-analyzer-deadcode.DeadStores)
char* version = "?";
char* revision = "?";
char* builddate = "?";
char* compilever = "?";
// NOLINTEND(clang-analyzer-deadcode.DeadStores)
#ifdef LIDM_VERSION
version = LIDM_VERSION;
#endif
#ifdef LIDM_GIT_REV
revision = LIDM_GIT_REV;
#endif
#ifdef LIDM_BUILD_TS
time_t ts = LIDM_BUILD_TS;
char date_buf[DATESTR_MAXBUFSIZE];
builddate = date_buf;
if (strftime(date_buf, 0xff, "%Y-%m-%dT%H:%M:%SZ", localtime(&ts)) > 0)
builddate = date_buf;
#endif
#ifdef COMPILER_VERSION
compilever = COMPILER_VERSION;
#endif
printf("lidm version %s (git %s, build date %s, compiler %s)\n", version,
revision, builddate, compilever);
return 0;
}
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
printf(
"Usage: lidm [vt number]\n"
"Options:\n"
" -h, --help Display help menu\n"
" -v, --version Display version information\n");
return 0;
}
// Chvt
chvt_str(argv[1]);
}
struct config config = DEFAULT_CONFIG;
char* conf_override = getenv("LIDM_CONF");

203
src/ui.c
View File

@@ -1,11 +1,13 @@
// i'm sorry
// really sorry
#include <asm-generic/errno.h>
#include <errno.h>
#include <pwd.h>
#include <signal.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -31,21 +33,20 @@
const u_char INPUTS_N = 3;
static void print_box();
static void print_footer();
static void restore_all();
static void signal_handler(int code);
struct uint_point {
uint x;
uint y;
};
static void print_session(struct uint_point origin, struct session session,
bool multiple);
static void print_user(struct uint_point origin, struct user user,
bool multiple);
static void print_passwd(struct uint_point origin, uint length, bool err);
static void print_box();
static void print_head();
static void print_footer();
static void restore_all();
static void signal_handler(int code);
static void print_session(struct session session, bool multiple);
static void print_user(struct user user, bool multiple);
static void print_passwd(uint length, bool err);
static void scratch_print_ui();
// ansi resource: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
@@ -79,14 +80,10 @@ void setup(struct config* config) {
(void)atexit(restore_all);
(void)signal(SIGINT, signal_handler);
(void)signal(SIGWINCH, process_sigwinch);
(void)fflush(stdout);
}
static struct uint_point box_start() {
return (struct uint_point){
.x = ((window.ws_col - BOX_WIDTH) / 2) + 1, // looks better
.y = ((window.ws_row - BOX_HEIGHT) / 2), // leave more space under
};
}
static struct uint_point box_start = {.x = 0, .y = 0};
#define STRFTIME_PREALLOC 64
#define TM_YEAR_EPOCH 1900
@@ -98,7 +95,8 @@ static char* fmt_time(const char* fmt) {
char* buf = malloc(alloc_size);
if (!buf) return NULL;
while (true) {
if (strftime(buf, alloc_size, fmt, &tm) != 0) return buf;
if (strftime(buf, alloc_size, fmt, &tm) != 0 && strlen(fmt) != 0)
return buf;
alloc_size *= 2;
char* nbuf = realloc(buf, alloc_size);
@@ -110,10 +108,35 @@ static char* fmt_time(const char* fmt) {
}
}
char* trunc_gethostname(const size_t MAXSIZE, const char* const ELLIPSIS) {
if (utf8len(ELLIPSIS) > MAXSIZE) return NULL;
size_t alloc_size = MAXSIZE + 1;
char* buf = malloc(alloc_size);
if (!buf) return NULL;
while (true) {
if (gethostname(buf, alloc_size) == 0) return buf;
if (errno == ENAMETOOLONG) {
buf[alloc_size] = '\0';
if (utf8len(buf) > MAXSIZE - utf8len(ELLIPSIS)) {
strcpy(&buf[MAXSIZE - utf8len(ELLIPSIS)], ELLIPSIS);
return buf;
}
alloc_size *= 2;
char* nbuf = realloc(buf, alloc_size);
if (!nbuf) goto fail;
buf = nbuf;
} else
goto fail;
}
fail:
free(buf);
return NULL;
}
void ui_update_cursor_focus() {
struct uint_point bstart = box_start();
u_char line = bstart.y;
u_char col = bstart.x + VALUES_COL;
u_char line = box_start.y;
u_char col = box_start.x + VALUES_COL;
struct opts_field* ofield = get_opts_ffield();
u_char maxlen = VALUE_MAXLEN;
@@ -133,19 +156,16 @@ void ui_update_cursor_focus() {
line += PASSWD_ROW;
(void)printf("\x1b[%d;%dH", line, col);
(void)fflush(stdout);
}
void ui_update_field(enum input focused_input) {
struct uint_point origin = box_start();
if (focused_input == PASSWD) {
print_passwd(origin, utf8len(of_passwd.efield.content), false);
print_passwd(utf8len(of_passwd.efield.content), false);
} else if (focused_input == SESSION) {
print_session(origin, st_session(g_config->behavior.include_defshell),
print_session(st_session(g_config->behavior.include_defshell),
of_session.opts > 1);
} else if (focused_input == USER) {
print_user(origin, st_user(), of_user.opts > 1);
print_user(st_user(), of_user.opts > 1);
ui_update_field(SESSION);
}
@@ -170,9 +190,12 @@ void ui_update_ofield(struct opts_field* NNULLABLE self) {
ui_update_field(input);
}
static char* unknown_str = "unknown";
void scratch_print_ui() {
ioctl(STDOUT_FILENO, TIOCGWINSZ, &window);
box_start = (struct uint_point){
.x = ((window.ws_col - BOX_WIDTH) / 2) + 1, // looks better
.y = ((window.ws_row - BOX_HEIGHT) / 2), // leave more space under
};
if (window.ws_row < BOX_HEIGHT + INNER_BOX_OUT_MARGIN * 2 ||
window.ws_col < BOX_WIDTH + INNER_BOX_OUT_MARGIN * 2) {
@@ -184,39 +207,11 @@ void scratch_print_ui() {
printf("\033[2J\033[H"); // Clear screen
// hostnames larger won't render properly
const u_char HOSTNAME_SIZE = VALUES_COL - VALUES_SEPR - BOX_HMARGIN;
char hostname_buf[HOSTNAME_SIZE];
char* hostname = hostname_buf;
if (gethostname(hostname_buf, HOSTNAME_SIZE) != 0) {
hostname = unknown_str;
} else {
// Ig "successful completion" doesn't contemplate truncation case, so need
// to append the unspecified nullbyte
// char* hidx =
// (char*)utf8back(&hostname[VALUES_COL - VALUES_SEPR - BOX_HMARGIN -
// 1]);
// *hidx = '\0';
}
/// PRINTING
const struct uint_point BOXSTART = box_start();
// printf box
print_box();
// put hostname
printf("\x1b[%d;%dH\x1b[%sm%s\x1b[%sm", BOXSTART.y + HEAD_ROW,
BOXSTART.x + VALUES_COL - VALUES_SEPR - (uint)utf8len(hostname),
g_config->colors.e_hostname, hostname, g_config->colors.fg);
// put date
char* fmtd_time = fmt_time(g_config->behavior.timefmt);
printf("\x1b[%d;%dH\x1b[%sm%s\x1b[%sm", BOXSTART.y + HEAD_ROW,
BOXSTART.x + BOX_WIDTH - 1 - BOX_HMARGIN - (uint)utf8len(fmtd_time),
g_config->colors.e_date, fmtd_time, g_config->colors.fg);
free(fmtd_time);
print_head();
print_footer();
ui_update_field(SESSION);
@@ -225,12 +220,12 @@ void scratch_print_ui() {
ui_update_cursor_focus();
}
#define READ_NONBLOCK_DELAY 100000
#define MS_PER_S 1000
#define US_PER_MS 1000
// NOLINTNEXTLINE(readability-function-cognitive-complexity)
int load(struct Vector* users, struct Vector* sessions) {
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = READ_NONBLOCK_DELAY; // timeout = 100ms
long long ms_time = g_config->behavior.refresh_rate;
ms_time = ms_time < 0 ? 0 : ms_time;
/// SETUP
gusers = users;
@@ -279,8 +274,17 @@ int load(struct Vector* users, struct Vector* sessions) {
if (need_resize) {
need_resize = 0;
scratch_print_ui();
} else {
// partial refresh
print_head();
ui_update_cursor_focus();
}
struct timeval tv;
tv.tv_usec = (ms_time % MS_PER_S) * US_PER_MS;
tv.tv_sec = ms_time / MS_PER_S;
(void)fflush(stdout);
if (!read_press_nb(&len, seq, &tv)) continue;
if (*seq == '\x1b') {
enum keys ansi_code = find_ansi(seq);
@@ -318,7 +322,7 @@ int load(struct Vector* users, struct Vector* sessions) {
if (!launch(st_user().username, of_passwd.efield.content,
st_session(g_config->behavior.include_defshell),
&restore_all, g_config)) {
print_passwd(box_start(), utf8len(of_passwd.efield.content), true);
print_passwd(utf8len(of_passwd.efield.content), true);
ui_update_cursor_focus();
}
} else
@@ -344,9 +348,30 @@ u_char get_render_pos_offset(struct opts_field* self, u_char maxlen) {
return pos - ofield_display_cursor_col(self, maxlen);
}
void print_session(struct uint_point origin, struct session session,
bool multiple) {
clean_line(origin, SESSION_ROW);
#define HOSTNAME_SIZE (VALUES_COL - VALUES_SEPR - BOX_HMARGIN - 1)
void print_head() {
// hostname doesn't just change on runtime
static char* hostname = NULL;
if (!hostname)
hostname = trunc_gethostname(HOSTNAME_SIZE, g_config->strings.ellipsis);
if (!hostname) hostname = "unknown";
clean_line(box_start, HEAD_ROW);
// put hostname
printf("\x1b[%dG\x1b[%sm%s\x1b[%sm",
box_start.x + VALUES_COL - VALUES_SEPR - (uint)utf8len(hostname),
g_config->colors.e_hostname, hostname, g_config->colors.fg);
// put date
char* fmtd_time = fmt_time(g_config->behavior.timefmt);
printf("\x1b[%dG\x1b[%sm%s\x1b[%sm",
box_start.x + BOX_WIDTH - 1 - BOX_HMARGIN - (uint)utf8len(fmtd_time),
g_config->colors.e_date, fmtd_time, g_config->colors.fg);
free(fmtd_time);
}
void print_session(struct session session, bool multiple) {
clean_line(box_start, SESSION_ROW);
const char* NNULLABLE session_type;
if (session.type == XORG) {
@@ -361,10 +386,10 @@ void print_session(struct uint_point origin, struct session session,
// already in the box, - 1 bcs no need to step over margin, same reasoning in
// other places
printf(
"\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(origin.x + VALUES_COL - VALUES_SEPR - utf8len(session_type) - 1),
g_config->colors.e_header, session_type, g_config->colors.fg);
printf("\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(box_start.x + VALUES_COL - VALUES_SEPR -
utf8len(session_type) - 1),
g_config->colors.e_header, session_type, g_config->colors.fg);
char* session_color;
if (session.type == XORG) {
@@ -382,21 +407,21 @@ void print_session(struct uint_point origin, struct session session,
toprint += get_render_pos_offset(&of_session, maxlen);
size_t printlen = utf8seekn(toprint, maxlen) - toprint;
printf("\r\x1b[%dC%s\x1b[%sm%.*s\x1b[%sm%s", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC%s\x1b[%sm%.*s\x1b[%sm%s", box_start.x + VALUES_COL - 1,
g_config->strings.opts_pre, session_color, (int)printlen, toprint,
g_config->colors.fg, g_config->strings.opts_post);
} else {
toprint += get_render_pos_offset(&of_session, VALUE_MAXLEN);
size_t printlen = utf8seekn(toprint, VALUE_MAXLEN) - toprint;
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", box_start.x + VALUES_COL - 1,
session_color, (int)printlen, toprint, g_config->colors.fg);
}
}
void print_user(struct uint_point origin, struct user user, bool multiple) {
clean_line(origin, USER_ROW);
void print_user(struct user user, bool multiple) {
clean_line(box_start, USER_ROW);
printf("\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(origin.x + VALUES_COL - VALUES_SEPR -
(ulong)(box_start.x + VALUES_COL - VALUES_SEPR -
utf8len(g_config->strings.e_user) - 1),
g_config->colors.e_header, g_config->strings.e_user,
g_config->colors.fg);
@@ -410,21 +435,21 @@ void print_user(struct uint_point origin, struct user user, bool multiple) {
toprint += get_render_pos_offset(&of_session, maxlen);
size_t printlen = utf8seekn(toprint, maxlen) - toprint;
printf("\r\x1b[%dC< \x1b[%sm%.*s\x1b[%sm >", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC< \x1b[%sm%.*s\x1b[%sm >", box_start.x + VALUES_COL - 1,
user_color, (int)printlen, toprint, g_config->colors.fg);
} else {
toprint += get_render_pos_offset(&of_user, VALUE_MAXLEN);
size_t printlen = utf8seekn(toprint, VALUE_MAXLEN) - toprint;
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", origin.x + VALUES_COL - 1,
printf("\r\x1b[%dC\x1b[%sm%.*s\x1b[%sm", box_start.x + VALUES_COL - 1,
user_color, (int)printlen, toprint, g_config->colors.fg);
}
}
void print_passwd(struct uint_point origin, uint length, bool err) {
void print_passwd(uint length, bool err) {
char passwd_prompt[VALUE_MAXLEN + 1];
clean_line(origin, PASSWD_ROW);
clean_line(box_start, PASSWD_ROW);
printf("\r\x1b[%luC\x1b[%sm%s\x1b[%sm",
(ulong)(origin.x + VALUES_COL - VALUES_SEPR -
(ulong)(box_start.x + VALUES_COL - VALUES_SEPR -
utf8len(g_config->strings.e_passwd) - 1),
g_config->colors.e_header, g_config->strings.e_passwd,
g_config->colors.fg);
@@ -440,7 +465,7 @@ void print_passwd(struct uint_point origin, uint length, bool err) {
memset(passwd_prompt, '*', actual_len);
passwd_prompt[VALUE_MAXLEN] = '\0';
printf("\r\x1b[%dC\x1b[%sm", origin.x + VALUES_COL - 1, pass_color);
printf("\r\x1b[%dC\x1b[%sm", box_start.x + VALUES_COL - 1, pass_color);
printf("%s", passwd_prompt);
printf("\x1b[%sm", g_config->colors.fg);
@@ -464,9 +489,8 @@ static void print_row(uint wid, uint n, char* edge1, char* edge2,
}
static void print_box() {
const struct uint_point BSTART = box_start();
printf("\x1b[%d;%dH\x1b[%sm", BSTART.y, BSTART.x, g_config->colors.e_box);
printf("\x1b[%d;%dH\x1b[%sm", box_start.y, box_start.x,
g_config->colors.e_box);
print_row(BOX_WIDTH - 2, 1, g_config->chars.ctl, g_config->chars.ctr,
g_config->chars.hb);
print_empty_row(BOX_WIDTH - 2, BOX_HEIGHT - 2, g_config->chars.vb,
@@ -474,7 +498,6 @@ static void print_box() {
print_row(BOX_WIDTH - 2, 1, g_config->chars.cbl, g_config->chars.cbr,
g_config->chars.hb);
printf("\x1b[%sm", g_config->colors.fg);
(void)fflush(stdout);
}
static void print_footer() {
@@ -498,24 +521,21 @@ static void print_footer() {
KEY_NAMES[g_config->functions.reboot],
KEY_NAMES[g_config->functions.refresh], g_config->strings.f_poweroff,
g_config->strings.f_reboot, g_config->strings.f_refresh);
(void)fflush(stdout);
}
void print_err(const char* msg) {
struct uint_point origin = box_start();
(void)fprintf(stderr, "\x1b[%d;%dH%s(%d): %s", origin.y - 1, origin.x, msg,
errno, strerror(errno));
(void)fprintf(stderr, "\x1b[%d;%dH%s(%d): %s", box_start.y - 1, box_start.x,
msg, errno, strerror(errno));
}
void print_errno(const char* descr) {
struct uint_point origin = box_start();
if (descr == NULL)
(void)fprintf(stderr, "\x1b[%d;%dH\x1b[%smunknown error(%d): %s",
origin.y - 1, origin.x, g_config->colors.err, errno,
box_start.y - 1, box_start.x, g_config->colors.err, errno,
strerror(errno));
else {
(void)fprintf(stderr, "\x1b[%d;%dH\x1b[%sm%s(%d): %s", origin.y - 1,
origin.x, g_config->colors.err, descr, errno,
(void)fprintf(stderr, "\x1b[%d;%dH\x1b[%sm%s(%d): %s", box_start.y - 1,
box_start.x, g_config->colors.err, descr, errno,
strerror(errno));
}
}
@@ -523,7 +543,6 @@ void print_errno(const char* descr) {
void restore_all() {
// restore cursor pos, restore screen and show cursor
(void)printf("\x1b[u\x1b[?47l\x1b[?25h");
(void)fflush(stdout);
tcsetattr(STDOUT_FILENO, TCSANOW, &orig_term);
}

View File

@@ -59,8 +59,9 @@ bool read_press_nb(u_char* length, char* out, struct timeval* tv) {
fd_set fds;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds);
errno = 0;
int ret = select(STDIN_FILENO + 1, &fds, NULL, NULL, tv);
if ((ret < 0 && errno == EINTR) || ret == 0) return false;
if (errno || ret <= 0) return false;
read_press(length, out);
return true;

View File

@@ -38,10 +38,12 @@ e_key = "1;23;38;5;197"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
# timefmt = "%X %x"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
# timefmt = "%X %x"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_user = "38;2;148;89;84"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_user = "38;2;211;137;88"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -39,10 +39,12 @@ s_xorg = "X"
s_shell = "$"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "\xef\x80\x97 %X \xef\x84\xb3 %x"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_key = "32"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ e_key = "34"
# s_shell = "shell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -40,10 +40,12 @@ s_xorg = ""
s_shell = ""
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = " "
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -38,10 +38,12 @@ s_xorg = "xworg"
s_shell = "swell"
# opts_pre = "< "
# opts_post = " >"
# ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"

View File

@@ -39,10 +39,12 @@ s_xorg = "xorg"
s_shell = "sh"
opts_pre = "· "
opts_post = " "
ellipsis = "…"
[behavior]
# include_defshell = true
timefmt = "%Y-%m-%d %H:%M:%S"
# refresh_rate = 100
source = "/etc/lidm.env"
source = "/etc/locale.conf"
user_source = ".lidm.env"