mirror of
https://github.com/noctalia-dev/noctalia-shell.git
synced 2026-05-11 17:08:27 +08:00
fix(wallpaper): cleanup misleading code
This commit is contained in:
@@ -16,6 +16,7 @@ Singleton {
|
||||
property bool isSway: false
|
||||
property bool isMango: false
|
||||
property bool isLabwc: false
|
||||
property bool isExtWorkspace: false
|
||||
property bool isScroll: false
|
||||
|
||||
// Generic workspace and window data
|
||||
@@ -77,6 +78,7 @@ Singleton {
|
||||
isSway = false;
|
||||
isMango = true;
|
||||
isLabwc = false;
|
||||
isExtWorkspace = false;
|
||||
backendLoader.sourceComponent = mangoComponent;
|
||||
} else if (labwcPid && labwcPid.length > 0) {
|
||||
isHyprland = false;
|
||||
@@ -84,6 +86,7 @@ Singleton {
|
||||
isSway = false;
|
||||
isMango = false;
|
||||
isLabwc = true;
|
||||
isExtWorkspace = false;
|
||||
backendLoader.sourceComponent = labwcComponent;
|
||||
Logger.i("CompositorService", "Detected LabWC with PID: " + labwcPid);
|
||||
} else if (niriSocket && niriSocket.length > 0) {
|
||||
@@ -92,6 +95,7 @@ Singleton {
|
||||
isSway = false;
|
||||
isMango = false;
|
||||
isLabwc = false;
|
||||
isExtWorkspace = false;
|
||||
backendLoader.sourceComponent = niriComponent;
|
||||
} else if (hyprlandSignature && hyprlandSignature.length > 0) {
|
||||
isHyprland = true;
|
||||
@@ -99,6 +103,7 @@ Singleton {
|
||||
isSway = false;
|
||||
isMango = false;
|
||||
isLabwc = false;
|
||||
isExtWorkspace = false;
|
||||
backendLoader.sourceComponent = hyprlandComponent;
|
||||
} else if (swaySock && swaySock.length > 0) {
|
||||
isHyprland = false;
|
||||
@@ -106,16 +111,19 @@ Singleton {
|
||||
isSway = true;
|
||||
isMango = false;
|
||||
isLabwc = false;
|
||||
isExtWorkspace = false;
|
||||
isScroll = currentDesktop && currentDesktop.toLowerCase().includes("scroll");
|
||||
backendLoader.sourceComponent = swayComponent;
|
||||
} else {
|
||||
// Always fallback to Niri
|
||||
// Always fallback to ext-workspace-v1
|
||||
isHyprland = false;
|
||||
isNiri = true;
|
||||
isNiri = false;
|
||||
isSway = false;
|
||||
isMango = false;
|
||||
isLabwc = false;
|
||||
backendLoader.sourceComponent = niriComponent;
|
||||
isExtWorkspace = true;
|
||||
backendLoader.sourceComponent = extWorkspaceComponent;
|
||||
Logger.i("CompositorService", "Using generic ext-workspace backend (no recognized compositor env)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,6 +199,14 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
// Generic ext-workspace (WindowManager) when compositor env is unknown
|
||||
Component {
|
||||
id: extWorkspaceComponent
|
||||
ExtWorkspaceService {
|
||||
id: extWorkspaceBackend
|
||||
}
|
||||
}
|
||||
|
||||
function setupBackendConnections() {
|
||||
if (!backend)
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.WindowManager
|
||||
import qs.Commons
|
||||
|
||||
// Generic ext-workspace-v1 + toplevel handling
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property ListModel workspaces: ListModel {}
|
||||
property var windows: []
|
||||
property int focusedWindowIndex: -1
|
||||
property var trackedToplevels: new Set()
|
||||
|
||||
property bool globalWorkspaces: false
|
||||
|
||||
property var nativeWorkspaceMap: ({})
|
||||
property var connectedWorkspaces: ({})
|
||||
|
||||
signal workspaceChanged
|
||||
signal activeWindowChanged
|
||||
signal windowListChanged
|
||||
signal displayScalesChanged
|
||||
|
||||
function initialize() {
|
||||
updateWindows();
|
||||
connectWorkspaceSignals();
|
||||
syncWorkspaces();
|
||||
Logger.i("ExtWorkspaceService", "Service started (generic ext-workspace-v1)");
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: WindowManager
|
||||
|
||||
function onWindowsetsChanged() {
|
||||
root.connectWorkspaceSignals();
|
||||
Qt.callLater(root.syncWorkspaces);
|
||||
}
|
||||
|
||||
function onWindowsetProjectionsChanged() {
|
||||
Qt.callLater(root.syncWorkspaces);
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
interval: 500
|
||||
running: true
|
||||
repeat: false
|
||||
onTriggered: {
|
||||
if (WindowManager.windowsets.length > 0) {
|
||||
root.connectWorkspaceSignals();
|
||||
root.syncWorkspaces();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function connectWorkspaceSignals() {
|
||||
const nativeWs = WindowManager.windowsets;
|
||||
const newConnected = {};
|
||||
|
||||
for (const ws of nativeWs) {
|
||||
const key = ws.id || ws.toString();
|
||||
newConnected[key] = true;
|
||||
|
||||
if (connectedWorkspaces[key])
|
||||
continue;
|
||||
|
||||
ws.activeChanged.connect(() => {
|
||||
Qt.callLater(root.syncWorkspaces);
|
||||
});
|
||||
|
||||
ws.urgentChanged.connect(() => {
|
||||
Qt.callLater(root.syncWorkspaces);
|
||||
});
|
||||
|
||||
ws.shouldDisplayChanged.connect(() => {
|
||||
Qt.callLater(root.syncWorkspaces);
|
||||
});
|
||||
|
||||
ws.nameChanged.connect(() => {
|
||||
Qt.callLater(root.syncWorkspaces);
|
||||
});
|
||||
}
|
||||
|
||||
connectedWorkspaces = newConnected;
|
||||
}
|
||||
|
||||
function syncWorkspaces() {
|
||||
const nativeWs = WindowManager.windowsets;
|
||||
|
||||
workspaces.clear();
|
||||
nativeWorkspaceMap = {};
|
||||
|
||||
let idx = 1;
|
||||
|
||||
for (const ws of nativeWs) {
|
||||
if (!ws.shouldDisplay) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let outputName = "";
|
||||
if (ws.projection) {
|
||||
const projScreens = ws.projection.screens;
|
||||
if (projScreens && projScreens.length > 0) {
|
||||
outputName = projScreens[0].name || "";
|
||||
}
|
||||
}
|
||||
|
||||
const wsEntry = {
|
||||
"id": ws.id || idx.toString(),
|
||||
"idx": idx,
|
||||
"name": ws.name || ("Workspace " + idx),
|
||||
"output": outputName,
|
||||
"isFocused": ws.active,
|
||||
"isActive": true,
|
||||
"isUrgent": ws.urgent,
|
||||
"isOccupied": false,
|
||||
"oid": ws.id || idx.toString()
|
||||
};
|
||||
|
||||
workspaces.append(wsEntry);
|
||||
nativeWorkspaceMap[wsEntry.id] = ws;
|
||||
|
||||
idx++;
|
||||
}
|
||||
|
||||
updateWindowWorkspaces();
|
||||
workspaceChanged();
|
||||
}
|
||||
|
||||
function updateWindowWorkspaces() {
|
||||
let activeId = "";
|
||||
for (let i = 0; i < workspaces.count; i++) {
|
||||
const ws = workspaces.get(i);
|
||||
if (ws.isFocused) {
|
||||
activeId = ws.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < windows.length; i++) {
|
||||
if (activeId) {
|
||||
windows[i].workspaceId = activeId;
|
||||
}
|
||||
}
|
||||
windowListChanged();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ToplevelManager.toplevels
|
||||
function onValuesChanged() {
|
||||
updateWindows();
|
||||
}
|
||||
}
|
||||
|
||||
function connectToToplevel(toplevel) {
|
||||
if (!toplevel)
|
||||
return;
|
||||
|
||||
toplevel.activatedChanged.connect(() => {
|
||||
Qt.callLater(onToplevelActivationChanged);
|
||||
});
|
||||
|
||||
toplevel.titleChanged.connect(() => {
|
||||
Qt.callLater(updateWindows);
|
||||
});
|
||||
}
|
||||
|
||||
function onToplevelActivationChanged() {
|
||||
updateWindows();
|
||||
activeWindowChanged();
|
||||
}
|
||||
|
||||
function updateWindows() {
|
||||
const newWindows = [];
|
||||
const toplevels = ToplevelManager.toplevels?.values || [];
|
||||
|
||||
let focusedIdx = -1;
|
||||
let idx = 0;
|
||||
|
||||
let activeId = "";
|
||||
for (let i = 0; i < workspaces.count; i++) {
|
||||
const ws = workspaces.get(i);
|
||||
if (ws.isFocused) {
|
||||
activeId = ws.id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const toplevel of toplevels) {
|
||||
if (!toplevel)
|
||||
continue;
|
||||
|
||||
if (!trackedToplevels.has(toplevel)) {
|
||||
connectToToplevel(toplevel);
|
||||
trackedToplevels.add(toplevel);
|
||||
}
|
||||
|
||||
const output = (toplevel.screens && toplevel.screens.length > 0) ? (toplevel.screens[0].name || "") : "";
|
||||
|
||||
const windowId = (toplevel.appId || "") + ":" + idx;
|
||||
|
||||
newWindows.push({
|
||||
"id": windowId,
|
||||
"appId": toplevel.appId || "",
|
||||
"title": toplevel.title || "",
|
||||
"output": output,
|
||||
"workspaceId": activeId || "1",
|
||||
"isFocused": toplevel.activated || false,
|
||||
"toplevel": toplevel
|
||||
});
|
||||
|
||||
if (toplevel.activated) {
|
||||
focusedIdx = idx;
|
||||
}
|
||||
idx++;
|
||||
}
|
||||
windows = newWindows;
|
||||
focusedWindowIndex = focusedIdx;
|
||||
|
||||
windowListChanged();
|
||||
}
|
||||
|
||||
function focusWindow(window) {
|
||||
if (window.toplevel && typeof window.toplevel.activate === "function") {
|
||||
window.toplevel.activate();
|
||||
}
|
||||
}
|
||||
|
||||
function closeWindow(window) {
|
||||
if (window.toplevel && typeof window.toplevel.close === "function") {
|
||||
window.toplevel.close();
|
||||
}
|
||||
}
|
||||
|
||||
function switchToWorkspace(workspace) {
|
||||
const nativeWs = nativeWorkspaceMap[workspace.id] || nativeWorkspaceMap[workspace.oid];
|
||||
if (nativeWs && nativeWs.canActivate) {
|
||||
nativeWs.activate();
|
||||
} else {
|
||||
Logger.w("ExtWorkspaceService", "Cannot activate workspace: " + (workspace.name || workspace.id));
|
||||
}
|
||||
}
|
||||
|
||||
function turnOffMonitors() {
|
||||
try {
|
||||
Quickshell.execDetached(["wlr-randr", "--off"]);
|
||||
} catch (e) {
|
||||
Logger.e("ExtWorkspaceService", "Failed to turn off monitors:", e);
|
||||
}
|
||||
}
|
||||
|
||||
function turnOnMonitors() {
|
||||
try {
|
||||
Quickshell.execDetached(["wlr-randr", "--on"]);
|
||||
} catch (e) {
|
||||
Logger.e("ExtWorkspaceService", "Failed to turn on monitors:", e);
|
||||
}
|
||||
}
|
||||
|
||||
function logout() {
|
||||
const sid = Quickshell.env("XDG_SESSION_ID");
|
||||
try {
|
||||
if (sid && sid.length > 0) {
|
||||
Quickshell.execDetached(["loginctl", "terminate-session", sid]);
|
||||
} else {
|
||||
Logger.w("ExtWorkspaceService", "logout: XDG_SESSION_ID unset; use session menu custom command or compositor-specific backend");
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.e("ExtWorkspaceService", "Failed to logout:", e);
|
||||
}
|
||||
}
|
||||
|
||||
function cycleKeyboardLayout() {
|
||||
Logger.w("ExtWorkspaceService", "Keyboard layout cycling not supported");
|
||||
}
|
||||
|
||||
function queryDisplayScales() {
|
||||
Logger.w("ExtWorkspaceService", "Display scale queries not supported via ToplevelManager");
|
||||
}
|
||||
|
||||
function getFocusedScreen() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ Singleton {
|
||||
|
||||
// Check if airplane mode has been toggled
|
||||
function checkAirplaneMode() {
|
||||
var isAirplaneModeActive = !NetworkService.wifiEnabled && adapter.state === BluetoothAdapter.Blocked
|
||||
var isAirplaneModeActive = !NetworkService.wifiEnabled && adapter.state === BluetoothAdapter.Blocked;
|
||||
if (isAirplaneModeActive && !NetworkService.airplaneModeEnabled) {
|
||||
NetworkService.airplaneModeToggled = true;
|
||||
NetworkService.airplaneModeEnabled = true;
|
||||
|
||||
@@ -155,7 +155,7 @@ Singleton {
|
||||
}
|
||||
return;
|
||||
}
|
||||
var isAirplaneModeActive = !root.wifiEnabled && BluetoothService.blocked
|
||||
var isAirplaneModeActive = !root.wifiEnabled && BluetoothService.blocked;
|
||||
// Extra check for Airplane Mode if Bluetooth has been blocked before Wi-Fi
|
||||
if (isAirplaneModeActive && !root.airplaneModeEnabled) {
|
||||
root.airplaneModeEnabled = true;
|
||||
|
||||
@@ -149,6 +149,8 @@ Singleton {
|
||||
return "MangoWC";
|
||||
if (CompositorService.isLabwc)
|
||||
return "LabWC";
|
||||
if (CompositorService.isExtWorkspace)
|
||||
return "ExtWorkspace";
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1307,6 +1307,11 @@ Singleton {
|
||||
// -------------------------------------------------------------------
|
||||
// Favorites
|
||||
// -------------------------------------------------------------------
|
||||
// TODO (~few weeks): Remove per-favorite `darkMode` (the boolean on each
|
||||
// Settings.data.wallpaper.favorites[] entry). It duplicates `appearance` and is
|
||||
// unrelated to Settings.data.colorSchemes.darkMode (global shell light/dark).
|
||||
// Plan: one-time migration, then drop writes and the fallback in _favoriteAppearanceSlot.
|
||||
// -------------------------------------------------------------------
|
||||
readonly property int _favoriteNotFound: -1
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
@@ -1371,7 +1376,8 @@ Singleton {
|
||||
"path": path,
|
||||
"appearance": app,
|
||||
"colorScheme": Settings.data.colorSchemes.predefinedScheme,
|
||||
"darkMode": app === "dark",
|
||||
"darkMode": app === "dark" // TODO: remove per-favorite field (see Favorites section note)
|
||||
,
|
||||
"useWallpaperColors": Settings.data.colorSchemes.useWallpaperColors,
|
||||
"generationMethod": Settings.data.colorSchemes.generationMethod,
|
||||
"paletteColors": [Color.mPrimary.toString(), Color.mSecondary.toString(), Color.mTertiary.toString(), Color.mError.toString()]
|
||||
|
||||
Reference in New Issue
Block a user