diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp index d4f0ae40..9832a22d 100644 --- a/src/debug/HyprCtl.cpp +++ b/src/debug/HyprCtl.cpp @@ -38,11 +38,11 @@ R"#({ "active": "%s" },)#", m->ID, - m->szName.c_str(), + escapeJSONStrings(m->szName).c_str(), (int)m->vecPixelSize.x, (int)m->vecPixelSize.y, m->refreshRate, (int)m->vecPosition.x, (int)m->vecPosition.y, - m->activeWorkspace, g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName.c_str(), + m->activeWorkspace, escapeJSONStrings(g_pCompositor->getWorkspaceByID(m->activeWorkspace)->m_szName).c_str(), (int)m->vecReservedTopLeft.x, (int)m->vecReservedTopLeft.y, (int)m->vecReservedBottomRight.x, (int)m->vecReservedBottomRight.y, m->scale, (int)m->transform, @@ -86,14 +86,14 @@ R"#({ "title": "%s", "pid": %i },)#", - &w, + w.get(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, - w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), + w->m_iWorkspaceID, escapeJSONStrings(w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID))).c_str(), (int)w->m_bIsFloating, w->m_iMonitorID, - g_pXWaylandManager->getAppIDClass(w.get()).c_str(), - g_pXWaylandManager->getTitle(w.get()).c_str(), + escapeJSONStrings(g_pXWaylandManager->getAppIDClass(w.get())).c_str(), + escapeJSONStrings(g_pXWaylandManager->getTitle(w.get())).c_str(), w->getPID() ); } @@ -107,7 +107,7 @@ R"#({ for (auto& w : g_pCompositor->m_vWindows) { if (w->m_bIsMapped) { result += getFormat("Window %x -> %s:\n\tat: %i,%i\n\tsize: %i,%i\n\tworkspace: %i (%s)\n\tfloating: %i\n\tmonitor: %i\n\tclass: %s\n\ttitle: %s\n\tpid: %i\n\n", - &w, w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID()); + w.get(), w->m_szTitle.c_str(), (int)w->m_vRealPosition.vec().x, (int)w->m_vRealPosition.vec().y, (int)w->m_vRealSize.vec().x, (int)w->m_vRealSize.vec().y, w->m_iWorkspaceID, (w->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID) ? g_pCompositor->getWorkspaceByID(w->m_iWorkspaceID)->m_szName.c_str() : std::string("Invalid workspace " + std::to_string(w->m_iWorkspaceID)).c_str()), (int)w->m_bIsFloating, w->m_iMonitorID, g_pXWaylandManager->getAppIDClass(w.get()).c_str(), g_pXWaylandManager->getTitle(w.get()).c_str(), w->getPID()); } } @@ -130,8 +130,8 @@ R"#({ "hasfullscreen": %i },)#", w->m_iID, - w->m_szName.c_str(), - g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName.c_str(), + escapeJSONStrings(w->m_szName).c_str(), + escapeJSONStrings(g_pCompositor->getMonitorFromID(w->m_iMonitorID)->szName).c_str(), g_pCompositor->getWindowsOnWorkspace(w->m_iID), (int)w->m_bHasFullscreenWindow ); @@ -175,11 +175,11 @@ R"#({ PWINDOW, (int)PWINDOW->m_vRealPosition.vec().x, (int)PWINDOW->m_vRealPosition.vec().y, (int)PWINDOW->m_vRealSize.vec().x, (int)PWINDOW->m_vRealSize.vec().y, - PWINDOW->m_iWorkspaceID, (PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName.c_str()), + PWINDOW->m_iWorkspaceID, escapeJSONStrings(PWINDOW->m_iWorkspaceID == -1 ? "" : g_pCompositor->getWorkspaceByID(PWINDOW->m_iWorkspaceID)->m_szName).c_str(), (int)PWINDOW->m_bIsFloating, PWINDOW->m_iMonitorID, - g_pXWaylandManager->getAppIDClass(PWINDOW).c_str(), - g_pXWaylandManager->getTitle(PWINDOW).c_str(), + escapeJSONStrings(g_pXWaylandManager->getAppIDClass(PWINDOW)).c_str(), + escapeJSONStrings(g_pXWaylandManager->getTitle(PWINDOW)).c_str(), PWINDOW->getPID() ); } else { @@ -199,7 +199,7 @@ std::string layersRequest(HyprCtl::eHyprCtlOutputFormat format) { R"#("%s": { "levels": { )#", - mon->szName.c_str() + escapeJSONStrings(mon->szName).c_str() ); int layerLevel = 0; @@ -225,7 +225,7 @@ R"#( { layer->geometry.y, layer->geometry.width, layer->geometry.height, - layer->szNamespace.c_str() + escapeJSONStrings(layer->szNamespace).c_str() ); } @@ -285,7 +285,7 @@ R"#( { "name": "%s" },)#", &m, - m.mouse->name + escapeJSONStrings(m.mouse->name).c_str() ); } @@ -308,13 +308,13 @@ R"#( { "active_keymap": "%s" },)#", &k, - k.keyboard->name, - k.currentRules.rules.c_str(), - k.currentRules.model.c_str(), - k.currentRules.layout.c_str(), - k.currentRules.variant.c_str(), - k.currentRules.options.c_str(), - KM + escapeJSONStrings(k.keyboard->name).c_str(), + escapeJSONStrings(k.currentRules.rules).c_str(), + escapeJSONStrings(k.currentRules.model).c_str(), + escapeJSONStrings(k.currentRules.layout).c_str(), + escapeJSONStrings(k.currentRules.variant).c_str(), + escapeJSONStrings(k.currentRules.options).c_str(), + escapeJSONStrings(KM).c_str() ); } @@ -336,7 +336,7 @@ R"#( { },)#", &d, d.pTabletParent, - d.pTabletParent ? d.pTabletParent->wlrDevice ? d.pTabletParent->wlrDevice->name : "" : "" + escapeJSONStrings(d.pTabletParent ? d.pTabletParent->wlrDevice ? d.pTabletParent->wlrDevice->name : "" : "").c_str() ); } @@ -347,7 +347,7 @@ R"#( { "name": "%s" },)#", &d, - d.wlrDevice ? d.wlrDevice->name : "" + escapeJSONStrings(d.wlrDevice ? d.wlrDevice->name : "").c_str() ); } diff --git a/src/helpers/MiscFunctions.cpp b/src/helpers/MiscFunctions.cpp index 126600f3..8f8ee0f9 100644 --- a/src/helpers/MiscFunctions.cpp +++ b/src/helpers/MiscFunctions.cpp @@ -3,6 +3,7 @@ #include #include "../Compositor.hpp" #include +#include static const float transforms[][9] = {{ 1.0f, 0.0f, 0.0f, @@ -113,6 +114,29 @@ std::string getFormat(const char *fmt, ...) { return output; } +std::string escapeJSONStrings(const std::string& str) { + std::ostringstream oss; + for (auto &c : str) { + switch (c) { + case '"': oss << "\\\""; break; + case '\\': oss << "\\\\"; break; + case '\b': oss << "\\b"; break; + case '\f': oss << "\\f"; break; + case '\n': oss << "\\n"; break; + case '\r': oss << "\\r"; break; + case '\t': oss << "\\t"; break; + default: + if ('\x00' <= c && c <= '\x1f') { + oss << "\\u" + << std::hex << std::setw(4) << std::setfill('0') << static_cast(c); + } else { + oss << c; + } + } + } + return oss.str(); +} + void scaleBox(wlr_box* box, float scale) { box->width = std::round(box->width * scale); box->height = std::round(box->height * scale); diff --git a/src/helpers/MiscFunctions.hpp b/src/helpers/MiscFunctions.hpp index 108ac7f7..a40471a9 100644 --- a/src/helpers/MiscFunctions.hpp +++ b/src/helpers/MiscFunctions.hpp @@ -5,6 +5,7 @@ void addWLSignal(wl_signal*, wl_listener*, void* pOwner, std::string ownerString); void wlr_signal_emit_safe(struct wl_signal *signal, void *data); std::string getFormat(const char *fmt, ...); // Basically Debug::log to a string +std::string escapeJSONStrings(const std::string& str); void scaleBox(wlr_box*, float); std::string removeBeginEndSpacesTabs(std::string); bool isNumber(const std::string&, bool allowfloat = false); diff --git a/src/managers/KeybindManager.cpp b/src/managers/KeybindManager.cpp index 1ad338cd..2c91f81f 100644 --- a/src/managers/KeybindManager.cpp +++ b/src/managers/KeybindManager.cpp @@ -1067,28 +1067,57 @@ void CKeybindManager::circleNext(std::string arg) { } void CKeybindManager::focusWindow(std::string regexp) { - bool titleRegex = false; + eFocusWindowMode mode = MODE_CLASS_REGEX; + std::regex regexCheck(regexp); + std::string matchCheck; if (regexp.find("title:") == 0) { - titleRegex = true; + mode = MODE_TITLE_REGEX; regexCheck = std::regex(regexp.substr(6)); } + else if (regexp.find("address:") == 0) { + mode = MODE_ADDRESS; + matchCheck = regexp.substr(8); + } + else if (regexp.find("pid:") == 0) { + mode = MODE_PID; + matchCheck = regexp.substr(4); + } for (auto& w : g_pCompositor->m_vWindows) { if (!w->m_bIsMapped || w->m_bHidden) continue; - if (titleRegex) { - const auto windowTitle = g_pXWaylandManager->getTitle(w.get()); - if (!std::regex_search(windowTitle, regexCheck)) - continue; - } - else { - const auto windowClass = g_pXWaylandManager->getAppIDClass(w.get()); - if (!std::regex_search(windowClass, regexCheck)) - continue; + switch (mode) { + case MODE_CLASS_REGEX: { + const auto windowClass = g_pXWaylandManager->getAppIDClass(w.get()); + if (!std::regex_search(g_pXWaylandManager->getAppIDClass(w.get()), regexCheck)) + continue; + break; + } + case MODE_TITLE_REGEX: { + const auto windowTitle = g_pXWaylandManager->getTitle(w.get()); + if (!std::regex_search(windowTitle, regexCheck)) + continue; + break; + } + case MODE_ADDRESS: { + std::string addr = getFormat("0x%x", w.get()); + if (matchCheck != addr) + continue; + break; + } + case MODE_PID: { + std::string pid = getFormat("%d", w->getPID()); + if (matchCheck != pid) + continue; + break; + } + default: + break; } + Debug::log(LOG, "Focusing to window name: %s", w->m_szTitle.c_str()); changeworkspace("[internal]" + std::to_string(w->m_iWorkspaceID)); diff --git a/src/managers/KeybindManager.hpp b/src/managers/KeybindManager.hpp index 08a1cba3..3aece7be 100644 --- a/src/managers/KeybindManager.hpp +++ b/src/managers/KeybindManager.hpp @@ -66,6 +66,13 @@ private: static void setSubmap(std::string); friend class CCompositor; + + enum eFocusWindowMode { + MODE_CLASS_REGEX = 0, + MODE_TITLE_REGEX, + MODE_ADDRESS, + MODE_PID + }; }; -inline std::unique_ptr g_pKeybindManager; \ No newline at end of file +inline std::unique_ptr g_pKeybindManager;