From 9cd78a403ce18b1c475b2b141a75a78deb820ee6 Mon Sep 17 00:00:00 2001 From: WarmUpTill Date: Wed, 13 Jul 2016 00:08:39 +0200 Subject: [PATCH] Fixed crash when only one value per line was, added Scene Round Trip option --- SceneSwitcher.cpp | 83 ++++++------- settings.cpp | 101 ++++++++++------ settings.h | 4 +- switcher.cpp | 290 +++++++++++++++++++++++++--------------------- switcher.h | 2 + 5 files changed, 265 insertions(+), 215 deletions(-) diff --git a/SceneSwitcher.cpp b/SceneSwitcher.cpp index 7e64489a..f7629eb0 100644 --- a/SceneSwitcher.cpp +++ b/SceneSwitcher.cpp @@ -32,17 +32,18 @@ void saveKeybinding(string name, obs_data_array_t *hotkeyData) { ofstream file; file.open(string(configPath).append(name), ofstream::trunc); //hotkeyData = obs_hotkey_save(pauseHotkeyId); //doesnt seem to work in obs_module_unload (hotkey data freed already (<- Jim)) - size_t num = obs_data_array_count(hotkeyData); - for (size_t i = 0; i < num; i++) { - string temp = obs_data_get_json(obs_data_array_item(hotkeyData, i)); - file << temp; + if (file.is_open()) { + size_t num = obs_data_array_count(hotkeyData); + for (size_t i = 0; i < num; i++) { + string temp = obs_data_get_json(obs_data_array_item(hotkeyData, i)); + file << temp; + } + file.close(); } - file.close(); } } -string loadConfigFile(string filename) -{ +string loadConfigFile(string filename) { ifstream settingsFile; settingsFile.open(string(configPath).append(filename)); string value; @@ -52,8 +53,8 @@ string loadConfigFile(string filename) value.reserve(settingsFile.tellg()); settingsFile.seekg(0, ios::beg); value.assign((istreambuf_iterator(settingsFile)), istreambuf_iterator()); + settingsFile.close(); } - settingsFile.close(); return value; } @@ -70,8 +71,7 @@ void loadKeybinding(string name, obs_data_array_t *hotkeyData, obs_hotkey_id hot OBS_DECLARE_MODULE() OBS_MODULE_USE_DEFAULT_LOCALE("SceneSwitcher", "en-US") -void SceneSwitcherPauseHotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed) -{ +void SceneSwitcherPauseHotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey, bool pressed) { UNUSED_PARAMETER(id); UNUSED_PARAMETER(hotkey); @@ -91,8 +91,7 @@ void SceneSwitcherPauseHotkey(void *data, obs_hotkey_id id, obs_hotkey_t *hotkey pauseHotkeyData = obs_hotkey_save(pauseHotkeyId); } -const char *sceneSwitcherOptionsGetName(void *type_data) -{ +const char *sceneSwitcherOptionsGetName(void *type_data) { UNUSED_PARAMETER(type_data); return "Scene Switcher Options"; } @@ -104,25 +103,21 @@ void *sceneSwitcherOptionsCreate(obs_data_t *settings, obs_source_t *source) { void sceneSwitcherOptionsDestroy(void *data) { UNUSED_PARAMETER(data); } -uint32_t sceneSwitcherOptionsGetWidth(void *data) -{ +uint32_t sceneSwitcherOptionsGetWidth(void *data) { UNUSED_PARAMETER(data); return 0; } -uint32_t sceneSwitcherOptionsGetHeight(void *data) -{ +uint32_t sceneSwitcherOptionsGetHeight(void *data) { UNUSED_PARAMETER(data); return 0; } -void sceneSwitcherOptionsSourceGetDefaults(obs_data_t *settings) -{ +void sceneSwitcherOptionsSourceGetDefaults(obs_data_t *settings) { //load settings file string temp = loadConfigFile("settings.txt"); //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) -{ +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; @@ -137,8 +132,8 @@ bool loadOldSettings(obs_properties_t *props, obs_property_t *property, void *da { getline(oldSettingsFile, line); if (!line.empty()) { - newFormat += valueBeginning + line + "\"\n" + valueEnd; - } + newFormat += valueBeginning + line + "\"\n" + valueEnd; + } } oldSettingsFile.close(); //remove trailing ',' and newline @@ -148,10 +143,11 @@ bool loadOldSettings(obs_properties_t *props, obs_property_t *property, void *da //check if there are useful new settings if (newFormat != "{\n\t\"WindowList\": \n\t]\n}") { //write to new settings file - ofstream file; - file.open(string(configPath).append("settings.txt")); - file << newFormat; - file.close(); + 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()) { @@ -162,11 +158,10 @@ bool loadOldSettings(obs_properties_t *props, obs_property_t *property, void *da } return true; } -obs_properties_t *sceneSwitcherOptionsSourceGetProperties(void *data) -{ +obs_properties_t *sceneSwitcherOptionsSourceGetProperties(void *data) { UNUSED_PARAMETER(data); obs_properties_t *props = obs_properties_create(); - obs_properties_add_bool(props,"StartMessageDisable","Disable Start Message"); + obs_properties_add_bool(props, "StartMessageDisable", "Disable Start Message"); obs_properties_add_editable_list(props, "WindowList", "", (enum obs_editable_list_type)0, "", @@ -174,8 +169,7 @@ obs_properties_t *sceneSwitcherOptionsSourceGetProperties(void *data) 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) -{ +void sceneSwitcherOptionsSourceSave(void *data, obs_data_t *settings) { //check if user chose to load old settings if (oldSettingsLoaded) { //oldSettingsLoaded = false; @@ -184,16 +178,17 @@ void sceneSwitcherOptionsSourceSave(void *data, obs_data_t *settings) //hang here if multiple instances of Scene Switcher Options are active (why?) ofstream settingsFile; settingsFile.open(string(configPath).append("settings.txt"), ofstream::trunc); - settingsFile << obs_data_get_json(settings); - settingsFile.close(); + if (settingsFile.is_open()) { + settingsFile << obs_data_get_json(settings); + settingsFile.close(); + } if (switcher->getIsRunning()) switcher->stop(); switcher->load(); switcher->start(); } } -void sceneSwitcherOptionsSourceLoad(void *data, obs_data_t *settings) -{ +void sceneSwitcherOptionsSourceLoad(void *data, obs_data_t *settings) { UNUSED_PARAMETER(data); //load settings file string temp = loadConfigFile("settings.txt"); @@ -201,8 +196,7 @@ void sceneSwitcherOptionsSourceLoad(void *data, obs_data_t *settings) obs_data_apply(settings, obs_data_create_from_json(temp.c_str())); } -void sceneSwitcherOptionsSourceSetup() -{ +void sceneSwitcherOptionsSourceSetup() { sceneSwitcherOptionsSource.id = "Scene Switcher Options"; sceneSwitcherOptionsSource.type = OBS_SOURCE_TYPE_INPUT; sceneSwitcherOptionsSource.get_name = sceneSwitcherOptionsGetName; @@ -212,14 +206,12 @@ void sceneSwitcherOptionsSourceSetup() sceneSwitcherOptionsSource.get_height = sceneSwitcherOptionsGetHeight; sceneSwitcherOptionsSource.get_defaults = sceneSwitcherOptionsSourceGetDefaults; //create settings file if not present sceneSwitcherOptionsSource.get_properties = sceneSwitcherOptionsSourceGetProperties; - sceneSwitcherOptionsSource.save = sceneSwitcherOptionsSourceSave; //save new settings to file + sceneSwitcherOptionsSource.update = sceneSwitcherOptionsSourceSave; //save new settings to file sceneSwitcherOptionsSource.load = sceneSwitcherOptionsSourceLoad; //read settings file - obs_register_source(&sceneSwitcherOptionsSource); } -bool obs_module_load(void) -{ +bool obs_module_load(void) { //set config path and check if config dir was set up configPath = obs_module_config_path(""); boost::filesystem::create_directories(configPath); @@ -246,17 +238,14 @@ void obs_module_unload(void) { //saveKeybinding(OPTIONS_HOTKEY_NAME, optionsHotkeyData); } -const char *obs_module_author(void) -{ +const char *obs_module_author(void) { return "WarmUpTill"; } -const char *obs_module_name(void) -{ +const char *obs_module_name(void) { return "Scene Switcher"; } -const char *obs_module_description(void) -{ +const char *obs_module_description(void) { return "Automatic scene switching"; } diff --git a/settings.cpp b/settings.cpp index be340bad..4a7a13d4 100644 --- a/settings.cpp +++ b/settings.cpp @@ -19,8 +19,9 @@ void Settings::setSettingsFilePath(string path) } void Settings::load() { - //clear settings map - settings = map (); + //reset the settings + settings = map(); + sceneRoundTrip = vector(); //read the settings file vector settingsElements; ifstream infile(settingsFilePath); @@ -39,59 +40,83 @@ void Settings::load() { //disable the start message? if (!startMessageDisableFound) { pos = line.find("\"StartMessageDisable\": "); - if (pos != line.npos) { - startMessageDisableFound = true; - startMessageDisable = line.find("true") == line.npos ? false : true; - } + if (pos != line.npos) { + startMessageDisableFound = true; + startMessageDisable = line.find("true") == line.npos ? false : true; + } } - //get switcher info + //read values of the "editable list" UI element pos = line.find("\"value\":"); - if (!line.empty() && pos != string::npos) { - string temp = line.substr(pos + 10, string::npos - 1); - temp.pop_back(); + if (!line.empty() && pos != line.npos) { + string temp = line.substr(pos + 10, line.npos - 1); stringstream lineStream = stringstream(temp); numValues = 0; - while (lineStream.good()) { + //find Scene Round Trip + if (temp.find("Scene Round Trip") != temp.npos) { + + //discard the first value ("Scene Round Trip") getline(lineStream, value, ','); - settingsElements.push_back(value); - numValues++; + while (lineStream.good()) { + //Scene Round Trip,TriggerSceneHere,DelayHere,NextSceneHere,DelayHere,AnotherSceneHere,DelayHere,... + getline(lineStream, value, ','); + sceneRoundTrip.push_back(value); + } + //remove trailing /" of last value + if (sceneRoundTrip.size() > 0) { + sceneRoundTrip.back().pop_back(); + } + if (sceneRoundTrip.size() == 0 || sceneRoundTrip.size() % 2 != 0) { + sceneRoundTrip.push_back(""); + } } - //two values per line are expected - //add missing value - if(numValues < 3) { - settingsElements.push_back(""); - } - //discard additional values - for (numValues; numValues > 3; numValues--) { + //find values for Scene switching + else + { + //windowTitle,sceneName,isFullscreenValue + while (lineStream.good()) { + getline(lineStream, value, ','); + settingsElements.push_back(value); + numValues++; + } + //two values per line are expected + //add missing value + if (numValues < 3) { + settingsElements.push_back(""); + } + //discard additional values + for (numValues; numValues > 3; numValues--) { + settingsElements.pop_back(); + } + + //assing to data + Data d = Data(); + string isFullscreen = settingsElements.back(); + d.isFullscreen = (isFullscreen.find("isFullscreen") != isFullscreen.npos) ? true : false; + //dont remove an element if isFullscreen was not found + if (d.isFullscreen) { + settingsElements.pop_back(); + } + string sceneName = settingsElements.back(); + d.sceneName = sceneName; + settingsElements.pop_back(); + string windowName = settingsElements.back(); + settings.insert(pair(windowName, d)); settingsElements.pop_back(); } - - //assing to data - Data d = Data(); - string isFullscreen = settingsElements.back(); - d.isFullscreen = (isFullscreen.find("isFullscreen") == string::npos) ? false : true; - settingsElements.pop_back(); - string sceneName = settingsElements.back(); - d.sceneName = sceneName; - settingsElements.pop_back(); - string windowName = settingsElements.back(); - Settings::addToMap(windowName,d); - settingsElements.pop_back(); } } infile.close(); } -bool Settings::getStartMessageDisable() -{ +bool Settings::getStartMessageDisable(){ return startMessageDisable; } -void Settings::addToMap(string s1, Data s2) { - settings.insert(pair(s1, s2)); -} - map Settings::getMap() { return settings; } +vector Settings::getSceneRoundTrip(){ + return sceneRoundTrip; +} + diff --git a/settings.h b/settings.h index ae87cc05..a53f6c7c 100644 --- a/settings.h +++ b/settings.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include @@ -11,15 +12,16 @@ struct Data { }; class Settings { + vector sceneRoundTrip; map settings; bool startMessageDisable = false; public: void load(); bool getStartMessageDisable(); map getMap(); + vector getSceneRoundTrip(); string getSettingsFilePath(); void setSettingsFilePath(string path); private: string settingsFilePath = ""; - void addToMap(string, Data); }; diff --git a/switcher.cpp b/switcher.cpp index 1aca7c2d..d12a0ae4 100644 --- a/switcher.cpp +++ b/switcher.cpp @@ -7,85 +7,114 @@ #include #include "switcher.h" #ifdef _WIN32 - #define NOMINMAX - #include +#define NOMINMAX +#include #endif #ifdef __APPLE__ - #include +#include #endif using namespace std; //scene switching is done in here void Switcher::switcherThreadFunc() { + bool sceneRoundTripActive = false; + size_t roundTripPos = 0; + bool match = false; + string windowname = ""; + string sceneName = ""; + bool checkFullscreen = false; while (isRunning) { - //get active window title - string windowname = GetActiveWindowTitle(); - bool match = false; - string name = ""; - bool checkFullscreen = false; - //first check if there is a direct match - map::iterator it = settingsMap.find(windowname); - if (it != settingsMap.end()) { - name = it->second.sceneName; - checkFullscreen = it->second.isFullscreen; - match = true; + //get Scene Name + obs_source_t * transitionUsed = obs_get_output_source(0); + obs_source_t * sceneUsed = obs_transition_get_active_source(transitionUsed); + const char *sceneUsedName = obs_source_get_name(sceneUsed); + //check if a Scene Round Trip should be started + if ((sceneUsedName) && strcmp(sceneUsedName, sceneRoundTrip.front().c_str()) == 0) { + sceneRoundTripActive = true; + roundTripPos = 1; } - else { - for (map::iterator iter = settingsMap.begin(); iter != settingsMap.end(); ++iter) - { - try - { - regex e = regex(iter->first); - match = regex_match(windowname, e); - if (match) { - name = iter->second.sceneName; - checkFullscreen = iter->second.isFullscreen; - break; - } - } - catch (...) - { - - } + if (sceneRoundTripActive) { + //get delay and wait + try { + this_thread::sleep_for(chrono::milliseconds(1000 * stoi(sceneRoundTrip.at(roundTripPos), nullptr, 10))); } - } - //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())) { - name = settingsMap.find("Backup Scene Name")->second.sceneName; - } + catch (...) { + //just wait for 3 seconds if value was not set properly + this_thread::sleep_for(chrono::milliseconds(3000)); + } + //are we done with the Scene Round trip? + if (roundTripPos + 1 >= sceneRoundTrip.size()) { + sceneRoundTripActive = false; + roundTripPos = 0; + } + else { + //switch scene + sceneName = sceneRoundTrip.at(roundTripPos + 1); obs_source_t * transitionUsed = obs_get_output_source(0); - obs_source_t * sceneUsed = obs_transition_get_active_source(transitionUsed); - const char *sceneUsedName = obs_source_get_name(sceneUsed); - //check if current scene is already the desired scene - if ((sceneUsedName) && strcmp(sceneUsedName, name.c_str()) != 0) { - //switch scene - obs_source_t *source = obs_get_source_by_name(name.c_str()); - if (source == NULL) - { - //warn("Source not found: \"%s\"", name); - ; - } - else if (obs_scene_from_source(source) == NULL) - { - //warn("\"%s\" is not a scene", name); - ; - } - else { - //create transition to new scene (otherwise UI wont work anymore) - //OBS_TRANSITION_MODE_AUTO uses the obs user settings for transitions - obs_transition_start(transitionUsed, OBS_TRANSITION_MODE_AUTO, 300, source); - } - obs_source_release(source); + obs_source_t *source = obs_get_source_by_name(sceneName.c_str()); + if (source != NULL) { + //create transition to new scene + obs_transition_start(transitionUsed, OBS_TRANSITION_MODE_AUTO, 300, source); //OBS_TRANSITION_MODE_AUTO uses the obs user settings for transitions } - obs_source_release(sceneUsed); - obs_source_release(transitionUsed); + obs_source_release(source); + //prepare for next sceneName,Delay pair + roundTripPos += 2; } } - //sleep for a bit - this_thread::sleep_for(chrono::milliseconds(1000)); + //normal scene switching here + else { + //get active window title and reset values + windowname = GetActiveWindowTitle(); + match = false; + sceneName = ""; + checkFullscreen = false; + //first check if there is a direct match + map::iterator it = settingsMap.find(windowname); + if (it != settingsMap.end()) { + sceneName = it->second.sceneName; + checkFullscreen = it->second.isFullscreen; + match = true; + } + else { + //maybe there is a regular expression match + for (map::iterator iter = settingsMap.begin(); iter != settingsMap.end(); ++iter) + { + try { + regex e = regex(iter->first); + match = regex_match(windowname, e); + if (match) { + sceneName = iter->second.sceneName; + checkFullscreen = iter->second.isFullscreen; + 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 + } + obs_source_release(source); + } + obs_source_release(sceneUsed); + obs_source_release(transitionUsed); + } + } + //sleep for a bit + this_thread::sleep_for(chrono::milliseconds(1000)); + } } } @@ -93,6 +122,7 @@ void Switcher::switcherThreadFunc() { void Switcher::firstLoad() { settings.load(); settingsMap = settings.getMap(); + sceneRoundTrip = settings.getSceneRoundTrip(); if (!settings.getStartMessageDisable()) { string message = "The following settings were found for Scene Switcher:\n"; for (auto it = settingsMap.cbegin(); it != settingsMap.cend(); ++it) @@ -107,33 +137,34 @@ void Switcher::firstLoad() { #ifdef __APPLE__ void Switcher::firstLoad() { - settings.load(); - settingsMap = settings.getMap(); - if (!settings.getStartMessageDisable()) { - string message = "The following settings were found for Scene Switcher:\n"; - for (auto it = settingsMap.cbegin(); it != settingsMap.cend(); ++it) - { - message += (it->first) + " -> " + it->second.sceneName + "\n"; - } + settings.load(); + settingsMap = settings.getMap(); + sceneRoundTrip = settings.getSceneRoundTrip(); + if (!settings.getStartMessageDisable()) { + string message = "The following settings were found for Scene Switcher:\n"; + for (auto it = settingsMap.cbegin(); it != settingsMap.cend(); ++it) + { + message += (it->first) + " -> " + it->second.sceneName + "\n"; + } message += "\n(settings file located at: " + settings.getSettingsFilePath() + ")"; - SInt32 nRes = 0; - CFUserNotificationRef pDlg = NULL; - const void* keys[] = { kCFUserNotificationAlertHeaderKey, - kCFUserNotificationAlertMessageKey }; - const void* vals[] = { - CFSTR("Test Foundation Message Box"), - CFStringCreateWithCString(kCFAllocatorDefault,message.c_str(),kCFStringEncodingMacRoman) - }; - - CFDictionaryRef dict = CFDictionaryCreate(0, keys, vals, - sizeof(keys)/sizeof(*keys), - &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - pDlg = CFUserNotificationCreate(kCFAllocatorDefault, 0, - kCFUserNotificationPlainAlertLevel, - &nRes, dict); - } + SInt32 nRes = 0; + CFUserNotificationRef pDlg = NULL; + const void* keys[] = { kCFUserNotificationAlertHeaderKey, + kCFUserNotificationAlertMessageKey }; + const void* vals[] = { + CFSTR("Test Foundation Message Box"), + CFStringCreateWithCString(kCFAllocatorDefault,message.c_str(),kCFStringEncodingMacRoman) + }; + + CFDictionaryRef dict = CFDictionaryCreate(0, keys, vals, + sizeof(keys) / sizeof(*keys), + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + pDlg = CFUserNotificationCreate(kCFAllocatorDefault, 0, + kCFUserNotificationPlainAlertLevel, + &nRes, dict); + } } #endif @@ -141,6 +172,7 @@ void Switcher::firstLoad() { //load the settings needed to start the thread void Switcher::load() { settings.load(); + sceneRoundTrip = settings.getSceneRoundTrip(); settingsMap = settings.getMap(); } @@ -177,37 +209,37 @@ bool Switcher::isWindowFullscreen() { //get screen resolution string cmd = "osascript -e 'tell application \"Finder\" to get the bounds of the window of the desktop'"; char resolution[256]; - FILE * f1 = popen(cmd.c_str(), "r"); - fgets(resolution, 255, f1); - pclose(f1); - string resolutionString = string(resolution); + FILE * f1 = popen(cmd.c_str(), "r"); + fgets(resolution, 255, f1); + pclose(f1); + string resolutionString = string(resolution); - //get window resolution - cmd = "osascript " - "-e 'global frontApp, frontAppName, windowTitle, boundsValue' " - "-e 'set windowTitle to \"\"' " - "-e 'tell application \"System Events\"' " + //get window resolution + cmd = "osascript " + "-e 'global frontApp, frontAppName, windowTitle, boundsValue' " + "-e 'set windowTitle to \"\"' " + "-e 'tell application \"System Events\"' " "-e 'set frontApp to first application process whose frontmost is true' " "-e 'set frontAppName to name of frontApp' " "-e 'tell process frontAppName' " - "-e 'tell (1st window whose value of attribute \"AXMain\" is true)' " - "-e 'set windowTitle to value of attribute \"AXTitle\"' " - "-e 'end tell' " + "-e 'tell (1st window whose value of attribute \"AXMain\" is true)' " + "-e 'set windowTitle to value of attribute \"AXTitle\"' " "-e 'end tell' " - "-e 'end tell' " - "-e 'tell application frontAppName' " + "-e 'end tell' " + "-e 'end tell' " + "-e 'tell application frontAppName' " "-e 'set boundsValue to bounds of front window' " - "-e 'end tell' " - "-e 'return boundsValue' "; + "-e 'end tell' " + "-e 'return boundsValue' "; char bounds[256]; - FILE * f2 = popen(cmd.c_str(), "r"); - fgets(bounds, 255, f2); - pclose(f2); - string boundsString = string(bounds); + FILE * f2 = popen(cmd.c_str(), "r"); + fgets(bounds, 255, f2); + pclose(f2); + string boundsString = string(bounds); - return resolutionString.compare(boundsString) == 0; + return resolutionString.compare(boundsString) == 0; } #endif @@ -226,28 +258,28 @@ string Switcher::GetActiveWindowTitle() #ifdef __APPLE__ string Switcher::GetActiveWindowTitle() { - string cmd = "osascript " - "-e 'global frontApp, frontAppName, windowTitle' " - "-e 'set windowTitle to \"\"' " - "-e 'tell application \"System Events\"' " + string cmd = "osascript " + "-e 'global frontApp, frontAppName, windowTitle' " + "-e 'set windowTitle to \"\"' " + "-e 'tell application \"System Events\"' " "-e 'set frontApp to first application process whose frontmost is true' " "-e 'set frontAppName to name of frontApp' " "-e 'tell process frontAppName' " - "-e 'tell (1st window whose value of attribute \"AXMain\" is true)' " - "-e 'set windowTitle to value of attribute \"AXTitle\"' " - "-e 'end tell' " + "-e 'tell (1st window whose value of attribute \"AXMain\" is true)' " + "-e 'set windowTitle to value of attribute \"AXTitle\"' " "-e 'end tell' " - "-e 'end tell' " - "-e 'return windowTitle' "; + "-e 'end tell' " + "-e 'end tell' " + "-e 'return windowTitle' "; - char buffer[256]; - FILE * f = popen(cmd.c_str(), "r"); - fgets(buffer, 255, f); - pclose(f); - //osascript adds carriage return that we need to remove - string windowname = string(buffer); - windowname.pop_back(); - return windowname; + char buffer[256]; + FILE * f = popen(cmd.c_str(), "r"); + fgets(buffer, 255, f); + pclose(f); + //osascript adds carriage return that we need to remove + string windowname = string(buffer); + windowname.pop_back(); + return windowname; } #endif diff --git a/switcher.h b/switcher.h index 1505cde1..ca8f0e12 100644 --- a/switcher.h +++ b/switcher.h @@ -1,6 +1,7 @@ #pragma once #include "settings.h" #include +#include #include using namespace std; @@ -20,6 +21,7 @@ private: bool isRunning = true; Settings settings; map settingsMap; + vector sceneRoundTrip; void switcherThreadFunc(); bool isWindowFullscreen(); string GetActiveWindowTitle();