diff --git a/pkg/PKGBUILD b/pkg/PKGBUILD index 44e215e..2c6a891 100644 --- a/pkg/PKGBUILD +++ b/pkg/PKGBUILD @@ -44,7 +44,7 @@ package() { cd "$srcdir/greetd-moongreet" python -m installer --destdir="$pkgdir" dist/*.whl - # Example config + # Greeter config install -Dm644 config/moongreet.toml "$pkgdir/etc/moongreet/moongreet.toml" # Cache directory diff --git a/pkg/greetd-moongreet/HEAD b/pkg/greetd-moongreet/HEAD new file mode 100644 index 0000000..b870d82 --- /dev/null +++ b/pkg/greetd-moongreet/HEAD @@ -0,0 +1 @@ +ref: refs/heads/main diff --git a/pkg/greetd-moongreet/config b/pkg/greetd-moongreet/config new file mode 100644 index 0000000..1839de9 --- /dev/null +++ b/pkg/greetd-moongreet/config @@ -0,0 +1,9 @@ +[core] + repositoryformatversion = 0 + filemode = true + bare = true +[remote "origin"] + url = https://gitea.moonarch.de/nevaforget/greetd-moongreet.git + tagOpt = --no-tags + fetch = +refs/*:refs/* + mirror = true diff --git a/pkg/greetd-moongreet/description b/pkg/greetd-moongreet/description new file mode 100644 index 0000000..498b267 --- /dev/null +++ b/pkg/greetd-moongreet/description @@ -0,0 +1 @@ +Unnamed repository; edit this file 'description' to name the repository. diff --git a/pkg/greetd-moongreet/hooks/applypatch-msg.sample b/pkg/greetd-moongreet/hooks/applypatch-msg.sample new file mode 100755 index 0000000..a5d7b84 --- /dev/null +++ b/pkg/greetd-moongreet/hooks/applypatch-msg.sample @@ -0,0 +1,15 @@ +#!/bin/sh +# +# An example hook script to check the commit log message taken by +# applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. The hook is +# allowed to edit the commit message file. +# +# To enable this hook, rename this file to "applypatch-msg". + +. git-sh-setup +commitmsg="$(git rev-parse --git-path hooks/commit-msg)" +test -x "$commitmsg" && exec "$commitmsg" ${1+"$@"} +: diff --git a/pkg/greetd-moongreet/hooks/commit-msg.sample b/pkg/greetd-moongreet/hooks/commit-msg.sample new file mode 100755 index 0000000..b58d118 --- /dev/null +++ b/pkg/greetd-moongreet/hooks/commit-msg.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to check the commit log message. +# Called by "git commit" with one argument, the name of the file +# that has the commit message. The hook should exit with non-zero +# status after issuing an appropriate message if it wants to stop the +# commit. The hook is allowed to edit the commit message file. +# +# To enable this hook, rename this file to "commit-msg". + +# Uncomment the below to add a Signed-off-by line to the message. +# Doing this in a hook is a bad idea in general, but the prepare-commit-msg +# hook is more suited to it. +# +# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" + +# This example catches duplicate Signed-off-by lines. + +test "" = "$(grep '^Signed-off-by: ' "$1" | + sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { + echo >&2 Duplicate Signed-off-by lines. + exit 1 +} diff --git a/pkg/greetd-moongreet/hooks/fsmonitor-watchman.sample b/pkg/greetd-moongreet/hooks/fsmonitor-watchman.sample new file mode 100755 index 0000000..23e856f --- /dev/null +++ b/pkg/greetd-moongreet/hooks/fsmonitor-watchman.sample @@ -0,0 +1,174 @@ +#!/usr/bin/perl + +use strict; +use warnings; +use IPC::Open2; + +# An example hook script to integrate Watchman +# (https://facebook.github.io/watchman/) with git to speed up detecting +# new and modified files. +# +# The hook is passed a version (currently 2) and last update token +# formatted as a string and outputs to stdout a new update token and +# all files that have been modified since the update token. Paths must +# be relative to the root of the working tree and separated by a single NUL. +# +# To enable this hook, rename this file to "query-watchman" and set +# 'git config core.fsmonitor .git/hooks/query-watchman' +# +my ($version, $last_update_token) = @ARGV; + +# Uncomment for debugging +# print STDERR "$0 $version $last_update_token\n"; + +# Check the hook interface version +if ($version ne 2) { + die "Unsupported query-fsmonitor hook version '$version'.\n" . + "Falling back to scanning...\n"; +} + +my $git_work_tree = get_working_dir(); + +my $retry = 1; + +my $json_pkg; +eval { + require JSON::XS; + $json_pkg = "JSON::XS"; + 1; +} or do { + require JSON::PP; + $json_pkg = "JSON::PP"; +}; + +launch_watchman(); + +sub launch_watchman { + my $o = watchman_query(); + if (is_work_tree_watched($o)) { + output_result($o->{clock}, @{$o->{files}}); + } +} + +sub output_result { + my ($clockid, @files) = @_; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # binmode $fh, ":utf8"; + # print $fh "$clockid\n@files\n"; + # close $fh; + + binmode STDOUT, ":utf8"; + print $clockid; + print "\0"; + local $, = "\0"; + print @files; +} + +sub watchman_clock { + my $response = qx/watchman clock "$git_work_tree"/; + die "Failed to get clock id on '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + + return $json_pkg->new->utf8->decode($response); +} + +sub watchman_query { + my $pid = open2(\*CHLD_OUT, \*CHLD_IN, 'watchman -j --no-pretty') + or die "open2() failed: $!\n" . + "Falling back to scanning...\n"; + + # In the query expression below we're asking for names of files that + # changed since $last_update_token but not from the .git folder. + # + # To accomplish this, we're using the "since" generator to use the + # recency index to select candidate nodes and "fields" to limit the + # output to file names only. Then we're using the "expression" term to + # further constrain the results. + my $last_update_line = ""; + if (substr($last_update_token, 0, 1) eq "c") { + $last_update_token = "\"$last_update_token\""; + $last_update_line = qq[\n"since": $last_update_token,]; + } + my $query = <<" END"; + ["query", "$git_work_tree", {$last_update_line + "fields": ["name"], + "expression": ["not", ["dirname", ".git"]] + }] + END + + # Uncomment for debugging the watchman query + # open (my $fh, ">", ".git/watchman-query.json"); + # print $fh $query; + # close $fh; + + print CHLD_IN $query; + close CHLD_IN; + my $response = do {local $/; }; + + # Uncomment for debugging the watch response + # open ($fh, ">", ".git/watchman-response.json"); + # print $fh $response; + # close $fh; + + die "Watchman: command returned no output.\n" . + "Falling back to scanning...\n" if $response eq ""; + die "Watchman: command returned invalid output: $response\n" . + "Falling back to scanning...\n" unless $response =~ /^\{/; + + return $json_pkg->new->utf8->decode($response); +} + +sub is_work_tree_watched { + my ($output) = @_; + my $error = $output->{error}; + if ($retry > 0 and $error and $error =~ m/unable to resolve root .* directory (.*) is not watched/) { + $retry--; + my $response = qx/watchman watch "$git_work_tree"/; + die "Failed to make watchman watch '$git_work_tree'.\n" . + "Falling back to scanning...\n" if $? != 0; + $output = $json_pkg->new->utf8->decode($response); + $error = $output->{error}; + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + # Uncomment for debugging watchman output + # open (my $fh, ">", ".git/watchman-output.out"); + # close $fh; + + # Watchman will always return all files on the first query so + # return the fast "everything is dirty" flag to git and do the + # Watchman query just to get it over with now so we won't pay + # the cost in git to look up each individual file. + my $o = watchman_clock(); + $error = $output->{error}; + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + output_result($o->{clock}, ("/")); + $last_update_token = $o->{clock}; + + eval { launch_watchman() }; + return 0; + } + + die "Watchman: $error.\n" . + "Falling back to scanning...\n" if $error; + + return 1; +} + +sub get_working_dir { + my $working_dir; + if ($^O =~ 'msys' || $^O =~ 'cygwin') { + $working_dir = Win32::GetCwd(); + $working_dir =~ tr/\\/\//; + } else { + require Cwd; + $working_dir = Cwd::cwd(); + } + + return $working_dir; +} diff --git a/pkg/greetd-moongreet/hooks/post-update.sample b/pkg/greetd-moongreet/hooks/post-update.sample new file mode 100755 index 0000000..ec17ec1 --- /dev/null +++ b/pkg/greetd-moongreet/hooks/post-update.sample @@ -0,0 +1,8 @@ +#!/bin/sh +# +# An example hook script to prepare a packed repository for use over +# dumb transports. +# +# To enable this hook, rename this file to "post-update". + +exec git update-server-info diff --git a/pkg/greetd-moongreet/hooks/pre-applypatch.sample b/pkg/greetd-moongreet/hooks/pre-applypatch.sample new file mode 100755 index 0000000..4142082 --- /dev/null +++ b/pkg/greetd-moongreet/hooks/pre-applypatch.sample @@ -0,0 +1,14 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed +# by applypatch from an e-mail message. +# +# The hook should exit with non-zero status after issuing an +# appropriate message if it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-applypatch". + +. git-sh-setup +precommit="$(git rev-parse --git-path hooks/pre-commit)" +test -x "$precommit" && exec "$precommit" ${1+"$@"} +: diff --git a/pkg/greetd-moongreet/hooks/pre-commit.sample b/pkg/greetd-moongreet/hooks/pre-commit.sample new file mode 100755 index 0000000..29ed5ee --- /dev/null +++ b/pkg/greetd-moongreet/hooks/pre-commit.sample @@ -0,0 +1,49 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git commit" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message if +# it wants to stop the commit. +# +# To enable this hook, rename this file to "pre-commit". + +if git rev-parse --verify HEAD >/dev/null 2>&1 +then + against=HEAD +else + # Initial commit: diff against an empty tree object + against=$(git hash-object -t tree /dev/null) +fi + +# If you want to allow non-ASCII filenames set this variable to true. +allownonascii=$(git config --type=bool hooks.allownonascii) + +# Redirect output to stderr. +exec 1>&2 + +# Cross platform projects tend to avoid non-ASCII filenames; prevent +# them from being added to the repository. We exploit the fact that the +# printable range starts at the space character and ends with tilde. +if [ "$allownonascii" != "true" ] && + # Note that the use of brackets around a tr range is ok here, (it's + # even required, for portability to Solaris 10's /usr/bin/tr), since + # the square bracket bytes happen to fall in the designated range. + test $(git diff-index --cached --name-only --diff-filter=A -z $against | + LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0 +then + cat <<\EOF +Error: Attempt to add a non-ASCII file name. + +This can cause problems if you want to work with people on other platforms. + +To be portable it is advisable to rename the file. + +If you know what you are doing you can disable this check using: + + git config hooks.allownonascii true +EOF + exit 1 +fi + +# If there are whitespace errors, print the offending file names and fail. +exec git diff-index --check --cached $against -- diff --git a/pkg/greetd-moongreet/hooks/pre-merge-commit.sample b/pkg/greetd-moongreet/hooks/pre-merge-commit.sample new file mode 100755 index 0000000..399eab1 --- /dev/null +++ b/pkg/greetd-moongreet/hooks/pre-merge-commit.sample @@ -0,0 +1,13 @@ +#!/bin/sh +# +# An example hook script to verify what is about to be committed. +# Called by "git merge" with no arguments. The hook should +# exit with non-zero status after issuing an appropriate message to +# stderr if it wants to stop the merge commit. +# +# To enable this hook, rename this file to "pre-merge-commit". + +. git-sh-setup +test -x "$GIT_DIR/hooks/pre-commit" && + exec "$GIT_DIR/hooks/pre-commit" +: diff --git a/pkg/greetd-moongreet/hooks/pre-push.sample b/pkg/greetd-moongreet/hooks/pre-push.sample new file mode 100755 index 0000000..4ce688d --- /dev/null +++ b/pkg/greetd-moongreet/hooks/pre-push.sample @@ -0,0 +1,53 @@ +#!/bin/sh + +# An example hook script to verify what is about to be pushed. Called by "git +# push" after it has checked the remote status, but before anything has been +# pushed. If this script exits with a non-zero status nothing will be pushed. +# +# This hook is called with the following parameters: +# +# $1 -- Name of the remote to which the push is being done +# $2 -- URL to which the push is being done +# +# If pushing without using a named remote those arguments will be equal. +# +# Information about the commits which are being pushed is supplied as lines to +# the standard input in the form: +# +# +# +# This sample shows how to prevent push of commits where the log message starts +# with "WIP" (work in progress). + +remote="$1" +url="$2" + +zero=$(git hash-object --stdin &2 "Found WIP commit in $local_ref, not pushing" + exit 1 + fi + fi +done + +exit 0 diff --git a/pkg/greetd-moongreet/hooks/pre-rebase.sample b/pkg/greetd-moongreet/hooks/pre-rebase.sample new file mode 100755 index 0000000..6cbef5c --- /dev/null +++ b/pkg/greetd-moongreet/hooks/pre-rebase.sample @@ -0,0 +1,169 @@ +#!/bin/sh +# +# Copyright (c) 2006, 2008 Junio C Hamano +# +# The "pre-rebase" hook is run just before "git rebase" starts doing +# its job, and can prevent the command from running by exiting with +# non-zero status. +# +# The hook is called with the following parameters: +# +# $1 -- the upstream the series was forked from. +# $2 -- the branch being rebased (or empty when rebasing the current branch). +# +# This sample shows how to prevent topic branches that are already +# merged to 'next' branch from getting rebased, because allowing it +# would result in rebasing already published history. + +publish=next +basebranch="$1" +if test "$#" = 2 +then + topic="refs/heads/$2" +else + topic=`git symbolic-ref HEAD` || + exit 0 ;# we do not interrupt rebasing detached HEAD +fi + +case "$topic" in +refs/heads/??/*) + ;; +*) + exit 0 ;# we do not interrupt others. + ;; +esac + +# Now we are dealing with a topic branch being rebased +# on top of master. Is it OK to rebase it? + +# Does the topic really exist? +git show-ref -q "$topic" || { + echo >&2 "No such branch $topic" + exit 1 +} + +# Is topic fully merged to master? +not_in_master=`git rev-list --pretty=oneline ^master "$topic"` +if test -z "$not_in_master" +then + echo >&2 "$topic is fully merged to master; better remove it." + exit 1 ;# we could allow it, but there is no point. +fi + +# Is topic ever merged to next? If so you should not be rebasing it. +only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` +only_next_2=`git rev-list ^master ${publish} | sort` +if test "$only_next_1" = "$only_next_2" +then + not_in_topic=`git rev-list "^$topic" master` + if test -z "$not_in_topic" + then + echo >&2 "$topic is already up to date with master" + exit 1 ;# we could allow it, but there is no point. + else + exit 0 + fi +else + not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` + /usr/bin/perl -e ' + my $topic = $ARGV[0]; + my $msg = "* $topic has commits already merged to public branch:\n"; + my (%not_in_next) = map { + /^([0-9a-f]+) /; + ($1 => 1); + } split(/\n/, $ARGV[1]); + for my $elem (map { + /^([0-9a-f]+) (.*)$/; + [$1 => $2]; + } split(/\n/, $ARGV[2])) { + if (!exists $not_in_next{$elem->[0]}) { + if ($msg) { + print STDERR $msg; + undef $msg; + } + print STDERR " $elem->[1]\n"; + } + } + ' "$topic" "$not_in_next" "$not_in_master" + exit 1 +fi + +<<\DOC_END + +This sample hook safeguards topic branches that have been +published from being rewound. + +The workflow assumed here is: + + * Once a topic branch forks from "master", "master" is never + merged into it again (either directly or indirectly). + + * Once a topic branch is fully cooked and merged into "master", + it is deleted. If you need to build on top of it to correct + earlier mistakes, a new topic branch is created by forking at + the tip of the "master". This is not strictly necessary, but + it makes it easier to keep your history simple. + + * Whenever you need to test or publish your changes to topic + branches, merge them into "next" branch. + +The script, being an example, hardcodes the publish branch name +to be "next", but it is trivial to make it configurable via +$GIT_DIR/config mechanism. + +With this workflow, you would want to know: + +(1) ... if a topic branch has ever been merged to "next". Young + topic branches can have stupid mistakes you would rather + clean up before publishing, and things that have not been + merged into other branches can be easily rebased without + affecting other people. But once it is published, you would + not want to rewind it. + +(2) ... if a topic branch has been fully merged to "master". + Then you can delete it. More importantly, you should not + build on top of it -- other people may already want to + change things related to the topic as patches against your + "master", so if you need further changes, it is better to + fork the topic (perhaps with the same name) afresh from the + tip of "master". + +Let's look at this example: + + o---o---o---o---o---o---o---o---o---o "next" + / / / / + / a---a---b A / / + / / / / + / / c---c---c---c B / + / / / \ / + / / / b---b C \ / + / / / / \ / + ---o---o---o---o---o---o---o---o---o---o---o "master" + + +A, B and C are topic branches. + + * A has one fix since it was merged up to "next". + + * B has finished. It has been fully merged up to "master" and "next", + and is ready to be deleted. + + * C has not merged to "next" at all. + +We would want to allow C to be rebased, refuse A, and encourage +B to be deleted. + +To compute (1): + + git rev-list ^master ^topic next + git rev-list ^master next + + if these match, topic has not merged in next at all. + +To compute (2): + + git rev-list master..topic + + if this is empty, it is fully merged to "master". + +DOC_END diff --git a/pkg/greetd-moongreet/hooks/pre-receive.sample b/pkg/greetd-moongreet/hooks/pre-receive.sample new file mode 100755 index 0000000..a1fd29e --- /dev/null +++ b/pkg/greetd-moongreet/hooks/pre-receive.sample @@ -0,0 +1,24 @@ +#!/bin/sh +# +# An example hook script to make use of push options. +# The example simply echoes all push options that start with 'echoback=' +# and rejects all pushes when the "reject" push option is used. +# +# To enable this hook, rename this file to "pre-receive". + +if test -n "$GIT_PUSH_OPTION_COUNT" +then + i=0 + while test "$i" -lt "$GIT_PUSH_OPTION_COUNT" + do + eval "value=\$GIT_PUSH_OPTION_$i" + case "$value" in + echoback=*) + echo "echo from the pre-receive-hook: ${value#*=}" >&2 + ;; + reject) + exit 1 + esac + i=$((i + 1)) + done +fi diff --git a/pkg/greetd-moongreet/hooks/prepare-commit-msg.sample b/pkg/greetd-moongreet/hooks/prepare-commit-msg.sample new file mode 100755 index 0000000..10fa14c --- /dev/null +++ b/pkg/greetd-moongreet/hooks/prepare-commit-msg.sample @@ -0,0 +1,42 @@ +#!/bin/sh +# +# An example hook script to prepare the commit log message. +# Called by "git commit" with the name of the file that has the +# commit message, followed by the description of the commit +# message's source. The hook's purpose is to edit the commit +# message file. If the hook fails with a non-zero status, +# the commit is aborted. +# +# To enable this hook, rename this file to "prepare-commit-msg". + +# This hook includes three examples. The first one removes the +# "# Please enter the commit message..." help message. +# +# The second includes the output of "git diff --name-status -r" +# into the message, just before the "git status" output. It is +# commented because it doesn't cope with --amend or with squashed +# commits. +# +# The third example adds a Signed-off-by line to the message, that can +# still be edited. This is rarely a good idea. + +COMMIT_MSG_FILE=$1 +COMMIT_SOURCE=$2 +SHA1=$3 + +/usr/bin/perl -i.bak -ne 'print unless(m/^. Please enter the commit message/..m/^#$/)' "$COMMIT_MSG_FILE" + +# case "$COMMIT_SOURCE,$SHA1" in +# ,|template,) +# /usr/bin/perl -i.bak -pe ' +# print "\n" . `git diff --cached --name-status -r` +# if /^#/ && $first++ == 0' "$COMMIT_MSG_FILE" ;; +# *) ;; +# esac + +# SOB=$(git var GIT_COMMITTER_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') +# git interpret-trailers --in-place --trailer "$SOB" "$COMMIT_MSG_FILE" +# if test -z "$COMMIT_SOURCE" +# then +# /usr/bin/perl -i.bak -pe 'print "\n" if !$first_line++' "$COMMIT_MSG_FILE" +# fi diff --git a/pkg/greetd-moongreet/hooks/push-to-checkout.sample b/pkg/greetd-moongreet/hooks/push-to-checkout.sample new file mode 100755 index 0000000..af5a0c0 --- /dev/null +++ b/pkg/greetd-moongreet/hooks/push-to-checkout.sample @@ -0,0 +1,78 @@ +#!/bin/sh + +# An example hook script to update a checked-out tree on a git push. +# +# This hook is invoked by git-receive-pack(1) when it reacts to git +# push and updates reference(s) in its repository, and when the push +# tries to update the branch that is currently checked out and the +# receive.denyCurrentBranch configuration variable is set to +# updateInstead. +# +# By default, such a push is refused if the working tree and the index +# of the remote repository has any difference from the currently +# checked out commit; when both the working tree and the index match +# the current commit, they are updated to match the newly pushed tip +# of the branch. This hook is to be used to override the default +# behaviour; however the code below reimplements the default behaviour +# as a starting point for convenient modification. +# +# The hook receives the commit with which the tip of the current +# branch is going to be updated: +commit=$1 + +# It can exit with a non-zero status to refuse the push (when it does +# so, it must not modify the index or the working tree). +die () { + echo >&2 "$*" + exit 1 +} + +# Or it can make any necessary changes to the working tree and to the +# index to bring them to the desired state when the tip of the current +# branch is updated to the new commit, and exit with a zero status. +# +# For example, the hook can simply run git read-tree -u -m HEAD "$1" +# in order to emulate git fetch that is run in the reverse direction +# with git push, as the two-tree form of git read-tree -u -m is +# essentially the same as git switch or git checkout that switches +# branches while keeping the local changes in the working tree that do +# not interfere with the difference between the branches. + +# The below is a more-or-less exact translation to shell of the C code +# for the default behaviour for git's push-to-checkout hook defined in +# the push_to_deploy() function in builtin/receive-pack.c. +# +# Note that the hook will be executed from the repository directory, +# not from the working tree, so if you want to perform operations on +# the working tree, you will have to adapt your code accordingly, e.g. +# by adding "cd .." or using relative paths. + +if ! git update-index -q --ignore-submodules --refresh +then + die "Up-to-date check failed" +fi + +if ! git diff-files --quiet --ignore-submodules -- +then + die "Working directory has unstaged changes" +fi + +# This is a rough translation of: +# +# head_has_history() ? "HEAD" : EMPTY_TREE_SHA1_HEX +if git cat-file -e HEAD 2>/dev/null +then + head=HEAD +else + head=$(git hash-object -t tree --stdin &2 + exit 1 +} + +unset GIT_DIR GIT_WORK_TREE +cd "$worktree" && + +if grep -q "^diff --git " "$1" +then + validate_patch "$1" +else + validate_cover_letter "$1" +fi && + +if test "$GIT_SENDEMAIL_FILE_COUNTER" = "$GIT_SENDEMAIL_FILE_TOTAL" +then + git config --unset-all sendemail.validateWorktree && + trap 'git worktree remove -ff "$worktree"' EXIT && + validate_series +fi diff --git a/pkg/greetd-moongreet/hooks/update.sample b/pkg/greetd-moongreet/hooks/update.sample new file mode 100755 index 0000000..c4d426b --- /dev/null +++ b/pkg/greetd-moongreet/hooks/update.sample @@ -0,0 +1,128 @@ +#!/bin/sh +# +# An example hook script to block unannotated tags from entering. +# Called by "git receive-pack" with arguments: refname sha1-old sha1-new +# +# To enable this hook, rename this file to "update". +# +# Config +# ------ +# hooks.allowunannotated +# This boolean sets whether unannotated tags will be allowed into the +# repository. By default they won't be. +# hooks.allowdeletetag +# This boolean sets whether deleting tags will be allowed in the +# repository. By default they won't be. +# hooks.allowmodifytag +# This boolean sets whether a tag may be modified after creation. By default +# it won't be. +# hooks.allowdeletebranch +# This boolean sets whether deleting branches will be allowed in the +# repository. By default they won't be. +# hooks.denycreatebranch +# This boolean sets whether remotely creating branches will be denied +# in the repository. By default this is allowed. +# + +# --- Command line +refname="$1" +oldrev="$2" +newrev="$3" + +# --- Safety check +if [ -z "$GIT_DIR" ]; then + echo "Don't run this script from the command line." >&2 + echo " (if you want, you could supply GIT_DIR then run" >&2 + echo " $0 )" >&2 + exit 1 +fi + +if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then + echo "usage: $0 " >&2 + exit 1 +fi + +# --- Config +allowunannotated=$(git config --type=bool hooks.allowunannotated) +allowdeletebranch=$(git config --type=bool hooks.allowdeletebranch) +denycreatebranch=$(git config --type=bool hooks.denycreatebranch) +allowdeletetag=$(git config --type=bool hooks.allowdeletetag) +allowmodifytag=$(git config --type=bool hooks.allowmodifytag) + +# check for no description +projectdesc=$(sed -e '1q' "$GIT_DIR/description") +case "$projectdesc" in +"Unnamed repository"* | "") + echo "*** Project description file hasn't been set" >&2 + exit 1 + ;; +esac + +# --- Check types +# if $newrev is 0000...0000, it's a commit to delete a ref. +zero=$(git hash-object --stdin &2 + echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 + exit 1 + fi + ;; + refs/tags/*,delete) + # delete tag + if [ "$allowdeletetag" != "true" ]; then + echo "*** Deleting a tag is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/tags/*,tag) + # annotated tag + if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 + then + echo "*** Tag '$refname' already exists." >&2 + echo "*** Modifying a tag is not allowed in this repository." >&2 + exit 1 + fi + ;; + refs/heads/*,commit) + # branch + if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then + echo "*** Creating a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/heads/*,delete) + # delete branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + refs/remotes/*,commit) + # tracking branch + ;; + refs/remotes/*,delete) + # delete tracking branch + if [ "$allowdeletebranch" != "true" ]; then + echo "*** Deleting a tracking branch is not allowed in this repository" >&2 + exit 1 + fi + ;; + *) + # Anything else (is there anything else?) + echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 + exit 1 + ;; +esac + +# --- Finished +exit 0 diff --git a/pkg/greetd-moongreet/info/attributes b/pkg/greetd-moongreet/info/attributes new file mode 100644 index 0000000..1c897b7 --- /dev/null +++ b/pkg/greetd-moongreet/info/attributes @@ -0,0 +1 @@ +* -export-subst -export-ignore diff --git a/pkg/greetd-moongreet/info/exclude b/pkg/greetd-moongreet/info/exclude new file mode 100644 index 0000000..a5196d1 --- /dev/null +++ b/pkg/greetd-moongreet/info/exclude @@ -0,0 +1,6 @@ +# git ls-files --others --exclude-from=.git/info/exclude +# Lines that start with '#' are comments. +# For a project mostly in C, the following would be a good set of +# exclude patterns (uncomment them if you want to use them): +# *.[oa] +# *~ diff --git a/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.idx b/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.idx new file mode 100644 index 0000000..394c9ef Binary files /dev/null and b/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.idx differ diff --git a/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.pack b/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.pack new file mode 100644 index 0000000..c98cfd0 Binary files /dev/null and b/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.pack differ diff --git a/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.rev b/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.rev new file mode 100644 index 0000000..1dbf32b Binary files /dev/null and b/pkg/greetd-moongreet/objects/pack/pack-a0ce5f72a6ad2d48de49dd402b30d70ca72b907a.rev differ diff --git a/pkg/greetd-moongreet/packed-refs b/pkg/greetd-moongreet/packed-refs new file mode 100644 index 0000000..4760fa0 --- /dev/null +++ b/pkg/greetd-moongreet/packed-refs @@ -0,0 +1,3 @@ +# pack-refs with: peeled fully-peeled sorted +99c016adbc27e6455463b47fc6e6b3d2eb157def refs/heads/main +99c016adbc27e6455463b47fc6e6b3d2eb157def refs/tags/v0.1.0 diff --git a/pkg/moongreet-0.1.0-1-any.pkg.tar.zst b/pkg/moongreet-0.1.0-1-any.pkg.tar.zst new file mode 100644 index 0000000..9307afd Binary files /dev/null and b/pkg/moongreet-0.1.0-1-any.pkg.tar.zst differ diff --git a/pkg/moongreet.install b/pkg/moongreet.install index 5dccda6..5b1f646 100644 --- a/pkg/moongreet.install +++ b/pkg/moongreet.install @@ -1,16 +1,14 @@ # ABOUTME: pacman install hooks for Moongreet. -# ABOUTME: Sets ownership on cache directory for the greeter user. +# ABOUTME: Sets ownership on cache directory and prints setup instructions. post_install() { if getent passwd greeter > /dev/null 2>&1; then chown greeter:greeter /var/cache/moongreet fi - echo "==> Copy /etc/moongreet/moongreet.toml and adjust the wallpaper path." - echo "==> Configure greetd to use moongreet:" - echo " [default_session]" - echo " command = \"moongreet\"" - echo " user = \"greeter\"" + echo "==> Moongreet installed." + echo "==> Add moongreet to your greeter compositor command in /etc/greetd/config.toml." + echo "==> Adjust wallpaper: /etc/moongreet/moongreet.toml" } post_upgrade() { diff --git a/pkg/pkg/moongreet/.BUILDINFO b/pkg/pkg/moongreet/.BUILDINFO new file mode 100644 index 0000000..e006bff --- /dev/null +++ b/pkg/pkg/moongreet/.BUILDINFO @@ -0,0 +1,1122 @@ +format = 2 +pkgname = moongreet +pkgbase = moongreet +pkgver = 0.1.0-1 +pkgarch = any +pkgbuild_sha256sum = 390ab11bc1f8428ed7a369c982de0db7d83a35fddcd2f1538645a999e5814ae7 +packager = Unknown Packager +builddate = 1774528075 +builddir = /home/dkressler/Projects/moongreet/pkg +startdir = /home/dkressler/Projects/moongreet/pkg +buildtool = makepkg +buildtoolver = 7.1.0 +buildenv = !distcc +buildenv = color +buildenv = !ccache +buildenv = check +buildenv = !sign +options = strip +options = docs +options = !libtool +options = !staticlibs +options = emptydirs +options = zipman +options = purge +options = debug +options = lto +installed = aalib-1.4rc5-19-x86_64 +installed = abseil-cpp-20250814.1-1-x86_64 +installed = accountsservice-26.12.8-1-x86_64 +installed = acl-2.3.2-1-x86_64 +installed = acli-bin-1.3.14-1-x86_64 +installed = ada-3.4.3-1-x86_64 +installed = adwaita-cursors-49.0-1-any +installed = adwaita-fonts-50.0-1-any +installed = adwaita-icon-theme-49.0-1-any +installed = adwaita-icon-theme-legacy-46.2-3-any +installed = alacritty-0.16.1-1-x86_64 +installed = alarm-clock-applet-1:0.4.1-5-x86_64 +installed = alsa-card-profiles-1:1.6.2-1-x86_64 +installed = alsa-lib-1.2.15.3-2-x86_64 +installed = alsa-topology-conf-1.2.5.1-4-any +installed = alsa-ucm-conf-1.2.15.3-1-any +installed = alsa-utils-1.2.15.2-2-x86_64 +installed = amd-ucode-20260309-1-any +installed = aom-3.13.2-1-x86_64 +installed = apparmor-4.1.7-1-x86_64 +installed = appstream-1.1.2-1-x86_64 +installed = aquamarine-0.10.0-2-x86_64 +installed = archlinux-keyring-20260301-1-any +installed = argon2-20190702-6-x86_64 +installed = aribb24-1.0.3-4-x86_64 +installed = ashell-0.7.0-2-x86_64 +installed = ast-grep-bin-0.42.0-1-x86_64 +installed = at-spi2-core-2.58.4-1-x86_64 +installed = atkmm-2.28.4-1-x86_64 +installed = attr-2.5.2-1-x86_64 +installed = audacity-1:3.7.7-1-x86_64 +installed = audit-4.1.3-1-x86_64 +installed = auto-cpufreq-3.0.0-3-any +installed = autoconf-2.72-1-any +installed = automake-1.18.1-1-any +installed = avahi-1:0.9rc3-1-x86_64 +installed = awww-git-0.11.2.r141.g2c86d41-1-x86_64 +installed = ayatana-ido-0.10.4-1-x86_64 +installed = babl-0.1.124-1-x86_64 +installed = base-3-3-any +installed = base-devel-1-2-any +installed = bash-5.3.9-1-x86_64 +installed = bat-0.26.1-2-x86_64 +installed = bc-1.08.2-1-x86_64 +installed = binutils-2.46-1-x86_64 +installed = bison-3.8.2-8-x86_64 +installed = bitwarden-2025.10.0-1-x86_64 +installed = blas-3.12.1-2-x86_64 +installed = blueberry-1.4.8-2-any +installed = bluez-5.86-4-x86_64 +installed = bluez-libs-5.86-4-x86_64 +installed = bluez-tools-0.2.0-6-x86_64 +installed = boost-libs-1.89.0-4-x86_64 +installed = brightnessctl-0.5.1-3-x86_64 +installed = brotli-1.2.0-1-x86_64 +installed = btop-1.4.6-1-x86_64 +installed = btrfs-progs-6.19-1-x86_64 +installed = bubblewrap-0.11.0-2-x86_64 +installed = bzip2-1.0.8-6-x86_64 +installed = c-ares-1.34.6-1-x86_64 +installed = ca-certificates-20240618-1-any +installed = ca-certificates-mozilla-3.121-1-x86_64 +installed = ca-certificates-utils-20240618-1-any +installed = cage-0.2.1-1-x86_64 +installed = cairo-1.18.4-1-x86_64 +installed = cairomm-1.14.5-2-x86_64 +installed = cairomm-1.16-1.18.0-2-x86_64 +installed = catppuccin-gtk-theme-mocha-1.0.3-1-any +installed = cblas-3.12.1-2-x86_64 +installed = cdparanoia-10.2-9-x86_64 +installed = celluloid-0.29-1-x86_64 +installed = check-0.15.2-3-x86_64 +installed = cifs-utils-7.5-1-x86_64 +installed = cinnamon-translations-6.6.2-1-any +installed = cjs-128.1-1-x86_64 +installed = clang-22.1.1-1-x86_64 +installed = claude-code-2.1.80-1-x86_64 +installed = cliphist-1:0.7.0-2-x86_64 +installed = cloudreverb-0.4.1-2-x86_64 +installed = clucene-2.3.3.4-17-x86_64 +installed = clutter-1.26.4-4-x86_64 +installed = clutter-gst-3.0.27-5-x86_64 +installed = clutter-gtk-1.8.4-5-x86_64 +installed = cmake-4.3.0-1-x86_64 +installed = cogl-1.22.8-5-x86_64 +installed = colord-1.4.8-1-x86_64 +installed = compiler-rt-22.1.1-1-x86_64 +installed = confuse-3.3-4-x86_64 +installed = containerd-2.2.2-1-x86_64 +installed = coreutils-9.10-1-x86_64 +installed = cpio-2.15-3-x86_64 +installed = cppdap-1.58.0-2-x86_64 +installed = cronie-1.7.2-2-x86_64 +installed = cryptsetup-2.8.4-1-x86_64 +installed = curl-8.19.0-1-x86_64 +installed = dav1d-1.5.3-1-x86_64 +installed = db5.3-5.3.28-7-x86_64 +installed = dbus-1.16.2-1-x86_64 +installed = dbus-broker-37-3-x86_64 +installed = dbus-broker-units-37-3-x86_64 +installed = dbus-glib-0.114-1-x86_64 +installed = dbus-units-37-3-x86_64 +installed = dconf-0.49.0-1-x86_64 +installed = debugedit-5.2-1-x86_64 +installed = default-cursors-3-1-any +installed = desktop-file-utils-0.28-1-x86_64 +installed = device-mapper-2.03.38-1-x86_64 +installed = diffutils-3.12-2-x86_64 +installed = displaylink-6.2-1-x86_64 +installed = distrho-ports-2021.03.15-4-x86_64 +installed = distrho-ports-lv2-2021.03.15-4-x86_64 +installed = distrho-ports-vst-2021.03.15-4-x86_64 +installed = distrho-ports-vst3-2021.03.15-4-x86_64 +installed = dkms-3.3.0-1-any +installed = dmidecode-3.7-1-x86_64 +installed = docbook-xml-4.5-11-any +installed = docbook-xsl-1.79.2-9-any +installed = docker-1:29.3.0-1-x86_64 +installed = docker-compose-5.1.0-1-x86_64 +installed = dosfstools-4.2-5-x86_64 +installed = double-conversion-3.4.0-1-x86_64 +installed = dracula-gtk-theme-v4.0.0-1-any +installed = dragonfly-reverb-lv2-3.2.10-5-x86_64 +installed = duktape-2.7.0-7-x86_64 +installed = dunst-1.13.1-1-x86_64 +installed = e2fsprogs-1.47.4-1-x86_64 +installed = efibootmgr-18-3-x86_64 +installed = efivar-39-1-x86_64 +installed = electron36-36.9.3-1-x86_64 +installed = enchant-2.8.15-1-x86_64 +installed = evdi-dkms-1.14.15-1-x86_64 +installed = ex-vi-compat-2-1-any +installed = exempi-2.6.6-2-x86_64 +installed = exiv2-0.28.7-1-x86_64 +installed = exo-4.20.0-2-x86_64 +installed = expat-2.7.5-1-x86_64 +installed = eza-0.23.4-3-x86_64 +installed = fakeroot-1.37.2-1-x86_64 +installed = fastfetch-2.60.0-1-x86_64 +installed = fcft-3.3.3-1-x86_64 +installed = fd-10.4.2-1-x86_64 +installed = ffmpeg-2:8.1-2-x86_64 +installed = fftw-3.3.10-8-x86_64 +installed = file-5.47-1-x86_64 +installed = filesystem-2025.10.12-1-any +installed = filezilla-3.69.6-1-x86_64 +installed = findutils-4.10.0-3-x86_64 +installed = flac-1.5.0-1-x86_64 +installed = flashrom-1.7.0-1-x86_64 +installed = flatery-icon-theme-git-r362.30bef81b-1-any +installed = flex-2.6.4-5-x86_64 +installed = fmt-12.1.0-2-x86_64 +installed = fontconfig-2:2.17.1-1-x86_64 +installed = foot-1.26.1-1-x86_64 +installed = foot-terminfo-1.26.1-1-x86_64 +installed = fprintd-1.94.5-1-x86_64 +installed = freeglut-3.8.0-1-x86_64 +installed = freetype2-2.14.2-1-x86_64 +installed = freeverb3-3.2.1-5-x86_64 +installed = frei0r-plugins-2.5.5-1-x86_64 +installed = fresh-editor-bin-0.2.17-1-x86_64 +installed = fribidi-1.0.16-2-x86_64 +installed = fuse-common-3.18.1-1-x86_64 +installed = fuse2-2.9.9-5-x86_64 +installed = fuse3-3.18.1-1-x86_64 +installed = fwupd-2.1.1-2-x86_64 +installed = fwupd-efi-1.8-2-any +installed = fzf-0.70.0-1-x86_64 +installed = fzur-git-r78.e99d68c-1-any +installed = galculator-2.1.4-10-x86_64 +installed = gawk-5.4.0-1-x86_64 +installed = gc-8.2.12-1-x86_64 +installed = gcc-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = gcc-libs-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = gcr-3.41.2-2-x86_64 +installed = gcr-4-4.4.0.1-1-x86_64 +installed = gd-2.3.3-9-x86_64 +installed = gdbm-1.26-2-x86_64 +installed = gdk-pixbuf2-2.44.4-1-x86_64 +installed = gegl-0.4.68-1-x86_64 +installed = gettext-1.0-2-x86_64 +installed = gexiv2-0.16.0-1-x86_64 +installed = ghostscript-10.07.0-1-x86_64 +installed = giflib-5.2.2-2-x86_64 +installed = gimp-3.2.0-1-x86_64 +installed = git-2.53.0-1-x86_64 +installed = glab-1.89.0-1-x86_64 +installed = glib-networking-1:2.80.1-1-x86_64 +installed = glib2-2.86.4-1-x86_64 +installed = glib2-devel-2.86.4-1-x86_64 +installed = glib2-docs-2.86.4-1-x86_64 +installed = glibc-2.43+r5+g856c426a7534-1-x86_64 +installed = glibmm-2.66.8-1-x86_64 +installed = glibmm-2.68-2.86.0-1-x86_64 +installed = glslang-1:1.4.341.0-2-x86_64 +installed = glu-9.0.3-3-x86_64 +installed = glycin-2.0.8-1-x86_64 +installed = gmp-6.3.0-3-x86_64 +installed = gnome-autoar-0.4.5-1-x86_64 +installed = gnome-bluetooth-3.34.5+r16+g61cfff1c-3-x86_64 +installed = gnome-desktop-4-1:44.5-1-x86_64 +installed = gnome-desktop-common-1:44.5-1-x86_64 +installed = gnome-keyring-1:48.0-1-x86_64 +installed = gnulib-l10n-20241231-1-any +installed = gnupg-2.4.9-1-x86_64 +installed = gnutls-3.8.12-2-x86_64 +installed = go-2:1.26.1-1-x86_64 +installed = gobject-introspection-1.86.0-2-x86_64 +installed = gobject-introspection-runtime-1.86.0-2-x86_64 +installed = gparted-1.8.1-1-x86_64 +installed = gperftools-2.17.2-1-x86_64 +installed = gpgme-2.0.1-3-x86_64 +installed = gpgmepp-2.0.0-2-x86_64 +installed = gpm-1.20.7.r38.ge82d1a6-6-x86_64 +installed = gpsd-3.27.5-1-x86_64 +installed = graphene-1.10.8-2-x86_64 +installed = graphicsmagick-1.3.46-1-x86_64 +installed = graphite-1:1.3.14-6-x86_64 +installed = graphviz-14.1.3-1-x86_64 +installed = greetd-0.10.3-1-x86_64 +installed = greetd-agreety-0.10.3-1-x86_64 +installed = greetd-regreet-0.2.0-1-x86_64 +installed = greetd-tuigreet-0.9.1-1-x86_64 +installed = grep-3.12-2-x86_64 +installed = grim-1.5.0-2-x86_64 +installed = groff-1.24.1-1-x86_64 +installed = gsettings-desktop-schemas-49.1-1-any +installed = gsettings-system-schemas-49.1-1-any +installed = gsfonts-20200910-6-any +installed = gsl-2.8-1-x86_64 +installed = gsm-1.0.24-1-x86_64 +installed = gspell-1.14.3-1-x86_64 +installed = gssdp-1.6.4-1-x86_64 +installed = gst-plugin-pipewire-1:1.6.2-1-x86_64 +installed = gst-plugins-bad-libs-1.28.1-1-x86_64 +installed = gst-plugins-base-1.28.1-1-x86_64 +installed = gst-plugins-base-libs-1.28.1-1-x86_64 +installed = gst-plugins-good-1.28.1-1-x86_64 +installed = gstreamer-1.28.1-1-x86_64 +installed = gtest-1.17.0-2-x86_64 +installed = gtk-doc-1.36.0-1-any +installed = gtk-layer-shell-0.10.0-1-x86_64 +installed = gtk-session-lock-0.2.0-2-x86_64 +installed = gtk-update-icon-cache-1:4.20.3-1-x86_64 +installed = gtk3-1:3.24.51-1-x86_64 +installed = gtk4-1:4.20.3-1-x86_64 +installed = gtk4-layer-shell-1.3.0-1-x86_64 +installed = gtklock-4.0.0-1-x86_64 +installed = gtklock-dpms-module-4.0.0-1-x86_64 +installed = gtklock-playerctl-module-4.0.0-1-x86_64 +installed = gtklock-powerbar-module-4.0.0-1-x86_64 +installed = gtklock-userinfo-module-4.0.1-1-x86_64 +installed = gtkmm-4.0-4.20.0-1-x86_64 +installed = gtkmm3-3.24.10-1-x86_64 +installed = gtksourceview4-4.8.4-2-x86_64 +installed = gts-0.7.6.121130-5-x86_64 +installed = guile-3.0.11-1-x86_64 +installed = gupnp-1:1.6.9-1-x86_64 +installed = gupnp-dlna-0.12.0-4-x86_64 +installed = gupnp-igd-1.6.0-2-x86_64 +installed = gvfs-1.58.3-1-x86_64 +installed = gvfs-dnssd-1.58.3-1-x86_64 +installed = gvfs-mtp-1.58.3-1-x86_64 +installed = gvfs-smb-1.58.3-1-x86_64 +installed = gzip-1.14-2-x86_64 +installed = hardinfo2-2.2.16-1-x86_64 +installed = harfbuzz-13.2.1-1-x86_64 +installed = harfbuzz-icu-13.2.1-1-x86_64 +installed = hicolor-icon-theme-0.18-1-any +installed = hidapi-0.15.0-1-x86_64 +installed = highway-1.3.0-2-x86_64 +installed = hunspell-1.7.2-3-x86_64 +installed = hwdata-0.405-1-any +installed = hyphen-2.8.8-6-x86_64 +installed = hyprcursor-0.1.13-4-x86_64 +installed = hyprgraphics-0.5.0-2-x86_64 +installed = hypridle-0.1.7-7-x86_64 +installed = hyprkeys-1.0.3-1-x86_64 +installed = hyprland-0.54.2-2-x86_64 +installed = hyprland-guiutils-0.2.1-2-x86_64 +installed = hyprland-qt-support-0.1.0-10-x86_64 +installed = hyprlang-0.6.8-2-x86_64 +installed = hyprlock-0.9.2-9-x86_64 +installed = hyprpicker-0.4.6-2-x86_64 +installed = hyprpolkitagent-0.1.3-5-x86_64 +installed = hyprshade-git-3.2.1.r291.g890ff11-1-any +installed = hyprtoolkit-0.5.3-1-x86_64 +installed = hyprutils-0.11.1-1-x86_64 +installed = hyprwayland-scanner-0.4.5-1-x86_64 +installed = hyprwire-0.3.0-1-x86_64 +installed = iana-etc-20260306-1-any +installed = icu-78.3-1-x86_64 +installed = ijs-0.35-6-x86_64 +installed = imagemagick-7.1.2.17-1-x86_64 +installed = imath-3.2.2-3-x86_64 +installed = imlib2-1.12.6-1-x86_64 +installed = inetutils-2.7-2-x86_64 +installed = iniparser-4.2.6-2-x86_64 +installed = inkscape-1.4.3-6-x86_64 +installed = intltool-0.51.0-6-any +installed = iperf3-3.20-1-x86_64 +installed = iproute2-6.19.0-2-x86_64 +installed = iptables-1:1.8.11-2-x86_64 +installed = iputils-20250605-1-x86_64 +installed = iso-codes-4.20.1-1-any +installed = jansson-2.15.0-1-x86_64 +installed = jasper-4.2.8-1-x86_64 +installed = jbig2dec-0.20-1-x86_64 +installed = jbigkit-2.1-8-x86_64 +installed = jemalloc-1:5.3.0-7-x86_64 +installed = jq-1.8.1-1-x86_64 +installed = js128-128.14.0-1-x86_64 +installed = json-c-0.18-2-x86_64 +installed = json-glib-1.10.8-1-x86_64 +installed = jsoncpp-1.9.6-3-x86_64 +installed = kbd-2.9.0-1-x86_64 +installed = kcolorscheme-6.24.0-1-x86_64 +installed = kconfig-6.24.0-1-x86_64 +installed = kcoreaddons-6.24.0-1-x86_64 +installed = kcrash-6.24.0-1-x86_64 +installed = kdbusaddons-6.24.0-1-x86_64 +installed = keyutils-1.6.3-3-x86_64 +installed = kguiaddons-6.24.0-1-x86_64 +installed = ki18n-6.24.0-1-x86_64 +installed = kmod-34.2-1-x86_64 +installed = knotifications-6.24.0-1-x86_64 +installed = krb5-1.21.3-2-x86_64 +installed = kwallet-6.24.0-1-x86_64 +installed = kwidgetsaddons-6.24.0-1-x86_64 +installed = kwindowsystem-6.24.0-1-x86_64 +installed = l-smash-2.14.5-4-x86_64 +installed = lame-3.101.r6531-1-x86_64 +installed = lapack-3.12.1-2-x86_64 +installed = lazygit-0.60.0-1-x86_64 +installed = lcms2-2.18-1-x86_64 +installed = ldb-2:4.23.6-1-x86_64 +installed = leancrypto-1.6.0-1-x86_64 +installed = lensfun-1:0.3.4-6-x86_64 +installed = less-1:692-1-x86_64 +installed = lib2geom-1.4-2-x86_64 +installed = libabw-0.1.3-6-x86_64 +installed = libadwaita-1:1.8.4-1-x86_64 +installed = libappindicator-12.10.1-1-x86_64 +installed = libarchive-3.8.6-1-x86_64 +installed = libasan-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libass-0.17.4-1-x86_64 +installed = libassuan-3.0.0-1-x86_64 +installed = libasyncns-1:0.8+r3+g68cd5af-3-x86_64 +installed = libatasmart-0.19-7-x86_64 +installed = libatomic-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libatomic_ops-7.8.2-2-x86_64 +installed = libavc1394-0.5.4-7-x86_64 +installed = libavif-1.4.0-1-x86_64 +installed = libayatana-appindicator-0.5.94-1-x86_64 +installed = libayatana-indicator-0.9.4-1-x86_64 +installed = libb2-0.98.1-3-x86_64 +installed = libblockdev-3.4.0-2-x86_64 +installed = libblockdev-crypto-3.4.0-2-x86_64 +installed = libblockdev-fs-3.4.0-2-x86_64 +installed = libblockdev-loop-3.4.0-2-x86_64 +installed = libblockdev-mdraid-3.4.0-2-x86_64 +installed = libblockdev-nvme-3.4.0-2-x86_64 +installed = libblockdev-part-3.4.0-2-x86_64 +installed = libblockdev-smart-3.4.0-2-x86_64 +installed = libblockdev-swap-3.4.0-2-x86_64 +installed = libbluray-1.4.1-1-x86_64 +installed = libbpf-1.6.2-1-x86_64 +installed = libbs2b-3.1.0-10-x86_64 +installed = libbsd-0.12.2-2-x86_64 +installed = libbytesize-2.12-3-x86_64 +installed = libcaca-0.99.beta20-6-x86_64 +installed = libcanberra-1:0.30+r2+gc0620e4-6-x86_64 +installed = libcap-2.77-1-x86_64 +installed = libcap-ng-0.9.1-1-x86_64 +installed = libcbor-0.12.0-1-x86_64 +installed = libcdio-2.3.0-1-x86_64 +installed = libcdio-paranoia-10.2+2.0.2-1-x86_64 +installed = libcdr-0.1.8-4-x86_64 +installed = libcloudproviders-0.4.0-1-x86_64 +installed = libcmis-0.6.2-7-x86_64 +installed = libcolord-1.4.8-1-x86_64 +installed = libcue-2.3.0-1-x86_64 +installed = libcups-2:2.4.16-2-x86_64 +installed = libdaemon-0.14-6-x86_64 +installed = libdatrie-0.2.14-1-x86_64 +installed = libdbusmenu-glib-18.10.20180917-1-x86_64 +installed = libdbusmenu-gtk3-18.10.20180917-1-x86_64 +installed = libde265-1.0.18-1-x86_64 +installed = libdecor-0.2.5-1-x86_64 +installed = libdeflate-1.25-1-x86_64 +installed = libdisplay-info-0.3.0-1-x86_64 +installed = libdovi-3.3.2-1-x86_64 +installed = libdrm-2.4.131-1-x86_64 +installed = libdv-1.0.0-11-x86_64 +installed = libdvdnav-7.0.0-1-x86_64 +installed = libdvdread-7.0.1-1-x86_64 +installed = libe-book-0.1.3-20-x86_64 +installed = libebur128-1.2.6-2-x86_64 +installed = libedit-20251016_3.1-1-x86_64 +installed = libei-1.5.0-1-x86_64 +installed = libelf-0.194-2-x86_64 +installed = libepoxy-1.5.10-3-x86_64 +installed = libepubgen-0.1.1-6-x86_64 +installed = libetonyek-0.1.13-2-x86_64 +installed = libevdev-1.13.6-1-x86_64 +installed = libevent-2.1.12-5-x86_64 +installed = libexif-0.6.25-1-x86_64 +installed = libexttextcat-3.4.7-1-x86_64 +installed = libfdk-aac-2.0.3-1-x86_64 +installed = libffi-3.5.2-1-x86_64 +installed = libfilezilla-1:0.54.1-2-x86_64 +installed = libfm-1.4.1-1-x86_64 +installed = libfm-extra-1.4.1-1-x86_64 +installed = libfm-gtk3-1.4.1-1-x86_64 +installed = libfontenc-1.1.9-1-x86_64 +installed = libfprint-1.94.10-1-x86_64 +installed = libfreeaptx-0.2.2-1-x86_64 +installed = libfreehand-0.1.2-6-x86_64 +installed = libftdi-1.5-10-x86_64 +installed = libfyaml-0.9.6-1-x86_64 +installed = libgcc-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libgcrypt-1.12.1-1-x86_64 +installed = libgee-0.20.8-1-x86_64 +installed = libgexiv2-0.14.6-2-x86_64 +installed = libgfortran-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libgirepository-1.86.0-2-x86_64 +installed = libgit2-1:1.9.2-3-x86_64 +installed = libglvnd-1.7.0-3-x86_64 +installed = libgnomekbd-1:3.28.1-2-x86_64 +installed = libgomp-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libgpg-error-1.59-1-x86_64 +installed = libgsf-1.14.56-1-x86_64 +installed = libgtop-2.41.3-2-x86_64 +installed = libgudev-238-3-x86_64 +installed = libgusb-0.4.9-2-x86_64 +installed = libgxps-0.3.2-5-x86_64 +installed = libheif-1.21.2-2-x86_64 +installed = libice-1.1.2-1-x86_64 +installed = libid3tag-0.16.4-1-x86_64 +installed = libidn-1.43-1-x86_64 +installed = libidn2-2.3.8-1-x86_64 +installed = libiec61883-1.2.0-9-x86_64 +installed = libimagequant-4.4.1-1-x86_64 +installed = libimobiledevice-1.4.0-2-x86_64 +installed = libimobiledevice-glue-1.3.2-1-x86_64 +installed = libinih-62-2-x86_64 +installed = libinput-1.30.1-1-x86_64 +installed = libiptcdata-1.0.5-5-x86_64 +installed = libisl-0.27-1-x86_64 +installed = libixion-0.20.0-5-x86_64 +installed = libjcat-0.2.5-1-x86_64 +installed = libjpeg-turbo-3.1.3-1-x86_64 +installed = libjxl-0.11.2-2-x86_64 +installed = libksba-1.6.8-1-x86_64 +installed = liblangtag-0.6.8-1-x86_64 +installed = liblc3-1.1.3-2-x86_64 +installed = libldac-2.0.2.3-3-x86_64 +installed = libldap-2.6.13-1-x86_64 +installed = libliftoff-0.5.0-1-x86_64 +installed = liblqr-0.4.3-1-x86_64 +installed = liblsan-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libluv-1.51.0-1-x86_64 +installed = libmad-0.15.1b-10-x86_64 +installed = libmakepkg-dropins-20-1-any +installed = libmanette-0.2.13-1-x86_64 +installed = libmbim-1.34.0-1-x86_64 +installed = libmd-1.1.0-2-x86_64 +installed = libmm-glib-1.24.2-1-x86_64 +installed = libmng-2.0.3-4-x86_64 +installed = libmnl-1.0.5-2-x86_64 +installed = libmodplug-0.8.9.0-6-x86_64 +installed = libmpc-1.3.1-2-x86_64 +installed = libmpdclient-2.23-1-x86_64 +installed = libmspack-1:1.11-1-x86_64 +installed = libmspub-0.1.4-19-x86_64 +installed = libmtp-1.1.23-1-x86_64 +installed = libmusicbrainz5-5.1.0-10-x86_64 +installed = libmwaw-0.3.22-4-x86_64 +installed = libmypaint-1.6.1-2-x86_64 +installed = libmysofa-1.3.3-1-x86_64 +installed = libnautilus-extension-49.5-1-x86_64 +installed = libndp-1.9-1-x86_64 +installed = libnetfilter_conntrack-1.0.9-2-x86_64 +installed = libnewt-0.52.25-2-x86_64 +installed = libnfnetlink-1.0.2-2-x86_64 +installed = libnftnl-1.3.1-1-x86_64 +installed = libnghttp2-1.68.0-1-x86_64 +installed = libnghttp3-1.15.0-1-x86_64 +installed = libngtcp2-1.21.0-1-x86_64 +installed = libnice-0.1.23-1-x86_64 +installed = libnl-3.12.0-1-x86_64 +installed = libnm-1.56.0-1-x86_64 +installed = libnma-1.10.6-3-x86_64 +installed = libnma-common-1.10.6-3-x86_64 +installed = libnma-gtk4-1.10.6-3-x86_64 +installed = libnotify-0.8.8-1-x86_64 +installed = libnsl-2.0.1-1-x86_64 +installed = libnss_nis-3.4-1-x86_64 +installed = libnumbertext-1.0.11-3-x86_64 +installed = libnvme-1.16.1-3-x86_64 +installed = libobjc-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libodfgen-0.1.8-5-x86_64 +installed = libogg-1.3.6-1-x86_64 +installed = libopenmpt-0.8.4-1-x86_64 +installed = liborcus-0.21.0-4-x86_64 +installed = libosinfo-1.12.0-2-x86_64 +installed = libp11-kit-0.26.2-1-x86_64 +installed = libpagemaker-0.0.4-5-x86_64 +installed = libpaper-2.2.7-1-x86_64 +installed = libpcap-1.10.6-1-x86_64 +installed = libpciaccess-0.19-1-x86_64 +installed = libpgm-5.3.128-3-x86_64 +installed = libpipeline-1.5.8-1-x86_64 +installed = libpipewire-1:1.6.2-1-x86_64 +installed = libplacebo-7.360.1-1-x86_64 +installed = libplist-2.7.0-3-x86_64 +installed = libpng-1.6.55-1-x86_64 +installed = libportal-0.9.1-2-x86_64 +installed = libportal-gtk4-0.9.1-2-x86_64 +installed = libproxy-0.5.12-1-x86_64 +installed = libpsl-0.21.5-2-x86_64 +installed = libpulse-17.0+r98+gb096704c0-1-x86_64 +installed = libqmi-1.38.0-1-x86_64 +installed = libqrtr-glib-1.4.0-1-x86_64 +installed = libquadmath-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libqxp-0.0.2-15-x86_64 +installed = libraqm-0.10.4-1-x86_64 +installed = libraw-0.22.0-2-x86_64 +installed = libraw1394-2.1.2-4-x86_64 +installed = libreoffice-fresh-26.2.1-2-x86_64 +installed = libreoffice-fresh-de-26.2.1-1-any +installed = librevenge-0.0.5-4-x86_64 +installed = librsvg-2:2.61.4-1-x86_64 +installed = libsamplerate-0.2.2-3-x86_64 +installed = libsasl-2.1.28-5-x86_64 +installed = libsbsms-2.3.0-5-x86_64 +installed = libseccomp-2.6.0-1-x86_64 +installed = libsecret-0.21.7-1-x86_64 +installed = libshout-1:2.4.6-5-x86_64 +installed = libsigc++-2.12.1-2-x86_64 +installed = libsigc++-3.0-3.8.0-1-x86_64 +installed = libsixel-1.10.5-1-x86_64 +installed = libsm-1.2.6-1-x86_64 +installed = libsndfile-1.2.2-4-x86_64 +installed = libsodium-1.0.21-1-x86_64 +installed = libsoup3-3.6.6-2-x86_64 +installed = libsoxr-0.1.3-4-x86_64 +installed = libspiro-1:20240903-1-x86_64 +installed = libssh-0.12.0-1-x86_64 +installed = libssh2-1.11.1-1-x86_64 +installed = libstaroffice-0.0.7-5-x86_64 +installed = libstdc++-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libstemmer-3.0.1-1-x86_64 +installed = libsysprof-capture-49.0-2-x86_64 +installed = libtasn1-4.21.0-1-x86_64 +installed = libtatsu-1.0.5-1-x86_64 +installed = libteam-1.32-3-x86_64 +installed = libthai-0.1.30-1-x86_64 +installed = libtheora-1.2.0-1-x86_64 +installed = libtiff-4.7.1-1-x86_64 +installed = libtirpc-1.3.7-1-x86_64 +installed = libtommath-1.3.0-2-x86_64 +installed = libtool-2.6.0-4-x86_64 +installed = libtsan-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libubsan-15.2.1+r604+g0b99615a8aef-1-x86_64 +installed = libunibreak-6.1-1-x86_64 +installed = libunistring-1.4.1-1-x86_64 +installed = libunwind-1.8.2-1-x86_64 +installed = liburcu-0.15.6-1-x86_64 +installed = liburing-2.14-1-x86_64 +installed = libusb-1.0.29-1-x86_64 +installed = libusbmuxd-2.1.1-2-x86_64 +installed = libutf8proc-2.11.3-1-x86_64 +installed = libuv-1.52.1-1-x86_64 +installed = libva-2.23.0-1-x86_64 +installed = libvdpau-1.5-4-x86_64 +installed = libverto-0.3.2-5-x86_64 +installed = libvisio-0.1.10-3-x86_64 +installed = libvorbis-1.3.7-4-x86_64 +installed = libvpl-2.16.0-2-x86_64 +installed = libvpx-1.15.2-3-x86_64 +installed = libvterm-0.3.3-2-x86_64 +installed = libwacom-2.18.0-2-x86_64 +installed = libwbclient-2:4.23.6-1-x86_64 +installed = libwebp-1.6.0-2-x86_64 +installed = libwireplumber-0.5.13-1-x86_64 +installed = libwmf-0.2.13-4-x86_64 +installed = libwpd-0.10.3-6-x86_64 +installed = libwpg-0.3.4-3-x86_64 +installed = libwps-0.4.14-4-x86_64 +installed = libx11-1.8.13-1-x86_64 +installed = libxau-1.0.12-1-x86_64 +installed = libxcb-1.17.0-1-x86_64 +installed = libxcomposite-0.4.7-1-x86_64 +installed = libxcrypt-4.5.2-1-x86_64 +installed = libxcursor-1.2.3-1-x86_64 +installed = libxcvt-0.1.3-1-x86_64 +installed = libxdamage-1.1.7-1-x86_64 +installed = libxdg-basedir-1.2.3-2-x86_64 +installed = libxdmcp-1.1.5-1-x86_64 +installed = libxext-1.3.7-1-x86_64 +installed = libxfce4ui-4.20.2-1-x86_64 +installed = libxfce4util-4.20.1-1-x86_64 +installed = libxfixes-6.0.2-1-x86_64 +installed = libxfont2-2.0.7-1-x86_64 +installed = libxft-2.3.9-1-x86_64 +installed = libxi-1.8.2-1-x86_64 +installed = libxinerama-1.1.6-1-x86_64 +installed = libxkbcommon-1.13.1-1-x86_64 +installed = libxkbcommon-x11-1.13.1-1-x86_64 +installed = libxkbfile-1.2.0-1-x86_64 +installed = libxklavier-5.4-7-x86_64 +installed = libxml2-2.15.2-1-x86_64 +installed = libxmlb-0.3.25-1-x86_64 +installed = libxmu-1.3.1-1-x86_64 +installed = libxpm-3.5.18-1-x86_64 +installed = libxpresent-1.0.2-1-x86_64 +installed = libxrandr-1.5.5-1-x86_64 +installed = libxrender-0.9.12-1-x86_64 +installed = libxshmfence-1.3.3-1-x86_64 +installed = libxslt-1.1.45-2-x86_64 +installed = libxss-1.2.5-1-x86_64 +installed = libxt-1.3.1-1-x86_64 +installed = libxtst-1.2.5-1-x86_64 +installed = libxv-1.0.13-1-x86_64 +installed = libxxf86vm-1.1.7-1-x86_64 +installed = libyuv-r2426+464c51a03-1-x86_64 +installed = libzip-1.11.4-1-x86_64 +installed = libzmf-0.0.2-20-x86_64 +installed = licenses-20240728-1-any +installed = lilv-0.26.4-1-x86_64 +installed = linux-api-headers-6.19-1-x86_64 +installed = linux-firmware-20260309-1-any +installed = linux-firmware-amdgpu-20260309-1-any +installed = linux-firmware-atheros-20260309-1-any +installed = linux-firmware-broadcom-20260309-1-any +installed = linux-firmware-cirrus-20260309-1-any +installed = linux-firmware-intel-20260309-1-any +installed = linux-firmware-mediatek-20260309-1-any +installed = linux-firmware-nvidia-20260309-1-any +installed = linux-firmware-other-20260309-1-any +installed = linux-firmware-radeon-20260309-1-any +installed = linux-firmware-realtek-20260309-1-any +installed = linux-firmware-whence-20260309-1-any +installed = linux-tkg-6.19.8-273-x86_64 +installed = linux-tkg-headers-6.19.8-273-x86_64 +installed = linux-zen-6.19.8.zen1-1-x86_64 +installed = linux-zen-headers-6.19.8.zen1-1-x86_64 +installed = lksctp-tools-1.0.21-1-x86_64 +installed = llhttp-9.3.1-1-x86_64 +installed = llvm-libs-22.1.1-1-x86_64 +installed = lm_sensors-1:3.6.2-1-x86_64 +installed = lmdb-0.9.35-1-x86_64 +installed = localsearch-3.10.2-1-x86_64 +installed = lpsolve-5.5.2.14-1-x86_64 +installed = lsp-plugins-lv2-1.2.27-1-x86_64 +installed = lua-5.4.8-2-x86_64 +installed = lua51-lpeg-1.1.0-4-x86_64 +installed = luajit-2.1.1772619647+659a616-1-x86_64 +installed = luarocks-3.13.0-1-any +installed = lv2-1.18.10-2-x86_64 +installed = lxmenu-data-0.1.7-1-any +installed = lz4-1:1.10.0-2-x86_64 +installed = lzo-2.10-5-x86_64 +installed = m4-1.4.21-1-x86_64 +installed = mailcap-2.1.54-2-any +installed = make-4.4.1-2-x86_64 +installed = man-db-2.13.1-1-x86_64 +installed = mariadb-libs-12.2.2-2-x86_64 +installed = md4c-0.5.2-1-x86_64 +installed = mdadm-4.5-2-x86_64 +installed = menu-cache-1.1.1-2-x86_64 +installed = mesa-1:26.0.3-1-x86_64 +installed = mesa-utils-9.0.0-7-x86_64 +installed = meson-1.10.2-1-any +installed = minizip-1:1.3.2-3-x86_64 +installed = mkinitcpio-40-4-any +installed = mkinitcpio-busybox-1.36.1-1-x86_64 +installed = mobile-broadband-provider-info-20251101-1-any +installed = mpdecimal-4.0.1-1-x86_64 +installed = mpfr-4.2.2-1-x86_64 +installed = mpg123-1.33.4-1-x86_64 +installed = mpv-1:0.41.0-3-x86_64 +installed = msgpack-c-6.1.0-2-x86_64 +installed = mtdev-1.1.7-1-x86_64 +installed = mujs-1.3.9-1-x86_64 +installed = muparser-2.3.5-2-x86_64 +installed = mypaint-brushes-2.0.2-2-any +installed = mypaint-brushes1-1.3.1-2-any +installed = nautilus-49.5-1-x86_64 +installed = ncurses-6.6-1-x86_64 +installed = nemo-preview-6.6.0-3-x86_64 +installed = neon-0.36.0-1-x86_64 +installed = neovim-0.11.6-1-x86_64 +installed = netpbm-10.86.48-1-x86_64 +installed = nettle-3.10.2-1-x86_64 +installed = network-manager-applet-1.36.0-1-x86_64 +installed = networkmanager-1.56.0-1-x86_64 +installed = networkmanager-openvpn-1.12.5-1-x86_64 +installed = networkmanager-vpn-plugin-openvpn-1.12.5-1-x86_64 +installed = newaita-reborn-icons-git-r88.5b19f46a-1-any +installed = nftables-1:1.1.6-3-x86_64 +installed = ninja-1.13.2-3-x86_64 +installed = niri-25.11-2-x86_64 +installed = nm-connection-editor-1.36.0-1-x86_64 +installed = nmap-7.98-5-x86_64 +installed = node-gyp-12.2.0-1-any +installed = nodejs-25.8.1-1-x86_64 +installed = nodejs-nopt-8.1.0-1-any +installed = noise-suppression-for-voice-1.10-1-x86_64 +installed = npm-11.12.0-1-any +installed = npth-1.8-1-x86_64 +installed = nspr-4.38.2-1-x86_64 +installed = nss-3.121-1-x86_64 +installed = ntfs-3g-2022.10.3-2-x86_64 +installed = nwg-look-1.0.6-1-x86_64 +installed = ocl-icd-2.3.4-1-x86_64 +installed = oniguruma-6.9.10-1-x86_64 +installed = openal-1.25.1-1-x86_64 +installed = opencore-amr-0.1.6-2-x86_64 +installed = openexr-3.4.7-2-x86_64 +installed = openh264-2.6.0-2-x86_64 +installed = openjpeg2-2.5.4-1-x86_64 +installed = openjph-0.26.3-3-x86_64 +installed = openssh-10.2p1-2-x86_64 +installed = openssl-3.6.1-1-x86_64 +installed = openvpn-2.7.0-1-x86_64 +installed = opus-1.6.1-1-x86_64 +installed = opusfile-0.12-4-x86_64 +installed = orc-0.4.42-1-x86_64 +installed = orchis-theme-2025_04_25-2-any +installed = osinfo-db-20251212-1-any +installed = p11-kit-0.26.2-1-x86_64 +installed = pacman-7.1.0.r9.g54d9411-1-x86_64 +installed = pacman-mirrorlist-20260213-1-any +installed = pahole-1:1.31-2-x86_64 +installed = pam-1.7.2-2-x86_64 +installed = pambase-20250719-1-any +installed = pango-1:1.57.0-2-x86_64 +installed = pangomm-2.46.4-1-x86_64 +installed = pangomm-2.48-2.56.1-1-x86_64 +installed = parted-3.6-2-x86_64 +installed = paru-2.1.0-2-x86_64 +installed = paru-debug-2.1.0-2-x86_64 +installed = passim-0.1.10-1-x86_64 +installed = patch-2.8-1-x86_64 +installed = patchutils-0.4.5-1-x86_64 +installed = pavucontrol-1:6.2-1-x86_64 +installed = pciutils-3.14.0-1-x86_64 +installed = pcre-8.45-4-x86_64 +installed = pcre2-10.47-1-x86_64 +installed = pcsclite-2.4.1-1-x86_64 +installed = perl-5.42.1-1-x86_64 +installed = perl-clone-0.48-1-x86_64 +installed = perl-encode-locale-1.05-15-any +installed = perl-error-0.17030-3-any +installed = perl-file-listing-6.16-6-any +installed = perl-html-parser-3.83-2-x86_64 +installed = perl-html-tagset-3.24-4-any +installed = perl-http-cookiejar-0.014-5-any +installed = perl-http-cookies-6.11-4-any +installed = perl-http-daemon-6.16-6-any +installed = perl-http-date-6.06-5-any +installed = perl-http-message-7.01-2-any +installed = perl-http-negotiate-6.01-16-any +installed = perl-io-html-1.004-8-any +installed = perl-libwww-6.81-2-any +installed = perl-lwp-mediatypes-6.04-8-any +installed = perl-mailtools-2.22-3-any +installed = perl-net-http-6.24-2-any +installed = perl-timedate-2.34-1-any +installed = perl-try-tiny-0.32-4-any +installed = perl-uri-5.34-2-any +installed = perl-www-robotrules-6.02-16-any +installed = perl-xml-parser-2.47-3-x86_64 +installed = php-8.5.4-1-x86_64 +installed = pinentry-1.3.2-2-x86_64 +installed = pipewire-1:1.6.2-1-x86_64 +installed = pipewire-alsa-1:1.6.2-1-x86_64 +installed = pipewire-audio-1:1.6.2-1-x86_64 +installed = pipewire-jack-1:1.6.2-1-x86_64 +installed = pipewire-pulse-1:1.6.2-1-x86_64 +installed = pixman-0.46.4-1-x86_64 +installed = pkcs11-helper-1.31.0-1-x86_64 +installed = pkgconf-2.5.1-1-x86_64 +installed = playerctl-2.4.1-5-x86_64 +installed = plocate-1.1.24-1-x86_64 +installed = polkit-127-3-x86_64 +installed = polkit-qt6-0.200.0-1-x86_64 +installed = ponymix-5-5-x86_64 +installed = poppler-26.03.0-1-x86_64 +installed = poppler-data-0.4.12-2-any +installed = poppler-glib-26.03.0-1-x86_64 +installed = popt-1.19-2-x86_64 +installed = portaudio-1:19.7.0-4-x86_64 +installed = portmidi-1:2.0.8-1-x86_64 +installed = portsmf-234-3-x86_64 +installed = postgresql-libs-18.3-2-x86_64 +installed = potrace-1.16-4-x86_64 +installed = pps-tools-1.0.3-2-x86_64 +installed = procps-ng-4.0.6-1-x86_64 +installed = protobuf-33.1-4-x86_64 +installed = protobuf-c-1.5.2-8-x86_64 +installed = psmisc-23.7-1-x86_64 +installed = pugixml-1.15-3-x86_64 +installed = pybind11-3.0.2-1-any +installed = python-3.14.3-1-x86_64 +installed = python-appdirs-1.4.4-12-any +installed = python-autocommand-2.2.2-9-any +installed = python-babel-2.17.0-3-any +installed = python-beautifulsoup4-4.14.3-2-any +installed = python-build-1.4.0-1-any +installed = python-cachecontrol-1:0.14.4-3-any +installed = python-cairo-1.29.0-2-x86_64 +installed = python-certifi-2026.02.25-1-any +installed = python-chardet-6.0.0.post1-1-any +installed = python-charset-normalizer-3.4.6-1-x86_64 +installed = python-chevron-0.14.0-1-any +installed = python-click-8.3.2-1-any +installed = python-cssselect-1.4.0-1-any +installed = python-dbus-1.4.0-2-x86_64 +installed = python-distro-1.9.0-4-any +installed = python-docutils-1:0.22.4-1-any +installed = python-editables-0.5-7-any +installed = python-filelock-3.25.2-1-any +installed = python-gobject-3.54.5-2-x86_64 +installed = python-hatchling-1.29.0-1-any +installed = python-idna-3.11-2-any +installed = python-imageio-2.37.3-1-any +installed = python-imageio-ffmpeg-0.6.0-2-any +installed = python-imagesize-1.4.1-7-any +installed = python-iniconfig-2.2.0-1-any +installed = python-installer-0.7.0-14-any +installed = python-jaraco.collections-5.1.0-3-any +installed = python-jaraco.context-6.0.1-3-any +installed = python-jaraco.functools-4.1.0-3-any +installed = python-jaraco.text-4.0.0-4-any +installed = python-jinja-1:3.1.6-3-any +installed = python-legacy-cgi-2.6.4-2-any +installed = python-lockfile-0.12.2-15-any +installed = python-lxml-6.0.2-2-x86_64 +installed = python-mako-1.3.10-4-any +installed = python-markdown-3.10.2-1-any +installed = python-markupsafe-3.0.3-1-x86_64 +installed = python-more-itertools-10.8.0-2-any +installed = python-msgpack-1.1.2-2-x86_64 +installed = python-numpy-2.4.3-1-x86_64 +installed = python-packaging-26.0-1-any +installed = python-pathspec-1.0.4-1-any +installed = python-pillow-12.1.1-1-x86_64 +installed = python-pkg_resources-81.0.0-1-any +installed = python-platformdirs-4.9.4-1-any +installed = python-pluggy-1.6.0-3-any +installed = python-psutil-7.2.2-1-x86_64 +installed = python-pyasyncore-1.0.5-1-any +installed = python-pygments-2.19.2-3-any +installed = python-pyinotify-0.9.6-16-any +installed = python-pyproject-hooks-1.2.0-6-any +installed = python-pyserial-3.5-8-any +installed = python-pytest-1:8.4.2-3-any +installed = python-pytz-2025.2-2-any +installed = python-requests-2.32.5-4-any +installed = python-roman-numerals-py-3.1.0-2-any +installed = python-screeninfo-0.8.1-2-any +installed = python-setproctitle-1.3.7-2-x86_64 +installed = python-setuptools-1:82.0.1-1-any +installed = python-six-1.17.0-2-any +installed = python-snowballstemmer-3.0.0.1-1-any +installed = python-soupsieve-2.8.3-1-any +installed = python-sphinx-9.1.0-1-any +installed = python-sphinx-alabaster-theme-1.0.0-6-any +installed = python-sphinx_rtd_theme-2.0.0-3-any +installed = python-sphinxcontrib-applehelp-2.0.0-5-any +installed = python-sphinxcontrib-devhelp-2.0.0-6-any +installed = python-sphinxcontrib-htmlhelp-2.1.0-5-any +installed = python-sphinxcontrib-jquery-4.1-5-any +installed = python-sphinxcontrib-jsmath-1.0.1-21-any +installed = python-sphinxcontrib-qthelp-2.0.0-5-any +installed = python-sphinxcontrib-serializinghtml-2.0.0-5-any +installed = python-tinycss2-1.5.1-2-any +installed = python-tqdm-4.67.3-1-any +installed = python-trove-classifiers-2026.1.14.14-1-any +installed = python-typing_extensions-4.15.0-3-any +installed = python-urllib3-2.6.3-1-any +installed = python-urwid-3.0.5-1-any +installed = python-wcwidth-0.6.0-1-any +installed = python-webencodings-0.5.1-13-any +installed = python-wheel-0.46.3-1-any +installed = python-zstandard-0.25.0-2-x86_64 +installed = qca-qt6-2.3.10-5-x86_64 +installed = qt5-base-5.15.18+kde+r109-2-x86_64 +installed = qt5-svg-5.15.18+kde+r5-1-x86_64 +installed = qt5-translations-5.15.18-1-any +installed = qt5-x11extras-5.15.18-1-x86_64 +installed = qt6-5compat-6.10.2-1-x86_64 +installed = qt6-base-6.10.2-1-x86_64 +installed = qt6-declarative-6.10.2-1-x86_64 +installed = qt6-shadertools-6.10.2-1-x86_64 +installed = qt6-svg-6.10.2-1-x86_64 +installed = qt6-translations-6.10.2-1-any +installed = qt6-wayland-6.10.2-1-x86_64 +installed = quickshell-0.2.1-5-x86_64 +installed = ragel-6.10-4-x86_64 +installed = raptor-2.0.16-9-x86_64 +installed = rasqal-1:0.9.33-7-x86_64 +installed = rav1e-0.8.1-2-x86_64 +installed = re2-2:2025.11.05-1-x86_64 +installed = readline-8.3.003-1-x86_64 +installed = reapack-1.2.6-2-x86_64 +installed = reaper-7.66-1-x86_64 +installed = redland-1:1.0.17-9-x86_64 +installed = rhash-1.4.6-1-x86_64 +installed = ripgrep-15.1.0-2-x86_64 +installed = rofi-lbonn-wayland-git-1.7.9.wayland1.r1.gd4b16e6f-1-x86_64 +installed = rsync-3.4.1-2-x86_64 +installed = rtkit-0.14-1-x86_64 +installed = rubberband-4.0.0-1-x86_64 +installed = run-parts-5.23.2-1-x86_64 +installed = runc-1.4.1-1-x86_64 +installed = rustup-1.29.0-1-x86_64 +installed = satty-0.20.1-2-x86_64 +installed = sbc-2.2-1-x86_64 +installed = scdoc-1.11.4-1-x86_64 +installed = scour-0.38.2-6-any +installed = sdbus-cpp-2.2.1-1-x86_64 +installed = sddm-0.21.0-6-x86_64 +installed = sdl2-compat-2.32.64-1-x86_64 +installed = sdl3-3.4.2-1-x86_64 +installed = seatd-0.9.3-1-x86_64 +installed = sed-4.9-3-x86_64 +installed = semver-7.7.4-1-any +installed = serd-0.32.8-1-x86_64 +installed = shaderc-2026.1-2-x86_64 +installed = shadow-4.18.0-1-x86_64 +installed = shared-mime-info-2.4-3-x86_64 +installed = simdjson-1:4.4.0-1-x86_64 +installed = slang-2.3.3-4-x86_64 +installed = slurp-1.5.0-1-x86_64 +installed = smbclient-2:4.23.6-1-x86_64 +installed = snappy-1.2.2-3-x86_64 +installed = sndio-1.10.0-1-x86_64 +installed = sord-0.16.22-1-x86_64 +installed = sound-theme-freedesktop-0.8-6-any +installed = soundtouch-2.4.0-1-x86_64 +installed = spandsp-0.0.6-7-x86_64 +installed = spdlog-1.17.0-2-x86_64 +installed = speex-1.2.1-2-x86_64 +installed = speexdsp-1.2.1-2-x86_64 +installed = spirv-tools-1:1.4.341.0-2-x86_64 +installed = sqlite-3.52.0-1-x86_64 +installed = sratom-0.6.22-1-x86_64 +installed = srt-1.5.4-1-x86_64 +installed = sshfs-3.7.5-1-x86_64 +installed = startup-notification-0.12-9-x86_64 +installed = stasis-1.1.0-1-x86_64 +installed = stow-2.4.1-1-any +installed = sublime-text-4-4.4200-1-x86_64 +installed = sudo-1.9.17.p2-2-x86_64 +installed = suil-0.10.26-1-x86_64 +installed = suitesparse-7.12.2-1-x86_64 +installed = svt-av1-4.0.1-1-x86_64 +installed = swaylock-effects-1.8.1-1-x86_64 +installed = swww-0.11.2-1-x86_64 +installed = sysbench-1.0.20-2-x86_64 +installed = systemd-259.5-1-x86_64 +installed = systemd-libs-259.5-1-x86_64 +installed = systemd-sysvcompat-259.5-1-x86_64 +installed = taglib-2.2.1-1-x86_64 +installed = talloc-2.4.4-1-x86_64 +installed = tar-1.35-2-x86_64 +installed = tdb-1.4.15-1-x86_64 +installed = tevent-1:0.17.1-2-x86_64 +installed = texinfo-7.2-1-x86_64 +installed = timeshift-25.12.4-1-x86_64 +installed = timeshift-autosnap-0.10.0-1-any +installed = tinysparql-3.10.1-2-x86_64 +installed = tomlplusplus-3.4.0-1-x86_64 +installed = totem-pl-parser-3.26.6+r30+g51b8439-2-x86_64 +installed = tpm2-tss-4.1.3-1-x86_64 +installed = tree-sitter-0.25.10-3-x86_64 +installed = tree-sitter-c-0.24.1-1-x86_64 +installed = tree-sitter-lua-0.5.0-1-x86_64 +installed = tree-sitter-markdown-0.5.1-1-x86_64 +installed = tree-sitter-query-0.7.0-1-x86_64 +installed = tree-sitter-vim-0.8.1-1-x86_64 +installed = tree-sitter-vimdoc-4.0.0-1-x86_64 +installed = tslib-1.24-1-x86_64 +installed = ttf-hack-nerd-3.4.0-2-any +installed = ttf-input-nerd-3.4.0-4-any +installed = ttf-liberation-2.1.5-2-any +installed = twolame-0.4.0-4-x86_64 +installed = tzdata-2026a-1-x86_64 +installed = uchardet-0.0.8-3-x86_64 +installed = udisks2-2.11.1-2-x86_64 +installed = ufw-0.36.2-7-any +installed = ungoogled-chromium-bin-146.0.7680.153-1-x86_64 +installed = unibilium-2.1.2-1-x86_64 +installed = unzip-6.0-23-x86_64 +installed = upower-1.91.1-1-x86_64 +installed = usbutils-019-1-x86_64 +installed = util-linux-2.41.3-2-x86_64 +installed = util-linux-libs-2.41.3-2-x86_64 +installed = v4l-utils-1.32.0-2-x86_64 +installed = vamp-plugin-sdk-1:2.10-1-x86_64 +installed = vapoursynth-73-2-x86_64 +installed = vid.stab-1.1.1-2-x86_64 +installed = viewnior-1.8-7-x86_64 +installed = vim-9.2.0204-1-x86_64 +installed = vim-runtime-9.2.0204-1-x86_64 +installed = vmaf-3.0.0-2-x86_64 +installed = volume_key-0.3.12-12-x86_64 +installed = vte-common-0.82.3-1-x86_64 +installed = vte3-0.82.3-1-x86_64 +installed = vulkan-icd-loader-1.4.341.0-1-x86_64 +installed = vulkan-tools-1.4.341.0-2-x86_64 +installed = waterfox-bin-1:6.6.9-1-x86_64 +installed = wavpack-5.9.0-1-x86_64 +installed = waybar-0.15.0-2-x86_64 +installed = waybar-niri-windows-bin-2.3.0-1-x86_64 +installed = waybar-niri-workspaces-enhanced-git-r17.8f4725f-1-x86_64 +installed = wayland-1.24.0-1-x86_64 +installed = wayland-protocols-1.47-1-any +installed = waypaper-2.7-1-any +installed = wdisplays-git-1.1.r21.g157b8c5-1-x86_64 +installed = webkit2gtk-4.1-2.50.6-1-x86_64 +installed = webrtc-audio-processing-1-1.3-5-x86_64 +installed = weston-14.0.2-3-x86_64 +installed = wget-1.25.0-3-x86_64 +installed = which-2.23-1-x86_64 +installed = wireplumber-0.5.13-1-x86_64 +installed = wl-clipboard-1:2.2.1-3-x86_64 +installed = wlogout-1.2.2-0-x86_64 +installed = wlroots0.19-0.19.2-2-x86_64 +installed = woff2-1.0.2-6-x86_64 +installed = wpa_supplicant-2:2.11-5-x86_64 +installed = wxwidgets-common-3.2.10-1-x86_64 +installed = wxwidgets-gtk3-3.2.10-1-x86_64 +installed = x264-3:0.165.r3222.b35605a-2-x86_64 +installed = x265-4.1-1-x86_64 +installed = xapp-3.2.2-1-x86_64 +installed = xapp-symbolic-icons-1.0.9-1-any +installed = xarchiver-0.5.4.26-1-x86_64 +installed = xcb-proto-1.17.0-4-any +installed = xcb-util-0.4.1-2-x86_64 +installed = xcb-util-cursor-0.1.6-1-x86_64 +installed = xcb-util-errors-1.0.1-2-x86_64 +installed = xcb-util-image-0.4.1-3-x86_64 +installed = xcb-util-keysyms-0.4.1-5-x86_64 +installed = xcb-util-renderutil-0.3.10-2-x86_64 +installed = xcb-util-wm-0.4.2-2-x86_64 +installed = xcb-util-xrm-1.3-4-x86_64 +installed = xcur2png-0.7.1-8-x86_64 +installed = xdg-dbus-proxy-0.1.6-1-x86_64 +installed = xdg-desktop-portal-1.20.3-2-x86_64 +installed = xdg-desktop-portal-gnome-49.0-1-x86_64 +installed = xdg-desktop-portal-gtk-1.15.3-1-x86_64 +installed = xdg-desktop-portal-hyprland-1.3.11-3-x86_64 +installed = xdg-user-dirs-0.19-2-x86_64 +installed = xdg-user-dirs-gtk-0.16-1-x86_64 +installed = xdg-utils-1.2.1-2-any +installed = xf86-input-libinput-1.5.0-1-x86_64 +installed = xfconf-4.20.0-2-x86_64 +installed = xfsprogs-6.18.0-1-x86_64 +installed = xkeyboard-config-2.47-1-any +installed = xmlsec-1.3.9-1-x86_64 +installed = xmlto-0.0.29-1-x86_64 +installed = xorg-fonts-encodings-1.1.0-1-any +installed = xorg-server-21.1.21-1-x86_64 +installed = xorg-server-common-21.1.21-1-x86_64 +installed = xorg-setxkbmap-1.3.4-2-x86_64 +installed = xorg-xauth-1.1.5-1-x86_64 +installed = xorg-xcursorgen-1.0.9-1-x86_64 +installed = xorg-xeyes-1.3.1-1-x86_64 +installed = xorg-xhost-1.0.10-1-x86_64 +installed = xorg-xkbcomp-1.5.0-1-x86_64 +installed = xorg-xprop-1.2.8-1-x86_64 +installed = xorg-xset-1.2.5-2-x86_64 +installed = xorg-xwayland-24.1.9-1-x86_64 +installed = xorgproto-2025.1-1-any +installed = xreader-4.6.3-1-x86_64 +installed = xvidcore-1.3.7-3-x86_64 +installed = xwayland-satellite-0.8.1-1-x86_64 +installed = xxhash-0.8.3-1-x86_64 +installed = xz-5.8.2-1-x86_64 +installed = yarn-1.22.22-2-any +installed = yyjson-0.12.0-1-x86_64 +installed = zeromq-4.3.5-3-x86_64 +installed = zimg-3.0.6-1-x86_64 +installed = zint-2.16.0-1-x86_64 +installed = zip-3.0-11-x86_64 +installed = zix-0.8.0-1-x86_64 +installed = zlib-1:1.3.2-3-x86_64 +installed = zlib-ng-2.3.3-1-x86_64 +installed = zsh-5.9-5-x86_64 +installed = zstd-1.5.7-3-x86_64 +installed = zxing-cpp-3.0.2-1-x86_64 diff --git a/pkg/pkg/moongreet/.INSTALL b/pkg/pkg/moongreet/.INSTALL new file mode 100644 index 0000000..5dccda6 --- /dev/null +++ b/pkg/pkg/moongreet/.INSTALL @@ -0,0 +1,18 @@ +# ABOUTME: pacman install hooks for Moongreet. +# ABOUTME: Sets ownership on cache directory for the greeter user. + +post_install() { + if getent passwd greeter > /dev/null 2>&1; then + chown greeter:greeter /var/cache/moongreet + fi + + echo "==> Copy /etc/moongreet/moongreet.toml and adjust the wallpaper path." + echo "==> Configure greetd to use moongreet:" + echo " [default_session]" + echo " command = \"moongreet\"" + echo " user = \"greeter\"" +} + +post_upgrade() { + post_install +} diff --git a/pkg/pkg/moongreet/.MTREE b/pkg/pkg/moongreet/.MTREE new file mode 100644 index 0000000..887db7b Binary files /dev/null and b/pkg/pkg/moongreet/.MTREE differ diff --git a/pkg/pkg/moongreet/.PKGINFO b/pkg/pkg/moongreet/.PKGINFO new file mode 100644 index 0000000..7cd4a8f --- /dev/null +++ b/pkg/pkg/moongreet/.PKGINFO @@ -0,0 +1,22 @@ +# Generated by makepkg 7.1.0 +# using fakeroot version 1.37.2 +pkgname = moongreet +pkgbase = moongreet +xdata = pkgtype=pkg +pkgver = 0.1.0-1 +pkgdesc = A greetd greeter for Wayland, built with Python + GTK4 + gtk4-layer-shell +url = https://gitea.moonarch.de/nevaforget/greetd-moongreet +builddate = 1774528075 +packager = Unknown Packager +size = 567020 +arch = any +license = MIT +depend = python +depend = python-gobject +depend = gtk4 +depend = gtk4-layer-shell +depend = greetd +makedepend = git +makedepend = python-build +makedepend = python-installer +makedepend = python-hatchling diff --git a/pkg/pkg/moongreet/etc/moongreet/moongreet.toml b/pkg/pkg/moongreet/etc/moongreet/moongreet.toml new file mode 100644 index 0000000..1069fae --- /dev/null +++ b/pkg/pkg/moongreet/etc/moongreet/moongreet.toml @@ -0,0 +1,6 @@ +# ABOUTME: Example configuration for the Moongreet greeter. +# ABOUTME: Copy to /etc/moongreet/moongreet.toml and adjust paths. + +[appearance] +# Absolute path to wallpaper image +background = "/usr/share/backgrounds/wallpaper.jpg" diff --git a/pkg/pkg/moongreet/usr/bin/moongreet b/pkg/pkg/moongreet/usr/bin/moongreet new file mode 100755 index 0000000..cdb1f6f --- /dev/null +++ b/pkg/pkg/moongreet/usr/bin/moongreet @@ -0,0 +1,8 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +import re +import sys +from moongreet.main import main +if __name__ == "__main__": + sys.argv[0] = re.sub(r"(-script\.pyw|\.exe)?$", "", sys.argv[0]) + sys.exit(main()) diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/METADATA b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/METADATA new file mode 100644 index 0000000..8152d02 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/METADATA @@ -0,0 +1,7 @@ +Metadata-Version: 2.4 +Name: moongreet +Version: 0.1.0 +Summary: A greetd greeter for Wayland with GTK4 +License-Expression: MIT +Requires-Python: >=3.11 +Requires-Dist: pygobject>=3.46 diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/RECORD b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/RECORD new file mode 100644 index 0000000..3a24620 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/RECORD @@ -0,0 +1,18 @@ +../../../bin/moongreet,sha256=fhnGyAMSfkZpGxKQbKkSeaRAge-a8Fggfv3Pu0coQFs,212 +moongreet/__init__.py,sha256=QXh8GSCKrfiZ7_H2eiWGhfpBpznWUo4pFoIBqcTh07U,116 +moongreet/config.py,sha256=_WUlBma-KPQUpxeepvQbpR3e2lTIuVBGVcyc_qTi4mA,2100 +moongreet/greeter.py,sha256=Zist1Utwd3SzMDynbWQZG2l36E5C7h-anxQ1TXl6Hu4,22735 +moongreet/i18n.py,sha256=RNGu2Yo5RxM8Cok1HZMPabY5X3t_Ga4M78MRTJHvs1c,3972 +moongreet/ipc.py,sha256=55Np1qyY_T4ceRBr2nhGa4Dwed3__MBHzM16at4c2ss,2111 +moongreet/main.py,sha256=WazQV9yncPMHTkfVqDQUYR6_KtPVqpf-h7HudmeWzaA,4648 +moongreet/power.py,sha256=RYVvJrkGk0KFuWdE64xRch3oX_p2-Q78ieS-K5ZMMmg,468 +moongreet/sessions.py,sha256=7abDbPeSEXZqhbphl_0AvY-4P8MqO_SlNl6pRVT-JFs,1947 +moongreet/style.css,sha256=qpGjJSvTxy16SlYBQAKpFkmX1xeot0lHWNlim0nOpSs,1673 +moongreet/users.py,sha256=jso4iswMJuxxlqMruga2NJMZbnEbQ_OzMPs78h8i5yY,3111 +moongreet/data/default-avatar.svg,sha256=FaRdOK0qf6iR37j7uyAS6sh6cLelmwK6S9apIjC96yQ,2684 +moongreet/data/wallpaper.jpg,sha256=wZEatvO-9VCSOgZ_H9bsre6m3vp5a63RljUK6ujXuKs,374226 +moongreet/data/icons/hicolor/scalable/apps/moongreet-default-avatar-symbolic.svg,sha256=Zx9vJBV4JvoIY8MTzw3Cbx_Wy2d-qLFdfHFWnYwqqGc,2679 +moongreet-0.1.0.dist-info/METADATA,sha256=5aE4QV5Xf60TwCt8HGpQGCXQvbPpLlXoUs3uBRk4m9A,180 +moongreet-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87 +moongreet-0.1.0.dist-info/entry_points.txt,sha256=_QpPvWlESl0gCjntxS5V8JmsKWEz8AtkneySdVW2r08,50 +moongreet-0.1.0.dist-info/RECORD,, diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/WHEEL b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/WHEEL new file mode 100644 index 0000000..b1b94fd --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/WHEEL @@ -0,0 +1,4 @@ +Wheel-Version: 1.0 +Generator: hatchling 1.29.0 +Root-Is-Purelib: true +Tag: py3-none-any diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/entry_points.txt b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/entry_points.txt new file mode 100644 index 0000000..2113571 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet-0.1.0.dist-info/entry_points.txt @@ -0,0 +1,2 @@ +[console_scripts] +moongreet = moongreet.main:main diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/__init__.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/__init__.py new file mode 100644 index 0000000..61840b5 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/__init__.py @@ -0,0 +1,2 @@ +# ABOUTME: Moongreet package — a greetd greeter for Wayland with GTK4. +# ABOUTME: Part of the Moonarch ecosystem. diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/config.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/config.py new file mode 100644 index 0000000..aa93afe --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/config.py @@ -0,0 +1,75 @@ +# ABOUTME: Configuration loading from moongreet.toml. +# ABOUTME: Parses appearance and behavior settings with wallpaper path resolution. + +import tomllib +from contextlib import AbstractContextManager +from dataclasses import dataclass +from importlib.resources import as_file, files +from pathlib import Path + +DEFAULT_CONFIG_PATHS = [ + Path("/etc/moongreet/moongreet.toml"), +] + + +@dataclass +class Config: + """Greeter configuration loaded from moongreet.toml.""" + + background: Path | None = None + + +def load_config(config_path: Path | None = None) -> Config: + """Load configuration from a TOML file. + + Relative paths in the config are resolved against the config file's directory. + """ + if config_path is None: + for path in DEFAULT_CONFIG_PATHS: + if path.exists(): + config_path = path + break + if config_path is None: + return Config() + + if not config_path.exists(): + return Config() + + try: + with open(config_path, "rb") as f: + data = tomllib.load(f) + except (tomllib.TOMLDecodeError, OSError): + return Config() + + config = Config() + appearance = data.get("appearance", {}) + + bg = appearance.get("background") + if bg: + bg_path = Path(bg) + if not bg_path.is_absolute(): + bg_path = config_path.parent / bg_path + config.background = bg_path + + return config + + +_PACKAGE_DATA = files("moongreet") / "data" +_DEFAULT_WALLPAPER_PATH = _PACKAGE_DATA / "wallpaper.jpg" + + +def resolve_wallpaper_path( + config: Config, +) -> tuple[Path, AbstractContextManager | None]: + """Resolve the wallpaper path from config or fall back to the package default. + + Returns (path, context_manager). The context_manager is non-None when a + package resource was extracted to a temporary file — the caller must keep + it alive and call __exit__ when done. + """ + if config.background and config.background.exists(): + return config.background, None + + ctx = as_file(_DEFAULT_WALLPAPER_PATH) + path = ctx.__enter__() + return path, ctx diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/default-avatar.svg b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/default-avatar.svg new file mode 100644 index 0000000..e3da366 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/default-avatar.svg @@ -0,0 +1 @@ + diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/icons/hicolor/scalable/apps/moongreet-default-avatar-symbolic.svg b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/icons/hicolor/scalable/apps/moongreet-default-avatar-symbolic.svg new file mode 100644 index 0000000..9db9ddc --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/icons/hicolor/scalable/apps/moongreet-default-avatar-symbolic.svg @@ -0,0 +1 @@ + diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/wallpaper.jpg b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/wallpaper.jpg new file mode 100644 index 0000000..86371cd Binary files /dev/null and b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/data/wallpaper.jpg differ diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/greeter.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/greeter.py new file mode 100644 index 0000000..3c1d657 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/greeter.py @@ -0,0 +1,587 @@ +# ABOUTME: Main greeter window — builds the GTK4 UI layout for the Moongreet greeter. +# ABOUTME: Handles user selection, session choice, password entry, and power actions. + +import logging +import os +import re +import shlex +import shutil +import socket +import stat +import subprocess +import threading +from importlib.resources import files +from pathlib import Path + +import gi +gi.require_version("Gtk", "4.0") +gi.require_version("Gdk", "4.0") +from gi.repository import Gtk, Gdk, GLib, GdkPixbuf + +from moongreet.config import load_config, resolve_wallpaper_path +from moongreet.i18n import load_strings, Strings +from moongreet.ipc import create_session, post_auth_response, start_session, cancel_session +from moongreet.users import User, get_users, get_avatar_path, get_user_gtk_theme +from moongreet.sessions import Session, get_sessions +from moongreet.power import reboot, shutdown + +logger = logging.getLogger(__name__) + +LAST_USER_PATH = Path("/var/cache/moongreet/last-user") +FAILLOCK_MAX_ATTEMPTS = 3 +VALID_USERNAME = re.compile(r"^[a-zA-Z0-9_.-]+$") +MAX_USERNAME_LENGTH = 256 +PACKAGE_DATA = files("moongreet") / "data" +DEFAULT_AVATAR_PATH = PACKAGE_DATA / "default-avatar.svg" +AVATAR_SIZE = 128 + + +def faillock_warning(attempt_count: int, strings: Strings | None = None) -> str | None: + """Return a warning if the user is approaching or has reached the faillock limit.""" + if strings is None: + strings = load_strings() + remaining = FAILLOCK_MAX_ATTEMPTS - attempt_count + if remaining <= 0: + return strings.faillock_locked + if remaining == 1: + return strings.faillock_attempts_remaining.format(n=remaining) + return None + + +def _build_wallpaper_widget(bg_path: Path | None) -> Gtk.Widget: + """Create a wallpaper widget that fills the available space.""" + if bg_path and bg_path.exists(): + background = Gtk.Picture() + background.set_filename(str(bg_path)) + background.set_content_fit(Gtk.ContentFit.COVER) + background.set_hexpand(True) + background.set_vexpand(True) + return background + background = Gtk.Box() + background.set_hexpand(True) + background.set_vexpand(True) + return background + + +class WallpaperWindow(Gtk.ApplicationWindow): + """A window that shows only the wallpaper — used for secondary monitors.""" + + def __init__(self, bg_path: Path | None = None, **kwargs) -> None: + super().__init__(**kwargs) + self.add_css_class("greeter") + self.set_default_size(1920, 1080) + self.set_child(_build_wallpaper_widget(bg_path)) + + +class GreeterWindow(Gtk.ApplicationWindow): + """The main greeter window with login UI.""" + + def __init__(self, bg_path: Path | None = None, **kwargs) -> None: + super().__init__(**kwargs) + self.add_css_class("greeter") + self.set_default_size(1920, 1080) + + self._config = load_config() + self._strings = load_strings() + self._users = get_users() + self._sessions = get_sessions() + self._selected_user: User | None = None + self._greetd_sock: socket.socket | None = None + self._greetd_sock_lock = threading.Lock() + self._default_avatar_pixbuf: GdkPixbuf.Pixbuf | None = None + self._avatar_cache: dict[str, GdkPixbuf.Pixbuf] = {} + self._failed_attempts: dict[str, int] = {} + self._bg_path = bg_path + + self._build_ui() + self._setup_keyboard_navigation() + # Defer initial user selection until the window is realized, + # so get_color() returns the actual theme foreground for SVG tinting + self.connect("realize", self._on_realize) + + def _on_realize(self, widget: Gtk.Widget) -> None: + """Called when the window is realized — select initial user. + + Deferred from __init__ so get_color() returns actual theme values + for SVG tinting. Uses idle_add so the first frame renders before + avatar loading blocks the main loop. + """ + GLib.idle_add(self._select_initial_user) + + def _build_ui(self) -> None: + """Build the complete greeter UI layout.""" + # Root overlay for layering + overlay = Gtk.Overlay() + self.set_child(overlay) + + # Background wallpaper + overlay.set_child(_build_wallpaper_widget(self._bg_path)) + + # Main layout: 3 rows (top spacer, center login, bottom bar) + main_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + main_box.set_hexpand(True) + main_box.set_vexpand(True) + overlay.add_overlay(main_box) + + # Top spacer + top_spacer = Gtk.Box() + top_spacer.set_vexpand(True) + main_box.append(top_spacer) + + # Center: login box + center_box = self._build_login_box() + center_box.set_halign(Gtk.Align.CENTER) + main_box.append(center_box) + + # Bottom spacer + bottom_spacer = Gtk.Box() + bottom_spacer.set_vexpand(True) + main_box.append(bottom_spacer) + + # Bottom bar overlay (user list left, power buttons right) + bottom_bar = self._build_bottom_bar() + bottom_bar.set_valign(Gtk.Align.END) + overlay.add_overlay(bottom_bar) + + def _build_login_box(self) -> Gtk.Box: + """Build the central login area with avatar, name, session, password.""" + box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + box.add_css_class("login-box") + box.set_halign(Gtk.Align.CENTER) + box.set_valign(Gtk.Align.CENTER) + box.set_spacing(12) + + # Avatar — wrapped in a clipping frame for round shape + avatar_frame = Gtk.Box() + avatar_frame.set_size_request(AVATAR_SIZE, AVATAR_SIZE) + avatar_frame.set_halign(Gtk.Align.CENTER) + avatar_frame.set_overflow(Gtk.Overflow.HIDDEN) + avatar_frame.add_css_class("avatar") + self._avatar_image = Gtk.Image() + self._avatar_image.set_pixel_size(AVATAR_SIZE) + avatar_frame.append(self._avatar_image) + box.append(avatar_frame) + + # Username label + self._username_label = Gtk.Label(label="") + self._username_label.add_css_class("username-label") + box.append(self._username_label) + + # Session dropdown + self._session_dropdown = Gtk.DropDown() + self._session_dropdown.add_css_class("session-dropdown") + self._session_dropdown.set_hexpand(True) + if self._sessions: + session_names = [s.name for s in self._sessions] + string_list = Gtk.StringList.new(session_names) + self._session_dropdown.set_model(string_list) + box.append(self._session_dropdown) + + # Password entry + self._password_entry = Gtk.PasswordEntry() + self._password_entry.set_hexpand(True) + self._password_entry.set_property("placeholder-text", self._strings.password_placeholder) + self._password_entry.set_property("show-peek-icon", True) + self._password_entry.add_css_class("password-entry") + self._password_entry.connect("activate", self._on_login_activate) + box.append(self._password_entry) + + # Error label (hidden by default) + self._error_label = Gtk.Label(label="") + self._error_label.add_css_class("error-label") + self._error_label.set_visible(False) + box.append(self._error_label) + + return box + + def _build_bottom_bar(self) -> Gtk.Box: + """Build the bottom bar with user list (left) and power buttons (right).""" + bar = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + bar.set_hexpand(True) + bar.set_margin_start(16) + bar.set_margin_end(16) + bar.set_margin_bottom(16) + + # User list (left) + user_list_box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) + user_list_box.add_css_class("user-list") + user_list_box.set_halign(Gtk.Align.START) + user_list_box.set_valign(Gtk.Align.END) + + for user in self._users: + btn = Gtk.Button(label=user.display_name) + btn.add_css_class("user-list-item") + btn.connect("clicked", self._on_user_clicked, user) + user_list_box.append(btn) + + bar.append(user_list_box) + + # Spacer + spacer = Gtk.Box() + spacer.set_hexpand(True) + bar.append(spacer) + + # Power buttons (right) + power_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) + power_box.set_halign(Gtk.Align.END) + power_box.set_valign(Gtk.Align.END) + power_box.set_spacing(8) + + reboot_btn = Gtk.Button() + reboot_btn.set_icon_name("system-reboot-symbolic") + reboot_btn.add_css_class("power-button") + reboot_btn.set_tooltip_text(self._strings.reboot_tooltip) + reboot_btn.connect("clicked", self._on_reboot_clicked) + power_box.append(reboot_btn) + + shutdown_btn = Gtk.Button() + shutdown_btn.set_icon_name("system-shutdown-symbolic") + shutdown_btn.add_css_class("power-button") + shutdown_btn.set_tooltip_text(self._strings.shutdown_tooltip) + shutdown_btn.connect("clicked", self._on_shutdown_clicked) + power_box.append(shutdown_btn) + + bar.append(power_box) + + return bar + + def _select_initial_user(self) -> None: + """Select the last user or the first available user.""" + if not self._users: + return + + # Try to load last user + last_username = self._load_last_user() + target_user = None + + if last_username: + for user in self._users: + if user.username == last_username: + target_user = user + break + + if target_user is None: + target_user = self._users[0] + + self._switch_to_user(target_user) + + def _switch_to_user(self, user: User) -> None: + """Update the UI to show the selected user.""" + self._selected_user = user + self._username_label.set_text(user.display_name) + self._password_entry.set_text("") + self._error_label.set_visible(False) + + # Update avatar (use cache if available) + if user.username in self._avatar_cache: + self._avatar_image.set_from_pixbuf(self._avatar_cache[user.username]) + else: + avatar_path = get_avatar_path( + user.username, home_dir=user.home + ) + if avatar_path and avatar_path.exists(): + self._set_avatar_from_file(avatar_path, user.username) + else: + # Default avatar — _set_default_avatar uses Traversable.read_text() + # which works in ZIP wheels too, no exists() check needed + self._set_default_avatar() + + # Apply user's GTK theme if available + self._apply_user_theme(user) + + # Focus password entry + self._password_entry.grab_focus() + + def _apply_user_theme(self, user: User) -> None: + """Load the user's preferred GTK theme from their settings.ini.""" + gtk_config_dir = user.home / ".config" / "gtk-4.0" + theme_name = get_user_gtk_theme(config_dir=gtk_config_dir) + + settings = Gtk.Settings.get_default() + if settings is None: + return + + current = settings.get_property("gtk-theme-name") + if theme_name and current != theme_name: + settings.set_property("gtk-theme-name", theme_name) + elif not theme_name and current: + settings.reset_property("gtk-theme-name") + + def _get_foreground_color(self) -> str: + """Get the current GTK theme foreground color as a hex string.""" + rgba = self.get_color() + r = int(rgba.red * 255) + g = int(rgba.green * 255) + b = int(rgba.blue * 255) + return f"#{r:02x}{g:02x}{b:02x}" + + def _set_default_avatar(self) -> None: + """Load the default avatar SVG, tinted with the GTK foreground color.""" + if self._default_avatar_pixbuf: + self._avatar_image.set_from_pixbuf(self._default_avatar_pixbuf) + return + try: + svg_text = DEFAULT_AVATAR_PATH.read_text() + fg_color = self._get_foreground_color() + svg_text = svg_text.replace("#PLACEHOLDER", fg_color) + svg_bytes = svg_text.encode("utf-8") + loader = GdkPixbuf.PixbufLoader.new_with_type("svg") + loader.set_size(AVATAR_SIZE, AVATAR_SIZE) + loader.write(svg_bytes) + loader.close() + pixbuf = loader.get_pixbuf() + if pixbuf: + self._default_avatar_pixbuf = pixbuf + self._avatar_image.set_from_pixbuf(pixbuf) + except (GLib.Error, OSError): + self._avatar_image.set_from_icon_name("avatar-default-symbolic") + + def _set_avatar_from_file(self, path: Path, username: str | None = None) -> None: + """Load an image file and set it as the avatar, scaled to AVATAR_SIZE.""" + try: + pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_scale( + str(path), AVATAR_SIZE, AVATAR_SIZE, True + ) + if username: + self._avatar_cache[username] = pixbuf + self._avatar_image.set_from_pixbuf(pixbuf) + except GLib.Error: + self._avatar_image.set_from_icon_name("avatar-default-symbolic") + + def _setup_keyboard_navigation(self) -> None: + """Set up keyboard shortcuts.""" + controller = Gtk.EventControllerKey() + controller.connect("key-pressed", self._on_key_pressed) + self.add_controller(controller) + + def _on_key_pressed( + self, + controller: Gtk.EventControllerKey, + keyval: int, + keycode: int, + state: Gdk.ModifierType, + ) -> bool: + """Handle global key presses.""" + if keyval == Gdk.KEY_Escape: + self._password_entry.set_text("") + self._error_label.set_visible(False) + return True + return False + + def _on_user_clicked(self, button: Gtk.Button, user: User) -> None: + """Handle user selection from the user list.""" + self._cancel_pending_session() + self._switch_to_user(user) + + def _on_login_activate(self, entry: Gtk.PasswordEntry) -> None: + """Handle Enter key in the password field — attempt login.""" + if not self._selected_user: + return + + password = entry.get_text() + session = self._get_selected_session() + if not session: + self._show_error(self._strings.no_session_selected) + return + + self._attempt_login(self._selected_user, password, session) + + def _validate_greetd_sock(self, sock_path: str) -> bool: + """Validate that GREETD_SOCK points to an absolute path and a real socket.""" + path = Path(sock_path) + if not path.is_absolute(): + self._show_error(self._strings.greetd_sock_not_absolute) + return False + try: + mode = path.stat().st_mode + if not stat.S_ISSOCK(mode): + self._show_error(self._strings.greetd_sock_not_socket) + return False + except OSError: + self._show_error(self._strings.greetd_sock_unreachable) + return False + return True + + def _close_greetd_sock(self) -> None: + """Close the greetd socket and reset the reference.""" + with self._greetd_sock_lock: + if self._greetd_sock: + try: + self._greetd_sock.close() + except OSError: + pass + self._greetd_sock = None + + def _set_login_sensitive(self, sensitive: bool) -> None: + """Enable or disable login controls during authentication.""" + self._password_entry.set_sensitive(sensitive) + self._session_dropdown.set_sensitive(sensitive) + + def _attempt_login(self, user: User, password: str, session: Session) -> None: + """Attempt to authenticate and start a session via greetd IPC.""" + sock_path = os.environ.get("GREETD_SOCK") + if not sock_path: + self._show_error(self._strings.greetd_sock_not_set) + return + + if not self._validate_greetd_sock(sock_path): + return + + # Disable UI while authenticating — the IPC runs in a background thread + self._set_login_sensitive(False) + thread = threading.Thread( + target=self._login_worker, + args=(user, password, session, sock_path), + daemon=True, + ) + thread.start() + + def _login_worker(self, user: User, password: str, session: Session, sock_path: str) -> None: + """Run greetd IPC in a background thread to avoid blocking the GTK main loop.""" + try: + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.settimeout(10.0) + sock.connect(sock_path) + with self._greetd_sock_lock: + self._greetd_sock = sock + + # Step 1: Create session + response = create_session(sock, user.username) + + if response.get("type") == "error": + GLib.idle_add(self._on_login_error, response, self._strings.auth_failed) + return + + # Step 2: Send password if auth message received + if response.get("type") == "auth_message": + response = post_auth_response(sock, password) + + if response.get("type") == "error": + self._failed_attempts[user.username] = self._failed_attempts.get(user.username, 0) + 1 + warning = faillock_warning(self._failed_attempts[user.username], self._strings) + GLib.idle_add(self._on_login_auth_error, response, warning) + return + + if response.get("type") == "auth_message": + # Multi-stage auth (e.g. TOTP) is not supported + cancel_session(sock) + GLib.idle_add(self._on_login_error, None, self._strings.multi_stage_unsupported) + return + + # Step 3: Start session + if response.get("type") == "success": + cmd = shlex.split(session.exec_cmd) + if not cmd or not shutil.which(cmd[0]): + cancel_session(sock) + GLib.idle_add(self._on_login_error, None, self._strings.invalid_session_command) + return + response = start_session(sock, cmd) + + if response.get("type") == "success": + self._save_last_user(user.username) + self._close_greetd_sock() + GLib.idle_add(self.get_application().quit) + return + else: + GLib.idle_add(self._on_login_error, response, self._strings.session_start_failed) + + self._close_greetd_sock() + + except ConnectionError as e: + logger.error("greetd connection error: %s", e) + self._close_greetd_sock() + GLib.idle_add(self._on_login_error, None, self._strings.connection_error) + except (OSError, ValueError) as e: + logger.error("greetd socket error: %s", e) + self._close_greetd_sock() + GLib.idle_add(self._on_login_error, None, self._strings.socket_error) + + def _on_login_error(self, response: dict | None, message: str) -> None: + """Handle login error on the GTK main thread.""" + if response: + self._show_greetd_error(response, message) + else: + self._show_error(message) + self._close_greetd_sock() + self._set_login_sensitive(True) + + def _on_login_auth_error(self, response: dict, warning: str | None) -> None: + """Handle authentication failure with optional faillock warning on the GTK main thread.""" + self._show_greetd_error(response, self._strings.wrong_password) + if warning: + current = self._error_label.get_text() + self._error_label.set_text(f"{current}\n{warning}") + self._close_greetd_sock() + self._set_login_sensitive(True) + + def _cancel_pending_session(self) -> None: + """Cancel any in-progress greetd session.""" + with self._greetd_sock_lock: + if self._greetd_sock: + try: + cancel_session(self._greetd_sock) + except (ConnectionError, OSError): + pass + self._close_greetd_sock() + + def _get_selected_session(self) -> Session | None: + """Get the currently selected session from the dropdown.""" + if not self._sessions: + return None + idx = self._session_dropdown.get_selected() + if idx < len(self._sessions): + return self._sessions[idx] + return None + + MAX_GREETD_ERROR_LENGTH = 200 + + def _show_greetd_error(self, response: dict, fallback: str) -> None: + """Display an error from greetd, using a fallback for missing or oversized descriptions.""" + description = response.get("description", "") + if description and len(description) <= self.MAX_GREETD_ERROR_LENGTH: + self._show_error(description) + else: + self._show_error(fallback) + + def _show_error(self, message: str) -> None: + """Display an error message below the password field.""" + self._error_label.set_text(message) + self._error_label.set_visible(True) + self._password_entry.set_text("") + self._password_entry.grab_focus() + + def _on_reboot_clicked(self, button: Gtk.Button) -> None: + """Handle reboot button click.""" + try: + reboot() + except subprocess.CalledProcessError: + self._show_error(self._strings.reboot_failed) + + def _on_shutdown_clicked(self, button: Gtk.Button) -> None: + """Handle shutdown button click.""" + try: + shutdown() + except subprocess.CalledProcessError: + self._show_error(self._strings.shutdown_failed) + + @staticmethod + def _load_last_user() -> str | None: + """Load the last logged-in username from cache.""" + if LAST_USER_PATH.exists(): + try: + username = LAST_USER_PATH.read_text().strip() + except OSError: + return None + if len(username) > MAX_USERNAME_LENGTH or not VALID_USERNAME.match(username): + return None + return username + return None + + @staticmethod + def _save_last_user(username: str) -> None: + """Save the last logged-in username to cache.""" + try: + LAST_USER_PATH.parent.mkdir(parents=True, exist_ok=True) + LAST_USER_PATH.write_text(username) + except OSError: + pass # Non-critical — cache dir may not be writable diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/i18n.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/i18n.py new file mode 100644 index 0000000..f445a92 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/i18n.py @@ -0,0 +1,117 @@ +# ABOUTME: Locale detection and string lookup for the greeter UI. +# ABOUTME: Reads system locale (LANG or /etc/locale.conf) and provides DE or EN strings. + +import os +from dataclasses import dataclass +from pathlib import Path + +DEFAULT_LOCALE_CONF = Path("/etc/locale.conf") + + +@dataclass(frozen=True) +class Strings: + """All user-visible strings for the greeter UI.""" + + # UI labels + password_placeholder: str + reboot_tooltip: str + shutdown_tooltip: str + + # Error messages + no_session_selected: str + greetd_sock_not_set: str + greetd_sock_not_absolute: str + greetd_sock_not_socket: str + greetd_sock_unreachable: str + auth_failed: str + wrong_password: str + multi_stage_unsupported: str + invalid_session_command: str + session_start_failed: str + reboot_failed: str + shutdown_failed: str + + # Error messages (continued) + connection_error: str + socket_error: str + + # Templates (use .format()) + faillock_attempts_remaining: str + faillock_locked: str + + +_STRINGS_DE = Strings( + password_placeholder="Passwort", + reboot_tooltip="Neustart", + shutdown_tooltip="Herunterfahren", + no_session_selected="Keine Session ausgewählt", + greetd_sock_not_set="GREETD_SOCK nicht gesetzt", + greetd_sock_not_absolute="GREETD_SOCK ist kein absoluter Pfad", + greetd_sock_not_socket="GREETD_SOCK zeigt nicht auf einen Socket", + greetd_sock_unreachable="GREETD_SOCK nicht erreichbar", + auth_failed="Authentifizierung fehlgeschlagen", + wrong_password="Falsches Passwort", + multi_stage_unsupported="Mehrstufige Authentifizierung wird nicht unterstützt", + invalid_session_command="Ungültiger Session-Befehl", + session_start_failed="Session konnte nicht gestartet werden", + reboot_failed="Neustart fehlgeschlagen", + shutdown_failed="Herunterfahren fehlgeschlagen", + connection_error="Verbindungsfehler", + socket_error="Socket-Fehler", + faillock_attempts_remaining="Noch {n} Versuch(e) vor Kontosperrung!", + faillock_locked="Konto ist möglicherweise gesperrt", +) + +_STRINGS_EN = Strings( + password_placeholder="Password", + reboot_tooltip="Reboot", + shutdown_tooltip="Shut down", + no_session_selected="No session selected", + greetd_sock_not_set="GREETD_SOCK not set", + greetd_sock_not_absolute="GREETD_SOCK is not an absolute path", + greetd_sock_not_socket="GREETD_SOCK does not point to a socket", + greetd_sock_unreachable="GREETD_SOCK unreachable", + auth_failed="Authentication failed", + wrong_password="Wrong password", + multi_stage_unsupported="Multi-stage authentication is not supported", + invalid_session_command="Invalid session command", + session_start_failed="Failed to start session", + reboot_failed="Reboot failed", + shutdown_failed="Shutdown failed", + connection_error="Connection error", + socket_error="Socket error", + faillock_attempts_remaining="{n} attempt(s) remaining before lockout!", + faillock_locked="Account may be locked", +) + +_LOCALE_MAP: dict[str, Strings] = { + "de": _STRINGS_DE, + "en": _STRINGS_EN, +} + + +def detect_locale(locale_conf_path: Path = DEFAULT_LOCALE_CONF) -> str: + """Determine the system language from LANG env var or /etc/locale.conf.""" + lang = os.environ.get("LANG") + + if not lang and locale_conf_path.exists(): + for line in locale_conf_path.read_text().splitlines(): + if line.startswith("LANG="): + lang = line.split("=", 1)[1].strip() + break + + if not lang or lang in ("C", "POSIX"): + return "en" + + # Extract language prefix: "de_DE.UTF-8" → "de" + lang = lang.split("_")[0].split(".")[0].lower() + if not lang.isalpha(): + return "en" + return lang + + +def load_strings(locale: str | None = None) -> Strings: + """Return the string table for the given locale, defaulting to English.""" + if locale is None: + locale = detect_locale() + return _LOCALE_MAP.get(locale, _STRINGS_EN) diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/ipc.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/ipc.py new file mode 100644 index 0000000..562b977 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/ipc.py @@ -0,0 +1,62 @@ +# ABOUTME: greetd IPC protocol implementation — communicates via Unix socket. +# ABOUTME: Uses length-prefixed JSON encoding as specified by the greetd IPC protocol. + +import json +import struct +from typing import Any + +MAX_PAYLOAD_SIZE = 65536 + + +def _recvall(sock: Any, n: int) -> bytes: + """Receive exactly n bytes from socket, looping on partial reads.""" + buf = bytearray() + while len(buf) < n: + chunk = sock.recv(n - len(buf)) + if not chunk: + raise ConnectionError("Connection closed while reading data") + buf.extend(chunk) + return bytes(buf) + + +def send_message(sock: Any, msg: dict) -> None: + """Send a length-prefixed JSON message to the greetd socket.""" + payload = json.dumps(msg).encode("utf-8") + header = struct.pack("!I", len(payload)) + sock.sendall(header + payload) + + +def recv_message(sock: Any) -> dict: + """Receive a length-prefixed JSON message from the greetd socket.""" + header = _recvall(sock, 4) + length = struct.unpack("!I", header)[0] + + if length > MAX_PAYLOAD_SIZE: + raise ConnectionError(f"Payload too large: {length} bytes (max {MAX_PAYLOAD_SIZE})") + + payload = _recvall(sock, length) + return json.loads(payload.decode("utf-8")) + + +def create_session(sock: Any, username: str) -> dict: + """Send a create_session request to greetd and return the response.""" + send_message(sock, {"type": "create_session", "username": username}) + return recv_message(sock) + + +def post_auth_response(sock: Any, response: str | None) -> dict: + """Send an authentication response (e.g. password) to greetd.""" + send_message(sock, {"type": "post_auth_message_response", "response": response}) + return recv_message(sock) + + +def start_session(sock: Any, cmd: list[str]) -> dict: + """Send a start_session request to launch the user's session.""" + send_message(sock, {"type": "start_session", "cmd": cmd}) + return recv_message(sock) + + +def cancel_session(sock: Any) -> dict: + """Cancel the current authentication session.""" + send_message(sock, {"type": "cancel_session"}) + return recv_message(sock) diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/main.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/main.py new file mode 100644 index 0000000..ecca7fe --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/main.py @@ -0,0 +1,126 @@ +# ABOUTME: Entry point for Moongreet — sets up GTK Application and Layer Shell. +# ABOUTME: Handles multi-monitor setup: login UI on primary, wallpaper on secondary monitors. + +import logging +import sys +from importlib.resources import files + +import gi +gi.require_version("Gtk", "4.0") +gi.require_version("Gdk", "4.0") +from gi.repository import Gtk, Gdk + +from moongreet.config import load_config, resolve_wallpaper_path +from moongreet.greeter import GreeterWindow, WallpaperWindow + +# gtk4-layer-shell is optional for development/testing +try: + gi.require_version("Gtk4LayerShell", "1.0") + from gi.repository import Gtk4LayerShell + HAS_LAYER_SHELL = True +except (ValueError, ImportError): + HAS_LAYER_SHELL = False + +logger = logging.getLogger(__name__) + + +class MoongreetApp(Gtk.Application): + """GTK Application for the Moongreet greeter.""" + + def __init__(self) -> None: + super().__init__(application_id="dev.moonarch.moongreet") + self._wallpaper_ctx = None + self._secondary_windows: list[WallpaperWindow] = [] + + def do_activate(self) -> None: + """Create and present greeter windows on all monitors.""" + self._register_icons() + self._load_css() + + # Resolve wallpaper once, share across all windows + config = load_config() + bg_path, self._wallpaper_ctx = resolve_wallpaper_path(config) + + display = Gdk.Display.get_default() + monitors = display.get_monitors() + primary_monitor = None + + # Find primary monitor — fall back to first available + for i in range(monitors.get_n_items()): + monitor = monitors.get_item(i) + if hasattr(monitor, 'is_primary') and monitor.is_primary(): + primary_monitor = monitor + break + if primary_monitor is None and monitors.get_n_items() > 0: + primary_monitor = monitors.get_item(0) + + # Main greeter window (login UI) on primary monitor + greeter = GreeterWindow(bg_path=bg_path, application=self) + if HAS_LAYER_SHELL: + self._setup_layer_shell(greeter, keyboard=True) + if primary_monitor is not None: + Gtk4LayerShell.set_monitor(greeter, primary_monitor) + greeter.present() + + # Wallpaper-only windows on secondary monitors + for i in range(monitors.get_n_items()): + monitor = monitors.get_item(i) + if monitor == primary_monitor: + continue + wallpaper_win = WallpaperWindow(bg_path=bg_path, application=self) + if HAS_LAYER_SHELL: + self._setup_layer_shell(wallpaper_win, keyboard=False) + Gtk4LayerShell.set_monitor(wallpaper_win, monitor) + wallpaper_win.present() + self._secondary_windows.append(wallpaper_win) + + def do_shutdown(self) -> None: + """Clean up wallpaper context manager on exit.""" + if self._wallpaper_ctx is not None: + self._wallpaper_ctx.__exit__(None, None, None) + self._wallpaper_ctx = None + Gtk.Application.do_shutdown(self) + + def _register_icons(self) -> None: + """Register custom icons from the package data/icons directory.""" + icons_dir = files("moongreet") / "data" / "icons" + icon_theme = Gtk.IconTheme.get_for_display(Gdk.Display.get_default()) + icon_theme.add_search_path(str(icons_dir)) + + def _load_css(self) -> None: + """Load the CSS stylesheet for the greeter.""" + css_provider = Gtk.CssProvider() + css_path = files("moongreet") / "style.css" + css_provider.load_from_path(str(css_path)) + Gtk.StyleContext.add_provider_for_display( + Gdk.Display.get_default(), + css_provider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION, + ) + + def _setup_layer_shell(self, window: Gtk.Window, keyboard: bool = False) -> None: + """Configure gtk4-layer-shell for fullscreen display.""" + Gtk4LayerShell.init_for_window(window) + Gtk4LayerShell.set_layer(window, Gtk4LayerShell.Layer.TOP) + if keyboard: + Gtk4LayerShell.set_keyboard_mode( + window, Gtk4LayerShell.KeyboardMode.EXCLUSIVE + ) + # Anchor to all edges for fullscreen + for edge in [ + Gtk4LayerShell.Edge.TOP, + Gtk4LayerShell.Edge.BOTTOM, + Gtk4LayerShell.Edge.LEFT, + Gtk4LayerShell.Edge.RIGHT, + ]: + Gtk4LayerShell.set_anchor(window, edge, True) + + +def main() -> None: + """Run the Moongreet application.""" + app = MoongreetApp() + app.run(sys.argv) + + +if __name__ == "__main__": + main() diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/power.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/power.py new file mode 100644 index 0000000..6d6b3c2 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/power.py @@ -0,0 +1,17 @@ +# ABOUTME: Power actions — reboot and shutdown via loginctl. +# ABOUTME: Simple wrappers around system commands for the greeter UI. + +import subprocess + + +POWER_TIMEOUT = 30 + + +def reboot() -> None: + """Reboot the system via loginctl.""" + subprocess.run(["loginctl", "reboot"], check=True, timeout=POWER_TIMEOUT) + + +def shutdown() -> None: + """Shut down the system via loginctl.""" + subprocess.run(["loginctl", "poweroff"], check=True, timeout=POWER_TIMEOUT) diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/sessions.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/sessions.py new file mode 100644 index 0000000..fca1dad --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/sessions.py @@ -0,0 +1,63 @@ +# ABOUTME: Session detection — discovers available Wayland and X11 sessions. +# ABOUTME: Parses .desktop files from standard session directories. + +import configparser +from collections.abc import Sequence +from dataclasses import dataclass +from pathlib import Path + +DEFAULT_WAYLAND_DIRS = (Path("/usr/share/wayland-sessions"),) +DEFAULT_XSESSION_DIRS = (Path("/usr/share/xsessions"),) + + +@dataclass +class Session: + """Represents an available login session.""" + + name: str + exec_cmd: str + session_type: str # "wayland" or "x11" + + +def _parse_desktop_file(path: Path, session_type: str) -> Session | None: + """Parse a .desktop file and return a Session, or None if invalid.""" + config = configparser.ConfigParser(interpolation=None) + config.read(path) + + section = "Desktop Entry" + if not config.has_section(section): + return None + + name = config.get(section, "Name", fallback=None) + exec_cmd = config.get(section, "Exec", fallback=None) + + if not name or not exec_cmd: + return None + + return Session(name=name, exec_cmd=exec_cmd, session_type=session_type) + + +def get_sessions( + wayland_dirs: Sequence[Path] = DEFAULT_WAYLAND_DIRS, + xsession_dirs: Sequence[Path] = DEFAULT_XSESSION_DIRS, +) -> list[Session]: + """Discover available sessions from .desktop files.""" + sessions: list[Session] = [] + + for directory in wayland_dirs: + if not directory.exists(): + continue + for desktop_file in sorted(directory.glob("*.desktop")): + session = _parse_desktop_file(desktop_file, "wayland") + if session: + sessions.append(session) + + for directory in xsession_dirs: + if not directory.exists(): + continue + for desktop_file in sorted(directory.glob("*.desktop")): + session = _parse_desktop_file(desktop_file, "x11") + if session: + sessions.append(session) + + return sessions diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/style.css b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/style.css new file mode 100644 index 0000000..6daca30 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/style.css @@ -0,0 +1,87 @@ +/* ABOUTME: GTK4 CSS stylesheet for the Moongreet greeter. */ +/* ABOUTME: Defines styling for the login screen layout. */ + +/* Main window background */ +window.greeter { + background-color: #1a1a2e; + background-size: cover; + background-position: center; +} + +/* Central login area */ +.login-box { + padding: 40px; + border-radius: 12px; + background-color: alpha(@theme_bg_color, 0.7); +} + +/* Round avatar image — size is set via set_size_request() in code */ +.avatar { + border-radius: 50%; + min-width: 128px; + min-height: 128px; + background-color: @theme_selected_bg_color; + border: 3px solid alpha(white, 0.3); +} + +/* Username label */ +.username-label { + font-size: 24px; + font-weight: bold; + color: white; + margin-top: 12px; + margin-bottom: 40px; +} + +/* Session dropdown */ +.session-dropdown { + min-width: 280px; +} + +/* Password entry field */ +.password-entry { + min-width: 280px; +} + +/* Error message label */ +.error-label { + color: #ff6b6b; + font-size: 14px; +} + +/* User list on the bottom left */ +.user-list { + background-color: transparent; + padding: 8px; +} + +.user-list-item { + padding: 8px 16px; + border-radius: 8px; + color: white; + font-size: 14px; +} + +.user-list-item:hover { + background-color: alpha(white, 0.15); +} + +.user-list-item:selected { + background-color: alpha(white, 0.2); +} + +/* Power buttons on the bottom right */ +.power-button { + min-width: 48px; + min-height: 48px; + padding: 0px; + border-radius: 24px; + background-color: alpha(white, 0.1); + color: white; + border: none; + margin: 4px; +} + +.power-button:hover { + background-color: alpha(white, 0.25); +} diff --git a/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/users.py b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/users.py new file mode 100644 index 0000000..cf1f508 --- /dev/null +++ b/pkg/pkg/moongreet/usr/lib/python3.14/site-packages/moongreet/users.py @@ -0,0 +1,113 @@ +# ABOUTME: User detection — parses /etc/passwd for login users, finds avatars and GTK themes. +# ABOUTME: Provides User dataclass and helper functions for the greeter UI. + +import configparser +import re +from dataclasses import dataclass +from pathlib import Path + +VALID_THEME_NAME = re.compile(r"^[A-Za-z0-9_-]+$") + +NOLOGIN_SHELLS = {"/usr/sbin/nologin", "/sbin/nologin", "/bin/false", "/usr/bin/nologin"} +MIN_UID = 1000 +MAX_UID = 65533 + +DEFAULT_PASSWD = Path("/etc/passwd") +DEFAULT_ACCOUNTSSERVICE_DIR = Path("/var/lib/AccountsService/icons") + + +@dataclass +class User: + """Represents a system user suitable for login.""" + + username: str + uid: int + gecos: str + home: Path + shell: str + + @property + def display_name(self) -> str: + """Return gecos if available, otherwise username.""" + return self.gecos if self.gecos else self.username + + +def get_users(passwd_path: Path = DEFAULT_PASSWD) -> list[User]: + """Parse /etc/passwd and return users with UID in the login range.""" + users: list[User] = [] + + if not passwd_path.exists(): + return users + + for line in passwd_path.read_text().splitlines(): + parts = line.split(":") + if len(parts) < 7: + continue + + username, _, uid_str, _, gecos, home, shell = parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6] + + try: + uid = int(uid_str) + except ValueError: + continue + + if uid < MIN_UID or uid > MAX_UID: + continue + if shell in NOLOGIN_SHELLS: + continue + if "/" in username or username.startswith("."): + continue + + users.append(User( + username=username, + uid=uid, + gecos=gecos, + home=Path(home), + shell=shell, + )) + + return users + + +def get_avatar_path( + username: str, + accountsservice_dir: Path = DEFAULT_ACCOUNTSSERVICE_DIR, + home_dir: Path | None = None, +) -> Path | None: + """Find avatar for a user: AccountsService icon → ~/.face → None.""" + # AccountsService icon + icon = accountsservice_dir / username + if icon.exists() and not icon.is_symlink(): + return icon + + # ~/.face fallback + if home_dir is not None: + face = home_dir / ".face" + if face.exists() and not face.is_symlink(): + return face + + return None + + +def get_user_gtk_theme(config_dir: Path | None = None) -> str | None: + """Read the GTK theme name from a user's gtk-4.0/settings.ini.""" + if config_dir is None: + return None + + settings_file = config_dir / "settings.ini" + if not settings_file.exists(): + return None + + config = configparser.ConfigParser(interpolation=None) + try: + config.read(settings_file) + except configparser.Error: + return None + + if config.has_option("Settings", "gtk-theme-name"): + theme = config.get("Settings", "gtk-theme-name") + # Validate against path traversal — only allow safe theme names + if theme and VALID_THEME_NAME.match(theme): + return theme + + return None diff --git a/pkg/src/greetd-moongreet b/pkg/src/greetd-moongreet new file mode 160000 index 0000000..99c016a --- /dev/null +++ b/pkg/src/greetd-moongreet @@ -0,0 +1 @@ +Subproject commit 99c016adbc27e6455463b47fc6e6b3d2eb157def