diff --git a/SceneSwitcher.cpp b/SceneSwitcher.cpp index f7629eb0..9ec0d2ec 100644 --- a/SceneSwitcher.cpp +++ b/SceneSwitcher.cpp @@ -117,47 +117,6 @@ void sceneSwitcherOptionsSourceGetDefaults(obs_data_t *settings) { //set values from file obs_data_apply(settings, obs_data_create_from_json(temp.c_str())); } -bool loadOldSettings(obs_properties_t *props, obs_property_t *property, void *data) { - //read old settings - string oldPath = "../../data/obs-plugins/SceneSwitcher/settings.txt"; - ifstream oldSettingsFile; - oldSettingsFile.open(oldPath); - string line; - string value; - //construct new settings format - string newFormat = "{\n\t\"WindowList\": [\n"; - string valueBeginning = "\t\t{\n\t\t\t\"value\": \""; - string valueEnd = "\t\t},\n"; - while (oldSettingsFile.good()) - { - getline(oldSettingsFile, line); - if (!line.empty()) { - newFormat += valueBeginning + line + "\"\n" + valueEnd; - } - } - oldSettingsFile.close(); - //remove trailing ',' and newline - newFormat.pop_back(); - newFormat.pop_back(); - newFormat += "\n\t]\n}"; - //check if there are useful new settings - if (newFormat != "{\n\t\"WindowList\": \n\t]\n}") { - //write to new settings file - ofstream file(string(configPath).append("settings.txt")); - if (file.is_open()) { - file << newFormat; - file.close(); - } - //make sure not to overwrite the settings - oldSettingsLoaded = true; - if (switcher->getIsRunning()) { - switcher->stop(); - } - switcher->load(); - switcher->start(); - } - return true; -} obs_properties_t *sceneSwitcherOptionsSourceGetProperties(void *data) { UNUSED_PARAMETER(data); obs_properties_t *props = obs_properties_create(); @@ -166,7 +125,6 @@ obs_properties_t *sceneSwitcherOptionsSourceGetProperties(void *data) { "WindowList", "", (enum obs_editable_list_type)0, "", NULL); - obs_properties_add_button(props, "LoadOldSettings", "Load settings from old version of this plugin (restart OBS after clicking this button)", &loadOldSettings); return props; } void sceneSwitcherOptionsSourceSave(void *data, obs_data_t *settings) { diff --git a/switcher.cpp b/switcher.cpp index 2e84f112..1b9846a8 100644 --- a/switcher.cpp +++ b/switcher.cpp @@ -12,6 +12,7 @@ #endif #ifdef __APPLE__ #include +#include #endif using namespace std; @@ -76,7 +77,7 @@ void Switcher::switcherThreadFunc() { } //normal scene switching here else { - //get active window title and reset values + //get active window title windowname = GetActiveWindowTitle(); //should we ignore this window name? if (find(ignoreNames.begin(), ignoreNames.end(), windowname) == ignoreNames.end()) { @@ -96,46 +97,106 @@ void Switcher::switcherThreadFunc() { for (map::iterator iter = settingsMap.begin(); iter != settingsMap.end(); ++iter) { try { - regex e = regex(iter->first); - match = regex_match(windowname, e); - if (match) { + if (regex_match(windowname, regex(iter->first))) { sceneName = iter->second.sceneName; checkFullscreen = iter->second.isFullscreen; + match = true; break; } } catch (...) {} } } - //do we only switch if window is also fullscreen? - if (!checkFullscreen || (checkFullscreen && isWindowFullscreen())) { - //do we know the window title or is a fullscreen/backup Scene set? - if (!(settingsMap.find("Backup Scene Name") == settingsMap.end()) || match) { - if (!match && !(settingsMap.find("Backup Scene Name") == settingsMap.end())) { - sceneName = settingsMap.find("Backup Scene Name")->second.sceneName; - } - //check if current scene is already the desired scene - if ((sceneUsedName) && strcmp(sceneUsedName, sceneName.c_str()) != 0) { - //switch scene - obs_source_t *source = obs_get_source_by_name(sceneName.c_str()); - if (source != NULL) { - //create transition to new scene (otherwise UI wont work anymore) - obs_transition_start(transitionUsed, OBS_TRANSITION_MODE_AUTO, 300, source); //OBS_TRANSITION_MODE_AUTO uses the obs user settings for transitions + //check cursor regions + if (!match) + { + pair cursorPos = getCursorXY(); + // compare against rectangular region format + regex rules = regex("<-?[0-9]+x-?[0-9]+.-?[0-9]+x-?[0-9]+>"); + int minRegionSize = 99999; + for (map::iterator iter = settingsMap.begin(); iter != settingsMap.end(); ++iter) + { + try + { + if (regex_match(iter->first, rules)) + { + int minX, minY, maxX, maxY; + int parsedValues = sscanf(iter->first.c_str(), "<%dx%d.%dx%d>", &minX, &minY, &maxX, &maxY); + + if (parsedValues == 4) + { + if (cursorPos.first >= minX && cursorPos.second >= minY && cursorPos.first <= maxX && cursorPos.second <= maxY) + { + // prioritize smaller regions over larger regions + int regionSize = (maxX - minX) + (maxY - minY); + if (regionSize < minRegionSize) + { + match = true; + sceneName = iter->second.sceneName; + checkFullscreen = iter->second.isFullscreen; + minRegionSize = regionSize; + // break; + } + } + } } - obs_source_release(source); } - obs_source_release(sceneUsed); - obs_source_release(transitionUsed); + catch (...) {} + } + } + //do we only switch if window is also fullscreen? + match = match && (!checkFullscreen || (checkFullscreen && isWindowFullscreen())); + //match or backup scene set + if (settingsMap.find("Backup Scene Name") != settingsMap.end() || match) { + //no match -> backup scene + if (!match) { + sceneName = settingsMap.find("Backup Scene Name")->second.sceneName; + } + //check if current scene is already the desired scene + if ((sceneUsedName) && strcmp(sceneUsedName, sceneName.c_str()) != 0) { + //switch scene + obs_source_t *source = obs_get_source_by_name(sceneName.c_str()); + if (source != NULL) { + //create transition to new scene (otherwise UI wont work anymore) + obs_transition_start(transitionUsed, OBS_TRANSITION_MODE_AUTO, 300, source); //OBS_TRANSITION_MODE_AUTO uses the obs user settings for transitions + } + obs_source_release(source); } } } } - //sleep for a bit - this_thread::sleep_for(chrono::milliseconds(1000)); } + obs_source_release(sceneUsed); + obs_source_release(transitionUsed); + //sleep for a bit + this_thread::sleep_for(chrono::milliseconds(1000)); } } +#ifdef _WIN32 +pair Switcher::getCursorXY() { + pair pos(0, 0); + POINT cursorPos; + if (GetPhysicalCursorPos(&cursorPos)) { + pos.first = cursorPos.x; + pos.second = cursorPos.y; + } + return pos; +} +#endif + +#ifdef __APPLE__ +pair Switcher::getCursorXY() { + pair pos(0, 0); + CGEventRef event = CGEventCreate(NULL); + CGPoint cursorPos = CGEventGetLocation(event); + CFRelease(event); + pos.first = cursorPos.x; + pos.second = cursorPos.y; + return pos; +} +#endif + #ifdef _WIN32 void Switcher::firstLoad() { settings.load(); diff --git a/switcher.h b/switcher.h index 1470b1a4..b337e39f 100644 --- a/switcher.h +++ b/switcher.h @@ -27,4 +27,5 @@ private: void switcherThreadFunc(); bool isWindowFullscreen(); string GetActiveWindowTitle(); + pair getCursorXY(); }; \ No newline at end of file