feat: add dynamic preview panel resizing and individual window instance close button
This commit is contained in:
parent
7e815d4a51
commit
f40fc29e3f
@ -495,10 +495,14 @@ Item {
|
||||
|
||||
GlassPanel {
|
||||
id: previewGlass
|
||||
implicitWidth: previewMainCol.implicitWidth + 20
|
||||
implicitWidth: previewMainCol.implicitWidth + 24
|
||||
implicitHeight: previewMainCol.implicitHeight + 16
|
||||
anchors.fill: parent
|
||||
|
||||
Behavior on implicitWidth {
|
||||
NumberAnimation { duration: 180; easing.type: Easing.OutCubic }
|
||||
}
|
||||
|
||||
opacity: dockWindowPreview.animProgress
|
||||
scale: 0.90 + 0.10 * dockWindowPreview.animProgress
|
||||
transformOrigin: Item.Bottom
|
||||
@ -634,9 +638,13 @@ Item {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
onClicked: {
|
||||
TaskService.closeApp(modelData.appId)
|
||||
previewPopIn.running = false
|
||||
previewPopOut.restart()
|
||||
TaskService.closeSpecificWindow(modelData)
|
||||
let rem = root.previewWindowInstances ? root.previewWindowInstances.filter(w => w.id !== modelData.id) : []
|
||||
root.previewWindowInstances = rem
|
||||
if (!rem || rem.length === 0) {
|
||||
previewPopIn.running = false
|
||||
previewPopOut.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -169,6 +169,16 @@ Item {
|
||||
proc.running = true
|
||||
}
|
||||
|
||||
function closeSpecificWindow(winObj) {
|
||||
if (!winObj) return;
|
||||
let winId = (winObj.id || "").toString().trim()
|
||||
let query = (winObj.caption || winObj.appId || "").toLowerCase().trim()
|
||||
|
||||
proc.running = false
|
||||
proc.command = ["python3", Quickshell.env("HOME") + "/.config/quickshell/services/python/kwin_close.py", winId, query]
|
||||
proc.running = true
|
||||
}
|
||||
|
||||
function focusApp(appId, cmd, iconX, iconY) {
|
||||
if (!appId) return;
|
||||
let lower = appId.toLowerCase().trim()
|
||||
|
||||
30
quickshell/services/js/kwin_close.js
Normal file
30
quickshell/services/js/kwin_close.js
Normal file
@ -0,0 +1,30 @@
|
||||
// KWin JavaScript Script: Gracefully Close Specific Window Instance
|
||||
var targetId = "%WIN_ID%".trim();
|
||||
var targetQuery = "%TARGET_QUERY%".toLowerCase().trim();
|
||||
|
||||
if (targetId || targetQuery) {
|
||||
var windows = workspace.windowList();
|
||||
for (var i = 0; i < windows.length; i++) {
|
||||
var win = windows[i];
|
||||
var id = String(win.internalId || win.windowId || "");
|
||||
var cls = (win.desktopFileName || win.resourceClass || win.resourceName || "").toLowerCase().trim();
|
||||
var caption = (win.caption || "").toLowerCase().trim();
|
||||
|
||||
var matches = false;
|
||||
if (targetId && id && (id === targetId || id.indexOf(targetId) !== -1)) {
|
||||
matches = true;
|
||||
}
|
||||
if (!matches && targetQuery) {
|
||||
if (caption && caption.indexOf(targetQuery) !== -1) {
|
||||
matches = true;
|
||||
} else if (cls && cls.indexOf(targetQuery) !== -1) {
|
||||
matches = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (matches) {
|
||||
win.closeWindow();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
quickshell/services/python/kwin_close.py
Normal file
36
quickshell/services/python/kwin_close.py
Normal file
@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
JS_TEMPLATE_PATH = os.path.expanduser('~/.config/quickshell/services/js/kwin_close.js')
|
||||
|
||||
def close_window(win_id="", target_query=""):
|
||||
try:
|
||||
with open(JS_TEMPLATE_PATH, 'r', encoding='utf-8') as f:
|
||||
template = f.read()
|
||||
|
||||
script = template.replace('%WIN_ID%', win_id).replace('%TARGET_QUERY%', target_query)
|
||||
|
||||
target_js = '/tmp/kwin_close.js'
|
||||
with open(target_js, 'w', encoding='utf-8') as f:
|
||||
f.write(script)
|
||||
|
||||
# Unload previous script instance to prevent KWin memory leaks
|
||||
subprocess.run(['busctl', '--user', 'call', 'org.kde.KWin', '/Scripting', 'org.kde.kwin.Scripting', 'unloadScript', 's', target_js], capture_output=True)
|
||||
|
||||
res = subprocess.check_output(
|
||||
['busctl', '--user', 'call', 'org.kde.KWin', '/Scripting', 'org.kde.kwin.Scripting', 'loadScript', 's', target_js],
|
||||
text=True
|
||||
)
|
||||
sid = res.strip().split()[-1]
|
||||
subprocess.run(['busctl', '--user', 'call', 'org.kde.KWin', f'/Scripting/Script{sid}', 'org.kde.kwin.Script', 'run'], capture_output=True)
|
||||
subprocess.run(['busctl', '--user', 'call', 'org.kde.KWin', f'/Scripting/Script{sid}', 'org.kde.kwin.Script', 'stop'], capture_output=True)
|
||||
subprocess.run(['busctl', '--user', 'call', 'org.kde.KWin', '/Scripting', 'org.kde.kwin.Scripting', 'unloadScript', 's', target_js], capture_output=True)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if __name__ == '__main__':
|
||||
win_id = sys.argv[1] if len(sys.argv) >= 2 else ""
|
||||
target_query = sys.argv[2] if len(sys.argv) >= 3 else ""
|
||||
close_window(win_id, target_query)
|
||||
Loading…
Reference in New Issue
Block a user