summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhil Jones <philj56@gmail.com>2021-11-15 00:08:23 +0000
committerPhil Jones <philj56@gmail.com>2021-11-15 00:08:23 +0000
commit108df42e561b7e81ba09a8c278a562129e651bb6 (patch)
tree496e10b768ea44addfc403fb1634ccc2d7be62b9
parentd65bdf025f9685f3b332aefffe6f8b5c8dbe8827 (diff)
Switch from subsurface setup to just one surface.
The subsurface was playing havoc with layer shell stuff, and I don't think any potential efficiency gain is worth the complicated code to work out how big the subsurface should be. Instead, the entry code now just draws directly onto the main surface. Damage information should be passed to glTexSubImage2D() in future, to avoid redrawing the entire window every keypress.
-rw-r--r--src/entry.c51
-rw-r--r--src/entry.h7
-rw-r--r--src/main.c111
-rw-r--r--src/tofi.h2
4 files changed, 42 insertions, 129 deletions
diff --git a/src/entry.c b/src/entry.c
index d6e6c81..def32b2 100644
--- a/src/entry.c
+++ b/src/entry.c
@@ -8,32 +8,13 @@
#include "log.h"
#include "nelem.h"
-#ifndef TWO_PI
-#define TWO_PI 6.283185307179586f
-#endif
-
-void entry_init(struct entry *entry, uint32_t scale)
+void entry_init(struct entry *entry, uint32_t width, uint32_t height, uint32_t scale)
{
- /* Calculate the size of the entry from our font and various widths. */
- //calculate_font_extents(entry, scale);
- entry->text_bounds.width = 200;
- entry->text_bounds.height = 200;
-
- 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;
+ entry->image.width = width;
+ entry->image.height = height;
+ width /= scale;
+ height /= scale;
/*
* Cairo uses native 32 bit integers for pixels, so if this processor
@@ -48,16 +29,12 @@ void entry_init(struct entry *entry, uint32_t scale)
*/
cairo_surface_t *surface = cairo_image_surface_create(
CAIRO_FORMAT_ARGB32,
- entry->surface.width,
- entry->surface.height
+ width * scale,
+ height * scale
);
cairo_surface_set_device_scale(surface, scale, scale);
cairo_t *cr = cairo_create(surface);
- /* Running size of current drawing area. */
- int32_t width = entry->surface.width / scale;
- int32_t height = entry->surface.height / scale;
-
/* Draw the outer outline */
struct color color = entry->border.outline_color;
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
@@ -112,12 +89,6 @@ void entry_init(struct entry *entry, uint32_t scale)
cairo_rectangle(cr, 0, 0, width, height);
cairo_clip(cr);
- /*
- * Move the cursor back up, so that Pango draws in the correct place if
- * we're doing a tight layout.
- */
- //cairo_translate(cr, -entry->text_bounds.x, -entry->text_bounds.y);
-
/* Setup Pango. */
PangoContext *context = pango_cairo_create_context(cr);
@@ -143,8 +114,6 @@ void entry_init(struct entry *entry, uint32_t scale)
entry->cairo.surface = surface;
entry->cairo.cr = cr;
- entry->image.width = entry->surface.width;
- entry->image.height = entry->surface.height;
entry->image.buffer = cairo_image_surface_get_data(surface);
}
@@ -167,12 +136,12 @@ void entry_update(struct entry *entry)
entry->image.redraw = true;
/* Clear the image. */
- cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
+ struct color color = entry->background_color;
+ cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
cairo_paint(cr);
- cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
/* Draw our text. */
- struct color color = entry->foreground_color;
+ color = entry->foreground_color;
cairo_set_source_rgba(cr, color.r, color.g, color.b, color.a);
pango_layout_set_text(entry->pango.entry_layout, entry->input_mb, -1);
diff --git a/src/entry.h b/src/entry.h
index 0f22cf4..a362ec9 100644
--- a/src/entry.h
+++ b/src/entry.h
@@ -7,11 +7,9 @@
#include "surface.h"
#include "string_vec.h"
-#define MAX_INPUT_LENGTH 64
+#define MAX_INPUT_LENGTH 128
struct entry {
- struct surface surface;
- struct wl_subsurface *wl_subsurface;
struct image image;
struct {
PangoContext *context;
@@ -22,7 +20,6 @@ struct entry {
cairo_surface_t *surface;
cairo_t *cr;
} cairo;
- PangoRectangle text_bounds;
wchar_t input[MAX_INPUT_LENGTH];
/* Assume maximum of 4 bytes per wchar_t (for UTF-8) */
@@ -49,7 +46,7 @@ struct entry {
} border;
};
-void entry_init(struct entry *entry, uint32_t scale);
+void entry_init(struct entry *entry, uint32_t width, uint32_t height, uint32_t scale);
void entry_destroy(struct entry *entry);
void entry_update(struct entry *entry);
void entry_set_scale(struct entry *entry, uint32_t scale);
diff --git a/src/main.c b/src/main.c
index 53ad136..ed865ed 100644
--- a/src/main.c
+++ b/src/main.c
@@ -33,7 +33,6 @@
static void resize(struct tofi *tofi)
{
struct surface *surface = &tofi->window.surface;
- struct surface *entry_surface = &tofi->window.entry.surface;
/*
* Resize the main window.
@@ -219,7 +218,6 @@ static void wl_keyboard_key(
return;
}
entry_update(&tofi->window.entry);
- tofi->window.entry.surface.redraw = true;
tofi->window.surface.redraw = true;
}
@@ -475,13 +473,6 @@ static void registry_global(
&wl_compositor_interface,
4);
log_debug("Bound to compositor %u.\n", name);
- } else if (!strcmp(interface, wl_subcompositor_interface.name)) {
- tofi->wl_subcompositor = wl_registry_bind(
- wl_registry,
- name,
- &wl_subcompositor_interface,
- 1);
- log_debug("Bound to subcompositor %u.\n", name);
} else if (!strcmp(interface, wl_seat_interface.name)) {
tofi->wl_seat = wl_registry_bind(
wl_registry,
@@ -763,10 +754,9 @@ int main(int argc, char *argv[])
log_debug("Second roundtrip done.\n");
/*
- * Next, we create the Wayland surfaces that we need - one for
- * the whole window, and another for the entry box.
+ * Next, we create the Wayland surface, which takes on the
+ * layer shell role.
*/
- /* The main window surface takes on the layer_shell_surface role. */
log_debug("Creating main window surface.\n");
tofi.window.surface.wl_surface =
wl_compositor_create_surface(tofi.wl_compositor);
@@ -792,26 +782,28 @@ int main(int argc, char *argv[])
tofi.window.zwlr_layer_surface,
&zwlr_layer_surface_listener,
&tofi);
+ zwlr_layer_surface_v1_set_anchor(
+ tofi.window.zwlr_layer_surface,
+ ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT
+ | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT);
+ zwlr_layer_surface_v1_set_exclusive_zone(
+ tofi.window.zwlr_layer_surface,
+ -1);
+ wl_surface_commit(tofi.window.surface.wl_surface);
/*
- * The entry surface takes on a subsurface role and is set to be
- * desynchronised, so that we can update it independently from the main
- * window.
+ * Now that we've done all our Wayland-related setup, we do another
+ * roundtrip. This should cause the layer surface window to be
+ * configured, after which we're ready to start drawing to the screen.
*/
- log_debug("Creating entry surface.\n");
- tofi.window.entry.surface.wl_surface =
- wl_compositor_create_surface(tofi.wl_compositor);
- wl_surface_set_buffer_scale(
- tofi.window.entry.surface.wl_surface,
- tofi.window.scale);
-
- tofi.window.entry.wl_subsurface = wl_subcompositor_get_subsurface(
- tofi.wl_subcompositor,
- tofi.window.entry.surface.wl_surface,
- tofi.window.surface.wl_surface);
- wl_subsurface_set_desync(tofi.window.entry.wl_subsurface);
+ log_debug("Third roundtrip start.\n");
+ wl_display_roundtrip(tofi.wl_display);
+ log_debug("Third roundtrip done.\n");
- wl_surface_commit(tofi.window.entry.surface.wl_surface);
+ /* Call resize() just to center the entry properly. */
+ resize(&tofi);
/*
* Initialise the Pango & Cairo structures for rendering the entry.
@@ -823,31 +815,14 @@ int main(int argc, char *argv[])
* shouldn't be moving between outputs while running.
*/
log_debug("Initialising Pango / Cairo.\n");
- entry_init(&tofi.window.entry, tofi.window.scale);
+ entry_init(
+ &tofi.window.entry,
+ tofi.window.surface.width,
+ tofi.window.surface.height,
+ tofi.window.scale);
+ entry_update(&tofi.window.entry);
log_debug("Pango / Cairo initialised.\n");
- /* Tell the compositor not to make our window smaller than the entry. */
- //zwlr_layer_surface_v1_set_size(
- // tofi.window.zwlr_layer_surface,
- // 100,
- // 100);
- zwlr_layer_surface_v1_set_anchor(
- tofi.window.zwlr_layer_surface,
- 0x0Fu);
- wl_surface_commit(tofi.window.surface.wl_surface);
-
- /*
- * Now that we've done all our Wayland-related setup, we do another
- * roundtrip. This should cause the layer surface window to be
- * configured, after which we're ready to start drawing to the screen.
- */
- log_debug("Third roundtrip start.\n");
- wl_display_roundtrip(tofi.wl_display);
- log_debug("Third roundtrip done.\n");
-
- /* Call resize() just to center the entry properly. */
- resize(&tofi);
-
/*
* Create the various EGL and GL structures for each surface, and
* perform an initial render of everything.
@@ -856,22 +831,9 @@ int main(int argc, char *argv[])
surface_initialise(
&tofi.window.surface,
tofi.wl_display,
- &tofi.window.background_image);
- surface_draw(
- &tofi.window.surface,
- &tofi.window.background_color,
- &tofi.window.background_image);
-
- log_debug("Initialising entry window surface.\n");
- surface_initialise(
- &tofi.window.entry.surface,
- tofi.wl_display,
&tofi.window.entry.image);
-
- log_debug("Initial draw\n");
- entry_update(&tofi.window.entry);
surface_draw(
- &tofi.window.entry.surface,
+ &tofi.window.surface,
&tofi.window.background_color,
&tofi.window.entry.image);
@@ -879,9 +841,8 @@ int main(int argc, char *argv[])
* We've just rendered everything and resized, so we don't need to do
* it again right now.
*/
- //tofi.window.resize = false;
- //tofi.window.surface.redraw = false;
- //tofi.window.entry.surface.redraw = false;
+ tofi.window.resize = false;
+ tofi.window.surface.redraw = false;
while (wl_display_dispatch(tofi.wl_display) != -1) {
if (tofi.closed) {
@@ -892,19 +853,11 @@ int main(int argc, char *argv[])
tofi.window.resize = false;
}
if (tofi.window.surface.redraw) {
- log_debug("Redraw main window.\n");
surface_draw(
&tofi.window.surface,
&tofi.window.background_color,
- &tofi.window.background_image);
- tofi.window.surface.redraw = false;
- }
- if (tofi.window.entry.surface.redraw) {
- surface_draw(
- &tofi.window.entry.surface,
- &tofi.window.background_color,
&tofi.window.entry.image);
- tofi.window.entry.surface.redraw = false;
+ tofi.window.surface.redraw = false;
}
if (tofi.submit) {
if (tofi.window.entry.results.count > 0) {
@@ -922,15 +875,12 @@ int main(int argc, char *argv[])
* mostly from OpenGL libs and Pango.
*/
entry_destroy(&tofi.window.entry);
- surface_destroy(&tofi.window.entry.surface);
surface_destroy(&tofi.window.surface);
if (tofi.window.background_image.buffer != NULL) {
free(tofi.window.background_image.buffer);
tofi.window.background_image.buffer = NULL;
}
eglTerminate(tofi.window.surface.egl.display);
- wl_subsurface_destroy(tofi.window.entry.wl_subsurface);
- wl_surface_destroy(tofi.window.entry.surface.wl_surface);
wl_surface_destroy(tofi.window.surface.wl_surface);
if (tofi.wl_keyboard != NULL) {
wl_keyboard_release(tofi.wl_keyboard);
@@ -939,7 +889,6 @@ int main(int argc, char *argv[])
wl_pointer_release(tofi.wl_pointer);
}
wl_compositor_destroy(tofi.wl_compositor);
- wl_subcompositor_destroy(tofi.wl_subcompositor);
wl_seat_release(tofi.wl_seat);
wl_output_release(tofi.wl_output);
xkb_state_unref(tofi.xkb_state);
diff --git a/src/tofi.h b/src/tofi.h
index d7a9dbb..586d1ca 100644
--- a/src/tofi.h
+++ b/src/tofi.h
@@ -15,7 +15,6 @@ struct tofi {
struct wl_display *wl_display;
struct wl_registry *wl_registry;
struct wl_compositor *wl_compositor;
- struct wl_subcompositor *wl_subcompositor;
struct wl_seat *wl_seat;
struct wl_output *wl_output;
struct zwlr_layer_shell_v1 *zwlr_layer_shell;
@@ -23,7 +22,6 @@ struct tofi {
uint32_t wl_display_name;
uint32_t wl_registry_name;
uint32_t wl_compositor_name;
- uint32_t wl_subcompositor_name;
uint32_t wl_seat_name;
uint32_t wl_output_name;
uint32_t zwlr_layer_shell_name;