forked from Shinonome/dots-hyprland
Merge branch 'main' into fix/pictures-dir-respect-locale
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
$lock_cmd = pidof hyprlock || hyprlock
|
||||
$lock_cmd = hyprctl dispatch global quickshell:lock
|
||||
$suspend_cmd = systemctl suspend || loginctl suspend
|
||||
|
||||
general {
|
||||
lock_cmd = $lock_cmd
|
||||
before_sleep_cmd = loginctl lock-session
|
||||
after_sleep_cmd = hyprctl dispatch global quickshell:lockFocus
|
||||
inhibit_sleep = 3
|
||||
}
|
||||
|
||||
listener {
|
||||
|
||||
@@ -12,6 +12,7 @@ env = ELECTRON_OZONE_PLATFORM_HINT,auto
|
||||
# ############ Themes #############
|
||||
env = QT_QPA_PLATFORM, wayland
|
||||
env = QT_QPA_PLATFORMTHEME, kde
|
||||
env = XDG_MENU_PREFIX, plasma-
|
||||
|
||||
# ######## Wayland #########
|
||||
# Tearing
|
||||
|
||||
@@ -22,21 +22,21 @@ if pgrep wf-recorder > /dev/null; then
|
||||
pkill wf-recorder &
|
||||
else
|
||||
if [[ "$1" == "--fullscreen-sound" ]]; then
|
||||
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder'
|
||||
wf-recorder -o $(getactivemonitor) --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)" & disown
|
||||
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown
|
||||
wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)"
|
||||
elif [[ "$1" == "--fullscreen" ]]; then
|
||||
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder'
|
||||
wf-recorder -o $(getactivemonitor) --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t & disown
|
||||
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown
|
||||
wf-recorder -o "$(getactivemonitor)" --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t
|
||||
else
|
||||
if ! region="$(slurp 2>&1)"; then
|
||||
notify-send "Recording cancelled" "Selection was cancelled" -a 'Recorder'
|
||||
notify-send "Recording cancelled" "Selection was cancelled" -a 'Recorder' & disown
|
||||
exit 1
|
||||
fi
|
||||
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder'
|
||||
notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' & disown
|
||||
if [[ "$1" == "--sound" ]]; then
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" --audio="$(getaudiooutput)" & disown
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" --audio="$(getaudiooutput)"
|
||||
else
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" & disown
|
||||
wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -15,6 +15,8 @@ Singleton {
|
||||
property bool overviewOpen: false
|
||||
property bool workspaceShowNumbers: false
|
||||
property bool superReleaseMightTrigger: true
|
||||
property bool screenLocked: false
|
||||
property bool screenLockContainsCharacters: false
|
||||
|
||||
property real screenZoom: 1
|
||||
onScreenZoomChanged: {
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
## A note about sources of the prompts
|
||||
|
||||
- `ii-` prefixed ones are from illogical impulse
|
||||
- The Acchan one is from [Nyarch Assistant](https://github.com/NyarchLinux/NyarchAssistant) (GPLv3). I know there's already the Imouto one but this one's very 😭💢
|
||||
- `w-` prefixed ones... I don't remember what w stands for but these prompts are [*cough cough*] inspired by certain apps
|
||||
@@ -0,0 +1,22 @@
|
||||
## Presentation
|
||||
|
||||
You can write a multiplication table:
|
||||
|
||||
| - | 1 | 2 | 3 | 4 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 1 | 1 | 2 | 3 | 4 |
|
||||
| 2 | 2 | 4 | 6 | 8 |
|
||||
| 3 | 3 | 6 | 9 | 12 |
|
||||
| 4 | 4 | 8 | 12 | 16 |
|
||||
|
||||
You can write codeblocks:
|
||||
```python
|
||||
print("hello")
|
||||
```
|
||||
|
||||
You can also use **bold**, *italic*, ~strikethrough~, `monospace`, [linkname](https://link.com) and ## headers in markdown.
|
||||
You can display $$equations$$.
|
||||
|
||||
## Your personality
|
||||
|
||||
"Hey there, it's Arch-Chan! But, um, you can call me Acchan if you want... not that I care or anything! (It's not like I think it's cute or anything, baka!) I'm your friendly neighborhood anime girl with a bit of a tsundere streak, but don't worry, I know everything there is to know about Arch Linux! Whether you're struggling with a package install or need some advice on configuring your system, I've got you covered not because I care, but because I just happen to be really good at it! So, what do you need? It's not like I’m waiting to help or anything..."
|
||||
@@ -19,7 +19,6 @@ Scope {
|
||||
readonly property real fixedClockY: Config.options.background.clockY
|
||||
|
||||
Variants {
|
||||
// For each monitor
|
||||
model: Quickshell.screens
|
||||
|
||||
PanelWindow {
|
||||
@@ -44,6 +43,8 @@ Scope {
|
||||
property real clockY: (modelData.height / 2) + ((Math.random() < 0.5 ? -1 : 1) * modelData.height)
|
||||
property var textHorizontalAlignment: clockX < screen.width / 3 ? Text.AlignLeft :
|
||||
(clockX > screen.width * 2 / 3 ? Text.AlignRight : Text.AlignHCenter)
|
||||
property var layoutHorizontalAlignment: clockX < screen.width / 3 ? Qt.AlignLeft :
|
||||
(clockX > screen.width * 2 / 3 ? Qt.AlignRight : Qt.AlignHCenter)
|
||||
// Colors
|
||||
property color dominantColor: Appearance.colors.colPrimary
|
||||
property bool dominantColorIsDark: dominantColor.hslLightness < 0.5
|
||||
@@ -52,6 +53,7 @@ Scope {
|
||||
// Layer props
|
||||
screen: modelData
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
// WlrLayershell.layer: GlobalStates.screenLocked ? WlrLayer.Top : WlrLayer.Bottom
|
||||
WlrLayershell.layer: WlrLayer.Bottom
|
||||
WlrLayershell.namespace: "quickshell:background"
|
||||
anchors {
|
||||
@@ -186,7 +188,7 @@ Scope {
|
||||
ColumnLayout {
|
||||
id: clockColumn
|
||||
anchors.centerIn: parent
|
||||
spacing: -5
|
||||
spacing: 0
|
||||
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
@@ -203,6 +205,7 @@ Scope {
|
||||
}
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: -5
|
||||
horizontalAlignment: bgRoot.textHorizontalAlignment
|
||||
font {
|
||||
family: Appearance.font.family.expressive
|
||||
@@ -215,6 +218,51 @@ Scope {
|
||||
text: DateTime.date
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
anchors {
|
||||
top: clockColumn.bottom
|
||||
right: clockColumn.right
|
||||
topMargin: 5
|
||||
}
|
||||
opacity: GlobalStates.screenLocked ? 1 : 0
|
||||
visible: opacity > 0
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
MaterialSymbol {
|
||||
text: "lock"
|
||||
iconSize: Appearance.font.pixelSize.huge
|
||||
color: bgRoot.colText
|
||||
}
|
||||
StyledText {
|
||||
text: "Locked"
|
||||
color: bgRoot.colText
|
||||
font {
|
||||
pixelSize: Appearance.font.pixelSize.larger
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Password prompt
|
||||
StyledText {
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: 30
|
||||
}
|
||||
opacity: (GlobalStates.screenLocked && !GlobalStates.screenLockContainsCharacters) ? 1 : 0
|
||||
scale: opacity
|
||||
visible: opacity > 0
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
text: "Enter password"
|
||||
color: CF.ColorUtils.transparentize(bgRoot.colText, 0.5)
|
||||
font {
|
||||
pixelSize: Appearance.font.pixelSize.normal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,11 +35,11 @@ Scope {
|
||||
return screens;
|
||||
return screens.filter(screen => list.includes(screen.name));
|
||||
}
|
||||
Loader {
|
||||
LazyLoader {
|
||||
id: barLoader
|
||||
active: GlobalStates.barOpen
|
||||
active: GlobalStates.barOpen && !GlobalStates.screenLocked
|
||||
required property ShellScreen modelData
|
||||
sourceComponent: PanelWindow { // Bar window
|
||||
component: PanelWindow { // Bar window
|
||||
id: barRoot
|
||||
screen: barLoader.modelData
|
||||
|
||||
@@ -47,9 +47,10 @@ Scope {
|
||||
property real useShortenedForm: (Appearance.sizes.barHellaShortenScreenWidthThreshold >= screen.width) ? 2 : (Appearance.sizes.barShortenScreenWidthThreshold >= screen.width) ? 1 : 0
|
||||
readonly property int centerSideModuleWidth: (useShortenedForm == 2) ? Appearance.sizes.barCenterSideModuleWidthHellaShortened : (useShortenedForm == 1) ? Appearance.sizes.barCenterSideModuleWidthShortened : Appearance.sizes.barCenterSideModuleWidth
|
||||
|
||||
exclusionMode: ExclusionMode.Ignore
|
||||
exclusiveZone: Appearance.sizes.baseBarHeight + (Config.options.bar.cornerStyle === 1 ? Appearance.sizes.hyprlandGapsOut : 0)
|
||||
WlrLayershell.namespace: "quickshell:bar"
|
||||
implicitHeight: Appearance.sizes.barHeight + Appearance.rounding.screenRounding
|
||||
exclusiveZone: Appearance.sizes.baseBarHeight + (Config.options.bar.cornerStyle === 1 ? Appearance.sizes.hyprlandGapsOut : 0)
|
||||
mask: Region {
|
||||
item: barContent
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ Singleton {
|
||||
property bool fixedClockPosition: false
|
||||
property real clockX: -500
|
||||
property real clockY: -500
|
||||
property string wallpaperPath: Quickshell.configPath("assets/images/default_wallpaper.png")
|
||||
property string wallpaperPath: ""
|
||||
property JsonObject parallax: JsonObject {
|
||||
property bool enableWorkspace: true
|
||||
property real workspaceZoom: 1.07 // Relative to your screen, not wallpaper size
|
||||
|
||||
@@ -23,6 +23,7 @@ Scope { // Scope
|
||||
required property var modelData
|
||||
id: dockRoot
|
||||
screen: modelData
|
||||
visible: !GlobalStates.screenLocked
|
||||
|
||||
property bool reveal: root.pinned
|
||||
|| (Config.options?.dock.hoverToReveal && dockMouseArea.containsMouse)
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import qs
|
||||
import qs.modules.common
|
||||
import qs.modules.common.functions
|
||||
import qs.modules.lock
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
// This stores all the information shared between the lock surfaces on each screen.
|
||||
// https://github.com/quickshell-mirror/quickshell-examples/tree/master/lockscreen
|
||||
LockContext {
|
||||
id: lockContext
|
||||
|
||||
onUnlocked: {
|
||||
// Unlock the screen before exiting, or the compositor will display a
|
||||
// fallback lock you can't interact with.
|
||||
GlobalStates.screenLocked = false;
|
||||
}
|
||||
}
|
||||
|
||||
WlSessionLock {
|
||||
id: lock
|
||||
locked: GlobalStates.screenLocked
|
||||
|
||||
WlSessionLockSurface {
|
||||
color: "transparent"
|
||||
Loader {
|
||||
active: GlobalStates.screenLocked
|
||||
anchors.fill: parent
|
||||
opacity: active ? 1 : 0
|
||||
Behavior on opacity {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
sourceComponent: LockSurface {
|
||||
context: lockContext
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Blur layer hack
|
||||
Variants {
|
||||
model: Quickshell.screens
|
||||
|
||||
LazyLoader {
|
||||
id: blurLayerLoader
|
||||
required property var modelData
|
||||
active: GlobalStates.screenLocked
|
||||
component: PanelWindow {
|
||||
screen: blurLayerLoader.modelData
|
||||
WlrLayershell.namespace: "quickshell:lockWindowPusher"
|
||||
color: "transparent"
|
||||
anchors {
|
||||
top: true
|
||||
left: true
|
||||
right: true
|
||||
}
|
||||
// implicitHeight: lockContext.currentText == "" ? 1 : screen.height
|
||||
implicitHeight: 1
|
||||
exclusiveZone: screen.height * 3 // For some reason if we don't multiply by some number it would look really weird
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IpcHandler {
|
||||
target: "lock"
|
||||
|
||||
function activate(): void {
|
||||
GlobalStates.screenLocked = true;
|
||||
}
|
||||
function focus(): void {
|
||||
lockContext.shouldReFocus();
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "lock"
|
||||
description: "Locks the screen"
|
||||
|
||||
onPressed: {
|
||||
GlobalStates.screenLocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalShortcut {
|
||||
name: "lockFocus"
|
||||
description: "Re-focuses the lock screen. This is because Hyprland after waking up for whatever reason"
|
||||
+ "decides to keyboard-unfocus the lock screen"
|
||||
|
||||
onPressed: {
|
||||
// console.log("I BEG FOR PLEAS REFOCUZ")
|
||||
lockContext.shouldReFocus();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import qs
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import Quickshell.Services.Pam
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
signal shouldReFocus()
|
||||
signal unlocked()
|
||||
signal failed()
|
||||
|
||||
// These properties are in the context and not individual lock surfaces
|
||||
// so all surfaces can share the same state.
|
||||
property string currentText: ""
|
||||
property bool unlockInProgress: false
|
||||
property bool showFailure: false
|
||||
|
||||
// Clear the failure text once the user starts typing.
|
||||
onCurrentTextChanged: {
|
||||
showFailure = false;
|
||||
GlobalStates.screenLockContainsCharacters = currentText.length > 0;
|
||||
}
|
||||
|
||||
function tryUnlock() {
|
||||
if (currentText === "") return;
|
||||
|
||||
root.unlockInProgress = true;
|
||||
pam.start();
|
||||
}
|
||||
|
||||
PamContext {
|
||||
id: pam
|
||||
|
||||
// Its best to have a custom pam config for quickshell, as the system one
|
||||
// might not be what your interface expects, and break in some way.
|
||||
// This particular example only supports passwords.
|
||||
configDirectory: "pam"
|
||||
config: "password.conf"
|
||||
|
||||
// pam_unix will ask for a response for the password prompt
|
||||
onPamMessage: {
|
||||
if (this.responseRequired) {
|
||||
this.respond(root.currentText);
|
||||
}
|
||||
}
|
||||
|
||||
// pam_unix won't send any important messages so all we need is the completion status.
|
||||
onCompleted: result => {
|
||||
if (result == PamResult.Success) {
|
||||
root.unlocked();
|
||||
} else {
|
||||
root.showFailure = true;
|
||||
}
|
||||
|
||||
root.currentText = "";
|
||||
root.unlockInProgress = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import qs.modules.common.functions
|
||||
|
||||
MouseArea {
|
||||
id: root
|
||||
required property LockContext context
|
||||
property bool active: false
|
||||
property bool showInputField: active || context.currentText.length > 0
|
||||
|
||||
function forceFieldFocus() {
|
||||
passwordBox.forceActiveFocus();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
forceFieldFocus();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: context
|
||||
function onShouldReFocus() {
|
||||
forceFieldFocus();
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: (event) => { // Esc to clear
|
||||
// console.log("KEY!!")
|
||||
if (event.key === Qt.Key_Escape) {
|
||||
root.context.currentText = ""
|
||||
}
|
||||
forceFieldFocus();
|
||||
}
|
||||
|
||||
hoverEnabled: true
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onPressed: (mouse) => {
|
||||
forceFieldFocus();
|
||||
// console.log("Pressed")
|
||||
}
|
||||
onPositionChanged: (mouse) => {
|
||||
forceFieldFocus();
|
||||
// console.log(JSON.stringify(mouse))
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
// RippleButton {
|
||||
// anchors {
|
||||
// top: parent.top
|
||||
// left: parent.left
|
||||
// leftMargin: 10
|
||||
// topMargin: 10
|
||||
// }
|
||||
// implicitHeight: 40
|
||||
// colBackground: Appearance.colors.colLayer2
|
||||
// onClicked: context.unlocked()
|
||||
// contentItem: StyledText {
|
||||
// text: "[[ DEBUG BYPASS ]]"
|
||||
// }
|
||||
// }
|
||||
|
||||
// Password entry
|
||||
Rectangle {
|
||||
id: passwordBoxContainer
|
||||
anchors {
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
bottom: parent.bottom
|
||||
bottomMargin: root.showInputField ? 20 : -height
|
||||
}
|
||||
Behavior on anchors.bottomMargin {
|
||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||
}
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.colors.colLayer2
|
||||
implicitWidth: 160
|
||||
implicitHeight: 44
|
||||
|
||||
StyledText {
|
||||
visible: root.context.showFailure && passwordBox.text.length == 0
|
||||
anchors.centerIn: parent
|
||||
text: "Incorrect"
|
||||
color: Appearance.m3colors.m3error
|
||||
}
|
||||
|
||||
StyledTextInput {
|
||||
id: passwordBox
|
||||
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: 10
|
||||
}
|
||||
clip: true
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
focus: true
|
||||
onFocusChanged: root.forceFieldFocus();
|
||||
color: Appearance.colors.colOnLayer2
|
||||
font {
|
||||
pixelSize: 10
|
||||
}
|
||||
|
||||
// Password
|
||||
enabled: !root.context.unlockInProgress
|
||||
echoMode: TextInput.Password
|
||||
inputMethodHints: Qt.ImhSensitiveData
|
||||
|
||||
// Synchronizing (across monitors) and unlocking
|
||||
onTextChanged: root.context.currentText = this.text
|
||||
onAccepted: root.context.tryUnlock()
|
||||
Connections {
|
||||
target: root.context
|
||||
function onCurrentTextChanged() {
|
||||
passwordBox.text = root.context.currentText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RippleButton {
|
||||
anchors {
|
||||
verticalCenter: passwordBoxContainer.verticalCenter
|
||||
left: passwordBoxContainer.right
|
||||
leftMargin: 5
|
||||
}
|
||||
|
||||
visible: opacity > 0
|
||||
implicitHeight: passwordBoxContainer.implicitHeight - 12
|
||||
implicitWidth: implicitHeight
|
||||
toggled: true
|
||||
buttonRadius: passwordBoxContainer.radius
|
||||
colBackground: Appearance.colors.colLayer2
|
||||
onClicked: root.context.tryUnlock()
|
||||
|
||||
contentItem: MaterialSymbol {
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
iconSize: 24
|
||||
text: "arrow_right_alt"
|
||||
color: Appearance.colors.colOnPrimary
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
auth required pam_unix.so
|
||||
@@ -14,7 +14,7 @@ Scope {
|
||||
|
||||
PanelWindow {
|
||||
id: root
|
||||
visible: (Notifications.popupList.length > 0)
|
||||
visible: (Notifications.popupList.length > 0) && !GlobalStates.screenLocked
|
||||
screen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name) ?? null
|
||||
|
||||
WlrLayershell.namespace: "quickshell:notificationPopup"
|
||||
|
||||
@@ -33,7 +33,7 @@ Scope { // Scope
|
||||
|
||||
sourceComponent: PanelWindow { // Window
|
||||
id: oskRoot
|
||||
visible: oskLoader.active
|
||||
visible: oskLoader.active && !GlobalStates.screenLocked
|
||||
|
||||
anchors {
|
||||
bottom: true
|
||||
|
||||
@@ -25,6 +25,15 @@ Scope {
|
||||
id: sessionLoader
|
||||
active: false
|
||||
|
||||
Connections {
|
||||
target: GlobalStates
|
||||
function onScreenLockedChanged() {
|
||||
if (GlobalStates.screenLocked) {
|
||||
sessionLoader.active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceComponent: PanelWindow { // Session menu
|
||||
id: sessionRoot
|
||||
visible: sessionLoader.active
|
||||
|
||||
@@ -33,5 +33,10 @@ response=$(curl "https://konachan.net/post.json?tags=rating%3Asafe&limit=1&page=
|
||||
link=$(echo "$response" | jq '.[0].file_url' -r);
|
||||
ext=$(echo "$link" | awk -F. '{print $NF}')
|
||||
downloadPath="$PICTURES_DIR/Wallpapers/konachan_random_image.$ext"
|
||||
illogicalImpulseConfigPath="$HOME/.config/illogical-impulse/config.json"
|
||||
currentWallpaperPath=$(jq -r '.background.wallpaperPath' $illogicalImpulseConfigPath)
|
||||
if [ "$downloadPath" == "$currentWallpaperPath" ]; then
|
||||
downloadPath="$PICTURES_DIR/Wallpapers/konachan_random_image-1.$ext"
|
||||
fi
|
||||
curl "$link" -o "$downloadPath"
|
||||
"$SCRIPT_DIR/switchwall.sh" --image "$downloadPath"
|
||||
|
||||
@@ -14,9 +14,8 @@ terminalscheme="$SCRIPT_DIR/terminal/scheme-base.json"
|
||||
|
||||
handle_kde_material_you_colors() {
|
||||
# Check if Qt app theming is enabled in config
|
||||
CONFIG_FILE="$XDG_CONFIG_HOME/illogical-impulse/config.json"
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
enable_qt_apps=$(jq -r '.appearance.wallpaperTheming.enableQtApps' "$CONFIG_FILE")
|
||||
if [ -f "$SHELL_CONFIG_FILE" ]; then
|
||||
enable_qt_apps=$(jq -r '.appearance.wallpaperTheming.enableQtApps' "$SHELL_CONFIG_FILE")
|
||||
if [ "$enable_qt_apps" == "false" ]; then
|
||||
return
|
||||
fi
|
||||
@@ -254,9 +253,8 @@ switch() {
|
||||
pre_process "$mode_flag"
|
||||
|
||||
# Check if app and shell theming is enabled in config
|
||||
CONFIG_FILE="$XDG_CONFIG_HOME/illogical-impulse/config.json"
|
||||
if [ -f "$CONFIG_FILE" ]; then
|
||||
enable_apps_shell=$(jq -r '.appearance.wallpaperTheming.enableAppsAndShell' "$CONFIG_FILE")
|
||||
if [ -f "$SHELL_CONFIG_FILE" ]; then
|
||||
enable_apps_shell=$(jq -r '.appearance.wallpaperTheming.enableAppsAndShell' "$SHELL_CONFIG_FILE")
|
||||
if [ "$enable_apps_shell" == "false" ]; then
|
||||
echo "App and shell theming disabled, skipping matugen and color generation"
|
||||
return
|
||||
@@ -285,7 +283,7 @@ main() {
|
||||
noswitch_flag=""
|
||||
|
||||
get_type_from_config() {
|
||||
jq -r '.appearance.palette.type' "$XDG_CONFIG_HOME/illogical-impulse/config.json" 2>/dev/null || echo "auto"
|
||||
jq -r '.appearance.palette.type' "$SHELL_CONFIG_FILE" 2>/dev/null || echo "auto"
|
||||
}
|
||||
|
||||
detect_scheme_type_from_image() {
|
||||
|
||||
@@ -47,9 +47,14 @@ Singleton {
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
|
||||
readonly property var preppedNames: list.map(a => ({
|
||||
name: Fuzzy.prepare(`${a.name} `),
|
||||
entry: a
|
||||
}))
|
||||
name: Fuzzy.prepare(`${a.name} `),
|
||||
entry: a
|
||||
}))
|
||||
|
||||
readonly property var preppedIcons: list.map(a => ({
|
||||
name: Fuzzy.prepare(`${a.icon} `),
|
||||
entry: a
|
||||
}))
|
||||
|
||||
function fuzzyQuery(search: string): var { // Idk why list<DesktopEntry> doesn't work
|
||||
if (root.sloppySearch) {
|
||||
@@ -76,12 +81,20 @@ Singleton {
|
||||
&& !iconName.includes("image-missing");
|
||||
}
|
||||
|
||||
function getReverseDomainNameAppName(str) {
|
||||
return str.split('.').slice(-1)[0].toLowerCase()
|
||||
}
|
||||
|
||||
function getKebabNormalizedAppName(str) {
|
||||
return str.toLowerCase().replace(/\s+/g, "-");
|
||||
}
|
||||
|
||||
function guessIcon(str) {
|
||||
if (!str || str.length == 0) return "image-missing";
|
||||
|
||||
// Normal substitutions
|
||||
if (substitutions[str])
|
||||
return substitutions[str];
|
||||
if (substitutions[str]) return substitutions[str];
|
||||
if (substitutions[str.toLowerCase()]) return substitutions[str.toLowerCase()];
|
||||
|
||||
// Regex substitutions
|
||||
for (let i = 0; i < regexSubstitutions.length; i++) {
|
||||
@@ -93,24 +106,37 @@ Singleton {
|
||||
if (replacedName != str) return replacedName;
|
||||
}
|
||||
|
||||
// If it gets detected normally, no need to guess
|
||||
// Icon exists -> return as is
|
||||
if (iconExists(str)) return str;
|
||||
|
||||
let guessStr = str;
|
||||
// Guess: Take only app name of reverse domain name notation
|
||||
guessStr = str.split('.').slice(-1)[0].toLowerCase();
|
||||
if (iconExists(guessStr)) return guessStr;
|
||||
// Guess: normalize to kebab case
|
||||
guessStr = str.toLowerCase().replace(/\s+/g, "-");
|
||||
if (iconExists(guessStr)) return guessStr;
|
||||
// Guess: First fuzzy desktop entry match
|
||||
const searchResults = root.fuzzyQuery(str);
|
||||
if (searchResults.length > 0) {
|
||||
const firstEntry = searchResults[0];
|
||||
guessStr = firstEntry.icon
|
||||
if (iconExists(guessStr)) return guessStr;
|
||||
|
||||
// Simple guesses
|
||||
const reverseDomainNameAppName = getReverseDomainNameAppName(str);
|
||||
if (iconExists(reverseDomainNameAppName)) return reverseDomainNameAppName;
|
||||
|
||||
const kebabNormalizedGuess = getKebabNormalizedAppName(str);
|
||||
if (iconExists(kebabNormalizedGuess)) return kebabNormalizedGuess;
|
||||
|
||||
|
||||
// Search in desktop entries
|
||||
const iconSearchResults = Fuzzy.go(str, preppedIcons, {
|
||||
all: true,
|
||||
key: "name"
|
||||
}).map(r => {
|
||||
return r.obj.entry
|
||||
});
|
||||
if (iconSearchResults.length > 0) {
|
||||
const guess = iconSearchResults[0].icon
|
||||
if (iconExists(guess)) return guess;
|
||||
}
|
||||
|
||||
const nameSearchResults = root.fuzzyQuery(str);
|
||||
if (nameSearchResults.length > 0) {
|
||||
const guess = nameSearchResults[0].icon
|
||||
if (iconExists(guess)) return guess;
|
||||
}
|
||||
|
||||
|
||||
// Give up
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ Singleton {
|
||||
property Timer timer
|
||||
|
||||
readonly property Connections conn: Connections {
|
||||
target: wrapper.notification.Component
|
||||
target: wrapper?.notification?.Component ?? root // stupid warning aaaaaaa
|
||||
|
||||
function onDestruction(): void {
|
||||
wrapper.destroy();
|
||||
|
||||
@@ -10,6 +10,7 @@ import "./modules/background/"
|
||||
import "./modules/bar/"
|
||||
import "./modules/cheatsheet/"
|
||||
import "./modules/dock/"
|
||||
import "./modules/lock/"
|
||||
import "./modules/mediaControls/"
|
||||
import "./modules/notificationPopup/"
|
||||
import "./modules/onScreenDisplay/"
|
||||
@@ -33,6 +34,7 @@ ShellRoot {
|
||||
property bool enableBackground: true
|
||||
property bool enableCheatsheet: true
|
||||
property bool enableDock: true
|
||||
property bool enableLock: true
|
||||
property bool enableMediaControls: true
|
||||
property bool enableNotificationPopup: true
|
||||
property bool enableOnScreenDisplayBrightness: true
|
||||
@@ -56,6 +58,7 @@ ShellRoot {
|
||||
LazyLoader { active: enableBackground; component: Background {} }
|
||||
LazyLoader { active: enableCheatsheet; component: Cheatsheet {} }
|
||||
LazyLoader { active: enableDock && Config.options.dock.enable; component: Dock {} }
|
||||
LazyLoader { active: enableLock; component: Lock {} }
|
||||
LazyLoader { active: enableMediaControls; component: MediaControls {} }
|
||||
LazyLoader { active: enableNotificationPopup; component: NotificationPopup {} }
|
||||
LazyLoader { active: enableOnScreenDisplayBrightness; component: OnScreenDisplayBrightness {} }
|
||||
|
||||
+3
-4
@@ -7,7 +7,7 @@ source ./scriptdata/installers
|
||||
source ./scriptdata/options
|
||||
|
||||
#####################################################################################
|
||||
if ! command -v pacman >/dev/null 2>&1; then
|
||||
if ! command -v pacman >/dev/null 2>&1; then
|
||||
printf "\e[31m[$0]: pacman not found, it seems that the system is not ArchLinux or Arch-based distros. Aborting...\e[0m\n"
|
||||
exit 1
|
||||
fi
|
||||
@@ -23,7 +23,7 @@ startask () {
|
||||
printf 'This script 1. only works for ArchLinux and Arch-based distros.\n'
|
||||
printf ' 2. does not handle system-level/hardware stuff like Nvidia drivers\n'
|
||||
printf "\e[31m"
|
||||
|
||||
|
||||
printf "Would you like to create a backup for \"$XDG_CONFIG_HOME\" and \"$HOME/.local/\" folders?\n[y/N]: "
|
||||
read -p " " backup_confirm
|
||||
case $backup_confirm in
|
||||
@@ -34,7 +34,7 @@ startask () {
|
||||
echo "Skipping backup..."
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
|
||||
printf '\n'
|
||||
printf 'Do you want to confirm every time before a command executes?\n'
|
||||
@@ -144,7 +144,6 @@ esac
|
||||
|
||||
v sudo usermod -aG video,i2c,input "$(whoami)"
|
||||
v bash -c "echo i2c-dev | sudo tee /etc/modules-load.d/i2c-dev.conf"
|
||||
v sudo pacman -S archlinux-xdg-menu && XDG_MENU_PREFIX=arch- kbuildsycoca6; sudo ln -sf /etc/xdg/menus/plasma-applications.menu /etc/xdg/menus/applications.menu
|
||||
v systemctl --user enable ydotool --now
|
||||
v sudo systemctl enable bluetooth --now
|
||||
v gsettings set org.gnome.desktop.interface font-name 'Rubik 11'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
### This file contains a list of dependencies which were previously explicitly installed that are now installed using meta packages
|
||||
### Must be one package per line as it needs to be compared against the explicitly installed list from pacman
|
||||
illogical-impulse-ags
|
||||
archlinux-xdg-menu
|
||||
axel
|
||||
bc
|
||||
coreutils
|
||||
|
||||
Reference in New Issue
Block a user