From daab8e35038e74f9b21b62cc2d7f74635fb5a34b Mon Sep 17 00:00:00 2001
From: Ryan Dwyer <ryandwyer1@gmail.com>
Date: Wed, 2 May 2018 08:40:38 +1000
Subject: [PATCH] Support alpha in border colours

The alpha component is merged with the container's opacity.

Completes #1882.
---
 sway/commands/client.c | 15 ++++++++++-----
 sway/desktop/output.c  | 34 ++++++++++++++++++++--------------
 2 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/sway/commands/client.c b/sway/commands/client.c
index 156ff95c..c3dc2ee2 100644
--- a/sway/commands/client.c
+++ b/sway/commands/client.c
@@ -8,7 +8,7 @@ static bool parse_color(char *hexstring, float dest[static 4]) {
 		return false;
 	}
 
-	if (strlen(hexstring) != 7) {
+	if (strlen(hexstring) != 7 && strlen(hexstring) != 9) {
 		return false;
 	}
 
@@ -20,10 +20,15 @@ static bool parse_color(char *hexstring, float dest[static 4]) {
 		return false;
 	}
 
-	dest[0] = ((decimal >> 16) & 0xff) / 255.0;
-	dest[1] = ((decimal >> 8) & 0xff) / 255.0;
-	dest[2] = (decimal & 0xff) / 255.0;
-	dest[3] = 1.0;
+	if (strlen(hexstring) == 6) {
+		// Add alpha
+		decimal = (decimal << 8) | 0xff;
+	}
+
+	dest[0] = ((decimal >> 24) & 0xff) / 255.0;
+	dest[1] = ((decimal >> 16) & 0xff) / 255.0;
+	dest[2] = ((decimal >> 8) & 0xff) / 255.0;
+	dest[3] = (decimal & 0xff) / 255.0;
 	return true;
 }
 
diff --git a/sway/desktop/output.c b/sway/desktop/output.c
index e0a211d1..4fff8cd3 100644
--- a/sway/desktop/output.c
+++ b/sway/desktop/output.c
@@ -232,10 +232,10 @@ static void render_container_simple_border_normal(struct sway_output *output,
 		wlr_backend_get_renderer(output->wlr_output->backend);
 	struct wlr_box box;
 	float color[4];
-	color[3] = con->alpha;
 
 	// Child border - left edge
-	memcpy(&color, colors->child_border, sizeof(float) * 3);
+	memcpy(&color, colors->child_border, sizeof(float) * 4);
+	color[3] *= con->alpha;
 	box.x = con->x;
 	box.y = con->y + 1;
 	box.width = con->sway_view->border_thickness;
@@ -246,10 +246,11 @@ static void render_container_simple_border_normal(struct sway_output *output,
 
 	// Child border - right edge
 	if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) {
-		memcpy(&color, colors->indicator, sizeof(float) * 3);
+		memcpy(&color, colors->indicator, sizeof(float) * 4);
 	} else {
-		memcpy(&color, colors->child_border, sizeof(float) * 3);
+		memcpy(&color, colors->child_border, sizeof(float) * 4);
 	}
+	color[3] *= con->alpha;
 	box.x = con->x + con->width - con->sway_view->border_thickness;
 	box.y = con->y + 1;
 	box.width = con->sway_view->border_thickness;
@@ -260,10 +261,11 @@ static void render_container_simple_border_normal(struct sway_output *output,
 
 	// Child border - bottom edge
 	if (con->parent->children->length == 1 && con->parent->layout == L_VERT) {
-		memcpy(&color, colors->indicator, sizeof(float) * 3);
+		memcpy(&color, colors->indicator, sizeof(float) * 4);
 	} else {
-		memcpy(&color, colors->child_border, sizeof(float) * 3);
+		memcpy(&color, colors->child_border, sizeof(float) * 4);
 	}
+	color[3] *= con->alpha;
 	box.x = con->x;
 	box.y = con->y + con->height - con->sway_view->border_thickness;
 	box.width = con->width;
@@ -273,7 +275,8 @@ static void render_container_simple_border_normal(struct sway_output *output,
 			output->wlr_output->transform_matrix);
 
 	// Single pixel bar above title
-	memcpy(&color, colors->border, sizeof(float) * 3);
+	memcpy(&color, colors->border, sizeof(float) * 4);
+	color[3] *= con->alpha;
 	box.x = con->x;
 	box.y = con->y;
 	box.width = con->width;
@@ -292,7 +295,8 @@ static void render_container_simple_border_normal(struct sway_output *output,
 			output->wlr_output->transform_matrix);
 
 	// Title background
-	memcpy(&color, colors->background, sizeof(float) * 3);
+	memcpy(&color, colors->background, sizeof(float) * 4);
+	color[3] *= con->alpha;
 	box.x = con->x + con->sway_view->border_thickness;
 	box.y = con->y + 1;
 	box.width = con->width - con->sway_view->border_thickness * 2;
@@ -314,10 +318,10 @@ static void render_container_simple_border_pixel(struct sway_output *output,
 		wlr_backend_get_renderer(output->wlr_output->backend);
 	struct wlr_box box;
 	float color[4];
-	color[3] = con->alpha;
 
 	// Child border - left edge
-	memcpy(&color, colors->child_border, sizeof(float) * 3);
+	memcpy(&color, colors->child_border, sizeof(float) * 4);
+	color[3] *= con->alpha;
 	box.x = con->x;
 	box.y = con->y;
 	box.width = con->sway_view->border_thickness;
@@ -328,10 +332,11 @@ static void render_container_simple_border_pixel(struct sway_output *output,
 
 	// Child border - right edge
 	if (con->parent->children->length == 1 && con->parent->layout == L_HORIZ) {
-		memcpy(&color, colors->indicator, sizeof(float) * 3);
+		memcpy(&color, colors->indicator, sizeof(float) * 4);
 	} else {
-		memcpy(&color, colors->child_border, sizeof(float) * 3);
+		memcpy(&color, colors->child_border, sizeof(float) * 4);
 	}
+	color[3] *= con->alpha;
 	box.x = con->x + con->width - con->sway_view->border_thickness;
 	box.y = con->y;
 	box.width = con->sway_view->border_thickness;
@@ -351,10 +356,11 @@ static void render_container_simple_border_pixel(struct sway_output *output,
 
 	// Child border - bottom edge
 	if (con->parent->children->length == 1 && con->parent->layout == L_VERT) {
-		memcpy(&color, colors->indicator, sizeof(float) * 3);
+		memcpy(&color, colors->indicator, sizeof(float) * 4);
 	} else {
-		memcpy(&color, colors->child_border, sizeof(float) * 3);
+		memcpy(&color, colors->child_border, sizeof(float) * 4);
 	}
+	color[3] *= con->alpha;
 	box.x = con->x;
 	box.y = con->y + con->height - con->sway_view->border_thickness;
 	box.width = con->width;