mirror of https://github.com/cutefishos/settings
feat(settings): add a hot corners page and list the show desktop shortcut
parent
e11e9b7e8f
commit
266e9aa388
@ -0,0 +1,99 @@
|
||||
// SPDX-FileCopyrightText: 2026 Reion Wong <reionwong@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "hotcorners.h"
|
||||
|
||||
#include <QDBusPendingCall>
|
||||
#include <QDBusPendingCallWatcher>
|
||||
#include <QDBusPendingReply>
|
||||
#include <QDBusReply>
|
||||
#include <QDBusServiceWatcher>
|
||||
#include <QDebug>
|
||||
|
||||
static constexpr auto service = "com.cutefish.HotCorners1";
|
||||
static constexpr auto path = "/com/cutefish/HotCorners1";
|
||||
|
||||
// The compositor's modifier bits, as in the shortcuts service.
|
||||
static constexpr int ShiftDown = 1 << 0;
|
||||
static constexpr int ControlDown = 1 << 1;
|
||||
static constexpr int AltDown = 1 << 2;
|
||||
static constexpr int MetaDown = 1 << 3;
|
||||
|
||||
HotCorners::HotCorners(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
auto *watcher = new QDBusServiceWatcher(QLatin1String(service), QDBusConnection::sessionBus(),
|
||||
QDBusServiceWatcher::WatchForOwnerChange, this);
|
||||
connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &HotCorners::refreshInterface);
|
||||
refreshInterface();
|
||||
|
||||
QDBusInterface shortcuts(QStringLiteral("com.cutefish.Shortcuts1"),
|
||||
QStringLiteral("/com/cutefish/Shortcuts1"),
|
||||
QStringLiteral("com.cutefish.Shortcuts1"), QDBusConnection::sessionBus());
|
||||
m_commandKeys = shortcuts.isValid()
|
||||
&& shortcuts.property("shortcutConvention").toString() == QLatin1String("command");
|
||||
}
|
||||
|
||||
void HotCorners::refreshInterface()
|
||||
{
|
||||
delete m_interface;
|
||||
m_interface = new QDBusInterface(QLatin1String(service), QLatin1String(path),
|
||||
QLatin1String(service), QDBusConnection::sessionBus(), this);
|
||||
if (m_interface->isValid())
|
||||
connect(m_interface, SIGNAL(changed()), this, SIGNAL(changed()));
|
||||
emit changed();
|
||||
}
|
||||
|
||||
bool HotCorners::available() const
|
||||
{
|
||||
return m_interface->isValid();
|
||||
}
|
||||
|
||||
void HotCorners::setCorner(const QString &corner, const QString &action, int modifiers)
|
||||
{
|
||||
if (!m_interface->isValid())
|
||||
return;
|
||||
auto *watcher = new QDBusPendingCallWatcher(
|
||||
m_interface->asyncCall(QStringLiteral("setCorner"), corner, action, modifiers), this);
|
||||
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *reply) {
|
||||
const QDBusPendingReply<> result = *reply;
|
||||
if (result.isError()) {
|
||||
qWarning() << "Cannot update hot corner" << result.error().message();
|
||||
emit changed();
|
||||
}
|
||||
reply->deleteLater();
|
||||
});
|
||||
}
|
||||
|
||||
int HotCorners::heldModifiers() const
|
||||
{
|
||||
if (!m_interface->isValid())
|
||||
return 0;
|
||||
const QDBusReply<int> reply = m_interface->call(QStringLiteral("heldModifiers"));
|
||||
return reply.isValid() ? reply.value() : 0;
|
||||
}
|
||||
|
||||
QString HotCorners::modifierText(int modifiers) const
|
||||
{
|
||||
// Under the Command convention Meta is the Command key, Alt is Option.
|
||||
QStringList parts;
|
||||
if (modifiers & ControlDown)
|
||||
parts << (m_commandKeys ? tr("Control") : tr("Ctrl"));
|
||||
if (modifiers & AltDown)
|
||||
parts << (m_commandKeys ? tr("Option") : tr("Alt"));
|
||||
if (modifiers & ShiftDown)
|
||||
parts << tr("Shift");
|
||||
if (modifiers & MetaDown)
|
||||
parts << (m_commandKeys ? tr("Command") : tr("Meta"));
|
||||
return parts.join(QStringLiteral(" + "));
|
||||
}
|
||||
|
||||
QString HotCorners::stringProperty(const char *name) const
|
||||
{
|
||||
return m_interface->isValid() ? m_interface->property(name).toString() : QString();
|
||||
}
|
||||
|
||||
int HotCorners::intProperty(const char *name) const
|
||||
{
|
||||
return m_interface->isValid() ? m_interface->property(name).toInt() : 0;
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
// SPDX-FileCopyrightText: 2026 Reion Wong <reionwong@gmail.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#ifndef HOTCORNERS_H
|
||||
#define HOTCORNERS_H
|
||||
|
||||
#include <QDBusInterface>
|
||||
#include <QObject>
|
||||
|
||||
// The compositor's com.cutefish.HotCorners1: what each screen corner runs.
|
||||
class HotCorners : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool available READ available NOTIFY changed)
|
||||
Q_PROPERTY(QString topLeft READ topLeft NOTIFY changed)
|
||||
Q_PROPERTY(int topLeftModifiers READ topLeftModifiers NOTIFY changed)
|
||||
Q_PROPERTY(QString topRight READ topRight NOTIFY changed)
|
||||
Q_PROPERTY(int topRightModifiers READ topRightModifiers NOTIFY changed)
|
||||
Q_PROPERTY(QString bottomLeft READ bottomLeft NOTIFY changed)
|
||||
Q_PROPERTY(int bottomLeftModifiers READ bottomLeftModifiers NOTIFY changed)
|
||||
Q_PROPERTY(QString bottomRight READ bottomRight NOTIFY changed)
|
||||
Q_PROPERTY(int bottomRightModifiers READ bottomRightModifiers NOTIFY changed)
|
||||
|
||||
public:
|
||||
explicit HotCorners(QObject *parent = nullptr);
|
||||
|
||||
bool available() const;
|
||||
QString topLeft() const { return stringProperty("topLeft"); }
|
||||
int topLeftModifiers() const { return intProperty("topLeftModifiers"); }
|
||||
QString topRight() const { return stringProperty("topRight"); }
|
||||
int topRightModifiers() const { return intProperty("topRightModifiers"); }
|
||||
QString bottomLeft() const { return stringProperty("bottomLeft"); }
|
||||
int bottomLeftModifiers() const { return intProperty("bottomLeftModifiers"); }
|
||||
QString bottomRight() const { return stringProperty("bottomRight"); }
|
||||
int bottomRightModifiers() const { return intProperty("bottomRightModifiers"); }
|
||||
|
||||
// `corner` is top-left, top-right, bottom-left or bottom-right; an empty
|
||||
// action turns it off.
|
||||
Q_INVOKABLE void setCorner(const QString &corner, const QString &action, int modifiers);
|
||||
// The modifiers held now, as the compositor sees them.
|
||||
Q_INVOKABLE int heldModifiers() const;
|
||||
// "Option + Shift" and the like, in the session's shortcut convention.
|
||||
Q_INVOKABLE QString modifierText(int modifiers) const;
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
|
||||
private:
|
||||
void refreshInterface();
|
||||
QString stringProperty(const char *name) const;
|
||||
int intProperty(const char *name) const;
|
||||
|
||||
QDBusInterface *m_interface = nullptr;
|
||||
bool m_commandKeys = false;
|
||||
};
|
||||
|
||||
#endif // HOTCORNERS_H
|
||||
Loading…
Reference in New Issue