Merge branch 'main' of github.com:noctalia-dev/noctalia-shell

This commit is contained in:
Lemmy
2026-02-07 08:18:26 -05:00
7 changed files with 92 additions and 35 deletions
+1 -1
View File
@@ -1889,4 +1889,4 @@
"poor": "Poor"
}
}
}
}
+15
View File
@@ -177,6 +177,9 @@ Variants {
}
function onBrightnessChanged(newBrightness) {
if (!root)
return;
root.currentBrightness = newBrightness;
// Don't show OSD if brightness panel is open
var brightnessPanel = PanelService.getPanel("brightnessPanel", root.modelData);
@@ -327,6 +330,18 @@ Variants {
}
}
Component.onDestruction: {
if (typeof BrightnessService !== "undefined" && BrightnessService.monitors) {
for (var i = 0; i < BrightnessService.monitors.length; i++) {
try {
BrightnessService.monitors[i].brightnessUpdated.disconnect(onBrightnessChanged);
} catch (e) {
// Ignore errors if already disconnected or not connected
}
}
}
}
// Visual Component
sourceComponent: PanelWindow {
id: panel
@@ -141,20 +141,13 @@ Item {
launcher.close();
Qt.callLater(() => {
executeAction(action, command);
executeAction(action);
});
};
}
function executeAction(action, command) {
// If custom command is defined, execute it
if (command && command.trim() !== "") {
Logger.i("SessionProvider", "Executing custom command for action:", action, "Command:", command);
Quickshell.execDetached(["sh", "-c", command]);
return;
}
// Otherwise, use default behavior
function executeAction(action) {
// Default behavior or custom command handled by CompositorService
switch (action) {
case "lock":
if (PanelService.lockScreen && !PanelService.lockScreen.active) {
+1 -19
View File
@@ -211,25 +211,7 @@ SmartPanel {
// Stop timer but don't reset other properties yet
countdownTimer.stop();
// Find the option to check for custom command
var option = null;
for (var i = 0; i < powerOptions.length; i++) {
if (powerOptions[i].action === action) {
option = powerOptions[i];
break;
}
}
// If custom command is defined, execute it
if (option && option.command && option.command.trim() !== "") {
Logger.i("SessionMenu", "Executing custom command for action:", action, "Command:", option.command);
Quickshell.execDetached(["sh", "-c", option.command]);
cancelTimer();
root.close();
return;
}
// Otherwise, use default behavior
// Use default behavior or custom command handled by CompositorService
switch (action) {
case "lock":
// Access lockScreen via PanelService
+31 -2
View File
@@ -17,6 +17,29 @@ async def run_command(*args):
return stdout.decode().strip()
def theme_exists(theme_name: str) -> bool:
"""Check if a GTK theme exists in common locations."""
search_paths = [
Path.home() / ".themes",
Path.home() / ".local/share/themes",
Path("/usr/share/themes"),
Path("/usr/local/share/themes"),
]
# Add paths from XDG_DATA_DIRS
xdg_data_dirs = os.environ.get("XDG_DATA_DIRS", "")
if xdg_data_dirs:
for path in xdg_data_dirs.split(":"):
if path:
search_paths.append(Path(path) / "themes")
for base_path in search_paths:
if (base_path / theme_name).is_dir():
return True
return False
async def apply_gtk3_colors(config_dir: Path):
gtk3_dir = config_dir / "gtk-3.0"
colors_file = gtk3_dir / "noctalia.css"
@@ -66,16 +89,22 @@ async def refresh_theme():
else:
target_theme = "adw-gtk3-dark"
theme_available = theme_exists(target_theme)
if not theme_available:
print(f"Theme '{target_theme}' not found, skipping GTK theme set")
if has_gsettings:
schemas = await run_command("gsettings", "list-schemas")
if schemas and "org.gnome.desktop.interface" in schemas:
await run_command("gsettings", "set", "org.gnome.desktop.interface", "color-scheme", f"prefer-{mode}")
await run_command("gsettings", "set", "org.gnome.desktop.interface", "gtk-theme", f"{target_theme}")
if theme_available:
await run_command("gsettings", "set", "org.gnome.desktop.interface", "gtk-theme", f"{target_theme}")
return
if has_dconf:
await run_command("dconf", "write", "/org/gnome/desktop/interface/color-scheme", f"'prefer-{mode}'")
await run_command("dconf", "write", "/org/gnome/desktop/interface/gtk-theme", f"'{target_theme}'")
if theme_available:
await run_command("dconf", "write", "/org/gnome/desktop/interface/gtk-theme", f"'{target_theme}'")
async def get_config_dir() -> Path:
+38 -1
View File
@@ -425,10 +425,35 @@ Singleton {
}
}
// Session management helper for custom commands
function getCustomCommand(action) {
const powerOptions = Settings.data.sessionMenu.powerOptions || [];
for (let i = 0; i < powerOptions.length; i++) {
const option = powerOptions[i];
if (option.action === action && option.enabled && option.command && option.command.trim() !== "") {
return option.command.trim();
}
}
return "";
}
function executeSessionAction(action, defaultCommand) {
const customCommand = getCustomCommand(action);
if (customCommand) {
Logger.i("Compositor", `Executing custom command for action: ${action} Command: ${customCommand}`);
Quickshell.execDetached(["sh", "-c", customCommand]);
return true;
}
return false;
}
// Session management
function logout() {
Logger.i("Compositor", "Logout requested");
if (executeSessionAction("logout"))
return;
if (backend && backend.logout) {
Logger.i("Compositor", "Logout requested");
backend.logout();
} else {
Logger.w("Compositor", "No backend available for logout");
@@ -437,6 +462,9 @@ Singleton {
function shutdown() {
Logger.i("Compositor", "Shutdown requested");
if (executeSessionAction("shutdown"))
return;
HooksService.executeSessionHook("shutdown", () => {
Quickshell.execDetached(["sh", "-c", "systemctl poweroff || loginctl poweroff"]);
});
@@ -444,6 +472,9 @@ Singleton {
function reboot() {
Logger.i("Compositor", "Reboot requested");
if (executeSessionAction("reboot"))
return;
HooksService.executeSessionHook("reboot", () => {
Quickshell.execDetached(["sh", "-c", "systemctl reboot || loginctl reboot"]);
});
@@ -451,11 +482,17 @@ Singleton {
function suspend() {
Logger.i("Compositor", "Suspend requested");
if (executeSessionAction("suspend"))
return;
Quickshell.execDetached(["sh", "-c", "systemctl suspend || loginctl suspend"]);
}
function hibernate() {
Logger.i("Compositor", "Hibernate requested");
if (executeSessionAction("hibernate"))
return;
Quickshell.execDetached(["sh", "-c", "systemctl hibernate || loginctl hibernate"]);
}
+3 -2
View File
@@ -1319,16 +1319,17 @@ Singleton {
// Priority (when dGPU monitoring enabled): NVIDIA > AMD dGPU > Intel Arc > AMD iGPU
// Priority (when dGPU monitoring disabled): AMD iGPU only (discrete GPUs skipped to preserve D3cold)
function selectBestGpu() {
const dgpuEnabled = Settings.data.systemMonitor.enableDgpuMonitoring;
if (root.foundGpuSensors.length === 0) {
// No hwmon GPU sensors found, try thermal_zone fallback
if (root.gpuThermalZonePath === "" && root.gpuThermalZonePaths.length === 0) {
if (dgpuEnabled && root.gpuThermalZonePath === "" && root.gpuThermalZonePaths.length === 0) {
// Thermal zone scanner hasn't found GPU zones yet; start a scan
thermalZoneScanner.startScan();
}
return;
}
const dgpuEnabled = Settings.data.systemMonitor.enableDgpuMonitoring;
let best = null;
for (var i = 0; i < root.foundGpuSensors.length; i++) {