summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/greetd-mini-wl-greeter.1.scd7
-rw-r--r--src/entry.c118
-rw-r--r--src/entry.h6
-rw-r--r--src/main.c3
4 files changed, 92 insertions, 42 deletions
diff --git a/doc/greetd-mini-wl-greeter.1.scd b/doc/greetd-mini-wl-greeter.1.scd
index 7beab36..988c2db 100644
--- a/doc/greetd-mini-wl-greeter.1.scd
+++ b/doc/greetd-mini-wl-greeter.1.scd
@@ -6,7 +6,7 @@ greetd-mini-wl-greeter - An extremely simple raw Wayland greeter for greetd
# SYNOPSIS
-*greetd-mini-wl-greeter* -u user -c command [options]
+*greetd-mini-wl-greeter* -u user -c command [-bBCeEfFhHnoOrRw]
# DESCRIPTION
@@ -73,6 +73,11 @@ All options which take a color expect a 3- or 6-digit hex code, e.g. F9A733.
# 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:
diff --git a/src/entry.c b/src/entry.c
index fe2953c..95ab308 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -9,12 +9,34 @@
#include "log.h"
#include "nelem.h"
+#ifndef TWO_PI
+#define TWO_PI 6.283185307179586f
+#endif
+
static void calculate_font_extents(struct entry *entry, uint32_t scale);
+static void draw_circles(struct entry *entry);
void entry_init(struct entry *entry, uint32_t scale)
{
+ entry->dot_radius = entry->font_size >> 3;
+ /* Calculate the size of the entry from our font and various widths. */
calculate_font_extents(entry, scale);
- struct color color;
+
+ entry->surface.width = entry->text_bounds.width;
+ entry->surface.height = entry->text_bounds.height;
+ entry->surface.width += 2 * (
+ entry->border.width
+ + 2 * entry->border.outline_width
+ + entry->padding
+ );
+ entry->surface.height += 2 * (
+ entry->border.width
+ + 2 * entry->border.outline_width
+ + entry->padding
+ );
+ entry->surface.width *= scale;
+ entry->surface.height *= scale;
+
/*
* Cairo uses native 32 bit integers for pixels, so if this processor
@@ -40,7 +62,7 @@ void entry_init(struct entry *entry, uint32_t scale)
int32_t height = entry->surface.height / scale;
/* Draw the outer outline */
- color = entry->border.outline_color;
+ struct color color = entry->border.outline_color;
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
cairo_paint(cr);
@@ -100,22 +122,25 @@ void entry_init(struct entry *entry, uint32_t scale)
cairo_translate(cr, -entry->text_bounds.x, -entry->text_bounds.y);
/* Setup Pango. */
- PangoContext *context = pango_cairo_create_context(cr);
- PangoLayout *layout = pango_layout_new(context);
- pango_layout_set_text(layout, "", -1);
+ if (entry->use_pango) {
+ PangoContext *context = pango_cairo_create_context(cr);
+ PangoLayout *layout = pango_layout_new(context);
+ pango_layout_set_text(layout, "", -1);
- PangoFontDescription *font_description =
- pango_font_description_from_string(entry->font_name);
- pango_font_description_set_size(
- font_description,
- entry->font_size * PANGO_SCALE);
- pango_layout_set_font_description(layout, font_description);
- pango_font_description_free(font_description);
+ PangoFontDescription *font_description =
+ pango_font_description_from_string(entry->font_name);
+ pango_font_description_set_size(
+ font_description,
+ entry->font_size * PANGO_SCALE);
+ pango_layout_set_font_description(layout, font_description);
+ pango_font_description_free(font_description);
+
+ entry->pango.context = context;
+ entry->pango.layout = layout;
+ }
+ entry->cairo.surface = surface;
+ entry->cairo.cr = cr;
- entry->pangocairo.surface = surface;
- entry->pangocairo.cr = cr;
- entry->pangocairo.context = context;
- entry->pangocairo.layout = layout;
entry->image.width = entry->surface.width;
entry->image.height = entry->surface.height;
entry->image.buffer = cairo_image_surface_get_data(surface);
@@ -123,25 +148,34 @@ void entry_init(struct entry *entry, uint32_t scale)
void entry_destroy(struct entry *entry)
{
- g_object_unref(entry->pangocairo.layout);
- g_object_unref(entry->pangocairo.context);
- cairo_destroy(entry->pangocairo.cr);
- cairo_surface_destroy(entry->pangocairo.surface);
+ if (entry->use_pango) {
+ g_object_unref(entry->pango.layout);
+ g_object_unref(entry->pango.context);
+ }
+ cairo_destroy(entry->cairo.cr);
+ cairo_surface_destroy(entry->cairo.surface);
}
void entry_update(struct entry *entry)
{
- cairo_t *cr = entry->pangocairo.cr;
- PangoLayout *layout = entry->pangocairo.layout;
+ cairo_t *cr = entry->cairo.cr;
+ PangoLayout *layout = entry->pango.layout;
+
+ entry->image.redraw = true;
/* Redraw the background. */
struct color color = entry->background_color;
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
cairo_paint(cr);
- /* Draw our text with Pango. */
+ /* Draw our text. */
color = entry->foreground_color;
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
+
+ if (!entry->use_pango) {
+ draw_circles(entry);
+ return;
+ }
size_t len = 0;
for (unsigned int i = 0; i < entry->password_length; i++) {
len += wcrtomb(entry->password_mb_print + len, entry->password_character, NULL);
@@ -150,17 +184,21 @@ void entry_update(struct entry *entry)
pango_layout_set_text(layout, entry->password_mb_print, -1);
pango_cairo_update_layout(cr, layout);
pango_cairo_show_layout(cr, layout);
-
- entry->image.redraw = true;
}
void entry_set_scale(struct entry *entry, uint32_t scale)
{
- cairo_surface_set_device_scale(entry->pangocairo.surface, scale, scale);
+ cairo_surface_set_device_scale(entry->cairo.surface, scale, scale);
}
void calculate_font_extents(struct entry *entry, uint32_t scale)
{
+ if (!entry->use_pango) {
+ /* If we're not using pango, just do a simple calculation. */
+ entry->text_bounds.height = 2 * entry->dot_radius;
+ entry->text_bounds.width = 3 * entry->num_characters * entry->dot_radius;
+ return;
+ }
/*
* To calculate the size of the password box, we do the following:
* 1. Load the font we're going to use.
@@ -219,22 +257,22 @@ void calculate_font_extents(struct entry *entry, uint32_t scale)
rect.x -= 1;
rect.y -= 1;
- int width = rect.width;
- int height = rect.height;
- width += 2 * (
- entry->border.width
- + 2 * entry->border.outline_width
- + entry->padding
- );
- height += 2 * (
- entry->border.width
- + 2 * entry->border.outline_width
- + entry->padding
- );
- entry->surface.width = width * scale;
- entry->surface.height = height * scale;
entry->text_bounds = rect;
g_object_unref(layout);
g_object_unref(context);
}
+
+void draw_circles(struct entry *entry)
+{
+ cairo_t *cr = entry->cairo.cr;
+ uint32_t radius = entry->dot_radius;
+ cairo_save(cr);
+ cairo_translate(cr, radius, radius);
+ for (uint32_t i = 0; i < entry->password_length && i < entry->num_characters; i++) {
+ /* Draw circles with a one-radius gap between them. */
+ cairo_arc(cr, 3 * i * radius, 0, radius, 0, TWO_PI);
+ }
+ cairo_fill(cr);
+ cairo_restore(cr);
+}
diff --git a/src/entry.h b/src/entry.h
index 05c459b..b0e9542 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -15,9 +15,11 @@ struct entry {
struct {
PangoContext *context;
PangoLayout *layout;
+ } pango;
+ struct {
cairo_surface_t *surface;
cairo_t *cr;
- } pangocairo;
+ } cairo;
PangoRectangle text_bounds;
wchar_t password[MAX_PASSWORD_LENGTH];
@@ -28,6 +30,8 @@ struct entry {
bool password_visible;
/* Options */
+ bool use_pango;
+ uint32_t dot_radius;
uint32_t font_size;
const char *font_name;
uint32_t padding;
diff --git a/src/main.c b/src/main.c
index 64e5975..4f20bd7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -701,6 +701,7 @@ int main(int argc, char *argv[])
break;
case 'f':
state.window.entry.font_name = optarg;
+ state.window.entry.use_pango = true;
break;
case 'F':
state.window.entry.font_size =
@@ -712,6 +713,7 @@ int main(int argc, char *argv[])
optarg,
4,
NULL);
+ state.window.entry.use_pango = true;
break;
case 'c':
state.command = optarg;
@@ -725,6 +727,7 @@ int main(int argc, char *argv[])
break;
case 'w':
state.window.entry.tight_layout = false;
+ state.window.entry.use_pango = true;
break;
case 'H':
state.hide_cursor = true;