Merge branch 'end-4:main' into feat/sticky

This commit is contained in:
Marepalli Santhosh
2025-11-09 11:44:33 +05:30
committed by GitHub
36 changed files with 931 additions and 105 deletions
+1 -1
View File
@@ -4,7 +4,7 @@ labels: ["ISSUE"]
body:
- type: markdown
attributes:
value: "**Welcome to submit a new issue!**\n- Please search in [existing issues](https://github.com/end-4/dots-hyprland/issues?q=is%3Aissue) before continue.\n- It takes only 3 steps, so please be patient :)\n- Tip: If your issue is not a feature request, and it does not fit into the following form, for example \"how can I edit some widget\", please use [Discussions](https://github.com/end-4/dots-hyprland/discussions) instead."
value: "**Welcome to submit a new issue!**\n- Please search in [existing issues](https://github.com/end-4/dots-hyprland/issues?q=is%3Aissue) before continue.\n- It takes only 3 steps, so please be patient :)\n- NOTE 1: If your issue is not a feature request, and it does not fit into the following form, for example \"how can I edit some widget\", please use [Discussions](https://github.com/end-4/dots-hyprland/discussions) instead.\n- NOTE 2: If your problem is distro specific and you do not use Arch(-based) distros, plesae submit [Discussion at Extra Distros](https://github.com/end-4/dots-hyprland/discussions/new?category=extra-distros) instead."
- type: checkboxes
attributes:
label: "Step 1. Before you submit"
@@ -0,0 +1,30 @@
# Bar, wallpaper
exec-once = ~/.config/hypr/hyprland/scripts/start_geoclue_agent.sh
exec-once = qs -c $qsConfig &
# Input method
# exec-once = fcitx5
# Core components (authentication, lock screen, notification daemon)
exec-once = gnome-keyring-daemon --start --components=secrets
exec-once = hypridle
exec-once = dbus-update-activation-environment --all
exec-once = sleep 1 && dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # Some fix idk
exec-once = hyprpm reload
# Audio
exec-once = easyeffects --gapplication-service
# Clipboard: history
# exec-once = wl-paste --watch cliphist store &
exec-once = wl-paste --type text --watch bash -c 'cliphist store && qs -c $qsConfig ipc call cliphistService update'
exec-once = wl-paste --type image --watch bash -c 'cliphist store && qs -c $qsConfig ipc call cliphistService update'
# Cursor
exec-once = hyprctl setcursor Bibata-Modern-Classic 24
# Fix dock pinned apps not launching properly (https://github.com/end-4/dots-hyprland/issues/2200)
exec-once = sleep 3.5 && hyprctl reload && sleep 0.5 && touch ~/.config/quickshell/ii/shell.qml
# For fedora to setup polkit
exec-once = /usr/libexec/kf6/polkit-kde-authentication-agent-1
@@ -58,7 +58,7 @@ Item {
property var keyBlacklist: ["Super_L"]
property var keySubstitutions: Object.assign({
"Super": "󰖳",
"Super": "",
"mouse_up": "Scroll ↓", // ikr, weird
"mouse_down": "Scroll ↑", // trust me bro
"mouse:272": "LMB",
@@ -272,7 +272,7 @@ Singleton {
// 0: 󰖳 | 1: 󰌽 | 2: 󰘳 | 3:  | 4: 󰨡
// 5:  | 6:  | 7: 󰣇 | 8:  | 9: 
// 10:  | 11:  | 12:  | 13:  | 14: 󱄛
property string superKey: "󰖳"
property string superKey: ""
property bool useMacSymbol: false
property bool splitButtons: true
property bool useMouseSymbol: false
@@ -84,20 +84,26 @@ Singleton {
property JsonObject crosshair: JsonObject {
property bool pinned: false
property bool clickthrough: true
property real x: 835
property real y: 483
property real x: 827
property real y: 441
property real width: 250
property real height: 100
}
property JsonObject recorder: JsonObject {
property bool pinned: false
property bool clickthrough: false
property real x: 80
property real y: 80
property real width: 350
property real height: 130
}
property JsonObject resources: JsonObject {
property bool pinned: false
property bool clickthrough: true
property real x: 1500
property real y: 770
property real width: 350
property real height: 200
property int tabIndex: 0
}
property JsonObject volumeMixer: JsonObject {
@@ -105,6 +111,8 @@ Singleton {
property bool clickthrough: false
property real x: 80
property real y: 280
property real width: 350
property real height: 600
property int tabIndex: 0
}
property JsonObject fpsLimiter: JsonObject {
@@ -112,6 +120,8 @@ Singleton {
property bool clickthrough: false
property real x: 1576
property real y: 630
property real width: 280
property real height: 80
}
property JsonObject stickypad: JsonObject {
property bool pinned: true
@@ -0,0 +1,15 @@
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Controls
import qs.modules.common
ComboBox {
id: root
Material.theme: Material.System
Material.accent: Appearance.m3colors.m3primary
Material.primary: Appearance.m3colors.m3primary
Material.background: Appearance.m3colors.m3surface
Material.foreground: Appearance.m3colors.m3onSurface
Material.containerStyle: Material.Outlined
}
@@ -12,7 +12,7 @@ import Quickshell.Widgets
* It doesn't exactly match the spec because it does not make sense to have stuff on a computer that fucking huge.
* Should be at 3/4 scale...
*/
Slider {
id: root
@@ -8,6 +8,8 @@ import qs.modules.common
MouseArea {
id: root
property alias animateXPos: xBehavior.enabled
property alias animateYPos: yBehavior.enabled
property bool draggable: true
drag.target: draggable ? root : undefined
cursorShape: (draggable && containsPress) ? Qt.ClosedHandCursor : draggable ? Qt.OpenHandCursor : Qt.ArrowCursor
@@ -18,9 +20,11 @@ MouseArea {
}
Behavior on x {
id: xBehavior
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
}
Behavior on y {
id: yBehavior
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
}
}
@@ -13,29 +13,67 @@ import qs.modules.common.widgets.widgetCanvas
* To make an overlay widget:
* 1. Create a modules/overlay/<yourWidget>/<YourWidget>.qml, using this as the base class and declare your widget content as contentItem
* 2. Add an entry to OverlayContext.availableWidgets with identifier=<yourWidgetIdentifier>
* 3. Add an entry in Persistent.states.overlay.<yourWidgetIdentifier> with x, y, pinned, clickthrough properties set to reasonable defaults
* 3. Add an entry in Persistent.states.overlay.<yourWidgetIdentifier> with x, y, width, height, pinned, clickthrough properties set to reasonable defaults
* 4. Add an entry in OverlayWidgetDelegateChooser with roleValue=<yourWidgetIdentifier> and Declare your widget in there
* Use existing entries as reference.
*/
AbstractOverlayWidget {
id: root
// To be defined by subclasses
required property Item contentItem
property bool fancyBorders: true
property bool showCenterButton: false
property bool showClickabilityButton: true
// Defaults n stuff
required property var modelData
readonly property string identifier: modelData.identifier
readonly property string materialSymbol: modelData.materialSymbol ?? "widgets"
property string title: identifier.replace(/([A-Z])/g, " $1").replace(/^./, function(str){ return str.toUpperCase(); })
property var persistentStateEntry: Persistent.states.overlay[identifier]
property real radius: Appearance.rounding.windowRounding
property real minWidth: 250
property real minimumWidth: 250
property real minimumHeight: 100
property real resizeMargin: 8
property real padding: 6
property real contentRadius: radius - padding
// Resizing
function getXResizeDirection(x) {
return (x < root.resizeMargin) ? -1 : (x > root.width - root.resizeMargin) ? 1 : 0
}
function getYResizeDirection(y) {
return (y < root.resizeMargin) ? -1 : (y > root.height - root.resizeMargin) ? 1 : 0
}
hoverEnabled: true
property bool resizable: true
property bool resizing: false
property int resizeXDirection: getXResizeDirection(mouseX)
property int resizeYDirection: getYResizeDirection(mouseY)
draggable: GlobalStates.overlayOpen
drag.target: undefined
animateXPos: !dragHandler.active
animateYPos: !dragHandler.active
z: dragHandler.active ? 2 : 1
cursorShape: {
if (dragHandler.active) return root.resizing ? cursorShape : Qt.ArrowCursor;
if (resizeMargin < mouseX && mouseX < width - resizeMargin &&
resizeMargin < mouseY && mouseY < height - resizeMargin) {
return Qt.ArrowCursor;
} else {
if (!root.resizable) return Qt.ArrowCursor;
const dragIsLeft = mouseX < width / 2
const dragIsTop = mouseY < height / 2
if ((dragIsLeft && dragIsTop) || (!dragIsLeft && !dragIsTop)) {
return Qt.SizeFDiagCursor
} else {
return Qt.SizeBDiagCursor
}
}
}
// Positioning & sizing
x: Math.round(persistentStateEntry.x) // Round or it'll be blurry
y: Math.round(persistentStateEntry.y) // Round or it'll be blurry
pinned: persistentStateEntry.pinned
@@ -68,7 +106,52 @@ AbstractOverlayWidget {
}
// Hooks
onReleased: savePosition();
onPressed: (event) => {
// We're only interested in handling resize here
// Early returns
if (!root.resizable) return;
if (root.resizeMargin < event.x && event.x < root.width - root.resizeMargin &&
root.resizeMargin < event.y && event.y < root.height - root.resizeMargin) {
return;
}
// Resizing setup
root.resizing = true;
root.resizeXDirection = getXResizeDirection(event.x);
root.resizeYDirection = getYResizeDirection(event.y);
if (root.resizeYDirection !== 0 && root.resizeXDirection === 0) {
root.resizeXDirection = event.x < root.width / 2 ? -1 : 1;
} else if (root.resizeXDirection !== 0 && root.resizeYDirection === 0) {
root.resizeYDirection = event.y < root.height / 2 ? -1 : 1;
}
}
onPositionChanged: (event) => {
if (!resizing) return;
contentContainer.implicitWidth = Math.max(root.persistentStateEntry.width + dragHandler.xAxis.activeValue * root.resizeXDirection, root.minimumWidth);
contentContainer.implicitHeight = Math.max(root.persistentStateEntry.height + dragHandler.yAxis.activeValue * root.resizeYDirection, root.minimumHeight);
const negativeXDrag = root.resizeXDirection === -1;
const negativeYDrag = root.resizeYDirection === -1;
const wantedX = root.persistentStateEntry.x + (negativeXDrag ? dragHandler.xAxis.activeValue : 0)
const wantedY = root.persistentStateEntry.y + (negativeYDrag ? dragHandler.yAxis.activeValue : 0)
const negativeXDragLimit = root.persistentStateEntry.x + root.persistentStateEntry.width - contentContainer.implicitWidth;
const negativeYDragLimit = root.persistentStateEntry.y + root.persistentStateEntry.height - contentContainer.implicitHeight;
root.x = negativeXDrag ? Math.min(wantedX, negativeXDragLimit) : wantedX;
root.y = negativeYDrag ? Math.min(wantedY, negativeYDragLimit) : wantedY;
}
DragHandler {
id: dragHandler
acceptedButtons: Qt.LeftButton | Qt.RightButton
target: (root.draggable && !root.resizing) ? root : null
onActiveChanged: { // Handle drag release
if (!active) {
root.resizing = false;
root.savePosition();
}
}
xAxis.minimum: 0
xAxis.maximum: root.parent?.width - root.width
yAxis.minimum: 0
yAxis.maximum: root.parent?.height - root.height
}
function close() {
Persistent.states.overlay.open = Persistent.states.overlay.open.filter(type => type !== root.identifier);
@@ -82,35 +165,36 @@ AbstractOverlayWidget {
persistentStateEntry.clickthrough = !persistentStateEntry.clickthrough;
}
function savePosition(xPos = root.x, yPos = root.y) {
persistentStateEntry.x = xPos;
persistentStateEntry.y = yPos;
function savePosition(xPos = root.x, yPos = root.y, width = contentContainer.implicitWidth, height = contentContainer.implicitHeight) {
persistentStateEntry.x = Math.round(xPos);
persistentStateEntry.y = Math.round(yPos);
persistentStateEntry.width = Math.round(width);
persistentStateEntry.height = Math.round(height);
}
function center() {
const targetX = (root.parent.width - contentColumn.width) / 2
const targetY = (root.parent.height - contentItem.height) / 2 - titleBar.implicitHeight + border.border.width
const targetX = (root.parent.width - contentColumn.width) / 2 - root.resizeMargin
const targetY = (root.parent.height - contentContainer.height) / 2 - titleBar.implicitHeight + border.border.width - root.resizeMargin
root.x = targetX
root.y = targetY
root.savePosition(targetX, targetY)
}
visible: GlobalStates.overlayOpen || actuallyPinned
implicitWidth: Math.max(contentColumn.implicitWidth, minWidth)
implicitHeight: contentColumn.implicitHeight
implicitWidth: contentColumn.implicitWidth + resizeMargin * 2
implicitHeight: contentColumn.implicitHeight + resizeMargin * 2
Rectangle {
id: border
anchors.fill: parent
color: (root.fancyBorders && GlobalStates.overlayOpen) ? Appearance.colors.colLayer1 : "transparent"
anchors {
fill: parent
margins: root.resizeMargin
}
color: ColorUtils.transparentize(Appearance.colors.colLayer1, (root.fancyBorders && GlobalStates.overlayOpen) ? 0 : 1)
radius: root.radius
border.color: ColorUtils.transparentize(Appearance.colors.colOutlineVariant, GlobalStates.overlayOpen ? 0 : 1)
border.width: 1
Behavior on color {
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
}
layer.enabled: GlobalStates.overlayOpen
layer.effect: OpacityMask {
maskSource: Rectangle {
@@ -205,8 +289,8 @@ AbstractOverlayWidget {
Layout.margins: root.fancyBorders ? root.padding : 0
Layout.topMargin: -border.border.width // Border of a rectangle is drawn inside its bounds, so we do this to make the gap not too big
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
implicitWidth: root.contentItem.implicitWidth
implicitHeight: root.contentItem.implicitHeight
implicitWidth: Math.max(root.persistentStateEntry.width, root.minimumWidth)
implicitHeight: Math.max(root.persistentStateEntry.height, root.minimumHeight)
children: [root.contentItem]
}
}
@@ -11,6 +11,7 @@ StyledOverlayWidget {
opacity: 1 // The crosshair itself already has transparency if configured
showClickabilityButton: false
clickthrough: true
resizable: false
contentItem: CrosshairContent {
anchors.centerIn: parent
@@ -6,6 +6,8 @@ import qs.modules.overlay
StyledOverlayWidget {
id: root
title: "MangoHud FPS"
minimumWidth: 275
minimumHeight: 100
contentItem: FpsLimiterContent {
radius: root.contentRadius
}
@@ -9,25 +9,22 @@ import qs.modules.overlay
StyledOverlayWidget {
id: root
minimumWidth: 310
minimumHeight: 130
contentItem: Rectangle {
id: contentItem
anchors.centerIn: parent
anchors.fill: parent
radius: root.contentRadius
color: Appearance.m3colors.m3surfaceContainer
property real padding: 8
implicitHeight: contentColumn.implicitHeight + padding * 2
implicitWidth: 350
ColumnLayout {
id: contentColumn
anchors {
fill: parent
margins: parent.padding
}
anchors.centerIn: parent
spacing: 10
Row {
Layout.alignment: Qt.AlignHCenter
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
spacing: 10
BigRecorderButton {
@@ -68,7 +65,7 @@ StyledOverlayWidget {
}
RippleButton {
Layout.alignment: Qt.AlignHCenter
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.fillWidth: false
buttonRadius: height / 2
colBackground: Appearance.colors.colLayer3
@@ -14,6 +14,8 @@ import qs.modules.overlay
StyledOverlayWidget {
id: root
minimumWidth: 300
minimumHeight: 200
property list<var> resources: [
{
"icon": "planner_review",
@@ -37,13 +39,10 @@ StyledOverlayWidget {
contentItem: Rectangle {
id: contentItem
anchors.centerIn: parent
anchors.fill: parent
color: Appearance.m3colors.m3surfaceContainer
radius: root.contentRadius
property real padding: 4
implicitWidth: 350
implicitHeight: 200
// implicitHeight: contentColumn.implicitHeight + padding * 2
ColumnLayout {
id: contentColumn
anchors {
@@ -10,13 +10,14 @@ import qs.modules.sidebarRight.volumeMixer
StyledOverlayWidget {
id: root
minimumWidth: 300
minimumHeight: 380
contentItem: Rectangle {
anchors.centerIn: parent
anchors.fill: parent
color: Appearance.m3colors.m3surfaceContainer
radius: root.contentRadius
property real padding: 6
implicitHeight: 600
implicitWidth: 350
ColumnLayout {
id: contentColumn
@@ -11,21 +11,22 @@ import Quickshell.Services.Pipewire
WindowDialog {
id: root
property bool isSink: true
backgroundHeight: 700
backgroundHeight: 600
WindowDialogTitle {
text: root.isSink ? Translation.tr("Audio output") : Translation.tr("Audio input")
}
VolumeDialogContent {
isSink: root.isSink
}
WindowDialogSeparator {
Layout.topMargin: -22
Layout.leftMargin: 0
Layout.rightMargin: 0
}
VolumeDialogContent {
isSink: root.isSink
}
WindowDialogButtonRow {
DialogButton {
buttonText: Translation.tr("Details")
@@ -16,25 +16,15 @@ ColumnLayout {
readonly property list<var> appPwNodes: Pipewire.nodes.values.filter((node) => { // Should be list<PwNode> but it breaks ScriptModel
return root.correctType(node) && node.isStream
})
readonly property list<var> devices: Pipewire.nodes.values.filter(node => {
return root.correctType(node) && !node.isStream
})
readonly property bool hasApps: appPwNodes.length > 0
spacing: 16
WindowDialogSectionHeader {
visible: root.hasApps
text: Translation.tr("Applications")
}
WindowDialogSeparator {
visible: root.hasApps
Layout.topMargin: -22
Layout.leftMargin: 0
Layout.rightMargin: 0
color: Appearance.colors.colOutlineVariant
}
DialogSectionListView {
visible: root.hasApps
Layout.fillHeight: true
topMargin: 14
model: ScriptModel {
values: root.appPwNodes
@@ -49,44 +39,26 @@ ColumnLayout {
}
}
WindowDialogSectionHeader {
text: Translation.tr("Devices")
}
WindowDialogSeparator {
Layout.topMargin: -22
Layout.leftMargin: 0
Layout.rightMargin: 0
color: Appearance.colors.colOutlineVariant
}
DialogSectionListView {
Layout.fillHeight: !root.hasApps
Layout.preferredHeight: 180
model: ScriptModel {
values: Pipewire.nodes.values.filter(node => {
return root.correctType(node) && !node.isStream
})
}
delegate: StyledRadioButton {
id: radioButton
required property var modelData
anchors {
left: parent?.left
right: parent?.right
StyledComboBox {
id: deviceSelector
Layout.fillHeight: false
Layout.fillWidth: true
Layout.bottomMargin: 6
model: root.devices.map(node => node.description)
currentIndex: root.devices.findIndex(item => {
if (root.isSink) {
return item.id === Pipewire.preferredDefaultAudioSink?.id
} else {
return item.id === Pipewire.preferredDefaultAudioSource?.id
}
description: modelData.description
checked: modelData.id === (root.isSink ? Pipewire.preferredDefaultAudioSink?.id : Pipewire.preferredDefaultAudioSource?.id)
onCheckedChanged: {
if (!checked) return;
if (root.isSink) {
Pipewire.preferredDefaultAudioSink = modelData
} else {
Pipewire.preferredDefaultAudioSource = modelData
}
})
onActivated: (index) => {
print(index)
const item = root.devices[index]
if (root.isSink) {
Pipewire.preferredDefaultAudioSink = item
} else {
Pipewire.preferredDefaultAudioSource = item
}
}
}
@@ -106,4 +78,9 @@ ColumnLayout {
spacing: 4
animateAppearance: false
}
Component {
id: listElementComp
ListElement {}
}
}
@@ -146,14 +146,14 @@ Singleton {
// Thumbnail generation
function generateThumbnail(size: string) {
// console.log("[Wallpapers] Updating thumbnails")
if (!["normal", "large", "x-large", "xx-large"].includes(size)) throw new Error("Invalid thumbnail size");
thumbgenProc.directory = root.directory
thumbgenProc.running = false
thumbgenProc.command = [
"bash", "-c",
`${thumbgenScriptPath} --size ${size} --machine_progress -d ${FileUtils.trimFileProtocol(root.directory)} || ${generateThumbnailsMagickScriptPath} --size ${size} -d ${root.directory}`,
`${thumbgenScriptPath} --size ${size} --machine_progress -d ${FileUtils.trimFileProtocol(root.directory)} || ${generateThumbnailsMagickScriptPath} --size ${size} -d ${FileUtils.trimFileProtocol(root.directory)}`,
]
// console.log("[Wallpapers] Updating thumbnails with command ", thumbgenProc.command.join(" "))
root.thumbnailGenerationProgress = 0
thumbgenProc.running = true
}
@@ -177,6 +177,7 @@ Singleton {
}
}
onExited: (exitCode, exitStatus) => {
// print("[Wallpapers] Thumbnail generation completed with exit code", exitCode)
root.thumbnailGenerated(thumbgenProc.directory)
}
}
+3
View File
@@ -0,0 +1,3 @@
/*/*.tar.*
/*/pkg/
/*/src/
+26
View File
@@ -0,0 +1,26 @@
# Install scripts for Fedora Linux
Note:
- The scripts here are **not** meant to be executed directly.
- This folder should reflect the equivalents of `/sdata/dist-arch/` but under Fedora.
- **When `/sdata/dist-arch/` is newer than this folder, an update on this folder is very likely needed.**
- Useful link: [Commit history on sdata/dist-arch/](https://github.com/end-4/dots-hyprland/commits/main/sdata/dist-arch)
- See also [Install scripts | illogical-impulse](https://ii.clsty.link/en/dev/inst-script/)
## Contributors
- Author: [ririko6z](https://github.com/ririko6z)
## Tested
- It has been tested on Fedora 43 (KDE Plasma Desktop Edition) on the `x86_64` platform.
## Post installation
- Fix the issue of the right column crashing when clicking the `Details` button in Wi-Fi mode. Edit this file: `~/.config/illogical-impulse/config.json`
```diff
@@ 44,3 44,3 @@
- "apps": {
- "bluetooth": "kcmshell6 kcm_bluetooth",
- "network": "kitty -1 fish -c nmtui",
+ "apps": {
+ "bluetooth": "kcmshell6 kcm_bluetooth",
+ "network": "plasmawindowed org.kde.plasma.networkmanagement",
```
@@ -0,0 +1,36 @@
Name: Bibata-Modern-Classic
Version: 2.0.7
Release: %autorelease
Summary: Open source, compact, and material designed cursor set.
License: GPL-3.0
URL: https://github.com/ful1e5/Bibata_Cursor
Source0: %{name}.tar.xz
BuildArch: noarch
%description
Open source, compact, and material designed cursor set.
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/releases/download/v%{version}/Bibata-Modern-Classic.tar.xz
wget -q -O %{_buildrootdir}/LICENSE %{url}/raw/refs/heads/main/LICENSE
%setup -q -n %{name}
%build
:
%install
install -d -m 0755 %{buildroot}%{_iconsdir}/Bibata-Modern-Classic
cp -r * %{buildroot}%{_iconsdir}/Bibata-Modern-Classic
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 %{_buildrootdir}/LICENSE %{buildroot}%{_licensedir}/%{name}/
%files
%{_iconsdir}/Bibata-Modern-Classic
%license %{_licensedir}/%{name}/LICENSE
%changelog
%autochangelog
@@ -0,0 +1,42 @@
Name: JetBrainsMonoNerdFont-Regular
Version: 1.2
Release: %autorelease
Summary: JetBrainsMonoNerdFonts (TrueType Outlines) (Regulear)
License: MIT
URL: https://github.com/Zhaopudark/JetBrainsMonoNerdFonts
Source0: %{name}
BuildRequires: fonts-rpm-macros
BuildArch: noarch
%description
An auto-updated compiling version of JetBrains Mono that has been patched with Nerd Fonts.
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/releases/download/v%{version}/JetBrainsMonoNerdFont-Regular-v%{version}.ttf
wget -q -P %{_sourcedir} %{url}/raw/refs/heads/main/LICENSE
%build
:
%install
install -d -m 0755 %{buildroot}%{_fontdir}
install -m 0644 %{_sourcedir}/JetBrainsMonoNerdFont*ttf %{buildroot}%{_fontdir}
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 %{_sourcedir}/LICENSE %{buildroot}%{_licensedir}/%{name}/
%post
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%postun
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%files
%{_fontdir}/JetBrainsMonoNerdFont*ttf
%license %{_licensedir}/%{name}/LICENSE
%changelog
%autochangelog
+50
View File
@@ -0,0 +1,50 @@
%global commit0 0e3707f6dafebb121d98b53c64364d16fefe481d
%global shortcommit0 %(c=%{commit0}; echo ${c:0:7})
%global bumpver 100
Name: MicroTeX
Version: 0.0.1%{?bumpver:^%{bumpver}.git%{shortcommit0}}
Release: %autorelease
Summary: A dynamic, cross-platform, and embeddable LaTeX rendering library
License: MIT
URL: https://github.com/NanoMichael/MicroTeX
Source0: %{name}-%{shortcommit0}.tar.gz
BuildRequires: gcc-c++ cmake
BuildRequires: pkgconfig(tinyxml2)
BuildRequires: gtkmm3.0-devel gtksourceviewmm3-devel cairomm-devel
%description
MicroTeX is a library for rendering LaTeX mathematical formulas, supporting multiple backends
such as GTK+, Qt, and Skia. It provides both library components and demo applications for
testing LaTeX rendering.
%prep
curl -fsSL --retry 3 \
https://codeload.github.com/NanoMichael/MicroTeX/tar.gz/%{shortcommit0} \
-o %{_sourcedir}/%{name}-%{shortcommit0}.tar.gz
%setup -q -n %{name}-%{shortcommit0}
%build
mkdir -p build
cd build
cmake ..
make -j$(nproc)
%install
mkdir -p %{buildroot}/opt/MicroTeX
cp build/LaTeX %{buildroot}/opt/MicroTeX/
cp -r build/res %{buildroot}/opt/MicroTeX/
install -Dpm 0644 LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE
install -Dpm 0644 res/greek/LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE-greek
install -Dpm 0644 res/cyrillic/LICENSE %{buildroot}%{_licensedir}/%{name}/LICENSE-cyrillic
%files
/opt/MicroTeX/
%license %{_licensedir}/%{name}/
%changelog
%autochangelog
+38
View File
@@ -0,0 +1,38 @@
Name: breeze-plus
Version: 6.19.0
Release: %autorelease
Summary: Breeze theme with additional icons
License: LGPL-2.1
URL: https://github.com/mjkim0727/breeze-plus
Source0: %{name}-%{version}.tar.gz
BuildArch: noarch
%description
Breeze icon theme with additional icons for applications not covered by the
official Breeze theme. Includes icons for Wine, third-party apps, and more.
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/archive/refs/tags/%{version}.tar.gz
%setup -q
%build
:
%install
install -d -m 0755 %{buildroot}%{_iconsdir}/breeze-plus
cp -r src/breeze-plus %{buildroot}%{_iconsdir}/
cp -r src/breeze-plus-dark %{buildroot}%{_iconsdir}/
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 LICENSE %{buildroot}%{_licensedir}/%{name}/
%files
%{_iconsdir}/breeze-plus/
%{_iconsdir}/breeze-plus-dark/
%license %{_licensedir}/%{name}/LICENSE
%changelog
%autochangelog
@@ -0,0 +1,46 @@
# Original-Spec: https://copr-dist-git.fedorainfracloud.org/packages/solopasha/hyprland/hyprland-qt-support.git/plain/hyprland-qt-support.spec?h=master
Name: hyprland-qt-support
Version: 0.1.0
Release: %autorelease -b9
Summary: A Qt6 Qml style provider for hypr* apps
License: BSD-3-Clause
URL: https://github.com/hyprwm/hyprland-qt-support
Source: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
# https://fedoraproject.org/wiki/Changes/EncourageI686LeafRemoval
ExcludeArch: %{ix86}
BuildRequires: cmake
BuildRequires: gcc-c++
BuildRequires: qt6-rpm-macros
BuildRequires: cmake(Qt6Quick)
BuildRequires: cmake(Qt6QuickControls2)
BuildRequires: cmake(Qt6Qml)
BuildRequires: pkgconfig(hyprlang)
%description
%{summary}.
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
%autosetup -p1
%build
%cmake -DINSTALL_QMLDIR=%{_qt6_qmldir}
%cmake_build
%install
%cmake_install
%files
%license LICENSE
%doc README.md
%{_prefix}/lib/libhyprland-quick-style-impl.so
%{_prefix}/lib/libhyprland-quick-style.so
%{_qt6_qmldir}/org/hyprland/
%changelog
%autochangelog
@@ -0,0 +1,44 @@
Name: otf-SpaceGrotesk
Version: 2.0.0
Release: %autorelease
Summary: Space Grotesk: a proportional variant of the original fixed-width Space Mono family
License: OFL-1.1
URL: https://github.com/floriankarsten/space-grotesk
Source0: %{name}-%{version}
BuildRequires: fonts-rpm-macros
BuildArch: noarch
%description
Space Grotesk is a proportional sans-serif typeface variant based on Colophon Foundry's fixed-width Space Mono family (2016).
Originally designed by Florian Karsten in 2018,
Space Grotesk retains the monospace's idiosyncratic details while optimizing for improved readability at non-display sizes.
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/releases/download/%{version}/SpaceGrotesk-%{version}.zip
unzip %{_sourcedir}/SpaceGrotesk-%{version}.zip
%build
:
%install
install -d -m 0755 %{buildroot}%{_fontdir}
install -m 0644 %{_buildrootdir}/SpaceGrotesk-%{version}/otf/SpaceGrotesk*otf %{buildroot}%{_fontdir}
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 %{_buildrootdir}/SpaceGrotesk-%{version}/OFL.txt %{buildroot}%{_licensedir}/%{name}/
%post
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%postun
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%files
%{_fontdir}/SpaceGrotesk*otf
%license %{_licensedir}/%{name}/OFL.txt
%changelog
%autochangelog
@@ -0,0 +1,89 @@
# Original-Spec: https://copr-dist-git.fedorainfracloud.org/packages/errornointernet/quickshell/quickshell-git.git/plain/quickshell-git.spec?h=master
%bcond_with asan
%global commit db1777c20b936a86528c1095cbcb1ebd92801402
%global commits 699
%global snapdate 20251030
%global tag 0.2.1
Name: quickshell-git
Version: %{tag}^%{commits}.git%(c=%{commit}; echo ${c:0:7})
Release: 0%{?dist}
Summary: Flexible QtQuick based desktop shell toolkit
License: LGPL-3.0-only AND GPL-3.0-only
URL: https://github.com/quickshell-mirror/quickshell
Source0: %{url}/archive/%{commit}/quickshell-%{commit}.tar.gz
Conflicts: quickshell <= %{tag}
%if 0%{fedora} >= 43
BuildRequires: breakpad-static
%endif
BuildRequires: cmake
BuildRequires: cmake(Qt6Core)
BuildRequires: cmake(Qt6Qml)
BuildRequires: cmake(Qt6ShaderTools)
BuildRequires: cmake(Qt6WaylandClient)
BuildRequires: gcc-c++
BuildRequires: ninja-build
BuildRequires: pkgconfig(breakpad)
BuildRequires: pkgconfig(CLI11)
BuildRequires: pkgconfig(gbm)
BuildRequires: pkgconfig(glib-2.0)
BuildRequires: pkgconfig(jemalloc)
BuildRequires: pkgconfig(libdrm)
BuildRequires: pkgconfig(libpipewire-0.3)
BuildRequires: pkgconfig(pam)
BuildRequires: pkgconfig(polkit-agent-1)
BuildRequires: pkgconfig(wayland-client)
BuildRequires: pkgconfig(wayland-protocols)
BuildRequires: qt6-qtbase-private-devel
BuildRequires: spirv-tools
%if %{with asan}
BuildRequires: libasan
%endif
Provides: desktop-notification-daemon
%description
Flexible toolkit for making desktop shells with QtQuick, targeting
Wayland and X11.
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/archive/%{commit}/quickshell-%{commit}.tar.gz
%autosetup -n quickshell-%{commit} -p1
%build
%cmake -GNinja \
%if %{with asan}
-DASAN=ON \
%endif
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DDISTRIBUTOR="Fedora COPR (errornointernet/quickshell)" \
-DDISTRIBUTOR_DEBUGINFO_AVAILABLE=YES \
-DGIT_REVISION=%{commit} \
-DINSTALL_QML_PREFIX=%{_lib}/qt6/qml
%cmake_build
%install
%cmake_install
%files
%license LICENSE
%license LICENSE-GPL
%doc BUILD.md
%doc CONTRIBUTING.md
%doc README.md
%doc changelog/v%{tag}.md
%{_bindir}/qs
%{_bindir}/quickshell
%{_datadir}/applications/org.quickshell.desktop
%{_datadir}/icons/hicolor/scalable/apps/org.quickshell.svg
%{_libdir}/qt6/qml/Quickshell
%changelog
%autochangelog
+46
View File
@@ -0,0 +1,46 @@
%global commit0 1f3fb39d6449eefa880543f109f33ede0cd4064f
%global shortcommit0 %(c=%{commit0}; echo ${c:0:7})
%global bumpver 100
Name: ttf-gabarito
Version: 1.000%{?bumpver:^%{bumpver}.git%{shortcommit0}}
Release: %autorelease
Summary: Gabarito Font
License: OFL-1.1
URL: https://github.com/naipefoundry/gabarito
Source0: gabarito-%{shortcommit0}.tar.gz
BuildRequires: fonts-rpm-macros
BuildArch: noarch
%description
Gabarito is a light-hearted geometric sans typeface with 6 weights ranging from Regular to Black originally designed for an online learning platform in Brazil.
%prep
wget --content-disposition -q -N -P %{_sourcedir} https://codeload.github.com/naipefoundry/gabarito/tar.gz/%{shortcommit0}
%setup -q -n gabarito-%{shortcommit0}
%build
:
%install
install -d -m 0755 %{buildroot}%{_fontdir}
install -m 0644 fonts/ttf/Gabarito*.ttf %{buildroot}%{_fontdir}
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 OFL.txt %{buildroot}%{_licensedir}/%{name}/
%post
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%postun
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%files
%{_fontdir}/Gabarito*ttf
%license %{_licensedir}/%{name}/OFL.txt
%changelog
%autochangelog
@@ -0,0 +1,42 @@
Name: ttf-material-symbols-variable
Version: 4.0.0
Release: %autorelease
Summary: Material Design icons by Google (Material Symbols)
License: Apache-2.0
URL: https://github.com/google/material-design-icons
Source0: %{name}-%{version}
BuildRequires: fonts-rpm-macros
BuildArch: noarch
%description
Google Material Symbols Rounded
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/raw/refs/heads/master/variablefont/MaterialSymbolsRounded%5BFILL,GRAD,opsz,wght%5D.ttf
wget -q -N -P %{_sourcedir} %{url}/raw/refs/heads/master/LICENSE
%build
:
%install
install -d -m 0755 %{buildroot}%{_fontdir}/variable-fonts
install -m 0644 %{_sourcedir}/MaterialSymbolsRounded*ttf %{buildroot}%{_fontdir}/variable-fonts/
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 %{_sourcedir}/LICENSE %{buildroot}%{_licensedir}/%{name}/
%post
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%postun
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%files
%{_fontdir}/variable-fonts/MaterialSymbolsRounded*ttf
%license %{_licensedir}/%{name}/LICENSE
%changelog
%autochangelog
@@ -0,0 +1,42 @@
Name: ttf-roboto-flex
Version: 3.200
Release: %autorelease
Summary: Roboto Flex
License: OFL-1.1
URL: https://github.com/googlefonts/roboto-flex
Source0: %{name}
BuildRequires: fonts-rpm-macros
BuildArch: noarch
%description
:
%prep
wget --content-disposition -q -N -P %{_sourcedir} %{url}/raw/refs/heads/main/fonts/RobotoFlex%5BGRAD,XOPQ,XTRA,YOPQ,YTAS,YTDE,YTFI,YTLC,YTUC,opsz,slnt,wdth,wght%5D.ttf
wget -q -O %{_sourcedir}/OFL.txt %{url}/raw/refs/heads/main/OFL.txt
%build
:
%install
install -d -m 0755 %{buildroot}%{_fontdir}
install -m 0644 %{_sourcedir}/RobotoFlex*ttf %{buildroot}%{_fontdir}
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 %{_sourcedir}/OFL.txt %{buildroot}%{_licensedir}/%{name}/
%post
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%postun
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%files
%{_fontdir}/RobotoFlex*ttf
%license %{_licensedir}/%{name}/OFL.txt
%changelog
%autochangelog
@@ -0,0 +1,46 @@
%global commit0 e337a5f69a9bea30e58d05bd40184d79cc099628
%global shortcommit0 %(c=%{commit0}; echo ${c:0:7})
%global bumpver 100
Name: ttf-rubik-variable
Version: 1.0%{?bumpver:^%{bumpver}.git%{shortcommit0}}
Release: %autorelease
Summary: Rubik fonts variable
License: OFL-1.1
URL: https://github.com/googlefonts/rubik
Source0: rubik-%{shortcommit0}.tar.gz
BuildRequires: fonts-rpm-macros
BuildArch: noarch
%description
:
%prep
wget --content-disposition -q -N -P %{_sourcedir} https://codeload.github.com/googlefonts/rubik/tar.gz/%{shortcommit0}
%setup -q -n rubik-%{shortcommit0}
%build
:
%install
install -d -m 0755 %{buildroot}%{_fontdir}/variable-fonts
install -m 0644 fonts/variable/Rubik*ttf %{buildroot}%{_fontdir}/variable-fonts/
install -d -m 0755 %{buildroot}%{_licensedir}/%{name}
install -m 0644 OFL.txt %{buildroot}%{_licensedir}/%{name}/
%post
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%postun
/usr/bin/fc-cache -fv >/dev/null 2>&1 || :
%files
%{_fontdir}/variable-fonts/Rubik*ttf
%license %{_licensedir}/%{name}/OFL.txt
%changelog
%autochangelog
+119
View File
@@ -0,0 +1,119 @@
# This script is meant to be sourced.
# It's not for directly running.
if ! command -v dnf >/dev/null 2>&1; then
printf "${STY_RED}[$0]: dnf not found, it seems that the system is not Fedora 42 or later distros. Aborting...${STY_RST}\n"
exit 1
fi
# Update System
case $SKIP_SYSUPDATE in
true) sleep 0;;
*) v sudo dnf upgrade --refresh -y;;
esac
# Development-tools installation
v sudo dnf install @development-tools fedora-packager rpmdevtools fonts-rpm-macros qt6-rpm-macros -y
# COPR repositories
v sudo dnf copr enable solopasha/hyprland -y
v sudo dnf copr enable errornointernet/quickshell -y
v sudo dnf copr enable errornointernet/packages -y
v sudo dnf copr enable deltacopy/darkly -y
v sudo dnf copr enable alternateved/eza -y
v sudo dnf copr enable atim/starship -y
# Audio
v sudo dnf install cava pavucontrol wireplumber libdbusmenu-gtk3-devel playerctl -y
# Backlight
v sudo dnf install geoclue2 brightnessctl ddcutil -y
# Basic
v sudo dnf install bc coreutils cliphist cmake curl wget2 ripgrep jq xdg-utils rsync yq -y
# Fonts & Themes
themes_deps=(
adw-gtk3-theme breeze-cursor-theme grub2-breeze-theme breeze-icon-theme{,-fedora}
kf6-breeze-icons sddm-breeze darkly eza fish fontconfig kitty matugen starship
jetbrains-mono-nl-fonts material-icons-fonts twitter-twemoji-fonts
)
v sudo dnf install ${themes_deps[@]} -y
# Hyprland
hyprland_deps=(
hypridle hyprland hyprlock hyprpicker hyprsunset
xdg-desktop-portal-hyprland wl-clipboard
)
v sudo dnf install --setopt="install_weak_deps=False" "${hyprland_deps[@]}" -y
# hyprland-qt-support's build deps
v sudo dnf install hyprlang-devel -y
# KDE
v sudo dnf install bluedevil gnome-keyring NetworkManager plasma-nm polkit-kde dolphin plasma-systemsettings -y
# Microtex-git
v sudo dnf install --setopt="install_weak_deps=False" tinyxml2-devel gtkmm3.0-devel gtksourceviewmm3-devel cairomm-devel -y
# Portal
v sudo dnf install xdg-desktop-portal{,-gtk,-kde,-hyprland} -y
# Python
v sudo dnf install --setopt="install_weak_deps=False" clang uv gtk4-devel libadwaita-devel \
libsoup3-devel libportal-gtk4 gobject-introspection-devel -y
v sudo dnf install python3{,.12}{,-devel} -y
# Quickshell-git
quickshell_deps=(
qt6-qtdeclarative qt6-qtbase jemalloc qt6-qtsvg pipewire-libs
libxcb wayland-devel qt6-qtwayland qt5-qtwayland libdrm breakpad
)
# NOTE: Below are custom dependencies of illogical-impulse
quickshell_custom_deps=(
qt6-qt5compat qt6-qtimageformats qt6-qtpositioning
qt6-qtquicktimeline qt6-qtsensors qt6-qttools qt6-qttranslations
qt6-qtvirtualkeyboard qt6-qtwayland kdialog kf6-syntax-highlighting
)
quickshell_build_deps=(
breakpad-static breakpad-devel gcc-c++ ninja-build mesa-libgbm-devel cli11-devel glib2-devel
jemalloc-devel libdrm-devel pipewire-devel pam-devel polkit-devel wayland-devel wayland-protocols-devel
qt6-qtdeclarative-devel qt6-qtshadertools-devel qt6-qtbase-private-devel spirv-tools
libasan
)
v sudo dnf install "${quickshell_deps[@]}" -y
v sudo dnf install "${quickshell_custom_deps[@]}" -y
v sudo dnf install "${quickshell_build_deps[@]}" -y
# Screencapture
v sudo dnf install hyprshot slurp swappy tesseract tesseract-langpack-eng tesseract-langpack-chi_sim wf-recorder -y
# Toolkit
v sudo dnf install upower wtype ydotool -y
# Widgets
v sudo dnf install fuzzel glib2 ImageMagick hypridle hyprlock hyprpicker songrec translate-shell wlogout -y
# Extra
v sudo dnf install --setopt="install_weak_deps=False" mpvpaper plasma-systemmonitor unzip -y
# Start building the missing RPM package locally.
install_RPMS() {
rpmbuildroot=${REPO_ROOT}/cache/rpmbuild
x mkdir -p $rpmbuildroot/{BUILD,RPMS,SOURCES}
x cp -r ${REPO_ROOT}/sdata/dist-fedora/SPECS $rpmbuildroot/
x cd $rpmbuildroot/SPECS
mapfile -t -d '' local_specs < <(find "$rpmbuildroot/SPECS" -maxdepth 1 -type f -name "*.spec" -print0)
for spec_file in ${local_specs[@]}; do
x rpmbuild -bb --define "_topdir $rpmbuildroot" $spec_file
done
mapfile -t -d '' local_rpms < <(find "$rpmbuildroot/RPMS" -maxdepth 2 -type f -name '*.rpm' -not -name '*debug*' -print0)
echo -e "${STY_BLUE}Next command:${STY_RST} sudo dnf install ${local_rpms[@]} -y"
x sudo dnf install "${local_rpms[@]}" -y
x cd ${REPO_ROOT}
}
showfun install_RPMS
v install_RPMS
# hyprland-qtutils depends on hyprland-qt-support
v sudo dnf install hyprland-qtutils -y
+19
View File
@@ -0,0 +1,19 @@
# This script is meant to be sourced.
# It's not for directly running.
#####################################################################################
# These python packages are installed using uv into the venv (virtual environment). Once the folder of the venv gets deleted, they are all gone cleanly. So it's considered as setups, not dependencies.
showfun install-python-packages
v install-python-packages
v sudo usermod -aG video,input "$(whoami)"
v mkdir -p "${XDG_CONFIG_HOME}/systemd/user"
v ln -s /usr/lib/systemd/system/ydotool.service "${XDG_CONFIG_HOME}/systemd/user/ydotool.service"
v bash -c "echo uinput | sudo tee /etc/modules-load.d/uinput.conf"
v bash -c 'echo SUBSYSTEM==\"misc\", KERNEL==\"uinput\", MODE=\"0660\", GROUP=\"input\" |
sudo tee /etc/udev/rules.d/99-uinput.rules'
v systemctl --user enable ydotool
v sudo systemctl enable bluetooth --now
v gsettings set org.gnome.desktop.interface font-name 'Rubik 11'
v gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'
v kwriteconfig6 --file kdeglobals --group KDE --key widgetStyle Darkly
+1
View File
@@ -0,0 +1 @@
AUTO
+2
View File
@@ -25,3 +25,5 @@ STY_RST='\e[00m'
# Used by register_temp_file()
declare -a TEMP_FILES_TO_CLEANUP=()
+17 -7
View File
@@ -138,13 +138,14 @@ elif [[ -f "./sdata/dist-${OS_DISTRO_ID}/install-deps.sh" ]]; then
printf "\n"
if [ "$ask" = "false" ]; then
echo "Urgent problem encountered, aborting...";exit 1
else
printf "${STY_RED}Still proceed?${STY_RST}\n"
read -p "[y/N]: " p
case "$p" in
[yY])sleep 0;;
*)echo "Aborting...";exit 1;;
esac
fi
printf "${STY_RED}Still proceed?${STY_RST}\n"
read -p "[y/N]: " p
case "$p" in
[yY])sleep 0;;
*)echo "Aborting...";exit 1;;
esac
fi
source ./sdata/dist-${TARGET_ID}/install-deps.sh
@@ -177,7 +178,16 @@ else
printf "2. It is WIP and only contains small number of dependencies far from enough.\n"
printf "Proceed only at your own risk.\n"
printf "${STY_RST}"
pause
if [ "$ask" = "false" ]; then
echo "Urgent problem encountered, aborting...";exit 1
else
printf "${STY_RED}Still proceed?${STY_RST}\n"
read -p "[y/N]: " p
case "$p" in
[yY])sleep 0;;
*)echo "Aborting...";exit 1;;
esac
fi
source ./sdata/dist-${TARGET_ID}/install-deps.sh
fi
+3
View File
@@ -59,6 +59,9 @@ case $SKIP_HYPRLAND in
true) sleep 0;;
*)
warning_rsync_delete; v rsync -av --delete "${arg_excludes[@]}" dots/.config/hypr/ "$XDG_CONFIG_HOME"/hypr/
if [ "$OS_DISTRO_ID" = "fedora" ];then
v rsync -av "${REPO_ROOT}/dots-extra/fedora/hypr/hyprland/execs.conf" "$XDG_CONFIG_HOME/hypr/hyprland/execs.conf"
fi
# When hypr/custom does not exist, we assume that it's the firstrun.
if [ -d "$XDG_CONFIG_HOME/hypr/custom" ];then ii_firstrun=false;else ii_firstrun=true;fi
t="$XDG_CONFIG_HOME/hypr/hyprland.conf"