Merge branch 'end-4:main' into main

This commit is contained in:
Dignity
2025-07-19 19:18:54 +02:00
committed by GitHub
24 changed files with 230 additions and 90 deletions
+8 -9
View File
@@ -1,24 +1,23 @@
# ######### Input method ##########
# ######### Input method ##########
# See https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland
env = QT_IM_MODULE, fcitx
env = XMODIFIERS, @im=fcitx
# env = GTK_IM_MODULE, wayland # Crashes electron apps in xwayland
# env = GTK_IM_MODULE, fcitx # My Gtk apps no longer require this to work with fcitx5 hmm
env = SDL_IM_MODULE, fcitx
env = GLFW_IM_MODULE, ibus
env = INPUT_METHOD, fcitx
# ############ Wayland #############
env = ELECTRON_OZONE_PLATFORM_HINT,auto
# ############ Themes #############
env = QT_QPA_PLATFORM, wayland
env = QT_QPA_PLATFORMTHEME, kde
# env = QT_STYLE_OVERRIDE,kvantum
# env = WLR_NO_HARDWARE_CURSORS, 1
# ######## Screen tearing #########
# ######## Wayland #########
# Tearing
# env = WLR_DRM_NO_ATOMIC, 1
# ?
# env = WLR_NO_HARDWARE_CURSORS, 1
# ######## Virtual envrionment #########
env = ILLOGICAL_IMPULSE_VIRTUAL_ENV, ~/.local/state/quickshell/.venv
# ############ Others #############
+1 -1
View File
@@ -205,7 +205,7 @@ bind = Super, Return, exec, ~/.config/hypr/hyprland/scripts/launch_first_availab
bind = Super, T, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # [hidden] Kitty (terminal) (alt)
bind = Ctrl+Alt, T, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # [hidden] Kitty (for Ubuntu people)
bind = Super, E, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "dolphin" "nautilus" "nemo" "thunar" "kitty -1 fish -c yazi" # File manager
bind = Super, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "google-chrome-stable" "zen-browser" "firefox" "brave" "chromium" "microsoft-edge-stable" "opera" # Browser
bind = Super, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "google-chrome-stable" "zen-browser" "firefox" "brave" "chromium" "microsoft-edge-stable" "opera" "librewolf" # Browser
bind = Super, C, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "code" "codium" "cursor" "zed" "zedit" "zeditor" "kate" "gnome-text-editor" "emacs" "command -v nvim && kitty -1 nvim" # Code editor
bind = Super+Shift, W, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "wps" "onlyoffice-desktopeditors" # Office software
bind = Super, X, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kate" "gnome-text-editor" "emacs" # Text editor
@@ -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 Im waiting to help or anything..."
@@ -13,9 +13,9 @@ Item {
readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen)
readonly property Toplevel activeWindow: ToplevelManager.activeToplevel
property string activeWindowAddress: `0x${activeWindow.HyprlandToplevel.address}`
property string activeWindowAddress: `0x${activeWindow?.HyprlandToplevel?.address}`
property bool focusingThisMonitor: HyprlandData.activeWorkspace.monitor == monitor.name
property var biggestWindow: HyprlandData.biggestWindowForWorkspace(HyprlandData.monitors[root.monitor.id].activeWorkspace.id)
property var biggestWindow: HyprlandData.biggestWindowForWorkspace(HyprlandData.monitors[root.monitor.id]?.activeWorkspace.id)
implicitWidth: colLayout.implicitWidth
@@ -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
@@ -53,7 +53,7 @@ Item { // Notification group area
onFinished: () => {
root.notifications.forEach((notif) => {
Qt.callLater(() => {
Notifications.discardNotification(notif.id);
Notifications.discardNotification(notif.notificationId);
});
});
}
@@ -70,7 +70,7 @@ Item { // Notification item area
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
}
onFinished: () => {
Notifications.discardNotification(notificationObject.id);
Notifications.discardNotification(notificationObject.notificationId);
}
}
@@ -208,7 +208,7 @@ Item { // Notification item area
elide: Text.ElideRight
textFormat: Text.RichText
text: {
return `<style>img{max-width:${notificationBodyText.width}px;}</style>` +
return `<style>img{max-width:${300 /* binding to notificationBodyText.width would cause a binding loop */}px;}</style>` +
`${processNotificationBody(notificationObject.body, notificationObject.appName || notificationObject.summary).replace(/\n/g, "<br/>")}`
}
@@ -269,7 +269,7 @@ Item { // Notification item area
buttonText: modelData.text
urgency: notificationObject.urgency
onClicked: {
Notifications.attemptInvokeAction(notificationObject.id, modelData.identifier);
Notifications.attemptInvokeAction(notificationObject.notificationId, modelData.identifier);
}
}
}
@@ -199,11 +199,13 @@ Item {
onExited: hovered = false // For hover color change
acceptedButtons: Qt.LeftButton | Qt.MiddleButton
drag.target: parent
onPressed: {
onPressed: (mouse) => {
root.draggingFromWorkspace = windowData?.workspace.id
window.pressed = true
window.Drag.active = true
window.Drag.source = window
window.Drag.hotSpot.x = mouse.x
window.Drag.hotSpot.y = mouse.y
// console.log(`[OverviewWindow] Dragging window ${windowData?.address} from position (${window.x}, ${window.y})`)
}
onReleased: {
@@ -14,7 +14,7 @@ RippleButton {
property var entry
property string query
property bool entryShown: entry?.shown ?? true
property string itemType: entry?.type
property string itemType: entry?.type ?? Translation.tr("App")
property string itemName: entry?.name
property string itemIcon: entry?.icon ?? ""
property var itemExecute: entry?.execute
@@ -221,5 +221,47 @@ RippleButton {
horizontalAlignment: Text.AlignRight
text: root.itemClickActionName
}
RowLayout {
spacing: 4
Repeater {
model: (root.entry.actions ?? []).slice(0, 4)
delegate: RippleButton {
id: actionButton
required property var modelData
implicitHeight: 34
implicitWidth: 34
contentItem: Item {
id: actionContentItem
anchors.centerIn: parent
Loader {
anchors.centerIn: parent
active: !(actionButton.modelData.icon && actionButton.modelData.icon !== "")
sourceComponent: MaterialSymbol {
text: "video_settings"
font.pixelSize: Appearance.font.pixelSize.hugeass
color: Appearance.m3colors.m3onSurface
}
}
Loader {
anchors.centerIn: parent
active: actionButton.modelData.icon && actionButton.modelData.icon !== ""
sourceComponent: IconImage {
source: Quickshell.iconPath(actionButton.modelData.icon)
implicitSize: 20
}
}
}
onClicked: modelData.execute()
StyledToolTip {
content: modelData.name
}
}
}
}
}
}
@@ -294,8 +294,17 @@ Item { // Wrapper
clickActionName: "",
type: `#${entry.match(/^\s*(\S+)/)?.[1] || ""}`,
execute: () => {
Quickshell.execDetached(["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(entry)}' | cliphist decode | wl-copy`]);
}
Cliphist.copy(entry)
},
actions: [
{
name: "Delete",
icon: "delete",
execute: () => {
Cliphist.deleteEntry(entry);
}
}
]
};
}).filter(Boolean);
}
@@ -15,6 +15,12 @@ Scope {
id: root
property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name)
function closeAllWindows() {
HyprlandData.windowList.map(w => w.pid).forEach((pid) => {
Quickshell.execDetached(["kill", pid]);
});
}
Loader {
id: sessionLoader
active: false
@@ -111,7 +117,7 @@ Scope {
id: sessionLogout
buttonIcon: "logout"
buttonText: Translation.tr("Logout")
onClicked: { Quickshell.execDetached(["pkill", "Hyprland"]); sessionRoot.hide() }
onClicked: { root.closeAllWindows(); Quickshell.execDetached(["pkill", "Hyprland"]); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionSleep
KeyNavigation.right: sessionTaskManager
@@ -140,7 +146,7 @@ Scope {
id: sessionShutdown
buttonIcon: "power_settings_new"
buttonText: Translation.tr("Shutdown")
onClicked: { Quickshell.execDetached(["bash", "-c", `systemctl poweroff || loginctl poweroff`]); sessionRoot.hide() }
onClicked: { root.closeAllWindows(); Quickshell.execDetached(["bash", "-c", `systemctl poweroff || loginctl poweroff`]); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionHibernate
KeyNavigation.right: sessionReboot
@@ -150,7 +156,7 @@ Scope {
id: sessionReboot
buttonIcon: "restart_alt"
buttonText: Translation.tr("Reboot")
onClicked: { Quickshell.execDetached(["bash", "-c", `reboot || loginctl reboot`]); sessionRoot.hide() }
onClicked: { root.closeAllWindows(); Quickshell.execDetached(["bash", "-c", `reboot || loginctl reboot`]); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.left: sessionShutdown
KeyNavigation.right: sessionFirmwareReboot
@@ -160,7 +166,7 @@ Scope {
id: sessionFirmwareReboot
buttonIcon: "settings_applications"
buttonText: Translation.tr("Reboot to firmware settings")
onClicked: { Quickshell.execDetached(["bash", "-c", `systemctl reboot --firmware-setup || loginctl reboot --firmware-setup`]); sessionRoot.hide() }
onClicked: { root.closeAllWindows(); Quickshell.execDetached(["bash", "-c", `systemctl reboot --firmware-setup || loginctl reboot --firmware-setup`]); sessionRoot.hide() }
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
KeyNavigation.up: sessionTaskManager
KeyNavigation.left: sessionReboot
@@ -176,8 +176,8 @@ Scope {
NightLight {}
GameMode {}
IdleInhibitor {}
CloudflareWarp {}
EasyEffectsToggle {}
CloudflareWarp {}
}
// Center widget group
@@ -1,4 +1,3 @@
import qs.modules.common
import qs.modules.common.widgets
import qs
import Quickshell.Io
+1 -1
View File
@@ -7,11 +7,11 @@
pragma ComponentBehavior: "Bound"
import qs
import qs.services
import qs.modules.common
import qs.modules.common.widgets
import qs.modules.common.functions
import QtQuick
import QtQuick.Effects
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
@@ -11,7 +11,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
mkdir -p ~/Pictures/Wallpapers
page=$((1 + RANDOM % 1000));
response=$(curl "https://konachan.com/post.json?tags=rating%3Asafe&limit=1&page=$page")
response=$(curl "https://konachan.net/post.json?tags=rating%3Asafe&limit=1&page=$page")
link=$(echo "$response" | jq '.[0].file_url' -r);
ext=$(echo "$link" | awk -F. '{print $NF}')
downloadPath="$HOME/Pictures/Wallpapers/konachan_random_image-0.$ext"
+45 -19
View File
@@ -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;
}
+4 -4
View File
@@ -58,8 +58,8 @@ Singleton {
},
"konachan": {
"name": "Konachan",
"url": "https://konachan.com",
"api": "https://konachan.com/post.json",
"url": "https://konachan.net",
"api": "https://konachan.net/post.json",
"description": Translation.tr("For desktop wallpapers | Good quality"),
"mapFunc": (response) => {
return response.map(item => {
@@ -80,7 +80,7 @@ Singleton {
}
})
},
"tagSearchTemplate": "https://konachan.com/tag.json?order=count&name={{query}}*",
"tagSearchTemplate": "https://konachan.net/tag.json?order=count&name={{query}}*",
"tagMapFunc": (response) => {
return response.map(item => {
return {
@@ -360,7 +360,7 @@ Singleton {
function makeRequest(tags, nsfw=false, limit=20, page=1) {
var url = constructRequestUrl(tags, nsfw, limit, page)
// console.log("[Booru] Making request to " + url)
console.log("[Booru] Making request to " + url)
const newResponse = root.booruResponseDataComponent.createObject(null, {
"provider": currentProvider,
@@ -4,7 +4,6 @@ pragma ComponentBehavior: Bound
// From https://github.com/caelestia-dots/shell/ (`quickshell` branch) with modifications.
// License: GPLv3
import qs
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
+23 -1
View File
@@ -4,7 +4,7 @@ pragma ComponentBehavior: Bound
import "root:/modules/common/functions/fuzzysort.js" as Fuzzy
import "root:/modules/common/functions/levendist.js" as Levendist
import qs.modules.common
import qs
import qs.modules.common.functions
import QtQuick
import Quickshell
import Quickshell.Io
@@ -42,6 +42,28 @@ Singleton {
readProc.running = true
}
function copy(entry) {
Quickshell.execDetached(["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(entry)}' | cliphist decode | wl-copy`]);
}
Process {
id: deleteProc
property string entry: ""
command: ["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(deleteProc.entry)}' | cliphist delete`]
function deleteEntry(entry) {
deleteProc.entry = entry;
deleteProc.running = true;
deleteProc.entry = "";
}
onExited: (exitCode, exitStatus) => {
root.refresh();
}
}
function deleteEntry(entry) {
deleteProc.deleteEntry(entry);
}
Connections {
target: Quickshell
function onClipboardTextChanged() {
@@ -17,7 +17,8 @@ import Quickshell.Services.Notifications
Singleton {
id: root
component Notif: QtObject {
required property int id
id: wrapper
required property int notificationId // Could just be `id` but it conflicts with the default prop in QtObject
property Notification notification
property list<var> actions: notification?.actions.map((action) => ({
"identifier": action.identifier,
@@ -32,11 +33,19 @@ Singleton {
property double time
property string urgency: notification?.urgency.toString() ?? "normal"
property Timer timer
readonly property Connections conn: Connections {
target: wrapper?.notification?.Component ?? root // stupid warning aaaaaaa
function onDestruction(): void {
wrapper.destroy();
}
}
}
function notifToJSON(notif) {
return {
"id": notif.id,
"notificationId": notif.notificationId,
"actions": notif.actions,
"appIcon": notif.appIcon,
"appName": notif.appName,
@@ -52,11 +61,11 @@ Singleton {
}
component NotifTimer: Timer {
required property int id
required property int notificationId
interval: 5000
running: true
onTriggered: () => {
root.timeoutNotification(id);
root.timeoutNotification(notificationId);
destroy()
}
}
@@ -130,7 +139,7 @@ Singleton {
property int idOffset
signal initDone();
signal notify(notification: var);
signal discard(id: var);
signal discard(id: int);
signal discardAll();
signal timeout(id: var);
@@ -149,7 +158,7 @@ Singleton {
onNotification: (notification) => {
notification.tracked = true
const newNotifObject = notifComponent.createObject(root, {
"id": notification.id + root.idOffset,
"notificationId": notification.id + root.idOffset,
"notification": notification,
"time": Date.now(),
});
@@ -159,7 +168,7 @@ Singleton {
if (!root.popupInhibited) {
newNotifObject.popup = true;
newNotifObject.timer = notifTimerComponent.createObject(root, {
"id": newNotifObject.id,
"notificationId": newNotifObject.notificationId,
"interval": notification.expireTimeout < 0 ? 5000 : notification.expireTimeout,
});
}
@@ -171,7 +180,8 @@ Singleton {
}
function discardNotification(id) {
const index = root.list.findIndex((notif) => notif.id === id);
console.log("[Notifications] Discarding notification with ID: " + id);
const index = root.list.findIndex((notif) => notif.notificationId === id);
const notifServerIndex = notifServer.trackedNotifications.values.findIndex((notif) => notif.id + root.idOffset === id);
if (index !== -1) {
root.list.splice(index, 1);
@@ -181,7 +191,7 @@ Singleton {
if (notifServerIndex !== -1) {
notifServer.trackedNotifications.values[notifServerIndex].dismiss()
}
root.discard(id);
root.discard(id); // Emit signal
}
function discardAllNotifications() {
@@ -195,7 +205,7 @@ Singleton {
}
function timeoutNotification(id) {
const index = root.list.findIndex((notif) => notif.id === id);
const index = root.list.findIndex((notif) => notif.notificationId === id);
if (root.list[index] != null)
root.list[index].popup = false;
root.timeout(id);
@@ -203,7 +213,7 @@ Singleton {
function timeoutAll() {
root.popupList.forEach((notif) => {
root.timeout(notif.id);
root.timeout(notif.notificationId);
})
root.popupList.forEach((notif) => {
notif.popup = false;
@@ -211,10 +221,13 @@ Singleton {
}
function attemptInvokeAction(id, notifIdentifier) {
console.log("[Notifications] Attempting to invoke action with identifier: " + notifIdentifier + " for notification ID: " + id);
const notifServerIndex = notifServer.trackedNotifications.values.findIndex((notif) => notif.id + root.idOffset === id);
console.log("Notification server index: " + notifServerIndex);
if (notifServerIndex !== -1) {
const notifServerNotif = notifServer.trackedNotifications.values[notifServerIndex];
const action = notifServerNotif.actions.find((action) => action.identifier === notifIdentifier);
console.log("Action found: " + JSON.stringify(action));
action.invoke()
}
else {
@@ -242,7 +255,7 @@ Singleton {
const fileContents = notifFileView.text()
root.list = JSON.parse(fileContents).map((notif) => {
return notifComponent.createObject(root, {
"id": notif.id,
"notificationId": notif.notificationId,
"actions": [], // Notification actions are meaningless if they're not tracked by the server or the sender is dead
"appIcon": notif.appIcon,
"appName": notif.appName,
@@ -253,10 +266,10 @@ Singleton {
"urgency": notif.urgency,
});
});
// Find largest id
// Find largest notificationId
let maxId = 0
root.list.forEach((notif) => {
maxId = Math.max(maxId, notif.id)
maxId = Math.max(maxId, notif.notificationId)
})
console.log("[Notifications] File loaded")
+4 -4
View File
@@ -7,18 +7,18 @@
{
"label" : "hibernate",
"action" : "systemctl hibernate || loginctl hibernate",
"text" : "save",
"text" : "downloading",
"keybind" : "h"
}
{
"label" : "logout",
"action" : "pkill Hyprland || pkill sway || pkill niri || loginctl terminate-user $USER",
"action" : "hyprctl clients -j | jq -r '.[].pid' | xargs kill; pkill Hyprland || pkill sway || pkill niri || loginctl terminate-user $USER",
"text" : "logout",
"keybind" : "e"
}
{
"label" : "shutdown",
"action" : "systemctl poweroff || loginctl poweroff",
"action" : "hyprctl clients -j | jq -r '.[].pid' | xargs kill; systemctl poweroff || loginctl poweroff",
"text" : "power_settings_new",
"keybind" : "s"
}
@@ -30,7 +30,7 @@
}
{
"label" : "reboot",
"action" : "systemctl reboot || loginctl reboot",
"action" : "hyprctl clients -j | jq -r '.[].pid' | xargs kill; systemctl reboot || loginctl reboot",
"text" : "restart_alt",
"keybind" : "r"
}
+9
View File
@@ -1,4 +1,13 @@
# Contributing
- Please understand that dotfiles are after all personal. I can accept features I do not personally want, but in that case I will ask you to make it configurable/optionally loaded
- If you add new stuff, it's a good idea to ask me first to not waste your work
- Please make multiple PRs if you have many features
# Technical steps
_Complete steps, might not be necessary depending on what you change_
- Install the dotfiles (if you don't wanna replace your stuff completely, do it on a new user)
- For Quickshell: `touch ~/.config/quickshell/ii/.qmlls.ini` for proper LSP support
- Make changes, copy changes to a fork, PR
+5 -18
View File
@@ -26,25 +26,12 @@
- **Transparent installation**: Every command is shown before it's run
</details>
<details>
<summary>Instructions</summary>
<summary>Installation instructions</summary>
- **Prerequisite**: Your system works. That's it. You don't have to reinstall your system!
- **Automatic**, but guided and transparent, installation for Arch(-based) Linux:
```bash
bash <(curl -s "https://end-4.github.io/dots-hyprland-wiki/setup.sh")
```
If you are using fish shell (non-posix-compliant shell) then:
```bash
bash -c "$(curl -s https://end-4.github.io/dots-hyprland-wiki/setup.sh)"
```
- **Manual** installation, other distros and more:
- See the [Wiki](https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/01setup/)
- **Default keybinds**: Should be somewhat familiar if you've used Windows or GNOME.
- For a list, hit `Super`+`/`
- For a terminal, hit `Super`+`Enter`
- See the [Wiki](https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/01setup/)
- **Default keybinds**: Should be somewhat familiar to Windows or GNOME users.
- `Super`+`/` = keybind list
- `Super`+`Enter` = terminal
</details>