diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini
index 8f8e28860..64aa00c56 100644
--- a/data/locale/en-US.ini
+++ b/data/locale/en-US.ini
@@ -770,6 +770,9 @@ AdvSceneSwitcher.condition.streamDeck.startListen="Start listening"
AdvSceneSwitcher.condition.streamDeck.stopListen="Stop listening"
AdvSceneSwitcher.condition.streamDeck.pluginDownload="
The Stream Deck plugin can be found here on GitHub.
"
+AdvSceneSwitcher.condition.screenshot="Screenshot"
+AdvSceneSwitcher.condition.screenshot.entry="A screenshot was taken"
+
# Macro Actions
AdvSceneSwitcher.action.unknown="Unknown action"
AdvSceneSwitcher.action.scene="Switch scene"
@@ -1971,6 +1974,9 @@ AdvSceneSwitcher.tempVar.queue.size="Size"
AdvSceneSwitcher.tempVar.queue.running="Is running"
AdvSceneSwitcher.tempVar.queue.running.description="Returns \"true\" if the queue is started and \"false\" if it is stopped."
+AdvSceneSwitcher.tempVar.screenshot.lastScreenshotPath="Last screenshot path"
+AdvSceneSwitcher.tempVar.screenshot.lastScreenshotPath.description="The filesystem path to the last screenshot taken."
+
AdvSceneSwitcher.selectScene="--select scene--"
AdvSceneSwitcher.selectPreviousScene="Previous Scene"
AdvSceneSwitcher.selectCurrentScene="Current Scene"
diff --git a/plugins/base/CMakeLists.txt b/plugins/base/CMakeLists.txt
index f2ec114b0..7997700de 100644
--- a/plugins/base/CMakeLists.txt
+++ b/plugins/base/CMakeLists.txt
@@ -117,6 +117,8 @@ target_sources(
macro-condition-scene-visibility.hpp
macro-condition-scene.cpp
macro-condition-scene.hpp
+ macro-condition-screenshot.cpp
+ macro-condition-screenshot.hpp
macro-condition-slideshow.cpp
macro-condition-slideshow.hpp
macro-condition-source.cpp
diff --git a/plugins/base/macro-condition-screenshot.cpp b/plugins/base/macro-condition-screenshot.cpp
new file mode 100644
index 000000000..faa15d01d
--- /dev/null
+++ b/plugins/base/macro-condition-screenshot.cpp
@@ -0,0 +1,94 @@
+#include "macro-condition-screenshot.hpp"
+#include "layout-helpers.hpp"
+
+#include
+#include
+
+namespace advss {
+
+const std::string MacroConditionScreenshot::id = "screenshot";
+
+#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(29, 0, 0)
+bool MacroConditionScreenshot::_registered = MacroConditionFactory::Register(
+ MacroConditionScreenshot::id,
+ {MacroConditionScreenshot::Create, MacroConditionScreenshotEdit::Create,
+ "AdvSceneSwitcher.condition.screenshot"});
+#endif
+
+static std::chrono::high_resolution_clock::time_point screenshotTakenTime{};
+static bool setupScreenshotTakenEventHandler();
+static bool setupDone = setupScreenshotTakenEventHandler();
+
+static bool setupScreenshotTakenEventHandler()
+{
+ static auto handleScreenshotEvent = [](enum obs_frontend_event event,
+ void *) {
+ switch (event) {
+#if LIBOBS_API_VER >= MAKE_SEMANTIC_VERSION(29, 0, 0)
+ case OBS_FRONTEND_EVENT_SCREENSHOT_TAKEN:
+ screenshotTakenTime =
+ std::chrono::high_resolution_clock::now();
+ break;
+#endif
+ default:
+ break;
+ };
+ };
+ obs_frontend_add_event_callback(handleScreenshotEvent, nullptr);
+ return true;
+}
+
+bool MacroConditionScreenshot::CheckCondition()
+{
+ if (!_screenshotTimeInitialized) {
+ _screenshotTime = screenshotTakenTime;
+ _screenshotTimeInitialized = true;
+ return false;
+ }
+
+ auto lastScreenshotPath = obs_frontend_get_last_screenshot();
+ SetTempVarValue("lastScreenshotPath", lastScreenshotPath);
+ bfree(lastScreenshotPath);
+
+ bool newSaveOccurred = _screenshotTime != screenshotTakenTime;
+ _screenshotTime = screenshotTakenTime;
+ return newSaveOccurred;
+}
+
+bool MacroConditionScreenshot::Save(obs_data_t *obj) const
+{
+ MacroCondition::Save(obj);
+ return true;
+}
+
+bool MacroConditionScreenshot::Load(obs_data_t *obj)
+{
+ MacroCondition::Load(obj);
+ return true;
+}
+
+void MacroConditionScreenshot::SetupTempVars()
+{
+ MacroCondition::SetupTempVars();
+ AddTempvar(
+ "lastScreenshotPath",
+ obs_module_text(
+ "AdvSceneSwitcher.tempVar.screenshot.lastScreenshotPath"),
+ obs_module_text(
+ "AdvSceneSwitcher.tempVar.screenshot.lastScreenshotPath.description"));
+}
+
+MacroConditionScreenshotEdit::MacroConditionScreenshotEdit(
+ QWidget *parent, std::shared_ptr entryData)
+ : QWidget(parent)
+{
+ auto layout = new QHBoxLayout;
+ PlaceWidgets(
+ obs_module_text("AdvSceneSwitcher.condition.screenshot.entry"),
+ layout, {});
+ setLayout(layout);
+
+ _entryData = entryData;
+}
+
+} // namespace advss
diff --git a/plugins/base/macro-condition-screenshot.hpp b/plugins/base/macro-condition-screenshot.hpp
new file mode 100644
index 000000000..4af926236
--- /dev/null
+++ b/plugins/base/macro-condition-screenshot.hpp
@@ -0,0 +1,50 @@
+#pragma once
+#include "macro-condition-edit.hpp"
+
+#include
+#include
+
+namespace advss {
+
+class MacroConditionScreenshot : public MacroCondition {
+public:
+ MacroConditionScreenshot(Macro *m) : MacroCondition(m) {}
+ bool CheckCondition();
+ bool Save(obs_data_t *obj) const;
+ bool Load(obs_data_t *obj);
+ std::string GetId() const { return id; };
+ static std::shared_ptr Create(Macro *m)
+ {
+ return std::make_shared(m);
+ }
+
+private:
+ void SetupTempVars();
+
+ bool _screenshotTimeInitialized = false;
+ std::chrono::high_resolution_clock::time_point _screenshotTime = {};
+ static bool _registered;
+ static const std::string id;
+};
+
+class MacroConditionScreenshotEdit : public QWidget {
+ Q_OBJECT
+
+public:
+ MacroConditionScreenshotEdit(
+ QWidget *parent,
+ std::shared_ptr cond = nullptr);
+ static QWidget *Create(QWidget *parent,
+ std::shared_ptr cond)
+ {
+ return new MacroConditionScreenshotEdit(
+ parent,
+ std::dynamic_pointer_cast(
+ cond));
+ }
+
+private:
+ std::shared_ptr _entryData;
+};
+
+} // namespace advss