From 3c13552198b5b94d7c366a47d53651d3cdf3be53 Mon Sep 17 00:00:00 2001 From: Wayne Heaney <42350981+wheaney@users.noreply.github.com> Date: Thu, 22 Jan 2026 20:42:16 -0800 Subject: [PATCH] Add force reset driver action to Breezy Desktop (#147) --- VERSION | 2 +- kwin/src/kcm/breezydesktopeffectkcm.cpp | 21 +++ kwin/src/kcm/breezydesktopeffectkcm.ui | 217 +++++++++++++----------- kwin/src/xrdriveripc/xrdriveripc.cpp | 7 + kwin/src/xrdriveripc/xrdriveripc.h | 1 + ui/modules/PyXRLinuxDriverIPC | 2 +- ui/src/main.py | 6 +- 7 files changed, 155 insertions(+), 101 deletions(-) diff --git a/VERSION b/VERSION index 2714f53..57cf282 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.6.4 +2.6.5 diff --git a/kwin/src/kcm/breezydesktopeffectkcm.cpp b/kwin/src/kcm/breezydesktopeffectkcm.cpp index f9f18c6..223c43e 100644 --- a/kwin/src/kcm/breezydesktopeffectkcm.cpp +++ b/kwin/src/kcm/breezydesktopeffectkcm.cpp @@ -444,6 +444,27 @@ BreezyDesktopEffectConfig::BreezyDesktopEffectConfig(QObject *parent, const KPlu } }); } + + // Advanced tab: Force reset xr-driver (matches the Python UI's reset action) + if (auto btnResetDriver = widget()->findChild(QStringLiteral("buttonResetDriver"))) { + connect(btnResetDriver, &QPushButton::clicked, this, [this]() { + auto labelStatus = widget()->findChild(QStringLiteral("labelResetDriverStatus")); + if (labelStatus) { + labelStatus->setVisible(false); + } + + setRequestInProgress({sender()}, true); + + const bool ok = XRDriverIPC::instance().resetDriver(); + if (ok) { + showStatus(labelStatus, true, tr("Driver restarted.")); + } else { + showStatus(labelStatus, false, tr("Failed to restart driver.")); + } + + setRequestInProgress({sender()}, false); + }); + } } BreezyDesktopEffectConfig::~BreezyDesktopEffectConfig() diff --git a/kwin/src/kcm/breezydesktopeffectkcm.ui b/kwin/src/kcm/breezydesktopeffectkcm.ui index 32b76ed..2ea3bae 100644 --- a/kwin/src/kcm/breezydesktopeffectkcm.ui +++ b/kwin/src/kcm/breezydesktopeffectkcm.ui @@ -208,14 +208,72 @@ - + + + + Display Horizontal Offset: + + + + + + + 2 + + + QSlider::NoTicks + + + 50 + + + 100 + + + Qt::Horizontal + + + true + + + + + + + Display Vertical Offset: + + + + + + + 2 + + + QSlider::NoTicks + + + 50 + + + 100 + + + Qt::Horizontal + + + true + + + + Follow threshold: - + Qt::Horizontal @@ -237,7 +295,7 @@ - + Add Virtual Display: @@ -250,7 +308,7 @@ - + false @@ -313,7 +371,7 @@ - + false false @@ -469,62 +527,34 @@ - - - - Display Horizontal Offset: - + + + + false + + + false + + + Remove virtual displays on disable + + true - - - - 2 - - - QSlider::NoTicks - - - 50 - - - 100 - - - Qt::Horizontal - - - true - + + + + Mirror physical displays (may impact performance) + + false - - - - Display Vertical Offset: - - - - - - - 2 - - - QSlider::NoTicks - - - 50 - - - 100 - - - Qt::Horizontal - - - true - + + + + Enable multi-tap detection + + false @@ -553,44 +583,14 @@ - - - - false - - - false - - - Remove virtual displays on disable - - true - - - - - - Mirror physical displays (may impact performance) - - false - - - - - - Enable multi-tap detection - - false - - - + Neck-saver horizontal: - + 2 @@ -618,14 +618,14 @@ - + Neck-saver vertical: - + 2 @@ -653,14 +653,14 @@ - + Dead-zone threshold (deg): - + 1 @@ -688,16 +688,43 @@ - + Measurement units: - + + + + + Reset driver: + + + + + + + Force reset driver + + + + + + + + + + false + + + true + + + diff --git a/kwin/src/xrdriveripc/xrdriveripc.cpp b/kwin/src/xrdriveripc/xrdriveripc.cpp index 2e93e56..574140d 100644 --- a/kwin/src/xrdriveripc/xrdriveripc.cpp +++ b/kwin/src/xrdriveripc/xrdriveripc.cpp @@ -108,3 +108,10 @@ bool XRDriverIPC::verifyToken(const std::string &token) { QString result = QString::fromUtf8(out).trimmed().toLower(); return result == QStringLiteral("true"); } + +bool XRDriverIPC::resetDriver() { + QByteArray out = invokePython(QStringLiteral("reset_driver"), {}, {}); + if (out.isEmpty()) return false; + QString result = QString::fromUtf8(out).trimmed().toLower(); + return result == QStringLiteral("true"); +} \ No newline at end of file diff --git a/kwin/src/xrdriveripc/xrdriveripc.h b/kwin/src/xrdriveripc/xrdriveripc.h index d349c6e..4fecdf8 100644 --- a/kwin/src/xrdriveripc/xrdriveripc.h +++ b/kwin/src/xrdriveripc/xrdriveripc.h @@ -85,6 +85,7 @@ public: bool writeControlFlags(const QJsonObject &flags); bool requestToken(const std::string &email); bool verifyToken(const std::string &token); + bool resetDriver(); private: diff --git a/ui/modules/PyXRLinuxDriverIPC b/ui/modules/PyXRLinuxDriverIPC index 6f18448..60b417b 160000 --- a/ui/modules/PyXRLinuxDriverIPC +++ b/ui/modules/PyXRLinuxDriverIPC @@ -1 +1 @@ -Subproject commit 6f1844829e11fcc7664398d4c95d8fbdb6341669 +Subproject commit 60b417baa5721496a3a39d4929460575f2479838 diff --git a/ui/src/main.py b/ui/src/main.py index d12bbc8..61f3cc2 100644 --- a/ui/src/main.py +++ b/ui/src/main.py @@ -103,7 +103,7 @@ class BreezydesktopApplication(Adw.Application): logo_icon_name='com.xronlinux.BreezyDesktop', version=self.version, authors=['Wayne Heaney'], - copyright='© 2025 Wayne Heaney', + copyright='© 2026 Wayne Heaney', license_type=Gtk.License.GPL_3_0, wrap_license=True) about.present() @@ -114,9 +114,7 @@ class BreezydesktopApplication(Adw.Application): dialog.present() def on_reset_driver_action(self, widget, _): - XRDriverIPC.get_instance().write_control_flags({ - 'force_quit': True - }) + XRDriverIPC.get_instance().reset_driver(as_user=None) def create_action(self, name, callback, shortcuts=None): """Add an application action.