networking: add PSK, settings and connection status support

This commit is contained in:
Carson Powers 2026-02-01 22:15:42 -06:00 committed by outfoxxed
parent 92b336c80c
commit 20c691cdf1
No known key found for this signature in database
GPG key ID: 4C88A185FB89301E
34 changed files with 2200 additions and 881 deletions

View file

@ -6,90 +6,15 @@
#include <qtmetamacros.h>
#include <qtypes.h>
#include "../core/doc.hpp"
#include "../core/model.hpp"
#include "device.hpp"
#include "enums.hpp"
#include "network.hpp"
namespace qs::network {
///! The security type of a wifi network.
class WifiSecurityType: public QObject {
Q_OBJECT;
QML_ELEMENT;
QML_SINGLETON;
public:
enum Enum : quint8 {
Wpa3SuiteB192 = 0,
Sae = 1,
Wpa2Eap = 2,
Wpa2Psk = 3,
WpaEap = 4,
WpaPsk = 5,
StaticWep = 6,
DynamicWep = 7,
Leap = 8,
Owe = 9,
Open = 10,
Unknown = 11,
};
Q_ENUM(Enum);
Q_INVOKABLE static QString toString(WifiSecurityType::Enum type);
};
///! The 802.11 mode of a wifi device.
class WifiDeviceMode: public QObject {
Q_OBJECT;
QML_ELEMENT;
QML_SINGLETON;
public:
enum Enum : quint8 {
/// The device is part of an Ad-Hoc network without a central access point.
AdHoc = 0,
/// The device is a station that can connect to networks.
Station = 1,
/// The device is a local hotspot/access point.
AccessPoint = 2,
/// The device is an 802.11s mesh point.
Mesh = 3,
/// The device mode is unknown.
Unknown = 4,
};
Q_ENUM(Enum);
Q_INVOKABLE static QString toString(WifiDeviceMode::Enum mode);
};
///! NetworkManager-specific reason for a WifiNetworks connection state.
/// In sync with https://networkmanager.dev/docs/api/latest/nm-dbus-types.html#NMActiveConnectionStateReason.
class NMConnectionStateReason: public QObject {
Q_OBJECT;
QML_ELEMENT;
QML_SINGLETON;
public:
enum Enum : quint8 {
Unknown = 0,
None = 1,
UserDisconnected = 2,
DeviceDisconnected = 3,
ServiceStopped = 4,
IpConfigInvalid = 5,
ConnectTimeout = 6,
ServiceStartTimeout = 7,
ServiceStartFailed = 8,
NoSecrets = 9,
LoginFailed = 10,
ConnectionRemoved = 11,
DependencyFailed = 12,
DeviceRealizeFailed = 13,
DeviceRemoved = 14
};
Q_ENUM(Enum);
Q_INVOKABLE static QString toString(NMConnectionStateReason::Enum reason);
};
///! An available wifi network.
///! WiFi subtype of @@Network.
class WifiNetwork: public Network {
Q_OBJECT;
QML_ELEMENT;
@ -97,58 +22,46 @@ class WifiNetwork: public Network {
// clang-format off
/// The current signal strength of the network, from 0.0 to 1.0.
Q_PROPERTY(qreal signalStrength READ default NOTIFY signalStrengthChanged BINDABLE bindableSignalStrength);
/// True if the wifi network has known connection settings saved.
Q_PROPERTY(bool known READ default NOTIFY knownChanged BINDABLE bindableKnown);
/// The security type of the wifi network.
Q_PROPERTY(WifiSecurityType::Enum security READ default NOTIFY securityChanged BINDABLE bindableSecurity);
/// A specific reason for the connection state when the backend is NetworkManager.
Q_PROPERTY(NMConnectionStateReason::Enum nmReason READ default NOTIFY nmReasonChanged BINDABLE bindableNmReason);
// clang-format on
public:
explicit WifiNetwork(QString ssid, QObject* parent = nullptr);
/// Attempt to connect to the wifi network.
/// Attempt to connect to the network with the given PSK. If the PSK is wrong,
/// a @@Network.connectionFailed(s) signal will be emitted with `NoSecrets`.
///
/// > [!WARNING] Quickshell does not yet provide a NetworkManager authentication agent,
/// > meaning another agent will need to be active to enter passwords for unsaved networks.
Q_INVOKABLE void connect();
/// Disconnect from the wifi network.
Q_INVOKABLE void disconnect();
/// Forget all connection settings for this wifi network.
Q_INVOKABLE void forget();
/// The networking backend may store the PSK for future use with @@Network.connect().
/// As such, calling that function first is recommended to avoid having to show a
/// prompt if not required.
///
/// > [!NOTE] PSKs should only be provided when the @@security is one of
/// > `WpaPsk`, `Wpa2Psk`, or `Sae`.
Q_INVOKABLE void connectWithPsk(const QString& psk);
QBindable<qreal> bindableSignalStrength() { return &this->bSignalStrength; }
QBindable<bool> bindableKnown() { return &this->bKnown; }
QBindable<NMConnectionStateReason::Enum> bindableNmReason() { return &this->bNmReason; }
QBindable<WifiSecurityType::Enum> bindableSecurity() { return &this->bSecurity; }
signals:
void requestConnect();
void requestDisconnect();
void requestForget();
QSDOC_HIDE void requestConnectWithPsk(QString psk);
void signalStrengthChanged();
void knownChanged();
void securityChanged();
void nmReasonChanged();
private:
// clang-format off
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, qreal, bSignalStrength, &WifiNetwork::signalStrengthChanged);
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, bool, bKnown, &WifiNetwork::knownChanged);
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, NMConnectionStateReason::Enum, bNmReason, &WifiNetwork::nmReasonChanged);
Q_OBJECT_BINDABLE_PROPERTY(WifiNetwork, WifiSecurityType::Enum, bSecurity, &WifiNetwork::securityChanged);
// clang-format on
};
///! Wireless variant of a NetworkDevice.
///! WiFi variant of a @@NetworkDevice.
class WifiDevice: public NetworkDevice {
Q_OBJECT;
QML_ELEMENT;
QML_UNCREATABLE("");
// clang-format off
/// A list of this available and connected wifi networks.
/// A list of this available or connected wifi networks.
QSDOC_TYPE_OVERRIDE(ObjectModel<WifiNetwork>*);
Q_PROPERTY(UntypedObjectModel* networks READ networks CONSTANT);
/// True when currently scanning for networks.
@ -164,9 +77,9 @@ public:
void networkAdded(WifiNetwork* net);
void networkRemoved(WifiNetwork* net);
[[nodiscard]] ObjectModel<WifiNetwork>* networks() { return &this->mNetworks; };
QBindable<bool> bindableScannerEnabled() { return &this->bScannerEnabled; };
[[nodiscard]] bool scannerEnabled() const { return this->bScannerEnabled; };
[[nodiscard]] ObjectModel<WifiNetwork>* networks() { return &this->mNetworks; }
QBindable<bool> bindableScannerEnabled() { return &this->bScannerEnabled; }
[[nodiscard]] bool scannerEnabled() const { return this->bScannerEnabled; }
void setScannerEnabled(bool enabled);
QBindable<WifiDeviceMode::Enum> bindableMode() { return &this->bMode; }