diff --git a/CMakeLists.txt b/CMakeLists.txt index f80e9438..95643471 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -100,6 +100,7 @@ set(advanced-scene-switcher_HEADERS src/headers/macro-condition-scene.hpp src/headers/macro-condition-streaming.hpp src/headers/macro-condition-video.hpp + src/headers/macro-condition-virt-desktop.hpp src/headers/macro-condition-window.hpp src/headers/macro.hpp src/headers/curl-helper.hpp @@ -156,6 +157,7 @@ set(advanced-scene-switcher_SOURCES src/macro-condition-scene.cpp src/macro-condition-streaming.cpp src/macro-condition-video.cpp + src/macro-condition-virt-desktop.cpp src/macro-condition-window.cpp src/macro.cpp src/macro-tab.cpp diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 9524bfaa..c3717944 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -122,6 +122,8 @@ AdvSceneSwitcher.condition.idle.entry="No keyboard or mouse inputs for {{duratio AdvSceneSwitcher.condition.pluginState="Plugin state" AdvSceneSwitcher.condition.pluginState.state.sceneSwitched="Automated scene change was triggered in this interval" AdvSceneSwitcher.condition.pluginState.entry="{{condition}}" +AdvSceneSwitcher.condition.virtDesktop="Virtual desktop" +AdvSceneSwitcher.condition.virtDesktop.entry="Currently active virtual desktop is {{virtDesktops}}" ; Macro Actions AdvSceneSwitcher.action.switchScene="Switch scene" diff --git a/src/headers/advanced-scene-switcher.hpp b/src/headers/advanced-scene-switcher.hpp index 737cd3b5..217acfab 100644 --- a/src/headers/advanced-scene-switcher.hpp +++ b/src/headers/advanced-scene-switcher.hpp @@ -284,6 +284,8 @@ void GetWindowList(QStringList &windows); void GetCurrentWindowTitle(std::string &title); bool isFullscreen(std::string &title); bool isMaximized(std::string &title); +bool GetCurrentVirtualDesktop(long &desktop); +bool GetVirtualDesktopCount(long &ndesktops); /****************************************************************************** * Screenregion helper diff --git a/src/headers/macro-condition-virt-desktop.hpp b/src/headers/macro-condition-virt-desktop.hpp new file mode 100644 index 00000000..52fdf7e2 --- /dev/null +++ b/src/headers/macro-condition-virt-desktop.hpp @@ -0,0 +1,48 @@ +#pragma once +#include "macro.hpp" +#include +#include + +class MacroConditionVirtDesktop : public MacroCondition { +public: + bool CheckCondition(); + bool Save(obs_data_t *obj); + bool Load(obs_data_t *obj); + int GetId() { return id; }; + static std::shared_ptr Create() + { + return std::make_shared(); + } + long _desktop = 0; + +private: + static bool _registered; + static const int id; +}; + +class MacroConditionVirtDesktopEdit : public QWidget { + Q_OBJECT + +public: + MacroConditionVirtDesktopEdit( + QWidget *parent, + std::shared_ptr cond = nullptr); + void UpdateEntryData(); + static QWidget *Create(QWidget *parent, + std::shared_ptr cond) + { + return new MacroConditionVirtDesktopEdit( + parent, + std::dynamic_pointer_cast(cond)); + } + +private slots: + void DesktopChanged(int value); + +protected: + QComboBox *_virtDesktops; + std::shared_ptr _entryData; + +private: + bool _loading = true; +}; diff --git a/src/linux/advanced-scene-switcher-nix.cpp b/src/linux/advanced-scene-switcher-nix.cpp index 9f1c1db3..90766c18 100644 --- a/src/linux/advanced-scene-switcher-nix.cpp +++ b/src/linux/advanced-scene-switcher-nix.cpp @@ -393,3 +393,67 @@ int secondsSinceLastInput() return idle_time; } + +static bool GetCurrentVirtualDesktop(long &desktop) +{ + Atom type; + long unsigned nitems; + long unsigned int bytes = 0; + int format = 0; + unsigned char *data; + Window root; + Atom request; + Display *display = disp(); + + //TODO check for _NET_CURRENT_DESKTOP + if (!ewmhIsSupported()) { + return false; + } + + request = XInternAtom(display, "_NET_CURRENT_DESKTOP", False); + root = XDefaultRootWindow(display); + + int status = XGetWindowProperty(display, root, request, 0L, 1L, false, + XA_CARDINAL, &type, &format, &nitems, + &bytes, &data); + + if (status == Success && nitems > 0) { + desktop = *((long *)data); + } else { + desktop = -1; + } + free(data); + return desktop != -1; +} + +static bool GetVirtualDesktopCount(long &ndesktops) +{ + Atom type; + long unsigned nitems; + long unsigned int bytes = 0; + int format = 0; + unsigned char *data; + Window root; + Atom request; + Display *display = disp(); + + //TODO check for _NET_NUMBER_OF_DESKTOPS + if (!ewmhIsSupported()) { + return false; + } + + request = XInternAtom(display, "_NET_CURRENT_DESKTOP", False); + root = XDefaultRootWindow(display); + + int status = XGetWindowProperty(display, root, request, 0L, 1L, false, + XA_CARDINAL, &type, &format, &nitems, + &bytes, &data); + + if (status == Success && nitems > 0) { + ndesktops = *((long *)data); + } else { + ndesktops = 0; + } + free(data); + return ndesktops != 0; +} diff --git a/src/macro-condition-virt-desktop.cpp b/src/macro-condition-virt-desktop.cpp new file mode 100644 index 00000000..a7492c3a --- /dev/null +++ b/src/macro-condition-virt-desktop.cpp @@ -0,0 +1,87 @@ +#include "headers/macro-condition-edit.hpp" +#include "headers/macro-condition-virt-desktop.hpp" +#include "headers/utility.hpp" +#include "headers/advanced-scene-switcher.hpp" + +const int MacroConditionVirtDesktop::id = 12; + +bool MacroConditionVirtDesktop::_registered = MacroConditionFactory::Register( + MacroConditionVirtDesktop::id, + {MacroConditionVirtDesktop::Create, + MacroConditionVirtDesktopEdit::Create, + "AdvSceneSwitcher.condition.virtDesktop"}); + +bool MacroConditionVirtDesktop::CheckCondition() +{ + long curDesktop; + GetCurrentVirtualDesktop(curDesktop); + return _desktop == curDesktop; +} + +bool MacroConditionVirtDesktop::Save(obs_data_t *obj) +{ + MacroCondition::Save(obj); + obs_data_set_int(obj, "desktop", static_cast(_desktop)); + return true; +} + +bool MacroConditionVirtDesktop::Load(obs_data_t *obj) +{ + MacroCondition::Load(obj); + _desktop = obs_data_get_int(obj, "desktop"); + return true; +} + +static void populateVirtualDesktopSelection(QComboBox *list) +{ + long count; + GetVirtualDesktopCount(count); + + for (long i = 0; i < count; i++) { + list->addItem(std::to_string(i).c_str()); + } +} + +MacroConditionVirtDesktopEdit::MacroConditionVirtDesktopEdit( + QWidget *parent, std::shared_ptr entryData) + : QWidget(parent) +{ + _virtDesktops = new QComboBox(); + + QWidget::connect(_virtDesktops, SIGNAL(currentIndexChanged(int)), this, + SLOT(DesktopChanged(int))); + + QHBoxLayout *mainLayout = new QHBoxLayout; + + std::unordered_map widgetPlaceholders = { + {"{{virtDesktops}}", _virtDesktops}, + }; + + placeWidgets( + obs_module_text("AdvSceneSwitcher.condition.virtDesktop.entry"), + mainLayout, widgetPlaceholders); + setLayout(mainLayout); + + _entryData = entryData; + UpdateEntryData(); + _loading = false; +} + +void MacroConditionVirtDesktopEdit::DesktopChanged(int value) +{ + if (_loading || !_entryData) { + return; + } + + std::lock_guard lock(switcher->m); + _entryData->_desktop = value; +} + +void MacroConditionVirtDesktopEdit::UpdateEntryData() +{ + if (!_entryData) { + return; + } + + _virtDesktops->setCurrentIndex(_entryData->_desktop); +} diff --git a/src/osx/advanced-scene-switcher-osx.mm b/src/osx/advanced-scene-switcher-osx.mm index 1bb0c578..4f9bccb0 100644 --- a/src/osx/advanced-scene-switcher-osx.mm +++ b/src/osx/advanced-scene-switcher-osx.mm @@ -247,3 +247,13 @@ bool isInFocus(const QString &executable) return (equals || matches); } + +bool GetCurrentVirtualDesktop(long &desktop) +{ + return false; +} + +bool GetVirtualDesktopCount(long &ndesktops) +{ + return false; +} diff --git a/src/win/advanced-scene-switcher-win.cpp b/src/win/advanced-scene-switcher-win.cpp index 02e64712..c6f0dd34 100644 --- a/src/win/advanced-scene-switcher-win.cpp +++ b/src/win/advanced-scene-switcher-win.cpp @@ -285,3 +285,13 @@ int secondsSinceLastInput() { return (getTime() - getLastInputTime()) / 1000; } + +bool GetCurrentVirtualDesktop(long &desktop) +{ + return false; +} + +bool GetVirtualDesktopCount(long &ndesktops) +{ + return false; +}