cleanup: removed unnecessary comments
This commit is contained in:
parent
978a3f4302
commit
147410e39b
22 changed files with 9 additions and 194 deletions
|
|
@ -97,6 +97,5 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// Expose initialOpeningComplete for NavRail to prevent tab switching during opening animation
|
||||
readonly property bool initialOpeningComplete: panes.initialOpeningComplete
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ ClippingRectangle {
|
|||
|
||||
required property Session session
|
||||
|
||||
// Expose initialOpeningComplete so parent can check if opening animation is done
|
||||
readonly property bool initialOpeningComplete: layout.initialOpeningComplete
|
||||
|
||||
color: "transparent"
|
||||
|
|
@ -27,7 +26,6 @@ ClippingRectangle {
|
|||
focus: false
|
||||
activeFocusOnTab: false
|
||||
|
||||
// Clear focus when clicking anywhere in the panes area
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
|
|
@ -37,7 +35,6 @@ ClippingRectangle {
|
|||
}
|
||||
}
|
||||
|
||||
// Clear focus when switching panes
|
||||
Connections {
|
||||
target: root.session
|
||||
|
||||
|
|
@ -54,8 +51,6 @@ ClippingRectangle {
|
|||
clip: true
|
||||
|
||||
property bool animationComplete: true
|
||||
// Track if initial opening animation has completed
|
||||
// During initial opening, only the active pane loads to avoid hiccups
|
||||
property bool initialOpeningComplete: false
|
||||
|
||||
Timer {
|
||||
|
|
@ -66,8 +61,6 @@ ClippingRectangle {
|
|||
}
|
||||
}
|
||||
|
||||
// Timer to detect when initial opening animation completes
|
||||
// Uses large duration to cover both normal and detached opening cases
|
||||
Timer {
|
||||
id: initialOpeningTimer
|
||||
interval: Appearance.anim.durations.large
|
||||
|
|
@ -94,7 +87,6 @@ ClippingRectangle {
|
|||
Connections {
|
||||
target: root.session
|
||||
function onActiveIndexChanged(): void {
|
||||
// Mark animation as incomplete and start delay timer
|
||||
layout.animationComplete = false;
|
||||
animationDelayTimer.restart();
|
||||
}
|
||||
|
|
@ -110,28 +102,21 @@ ClippingRectangle {
|
|||
implicitWidth: root.width
|
||||
implicitHeight: root.height
|
||||
|
||||
// Track if this pane has ever been loaded to enable caching
|
||||
property bool hasBeenLoaded: false
|
||||
|
||||
// Function to compute if this pane should be active
|
||||
function updateActive(): void {
|
||||
const diff = Math.abs(root.session.activeIndex - pane.paneIndex);
|
||||
const isActivePane = diff === 0;
|
||||
let shouldBeActive = false;
|
||||
|
||||
// During initial opening animation, only load the active pane
|
||||
// This prevents hiccups from multiple panes loading simultaneously
|
||||
if (!layout.initialOpeningComplete) {
|
||||
shouldBeActive = isActivePane;
|
||||
} else {
|
||||
// After initial opening, allow current and adjacent panes for smooth transitions
|
||||
if (diff <= 1) {
|
||||
shouldBeActive = true;
|
||||
} else if (pane.hasBeenLoaded) {
|
||||
// For distant panes that have been loaded before, keep them active to preserve cached data
|
||||
shouldBeActive = true;
|
||||
} else {
|
||||
// For new distant panes, wait until animation completes to avoid heavy loading during transition
|
||||
shouldBeActive = layout.animationComplete;
|
||||
}
|
||||
}
|
||||
|
|
@ -152,12 +137,10 @@ ClippingRectangle {
|
|||
}
|
||||
|
||||
onActiveChanged: {
|
||||
// Mark pane as loaded when it becomes active
|
||||
if (active && !pane.hasBeenLoaded) {
|
||||
pane.hasBeenLoaded = true;
|
||||
}
|
||||
|
||||
// Load the component with initial properties when activated
|
||||
if (active && !item) {
|
||||
loader.setSource(pane.componentPath, {
|
||||
"session": root.session
|
||||
|
|
@ -166,7 +149,6 @@ ClippingRectangle {
|
|||
}
|
||||
|
||||
onItemChanged: {
|
||||
// Mark pane as loaded when item is created
|
||||
if (item) {
|
||||
pane.hasBeenLoaded = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ QtObject {
|
|||
property int activeIndex: 0
|
||||
property bool navExpanded: false
|
||||
|
||||
// Pane-specific state objects
|
||||
readonly property BluetoothState bt: BluetoothState {}
|
||||
readonly property NetworkState network: NetworkState {}
|
||||
readonly property EthernetState ethernet: EthernetState {}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ Item {
|
|||
|
||||
required property Session session
|
||||
|
||||
// Appearance settings
|
||||
property real animDurationsScale: Config.appearance.anim.durations.scale ?? 1
|
||||
property string fontFamilyMaterial: Config.appearance.font.family.material ?? "Material Symbols Rounded"
|
||||
property string fontFamilyMono: Config.appearance.font.family.mono ?? "CaskaydiaCove NF"
|
||||
|
|
@ -37,7 +36,6 @@ Item {
|
|||
property real borderRounding: Config.border.rounding ?? 1
|
||||
property real borderThickness: Config.border.thickness ?? 1
|
||||
|
||||
// Background settings
|
||||
property bool desktopClockEnabled: Config.background.desktopClock.enabled ?? false
|
||||
property bool backgroundEnabled: Config.background.enabled ?? true
|
||||
property bool visualiserEnabled: Config.background.visualiser.enabled ?? false
|
||||
|
|
@ -127,13 +125,8 @@ Item {
|
|||
anchors.fill: parent
|
||||
asynchronous: true
|
||||
active: {
|
||||
// Lazy load: only activate when:
|
||||
// 1. Right pane is loaded AND
|
||||
// 2. Appearance pane is active (index 3) or adjacent (for smooth transitions)
|
||||
// This prevents loading all wallpapers when control center opens but appearance pane isn't visible
|
||||
const isActive = root.session.activeIndex === 3;
|
||||
const isAdjacent = Math.abs(root.session.activeIndex - 3) === 1;
|
||||
// Access loader through SplitPaneLayout's rightLoader
|
||||
const splitLayout = root.children[0];
|
||||
const loader = splitLayout && splitLayout.rightLoader ? splitLayout.rightLoader : null;
|
||||
const shouldActivate = loader && loader.item !== null && (isActive || isAdjacent);
|
||||
|
|
@ -150,7 +143,6 @@ Item {
|
|||
onActiveChanged: {
|
||||
if (!active && wallpaperLoader.item) {
|
||||
const container = wallpaperLoader.item;
|
||||
// Access timer through wallpaperGrid
|
||||
if (container && container.wallpaperGrid) {
|
||||
const grid = container.wallpaperGrid;
|
||||
if (grid.imageUpdateTimer) {
|
||||
|
|
@ -186,20 +178,17 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// Lazy loading model: loads one image at a time, only when touching bottom
|
||||
// This prevents GridView from creating all delegates at once
|
||||
QtObject {
|
||||
id: lazyModel
|
||||
|
||||
property var sourceList: null
|
||||
property int loadedCount: 0 // Total items available to load
|
||||
property int visibleCount: 0 // Items actually exposed to GridView (only visible + buffer)
|
||||
property int loadedCount: 0
|
||||
property int visibleCount: 0
|
||||
property int totalCount: 0
|
||||
|
||||
function initialize(list) {
|
||||
sourceList = list;
|
||||
totalCount = list ? list.length : 0;
|
||||
// Start with enough items to fill the initial viewport (~3 rows)
|
||||
const initialRows = 3;
|
||||
const cols = wallpaperGrid.columnsCount > 0 ? wallpaperGrid.columnsCount : 3;
|
||||
const initialCount = Math.min(initialRows * cols, totalCount);
|
||||
|
|
@ -216,7 +205,6 @@ Item {
|
|||
}
|
||||
|
||||
function updateVisibleCount(neededCount) {
|
||||
// Always round up to complete rows to avoid incomplete rows in the grid
|
||||
const cols = wallpaperGrid.columnsCount > 0 ? wallpaperGrid.columnsCount : 1;
|
||||
const maxVisible = Math.min(neededCount, loadedCount);
|
||||
const rows = Math.ceil(maxVisible / cols);
|
||||
|
|
@ -237,7 +225,6 @@ Item {
|
|||
readonly property int minCellWidth: 200 + Appearance.spacing.normal
|
||||
readonly property int columnsCount: Math.max(1, Math.floor(parent.width / minCellWidth))
|
||||
|
||||
// Height based on visible items only - prevents GridView from creating all delegates
|
||||
readonly property int layoutPreferredHeight: {
|
||||
if (!lazyModel || lazyModel.visibleCount === 0 || columnsCount === 0) {
|
||||
return 0;
|
||||
|
|
@ -255,7 +242,6 @@ Item {
|
|||
topMargin: 0
|
||||
bottomMargin: 0
|
||||
|
||||
// Use ListModel for incremental updates to prevent flashing when new items are added
|
||||
ListModel {
|
||||
id: wallpaperListModel
|
||||
}
|
||||
|
|
@ -270,7 +256,6 @@ Item {
|
|||
const newCount = lazyModel.visibleCount;
|
||||
const currentCount = wallpaperListModel.count;
|
||||
|
||||
// Only append new items - never remove or replace existing ones
|
||||
if (newCount > currentCount) {
|
||||
const flickable = wallpaperGridContainer.parentFlickable;
|
||||
const oldScrollY = flickable ? flickable.contentY : 0;
|
||||
|
|
@ -279,7 +264,6 @@ Item {
|
|||
wallpaperListModel.append({modelData: lazyModel.sourceList[i]});
|
||||
}
|
||||
|
||||
// Preserve scroll position after model update
|
||||
if (flickable) {
|
||||
Qt.callLater(function() {
|
||||
if (Math.abs(flickable.contentY - oldScrollY) < 1) {
|
||||
|
|
@ -382,7 +366,6 @@ Item {
|
|||
const neededCount = Math.min((neededBottomRow + 1) * wallpaperGrid.columnsCount, lazyModel.loadedCount);
|
||||
lazyModel.updateVisibleCount(neededCount);
|
||||
|
||||
// Load more when we're within 1 row of running out of loaded items
|
||||
const loadedRows = Math.ceil(lazyModel.loadedCount / wallpaperGrid.columnsCount);
|
||||
const rowsRemaining = loadedRows - (bottomRow + 1);
|
||||
|
||||
|
|
@ -434,7 +417,6 @@ Item {
|
|||
const neededCount = Math.min((neededBottomRow + 1) * wallpaperGrid.columnsCount, lazyModel.loadedCount);
|
||||
lazyModel.updateVisibleCount(neededCount);
|
||||
|
||||
// Load more when we're within 1 row of running out of loaded items
|
||||
const loadedRows = Math.ceil(lazyModel.loadedCount / wallpaperGrid.columnsCount);
|
||||
const rowsRemaining = loadedRows - (bottomRow + 1);
|
||||
|
||||
|
|
@ -450,8 +432,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Parent Flickable handles scrolling
|
||||
interactive: false
|
||||
|
||||
|
||||
|
|
@ -786,11 +766,9 @@ Item {
|
|||
function onClicked(): void {
|
||||
const variant = modelData.variant;
|
||||
|
||||
// Optimistic update - set immediately for responsive UI
|
||||
Schemes.currentVariant = variant;
|
||||
Quickshell.execDetached(["caelestia", "scheme", "set", "-v", variant]);
|
||||
|
||||
// Reload after a delay to confirm changes
|
||||
Qt.callLater(() => {
|
||||
reloadTimer.restart();
|
||||
});
|
||||
|
|
@ -873,11 +851,9 @@ Item {
|
|||
const flavour = modelData.flavour;
|
||||
const schemeKey = `${name} ${flavour}`;
|
||||
|
||||
// Optimistic update - set immediately for responsive UI
|
||||
Schemes.currentScheme = schemeKey;
|
||||
Quickshell.execDetached(["caelestia", "scheme", "set", "-n", name, "-f", flavour]);
|
||||
|
||||
// Reload after a delay to confirm changes
|
||||
Qt.callLater(() => {
|
||||
reloadTimer.restart();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ Item {
|
|||
anchors.right: parent.right
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
// Audio header above the collapsible sections
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Appearance.spacing.smaller
|
||||
|
|
|
|||
|
|
@ -440,7 +440,6 @@ StyledFlickable {
|
|||
}
|
||||
}
|
||||
|
||||
// FAB Menu (positioned absolutely relative to flickable)
|
||||
ColumnLayout {
|
||||
anchors.right: fabRoot.right
|
||||
anchors.bottom: fabRoot.top
|
||||
|
|
|
|||
|
|
@ -328,7 +328,7 @@ ColumnLayout {
|
|||
|
||||
anchors.left: parent.left
|
||||
|
||||
text: qsTr("Rename adapter (currently does not work)") // FIXME: remove disclaimer when fixed
|
||||
text: qsTr("Rename adapter (currently does not work)")
|
||||
color: Colours.palette.m3outline
|
||||
font.pointSize: Appearance.font.size.small
|
||||
}
|
||||
|
|
@ -345,8 +345,6 @@ ColumnLayout {
|
|||
readOnly: !root.session.bt.editingAdapterName
|
||||
onAccepted: {
|
||||
root.session.bt.editingAdapterName = false;
|
||||
// Doesn't work for now, will be added to QS later
|
||||
// root.session.bt.currentAdapter.name = text;
|
||||
}
|
||||
|
||||
leftPadding: Appearance.padding.normal
|
||||
|
|
|
|||
|
|
@ -18,10 +18,7 @@ Item {
|
|||
property Component headerComponent: null
|
||||
property list<Component> sections: []
|
||||
|
||||
// Optional: Custom content to insert after header but before sections
|
||||
property Component topContent: null
|
||||
|
||||
// Optional: Custom content to insert after all sections
|
||||
property Component bottomContent: null
|
||||
|
||||
implicitWidth: layout.implicitWidth
|
||||
|
|
@ -35,7 +32,6 @@ Item {
|
|||
anchors.top: parent.top
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
// Header component (e.g., ConnectionHeader or SettingsHeader)
|
||||
Loader {
|
||||
id: headerLoader
|
||||
|
||||
|
|
@ -44,7 +40,6 @@ Item {
|
|||
visible: root.headerComponent !== null
|
||||
}
|
||||
|
||||
// Top content (optional)
|
||||
Loader {
|
||||
id: topContentLoader
|
||||
|
||||
|
|
@ -53,7 +48,6 @@ Item {
|
|||
visible: root.topContent !== null
|
||||
}
|
||||
|
||||
// Sections
|
||||
Repeater {
|
||||
model: root.sections
|
||||
|
||||
|
|
@ -65,7 +59,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// Bottom content (optional)
|
||||
Loader {
|
||||
id: bottomContentLoader
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ ColumnLayout {
|
|||
|
||||
spacing: Appearance.spacing.small
|
||||
|
||||
// Header with action buttons (optional)
|
||||
Loader {
|
||||
id: headerLoader
|
||||
|
||||
|
|
@ -37,7 +36,6 @@ ColumnLayout {
|
|||
visible: root.headerComponent !== null && root.showHeader
|
||||
}
|
||||
|
||||
// Title and description row
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: root.headerComponent ? 0 : 0
|
||||
|
|
@ -61,10 +59,8 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// Expose view for access from parent components
|
||||
property alias view: view
|
||||
|
||||
// Description text
|
||||
StyledText {
|
||||
visible: root.description !== ""
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -72,20 +68,18 @@ ColumnLayout {
|
|||
color: Colours.palette.m3outline
|
||||
}
|
||||
|
||||
// List view
|
||||
StyledListView {
|
||||
id: view
|
||||
|
||||
Layout.fillWidth: true
|
||||
// Use contentHeight to show all items without estimation
|
||||
implicitHeight: contentHeight
|
||||
|
||||
model: root.model
|
||||
delegate: root.delegate
|
||||
|
||||
spacing: Appearance.spacing.small / 2
|
||||
interactive: false // Disable individual scrolling - parent pane handles it
|
||||
clip: false // Don't clip - let parent handle scrolling
|
||||
interactive: false
|
||||
clip: false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,26 +3,17 @@ pragma ComponentBehavior: Bound
|
|||
import qs.config
|
||||
import QtQuick
|
||||
|
||||
// Reusable pane transition animation component
|
||||
// Provides standard fade-out/scale-down → update → fade-in/scale-up animation
|
||||
// Used when switching between detail/settings views in panes
|
||||
SequentialAnimation {
|
||||
id: root
|
||||
|
||||
// The Loader element to animate
|
||||
required property Item target
|
||||
|
||||
// Optional list of PropertyActions to execute during the transition
|
||||
// These typically update the component being displayed
|
||||
property list<PropertyAction> propertyActions
|
||||
|
||||
// Animation parameters (with sensible defaults)
|
||||
property real scaleFrom: 1.0
|
||||
property real scaleTo: 0.8
|
||||
property real opacityFrom: 1.0
|
||||
property real opacityTo: 0.0
|
||||
|
||||
// Fade out and scale down
|
||||
ParallelAnimation {
|
||||
NumberAnimation {
|
||||
target: root.target
|
||||
|
|
@ -45,8 +36,6 @@ SequentialAnimation {
|
|||
}
|
||||
}
|
||||
|
||||
// Execute property actions (component switching, state updates, etc.)
|
||||
// This is where the component change happens while invisible
|
||||
ScriptAction {
|
||||
script: {
|
||||
for (let i = 0; i < root.propertyActions.length; i++) {
|
||||
|
|
@ -58,7 +47,6 @@ SequentialAnimation {
|
|||
}
|
||||
}
|
||||
|
||||
// Fade in and scale up
|
||||
ParallelAnimation {
|
||||
NumberAnimation {
|
||||
target: root.target
|
||||
|
|
|
|||
|
|
@ -15,19 +15,14 @@ RowLayout {
|
|||
property Component leftContent: null
|
||||
property Component rightContent: null
|
||||
|
||||
// Left pane configuration
|
||||
property real leftWidthRatio: 0.4
|
||||
property int leftMinimumWidth: 420
|
||||
property var leftLoaderProperties: ({})
|
||||
|
||||
// Right pane configuration
|
||||
property var rightLoaderProperties: ({})
|
||||
|
||||
// Expose loaders for customization (access via splitLayout.leftLoader or splitLayout.rightLoader)
|
||||
property alias leftLoader: leftLoader
|
||||
property alias rightLoader: rightLoader
|
||||
|
||||
// Left pane
|
||||
Item {
|
||||
id: leftPane
|
||||
|
||||
|
|
@ -57,7 +52,6 @@ RowLayout {
|
|||
asynchronous: true
|
||||
sourceComponent: root.leftContent
|
||||
|
||||
// Apply any additional properties from leftLoaderProperties
|
||||
Component.onCompleted: {
|
||||
for (const key in root.leftLoaderProperties) {
|
||||
leftLoader[key] = root.leftLoaderProperties[key];
|
||||
|
|
@ -74,7 +68,6 @@ RowLayout {
|
|||
}
|
||||
}
|
||||
|
||||
// Right pane
|
||||
Item {
|
||||
id: rightPane
|
||||
|
||||
|
|
@ -101,7 +94,6 @@ RowLayout {
|
|||
asynchronous: true
|
||||
sourceComponent: root.rightContent
|
||||
|
||||
// Apply any additional properties from rightLoaderProperties
|
||||
Component.onCompleted: {
|
||||
for (const key in root.rightLoaderProperties) {
|
||||
rightLoader[key] = root.rightLoaderProperties[key];
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ Item {
|
|||
property var activeItem: null
|
||||
property var paneIdGenerator: function(item) { return item ? String(item) : ""; }
|
||||
|
||||
// Optional: Additional component to overlay on top (e.g., password dialogs)
|
||||
property Component overlayComponent: null
|
||||
|
||||
SplitPaneLayout {
|
||||
|
|
@ -82,7 +81,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// Overlay component (e.g., password dialogs)
|
||||
Loader {
|
||||
id: overlayLoader
|
||||
|
||||
|
|
|
|||
|
|
@ -62,26 +62,20 @@ Item {
|
|||
|
||||
const appId = root.selectedApp.id || root.selectedApp.entry?.id;
|
||||
|
||||
// Create a new array to ensure change detection
|
||||
const hiddenApps = Config.launcher.hiddenApps ? [...Config.launcher.hiddenApps] : [];
|
||||
|
||||
if (isHidden) {
|
||||
// Add to hiddenApps if not already there
|
||||
if (!hiddenApps.includes(appId)) {
|
||||
hiddenApps.push(appId);
|
||||
}
|
||||
} else {
|
||||
// Remove from hiddenApps
|
||||
const index = hiddenApps.indexOf(appId);
|
||||
if (index !== -1) {
|
||||
hiddenApps.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Update Config
|
||||
Config.launcher.hiddenApps = hiddenApps;
|
||||
|
||||
// Persist changes to disk
|
||||
Config.save();
|
||||
}
|
||||
|
||||
|
|
@ -90,15 +84,13 @@ Item {
|
|||
id: allAppsDb
|
||||
|
||||
path: `${Paths.state}/apps.sqlite`
|
||||
entries: DesktopEntries.applications.values // No filter - show all apps
|
||||
entries: DesktopEntries.applications.values
|
||||
}
|
||||
|
||||
property string searchText: ""
|
||||
|
||||
function filterApps(search: string): list<var> {
|
||||
// If search is empty, return all apps directly
|
||||
if (!search || search.trim() === "") {
|
||||
// Convert QQmlListProperty to array
|
||||
const apps = [];
|
||||
for (let i = 0; i < allAppsDb.apps.length; i++) {
|
||||
apps.push(allAppsDb.apps[i]);
|
||||
|
|
@ -110,7 +102,6 @@ Item {
|
|||
return [];
|
||||
}
|
||||
|
||||
// Prepare apps for fuzzy search
|
||||
const preparedApps = [];
|
||||
for (let i = 0; i < allAppsDb.apps.length; i++) {
|
||||
const app = allAppsDb.apps[i];
|
||||
|
|
@ -121,14 +112,12 @@ Item {
|
|||
});
|
||||
}
|
||||
|
||||
// Perform fuzzy search
|
||||
const results = Fuzzy.go(search, preparedApps, {
|
||||
all: true,
|
||||
keys: ["name"],
|
||||
scoreFn: r => r[0].score
|
||||
});
|
||||
|
||||
// Return sorted by score (highest first)
|
||||
return results
|
||||
.sort((a, b) => b._score - a._score)
|
||||
.map(r => r.obj._item);
|
||||
|
|
@ -192,7 +181,6 @@ Item {
|
|||
if (root.session.launcher.active) {
|
||||
root.session.launcher.active = null;
|
||||
} else {
|
||||
// Toggle to show settings - if there are apps, select the first one, otherwise show settings
|
||||
if (root.filteredApps.length > 0) {
|
||||
root.session.launcher.active = root.filteredApps[0];
|
||||
}
|
||||
|
|
@ -302,13 +290,7 @@ Item {
|
|||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
asynchronous: true
|
||||
active: {
|
||||
// Lazy load: activate when left pane is loaded
|
||||
// The ListView will load asynchronously, and search will work because filteredApps
|
||||
// is updated regardless of whether the ListView is loaded
|
||||
// Access loader through parent - this will be set when component loads
|
||||
return true;
|
||||
}
|
||||
active: true
|
||||
|
||||
sourceComponent: StyledListView {
|
||||
id: appsListView
|
||||
|
|
@ -418,11 +400,9 @@ Item {
|
|||
sourceComponent: rightLauncherPane.targetComponent
|
||||
active: true
|
||||
|
||||
// Expose displayedApp to loaded components
|
||||
property var displayedApp: rightLauncherPane.displayedApp
|
||||
|
||||
onItemChanged: {
|
||||
// Ensure displayedApp is set when item is created (for async loading)
|
||||
if (item && rightLauncherPane.pane && rightLauncherPane.displayedApp !== rightLauncherPane.pane) {
|
||||
rightLauncherPane.displayedApp = rightLauncherPane.pane;
|
||||
}
|
||||
|
|
@ -508,12 +488,10 @@ Item {
|
|||
id: appDetailsLayout
|
||||
anchors.fill: parent
|
||||
|
||||
// Get displayedApp from parent Loader (the Loader has displayedApp property we set)
|
||||
readonly property var displayedApp: parent && parent.displayedApp !== undefined ? parent.displayedApp : null
|
||||
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
// Show SettingsHeader when no app is selected, or show app icon + title when app is selected
|
||||
SettingsHeader {
|
||||
Layout.leftMargin: Appearance.padding.large * 2
|
||||
Layout.rightMargin: Appearance.padding.large * 2
|
||||
|
|
@ -523,7 +501,6 @@ Item {
|
|||
title: qsTr("Launcher Applications")
|
||||
}
|
||||
|
||||
// App icon and title display (shown when app is selected)
|
||||
Item {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.leftMargin: Appearance.padding.large * 2
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@ Item {
|
|||
anchors.right: parent.right
|
||||
spacing: Appearance.spacing.normal
|
||||
|
||||
// Network header above the collapsible sections
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
spacing: Appearance.spacing.smaller
|
||||
|
|
@ -102,7 +101,6 @@ Item {
|
|||
root.session.ethernet.active = null;
|
||||
root.session.network.active = null;
|
||||
} else {
|
||||
// Toggle to show settings - prefer ethernet if available, otherwise wireless
|
||||
if (Nmcli.ethernetDevices.length > 0) {
|
||||
root.session.ethernet.active = Nmcli.ethernetDevices[0];
|
||||
} else if (Nmcli.networks.length > 0) {
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ DeviceDetails {
|
|||
}
|
||||
|
||||
onNetworkChanged: {
|
||||
// Restart timer when network changes
|
||||
connectionUpdateTimer.stop();
|
||||
if (network && network.ssid) {
|
||||
connectionUpdateTimer.start();
|
||||
|
|
@ -48,11 +47,9 @@ DeviceDetails {
|
|||
updateDeviceDetails();
|
||||
}
|
||||
function onWirelessDeviceDetailsChanged() {
|
||||
// When details are updated, check if we should stop the timer
|
||||
if (network && network.ssid) {
|
||||
const isActive = network.active || (Nmcli.active && Nmcli.active.ssid === network.ssid);
|
||||
if (isActive && Nmcli.wirelessDeviceDetails && Nmcli.wirelessDeviceDetails !== null) {
|
||||
// We have details for the active network, stop the timer
|
||||
connectionUpdateTimer.stop();
|
||||
}
|
||||
}
|
||||
|
|
@ -65,22 +62,16 @@ DeviceDetails {
|
|||
repeat: true
|
||||
running: network && network.ssid
|
||||
onTriggered: {
|
||||
// Periodically check if network becomes active and update details
|
||||
if (network) {
|
||||
const isActive = network.active || (Nmcli.active && Nmcli.active.ssid === network.ssid);
|
||||
if (isActive) {
|
||||
// Network is active - check if we have details
|
||||
if (!Nmcli.wirelessDeviceDetails || Nmcli.wirelessDeviceDetails === null) {
|
||||
// Network is active but we don't have details yet, fetch them
|
||||
Nmcli.getWirelessDeviceDetails("", () => {
|
||||
// After fetching, check if we got details - if not, timer will try again
|
||||
});
|
||||
} else {
|
||||
// We have details, can stop the timer
|
||||
connectionUpdateTimer.stop();
|
||||
}
|
||||
} else {
|
||||
// Network is not active, clear details
|
||||
if (Nmcli.wirelessDeviceDetails !== null) {
|
||||
Nmcli.wirelessDeviceDetails = null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,10 +33,8 @@ DeviceList {
|
|||
|
||||
model: ScriptModel {
|
||||
values: [...Nmcli.networks].sort((a, b) => {
|
||||
// Put active/connected network first
|
||||
if (a.active !== b.active)
|
||||
return b.active - a.active;
|
||||
// Then sort by signal strength
|
||||
return b.strength - a.strength;
|
||||
})
|
||||
}
|
||||
|
|
@ -114,7 +112,6 @@ DeviceList {
|
|||
StateLayer {
|
||||
function onClicked(): void {
|
||||
root.session.network.active = modelData;
|
||||
// Check if we need to refresh saved connections when selecting a network
|
||||
if (modelData && modelData.ssid) {
|
||||
root.checkSavedProfileForNetwork(modelData.ssid);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ Item {
|
|||
required property Session session
|
||||
|
||||
readonly property var network: {
|
||||
// Prefer pendingNetwork, then active network
|
||||
if (session.network.pendingNetwork) {
|
||||
return session.network.pendingNetwork;
|
||||
}
|
||||
|
|
@ -157,12 +156,10 @@ Item {
|
|||
|
||||
focus: true
|
||||
Keys.onPressed: event => {
|
||||
// Ensure we have focus when receiving keyboard input
|
||||
if (!activeFocus) {
|
||||
forceActiveFocus();
|
||||
}
|
||||
|
||||
// Clear error when user starts typing
|
||||
if (connectButton.hasError && event.text && event.text.length > 0) {
|
||||
connectButton.hasError = false;
|
||||
}
|
||||
|
|
@ -191,7 +188,6 @@ Item {
|
|||
target: root.session.network
|
||||
function onShowPasswordDialogChanged(): void {
|
||||
if (root.session.network.showPasswordDialog) {
|
||||
// Use callLater to ensure focus happens after dialog is fully rendered
|
||||
Qt.callLater(() => {
|
||||
passwordContainer.forceActiveFocus();
|
||||
passwordContainer.passwordBuffer = "";
|
||||
|
|
@ -205,7 +201,6 @@ Item {
|
|||
target: root
|
||||
function onVisibleChanged(): void {
|
||||
if (root.visible) {
|
||||
// Use callLater to ensure focus happens after dialog is fully rendered
|
||||
Qt.callLater(() => {
|
||||
passwordContainer.forceActiveFocus();
|
||||
});
|
||||
|
|
@ -383,46 +378,36 @@ Item {
|
|||
return;
|
||||
}
|
||||
|
||||
// Clear any previous error
|
||||
hasError = false;
|
||||
|
||||
// Set connecting state
|
||||
connecting = true;
|
||||
enabled = false;
|
||||
text = qsTr("Connecting...");
|
||||
|
||||
// Connect to network
|
||||
NetworkConnection.connectWithPassword(root.network, password, result => {
|
||||
if (result && result.success)
|
||||
// Connection successful, monitor will handle the rest
|
||||
{} else if (result && result.needsPassword) {
|
||||
// Shouldn't happen since we provided password
|
||||
if (result && result.success) {
|
||||
} else if (result && result.needsPassword) {
|
||||
connectionMonitor.stop();
|
||||
connecting = false;
|
||||
hasError = true;
|
||||
enabled = true;
|
||||
text = qsTr("Connect");
|
||||
passwordContainer.passwordBuffer = "";
|
||||
// Delete the failed connection
|
||||
if (root.network && root.network.ssid) {
|
||||
Nmcli.forgetNetwork(root.network.ssid);
|
||||
}
|
||||
} else {
|
||||
// Connection failed immediately - show error
|
||||
connectionMonitor.stop();
|
||||
connecting = false;
|
||||
hasError = true;
|
||||
enabled = true;
|
||||
text = qsTr("Connect");
|
||||
passwordContainer.passwordBuffer = "";
|
||||
// Delete the failed connection
|
||||
if (root.network && root.network.ssid) {
|
||||
Nmcli.forgetNetwork(root.network.ssid);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Start monitoring connection
|
||||
connectionMonitor.start();
|
||||
}
|
||||
}
|
||||
|
|
@ -435,19 +420,14 @@ Item {
|
|||
return;
|
||||
}
|
||||
|
||||
// Check if we're connected to the target network (case-insensitive SSID comparison)
|
||||
const isConnected = root.network && Nmcli.active && Nmcli.active.ssid && Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
|
||||
|
||||
if (isConnected) {
|
||||
// Successfully connected - give it a moment for network list to update
|
||||
// Use Timer for actual delay
|
||||
connectionSuccessTimer.start();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for connection failures - if pending connection was cleared but we're not connected
|
||||
if (Nmcli.pendingConnection === null && connectButton.connecting) {
|
||||
// Wait a bit more before giving up (allow time for connection to establish)
|
||||
if (connectionMonitor.repeatCount > 10) {
|
||||
connectionMonitor.stop();
|
||||
connectButton.connecting = false;
|
||||
|
|
@ -455,7 +435,6 @@ Item {
|
|||
connectButton.enabled = true;
|
||||
connectButton.text = qsTr("Connect");
|
||||
passwordContainer.passwordBuffer = "";
|
||||
// Delete the failed connection
|
||||
if (root.network && root.network.ssid) {
|
||||
Nmcli.forgetNetwork(root.network.ssid);
|
||||
}
|
||||
|
|
@ -486,7 +465,6 @@ Item {
|
|||
id: connectionSuccessTimer
|
||||
interval: 500
|
||||
onTriggered: {
|
||||
// Double-check connection is still active
|
||||
if (root.visible && Nmcli.active && Nmcli.active.ssid) {
|
||||
const stillConnected = Nmcli.active.ssid.toLowerCase().trim() === root.network.ssid.toLowerCase().trim();
|
||||
if (stillConnected) {
|
||||
|
|
@ -514,7 +492,6 @@ Item {
|
|||
connectButton.enabled = true;
|
||||
connectButton.text = qsTr("Connect");
|
||||
passwordContainer.passwordBuffer = "";
|
||||
// Delete the failed connection
|
||||
Nmcli.forgetNetwork(ssid);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,13 +4,8 @@ import QtQuick
|
|||
QtObject {
|
||||
id: root
|
||||
|
||||
// Active selected device
|
||||
property BluetoothDevice active: null
|
||||
|
||||
// Current adapter being used
|
||||
property BluetoothAdapter currentAdapter: Bluetooth.defaultAdapter
|
||||
|
||||
// UI state flags
|
||||
property bool editingAdapterName: false
|
||||
property bool fabMenuOpen: false
|
||||
property bool editingDeviceName: false
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import QtQuick
|
|||
QtObject {
|
||||
id: root
|
||||
|
||||
// Active selected ethernet interface
|
||||
property var active: null
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import QtQuick
|
|||
QtObject {
|
||||
id: root
|
||||
|
||||
// Active selected application
|
||||
property var active: null
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,10 +3,7 @@ import QtQuick
|
|||
QtObject {
|
||||
id: root
|
||||
|
||||
// Active selected wireless network
|
||||
property var active: null
|
||||
|
||||
// Password dialog state
|
||||
property bool showPasswordDialog: false
|
||||
property var pendingNetwork: null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,15 +18,10 @@ Item {
|
|||
|
||||
required property Session session
|
||||
|
||||
// Clock
|
||||
property bool clockShowIcon: Config.bar.clock.showIcon ?? true
|
||||
|
||||
// Bar Behavior
|
||||
property bool persistent: Config.bar.persistent ?? true
|
||||
property bool showOnHover: Config.bar.showOnHover ?? true
|
||||
property int dragThreshold: Config.bar.dragThreshold ?? 20
|
||||
|
||||
// Status Icons
|
||||
property bool showAudio: Config.bar.status.showAudio ?? true
|
||||
property bool showMicrophone: Config.bar.status.showMicrophone ?? true
|
||||
property bool showKbLayout: Config.bar.status.showKbLayout ?? false
|
||||
|
|
@ -34,25 +29,17 @@ Item {
|
|||
property bool showBluetooth: Config.bar.status.showBluetooth ?? true
|
||||
property bool showBattery: Config.bar.status.showBattery ?? true
|
||||
property bool showLockStatus: Config.bar.status.showLockStatus ?? true
|
||||
|
||||
// Tray Settings
|
||||
property bool trayBackground: Config.bar.tray.background ?? false
|
||||
property bool trayCompact: Config.bar.tray.compact ?? false
|
||||
property bool trayRecolour: Config.bar.tray.recolour ?? false
|
||||
|
||||
// Workspaces
|
||||
property int workspacesShown: Config.bar.workspaces.shown ?? 5
|
||||
property bool workspacesActiveIndicator: Config.bar.workspaces.activeIndicator ?? true
|
||||
property bool workspacesOccupiedBg: Config.bar.workspaces.occupiedBg ?? false
|
||||
property bool workspacesShowWindows: Config.bar.workspaces.showWindows ?? false
|
||||
property bool workspacesPerMonitor: Config.bar.workspaces.perMonitorWorkspaces ?? true
|
||||
|
||||
// Scroll Actions
|
||||
property bool scrollWorkspaces: Config.bar.scrollActions.workspaces ?? true
|
||||
property bool scrollVolume: Config.bar.scrollActions.volume ?? true
|
||||
property bool scrollBrightness: Config.bar.scrollActions.brightness ?? true
|
||||
|
||||
// Popouts
|
||||
property bool popoutActiveWindow: Config.bar.popouts.activeWindow ?? true
|
||||
property bool popoutTray: Config.bar.popouts.tray ?? true
|
||||
property bool popoutStatusIcons: Config.bar.popouts.statusIcons ?? true
|
||||
|
|
@ -60,7 +47,6 @@ Item {
|
|||
anchors.fill: parent
|
||||
|
||||
Component.onCompleted: {
|
||||
// Update entries
|
||||
if (Config.bar.entries) {
|
||||
entriesModel.clear();
|
||||
for (let i = 0; i < Config.bar.entries.length; i++) {
|
||||
|
|
@ -74,15 +60,10 @@ Item {
|
|||
}
|
||||
|
||||
function saveConfig(entryIndex, entryEnabled) {
|
||||
// Update clock setting
|
||||
Config.bar.clock.showIcon = root.clockShowIcon;
|
||||
|
||||
// Update bar behavior
|
||||
Config.bar.persistent = root.persistent;
|
||||
Config.bar.showOnHover = root.showOnHover;
|
||||
Config.bar.dragThreshold = root.dragThreshold;
|
||||
|
||||
// Update status icons
|
||||
Config.bar.status.showAudio = root.showAudio;
|
||||
Config.bar.status.showMicrophone = root.showMicrophone;
|
||||
Config.bar.status.showKbLayout = root.showKbLayout;
|
||||
|
|
@ -90,35 +71,24 @@ Item {
|
|||
Config.bar.status.showBluetooth = root.showBluetooth;
|
||||
Config.bar.status.showBattery = root.showBattery;
|
||||
Config.bar.status.showLockStatus = root.showLockStatus;
|
||||
|
||||
// Update tray settings
|
||||
Config.bar.tray.background = root.trayBackground;
|
||||
Config.bar.tray.compact = root.trayCompact;
|
||||
Config.bar.tray.recolour = root.trayRecolour;
|
||||
|
||||
// Update workspaces
|
||||
Config.bar.workspaces.shown = root.workspacesShown;
|
||||
Config.bar.workspaces.activeIndicator = root.workspacesActiveIndicator;
|
||||
Config.bar.workspaces.occupiedBg = root.workspacesOccupiedBg;
|
||||
Config.bar.workspaces.showWindows = root.workspacesShowWindows;
|
||||
Config.bar.workspaces.perMonitorWorkspaces = root.workspacesPerMonitor;
|
||||
|
||||
// Update scroll actions
|
||||
Config.bar.scrollActions.workspaces = root.scrollWorkspaces;
|
||||
Config.bar.scrollActions.volume = root.scrollVolume;
|
||||
Config.bar.scrollActions.brightness = root.scrollBrightness;
|
||||
|
||||
// Update popouts
|
||||
Config.bar.popouts.activeWindow = root.popoutActiveWindow;
|
||||
Config.bar.popouts.tray = root.popoutTray;
|
||||
Config.bar.popouts.statusIcons = root.popoutStatusIcons;
|
||||
|
||||
// Update entries from the model (same approach as clock - use provided value if available)
|
||||
const entries = [];
|
||||
for (let i = 0; i < entriesModel.count; i++) {
|
||||
const entry = entriesModel.get(i);
|
||||
// If this is the entry being updated, use the provided value (same as clock toggle reads from switch)
|
||||
// Otherwise use the value from the model
|
||||
let enabled = entry.enabled;
|
||||
if (entryIndex !== undefined && i === entryIndex) {
|
||||
enabled = entryEnabled;
|
||||
|
|
@ -129,8 +99,6 @@ Item {
|
|||
});
|
||||
}
|
||||
Config.bar.entries = entries;
|
||||
|
||||
// Persist changes to disk
|
||||
Config.save();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue