From ae23e86114f559ce6d01a3e2499fc5417dc90d37 Mon Sep 17 00:00:00 2001 From: Phil Jones Date: Sat, 6 Nov 2021 18:44:27 +0000 Subject: Start conversion to tofi. --- README.md | 47 +--------------- completions/greetd-mini-wl-greeter | 55 ------------------- completions/tofi | 55 +++++++++++++++++++ doc/greetd-mini-wl-greeter.1.scd | 109 ------------------------------------- doc/tofi.1.scd | 109 +++++++++++++++++++++++++++++++++++++ meson.build | 14 +++-- shaders/frag.frag | 2 +- shaders/vert.vert | 2 + src/compgen.c | 50 +++++++++++++++++ src/compgen.h | 8 +++ src/main.c | 2 + src/string_vec.c | 84 ++++++++++++++++++++++++++++ src/string_vec.h | 28 ++++++++++ 13 files changed, 350 insertions(+), 215 deletions(-) delete mode 100644 completions/greetd-mini-wl-greeter create mode 100644 completions/tofi delete mode 100644 doc/greetd-mini-wl-greeter.1.scd create mode 100644 doc/tofi.1.scd create mode 100644 src/compgen.c create mode 100644 src/compgen.h create mode 100644 src/string_vec.c create mode 100644 src/string_vec.h diff --git a/README.md b/README.md index a48953f..a2d239c 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,5 @@ -# greetd-mini-wl-greeter +# tofi -An extremely simple raw Wayland greeter for -[greetd](https://sr.ht/~kennylevinsen/greetd/), inspired by -[lightdm-mini-greeter](https://github.com/prikhi/lightdm-mini-greeter). +An extremely simple dmenu/rofi replacement for Wayland. -![Screenshot](screenshot.png) - -The aim is to do just what I want it to as quick as possible. On a 2015 Macbook -Pro, with no background image or font options, startup takes ~35ms. On a -Raspberry Pi Zero 2, it takes ~500ms, mostly waiting for EGL / OpenGL to -initialise. - -## Usage - -Follow the same steps as for e.g. gtkgreet in the [greetd -wiki](https://man.sr.ht/~kennylevinsen/greetd/). See the man page for -configuration options. All colors and sizes can be customised, and a PNG -background image can be displayed scaled and centered. - -## Install - -### Arch - -greetd-mini-wl-greeter is available on the -[AUR](https://aur.archlinux.org/packages/greetd-mini-wl-greeter-git/): -```sh -paru -S greetd-mini-wl-greeter-git -``` - -### Source -```sh -meson build -ninja -C build -``` - -## Tips - -It's quite entertaining to set the password character to one from the -[combining diacritical -marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) page, e.g. -```sh -greetd-mini-wl-greeter -C ̣ -``` - -![Combining diacritical screenshot](screenshot_vertical.png) +The aim is to do just what I want it to as quick as possible. diff --git a/completions/greetd-mini-wl-greeter b/completions/greetd-mini-wl-greeter deleted file mode 100644 index be5a7b1..0000000 --- a/completions/greetd-mini-wl-greeter +++ /dev/null @@ -1,55 +0,0 @@ -# vi: ft=bash - -containsElement () { - local e match="$1" - shift - for e; do [[ "$e" =~ $match ]] && return 0; done - return 1 -} - -_greetd_mini_wl_greeter() -{ - local cur prev opts remaining - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - opts="--background-image --background-color --border-width --border-color --outline-width --outline-color --entry-padding --entry-color --text-color --font-name --font-size --password-character --command --user --width-characters --wide-layout --hide-cursor --help" - - - case "${prev}" in - --user|-u) - COMPREPLY=( $(compgen -W "${users}" -- ${cur}) ) - return 0 - ;; - --command|-c) - return 0 - ;; - --background-image|-b) - if ! containsElement '.*\.png' "${COMP_WORDS[@]}"; then - _filedir '*@(png)' - fi - return 0 - ;; - --wide-layout|-w) - ;& # Fallthrough - --hide-cursor|-H) - ;& # Fallthrough - --help|-h) - ;; - *) - return 0 - ;; - esac - case "${cur}" in - -[a-zA-Z]) - COMPREPLY=$cur - ;; - *) - remaining=$(echo ${opts[@]} ${COMP_WORDS[@]} ${COMP_WORDS[@]} | tr ' ' '\n' | sort | uniq -u) - COMPREPLY=( $(compgen -W "${remaining}" -- ${cur}) ) - return 0 - ;; - esac - true -} -complete -F _greetd_mini_wl_greeter greetd-mini-wl-greeter diff --git a/completions/tofi b/completions/tofi new file mode 100644 index 0000000..be5a7b1 --- /dev/null +++ b/completions/tofi @@ -0,0 +1,55 @@ +# vi: ft=bash + +containsElement () { + local e match="$1" + shift + for e; do [[ "$e" =~ $match ]] && return 0; done + return 1 +} + +_greetd_mini_wl_greeter() +{ + local cur prev opts remaining + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + opts="--background-image --background-color --border-width --border-color --outline-width --outline-color --entry-padding --entry-color --text-color --font-name --font-size --password-character --command --user --width-characters --wide-layout --hide-cursor --help" + + + case "${prev}" in + --user|-u) + COMPREPLY=( $(compgen -W "${users}" -- ${cur}) ) + return 0 + ;; + --command|-c) + return 0 + ;; + --background-image|-b) + if ! containsElement '.*\.png' "${COMP_WORDS[@]}"; then + _filedir '*@(png)' + fi + return 0 + ;; + --wide-layout|-w) + ;& # Fallthrough + --hide-cursor|-H) + ;& # Fallthrough + --help|-h) + ;; + *) + return 0 + ;; + esac + case "${cur}" in + -[a-zA-Z]) + COMPREPLY=$cur + ;; + *) + remaining=$(echo ${opts[@]} ${COMP_WORDS[@]} ${COMP_WORDS[@]} | tr ' ' '\n' | sort | uniq -u) + COMPREPLY=( $(compgen -W "${remaining}" -- ${cur}) ) + return 0 + ;; + esac + true +} +complete -F _greetd_mini_wl_greeter greetd-mini-wl-greeter diff --git a/doc/greetd-mini-wl-greeter.1.scd b/doc/greetd-mini-wl-greeter.1.scd deleted file mode 100644 index 4e58a56..0000000 --- a/doc/greetd-mini-wl-greeter.1.scd +++ /dev/null @@ -1,109 +0,0 @@ -greetd-mini-wl-greeter(1) - -# NAME - -greetd-mini-wl-greeter - An extremely simple raw Wayland greeter for greetd - -# SYNOPSIS - -*greetd-mini-wl-greeter* -u user -c command [-bBCeEfFhHnoOrRw] - -# DESCRIPTION - -greetd-mini-wl-greeter is a raw Wayland greeter for greetd, designed for a -single user. It requires a Wayland compositor to run, such as *cage*(1) or -*sway*(1). - -# OPTIONS - -All options which take a color expect a 3- or 6-digit hex code, e.g. F9A733. - -*-u, --user* - The user to login as. - -*-c, --command* - The command to run on login. - -*-b, --background-image* - An image to use as the background. Currently only PNG images are supported. - -*-B, --background-color* - Color of the background in the absence of an image. - -*-o, --outline-width* - Width of the outlines around the border, in pixels. - -*-O, --outline-color* - Color of the outlines around the border. - -*-r, --border-width* - Width of the border in pixels. - -*-R, --border-color* - Color of the border. - -*-e, --entry-padding* - Padding around the password text in pixels. - -*-E, --entry-color* - Color of the password entry box. - -*-f, --font-name* - Font to use for the password entry. - -*-F, --font-size* - Point size of the password text. - -*-T, --text-color* - Color of the password text. - -*-C, --password-character* - Character to use to hide the password. Defaults to full-stop. - -*-n, --width-characters* - Make the password entry box big enough to fit this many characters. - -*-w, --wide-layout* - By default, the password entry box will be shrunk vertically to exactly fit - the specified password character. Use this option if you'd rather that it got - laid out like normal text, i.e. the box remains one full character tall. - -*-H, --hide-cursor* - Hide the cursor. - -*-h, --help* - Print help and exit. - -# EXAMPLES - -greetd-mini-wl-greeter aims to be as fast and simple as possible by default. If -none of the *-f*, *-C* or *-w* options are given, a simple circle will be used -for the password character, avoiding the need to use Pango, thus lowering -startup time. This is only likely noticeable on very slow machines however. - -When using sway as the compositor for greetd-mini-greeter, something like the -following sway config lines produce a nice look: - -``` -# Remove any window borders -default_border none -hide_edge_borders both - -# Add a background image, to avoid a flicker of default background color -output * background /path/to/image fill - -# Use the same background image for the greeter -exec greetd-mini-wl-greeter -u username -c command -b /path/to/image -``` - -Fun can be had with the *-C* option, as it should support any character from -your locale, which is probably a UTF-8 one. For example, the Unicode "Combining -Dot Below" character ( ̣) produces a nice effect. - -# AUTHORS - -Philip Jones - -# SEE ALSO - -*greetd*(1) diff --git a/doc/tofi.1.scd b/doc/tofi.1.scd new file mode 100644 index 0000000..4e58a56 --- /dev/null +++ b/doc/tofi.1.scd @@ -0,0 +1,109 @@ +greetd-mini-wl-greeter(1) + +# NAME + +greetd-mini-wl-greeter - An extremely simple raw Wayland greeter for greetd + +# SYNOPSIS + +*greetd-mini-wl-greeter* -u user -c command [-bBCeEfFhHnoOrRw] + +# DESCRIPTION + +greetd-mini-wl-greeter is a raw Wayland greeter for greetd, designed for a +single user. It requires a Wayland compositor to run, such as *cage*(1) or +*sway*(1). + +# OPTIONS + +All options which take a color expect a 3- or 6-digit hex code, e.g. F9A733. + +*-u, --user* + The user to login as. + +*-c, --command* + The command to run on login. + +*-b, --background-image* + An image to use as the background. Currently only PNG images are supported. + +*-B, --background-color* + Color of the background in the absence of an image. + +*-o, --outline-width* + Width of the outlines around the border, in pixels. + +*-O, --outline-color* + Color of the outlines around the border. + +*-r, --border-width* + Width of the border in pixels. + +*-R, --border-color* + Color of the border. + +*-e, --entry-padding* + Padding around the password text in pixels. + +*-E, --entry-color* + Color of the password entry box. + +*-f, --font-name* + Font to use for the password entry. + +*-F, --font-size* + Point size of the password text. + +*-T, --text-color* + Color of the password text. + +*-C, --password-character* + Character to use to hide the password. Defaults to full-stop. + +*-n, --width-characters* + Make the password entry box big enough to fit this many characters. + +*-w, --wide-layout* + By default, the password entry box will be shrunk vertically to exactly fit + the specified password character. Use this option if you'd rather that it got + laid out like normal text, i.e. the box remains one full character tall. + +*-H, --hide-cursor* + Hide the cursor. + +*-h, --help* + Print help and exit. + +# EXAMPLES + +greetd-mini-wl-greeter aims to be as fast and simple as possible by default. If +none of the *-f*, *-C* or *-w* options are given, a simple circle will be used +for the password character, avoiding the need to use Pango, thus lowering +startup time. This is only likely noticeable on very slow machines however. + +When using sway as the compositor for greetd-mini-greeter, something like the +following sway config lines produce a nice look: + +``` +# Remove any window borders +default_border none +hide_edge_borders both + +# Add a background image, to avoid a flicker of default background color +output * background /path/to/image fill + +# Use the same background image for the greeter +exec greetd-mini-wl-greeter -u username -c command -b /path/to/image +``` + +Fun can be had with the *-C* option, as it should support any character from +your locale, which is probably a UTF-8 one. For example, the Unicode "Combining +Dot Below" character ( ̣) produces a nice effect. + +# AUTHORS + +Philip Jones + +# SEE ALSO + +*greetd*(1) diff --git a/meson.build b/meson.build index ee860ab..abc3d0e 100644 --- a/meson.build +++ b/meson.build @@ -1,5 +1,5 @@ project( - 'greetd-mini-wl-greeter', + 'tofi', 'c', license: 'MIT', default_options: [ @@ -22,7 +22,7 @@ endif data_location = join_paths( get_option('prefix'), get_option('datadir'), - 'greetd-mini-wl-greeter' + 'tofi' ) shader_location = join_paths( @@ -44,7 +44,7 @@ install_subdir( ) install_data( - 'completions/greetd-mini-wl-greeter', + 'completions/tofi', install_dir: completion_location ) @@ -63,6 +63,7 @@ add_project_arguments( sources = files( 'src/main.c', 'src/color.c', + 'src/compgen.c', 'src/egl.c', 'src/entry.c', 'src/gl.c', @@ -70,6 +71,7 @@ sources = files( 'src/image.c', 'src/ipc.c', 'src/log.c', + 'src/string_vec.c', 'src/surface.c', ) @@ -115,7 +117,7 @@ foreach proto : wl_proto_xml endforeach executable( - 'greetd-mini-wl-greeter', + 'tofi', sources, wl_proto_src, wl_proto_headers, dependencies: [epoxy, json, glib, pangocairo, png, wayland_egl, xkbcommon], install: true @@ -126,8 +128,8 @@ if scdoc.found() sed = find_program('sed') sh = find_program('sh') mandir = get_option('mandir') - manpage = 'doc/greetd-mini-wl-greeter.1.scd' - output = 'greetd-mini-wl-greeter.1' + manpage = 'doc/tofi.1.scd' + output = 'tofi.1' custom_target( output, input: manpage, diff --git a/shaders/frag.frag b/shaders/frag.frag index 3528c6c..88d2337 100644 --- a/shaders/frag.frag +++ b/shaders/frag.frag @@ -11,7 +11,7 @@ * I don't think you can really copyright this shader though :) */ -precision mediump float; +precision lowp float; varying vec2 Texcoord; diff --git a/shaders/vert.vert b/shaders/vert.vert index 9d3a0eb..3364718 100644 --- a/shaders/vert.vert +++ b/shaders/vert.vert @@ -10,6 +10,8 @@ * */ +precision lowp float; + attribute vec2 position; attribute vec2 texcoord; diff --git a/src/compgen.c b/src/compgen.c new file mode 100644 index 0000000..e04e0a5 --- /dev/null +++ b/src/compgen.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include "log.h" +#include "string_vec.h" + +struct string_vec compgen() +{ + log_debug("Retrieving PATH.\n"); + const char *env_path = getenv("PATH"); + if (env_path == NULL) { + log_error("Couldn't retrieve PATH from environment."); + exit(EXIT_FAILURE); + } + struct string_vec programs = string_vec_create(); + char *path = strdup(env_path); + char *saveptr = NULL; + char *path_entry = strtok_r(path, ":", &saveptr); + log_debug("Scanning PATH for binaries.\n"); + while (path_entry != NULL) { + DIR *dir = opendir(path_entry); + if (dir != NULL) { + int fd = dirfd(dir); + struct dirent *d; + while ((d = readdir(dir)) != NULL) { + struct stat sb; + if (fstatat(fd, d->d_name, &sb, 0) == -1) { + continue; + } + if (!(sb.st_mode & S_IXUSR)) { + continue; + } + if (!S_ISREG(sb.st_mode)) { + continue; + } + string_vec_add(&programs, d->d_name); + } + closedir(dir); + } + path_entry = strtok_r(NULL, ":", &saveptr); + } + free(path); + log_debug("Sorting results.\n"); + string_vec_sort(&programs); + log_debug("Making unique.\n"); + string_vec_uniq(&programs); + log_debug("Done.\n"); + return programs; +} diff --git a/src/compgen.h b/src/compgen.h new file mode 100644 index 0000000..b3b54b5 --- /dev/null +++ b/src/compgen.h @@ -0,0 +1,8 @@ +#ifndef COMPGEN_H +#define COMPGEN_H + +#include "string_vec.h" + +struct string_vec compgen(); + +#endif /* COMPGEN_H */ diff --git a/src/main.c b/src/main.c index 5a3c894..a1c873c 100644 --- a/src/main.c +++ b/src/main.c @@ -16,6 +16,7 @@ #include #include #include "client.h" +#include "compgen.h" #include "egl.h" #include "entry.h" #include "image.h" @@ -23,6 +24,7 @@ #include "greetd.h" #include "log.h" #include "nelem.h" +#include "string_vec.h" #undef MAX #define MAX(a, b) ((a) > (b) ? (a) : (b)) diff --git a/src/string_vec.c b/src/string_vec.c new file mode 100644 index 0000000..94f41fa --- /dev/null +++ b/src/string_vec.c @@ -0,0 +1,84 @@ +#include +#include +#include "string_vec.h" + +static int cmpstringp(const void *a, const void *b) +{ + /* + * We receive pointers to the array elements (which are pointers to + * char), so convert and dereference them for comparison. + */ + const char *str1 = *(const char **)a; + const char *str2 = *(const char **)b; + + /* + * Ensure any NULL strings are shoved to the end. + */ + if (str1 == NULL) { + return 1; + } + if (str2 == NULL) { + return -1; + } + return strcmp(str1, str2); +} + +struct string_vec string_vec_create() +{ + struct string_vec vec = { + .count = 0, + .size = 128, + .buf = calloc(128, sizeof(char *)) + }; + return vec; +} + +void string_vec_destroy(struct string_vec *restrict vec) +{ + for (size_t i = 0; i < vec->count; i++) { + free(vec->buf[i]); + } + free(vec->buf); +} + +void string_vec_add(struct string_vec *restrict vec, const char *restrict str) +{ + if (vec->count == vec->size) { + vec->size *= 2; + vec->buf = realloc(vec->buf, vec->size * sizeof(vec->buf[0])); + } + vec->buf[vec->count] = strdup(str); + vec->count++; +} + +void string_vec_sort(struct string_vec *restrict vec) +{ + qsort(vec->buf, vec->count, sizeof(vec->buf[0]), cmpstringp); +} + +void string_vec_uniq(struct string_vec *restrict vec) +{ + size_t count = vec->count; + for (size_t i = 1; i < vec->count; i++) { + if (!strcmp(vec->buf[i], vec->buf[i-1])) { + free(vec->buf[i-1]); + vec->buf[i-1] = NULL; + count--; + } + } + string_vec_sort(vec); + vec->count = count; +} + +struct string_vec string_vec_filter( + struct string_vec *restrict vec, + const char *restrict substr) +{ + struct string_vec filt = string_vec_create(); + for (size_t i = 0; i < vec->count; i++) { + if (strstr(vec->buf[i], substr) != NULL) { + string_vec_add(&filt, vec->buf[i]); + } + } + return filt; +} diff --git a/src/string_vec.h b/src/string_vec.h new file mode 100644 index 0000000..0054c09 --- /dev/null +++ b/src/string_vec.h @@ -0,0 +1,28 @@ +#ifndef STRING_VEC_H +#define STRING_VEC_H + +#include + +struct string_vec { + size_t count; + size_t size; + char **buf; +}; + +[[nodiscard]] +struct string_vec string_vec_create(); + +void string_vec_destroy(struct string_vec *restrict vec); + +void string_vec_add(struct string_vec *restrict vec, const char *restrict str); + +void string_vec_sort(struct string_vec *restrict vec); + +void string_vec_uniq(struct string_vec *restrict vec); + +[[nodiscard]] [[gnu::nonnull]] +struct string_vec string_vec_filter( + struct string_vec *restrict vec, + const char *restrict substr); + +#endif /* STRING_VEC_H */ -- cgit v1.2.3