Add easier keyboard navigation through outputs using page keys
This commit is contained in:
parent
7dabcbb621
commit
c725c4fdb6
7 changed files with 169 additions and 21 deletions
|
@ -40,6 +40,9 @@ set(PROJECT_SOURCES
|
|||
Keys/CloseSwaymuxKeyListener.h
|
||||
sway_bindings/swayoutputs.h
|
||||
Keys/SwitchToKeybindListener.h
|
||||
Keys/JumpOutputKeyListener.h
|
||||
Keys/PrevOutputKeyListener.h
|
||||
Keys/NextOutputKeyListener.h
|
||||
)
|
||||
|
||||
if(${QT_VERSION_MAJOR} GREATER_EQUAL 6)
|
||||
|
|
55
Keys/JumpOutputKeyListener.h
Normal file
55
Keys/JumpOutputKeyListener.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
//
|
||||
// Created by grimmauld on 09.03.24.
|
||||
//
|
||||
|
||||
#ifndef SWAYMUX_JUMPOUTPUTKEYLISTENER_H
|
||||
#define SWAYMUX_JUMPOUTPUTKEYLISTENER_H
|
||||
|
||||
#include <QTreeView>
|
||||
#include <iostream>
|
||||
#include <QGuiApplication>
|
||||
#include "AbstractKeyListener.h"
|
||||
#include "../tree/SwayTreeModel.h"
|
||||
#include "../sway_bindings/swayoutputs.h"
|
||||
|
||||
class JumpOutputKeyListener : public AbstractKeyListener {
|
||||
public:
|
||||
explicit JumpOutputKeyListener(SwayTreeModel *swayTreeModel, QTreeView *treeView) : swayTreeModel(
|
||||
swayTreeModel), treeView(treeView) {};
|
||||
|
||||
void handleKeyEvent(const QKeyEvent *keyEvent) const override {
|
||||
auto current = treeView->selectionModel()->currentIndex();
|
||||
auto *selected = swayTreeModel->getSelectedNode(current);
|
||||
if (selected == nullptr)
|
||||
return;
|
||||
|
||||
auto *output = selected->findOutput();
|
||||
if (output == nullptr) {
|
||||
if (selected->node.type == NodeType::root)
|
||||
output = selected->child(0);
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
if (output->parentItem() == nullptr)
|
||||
return;
|
||||
|
||||
auto *toFocus = output->parentItem()->child(output->row() + getOffset(selected));
|
||||
if (toFocus == nullptr) // happens if index out of bounds
|
||||
return;
|
||||
|
||||
auto focusIndex = swayTreeModel->findIndexByNode(toFocus);
|
||||
auto modifiers = QGuiApplication::queryKeyboardModifiers();
|
||||
treeView->selectionModel()->setCurrentIndex(focusIndex, modifiers.testFlag(Qt::ControlModifier)
|
||||
? QItemSelectionModel::Current
|
||||
: QItemSelectionModel::ClearAndSelect);
|
||||
}
|
||||
|
||||
[[nodiscard]] inline virtual int getOffset(const SwayTreeNode* selected) const = 0;
|
||||
|
||||
private:
|
||||
SwayTreeModel *swayTreeModel;
|
||||
QTreeView *treeView;
|
||||
};
|
||||
|
||||
#endif //SWAYMUX_JUMPOUTPUTKEYLISTENER_H
|
32
Keys/NextOutputKeyListener.h
Normal file
32
Keys/NextOutputKeyListener.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// Created by grimmauld on 09.03.24.
|
||||
//
|
||||
|
||||
#ifndef SWAYMUX_NEXTOUTPUTKEYLISTENER_H
|
||||
#define SWAYMUX_NEXTOUTPUTKEYLISTENER_H
|
||||
|
||||
|
||||
class NextOutputKeyListener : public JumpOutputKeyListener {
|
||||
public:
|
||||
explicit NextOutputKeyListener(SwayTreeModel *swayTreeModel, QTreeView *treeView) : JumpOutputKeyListener(
|
||||
swayTreeModel, treeView) {};
|
||||
|
||||
std::string getDescription() override {
|
||||
return "Jump focus to output below";
|
||||
}
|
||||
|
||||
std::string getKeyText() override {
|
||||
return "Page Down";
|
||||
}
|
||||
|
||||
[[nodiscard]] bool canAcceptKey(int key) const override {
|
||||
return key == Qt::Key_PageDown;
|
||||
}
|
||||
|
||||
int getOffset(const SwayTreeNode *selected) const override {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif //SWAYMUX_NEXTOUTPUTKEYLISTENER_H
|
38
Keys/PrevOutputKeyListener.h
Normal file
38
Keys/PrevOutputKeyListener.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
//
|
||||
// Created by grimmauld on 09.03.24.
|
||||
//
|
||||
|
||||
#ifndef SWAYMUX_PREVOUTPUTKEYLISTENER_H
|
||||
#define SWAYMUX_PREVOUTPUTKEYLISTENER_H
|
||||
|
||||
#include <QTreeView>
|
||||
#include <iostream>
|
||||
#include <QGuiApplication>
|
||||
#include "AbstractKeyListener.h"
|
||||
#include "../tree/SwayTreeModel.h"
|
||||
#include "../sway_bindings/swayoutputs.h"
|
||||
#include "JumpOutputKeyListener.h"
|
||||
|
||||
class PrevOutputKeyListener : public JumpOutputKeyListener {
|
||||
public:
|
||||
explicit PrevOutputKeyListener(SwayTreeModel *swayTreeModel, QTreeView *treeView) : JumpOutputKeyListener(
|
||||
swayTreeModel, treeView) {};
|
||||
|
||||
std::string getDescription() override {
|
||||
return "Jump focus to output above";
|
||||
}
|
||||
|
||||
std::string getKeyText() override {
|
||||
return "Page Up";
|
||||
}
|
||||
|
||||
[[nodiscard]] bool canAcceptKey(int key) const override {
|
||||
return key == Qt::Key_PageUp;
|
||||
}
|
||||
|
||||
int getOffset(const SwayTreeNode *selected) const override {
|
||||
return selected != nullptr && selected->node.type != NodeType::output ? 0 : -1;
|
||||
}
|
||||
};
|
||||
|
||||
#endif //SWAYMUX_PREVOUTPUTKEYLISTENER_H
|
|
@ -6,6 +6,9 @@
|
|||
#include "Keys/CreateWorkspaceKeyListener.h"
|
||||
#include "Keys/CloseSwaymuxKeyListener.h"
|
||||
#include "Keys/SwitchToKeybindListener.h"
|
||||
#include "Keys/PrevOutputKeyListener.h"
|
||||
#include "Keys/NextOutputKeyListener.h"
|
||||
#include "Keys/NextOutputKeyListener.h"
|
||||
#include <QTimer>
|
||||
#include <iostream>
|
||||
|
||||
|
@ -34,6 +37,8 @@ MainWindow::MainWindow(QWidget *parent)
|
|||
swayTreeKeyHandler->addListener(new CloseSwaymuxKeyListener());
|
||||
swayTreeKeyHandler->addListener(new CreateWorkspaceKeyListener(model, ui->treeView));
|
||||
swayTreeKeyHandler->addListener(new SwitchToKeybindListener(model, ui->treeView));
|
||||
swayTreeKeyHandler->addListener(new PrevOutputKeyListener(model, ui->treeView));
|
||||
swayTreeKeyHandler->addListener(new NextOutputKeyListener(model, ui->treeView));
|
||||
|
||||
closeHelpKeyHandler = new KeyHandler(ui->tree_page);
|
||||
closeHelpKeyHandler->addListener(new CloseHelpKeyListener(ui->tree_page));
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
#include "SwayTreeModel.h"
|
||||
|
||||
QModelIndex SwayTreeModel::findFocusedWindowIndex() const {
|
||||
QModelIndex SwayTreeModel::findIndexByNode(const SwayTreeNode* node) const {
|
||||
std::vector<int> indices;
|
||||
for (const auto *head = getRoot()->findFocused(); head != nullptr; head = head->parentItem()) {
|
||||
for (const auto *head = node; head != nullptr; head = head->parentItem()) {
|
||||
indices.insert(indices.cbegin(), head->row());
|
||||
}
|
||||
|
||||
// weirdness, idk... ask QT
|
||||
// weirdness, idk ask QT
|
||||
QModelIndex idx = this->index(indices.size() < 2 ? 0 : indices[1], 0);
|
||||
for (int i = 2; i < indices.size(); ++i) {
|
||||
idx = this->index(indices[i], 0, idx);
|
||||
|
@ -21,26 +21,36 @@ QModelIndex SwayTreeModel::findFocusedWindowIndex() const {
|
|||
|
||||
std::set<SwayTreeNode *> SwayTreeModel::getSelectedNodes(const QTreeView *treeView) const {
|
||||
std::set<SwayTreeNode *> selectedNodes;
|
||||
if (rootItem == nullptr)
|
||||
return selectedNodes;
|
||||
|
||||
auto indexes = treeView->selectionModel()->selectedIndexes();
|
||||
for (auto i: indexes) {
|
||||
if (rootItem == nullptr)
|
||||
return selectedNodes;
|
||||
|
||||
std::vector<int> 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:;
|
||||
auto node = getSelectedNode(i);
|
||||
if (node != nullptr)
|
||||
selectedNodes.insert(node);
|
||||
}
|
||||
|
||||
return selectedNodes;
|
||||
}
|
||||
|
||||
SwayTreeNode *SwayTreeModel::getSelectedNode(const QModelIndex &i) const {
|
||||
if (rootItem == nullptr)
|
||||
return nullptr;
|
||||
|
||||
std::vector<int> 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)
|
||||
return nullptr;
|
||||
}
|
||||
return head;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -43,10 +43,15 @@ public:
|
|||
};
|
||||
|
||||
|
||||
[[nodiscard]] QModelIndex findFocusedWindowIndex() const;
|
||||
[[nodiscard]] inline QModelIndex findFocusedWindowIndex() const {
|
||||
return findIndexByNode(getRoot()->findFocused());
|
||||
}
|
||||
|
||||
[[nodiscard]] std::set<SwayTreeNode*> getSelectedNodes(const QTreeView* treeView) const;
|
||||
|
||||
[[nodiscard]] SwayTreeNode * getSelectedNode(const QModelIndex &i) const;
|
||||
|
||||
[[nodiscard]] QModelIndex findIndexByNode(const SwayTreeNode *node) const;
|
||||
|
||||
private:
|
||||
SwayTreeNode * rootItem;
|
||||
|
|
Loading…
Reference in a new issue