forked from Shinonome/dots-hyprland
Merge remote-tracking branch 'origin/main' into addon-i18n
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
--password-store=gnome-libsecret
|
||||
# --ozone-platform-hint=wayland
|
||||
--ozone-platform-hint=wayland
|
||||
--gtk-version=4
|
||||
--ignore-gpu-blocklist
|
||||
--enable-features=TouchpadOverscrollHistoryNavigation
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# --ozone-platform-hint=wayland
|
||||
--ozone-platform-hint=wayland
|
||||
--gtk-version=4
|
||||
--ignore-gpu-blocklist
|
||||
--enable-features=TouchpadOverscrollHistoryNavigation
|
||||
|
||||
@@ -97,10 +97,10 @@ animations {
|
||||
animation = border, 1, 10, emphasizedDecel
|
||||
# layers
|
||||
animation = layersIn, 1, 2.7, emphasizedDecel, popin 93%
|
||||
animation = layersOut, 1, 2, menu_accel, popin 94%
|
||||
animation = layersOut, 1, 2.4, menu_accel, popin 94%
|
||||
# fade
|
||||
animation = fadeLayersIn, 1, 0.5, menu_decel
|
||||
animation = fadeLayersOut, 1, 2.2, menu_accel
|
||||
animation = fadeLayersOut, 1, 2.7, menu_accel
|
||||
# workspaces
|
||||
animation = workspaces, 1, 7, menu_decel, slide
|
||||
## specialWorkspace
|
||||
@@ -133,7 +133,7 @@ misc {
|
||||
key_press_enables_dpms = true
|
||||
animate_manual_resizes = false
|
||||
animate_mouse_windowdragging = false
|
||||
enable_swallow = true
|
||||
enable_swallow = false
|
||||
swallow_regex = (foot|kitty|allacritty|Alacritty)
|
||||
new_window_takes_over_fullscreen = 2
|
||||
allow_session_lock_restore = true
|
||||
|
||||
@@ -51,7 +51,7 @@ bind = Ctrl+Super, R, exec, killall ags agsv1 gjs ydotool qs quickshell; qs & #
|
||||
bindd = Super, V, Copy clipboard history entry, exec, qs ipc call TEST_ALIVE || pkill fuzzel || cliphist list | fuzzel --match-mode fzf --dmenu | cliphist decode | wl-copy # [hidden] Clipboard history >> clipboard (fallback)
|
||||
bindd = Super, Period, Copy an emoji, exec, qs ipc call TEST_ALIVE || pkill fuzzel || ~/.config/hypr/hyprland/scripts/fuzzel-emoji.sh copy # [hidden] Emoji >> clipboard (fallback)
|
||||
bindd = Super+Shift, S, Screen snip, exec, pidof slurp || hyprshot --freeze --clipboard-only --mode region --silent # Screen snip >> clipboard
|
||||
bindd = Super+Shift+Alt, S, Screen snip and annotate, exec, pidof slurp || grim -g "$(slurp)" - | swappy -f - # Screen snip and annotate
|
||||
bindd = Super+Shift+Alt, S, Screen snip and annotate, exec, pidof slurp || grim -g "$(slurp)" - | ksnip -e - # Screen snip and annotate
|
||||
# OCR
|
||||
bindd = Super+Shift, T, Character recognition,exec,grim -g "$(slurp $SLURP_ARGS)" "tmp.png" && tesseract "tmp.png" - | wl-copy && rm "tmp.png" # [hidden]
|
||||
# Color picker
|
||||
@@ -64,7 +64,7 @@ bindd = Super+Alt, R, Record region (no sound), exec, ~/.config/hypr/hyprland/sc
|
||||
bindd = Ctrl+Alt, R, Record screen (no sound), exec, ~/.config/hypr/hyprland/scripts/record.sh --fullscreen # [hidden] Record screen (no sound)
|
||||
bindd = Super+Shift+Alt, R, Record screen (with sound), exec, ~/.config/hypr/hyprland/scripts/record.sh --fullscreen-sound # Record screen (with sound)
|
||||
# AI
|
||||
bindd = Super+Shift+Alt, mouse:273, Generate AI summary for selected text, exec, ~/.config/ags/scripts/ai/primary-buffer-query.sh # AI summary for selected text
|
||||
bindd = Super+Shift+Alt, mouse:273, Generate AI summary for selected text, exec, ~/.config/hypr/hyprland/scripts/ai/primary-buffer-query.sh # AI summary for selected text
|
||||
|
||||
#!
|
||||
##! Window
|
||||
@@ -202,13 +202,13 @@ bindl= ,XF86AudioPause, exec, playerctl play-pause # [hidden]
|
||||
bind = Super, Return, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "kitty -1" "foot" "alacritty" "wezterm" "konsole" "kgx" "uxterm" "xterm" # Terminal
|
||||
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" # File manager
|
||||
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 "zen-browser" "firefox" "brave" "chromium" "google-chrome-stable" "microsoft-edge-stable" "opera" # Browser
|
||||
bind = Super, C, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "code" "codium" "zed" "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
|
||||
bind = Ctrl+Super, V, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "pavucontrol-qt" "pavucontrol" # Volume mixer
|
||||
bind = Super, I, exec, XDG_CURRENT_DESKTOP=gnome ~/.config/hypr/hyprland/scripts/launch_first_available.sh "systemsettings" "gnome-control-center" "better-control" # Settings app
|
||||
bind = Super, I, exec, XDG_CURRENT_DESKTOP=gnome ~/.config/hypr/hyprland/scripts/launch_first_available.sh "qs -p ~/.config/quickshell/settings.qml" "systemsettings" "gnome-control-center" "better-control" # Settings app
|
||||
bind = Ctrl+Shift, Escape, exec, ~/.config/hypr/hyprland/scripts/launch_first_available.sh "gnome-system-monitor" "plasma-systemmonitzor --page-name Processes" "command -v btop && kitty -1 fish -c btop" # System monitor
|
||||
|
||||
# Cursed stuff
|
||||
|
||||
@@ -22,7 +22,8 @@ windowrulev2 = center, class:^(nm-connection-editor)$
|
||||
windowrulev2 = float, class:.*plasmawindowed.*
|
||||
windowrulev2 = float, class:kcm_.*
|
||||
windowrulev2 = float, class:.*bluedevilwizard
|
||||
windowrulev2 = float, title:.*Welcome.*
|
||||
windowrulev2 = float, title:.*Welcome
|
||||
windowrulev2 = float, title:^(illogical-impulse Settings)$
|
||||
|
||||
# No appearance
|
||||
# kde-material-you-colors spawns a window when changing dark/light theme. This is to make sure it doesn't interfere at all.
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Default system prompt
|
||||
SYSTEM_PROMPT="You are a helpful, quick assistant that provides brief and concise explanation \
|
||||
to given content in at most 100 characters. If the given content is not in English, translate \
|
||||
it to English. If the content is an English word, provide its meaning. If the content is a name, \
|
||||
provide some info about it. For a math expression, provide a simplification, \
|
||||
each step on a line following this style: \`2x=11 (subtract 7 from both sides)\`. \
|
||||
If you do not know the answer, simply say 'No info available'. \
|
||||
Only respond for the appropriate case and use as little text as possible.\
|
||||
The content:"
|
||||
|
||||
first_loaded_model=$("$(dirname "$0")/show-loaded-ollama-models.sh" -j | jq -r '.[0].model' 2>/dev/null) || first_loaded_model=""
|
||||
model=${first_loaded_model:-"llama3.2"}
|
||||
|
||||
# Parse command-line arguments
|
||||
while [[ "$#" -gt 0 ]]; do
|
||||
case $1 in
|
||||
--model) model="$2"; shift ;; # Set the model from the flag
|
||||
*) echo "Unknown parameter: $1"; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Combine the system prompt with the clipboard content
|
||||
content=$(wl-paste -p | tr '\n' ' ')
|
||||
prompt="$SYSTEM_PROMPT $content"
|
||||
|
||||
# Make the API call with the specified or default model
|
||||
response=$(curl http://localhost:11434/api/generate -d \
|
||||
"{\"model\": \"$model\",\"prompt\": \"$prompt\",\"stream\": false}" \
|
||||
| jq -r '.response')
|
||||
|
||||
# Check if content is a single line and no longer than 30 characters
|
||||
if [[ ${#content} -le 30 && "$content" != *$'\n'* ]]; then
|
||||
notify-send --app-name="Text selection query" --expire-time=10000 \
|
||||
"$content" "$response"
|
||||
else
|
||||
notify-send --app-name="Text selection query" --expire-time=10000 \
|
||||
"AI Response" "$response"
|
||||
fi
|
||||
@@ -0,0 +1,99 @@
|
||||
#!/bin/bash
|
||||
|
||||
# From strikeoncmputrz/LLM_Scripts
|
||||
# License: Apache-2.0, can be found in the same folder as this script
|
||||
|
||||
# Global Vars
|
||||
ollama_url=http://localhost
|
||||
port="11434"
|
||||
blobs=()
|
||||
model_name_paths=()
|
||||
|
||||
|
||||
#Parse arguments
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
echo
|
||||
echo " Identifies Ollama models running on this operating system by parsing running processes."
|
||||
echo
|
||||
echo " Usage: $0 [options]"
|
||||
echo
|
||||
echo " Options:"
|
||||
echo " -j, --json_output Prints result as a json object. Other output disabled. (Default: false)"
|
||||
echo " -p, --port [port number] Specify Ollama Server port (Default: 11434)"
|
||||
echo " -u, --ollama_url [url] Specify Ollama Server URL (Default: http://localhost)"
|
||||
echo
|
||||
echo " Dependencies: jq"
|
||||
exit 0
|
||||
;;
|
||||
-j|--json_output)
|
||||
json_out=1
|
||||
shift 1
|
||||
;;
|
||||
-u|--ollama_url)
|
||||
ollama_url=$2
|
||||
shift 2
|
||||
;;
|
||||
-p|--port)
|
||||
port=$2
|
||||
shift 2
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
compare_running_models_and_modelfiles() {
|
||||
json_match=()
|
||||
json_output=()
|
||||
local matching_models=()
|
||||
OLDIFS=$IFS
|
||||
for ((i=0; i<${#model_name_paths[@]}; i++)); do # Iterate over the array of modelname,blob-path
|
||||
for blob in "${blobs[@]}"; do
|
||||
IFS=',', read -ra fields <<< "${model_name_paths[i]}" # Split the string into parts
|
||||
if [ "${fields[1]}" == "$blob" ]; then # Check if current 'field' matches a blob
|
||||
matching_models+=( '{ "model": "'"${fields[0]}"'", "path": "'"${fields[1]}"'"}') # Add to list of matching models
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
if [ -z "$json_out" ]; then
|
||||
echo -e "\nModel Found: \n $(echo ${matching_models[*]} | jq '.' | sed s/[{}]//g) \n"
|
||||
else
|
||||
local json_match="${matching_models[*]}"
|
||||
json_output=$(echo $json_match | jq -c -s .)
|
||||
echo "$json_output"
|
||||
fi
|
||||
IFS=$OLDIFS
|
||||
}
|
||||
|
||||
get_running_model_paths() {
|
||||
blobs=$(ps aux | grep -- '--model' | grep -v grep | grep -Po '(?<=--model\s).*' | cut -d ' ' -f1)
|
||||
if [ -z "$blobs" ]; then
|
||||
echo -e "\n\n Warning: No running Ollama models detected!\n"
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
parse_modelfiles() {
|
||||
if [ -z "$json_out" ]; then
|
||||
echo -e "\nConnecting to $ollama_url:$port\n"
|
||||
if [ -z "$(curl -s $ollama_url:$port)" ]; then
|
||||
echo -e "Could not connect to Ollama. Check the ollama_url parameter and that the server is running\n"
|
||||
exit 1
|
||||
fi
|
||||
curl -s "$ollama_url:$port"
|
||||
fi
|
||||
local models=( $(curl -s "$ollama_url:$port/api/tags" | jq -r '.models[].name') )
|
||||
for model in "${models[@]}"; do
|
||||
local modelfile=$(curl -s "$ollama_url:$port/api/show" -d '{ "name": "'"$model"'", "modelfile": true }' | jq -r '.modelfile')
|
||||
model_name_paths+=($model,$(echo "$modelfile" | awk '/^FROM/{print $2}'))
|
||||
done
|
||||
}
|
||||
|
||||
parse_modelfiles
|
||||
get_running_model_paths
|
||||
compare_running_models_and_modelfiles
|
||||
@@ -1,7 +1,7 @@
|
||||
import "root:/"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import "root:/services"
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
@@ -240,25 +240,36 @@ Scope {
|
||||
|
||||
VerticalBarSeparator {visible: ConfigOptions?.bar.borderless}
|
||||
|
||||
BarGroup {
|
||||
MouseArea {
|
||||
id: rightCenterGroup
|
||||
implicitWidth: rightCenterGroupContent.implicitWidth
|
||||
implicitHeight: rightCenterGroupContent.implicitHeight
|
||||
Layout.preferredWidth: barRoot.centerSideModuleWidth
|
||||
Layout.fillHeight: true
|
||||
|
||||
ClockWidget {
|
||||
showDate: (ConfigOptions.bar.verbose && barRoot.useShortenedForm < 2)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
onPressed: {
|
||||
Hyprland.dispatch('global quickshell:sidebarRightToggle')
|
||||
}
|
||||
|
||||
UtilButtons {
|
||||
visible: (ConfigOptions.bar.verbose && barRoot.useShortenedForm === 0)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
BarGroup {
|
||||
id: rightCenterGroupContent
|
||||
anchors.fill: parent
|
||||
|
||||
ClockWidget {
|
||||
showDate: (ConfigOptions.bar.verbose && barRoot.useShortenedForm < 2)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
BatteryIndicator {
|
||||
visible: (barRoot.useShortenedForm < 2 && UPower.displayDevice.isLaptopBattery)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
UtilButtons {
|
||||
visible: (ConfigOptions.bar.verbose && barRoot.useShortenedForm === 0)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
|
||||
BatteryIndicator {
|
||||
visible: (barRoot.useShortenedForm < 2 && UPower.displayDevice.isLaptopBattery)
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,6 +456,7 @@ Scope {
|
||||
bottom: ConfigOptions.bar.bottom ? barContent.top : undefined
|
||||
}
|
||||
height: Appearance.rounding.screenRounding
|
||||
visible: showBarBackground
|
||||
|
||||
RoundCorner {
|
||||
anchors.top: parent.top
|
||||
@@ -452,6 +464,7 @@ Scope {
|
||||
size: Appearance.rounding.screenRounding
|
||||
corner: ConfigOptions.bar.bottom ? cornerEnum.bottomLeft : cornerEnum.topLeft
|
||||
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||
opacity: 1.0 - Appearance.transparency
|
||||
}
|
||||
RoundCorner {
|
||||
anchors.top: parent.top
|
||||
@@ -459,6 +472,7 @@ Scope {
|
||||
size: Appearance.rounding.screenRounding
|
||||
corner: ConfigOptions.bar.bottom ? cornerEnum.bottomRight : cornerEnum.topRight
|
||||
color: showBarBackground ? Appearance.colors.colLayer0 : "transparent"
|
||||
opacity: 1.0 - Appearance.transparency
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@ Singleton {
|
||||
property string syntaxHighlightingTheme
|
||||
|
||||
// Extremely conservative transparency values for consistency and readability
|
||||
property real transparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.1 : 0) : 0
|
||||
property real contentTransparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.55 : 0) : 0
|
||||
property real transparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.1 : 0.07) : 0
|
||||
property real contentTransparency: ConfigOptions?.appearance.transparency ? (m3colors.darkmode ? 0.55 : 0.55) : 0
|
||||
|
||||
m3colors: QtObject {
|
||||
property bool darkmode: false
|
||||
@@ -126,10 +126,11 @@ Singleton {
|
||||
property color colPrimaryContainer: m3colors.m3primaryContainer
|
||||
property color colPrimaryContainerHover: ColorUtils.mix(colors.colPrimaryContainer, colLayer1Hover, 0.7)
|
||||
property color colPrimaryContainerActive: ColorUtils.mix(colors.colPrimaryContainer, colLayer1Active, 0.6)
|
||||
property color colOnPrimaryContainer: m3colors.m3onPrimaryContainer
|
||||
property color colSecondary: m3colors.m3secondary
|
||||
property color colSecondaryHover: ColorUtils.mix(m3colors.m3secondary, colLayer1Hover, 0.85)
|
||||
property color colSecondaryActive: ColorUtils.mix(m3colors.m3secondary, colLayer1Active, 0.4)
|
||||
property color colSecondaryContainer: ColorUtils.transparentize(m3colors.m3secondaryContainer, root.contentTransparency)
|
||||
property color colSecondaryContainer: m3colors.m3secondaryContainer
|
||||
property color colSecondaryContainerHover: ColorUtils.mix(m3colors.m3secondaryContainer, colLayer1Hover, 0.6)
|
||||
property color colSecondaryContainerActive: ColorUtils.mix(m3colors.m3secondaryContainer, colLayer1Active, 0.54)
|
||||
property color colOnSecondaryContainer: m3colors.m3onSecondaryContainer
|
||||
@@ -177,7 +178,7 @@ Singleton {
|
||||
property int larger: 19
|
||||
property int huge: 22
|
||||
property int hugeass: 23
|
||||
property int title: 28
|
||||
property int title: huge
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,11 +188,17 @@ Singleton {
|
||||
readonly property list<real> expressiveSlowSpatial: [0.39, 1.29, 0.35, 0.98, 1, 1] // Default, 650ms
|
||||
readonly property list<real> expressiveEffects: [0.34, 0.80, 0.34, 1.00, 1, 1] // Default, 200ms
|
||||
readonly property list<real> emphasized: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82, 0.25, 1, 1, 1]
|
||||
readonly property list<real> emphasizedFirstHalf: [0.05, 0, 2 / 15, 0.06, 1 / 6, 0.4, 5 / 24, 0.82]
|
||||
readonly property list<real> emphasizedLastHalf: [5 / 24, 0.82, 0.25, 1, 1, 1]
|
||||
readonly property list<real> emphasizedAccel: [0.3, 0, 0.8, 0.15, 1, 1]
|
||||
readonly property list<real> emphasizedDecel: [0.05, 0.7, 0.1, 1, 1, 1]
|
||||
readonly property list<real> standard: [0.2, 0, 0, 1, 1, 1]
|
||||
readonly property list<real> standardAccel: [0.3, 0, 1, 1, 1, 1]
|
||||
readonly property list<real> standardDecel: [0, 0, 0, 1, 1, 1]
|
||||
readonly property real expressiveFastSpatialDuration: 350
|
||||
readonly property real expressiveDefaultSpatialDuration: 500
|
||||
readonly property real expressiveSlowSpatialDuration: 650
|
||||
readonly property real expressiveEffectsDuration: 200
|
||||
}
|
||||
|
||||
animation: QtObject {
|
||||
|
||||
@@ -31,10 +31,8 @@ Singleton {
|
||||
|
||||
property QtObject apps: QtObject {
|
||||
property string bluetooth: "kcmshell6 kcm_bluetooth"
|
||||
property string imageViewer: "loupe"
|
||||
property string network: "plasmawindowed org.kde.plasma.networkmanagement"
|
||||
property string networkEthernet: "kcmshell6 kcm_networkmanagement"
|
||||
property string settings: "systemsettings"
|
||||
property string taskManager: "plasma-systemmonitor --page-name Processes"
|
||||
property string terminal: "kitty -1" // This is only for shell actions
|
||||
}
|
||||
@@ -157,6 +155,7 @@ Singleton {
|
||||
|
||||
property QtObject windows: QtObject {
|
||||
property bool showTitlebar: true // Client-side decoration for shell apps
|
||||
property bool centerTitle: true
|
||||
}
|
||||
|
||||
property QtObject hacks: QtObject {
|
||||
|
||||
@@ -32,12 +32,12 @@ Singleton {
|
||||
property string wallpaperSwitchScriptPath: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/scripts/colors/switchwall.sh`)
|
||||
// Cleanup on init
|
||||
Component.onCompleted: {
|
||||
Hyprland.dispatch(`exec mkdir -p '${shellConfig}'`)
|
||||
Hyprland.dispatch(`exec mkdir -p '${favicons}'`)
|
||||
Hyprland.dispatch(`exec rm -rf '${coverArt}'; mkdir -p '${coverArt}'`)
|
||||
Hyprland.dispatch(`exec rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`)
|
||||
Hyprland.dispatch(`exec mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`)
|
||||
Hyprland.dispatch(`exec rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`)
|
||||
Hyprland.dispatch(`exec rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`)
|
||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${shellConfig}'`])
|
||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${favicons}'`])
|
||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${coverArt}'; mkdir -p '${coverArt}'`])
|
||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${booruPreviews}'; mkdir -p '${booruPreviews}'`])
|
||||
Quickshell.execDetached(["bash", "-c", `mkdir -p '${booruDownloads}' && mkdir -p '${booruDownloadsNsfw}'`])
|
||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${latexOutput}'; mkdir -p '${latexOutput}'`])
|
||||
Quickshell.execDetached(["bash", "-c", `rm -rf '${cliphistDecode}'; mkdir -p '${cliphistDecode}'`])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import Qt.labs.platform
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
import Quickshell.Hyprland
|
||||
@@ -71,7 +72,7 @@ Rectangle {
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
Hyprland.dispatch(`exec bash -c "[ -f '${imageDecodeFilePath}' ] && rm -f '${imageDecodeFilePath}'"`)
|
||||
Quickshell.execDetached(["bash", "-c", `[ -f '${imageDecodeFilePath}' ] && rm -f '${imageDecodeFilePath}'`])
|
||||
}
|
||||
|
||||
Image {
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
|
||||
RowLayout {
|
||||
property bool uniform: false
|
||||
spacing: 10
|
||||
uniformCellSizes: uniform
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import "root:/services/"
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import "root:/modules/common/functions/file_utils.js" as FileUtils
|
||||
|
||||
Flow {
|
||||
id: root
|
||||
Layout.fillWidth: true
|
||||
spacing: 2
|
||||
property list<var> options: []
|
||||
property string configOptionName: ""
|
||||
property var currentValue: null
|
||||
|
||||
signal selected(var newValue)
|
||||
|
||||
Repeater {
|
||||
model: root.options
|
||||
delegate: SelectionGroupButton {
|
||||
id: paletteButton
|
||||
required property var modelData
|
||||
required property int index
|
||||
onYChanged: {
|
||||
if (index === 0) {
|
||||
paletteButton.leftmost = true
|
||||
} else {
|
||||
var prev = root.children[index - 1]
|
||||
var thisIsOnNewLine = prev && prev.y !== paletteButton.y
|
||||
paletteButton.leftmost = thisIsOnNewLine
|
||||
prev.rightmost = thisIsOnNewLine
|
||||
}
|
||||
}
|
||||
leftmost: index === 0
|
||||
rightmost: index === root.options.length - 1
|
||||
buttonText: modelData.displayName;
|
||||
toggled: root.currentValue === modelData.value
|
||||
onClicked: {
|
||||
root.selected(modelData.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import "root:/modules/common/widgets/"
|
||||
import "root:/modules/common/"
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls
|
||||
|
||||
RippleButton {
|
||||
id: root
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: contentItem.implicitHeight + 8 * 2
|
||||
|
||||
contentItem: RowLayout {
|
||||
spacing: 10
|
||||
StyledText {
|
||||
id: labelWidget
|
||||
Layout.fillWidth: true
|
||||
text: root.text
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
StyledSwitch {
|
||||
id: switchWidget
|
||||
down: root.down
|
||||
scale: 0.6
|
||||
Layout.fillWidth: false
|
||||
checked: root.checked
|
||||
onClicked: root.clicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
Flickable {
|
||||
id: root
|
||||
property real baseWidth: 500
|
||||
property bool forceWidth: false
|
||||
property real bottomContentPadding: 100
|
||||
|
||||
default property alias data: contentColumn.data
|
||||
|
||||
clip: true
|
||||
contentHeight: contentColumn.implicitHeight + root.bottomContentPadding // Add some padding at the bottom
|
||||
implicitWidth: contentColumn.implicitWidth
|
||||
|
||||
ColumnLayout {
|
||||
id: contentColumn
|
||||
width: root.forceWidth ? root.baseWidth : Math.max(root.baseWidth, implicitWidth)
|
||||
anchors {
|
||||
top: parent.top
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 10
|
||||
}
|
||||
spacing: 20
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
property string title
|
||||
default property alias data: sectionContent.data
|
||||
|
||||
Layout.fillWidth: true
|
||||
spacing: 8
|
||||
StyledText {
|
||||
text: root.title
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
}
|
||||
ColumnLayout {
|
||||
id: sectionContent
|
||||
spacing: 4
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
/**
|
||||
* Material 3 FAB.
|
||||
*/
|
||||
RippleButton {
|
||||
id: root
|
||||
property string iconText: "add"
|
||||
property bool expanded: false
|
||||
property real baseSize: 56
|
||||
property real elementSpacing: 5
|
||||
implicitWidth: Math.max(contentRowLayout.implicitWidth + 10 * 2, baseSize)
|
||||
implicitHeight: baseSize
|
||||
buttonRadius: Appearance.rounding.small
|
||||
colBackground: Appearance.colors.colPrimaryContainer
|
||||
colBackgroundHover: Appearance.colors.colPrimaryContainerHover
|
||||
colRipple: Appearance.colors.colPrimaryContainerActive
|
||||
contentItem: RowLayout {
|
||||
id: contentRowLayout
|
||||
property real horizontalMargins: (root.baseSize - icon.width) / 2
|
||||
anchors {
|
||||
verticalCenter: parent?.verticalCenter
|
||||
left: parent?.left
|
||||
leftMargin: contentRowLayout.horizontalMargins
|
||||
}
|
||||
spacing: 0
|
||||
|
||||
MaterialSymbol {
|
||||
id: icon
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
iconSize: 24
|
||||
color: Appearance.colors.colOnPrimaryContainer
|
||||
text: root.iconText
|
||||
}
|
||||
Loader {
|
||||
active: true
|
||||
sourceComponent: Revealer {
|
||||
visible: root.expanded || implicitWidth > 0
|
||||
reveal: root.expanded
|
||||
implicitWidth: reveal ? (buttonText.implicitWidth + root.elementSpacing + contentRowLayout.horizontalMargins) : 0
|
||||
StyledText {
|
||||
id: buttonText
|
||||
anchors {
|
||||
left: parent.left
|
||||
leftMargin: root.elementSpacing
|
||||
}
|
||||
text: root.buttonText
|
||||
color: Appearance.colors.colOnPrimaryContainer
|
||||
font.pixelSize: 14
|
||||
font.weight: 450
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ Rectangle {
|
||||
property real extraBottomBorderWidth: 2
|
||||
property color borderColor: Appearance.colors.colOnLayer0
|
||||
property real borderRadius: 5
|
||||
property color keyColor: Appearance.colors.colSurfaceContainerLow
|
||||
property color keyColor: Appearance.m3colors.m3surfaceContainerLow
|
||||
implicitWidth: keyFace.implicitWidth + borderWidth * 2
|
||||
implicitHeight: keyFace.implicitHeight + borderWidth * 2 + extraBottomBorderWidth
|
||||
radius: borderRadius
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
|
||||
GroupButton {
|
||||
id: lightDarkButtonRoot
|
||||
required property bool dark
|
||||
property color previewBg: dark ? ColorUtils.colorWithHueOf("#3f3838", Appearance.m3colors.m3primary) :
|
||||
ColorUtils.colorWithHueOf("#F7F9FF", Appearance.m3colors.m3primary)
|
||||
property color previewFg: dark ? Qt.lighter(previewBg, 2.2) : ColorUtils.mix(previewBg, "#292929", 0.85)
|
||||
padding: 5
|
||||
Layout.fillWidth: true
|
||||
colBackground: Appearance.colors.colLayer2
|
||||
toggled: Appearance.m3colors.darkmode === dark
|
||||
onClicked: {
|
||||
Quickshell.execDetached(["bash", "-c", `${Directories.wallpaperSwitchScriptPath} --mode ${dark ? "dark" : "light"} --noswitch`])
|
||||
}
|
||||
contentItem: Item {
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: buttonContentLayout.implicitWidth
|
||||
implicitHeight: buttonContentLayout.implicitHeight
|
||||
ColumnLayout {
|
||||
id: buttonContentLayout
|
||||
anchors.centerIn: parent
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: 250
|
||||
implicitHeight: skeletonColumnLayout.implicitHeight + 10 * 2
|
||||
radius: lightDarkButtonRoot.buttonRadius - lightDarkButtonRoot.padding
|
||||
color: lightDarkButtonRoot.previewBg
|
||||
border {
|
||||
width: 1
|
||||
color: Appearance.m3colors.m3outlineVariant
|
||||
}
|
||||
|
||||
// Some skeleton items
|
||||
ColumnLayout {
|
||||
id: skeletonColumnLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
spacing: 10
|
||||
RowLayout {
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.full
|
||||
color: lightDarkButtonRoot.previewFg
|
||||
implicitWidth: 50
|
||||
implicitHeight: 50
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 4
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.unsharpenmore
|
||||
color: lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 22
|
||||
}
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.unsharpenmore
|
||||
color: lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 45
|
||||
implicitHeight: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
StyledProgressBar {
|
||||
Layout.topMargin: 5
|
||||
Layout.bottomMargin: 5
|
||||
Layout.fillWidth: true
|
||||
value: 0.7
|
||||
sperm: true
|
||||
animateSperm: lightDarkButtonRoot.toggled
|
||||
highlightColor: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
|
||||
trackColor: ColorUtils.mix(lightDarkButtonRoot.previewBg, lightDarkButtonRoot.previewFg, 0.5)
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.full
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 30
|
||||
MaterialSymbol {
|
||||
visible: lightDarkButtonRoot.toggled
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "check"
|
||||
iconSize: 20
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3onPrimary : lightDarkButtonRoot.previewBg
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.unsharpenmore
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3secondaryContainer : lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 30
|
||||
}
|
||||
Rectangle {
|
||||
topLeftRadius: Appearance.rounding.unsharpenmore
|
||||
bottomLeftRadius: Appearance.rounding.unsharpenmore
|
||||
topRightRadius: Appearance.rounding.full
|
||||
bottomRightRadius: Appearance.rounding.full
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3secondaryContainer : lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 30
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: dark ? "Dark" : "Light"
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer2
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@ Text {
|
||||
hintingPreference: Font.PreferFullHinting
|
||||
family: Appearance?.font.family.iconMaterial ?? "Material Symbols Rounded"
|
||||
pixelSize: iconSize
|
||||
weight: Font.Normal + (Font.DemiBold - Font.Normal) * fill
|
||||
}
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
color: Appearance.m3colors.m3onBackground
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
|
||||
Button {
|
||||
id: button
|
||||
|
||||
property bool toggled
|
||||
property string buttonIcon
|
||||
property string buttonText
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitHeight: columnLayout.implicitHeight
|
||||
implicitWidth: columnLayout.implicitWidth
|
||||
|
||||
background: null
|
||||
PointingHandInteraction {}
|
||||
|
||||
// Real stuff
|
||||
ColumnLayout {
|
||||
id: columnLayout
|
||||
spacing: 5
|
||||
Rectangle {
|
||||
width: 62
|
||||
implicitHeight: navRailButtonIcon.height + 2 * 2
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
radius: Appearance.rounding.full
|
||||
color: toggled ?
|
||||
(button.down ? Appearance.colors.colSecondaryContainerActive : button.hovered ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colSecondaryContainer) :
|
||||
(button.down ? Appearance.colors.colLayer1Active : button.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1))
|
||||
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
MaterialSymbol {
|
||||
id: navRailButtonIcon
|
||||
anchors.centerIn: parent
|
||||
iconSize: Appearance.font.pixelSize.hugeass
|
||||
fill: toggled ? 1 : 0
|
||||
text: buttonIcon
|
||||
color: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer1
|
||||
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: buttonText
|
||||
color: Appearance.colors.colOnLayer1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
ColumnLayout { // Window content with navigation rail and content pane
|
||||
id: root
|
||||
property bool expanded: true
|
||||
property int currentIndex: 0
|
||||
spacing: 5
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
|
||||
TabButton {
|
||||
id: root
|
||||
|
||||
property bool toggled: TabBar.tabBar.currentIndex === TabBar.index
|
||||
property string buttonIcon
|
||||
property string buttonText
|
||||
property bool expanded: false
|
||||
property bool showToggledHighlight: true
|
||||
readonly property real visualWidth: root.expanded ? root.baseSize + 20 + itemText.implicitWidth : root.baseSize
|
||||
|
||||
property real baseSize: 56
|
||||
property real baseHighlightHeight: 32
|
||||
property real highlightCollapsedTopMargin: 8
|
||||
padding: 0
|
||||
|
||||
// The navigation item’s target area always spans the full width of the
|
||||
// nav rail, even if the item container hugs its contents.
|
||||
Layout.fillWidth: true
|
||||
// implicitWidth: contentItem.implicitWidth
|
||||
implicitHeight: baseSize
|
||||
|
||||
background: null
|
||||
PointingHandInteraction {}
|
||||
|
||||
// Real stuff
|
||||
contentItem: Item {
|
||||
id: buttonContent
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
left: parent.left
|
||||
right: undefined
|
||||
}
|
||||
|
||||
implicitWidth: root.visualWidth
|
||||
implicitHeight: root.expanded ? itemIconBackground.implicitHeight : itemIconBackground.implicitHeight + itemText.implicitHeight
|
||||
|
||||
Rectangle {
|
||||
id: itemBackground
|
||||
anchors.top: itemIconBackground.top
|
||||
anchors.left: itemIconBackground.left
|
||||
anchors.bottom: itemIconBackground.bottom
|
||||
implicitWidth: root.visualWidth
|
||||
radius: Appearance.rounding.full
|
||||
color: toggled ?
|
||||
root.showToggledHighlight ?
|
||||
(root.down ? Appearance.colors.colSecondaryContainerActive : root.hovered ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colSecondaryContainer)
|
||||
: ColorUtils.transparentize(Appearance.colors.colSecondaryContainer) :
|
||||
(root.down ? Appearance.colors.colLayer1Active : root.hovered ? Appearance.colors.colLayer1Hover : ColorUtils.transparentize(Appearance.colors.colLayer1Hover, 1))
|
||||
|
||||
states: State {
|
||||
name: "expanded"
|
||||
when: root.expanded
|
||||
AnchorChanges {
|
||||
target: itemBackground
|
||||
anchors.top: buttonContent.top
|
||||
anchors.left: buttonContent.left
|
||||
anchors.bottom: buttonContent.bottom
|
||||
}
|
||||
PropertyChanges {
|
||||
target: itemBackground
|
||||
implicitWidth: root.visualWidth
|
||||
}
|
||||
}
|
||||
transitions: Transition {
|
||||
AnchorAnimation {
|
||||
duration: Appearance.animation.elementMoveFast.duration
|
||||
easing.type: Appearance.animation.elementMoveFast.type
|
||||
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: itemBackground
|
||||
property: "implicitWidth"
|
||||
duration: Appearance.animation.elementMove.duration
|
||||
easing.type: Appearance.animation.elementMove.type
|
||||
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: itemIconBackground
|
||||
implicitWidth: root.baseSize
|
||||
implicitHeight: root.baseHighlightHeight
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
MaterialSymbol {
|
||||
id: navRailButtonIcon
|
||||
anchors.centerIn: parent
|
||||
iconSize: 24
|
||||
fill: toggled ? 1 : 0
|
||||
font.weight: (toggled || root.hovered) ? Font.DemiBold : Font.Normal
|
||||
text: buttonIcon
|
||||
color: toggled ? Appearance.m3colors.m3onSecondaryContainer : Appearance.colors.colOnLayer1
|
||||
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: itemText
|
||||
anchors {
|
||||
top: itemIconBackground.bottom
|
||||
topMargin: 2
|
||||
horizontalCenter: itemIconBackground.horizontalCenter
|
||||
}
|
||||
states: State {
|
||||
name: "expanded"
|
||||
when: root.expanded
|
||||
AnchorChanges {
|
||||
target: itemText
|
||||
anchors {
|
||||
top: undefined
|
||||
horizontalCenter: undefined
|
||||
left: itemIconBackground.right
|
||||
verticalCenter: itemIconBackground.verticalCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
transitions: Transition {
|
||||
AnchorAnimation {
|
||||
duration: Appearance.animation.elementMoveFast.duration
|
||||
easing.type: Appearance.animation.elementMoveFast.type
|
||||
easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve
|
||||
}
|
||||
}
|
||||
text: buttonText
|
||||
font.pixelSize: 14
|
||||
color: Appearance.colors.colOnLayer1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
RippleButton {
|
||||
id: root
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
implicitWidth: 40
|
||||
implicitHeight: 40
|
||||
Layout.leftMargin: 8
|
||||
onClicked: {
|
||||
parent.expanded = !parent.expanded;
|
||||
}
|
||||
buttonRadius: Appearance.rounding.full
|
||||
contentItem: MaterialSymbol {
|
||||
id: icon
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
iconSize: 24
|
||||
color: Appearance.colors.colOnLayer1
|
||||
text: root.parent.expanded ? "menu_open" : "menu"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell.Io
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property int currentIndex: 0
|
||||
property bool expanded: false
|
||||
default property alias data: tabBarColumn.data
|
||||
implicitHeight: tabBarColumn.implicitHeight
|
||||
implicitWidth: tabBarColumn.implicitWidth
|
||||
Layout.topMargin: 25
|
||||
Rectangle {
|
||||
property real itemHeight: tabBarColumn.children[0].baseSize
|
||||
property real baseHighlightHeight: tabBarColumn.children[0].baseHighlightHeight
|
||||
anchors {
|
||||
top: tabBarColumn.top
|
||||
left: tabBarColumn.left
|
||||
topMargin: itemHeight * root.currentIndex + (root.expanded ? 0 : ((itemHeight - baseHighlightHeight) / 2))
|
||||
}
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.colors.colSecondaryContainer
|
||||
implicitHeight: root.expanded ? itemHeight : baseHighlightHeight
|
||||
implicitWidth: tabBarColumn.children[root.currentIndex].visualWidth
|
||||
|
||||
Behavior on anchors.topMargin {
|
||||
NumberAnimation {
|
||||
duration: Appearance.animationCurves.expressiveFastSpatialDuration
|
||||
easing.type: Appearance.animation.elementMove.type
|
||||
easing.bezierCurve: Appearance.animationCurves.expressiveFastSpatial
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
id: tabBarColumn
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
}
|
||||
}
|
||||
@@ -94,12 +94,6 @@ Item { // Notification item area
|
||||
}
|
||||
}
|
||||
|
||||
onPressAndHold: (mouse) => {
|
||||
if (mouse.button === Qt.LeftButton) {
|
||||
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(notificationObject.body)}'`)
|
||||
notificationSummaryText.text = String.format(Translation.tr("{0} (copied)"), notificationObject.summary)
|
||||
}
|
||||
}
|
||||
onDraggingChanged: () => {
|
||||
if (dragging) {
|
||||
root.qmlParent.dragIndex = root.index ?? root.parent.children.indexOf(root);
|
||||
@@ -226,12 +220,8 @@ Item { // Notification item area
|
||||
Qt.openUrlExternally(link)
|
||||
Hyprland.dispatch("global quickshell:sidebarRightClose")
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton // Only for hover
|
||||
hoverEnabled: true
|
||||
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
|
||||
PointingHandLinkHover {}
|
||||
}
|
||||
|
||||
Flickable { // Notification actions
|
||||
@@ -295,7 +285,7 @@ Item { // Notification item area
|
||||
(contentItem.implicitWidth + leftPadding + rightPadding)
|
||||
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(notificationObject.body)}'`)
|
||||
Quickshell.clipboardText = notificationObject.body
|
||||
copyIcon.text = "inventory"
|
||||
copyIconTimer.restart()
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import QtQuick
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton // Only for hover
|
||||
hoverEnabled: true
|
||||
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
@@ -13,7 +13,7 @@ Item {
|
||||
|
||||
implicitWidth: (reveal || vertical) ? childrenRect.width : 0
|
||||
implicitHeight: (reveal || !vertical) ? childrenRect.height : 0
|
||||
visible: reveal && width > 0 && height > 0
|
||||
visible: reveal || (width > 0 && height > 0)
|
||||
|
||||
Behavior on implicitWidth {
|
||||
enabled: !vertical
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
RippleButton {
|
||||
id: buttonWithIconRoot
|
||||
property string nerdIcon
|
||||
property string materialIcon
|
||||
property bool materialIconFill: true
|
||||
property string mainText: "Button text"
|
||||
property Component mainContentComponent: Component {
|
||||
StyledText {
|
||||
text: buttonWithIconRoot.mainText
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
}
|
||||
implicitHeight: 35
|
||||
horizontalPadding: 15
|
||||
buttonRadius: Appearance.rounding.small
|
||||
colBackground: Appearance.colors.colLayer2
|
||||
|
||||
contentItem: RowLayout {
|
||||
Item {
|
||||
implicitWidth: Math.max(materialIconLoader.implicitWidth, nerdIconLoader.implicitWidth)
|
||||
Loader {
|
||||
id: materialIconLoader
|
||||
anchors.centerIn: parent
|
||||
active: !nerdIcon
|
||||
sourceComponent: MaterialSymbol {
|
||||
text: buttonWithIconRoot.materialIcon
|
||||
iconSize: Appearance.font.pixelSize.larger
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
fill: buttonWithIconRoot.materialIconFill ? 1 : 0
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: nerdIconLoader
|
||||
anchors.centerIn: parent
|
||||
active: nerdIcon
|
||||
sourceComponent: StyledText {
|
||||
text: buttonWithIconRoot.nerdIcon
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
font.family: Appearance.font.family.iconNerd
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
sourceComponent: buttonWithIconRoot.mainContentComponent
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import "root:/services/"
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
GroupButton {
|
||||
id: root
|
||||
horizontalPadding: 12
|
||||
verticalPadding: 8
|
||||
bounce: false
|
||||
property bool leftmost: false
|
||||
property bool rightmost: false
|
||||
leftRadius: (toggled || leftmost) ? (height / 2) : Appearance.rounding.unsharpenmore
|
||||
rightRadius: (toggled || rightmost) ? (height / 2) : Appearance.rounding.unsharpenmore
|
||||
colBackground: Appearance.colors.colSecondaryContainer
|
||||
contentItem: StyledText {
|
||||
color: parent.toggled ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer
|
||||
text: root.buttonText
|
||||
}
|
||||
}
|
||||
@@ -41,8 +41,7 @@ ProgressBar {
|
||||
}
|
||||
|
||||
contentItem: Item {
|
||||
implicitWidth: parent.width
|
||||
implicitHeight: parent.height
|
||||
anchors.fill: parent
|
||||
|
||||
Canvas {
|
||||
id: wavyFill
|
||||
|
||||
@@ -6,7 +6,8 @@ RectangularShadow {
|
||||
required property var target
|
||||
anchors.fill: target
|
||||
radius: target.radius
|
||||
blur: 1.2 * Appearance.sizes.elevationMargin
|
||||
blur: 0.9 * Appearance.sizes.elevationMargin
|
||||
offset: Qt.vector2d(0.0, 1.0)
|
||||
spread: 1
|
||||
color: Appearance.colors.colShadow
|
||||
cached: true
|
||||
|
||||
@@ -36,13 +36,13 @@ Switch {
|
||||
|
||||
// Custom thumb styling
|
||||
indicator: Rectangle {
|
||||
width: root.pressed ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
|
||||
height: root.pressed ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
|
||||
width: (root.pressed || root.down) ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
|
||||
height: (root.pressed || root.down) ? (28 * root.scale) : root.checked ? (24 * root.scale) : (16 * root.scale)
|
||||
radius: Appearance.rounding.full
|
||||
color: root.checked ? Appearance.m3colors.m3onPrimary : Appearance.m3colors.m3outline
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: root.checked ? (root.pressed ? (22 * root.scale) : 24 * root.scale) : (root.pressed ? (2 * root.scale) : 8 * root.scale)
|
||||
anchors.leftMargin: root.checked ? ((root.pressed || root.down) ? (22 * root.scale) : 24 * root.scale) : ((root.pressed || root.down) ? (2 * root.scale) : 8 * root.scale)
|
||||
|
||||
Behavior on anchors.leftMargin {
|
||||
animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
|
||||
|
||||
@@ -2,6 +2,9 @@ import "root:/modules/common"
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
|
||||
/**
|
||||
* Does not include visual layout, but includes the easily neglected colors.
|
||||
*/
|
||||
TextArea {
|
||||
renderType: Text.NativeRendering
|
||||
selectedTextColor: Appearance.m3colors.m3onSecondaryContainer
|
||||
|
||||
@@ -54,7 +54,9 @@ Scope {
|
||||
for (let j = i + 1; j < players.length; ++j) {
|
||||
let p2 = players[j];
|
||||
if (p1.trackTitle && p2.trackTitle &&
|
||||
(p1.trackTitle.includes(p2.trackTitle) || p2.trackTitle.includes(p1.trackTitle))) {
|
||||
(p1.trackTitle.includes(p2.trackTitle)
|
||||
|| p2.trackTitle.includes(p1.trackTitle))
|
||||
|| (p1.position - p2.position <= 2 && p1.length - p2.length <= 2)) {
|
||||
group.push(j);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,6 @@ Item {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onClicked: {
|
||||
if (root.draggingTargetWorkspace === -1) {
|
||||
// Hyprland.dispatch(`exec qs ipc call overview close`)
|
||||
GlobalStates.overviewOpen = false
|
||||
Hyprland.dispatch(`workspace ${workspaceValue}`)
|
||||
}
|
||||
|
||||
@@ -303,7 +303,9 @@ Item { // Wrapper
|
||||
clickActionName: "",
|
||||
type: `#${entry.match(/^\s*(\S+)/)?.[1] || ""}`,
|
||||
execute: () => {
|
||||
Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(entry)}' | cliphist decode | wl-copy`);
|
||||
Quickshell.execDetached(
|
||||
["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(entry)}' | cliphist decode | wl-copy`]
|
||||
);
|
||||
}
|
||||
};
|
||||
}).filter(Boolean);
|
||||
@@ -318,7 +320,7 @@ Item { // Wrapper
|
||||
clickActionName: "",
|
||||
type: "Emoji",
|
||||
execute: () => {
|
||||
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(entry.match(/^\s*(\S+)/)?.[1])}'`);
|
||||
Quickshell.clipboardText = entry.match(/^\s*(\S+)/)?.[1]
|
||||
}
|
||||
};
|
||||
}).filter(Boolean);
|
||||
@@ -334,7 +336,7 @@ Item { // Wrapper
|
||||
fontType: "monospace",
|
||||
materialSymbol: 'calculate',
|
||||
execute: () => {
|
||||
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(root.mathResult)}'`)
|
||||
Quickshell.clipboardText = root.mathResult;
|
||||
}
|
||||
}
|
||||
const commandResultObject = {
|
||||
|
||||
@@ -122,7 +122,7 @@ Scope {
|
||||
id: sessionTaskManager
|
||||
buttonIcon: "browse_activity"
|
||||
buttonText: Translation.tr("Task Manager")
|
||||
onClicked: { Hyprland.dispatch(`exec ${ConfigOptions.apps.taskManager}`); sessionRoot.hide() }
|
||||
onClicked: { Quickshell.execDetached(["bash", "-c", `${ConfigOptions.apps.taskManager}`]); sessionRoot.hide() }
|
||||
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
|
||||
KeyNavigation.left: sessionLogout
|
||||
KeyNavigation.down: sessionFirmwareReboot
|
||||
@@ -132,7 +132,7 @@ Scope {
|
||||
id: sessionHibernate
|
||||
buttonIcon: "downloading"
|
||||
buttonText: Translation.tr("Hibernate")
|
||||
onClicked: { Hyprland.dispatch("exec systemctl hibernate || loginctl hibernate"); sessionRoot.hide() }
|
||||
onClicked: { Quickshell.execDetached(["bash", "-c", `systemctl hibernate || loginctl hibernate`]); sessionRoot.hide() }
|
||||
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
|
||||
KeyNavigation.up: sessionLock
|
||||
KeyNavigation.right: sessionShutdown
|
||||
@@ -141,7 +141,7 @@ Scope {
|
||||
id: sessionShutdown
|
||||
buttonIcon: "power_settings_new"
|
||||
buttonText: Translation.tr("Shutdown")
|
||||
onClicked: { Hyprland.dispatch("exec systemctl poweroff || loginctl poweroff"); sessionRoot.hide() }
|
||||
onClicked: { Quickshell.execDetached(["bash", "-c", `systemctl poweroff || loginctl poweroff`]); sessionRoot.hide() }
|
||||
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
|
||||
KeyNavigation.left: sessionHibernate
|
||||
KeyNavigation.right: sessionReboot
|
||||
@@ -151,7 +151,7 @@ Scope {
|
||||
id: sessionReboot
|
||||
buttonIcon: "restart_alt"
|
||||
buttonText: Translation.tr("Reboot")
|
||||
onClicked: { Hyprland.dispatch("exec reboot || loginctl reboot"); sessionRoot.hide() }
|
||||
onClicked: { Quickshell.execDetached(["bash", "-c", `reboot || loginctl reboot`]); sessionRoot.hide() }
|
||||
onFocusChanged: { if (focus) sessionRoot.subtitle = buttonText }
|
||||
KeyNavigation.left: sessionShutdown
|
||||
KeyNavigation.right: sessionFirmwareReboot
|
||||
@@ -161,7 +161,7 @@ Scope {
|
||||
id: sessionFirmwareReboot
|
||||
buttonIcon: "settings_applications"
|
||||
buttonText: Translation.tr("Reboot to firmware settings")
|
||||
onClicked: { Hyprland.dispatch("exec systemctl reboot --firmware-setup || loginctl reboot --firmware-setup"); sessionRoot.hide() }
|
||||
onClicked: { 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
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Widgets
|
||||
import "root:/services/"
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
ContentPage {
|
||||
forceWidth: true
|
||||
|
||||
ContentSection {
|
||||
title: "Distro"
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 20
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
IconImage {
|
||||
implicitSize: 100
|
||||
source: Quickshell.iconPath(SystemInfo.logo)
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
// spacing: 10
|
||||
StyledText {
|
||||
text: SystemInfo.distroName
|
||||
font.pixelSize: Appearance.font.pixelSize.title
|
||||
}
|
||||
StyledText {
|
||||
font.pixelSize: Appearance.font.pixelSize.normal
|
||||
text: SystemInfo.homeUrl
|
||||
textFormat: Text.MarkdownText
|
||||
onLinkActivated: (link) => {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
PointingHandLinkHover {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "auto_stories"
|
||||
mainText: "Documentation"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(SystemInfo.documentationUrl)
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "support"
|
||||
mainText: "Help & Support"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(SystemInfo.supportUrl)
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "bug_report"
|
||||
mainText: "Report a Bug"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(SystemInfo.bugReportUrl)
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "policy"
|
||||
materialIconFill: false
|
||||
mainText: "Privacy Policy"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(SystemInfo.privacyPolicyUrl)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
ContentSection {
|
||||
title: "Dotfiles"
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 20
|
||||
Layout.topMargin: 10
|
||||
Layout.bottomMargin: 10
|
||||
MaterialSymbol {
|
||||
iconSize: 70
|
||||
text: "files"
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
// spacing: 10
|
||||
StyledText {
|
||||
text: "illogical-impulse"
|
||||
font.pixelSize: Appearance.font.pixelSize.title
|
||||
}
|
||||
StyledText {
|
||||
text: "https://github.com/end-4/dots-hyprland"
|
||||
font.pixelSize: Appearance.font.pixelSize.normal
|
||||
textFormat: Text.MarkdownText
|
||||
onLinkActivated: (link) => {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
PointingHandLinkHover {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "auto_stories"
|
||||
mainText: "Documentation"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/02usage/")
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "adjust"
|
||||
materialIconFill: false
|
||||
mainText: "Issues"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/end-4/dots-hyprland/issues")
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "forum"
|
||||
mainText: "Discussions"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/end-4/dots-hyprland/discussions")
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "favorite"
|
||||
mainText: "Donate"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/sponsors/end-4")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import "root:/services/"
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
|
||||
ContentPage {
|
||||
ContentSection {
|
||||
title: "Policies"
|
||||
|
||||
ConfigRow {
|
||||
ColumnLayout { // Weeb policy
|
||||
StyledText {
|
||||
text: "Weeb"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
ConfigSelectionArray {
|
||||
currentValue: ConfigOptions.policies.weeb
|
||||
configOptionName: "policies.weeb"
|
||||
onSelected: (newValue) => {
|
||||
ConfigLoader.setConfigValueAndSave("policies.weeb", newValue);
|
||||
}
|
||||
options: [
|
||||
{ displayName: "No", value: 0 },
|
||||
{ displayName: "Yes", value: 1 },
|
||||
{ displayName: "Closet", value: 2 }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout { // AI policy
|
||||
StyledText {
|
||||
text: "AI"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
ConfigSelectionArray {
|
||||
currentValue: ConfigOptions.policies.ai
|
||||
configOptionName: "policies.ai"
|
||||
onSelected: (newValue) => {
|
||||
ConfigLoader.setConfigValueAndSave("policies.ai", newValue);
|
||||
}
|
||||
options: [
|
||||
{ displayName: "No", value: 0 },
|
||||
{ displayName: "Yes", value: 1 },
|
||||
{ displayName: "Local only", value: 2 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import "root:/services/"
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import "root:/modules/common/functions/file_utils.js" as FileUtils
|
||||
|
||||
ContentPage {
|
||||
baseWidth: lightDarkButtonGroup.implicitWidth
|
||||
forceWidth: true
|
||||
|
||||
Process {
|
||||
id: konachanWallProc
|
||||
property string status: ""
|
||||
command: ["bash", "-c", FileUtils.trimFileProtocol(`${Directories.config}/quickshell/scripts/colors/random_konachan_wall.sh`)]
|
||||
stdout: SplitParser {
|
||||
onRead: data => {
|
||||
console.log(`Konachan wall proc output: ${data}`);
|
||||
konachanWallProc.status = data.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSection {
|
||||
title: "Colors & Wallpaper"
|
||||
|
||||
// Light/Dark mode preference
|
||||
ButtonGroup {
|
||||
id: lightDarkButtonGroup
|
||||
Layout.fillWidth: true
|
||||
LightDarkPreferenceButton {
|
||||
dark: false
|
||||
}
|
||||
LightDarkPreferenceButton {
|
||||
dark: true
|
||||
}
|
||||
}
|
||||
|
||||
// Material palette selection
|
||||
StyledText {
|
||||
text: "Material palette"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
|
||||
ConfigSelectionArray {
|
||||
currentValue: ConfigOptions.appearance.palette.type
|
||||
configOptionName: "appearance.palette.type"
|
||||
onSelected: (newValue) => {
|
||||
ConfigLoader.setConfigValueAndSave("appearance.palette.type", newValue);
|
||||
}
|
||||
options: [
|
||||
{"value": "auto", "displayName": "Auto"},
|
||||
{"value": "scheme-content", "displayName": "Content"},
|
||||
{"value": "scheme-expressive", "displayName": "Expressive"},
|
||||
{"value": "scheme-fidelity", "displayName": "Fidelity"},
|
||||
{"value": "scheme-fruit-salad", "displayName": "Fruit Salad"},
|
||||
{"value": "scheme-monochrome", "displayName": "Monochrome"},
|
||||
{"value": "scheme-neutral", "displayName": "Neutral"},
|
||||
{"value": "scheme-rainbow", "displayName": "Rainbow"},
|
||||
{"value": "scheme-tonal-spot", "displayName": "Tonal Spot"}
|
||||
]
|
||||
}
|
||||
|
||||
// Wallpaper selection
|
||||
StyledText {
|
||||
text: "Wallpaper"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
RippleButtonWithIcon {
|
||||
id: rndWallBtn
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
buttonRadius: Appearance.rounding.small
|
||||
materialIcon: "wallpaper"
|
||||
mainText: konachanWallProc.running ? "Be patient..." : "Random: Konachan"
|
||||
onClicked: {
|
||||
console.log(konachanWallProc.command.join(" "))
|
||||
konachanWallProc.running = true;
|
||||
}
|
||||
StyledToolTip {
|
||||
content: "Random SFW Anime wallpaper from Konachan\nImage is saved to ~/Pictures/Wallpapers"
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "wallpaper"
|
||||
StyledToolTip {
|
||||
content: "Pick wallpaper image on your system"
|
||||
}
|
||||
onClicked: {
|
||||
Quickshell.execDetached(`${Directories.wallpaperSwitchScriptPath}`)
|
||||
}
|
||||
mainContentComponent: Component {
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
StyledText {
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
text: "Choose file"
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 3
|
||||
KeyboardKey {
|
||||
key: "Ctrl"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: ""
|
||||
}
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "+"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: "T"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Change any time later with /dark, /light, /img in the launcher"
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ContentSection {
|
||||
title: "Shell style"
|
||||
|
||||
ColumnLayout { // Fake screen rounding
|
||||
StyledText {
|
||||
text: "Fake screen rounding"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
ButtonGroup {
|
||||
id: fakeScreenRoundingButtonGroup
|
||||
property int selectedPolicy: ConfigOptions.appearance.fakeScreenRounding
|
||||
spacing: 2
|
||||
SelectionGroupButton {
|
||||
property int value: 0
|
||||
leftmost: true
|
||||
buttonText: "No"
|
||||
toggled: (fakeScreenRoundingButtonGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("appearance.fakeScreenRounding", value);
|
||||
}
|
||||
}
|
||||
SelectionGroupButton {
|
||||
property int value: 1
|
||||
buttonText: "Yes"
|
||||
toggled: (fakeScreenRoundingButtonGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("appearance.fakeScreenRounding", value);
|
||||
}
|
||||
}
|
||||
SelectionGroupButton {
|
||||
property int value: 2
|
||||
rightmost: true
|
||||
buttonText: "When not fullscreen"
|
||||
toggled: (fakeScreenRoundingButtonGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("appearance.fakeScreenRounding", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConfigSwitch {
|
||||
text: "Transparency"
|
||||
checked: ConfigOptions.appearance.transparency
|
||||
onClicked: checked = !checked;
|
||||
onCheckedChanged: {
|
||||
ConfigLoader.setConfigValueAndSave("appearance.transparency", checked);
|
||||
}
|
||||
StyledToolTip {
|
||||
content: "Might look ass. Unsupported."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSection {
|
||||
title: "Shell windows"
|
||||
spacing: 4
|
||||
|
||||
ConfigRow {
|
||||
uniform: true
|
||||
ConfigSwitch {
|
||||
text: "Title bar"
|
||||
checked: ConfigOptions.windows.showTitlebar
|
||||
onClicked: checked = !checked;
|
||||
onCheckedChanged: {
|
||||
ConfigLoader.setConfigValueAndSave("windows.showTitlebar", checked);
|
||||
}
|
||||
}
|
||||
ConfigSwitch {
|
||||
text: "Center title"
|
||||
checked: ConfigOptions.windows.centerTitle
|
||||
onClicked: checked = !checked;
|
||||
onCheckedChanged: {
|
||||
ConfigLoader.setConfigValueAndSave("windows.centerTitle", checked);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -185,7 +185,7 @@ Rectangle {
|
||||
buttonIcon: activated ? "inventory" : "content_copy"
|
||||
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(root.messageData?.content)}'`)
|
||||
Quickshell.clipboardText = root.messageData?.content
|
||||
copyButton.activated = true
|
||||
copyIconTimer.restart()
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ ColumnLayout {
|
||||
buttonIcon: activated ? "inventory" : "content_copy"
|
||||
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`exec wl-copy '${StringUtils.shellSingleQuoteEscape(segmentContent)}'`)
|
||||
Quickshell.clipboardText = segmentContent
|
||||
copyCodeButton.activated = true
|
||||
copyIconTimer.restart()
|
||||
}
|
||||
@@ -96,8 +96,10 @@ ColumnLayout {
|
||||
|
||||
onClicked: {
|
||||
const downloadPath = FileUtils.trimFileProtocol(Directories.downloads)
|
||||
Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(segmentContent)}' > '${downloadPath}/code.${segmentLang || "txt"}'`)
|
||||
Hyprland.dispatch(`exec notify-send 'Code saved to file' '${downloadPath}/code.${segmentLang || "txt"}' -a Shell`)
|
||||
Quickshell.execDetached(["bash", "-c",
|
||||
`echo '${StringUtils.shellSingleQuoteEscape(segmentContent)}' > '${downloadPath}/code.${segmentLang || "txt"}'`
|
||||
])
|
||||
Quickshell.execDetached(["bash", "-c", `notify-send 'Code saved to file' '${downloadPath}/code.${segmentLang || "txt"}' -a Shell`])
|
||||
saveCodeButton.activated = true
|
||||
saveIconTimer.restart()
|
||||
}
|
||||
|
||||
@@ -180,7 +180,9 @@ Button {
|
||||
buttonText: Translation.tr("Download")
|
||||
onClicked: {
|
||||
root.showActions = false
|
||||
Hyprland.dispatch(`exec curl '${root.imageData.file_url}' -o '${root.imageData.is_nsfw ? root.nsfwPath : root.downloadPath}/${root.fileName}' && notify-send '${Translation.tr("Download complete")}' '${root.downloadPath}/${root.fileName}' -a 'Shell'`)
|
||||
Quickshell.execDetached(["bash", "-c",
|
||||
`curl '${root.imageData.file_url}' -o '${root.imageData.is_nsfw ? root.nsfwPath : root.downloadPath}/${root.fileName}' && notify-send '${qsTr("Download complete")}' '${root.downloadPath}/${root.fileName}' -a 'Shell'`
|
||||
])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,12 +163,7 @@ Rectangle {
|
||||
Qt.openUrlExternally(link)
|
||||
Hyprland.dispatch("global quickshell:sidebarLeftClose")
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton // Only for hover
|
||||
hoverEnabled: true
|
||||
cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
PointingHandLinkHover {}
|
||||
}
|
||||
|
||||
Repeater {
|
||||
|
||||
@@ -130,15 +130,17 @@ Rectangle {
|
||||
Layout.topMargin: 10
|
||||
width: tabBar.width
|
||||
// Navigation rail buttons
|
||||
ColumnLayout {
|
||||
NavigationRailTabArray {
|
||||
id: tabBar
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 5
|
||||
id: tabBar
|
||||
spacing: 15
|
||||
currentIndex: root.selectedTab
|
||||
expanded: false
|
||||
Repeater {
|
||||
model: root.tabs
|
||||
NavRailButton {
|
||||
NavigationRailButton {
|
||||
showToggledHighlight: false
|
||||
toggled: root.selectedTab == index
|
||||
buttonText: modelData.name
|
||||
buttonIcon: modelData.icon
|
||||
|
||||
@@ -3,6 +3,7 @@ import "root:/services"
|
||||
import "root:/modules/common"
|
||||
import "root:/modules/common/widgets"
|
||||
import "root:/modules/common/functions/string_utils.js" as StringUtils
|
||||
import "root:/modules/common/functions/file_utils.js" as FileUtils
|
||||
import "./quickToggles/"
|
||||
import "root:/services/"
|
||||
import QtQuick
|
||||
@@ -17,8 +18,10 @@ import Quickshell.Wayland
|
||||
import Quickshell.Hyprland
|
||||
|
||||
Scope {
|
||||
id: root
|
||||
property int sidebarWidth: Appearance.sizes.sidebarWidth
|
||||
property int sidebarPadding: 15
|
||||
property string settingsQmlPath: FileUtils.trimFileProtocol(`${Directories.config}/quickshell/settings.qml`)
|
||||
|
||||
PanelWindow {
|
||||
id: sidebarRoot
|
||||
@@ -144,11 +147,11 @@ Scope {
|
||||
toggled: false
|
||||
buttonIcon: "settings"
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`exec ${ConfigOptions.apps.settings}`)
|
||||
Hyprland.dispatch(`global quickshell:sidebarRightClose`)
|
||||
Hyprland.dispatch("global quickshell:sidebarRightClose")
|
||||
Quickshell.execDetached(["qs", "-p", root.settingsQmlPath])
|
||||
}
|
||||
StyledToolTip {
|
||||
content: Translation.tr("Plasma Settings")
|
||||
content: Translation.tr("Settings")
|
||||
}
|
||||
}
|
||||
QuickToggleButton {
|
||||
|
||||
@@ -15,8 +15,8 @@ QuickToggleButton {
|
||||
toggleBluetooth.running = true
|
||||
}
|
||||
altAction: () => {
|
||||
Hyprland.dispatch(`exec ${ConfigOptions.apps.bluetooth}`)
|
||||
Hyprland.dispatch("global quickshell:sidebarRightClose")
|
||||
Quickshell.execDetached(["bash", "-c", `${ConfigOptions.apps.bluetooth}`])
|
||||
Hyprland.dispatch("global quickshell:sidebarRightClose")
|
||||
}
|
||||
Process {
|
||||
id: toggleBluetooth
|
||||
|
||||
@@ -7,20 +7,27 @@ import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
|
||||
QuickToggleButton {
|
||||
property bool enabled: false
|
||||
id: root
|
||||
buttonIcon: "gamepad"
|
||||
toggled: enabled
|
||||
toggled: toggled
|
||||
|
||||
onClicked: {
|
||||
enabled = !enabled
|
||||
if (enabled) {
|
||||
// gameModeOn.running = true
|
||||
Hyprland.dispatch(`exec hyprctl --batch "keyword animations:enabled 0; keyword decoration:shadow:enabled 0; keyword decoration:blur:enabled 0; keyword general:gaps_in 0; keyword general:gaps_out 0; keyword general:border_size 1; keyword decoration:rounding 0; keyword general:allow_tearing 1"`)
|
||||
root.toggled = !root.toggled
|
||||
if (root.toggled) {
|
||||
Quickshell.execDetached(["bash", "-c", `hyprctl --batch "keyword animations:enabled 0; keyword decoration:shadow:enabled 0; keyword decoration:blur:enabled 0; keyword general:gaps_in 0; keyword general:gaps_out 0; keyword general:border_size 1; keyword decoration:rounding 0; keyword general:allow_tearing 1"`])
|
||||
} else {
|
||||
Hyprland.dispatch("exec hyprctl reload")
|
||||
Quickshell.execDetached(["hyprctl", "reload"])
|
||||
}
|
||||
}
|
||||
Process {
|
||||
id: fetchActiveState
|
||||
running: true
|
||||
command: ["bash", "-c", `test "$(hyprctl getoption animations:enabled -j | jq ".int")" -ne 0`]
|
||||
onExited: (exitCode, exitStatus) => {
|
||||
console.log("Game mode toggle exited with code:", exitCode, "and status:", exitStatus)
|
||||
root.toggled = exitCode !== 0 // Inverted because enabled = nonzero exit
|
||||
}
|
||||
}
|
||||
|
||||
StyledToolTip {
|
||||
content: Translation.tr("Game mode")
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ QuickToggleButton {
|
||||
toggleNetwork.running = true
|
||||
}
|
||||
altAction: () => {
|
||||
Hyprland.dispatch(`exec ${Network.ethernet ? ConfigOptions.apps.networkEthernet : ConfigOptions.apps.network}`)
|
||||
Quickshell.execDetached(["bash", "-c", `${Network.ethernet ? ConfigOptions.apps.networkEthernet : ConfigOptions.apps.network}`])
|
||||
Hyprland.dispatch("global quickshell:sidebarRightClose")
|
||||
}
|
||||
Process {
|
||||
|
||||
@@ -154,31 +154,18 @@ Item {
|
||||
// + FAB
|
||||
StyledRectangularShadow {
|
||||
target: fabButton
|
||||
radius: Appearance.rounding.normal
|
||||
radius: fabButton.buttonRadius
|
||||
blur: 0.6 * Appearance.sizes.elevationMargin
|
||||
}
|
||||
Button {
|
||||
FloatingActionButton {
|
||||
id: fabButton
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.rightMargin: root.fabMargins
|
||||
anchors.bottomMargin: root.fabMargins
|
||||
width: root.fabSize
|
||||
height: root.fabSize
|
||||
PointingHandInteraction {}
|
||||
|
||||
onClicked: root.showAddDialog = true
|
||||
|
||||
background: Rectangle {
|
||||
id: fabBackground
|
||||
anchors.fill: parent
|
||||
radius: Appearance.rounding.normal
|
||||
color: (fabButton.down) ? Appearance.colors.colPrimaryContainerActive : (fabButton.hovered ? Appearance.colors.colPrimaryContainerHover : Appearance.colors.colPrimaryContainer)
|
||||
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: MaterialSymbol {
|
||||
text: "add"
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
||||
@@ -219,7 +219,7 @@ switch() {
|
||||
# Set wallpaper with swww
|
||||
swww img "$imgpath" --transition-step 100 --transition-fps 120 \
|
||||
--transition-type grow --transition-angle 30 --transition-duration 1 \
|
||||
--transition-pos "$cursorposx, $cursorposy_inverted"
|
||||
--transition-pos "$cursorposx, $cursorposy_inverted" &
|
||||
remove_restore
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -21,10 +21,12 @@ Singleton {
|
||||
property bool isCriticalAndNotCharging: isCritical && !isCharging
|
||||
|
||||
onIsLowAndNotChargingChanged: {
|
||||
if (available && isLowAndNotCharging) Hyprland.dispatch(`exec notify-send "Low battery" "Consider plugging in your device" -u critical -a "Shell"`)
|
||||
if (available && isLowAndNotCharging)
|
||||
Quickshell.execDetached(["bash", "-c", `notify-send "Low battery" "Consider plugging in your device" -u critical -a "Shell"`]);
|
||||
}
|
||||
|
||||
onIsCriticalAndNotChargingChanged: {
|
||||
if (available && isCriticalAndNotCharging) Hyprland.dispatch(`exec notify-send "Critically low battery" "🙏 I beg for pleas charg\nAutomatic suspend triggers at ${ConfigOptions.battery.suspend}%" -u critical -a "Shell"`)
|
||||
if (available && isCriticalAndNotCharging)
|
||||
Quickshell.execDetached(["bash", "-c", `notify-send "Critically low battery" "🙏 I beg for pleas charg\nAutomatic suspend triggers at ${ConfigOptions.battery.suspend}%" -u critical -a "Shell"`]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,8 @@ Singleton {
|
||||
} catch (e) {
|
||||
console.error("[ConfigLoader] Error reading file:", e);
|
||||
console.log("[ConfigLoader] File content was:", fileContent);
|
||||
Hyprland.dispatch(`exec notify-send "${Translation.tr("Shell configuration failed to load")}" "${root.filePath}"`)
|
||||
Quickshell.execDetached(["bash", "-c", `notify-send '${Translation.tr("Shell configuration failed to load")}' '${root.filePath}'`])
|
||||
return;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +81,7 @@ Singleton {
|
||||
|
||||
function saveConfig() {
|
||||
const plainConfig = ObjectUtils.toPlainObject(ConfigOptions)
|
||||
Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(JSON.stringify(plainConfig, null, 2))}' > '${root.filePath}'`)
|
||||
Quickshell.execDetached(["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(JSON.stringify(plainConfig, null, 2))}' > '${FileUtils.trimFileProtocol(root.filePath)}'`])
|
||||
}
|
||||
|
||||
function setConfigValueAndSave(nestedKey, value, preventNextNotification = true) {
|
||||
@@ -105,7 +104,7 @@ Singleton {
|
||||
} else {
|
||||
root.applyConfig(configFileView.text())
|
||||
if (!root.preventNextNotification) {
|
||||
// Hyprland.dispatch(`exec notify-send "${Translation.tr("Shell configuration reloaded")}" "${root.filePath}"`)
|
||||
// Quickshell.execDetached(["bash", "-c", `notify-send '${qsTr("Shell configuration reloaded")}' '${root.filePath}'`])
|
||||
} else {
|
||||
root.preventNextNotification = false;
|
||||
}
|
||||
@@ -129,9 +128,9 @@ Singleton {
|
||||
if(error == FileViewError.FileNotFound) {
|
||||
console.log("[ConfigLoader] File not found, creating new file.")
|
||||
root.saveConfig()
|
||||
Hyprland.dispatch(`exec notify-send "${Translation.tr("Shell configuration created")}" "${root.filePath}"`)
|
||||
Quickshell.execDetached(["bash", "-c", `notify-send '${Translation.tr("Shell configuration created")}' '${root.filePath}'`])
|
||||
} else {
|
||||
Hyprland.dispatch(`exec notify-send "${Translation.tr("Shell configuration failed to load")}" "${root.filePath}"`)
|
||||
Quickshell.execDetached(["bash", "-c", `notify-send '${Translation.tr("Shell configuration failed to load")}' '${root.filePath}'`])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,9 +9,9 @@ pragma ComponentBehavior: Bound
|
||||
* A nice wrapper for date and time strings.
|
||||
*/
|
||||
Singleton {
|
||||
property string time: Qt.formatDateTime(clock.date, ConfigOptions?.time.format ?? "hh:mm")
|
||||
property string date: Qt.formatDateTime(clock.date, ConfigOptions?.time.dateFormat ?? "dddd, dd/MM")
|
||||
property string collapsedCalendarFormat: Qt.formatDateTime(clock.date, "dd MMMM yyyy")
|
||||
property string time: Qt.locale().toString(clock.date, ConfigOptions?.time.format ?? "hh:mm")
|
||||
property string date: Qt.locale().toString(clock.date, ConfigOptions?.time.dateFormat ?? "dddd, dd/MM")
|
||||
property string collapsedCalendarFormat: Qt.locale().toString(clock.date, "dd MMMM yyyy")
|
||||
property string uptime: "0h, 0m"
|
||||
|
||||
SystemClock {
|
||||
|
||||
@@ -20,15 +20,15 @@ Singleton {
|
||||
}
|
||||
|
||||
function enableNextTime() {
|
||||
Hyprland.dispatch(`exec rm -f '${root.firstRunFilePath}'`)
|
||||
Quickshell.execDetached(["rm", "-f", root.firstRunFilePath])
|
||||
}
|
||||
function disableNextTime() {
|
||||
Hyprland.dispatch(`exec echo '${root.firstRunFileContent}' > '${root.firstRunFilePath}'`)
|
||||
Quickshell.execDetached(["bash", "-c", `echo '${root.firstRunFileContent}' > '${root.firstRunFilePath}'`])
|
||||
}
|
||||
|
||||
function handleFirstRun() {
|
||||
Hyprland.dispatch(`exec swww query | grep 'image' || '${Directories.wallpaperSwitchScriptPath}' '${root.defaultWallpaperPath}'`)
|
||||
Hyprland.dispatch(`exec qs -p '${root.welcomeQmlPath}'`)
|
||||
Quickshell.execDetached(["bash", "-c", `swww query | grep 'image' || '${Directories.wallpaperSwitchScriptPath}' '${root.defaultWallpaperPath}'`])
|
||||
Quickshell.execDetached(["bash", "-c", `qs -p '${root.welcomeQmlPath}'`])
|
||||
}
|
||||
|
||||
FileView {
|
||||
|
||||
@@ -243,7 +243,7 @@ Singleton {
|
||||
root.list = JSON.parse(fileContents).map((notif) => {
|
||||
return notifComponent.createObject(root, {
|
||||
"id": notif.id,
|
||||
"actions": notif.actions,
|
||||
"actions": [], // Notification actions are meaningless if they're not tracked by the server or the sender is dead
|
||||
"appIcon": notif.appIcon,
|
||||
"appName": notif.appName,
|
||||
"body": notif.body,
|
||||
|
||||
@@ -9,10 +9,17 @@ import Quickshell.Io
|
||||
* Provides some system info: distro, username.
|
||||
*/
|
||||
Singleton {
|
||||
id: root
|
||||
property string distroName: "Unknown"
|
||||
property string distroId: "unknown"
|
||||
property string distroIcon: "linux-symbolic"
|
||||
property string username: "user"
|
||||
property string homeUrl: ""
|
||||
property string documentationUrl: ""
|
||||
property string supportUrl: ""
|
||||
property string bugReportUrl: ""
|
||||
property string privacyPolicyUrl: ""
|
||||
property string logo: ""
|
||||
|
||||
Timer {
|
||||
triggeredOnStart: true
|
||||
@@ -33,6 +40,20 @@ Singleton {
|
||||
const logoMatch = textOsRelease.match(/^LOGO=(.+)$/m)
|
||||
distroId = logoMatch ? logoMatch[1].replace(/"/g, "") : "unknown"
|
||||
|
||||
// Extract additional URLs and logo
|
||||
const homeUrlMatch = textOsRelease.match(/^HOME_URL="(.+?)"/m)
|
||||
homeUrl = homeUrlMatch ? homeUrlMatch[1] : ""
|
||||
const documentationUrlMatch = textOsRelease.match(/^DOCUMENTATION_URL="(.+?)"/m)
|
||||
documentationUrl = documentationUrlMatch ? documentationUrlMatch[1] : ""
|
||||
const supportUrlMatch = textOsRelease.match(/^SUPPORT_URL="(.+?)"/m)
|
||||
supportUrl = supportUrlMatch ? supportUrlMatch[1] : ""
|
||||
const bugReportUrlMatch = textOsRelease.match(/^BUG_REPORT_URL="(.+?)"/m)
|
||||
bugReportUrl = bugReportUrlMatch ? bugReportUrlMatch[1] : ""
|
||||
const privacyPolicyUrlMatch = textOsRelease.match(/^PRIVACY_POLICY_URL="(.+?)"/m)
|
||||
privacyPolicyUrl = privacyPolicyUrlMatch ? privacyPolicyUrlMatch[1] : ""
|
||||
const logoFieldMatch = textOsRelease.match(/^LOGO="?(.+?)"?$/m)
|
||||
logo = logoFieldMatch ? logoFieldMatch[1] : ""
|
||||
|
||||
// Update the distroIcon property based on distroId
|
||||
switch (distroId) {
|
||||
case "arch": distroIcon = "arch-symbolic"; break;
|
||||
@@ -57,7 +78,7 @@ Singleton {
|
||||
command: ["whoami"]
|
||||
stdout: SplitParser {
|
||||
onRead: data => {
|
||||
username = data.trim()
|
||||
root.username = data.trim()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,23 +20,36 @@ Singleton {
|
||||
|
||||
function releaseAllKeys() {
|
||||
const keycodes = Array.from(Array(249).keys());
|
||||
const releaseCommand = `ydotool key --key-delay 0 ${keycodes.map(keycode => `${keycode}:0`).join(" ")}`
|
||||
Hyprland.dispatch(`exec ${releaseCommand}`)
|
||||
Quickshell.execDetached([
|
||||
"ydotool",
|
||||
"key", "--key-delay", "0",
|
||||
...keycodes.map(keycode => `${keycode}:0`)
|
||||
])
|
||||
root.shiftMode = 0; // Reset shift mode
|
||||
}
|
||||
|
||||
function releaseShiftKeys() {
|
||||
const releaseCommand = `ydotool key --key-delay 0 ${root.shiftKeys.map(keycode => `${keycode}:0`).join(" ")}`
|
||||
Hyprland.dispatch(`exec ${releaseCommand}`)
|
||||
Quickshell.execDetached([
|
||||
"ydotool",
|
||||
"key", "--key-delay", "0",
|
||||
...root.shiftKeys.map(keycode => `${keycode}:0`)
|
||||
])
|
||||
root.shiftMode = 0; // Reset shift mode
|
||||
}
|
||||
|
||||
function press(keycode) {
|
||||
Hyprland.dispatch(`exec ydotool key --key-delay 0 ${keycode}:1`);
|
||||
Quickshell.execDetached([
|
||||
"ydotool",
|
||||
"key", "--key-delay", "0",
|
||||
`${keycode}:1`
|
||||
]);
|
||||
}
|
||||
|
||||
function release(keycode) {
|
||||
Hyprland.dispatch(`exec ydotool key --key-delay 0 ${keycode}:0`);
|
||||
Quickshell.execDetached([
|
||||
"ydotool",
|
||||
"key", "--key-delay", "0",
|
||||
`${keycode}:0`
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,219 @@
|
||||
//@ pragma UseQApplication
|
||||
//@ pragma Env QS_NO_RELOAD_POPUP=1
|
||||
//@ pragma Env QT_QUICK_CONTROLS_STYLE=Basic
|
||||
|
||||
// Adjust this to make the app smaller or larger
|
||||
//@ pragma Env QT_SCALE_FACTOR=1
|
||||
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Window
|
||||
import Quickshell
|
||||
import Quickshell.Io
|
||||
import Quickshell.Hyprland
|
||||
import "root:/services/"
|
||||
import "root:/modules/common/"
|
||||
import "root:/modules/common/widgets/"
|
||||
import "root:/modules/common/functions/color_utils.js" as ColorUtils
|
||||
import "root:/modules/common/functions/file_utils.js" as FileUtils
|
||||
import "root:/modules/common/functions/string_utils.js" as StringUtils
|
||||
|
||||
ApplicationWindow {
|
||||
id: root
|
||||
property string firstRunFilePath: FileUtils.trimFileProtocol(`${Directories.state}/user/first_run.txt`)
|
||||
property string firstRunFileContent: "This file is just here to confirm you've been greeted :>"
|
||||
property real contentPadding: 8
|
||||
property bool showNextTime: false
|
||||
property var pages: [
|
||||
{
|
||||
name: "Style",
|
||||
icon: "palette",
|
||||
component: "modules/settings/Style.qml"
|
||||
},
|
||||
{
|
||||
name: "Behavior",
|
||||
icon: "settings",
|
||||
component: "modules/settings/BehaviorConfig.qml"
|
||||
},
|
||||
{
|
||||
name: "About",
|
||||
icon: "info",
|
||||
component: "modules/settings/About.qml"
|
||||
}
|
||||
]
|
||||
property int currentPage: 0
|
||||
|
||||
visible: true
|
||||
onClosing: Qt.quit()
|
||||
title: "illogical-impulse Settings"
|
||||
|
||||
Component.onCompleted: {
|
||||
MaterialThemeLoader.reapplyTheme()
|
||||
ConfigLoader.loadConfig()
|
||||
}
|
||||
|
||||
minimumWidth: 600
|
||||
minimumHeight: 400
|
||||
width: 900
|
||||
height: 650
|
||||
color: Appearance.m3colors.m3background
|
||||
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: contentPadding
|
||||
}
|
||||
|
||||
Item { // Titlebar
|
||||
visible: ConfigOptions?.windows.showTitlebar
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: false
|
||||
implicitHeight: Math.max(titleText.implicitHeight, windowControlsRow.implicitHeight)
|
||||
StyledText {
|
||||
id: titleText
|
||||
anchors {
|
||||
left: ConfigOptions.windows.centerTitle ? undefined : parent.left
|
||||
horizontalCenter: ConfigOptions.windows.centerTitle ? parent.horizontalCenter : undefined
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 12
|
||||
}
|
||||
color: Appearance.colors.colOnLayer0
|
||||
text: "Settings"
|
||||
font.pixelSize: Appearance.font.pixelSize.title
|
||||
font.family: Appearance.font.family.title
|
||||
}
|
||||
RowLayout { // Window controls row
|
||||
id: windowControlsRow
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.right: parent.right
|
||||
RippleButton {
|
||||
buttonRadius: Appearance.rounding.full
|
||||
implicitWidth: 35
|
||||
implicitHeight: 35
|
||||
onClicked: root.close()
|
||||
contentItem: MaterialSymbol {
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "close"
|
||||
iconSize: 20
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout { // Window content with navigation rail and content pane
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
spacing: contentPadding
|
||||
Item {
|
||||
id: navRailWrapper
|
||||
Layout.fillHeight: true
|
||||
Layout.margins: 5
|
||||
implicitWidth: navRail.expanded ? 150 : fab.baseSize
|
||||
Behavior on implicitWidth {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
NavigationRail { // Window content with navigation rail and content pane
|
||||
id: navRail
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
spacing: 10
|
||||
expanded: root.width > 900
|
||||
|
||||
NavigationRailExpandButton {}
|
||||
|
||||
FloatingActionButton {
|
||||
id: fab
|
||||
iconText: "edit"
|
||||
buttonText: "Edit config"
|
||||
expanded: navRail.expanded
|
||||
onClicked: {
|
||||
Qt.openUrlExternally(`${Directories.config}/illogical-impulse/config.json`);
|
||||
}
|
||||
|
||||
StyledToolTip {
|
||||
extraVisibleCondition: !navRail.expanded
|
||||
content: "Edit shell config file"
|
||||
}
|
||||
}
|
||||
|
||||
NavigationRailTabArray {
|
||||
currentIndex: root.currentPage
|
||||
expanded: navRail.expanded
|
||||
Repeater {
|
||||
model: root.pages
|
||||
NavigationRailButton {
|
||||
required property var index
|
||||
required property var modelData
|
||||
toggled: root.currentPage === index
|
||||
onClicked: root.currentPage = index;
|
||||
expanded: navRail.expanded
|
||||
buttonIcon: modelData.icon
|
||||
buttonText: modelData.name
|
||||
showToggledHighlight: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle { // Content container
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
color: Appearance.m3colors.m3surfaceContainerLow
|
||||
radius: Appearance.rounding.windowRounding - root.contentPadding
|
||||
|
||||
Loader {
|
||||
id: pageLoader
|
||||
anchors.fill: parent
|
||||
opacity: 1.0
|
||||
source: root.pages[0].component
|
||||
Connections {
|
||||
target: root
|
||||
function onCurrentPageChanged() {
|
||||
if (pageLoader.sourceComponent !== root.pages[root.currentPage].component) {
|
||||
switchAnim.restart();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SequentialAnimation {
|
||||
id: switchAnim
|
||||
|
||||
NumberAnimation {
|
||||
target: pageLoader
|
||||
properties: "opacity"
|
||||
from: 1
|
||||
to: 0
|
||||
duration: 150
|
||||
easing.type: Appearance.animation.elementMoveExit.type
|
||||
easing.bezierCurve: Appearance.animationCurves.emphasizedFirstHalf
|
||||
}
|
||||
PropertyAction {
|
||||
target: pageLoader
|
||||
property: "source"
|
||||
value: root.pages[root.currentPage].component
|
||||
}
|
||||
NumberAnimation {
|
||||
target: pageLoader
|
||||
properties: "opacity"
|
||||
from: 0
|
||||
to: 1
|
||||
duration: 250
|
||||
easing.type: Appearance.animation.elementMoveEnter.type
|
||||
easing.bezierCurve: Appearance.animationCurves.emphasizedLastHalf
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ ShellRoot {
|
||||
property bool enableBar: true
|
||||
property bool enableBackgroundWidgets: true
|
||||
property bool enableCheatsheet: true
|
||||
property bool enableDock: true
|
||||
property bool enableDock: false
|
||||
property bool enableMediaControls: true
|
||||
property bool enableNotificationPopup: true
|
||||
property bool enableOnScreenDisplayBrightness: true
|
||||
|
||||
@@ -44,7 +44,6 @@
|
||||
"Disable NSFW content": "Disable NSFW content",
|
||||
"Done": "Done",
|
||||
"Download": "Download",
|
||||
"Download complete": "Download complete",
|
||||
"Edit": "Edit",
|
||||
"Enter text to translate...": "Enter text to translate...",
|
||||
"Finished tasks will go here": "Finished tasks will go here",
|
||||
@@ -90,7 +89,6 @@
|
||||
"Opens session screen on press": "Opens session screen on press",
|
||||
"Output": "Output",
|
||||
"Page {0}": "Page {0}",
|
||||
"Plasma Settings": "Plasma Settings",
|
||||
"Reboot": "Reboot",
|
||||
"Reboot to firmware settings": "Reboot to firmware settings",
|
||||
"Reload Hyprland & Quickshell": "Reload Hyprland & Quickshell",
|
||||
@@ -110,7 +108,6 @@
|
||||
"Set the current API provider": "Set the current API provider",
|
||||
"Shell configuration created": "Shell configuration created",
|
||||
"Shell configuration failed to load": "Shell configuration failed to load",
|
||||
"Shell configuration reloaded": "Shell configuration reloaded",
|
||||
"Shutdown": "Shutdown",
|
||||
"Silent": "Silent",
|
||||
"Sleep": "Sleep",
|
||||
@@ -151,7 +148,6 @@
|
||||
"Waifus only | Excellent quality, limited quantity": "Waifus only | Excellent quality, limited quantity",
|
||||
"Waiting for response...": "Waiting for response...",
|
||||
"Workspace": "Workspace",
|
||||
"{0} (copied)": "{0} (copied)",
|
||||
"{0} Safe Storage": "{0} Safe Storage",
|
||||
"{0} does not require an API key": "{0} does not require an API key",
|
||||
"{0} queries pending": "{0} queries pending",
|
||||
@@ -172,5 +168,6 @@
|
||||
"Switched to search mode. Continue with the user's request.": "Switched to search mode. Continue with the user's request.",
|
||||
"Experimental | Online | Google's model\nCan do a little more but doesn't search quickly": "Experimental | Online | Google's model\nCan do a little more but doesn't search quickly",
|
||||
"Message the model... \"{0}\" for commands": "Message the model... \"{0}\" for commands",
|
||||
"To set an API key, pass it with the command\n\nTo view the key, pass \"get\" with the command<br/>\n\n### For {0}:\n\n**Link**: {1}\n\n{2}": "To set an API key, pass it with the command\n\nTo view the key, pass \"get\" with the command<br/>\n\n### For {0}:\n\n**Link**: {1}\n\n{2}"
|
||||
"To set an API key, pass it with the command\n\nTo view the key, pass \"get\" with the command<br/>\n\n### For {0}:\n\n**Link**: {1}\n\n{2}": "To set an API key, pass it with the command\n\nTo view the key, pass \"get\" with the command<br/>\n\n### For {0}:\n\n**Link**: {1}\n\n{2}",
|
||||
"Settings": "Settings"
|
||||
}
|
||||
@@ -44,7 +44,6 @@
|
||||
"Disable NSFW content": "禁用 NSFW 内容",
|
||||
"Done": "完成",
|
||||
"Download": "下载",
|
||||
"Download complete": "下载完成",
|
||||
"Edit": "编辑",
|
||||
"Enter text to translate...": "输入要翻译的文本...",
|
||||
"Finished tasks will go here": "已完成的任务将显示在这里",
|
||||
@@ -90,7 +89,6 @@
|
||||
"Opens session screen on press": "按下时打开会话屏幕",
|
||||
"Output": "输出",
|
||||
"Page {0}": "第 {0} 页",
|
||||
"Plasma Settings": "Plasma 设置",
|
||||
"Reboot": "重启",
|
||||
"Reboot to firmware settings": "重启到固件设置",
|
||||
"Reload Hyprland & Quickshell": "重新加载 Hyprland 和 Quickshell",
|
||||
@@ -110,7 +108,6 @@
|
||||
"Set the current API provider": "设置当前 API 提供商",
|
||||
"Shell configuration created": "Shell 配置已创建",
|
||||
"Shell configuration failed to load": "Shell 配置加载失败",
|
||||
"Shell configuration reloaded": "Shell 配置已重新加载",
|
||||
"Shutdown": "关机",
|
||||
"Silent": "静音",
|
||||
"Sleep": "睡眠",
|
||||
@@ -151,7 +148,6 @@
|
||||
"Waifus only | Excellent quality, limited quantity": "仅限角色 | 优秀质量,数量有限",
|
||||
"Waiting for response...": "等待响应...",
|
||||
"Workspace": "工作区",
|
||||
"{0} (copied)": "{0}(已复制)",
|
||||
"{0} Safe Storage": "{0} 安全存储",
|
||||
"{0} does not require an API key": "{0} 不需要 API 密钥",
|
||||
"{0} queries pending": "{0} 个查询等待中",
|
||||
@@ -172,5 +168,6 @@
|
||||
"Enter tags, or \"{0}\" for commands": "输入标签,或 \"{0}\" 查看命令",
|
||||
"Online via {0} | {1}'s model": "通过 {0} 在线 | {1} 的模型",
|
||||
"That didn't work. Tips:\n- Check your tags and NSFW settings\n- If you don't have a tag in mind, type a page number": "没有找到结果。提示:\n- 检查您的标签和 NSFW 设置\n- 如果没有想到标签,请输入页码",
|
||||
"Online | Google's model\nGives up-to-date information with search.": "在线 | Google 模型\n通过搜索提供最新信息。"
|
||||
"Online | Google's model\nGives up-to-date information with search.": "在线 | Google 模型\n通过搜索提供最新信息。",
|
||||
"Settings": "设置"
|
||||
}
|
||||
+212
-451
@@ -24,7 +24,7 @@ ApplicationWindow {
|
||||
id: root
|
||||
property string firstRunFilePath: FileUtils.trimFileProtocol(`${Directories.state}/user/first_run.txt`)
|
||||
property string firstRunFileContent: "This file is just here to confirm you've been greeted :>"
|
||||
property real contentPadding: 5
|
||||
property real contentPadding: 8
|
||||
property bool showNextTime: false
|
||||
visible: true
|
||||
onClosing: Qt.quit()
|
||||
@@ -53,220 +53,27 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
component SelectionConnectedButton: GroupButton {
|
||||
id: selectionConnectedButtonRoot
|
||||
horizontalPadding: 12
|
||||
verticalPadding: 8
|
||||
bounce: false
|
||||
property bool leftmost: false
|
||||
property bool rightmost: false
|
||||
leftRadius: (toggled || leftmost) ? (height / 2) : Appearance.rounding.unsharpenmore
|
||||
rightRadius: (toggled || rightmost) ? (height / 2) : Appearance.rounding.unsharpenmore
|
||||
colBackground: Appearance.colors.colSecondaryContainer
|
||||
contentItem: StyledText {
|
||||
color: parent.toggled ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer
|
||||
text: selectionConnectedButtonRoot.buttonText
|
||||
}
|
||||
}
|
||||
|
||||
component Section: ColumnLayout {
|
||||
id: sectionRoot
|
||||
property string title
|
||||
default property alias data: sectionContent.data
|
||||
|
||||
Layout.fillWidth: true
|
||||
spacing: 8
|
||||
StyledText {
|
||||
text: sectionRoot.title
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
}
|
||||
ColumnLayout {
|
||||
id: sectionContent
|
||||
spacing: 5
|
||||
}
|
||||
}
|
||||
|
||||
component ButtonWithIcon: RippleButton {
|
||||
id: buttonWithIconRoot
|
||||
property string nerdIcon
|
||||
property string iconText
|
||||
property string mainText: "Button text"
|
||||
property Component mainContentComponent: Component {
|
||||
StyledText {
|
||||
text: buttonWithIconRoot.mainText
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
}
|
||||
implicitHeight: 35
|
||||
horizontalPadding: 15
|
||||
buttonRadius: Appearance.rounding.small
|
||||
colBackground: Appearance.colors.colLayer2
|
||||
|
||||
contentItem: RowLayout {
|
||||
Item {
|
||||
implicitWidth: Math.max(materialIconLoader.implicitWidth, nerdIconLoader.implicitWidth)
|
||||
Loader {
|
||||
id: materialIconLoader
|
||||
anchors.centerIn: parent
|
||||
active: !nerdIcon
|
||||
sourceComponent: MaterialSymbol {
|
||||
text: buttonWithIconRoot.iconText
|
||||
iconSize: Appearance.font.pixelSize.larger
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
fill: 1
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: nerdIconLoader
|
||||
anchors.centerIn: parent
|
||||
active: nerdIcon
|
||||
sourceComponent: StyledText {
|
||||
text: buttonWithIconRoot.nerdIcon
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
font.family: Appearance.font.family.iconNerd
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
sourceComponent: buttonWithIconRoot.mainContentComponent
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component LightDarkPrefButton: GroupButton {
|
||||
id: lightDarkButtonRoot
|
||||
required property bool dark
|
||||
property color previewBg: dark ? ColorUtils.colorWithHueOf("#3f3838", Appearance.m3colors.m3primary) :
|
||||
ColorUtils.colorWithHueOf("#F7F9FF", Appearance.m3colors.m3primary)
|
||||
property color previewFg: dark ? Qt.lighter(previewBg, 2.2) : ColorUtils.mix(previewBg, "#292929", 0.85)
|
||||
padding: 5
|
||||
Layout.fillWidth: true
|
||||
colBackground: Appearance.colors.colLayer2
|
||||
toggled: Appearance.m3colors.darkmode === dark
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`exec ${Directories.wallpaperSwitchScriptPath} --mode ${dark ? "dark" : "light"} --noswitch`)
|
||||
}
|
||||
contentItem: Item {
|
||||
anchors.centerIn: parent
|
||||
implicitWidth: buttonContentLayout.implicitWidth
|
||||
implicitHeight: buttonContentLayout.implicitHeight
|
||||
ColumnLayout {
|
||||
id: buttonContentLayout
|
||||
anchors.centerIn: parent
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
implicitWidth: 250
|
||||
implicitHeight: skeletonColumnLayout.implicitHeight + 10 * 2
|
||||
radius: lightDarkButtonRoot.buttonRadius - lightDarkButtonRoot.padding
|
||||
color: lightDarkButtonRoot.previewBg
|
||||
border {
|
||||
width: 1
|
||||
color: Appearance.m3colors.m3outlineVariant
|
||||
}
|
||||
|
||||
// Some skeleton items
|
||||
ColumnLayout {
|
||||
id: skeletonColumnLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
spacing: 10
|
||||
RowLayout {
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.full
|
||||
color: lightDarkButtonRoot.previewFg
|
||||
implicitWidth: 50
|
||||
implicitHeight: 50
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 4
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.unsharpenmore
|
||||
color: lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 22
|
||||
}
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.unsharpenmore
|
||||
color: lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
Layout.rightMargin: 45
|
||||
implicitHeight: 18
|
||||
}
|
||||
}
|
||||
}
|
||||
StyledProgressBar {
|
||||
Layout.topMargin: 5
|
||||
Layout.bottomMargin: 5
|
||||
Layout.fillWidth: true
|
||||
value: 0.7
|
||||
sperm: true
|
||||
animateSperm: lightDarkButtonRoot.toggled
|
||||
highlightColor: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
|
||||
trackColor: ColorUtils.mix(lightDarkButtonRoot.previewBg, lightDarkButtonRoot.previewFg, 0.5)
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 2
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.full
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3primary : lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 30
|
||||
MaterialSymbol {
|
||||
visible: lightDarkButtonRoot.toggled
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: "check"
|
||||
iconSize: 20
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3onPrimary : lightDarkButtonRoot.previewBg
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.unsharpenmore
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3secondaryContainer : lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 30
|
||||
}
|
||||
Rectangle {
|
||||
topLeftRadius: Appearance.rounding.unsharpenmore
|
||||
bottomLeftRadius: Appearance.rounding.unsharpenmore
|
||||
topRightRadius: Appearance.rounding.full
|
||||
bottomRightRadius: Appearance.rounding.full
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3secondaryContainer : lightDarkButtonRoot.previewFg
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 30
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
StyledText {
|
||||
Layout.fillWidth: true
|
||||
text: dark ? "Dark" : "Light"
|
||||
color: lightDarkButtonRoot.toggled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer2
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors {
|
||||
fill: parent
|
||||
margins: contentPadding
|
||||
}
|
||||
|
||||
Item {
|
||||
Item { // Titlebar
|
||||
visible: ConfigOptions?.windows.showTitlebar
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: Math.max(welcomeText.implicitHeight, windowControlsRow.implicitHeight)
|
||||
StyledText {
|
||||
id: welcomeText
|
||||
anchors.centerIn: parent
|
||||
anchors {
|
||||
left: ConfigOptions.windows.centerTitle ? undefined : parent.left
|
||||
horizontalCenter: ConfigOptions.windows.centerTitle ? parent.horizontalCenter : undefined
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 12
|
||||
}
|
||||
color: Appearance.colors.colOnLayer0
|
||||
text: "Yooooo hi there"
|
||||
font.pixelSize: Appearance.font.pixelSize.hugeass
|
||||
font.pixelSize: Appearance.font.pixelSize.title
|
||||
font.family: Appearance.font.family.title
|
||||
}
|
||||
RowLayout { // Window controls row
|
||||
@@ -284,10 +91,9 @@ ApplicationWindow {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
onCheckedChanged: {
|
||||
if (checked) {
|
||||
Hyprland.dispatch(`exec rm '${StringUtils.shellSingleQuoteEscape(root.firstRunFilePath)}'`)
|
||||
Quickshell.execDetached(["rm", root.firstRunFilePath])
|
||||
} else {
|
||||
console.log(`exec echo '${StringUtils.shellSingleQuoteEscape(root.firstRunFileContent)}' > '${StringUtils.shellSingleQuoteEscape(root.firstRunFilePath)}'`)
|
||||
Hyprland.dispatch(`exec echo '${StringUtils.shellSingleQuoteEscape(root.firstRunFileContent)}' > '${StringUtils.shellSingleQuoteEscape(root.firstRunFilePath)}'`)
|
||||
Quickshell.execDetached(["bash", "-c", `echo '${StringUtils.shellSingleQuoteEscape(root.firstRunFileContent)}' > '${StringUtils.shellSingleQuoteEscape(root.firstRunFilePath)}'`])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -305,262 +111,217 @@ ApplicationWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
Rectangle { // Content container
|
||||
color: Appearance.m3colors.m3surfaceContainerLow
|
||||
radius: Appearance.rounding.windowRounding - root.contentPadding
|
||||
implicitHeight: contentColumn.implicitHeight
|
||||
implicitWidth: contentColumn.implicitWidth
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
radius: Appearance.rounding.windowRounding - root.contentPadding
|
||||
Flickable {
|
||||
clip: true
|
||||
|
||||
|
||||
ContentPage {
|
||||
id: contentColumn
|
||||
anchors.fill: parent
|
||||
contentHeight: contentColumn.implicitHeight
|
||||
implicitWidth: contentColumn.implicitWidth
|
||||
ColumnLayout {
|
||||
id: contentColumn
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
horizontalCenter: parent.horizontalCenter
|
||||
margins: 10
|
||||
}
|
||||
spacing: 20
|
||||
ContentSection {
|
||||
title: "Style & wallpaper"
|
||||
|
||||
Section {
|
||||
title: "Style & wallpaper"
|
||||
|
||||
ButtonGroup {
|
||||
Layout.fillWidth: true
|
||||
LightDarkPrefButton {
|
||||
dark: false
|
||||
}
|
||||
LightDarkPrefButton {
|
||||
dark: true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
ButtonWithIcon {
|
||||
id: rndWallBtn
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
buttonRadius: Appearance.rounding.small
|
||||
iconText: "wallpaper"
|
||||
mainText: konachanWallProc.running ? "Be patient..." : "Random: Konachan"
|
||||
onClicked: {
|
||||
console.log(konachanWallProc.command.join(" "))
|
||||
konachanWallProc.running = true;
|
||||
}
|
||||
}
|
||||
ButtonWithIcon {
|
||||
iconText: "wallpaper"
|
||||
onClicked: {
|
||||
Hyprland.dispatch(`exec ${Directories.wallpaperSwitchScriptPath}`)
|
||||
}
|
||||
mainContentComponent: Component {
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
StyledText {
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
text: "Choose file"
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 3
|
||||
KeyboardKey {
|
||||
key: "Ctrl"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: ""
|
||||
}
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "+"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: "T"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Change any time later with /dark, /light, /img in the launcher"
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
title: "Policies"
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 15
|
||||
ColumnLayout { // Weeb policy
|
||||
StyledText {
|
||||
text: "Weeb"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
ButtonGroup {
|
||||
id: weebPolicyBtnGroup
|
||||
property int selectedPolicy: ConfigOptions.policies.weeb
|
||||
spacing: 2
|
||||
SelectionConnectedButton {
|
||||
property int value: 0
|
||||
leftmost: true
|
||||
buttonText: "No"
|
||||
toggled: (weebPolicyBtnGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("policies.weeb", value);
|
||||
}
|
||||
}
|
||||
SelectionConnectedButton {
|
||||
property int value: 1
|
||||
buttonText: "Yes"
|
||||
toggled: (weebPolicyBtnGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("policies.weeb", value);
|
||||
}
|
||||
}
|
||||
SelectionConnectedButton {
|
||||
property int value: 2
|
||||
rightmost: true
|
||||
buttonText: "Closet"
|
||||
toggled: (weebPolicyBtnGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("policies.weeb", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout { // AI policy
|
||||
StyledText {
|
||||
text: "AI"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
ButtonGroup {
|
||||
id: aiPolicyBtnGroup
|
||||
property int selectedPolicy: ConfigOptions.policies.ai
|
||||
spacing: 2
|
||||
SelectionConnectedButton {
|
||||
property int value: 0
|
||||
leftmost: true
|
||||
buttonText: "No"
|
||||
toggled: (aiPolicyBtnGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("policies.ai", value);
|
||||
}
|
||||
}
|
||||
SelectionConnectedButton {
|
||||
property int value: 1
|
||||
buttonText: "Yes"
|
||||
toggled: (aiPolicyBtnGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("policies.ai", value);
|
||||
}
|
||||
}
|
||||
SelectionConnectedButton {
|
||||
property int value: 2
|
||||
rightmost: true
|
||||
buttonText: "Local only"
|
||||
toggled: (aiPolicyBtnGroup.selectedPolicy === value)
|
||||
onClicked: {
|
||||
ConfigLoader.setConfigValueAndSave("policies.ai", value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
title: "Info"
|
||||
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
spacing: 10
|
||||
|
||||
ButtonWithIcon {
|
||||
iconText: "keyboard_alt"
|
||||
onClicked: {
|
||||
Hyprland.dispatch("global quickshell:cheatsheetOpen")
|
||||
}
|
||||
mainContentComponent: Component {
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
StyledText {
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
text: "Keybinds"
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 3
|
||||
KeyboardKey {
|
||||
key: ""
|
||||
}
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "+"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ButtonWithIcon {
|
||||
iconText: "help"
|
||||
mainText: "Usage"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/02usage/")
|
||||
}
|
||||
}
|
||||
ButtonWithIcon {
|
||||
iconText: "construction"
|
||||
mainText: "Configuration"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/03config/")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section {
|
||||
title: "Useless buttons"
|
||||
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
spacing: 10
|
||||
|
||||
ButtonWithIcon {
|
||||
nerdIcon: ""
|
||||
mainText: "GitHub"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/end-4/dots-hyprland")
|
||||
}
|
||||
}
|
||||
ButtonWithIcon {
|
||||
iconText: "favorite"
|
||||
mainText: "Funny number"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/sponsors/end-4")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
ButtonGroup {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
LightDarkPreferenceButton {
|
||||
dark: false
|
||||
}
|
||||
LightDarkPreferenceButton {
|
||||
dark: true
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
RippleButtonWithIcon {
|
||||
id: rndWallBtn
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
buttonRadius: Appearance.rounding.small
|
||||
materialIcon: "wallpaper"
|
||||
mainText: konachanWallProc.running ? "Be patient..." : "Random: Konachan"
|
||||
onClicked: {
|
||||
console.log(konachanWallProc.command.join(" "))
|
||||
konachanWallProc.running = true;
|
||||
}
|
||||
StyledToolTip {
|
||||
content: "Random SFW Anime wallpaper from Konachan\nImage is saved to ~/Pictures/Wallpapers"
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "wallpaper"
|
||||
StyledToolTip {
|
||||
content: "Pick wallpaper image on your system"
|
||||
}
|
||||
onClicked: {
|
||||
Quickshell.execDetached([`${Directories.wallpaperSwitchScriptPath}`])
|
||||
}
|
||||
mainContentComponent: Component {
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
StyledText {
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
text: "Choose file"
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 3
|
||||
KeyboardKey {
|
||||
key: "Ctrl"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: ""
|
||||
}
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "+"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: "T"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: "Change any time later with /dark, /light, /img in the launcher"
|
||||
font.pixelSize: Appearance.font.pixelSize.smaller
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
}
|
||||
|
||||
ContentSection {
|
||||
title: "Policies"
|
||||
|
||||
ConfigRow {
|
||||
ColumnLayout { // Weeb policy
|
||||
StyledText {
|
||||
text: "Weeb"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
ConfigSelectionArray {
|
||||
currentValue: ConfigOptions.policies.weeb
|
||||
configOptionName: "policies.weeb"
|
||||
onSelected: (newValue) => {
|
||||
ConfigLoader.setConfigValueAndSave("policies.weeb", newValue);
|
||||
}
|
||||
options: [
|
||||
{ displayName: "No", value: 0 },
|
||||
{ displayName: "Yes", value: 1 },
|
||||
{ displayName: "Closet", value: 2 }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout { // AI policy
|
||||
StyledText {
|
||||
text: "AI"
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
ConfigSelectionArray {
|
||||
currentValue: ConfigOptions.policies.ai
|
||||
configOptionName: "policies.ai"
|
||||
onSelected: (newValue) => {
|
||||
ConfigLoader.setConfigValueAndSave("policies.ai", newValue);
|
||||
}
|
||||
options: [
|
||||
{ displayName: "No", value: 0 },
|
||||
{ displayName: "Yes", value: 1 },
|
||||
{ displayName: "Local only", value: 2 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSection {
|
||||
title: "Info"
|
||||
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "keyboard_alt"
|
||||
onClicked: {
|
||||
Hyprland.dispatch("global quickshell:cheatsheetOpen")
|
||||
}
|
||||
mainContentComponent: Component {
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
StyledText {
|
||||
font.pixelSize: Appearance.font.pixelSize.small
|
||||
text: "Keybinds"
|
||||
color: Appearance.colors.colOnSecondaryContainer
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 3
|
||||
KeyboardKey {
|
||||
key: ""
|
||||
}
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
text: "+"
|
||||
}
|
||||
KeyboardKey {
|
||||
key: "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "help"
|
||||
mainText: "Usage"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/02usage/")
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "construction"
|
||||
mainText: "Configuration"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://end-4.github.io/dots-hyprland-wiki/en/ii-qs/03config/")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ContentSection {
|
||||
title: "Useless buttons"
|
||||
|
||||
Flow {
|
||||
Layout.fillWidth: true
|
||||
spacing: 5
|
||||
|
||||
RippleButtonWithIcon {
|
||||
nerdIcon: ""
|
||||
mainText: "GitHub"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/end-4/dots-hyprland")
|
||||
}
|
||||
}
|
||||
RippleButtonWithIcon {
|
||||
materialIcon: "favorite"
|
||||
mainText: "Funny number"
|
||||
onClicked: {
|
||||
Qt.openUrlExternally("https://github.com/sponsors/end-4")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ add_newline = false
|
||||
# Powerline symbols
|
||||
# Wedges 🭧🭒 🭣🭧🭓
|
||||
# Random noise 🬖🬥🬔🬗
|
||||
# Cool stuff
|
||||
|
||||
# format = """
|
||||
# $cmd_duration$username$hostname $directory $git_branch
|
||||
@@ -16,8 +17,8 @@ $character
|
||||
|
||||
# Replace the "❯" symbol in the prompt with "➜"
|
||||
[character] # The name of the module we are configuring is "character"
|
||||
success_symbol = "[ ](bold fg:blue)"
|
||||
error_symbol = "[ ](bold fg:red)"
|
||||
success_symbol = "[ ](bold fg:blue)"
|
||||
error_symbol = "[ ](bold fg:red)"
|
||||
|
||||
# Disable the package module, hiding it from the prompt completely
|
||||
[package]
|
||||
@@ -83,7 +84,7 @@ read_only = " "
|
||||
style = "bg:green fg:black"
|
||||
truncation_length = 6
|
||||
truncation_symbol = " ••/"
|
||||
format = '[](bold fg:green)[ $path]($style)[](bold fg:green)'
|
||||
format = '[](bold fg:green)[ $path]($style)[](bold fg:green)'
|
||||
|
||||
|
||||
[directory.substitutions]
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
[preferred]
|
||||
default = hyprland;gtk
|
||||
org.freedesktop.impl.portal.FileChooser = kde
|
||||
@@ -6,7 +6,7 @@ arch=(any)
|
||||
license=(None)
|
||||
depends=(
|
||||
xdg-desktop-portal
|
||||
xdg-desktop-portal-gtk
|
||||
xdg-desktop-portal-kde
|
||||
xdg-desktop-portal-hyprland
|
||||
)
|
||||
|
||||
|
||||
@@ -5,11 +5,10 @@ pkgdesc='Illogical Impulse Screenshot and Recording Dependencies'
|
||||
arch=(any)
|
||||
license=(None)
|
||||
depends=(
|
||||
swappy
|
||||
wf-recorder
|
||||
hyprshot
|
||||
ksnip
|
||||
slurp
|
||||
tesseract
|
||||
tesseract-data-eng
|
||||
slurp
|
||||
wf-recorder
|
||||
)
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ depends=(
|
||||
hyprlock
|
||||
hyprpicker
|
||||
nm-connection-editor
|
||||
quickshell
|
||||
quickshell-git
|
||||
swww
|
||||
translate-shell
|
||||
wlogout
|
||||
|
||||
Reference in New Issue
Block a user