From cd76702ab21bfe39c7b1804f63caf8994c435ced Mon Sep 17 00:00:00 2001
From: Přemysl Eric Janouch 
Date: Thu, 14 Nov 2024 12:26:22 +0100
Subject: xA/xW: dehighlight current buffer appropriately
---
 xW/xW.cpp | 175 ++++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 101 insertions(+), 74 deletions(-)
(limited to 'xW/xW.cpp')
diff --git a/xW/xW.cpp b/xW/xW.cpp
index 20ae32e..7fd8950 100644
--- a/xW/xW.cpp
+++ b/xW/xW.cpp
@@ -255,73 +255,6 @@ buffer_by_name(const std::wstring &name)
 	return nullptr;
 }
 
-static void
-buffer_activate(const std::wstring &name)
-{
-	auto activate = new Relay::CommandData_BufferActivate();
-	activate->buffer_name = name;
-	relay_send(activate);
-}
-
-static void
-buffer_toggle_unimportant(const std::wstring &name)
-{
-	auto toggle = new Relay::CommandData_BufferToggleUnimportant();
-	toggle->buffer_name = name;
-	relay_send(toggle);
-}
-
-// --- Current buffer ----------------------------------------------------------
-
-static void
-buffer_toggle_log(
-	const std::wstring &error, const Relay::ResponseData_BufferLog *response)
-{
-	if (!response) {
-		show_error_message(error.c_str());
-		return;
-	}
-
-	std::wstring log;
-	if (!LibertyXDR::utf8_to_wstring(
-			response->log.data(), response->log.size(), log)) {
-		show_error_message(L"Invalid encoding.");
-		return;
-	}
-
-	std::wstring filtered;
-	for (auto wch : log) {
-		if (wch == L'\n')
-			filtered += L"\r\n";
-		else
-			filtered += wch;
-	}
-
-	SetWindowText(g.hwndBufferLog, filtered.c_str());
-	ShowWindow(g.hwndBuffer, SW_HIDE);
-	ShowWindow(g.hwndBufferLog, SW_SHOW);
-}
-
-static void
-buffer_toggle_log()
-{
-	if (IsWindowVisible(g.hwndBufferLog)) {
-		ShowWindow(g.hwndBufferLog, SW_HIDE);
-		ShowWindow(g.hwndBuffer, SW_SHOW);
-		SetWindowText(g.hwndBufferLog, L"");
-		return;
-	}
-
-	auto log = new Relay::CommandData_BufferLog();
-	log->buffer_name = g.buffer_current;
-	relay_send(log, [name = g.buffer_current](auto error, auto response) {
-		if (g.buffer_current != name)
-			return;
-		buffer_toggle_log(error,
-			dynamic_cast(response));
-	});
-}
-
 static bool
 buffer_at_bottom()
 {
@@ -354,6 +287,7 @@ refresh_icon()
 		if (b.highlighted)
 			icon = g.hiconHighlighted;
 
+	// XXX: This may not change the taskbar icon.
 	SendMessage(g.hwndMain, WM_SETICON, ICON_SMALL, (LPARAM) icon);
 	SendMessage(g.hwndMain, WM_SETICON, ICON_BIG, (LPARAM) icon);
 }
@@ -430,6 +364,88 @@ refresh_status()
 		SetWindowText(g.hwndStatus, status.c_str());
 }
 
+static void
+recheck_highlighted()
+{
+	// Corresponds to the logic toggling the bool on.
+	auto b = buffer_by_name(g.buffer_current);
+	if (b && b->highlighted && buffer_at_bottom() &&
+		!IsIconic(g.hwndMain) && !IsWindowVisible(g.hwndBufferLog)) {
+		b->highlighted = false;
+		refresh_icon();
+		refresh_buffer_list();
+	}
+}
+
+// --- Buffer actions ----------------------------------------------------------
+
+static void
+buffer_activate(const std::wstring &name)
+{
+	auto activate = new Relay::CommandData_BufferActivate();
+	activate->buffer_name = name;
+	relay_send(activate);
+}
+
+static void
+buffer_toggle_unimportant(const std::wstring &name)
+{
+	auto toggle = new Relay::CommandData_BufferToggleUnimportant();
+	toggle->buffer_name = name;
+	relay_send(toggle);
+}
+
+static void
+buffer_toggle_log(
+	const std::wstring &error, const Relay::ResponseData_BufferLog *response)
+{
+	if (!response) {
+		show_error_message(error.c_str());
+		return;
+	}
+
+	std::wstring log;
+	if (!LibertyXDR::utf8_to_wstring(
+			response->log.data(), response->log.size(), log)) {
+		show_error_message(L"Invalid encoding.");
+		return;
+	}
+
+	std::wstring filtered;
+	for (auto wch : log) {
+		if (wch == L'\n')
+			filtered += L"\r\n";
+		else
+			filtered += wch;
+	}
+
+	SetWindowText(g.hwndBufferLog, filtered.c_str());
+	ShowWindow(g.hwndBuffer, SW_HIDE);
+	ShowWindow(g.hwndBufferLog, SW_SHOW);
+}
+
+static void
+buffer_toggle_log()
+{
+	if (IsWindowVisible(g.hwndBufferLog)) {
+		ShowWindow(g.hwndBufferLog, SW_HIDE);
+		ShowWindow(g.hwndBuffer, SW_SHOW);
+		SetWindowText(g.hwndBufferLog, L"");
+
+		recheck_highlighted();
+		return;
+	}
+
+	auto log = new Relay::CommandData_BufferLog();
+	log->buffer_name = g.buffer_current;
+	relay_send(log, [name = g.buffer_current](auto error, auto response) {
+		if (g.buffer_current != name)
+			return;
+		buffer_toggle_log(error,
+			dynamic_cast(response));
+	});
+}
+
 // --- Rich Edit formatting ----------------------------------------------------
 
 static COLORREF
@@ -728,6 +744,7 @@ refresh_buffer(const Buffer &b)
 
 	buffer_print_and_watch_trailing_date_changes();
 	buffer_scroll_to_bottom();
+	// We will get a scroll event, so no need to recheck_highlighted() here.
 
 	SendMessage(g.hwndBuffer, WM_SETREDRAW, (WPARAM) TRUE, 0);
 	InvalidateRect(g.hwndBuffer, NULL, TRUE);
@@ -749,8 +766,9 @@ relay_process_buffer_line(Buffer &b, Relay::EventData_BufferLine &m)
 	// Retained mode is complicated.
 	bool display = (!m.is_unimportant || !bc->hide_unimportant) &&
 		(b.buffer_name == g.buffer_current || m.leak_to_active);
+	// XXX: It would be great if it didn't autoscroll when focused.
 	bool to_bottom = display &&
-		buffer_at_bottom();
+		(buffer_at_bottom() || GetFocus() == g.hwndBuffer);
 	bool visible = display &&
 		to_bottom &&
 		!IsIconic(g.hwndMain) &&
@@ -1465,6 +1483,7 @@ richedit_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam,
 	{
 		// Dragging the scrollbar doesn't result in EN_VSCROLL.
 		LRESULT lResult = DefSubclassProc(hWnd, uMsg, wParam, lParam);
+		recheck_highlighted();
 		refresh_status();
 		return lResult;
 	}
@@ -1522,8 +1541,12 @@ process_resize(UINT w, UINT h)
 	MoveWindow(g.hwndBufferList, 3, top, 150, h - top - bottom, FALSE);
 	MoveWindow(g.hwndBuffer, 156, top, w - 159, h - top - bottom, FALSE);
 	MoveWindow(g.hwndBufferLog, 156, top, w - 159, h - top - bottom, FALSE);
-	if (to_bottom)
+	if (to_bottom) {
 		buffer_scroll_to_bottom();
+	} else {
+		recheck_highlighted();
+		refresh_status();
+	}
 
 	InvalidateRect(g.hwndMain, NULL, TRUE);
 }
@@ -1685,8 +1708,10 @@ window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 	}
 	case WM_SYSCOMMAND:
 	{
+		// We're not deiconified yet, so duplicate recheck_highlighted().
 		auto b = buffer_by_name(g.buffer_current);
-		if (b && wParam == SC_RESTORE) {
+		if (wParam == SC_RESTORE && b && b->highlighted && buffer_at_bottom() &&
+			!IsWindowVisible(g.hwndBufferLog)) {
 			b->highlighted = false;
 			refresh_icon();
 		}
@@ -1694,13 +1719,15 @@ window_proc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 		break;
 	}
 	case WM_COMMAND:
-		if (!lParam)
+		if (!lParam) {
 			process_accelerator(LOWORD(wParam));
-		else if (lParam == (LPARAM) g.hwndBufferList)
+		} else if (lParam == (LPARAM) g.hwndBufferList) {
 			process_bufferlist_notification(HIWORD(wParam));
-		else if (lParam == (LPARAM) g.hwndBuffer &&
-				HIWORD(wParam) == EN_VSCROLL)
+		} else if (lParam == (LPARAM) g.hwndBuffer &&
+				HIWORD(wParam) == EN_VSCROLL) {
+			recheck_highlighted();
 			refresh_status();
+		}
 		return 0;
 	case WM_NOTIFY:
 		switch (((LPNMHDR) lParam)->code) {
-- 
cgit v1.2.3-70-g09d2