diff --git a/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml b/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml index d6f4d53c..6068d59e 100644 --- a/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml +++ b/.config/quickshell/modules/sidebarLeft/SidebarLeft.qml @@ -17,191 +17,199 @@ Scope { // Scope property int sidebarPadding: 15 property var tabButtonList: [{"icon": "neurology", "name": qsTr("Intelligence")}, {"icon": "bookmark_heart", "name": qsTr("Anime")}] - PanelWindow { // Window - id: sidebarRoot - visible: false - focusable: true - property int selectedTab: PersistentStates.sidebar.leftSide.selectedTab - property bool extend: false - property bool pin: false - property real sidebarWidth: sidebarRoot.extend ? Appearance.sizes.sidebarWidthExtended : Appearance.sizes.sidebarWidth - - onVisibleChanged: { - GlobalStates.sidebarLeftOpenCount += visible ? 1 : -1 + Loader { + id: sidebarLoader + active: false + onActiveChanged: { + GlobalStates.sidebarLeftOpenCount += active ? 1 : -1 } + + PanelWindow { // Window + id: sidebarRoot + visible: sidebarLoader.active + focusable: true + property int selectedTab: PersistentStates.sidebar.leftSide.selectedTab + property bool extend: false + property bool pin: false + property real sidebarWidth: sidebarRoot.extend ? Appearance.sizes.sidebarWidthExtended : Appearance.sizes.sidebarWidth - exclusiveZone: pin ? sidebarWidth : 0 - implicitWidth: Appearance.sizes.sidebarWidthExtended - WlrLayershell.namespace: "quickshell:sidebarLeft" - // Hyprland 0.49: OnDemand is Exclusive, Exclusive just breaks click-outside-to-close - WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand - color: "transparent" - - anchors { - top: true - left: true - bottom: true - } - - mask: Region { - item: sidebarLeftBackground - } - - HyprlandFocusGrab { // Click outside to close - id: grab - windows: [ sidebarRoot ] - active: false - onCleared: () => { - if (!active) sidebarRoot.visible = false + function hide() { + sidebarLoader.active = false } - } - Connections { - target: sidebarRoot - function onVisibleChanged() { - delayedGrabTimer.start() - swipeView.children[0].children[0].children[sidebarRoot.selectedTab].forceActiveFocus() + exclusiveZone: pin ? sidebarWidth : 0 + implicitWidth: Appearance.sizes.sidebarWidthExtended + WlrLayershell.namespace: "quickshell:sidebarLeft" + // Hyprland 0.49: OnDemand is Exclusive, Exclusive just breaks click-outside-to-close + WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand + color: "transparent" + + anchors { + top: true + left: true + bottom: true } - function onPinChanged() { - grab.active = !sidebarRoot.pin + + mask: Region { + item: sidebarLeftBackground } - } - Timer { - id: delayedGrabTimer - interval: ConfigOptions.hacks.arbitraryRaceConditionDelay - repeat: false - onTriggered: { - grab.active = sidebarRoot.visible && !sidebarRoot.pin - } - } - - // Background - Rectangle { - id: sidebarLeftBackground - - anchors.top: parent.top - anchors.left: parent.left - anchors.topMargin: Appearance.sizes.hyprlandGapsOut - anchors.leftMargin: Appearance.sizes.hyprlandGapsOut - width: sidebarRoot.sidebarWidth - Appearance.sizes.hyprlandGapsOut * 2 - height: parent.height - Appearance.sizes.hyprlandGapsOut * 2 - color: Appearance.colors.colLayer0 - radius: Appearance.rounding.screenRounding - Appearance.sizes.elevationMargin + 1 - focus: sidebarRoot.visible - - Behavior on width { - NumberAnimation { - duration: Appearance.animation.elementMove.duration - easing.type: Appearance.animation.elementMove.type - easing.bezierCurve: Appearance.animation.elementMove.bezierCurve + HyprlandFocusGrab { // Click outside to close + id: grab + windows: [ sidebarRoot ] + active: false + onCleared: () => { + if (!active) sidebarRoot.hide() } } - Keys.onPressed: (event) => { - // console.log("Key pressed: " + event.key) - if (event.key === Qt.Key_Escape) { - sidebarRoot.visible = false; + Connections { + target: sidebarRoot + function onVisibleChanged() { + delayedGrabTimer.start() + swipeView.children[0].children[0].children[sidebarRoot.selectedTab].forceActiveFocus() } - if (event.modifiers === Qt.ControlModifier) { - if (event.key === Qt.Key_PageDown) { - PersistentStateManager.setState("sidebar.leftSide.selectedTab", Math.min(sidebarRoot.selectedTab + 1, root.tabButtonList.length - 1)) - } - else if (event.key === Qt.Key_PageUp) { - PersistentStateManager.setState("sidebar.leftSide.selectedTab", Math.max(sidebarRoot.selectedTab - 1, 0)) - } - else if (event.key === Qt.Key_Tab) { - PersistentStateManager.setState("sidebar.leftSide.selectedTab", (sidebarRoot.selectedTab + 1) % root.tabButtonList.length); - } - else if (event.key === Qt.Key_Backtab) { - PersistentStateManager.setState("sidebar.leftSide.selectedTab", (sidebarRoot.selectedTab - 1 + root.tabButtonList.length) % root.tabButtonList.length); - } - else if (event.key === Qt.Key_O) { - sidebarRoot.extend = !sidebarRoot.extend; - } - else if (event.key === Qt.Key_P) { - sidebarRoot.pin = !sidebarRoot.pin; - } - event.accepted = true; + function onPinChanged() { + grab.active = !sidebarRoot.pin } } - ColumnLayout { - anchors.fill: parent - anchors.margins: sidebarPadding - - spacing: sidebarPadding + Timer { + id: delayedGrabTimer + interval: ConfigOptions.hacks.arbitraryRaceConditionDelay + repeat: false + onTriggered: { + grab.active = sidebarRoot.visible && !sidebarRoot.pin + } + } - PrimaryTabBar { // Tab strip - id: tabBar - tabButtonList: root.tabButtonList - externalTrackedTab: sidebarRoot.selectedTab - function onCurrentIndexChanged(currentIndex) { - PersistentStateManager.setState("sidebar.leftSide.selectedTab", currentIndex) + // Background + Rectangle { + id: sidebarLeftBackground + + anchors.top: parent.top + anchors.left: parent.left + anchors.topMargin: Appearance.sizes.hyprlandGapsOut + anchors.leftMargin: Appearance.sizes.hyprlandGapsOut + width: sidebarRoot.sidebarWidth - Appearance.sizes.hyprlandGapsOut * 2 + height: parent.height - Appearance.sizes.hyprlandGapsOut * 2 + color: Appearance.colors.colLayer0 + radius: Appearance.rounding.screenRounding - Appearance.sizes.elevationMargin + 1 + focus: sidebarRoot.visible + + Behavior on width { + NumberAnimation { + duration: Appearance.animation.elementMove.duration + easing.type: Appearance.animation.elementMove.type + easing.bezierCurve: Appearance.animation.elementMove.bezierCurve } } - SwipeView { // Content pages - id: swipeView - Layout.topMargin: 5 - Layout.fillWidth: true - Layout.fillHeight: true - spacing: 10 - currentIndex: sidebarRoot.selectedTab - onCurrentIndexChanged: { - tabBar.enableIndicatorAnimation = true - PersistentStateManager.setState("sidebar.leftSide.selectedTab", currentIndex) + Keys.onPressed: (event) => { + // console.log("Key pressed: " + event.key) + if (event.key === Qt.Key_Escape) { + sidebarRoot.hide(); } + if (event.modifiers === Qt.ControlModifier) { + if (event.key === Qt.Key_PageDown) { + PersistentStateManager.setState("sidebar.leftSide.selectedTab", Math.min(sidebarRoot.selectedTab + 1, root.tabButtonList.length - 1)) + } + else if (event.key === Qt.Key_PageUp) { + PersistentStateManager.setState("sidebar.leftSide.selectedTab", Math.max(sidebarRoot.selectedTab - 1, 0)) + } + else if (event.key === Qt.Key_Tab) { + PersistentStateManager.setState("sidebar.leftSide.selectedTab", (sidebarRoot.selectedTab + 1) % root.tabButtonList.length); + } + else if (event.key === Qt.Key_Backtab) { + PersistentStateManager.setState("sidebar.leftSide.selectedTab", (sidebarRoot.selectedTab - 1 + root.tabButtonList.length) % root.tabButtonList.length); + } + else if (event.key === Qt.Key_O) { + sidebarRoot.extend = !sidebarRoot.extend; + } + else if (event.key === Qt.Key_P) { + sidebarRoot.pin = !sidebarRoot.pin; + } + event.accepted = true; + } + } - clip: true - layer.enabled: true - layer.effect: OpacityMask { - maskSource: Rectangle { - width: swipeView.width - height: swipeView.height - radius: Appearance.rounding.small + ColumnLayout { + anchors.fill: parent + anchors.margins: sidebarPadding + + spacing: sidebarPadding + + PrimaryTabBar { // Tab strip + id: tabBar + tabButtonList: root.tabButtonList + externalTrackedTab: sidebarRoot.selectedTab + function onCurrentIndexChanged(currentIndex) { + PersistentStateManager.setState("sidebar.leftSide.selectedTab", currentIndex) } } - AiChat { - panelWindow: sidebarRoot - } - Anime { - panelWindow: sidebarRoot + SwipeView { // Content pages + id: swipeView + Layout.topMargin: 5 + Layout.fillWidth: true + Layout.fillHeight: true + spacing: 10 + currentIndex: sidebarRoot.selectedTab + onCurrentIndexChanged: { + tabBar.enableIndicatorAnimation = true + PersistentStateManager.setState("sidebar.leftSide.selectedTab", currentIndex) + } + + clip: true + layer.enabled: true + layer.effect: OpacityMask { + maskSource: Rectangle { + width: swipeView.width + height: swipeView.height + radius: Appearance.rounding.small + } + } + + AiChat { + panelWindow: sidebarRoot + } + Anime { + panelWindow: sidebarRoot + } } + } - } - } - // Shadow - DropShadow { - anchors.fill: sidebarLeftBackground - horizontalOffset: 0 - verticalOffset: 2 - radius: Appearance.sizes.elevationMargin - samples: Appearance.sizes.elevationMargin * 2 + 1 // Ideally should be 2 * radius + 1, see qt docs - color: Appearance.colors.colShadow - source: sidebarLeftBackground - } + // Shadow + DropShadow { + anchors.fill: sidebarLeftBackground + horizontalOffset: 0 + verticalOffset: 2 + radius: Appearance.sizes.elevationMargin + samples: Appearance.sizes.elevationMargin * 2 + 1 // Ideally should be 2 * radius + 1, see qt docs + color: Appearance.colors.colShadow + source: sidebarLeftBackground + } + } } IpcHandler { target: "sidebarLeft" function toggle(): void { - sidebarRoot.visible = !sidebarRoot.visible; - if(sidebarRoot.visible) Notifications.timeoutAll(); + sidebarLoader.active = !sidebarLoader.active + if(sidebarLoader.active) Notifications.timeoutAll(); } function close(): void { - sidebarRoot.visible = false; + sidebarLoader.active = false } function open(): void { - sidebarRoot.visible = true; - if(sidebarRoot.visible) Notifications.timeoutAll(); + sidebarLoader.active = true + if(sidebarLoader.active) Notifications.timeoutAll(); } } @@ -210,8 +218,8 @@ Scope { // Scope description: "Toggles left sidebar on press" onPressed: { - sidebarRoot.visible = !sidebarRoot.visible; - if(sidebarRoot.visible) Notifications.timeoutAll(); + sidebarLoader.active = !sidebarLoader.active; + if(sidebarLoader.active) Notifications.timeoutAll(); } } @@ -220,8 +228,8 @@ Scope { // Scope description: "Opens left sidebar on press" onPressed: { - sidebarRoot.visible = true; - if(sidebarRoot.visible) Notifications.timeoutAll(); + sidebarLoader.active = true; + if(sidebarLoader.active) Notifications.timeoutAll(); } } @@ -230,7 +238,7 @@ Scope { // Scope description: "Closes left sidebar on press" onPressed: { - sidebarRoot.visible = false; + sidebarLoader.active = false; } }