diff --git a/CMakeLists.txt b/CMakeLists.txt index 8043144..f95cd47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) -set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets LinguistTools) @@ -35,6 +35,7 @@ set(PROJECT_SOURCES Keys/AbstractKeyListener.h Keys/HelpKeyListener.h Keys/CloseHelpKeyListener.h + Keys/CreateWorkspaceKeyListener.h ) if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) diff --git a/Keys/CreateWorkspaceKeyListener.h b/Keys/CreateWorkspaceKeyListener.h new file mode 100644 index 0000000..4057e21 --- /dev/null +++ b/Keys/CreateWorkspaceKeyListener.h @@ -0,0 +1,71 @@ +// +// Created by grimmauld on 07.03.24. +// + +#ifndef SWAYMUX_CREATEWORKSPACEKEYLISTENER_H +#define SWAYMUX_CREATEWORKSPACEKEYLISTENER_H + +#include +#include +#include "AbstractKeyListener.h" +#include "../tree/SwayTreeModel.h" + +class CreateWorkspaceKeyListener : public AbstractKeyListener { +public: + explicit CreateWorkspaceKeyListener(SwayTreeModel *swayTreeModel, QTreeView *treeView) : swayTreeModel( + swayTreeModel), treeView(treeView) {} + + void handleKeyEvent(const QKeyEvent *keyEvent) const override { + auto *root = swayTreeModel->getRoot(); + if (root == nullptr) + 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) { + cmd << "focus output " << output->node.name << " , "; + break; + } + hell:; + } + + auto used_workspaces = root->accumulateWorkspaces(); + int i = 1; // workspace 1 is the first one. We don't expect our users to be programmers. + for (; used_workspaces.contains(std::to_string(i)); ++i) {} + cmd << "workspace number " << i; + auto resp = SwayTreeModel::sway.sendIPC(swaymsg(0, cmd.str().c_str(), cmd.str().length())); + std::cout << resp.msg << "\n"; + } + + std::string getDescription() override { + return "Create and switch to new empty workspace on selected output"; + } + + std::string getKeyText() override { + return "C"; + } + + [[nodiscard]] bool canAcceptKey(int key) const override { + return key == Qt::Key_C; + } + + SwayTreeModel *swayTreeModel; + QTreeView *treeView; +}; + +#endif //SWAYMUX_CREATEWORKSPACEKEYLISTENER_H diff --git a/mainwindow.cpp b/mainwindow.cpp index 243d5e4..6926a76 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -3,6 +3,7 @@ #include "tree/SwayTreeModel.h" #include "Keys/HelpKeyListener.h" #include "Keys/CloseHelpKeyListener.h" +#include "Keys/CreateWorkspaceKeyListener.h" #include #include @@ -28,6 +29,7 @@ MainWindow::MainWindow(QWidget *parent) swayTreeKeyHandler = new KeyHandler(); swayTreeKeyHandler->addListener(new HelpKeyListener(ui->help_page)); + swayTreeKeyHandler->addListener(new CreateWorkspaceKeyListener(model, ui->treeView)); closeHelpKeyHandler = new KeyHandler(ui->tree_page); closeHelpKeyHandler->addListener(new CloseHelpKeyListener(ui->tree_page)); diff --git a/tree/AbstractTreeNode.h b/tree/AbstractTreeNode.h index 5054876..ec27701 100644 --- a/tree/AbstractTreeNode.h +++ b/tree/AbstractTreeNode.h @@ -76,7 +76,7 @@ public: if (parent == nullptr) return nullptr; - return this->findParentRecursive(test); + return parent->findParentRecursive(test); }; void removeChild(int i) { diff --git a/tree/swaytree.h b/tree/swaytree.h index e47f27a..24be54e 100644 --- a/tree/swaytree.h +++ b/tree/swaytree.h @@ -169,6 +169,20 @@ public: return this->findParentRecursive(matchNodeType(NodeType::workspace)); } + [[nodiscard]] std::set accumulateWorkspaces() const { + std::set workspaces; + if (node.type == NodeType::workspace) { + workspaces.insert(node.name); + return workspaces; // assumption: no workspaces within workspaces. This might be dangerous for the future, but is currently not a sway feature. + } + + for (int i = 0; i < childCount(); ++i) { + auto child_workspaces = child(i)->accumulateWorkspaces(); + workspaces.insert(child_workspaces.cbegin(), child_workspaces.cend()); + } + return workspaces; + } + private: [[nodiscard]] static std::function matchNodeType(const NodeType::NodeType type) { return [type](const SwayTreeNode *testNode) {