11#include " wireless.hpp"
22#include < utility>
33
4+ #include < qdatetime.h>
45#include < qdbusconnection.h>
56#include < qdbusextratypes.h>
67#include < qdbuspendingcall.h>
@@ -181,7 +182,9 @@ void NMWirelessNetwork::removeActiveConnection() {
181182 }
182183};
183184
184- NMWirelessDevice::NMWirelessDevice (const QString& path, QObject* parent): NMDevice(path, parent) {
185+ NMWirelessDevice::NMWirelessDevice (const QString& path, QObject* parent)
186+ : NMDevice(path, parent)
187+ , mScanTimer (this ) {
185188 this ->wirelessProxy = new DBusNMWirelessProxy (
186189 " org.freedesktop.NetworkManager" ,
187190 path,
@@ -202,6 +205,9 @@ NMWirelessDevice::NMWirelessDevice(const QString& path, QObject* parent): NMDevi
202205 Qt::SingleShotConnection
203206 );
204207
208+ QObject::connect (&this ->mScanTimer , &QTimer::timeout, this , &NMWirelessDevice::onScanTimeout);
209+ this ->mScanTimer .setSingleShot (true );
210+
205211 this ->wirelessProperties .setInterface (this ->wirelessProxy );
206212 this ->wirelessProperties .updateAllViaGetAll ();
207213}
@@ -213,7 +219,6 @@ void NMWirelessDevice::initWireless() {
213219 QObject::connect (this , &NMWirelessDevice::accessPointLoaded, this , &NMWirelessDevice::onAccessPointLoaded);
214220 QObject::connect (this , &NMWirelessDevice::connectionLoaded, this , &NMWirelessDevice::onConnectionLoaded);
215221 QObject::connect (this , &NMWirelessDevice::activeConnectionLoaded, this , &NMWirelessDevice::onActiveConnectionLoaded);
216- QObject::connect (this , &NMWirelessDevice::lastScanChanged, this , [this ]() { this ->bScanning = false ; });
217222 // clang-format on
218223 this ->registerAccessPoints ();
219224}
@@ -279,25 +284,47 @@ void NMWirelessDevice::registerAccessPoint(const QString& path) {
279284 );
280285}
281286
287+ // Only make WifiNetworks visible to the frontend WifiDevice when
288+ // scanning is enabled or the network is connected or the network has known settings.
289+ void NMWirelessDevice::updateNetworkVisibility (WifiNetwork* net) {
290+ const bool show = this ->mScanning || net->connected () || net->known ();
291+ const bool visible = this ->mVisibleNetworks .contains (net);
292+
293+ if (show && !visible) {
294+ this ->mVisibleNetworks .insert (net);
295+ emit this ->networkAdded (net);
296+ } else if (!show && visible) {
297+ this ->mVisibleNetworks .remove (net);
298+ emit this ->networkRemoved (net);
299+ }
300+ }
301+
282302NMWirelessNetwork* NMWirelessDevice::registerNetwork (const QString& ssid) {
283303 auto * backend = new NMWirelessNetwork (ssid, this );
284304 backend->bindableActiveApPath ().setBinding ([this ]() { return this ->activeApPath ().path (); });
285305 backend->bindableCapabilities ().setBinding ([this ]() { return this ->capabilities (); });
286306
287307 auto * frontend = new WifiNetwork (ssid, this );
288- frontend->bindableSignalStrength ().setBinding ([backend]() { return backend->signalStrength ()/100.0 ; });
308+ frontend->bindableSignalStrength ().setBinding ([backend]() {
309+ return backend->signalStrength () / 100.0 ;
310+ });
289311 frontend->bindableConnected ().setBinding ([backend]() {
290- return backend->state () != NMConnectionState::Deactivated ;
312+ return backend->state () == NMConnectionState::Activated ;
291313 });
292314 frontend->bindableKnown ().setBinding ([backend]() { return backend->known (); });
293315 frontend->bindableNmReason ().setBinding ([backend]() { return backend->reason (); });
294316 frontend->bindableSecurity ().setBinding ([backend]() { return backend->security (); });
295317 QObject::connect (backend, &NMWirelessNetwork::disappeared, this , [this , frontend, backend]() {
296318 QObject::disconnect (backend, nullptr , nullptr , nullptr );
297- emit this -> wifiNetworkRemoved (frontend);
319+ QObject::disconnect (frontend, nullptr , nullptr , nullptr );
298320 this ->mBackendNetworks .remove (backend->ssid ());
299- delete backend;
321+ this ->mNetworks .remove (frontend->name ());
322+ if (this ->mVisibleNetworks .contains (frontend)) {
323+ this ->mVisibleNetworks .remove (frontend);
324+ emit this ->networkRemoved (frontend);
325+ }
300326 delete frontend;
327+ delete backend;
301328 });
302329 QObject::connect (frontend, &WifiNetwork::requestConnect, this , [this , backend]() {
303330 if (backend->referenceConnection ()) {
@@ -315,9 +342,16 @@ NMWirelessNetwork* NMWirelessDevice::registerNetwork(const QString& ssid) {
315342 );
316343 }
317344 });
345+ QObject::connect (frontend, &WifiNetwork::connectedChanged, this , [this , frontend]() {
346+ updateNetworkVisibility (frontend);
347+ });
348+ QObject::connect (frontend, &WifiNetwork::knownChanged, this , [this , frontend]() {
349+ updateNetworkVisibility (frontend);
350+ });
318351
319352 this ->mBackendNetworks .insert (ssid, backend);
320- emit this ->wifiNetworkAdded (frontend);
353+ this ->mNetworks .insert (ssid, frontend);
354+ this ->updateNetworkVisibility (frontend);
321355 return backend;
322356}
323357
@@ -343,7 +377,7 @@ void NMWirelessDevice::onConnectionLoaded(NMConnectionSettings* conn) {
343377 return ;
344378 }
345379
346- const QString ssid = settings[" 802-11-wireless" ][" ssid" ].toString ();
380+ const auto ssid = settings[" 802-11-wireless" ][" ssid" ].toString ();
347381 auto * net = this ->mBackendNetworks .value (ssid);
348382 if (!net) net = this ->registerNetwork (ssid);
349383
@@ -366,9 +400,33 @@ void NMWirelessDevice::onActiveConnectionLoaded(NMActiveConnection* active) {
366400 }
367401}
368402
369- void NMWirelessDevice::scan () {
370- this ->wirelessProxy ->RequestScan ({});
371- this ->bScanning = true ;
403+ void NMWirelessDevice::onScanTimeout () {
404+ const QDateTime now = QDateTime::currentDateTime ();
405+ const QDateTime lastScan = this ->bLastScan ;
406+ const QDateTime lastScanRequest = this ->mLastScanRequest ;
407+
408+ if (lastScan.isValid () && lastScan.msecsTo (now) < this ->mScanIntervalMs ) {
409+ // Rate limit if backend scan property updated within the interval
410+ auto diff = static_cast <int >(this ->mScanIntervalMs - lastScan.msecsTo (now));
411+ this ->mScanTimer .start (diff);
412+ } else if (lastScanRequest.isValid () && lastScanRequest.msecsTo (now) < this ->mScanIntervalMs ) {
413+ // Rate limit if frontend changes scanner state within the interval
414+ auto diff = static_cast <int >(this ->mScanIntervalMs - lastScanRequest.msecsTo (now));
415+ this ->mScanTimer .start (diff);
416+ } else {
417+ this ->wirelessProxy ->RequestScan ({});
418+ this ->mLastScanRequest = now;
419+ this ->mScanTimer .start (this ->mScanIntervalMs );
420+ }
421+ }
422+
423+ void NMWirelessDevice::handleScanner (bool enabled) {
424+ if (this ->mScanning == enabled) return ;
425+ this ->mScanning = enabled;
426+ for (WifiNetwork* net: this ->mNetworks ) {
427+ updateNetworkVisibility (net);
428+ }
429+ enabled ? this ->onScanTimeout () : this ->mScanTimer .stop ();
372430}
373431
374432bool NMWirelessDevice::isWirelessValid () const {
@@ -384,4 +442,8 @@ DBusDataTransform<qs::network::NMWirelessCapabilities::Enum>::fromWire(quint32 w
384442 return DBusResult (static_cast <qs::network::NMWirelessCapabilities::Enum>(wire));
385443}
386444
445+ DBusResult<QDateTime> DBusDataTransform<QDateTime>::fromWire(qint64 wire) {
446+ return DBusResult (network::clockBootTimeToDateTime (wire));
447+ }
448+
387449} // namespace qs::dbus
0 commit comments