diff --git a/decoration/apply.sh b/decoration/apply.sh index 31234b2..87e3c24 100755 --- a/decoration/apply.sh +++ b/decoration/apply.sh @@ -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 diff --git a/decoration/contents/ui/FtButton.qml b/decoration/contents/ui/FtButton.qml index 0bdd2d7..a533e19 100644 --- a/decoration/contents/ui/FtButton.qml +++ b/decoration/contents/ui/FtButton.qml @@ -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); } } diff --git a/decoration/contents/ui/main.qml b/decoration/contents/ui/main.qml index db10c55..329d8d1 100644 --- a/decoration/contents/ui/main.qml +++ b/decoration/contents/ui/main.qml @@ -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 diff --git a/docs/floating-windows.md b/docs/floating-windows.md index 0000159..97eadfd 100644 --- a/docs/floating-windows.md +++ b/docs/floating-windows.md @@ -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. diff --git a/float/ft_floatd.py b/float/ft_floatd.py index 4ac286f..20d2ed5 100644 --- a/float/ft_floatd.py +++ b/float/ft_floatd.py @@ -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'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. diff --git a/session/frametop-session.sh b/session/frametop-session.sh index eb3b995..822bb6b 100755 --- a/session/frametop-session.sh +++ b/session/frametop-session.sh @@ -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"