From 6c678fa9cd111df116b219383d396efbd48c7c34 Mon Sep 17 00:00:00 2001 From: "Danilo M." Date: Sun, 18 Oct 2026 21:56:36 +0200 Subject: settings: titlebar row with maximize and close Hyprland draws no decorations, so the settings window had no way to fill the monitor and no visible close (only Ctrl+Q and Escape). It now carries a titlebar row of its own: "Keystone Settings" centred, and maximize and close at the right. Maximize toggles FloatingWindow.maximized, which Hyprland honours and undoes. A corner button floating over the page was tried first and covered the pages' Save buttons; a row of its own keeps clear of every page header without each page knowing about it. The buttons are Rectangles rather than the directory's Button.qml, because this file imports QtQuick.Controls and that import shadows it. Co-Authored-By: Claude Opus 5.5 --- AGENTS.md | 7 +++++++ desktop/Settings.qml | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/AGENTS.md b/AGENTS.md index eb35dfe..57f4914 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -197,6 +197,13 @@ changing that component. The ones that generalise: island's `implicitHeight` from 360 to 480 reloaded cleanly while `hyprctl layers` still reported `h: 360` and the performance panel stayed cut off; `./reload.sh desktop` applied it. Check the layer size, not the source. +- **`import QtQuick.Controls` shadows the directory's own `Button.qml`.** In + `Settings.qml`, which imports Controls, `Button { icon: ... }` became the + Controls button and logged `Unable to assign QString to QQuickIcon`. A file + that imports Controls builds its buttons from a `Rectangle` instead. +- **`FloatingWindow.maximized` works under Hyprland.** Setting it fills the + monitor and clearing it restores the old size, checked by eye; the settings + window's titlebar row uses it, since Hyprland draws no decorations. - **A QML method cannot be named `escape`.** It shadows the global JS function, and the file fails with `Illegal method name` at load, which a hot reload reports as the whole island being unavailable. The island's diff --git a/desktop/Settings.qml b/desktop/Settings.qml index 22af3da..c6d4b19 100644 --- a/desktop/Settings.qml +++ b/desktop/Settings.qml @@ -95,6 +95,7 @@ Scope { active: root.open FloatingWindow { + id: win title: "Settings" implicitWidth: 900 implicitHeight: 640 @@ -108,8 +109,55 @@ Scope { onActivated: root.close() } + // A titlebar of its own, since Hyprland draws none: maximize, to + // fill the monitor and back, and close. + Row { + id: titlebar + anchors { top: parent.top; right: parent.right; topMargin: 8; rightMargin: 12 } + height: 28 + spacing: 6 + + Repeater { + // nf-fa-compress / nf-fa-expand and nf-fa-xmark, present + // in Inconsolata Nerd Font. + model: [ + { icon: win.maximized ? "\uf066" : "\uf065", act: () => win.maximized = !win.maximized, danger: false }, + { icon: "\uf00d", act: () => root.close(), danger: true }, + ] + Rectangle { + required property var modelData + width: 28 + height: 28 + radius: 14 + color: btnArea.containsMouse ? Qt.alpha(modelData.danger ? Theme.red : Theme.accent, 0.25) : "transparent" + + Text { + anchors.centerIn: parent + text: parent.modelData.icon + font { family: Theme.iconFamily; pixelSize: Theme.fontSize - 2 } + color: Theme.text + } + + MouseArea { + id: btnArea + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: parent.modelData.act() + } + } + } + } + + Text { + anchors { horizontalCenter: parent.horizontalCenter; verticalCenter: titlebar.verticalCenter } + text: "Keystone Settings" + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2; bold: true } + color: Theme.subtext + } + Item { - anchors.fill: parent + anchors { top: titlebar.bottom; left: parent.left; right: parent.right; bottom: parent.bottom } focus: true Keys.onEscapePressed: root.back() -- cgit v1.2.3