diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/flake.nix b/flake.nix index d5d5d62..05b9746 100644 --- a/flake.nix +++ b/flake.nix @@ -15,9 +15,9 @@ (system: fn system nixpkgs.legacyPackages.${system}); in { packages = forEachSystem (system: pkgs: rec { - default = minmat; - minmat = pkgs.stdenv.mkDerivation { - pname = "minmat"; + default = dots; + dots = pkgs.stdenv.mkDerivation { + pname = "dots"; version = "0.1.0"; src = ./shell; diff --git a/shell/bar/Bar.qml b/shell/bar/Bar.qml index 9c8eb04..e8f1ab7 100644 --- a/shell/bar/Bar.qml +++ b/shell/bar/Bar.qml @@ -74,12 +74,9 @@ Variants { } // VolumeIndicator { - // id: volumeIndicator - // popup: root.popup + // bar: root // Layout.preferredWidth: this.height // Layout.fillHeight: true - // Layout.topMargin: 2 - // Layout.bottomMargin: 2 // } PowerMenu { diff --git a/shell/bar/systray/SysTray.qml b/shell/bar/systray/SysTray.qml index 47dfbe2..a4ffc74 100644 --- a/shell/bar/systray/SysTray.qml +++ b/shell/bar/systray/SysTray.qml @@ -5,8 +5,8 @@ import QtQuick.Layouts import Quickshell import Quickshell.Widgets import Quickshell.Services.SystemTray -import "../../widgets" -import ".." +import qs.bar +import qs.widgets // TODO: // 1. Get rid of leftItem/rightItem properties on menu diff --git a/shell/bar/volume/DeviceMixer.qml b/shell/bar/volume/DeviceMixer.qml index ed37a83..e7076dc 100644 --- a/shell/bar/volume/DeviceMixer.qml +++ b/shell/bar/volume/DeviceMixer.qml @@ -3,8 +3,9 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell.Services.Pipewire -import "../../widgets/" as Widgets -import "../.." +import Quickshell.Widgets +import qs +import qs.widgets ColumnLayout { id: root @@ -13,7 +14,7 @@ ColumnLayout { // don't load until the node is not null Loader { id: sinkLoader - active: sink !== null + active: sink !== null Layout.preferredWidth: 350 Layout.preferredHeight: 45 @@ -22,11 +23,11 @@ ColumnLayout { sourceComponent: VolumeCard { id: sinkCard node: sinkLoader.sink - button: Widgets.FontIconButton { - hoverEnabled: false - iconName: sinkCard.node.audio.muted ? "volume_off" : "volume_up" - checked: !sinkCard.node.audio.muted - inactiveColor: ShellSettings.colors["surface_container_highest"] + button: StyledMouseArea { + property bool checked: !sinkCard.node.audio.muted + + // IconImage {} + onClicked: { sinkCard.node.audio.muted = !sinkCard.node.audio.muted; } @@ -39,7 +40,7 @@ ColumnLayout { // microphone, same as above Loader { id: sourceLoader - active: source !== null + active: source !== null Layout.preferredWidth: 350 Layout.preferredHeight: 45 @@ -48,11 +49,11 @@ ColumnLayout { sourceComponent: VolumeCard { id: sourceCard node: sourceLoader.source - button: Widgets.FontIconButton { - hoverEnabled: false - iconName: sourceCard.node.audio.muted ? "mic_off" : "mic" - checked: !sourceCard.node.audio.muted - inactiveColor: ShellSettings.colors["surface_container_highest"] + button: StyledMouseArea { + property bool checked: !sourceCard.node.audio.muted + + // IconImage {} + onClicked: { sourceCard.node.audio.muted = !sourceCard.node.audio.muted; } diff --git a/shell/bar/volume/VolumeCard.qml b/shell/bar/volume/VolumeCard.qml index 32ff535..ea085de 100644 --- a/shell/bar/volume/VolumeCard.qml +++ b/shell/bar/volume/VolumeCard.qml @@ -1,50 +1,80 @@ +pragma ComponentBehavior: Bound + import QtQuick import QtQuick.Layouts +import QtQuick.Controls import Quickshell.Widgets import Quickshell.Services.Pipewire -import "../../widgets/" as Widgets -import "../.." +import qs +import qs.widgets -WrapperRectangle { +Loader { id: root - color: ShellSettings.colors["surface_container"] - radius: width / 2 - margin: 6 + active: node !== null required property PwNode node - property string text - property Component button - property Component icon - PwObjectTracker { - id: tracker - objects: [root.node] - } + sourceComponent: WrapperRectangle { + id: comp + color: ShellSettings.colors.surface_container_translucent + radius: 12 + margin: 6 - RowLayout { - Widgets.MaterialSlider { - value: root.node.audio.volume ?? 0 - text: root.text - icon: root.icon + border { + width: 1 + color: ShellSettings.colors.active_translucent + } - onValueChanged: { - // only allow changes when the node is ready other wise you will combust - if (!root.node.ready) - return; + // property string text + // property Component button + // property Component icon - root.node.audio.volume = value; + PwObjectTracker { + id: tracker + objects: [root.node] + } + + RowLayout { + Slider { + value: root.node.audio.volume ?? 0 + // text: root.text + // icon: root.icon + + onValueChanged: { + // only allow changes when the node is ready other wise you will combust + if (!root.node.ready) + return; + + root.node.audio.volume = value; + } + + Layout.fillWidth: true + Layout.fillHeight: true } - Layout.fillWidth: true - Layout.fillHeight: true - } - - Loader { - id: buttonLoader - sourceComponent: root.button - - Layout.preferredWidth: this.height - Layout.fillHeight: true + // Loader { + // id: buttonLoader + // sourceComponent: root.button + // + // Layout.preferredWidth: this.height + // Layout.fillHeight: true + // } } } + + // sourceComponent: VolumeCard { + // id: sinkCard + // node: sinkLoader.sink + // button: StyledMouseArea { + // property bool checked: !sinkCard.node.audio.muted + // + // // IconImage {} + // + // onClicked: { + // sinkCard.node.audio.muted = !sinkCard.node.audio.muted; + // } + // } + // + // anchors.fill: parent + // } } diff --git a/shell/bar/volume/VolumeControl.qml b/shell/bar/volume/VolumeControl.qml index 4423de1..bcb4f48 100644 --- a/shell/bar/volume/VolumeControl.qml +++ b/shell/bar/volume/VolumeControl.qml @@ -3,32 +3,34 @@ pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell.Widgets -import "../../widgets/" as Widgets +import qs.widgets -WrapperItem { - id: root - visible: false +DeviceMixer {} - ColumnLayout { - spacing: 10 - - Widgets.TabBar { - id: tabBar - model: ["headphones", "tune"] - Layout.fillWidth: true - Layout.preferredHeight: 35 - } - - StackLayout { - id: page - currentIndex: tabBar.currentIndex - Layout.fillWidth: true - Layout.preferredHeight: currentItem ? currentItem.implicitHeight : 0 - - readonly property Item currentItem: children[currentIndex] - - DeviceMixer {} - ApplicationMixer {} - } - } -} +// WrapperItem { +// id: root +// +// ColumnLayout { +// spacing: 10 +// +// // TabBar { +// // id: tabBar +// // model: ["headphones", "tune"] +// // Layout.fillWidth: true +// // Layout.preferredHeight: 35 +// // } +// +// +// // StackLayout { +// // id: page +// // currentIndex: tabBar.currentIndex +// // Layout.fillWidth: true +// // Layout.preferredHeight: currentItem ? currentItem.implicitHeight : 0 +// // +// // readonly property Item currentItem: children[currentIndex] +// // +// // DeviceMixer {} +// // ApplicationMixer {} +// // } +// } +// } diff --git a/shell/bar/volume/VolumeIndicator.qml b/shell/bar/volume/VolumeIndicator.qml index 66f7a6e..c251c4e 100644 --- a/shell/bar/volume/VolumeIndicator.qml +++ b/shell/bar/volume/VolumeIndicator.qml @@ -1,27 +1,65 @@ +pragma ComponentBehavior: Bound + import QtQuick -import "../../widgets/" as Widgets +import QtQuick.Layouts +import Quickshell.Widgets +import Quickshell.Services.Pipewire +import qs.widgets +import qs.bar -Item { +StyledMouseArea { id: root + onClicked: showMenu = !showMenu - required property var popup + required property var bar + property bool showMenu: false - Widgets.FontIconButton { - id: button - iconName: "volume_up" - anchors.fill: parent - onClicked: { - if (root.popup.content == volumeMenu) { - root.popup.hide(); - return; - } + IconImage { + id: icon + source: "root:resources/volume/volume-full.svg" - root.popup.set(this, volumeMenu); - root.popup.show(); + anchors { + fill: parent + margins: 2 } } - VolumeControl { - id: volumeMenu + property PopupItem menu: PopupItem { + id: menu + owner: root + popup: root.bar.popup + show: root.showMenu + onClosed: root.showMenu = false + + implicitWidth: 300 + implicitHeight: container.implicitHeight + (2 * 8) + + // implicitWidth: volumeMenu.implicitWidth + // implicitHeight: volumeMenu.implicitHeight + + // VolumeControl { + // id: volumeMenu + // } + + ColumnLayout { + id: container + + anchors { + fill: parent + margins: 8 + } + + VolumeCard { + node: Pipewire.defaultAudioSink + Layout.fillWidth: true + Layout.preferredHeight: 45 + } + + VolumeCard { + node: Pipewire.defaultAudioSource + Layout.fillWidth: true + Layout.preferredHeight: 45 + } + } } } diff --git a/shell/launcher/Controller.qml b/shell/launcher/Controller.qml index 3a24e00..e56f366 100644 --- a/shell/launcher/Controller.qml +++ b/shell/launcher/Controller.qml @@ -7,7 +7,8 @@ import Quickshell import Quickshell.Io import Quickshell.Wayland import Quickshell.Widgets -import ".." +import qs +import qs.widgets Singleton { PersistentProperties { @@ -33,46 +34,50 @@ Singleton { LazyLoader { id: loader - activeAsync: persist.launcherOpen + // activeAsync: persist.launcherOpen + active: persist.launcherOpen PanelWindow { - implicitWidth: 500 - implicitHeight: 7 + searchContainer.implicitHeight + list.topMargin * 2 + list.delegateHeight * 10 color: "transparent" + exclusiveZone: 0 WlrLayershell.keyboardFocus: WlrKeyboardFocus.Exclusive // WlrLayershell.namespace: "shell:launcher" - Rectangle { - id: container - color: ShellSettings.colors.surface_translucent - radius: 12 + anchors { + top: true + bottom: true + left: true + right: true + } - anchors { - fill: parent - margins: 10 + WrapperRectangle { + clip: true + radius: 12 + color: ShellSettings.colors.surface_translucent + margin: 6 + + border { + width: 1 + color: ShellSettings.colors.active_translucent } - Behavior on height { - NumberAnimation { - duration: 200 - easing.type: Easing.OutCubic - } + anchors { + horizontalCenter: parent.horizontalCenter + top: parent.top + topMargin: screen.height / 2.75 } ColumnLayout { - anchors.fill: parent - anchors.margins: 7 - anchors.topMargin: 10 - anchors.bottomMargin: 0 - spacing: 0 + id: column + anchors.centerIn: parent - Rectangle { + StyledRectangle { id: searchContainer - Layout.fillWidth: true implicitHeight: searchbox.implicitHeight + 15 radius: 6 - color: ShellSettings.colors.surface_container_translucent - border.color: ShellSettings.colors.border_translucent + + // Width is largely determined by size of the searchContainer + Layout.preferredWidth: 500 RowLayout { id: searchbox @@ -81,8 +86,8 @@ Singleton { TextInput { id: search - Layout.fillWidth: true color: ShellSettings.colors.highlight + Layout.fillWidth: true focus: true Keys.forwardTo: [list] @@ -115,97 +120,114 @@ Singleton { ListView { id: list - Layout.fillWidth: true - Layout.fillHeight: true + visible: Layout.preferredHeight > 1 clip: true cacheBuffer: 0 // works around QTBUG-131106 //reuseItems: true + + Layout.fillWidth: true + Layout.preferredHeight: Math.min(matchesLength * delegateHeight, 500) + + Behavior on Layout.preferredHeight { + NumberAnimation { + duration: 200 + easing.type: Easing.OutCubic + } + } + + property var matchesLength: model.values.length + model: ScriptModel { - values: DesktopEntries.applications.values.map(object => { + values: { const stxt = search.text.toLowerCase(); - const ntxt = object.name.toLowerCase(); - let si = 0; - let ni = 0; - let matches = []; - let startMatch = -1; + if (stxt === '') + return []; - for (let si = 0; si != stxt.length; ++si) { - const sc = stxt[si]; + return DesktopEntries.applications.values.map(object => { + // const stxt = search.text.toLowerCase(); - while (true) { - // Drop any entries with letters that don't exist in order - if (ni == ntxt.length) - return null; + const ntxt = object.name.toLowerCase(); + let si = 0; + let ni = 0; - const nc = ntxt[ni++]; + let matches = []; + let startMatch = -1; - if (nc == sc) { - if (startMatch == -1) - startMatch = ni; - break; - } else { - if (startMatch != -1) { - matches.push({ - index: startMatch, - length: ni - startMatch - }); + for (let si = 0; si != stxt.length; ++si) { + const sc = stxt[si]; - startMatch = -1; + while (true) { + // Drop any entries with letters that don't exist in order + if (ni == ntxt.length) + return null; + + const nc = ntxt[ni++]; + + if (nc == sc) { + if (startMatch == -1) + startMatch = ni; + break; + } else { + if (startMatch != -1) { + matches.push({ + index: startMatch, + length: ni - startMatch + }); + + startMatch = -1; + } } } } - } - if (startMatch != -1) { - matches.push({ - index: startMatch, - length: ni - startMatch + 1 - }); - } + if (startMatch != -1) { + matches.push({ + index: startMatch, + length: ni - startMatch + 1 + }); + } - return { - object: object, - matches: matches - }; - }).filter(entry => entry !== null).sort((a, b) => { - let ai = 0; - let bi = 0; - let s = 0; + return { + object: object, + matches: matches + }; + }).filter(entry => entry !== null).sort((a, b) => { + let ai = 0; + let bi = 0; + let s = 0; - while (ai != a.matches.length && bi != b.matches.length) { - const am = a.matches[ai]; - const bm = b.matches[bi]; + while (ai != a.matches.length && bi != b.matches.length) { + const am = a.matches[ai]; + const bm = b.matches[bi]; - s = bm.length - am.length; + s = bm.length - am.length; + if (s != 0) + return s; + + s = am.index - bm.index; + if (s != 0) + return s; + + ++ai; + ++bi; + } + + s = a.matches.length - b.matches.length; if (s != 0) return s; - s = am.index - bm.index; + s = a.object.name.length - b.object.name.length; if (s != 0) return s; - ++ai; - ++bi; - } - - s = a.matches.length - b.matches.length; - if (s != 0) - return s; - - s = a.object.name.length - b.object.name.length; - if (s != 0) - return s; - - return a.object.name.localeCompare(b.object.name); - }).map(entry => entry.object) + return a.object.name.localeCompare(b.object.name); + }).map(entry => entry.object); + } onValuesChanged: list.currentIndex = 0 } - topMargin: 7 - bottomMargin: list.count == 0 ? 0 : 7 - add: Transition { NumberAnimation { property: "opacity" @@ -271,6 +293,7 @@ Singleton { readonly property real delegateHeight: 44 delegate: MouseArea { + id: entryMouseArea required property DesktopEntry modelData implicitHeight: list.delegateHeight @@ -283,6 +306,7 @@ Singleton { RowLayout { id: delegateLayout + anchors { verticalCenter: parent.verticalCenter left: parent.left @@ -293,10 +317,11 @@ Singleton { Layout.alignment: Qt.AlignVCenter asynchronous: true implicitSize: 30 - source: Quickshell.iconPath(modelData.icon) + source: Quickshell.iconPath(entryMouseArea.modelData.icon) } + Text { - text: modelData.name + text: entryMouseArea.modelData.name color: ShellSettings.colors.active Layout.alignment: Qt.AlignVCenter } diff --git a/shell/notifications/ActiveToast.qml b/shell/notifications/ActiveToast.qml index 6f42c84..293ddaf 100644 --- a/shell/notifications/ActiveToast.qml +++ b/shell/notifications/ActiveToast.qml @@ -114,8 +114,8 @@ Item { font.bold: true elide: Text.ElideRight maximumLineCount: 1 - Layout.preferredWidth: implicitWidth - Layout.maximumWidth: topRow.width * 0.3 + // Layout.preferredWidth: implicitWidth + // Layout.maximumWidth: topRow.width * 0.3 } Text { diff --git a/shell/notifications/Controller.qml b/shell/notifications/Controller.qml index de7f5de..8eed4d4 100644 --- a/shell/notifications/Controller.qml +++ b/shell/notifications/Controller.qml @@ -39,7 +39,7 @@ Scope { onVisibleCountChanged: visible = visibleCount != 0 color: "transparent" - implicitWidth: 525 + implicitWidth: 500 visible: false exclusionMode: ExclusionMode.Normal diff --git a/shell/resources/volume/volume-full.svg b/shell/resources/volume/volume-full.svg index 5126fca..2c24be5 100644 --- a/shell/resources/volume/volume-full.svg +++ b/shell/resources/volume/volume-full.svg @@ -1,15 +1,9 @@ - - - - volume-up-solid - - - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/shell/resources/volume/volume-mute.svg b/shell/resources/volume/volume-mute.svg index 3604983..4b67e0c 100644 --- a/shell/resources/volume/volume-mute.svg +++ b/shell/resources/volume/volume-mute.svg @@ -1,16 +1,9 @@ - - - - volume-off-solid - - - - - - - - - - - - + + + + + + + + + \ No newline at end of file diff --git a/shell/screencapture/SelectionRectangle.qml b/shell/screencapture/SelectionRectangle.qml index 71df1cf..ff92c0e 100644 --- a/shell/screencapture/SelectionRectangle.qml +++ b/shell/screencapture/SelectionRectangle.qml @@ -17,8 +17,8 @@ Item { onVisibleChanged: { if (!visible) selectionRect.width -= borderSize; - selectionRect.height -= borderSize; - areaSelected(selectionRect); + selectionRect.height -= borderSize; + areaSelected(selectionRect); } MouseArea {