diff dep/animia/src/animia.cc @ 152:8700806c2cc2

dep/animia: awesome new breaking changes! I'm so tired
author Paper <mrpapersonic@gmail.com>
date Wed, 15 Nov 2023 02:34:59 -0500
parents aa4df5a84338
children bd439dd6ffc5
line wrap: on
line diff
--- a/dep/animia/src/animia.cc	Tue Nov 14 16:31:21 2023 -0500
+++ b/dep/animia/src/animia.cc	Wed Nov 15 02:34:59 2023 -0500
@@ -3,51 +3,90 @@
 #include <set>
 
 #include "animia.h"
+#include "animia/util.h"
 #include "animia/strategies.h"
 #include "animia/types.h"
 #include "animia/fd.h"
+#include "animia/win.h"
+
+#include <iostream>
 
 namespace animia {
 
-static bool ProcessInPlayers(const std::vector<Player>& players, std::string name, Player& player_) {
-	for (const auto& player : players) {
-		for (const auto& exe : player.executables) {
-			/* this is only really relevant on Windows, and even then
-			   executables can end in any number of extensions, so we should
-			   really remove them all... */
-			auto pos = name.rfind(".exe");
-			if (pos != std::string::npos)
-				name = name.substr(0, pos);
+namespace internal {
+
+static bool IsExecutableInList(const Player& player, const std::string& name) {
+	std::string stem;
+#ifdef WIN32
+	if (!util::Stem(name, stem))
+#endif
+		stem = name;
+
+	for (const auto& pattern : player.executables)
+		if (util::CheckPattern(pattern, stem))
+			return true;
 
-			if (exe == name) {
-				player_ = player;
-				return true;
-			}
-		}
+	return false;
+}
+
+static bool IsWindowInList(const Player& player, const std::string& name) {
+	for (const auto& pattern : player.windows)
+		if (util::CheckPattern(pattern, name))
+			return true;
+
+	return false;
+}
+
+static bool PlayerHasStrategy(const Player& player, const Strategy& strategy) {
+	for (const auto& pstrategy : player.strategies) {
+		if (pstrategy == strategy)
+			return true;
 	}
 	return false;
 }
 
+} // namespace internal
+
 bool GetResults(const std::vector<Player>& players, std::vector<Result>& results) {
-	std::set<internal::pid_t> pids;
+	/* Start out with file descriptors. */
+	auto process_proc = [&](const Process& process) -> bool {
+		for (const auto& player : players) {
+			if (!internal::PlayerHasStrategy(player, Strategy::OpenFiles))
+				continue;
 
-	if (!internal::fd.GetAllPids(pids))
+			if (!internal::IsExecutableInList(player, process.name))
+				continue;
+
+			results.push_back({ResultType::Process, player, process, {}, {}});
+			break;
+		}
+		return true;
+	};
+
+	if (!internal::fd.EnumerateOpenProcesses(process_proc))
 		return false;
 
-	for (const auto& pid : pids) {
-		std::string name;
-		internal::fd.GetProcessName(pid, name);
+	/* Then add our cool windows.
+	   Note: X11 is stupid and there's no reliable way to get a PID from a given window.
+	         This is because some windows might not even have a process attached to them.
+	         We should set the PID of the process if we can get it, but that'll be for when
+	         I can actually be arsed to implement the X11 backend. */
+	auto window_proc = [&](const Process& process, const Window& window) -> bool {
+		for (const auto& player : players) {
+			if (!internal::PlayerHasStrategy(player, Strategy::WindowTitle))
+				continue;
 
-		Player player;
-		if (!ProcessInPlayers(players, name, player))
-			continue;
+			if (!internal::IsWindowInList(player, window.class_name))
+				continue;
 
-		Result result;
-		result.process.pid = pid;
-		result.process.name = name;
-		result.player = player;
-		results.push_back(result);
-	}
+			results.push_back({ResultType::Window, player, process, window, {}});
+			break;
+		}
+		return true;
+	};
+
+	if (!internal::win.EnumerateWindows(window_proc))
+		return false;
 
 	return internal::ApplyStrategies(results);
 }