Add Nebula.Windows with Sway IPC backend
Introduces a new `core/windows` module (`Nebula.Windows`) with `WindowService`, window/workspace models, and a Sway IPC backend for live window tracking and control (focus, close, move/resize, snap, maximize/restore, minimize, workspace switch). The desktop shell now links this module, uses compositor focus for top-bar active app text, and adds an Open Windows section in the launcher with focus/close actions. Also updates application metadata handling to parse `StartupWMClass` and map window `app_id`/class to friendly names and icons, and revises Sway config/docs for the new floating-first Desktop 0.2 behavior with temporary compositor-provided decorations.
This commit is contained in:
@@ -91,3 +91,49 @@ const DesktopEntry *ApplicationModel::entryById(const QString &desktopId) const
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const DesktopEntry *ApplicationModel::entryMatchingWindow(const QString &appId, const QString &windowClass) const
|
||||
{
|
||||
auto stem = [](QString value) {
|
||||
if (value.endsWith(QLatin1String(".desktop"), Qt::CaseInsensitive))
|
||||
value.chop(8);
|
||||
return value.toLower();
|
||||
};
|
||||
|
||||
const QString app = stem(appId);
|
||||
const QString cls = stem(windowClass);
|
||||
const QString appLast = app.contains(QLatin1Char('.')) ? app.section(QLatin1Char('.'), -1) : app;
|
||||
const QString classLast = cls.contains(QLatin1Char('.')) ? cls.section(QLatin1Char('.'), -1) : cls;
|
||||
|
||||
const DesktopEntry *wmClassMatch = nullptr;
|
||||
const DesktopEntry *lastComponentMatch = nullptr;
|
||||
|
||||
for (const DesktopEntry &entry : m_entries) {
|
||||
const QString id = stem(entry.desktopId);
|
||||
if (!app.isEmpty() && id == app)
|
||||
return &entry;
|
||||
if (!cls.isEmpty() && id == cls)
|
||||
return &entry;
|
||||
|
||||
if (!entry.startupWmClass.isEmpty()) {
|
||||
const QString wm = stem(entry.startupWmClass);
|
||||
if ((!app.isEmpty() && wm == app) || (!cls.isEmpty() && wm == cls)
|
||||
|| (!appLast.isEmpty() && wm == appLast) || (!classLast.isEmpty() && wm == classLast)) {
|
||||
if (!wmClassMatch)
|
||||
wmClassMatch = &entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (!lastComponentMatch) {
|
||||
const QString idLast = id.contains(QLatin1Char('.')) ? id.section(QLatin1Char('.'), -1) : id;
|
||||
if (appLast.size() >= 3 && (id == appLast || idLast == appLast))
|
||||
lastComponentMatch = &entry;
|
||||
else if (classLast.size() >= 3 && (id == classLast || idLast == classLast))
|
||||
lastComponentMatch = &entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (wmClassMatch)
|
||||
return wmClassMatch;
|
||||
return lastComponentMatch;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user