left sidebar: pinning (closes #2395)

This commit is contained in:
end-4
2025-11-13 23:27:19 +01:00
parent 37c1d9cf61
commit 6c7ac470bd
2 changed files with 55 additions and 9 deletions
@@ -395,7 +395,7 @@ Inline w/ backslash and round brackets \\(e^{i\\pi} + 1 = 0\\)
shown: Ai.messageIDs.length === 0
icon: "neurology"
title: Translation.tr("Large language models")
description: Translation.tr("Type /key to get started with online models\nCtrl+O to expand the sidebar\nCtrl+P to detach sidebar into a window")
description: Translation.tr("Type /key to get started with online models\nCtrl+O to expand sidebar\nCtrl+P to pin sidebar\nCtrl+D to detach sidebar")
shape: MaterialShape.Shape.PixelCircle
}
@@ -11,9 +11,53 @@ import Quickshell.Hyprland
Scope { // Scope
id: root
property bool detach: false
property bool pin: false
property Component contentComponent: SidebarLeftContent {}
property Item sidebarContent
function toggleDetach() {
root.detach = !root.detach;
}
Process { // Dodge cursor away, pin, move cursor back
id: pinWithFunnyHyprlandWorkaroundProc
property var hook: null
property int cursorX;
property int cursorY;
function doIt() {
command = ["hyprctl", "cursorpos"]
hook = (output) => {
cursorX = parseInt(output.split(",")[0]);
cursorY = parseInt(output.split(",")[1]);
doIt2();
}
running = true;
}
function doIt2(output) {
command = ["bash", "-c", "hyprctl dispatch movecursor 9999 9999"];
hook = () => {
doIt3();
}
running = true;
}
function doIt3(output) {
root.pin = !root.pin;
command = ["bash", "-c", `sleep 0.01; hyprctl dispatch movecursor ${cursorX} ${cursorY}`];
hook = null
running = true;
}
stdout: StdioCollector {
onStreamFinished: {
pinWithFunnyHyprlandWorkaroundProc.hook(text);
}
}
}
function togglePin() {
if (!root.pin) pinWithFunnyHyprlandWorkaroundProc.doIt()
else root.pin = !root.pin;
}
Component.onCompleted: {
root.sidebarContent = contentComponent.createObject(null, {
"scopeRoot": root,
@@ -51,11 +95,12 @@ Scope { // Scope
GlobalStates.sidebarLeftOpen = false
}
exclusiveZone: 0
exclusionMode: ExclusionMode.Normal
exclusiveZone: root.pin ? sidebarWidth : 0
implicitWidth: Appearance.sizes.sidebarWidthExtended + Appearance.sizes.elevationMargin
WlrLayershell.namespace: "quickshell:sidebarLeft"
// Hyprland 0.49: OnDemand is Exclusive, Exclusive just breaks click-outside-to-close
// WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
color: "transparent"
anchors {
@@ -71,7 +116,7 @@ Scope { // Scope
HyprlandFocusGrab { // Click outside to close
id: grab
windows: [ sidebarRoot ]
active: sidebarRoot.visible
active: sidebarRoot.visible && !root.pin
onActiveChanged: { // Focus the selected tab
if (active) sidebarLeftBackground.children[0].focusActiveItem()
}
@@ -109,9 +154,10 @@ Scope { // Scope
if (event.modifiers === Qt.ControlModifier) {
if (event.key === Qt.Key_O) {
sidebarRoot.extend = !sidebarRoot.extend;
}
else if (event.key === Qt.Key_P) {
root.detach = !root.detach;
} else if (event.key === Qt.Key_D) {
root.toggleDetach();
} else if (event.key === Qt.Key_P) {
root.togglePin();
}
event.accepted = true;
}
@@ -141,8 +187,8 @@ Scope { // Scope
Keys.onPressed: (event) => {
if (event.modifiers === Qt.ControlModifier) {
if (event.key === Qt.Key_P) {
root.detach = !root.detach;
if (event.key === Qt.Key_D) {
root.toggleDetach();
}
event.accepted = true;
}