Fix window chrome positioning on Sway

Improves focused-window geometry so chrome placement stays stable across workspaces and floating containers. WindowService now exposes focused workspace X/Y, resolves workspace by name, and publishes those offsets with focused geometry. The Sway backend now tracks the active floating frame through recursion and consistently derives frame/deco/content rects from that frame. QML chrome placement was updated to use workspace-relative coordinates and simpler direct margins (removing interpolation behaviors), with safer title-bar height handling for vertical centering.
This commit is contained in:
2026-08-26 23:10:22 +12:00
parent e4ea19cd09
commit ba7945a1d6
7 changed files with 75 additions and 66 deletions
+28 -6
View File
@@ -156,6 +156,16 @@ int WindowService::focusedWindowTitleBarHeight() const
return m_focusedWindowTitleBarHeight;
}
int WindowService::focusedWorkspaceX() const
{
return m_focusedWorkspaceX;
}
int WindowService::focusedWorkspaceY() const
{
return m_focusedWorkspaceY;
}
bool WindowService::focusWindow(const QString &windowId)
{
return m_backend->focusWindow(parseWindowId(windowId));
@@ -333,6 +343,8 @@ void WindowService::publishFocusedGeometry(const WindowInfo *focused)
int decoHeight = 0;
int titleBarY = 0;
int titleBarHeight = 0;
int workspaceX = 0;
int workspaceY = 0;
bool fullscreen = false;
if (focused && !focused->minimized) {
@@ -349,13 +361,19 @@ void WindowService::publishFocusedGeometry(const WindowInfo *focused)
titleBarHeight = focused->decoHeight;
if (titleBarHeight <= 0)
titleBarHeight = focused->contentY;
if (titleBarHeight <= 0)
if (titleBarHeight < 16 || titleBarHeight > 48)
titleBarHeight = 32;
if (focused->decoHeight > 0 || focused->contentY > 0)
titleBarY = focused->y + focused->decoY;
else
titleBarY = focused->y - titleBarHeight;
// Frame rect from the floating container starts at the title bar.
titleBarY = focused->y + focused->decoY;
const WorkspaceInfo *workspace = m_workspaces->workspaceByName(focused->workspace);
if (!workspace)
workspace = m_workspaces->focusedWorkspace();
if (workspace) {
workspaceX = workspace->x;
workspaceY = workspace->y;
}
}
if (m_focusedWindowFullscreen != fullscreen) {
@@ -372,7 +390,9 @@ void WindowService::publishFocusedGeometry(const WindowInfo *focused)
|| m_focusedWindowDecoWidth != decoWidth
|| m_focusedWindowDecoHeight != decoHeight
|| m_focusedWindowTitleBarY != titleBarY
|| m_focusedWindowTitleBarHeight != titleBarHeight) {
|| m_focusedWindowTitleBarHeight != titleBarHeight
|| m_focusedWorkspaceX != workspaceX
|| m_focusedWorkspaceY != workspaceY) {
m_focusedWindowX = x;
m_focusedWindowY = y;
m_focusedWindowWidth = width;
@@ -383,6 +403,8 @@ void WindowService::publishFocusedGeometry(const WindowInfo *focused)
m_focusedWindowDecoHeight = decoHeight;
m_focusedWindowTitleBarY = titleBarY;
m_focusedWindowTitleBarHeight = titleBarHeight;
m_focusedWorkspaceX = workspaceX;
m_focusedWorkspaceY = workspaceY;
emit focusedWindowGeometryChanged();
}
}