forked from Shinonome/dots-hyprland
Merge branch 'end-4:main' into main
This commit is contained in:
@@ -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 #############
|
||||
|
||||
|
||||
@@ -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 I’m 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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user