forked from Shinonome/dots-hyprland
waffles: start menu base
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import qs.services
|
||||
import qs.modules.common.functions
|
||||
import QtCore
|
||||
import QtQuick
|
||||
@@ -46,6 +47,9 @@ Singleton {
|
||||
property string aiChats: FileUtils.trimFileProtocol(`${Directories.state}/user/ai/chats`)
|
||||
property string aiTranslationScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/ai/gemini-translate.sh`)
|
||||
property string recordScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/videos/record.sh`)
|
||||
property string userAvatarPathAccountsService: FileUtils.trimFileProtocol(`/var/lib/AccountsService/icons/${SystemInfo.username}`)
|
||||
property string userAvatarPathRicersAndWeirdSystems: FileUtils.trimFileProtocol(`${Directories.home}.face`)
|
||||
property string userAvatarPathRicersAndWeirdSystems2: FileUtils.trimFileProtocol(`${Directories.home}.face.icon`)
|
||||
// Cleanup on init
|
||||
Component.onCompleted: {
|
||||
Quickshell.execDetached(["mkdir", "-p", `${shellConfig}`])
|
||||
|
||||
@@ -12,4 +12,14 @@ Image {
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
property list<string> fallbacks: []
|
||||
property int currentFallbackIndex: 0
|
||||
|
||||
onStatusChanged: {
|
||||
if (status === Image.Error && currentFallbackIndex < fallbacks.length) {
|
||||
source = fallbacks[currentFallbackIndex];
|
||||
currentFallbackIndex += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ ToolTip {
|
||||
hintingPreference: Font.PreferNoHinting // Prevent shaky text
|
||||
}
|
||||
|
||||
delay: 0
|
||||
visible: internalVisibleCondition
|
||||
|
||||
contentItem: StyledToolTipContent {
|
||||
|
||||
@@ -162,7 +162,7 @@ Scope {
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "overview"
|
||||
target: "search"
|
||||
|
||||
function toggle() {
|
||||
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
||||
@@ -185,8 +185,8 @@ Scope {
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "overviewToggle"
|
||||
description: "Toggles overview on press"
|
||||
name: "searchToggle"
|
||||
description: "Toggles search on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.overviewOpen = !GlobalStates.overviewOpen;
|
||||
@@ -201,16 +201,8 @@ Scope {
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
name: "overviewClose"
|
||||
description: "Closes overview"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.overviewOpen = false;
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
name: "overviewToggleRelease"
|
||||
description: "Toggles overview on release"
|
||||
name: "searchToggleRelease"
|
||||
description: "Toggles search on release"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.superReleaseMightTrigger = true;
|
||||
@@ -225,8 +217,8 @@ Scope {
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
name: "overviewToggleReleaseInterrupt"
|
||||
description: "Interrupts possibility of overview being toggled on release. " + "This is necessary because GlobalShortcut.onReleased in quickshell triggers whether or not you press something else while holding the key. " + "To make sure this works consistently, use binditn = MODKEYS, catchall in an automatically triggered submap that includes everything."
|
||||
name: "searchToggleReleaseInterrupt"
|
||||
description: "Interrupts possibility of search being toggled on release. " + "This is necessary because GlobalShortcut.onReleased in quickshell triggers whether or not you press something else while holding the key. " + "To make sure this works consistently, use binditn = MODKEYS, catchall in an automatically triggered submap that includes everything."
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.superReleaseMightTrigger = false;
|
||||
|
||||
@@ -66,7 +66,7 @@ BarButton {
|
||||
}
|
||||
}
|
||||
|
||||
AppIcon {
|
||||
WAppIcon {
|
||||
id: iconWidget
|
||||
anchors.centerIn: parent
|
||||
iconName: root.iconName
|
||||
|
||||
@@ -14,8 +14,9 @@ AppButton {
|
||||
leftInset: Config.options.waffles.bar.leftAlignApps ? 12 : 0
|
||||
iconName: down ? "start-here-pressed" : "start-here"
|
||||
|
||||
checked: GlobalStates.searchOpen
|
||||
onClicked: {
|
||||
GlobalStates.overviewOpen = !GlobalStates.overviewOpen; // For now...
|
||||
GlobalStates.searchOpen = !GlobalStates.searchOpen;
|
||||
}
|
||||
|
||||
BarToolTip {
|
||||
|
||||
@@ -42,7 +42,7 @@ AppButton {
|
||||
}
|
||||
spacing: 6
|
||||
|
||||
AppIcon {
|
||||
WAppIcon {
|
||||
id: iconWidget
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconName: root.iconName
|
||||
|
||||
@@ -43,7 +43,7 @@ Button {
|
||||
Layout.fillHeight: false
|
||||
spacing: 8
|
||||
|
||||
AppIcon {
|
||||
WAppIcon {
|
||||
id: appIcon
|
||||
Layout.leftMargin: Looks.radius.large - root.padding + 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
|
||||
@@ -54,6 +54,7 @@ Singleton {
|
||||
property color controlFg: "#FFFFFF"
|
||||
property color accentUnfocused: "#848484"
|
||||
property color link: "#235CCF"
|
||||
property color inputBg: ColorUtils.transparentize(bg0, 0.4)
|
||||
}
|
||||
darkColors: QtObject {
|
||||
id: darkColors
|
||||
@@ -71,7 +72,7 @@ Singleton {
|
||||
property color bg2: '#8a8a8a'
|
||||
property color bg2Hover: '#b1b1b1'
|
||||
property color bg2Active: '#919191'
|
||||
property color bg2Border: '#c4c4c4'
|
||||
property color bg2Border: '#bdbdbd'
|
||||
property color subfg: "#CED1D7"
|
||||
property color fg: "#FFFFFF"
|
||||
property color fg1: "#D1D1D1"
|
||||
@@ -82,6 +83,7 @@ Singleton {
|
||||
property color controlFg: "#454545"
|
||||
property color accentUnfocused: "#989898"
|
||||
property color link: "#A7C9FC"
|
||||
property color inputBg: ColorUtils.transparentize(darkColors.bg0, 0.5)
|
||||
}
|
||||
colors: QtObject {
|
||||
id: colors
|
||||
@@ -112,6 +114,7 @@ Singleton {
|
||||
property color controlBg: root.dark ? root.darkColors.controlBg : root.lightColors.controlBg
|
||||
property color controlBgHover: root.dark ? root.darkColors.controlBgHover : root.lightColors.controlBgHover
|
||||
property color controlFg: root.dark ? root.darkColors.controlFg : root.lightColors.controlFg
|
||||
property color inputBg: root.dark ? root.darkColors.inputBg : root.lightColors.inputBg
|
||||
property color link: root.dark ? root.darkColors.link : root.lightColors.link
|
||||
property color danger: "#C42B1C"
|
||||
property color dangerActive: "#B62D1F"
|
||||
@@ -121,6 +124,7 @@ Singleton {
|
||||
property color accentActive: Appearance.colors.colPrimaryActive
|
||||
property color accentUnfocused: root.dark ? root.darkColors.accentUnfocused : root.lightColors.accentUnfocused
|
||||
property color accentFg: ColorUtils.isDark(accent) ? "#FFFFFF" : "#000000"
|
||||
property color selection: Appearance.colors.colPrimaryContainer
|
||||
}
|
||||
|
||||
radius: QtObject {
|
||||
|
||||
-1
@@ -2,7 +2,6 @@ import QtQuick
|
||||
import org.kde.kirigami as Kirigami
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
Kirigami.Icon {
|
||||
id: root
|
||||
@@ -53,10 +53,11 @@ Button {
|
||||
// Hover stuff
|
||||
signal hoverTimedOut
|
||||
property bool shouldShowTooltip: false
|
||||
ToolTip.delay: 400
|
||||
property Timer hoverTimer: Timer {
|
||||
id: hoverTimer
|
||||
running: root.hovered
|
||||
interval: 400
|
||||
interval: root.ToolTip.delay
|
||||
onTriggered: {
|
||||
root.hoverTimedOut();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
TextInput {
|
||||
id: root
|
||||
renderType: Text.NativeRendering
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: Looks.colors.fg
|
||||
|
||||
font {
|
||||
hintingPreference: Font.PreferFullHinting
|
||||
family: Looks.font.family.ui
|
||||
pixelSize: Looks.font.pixelSize.large
|
||||
weight: Looks.font.weight.regular
|
||||
}
|
||||
|
||||
selectionColor: Looks.colors.selection
|
||||
}
|
||||
+1
-2
@@ -68,9 +68,8 @@ WBarAttachedPanelContent {
|
||||
|
||||
WPane {
|
||||
id: calendarPane
|
||||
contentItem: ColumnLayout {
|
||||
contentItem: WPanelPageColumn {
|
||||
id: calendarColumnLayout
|
||||
spacing: 0
|
||||
DateHeader {
|
||||
Layout.fillWidth: true
|
||||
Synchronizer on collapsed {
|
||||
|
||||
+11
-5
@@ -13,7 +13,7 @@ MouseArea {
|
||||
id: root
|
||||
|
||||
required property var notification
|
||||
property bool expanded: false
|
||||
property bool expanded: notification.actions.length > 0
|
||||
property string groupExpandControlMessage: ""
|
||||
signal groupExpandToggle
|
||||
hoverEnabled: true
|
||||
@@ -58,13 +58,19 @@ MouseArea {
|
||||
|
||||
Loader {
|
||||
id: imageLoader
|
||||
anchors {
|
||||
top: parent.top
|
||||
left: parent.left
|
||||
}
|
||||
active: root.notification.image != ""
|
||||
sourceComponent: StyledImage {
|
||||
width: 48
|
||||
height: 48
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
readonly property int size: 48
|
||||
width: size
|
||||
height: size
|
||||
sourceSize.width: size
|
||||
sourceSize.height: size
|
||||
source: root.notification.image
|
||||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
FooterRectangle {
|
||||
id: root
|
||||
|
||||
property bool searching: text.length > 0
|
||||
property alias text: searchInput.text
|
||||
|
||||
Component.onCompleted: searchInput.forceActiveFocus()
|
||||
|
||||
focus: true
|
||||
color: searching ? Looks.colors.bgPanelBody : Looks.colors.bgPanelFooter
|
||||
|
||||
implicitWidth: 832 // TODO: Make sizes naturally inferred
|
||||
implicitHeight: 63
|
||||
|
||||
Rectangle {
|
||||
id: outline
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: 32
|
||||
rightMargin: 32
|
||||
topMargin: 16
|
||||
bottomMargin: 15
|
||||
}
|
||||
color: "transparent"
|
||||
radius: height / 2
|
||||
border.width: 1
|
||||
border.color: Looks.colors.bg2Border
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: searchInputBg
|
||||
anchors.fill: outline
|
||||
anchors.margins: 1
|
||||
radius: height / 2
|
||||
color: Looks.colors.inputBg
|
||||
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 11
|
||||
|
||||
WAppIcon {
|
||||
Layout.leftMargin: 14
|
||||
iconName: "system-search-checked"
|
||||
separateLightDark: true
|
||||
implicitSize: 18
|
||||
}
|
||||
|
||||
WTextInput {
|
||||
id: searchInput
|
||||
focus: true
|
||||
Layout.fillWidth: true
|
||||
|
||||
WText {
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
color: Looks.colors.accentUnfocused
|
||||
text: Translation.tr("Search for apps") // should also have "", settings, and documents" but we don't have those
|
||||
visible: searchInput.text.length === 0
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.IBeamCursor
|
||||
acceptedButtons: Qt.NoButton
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
BodyRectangle {
|
||||
id: root
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import Qt.labs.synchronizer
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
WBarAttachedPanelContent {
|
||||
id: root
|
||||
|
||||
property bool searching: false
|
||||
property string searchText: ""
|
||||
|
||||
contentItem: WPane {
|
||||
contentItem: WPanelPageColumn {
|
||||
SearchBar {
|
||||
focus: true
|
||||
Layout.fillWidth: true
|
||||
Synchronizer on searching {
|
||||
property alias target: root.searching
|
||||
}
|
||||
Synchronizer on text {
|
||||
property alias source: root.searchText
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: pageContentLoader
|
||||
Layout.fillWidth: true
|
||||
source: root.searching ? "SearchPageContent.qml" : "StartPageContent.qml"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import Quickshell
|
||||
import org.kde.kirigami as Kirigami
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.waffle.looks
|
||||
|
||||
WPanelPageColumn {
|
||||
id: root
|
||||
|
||||
WPanelSeparator {}
|
||||
|
||||
BodyRectangle {
|
||||
implicitHeight: 736 // TODO: Make sizes naturally inferred
|
||||
}
|
||||
|
||||
WPanelSeparator {}
|
||||
|
||||
StartFooter {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
component StartFooter: FooterRectangle {
|
||||
implicitHeight: 63
|
||||
|
||||
UserButton {
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: 52
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 12
|
||||
}
|
||||
}
|
||||
|
||||
PowerButton {
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 52
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 12
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component UserButton: WBorderlessButton {
|
||||
id: userButton
|
||||
implicitWidth: userButtonRow.implicitWidth + 12 * 2
|
||||
implicitHeight: 40
|
||||
|
||||
contentItem: Item {
|
||||
RowLayout {
|
||||
id: userButtonRow
|
||||
anchors.centerIn: parent
|
||||
spacing: 12
|
||||
|
||||
StyledImage {
|
||||
id: avatar
|
||||
// Use this for free fallback because I'm lazy
|
||||
Layout.alignment: Qt.AlignTop
|
||||
sourceSize: Qt.size(32, 32)
|
||||
source: Directories.userAvatarPathAccountsService
|
||||
fallbacks: [Directories.userAvatarPathRicersAndWeirdSystems, Directories.userAvatarPathRicersAndWeirdSystems2]
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Circle {
|
||||
diameter: avatar.height
|
||||
}
|
||||
}
|
||||
}
|
||||
WText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: SystemInfo.username
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component PowerButton: WBorderlessButton {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 40
|
||||
|
||||
contentItem: Item {
|
||||
FluentIcon {
|
||||
anchors.centerIn: parent
|
||||
icon: "power"
|
||||
implicitSize: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
import qs
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
|
||||
function onSearchOpenChanged() {
|
||||
if (GlobalStates.searchOpen)
|
||||
panelLoader.active = true;
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: panelLoader
|
||||
active: GlobalStates.searchOpen
|
||||
sourceComponent: PanelWindow {
|
||||
id: panelWindow
|
||||
exclusiveZone: 0
|
||||
WlrLayershell.namespace: "quickshell:wStartMenu"
|
||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
|
||||
color: "transparent"
|
||||
|
||||
anchors {
|
||||
bottom: Config.options.waffles.bar.bottom
|
||||
top: !Config.options.waffles.bar.bottom
|
||||
left: Config.options.waffles.bar.leftAlignApps
|
||||
}
|
||||
|
||||
implicitWidth: content.implicitWidth
|
||||
implicitHeight: content.implicitHeight
|
||||
|
||||
HyprlandFocusGrab {
|
||||
id: focusGrab
|
||||
active: true
|
||||
windows: [panelWindow]
|
||||
onCleared: content.close()
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onSearchOpenChanged() {
|
||||
if (!GlobalStates.searchOpen)
|
||||
content.close();
|
||||
}
|
||||
}
|
||||
|
||||
StartMenuContent {
|
||||
id: content
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
|
||||
onClosed: {
|
||||
GlobalStates.searchOpen = false;
|
||||
panelLoader.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "search"
|
||||
|
||||
function toggle() {
|
||||
GlobalStates.searchOpen = !GlobalStates.searchOpen;
|
||||
}
|
||||
function close() {
|
||||
GlobalStates.searchOpen = false;
|
||||
}
|
||||
function open() {
|
||||
GlobalStates.searchOpen = true;
|
||||
}
|
||||
function toggleReleaseInterrupt() {
|
||||
GlobalStates.superReleaseMightTrigger = false;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "searchToggle"
|
||||
description: "Toggles search on press"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.searchOpen = !GlobalStates.searchOpen;
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
name: "searchToggleRelease"
|
||||
description: "Toggles search on release"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.superReleaseMightTrigger = true;
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
if (!GlobalStates.superReleaseMightTrigger) {
|
||||
GlobalStates.superReleaseMightTrigger = true;
|
||||
return;
|
||||
}
|
||||
GlobalStates.searchOpen = !GlobalStates.searchOpen;
|
||||
}
|
||||
}
|
||||
GlobalShortcut {
|
||||
name: "searchToggleReleaseInterrupt"
|
||||
description: "Interrupts possibility of search being toggled on release. " + "This is necessary because GlobalShortcut.onReleased in quickshell triggers whether or not you press something else while holding the key. " + "To make sure this works consistently, use binditn = MODKEYS, catchall in an automatically triggered submap that includes everything."
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.superReleaseMightTrigger = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user