Edit SettingsWindow

This commit is contained in:
Ly-sec 2025-08-07 00:34:33 +02:00
parent 0bfef118dc
commit 6ef29ae745
17 changed files with 283 additions and 130 deletions

Binary file not shown.

Binary file not shown.

View file

@ -12,6 +12,13 @@ Item {
// Get list of available monitors/screens
property var monitors: Quickshell.screens || []
Component.onCompleted: {
console.log("[NotificationPopup] Initialized with", monitors.length, "monitors");
for (let i = 0; i < monitors.length; i++) {
console.log("[NotificationPopup] Monitor", i, ":", monitors[i].name);
}
}
// Global visibility state for all notification popups
property bool notificationsVisible: true
@ -20,6 +27,17 @@ Item {
notificationsVisible = !notificationsVisible;
console.log("[NotificationManager] New state: " + notificationsVisible);
}
function addNotification(notification): void {
console.log("[NotificationPopup] Adding notification to popup manager");
// Add notification to all monitor popups
for (let i = 0; i < children.length; i++) {
let child = children[i];
if (child.addNotification) {
child.addNotification(notification);
}
}
}
// Create a notification popup for each monitor
Repeater {
@ -50,8 +68,12 @@ Item {
property bool shouldShowOnThisMonitor: {
let notificationMonitors = Settings.settings.notificationMonitors || [];
let currentScreenName = modelData ? modelData.name : "";
return notificationMonitors.includes("*") ||
// Show notifications on all monitors if notificationMonitors is empty or contains "*"
let shouldShow = notificationMonitors.length === 0 ||
notificationMonitors.includes("*") ||
notificationMonitors.includes(currentScreenName);
console.log("[NotificationPopup] Monitor", currentScreenName, "should show:", shouldShow, "monitors:", JSON.stringify(notificationMonitors));
return shouldShow;
}
// Watch for changes in notification monitors setting
@ -75,6 +97,7 @@ Item {
property int spacing: 5
function addNotification(notification) {
console.log("[NotificationPopup] Adding notification to monitor popup:", notification.appName);
notificationModel.insert(0, {
id: notification.id,
appName: notification.appName || "Notification",

View file

@ -7,17 +7,74 @@ import QtQuick.Effects
import qs.Settings
import qs.Widgets.SettingsWindow.Tabs
import qs.Widgets.SettingsWindow.Tabs.Components
import qs.Components
PanelWindow {
PanelWithOverlay {
id: panelMain
implicitHeight: Quickshell.screens.length > 0 ? Quickshell.screens[0].height / 2 : 400
implicitWidth: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 2 : 600
color: "transparent"
property int activeTabIndex: 0
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
// Function to show wallpaper selector
function showWallpaperSelector() {
if (wallpaperSelector) {
wallpaperSelector.show();
}
}
// Function to show settings window
function showSettings() {
show();
}
// Handle activeTabIndex changes
onActiveTabIndexChanged: {
if (activeTabIndex >= 0 && activeTabIndex <= 8) {
loadComponentForTab(activeTabIndex);
}
}
// Function to load component for a specific tab
function loadComponentForTab(tabIndex) {
const componentMap = {
0: generalSettings,
1: barSettings,
2: timeWeatherSettings,
3: recordingSettings,
4: networkSettings,
5: displaySettings,
6: wallpaperSettings,
7: miscSettings,
8: aboutSettings
};
const tabNames = [
"General",
"Bar",
"Time & Weather",
"Recording",
"Network",
"Display",
"Wallpaper",
"Misc",
"About"
];
if (componentMap[tabIndex]) {
settingsLoader.sourceComponent = componentMap[tabIndex];
if (tabName) {
tabName.text = tabNames[tabIndex];
}
}
}
// Add safety checks for component loading
Component.onCompleted: {
// Ensure we start with a valid tab
@ -83,37 +140,47 @@ PanelWindow {
}
Rectangle {
id: background
color: Theme.backgroundPrimary
anchors.fill: parent
radius: 20
border.color: Theme.outline
border.width: 1
id: settingsWindowRect
implicitWidth: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 2 : 600
implicitHeight: Quickshell.screens.length > 0 ? Quickshell.screens[0].height / 2 : 400
visible: parent.visible
color: "transparent"
// Center the settings window on screen
anchors.centerIn: parent
MultiEffect {
source: background
anchors.fill: background
shadowEnabled: true
shadowColor: Theme.shadow
shadowOpacity: 0.3
shadowHorizontalOffset: 0
shadowVerticalOffset: 2
shadowBlur: 12
}
}
Rectangle {
id: background
color: Theme.backgroundPrimary
anchors.fill: parent
radius: 20
border.color: Theme.outline
border.width: 1
Rectangle {
id: settings
color: Theme.backgroundPrimary
anchors {
left: tabs.right
top: parent.top
bottom: parent.bottom
right: parent.right
margins: 12
MultiEffect {
source: background
anchors.fill: background
shadowEnabled: true
shadowColor: Theme.shadow
shadowOpacity: 0.3
shadowHorizontalOffset: 0
shadowVerticalOffset: 2
shadowBlur: 12
}
}
topRightRadius: 20
bottomRightRadius: 20
Rectangle {
id: settings
color: Theme.backgroundPrimary
anchors {
left: tabs.right
top: parent.top
bottom: parent.bottom
right: parent.right
margins: 12
}
topRightRadius: 20
bottomRightRadius: 20
Rectangle {
id: headerArea
@ -149,7 +216,7 @@ PanelWindow {
// Wallpaper Selection Button (only visible on Wallpaper tab)
Rectangle {
width: 32
width: 160
height: 32
radius: 16
color: wallpaperButtonArea.containsMouse ? Theme.accentPrimary : "transparent"
@ -157,12 +224,25 @@ PanelWindow {
border.width: 1
visible: activeTabIndex === 6 // Wallpaper tab index
Text {
Row {
anchors.centerIn: parent
text: "image"
font.family: wallpaperButtonArea.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined"
font.pixelSize: 18
color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
spacing: 6
Text {
text: "image"
font.family: wallpaperButtonArea.containsMouse ? "Material Symbols Rounded" : "Material Symbols Outlined"
font.pixelSize: 16
color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
anchors.verticalCenter: parent.verticalCenter
}
Text {
text: "Select Wallpaper"
font.pixelSize: 13
font.bold: true
color: wallpaperButtonArea.containsMouse ? Theme.onAccent : Theme.accentPrimary
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
@ -198,7 +278,7 @@ PanelWindow {
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: panelMain.visible = false
onClicked: panelMain.dismiss()
}
}
}
@ -242,15 +322,15 @@ PanelWindow {
}
}
Rectangle {
id: tabs
color: Theme.surface
width: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 9 : 100
height: panelMain.height
topLeftRadius: 20
bottomLeftRadius: 20
border.color: Theme.outline
border.width: 1
Rectangle {
id: tabs
color: Theme.surface
width: Quickshell.screens.length > 0 ? Quickshell.screens[0].width / 9 : 100
height: settingsWindowRect.height
topLeftRadius: 20
bottomLeftRadius: 20
border.color: Theme.outline
border.width: 1
Column {
width: parent.width
@ -332,36 +412,7 @@ PanelWindow {
cursorShape: Qt.PointingHandCursor
onClicked: {
activeTabIndex = index;
const newComponent = {
0: generalSettings,
1: barSettings,
2: timeWeatherSettings,
3: recordingSettings,
4: networkSettings,
5: displaySettings,
6: wallpaperSettings,
7: miscSettings,
8: aboutSettings
}[index];
const tabNames = [
"General",
"Bar",
"Time & Weather",
"Recording",
"Network",
"Display",
"Wallpaper",
"Misc",
"About"
];
tabName.text = tabNames[index];
// Simple component switching
if (newComponent) {
settingsLoader.sourceComponent = newComponent;
}
loadComponentForTab(index);
}
}
@ -377,4 +428,5 @@ PanelWindow {
}
}
}
}
}

View file

@ -22,7 +22,7 @@ ColumnLayout {
Text {
text: "Bar Elements"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8

View file

@ -37,7 +37,7 @@ ColumnLayout {
Text {
text: "Monitor Selection"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8

View file

@ -22,7 +22,7 @@ ColumnLayout {
Text {
text: "Profile"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8
@ -115,7 +115,7 @@ ColumnLayout {
Text {
text: "User Interface"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8

View file

@ -22,7 +22,7 @@ ColumnLayout {
Text {
text: "Media"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8

View file

@ -22,7 +22,7 @@ ColumnLayout {
Text {
text: "Wi-Fi"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
}
@ -105,7 +105,7 @@ ColumnLayout {
Text {
text: "Bluetooth"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
}

View file

@ -36,7 +36,7 @@ ColumnLayout {
Text {
text: "Screen Recording"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8

View file

@ -23,7 +23,7 @@ ColumnLayout {
Text {
text: "Time"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8
@ -176,7 +176,7 @@ ColumnLayout {
Text {
text: "Weather"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8

View file

@ -36,13 +36,13 @@ ColumnLayout {
spacing: 4
Layout.fillWidth: true
Text {
text: "Wallpaper"
font.pixelSize: 16
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8
}
Text {
text: "Wallpaper"
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8
}
@ -131,7 +131,7 @@ ColumnLayout {
Text {
text: "Automation"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8
@ -364,7 +364,7 @@ ColumnLayout {
Text {
text: "SWWW"
font.pixelSize: 16
font.pixelSize: 18
font.bold: true
color: Theme.textPrimary
Layout.bottomMargin: 8

View file

@ -70,9 +70,7 @@ PanelWithOverlay {
if (shell && shell.settingsWindow && shell.settingsWindow.visible) {
shell.settingsWindow.visible = false;
}
if (wallpaperPanelLoader.active && wallpaperPanelLoader.item && wallpaperPanelLoader.item.visible) {
wallpaperPanelLoader.item.visible = false;
}
if (wifiPanelLoader.active && wifiPanelLoader.item && wifiPanelLoader.item.visible) {
wifiPanelLoader.item.visible = false;
}
@ -151,19 +149,7 @@ PanelWithOverlay {
component: BluetoothPanel {}
}
// LazyLoader for WallpaperPanel
LazyLoader {
id: wallpaperPanelLoader
loading: false
component: WallpaperPanel {
Component.onCompleted: {
if (parent) {
anchors.top = parent.top;
anchors.right = parent.right;
}
}
}
}
// SettingsIcon component
SettingsIcon {
@ -175,6 +161,8 @@ PanelWithOverlay {
}
}
Item {
anchors.fill: mainRectangle
x: sidebarPopupRect.slideOffset
@ -363,12 +351,11 @@ PanelWithOverlay {
settingsModal.openSettings();
}
}
onWallpaperRequested: {
if (!wallpaperPanelLoader.active) {
wallpaperPanelLoader.loading = true;
}
if (wallpaperPanelLoader.item) {
wallpaperPanelLoader.item.visible = true;
onWallpaperSelectorRequested: {
// Use the SettingsModal's openSettings function with wallpaper tab (index 6)
if (typeof settingsModal !== 'undefined' && settingsModal && settingsModal.openSettings) {
settingsModal.openSettings(6); // 6 is the wallpaper tab index
}
}
}

View file

@ -20,6 +20,7 @@ Rectangle {
signal recordingStateMismatch(bool actualState)
signal settingsRequested()
signal wallpaperRequested()
signal wallpaperSelectorRequested()
Rectangle {
id: card
@ -161,7 +162,7 @@ Rectangle {
cursorShape: Qt.PointingHandCursor
hoverEnabled: true
onClicked: {
wallpaperRequested()
wallpaperSelectorRequested()
}
}
}

View file

@ -27,12 +27,25 @@ PanelWindow {
property var settingsWindow: null
// Function to open the modal and initialize temp values
function openSettings() {
function openSettings(initialTabIndex) {
if (!settingsWindow) {
// Create new window
settingsWindow = settingsComponent.createObject(null); // No parent to avoid dependency issues
if (settingsWindow) {
// Set the initial tab if provided
if (typeof initialTabIndex === 'number' && initialTabIndex >= 0 && initialTabIndex <= 8) {
settingsWindow.activeTabIndex = initialTabIndex;
}
settingsWindow.visible = true;
// Show wallpaper selector if opening wallpaper tab (after window is visible)
if (typeof initialTabIndex === 'number' && initialTabIndex === 6) {
Qt.callLater(function() {
if (settingsWindow && settingsWindow.showWallpaperSelector) {
settingsWindow.showWallpaperSelector();
}
}, 100); // Small delay to ensure window is fully loaded
}
// Handle window closure
settingsWindow.visibleChanged.connect(function() {
if (settingsWindow && !settingsWindow.visible) {

View file

@ -0,0 +1,81 @@
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell
import Quickshell.Wayland
import qs.Settings
import qs.Services
import qs.Widgets.SettingsWindow
import qs.Components
PanelWindow {
id: settingsModal
implicitWidth: 480
implicitHeight: 780
visible: false
color: "transparent"
anchors.top: true
anchors.right: true
margins.right: 0
margins.top: 0
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
// Property to track the settings window instance
property var settingsWindow: null
// Function to open the modal and initialize temp values
function openSettings() {
if (!settingsWindow) {
// Create new window
settingsWindow = settingsComponent.createObject(null); // No parent to avoid dependency issues
if (settingsWindow) {
settingsWindow.visible = true;
// Handle window closure
settingsWindow.visibleChanged.connect(function() {
if (settingsWindow && !settingsWindow.visible) {
var windowToDestroy = settingsWindow;
settingsWindow = null;
windowToDestroy.destroy();
}
});
}
} else if (settingsWindow.visible) {
// Close and destroy window
var windowToDestroy = settingsWindow;
settingsWindow = null;
windowToDestroy.visible = false;
windowToDestroy.destroy();
}
}
// Function to close the modal and release focus
function closeSettings() {
if (settingsWindow) {
var windowToDestroy = settingsWindow;
settingsWindow = null;
windowToDestroy.visible = false;
windowToDestroy.destroy();
}
}
Component {
id: settingsComponent
SettingsWindow {}
}
// Clean up on destruction
Component.onDestruction: {
if (settingsWindow) {
var windowToDestroy = settingsWindow;
settingsWindow = null;
windowToDestroy.destroy();
}
}
// Refresh weather data when hidden
onVisibleChanged: {
if (!visible && typeof weather !== 'undefined' && weather !== null && weather.fetchCityWeather) {
weather.fetchCityWeather();
}
}
}

View file

@ -97,15 +97,11 @@ Scope {
NotificationServer {
id: notificationServer
onNotification: function (notification) {
console.log("[Notification] Received notification:", notification.appName, "-", notification.summary);
notification.tracked = true;
if (notificationPopup.notificationsVisible) {
// Add notification to all popup instances
for (let i = 0; i < notificationPopup.children.length; i++) {
let child = notificationPopup.children[i];
if (child.addNotification) {
child.addNotification(notification);
}
}
// Add notification to the popup manager
notificationPopup.addNotification(notification);
}
if (notificationHistoryLoader.active && notificationHistoryLoader.item) {
notificationHistoryLoader.item.addToHistory({