diff --git a/CMakeLists.txt b/CMakeLists.txt index f95cd47..0d3bdca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,9 @@ set(PROJECT_SOURCES Keys/HelpKeyListener.h Keys/CloseHelpKeyListener.h Keys/CreateWorkspaceKeyListener.h + Keys/CloseSwaymuxKeyListener.h + Keys/CloseSwaymuxKeyListener.h + sway_bindings/swayoutputs.h ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) diff --git a/Keys/CloseSwaymuxKeyListener.h b/Keys/CloseSwaymuxKeyListener.h new file mode 100644 index 0000000..15bf7b8 --- /dev/null +++ b/Keys/CloseSwaymuxKeyListener.h @@ -0,0 +1,29 @@ +// +// Created by grimmauld on 08.03.24. +// + +#ifndef SWAYMUX_CLOSESWAYMUXKEYLISTENER_H +#define SWAYMUX_CLOSESWAYMUXKEYLISTENER_H + +#include "AbstractKeyListener.h" + +class CloseSwaymuxKeyListener : public AbstractKeyListener { +public: + void handleKeyEvent(const QKeyEvent *keyEvent) const override { + QApplication::quit(); + } + + std::string getDescription() override { + return "Exit Swaymux"; + } + + std::string getKeyText() override { + return "ESC"; + } + + [[nodiscard]] bool canAcceptKey(int key) const override { + return key == Qt::Key_Escape; + } +}; + +#endif //SWAYMUX_CLOSESWAYMUXKEYLISTENER_H diff --git a/Keys/CreateWorkspaceKeyListener.h b/Keys/CreateWorkspaceKeyListener.h index 4057e21..46e4df3 100644 --- a/Keys/CreateWorkspaceKeyListener.h +++ b/Keys/CreateWorkspaceKeyListener.h @@ -9,6 +9,7 @@ #include #include "AbstractKeyListener.h" #include "../tree/SwayTreeModel.h" +#include "../sway_bindings/swayoutputs.h" class CreateWorkspaceKeyListener : public AbstractKeyListener { public: @@ -21,27 +22,14 @@ public: return; Formatter cmd; - auto indexes = treeView->selectionModel()->selectedIndexes(); - for (auto i: indexes) { - std::vector indices; - for (auto j = i; j.isValid(); j = j.parent()) { - indices.insert(indices.cbegin(), j.row()); - } - - auto *head = root; - const SwayTreeNode *output; - for (auto j: indices) { - head = head->child(j); - if (head == nullptr) - goto hell; - } - - output = head->findOutput(); - if (output != nullptr) { + auto selectedNodes = swayTreeModel->getSelectedNodes(treeView); + auto availableOutputs = SwayOutputList(SwayTreeModel::sway); + for (auto node: selectedNodes) { + auto output = node->findOutput(); + if (availableOutputs.isOutputValid(output)) { cmd << "focus output " << output->node.name << " , "; break; } - hell:; } auto used_workspaces = root->accumulateWorkspaces(); @@ -50,6 +38,7 @@ public: cmd << "workspace number " << i; auto resp = SwayTreeModel::sway.sendIPC(swaymsg(0, cmd.str().c_str(), cmd.str().length())); std::cout << resp.msg << "\n"; + QApplication::quit(); } std::string getDescription() override { diff --git a/main.cpp b/main.cpp index 21e1c1e..6d0fcea 100644 --- a/main.cpp +++ b/main.cpp @@ -21,6 +21,12 @@ using json = nlohmann::json; int main(int argc, char *argv[]) { + /* + auto sway = Sway(); + auto resp = sway.sendIPC(SWAY_GET_OUTPUTS); + std::cout << resp.msg << "\n"; + */ + QApplication a(argc, argv); QCoreApplication::setOrganizationName("Grimmauld"); QCoreApplication::setApplicationName("SwayMux"); diff --git a/mainwindow.cpp b/mainwindow.cpp index 6926a76..511faf0 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -4,6 +4,7 @@ #include "Keys/HelpKeyListener.h" #include "Keys/CloseHelpKeyListener.h" #include "Keys/CreateWorkspaceKeyListener.h" +#include "Keys/CloseSwaymuxKeyListener.h" #include #include @@ -29,6 +30,7 @@ MainWindow::MainWindow(QWidget *parent) swayTreeKeyHandler = new KeyHandler(); swayTreeKeyHandler->addListener(new HelpKeyListener(ui->help_page)); + swayTreeKeyHandler->addListener(new CloseSwaymuxKeyListener()); swayTreeKeyHandler->addListener(new CreateWorkspaceKeyListener(model, ui->treeView)); closeHelpKeyHandler = new KeyHandler(ui->tree_page); diff --git a/sway_bindings/swayoutputs.h b/sway_bindings/swayoutputs.h new file mode 100644 index 0000000..48fe170 --- /dev/null +++ b/sway_bindings/swayoutputs.h @@ -0,0 +1,58 @@ +// +// Created by grimmauld on 08.03.24. +// + +#ifndef SWAYMUX_SWAYOUTPUTS_H +#define SWAYMUX_SWAYOUTPUTS_H + +#include +#include +#include "Sway.h" +#include "../tree/swaytree.h" + +using json = nlohmann::json; + +struct SwayOutput { + explicit SwayOutput() : id(0), name("none"), active(false), power(false) {}; + + explicit SwayOutput(const json &rep) : + id(rep["id"]), + name(rep["name"].is_null() ? "none" : rep["name"]), + active(rep["active"]), + power(rep["power"]) {}; + + const std::string name; + int id; + const bool active; + const bool power; + + [[nodiscard]] bool isValid() const { + return active && power; + } +}; + +class SwayOutputList { +public: + explicit SwayOutputList(const json &rep) { + for (const auto &o: rep) { + outputs.emplace_back(o); + } + } + + std::vector outputs; + + explicit SwayOutputList(const Sway &sway) : SwayOutputList(json::parse(sway.sendIPC(SWAY_GET_OUTPUTS).msg)) {}; + + [[nodiscard]] bool isOutputValid(const SwayTreeNode *test) { + if (test == nullptr) + return false; + if (test->node.type != NodeType::output) + return false; + + return std::ranges::any_of(outputs.begin(), outputs.end(), [test](const auto &o) { + return o.name == test->node.name && o.isValid(); + }); + } +}; + +#endif //SWAYMUX_SWAYOUTPUTS_H diff --git a/tree/SwayTreeModel.cpp b/tree/SwayTreeModel.cpp index 65e8901..6adf585 100644 --- a/tree/SwayTreeModel.cpp +++ b/tree/SwayTreeModel.cpp @@ -18,3 +18,29 @@ QModelIndex SwayTreeModel::findFocusedWindowIndex() const { return idx; } + +std::set SwayTreeModel::getSelectedNodes(const QTreeView *treeView) const { + std::set selectedNodes; + auto indexes = treeView->selectionModel()->selectedIndexes(); + for (auto i: indexes) { + if (rootItem == nullptr) + return selectedNodes; + + std::vector indices; + for (auto j = i; j.isValid(); j = j.parent()) { + indices.insert(indices.cbegin(), j.row()); + } + + auto *head = rootItem; + for (auto j: indices) { + head = head->child(j); + if (head == nullptr) + goto hell; + } + selectedNodes.insert(head); + + hell:; + } + + return selectedNodes; +} diff --git a/tree/SwayTreeModel.h b/tree/SwayTreeModel.h index bb46404..3091f66 100644 --- a/tree/SwayTreeModel.h +++ b/tree/SwayTreeModel.h @@ -14,6 +14,7 @@ #include #include +#include using json = nlohmann::json; @@ -44,6 +45,8 @@ public: [[nodiscard]] QModelIndex findFocusedWindowIndex() const; + [[nodiscard]] std::set getSelectedNodes(const QTreeView* treeView) const; + private: SwayTreeNode * rootItem; diff --git a/tree/swaytree.cpp b/tree/swaytree.cpp index a356aba..0fdf520 100644 --- a/tree/swaytree.cpp +++ b/tree/swaytree.cpp @@ -10,5 +10,5 @@ QVariant SwayTreeNode::data(int column) const { } QVariant SwayTreeNode::headerData(int column) const { - return "Title"; + return "Swaymux"; } diff --git a/tree/swaytree.h b/tree/swaytree.h index 24be54e..40b0dc8 100644 --- a/tree/swaytree.h +++ b/tree/swaytree.h @@ -11,6 +11,7 @@ using json = nlohmann::json; #include "AbstractTreeNode.h" +#include "../sway_bindings/Sway.h" namespace NodeType { enum NodeType {