Skip to content

Quickshell.Network NetworkManager backend #96

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 34 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
a7ff484
init: NetworkManager service
cpwrs Jul 3, 2025
e92a9ec
fix: CMake typo
cpwrs Jul 4, 2025
66fa5dc
feat: NetworkManager.state
cpwrs Jul 4, 2025
c3e1280
feat: devices, wifiDevice, device properties
cpwrs Jul 6, 2025
6ee3cb5
hotfix: revert unintended change to upower
cpwrs Jul 6, 2025
8679f79
feat(nix): nm buildInput
cpwrs Jul 9, 2025
3c32d88
test: device basics
cpwrs Jul 9, 2025
0391e02
test: nm state
cpwrs Jul 9, 2025
fdbdf1d
fix: devicetype enum matches NMDeviceType in spec
cpwrs Jul 9, 2025
208cfd0
style: shorten to NM
cpwrs Jul 9, 2025
2504210
Revert "feat(nix): nm buildInput"
cpwrs Jul 9, 2025
d323881
feat: AP, Wireless xml
cpwrs Jul 9, 2025
4705796
fix test
cpwrs Jul 9, 2025
a1515c1
feat: begin wireless
cpwrs Jul 9, 2025
19ac6db
Merge branch 'quickshell-mirror:master' into nm
cpwrs Jul 9, 2025
e445c9b
Quickshell.Network
cpwrs Jul 11, 2025
c4d8fc2
clean
cpwrs Jul 11, 2025
28bf2d7
refactor: nm dir
cpwrs Jul 11, 2025
1d02e1c
fix: log names
cpwrs Jul 11, 2025
112eb66
feat: Wireless
cpwrs Jul 11, 2025
87787dc
feat: frontend slots
cpwrs Jul 14, 2025
bdaaa5f
feat: state, working subdevices
cpwrs Jul 14, 2025
c9ece29
disconnect
cpwrs Jul 15, 2025
997f45b
feat: scan, lastScan, NetworkDeviceType
cpwrs Jul 15, 2025
560232c
feat: accessPoints
cpwrs Jul 16, 2025
7090633
fix: annotate RequestScan a{sv} for qdbusxml2cpp
cpwrs Jul 16, 2025
6429991
feat: AccessPoints -> WifiNetworks
cpwrs Jul 21, 2025
61f8c8f
feat: connected
cpwrs Jul 21, 2025
8b21137
feat: remove lastScan
cpwrs Jul 22, 2025
c955811
refactor: move nm_* to nm/ and seperate adapter classes
cpwrs Jul 23, 2025
e5e0544
feat: backend connections
cpwrs Jul 23, 2025
be80d20
feat: ap flags, device connections
cpwrs Jul 24, 2025
840e6ec
feat: merge backend connections + networks -> WifiNetwork.
cpwrs Jul 28, 2025
c936fb9
feat: add NMActiveConnectionAdapter
cpwrs Aug 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ boption(SERVICE_GREETD "Greetd" ON)
boption(SERVICE_UPOWER "UPower" ON)
boption(SERVICE_NOTIFICATIONS "Notifications" ON)
boption(BLUETOOTH "Bluetooth" ON)
boption(NETWORK "Network" ON)

include(cmake/install-qml-module.cmake)
include(cmake/util.cmake)
Expand Down Expand Up @@ -117,7 +118,7 @@ if (WAYLAND)
list(APPEND QT_FPDEPS WaylandClient)
endif()

if (SERVICE_STATUS_NOTIFIER OR SERVICE_MPRIS OR SERVICE_UPOWER OR SERVICE_NOTIFICATIONS OR BLUETOOTH)
if (SERVICE_STATUS_NOTIFIER OR SERVICE_MPRIS OR SERVICE_UPOWER OR SERVICE_NOTIFICATIONS OR BLUETOOTH OR NETWORK)
set(DBUS ON)
endif()

Expand Down
4 changes: 4 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,7 @@ add_subdirectory(services)
if (BLUETOOTH)
add_subdirectory(bluetooth)
endif()

if (NETWORK)
add_subdirectory(network)
endif()
92 changes: 92 additions & 0 deletions src/network/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# NetworkManager DBus
set_source_files_properties(nm/org.freedesktop.NetworkManager.xml PROPERTIES
CLASSNAME DBusNetworkManagerProxy
NO_NAMESPACE TRUE
)

qt_add_dbus_interface(NM_DBUS_INTERFACES
nm/org.freedesktop.NetworkManager.xml
nm/dbus_nm_backend
)

set_source_files_properties(nm/org.freedesktop.NetworkManager.Device.xml PROPERTIES
CLASSNAME DBusNMDeviceProxy
NO_NAMESPACE TRUE
)

qt_add_dbus_interface(NM_DBUS_INTERFACES
nm/org.freedesktop.NetworkManager.Device.xml
nm/dbus_nm_device
)

set_source_files_properties(nm/org.freedesktop.NetworkManager.Device.Wireless.xml PROPERTIES
CLASSNAME DBusNMWirelessProxy
NO_NAMESPACE TRUE
)

qt_add_dbus_interface(NM_DBUS_INTERFACES
nm/org.freedesktop.NetworkManager.Device.Wireless.xml
nm/dbus_nm_wireless
)

set_source_files_properties(nm/org.freedesktop.NetworkManager.AccessPoint.xml PROPERTIES
CLASSNAME DBusNMAccessPointProxy
NO_NAMESPACE TRUE
)

qt_add_dbus_interface(NM_DBUS_INTERFACES
nm/org.freedesktop.NetworkManager.AccessPoint.xml
nm/dbus_nm_accesspoint
)

set_source_files_properties(nm/org.freedesktop.NetworkManager.Settings.Connection.xml PROPERTIES
CLASSNAME DBusNMConnectionSettingsProxy
INCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/nm/dbus_types.hpp
)

qt_add_dbus_interface(NM_DBUS_INTERFACES
nm/org.freedesktop.NetworkManager.Settings.Connection.xml
nm/dbus_nm_connection_settings
)

set_source_files_properties(nm/org.freedesktop.NetworkManager.Connection.Active.xml PROPERTIES
CLASSNAME DBusNMActiveConnectionProxy
NO_NAMESPACE TRUE
)

qt_add_dbus_interface(NM_DBUS_INTERFACES
nm/org.freedesktop.NetworkManager.Connection.Active.xml
nm/dbus_nm_active_connection
)

qt_add_library(quickshell-network STATIC
frontend.cpp
nm/backend.cpp
nm/device.cpp
nm/connection.cpp
nm/accesspoint.cpp
nm/wireless.cpp
nm/utils.cpp
nm/enums.hpp
${NM_DBUS_INTERFACES}
)

# dbus headers
target_include_directories(quickshell-network PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
)

qt_add_qml_module(quickshell-network
URI Quickshell.Network
VERSION 0.1
DEPENDENCIES QtQml
)

qs_add_module_deps_light(quickshell-network Quickshell)
install_qml_module(quickshell-network)

target_link_libraries(quickshell-network PRIVATE Qt::Qml Qt::DBus)
qs_add_link_dependencies(quickshell-network quickshell-dbus)
target_link_libraries(quickshell PRIVATE quickshell-networkplugin)

qs_module_pch(quickshell-network SET dbus)
161 changes: 161 additions & 0 deletions src/network/frontend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
#include "frontend.hpp"

#include <qdbusconnection.h>
#include <qdbusconnectioninterface.h>
#include <qdbusextratypes.h>
#include <qdbuspendingcall.h>
#include <qdbuspendingreply.h>
#include <qdbusservicewatcher.h>
#include <qlogging.h>

#include "nm/backend.hpp"

namespace qs::network {

namespace {
Q_LOGGING_CATEGORY(logNetworkDevice, "quickshell.network.device", QtWarningMsg);
Q_LOGGING_CATEGORY(logNetwork, "quickshell.network", QtWarningMsg);
} // namespace

NetworkDevice::NetworkDevice(QObject* parent): QObject(parent) {};

QString NetworkDeviceState::toString(NetworkDeviceState::Enum state) {
switch (state) {
case NetworkDeviceState::Unknown: return QStringLiteral("Unknown");
case NetworkDeviceState::Disconnected: return QStringLiteral("Disconnected");
case NetworkDeviceState::Connecting: return QStringLiteral("Connecting");
case NetworkDeviceState::Connected: return QStringLiteral("Connected");
case NetworkDeviceState::Disconnecting: return QStringLiteral("Disconnecting");
default: return QStringLiteral("Unknown");
}
}

QString NetworkDeviceType::toString(NetworkDeviceType::Enum type) {
switch (type) {
case NetworkDeviceType::Other: return QStringLiteral("Other");
case NetworkDeviceType::Wireless: return QStringLiteral("Wireless");
default: return QStringLiteral("Unknown");
}
}

void NetworkDevice::setName(const QString& name) {
if (name != this->bName) {
this->bName = name;
}
}

void NetworkDevice::setAddress(const QString& address) {
if (address != this->bAddress) {
this->bAddress = address;
}
}

void NetworkDevice::setState(NetworkDeviceState::Enum state) {
if (state != this->bState) {
this->bState = state;
}
}

void NetworkDevice::disconnect() {
if (this->bState == NetworkDeviceState::Disconnected) {
qCCritical(logNetworkDevice) << "Device" << this << "is already disconnected";
return;
}

if (this->bState == NetworkDeviceState::Disconnecting) {
qCCritical(logNetworkDevice) << "Device" << this << "is already disconnecting";
return;
}

qCDebug(logNetworkDevice) << "Disconnecting from device" << this;

this->requestDisconnect();
}

NetworkWifiDevice::NetworkWifiDevice(QObject* parent): NetworkDevice(parent) {};

void NetworkWifiDevice::scanComplete() {
if (this->bScanning) {
this->bScanning = false;
emit this->scanningChanged();
}
}

void NetworkWifiDevice::scan() {
if (this->bScanning) {
qCCritical(logNetworkDevice) << "Wireless device" << this << "is already scanning";
return;
}

qCDebug(logNetworkDevice) << "Requesting scan on wireless device" << this;
this->bScanning = true;
this->requestScan();
}

void NetworkWifiDevice::wifiNetworkAdded(WifiNetwork* network) {
this->mNetworks.insertObject(network);
}

void NetworkWifiDevice::wifiNetworkRemoved(WifiNetwork* network) {
this->mNetworks.removeObject(network);
}

WifiNetwork::WifiNetwork(QObject* parent): QObject(parent) {};

void WifiNetwork::setSsid(const QString& ssid) {
if (this->bSsid != ssid) {
this->bSsid = ssid;
emit this->ssidChanged();
}
}

void WifiNetwork::setSignalStrength(quint8 signal) {
if (this->bSignalStrength != signal) {
this->bSignalStrength = signal;
emit this->signalStrengthChanged();
}
}

void WifiNetwork::setConnected(bool connected) {
if (this->bConnected != connected) {
this->bConnected = connected;
emit this->connectedChanged();
}
}

void WifiNetwork::setNmSecurity(NMWirelessSecurityType::Enum security) {
if (this->bNmSecurity != security) {
this->bNmSecurity = security;
emit this->nmSecurityChanged();
}
}

void WifiNetwork::setKnown(bool known) {
if (this->bKnown != known) {
this->bKnown = known;
emit this->knownChanged();
}
}

Network::Network(QObject* parent): QObject(parent) {
// Try each backend

// NetworkManager
auto* nm = new NetworkManager(this);
if (nm->isAvailable()) {
QObject::connect(nm, &NetworkManager::deviceAdded, this, &Network::addDevice);
QObject::connect(nm, &NetworkManager::deviceRemoved, this, &Network::removeDevice);
this->backend = nm;
return;
} else {
delete nm;
}

qCCritical(logNetwork) << "Network will not work. Could not find an available backend.";
}

void Network::addDevice(NetworkDevice* device) { this->mDevices.insertObject(device); }

void Network::removeDevice(NetworkDevice* device) { this->mDevices.removeObject(device); }

} // namespace qs::network
Loading