mirror of
https://github.com/end-4/dots-hyprland.git
synced 2026-06-05 14:59:27 -05:00
changes from main n stuff
This commit is contained in:
@@ -37,14 +37,6 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
property real screenZoom: 1
|
||||
onScreenZoomChanged: {
|
||||
Quickshell.execDetached(["hyprctl", "keyword", "cursor:zoom_factor", root.screenZoom.toString()]);
|
||||
}
|
||||
Behavior on screenZoom {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "workspaceNumber"
|
||||
description: "Hold to show workspace numbers, release to show icons"
|
||||
@@ -56,16 +48,4 @@ Singleton {
|
||||
root.superDown = false
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "zoom"
|
||||
|
||||
function zoomIn() {
|
||||
screenZoom = Math.min(screenZoom + 0.4, 3.0)
|
||||
}
|
||||
|
||||
function zoomOut() {
|
||||
screenZoom = Math.max(screenZoom - 0.4, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,9 @@ pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import qs.modules.common.functions
|
||||
|
||||
import "functions"
|
||||
import "config"
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
@@ -603,26 +605,8 @@ Singleton {
|
||||
}
|
||||
}
|
||||
|
||||
property JsonObject waffles: JsonObject {
|
||||
// Some spots are kinda janky/awkward. Setting the following to
|
||||
// false will make (some) stuff also be like that for accuracy.
|
||||
// Example: the right-click menu of the Start button
|
||||
property JsonObject tweaks: JsonObject {
|
||||
property bool switchHandlePositionFix: true
|
||||
property bool smootherMenuAnimations: true
|
||||
property bool smootherSearchBar: true
|
||||
}
|
||||
property JsonObject bar: JsonObject {
|
||||
property bool bottom: true
|
||||
property bool leftAlignApps: false
|
||||
}
|
||||
property JsonObject actionCenter: JsonObject {
|
||||
property list<string> toggles: [ "network", "bluetooth", "easyEffects", "powerProfile", "idleInhibitor", "nightLight", "darkMode", "antiFlashbang", "cloudflareWarp", "mic", "musicRecognition", "notifications", "onScreenKeyboard", "gameMode", "screenSnip", "colorPicker" ]
|
||||
}
|
||||
property JsonObject calendar: JsonObject {
|
||||
property bool force2CharDayOfWeek: true
|
||||
}
|
||||
}
|
||||
property JsonObject hefty: HeftyConfig {}
|
||||
property JsonObject waffles: WaffleConfig {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ Singleton {
|
||||
readonly property string music: StandardPaths.standardLocations(StandardPaths.MusicLocation)[0]
|
||||
readonly property string videos: StandardPaths.standardLocations(StandardPaths.MoviesLocation)[0]
|
||||
|
||||
// Other dirs used by the shell, without "file://"
|
||||
/////// Stuff below are without "file://" /////////
|
||||
// General
|
||||
property string assetsPath: Quickshell.shellPath("assets")
|
||||
property string scriptPath: Quickshell.shellPath("scripts")
|
||||
property string favicons: FileUtils.trimFileProtocol(`${Directories.cache}/media/favicons`)
|
||||
@@ -30,9 +31,6 @@ Singleton {
|
||||
property string booruDownloads: FileUtils.trimFileProtocol(Directories.pictures + "/homework")
|
||||
property string booruDownloadsNsfw: FileUtils.trimFileProtocol(Directories.pictures + "/homework/🌶️")
|
||||
property string latexOutput: FileUtils.trimFileProtocol(`${Directories.cache}/media/latex`)
|
||||
property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/illogical-impulse`)
|
||||
property string shellConfigName: "config.json"
|
||||
property string shellConfigPath: `${Directories.shellConfig}/${Directories.shellConfigName}`
|
||||
property string todoPath: FileUtils.trimFileProtocol(`${Directories.state}/user/todo.json`)
|
||||
property string notesPath: FileUtils.trimFileProtocol(`${Directories.state}/user/notes.txt`)
|
||||
property string conflictCachePath: FileUtils.trimFileProtocol(`${Directories.cache}/conflict-killer`)
|
||||
@@ -43,14 +41,21 @@ Singleton {
|
||||
property string screenshotTemp: "/tmp/quickshell/media/screenshot"
|
||||
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.scriptPath}/colors/switchwall.sh`)
|
||||
property string defaultAiPrompts: Quickshell.shellPath("defaults/ai/prompts")
|
||||
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
|
||||
property string userActions: FileUtils.trimFileProtocol(`${Directories.shellConfig}/actions`)
|
||||
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`)
|
||||
|
||||
// User
|
||||
property string shellConfig: FileUtils.trimFileProtocol(`${Directories.config}/illogical-impulse`)
|
||||
property string shellConfigName: "config.json"
|
||||
property string shellConfigPath: `${Directories.shellConfig}/${Directories.shellConfigName}`
|
||||
property string userAiPrompts: FileUtils.trimFileProtocol(`${Directories.shellConfig}/ai/prompts`)
|
||||
property string userActions: FileUtils.trimFileProtocol(`${Directories.shellConfig}/actions`)
|
||||
property string userComponents: FileUtils.trimFileProtocol(`${Directories.shellConfig}/components`)
|
||||
|
||||
// Cleanup on init
|
||||
Component.onCompleted: {
|
||||
Quickshell.execDetached(["mkdir", "-p", `${shellConfig}`])
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
JsonObject {
|
||||
property JsonObject bar: JsonObject {
|
||||
property list<var> leftWidgets: []
|
||||
property list<var> centerWidgets: []
|
||||
property list<var> rightWidgets: []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
|
||||
JsonObject {
|
||||
// Some spots are kinda janky/awkward. Setting the following to
|
||||
// false will make (some) stuff also be like that for accuracy.
|
||||
// Example: the right-click menu of the Start button
|
||||
property JsonObject tweaks: JsonObject {
|
||||
property bool switchHandlePositionFix: true
|
||||
property bool smootherMenuAnimations: true
|
||||
property bool smootherSearchBar: true
|
||||
}
|
||||
property JsonObject bar: JsonObject {
|
||||
property bool bottom: true
|
||||
property bool leftAlignApps: false
|
||||
}
|
||||
property JsonObject actionCenter: JsonObject {
|
||||
property list<string> toggles: [ "network", "bluetooth", "easyEffects", "powerProfile", "idleInhibitor", "nightLight", "darkMode", "antiFlashbang", "cloudflareWarp", "mic", "musicRecognition", "notifications", "onScreenKeyboard", "gameMode", "screenSnip", "colorPicker" ]
|
||||
}
|
||||
property JsonObject calendar: JsonObject {
|
||||
property bool force2CharDayOfWeek: true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import QtQuick
|
||||
import QtQuick.Effects
|
||||
import qs.modules.common
|
||||
|
||||
MultiEffect {
|
||||
property color sourceColor: "black"
|
||||
|
||||
colorization: 1
|
||||
brightness: 1 - sourceColor.hslLightness
|
||||
|
||||
Behavior on colorizationColor {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.modules.common
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
property alias load: loader.activeAsync
|
||||
property bool shown: true // By default show immediately when loaded
|
||||
property alias component: loader.component
|
||||
|
||||
property alias fade: opacityBehavior.enabled
|
||||
property alias animation: opacityBehavior.animation
|
||||
|
||||
opacity: loader.active && shown ? 1 : 0
|
||||
visible: opacity > 0
|
||||
Behavior on opacity {
|
||||
id: opacityBehavior
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
LazyLoader {
|
||||
id: loader
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import QtQuick
|
||||
|
||||
Loader {
|
||||
id: root
|
||||
|
||||
property int fallbackIndex: 0
|
||||
property list<url> fallbacks: []
|
||||
property list<Component> fallbackComponents: []
|
||||
|
||||
onStatusChanged: {
|
||||
if (status === Loader.Error && fallbackIndex < fallbacks.length) {
|
||||
if (fallbacks[fallbackIndex]) {
|
||||
source = fallbacks[fallbackIndex];
|
||||
if (fallbackComponents[fallbackIndex]) {
|
||||
console.warn("[FallbackLoader] Both fallbacks urls and components are set, using url fallback");
|
||||
}
|
||||
} else if (fallbackComponents[fallbackIndex]) {
|
||||
sourceComponent = fallbackComponents[fallbackIndex];
|
||||
} else {
|
||||
console.error("[FallbackLoader] Out of fallbacks, tried all", fallbackIndex);
|
||||
}
|
||||
fallbackIndex += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ MouseArea { // Notification group area
|
||||
automaticallyReset: false
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.MiddleButton
|
||||
|
||||
onPressed: {
|
||||
onPressed: (mouse) => {
|
||||
if (mouse.button === Qt.RightButton)
|
||||
root.toggleExpanded();
|
||||
}
|
||||
@@ -102,6 +102,7 @@ MouseArea { // Notification group area
|
||||
}
|
||||
|
||||
onDragDiffXChanged: () => {
|
||||
if (!dragging) return;
|
||||
root.qmlParent.dragDistance = dragDiffX;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,11 @@ Item {
|
||||
property int screenWidth: QsWindow.window.width
|
||||
property int screenHeight: QsWindow.window.height
|
||||
|
||||
// Signals
|
||||
// Signals & loading
|
||||
signal requestFocus()
|
||||
signal dismissed()
|
||||
property bool load: true
|
||||
property bool shown: true
|
||||
|
||||
// Some info
|
||||
property int reservedTop: 0
|
||||
|
||||
@@ -10,6 +10,8 @@ import "../../common/widgets/shapes/material-shapes.js" as MaterialShapes
|
||||
import "../../common/widgets/shapes/shapes/corner-rounding.js" as CornerRounding
|
||||
import "../../common/widgets/shapes/geometry/offset.js" as Offset
|
||||
|
||||
import "bar"
|
||||
|
||||
/**
|
||||
* Fullscreen layer. Uses masking to not block clicks on windows n' stuff.
|
||||
*/
|
||||
@@ -35,15 +37,31 @@ PanelWindow {
|
||||
///////////////// Content //////////////////
|
||||
|
||||
property alias roundedPolygon: backgroundShape.roundedPolygon
|
||||
property bool finishedMorphing: true
|
||||
onRoundedPolygonChanged: finishedMorphing = false
|
||||
Connections {
|
||||
target: backgroundShape
|
||||
function onProgressChanged() {
|
||||
// While it overshoots because of the spring animation, waiting for the bounce to finish entirely would be too slow
|
||||
// ^ (totally not an excuse for my laziness)
|
||||
if (backgroundShape.progress >= 1.0) {
|
||||
root.finishedMorphing = true
|
||||
}
|
||||
}
|
||||
}
|
||||
S.ShapeCanvas {
|
||||
id: backgroundShape
|
||||
anchors.fill: parent
|
||||
polygonIsNormalized: false
|
||||
roundedPolygon: MaterialShapes.customPolygon([new MaterialShapes.PointNRound(new Offset.Offset(root.screen.width, 0), new CornerRounding.CornerRounding(9999)),])
|
||||
animation: NumberAnimation {
|
||||
duration: 500
|
||||
easing.type: Easing.BezierSpline
|
||||
easing.bezierCurve: Appearance.animationCurves.expressiveDefaultSpatial
|
||||
// animation: NumberAnimation {
|
||||
// duration: 500
|
||||
// easing.type: Easing.BezierSpline
|
||||
// easing.bezierCurve: Appearance.animationCurves.expressiveDefaultSpatial
|
||||
// }
|
||||
animation: SpringAnimation {
|
||||
spring: 3.5
|
||||
damping: 0.35
|
||||
}
|
||||
color: Appearance.colors.colLayer0
|
||||
borderWidth: (root.currentPanel === bar && Config.options.bar.cornerStyle !== 1) ? 0 : 1
|
||||
@@ -60,7 +78,8 @@ PanelWindow {
|
||||
color: "#44000000"
|
||||
}
|
||||
|
||||
property HAbstractMorphedPanel currentPanel: bar
|
||||
property HAbstractMorphedPanel currentPanel: null
|
||||
Component.onCompleted: currentPanel = bar
|
||||
roundedPolygon: currentPanel.backgroundPolygon
|
||||
|
||||
// Do we want to have reserved area always follow the bar or maybe differ per panel?
|
||||
@@ -89,10 +108,14 @@ PanelWindow {
|
||||
|
||||
HBar {
|
||||
id: bar
|
||||
load: root.currentPanel === this
|
||||
shown: root.finishedMorphing
|
||||
}
|
||||
|
||||
HOverview {
|
||||
id: overview
|
||||
load: root.currentPanel === this
|
||||
shown: root.finishedMorphing
|
||||
onRequestFocus: root.currentPanel = overview;
|
||||
onDismissed: root.dismiss();
|
||||
}
|
||||
|
||||
+17
-3
@@ -1,8 +1,11 @@
|
||||
pragma ComponentBehavior: Bound
|
||||
import QtQuick
|
||||
import qs.modules.common
|
||||
import "../../common/widgets/shapes/material-shapes.js" as MaterialShapes
|
||||
import "../../common/widgets/shapes/shapes/corner-rounding.js" as CornerRounding
|
||||
import "../../common/widgets/shapes/geometry/offset.js" as Offset
|
||||
import qs.modules.common.widgets
|
||||
import "../../../common/widgets/shapes/material-shapes.js" as MaterialShapes
|
||||
import "../../../common/widgets/shapes/shapes/corner-rounding.js" as CornerRounding
|
||||
import "../../../common/widgets/shapes/geometry/offset.js" as Offset
|
||||
import ".."
|
||||
|
||||
HAbstractMorphedPanel {
|
||||
id: root
|
||||
@@ -131,4 +134,15 @@ HAbstractMorphedPanel {
|
||||
easing.bezierCurve: Appearance.animationCurves.expressiveDefaultSpatial
|
||||
}
|
||||
}
|
||||
|
||||
FadeLazyLoader {
|
||||
id: contentLoader
|
||||
load: root.load
|
||||
shown: root.shown
|
||||
anchors.fill: parent
|
||||
component: HBarContent {
|
||||
parent: contentLoader
|
||||
anchors.fill: parent
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import qs.services
|
||||
import qs.modules.common.widgets
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
Side {
|
||||
id: leftSide
|
||||
anchors.left: parent.left
|
||||
width: (parent.width - centerSide.width) / 2
|
||||
}
|
||||
|
||||
Side {
|
||||
id: centerSide
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
|
||||
FallbackLoader {
|
||||
asynchronous: true
|
||||
source: "/home/end/.config/quickshell/ii/modules/ii/bar/WrongModuleName"
|
||||
fallbacks: ["/home/end/.config/quickshell/ii/modules/ii/bar/Workspaces.qml"]
|
||||
}
|
||||
}
|
||||
|
||||
Side {
|
||||
id: rightSide
|
||||
anchors.right: parent.right
|
||||
width: (parent.width - centerSide.width) / 2
|
||||
}
|
||||
|
||||
component Side: RowLayout {
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,19 +80,21 @@ Item { // Bar content region
|
||||
RowLayout {
|
||||
id: leftSectionRowLayout
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
spacing: 0
|
||||
|
||||
LeftSidebarButton { // Left sidebar button
|
||||
id: leftSidebarButton
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: Appearance.rounding.screenRounding
|
||||
colBackground: barLeftSideMouseArea.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1)
|
||||
}
|
||||
|
||||
ActiveWindow {
|
||||
visible: root.useShortenedForm === 0
|
||||
Layout.leftMargin: 10 + (leftSidebarButton.visible ? 0 : Appearance.rounding.screenRounding)
|
||||
Layout.rightMargin: Appearance.rounding.screenRounding
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: root.useShortenedForm === 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,11 @@ RippleButton {
|
||||
|
||||
property bool showPing: false
|
||||
|
||||
property bool aiChatEnabled: Config.options.policies.ai !== 0
|
||||
property bool translatorEnabled: Config.options.sidebar.translator.enable
|
||||
property bool animeEnabled: Config.options.policies.weeb !== 0
|
||||
visible: aiChatEnabled || translatorEnabled || animeEnabled
|
||||
|
||||
property real buttonPadding: 5
|
||||
implicitWidth: distroIcon.width + buttonPadding * 2
|
||||
implicitHeight: distroIcon.height + buttonPadding * 2
|
||||
|
||||
@@ -181,6 +181,7 @@ Item {
|
||||
|
||||
// Workspaces - numbers
|
||||
Grid {
|
||||
id: wsNumbers
|
||||
z: 3
|
||||
|
||||
columns: root.vertical ? 1 : root.workspacesShown
|
||||
@@ -209,6 +210,11 @@ Item {
|
||||
property var biggestWindow: HyprlandData.biggestWindowForWorkspace(button.workspaceValue)
|
||||
property var mainAppIconSource: Quickshell.iconPath(AppSearch.guessIcon(biggestWindow?.class), "image-missing")
|
||||
|
||||
property color numberColor: (monitor?.activeWorkspace?.id == button.workspaceValue) ?
|
||||
Appearance.m3colors.m3onPrimary :
|
||||
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
||||
Appearance.colors.colOnLayer1Inactive)
|
||||
|
||||
StyledText { // Workspace number text
|
||||
opacity: root.showNumbers
|
||||
|| ((Config.options?.bar.workspaces.alwaysShowNumbers && (!Config.options?.bar.workspaces.showAppIcons || !workspaceButtonBackground.biggestWindow || root.showNumbers))
|
||||
@@ -225,10 +231,7 @@ Item {
|
||||
}
|
||||
text: Config.options?.bar.workspaces.numberMap[button.workspaceValue - 1] || button.workspaceValue
|
||||
elide: Text.ElideRight
|
||||
color: (monitor?.activeWorkspace?.id == button.workspaceValue) ?
|
||||
Appearance.m3colors.m3onPrimary :
|
||||
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
||||
Appearance.colors.colOnLayer1Inactive)
|
||||
color: workspaceButtonBackground.numberColor
|
||||
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
@@ -245,10 +248,7 @@ Item {
|
||||
width: workspaceButtonWidth * 0.18
|
||||
height: width
|
||||
radius: width / 2
|
||||
color: (monitor?.activeWorkspace?.id == button.workspaceValue) ?
|
||||
Appearance.m3colors.m3onPrimary :
|
||||
(workspaceOccupied[index] ? Appearance.m3colors.m3onSecondaryContainer :
|
||||
Appearance.colors.colOnLayer1Inactive)
|
||||
color: workspaceButtonBackground.numberColor
|
||||
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
@@ -308,12 +308,8 @@ Item {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ Item {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
clip: true
|
||||
color: Appearance.colors.colSurfaceContainer
|
||||
color: Appearance.m3colors.m3surfaceContainer
|
||||
radius: Appearance.rounding.normal
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: Appearance.sizes.elevationMargin
|
||||
|
||||
@@ -136,6 +136,8 @@ MouseArea {
|
||||
// Style
|
||||
clip: true
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
selectedTextColor: materialShapeChars ? "transparent" : Appearance.colors.colOnSecondaryContainer
|
||||
selectionColor: materialShapeChars ? "transparent" : Appearance.colors.colSecondaryContainer
|
||||
|
||||
// Password
|
||||
enabled: !root.context.unlockInProgress
|
||||
@@ -195,6 +197,9 @@ MouseArea {
|
||||
}
|
||||
sourceComponent: PasswordChars {
|
||||
length: root.context.currentText.length
|
||||
selectionStart: passwordBox.selectionStart
|
||||
selectionEnd: passwordBox.selectionEnd
|
||||
cursorPosition: passwordBox.cursorPosition
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +220,7 @@ MouseArea {
|
||||
iconSize: 24
|
||||
text: {
|
||||
if (root.context.targetAction === LockContext.ActionEnum.Unlock) {
|
||||
return root.ctrlHeld ? "emoji_food_beverage" : "arrow_right_alt";
|
||||
return root.ctrlHeld ? "coffee" : "arrow_right_alt";
|
||||
} else if (root.context.targetAction === LockContext.ActionEnum.Poweroff) {
|
||||
return "power_settings_new";
|
||||
} else if (root.context.targetAction === LockContext.ActionEnum.Reboot) {
|
||||
|
||||
@@ -9,29 +9,62 @@ import Quickshell
|
||||
|
||||
StyledFlickable {
|
||||
id: root
|
||||
|
||||
required property int length
|
||||
property int selectionStart
|
||||
property int selectionEnd
|
||||
property int cursorPosition
|
||||
|
||||
property color color: Appearance.colors.colPrimary
|
||||
property color selectedTextColor: Appearance.colors.colOnSecondaryContainer
|
||||
property color selectionColor: Appearance.colors.colSecondaryContainer
|
||||
|
||||
property int charSize: 20
|
||||
|
||||
contentWidth: dotsRow.implicitWidth
|
||||
contentX: (Math.max(contentWidth - width, 0))
|
||||
Behavior on contentX {
|
||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: cursor
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: root.charSize * root.cursorPosition
|
||||
}
|
||||
color: root.color
|
||||
implicitWidth: 2
|
||||
implicitHeight: root.charSize
|
||||
Behavior on anchors.leftMargin {
|
||||
animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(cursor)
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
id: dotsRow
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 4
|
||||
leftMargin: 4 - 5 // -5 to account for spacing being simulated by char item width
|
||||
}
|
||||
spacing: 10
|
||||
spacing: 0
|
||||
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
model: ScriptModel { // TODO: use proper custom object model to insert new char at the correct pos
|
||||
values: Array(root.length)
|
||||
}
|
||||
delegate: Item {
|
||||
|
||||
delegate: Rectangle {
|
||||
id: charItem
|
||||
required property int index
|
||||
implicitWidth: 10
|
||||
implicitHeight: 10
|
||||
implicitWidth: root.charSize
|
||||
implicitHeight: root.charSize
|
||||
property bool selected: index >= root.selectionStart && index < root.selectionEnd
|
||||
|
||||
color: ColorUtils.transparentize(root.selectionColor, selected ? 0 : 1)
|
||||
|
||||
MaterialShape {
|
||||
id: materialShape
|
||||
anchors.centerIn: parent
|
||||
@@ -46,7 +79,7 @@ StyledFlickable {
|
||||
]
|
||||
shape: charShapes[charItem.index % charShapes.length]
|
||||
// Animate on appearance
|
||||
color: Appearance.colors.colPrimary
|
||||
color: charItem.selected ? root.selectedTextColor : root.color
|
||||
implicitSize: 0
|
||||
opacity: 0
|
||||
scale: 0.5
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property var action
|
||||
property var selectionMode
|
||||
|
||||
property string description: switch (root.action) {
|
||||
case RegionSelection.SnipAction.Copy:
|
||||
case RegionSelection.SnipAction.Edit:
|
||||
return Translation.tr("Copy region (LMB) or annotate (RMB)");
|
||||
case RegionSelection.SnipAction.Search:
|
||||
return Translation.tr("Search with Google Lens");
|
||||
case RegionSelection.SnipAction.CharRecognition:
|
||||
return Translation.tr("Recognize text");
|
||||
case RegionSelection.SnipAction.Record:
|
||||
case RegionSelection.SnipAction.RecordWithSound:
|
||||
return Translation.tr("Record region");
|
||||
}
|
||||
property string materialSymbol: switch (root.action) {
|
||||
case RegionSelection.SnipAction.Copy:
|
||||
case RegionSelection.SnipAction.Edit:
|
||||
return "content_cut";
|
||||
case RegionSelection.SnipAction.Search:
|
||||
return "image_search";
|
||||
case RegionSelection.SnipAction.CharRecognition:
|
||||
return "document_scanner";
|
||||
case RegionSelection.SnipAction.Record:
|
||||
case RegionSelection.SnipAction.RecordWithSound:
|
||||
return "videocam";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
property bool showDescription: true
|
||||
function hideDescription() {
|
||||
root.showDescription = false
|
||||
}
|
||||
Timer {
|
||||
id: descTimeout
|
||||
interval: 1000
|
||||
running: true
|
||||
onTriggered: {
|
||||
root.hideDescription()
|
||||
}
|
||||
}
|
||||
onActionChanged: {
|
||||
root.showDescription = true
|
||||
descTimeout.restart()
|
||||
}
|
||||
|
||||
property int margins: 8
|
||||
implicitWidth: content.implicitWidth + margins * 2
|
||||
implicitHeight: content.implicitHeight + margins * 2
|
||||
|
||||
Rectangle {
|
||||
id: content
|
||||
anchors.centerIn: parent
|
||||
|
||||
property real padding: 8
|
||||
implicitHeight: 38
|
||||
implicitWidth: root.showDescription ? contentRow.implicitWidth + padding * 2 : implicitHeight
|
||||
clip: true
|
||||
|
||||
topLeftRadius: 6
|
||||
bottomLeftRadius: implicitHeight - topLeftRadius
|
||||
bottomRightRadius: bottomLeftRadius
|
||||
topRightRadius: bottomLeftRadius
|
||||
|
||||
color: Appearance.colors.colPrimary
|
||||
|
||||
Behavior on topLeftRadius {
|
||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||
}
|
||||
Behavior on implicitWidth {
|
||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||
}
|
||||
|
||||
Row {
|
||||
id: contentRow
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
leftMargin: content.padding
|
||||
}
|
||||
spacing: 12
|
||||
|
||||
MaterialSymbol {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
iconSize: 22
|
||||
color: Appearance.colors.colOnPrimary
|
||||
animateChange: true
|
||||
text: root.materialSymbol
|
||||
}
|
||||
|
||||
FadeLoader {
|
||||
id: descriptionLoader
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
shown: root.showDescription
|
||||
sourceComponent: StyledText {
|
||||
color: Appearance.colors.colOnPrimary
|
||||
text: root.description
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 6
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,48 +23,6 @@ Toolbar {
|
||||
// Signals
|
||||
signal dismiss()
|
||||
|
||||
MaterialShape {
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 2
|
||||
Layout.rightMargin: 2
|
||||
implicitSize: 36 // Intentionally smaller because this one is brighter than others
|
||||
shape: switch (root.action) {
|
||||
case RegionSelection.SnipAction.Copy:
|
||||
case RegionSelection.SnipAction.Edit:
|
||||
return MaterialShape.Shape.Cookie4Sided;
|
||||
case RegionSelection.SnipAction.Search:
|
||||
return MaterialShape.Shape.Pentagon;
|
||||
case RegionSelection.SnipAction.CharRecognition:
|
||||
return MaterialShape.Shape.Sunny;
|
||||
case RegionSelection.SnipAction.Record:
|
||||
case RegionSelection.SnipAction.RecordWithSound:
|
||||
return MaterialShape.Shape.Gem;
|
||||
default:
|
||||
return MaterialShape.Shape.Cookie12Sided;
|
||||
}
|
||||
color: Appearance.colors.colPrimary
|
||||
MaterialSymbol {
|
||||
anchors.centerIn: parent
|
||||
iconSize: 22
|
||||
color: Appearance.colors.colOnPrimary
|
||||
animateChange: true
|
||||
text: switch (root.action) {
|
||||
case RegionSelection.SnipAction.Copy:
|
||||
case RegionSelection.SnipAction.Edit:
|
||||
return "content_cut";
|
||||
case RegionSelection.SnipAction.Search:
|
||||
return "image_search";
|
||||
case RegionSelection.SnipAction.CharRecognition:
|
||||
return "document_scanner";
|
||||
case RegionSelection.SnipAction.Record:
|
||||
case RegionSelection.SnipAction.RecordWithSound:
|
||||
return "videocam";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarTabBar {
|
||||
id: tabBar
|
||||
tabButtonList: [
|
||||
@@ -76,5 +34,4 @@ Toolbar {
|
||||
root.selectionMode = currentIndex === 0 ? RegionSelection.SelectionMode.RectCorners : RegionSelection.SelectionMode.Circle;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+29
-11
@@ -33,22 +33,40 @@ Item {
|
||||
}
|
||||
|
||||
// Selection border
|
||||
Rectangle {
|
||||
// Rectangle {
|
||||
// id: selectionBorder
|
||||
// z: 1
|
||||
// anchors {
|
||||
// left: parent.left
|
||||
// top: parent.top
|
||||
// leftMargin: root.regionX
|
||||
// topMargin: root.regionY
|
||||
// }
|
||||
// width: root.regionWidth
|
||||
// height: root.regionHeight
|
||||
// color: "transparent"
|
||||
// border.color: root.color
|
||||
// border.width: 2
|
||||
// // radius: root.standardRounding
|
||||
// radius: 0 // TODO: figure out how to make the overlay thing work with rounding
|
||||
// }
|
||||
|
||||
DashedBorder {
|
||||
id: selectionBorder
|
||||
z: 1
|
||||
z: 9
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
leftMargin: root.regionX
|
||||
topMargin: root.regionY
|
||||
leftMargin: Math.round(root.regionX) - borderWidth
|
||||
topMargin: Math.round(root.regionY) - borderWidth
|
||||
}
|
||||
width: root.regionWidth
|
||||
height: root.regionHeight
|
||||
color: "transparent"
|
||||
border.color: root.color
|
||||
border.width: 2
|
||||
// radius: root.standardRounding
|
||||
radius: 0 // TODO: figure out how to make the overlay thing work with rounding
|
||||
width: Math.round(root.regionWidth) + borderWidth * 2
|
||||
height: Math.round(root.regionHeight) + borderWidth * 2
|
||||
|
||||
color: root.color
|
||||
dashLength: 6
|
||||
gapLength: 3
|
||||
borderWidth: 1
|
||||
}
|
||||
|
||||
StyledText {
|
||||
|
||||
@@ -35,7 +35,7 @@ PanelWindow {
|
||||
signal dismiss()
|
||||
|
||||
property string screenshotDir: Directories.screenshotTemp
|
||||
property color overlayColor: "#88111111"
|
||||
property color overlayColor: ColorUtils.transparentize("#000000", 0.4)
|
||||
property color brightText: Appearance.m3colors.darkmode ? Appearance.colors.colOnLayer0 : Appearance.colors.colLayer0
|
||||
property color brightSecondary: Appearance.m3colors.darkmode ? Appearance.colors.colSecondary : Appearance.colors.colOnSecondary
|
||||
property color brightTertiary: Appearance.m3colors.darkmode ? Appearance.colors.colTertiary : Qt.lighter(Appearance.colors.colPrimary)
|
||||
@@ -375,6 +375,14 @@ PanelWindow {
|
||||
}
|
||||
}
|
||||
|
||||
CursorGuide {
|
||||
z: 9999
|
||||
x: root.dragging ? root.regionX + root.regionWidth : mouseArea.mouseX
|
||||
y: root.dragging ? root.regionY + root.regionHeight : mouseArea.mouseY
|
||||
action: root.action
|
||||
selectionMode: root.selectionMode
|
||||
}
|
||||
|
||||
// Window regions
|
||||
Repeater {
|
||||
model: ScriptModel {
|
||||
@@ -447,7 +455,7 @@ PanelWindow {
|
||||
// Controls
|
||||
Row {
|
||||
id: regionSelectionControls
|
||||
z: 9999
|
||||
z: 10
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
|
||||
@@ -48,6 +48,7 @@ Item {
|
||||
spacing: sidebarPadding
|
||||
|
||||
Toolbar {
|
||||
visible: tabButtonList.length > 0
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
enableShadow: false
|
||||
ToolbarTabBar {
|
||||
@@ -83,9 +84,10 @@ Item {
|
||||
}
|
||||
|
||||
contentChildren: [
|
||||
...((root.aiChatEnabled || (!root.translatorEnabled && !root.animeEnabled)) ? [aiChat.createObject()] : []),
|
||||
...(root.aiChatEnabled ? [aiChat.createObject()] : []),
|
||||
...(root.translatorEnabled ? [translator.createObject()] : []),
|
||||
...(root.animeEnabled ? [anime.createObject()] : [])
|
||||
...((root.tabButtonList.length === 0 || (!root.aiChatEnabled && !root.translatorEnabled && root.animeCloset)) ? [placeholder.createObject()] : []),
|
||||
...(root.animeEnabled ? [anime.createObject()] : []),
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -102,6 +104,15 @@ Item {
|
||||
id: anime
|
||||
Anime {}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: placeholder
|
||||
Item {
|
||||
StyledText {
|
||||
anchors.centerIn: parent
|
||||
text: root.animeCloset ? Translation.tr("Nothing") : Translation.tr("Enjoy your empty sidebar...")
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,7 +138,7 @@ Rectangle {
|
||||
|
||||
anchors.fill: parent
|
||||
// implicitHeight: tabStack.implicitHeight
|
||||
spacing: 10
|
||||
spacing: 20
|
||||
|
||||
// Navigation rail
|
||||
Item {
|
||||
@@ -146,7 +146,7 @@ Rectangle {
|
||||
Layout.fillWidth: false
|
||||
Layout.leftMargin: 10
|
||||
Layout.topMargin: 10
|
||||
width: tabBar.width
|
||||
implicitWidth: tabBar.implicitWidth
|
||||
// Navigation rail buttons
|
||||
NavigationRailTabArray {
|
||||
id: tabBar
|
||||
|
||||
@@ -54,6 +54,7 @@ Scope {
|
||||
margins: Appearance.sizes.hyprlandGapsOut
|
||||
leftMargin: Appearance.sizes.elevationMargin
|
||||
}
|
||||
asynchronous: true
|
||||
width: sidebarWidth - Appearance.sizes.hyprlandGapsOut - Appearance.sizes.elevationMargin
|
||||
height: parent.height - Appearance.sizes.hyprlandGapsOut * 2
|
||||
|
||||
|
||||
+1
@@ -47,6 +47,7 @@ DialogListItem {
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
elide: Text.ElideRight
|
||||
text: root.device?.name || Translation.tr("Unknown device")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
StyledText {
|
||||
visible: (root.device?.connected || root.device?.paired) ?? false
|
||||
|
||||
@@ -40,6 +40,7 @@ DialogListItem {
|
||||
color: Appearance.colors.colOnSurfaceVariant
|
||||
elide: Text.ElideRight
|
||||
text: root.wifiNetwork?.ssid ?? Translation.tr("Unknown")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
MaterialSymbol {
|
||||
visible: (root.wifiNetwork?.isSecure || root.wifiNetwork?.active) ?? false
|
||||
|
||||
+1
@@ -41,6 +41,7 @@ ExpandableChoiceButton {
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
text: root.device?.name || Translation.tr("Unknown device")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
WText { // Status
|
||||
id: statusText
|
||||
|
||||
@@ -61,6 +61,7 @@ ExpandableChoiceButton {
|
||||
elide: Text.ElideRight
|
||||
font.pixelSize: Looks.font.pixelSize.large
|
||||
text: root.wifiNetwork?.ssid ?? Translation.tr("Unknown")
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
WText { // Status
|
||||
id: statusText
|
||||
|
||||
@@ -148,14 +148,12 @@ Singleton {
|
||||
const brightnessValue = Math.max(monitor.multipliedBrightness, 0);
|
||||
if (isDdc) {
|
||||
const rawValueRounded = Math.max(Math.floor(brightnessValue * monitor.rawMaxBrightness), 1);
|
||||
setProc.command = ["ddcutil", "-b", busNum, "setvcp", "10", rawValueRounded];
|
||||
setProc.startDetached();
|
||||
setProc.exec(["ddcutil", "-b", busNum, "setvcp", "10", rawValueRounded]);
|
||||
} else {
|
||||
const valuePercentNumber = Math.floor(brightnessValue * 100);
|
||||
let valuePercent = `${valuePercentNumber}%`;
|
||||
if (valuePercentNumber == 0) valuePercent = "1"; // Prevent fully black
|
||||
setProc.command = ["brightnessctl", "--class", "backlight", "s", valuePercent, "--quiet"];
|
||||
setProc.startDetached();
|
||||
setProc.exec(["brightnessctl", "--class", "backlight", "s", valuePercent, "--quiet"])
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,9 @@ Singleton {
|
||||
const actionName = fileName.replace(/\.[^/.]+$/, ""); // strip extension
|
||||
actions.push({
|
||||
action: actionName,
|
||||
execute: ((path) => (args) => {
|
||||
Quickshell.execDetached([path, ...(args ? args.split(" ") : [])]);
|
||||
})(FileUtils.trimFileProtocol(filePath.toString()))
|
||||
execute: (path => args => {
|
||||
Quickshell.execDetached([path, ...(args ? args.split(" ") : [])]);
|
||||
})(FileUtils.trimFileProtocol(filePath.toString()))
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -250,8 +250,8 @@ Singleton {
|
||||
if (!entry.runInTerminal)
|
||||
entry.execute();
|
||||
else {
|
||||
// Probably needs more proper escaping, but this will do for now
|
||||
Quickshell.execDetached(["bash", '-c', `${Config.options.apps.terminal} -e '${StringUtils.shellSingleQuoteEscape(entry.command.join(' '))}'`]);
|
||||
print([...Config.options.apps.terminal, "-e", ...entry.command])
|
||||
Quickshell.execDetached([...Config.options.apps.terminal, "-e", ...entry.command]);
|
||||
}
|
||||
},
|
||||
comment: entry.comment,
|
||||
@@ -267,7 +267,7 @@ Singleton {
|
||||
if (!action.runInTerminal)
|
||||
action.execute();
|
||||
else {
|
||||
Quickshell.execDetached(["bash", '-c', `${Config.options.apps.terminal} -e '${StringUtils.shellSingleQuoteEscape(action.command.join(' '))}'`]);
|
||||
Quickshell.execDetached([...Config.options.apps.terminal, "-e", ...action.command]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
//@ pragma Env QT_QUICK_CONTROLS_STYLE=Basic
|
||||
//@ pragma Env QT_QUICK_FLICKABLE_WHEEL_DECELERATION=10000
|
||||
|
||||
// Adjust this to make the shell smaller or larger
|
||||
//@ pragma Env QT_SCALE_FACTOR=1
|
||||
// Remove two slashes below and adjust the value to change the UI scale
|
||||
////@ pragma Env QT_SCALE_FACTOR=1
|
||||
|
||||
import "modules/common"
|
||||
import "services"
|
||||
|
||||
Reference in New Issue
Block a user