Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,28 @@ default, you must create it manually.
"launcher": {
"actionPrefix": ">",
"actions": [
{
"name": "Example subaction",
"icon": "tune",
"description": "example of a subaction",
"command": ["openGroup", "example"],
"enabled": true,
"dangerous": false,
"children": [
{
"name": "action1",
"icon": "settings",
"description": "example of action1",
"command": [""]
},
{
"name": "action2",
"icon": "settings",
"description": "example of action2",
"command": [""]
}
]
},
{
"name": "Calculator",
"icon": "calculate",
Expand Down Expand Up @@ -629,12 +651,13 @@ default, you must create it manually.
"nowPlaying": false
},
"vpn": {
"enabled": false,
"enabled": true,
"provider": [
{
"name": "wireguard",
"interface": "your-connection-name",
"displayName": "Wireguard (Your VPN)"
"displayName": "Wireguard (Your VPN)",
"enabled": false
}
]
}
Expand Down
1 change: 1 addition & 0 deletions config/BarConfig.qml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ JsonObject {
property bool showMicrophone: false
property bool showKbLayout: false
property bool showNetwork: true
property bool showWifi: true
property bool showBluetooth: true
property bool showBattery: true
property bool showLockStatus: true
Expand Down
1 change: 1 addition & 0 deletions config/Config.qml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ Singleton {
showMicrophone: bar.status.showMicrophone,
showKbLayout: bar.status.showKbLayout,
showNetwork: bar.status.showNetwork,
showWifi: bar.status.showWifi,
showBluetooth: bar.status.showBluetooth,
showBattery: bar.status.showBattery,
showLockStatus: bar.status.showLockStatus
Expand Down
23 changes: 14 additions & 9 deletions modules/background/DesktopClock.qml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Item {
spacing: Appearance.spacing.small

StyledText {
text: Time.format(Config.services.useTwelveHourClock ? "hh" : "HH")
text: Time.hourStr
font.pointSize: Appearance.font.size.extraLarge * 3 * root.scale
font.weight: Font.Bold
color: root.safePrimary
Expand All @@ -94,19 +94,24 @@ Item {
}

StyledText {
text: Time.format("mm")
text: Time.minuteStr
font.pointSize: Appearance.font.size.extraLarge * 3 * root.scale
font.weight: Font.Bold
color: root.safeSecondary
}

StyledText {
visible: Config.services.useTwelveHourClock
text: Time.format("A")
font.pointSize: Appearance.font.size.large * root.scale
color: root.safeSecondary
Loader {
Layout.alignment: Qt.AlignTop
Layout.topMargin: Appearance.padding.large * 1.4 * root.scale

active: Config.services.useTwelveHourClock
visible: active

sourceComponent: StyledText {
text: Time.amPmStr
font.pointSize: Appearance.font.size.large * root.scale
color: root.safeSecondary
}
}
}

Expand Down Expand Up @@ -155,10 +160,10 @@ Item {
easing.bezierCurve: Appearance.anim.curves.expressiveDefaultSpatial
}
}

Behavior on implicitWidth {
Anim {
duration: Appearance.anim.durations.small
}
}
}
}
2 changes: 1 addition & 1 deletion modules/bar/components/StatusIcons.qml
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ StyledRect {
// Network icon
WrappedLoader {
name: "network"
active: Config.bar.status.showNetwork
active: Config.bar.status.showNetwork && (! Nmcli.activeEthernet || Config.bar.status.showWifi)

sourceComponent: MaterialIcon {
animate: true
Expand Down
1 change: 1 addition & 0 deletions modules/controlcenter/Session.qml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ QtObject {
readonly property NetworkState network: NetworkState {}
readonly property EthernetState ethernet: EthernetState {}
readonly property LauncherState launcher: LauncherState {}
readonly property VpnState vpn: VpnState {}

onActiveChanged: activeIndex = Math.max(0, panes.indexOf(active))
onActiveIndexChanged: if (panes[activeIndex]) active = panes[activeIndex]
Expand Down
74 changes: 74 additions & 0 deletions modules/controlcenter/network/NetworkSettings.qml
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import ".."
import "../components"
import qs.components
import qs.components.controls
import qs.components.containers
import qs.components.effects
import qs.services
import qs.config
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts

ColumnLayout {
Expand Down Expand Up @@ -59,6 +61,45 @@ ColumnLayout {
}
}

SectionHeader {
Layout.topMargin: Appearance.spacing.large
title: qsTr("VPN")
description: qsTr("VPN provider settings")
visible: Config.utilities.vpn.enabled || Config.utilities.vpn.provider.length > 0
}

SectionContainer {
visible: Config.utilities.vpn.enabled || Config.utilities.vpn.provider.length > 0

ToggleRow {
label: qsTr("VPN enabled")
checked: Config.utilities.vpn.enabled
toggle.onToggled: {
Config.utilities.vpn.enabled = checked;
Config.save();
}
}

PropertyRow {
showTopMargin: true
label: qsTr("Providers")
value: qsTr("%1").arg(Config.utilities.vpn.provider.length)
}

TextButton {
Layout.fillWidth: true
Layout.topMargin: Appearance.spacing.normal
Layout.minimumHeight: Appearance.font.size.normal + Appearance.padding.normal * 2
text: qsTr("⚙ Manage VPN Providers")
inactiveColour: Colours.palette.m3secondaryContainer
inactiveOnColour: Colours.palette.m3onSecondaryContainer

onClicked: {
vpnSettingsDialog.open();
}
}
}

SectionHeader {
Layout.topMargin: Appearance.spacing.large
title: qsTr("Current connection")
Expand Down Expand Up @@ -94,5 +135,38 @@ ColumnLayout {
value: Nmcli.active ? qsTr("%1 MHz").arg(Nmcli.active.frequency) : qsTr("N/A")
}
}

Popup {
id: vpnSettingsDialog

parent: Overlay.overlay
anchors.centerIn: parent
width: Math.min(600, parent.width - Appearance.padding.large * 2)
height: Math.min(700, parent.height - Appearance.padding.large * 2)

modal: true
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside

background: StyledRect {
color: Colours.palette.m3surface
radius: Appearance.rounding.large
}

StyledFlickable {
anchors.fill: parent
anchors.margins: Appearance.padding.large * 1.5
flickableDirection: Flickable.VerticalFlick
contentHeight: vpnSettingsContent.height
clip: true

VpnSettings {
id: vpnSettingsContent

anchors.left: parent.left
anchors.right: parent.right
session: root.session
}
}
}
}

92 changes: 76 additions & 16 deletions modules/controlcenter/network/NetworkingPane.qml
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,24 @@ Item {
}
}

CollapsibleSection {
id: vpnListSection

Layout.fillWidth: true
title: qsTr("VPN")
expanded: true

Loader {
Layout.fillWidth: true
sourceComponent: Component {
VpnList {
session: root.session
showHeader: false
}
}
}
}

CollapsibleSection {
id: ethernetListSection

Expand Down Expand Up @@ -154,14 +172,16 @@ Item {
Item {
id: rightPaneItem

property var ethernetPane: root.session.ethernet.active
property var wirelessPane: root.session.network.active
property var pane: ethernetPane || wirelessPane
property string paneId: ethernetPane ? ("eth:" + (ethernetPane.interface || "")) : (wirelessPane ? ("wifi:" + (wirelessPane.ssid || wirelessPane.bssid || "")) : "settings")
property var vpnPane: root.session && root.session.vpn ? root.session.vpn.active : null
property var ethernetPane: root.session && root.session.ethernet ? root.session.ethernet.active : null
property var wirelessPane: root.session && root.session.network ? root.session.network.active : null
property var pane: vpnPane || ethernetPane || wirelessPane
property string paneId: vpnPane ? ("vpn:" + (vpnPane.name || "")) : (ethernetPane ? ("eth:" + (ethernetPane.interface || "")) : (wirelessPane ? ("wifi:" + (wirelessPane.ssid || wirelessPane.bssid || "")) : "settings"))
property Component targetComponent: settingsComponent
property Component nextComponent: settingsComponent

function getComponentForPane() {
if (vpnPane) return vpnDetailsComponent;
if (ethernetPane) return ethernetDetailsComponent;
if (wirelessPane) return wirelessDetailsComponent;
return settingsComponent;
Expand All @@ -173,28 +193,44 @@ Item {
}

Connections {
target: root.session.ethernet
target: root.session && root.session.vpn ? root.session.vpn : null
enabled: target !== null

function onActiveChanged() {
// Clear wireless when ethernet is selected
if (root.session.ethernet.active && root.session.network.active) {
root.session.network.active = null;
return; // Let the network.onActiveChanged handle the update
// Clear others when VPN is selected
if (root.session && root.session.vpn && root.session.vpn.active) {
if (root.session.ethernet && root.session.ethernet.active) root.session.ethernet.active = null;
if (root.session.network && root.session.network.active) root.session.network.active = null;
}
rightPaneItem.nextComponent = rightPaneItem.getComponentForPane();
// paneId will automatically update via property binding
}
}

Connections {
target: root.session.network
target: root.session && root.session.ethernet ? root.session.ethernet : null
enabled: target !== null

function onActiveChanged() {
// Clear ethernet when wireless is selected
if (root.session.network.active && root.session.ethernet.active) {
root.session.ethernet.active = null;
return; // Let the ethernet.onActiveChanged handle the update
// Clear others when ethernet is selected
if (root.session && root.session.ethernet && root.session.ethernet.active) {
if (root.session.vpn && root.session.vpn.active) root.session.vpn.active = null;
if (root.session.network && root.session.network.active) root.session.network.active = null;
}
rightPaneItem.nextComponent = rightPaneItem.getComponentForPane();
}
}

Connections {
target: root.session && root.session.network ? root.session.network : null
enabled: target !== null

function onActiveChanged() {
// Clear others when wireless is selected
if (root.session && root.session.network && root.session.network.active) {
if (root.session.vpn && root.session.vpn.active) root.session.vpn.active = null;
if (root.session.ethernet && root.session.ethernet.active) root.session.ethernet.active = null;
}
rightPaneItem.nextComponent = rightPaneItem.getComponentForPane();
// paneId will automatically update via property binding
}
}

Expand All @@ -208,6 +244,7 @@ Item {
transformOrigin: Item.Center
clip: false

asynchronous: true
sourceComponent: rightPaneItem.targetComponent
}

Expand Down Expand Up @@ -296,6 +333,29 @@ Item {
}
}

Component {
id: vpnDetailsComponent

StyledFlickable {
id: vpnFlickable
flickableDirection: Flickable.VerticalFlick
contentHeight: vpnDetailsInner.height

StyledScrollBar.vertical: StyledScrollBar {
flickable: vpnFlickable
}

VpnDetails {
id: vpnDetailsInner

anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
session: root.session
}
}
}

WirelessPasswordDialog {
anchors.fill: parent
session: root.session
Expand Down
Loading