From 56fe895a8100f6484890aafa414e23c5df3d59a9 Mon Sep 17 00:00:00 2001
From: "Adam D. Ruppe" <destructionator@gmail.com>
Date: Tue, 6 Dec 2022 09:29:21 -0500
Subject: [PATCH] more ime fixes and cursor placement support for embedded
 termnial

---
 minigui.d                 | 20 +++++++++++++++++++-
 minigui_addons/nanovega.d |  1 +
 simpledisplay.d           | 22 ++++++++++++++++++----
 terminalemulator.d        |  2 ++
 4 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/minigui.d b/minigui.d
index 9c23bca..acafd35 100644
--- a/minigui.d
+++ b/minigui.d
@@ -3485,6 +3485,20 @@ struct WidgetPainter {
 			this.screenPainter.setFont(font);
 	}
 
+	/++
+		EXPERIMENTAL. subject to change.
+
+		When you draw a cursor, you can draw this to notify your window of where it is,
+		for IME systems to use.
+	+/
+	void notifyCursorPosition(int x, int y, int width, int height) {
+		if(auto a = drawingUpon.parentWindow)
+		if(auto w = a.inputProxy) {
+			w.setIMEPopupLocation(x + screenPainter.originX + width, y + screenPainter.originY + height);
+		}
+	}
+
+
 	///
 	ScreenPainter screenPainter;
 	/// Forward to the screen painter for other methods
@@ -8134,7 +8148,7 @@ class Window : Widget {
 		// for input proxy
 		auto display = XDisplayConnection.get;
 		auto inputProxy = XCreateSimpleWindow(display, win.window, -1, -1, 1, 1, 0, 0, 0);
-		XSelectInput(display, inputProxy, EventMask.KeyPressMask | EventMask.KeyReleaseMask);
+		XSelectInput(display, inputProxy, EventMask.KeyPressMask | EventMask.KeyReleaseMask | EventMask.FocusChangeMask);
 		XMapWindow(display, inputProxy);
 		//import std.stdio; writefln("input proxy: 0x%0x", inputProxy);
 		this.inputProxy = new SimpleWindow(inputProxy);
@@ -11535,6 +11549,10 @@ else version(custom_widgets)
 	alias EditableTextWidgetParent = ScrollableWidget; ///
 else static assert(0);
 
+/+
+	This awful thing has to be rewritten. And it needs to takecare of parentWindow.inputProxy.setIMEPopupLocation too
++/
+
 /// Contains the implementation of text editing
 abstract class EditableTextWidget : EditableTextWidgetParent {
 	this(Widget parent) {
diff --git a/minigui_addons/nanovega.d b/minigui_addons/nanovega.d
index aa136c3..5df61ab 100644
--- a/minigui_addons/nanovega.d
+++ b/minigui_addons/nanovega.d
@@ -28,6 +28,7 @@ class NanoVegaWidget : OpenGlWidget {
 		};
 
 		win.visibleForTheFirstTime = delegate() {
+			win.setAsCurrentOpenGlContext();
 			nvg = nvgCreateContext();
 			if(nvg is null) throw new Exception("cannot initialize NanoVega");
 		};
diff --git a/simpledisplay.d b/simpledisplay.d
index 1733a5a..f7bb51d 100644
--- a/simpledisplay.d
+++ b/simpledisplay.d
@@ -2216,7 +2216,8 @@ class SimpleWindow : CapableOfHandlingNativeEvent, CapableOfBeingDrawnUpon {
 			imePopupLocation = location;
 			updateIMEPopupLocation();
 		} else {
-			throw new NotYetImplementedException();
+			// this is non-fatal at this point... but still wanna find it when i search for NotYetImplementedException at least
+			// throw new NotYetImplementedException();
 		}
 	}
 
@@ -4550,8 +4551,8 @@ class NotificationAreaIcon : CapableOfHandlingNativeEvent {
 								case 3: mb = MouseButton.right; break; // right
 								case 4: mb = MouseButton.wheelUp; break; // scroll up
 								case 5: mb = MouseButton.wheelDown; break; // scroll down
-								case 6: break; // idk
-								case 7: break; // idk
+								case 6: break; // scroll left...
+								case 7: break; // scroll right...
 								case 8: mb = MouseButton.backButton; break;
 								case 9: mb = MouseButton.forwardButton; break;
 								default:
@@ -9028,6 +9029,18 @@ struct ScreenPainter {
 		copyActiveOriginals();
 	}
 
+	/++
+		EXPERIMENTAL. subject to change.
+
+		When you draw a cursor, you can draw this to notify your window of where it is,
+		for IME systems to use.
+	+/
+	void notifyCursorPosition(int x, int y, int width, int height) {
+		if(auto w = cast(SimpleWindow) window) {
+			w.setIMEPopupLocation(x + _originX + width, y + _originY + height);
+		}
+	}
+
 	/++
 		If you are using manual invalidations, this informs the
 		window system that a section needs to be redrawn.
@@ -15496,8 +15509,9 @@ version(X11) {
 
 						if(win.setRequestedInputFocus !is null) {
 							auto s = win.setRequestedInputFocus();
-							if(s !is null)
+							if(s !is null) {
 								setTo = s;
+							}
 						}
 
 						assert(setTo !is null);
diff --git a/terminalemulator.d b/terminalemulator.d
index 9655b9e..1ece832 100644
--- a/terminalemulator.d
+++ b/terminalemulator.d
@@ -4894,6 +4894,8 @@ mixin template SdpyDraw() {
 			}
 			painter.rasterOp = RasterOp.normal;
 
+			painter.notifyCursorPosition(posx, posy, cursorWidth, cursorHeight);
+
 			// since the cursor draws over the cell, we need to make sure it is redrawn each time too
 			auto buffer = alternateScreenActive ? (&alternateScreen) : (&normalScreen);
 			if(cursorX >= 0 && cursorY >= 0 && cursorY < screenHeight && cursorX < screenWidth) {