diff --git a/osk.conf b/osk.conf
index 255128780407f4ce313df0d2bc19ccaef05d0310..042e4150fb6af0696dfee412881ec7f38307db34 100644
--- a/osk.conf
+++ b/osk.conf
@@ -9,9 +9,11 @@ keyboard-font = /usr/share/fonts/ttf-dejavu/DejaVuSans.ttf
 keyboard-font-size = 24
 
 key-foreground = #FFFFFF
+key-foreground-highlighted = #0E0E12
 key-background-letter = #5A606A
 key-background-return = #003C00
 key-background-other = #32363E
+key-background-highlighted = #FFFFFF
 key-radius = 0
 
 inputbox-background = #32363E
diff --git a/src/config.cpp b/src/config.cpp
index 110210ac9f635a9e30820236ec89438a0e7a9d5b..121656726b60f1ad6ee2068a5563658f6265c4d5 100644
--- a/src/config.cpp
+++ b/src/config.cpp
@@ -80,6 +80,12 @@ bool Config::Read(const std::string &path)
 		Config::keyForeground = parseHexString(hex);
 	}
 
+	it = Config::options.find("key-foreground-highlighted");
+	if (it != Config::options.end()) {
+		std::string hex = Config::options["key-foreground-highlighted"];
+		Config::keyForegroundHighlighted = parseHexString(hex);
+	}
+
 	it = Config::options.find("key-background-letter");
 	if (it != Config::options.end()) {
 		std::string hex = Config::options["key-background-letter"];
@@ -98,6 +104,12 @@ bool Config::Read(const std::string &path)
 		Config::keyBackgroundOther = parseHexString(hex);
 	}
 
+	it = Config::options.find("key-background-highlighted");
+	if (it != Config::options.end()) {
+		std::string hex = Config::options["key-background-highlighted"];
+		Config::keyBackgroundHighlighted = parseHexString(hex);
+	}
+
 	it = Config::options.find("key-radius");
 	if (it != Config::options.end()) {
 		Config::keyRadius = Config::options["key-radius"];
diff --git a/src/config.h b/src/config.h
index b35ac7ebd3a0e84cf5f0dbebc987f75668c9b81c..2d5eb79042af01549993f65281a3bce7e243d499 100644
--- a/src/config.h
+++ b/src/config.h
@@ -44,9 +44,11 @@ public:
 	int keyboardFontSize = 24;
 	std::string keyboardMap = "us";
 	argb keyForeground = parseHexString("#FFFFFF");
+	argb keyForegroundHighlighted = parseHexString("#000000");
 	argb keyBackgroundLetter = parseHexString("#5A606A");
 	argb keyBackgroundReturn = parseHexString("#003C00");
 	argb keyBackgroundOther = parseHexString("#32363E");
+	argb keyBackgroundHighlighted = parseHexString("#FFFFFF");
 	std::string keyRadius = "0";
 	argb inputBoxBackground = parseHexString("#32363E");
 	std::string inputBoxRadius = "0";
diff --git a/src/keyboard.cpp b/src/keyboard.cpp
index 2ff6249068e908a8684a8f3cb8c6c4a728427787..484ff1878214295fcbdc7f650585d24f3d7609d8 100644
--- a/src/keyboard.cpp
+++ b/src/keyboard.cpp
@@ -43,16 +43,16 @@ int Keyboard::init(SDL_Renderer *renderer)
 		keyRadius = keyLong;
 	}
 	for (auto &layer : keyboard) {
-		layer.surface = makeKeyboard(&layer);
-		if (!layer.surface) {
-			SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Unable to generate keyboard surface");
-			return 1;
-		}
-		layer.texture = SDL_CreateTextureFromSurface(renderer, layer.surface);
+		layer.texture = makeKeyboardTexture(renderer, &layer, false);
 		if (!layer.texture) {
 			SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Unable to generate keyboard texture");
 			return 1;
 		}
+		layer.highlightedTexture = makeKeyboardTexture(renderer, &layer, true);
+		if (!layer.highlightedTexture) {
+			SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Unable to generate highlighted keyboard texture");
+			return 1;
+		}
 	}
 	lastAnimTicks = SDL_GetTicks();
 	return 0;
@@ -111,7 +111,7 @@ void Keyboard::draw(SDL_Renderer *renderer, int screenHeight)
 {
 	updateAnimations();
 
-	SDL_Rect keyboardRect, srcRect;
+	SDL_Rect keyboardRect, srcRect, highlightDstRect, highlightSrcRect;
 
 	keyboardRect.x = 0;
 	keyboardRect.y = static_cast<int>(screenHeight - (keyboardHeight * position));
@@ -125,12 +125,35 @@ void Keyboard::draw(SDL_Renderer *renderer, int screenHeight)
 	srcRect.w = keyboardWidth;
 	srcRect.h = keyboardRect.h;
 
-	SDL_SetRenderDrawColor(renderer, config->keyboardBackground.r, config->keyboardBackground.g, config->keyboardBackground.b, config->keyboardBackground.a);
+	if (isKeyHighlighted) {
+		auto padding = keyboardWidth / 100;
+
+		highlightSrcRect.x = highlightedKey.x1 + padding;
+		highlightSrcRect.y = highlightedKey.y1 + padding;
+		highlightSrcRect.w = highlightedKey.x2 - highlightedKey.x1 - 2 * padding;
+		highlightSrcRect.h = highlightedKey.y2 - highlightedKey.y1 - 2 * padding;
+
+		highlightDstRect = highlightSrcRect;
+		highlightDstRect.y += keyboardRect.y;
+	}
 
 	for (const auto &layer : keyboard) {
-		if (layer.layerNum == activeLayer) {
-			SDL_RenderCopy(renderer, layer.texture, &srcRect, &keyboardRect);
+		if (layer.layerNum != activeLayer) {
+			continue;
 		}
+
+		SDL_RenderCopy(renderer, layer.texture, &srcRect, &keyboardRect);
+
+		if (!isKeyHighlighted) {
+			continue;
+		}
+
+		if (highlightedKey.isPreviewEnabled) {
+			SDL_SetRenderDrawColor(renderer, config->keyBackgroundHighlighted.r, config->keyBackgroundHighlighted.g, config->keyBackgroundHighlighted.b, config->keyBackgroundHighlighted.a);
+			SDL_RenderFillRect(renderer, &highlightDstRect);
+			highlightDstRect.y -= highlightDstRect.h;
+		}
+		SDL_RenderCopy(renderer, layer.highlightedTexture, &highlightSrcRect, &highlightDstRect);
 	}
 }
 
@@ -140,12 +163,12 @@ bool Keyboard::isInSlideAnimation() const
 }
 
 void Keyboard::drawRow(SDL_Surface *surface, std::vector<touchArea> &keyVector, int x, int y, int width, int height,
-	const std::vector<std::string> &keys, int padding, TTF_Font *font) const
+	const std::vector<std::string> &keys, int padding, TTF_Font *font, bool isHighlighted, bool isPreviewEnabled, argb foreground, argb background) const
 {
-	auto keyBackground = SDL_MapRGB(surface->format, config->keyBackgroundLetter.r, config->keyBackgroundLetter.g, config->keyBackgroundLetter.b);
-	SDL_Color textColor = { config->keyForeground.r, config->keyForeground.g, config->keyForeground.b, config->keyForeground.a };
+	auto keyBackground = SDL_MapRGB(surface->format, background.r, background.g, background.b);
+	SDL_Color textColor = { foreground.r, foreground.g, foreground.b, foreground.a };
 
-	auto background = SDL_MapRGB(surface->format, config->keyboardBackground.r, config->keyboardBackground.g, config->keyboardBackground.b);
+	auto keyboardBackground = SDL_MapRGB(surface->format, config->keyboardBackground.r, config->keyboardBackground.g, config->keyboardBackground.b);
 	int i = 0;
 	for (const auto &keyCap : keys) {
 		SDL_Rect keyRect;
@@ -155,10 +178,13 @@ void Keyboard::drawRow(SDL_Surface *surface, std::vector<touchArea> &keyVector,
 		keyRect.h = height - (2 * padding);
 		SDL_FillRect(surface, &keyRect, keyBackground);
 		if (keyRadius > 0) {
-			smooth_corners_surface(surface, background, &keyRect, keyRadius);
+			smooth_corners_surface(surface, keyboardBackground, &keyRect, keyRadius);
 		}
 		SDL_Surface *textSurface;
-		keyVector.push_back({ keyCap, x + (i * width), x + (i * width) + width, y, y + height });
+
+		if (!isHighlighted) {
+			keyVector.push_back({ keyCap, isPreviewEnabled, x + (i * width), x + (i * width) + width, y, y + height });
+		}
 
 		textSurface = TTF_RenderUTF8_Blended(font, keyCap.c_str(), textColor);
 
@@ -174,10 +200,10 @@ void Keyboard::drawRow(SDL_Surface *surface, std::vector<touchArea> &keyVector,
 }
 
 void Keyboard::drawKey(SDL_Surface *surface, std::vector<touchArea> &keyVector, int x, int y, int width, int height,
-	char *cap, const char *key, int padding, TTF_Font *font, argb background) const
+	char *cap, const char *key, int padding, TTF_Font *font, bool isHighlighted, bool isPreviewEnabled, argb foreground, argb background) const
 {
 	auto keyBackground = SDL_MapRGB(surface->format, background.r, background.g, background.b);
-	SDL_Color textColor = { config->keyForeground.r, config->keyForeground.g, config->keyForeground.b, config->keyForeground.a };
+	SDL_Color textColor = { foreground.r, foreground.g, foreground.b, foreground.a };
 
 	SDL_Rect keyRect;
 	keyRect.x = x + padding;
@@ -187,7 +213,9 @@ void Keyboard::drawKey(SDL_Surface *surface, std::vector<touchArea> &keyVector,
 	SDL_FillRect(surface, &keyRect, keyBackground);
 	SDL_Surface *textSurface;
 
-	keyVector.push_back({ key, x, x + width, y, y + height });
+	if (!isHighlighted) {
+		keyVector.push_back({ key, isPreviewEnabled, x, x + width, y, y + height });
+	}
 
 	textSurface = TTF_RenderUTF8_Blended(font, cap, textColor);
 
@@ -199,7 +227,7 @@ void Keyboard::drawKey(SDL_Surface *surface, std::vector<touchArea> &keyVector,
 	SDL_BlitSurface(textSurface, nullptr, surface, &keyCapRect);
 }
 
-SDL_Surface *Keyboard::makeKeyboard(KeyboardLayer *layer) const
+SDL_Surface *Keyboard::makeKeyboard(KeyboardLayer *layer, bool isHighlighted) const
 {
 	SDL_Surface *surface;
 	Uint32 rmask, gmask, bmask, amask;
@@ -226,8 +254,10 @@ SDL_Surface *Keyboard::makeKeyboard(KeyboardLayer *layer) const
 		return nullptr;
 	}
 
-	SDL_FillRect(surface, nullptr,
-		SDL_MapRGB(surface->format, config->keyboardBackground.r, config->keyboardBackground.g, config->keyboardBackground.b));
+	if (!isHighlighted) {
+		SDL_FillRect(surface, nullptr,
+			SDL_MapRGB(surface->format, config->keyboardBackground.r, config->keyboardBackground.g, config->keyboardBackground.b));
+	}
 
 	int rowCount = layer->rows.size();
 	int rowHeight = keyboardHeight / (rowCount + 1);
@@ -243,6 +273,11 @@ SDL_Surface *Keyboard::makeKeyboard(KeyboardLayer *layer) const
 		return nullptr;
 	}
 
+	auto keyForeground = isHighlighted ? config->keyForegroundHighlighted : config->keyForeground;
+	auto keyBackgroundLetter = isHighlighted ? config->keyBackgroundHighlighted : config->keyBackgroundLetter;
+	auto keyBackgroundReturn = isHighlighted ? config->keyBackgroundHighlighted : config->keyBackgroundReturn;
+	auto keyBackgroundOther = isHighlighted ? config->keyBackgroundHighlighted : config->keyBackgroundOther;
+
 	// Divide the bottom row in 20 columns and use that for calculations
 	int colw = keyboardWidth / 20;
 
@@ -257,7 +292,7 @@ SDL_Surface *Keyboard::makeKeyboard(KeyboardLayer *layer) const
 		if (i == 2) /* leave room for shift, "123" or "=\<" key */
 			x = keyboardWidth / 20 + colw * 2;
 		drawRow(surface, layer->keyVector, x, y, keyboardWidth / 10,
-			rowHeight, layer->rows[i], keyboardWidth / 100, font);
+			rowHeight, layer->rows[i], keyboardWidth / 100, font, isHighlighted, true, keyForeground, keyBackgroundLetter);
 		y += rowHeight;
 		i++;
 	}
@@ -266,29 +301,29 @@ SDL_Surface *Keyboard::makeKeyboard(KeyboardLayer *layer) const
 	if (layer->layerNum < 2) {
 		char nums[] = "123";
 		drawKey(surface, layer->keyVector, colw, y, colw * 3, rowHeight,
-			nums, KEYCAP_NUMBERS, keyboardWidth / 100, font, config->keyBackgroundOther);
+			nums, KEYCAP_NUMBERS, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundOther);
 	} else {
 		char abc[] = "abc";
 		drawKey(surface, layer->keyVector, colw, y, colw * 3, rowHeight,
-			abc, KEYCAP_ABC, keyboardWidth / 100, font, config->keyBackgroundOther);
+			abc, KEYCAP_ABC, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundOther);
 	}
 	/* Shift-key that transforms into "123" or "=\<" depending on layer: */
 	if (layer->layerNum == 2) {
 		char symb[] = "=\\<";
 		drawKey(surface, layer->keyVector, 0, y - rowHeight,
 			sidebuttonsWidth, rowHeight,
-			symb, KEYCAP_SYMBOLS, keyboardWidth / 100, font, config->keyBackgroundOther);
+			symb, KEYCAP_SYMBOLS, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundOther);
 	} else if (layer->layerNum == 3) {
 		char nums[] = "123";
 		drawKey(surface, layer->keyVector, 0, y - rowHeight,
 			sidebuttonsWidth, rowHeight,
-			nums, KEYCAP_NUMBERS, keyboardWidth / 100, font, config->keyBackgroundOther);
+			nums, KEYCAP_NUMBERS, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundOther);
 	} else {
 		char shift[64] = "";
 		memcpy(shift, KEYCAP_SHIFT, strlen(KEYCAP_SHIFT) + 1);
 		drawKey(surface, layer->keyVector, 0, y - rowHeight,
 			sidebuttonsWidth, rowHeight,
-			shift, KEYCAP_SHIFT, keyboardWidth / 100, font, config->keyBackgroundOther);
+			shift, KEYCAP_SHIFT, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundOther);
 	}
 	/* Backspace key that is larger-sized (hence also drawn separately) */
 	{
@@ -297,24 +332,36 @@ SDL_Surface *Keyboard::makeKeyboard(KeyboardLayer *layer) const
 			strlen(KEYCAP_BACKSPACE) + 1);
 		drawKey(surface, layer->keyVector, keyboardWidth / 20 + colw * 16,
 			y - rowHeight, sidebuttonsWidth, rowHeight,
-			bcksp, KEYCAP_BACKSPACE, keyboardWidth / 100, font, config->keyBackgroundOther);
+			bcksp, KEYCAP_BACKSPACE, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundOther);
 	}
 
 	char space[] = " ";
 	drawKey(surface, layer->keyVector, colw * 5, y, colw * 8, rowHeight,
-		space, KEYCAP_SPACE, keyboardWidth / 100, font, config->keyBackgroundLetter);
+		space, KEYCAP_SPACE, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundLetter);
 
 	char period[] = ".";
 	drawKey(surface, layer->keyVector, colw * 13, y, colw * 2, rowHeight,
-		period, KEYCAP_PERIOD, keyboardWidth / 100, font, config->keyBackgroundOther);
+		period, KEYCAP_PERIOD, keyboardWidth / 100, font, isHighlighted, true, keyForeground, keyBackgroundOther);
 
 	char enter[] = "OK";
 	drawKey(surface, layer->keyVector, colw * 15, y, colw * 5, rowHeight,
-		enter, KEYCAP_RETURN, keyboardWidth / 100, font, config->keyBackgroundReturn);
+		enter, KEYCAP_RETURN, keyboardWidth / 100, font, isHighlighted, false, keyForeground, keyBackgroundReturn);
 
 	return surface;
 }
 
+SDL_Texture *Keyboard::makeKeyboardTexture(SDL_Renderer *renderer, KeyboardLayer *layer, bool isHighlighted) const
+{
+	auto surface = makeKeyboard(layer, isHighlighted);
+	if (!surface) {
+		SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "Unable to generate keyboard surface");
+		return nullptr;
+	}
+	auto texture = SDL_CreateTextureFromSurface(renderer, surface);
+	SDL_FreeSurface(surface);
+	return texture;
+}
+
 void Keyboard::setActiveLayer(int layerNum)
 {
 	if (layerNum >= 0) {
@@ -370,16 +417,27 @@ void Keyboard::loadKeymap()
 	keyboard.push_back(layer3);
 }
 
-std::string Keyboard::getCharForCoordinates(int x, int y)
+touchArea Keyboard::getKeyForCoordinates(int x, int y)
 {
 	for (const auto &layer : keyboard) {
 		if (layer.layerNum == activeLayer) {
 			for (const auto &it : layer.keyVector) {
 				if (x > it.x1 && x < it.x2 && y > it.y1 && y < it.y2) {
-					return it.keyChar;
+					return it;
 				}
 			}
 		}
 	}
-	return "";
+	return { "", false, 0, 0, 0, 0 };
+}
+
+void Keyboard::setKeyHighlighted(touchArea area, bool isHighlighted)
+{
+	for (const auto &layer : keyboard) {
+		if (layer.layerNum != activeLayer) {
+			continue;
+		}
+		highlightedKey = area;
+		isKeyHighlighted = isHighlighted;
+	}
 }
diff --git a/src/keyboard.h b/src/keyboard.h
index 691b1b45b3a771fa51c48e18fd198b43dbaba6d6..ab517a3562d602d9ab44d0931d4a0b5407c4d3ea 100644
--- a/src/keyboard.h
+++ b/src/keyboard.h
@@ -39,6 +39,7 @@ constexpr char KEYCAP_PERIOD[] = ".";
 
 struct touchArea {
 	std::string keyChar;
+	bool isPreviewEnabled;
 	int x1;
 	int x2;
 	int y1;
@@ -52,8 +53,8 @@ struct rgb {
 };
 
 struct KeyboardLayer {
-	SDL_Surface *surface = nullptr;
 	SDL_Texture *texture = nullptr;
+	SDL_Texture *highlightedTexture = nullptr;
 	std::array<std::vector<std::string>, 3> rows;
 	std::vector<touchArea> keyVector;
 	int layerNum;
@@ -75,9 +76,15 @@ public:
 	  Get the character/key at the given coordinates
 	  @param x X-axis coordinate
 	  @param y Y-axis coordinate
-	  @return String with value of key at the given coordinates
+	  @return Touch area for the key at the given coordinates. When no key is found, keyChar will be an empty string.
 	  */
-	std::string getCharForCoordinates(int x, int y);
+	touchArea getKeyForCoordinates(int x, int y);
+	/**
+	  Set / unset the key to be highlighted on the next render pass
+	  @param area Touch area of the key
+	  @param isHighlighted Whether to highlight or unhighlight the key
+	  */
+	void setKeyHighlighted(touchArea area, bool isHighlighted);
 	/**
 	  Get position of keyboard
 	  @return Position as a value between 0 and 1 (0% and 100%)
@@ -135,11 +142,13 @@ private:
 	int activeLayer = 0;
 	std::vector<KeyboardLayer> keyboard;
 	Config *config;
+	touchArea highlightedKey = { "", false, 0, 0, 0, 0 };
+	bool isKeyHighlighted = false;
 
 	/**
 	  Draw keyboard row
 	  @param surface Surface to draw on
-	  @param keyList List of keys for keyboard layout
+	  @param keyVector List of keys for keyboard layout
 	  @param x X-axis coord. for start of row
 	  @param y Y-axis coord. for start of row
 	  @param width Width of row
@@ -148,10 +157,14 @@ private:
 	  @param key Key text
 	  @param padding Spacing to reserve around the key
 	  @param font Font to use for key character
+	  @param isHighlighted Whether the drawing is for the highlighted keys
+	  @param isPreviewEnabled Whether this key will show a preview on press
+	  @param foreground Foreground color for the keycap
+	  @param background Background color for the keycap
 	  */
 	void drawRow(SDL_Surface *surface, std::vector<touchArea> &keyVector, int x, int y,
 		int width, int height, const std::vector<std::string> &keys, int padding,
-		TTF_Font *font) const;
+		TTF_Font *font, bool isHighlighted, bool isPreviewEnabled, argb foreground, argb background) const;
 
 	/**
 	  Internal function to gradually update the animations.
@@ -162,7 +175,7 @@ private:
 	/**
 	  Draw key for keyboard
 	  @param surface Surface to draw on
-	  @param keyList List of keys for keyboard layout
+	  @param keyVector List of keys for keyboard layout
 	  @param x X-axis coord. for start of row
 	  @param y Y-axis coord. for start of row
 	  @param width Width of row
@@ -171,16 +184,28 @@ private:
 	  @param key Key text
 	  @param padding Spacing to reserve around the key
 	  @param font Font to use for key character
+	  @param isHighlighted Whether the drawing is for the highlighted keys
+	  @param isPreviewEnabled Whether this key will show a preview on press
+	  @param foreground Foreground color for the keycap
 	  @param background Background color for the keycap
 	  */
 	void drawKey(SDL_Surface *surface, std::vector<touchArea> &keyVector, int x, int y,
-		int width, int height, char *cap, const char *key, int padding, TTF_Font *font, argb background) const;
+		int width, int height, char *cap, const char *key, int padding, TTF_Font *font, bool isHighlighted, bool isPreviewEnabled, argb foreground, argb background) const;
+	/**
+	  Prepare new keyboard surface
+	  @param layer Keyboard layer to use
+	  @param isHighlighted Whether the drawing is for the highlighted keys
+	  @return New SDL_Surface, or nullptr on error
+	  */
+	SDL_Surface *makeKeyboard(KeyboardLayer *layer, bool isHighlighted) const;
 	/**
-	  Prepare new keyboard
+	  Prepare new keyboard texture
+	  @param renderer Initialized SDL_Renderer object
 	  @param layer Keyboard layer to use
+	  @param isHighlighted Whether the drawing is for the highlighted keys
 	  @return New SDL_Surface, or nullptr on error
 	  */
-	SDL_Surface *makeKeyboard(KeyboardLayer *layer) const;
+	SDL_Texture *makeKeyboardTexture(SDL_Renderer *renderer, KeyboardLayer *layer, bool isHighlighted) const;
 	/**
 	  Load a keymap into the keyboard
 	  */
diff --git a/src/main.cpp b/src/main.cpp
index 97c85b5c8b87fc877893d98083e7fcb43146abf5..5cd8d6d7a54a5ebde0291c04820b34a869cd31f5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -203,6 +203,7 @@ int main(int argc, char **args)
 
 	// The Main Loop.
 	bool done = false;
+	touchArea highlightedKey = { "", false, 0, 0, 0, 0 };
 	while (luksDev.isLocked() && !done) {
 		if (SDL_WaitEvent(&event)) {
 			int cur_ticks = SDL_GetTicks();
@@ -242,6 +243,20 @@ int main(int argc, char **args)
 				SDL_PushEvent(&renderEvent);
 				break; // SDL_KEYDOWN
 				// handle touchscreen
+			case SDL_FINGERDOWN: {
+				// x and y values are normalized!
+				auto xTouch = static_cast<unsigned>(event.tfinger.x * WIDTH);
+				auto yTouch = static_cast<unsigned>(event.tfinger.y * HEIGHT);
+				SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, "xTouch: %u\tyTouch: %u", xTouch, yTouch);
+				auto offsetYTouch = yTouch - static_cast<int>(HEIGHT - (keyboard.getHeight() * keyboard.getPosition()));
+				auto key = keyboard.getKeyForCoordinates(xTouch, offsetYTouch);
+				if (key.keyChar.length() > 0) {
+					keyboard.setKeyHighlighted(key, true);
+					highlightedKey = key;
+				}
+				SDL_PushEvent(&renderEvent);
+				break; // SDL_FINGERDOWN
+			}
 			case SDL_FINGERUP: {
 				showPasswordError = false;
 				// x and y values are normalized!
@@ -249,7 +264,11 @@ int main(int argc, char **args)
 				auto yTouch = static_cast<unsigned>(event.tfinger.y * HEIGHT);
 				SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, "xTouch: %u\tyTouch: %u", xTouch, yTouch);
 				auto offsetYTouch = yTouch - static_cast<int>(HEIGHT - (keyboard.getHeight() * keyboard.getPosition()));
-				tapped = keyboard.getCharForCoordinates(xTouch, offsetYTouch);
+				auto key = keyboard.getKeyForCoordinates(xTouch, offsetYTouch);
+				if (highlightedKey.keyChar.length() > 0) {
+					keyboard.setKeyHighlighted(highlightedKey, false);
+				}
+				tapped = key.keyChar;
 				if (!luksDev.unlockRunning()) {
 					done = handleVirtualKeyPress(tapped, keyboard, luksDev, passphrase, opts.keyscript);
 				}
@@ -257,13 +276,30 @@ int main(int argc, char **args)
 				break; // SDL_FINGERUP
 			}
 				// handle the mouse
+			case SDL_MOUSEBUTTONDOWN: {
+				auto xMouse = event.button.x;
+				auto yMouse = event.button.y;
+				SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, "xMouse: %u\tyMouse: %u", xMouse, yMouse);
+				auto offsetYMouse = yMouse - static_cast<int>(HEIGHT - (keyboard.getHeight() * keyboard.getPosition()));
+				auto key = keyboard.getKeyForCoordinates(xMouse, offsetYMouse);
+				if (key.keyChar.length() > 0) {
+					keyboard.setKeyHighlighted(key, true);
+					highlightedKey = key;
+				}
+				SDL_PushEvent(&renderEvent);
+				break; // SDL_MOUSEBUTTONDOWN
+			}
 			case SDL_MOUSEBUTTONUP: {
 				showPasswordError = false;
 				auto xMouse = event.button.x;
 				auto yMouse = event.button.y;
 				SDL_LogInfo(SDL_LOG_CATEGORY_VIDEO, "xMouse: %u\tyMouse: %u", xMouse, yMouse);
 				auto offsetYMouse = yMouse - static_cast<int>(HEIGHT - (keyboard.getHeight() * keyboard.getPosition()));
-				tapped = keyboard.getCharForCoordinates(xMouse, offsetYMouse);
+				auto key = keyboard.getKeyForCoordinates(xMouse, offsetYMouse);
+				if (highlightedKey.keyChar.length() > 0) {
+					keyboard.setKeyHighlighted(highlightedKey, false);
+				}
+				tapped = key.keyChar;
 				if (!luksDev.unlockRunning()) {
 					done = handleVirtualKeyPress(tapped, keyboard, luksDev, passphrase, opts.keyscript);
 				}
@@ -319,9 +355,6 @@ int main(int argc, char **args)
 				while (render_times < max_render_times) {
 					render_times++;
 					SDL_RenderCopy(renderer, wallpaperTexture, nullptr, nullptr);
-					// Hide keyboard if unlock luks thread is running
-					keyboard.setTargetPosition(!luksDev.unlockRunning());
-					keyboard.draw(renderer, HEIGHT);
 
 					topHalf = static_cast<int>(HEIGHT - (keyboard.getHeight() * keyboard.getPosition()));
 					// Only show either error box or password input box, not both
@@ -334,6 +367,10 @@ int main(int argc, char **args)
 						draw_password_box_dots(renderer, &config, inputHeight, WIDTH, passphrase.size(), inputBoxRect.y,
 							luksDev.unlockRunning());
 					}
+
+					// Hide keyboard if unlock luks thread is running
+					keyboard.setTargetPosition(!luksDev.unlockRunning());
+					keyboard.draw(renderer, HEIGHT);
 					SDL_RenderPresent(renderer);
 					if (keyboard.isInSlideAnimation()) {
 						// No need to double-flip if we'll redraw more for animation