Title bar button: fixes from trying it in the live desktop

- The decoration's "bottom" property clashed with Item's (KWin refused it).
- No On All Desktops button with one virtual desktop, like Breeze.
- decoration/apply.sh finds the session's D-Bus through plasmashell (KWin's
  environment isn't readable), and installs each try under a new name: KWin
  keeps a decoration's QML by name until it restarts.
- ft-floatd starts its script with Scripting.start: after a reload, the new
  script gets the old one's id while the old one is still being deleted, so
  run() on /Scripting/Script<id> went to the old script and the new one never
  ran (a second ft-floatd start left floating windows without their script).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DeeJanuzandClaude Opus 5.5 committed 2026-09-30 22:11:29 -06:00
1 parent f32187824a
commit 00dfd61396
6 files changed
+26 -15

No files matched your search

+13 -8
View File
@@ -10,10 +10,11 @@ deco=kwin4_decoration_qml_frametop
cfg=$HOME/.config/frametop
kwinrc=$cfg/kwinrc
# The desktop's KWin: the one using Frametop's config folder. Its D-Bus is the session's.
# The desktop's D-Bus: from its Plasma shell, which uses Frametop's config folder (KWin's own
# environment isn't readable: it runs with extra capabilities).
bus=
for pid in $(pgrep -x kwin_wayland); do
env=$(tr '\0' '\n' < "/proc/$pid/environ" 2>/dev/null) || continue
for pid in $(pgrep -x plasmashell); do
env=$( (tr '\0' '\n' < "/proc/$pid/environ") 2>/dev/null) || continue
grep -qx "XDG_CONFIG_HOME=$cfg" <<<"$env" || continue
bus=$(sed -n 's/^DBUS_SESSION_BUS_ADDRESS=//p' <<<"$env")
done
@@ -23,11 +24,15 @@ if [ "${1:-}" = --off ]; then
kwriteconfig6 --file "$kwinrc" --group org.kde.kdecoration2 --key library --delete
kwriteconfig6 --file "$kwinrc" --group org.kde.kdecoration2 --key theme --delete
else
dir=${XDG_DATA_HOME:-$HOME/.local/share}/kwin/decorations/$deco
rm -rf "$dir"
mkdir -p "$(dirname "$dir")"
cp -r "$here" "$dir"
rm -f "$dir/apply.sh"
# Under a new name each time: KWin keeps a decoration's QML (even a broken one) by name
# until it restarts. The next desktop start goes back to the plain name.
decos=${XDG_DATA_HOME:-$HOME/.local/share}/kwin/decorations
rm -rf "$decos/${deco}"_try*
deco=${deco}_try$(date +%s)
mkdir -p "$decos"
cp -r "$here" "$decos/$deco"
rm -f "$decos/$deco/apply.sh"
sed -i "s/\"Id\": \"[^\"]*\"/\"Id\": \"$deco\"/" "$decos/$deco/metadata.json"
kwriteconfig6 --file "$kwinrc" --group org.kde.kdecoration2 --key library org.kde.kwin.aurorae
kwriteconfig6 --file "$kwinrc" --group org.kde.kdecoration2 --key theme "$deco"
fi
+3
View File
@@ -116,5 +116,8 @@ DecorationButton {
visible = Qt.binding(() => decoration.client.providesContextHelp);
if (buttonType === DecorationOptions.DecorationButtonApplicationMenu)
visible = Qt.binding(() => decoration.client.hasApplicationMenu);
// Like Breeze: no On All Desktops button with only one virtual desktop.
if (buttonType === DecorationOptions.DecorationButtonOnAllDesktops)
visible = Qt.binding(() => decorationSettings.onAllDesktopsAvailable);
}
}
+4 -4
View File
@@ -44,24 +44,24 @@ Decoration {
default: return 4;
}
}
readonly property int bottom: borderSize === DecorationOptions.BorderNone ? 0
readonly property int bottomBorder: borderSize === DecorationOptions.BorderNone ? 0
: borderSize === DecorationOptions.BorderNoSides ? 4 : side
readonly property color outline: Qt.tint(options.titleBarColor, Qt.rgba(0, 0, 0, 0.35))
function applyBorders() {
borders.left = side;
borders.right = side;
borders.bottom = bottom;
borders.bottom = bottomBorder;
borders.top = titleHeight;
maximizedBorders.top = titleHeight;
// Without visible side borders, keep a strip to grab for resizing.
extendedBorders.left = side ? 0 : 4;
extendedBorders.right = side ? 0 : 4;
extendedBorders.bottom = bottom ? 0 : 4;
extendedBorders.bottom = bottomBorder ? 0 : 4;
}
onTitleHeightChanged: applyBorders()
onSideChanged: applyBorders()
onBottomChanged: applyBorders()
onBottomBorderChanged: applyBorders()
Component.onCompleted: applyBorders()
// The configured buttons, with the float button left of Close (or first on the right
+1 -1
View File
@@ -10,7 +10,7 @@ Built so far (2026-09-29; the KWin side tested on the headless test desktop, `sc
- The session adds `FLOAT_SLOTS` spares and starts ft-floatd from the desktop's autostart; ft-layout leaves the spares alone.
- The 3D mouse's drag lock crosses onto other Frametop panels (not while carrying one).
- The float key (2026-09-30): the input relay's `float_toggle` (Meta+Shift+F by default) and `dock_all`, through `float pointer` and `dock all` on ft-floatd. Tested on the headless desktop.
- The title bar button (2026-09-30, branch `float-titlebar`): `decoration/` (Frametop's QML window decoration, installed by the session script; `decoration/apply.sh` switches the running desktop to it or back to Breeze), and keep-below as the floating flag in the script. Not yet tried in a running KWin.
- The title bar button (2026-09-30, branch `float-titlebar`): `decoration/` (Frametop's QML window decoration, installed by the session script; `decoration/apply.sh` switches the running desktop to it or back to Breeze), and keep-below as the floating flag in the script. Tried on the live desktop: the button floats Dolphin and docks it again, the float key and `dock all` keep the flag in step, and maximized windows look right.
Not built yet: phase 2 (the ghost, tear-off by dragging, push-flush docking), phase 3 (launching floating, Launch as Standalone, remembered placement), and phase 4.
+4 -1
View File
@@ -197,7 +197,10 @@ class Daemon:
sid = int(kwin.loadScript(os.path.join(HERE, "frametop-float.js"), SCRIPT, signature="ss"))
if sid < 0:
raise RuntimeError("KWin didn't load the script")
bus.get_object("org.kde.KWin", f"/Scripting/Script{sid}").run(dbus_interface="org.kde.kwin.Script")
# Scripting.start runs every loaded script that isn't running. Not /Scripting/Script<id>'s
# run: a reloaded script gets the old one's id while the old one is still being deleted,
# so that path is still the old script's, and the new one would never run.
kwin.start()
log(f"script loaded ({sid})")
# Older scripts registered the float key with KWin; the input relay owns it now. Drop
# that shortcut, so System Settings doesn't list one that does nothing.
+1 -1
View File
@@ -204,7 +204,7 @@ deco=kwin4_decoration_qml_frametop
deco_dir=${XDG_DATA_HOME:-$HOME/.local/share}/kwin/decorations/$deco
kwinrc=$XDG_CONFIG_HOME/kwinrc
if [ "$float_slots" -gt 0 ]; then
rm -rf "$deco_dir"
rm -rf "$deco_dir" "$deco_dir"_try* # (decoration/apply.sh's copies)
mkdir -p "$(dirname "$deco_dir")"
cp -r "$here/../decoration" "$deco_dir"
rm -f "$deco_dir/apply.sh"