├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── sleex1.png ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── PKGBUILD ├── README.md ├── preview.mp4 ├── sleex-packages ├── .gitignore ├── README.md ├── build-all.sh ├── sleex-bibata-modern-classic-bin │ └── PKGBUILD └── sleex-microtex-git │ ├── .gitignore │ └── PKGBUILD ├── sleex-user-config ├── .gitignore ├── PKGBUILD ├── README.md └── src │ └── .config │ ├── Kvantum │ ├── Colloid │ │ ├── Colloid.kvconfig │ │ ├── Colloid.svg │ │ ├── ColloidDark.kvconfig │ │ └── ColloidDark.svg │ ├── MaterialAdw │ │ ├── MaterialAdw.kvconfig │ │ └── MaterialAdw.svg │ └── kvantum.kvconfig │ ├── anyrun │ ├── config.ron │ └── style.css │ ├── chrome-flags.conf │ ├── code-flags.conf │ ├── fish │ ├── auto-Hypr.fish │ ├── config.fish │ └── fish_variables │ ├── fontconfig │ └── conf.d │ ├── foot │ └── foot.ini │ ├── fuzzel │ ├── fuzzel.ini │ └── fuzzel_theme.ini │ ├── hypr │ ├── apps.conf │ ├── custom │ │ ├── env.conf │ │ ├── execs.conf │ │ ├── general.conf │ │ ├── keybinds.conf │ │ ├── rules.conf │ │ └── scripts │ │ │ └── __restore_video_wallpaper.sh │ ├── hypridle.conf │ ├── hyprland.conf │ ├── hyprland │ │ ├── colors.conf │ │ ├── env.conf │ │ ├── execs.conf │ │ ├── general.conf │ │ ├── keybinds_fr.conf │ │ ├── keybinds_us.conf │ │ └── rules.conf │ ├── monitors.conf │ └── workspaces.conf │ ├── kde-material-you-colors │ └── config.conf │ ├── kdeglobals │ ├── kitty │ ├── kitty.conf │ ├── scroll_mark.py │ └── search.py │ ├── matugen │ ├── config.toml │ ├── scripts │ │ └── least_busy_region.py │ └── templates │ │ ├── ags │ │ ├── _material.scss │ │ ├── sourceviewtheme-light.xml │ │ └── sourceviewtheme.xml │ │ ├── colors.json │ │ ├── discord.css │ │ ├── fuzzel │ │ └── fuzzel_theme.ini │ │ ├── gtk │ │ └── gtk-colors.css │ │ ├── hyprland │ │ ├── colors.conf │ │ └── hyprlock.conf │ │ ├── kde │ │ ├── color.txt │ │ └── kde-material-you-colors-wrapper.sh │ │ ├── wallpaper.txt │ │ └── zed.json │ ├── mpv │ └── mpv.conf │ ├── qt5ct │ └── qt5ct.conf │ ├── qt6ct │ └── qt6ct.conf │ ├── starship.toml │ ├── thorium-flags.conf │ ├── wlogout │ ├── layout │ └── style.css │ ├── xdg-desktop-portal │ └── hyprland-portals.conf │ └── zshrc.d │ ├── auto-Hypr.sh │ ├── dots-hyprland.zsh │ └── shortcuts.zsh └── src ├── bin ├── fuzzel-emoji ├── rubyshot └── sleex └── share ├── sleex ├── .gitignore ├── CMakeLists.txt ├── GlobalStates.qml ├── ReloadPopup.qml ├── assets │ ├── icons │ │ ├── ai-openai-symbolic.svg │ │ ├── arch-symbolic.svg │ │ ├── axos-symbolic.svg │ │ ├── cachyos-symbolic.svg │ │ ├── cloudflare-dns-symbolic.svg │ │ ├── crosshair-symbolic.svg │ │ ├── debian-symbolic.svg │ │ ├── deepseek-symbolic.svg │ │ ├── desktop-symbolic.svg │ │ ├── endeavouros-symbolic.svg │ │ ├── fedora-symbolic.svg │ │ ├── flatpak-symbolic.svg │ │ ├── github-symbolic.svg │ │ ├── google-gemini-symbolic.svg │ │ ├── linux-symbolic.svg │ │ ├── microsoft-symbolic.svg │ │ ├── mona-loading.gif │ │ ├── nixos-symbolic.svg │ │ ├── ollama-symbolic.svg │ │ ├── openai-symbolic.svg │ │ ├── openrouter-symbolic.svg │ │ ├── spark-symbolic.svg │ │ └── ubuntu-symbolic.svg │ ├── logo │ │ ├── 1024px │ │ │ ├── black.png │ │ │ ├── dark.png │ │ │ ├── light.png │ │ │ └── white.png │ │ ├── 128px │ │ │ ├── black.png │ │ │ ├── dark.png │ │ │ ├── light.png │ │ │ └── white.png │ │ ├── 256px │ │ │ ├── black.png │ │ │ ├── dark.png │ │ │ ├── light.png │ │ │ └── white.png │ │ ├── 512px │ │ │ ├── black.png │ │ │ ├── dark.png │ │ │ ├── light.png │ │ │ └── white.png │ │ ├── logotype │ │ │ ├── black.png │ │ │ ├── dark.png │ │ │ ├── light.png │ │ │ └── white.png │ │ ├── svg │ │ │ ├── black.svg │ │ │ ├── dark.svg │ │ │ ├── light.svg │ │ │ └── white.svg │ │ └── svg_logotype │ │ │ ├── dark.svg │ │ │ └── light.svg │ └── sounds │ │ └── battery │ │ ├── 01_full.wav │ │ ├── 02_plug.wav │ │ ├── 02_unplug.wav │ │ ├── 04_warn.wav │ │ └── 05_critical.wav ├── modules │ ├── background │ │ ├── Background.qml │ │ ├── Clock.qml │ │ ├── Quote.qml │ │ └── Watermark.qml │ ├── bar │ │ ├── ActiveWindow.qml │ │ ├── AudioOsd.qml │ │ ├── Bar.qml │ │ ├── BarGroupCenter.qml │ │ ├── BarGroupL.qml │ │ ├── BarGroupR.qml │ │ ├── BatteryIndicator.qml │ │ ├── BatteryIndicator.qml.back │ │ ├── BatteryPopup.qml │ │ ├── BluetoothIndicator.qml │ │ ├── BrightnessOsd.qml │ │ ├── BtPopup.qml │ │ ├── CircleUtilButton.qml │ │ ├── ClockWidget.qml │ │ ├── HyprlandXkbIndicator.qml │ │ ├── NotifIndicator.qml │ │ ├── Resource.qml │ │ ├── Resources.qml │ │ ├── ScrollHint.qml │ │ ├── StyledPopup.qml │ │ ├── SysTray.qml │ │ ├── SysTrayItem.qml │ │ ├── SysTrayMenu.qml │ │ ├── SysTrayMenuEntry.qml │ │ └── Workspaces.qml │ ├── cheatsheet │ │ ├── Cheatsheet.qml │ │ └── CheatsheetKeybinds.qml │ ├── common │ │ ├── Appearance.qml │ │ ├── Config.qml │ │ ├── ConfigOptions.qml │ │ ├── Directories.qml │ │ ├── Persistent.qml │ │ ├── PersistentStates.qml │ │ ├── StyledComboBox.qml │ │ ├── functions │ │ │ ├── ColorUtils.qml │ │ │ ├── FileUtils.qml │ │ │ ├── Fuzzy.qml │ │ │ ├── Lavendist.qml │ │ │ ├── ObjectUtils.qml │ │ │ ├── StringUtils.qml │ │ │ ├── fuzzysort.js │ │ │ ├── levendist.js │ │ │ └── object_utils.js │ │ └── widgets │ │ │ ├── AudioDeviceSelectorButton.qml │ │ │ ├── ButtonGroup.qml │ │ │ ├── CachingImage.qml │ │ │ ├── CircularProgress.qml │ │ │ ├── CliphistImage.qml │ │ │ ├── ClippedFilledCircularProgress.qml │ │ │ ├── ClippingRectangle.qml │ │ │ ├── ConfigRow.qml │ │ │ ├── ConfigSelectionArray.qml │ │ │ ├── ConfigSpinBox.qml │ │ │ ├── ConfigSwitch.qml │ │ │ ├── ContentPage.qml │ │ │ ├── ContentSection.qml │ │ │ ├── ContentSubsection.qml │ │ │ ├── ContentSubsectionLabel.qml │ │ │ ├── CustomIcon.qml │ │ │ ├── DialogButton.qml │ │ │ ├── DragManager.qml │ │ │ ├── Favicon.qml │ │ │ ├── FloatingActionButton.qml │ │ │ ├── FlowButtonGroup.qml │ │ │ ├── GroupButton.qml │ │ │ ├── KeyboardKey.qml │ │ │ ├── LightDarkPreferenceButton.qml │ │ │ ├── MaterialSymbol.qml │ │ │ ├── MaterialTextField.qml │ │ │ ├── MenuButton.qml │ │ │ ├── NavRailButton.qml │ │ │ ├── NavigationRail.qml │ │ │ ├── NavigationRailButton.qml │ │ │ ├── NavigationRailExpandButton.qml │ │ │ ├── NavigationRailTabArray.qml │ │ │ ├── NotificationActionButton.qml │ │ │ ├── NotificationAppIcon.qml │ │ │ ├── NotificationGroup.qml │ │ │ ├── NotificationGroupExpandButton.qml │ │ │ ├── NotificationItem.qml │ │ │ ├── NotificationListView.qml │ │ │ ├── PointingHandInteraction.qml │ │ │ ├── PointingHandLinkHover.qml │ │ │ ├── PopupToolTip.qml │ │ │ ├── PrimaryTabBar.qml │ │ │ ├── PrimaryTabButton.qml │ │ │ ├── Revealer.qml │ │ │ ├── RippleButton.qml │ │ │ ├── RippleButtonWithIcon.qml │ │ │ ├── RoundCorner.qml │ │ │ ├── ScrollEdgeFade.qml │ │ │ ├── SecondaryTabButton.qml │ │ │ ├── SelectionDialog.qml │ │ │ ├── SelectionGroupButton.qml │ │ │ ├── StyledBusyIndicator.qml │ │ │ ├── StyledComboBox.qml │ │ │ ├── StyledFlickable.qml │ │ │ ├── StyledLabel.qml │ │ │ ├── StyledListView.qml │ │ │ ├── StyledProgressBar.qml │ │ │ ├── StyledRadioButton.qml │ │ │ ├── StyledRectangularShadow.qml │ │ │ ├── StyledScrollBar.qml │ │ │ ├── StyledSlider.qml │ │ │ ├── StyledSpinBox.qml │ │ │ ├── StyledSwitch.qml │ │ │ ├── StyledText.qml │ │ │ ├── StyledTextArea.qml │ │ │ ├── StyledTextInput.qml │ │ │ ├── StyledToolTip.qml │ │ │ ├── StyledToolTipContent.qml │ │ │ ├── VerticalButtonGroup.qml │ │ │ ├── VolumeMixer.qml │ │ │ ├── WaveVisualizer.qml │ │ │ └── notification_utils.js │ ├── dashboard │ │ ├── AiWidgetGroup.qml │ │ ├── Dashboard.qml │ │ ├── DashboardTabs.qml │ │ ├── HomeWidgetGroup.qml │ │ ├── TodoWidgetGroup.qml │ │ ├── ai │ │ │ ├── AiChat.qml │ │ │ ├── ApiCommandButton.qml │ │ │ ├── ApiInputBoxIndicator.qml │ │ │ ├── DescriptionBox.qml │ │ │ └── aiChat │ │ │ │ ├── AiMessage.qml │ │ │ │ ├── AiMessageControlButton.qml │ │ │ │ ├── AnnotationSourceButton.qml │ │ │ │ ├── AttachedFileIndicator.qml │ │ │ │ ├── MessageCodeBlock.qml │ │ │ │ ├── MessageTextBlock.qml │ │ │ │ ├── MessageThinkBlock.qml │ │ │ │ └── SearchQueryButton.qml │ │ ├── calendar │ │ │ ├── CalendarDayButton.qml │ │ │ ├── CalendarHeaderButton.qml │ │ │ ├── CalendarWidget.qml │ │ │ ├── GhCalendar.qml │ │ │ └── calendar_layout.js │ │ ├── notifications │ │ │ ├── NotificationList.qml │ │ │ └── NotificationStatusButton.qml │ │ ├── quickToggles │ │ │ ├── BluetoothToggle.qml │ │ │ ├── GameMode.qml │ │ │ ├── IdleInhibitor.qml │ │ │ ├── NetworkToggle.qml │ │ │ ├── NightLight.qml │ │ │ └── QuickToggleButton.qml │ │ ├── todo │ │ │ ├── TaskList.qml │ │ │ ├── TodoItemActionButton.qml │ │ │ └── TodoWidget.qml │ │ └── weather │ │ │ ├── Weather.qml │ │ │ └── WeatherOff.qml │ ├── dock │ │ ├── Dock.qml │ │ ├── DockAppButton.qml │ │ ├── DockApps.qml │ │ ├── DockButton.qml │ │ └── DockSeparator.qml │ ├── lockscreen │ │ ├── Lock.qml │ │ ├── LockContext.qml │ │ ├── LockSurface.qml │ │ └── pam │ │ │ └── password.conf │ ├── mediaControls │ │ ├── MediaControls.qml │ │ ├── PlayerControl.qml │ │ └── PlayerControlBlank.qml │ ├── notificationPopup │ │ └── NotificationPopup.qml │ ├── onScreenDisplay │ │ ├── OnScreenDisplayBrightness.qml │ │ ├── OnScreenDisplayVolume.qml │ │ └── OsdValueIndicator.qml │ ├── overview │ │ ├── Overview.qml │ │ ├── OverviewWidget.qml │ │ ├── OverviewWindow.qml │ │ ├── SearchItem.qml │ │ └── SearchWidget.qml │ ├── screenCorners │ │ └── ScreenCorners.qml │ ├── session │ │ ├── Session.qml │ │ └── SessionActionButton.qml │ ├── settings │ │ ├── About.qml │ │ ├── BehaviorConfig.qml │ │ ├── Bluetooth.qml │ │ ├── Display.qml │ │ ├── Interface.qml │ │ ├── Privacy.qml │ │ ├── Sound.qml │ │ ├── Style.qml │ │ ├── Wifi.qml │ │ └── displaySettings │ │ │ ├── DisplaySettings.qml │ │ │ └── MonitorItem.qml │ ├── sidebarLeft │ │ ├── AiChat.qml │ │ ├── ApiCommandButton.qml │ │ ├── ApiInputBoxIndicator.qml │ │ ├── DescriptionBox.qml │ │ ├── SidebarLeft.qml │ │ ├── SidebarLeftContent.qml │ │ └── aiChat │ │ │ ├── AiMessage.qml │ │ │ ├── AiMessageControlButton.qml │ │ │ ├── AnnotationSourceButton.qml │ │ │ ├── AttachedFileIndicator.qml │ │ │ ├── MessageCodeBlock.qml │ │ │ ├── MessageTextBlock.qml │ │ │ ├── MessageThinkBlock.qml │ │ │ └── SearchQueryButton.qml │ └── wallpaperSelector │ │ └── WallpaperSelector.qml ├── plugins │ ├── CMakeLists.txt │ └── src │ │ └── Sleex │ │ ├── CMakeLists.txt │ │ └── services │ │ ├── CMakeLists.txt │ │ ├── bluetooth.cpp │ │ ├── bluetooth.hpp │ │ ├── brightness.cpp │ │ ├── brightness.hpp │ │ ├── displays.hpp │ │ ├── meta_types │ │ └── qt6sleex-services_metatypes.json │ │ ├── monitor.cpp │ │ ├── monitor.hpp │ │ ├── network.cpp │ │ ├── network.hpp │ │ ├── plugin.cpp │ │ ├── qmltypes │ │ └── sleex-services_foreign_types.txt │ │ ├── resourceUsage.cpp │ │ ├── resourceUsage.hpp │ │ ├── sleex-servicesplugin_Sleex_ServicesPlugin.cpp │ │ └── sleex-servicesplugin_Sleex_ServicesPlugin_in.cpp ├── qml │ └── Sleex │ │ └── Services │ │ ├── qmldir │ │ └── sleex-services_qml_module_dir_map.qrc ├── scripts │ ├── ai │ │ └── show-installed-ollama-models.sh │ ├── cava │ │ └── raw_output_config.txt │ ├── colors │ │ ├── applycolor.sh │ │ ├── generate_colors_material.py │ │ ├── scheme_for_image.py │ │ ├── switchwall.sh │ │ └── term_gen_colors.sh │ ├── firstRun.sh │ ├── grimblast.sh │ ├── hyprland │ │ ├── get_keybinds.py │ │ └── workspace_action.sh │ ├── insomnia │ │ └── insomnia.sh │ ├── kvantum │ │ ├── adwsvg.py │ │ ├── adwsvgDark.py │ │ ├── changeAdwColors.py │ │ └── materialQT.sh │ ├── record-script.sh │ ├── templates │ │ ├── gtk │ │ │ └── gtk-colors.css │ │ ├── term_emus │ │ │ ├── alacritty.tpl │ │ │ ├── foot.tpl │ │ │ ├── ghostty.tpl │ │ │ ├── kitty.tpl │ │ │ ├── wezterm.tpl │ │ │ └── zellij.tpl │ │ └── terminal │ │ │ ├── scheme-base.json │ │ │ ├── scheme-monochrome.json │ │ │ └── sequences.txt │ ├── terminal │ │ ├── scheme-base.json │ │ └── sequences.txt │ └── wayland-idle-inhibitor.py ├── services │ ├── Ai.qml │ ├── AiMessageData.qml │ ├── AppSearch.qml │ ├── Audio.qml │ ├── Battery.qml │ ├── Brightness.qml │ ├── Cliphist.qml │ ├── ConfigLoader.qml │ ├── DateTime.qml │ ├── Emojis.qml │ ├── FirstRunExperience.qml │ ├── Github.qml │ ├── HyprlandData.qml │ ├── HyprlandKeybinds.qml │ ├── HyprlandXkb.qml │ ├── KeyringStorage.qml │ ├── LatexRenderer.qml │ ├── MaterialThemeLoader.qml │ ├── Monitors.qml │ ├── MprisController.qml │ ├── Network.qml │ ├── NightLight.qml │ ├── Notifications.qml │ ├── PersistentStateManager.qml │ ├── Quotes.qml │ ├── SystemInfo.qml │ ├── Todo.qml │ ├── Wallpapers.qml │ ├── Weather.qml │ ├── Ydotool.qml │ └── ai │ │ ├── AiMessageData.qml │ │ ├── AiModel.qml │ │ ├── ApiStrategy.qml │ │ ├── GeminiApiStrategy.qml │ │ ├── MistralApiStrategy.qml │ │ └── OpenAiApiStrategy.qml ├── settings.qml ├── shell.qml ├── wallpapers │ ├── Glooe.png │ ├── Gloow.png │ ├── RenderBall.png │ ├── Robohand.png │ ├── SleexBlackSE.png │ ├── SleexFour.png │ ├── SleexFourB.png │ ├── SleexFourSE.png │ ├── SleexOne.png │ ├── SleexThree.png │ ├── SleexThreeSE.png │ ├── SleexTwo.png │ ├── SleexTwoSE.png │ ├── sakura.png │ └── skyline.jpg └── welcome.qml └── wayland-sessions └── sleex.desktop /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Version (please complete the following information):** 27 | - OS: [e.g. AxOS] 28 | - Sleex version: [e.g 1.15-1] 29 | 30 | **Additional context** 31 | Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/sleex1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/.github/sleex1.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.tar.zst 2 | pkg/ -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Sleex 2 | 3 | **Thanks for your interest in contributing to Sleex!** 4 | This project exists because of passionate people like you who want to build a clean, modern, and hackable desktop environment. Contributions of all kinds are welcome—code, documentation, bug reports, or even just good ideas. 5 | 6 | ## 🛠 How to Contribute 7 | ### 1. Reporting Issues 8 | - Use the [issue tracker](https://github.com/axos-project/sleex/issues) 9 | - Be clear and descriptive: explain what you expected to happen vs. what actually happened. 10 | - Include logs, screenshots, or configs if relevant. 11 | - Use labels when possible (bug, enhancement, docs, etc.). 12 | 13 | ### 2. Suggesting Features 14 | 15 | - Check if the idea already exists in the issues or discussions. 16 | - Open a new issue with the `enhancement` label. 17 | - Keep it realistic 18 | 19 | ### 3. Submitting Code 20 | 21 | - Fork the repo and create a feature branch: 22 | 23 | ``` 24 | git checkout -b feature/your-feature 25 | ``` 26 | - Test your changes on a real session before submitting. 27 | - Commit messages should be short and meaningful: 28 | 29 | ``` 30 | feat: add brightness plugin 31 | fix: resolve crash on startup 32 | ``` 33 | - Squash if too many commits have the same purpose 34 | 35 | ### 4. Pull Requests 36 | 37 | - PRs should be focused (one feature/fix per PR). 38 | - Reference the related issue if one exists (Fixes #123). 39 | - Write a summary of what your PR does. 40 | - Expect feedback—reviews are collaborative, not personal. 41 | 42 | ## 🧪 Testing 43 | 44 | - Test locally on Wayland with **Quickshell + Sleex** running. 45 | - Check that no regressions occur in core features (panels, windows, keybindings). 46 | - Automated tests are limited, so manual testing matters a lot. 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | AxOS 3 |

4 | 5 | Sleex is the third desktop environement of AxOS. It is based on Hyprland with Quickshell. 6 | 7 | ## Features 8 | - Fast and lightweight 9 | - AI chat integration with external providers (Gemini, OpenAI...) 10 | - Smooth animations 11 | - Tiling window management for seamless multitasking 12 | - Adaptative color scheme based on the wallpaper 13 | - Ready to use 14 | - Multiple available built in tools 15 | - Looks good 16 | 17 | | | 18 | |------| 19 | | ![preview](preview.mp4) | 20 | 21 | ## Installation 22 | 23 | > [!IMPORTANT] 24 | > If you already have an hyprland config, this will erase it. 25 | 26 | If you are using AxOS, you can simply use epsilon: 27 | ``` 28 | epsi i sleex 29 | ``` 30 | 31 | # Cross distro 32 | 33 | - Clone this repo 34 | - Build every sleex meta-packages in `sleex-packages` then install them 35 | - Build the user configuration in the `sleex-user-config` and copy the user files to your home dir with `cp -r /etc/skel/.config/* ~/.config`. 36 | - Build and install the main package 37 | 38 | Then, you can start sleex by selecting the sleex session on your greeter 39 | 40 | ## License 41 | Sleex is licensed under the GNU General Public License v3.0 42 | 43 | ## Special thanks 44 | - [@end-4](https://github.com/end-4/): Great inspiration | Sleex is based on his work 45 | - [@xHyperVoid](https://github.com/xHyperVoid): Designer | Made the logo and the wallpapers 46 | -------------------------------------------------------------------------------- /preview.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/preview.mp4 -------------------------------------------------------------------------------- /sleex-packages/.gitignore: -------------------------------------------------------------------------------- 1 | /*/*.tar.* 2 | /*/pkg/ 3 | /*/src/ 4 | out/ -------------------------------------------------------------------------------- /sleex-packages/README.md: -------------------------------------------------------------------------------- 1 | # Sleex packages 2 | 3 | Dependency wheel meta-packages for Sleex. 4 | -------------------------------------------------------------------------------- /sleex-packages/build-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | OUTDIR="./out" 6 | mkdir -p "$OUTDIR" 7 | 8 | GREEN='\033[0;32m' 9 | NC='\033[0m' # No Color 10 | 11 | for dir in */; do 12 | [[ -f "${dir}/PKGBUILD" ]] || continue 13 | echo -e "${GREEN}==> Building package in $dir${NC}" 14 | pushd "$dir" > /dev/null 15 | makepkg -fcs --noconfirm 16 | mv ./*.pkg.tar.zst "../$OUTDIR/" 17 | popd > /dev/null 18 | done 19 | 20 | echo -e "${GREEN}✅ All packages built and moved to $OUTDIR${NC}" 21 | notify-send "All packages built" "All packages have been built and moved to $OUTDIR" -a "Sleex packages" -------------------------------------------------------------------------------- /sleex-packages/sleex-bibata-modern-classic-bin/PKGBUILD: -------------------------------------------------------------------------------- 1 | pkgname=sleex-bibata-modern-classic-bin 2 | pkgver=2.0.6 3 | pkgrel=3 4 | pkgdesc="Material Based Cursor Theme, installed for Sleex" 5 | arch=('any') 6 | url="https://github.com/ful1e5/Bibata_Cursor" 7 | license=('GPL-3.0-or-later') 8 | conflicts=("bibata-cursor-theme" "bibata-cursor-theme-bin") 9 | options=('!strip') 10 | _variant=Bibata-Modern-Classic 11 | source=("${pkgname%-bin}-$pkgver.tar.xz::$url/releases/download/v$pkgver/$_variant.tar.xz") 12 | sha256sums=('SKIP') 13 | 14 | package() { 15 | install -dm755 "$pkgdir/usr/share/icons" 16 | cp -dr --no-preserve=mode $_variant "$pkgdir/usr/share/icons" 17 | } 18 | -------------------------------------------------------------------------------- /sleex-packages/sleex-microtex-git/.gitignore: -------------------------------------------------------------------------------- 1 | /MicroTeX/ 2 | -------------------------------------------------------------------------------- /sleex-packages/sleex-microtex-git/PKGBUILD: -------------------------------------------------------------------------------- 1 | pkgname=sleex-microtex-git 2 | _pkgname=MicroTeX 3 | pkgver=r494.0e3707f 4 | pkgrel=3 5 | pkgdesc='MicroTeX for Sleex.' 6 | #pkgdesc="A dynamic, cross-platform, and embeddable LaTeX rendering library" 7 | arch=("x86_64") 8 | url="https://github.com/NanoMichael/${_pkgname}" 9 | license=('MIT') 10 | depends=('tinyxml2' 'gtkmm3' 'gtksourceviewmm' 'cairomm') 11 | makedepends=("git" "cmake") 12 | source=("git+${url}.git") 13 | sha256sums=("SKIP") 14 | 15 | pkgver() { 16 | cd $_pkgname 17 | printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" 18 | } 19 | 20 | build() { 21 | cd $_pkgname 22 | cmake -B build -S . -DCMAKE_BUILD_TYPE=None 23 | cmake --build build 24 | } 25 | 26 | package() { 27 | cd $_pkgname 28 | install -Dm0755 -t "$pkgdir/opt/$_pkgname/" build/LaTeX 29 | cp -r build/res "$pkgdir/opt/$_pkgname/" 30 | install -Dm0644 -t "$pkgdir/usr/share/licenses/$pkgname/" LICENSE 31 | } 32 | -------------------------------------------------------------------------------- /sleex-user-config/.gitignore: -------------------------------------------------------------------------------- 1 | pkg/ 2 | *.tar.* -------------------------------------------------------------------------------- /sleex-user-config/PKGBUILD: -------------------------------------------------------------------------------- 1 | pkgname="sleex-user-config" 2 | pkgver="1.10" 3 | pkgrel="1" 4 | pkgdesc="User configuration for Sleex desktop environment" 5 | arch=("x86_64") 6 | depend=("sleex") 7 | 8 | provides=("axskel-hypr") 9 | replaces=("axskel-hypr") 10 | conflicts=("axskel-hypr") 11 | 12 | package(){ 13 | mkdir -p ${pkgdir}/etc/skel/ 14 | cp -r ${srcdir}/.config/ ${pkgdir}/etc/skel/ 15 | } 16 | -------------------------------------------------------------------------------- /sleex-user-config/README.md: -------------------------------------------------------------------------------- 1 | # axskel-hypr 2 | 3 | `axskel-hypr` is a custom desktop environment setup, featuring the **Hyprland** window manager and pre-configured settings. This package includes configurations for **Hyprland**, alongside several enhancements for usability, aesthetics, and functionality. 4 | 5 |
6 | 7 | After installation, the package deploys configuration files to `/etc/skel`. Customize these files as needed to tailor your desktop environment. 8 | 9 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/Kvantum/kvantum.kvconfig: -------------------------------------------------------------------------------- 1 | [General] 2 | theme=MaterialAdw 3 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/anyrun/config.ron: -------------------------------------------------------------------------------- 1 | Config( 2 | x: Fraction(0.500000), 3 | y: Absolute(15), 4 | width: Fraction(0.300000), 5 | height: Absolute(0), 6 | hide_icons: false, 7 | ignore_exclusive_zones: false, 8 | layer: Overlay, 9 | hide_plugin_info: true, 10 | close_on_click: true, 11 | show_results_immediately: false, 12 | max_entries: None, 13 | ) 14 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/anyrun/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | all: unset; 3 | font-size: 1.3rem; 4 | } 5 | 6 | #window, 7 | #match, 8 | #entry, 9 | #plugin, 10 | #main { 11 | background: transparent; 12 | } 13 | 14 | #match.activatable { 15 | border-radius: 16px; 16 | padding: 0.3rem 0.9rem; 17 | margin-top: 0.01rem; 18 | } 19 | #match.activatable:first-child { 20 | margin-top: 0.7rem; 21 | } 22 | #match.activatable:last-child { 23 | margin-bottom: 0.6rem; 24 | } 25 | 26 | #plugin:hover #match.activatable { 27 | border-radius: 10px; 28 | padding: 0.3rem; 29 | margin-top: 0.01rem; 30 | margin-bottom: 0; 31 | } 32 | 33 | #match:selected, 34 | #match:hover, 35 | #plugin:hover { 36 | background: #2e3131; 37 | } 38 | 39 | #entry { 40 | background: #0b0f10; 41 | border: 1px solid #0b0f10; 42 | border-radius: 16px; 43 | margin: 0.5rem; 44 | padding: 0.3rem 1rem; 45 | } 46 | 47 | list > #plugin { 48 | border-radius: 16px; 49 | margin: 0 0.3rem; 50 | } 51 | list > #plugin:first-child { 52 | margin-top: 0.3rem; 53 | } 54 | list > #plugin:last-child { 55 | margin-bottom: 0.3rem; 56 | } 57 | list > #plugin:hover { 58 | padding: 0.6rem; 59 | } 60 | 61 | box#main { 62 | background: #0b0f10; 63 | box-shadow: inset 0 0 0 1px #0b0f10, 0 0 0 1px #0b0f10; 64 | border-radius: 24px; 65 | padding: 0.3rem; 66 | } 67 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/chrome-flags.conf: -------------------------------------------------------------------------------- 1 | --password-store=gnome-libsecret 2 | --ozone-platform-hint=wayland 3 | --gtk-version=4 4 | --ignore-gpu-blocklist 5 | --enable-features=TouchpadOverscrollHistoryNavigation 6 | --enable-wayland-ime 7 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/code-flags.conf: -------------------------------------------------------------------------------- 1 | --ozone-platform-hint=wayland 2 | --gtk-version=4 3 | --ignore-gpu-blocklist 4 | --enable-features=TouchpadOverscrollHistoryNavigation 5 | --enable-wayland-ime 6 | --password-store=gnome-libsecret 7 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/fish/auto-Hypr.fish: -------------------------------------------------------------------------------- 1 | # Auto start Hyprland on tty1 2 | if test -z "$DISPLAY" ;and test "$XDG_VTNR" -eq 1 3 | mkdir -p ~/.cache 4 | exec Hyprland > ~/.cache/hyprland.log ^&1 5 | end 6 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/fish/config.fish: -------------------------------------------------------------------------------- 1 | function fish_prompt -d "Write out the prompt" 2 | # This shows up as USER@HOST /home/user/ >, with the directory colored 3 | # $USER and $hostname are set by fish, so you can just use them 4 | # instead of using `whoami` and `hostname` 5 | printf '%s@%s %s%s%s > ' $USER $hostname \ 6 | (set_color $fish_color_cwd) (prompt_pwd) (set_color normal) 7 | end 8 | 9 | if status is-interactive 10 | # Commands to run in interactive sessions can go here 11 | set fish_greeting 12 | 13 | end 14 | 15 | starship init fish | source 16 | if test -f ~/.local/state/sleex/user/generated/terminal/sequences.txt 17 | cat ~/.local/state/sleex/user/generated/terminal/sequences.txt 18 | end 19 | 20 | alias pamcan pacman 21 | alias ls 'eza --icons' 22 | alias clear "printf '\033[2J\033[3J\033[1;1H'" 23 | 24 | 25 | # function fish_prompt 26 | # set_color cyan; echo (pwd) 27 | # set_color green; echo '> ' 28 | # end 29 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/fish/fish_variables: -------------------------------------------------------------------------------- 1 | # This file contains fish universal variable definitions. 2 | # VERSION: 3.0 3 | SETUVAR __fish_initialized:3400 4 | SETUVAR _fisher_jorgebucaran_2F_fisher_files:\x7e/\x2econfig/fish/functions/fisher\x2efish\x1e\x7e/\x2econfig/fish/completions/fisher\x2efish 5 | SETUVAR _fisher_plugins:jorgebucaran/fisher 6 | SETUVAR _fisher_upgraded_to_4_4:\x1d 7 | SETUVAR fish_color_autosuggestion:555\x1ebrblack 8 | SETUVAR fish_color_cancel:\x2dr 9 | SETUVAR fish_color_command:blue 10 | SETUVAR fish_color_comment:red 11 | SETUVAR fish_color_cwd:green 12 | SETUVAR fish_color_cwd_root:red 13 | SETUVAR fish_color_end:green 14 | SETUVAR fish_color_error:brred 15 | SETUVAR fish_color_escape:brcyan 16 | SETUVAR fish_color_history_current:\x2d\x2dbold 17 | SETUVAR fish_color_host:normal 18 | SETUVAR fish_color_host_remote:yellow 19 | SETUVAR fish_color_normal:normal 20 | SETUVAR fish_color_operator:brcyan 21 | SETUVAR fish_color_param:cyan 22 | SETUVAR fish_color_quote:yellow 23 | SETUVAR fish_color_redirection:cyan\x1e\x2d\x2dbold 24 | SETUVAR fish_color_search_match:\x2d\x2dbackground\x3d111 25 | SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack 26 | SETUVAR fish_color_status:red 27 | SETUVAR fish_color_user:brgreen 28 | SETUVAR fish_color_valid_path:\x2d\x2dunderline 29 | SETUVAR fish_key_bindings:fish_default_key_bindings 30 | SETUVAR fish_pager_color_completion:normal 31 | SETUVAR fish_pager_color_description:B3A06D\x1eyellow\x1e\x2di 32 | SETUVAR fish_pager_color_prefix:cyan\x1e\x2d\x2dbold\x1e\x2d\x2dunderline 33 | SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan 34 | SETUVAR fish_pager_color_selected_background:\x2dr 35 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/fontconfig/conf.d: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | none 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/foot/foot.ini: -------------------------------------------------------------------------------- 1 | shell=fish 2 | term=xterm-256color 3 | 4 | title=foot 5 | 6 | font=JetBrainsMono Nerd Font:size=11 7 | letter-spacing=0 8 | dpi-aware=no 9 | 10 | pad=25x25 11 | 12 | bold-text-in-bright=no 13 | 14 | [scrollback] 15 | lines=10000 16 | 17 | [cursor] 18 | style=beam 19 | blink=no 20 | beam-thickness=1.5 21 | # underline-thickness= 22 | 23 | [key-bindings] 24 | scrollback-up-page=Page_Up 25 | scrollback-down-page=Page_Down 26 | clipboard-copy=Control+c 27 | clipboard-paste=Control+v 28 | # primary-paste=Shift+Insert 29 | search-start=Control+f 30 | font-increase=Control+plus Control+equal Control+KP_Add 31 | font-decrease=Control+minus Control+KP_Subtract 32 | font-reset=Control+0 Control+KP_0 33 | 34 | [search-bindings] 35 | cancel=Escape 36 | find-prev=Shift+F3 37 | find-next=F3 Control+G 38 | delete-prev-word=Control+BackSpace 39 | 40 | [text-bindings] 41 | \x03=Control+Shift+c 42 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/fuzzel/fuzzel.ini: -------------------------------------------------------------------------------- 1 | include="~/.config/fuzzel/fuzzel_theme.ini" 2 | font=Gabarito 3 | terminal=kitty -1 4 | prompt=">> " 5 | layer=overlay 6 | 7 | [border] 8 | radius=17 9 | width=1 10 | 11 | [dmenu] 12 | exit-immediately-if-empty=yes 13 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/fuzzel/fuzzel_theme.ini: -------------------------------------------------------------------------------- 1 | [colors] 2 | background=161217ff 3 | text=e9e0e8ff 4 | selection=4b454dff 5 | selection-text=cdc3ceff 6 | border=4b454ddd 7 | match=dfb8f6ff 8 | selection-match=dfb8f6ff 9 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/apps.conf: -------------------------------------------------------------------------------- 1 | #! 2 | ##! Apps 3 | bind = Super, Return, exec, # Launch foot (terminal) 4 | bind = Super, C, exec, code --password-store=gnome --enable-features=UseOzonePlatform --ozone-platform=wayland # Launch VSCode (editor) 5 | bind = Super, E, exec, pcmanfm-qt # Launch file manager 6 | bind = Super, W, exec, firefox # launch Firefox 7 | bind = Super, X, exec, kwrite # Launch Text Editor 8 | bind = Super, I, exec, qs -p /usr/share/sleex/settings.qml # Launch Sleex Settings 9 | bind = Ctrl+Super, V, exec, pavucontrol # Launch pavucontrol (volume mixer) 10 | bind = Ctrl+Super+Shift, V, exec, easyeffects # Launch EasyEffects (equalizer & other audio effects) 11 | bind = Ctrl+Shift, Escape, exec, missioncenter # Launch System monitor 12 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/custom/env.conf: -------------------------------------------------------------------------------- 1 | # You can put extra environment variables here 2 | # https://wiki.hyprland.org/Configuring/Environment-variables/ 3 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/custom/execs.conf: -------------------------------------------------------------------------------- 1 | # You can make apps auto-start here 2 | # Relevant Hyprland wiki section: https://wiki.hyprland.org/Configuring/Keywords/#executing 3 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/custom/general.conf: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/custom/keybinds.conf: -------------------------------------------------------------------------------- 1 | # You can put your preferred keybinds here 2 | # https://wiki.hyprland.org/Configuring/Binds/ 3 | 4 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/custom/rules.conf: -------------------------------------------------------------------------------- 1 | # You can put custom rules here 2 | # Window/layer rules: https://wiki.hyprland.org/Configuring/Window-Rules/ 3 | # Workspace rules: https://wiki.hyprland.org/Configuring/Workspace-Rules/ 4 | 5 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/custom/scripts/__restore_video_wallpaper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # The content of this script will be generated by switchwall.sh - Don't modify it by yourself. 3 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/hypridle.conf: -------------------------------------------------------------------------------- 1 | general { 2 | lock_cmd = qs -p /usr/share/sleex ipc call lock lock 3 | before_sleep_cmd = qs -p /usr/share/sleex ipc call lock lock # lock before suspend. 4 | after_sleep_cmd = hyprctl dispatch dpms on # to avoid having to press a key twice to turn on the display. 5 | } 6 | 7 | listener { 8 | timeout = 60 # 1min. 9 | on-timeout = brightnessctl -s set 10 # set monitor backlight to minimum, avoid 0 on OLED monitor. 10 | on-resume = brightnessctl -r # monitor backlight restore. 11 | } 12 | 13 | # turn off keyboard backlight if present (auto-detect device) 14 | listener { 15 | timeout = 180 # 3min. 16 | on-timeout = KBD=$(ls /sys/class/leds | grep -i kbd_backlight | head -n1) && \ 17 | [ -n "$KBD" ] && brightnessctl -sd "$KBD" set 0 18 | on-resume = KBD=$(ls /sys/class/leds | grep -i kbd_backlight | head -n1) && \ 19 | [ -n "$KBD" ] && brightnessctl -rd "$KBD" 20 | } 21 | 22 | listener { 23 | timeout = 300 # 5min. 24 | on-timeout = qs -p /usr/share/sleex ipc call lock lock # lock screen when timeout has passed 25 | } 26 | 27 | listener { 28 | timeout = 220 # 3min, 40sec 29 | on-timeout = hyprctl dispatch dpms off # screen off when timeout has passed 30 | on-resume = hyprctl dispatch dpms on && brightnessctl -r # screen on when activity is detected after timeout has fired. 31 | } 32 | 33 | listener { 34 | timeout = 600 # 10min 35 | on-timeout = systemctl suspend # suspend pc 36 | } 37 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/hyprland.conf: -------------------------------------------------------------------------------- 1 | # This file sources other files in `hyprland` and `custom` folders 2 | # You wanna add your stuff in file in `custom` 3 | exec = hyprctl dispatch submap global 4 | submap = global 5 | # Defaults 6 | source=~/.config/hypr/hyprland/env.conf 7 | source=~/.config/hypr/hyprland/execs.conf 8 | source=~/.config/hypr/hyprland/general.conf 9 | source=~/.config/hypr/hyprland/rules.conf 10 | source=~/.config/hypr/hyprland/colors.conf 11 | source=~/.config/hypr/hyprland/keybinds.conf 12 | 13 | # Custom 14 | source=~/.config/hypr/custom/env.conf 15 | source=~/.config/hypr/custom/execs.conf 16 | source=~/.config/hypr/custom/general.conf 17 | source=~/.config/hypr/custom/rules.conf 18 | source=~/.config/hypr/custom/keybinds.conf 19 | 20 | source=~/.config/hypr/monitors.conf 21 | 22 | # Applications bindings 23 | source=~/.config/hypr/apps.conf -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/hyprland/colors.conf: -------------------------------------------------------------------------------- 1 | general { 2 | col.active_border = rgba(dfe3e739) 3 | col.inactive_border = rgba(8b919830) 4 | } 5 | 6 | misc { 7 | background_color = rgba(101417FF) 8 | } 9 | 10 | plugin { 11 | hyprbars { 12 | # Honestly idk if it works like css, but well, why not 13 | bar_text_font = Rubik, Geist, AR One Sans, Reddit Sans, Inter, Roboto, Ubuntu, Noto Sans, sans-serif 14 | bar_height = 30 15 | bar_padding = 10 16 | bar_button_padding = 5 17 | bar_precedence_over_border = true 18 | bar_part_of_window = true 19 | 20 | bar_color = rgba(101417FF) 21 | col.text = rgba(dfe3e7FF) 22 | 23 | 24 | # example buttons (R -> L) 25 | # hyprbars-button = color, size, on-click 26 | hyprbars-button = rgb(dfe3e7), 13, 󰖭, hyprctl dispatch killactive 27 | hyprbars-button = rgb(dfe3e7), 13, 󰖯, hyprctl dispatch fullscreen 1 28 | hyprbars-button = rgb(dfe3e7), 13, 󰖰, hyprctl dispatch movetoworkspacesilent special 29 | } 30 | } 31 | 32 | windowrulev2 = bordercolor rgba(93cdf6AA) rgba(93cdf677),pinned:1 33 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/hyprland/env.conf: -------------------------------------------------------------------------------- 1 | # ######### Input method ########## 2 | # See https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland 3 | env = QT_IM_MODULE, fcitx 4 | env = XMODIFIERS, @im=fcitx 5 | # env = GTK_IM_MODULE, wayland # Crashes electron apps in xwayland 6 | env = SDL_IM_MODULE, fcitx 7 | env = GLFW_IM_MODULE, ibus 8 | env = INPUT_METHOD, fcitx 9 | 10 | # ############ Themes ############# 11 | env = QT_QPA_PLATFORM, wayland 12 | env = QT_QPA_PLATFORMTHEME, kde 13 | env = QT_STYLE_OVERRIDE,kvantum 14 | # env = WLR_NO_HARDWARE_CURSORS, 1 15 | 16 | env = XDG_SESSION_TYPE, wayland 17 | env = GDK_BACKEND, wayland 18 | env = QT_QPA_PLATFORM, wayland 19 | env = SDL_VIDEODRIVER, wayland 20 | env = CLUTTER_BACKEND, wayland 21 | env = MOZ_ENABLE_WAYLAND, 1 22 | 23 | # ######## Screen tearing ######### 24 | # env = WLR_DRM_NO_ATOMIC, 1 25 | 26 | # ############ Others ############# 27 | 28 | env = SLEEX_VIRTUAL_ENV, ~/.local/state/sleex/.venv 29 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/hyprland/execs.conf: -------------------------------------------------------------------------------- 1 | # Bar, wallpaper 2 | # exec-once = swww-daemon 3 | exec-once = qs -p /usr/share/sleex & 4 | 5 | # Core components (authentication, lock screen, notification daemon) 6 | exec-once = gnome-keyring-daemon --start --components=secrets 7 | exec-once = /usr/lib/polkit-gnome/polkit-gnome-authentication-agent-1 || /usr/libexec/polkit-gnome-authentication-agent-1 8 | exec-once = hypridle 9 | exec-once = dbus-update-activation-environment --all 10 | exec-once = sleep 1 && dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP # Some fix idk 11 | 12 | # Audio 13 | exec-once = easyeffects --gapplication-service 14 | 15 | # Clipboard: history 16 | # exec-once = wl-paste --watch cliphist store & 17 | exec-once = wl-paste --type text --watch cliphist store 18 | exec-once = wl-paste --type image --watch cliphist store 19 | 20 | # Cursor 21 | exec-once = hyprctl setcursor Bibata-Modern-Classic 24 22 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/monitors.conf: -------------------------------------------------------------------------------- 1 | # Generated by nwg-displays on 2025-06-09 at 12:05:41. Do not edit manually, use `nwg-displays` instead. 2 | 3 | monitor=,preferred,auto,1 4 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/hypr/workspaces.conf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/sleex-user-config/src/.config/hypr/workspaces.conf -------------------------------------------------------------------------------- /sleex-user-config/src/.config/kitty/kitty.conf: -------------------------------------------------------------------------------- 1 | # Font 2 | font_family JetBrains Mono Nerd Font 3 | font_size 11.0 4 | 5 | # Cursor 6 | cursor_shape beam 7 | cursor_trail 1 8 | 9 | # Padding (why weird value? consistency with foot) 10 | window_margin_width 21.75 11 | 12 | # No stupid close confirmation 13 | confirm_os_window_close 0 14 | 15 | # Use fish shell 16 | shell fish 17 | 18 | # Copy 19 | map ctrl+c copy_or_interrupt 20 | 21 | # Search 22 | map ctrl+f launch --location=hsplit --allow-remote-control kitty +kitten search.py @active-kitty-window-id 23 | map kitty_mod+f launch --location=hsplit --allow-remote-control kitty +kitten search.py @active-kitty-window-id 24 | 25 | # Scroll & Zoom 26 | map page_up scroll_page_up 27 | map page_down scroll_page_down 28 | 29 | map ctrl+plus change_font_size all +1 30 | map ctrl+equal change_font_size all +1 31 | map ctrl+kp_add change_font_size all +1 32 | map ctrl+minus change_font_size all -1 33 | map ctrl+underscore change_font_size all -1 34 | map ctrl+kp_subtract change_font_size all -1 35 | map ctrl+0 change_font_size all 0 36 | map ctrl+kp_0 change_font_size all 0 37 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/kitty/scroll_mark.py: -------------------------------------------------------------------------------- 1 | from kittens.tui.handler import result_handler 2 | from kitty.boss import Boss 3 | 4 | 5 | def main(args: list[str]) -> None: 6 | pass 7 | 8 | 9 | @result_handler(no_ui=True) 10 | def handle_result( 11 | args: list[str], answer: str, target_window_id: int, boss: Boss 12 | ) -> None: 13 | w = boss.window_id_map.get(target_window_id) 14 | if w is not None: 15 | if len(args) > 1 and args[1] != "prev": 16 | w.scroll_to_mark(prev=False) 17 | else: 18 | w.scroll_to_mark() 19 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/matugen/config.toml: -------------------------------------------------------------------------------- 1 | [config] 2 | version_check = false 3 | 4 | [templates.m3colors] 5 | input_path = '~/.config/matugen/templates/colors.json' 6 | output_path = '~/.local/state/sleex/user/generated/colors.json' 7 | 8 | [templates.hyprland] 9 | input_path = '~/.config/matugen/templates/hyprland/colors.conf' 10 | output_path = '~/.config/hypr/hyprland/colors.conf' 11 | 12 | [templates.hyprlock] 13 | input_path = '~/.config/matugen/templates/hyprland/hyprlock.conf' 14 | output_path = '~/.config/hypr/hyprlock.conf' 15 | 16 | [templates.fuzzel] 17 | input_path = '~/.config/matugen/templates/fuzzel/fuzzel_theme.ini' 18 | output_path = '~/.config/fuzzel/fuzzel_theme.ini' 19 | 20 | [templates.gtk3] 21 | input_path = '~/.config/matugen/templates/gtk/gtk-colors.css' 22 | output_path = '~/.config/gtk-3.0/gtk.css' 23 | 24 | [templates.gtk4] 25 | input_path = '~/.config/matugen/templates/gtk/gtk-colors.css' 26 | output_path = '~/.config/gtk-4.0/gtk.css' 27 | 28 | [templates.kde_colors] 29 | input_path = '~/.config/matugen/templates/kde/color.txt' 30 | output_path = '~/.local/state/sleex/user/generated/color.txt' 31 | 32 | [templates.wallpaper] 33 | input_path = '~/.config/matugen/templates/wallpaper.txt' 34 | output_path = '~/.local/state/sleex/user/generated/wallpaper/path.txt' 35 | 36 | [templates.discord] 37 | input_path = '~/.config/matugen/templates/discord.css' 38 | output_path = '~/.config/vesktop/themes/discord.css' 39 | 40 | [templates.vscode] 41 | input_path = '~/.config/matugen/templates/vscode.json' 42 | output_path = "~/.vscode/extensions/sleex-theme/themes/sleex.json" 43 | 44 | [templates.zed] 45 | input_path = '~/.config/matugen/templates/zed.json' 46 | output_path = "~/.config/zed/themes/sleex.json" 47 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/matugen/templates/fuzzel/fuzzel_theme.ini: -------------------------------------------------------------------------------- 1 | [colors] 2 | background={{colors.background.default.hex_stripped}}ff 3 | text={{colors.on_background.default.hex_stripped}}ff 4 | selection={{colors.surface_variant.default.hex_stripped}}ff 5 | selection-text={{colors.on_surface_variant.default.hex_stripped}}ff 6 | border={{colors.surface_variant.default.hex_stripped}}dd 7 | match={{colors.primary.default.hex_stripped}}ff 8 | selection-match={{colors.primary.default.hex_stripped}}ff 9 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/matugen/templates/gtk/gtk-colors.css: -------------------------------------------------------------------------------- 1 | /* 2 | * GTK Colors 3 | * Generated with Matugen 4 | */ 5 | 6 | @define-color accent_color {{colors.primary.default.hex}}; 7 | @define-color accent_fg_color {{colors.on_primary.default.hex}}; 8 | @define-color accent_bg_color {{colors.primary.default.hex}}; 9 | @define-color window_bg_color {{colors.background.default.hex}}; 10 | @define-color window_fg_color {{colors.on_background.default.hex}}; 11 | @define-color headerbar_bg_color {{colors.surface_dim.default.hex}}; 12 | @define-color headerbar_fg_color {{colors.on_surface.default.hex}}; 13 | @define-color popover_bg_color {{colors.surface_dim.default.hex}}; 14 | @define-color popover_fg_color {{colors.on_surface.default.hex}}; 15 | @define-color view_bg_color {{colors.surface.default.hex}}; 16 | @define-color view_fg_color {{colors.on_surface.default.hex}}; 17 | @define-color card_bg_color {{colors.surface.default.hex}}; 18 | @define-color card_fg_color {{colors.on_surface.default.hex}}; 19 | @define-color sidebar_bg_color @window_bg_color; 20 | @define-color sidebar_fg_color @window_fg_color; 21 | @define-color sidebar_border_color @window_bg_color; 22 | @define-color sidebar_backdrop_color @window_bg_color; 23 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/matugen/templates/hyprland/colors.conf: -------------------------------------------------------------------------------- 1 | general { 2 | col.active_border = rgba({{colors.on_surface.default.hex_stripped}}39) 3 | col.inactive_border = rgba({{colors.outline.default.hex_stripped}}30) 4 | } 5 | 6 | misc { 7 | background_color = rgba({{colors.surface.dark.hex_stripped}}FF) 8 | } 9 | 10 | plugin { 11 | hyprbars { 12 | # Honestly idk if it works like css, but well, why not 13 | bar_text_font = Rubik, Geist, AR One Sans, Reddit Sans, Inter, Roboto, Ubuntu, Noto Sans, sans-serif 14 | bar_height = 30 15 | bar_padding = 10 16 | bar_button_padding = 5 17 | bar_precedence_over_border = true 18 | bar_part_of_window = true 19 | 20 | bar_color = rgba({{colors.background.default.hex_stripped}}FF) 21 | col.text = rgba({{colors.on_background.default.hex_stripped}}FF) 22 | 23 | 24 | # example buttons (R -> L) 25 | # hyprbars-button = color, size, on-click 26 | hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖭, hyprctl dispatch killactive 27 | hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖯, hyprctl dispatch fullscreen 1 28 | hyprbars-button = rgb({{colors.on_background.default.hex_stripped}}), 13, 󰖰, hyprctl dispatch movetoworkspacesilent special 29 | } 30 | } 31 | 32 | windowrulev2 = bordercolor rgba({{colors.primary.default.hex_stripped}}AA) rgba({{colors.primary.default.hex_stripped}}77),pinned:1 33 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/matugen/templates/kde/color.txt: -------------------------------------------------------------------------------- 1 | {{colors.source_color.default.hex}} -------------------------------------------------------------------------------- /sleex-user-config/src/.config/matugen/templates/kde/kde-material-you-colors-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}" 4 | 5 | color=$(tr -d '\n' < "$XDG_STATE_HOME/sleex/user/generated/color.txt") 6 | 7 | current_mode=$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | tr -d "'") 8 | if [[ "$current_mode" == "prefer-dark" ]]; then 9 | mode_flag="-d" 10 | else 11 | mode_flag="-l" 12 | fi 13 | 14 | # Parse --scheme-variant flag 15 | scheme_variant_str="" 16 | while [[ $# -gt 0 ]]; do 17 | case "$1" in 18 | --scheme-variant) 19 | scheme_variant_str="$2" 20 | shift 2 21 | ;; 22 | *) 23 | shift 24 | ;; 25 | esac 26 | done 27 | 28 | # Map string variant to integer 29 | case "$scheme_variant_str" in 30 | scheme-content) sv_num=0 ;; 31 | scheme-expressive) sv_num=1 ;; 32 | scheme-fidelity) sv_num=2 ;; 33 | scheme-monochrome) sv_num=3 ;; 34 | scheme-neutral) sv_num=4 ;; 35 | scheme-tonal-spot) sv_num=5 ;; 36 | scheme-vibrant) sv_num=6 ;; 37 | scheme-rainbow) sv_num=7 ;; 38 | scheme-fruit-salad) sv_num=8 ;; 39 | "") sv_num=5 ;; 40 | *) 41 | echo "Unknown scheme variant: $scheme_variant_str" >&2 42 | exit 1 43 | ;; 44 | esac 45 | 46 | kde-material-you-colors "$mode_flag" --color "$color" -sv "$sv_num" 47 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/matugen/templates/wallpaper.txt: -------------------------------------------------------------------------------- 1 | {{image}} 2 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/mpv/mpv.conf: -------------------------------------------------------------------------------- 1 | keep-open=yes -------------------------------------------------------------------------------- /sleex-user-config/src/.config/qt5ct/qt5ct.conf: -------------------------------------------------------------------------------- 1 | [Appearance] 2 | color_scheme_path=/usr/share/qt5ct/colors/darker.conf 3 | custom_palette=true 4 | icon_theme=Papirus 5 | standard_dialogs=default 6 | style=kvantum-dark 7 | 8 | [Fonts] 9 | fixed="JetBrainsMono Nerd Font,11,-1,5,50,0,0,0,0,0,Regular" 10 | general="Rubik,11,-1,5,50,0,0,0,0,0" 11 | 12 | [Interface] 13 | activate_item_on_single_click=1 14 | buttonbox_layout=0 15 | cursor_flash_time=1000 16 | dialog_buttons_have_icons=1 17 | double_click_interval=400 18 | gui_effects=General 19 | keyboard_scheme=2 20 | menus_have_icons=true 21 | show_shortcuts_in_context_menus=true 22 | stylesheets=@Invalid() 23 | toolbutton_style=4 24 | underline_shortcut=1 25 | wheel_scroll_lines=3 26 | 27 | [SettingsWindow] 28 | geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\x4\x98\0\0\x3\x99\0\0\0\0\0\0\0\0\0\0\x2\xde\0\0\x3\x1\0\0\0\0\x2\0\0\0\a\x80\0\0\0\0\0\0\0\0\0\0\x4\x98\0\0\x3\x99) 29 | 30 | [Troubleshooting] 31 | force_raster_widgets=1 32 | ignored_applications=@Invalid() 33 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/qt6ct/qt6ct.conf: -------------------------------------------------------------------------------- 1 | [Appearance] 2 | color_scheme_path=/home/end/.config/qt6ct/style-colors.conf 3 | custom_palette=true 4 | icon_theme=Papirus 5 | standard_dialogs=default 6 | style=kvantum 7 | 8 | [Fonts] 9 | fixed="JetBrainsMono Nerd Font,11,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 10 | general="Rubik,11,-1,5,400,0,0,0,0,0,0,0,0,0,0,1,Regular" 11 | 12 | [Interface] 13 | activate_item_on_single_click=1 14 | buttonbox_layout=0 15 | cursor_flash_time=1000 16 | dialog_buttons_have_icons=1 17 | double_click_interval=400 18 | gui_effects=@Invalid() 19 | keyboard_scheme=2 20 | menus_have_icons=true 21 | show_shortcuts_in_context_menus=true 22 | stylesheets=@Invalid() 23 | toolbutton_style=4 24 | underline_shortcut=1 25 | wheel_scroll_lines=3 26 | 27 | [SettingsWindow] 28 | geometry=@ByteArray(\x1\xd9\xd0\xcb\0\x3\0\0\0\0\0\0\0\0\0\0\0\0\as\0\0\x4\x3\0\0\0\0\0\0\0\0\0\0\as\0\0\x4\x3\0\0\0\0\x2\0\0\0\a\x80\0\0\0\0\0\0\0\0\0\0\as\0\0\x4\x3) 29 | 30 | [Troubleshooting] 31 | force_raster_widgets=1 32 | ignored_applications=@Invalid() 33 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/thorium-flags.conf: -------------------------------------------------------------------------------- 1 | --password-store=gnome-libsecret 2 | --ozone-platform-hint=wayland 3 | --gtk-version=4 4 | --ignore-gpu-blocklist 5 | --enable-features=TouchpadOverscrollHistoryNavigation 6 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/wlogout/layout: -------------------------------------------------------------------------------- 1 | { 2 | "label" : "lock", 3 | "action" : "loginctl lock-session", 4 | "text" : "lock", 5 | "keybind" : "l" 6 | } 7 | { 8 | "label" : "hibernate", 9 | "action" : "systemctl hibernate || loginctl hibernate", 10 | "text" : "save", 11 | "keybind" : "h" 12 | } 13 | { 14 | "label" : "logout", 15 | "action" : "pkill Hyprland || pkill sway || pkill niri || loginctl terminate-user $USER", 16 | "text" : "logout", 17 | "keybind" : "e" 18 | } 19 | { 20 | "label" : "shutdown", 21 | "action" : "systemctl poweroff || loginctl poweroff", 22 | "text" : "power_settings_new", 23 | "keybind" : "s" 24 | } 25 | { 26 | "label" : "suspend", 27 | "action" : "systemctl suspend || loginctl suspend", 28 | "text" : "bedtime", 29 | "keybind" : "u" 30 | } 31 | { 32 | "label" : "reboot", 33 | "action" : "systemctl reboot || loginctl reboot", 34 | "text" : "restart_alt", 35 | "keybind" : "r" 36 | } 37 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/wlogout/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | all: unset; 3 | background-image: none; 4 | transition: 400ms cubic-bezier(0.05, 0.7, 0.1, 1); 5 | } 6 | 7 | window { 8 | background: rgba(0, 0, 0, 0.5); 9 | } 10 | 11 | button { 12 | font-family: 'Material Symbols Outlined'; 13 | font-size: 10rem; 14 | background-color: rgba(11, 11, 11, 0.4); 15 | color: #FFFFFF; 16 | margin: 2rem; 17 | border-radius: 2rem; 18 | padding: 3rem; 19 | } 20 | 21 | button:focus, 22 | button:active, 23 | button:hover { 24 | background-color: rgba(51, 51, 51, 0.5); 25 | border-radius: 4rem; 26 | } -------------------------------------------------------------------------------- /sleex-user-config/src/.config/xdg-desktop-portal/hyprland-portals.conf: -------------------------------------------------------------------------------- 1 | [preferred] 2 | default = hyprland;gtk 3 | org.freedesktop.impl.portal.FileChooser = kde 4 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/zshrc.d/auto-Hypr.sh: -------------------------------------------------------------------------------- 1 | # Auto start Hyprland on tty1 2 | if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" -eq 1 ]; then 3 | mkdir -p ~/.cache 4 | exec Hyprland > ~/.cache/hyprland.log 2>&1 5 | fi 6 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/zshrc.d/dots-hyprland.zsh: -------------------------------------------------------------------------------- 1 | # Use the generated color scheme 2 | 3 | if test -f ~/.local/state/sleex/user/generated/terminal/sequences.txt; then 4 | cat ~/.local/state/sleex/user/generated/terminal/sequences.txt 5 | fi 6 | -------------------------------------------------------------------------------- /sleex-user-config/src/.config/zshrc.d/shortcuts.zsh: -------------------------------------------------------------------------------- 1 | # Created by newuser for 5.9 2 | 3 | bindkey '^H' backward-kill-word 4 | bindkey '^Z' undo 5 | -------------------------------------------------------------------------------- /src/bin/rubyshot: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | WORKSPACES="$(hyprctl monitors -j | jq -r 'map(.activeWorkspace.id)')" 4 | WINDOWS="$(hyprctl clients -j | jq -r --argjson workspaces "$WORKSPACES" 'map(select([.workspace.id] | inside($workspaces)))' )" 5 | GEOM=$(echo "$WINDOWS" | jq -r '.[] | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1])"' | slurp -f '%x %y %w %h') 6 | wayshot -s "$GEOM" --stdout ${#:+"$@"} -------------------------------------------------------------------------------- /src/bin/sleex: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | export XDG_CURRENT_DESKTOP="Sleex" 3 | export HYPRLAND_INSTANCE_SIGNATURE="" 4 | systemctl --user import-environment XDG_CURRENT_DESKTOP 5 | Hyprland 6 | -------------------------------------------------------------------------------- /src/share/sleex/.gitignore: -------------------------------------------------------------------------------- 1 | .qmlls.ini 2 | .qt/ 3 | .rcc/ 4 | .vscode 5 | build/ 6 | CMakeFiles/ 7 | CMakeCache.txt 8 | cmake_install.cmake 9 | Makefile 10 | qml/ -------------------------------------------------------------------------------- /src/share/sleex/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.19) 2 | 3 | project(sleex VERSION 1.15 LANGUAGES CXX) 4 | 5 | set(CMAKE_CXX_STANDARD 20) 6 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 7 | set(CMAKE_CXX_EXTENSIONS OFF) 8 | set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") 9 | set(CMAKE_INSTALL_PREFIX "/") 10 | 11 | set(DISTRIBUTOR "Unset" CACHE STRING "Distributor") 12 | set(INSTALL_LIBDIR "usr/lib/sleex" CACHE STRING "Library install dir") 13 | set(INSTALL_QMLDIR "usr/lib/qt6/qml" CACHE STRING "QML install dir") 14 | 15 | add_subdirectory(plugins) 16 | -------------------------------------------------------------------------------- /src/share/sleex/assets/icons/ai-openai-symbolic.svg: -------------------------------------------------------------------------------- 1 | openai-symbolic.svg -------------------------------------------------------------------------------- /src/share/sleex/assets/icons/cloudflare-dns-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/share/sleex/assets/icons/desktop-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/share/sleex/assets/icons/google-gemini-symbolic.svg: -------------------------------------------------------------------------------- 1 | spark-symbolic.svg -------------------------------------------------------------------------------- /src/share/sleex/assets/icons/microsoft-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 14 | 16 | 34 | 39 | 44 | 49 | 54 | 55 | -------------------------------------------------------------------------------- /src/share/sleex/assets/icons/mona-loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/icons/mona-loading.gif -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/1024px/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/1024px/black.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/1024px/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/1024px/dark.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/1024px/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/1024px/light.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/1024px/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/1024px/white.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/128px/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/128px/black.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/128px/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/128px/dark.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/128px/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/128px/light.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/128px/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/128px/white.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/256px/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/256px/black.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/256px/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/256px/dark.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/256px/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/256px/light.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/256px/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/256px/white.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/512px/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/512px/black.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/512px/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/512px/dark.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/512px/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/512px/light.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/512px/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/512px/white.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/logotype/black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/logotype/black.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/logotype/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/logotype/dark.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/logotype/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/logotype/light.png -------------------------------------------------------------------------------- /src/share/sleex/assets/logo/logotype/white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/logo/logotype/white.png -------------------------------------------------------------------------------- /src/share/sleex/assets/sounds/battery/01_full.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/sounds/battery/01_full.wav -------------------------------------------------------------------------------- /src/share/sleex/assets/sounds/battery/02_plug.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/sounds/battery/02_plug.wav -------------------------------------------------------------------------------- /src/share/sleex/assets/sounds/battery/02_unplug.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/sounds/battery/02_unplug.wav -------------------------------------------------------------------------------- /src/share/sleex/assets/sounds/battery/04_warn.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/sounds/battery/04_warn.wav -------------------------------------------------------------------------------- /src/share/sleex/assets/sounds/battery/05_critical.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/assets/sounds/battery/05_critical.wav -------------------------------------------------------------------------------- /src/share/sleex/modules/background/Quote.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import Quickshell 4 | import Quickshell.Wayland 5 | import Quickshell.Io 6 | import qs.services 7 | 8 | // System version watermark display 9 | Item { 10 | id: root 11 | property bool visibleQuote: true 12 | property int marginLeft: 30 13 | property int marginBottom: 30 14 | 15 | // Set explicit size to contain the content 16 | width: quoteContent.implicitWidth 17 | height: quoteContent.implicitHeight 18 | 19 | anchors { 20 | left: parent.left 21 | bottom: parent.bottom 22 | leftMargin: marginLeft 23 | bottomMargin: marginBottom 24 | } 25 | 26 | visible: visibleQuote 27 | 28 | RowLayout { 29 | id: quoteContent 30 | spacing: 16 31 | 32 | anchors { 33 | left: parent.left 34 | bottom: parent.bottom 35 | } 36 | 37 | ColumnLayout { 38 | spacing: 2 39 | 40 | Text { 41 | text: Quotes.quote 42 | color: "#40ffffff" 43 | font.pointSize: 14 44 | font.weight: Font.DemiBold 45 | } 46 | 47 | Text { 48 | text: "- " + Quotes.author 49 | color: "#30ffffff" 50 | font.pointSize: 10 51 | font.weight: Font.Medium 52 | visible: text.length > 0 53 | } 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/ActiveWindow.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | import QtQuick.Layouts 5 | import Quickshell.Wayland 6 | import Quickshell.Hyprland 7 | 8 | Item { 9 | id: root 10 | required property var bar 11 | readonly property HyprlandMonitor monitor: Hyprland.monitorFor(bar.screen) 12 | readonly property Toplevel activeWindow: ToplevelManager.activeToplevel 13 | 14 | implicitWidth: colLayout.implicitWidth 15 | 16 | ColumnLayout { 17 | id: colLayout 18 | 19 | anchors.verticalCenter: parent.verticalCenter 20 | anchors.left: parent.left 21 | anchors.right: parent.right 22 | spacing: -4 23 | 24 | StyledText { 25 | Layout.fillWidth: true 26 | font.pixelSize: Appearance.font.pixelSize.smaller 27 | color: Appearance.colors.colSubtext 28 | elide: Text.ElideRight 29 | text: root.activeWindow?.activated ? root.activeWindow?.appId : qsTr("Desktop") 30 | } 31 | 32 | StyledText { 33 | Layout.fillWidth: true 34 | font.pixelSize: Appearance.font.pixelSize.small 35 | color: Appearance.colors.colOnLayer0 36 | elide: Text.ElideRight 37 | text: root.activeWindow?.activated ? root.activeWindow?.title : `${qsTr("Workspace")} ${monitor.activeWorkspace?.id}` 38 | } 39 | 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/AudioOsd.qml: -------------------------------------------------------------------------------- 1 | import Quickshell 2 | import Quickshell.Hyprland 3 | import QtQuick.Layouts 4 | import QtQuick 5 | import qs.modules.common 6 | import qs.modules.common.widgets 7 | import qs.services 8 | 9 | Revealer { 10 | id: root 11 | reveal: showOsdValues 12 | 13 | property bool showOsdValues: false 14 | 15 | function triggerOsd() { 16 | showOsdValues = true 17 | osdTimeout.restart() 18 | } 19 | 20 | Connections { // Listen to volume changes 21 | target: Audio.sink?.audio ?? null 22 | function onVolumeChanged() { 23 | if (!Audio.ready) return 24 | root.triggerOsd() 25 | } 26 | function onMutedChanged() { 27 | if (!Audio.ready) return 28 | root.triggerOsd() 29 | } 30 | } 31 | 32 | Connections { // Listen to protection triggers 33 | target: Audio 34 | function onSinkProtectionTriggered(reason) { 35 | root.protectionMessage = reason; 36 | root.triggerOsd() 37 | } 38 | } 39 | 40 | Timer { 41 | id: osdTimeout 42 | interval: Config.options.osd.timeout 43 | repeat: false 44 | running: false 45 | onTriggered: { 46 | showOsdValues = false 47 | } 48 | } 49 | 50 | RowLayout { 51 | 52 | BarGroupR { 53 | id: brightnessOsd 54 | padding: 10 55 | 56 | MaterialSymbol { 57 | text: "volume_up" 58 | iconSize: Appearance.font.pixelSize.normal 59 | } 60 | 61 | Item { 62 | implicitWidth: 5 63 | } 64 | 65 | StyledProgressBar { 66 | value: Audio.sink?.audio.volume ?? 0 67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/BarGroupCenter.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | import QtQuick.Layouts 6 | 7 | Item { 8 | id: root 9 | property real padding: 5 10 | property real margin: 0 11 | implicitHeight: 40 12 | implicitWidth: rowLayout.implicitWidth + padding * 2 13 | default property alias items: rowLayout.children 14 | 15 | Rectangle { 16 | id: background 17 | color: "transparent" 18 | anchors.fill: parent 19 | 20 | 21 | RowLayout { 22 | id: rowLayout 23 | spacing: 0 24 | 25 | anchors { 26 | verticalCenter: parent.verticalCenter 27 | leftMargin: root.margin 28 | rightMargin: root.margin 29 | } 30 | 31 | } 32 | 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/BarGroupL.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | import QtQuick.Layouts 6 | 7 | Item { 8 | id: root 9 | property real padding: 5 10 | implicitHeight: 40 11 | implicitWidth: rowLayout.implicitWidth + padding * 2 12 | default property alias items: rowLayout.children 13 | 14 | RowLayout { 15 | id: rowLayout 16 | anchors { 17 | verticalCenter: parent.verticalCenter 18 | left: parent.left 19 | right: parent.right 20 | leftMargin: root.padding 21 | rightMargin: root.padding 22 | } 23 | spacing: 4 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/BarGroupR.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | import QtQuick.Layouts 6 | 7 | Item { 8 | id: root 9 | property real padding: 5 10 | implicitHeight: 40 11 | implicitWidth: rowLayout.implicitWidth + padding * 2 12 | default property alias items: rowLayout.children 13 | 14 | RowLayout { 15 | id: rowLayout 16 | anchors { 17 | verticalCenter: parent.verticalCenter 18 | left: parent.left 19 | right: parent.right 20 | leftMargin: root.padding 21 | rightMargin: root.padding 22 | } 23 | spacing: 4 24 | 25 | } 26 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/BrightnessOsd.qml: -------------------------------------------------------------------------------- 1 | import Quickshell 2 | import Quickshell.Hyprland 3 | import QtQuick 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | import qs.services 7 | 8 | Revealer { 9 | id: root 10 | reveal: showOsdValues 11 | 12 | property bool showOsdValues: false 13 | property var focusedScreen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name) 14 | property var brightnessMonitor: Brightness.getMonitorForScreen(focusedScreen) 15 | 16 | Connections { 17 | target: Brightness 18 | function onBrightnessChanged() { 19 | if (!root.brightnessMonitor.ready) return 20 | root.triggerOsd() 21 | } 22 | } 23 | 24 | function triggerOsd() { 25 | showOsdValues = true 26 | osdTimeout.restart() 27 | } 28 | 29 | Timer { 30 | id: osdTimeout 31 | interval: Config.options.osd.timeout 32 | repeat: false 33 | running: false 34 | onTriggered: { 35 | showOsdValues = false 36 | } 37 | } 38 | 39 | BarGroupR { 40 | id: brightnessOsd 41 | padding: 10 42 | 43 | StyledProgressBar { 44 | value: root.brightnessMonitor?.brightness ?? 0.5 45 | } 46 | 47 | Item { 48 | implicitWidth: 5 49 | } 50 | 51 | MaterialSymbol { 52 | text: "clear_day" 53 | iconSize: Appearance.font.pixelSize.normal 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/BtPopup.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import Quickshell.Bluetooth 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | 7 | Rectangle { 8 | id: resourcePopup 9 | readonly property real margin: 10 10 | implicitWidth: columnLayout.implicitWidth + margin * 2 11 | implicitHeight: columnLayout.implicitHeight + margin * 2 12 | color: Appearance.m3colors.m3background 13 | radius: Appearance.rounding.small 14 | border.width: 1 15 | border.color: Appearance.colors.colLayer0 16 | clip: true 17 | 18 | property BluetoothDevice device: Bluetooth.devices.values.find(d => d.connected) ?? null 19 | 20 | ColumnLayout { 21 | id: columnLayout 22 | anchors.centerIn: parent 23 | spacing: 6 24 | 25 | RowLayout { 26 | spacing: 5 27 | 28 | MaterialSymbol { 29 | fill: 1 30 | text: "bluetooth" 31 | iconSize: Appearance.font.pixelSize.larger 32 | } 33 | 34 | StyledText { 35 | color: Appearance.colors.colOnLayer1 36 | text: device.name 37 | } 38 | } 39 | RowLayout { 40 | spacing: 5 41 | 42 | MaterialSymbol { 43 | fill: 1 44 | text: "battery_android_full" 45 | } 46 | 47 | StyledText { 48 | color: Appearance.colors.colOnLayer1 49 | text: `${Math.round(device.battery * 100 ?? 0)}% remaining` 50 | } 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/CircleUtilButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | import Quickshell 8 | import Quickshell.Io 9 | 10 | RippleButton { 11 | id: button 12 | 13 | required default property Item content 14 | property bool extraActiveCondition: false 15 | 16 | implicitHeight: Math.max(content.implicitHeight, 26, content.implicitHeight) 17 | implicitWidth: implicitHeight 18 | contentItem: content 19 | 20 | } 21 | -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/HyprlandXkbIndicator.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import qs.services 3 | import qs.modules.common 4 | import qs.modules.common.widgets 5 | 6 | Loader { 7 | id: root 8 | property bool vertical: false 9 | active: HyprlandXkb.layoutCodes.length > 1 10 | visible: active 11 | 12 | function abbreviateLayoutCode(fullCode) { 13 | return fullCode.split(':').map(layout => { 14 | const baseLayout = layout.split('-')[0]; 15 | return baseLayout.slice(0, 4); 16 | }).join('\n'); 17 | } 18 | 19 | sourceComponent: Item { 20 | implicitWidth: root.vertical ? null : layoutCodeText.implicitWidth 21 | implicitHeight: root.vertical ? layoutCodeText.implicitHeight : null 22 | 23 | StyledText { 24 | id: layoutCodeText 25 | anchors.centerIn: parent 26 | horizontalAlignment: Text.AlignHCenter 27 | text: abbreviateLayoutCode(HyprlandXkb.currentLayoutCode) 28 | font.pixelSize: text.includes("\n") ? Appearance.font.pixelSize.smallie : Appearance.font.pixelSize.small 29 | color: rightSidebarButton.colText 30 | animateChange: true 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/NotifIndicator.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | import QtQuick.Layouts 6 | import Quickshell 7 | import Quickshell.Io 8 | 9 | Item { 10 | id: root 11 | property int count: Notifications.list.length 12 | height: 20 13 | width: notifRow.width 14 | visible: count > 0 15 | 16 | RowLayout { 17 | id: notifRow 18 | anchors.margins: 2 19 | spacing: 2 20 | 21 | StyledText { 22 | font.pixelSize: 15 23 | text: count > 99 ? "99+" : count.toString() 24 | color: Appearance.colors.colOnLayer0 25 | } 26 | 27 | MaterialSymbol { 28 | id: icon 29 | iconSize: 20 30 | text: "notifications" 31 | color: Appearance.colors.colOnLayer0 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/Resources.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | import QtQuick.Layouts 6 | import Quickshell 7 | import Quickshell.Io 8 | import Quickshell.Services.Mpris 9 | import Sleex.Services 10 | 11 | Item { 12 | id: root 13 | property bool alwaysShowAllResources: true 14 | implicitWidth: rowLayout.implicitWidth + rowLayout.anchors.leftMargin + rowLayout.anchors.rightMargin 15 | implicitHeight: 32 16 | 17 | RowLayout { 18 | id: rowLayout 19 | 20 | spacing: 0 21 | anchors.fill: parent 22 | anchors.leftMargin: 4 23 | anchors.rightMargin: 4 24 | 25 | Resource { 26 | iconName: "memory" 27 | percentage: ResourceMonitor.memoryUsedPercentage 28 | } 29 | 30 | Resource { 31 | iconName: "swap_horiz" 32 | percentage: ResourceMonitor.swapUsedPercentage 33 | } 34 | 35 | Resource { 36 | iconName: "settings_slow_motion" 37 | percentage: ResourceMonitor.cpuUsage 38 | Layout.leftMargin: shown ? 4 : 0 39 | } 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/share/sleex/modules/bar/ScrollHint.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.modules.common 3 | import qs.modules.common.widgets 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | 8 | Revealer { // Scroll hint 9 | id: root 10 | property string icon 11 | property string side: "left" 12 | property string tooltipText: "" 13 | 14 | MouseArea { 15 | anchors.right: root.side === "left" ? parent.right : undefined 16 | anchors.left: root.side === "right" ? parent.left : undefined 17 | implicitWidth: contentColumnLayout.implicitWidth 18 | implicitHeight: contentColumnLayout.implicitHeight 19 | property bool hovered: false 20 | 21 | hoverEnabled: true 22 | onEntered: hovered = true 23 | onExited: hovered = false 24 | acceptedButtons: Qt.NoButton 25 | 26 | // StyledToolTip { 27 | // extraVisibleCondition: tooltipText.length > 0 28 | // content: tooltipText 29 | // } 30 | 31 | ColumnLayout { 32 | id: contentColumnLayout 33 | anchors.centerIn: parent 34 | spacing: -5 35 | MaterialSymbol { 36 | Layout.leftMargin: 5 37 | Layout.rightMargin: 5 38 | text: "keyboard_arrow_up" 39 | iconSize: 14 40 | color: Appearance.colors.colSubtext 41 | } 42 | MaterialSymbol { 43 | Layout.leftMargin: 5 44 | Layout.rightMargin: 5 45 | text: root.icon 46 | iconSize: 14 47 | color: Appearance.colors.colSubtext 48 | } 49 | MaterialSymbol { 50 | Layout.leftMargin: 5 51 | Layout.rightMargin: 5 52 | text: "keyboard_arrow_down" 53 | iconSize: 14 54 | color: Appearance.colors.colSubtext 55 | } 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/Persistent.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | pragma ComponentBehavior: Bound 3 | import QtQuick 4 | import Quickshell 5 | import Quickshell.Io 6 | 7 | Singleton { 8 | id: root 9 | property alias states: persistentStatesJsonAdapter 10 | property string fileDir: Directories.shellConfig 11 | property string fileName: "states.json" 12 | property string filePath: `${root.fileDir}/${root.fileName}` 13 | 14 | Timer { 15 | id: fileReloadTimer 16 | interval: 100 17 | repeat: false 18 | onTriggered: { 19 | persistentStatesFileView.reload() 20 | } 21 | } 22 | 23 | Timer { 24 | id: fileWriteTimer 25 | interval: 100 26 | repeat: false 27 | onTriggered: { 28 | persistentStatesFileView.writeAdapter() 29 | } 30 | } 31 | 32 | FileView { 33 | id: persistentStatesFileView 34 | path: root.filePath 35 | 36 | watchChanges: true 37 | onFileChanged: fileReloadTimer.restart() 38 | onAdapterUpdated: fileWriteTimer.restart() 39 | onLoadFailed: error => { 40 | console.log("Failed to load persistent states file:", error); 41 | if (error == FileViewError.FileNotFound) { 42 | fileWriteTimer.restart(); 43 | } 44 | } 45 | 46 | adapter: JsonAdapter { 47 | id: persistentStatesJsonAdapter 48 | property JsonObject ai: JsonObject { 49 | property string model 50 | property real temperature: 0.5 51 | } 52 | 53 | property JsonObject sidebar: JsonObject { 54 | property JsonObject bottomGroup: JsonObject { 55 | property bool collapsed: false 56 | property int tab: 0 57 | } 58 | } 59 | 60 | property JsonObject idle: JsonObject { 61 | property bool inhibit: false 62 | } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/PersistentStates.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Quickshell 3 | pragma Singleton 4 | pragma ComponentBehavior: Bound 5 | 6 | Singleton { 7 | property QtObject ai: QtObject { 8 | property string model 9 | property real temperature: 0.5 10 | } 11 | 12 | property QtObject sidebar: QtObject { 13 | property QtObject bottomGroup: QtObject { 14 | property bool collapsed: false 15 | } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/functions/FileUtils.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | import Quickshell 3 | 4 | Singleton { 5 | id: root 6 | 7 | /** 8 | * Trims the File protocol off the input string 9 | * @param {string} str 10 | * @returns {string} 11 | */ 12 | function trimFileProtocol(str) { 13 | return str.startsWith("file://") ? str.slice(7) : str; 14 | } 15 | 16 | /** 17 | * Extracts the file name from a file path 18 | * @param {string} str 19 | * @returns {string} 20 | */ 21 | function fileNameForPath(str) { 22 | if (typeof str !== "string") return ""; 23 | const trimmed = trimFileProtocol(str); 24 | return trimmed.split(/[\\/]/).pop(); 25 | } 26 | 27 | /** 28 | * Removes the file extension from a file path or name 29 | * @param {string} str 30 | * @returns {string} 31 | */ 32 | function trimFileExt(str) { 33 | if (typeof str !== "string") return ""; 34 | const trimmed = trimFileProtocol(str); 35 | const lastDot = trimmed.lastIndexOf("."); 36 | if (lastDot > -1 && lastDot > trimmed.lastIndexOf("/")) { 37 | return trimmed.slice(0, lastDot); 38 | } 39 | return trimmed; 40 | } 41 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/functions/Fuzzy.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | import Quickshell 3 | import "./fuzzysort.js" as FuzzySort 4 | 5 | /** 6 | * Wrapper for FuzzySort to play nicely with Quickshell's imports 7 | */ 8 | 9 | Singleton { 10 | function go(...args) { 11 | return FuzzySort.go(...args) 12 | } 13 | 14 | function prepare(...args) { 15 | return FuzzySort.prepare(...args) 16 | } 17 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/functions/Lavendist.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | import Quickshell 3 | import "./levendist.js" as Levendist 4 | 5 | /** 6 | * Wrapper for levendist.js to play nicely with Quickshell's imports 7 | */ 8 | 9 | Singleton { 10 | function computeScore(...args) { 11 | return Levendist.computeScore(...args) 12 | } 13 | 14 | function computeTextMatchScore(...args) { 15 | return Levendist.computeTextMatchScore(...args) 16 | } 17 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ButtonGroup.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | 8 | /** 9 | * A container that supports GroupButton children for bounciness. 10 | * See https://m3.material.io/components/button-groups/overview 11 | */ 12 | Rectangle { 13 | id: root 14 | default property alias data: rowLayout.data 15 | property real spacing: 5 16 | property real padding: 0 17 | property int clickIndex: rowLayout.clickIndex 18 | 19 | property real contentWidth: { 20 | let total = 0; 21 | for (let i = 0; i < rowLayout.children.length; ++i) { 22 | const child = rowLayout.children[i]; 23 | total += child.baseWidth ?? child.implicitWidth ?? child.width; 24 | } 25 | return total + rowLayout.spacing * (rowLayout.children.length - 1); 26 | } 27 | 28 | topLeftRadius: rowLayout.children.length > 0 ? (rowLayout.children[0].radius + padding) : 29 | Appearance?.rounding?.small 30 | bottomLeftRadius: topLeftRadius 31 | topRightRadius: rowLayout.children.length > 0 ? (rowLayout.children[rowLayout.children.length - 1].radius + padding) : 32 | Appearance?.rounding?.small 33 | bottomRightRadius: topRightRadius 34 | 35 | color: "transparent" 36 | width: root.contentWidth + padding * 2 37 | implicitHeight: rowLayout.implicitHeight + padding * 2 38 | implicitWidth: root.contentWidth + padding * 2 39 | 40 | children: [RowLayout { 41 | id: rowLayout 42 | anchors.fill: parent 43 | anchors.margins: root.padding 44 | spacing: root.spacing 45 | property int clickIndex: -1 46 | }] 47 | } 48 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/CachingImage.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common.functions 2 | import qs.modules.common 3 | import Quickshell 4 | import Quickshell.Io 5 | import QtQuick 6 | 7 | Image { 8 | id: root 9 | 10 | property string path 11 | property string hash 12 | readonly property string cachePath: `${Directories.wallpaperCache}/${hash}@${effectiveWidth}x${effectiveHeight}.png` 13 | 14 | readonly property real effectiveScale: QsWindow.window?.devicePixelRatio ?? 1 15 | readonly property int effectiveWidth: Math.ceil(width * effectiveScale) 16 | readonly property int effectiveHeight: Math.ceil(height * effectiveScale) 17 | 18 | asynchronous: true 19 | fillMode: Image.PreserveAspectCrop 20 | sourceSize.width: effectiveWidth 21 | sourceSize.height: effectiveHeight 22 | 23 | onPathChanged: shaProc.exec(["sha256sum", FileUtils.trimFileProtocol(path)]) 24 | 25 | onCachePathChanged: { 26 | if (hash) 27 | source = cachePath; 28 | } 29 | 30 | onStatusChanged: { 31 | if (source == cachePath && status === Image.Error) 32 | source = path; 33 | else if (source == path && status === Image.Ready) { 34 | Quickshell.execDetached(["mkdir", "-p", FileUtils.trimFileProtocol(cachePath)]); 35 | const grabPath = cachePath; 36 | grabToImage(res => res.saveToFile(grabPath)); 37 | } 38 | } 39 | 40 | Process { 41 | id: shaProc 42 | 43 | stdout: StdioCollector { 44 | onStreamFinished: root.hash = text.split(" ")[0] 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ClippingRectangle.qml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/modules/common/widgets/ClippingRectangle.qml -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ConfigRow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | 4 | RowLayout { 5 | property bool uniform: false 6 | spacing: 10 7 | uniformCellSizes: uniform 8 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ConfigSelectionArray.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import QtQuick.Layouts 4 | import Quickshell 5 | import Quickshell.Io 6 | import Quickshell.Hyprland 7 | import qs.services 8 | import qs.modules.common 9 | import qs.modules.common.widgets 10 | import qs.modules.common.functions 11 | import qs.modules.common.functions 12 | 13 | Flow { 14 | id: root 15 | Layout.fillWidth: true 16 | spacing: 2 17 | property list options: [] 18 | property string configOptionName: "" 19 | property var currentValue: null 20 | 21 | signal selected(var newValue) 22 | 23 | Repeater { 24 | model: root.options 25 | delegate: SelectionGroupButton { 26 | id: paletteButton 27 | required property var modelData 28 | required property int index 29 | onYChanged: { 30 | if (index === 0) { 31 | paletteButton.leftmost = true 32 | } else { 33 | var prev = root.children[index - 1] 34 | var thisIsOnNewLine = prev && prev.y !== paletteButton.y 35 | paletteButton.leftmost = thisIsOnNewLine 36 | prev.rightmost = thisIsOnNewLine 37 | } 38 | } 39 | leftmost: index === 0 40 | rightmost: index === root.options.length - 1 41 | buttonText: modelData.displayName; 42 | toggled: root.currentValue === modelData.value 43 | onClicked: { 44 | root.selected(modelData.value); 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ConfigSpinBox.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common.widgets 2 | import qs.modules.common 3 | import QtQuick 4 | import QtQuick.Layouts 5 | import QtQuick.Controls 6 | 7 | RowLayout { 8 | id: root 9 | property string text: "" 10 | property alias value: spinBoxWidget.value 11 | property alias stepSize: spinBoxWidget.stepSize 12 | property alias from: spinBoxWidget.from 13 | property alias to: spinBoxWidget.to 14 | spacing: 10 15 | Layout.leftMargin: 8 16 | Layout.rightMargin: 8 17 | 18 | StyledText { 19 | id: labelWidget 20 | Layout.fillWidth: true 21 | text: root.text 22 | font.pixelSize: Appearance.font.pixelSize.small 23 | color: Appearance.colors.colOnSecondaryContainer 24 | } 25 | 26 | StyledSpinBox { 27 | id: spinBoxWidget 28 | Layout.fillWidth: false 29 | value: root.value 30 | } 31 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ConfigSwitch.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common.widgets 2 | import qs.modules.common 3 | import QtQuick 4 | import QtQuick.Layouts 5 | import QtQuick.Controls 6 | 7 | RippleButton { 8 | id: root 9 | Layout.fillWidth: true 10 | implicitHeight: contentItem.implicitHeight + 8 * 2 11 | 12 | contentItem: RowLayout { 13 | spacing: 10 14 | StyledText { 15 | id: labelWidget 16 | Layout.fillWidth: true 17 | text: root.text 18 | font.pixelSize: Appearance.font.pixelSize.normal 19 | color: Appearance.colors.colOnSecondaryContainer 20 | } 21 | StyledSwitch { 22 | id: switchWidget 23 | down: root.down 24 | scale: 0.75 25 | Layout.fillWidth: false 26 | checked: root.checked 27 | onClicked: root.clicked() 28 | } 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ContentPage.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import QtQuick.Layouts 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | 7 | StyledFlickable { 8 | id: root 9 | property real baseWidth: 500 10 | property bool forceWidth: false 11 | 12 | default property alias data: contentColumn.data 13 | 14 | clip: true 15 | contentHeight: contentColumn.implicitHeight 16 | implicitWidth: contentColumn.implicitWidth 17 | 18 | ColumnLayout { 19 | id: contentColumn 20 | width: root.forceWidth ? root.baseWidth : Math.max(root.baseWidth, implicitWidth) 21 | anchors { 22 | top: parent.top 23 | bottom: parent.bottom 24 | horizontalCenter: parent.horizontalCenter 25 | margins: 10 26 | } 27 | spacing: 20 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ContentSection.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import QtQuick.Layouts 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | 7 | ColumnLayout { 8 | id: root 9 | property string title 10 | property color backgroundColor: Appearance.colors.colLayer1 11 | default property alias data: sectionContent.data 12 | 13 | Layout.fillWidth: true 14 | spacing: 8 15 | 16 | StyledText { 17 | text: root.title 18 | font.pixelSize: Appearance.font.pixelSize.larger 19 | font.weight: Font.Medium 20 | } 21 | 22 | Rectangle { 23 | Layout.fillWidth: true 24 | implicitHeight: sectionContent.implicitHeight + 24 // Content height + padding 25 | color: root.backgroundColor 26 | radius: 8 // Optional: rounded corners 27 | 28 | ColumnLayout { 29 | id: sectionContent 30 | anchors.fill: parent 31 | anchors.margins: 12 // Padding inside the background 32 | spacing: 4 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ContentSubsection.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import QtQuick.Layouts 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | 7 | ColumnLayout { 8 | id: root 9 | property string title: "" 10 | property string tooltip: "" 11 | default property alias data: sectionContent.data 12 | 13 | Layout.fillWidth: true 14 | Layout.topMargin: 4 15 | spacing: 2 16 | 17 | RowLayout { 18 | ContentSubsectionLabel { 19 | visible: root.title && root.title.length > 0 20 | text: root.title 21 | } 22 | MaterialSymbol { 23 | visible: root.tooltip && root.tooltip.length > 0 24 | text: "info" 25 | iconSize: Appearance.font.pixelSize.large 26 | 27 | color: Appearance.colors.colSubtext 28 | MouseArea { 29 | id: infoMouseArea 30 | anchors.fill: parent 31 | hoverEnabled: true 32 | cursorShape: Qt.WhatsThisCursor 33 | StyledToolTip { 34 | extraVisibleCondition: false 35 | alternativeVisibleCondition: infoMouseArea.containsMouse 36 | text: root.tooltip 37 | } 38 | } 39 | } 40 | Item { Layout.fillWidth: true } 41 | } 42 | ColumnLayout { 43 | id: sectionContent 44 | Layout.fillWidth: true 45 | spacing: 2 46 | } 47 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ContentSubsectionLabel.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import qs.modules.common 4 | import qs.modules.common.widgets 5 | 6 | StyledText { 7 | text: "Subsection" 8 | color: Appearance.colors.colSubtext 9 | Layout.leftMargin: 4 10 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/CustomIcon.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import Quickshell 3 | import Quickshell.Widgets 4 | import Qt5Compat.GraphicalEffects 5 | 6 | Item { 7 | id: root 8 | 9 | property bool colorize: false 10 | property color color 11 | property string source: "" 12 | property string iconFolder: Qt.resolvedUrl(Quickshell.shellPath("assets/icons")) // The folder to check first 13 | width: 30 14 | height: 30 15 | 16 | IconImage { 17 | id: iconImage 18 | anchors.fill: parent 19 | source: { 20 | const fullPathWhenSourceIsIconName = iconFolder + "/" + root.source; 21 | if (iconFolder && fullPathWhenSourceIsIconName) { 22 | return fullPathWhenSourceIsIconName 23 | } 24 | return root.source 25 | } 26 | implicitSize: root.height 27 | } 28 | 29 | Loader { 30 | active: root.colorize 31 | anchors.fill: iconImage 32 | sourceComponent: ColorOverlay { 33 | source: iconImage 34 | color: root.color 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/DialogButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.functions 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | import Quickshell 7 | import Quickshell.Io 8 | 9 | /** 10 | * Material 3 dialog button. See https://m3.material.io/components/dialogs/overview 11 | */ 12 | RippleButton { 13 | id: button 14 | 15 | property string buttonText 16 | implicitHeight: 30 17 | implicitWidth: buttonTextWidget.implicitWidth + 15 * 2 18 | buttonRadius: Appearance?.rounding.full ?? 9999 19 | 20 | property color colEnabled: Appearance?.colors.colPrimary ?? "#65558F" 21 | property color colDisabled: Appearance?.m3colors.m3outline ?? "#8D8C96" 22 | 23 | contentItem: StyledText { 24 | id: buttonTextWidget 25 | anchors.fill: parent 26 | anchors.leftMargin: 15 27 | anchors.rightMargin: 15 28 | text: buttonText 29 | horizontalAlignment: Text.AlignHCenter 30 | font.pixelSize: Appearance?.font.pixelSize.small ?? 12 31 | color: button.enabled ? button.colEnabled : button.colDisabled 32 | 33 | Behavior on color { 34 | animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) 35 | } 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/Favicon.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import qs.modules.common.functions 5 | import qs.modules.common.functions 6 | import Qt5Compat.GraphicalEffects 7 | import Qt.labs.platform 8 | import QtQuick 9 | import QtQuick.Controls 10 | import QtQuick.Layouts 11 | import Quickshell.Io 12 | import Quickshell.Widgets 13 | import Quickshell.Hyprland 14 | 15 | IconImage { 16 | id: root 17 | property string url 18 | property string displayText 19 | 20 | property real size: 32 21 | property string downloadUserAgent: Config.options?.networking.userAgent ?? "" 22 | property string faviconDownloadPath: Directories.favicons 23 | property string domainName: url.includes("vertexaisearch") ? displayText : StringUtils.getDomain(url) 24 | property string faviconUrl: `https://www.google.com/s2/favicons?domain=${domainName}&sz=32` 25 | property string fileName: `${domainName}.ico` 26 | property string faviconFilePath: `${faviconDownloadPath}/${fileName}` 27 | property string urlToLoad 28 | 29 | Process { 30 | id: faviconDownloadProcess 31 | running: false 32 | command: ["bash", "-c", `[ -f ${faviconFilePath} ] || curl -s '${root.faviconUrl}' -o '${faviconFilePath}' -L -H 'User-Agent: ${downloadUserAgent}'`] 33 | onExited: (exitCode, exitStatus) => { 34 | root.urlToLoad = root.faviconFilePath 35 | } 36 | } 37 | 38 | Component.onCompleted: { 39 | faviconDownloadProcess.running = true 40 | } 41 | 42 | source: Qt.resolvedUrl(root.urlToLoad) 43 | implicitSize: root.size 44 | 45 | layer.enabled: true 46 | layer.effect: OpacityMask { 47 | maskSource: Rectangle { 48 | width: root.implicitSize 49 | height: root.implicitSize 50 | radius: Appearance.rounding.full 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/FlowButtonGroup.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | /** 4 | * This is just to make sure `RippleButton`s can be used in a Flow layout. 5 | */ 6 | Flow { 7 | property int clickIndex: -1 8 | } 9 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/KeyboardKey.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick 3 | import QtQuick.Controls 4 | import QtQuick.Layouts 5 | import Quickshell 6 | import Quickshell.Io 7 | 8 | Rectangle { 9 | id: root 10 | property string key 11 | 12 | property real horizontalPadding: 7 13 | property real verticalPadding: 2 14 | property real borderWidth: 1 15 | property real extraBottomBorderWidth: 2 16 | property color borderColor: Appearance.colors.colOnLayer0 17 | property real borderRadius: 5 18 | property color keyColor: Appearance.m3colors.m3surfaceContainerLow 19 | implicitWidth: keyFace.implicitWidth + borderWidth * 2 20 | implicitHeight: keyFace.implicitHeight + borderWidth * 2 + extraBottomBorderWidth 21 | radius: borderRadius 22 | color: borderColor 23 | 24 | Rectangle { 25 | id: keyFace 26 | anchors { 27 | fill: parent 28 | topMargin: borderWidth 29 | leftMargin: borderWidth 30 | rightMargin: borderWidth 31 | bottomMargin: extraBottomBorderWidth + borderWidth 32 | } 33 | implicitWidth: keyText.implicitWidth + horizontalPadding * 2 34 | implicitHeight: keyText.implicitHeight + verticalPadding * 2 35 | color: keyColor 36 | radius: borderRadius - borderWidth 37 | 38 | StyledText { 39 | id: keyText 40 | anchors.centerIn: parent 41 | font.family: Appearance.font.family.monospace 42 | font.pixelSize: Appearance.font.pixelSize.smaller 43 | text: key 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/MaterialSymbol.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick 3 | import QtQuick.Layouts 4 | 5 | Text { 6 | id: root 7 | property real iconSize: Appearance?.font.pixelSize.small ?? 16 8 | property real fill: 0 9 | property real truncatedFill: Math.round(fill * 100) / 100 // Reduce memory consumption spikes from constant font remapping 10 | renderType: Text.NativeRendering 11 | font { 12 | hintingPreference: Font.PreferFullHinting 13 | family: Appearance?.font.family.iconMaterial ?? "Material Symbols Rounded" 14 | pixelSize: iconSize 15 | weight: Font.Normal + (Font.DemiBold - Font.Normal) * fill 16 | variableAxes: { 17 | "FILL": truncatedFill, 18 | // "wght": font.weight, 19 | // "GRAD": 0, 20 | "opsz": iconSize, 21 | } 22 | } 23 | verticalAlignment: Text.AlignVCenter 24 | color: Appearance.m3colors.m3onBackground 25 | 26 | // Behavior on fill { 27 | // NumberAnimation { 28 | // duration: Appearance?.animation.elementMoveFast.duration ?? 200 29 | // easing.type: Appearance?.animation.elementMoveFast.type ?? Easing.BezierSpline 30 | // easing.bezierCurve: Appearance?.animation.elementMoveFast.bezierCurve ?? [0.34, 0.80, 0.34, 1.00, 1, 1] 31 | // } 32 | // } 33 | } 34 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/MaterialTextField.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.functions 3 | import QtQuick 4 | import QtQuick.Controls.Material 5 | import QtQuick.Controls 6 | 7 | /** 8 | * Material 3 styled TextArea (filled style) 9 | * https://m3.material.io/components/text-fields/overview 10 | * Note: We don't use NativeRendering because it makes the small placeholder text look weird 11 | */ 12 | TextArea { 13 | id: root 14 | Material.theme: Material.System 15 | Material.accent: Appearance.m3colors.m3primary 16 | Material.primary: Appearance.m3colors.m3primary 17 | Material.background: Appearance.m3colors.m3surface 18 | Material.foreground: Appearance.m3colors.m3onSurface 19 | Material.containerStyle: Material.Filled 20 | renderType: Text.QtRendering 21 | 22 | selectedTextColor: Appearance.m3colors.m3onSecondaryContainer 23 | selectionColor: Appearance.colors.colSecondaryContainer 24 | placeholderTextColor: Appearance.m3colors.m3outline 25 | 26 | background: Rectangle { 27 | implicitHeight: 56 28 | color: Appearance.m3colors.m3surface 29 | topLeftRadius: 4 30 | topRightRadius: 4 31 | Rectangle { 32 | anchors { 33 | left: parent.left 34 | right: parent.right 35 | bottom: parent.bottom 36 | } 37 | height: 1 38 | color: root.focus ? Appearance.m3colors.m3primary : 39 | root.hovered ? Appearance.m3colors.m3outline : Appearance.m3colors.m3outlineVariant 40 | 41 | Behavior on color { 42 | animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) 43 | } 44 | } 45 | } 46 | 47 | font { 48 | family: Appearance?.font.family.main ?? "sans-serif" 49 | pixelSize: Appearance?.font.pixelSize.small ?? 15 50 | hintingPreference: Font.PreferFullHinting 51 | } 52 | wrapMode: TextEdit.Wrap 53 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/MenuButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.functions 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | import Quickshell 7 | import Quickshell.Io 8 | 9 | RippleButton { 10 | id: root 11 | 12 | buttonRadius: 0 13 | implicitHeight: 36 14 | implicitWidth: buttonTextWidget.implicitWidth + 14 * 2 15 | 16 | contentItem: StyledText { 17 | id: buttonTextWidget 18 | anchors.fill: parent 19 | anchors.leftMargin: 14 20 | anchors.rightMargin: 14 21 | text: root.buttonText 22 | horizontalAlignment: Text.AlignLeft 23 | font.pixelSize: Appearance.font.pixelSize.small 24 | color: root.enabled ? Appearance.m3colors.m3onSurface : Appearance.m3colors.m3outline 25 | 26 | Behavior on color { 27 | animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/NavigationRail.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import QtQuick.Layouts 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | 7 | ColumnLayout { // Window content with navigation rail and content pane 8 | id: root 9 | property bool expanded: true 10 | property int currentIndex: 0 11 | spacing: 5 12 | } 13 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/NavigationRailExpandButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import QtQuick.Layouts 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | 7 | RippleButton { 8 | id: root 9 | Layout.alignment: Qt.AlignLeft 10 | implicitWidth: 40 11 | implicitHeight: 40 12 | Layout.leftMargin: 8 13 | onClicked: { 14 | parent.expanded = !parent.expanded; 15 | } 16 | buttonRadius: Appearance.rounding.normal 17 | contentItem: MaterialSymbol { 18 | id: icon 19 | anchors.centerIn: parent 20 | horizontalAlignment: Text.AlignHCenter 21 | iconSize: 24 22 | color: Appearance.colors.colOnLayer1 23 | text: root.parent.expanded ? "menu_open" : "menu" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/NavigationRailTabArray.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | import Quickshell.Io 8 | 9 | Item { 10 | id: root 11 | property int currentIndex: 0 12 | property bool expanded: false 13 | default property alias data: tabBarColumn.data 14 | implicitHeight: tabBarColumn.implicitHeight 15 | implicitWidth: tabBarColumn.implicitWidth 16 | Layout.topMargin: 25 17 | Rectangle { 18 | property real itemHeight: tabBarColumn.children[0].baseSize 19 | property real baseHighlightHeight: tabBarColumn.children[0].baseHighlightHeight 20 | anchors { 21 | top: tabBarColumn.top 22 | left: tabBarColumn.left 23 | topMargin: itemHeight * root.currentIndex + (root.expanded ? 0 : ((itemHeight - baseHighlightHeight) / 2)) 24 | } 25 | radius: Appearance.rounding.normal 26 | color: Appearance.colors.colSecondaryContainer 27 | implicitHeight: root.expanded ? itemHeight : baseHighlightHeight 28 | implicitWidth: tabBarColumn.children[root.currentIndex].visualWidth 29 | 30 | Behavior on anchors.topMargin { 31 | NumberAnimation { 32 | duration: Appearance.animationCurves.expressiveFastSpatialDuration 33 | easing.type: Appearance.animation.elementMove.type 34 | easing.bezierCurve: Appearance.animationCurves.expressiveFastSpatial 35 | } 36 | } 37 | } 38 | ColumnLayout { 39 | id: tabBarColumn 40 | anchors.fill: parent 41 | spacing: 0 42 | 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/NotificationActionButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.services 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | import Quickshell 7 | import Quickshell.Services.Notifications 8 | 9 | RippleButton { 10 | id: button 11 | property string buttonText 12 | property string urgency 13 | 14 | implicitHeight: 30 15 | leftPadding: 15 16 | rightPadding: 15 17 | buttonRadius: Appearance.rounding.small 18 | colBackground: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainer : Appearance.colors.colSurfaceContainerHighest 19 | colBackgroundHover: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerHover : Appearance.colors.colSurfaceContainerHighestHover 20 | colRipple: (urgency == NotificationUrgency.Critical) ? Appearance.colors.colSecondaryContainerActive : Appearance.colors.colSurfaceContainerHighestActive 21 | 22 | contentItem: StyledText { 23 | horizontalAlignment: Text.AlignHCenter 24 | text: buttonText 25 | color: (urgency == NotificationUrgency.Critical) ? Appearance.m3colors.m3onSurfaceVariant : Appearance.m3colors.m3onSurface 26 | } 27 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/NotificationGroupExpandButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.services 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Effects 7 | import QtQuick.Layouts 8 | import Quickshell 9 | import Quickshell.Services.Notifications 10 | 11 | RippleButton { // Expand button 12 | id: root 13 | required property int count 14 | required property bool expanded 15 | property real fontSize: Appearance?.font.pixelSize.small ?? 12 16 | property real iconSize: Appearance?.font.pixelSize.normal ?? 16 17 | implicitHeight: fontSize + 4 * 2 18 | implicitWidth: Math.max(contentItem.implicitWidth + 5 * 2, 30) 19 | Layout.alignment: Qt.AlignVCenter 20 | Layout.fillHeight: false 21 | 22 | buttonRadius: Appearance.rounding.full 23 | colBackground: ColorUtils.mix(Appearance?.colors.colLayer2, Appearance?.colors.colLayer2Hover, 0.5) 24 | colBackgroundHover: Appearance?.colors.colLayer2Hover ?? "#E5DFED" 25 | colRipple: Appearance?.colors.colLayer2Active ?? "#D6CEE2" 26 | 27 | contentItem: Item { 28 | anchors.centerIn: parent 29 | implicitWidth: contentRow.implicitWidth 30 | RowLayout { 31 | id: contentRow 32 | anchors.centerIn: parent 33 | spacing: 3 34 | StyledText { 35 | Layout.leftMargin: 4 36 | visible: root.count > 1 37 | text: root.count 38 | font.pixelSize: root.fontSize 39 | } 40 | MaterialSymbol { 41 | text: "keyboard_arrow_down" 42 | iconSize: root.iconSize 43 | color: Appearance.colors.colOnLayer2 44 | rotation: expanded ? 180 : 0 45 | Behavior on rotation { 46 | animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) 47 | } 48 | } 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/NotificationListView.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.modules.common 3 | import qs.modules.common.widgets 4 | import qs.services 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | import Quickshell 9 | import Quickshell.Wayland 10 | import Quickshell.Hyprland 11 | 12 | StyledListView { // Scrollable window 13 | id: root 14 | property bool popup: false 15 | 16 | spacing: 3 17 | 18 | model: ScriptModel { 19 | values: root.popup ? Notifications.popupAppNameList : Notifications.appNameList 20 | } 21 | delegate: NotificationGroup { 22 | required property int index 23 | required property var modelData 24 | popup: root.popup 25 | anchors.left: parent?.left 26 | anchors.right: parent?.right 27 | notificationGroup: popup ? 28 | Notifications.popupGroupsByAppName[modelData] : 29 | Notifications.groupsByAppName[modelData] 30 | } 31 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/PointingHandInteraction.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | MouseArea { 4 | anchors.fill: parent 5 | onPressed: (mouse) => mouse.accepted = false 6 | cursorShape: Qt.PointingHandCursor 7 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/PointingHandLinkHover.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | MouseArea { 4 | anchors.fill: parent 5 | acceptedButtons: Qt.NoButton // Only for hover 6 | hoverEnabled: true 7 | cursorShape: parent.hoveredLink !== "" ? Qt.PointingHandCursor : Qt.ArrowCursor 8 | } 9 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/PopupToolTip.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | import Quickshell 7 | 8 | Item { 9 | id: root 10 | property string text: "" 11 | property bool extraVisibleCondition: true 12 | property bool alternativeVisibleCondition: false 13 | property real horizontalPadding: 10 14 | property real verticalPadding: 5 15 | 16 | property var anchorEdges: Edges.Top 17 | property var anchorGravity: anchorEdges 18 | 19 | readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition 20 | 21 | Loader { 22 | id: tooltipLoader 23 | anchors.fill: parent 24 | active: internalVisibleCondition 25 | sourceComponent: PopupWindow { 26 | visible: true 27 | anchor { 28 | window: root.QsWindow.window 29 | item: root.parent 30 | edges: root.anchorEdges 31 | gravity: root.anchorGravity 32 | } 33 | mask: Region { 34 | item: null 35 | } 36 | 37 | color: "transparent" 38 | implicitWidth: contentItem.implicitWidth + root.horizontalPadding * 2 39 | implicitHeight: contentItem.implicitHeight + root.verticalPadding * 2 40 | 41 | StyledToolTipContent { 42 | id: contentItem 43 | anchors.centerIn: parent 44 | text: root.text 45 | shown: false 46 | Component.onCompleted: shown = true 47 | horizontalPadding: root.horizontalPadding 48 | verticalPadding: root.verticalPadding 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/Revealer.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick 3 | import Quickshell 4 | 5 | /** 6 | * Recreation of GTK revealer. Expects one single child. 7 | */ 8 | Item { 9 | id: root 10 | property bool reveal 11 | property bool vertical: false 12 | clip: true 13 | 14 | implicitWidth: (reveal || vertical) ? childrenRect.width : 0 15 | implicitHeight: (reveal || !vertical) ? childrenRect.height : 0 16 | visible: reveal || (width > 0 && height > 0) 17 | 18 | Behavior on implicitWidth { 19 | enabled: !vertical 20 | animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) 21 | } 22 | Behavior on implicitHeight { 23 | enabled: vertical 24 | animation: Appearance.animation.elementMoveEnter.numberAnimation.createObject(this) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/RoundCorner.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.9 2 | 3 | Item { 4 | id: root 5 | 6 | property int size: 25 7 | property color color 8 | 9 | onColorChanged: { 10 | canvas.requestPaint(); 11 | } 12 | 13 | property QtObject cornerEnum: QtObject { 14 | property int topLeft: 0 15 | property int topRight: 1 16 | property int bottomLeft: 2 17 | property int bottomRight: 3 18 | } 19 | 20 | property int corner: cornerEnum.topLeft // Default to TopLeft 21 | 22 | width: size 23 | height: size 24 | 25 | Canvas { 26 | id: canvas 27 | 28 | anchors.fill: parent 29 | antialiasing: true 30 | 31 | onPaint: { 32 | var ctx = getContext("2d"); 33 | var r = root.size; 34 | 35 | ctx.beginPath(); 36 | switch (root.corner) { 37 | case cornerEnum.topLeft: 38 | ctx.arc(r, r, r, Math.PI, 3 * Math.PI / 2); 39 | ctx.lineTo(0, 0); 40 | break; 41 | case cornerEnum.topRight: 42 | ctx.arc(0, r, r, 3 * Math.PI / 2, 2 * Math.PI); 43 | ctx.lineTo(r, 0); 44 | break; 45 | case cornerEnum.bottomLeft: 46 | ctx.arc(r, 0, r, Math.PI / 2, Math.PI); 47 | ctx.lineTo(0, r); 48 | break; 49 | case cornerEnum.bottomRight: 50 | ctx.arc(0, 0, r, 0, Math.PI / 2); 51 | ctx.lineTo(r, r); 52 | break; 53 | } 54 | ctx.closePath(); 55 | ctx.fillStyle = root.color; 56 | ctx.fill(); 57 | } 58 | } 59 | 60 | Behavior on size { 61 | animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/ScrollEdgeFade.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import qs.modules.common 3 | import qs.modules.common.functions 4 | 5 | Item { 6 | id: root 7 | z: 99 8 | required property Item target 9 | property real fadeSize: Appearance.m3colors.darkmode ? 40 : 20 10 | property color color: ColorUtils.transparentize(Appearance.colors.colShadow, Appearance.m3colors.darkmode ? 0 : 0.7) 11 | property bool vertical: true 12 | 13 | anchors.fill: target 14 | 15 | EndGradient { 16 | anchors { 17 | top: parent.top 18 | left: parent.left 19 | right: vertical ? parent.right : undefined 20 | bottom: vertical ? undefined : parent.bottom 21 | } 22 | shown: !(root.vertical ? root.target.atYBeginning : root.target.atXBeginning) 23 | } 24 | 25 | EndGradient { 26 | anchors { 27 | bottom: parent.bottom 28 | right: parent.right 29 | left: vertical ? parent.left : undefined 30 | top: vertical ? undefined : parent.top 31 | } 32 | shown: !(root.vertical ? root.target.atYEnd : root.target.atXEnd) 33 | rotation: 180 34 | } 35 | 36 | component EndGradient: Rectangle { 37 | required property bool shown 38 | height: vertical ? root.fadeSize : parent.height 39 | width: vertical ? parent.width : root.fadeSize 40 | 41 | opacity: shown ? 1 : 0 42 | visible: opacity > 0 43 | Behavior on opacity { 44 | animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) 45 | } 46 | 47 | gradient: Gradient { 48 | orientation: root.vertical ? Gradient.Vertical : Gradient.Horizontal 49 | GradientStop { 50 | position: 0.0 51 | color: root.color 52 | } 53 | GradientStop { 54 | position: 1.0 55 | color: ColorUtils.transparentize(root.color) 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/SelectionGroupButton.qml: -------------------------------------------------------------------------------- 1 | import QtQuick.Controls 2 | import QtQuick.Layouts 3 | import Quickshell 4 | import Quickshell.Io 5 | import Quickshell.Hyprland 6 | import qs.services 7 | import qs.modules.common 8 | import qs.modules.common.widgets 9 | 10 | GroupButton { 11 | id: root 12 | horizontalPadding: 12 13 | verticalPadding: 8 14 | bounce: false 15 | property bool leftmost: false 16 | property bool rightmost: false 17 | leftRadius: (leftmost) ? (height / 2) : Appearance.rounding.unsharpenmore 18 | rightRadius: (rightmost) ? (height / 2) : Appearance.rounding.unsharpenmore 19 | colBackground: Appearance.colors.colSecondaryContainer 20 | contentItem: StyledText { 21 | color: parent.toggled ? Appearance.colors.colOnPrimary : Appearance.colors.colOnSecondaryContainer 22 | text: root.buttonText 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/StyledLabel.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick 3 | import QtQuick.Controls 4 | import QtQuick.Layouts 5 | 6 | Label { 7 | renderType: Text.NativeRendering 8 | verticalAlignment: Text.AlignVCenter 9 | font { 10 | hintingPreference: Font.PreferFullHinting 11 | family: Appearance?.font.family.main ?? "sans-serif" 12 | pixelSize: Appearance?.font.pixelSize.small ?? 15 13 | } 14 | color: Appearance?.m3colors.m3onBackground ?? "black" 15 | linkColor: Appearance?.m3colors.m3primary 16 | } 17 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/StyledRectangularShadow.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Effects 3 | import qs.modules.common 4 | 5 | RectangularShadow { 6 | required property var target 7 | anchors.fill: target 8 | radius: target.radius 9 | blur: 0.9 * Appearance.sizes.elevationMargin 10 | offset: Qt.vector2d(0.0, 1.0) 11 | spread: 1 12 | color: Appearance.colors.colShadow 13 | cached: true 14 | } 15 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/StyledScrollBar.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Controls 3 | import qs.modules.common 4 | import qs.modules.common.functions 5 | 6 | ScrollBar { 7 | id: root 8 | 9 | policy: ScrollBar.AsNeeded 10 | topPadding: Appearance.rounding.normal 11 | bottomPadding: Appearance.rounding.normal 12 | 13 | contentItem: Rectangle { 14 | implicitWidth: 4 15 | implicitHeight: root.visualSize 16 | radius: width / 2 17 | color: Appearance.colors.colOutlineVariant 18 | 19 | opacity: root.policy === ScrollBar.AlwaysOn || (root.active && root.size < 1.0) ? 0.5 : 0 20 | Behavior on opacity { 21 | NumberAnimation { 22 | duration: 350 23 | easing.type: Appearance.animation.elementMoveFast.type 24 | easing.bezierCurve: Appearance.animation.elementMoveFast.bezierCurve 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/StyledTextArea.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick 3 | import QtQuick.Controls 4 | 5 | /** 6 | * Does not include visual layout, but includes the easily neglected colors. 7 | */ 8 | TextArea { 9 | renderType: Text.NativeRendering 10 | selectedTextColor: Appearance.m3colors.m3onSecondaryContainer 11 | selectionColor: Appearance.colors.colSecondaryContainer 12 | placeholderTextColor: Appearance.m3colors.m3outline 13 | font { 14 | family: Appearance?.font.family.main ?? "sans-serif" 15 | pixelSize: Appearance?.font.pixelSize.small ?? 15 16 | hintingPreference: Font.PreferFullHinting 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/StyledTextInput.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick 3 | import QtQuick.Controls 4 | 5 | /** 6 | * Does not include visual layout, but includes the easily neglected colors. 7 | */ 8 | TextInput { 9 | renderType: Text.NativeRendering 10 | selectedTextColor: Appearance.m3colors.m3onSecondaryContainer 11 | selectionColor: Appearance.colors.colSecondaryContainer 12 | font { 13 | family: Appearance?.font.family.main ?? "sans-serif" 14 | pixelSize: Appearance?.font.pixelSize.small ?? 15 15 | hintingPreference: Font.PreferFullHinting 16 | } 17 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/StyledToolTip.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | 7 | ToolTip { 8 | id: root 9 | property bool extraVisibleCondition: true 10 | property bool alternativeVisibleCondition: false 11 | readonly property bool internalVisibleCondition: (extraVisibleCondition && (parent.hovered === undefined || parent?.hovered)) || alternativeVisibleCondition 12 | verticalPadding: 5 13 | horizontalPadding: 10 14 | background: null 15 | 16 | visible: internalVisibleCondition 17 | 18 | contentItem: StyledToolTipContent { 19 | id: contentItem 20 | text: root.text 21 | shown: root.internalVisibleCondition 22 | horizontalPadding: root.horizontalPadding 23 | verticalPadding: root.verticalPadding 24 | } 25 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/StyledToolTipContent.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | 7 | Item { 8 | id: root 9 | required property string text 10 | property bool shown: false 11 | property real horizontalPadding: 10 12 | property real verticalPadding: 5 13 | implicitWidth: tooltipTextObject.implicitWidth + 2 * root.horizontalPadding 14 | implicitHeight: tooltipTextObject.implicitHeight + 2 * root.verticalPadding 15 | 16 | property bool isVisible: backgroundRectangle.implicitHeight > 0 17 | 18 | Rectangle { 19 | id: backgroundRectangle 20 | anchors { 21 | bottom: root.bottom 22 | horizontalCenter: root.horizontalCenter 23 | } 24 | color: Appearance?.colors.colTooltip ?? "#3C4043" 25 | radius: Appearance?.rounding.verysmall ?? 7 26 | opacity: shown ? 1 : 0 27 | implicitWidth: shown ? (tooltipTextObject.implicitWidth + 2 * root.horizontalPadding) : 0 28 | implicitHeight: shown ? (tooltipTextObject.implicitHeight + 2 * root.verticalPadding) : 0 29 | clip: true 30 | 31 | Behavior on implicitWidth { 32 | animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) 33 | } 34 | Behavior on implicitHeight { 35 | animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) 36 | } 37 | Behavior on opacity { 38 | animation: Appearance?.animation.elementMoveFast.numberAnimation.createObject(this) 39 | } 40 | 41 | StyledText { 42 | id: tooltipTextObject 43 | anchors.centerIn: parent 44 | text: root.text 45 | font.pixelSize: Appearance?.font.pixelSize.smaller ?? 14 46 | font.hintingPreference: Font.PreferNoHinting // Prevent shaky text 47 | color: Appearance?.colors.colOnTooltip ?? "#FFFFFF" 48 | wrapMode: Text.Wrap 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/share/sleex/modules/common/widgets/VerticalButtonGroup.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | 8 | /** 9 | * A container that supports GroupButton children for bounciness. 10 | * See https://m3.material.io/components/button-groups/overview 11 | */ 12 | Rectangle { 13 | id: root 14 | default property alias content: columnLayout.data 15 | property real spacing: 5 16 | property real padding: 0 17 | property int clickIndex: columnLayout.clickIndex 18 | 19 | property real contentHeight: { 20 | let total = 0; 21 | for (let i = 0; i < columnLayout.children.length; ++i) { 22 | const child = columnLayout.children[i]; 23 | total += child.baseHeight ?? child.implicitHeight ?? child.height; 24 | } 25 | return total + columnLayout.spacing * (columnLayout.children.length - 1); 26 | } 27 | 28 | topLeftRadius: columnLayout.children.length > 0 ? (columnLayout.children[0].radius + padding) : 29 | Appearance?.rounding?.small 30 | topRightRadius: topLeftRadius 31 | bottomLeftRadius: columnLayout.children.length > 0 ? (columnLayout.children[columnLayout.children.length - 1].radius + padding) : 32 | Appearance?.rounding?.small 33 | bottomRightRadius: bottomLeftRadius 34 | 35 | color: "transparent" 36 | height: root.contentHeight + padding * 2 37 | implicitWidth: columnLayout.implicitWidth + padding * 2 38 | implicitHeight: root.contentHeight + padding * 2 39 | 40 | children: [ColumnLayout { 41 | id: columnLayout 42 | anchors.fill: parent 43 | anchors.margins: root.padding 44 | spacing: root.spacing 45 | property int clickIndex: -1 46 | }] 47 | } 48 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/AiWidgetGroup.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import "./ai" 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | import Quickshell 9 | 10 | Rectangle { 11 | id: root 12 | color: "transparent" 13 | clip: true 14 | 15 | AiChat { 16 | anchors.fill: parent 17 | } 18 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/TodoWidgetGroup.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import "./calendar" 5 | import "./todo" 6 | import QtQuick 7 | import QtQuick.Controls 8 | import QtQuick.Layouts 9 | import Quickshell 10 | 11 | Rectangle { 12 | id: root 13 | color: "transparent" 14 | clip: true 15 | 16 | 17 | TodoWidget { 18 | anchors.fill: parent 19 | anchors.margins: 5 20 | } 21 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/ai/ApiCommandButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | 5 | GroupButton { 6 | id: button 7 | property string buttonText 8 | 9 | horizontalPadding: 8 10 | verticalPadding: 6 11 | 12 | baseWidth: contentItem.implicitWidth + horizontalPadding * 2 13 | clickedWidth: baseWidth + 20 14 | baseHeight: contentItem.implicitHeight + verticalPadding * 2 15 | buttonRadius: down ? Appearance.rounding.verysmall : Appearance.rounding.small 16 | 17 | colBackground: Appearance.colors.colLayer2 18 | colBackgroundHover: Appearance.colors.colLayer2Hover 19 | colBackgroundActive: Appearance.colors.colLayer2Active 20 | 21 | contentItem: StyledText { 22 | horizontalAlignment: Text.AlignHCenter 23 | text: buttonText 24 | color: Appearance.m3colors.m3onSurface 25 | } 26 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/ai/ApiInputBoxIndicator.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | import QtQuick.Layouts 6 | 7 | Item { // Model indicator 8 | id: root 9 | property string icon: "api" 10 | property string text: "" 11 | property string tooltipText: "" 12 | implicitHeight: rowLayout.implicitHeight + 4 * 2 13 | implicitWidth: rowLayout.implicitWidth + 4 * 2 14 | 15 | RowLayout { 16 | id: rowLayout 17 | anchors.centerIn: parent 18 | 19 | MaterialSymbol { 20 | text: root.icon 21 | iconSize: Appearance.font.pixelSize.normal 22 | } 23 | StyledText { 24 | id: providerName 25 | font.pixelSize: Appearance.font.pixelSize.smaller 26 | color: Appearance.m3colors.m3onSurface 27 | elide: Text.ElideRight 28 | text: root.text 29 | animateChange: true 30 | } 31 | } 32 | 33 | Loader { 34 | active: root.tooltipText?.length > 0 35 | anchors.fill: parent 36 | sourceComponent: MouseArea { 37 | id: mouseArea 38 | hoverEnabled: true 39 | 40 | StyledToolTip { 41 | id: toolTip 42 | extraVisibleCondition: false 43 | alternativeVisibleCondition: mouseArea.containsMouse // Show tooltip when hovered 44 | text: root.tooltipText 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/ai/DescriptionBox.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.services 3 | import qs.modules.common 4 | import qs.modules.common.widgets 5 | import QtQuick 6 | import QtQuick.Layouts 7 | 8 | Item { // Tag suggestion description 9 | id: root 10 | property alias text: tagDescriptionText.text 11 | property bool showArrows: true 12 | property bool showTab: true 13 | 14 | visible: tagDescriptionText.text.length > 0 15 | Layout.fillWidth: true 16 | implicitHeight: tagDescriptionBackground.implicitHeight 17 | 18 | Rectangle { 19 | id: tagDescriptionBackground 20 | color: Appearance.colors.colLayer2 21 | anchors.fill: parent 22 | radius: Appearance.rounding.verysmall 23 | implicitHeight: descriptionRow.implicitHeight + 5 * 2 24 | 25 | RowLayout { 26 | id: descriptionRow 27 | spacing: 4 28 | anchors { 29 | fill: parent 30 | leftMargin: 10 31 | rightMargin: 10 32 | } 33 | 34 | StyledText { 35 | id: tagDescriptionText 36 | Layout.fillWidth: true 37 | font.pixelSize: Appearance.font.pixelSize.smaller 38 | color: Appearance.colors.colOnLayer2 39 | wrapMode: Text.Wrap 40 | } 41 | KeyboardKey { 42 | visible: root.showArrows 43 | key: "↑" 44 | } 45 | KeyboardKey { 46 | visible: root.showArrows 47 | key: "↓" 48 | } 49 | StyledText { 50 | visible: root.showArrows && root.showTab 51 | text: "or" 52 | font.pixelSize: Appearance.font.pixelSize.smaller 53 | } 54 | KeyboardKey { 55 | id: tagDescriptionKey 56 | visible: root.showTab 57 | key: "Tab" 58 | Layout.alignment: Qt.AlignVCenter 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/ai/aiChat/AiMessageControlButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | 6 | GroupButton { 7 | id: button 8 | property string buttonIcon 9 | property bool activated: false 10 | toggled: activated 11 | 12 | baseWidth: height 13 | 14 | contentItem: MaterialSymbol { 15 | horizontalAlignment: Text.AlignHCenter 16 | iconSize: Appearance.font.pixelSize.larger 17 | text: buttonIcon 18 | color: button.activated ? Appearance.m3colors.m3onPrimary : 19 | button.enabled ? Appearance.m3colors.m3onSurface : 20 | Appearance.colors.colOnLayer1Inactive 21 | 22 | Behavior on color { 23 | animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/ai/aiChat/AnnotationSourceButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import qs.services 5 | import QtQuick 6 | import QtQuick.Layouts 7 | import Quickshell.Hyprland 8 | 9 | RippleButton { 10 | id: root 11 | property string displayText 12 | property string url 13 | 14 | property real faviconSize: 20 15 | implicitHeight: 30 16 | leftPadding: (implicitHeight - faviconSize) / 2 17 | rightPadding: 10 18 | buttonRadius: Appearance.rounding.full 19 | colBackground: Appearance.colors.colSurfaceContainerHighest 20 | colBackgroundHover: Appearance.colors.colSurfaceContainerHighestHover 21 | colRipple: Appearance.colors.colSurfaceContainerHighestActive 22 | 23 | PointingHandInteraction {} 24 | onClicked: { 25 | if (url) { 26 | Qt.openUrlExternally(url) 27 | GlobalStates.sidebarLeftOpen = false 28 | } 29 | } 30 | 31 | contentItem: Item { 32 | anchors.centerIn: parent 33 | implicitWidth: rowLayout.implicitWidth 34 | implicitHeight: rowLayout.implicitHeight 35 | RowLayout { 36 | id: rowLayout 37 | anchors.fill: parent 38 | spacing: 5 39 | Favicon { 40 | url: root.url 41 | size: root.faviconSize 42 | displayText: root.displayText 43 | } 44 | StyledText { 45 | id: text 46 | horizontalAlignment: Text.AlignHCenter 47 | text: displayText 48 | color: Appearance.m3colors.m3onSurface 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/ai/aiChat/SearchQueryButton.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.modules.common 3 | import qs.modules.common.widgets 4 | import qs.services 5 | import qs.modules.common.functions 6 | import QtQuick 7 | import QtQuick.Layouts 8 | import Quickshell.Hyprland 9 | 10 | RippleButton { 11 | id: root 12 | property string query 13 | 14 | implicitHeight: 30 15 | leftPadding: 6 16 | rightPadding: 10 17 | buttonRadius: Appearance.rounding.verysmall 18 | colBackground: Appearance.colors.colSurfaceContainerHighest 19 | colBackgroundHover: Appearance.colors.colSurfaceContainerHighestHover 20 | colRipple: Appearance.colors.colSurfaceContainerHighestActive 21 | 22 | PointingHandInteraction {} 23 | onClicked: { 24 | let url = Config.options.search.engineBaseUrl + root.query; 25 | for (let site of (Config?.options?.search.excludedSites ?? [])) { 26 | url += ` -site:${site}`; 27 | } 28 | Qt.openUrlExternally(url); 29 | GlobalStates.sidebarLeftOpen = false; 30 | } 31 | 32 | contentItem: Item { 33 | anchors.centerIn: parent 34 | implicitWidth: rowLayout.implicitWidth 35 | implicitHeight: rowLayout.implicitHeight 36 | RowLayout { 37 | id: rowLayout 38 | anchors.centerIn: parent 39 | spacing: 5 40 | MaterialSymbol { 41 | text: "search" 42 | iconSize: 20 43 | color: Appearance.m3colors.m3onSurface 44 | } 45 | StyledText { 46 | id: text 47 | horizontalAlignment: Text.AlignHCenter 48 | text: root.query 49 | color: Appearance.m3colors.m3onSurface 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/calendar/CalendarDayButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | 8 | RippleButton { 9 | id: button 10 | property string day 11 | property int isToday 12 | property bool bold 13 | 14 | Layout.fillWidth: false 15 | Layout.fillHeight: false 16 | implicitWidth: 38; 17 | implicitHeight: 38; 18 | 19 | toggled: (isToday == 1) 20 | buttonRadius: Appearance.rounding.small 21 | 22 | contentItem: StyledText { 23 | anchors.fill: parent 24 | text: day 25 | horizontalAlignment: Text.AlignHCenter 26 | font.weight: bold ? Font.DemiBold : Font.Normal 27 | color: (isToday == 1) ? Appearance.m3colors.m3onPrimary : 28 | (isToday == 0) ? Appearance.colors.colOnLayer1 : 29 | Appearance.colors.colOutlineVariant 30 | 31 | Behavior on color { 32 | animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/calendar/CalendarHeaderButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | 7 | RippleButton { 8 | id: button 9 | property string buttonText: "" 10 | property string tooltipText: "" 11 | property bool forceCircle: false 12 | 13 | implicitHeight: 30 14 | implicitWidth: forceCircle ? implicitHeight : (contentItem.implicitWidth + 10 * 2) 15 | Behavior on implicitWidth { 16 | SmoothedAnimation { 17 | velocity: Appearance.animation.elementMove.velocity 18 | } 19 | } 20 | 21 | background.anchors.fill: button 22 | buttonRadius: Appearance.rounding.full 23 | colBackground: Appearance.colors.colLayer2 24 | colBackgroundHover: Appearance.colors.colLayer2Hover 25 | colRipple: Appearance.colors.colLayer2Active 26 | 27 | contentItem: StyledText { 28 | text: buttonText 29 | horizontalAlignment: Text.AlignHCenter 30 | font.pixelSize: Appearance.font.pixelSize.larger 31 | color: Appearance.colors.colOnLayer1 32 | } 33 | 34 | StyledToolTip { 35 | text: tooltipText 36 | extraVisibleCondition: tooltipText.length > 0 37 | } 38 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/notifications/NotificationStatusButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | 7 | GroupButton { 8 | id: button 9 | property string buttonText: "" 10 | property string buttonIcon: "" 11 | 12 | baseWidth: content.implicitWidth + 10 * 2 13 | baseHeight: 30 14 | 15 | buttonRadius: baseHeight / 2 16 | buttonRadiusPressed: Appearance.rounding.small 17 | colBackground: Appearance.colors.colLayer2 18 | colBackgroundHover: Appearance.colors.colLayer2Hover 19 | colBackgroundActive: Appearance.colors.colLayer2Active 20 | property color colText: toggled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer1 21 | 22 | contentItem: Item { 23 | id: content 24 | anchors.fill: parent 25 | implicitWidth: contentRowLayout.implicitWidth 26 | implicitHeight: contentRowLayout.implicitHeight 27 | RowLayout { 28 | id: contentRowLayout 29 | anchors.centerIn: parent 30 | spacing: 5 31 | MaterialSymbol { 32 | text: buttonIcon 33 | iconSize: Appearance.font.pixelSize.large 34 | color: button.colText 35 | } 36 | StyledText { 37 | text: buttonText 38 | font.pixelSize: Appearance.font.pixelSize.small 39 | color: button.colText 40 | } 41 | } 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/quickToggles/BluetoothToggle.qml: -------------------------------------------------------------------------------- 1 | import "../" 2 | import qs 3 | import qs.services 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | import qs.modules.common.functions 7 | import QtQuick 8 | import Quickshell 9 | import Quickshell.Io 10 | import Quickshell.Bluetooth 11 | import Quickshell.Hyprland 12 | 13 | import Sleex.Services 14 | 15 | QuickToggleButton { 16 | toggled: Bluetooth.defaultAdapter.enabled 17 | buttonIcon: BluetoothService.bluetoothConnected ? "bluetooth_connected" : Bluetooth.defaultAdapter.enabled ? "bluetooth" : "bluetooth_disabled" 18 | onClicked: { 19 | Bluetooth.defaultAdapter.enabled = !Bluetooth.defaultAdapter.enabled 20 | } 21 | altAction: () => { 22 | Quickshell.execDetached(["bash", "-c", `${Config.options.apps.bluetooth}`]) 23 | GlobalStates.dashboardOpen = false 24 | } 25 | Process { 26 | id: toggleBluetooth 27 | command: ["bash", "-c", `bluetoothctl power ${Bluetooth.defaultAdapter.enabled ? "off" : "on"}`] 28 | onRunningChanged: { 29 | if(!running) { 30 | BluetoothService.update() 31 | } 32 | } 33 | } 34 | StyledToolTip { 35 | text: StringUtils.format(qsTr("{0} | Right-click to configure"), 36 | (Bluetooth.defaultAdapter.enabled && BluetoothService.bluetoothDeviceName.length > 0) ? 37 | BluetoothService.bluetoothDeviceName : qsTr("Bluetooth")) 38 | 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/quickToggles/GameMode.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import "../" 4 | import Quickshell 5 | import Quickshell.Io 6 | import Quickshell.Hyprland 7 | 8 | QuickToggleButton { 9 | property bool enabled: false 10 | buttonIcon: "gamepad" 11 | toggled: enabled 12 | 13 | onClicked: { 14 | enabled = !enabled 15 | if (enabled) { 16 | // gameModeOn.running = true 17 | Quickshell.execDetached(["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"]) 18 | } else { 19 | Quickshell.execDetached(["hyprctl reload"]) 20 | } 21 | } 22 | 23 | StyledToolTip { 24 | text: qsTr("Game mode") 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/quickToggles/IdleInhibitor.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import "../" 4 | import Quickshell.Io 5 | import Quickshell 6 | import Quickshell.Hyprland 7 | 8 | QuickToggleButton { 9 | id: root 10 | toggled: false 11 | buttonIcon: "coffee" 12 | onClicked: { 13 | if (toggled) { 14 | root.toggled = false 15 | Quickshell.execDetached(["exec", "pkill", "wayland-idle"]) 16 | } else { 17 | root.toggled = true 18 | Quickshell.execDetached(["python", "/usr/share/sleex/scripts/wayland-idle-inhibitor.py"]) 19 | } 20 | } 21 | Process { 22 | id: fetchActiveState 23 | running: true 24 | command: ["bash", "-c", "pidof wayland-idle-inhibitor.py"] 25 | onExited: (exitCode, exitStatus) => { 26 | root.toggled = exitCode === 0 27 | } 28 | } 29 | StyledToolTip { 30 | text: qsTr("Keep system awake") 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/quickToggles/NetworkToggle.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.services 3 | import qs.modules.common 4 | import qs.modules.common.widgets 5 | import qs.modules.common.functions 6 | import "../" 7 | import QtQuick 8 | import Quickshell 9 | import Quickshell.Io 10 | import Quickshell.Hyprland 11 | 12 | import Sleex.Services 13 | 14 | QuickToggleButton { 15 | 16 | toggled: Network.wifiEnabled 17 | buttonIcon: Network.wifiEnabled ? Network.getNetworkIcon(Network.active.strength ?? 0) : "wifi_off" 18 | onClicked: { 19 | Network.toggleWifi() 20 | } 21 | altAction: () => { 22 | Quickshell.execDetached(["bash", "-c", `${Network.ethernet ? Config.options.apps.networkEthernet : Config.options.apps.network}`]) 23 | GlobalStates.dashboardOpen = false 24 | } 25 | StyledToolTip { 26 | text: StringUtils.format(qsTr("{0} | Right-click to configure"), Network.active.ssid) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/quickToggles/NightLight.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import qs.modules.common 3 | import qs.modules.common.widgets 4 | import qs 5 | import qs.services 6 | import Quickshell.Io 7 | 8 | QuickToggleButton { 9 | id: nightLightButton 10 | property bool enabled: NightLight.active 11 | toggled: enabled 12 | buttonIcon: Config.options.display.nightLightAuto ? "night_sight_auto" : "bedtime" 13 | onClicked: { 14 | NightLight.toggle() 15 | } 16 | 17 | altAction: () => { 18 | Config.options.display.nightLightAuto = !Config.options.display.nightLightAuto 19 | } 20 | 21 | Component.onCompleted: { 22 | NightLight.fetchState() 23 | } 24 | 25 | StyledToolTip { 26 | text: "Night Light | Right-click to toggle Auto mode" 27 | } 28 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/quickToggles/QuickToggleButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | import Quickshell.Io 8 | 9 | GroupButton { 10 | id: button 11 | property string buttonIcon 12 | baseWidth: altAction ? 60 : 40 13 | baseHeight: 40 14 | clickedWidth: baseWidth + 20 15 | toggled: false 16 | buttonRadius: (altAction && toggled) ? Appearance?.rounding.normal : Math.min(baseHeight, baseWidth) / 2 17 | buttonRadiusPressed: Appearance?.rounding?.small 18 | 19 | contentItem: MaterialSymbol { 20 | anchors.centerIn: parent 21 | iconSize: Appearance.font.pixelSize.larger 22 | fill: toggled ? 1 : 0 23 | color: toggled ? Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer1 24 | horizontalAlignment: Text.AlignHCenter 25 | verticalAlignment: Text.AlignVCenter 26 | text: buttonIcon 27 | 28 | Behavior on color { 29 | animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) 30 | } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/todo/TodoItemActionButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | 8 | RippleButton { 9 | id: button 10 | property string buttonText: "" 11 | property string tooltipText: "" 12 | 13 | implicitHeight: 30 14 | implicitWidth: implicitHeight 15 | 16 | Behavior on implicitWidth { 17 | SmoothedAnimation { 18 | velocity: Appearance.animation.elementMove.velocity 19 | } 20 | } 21 | 22 | buttonRadius: Appearance.rounding.small 23 | 24 | contentItem: StyledText { 25 | text: buttonText 26 | horizontalAlignment: Text.AlignHCenter 27 | font.pixelSize: Appearance.font.pixelSize.larger 28 | color: Appearance.colors.colOnLayer1 29 | } 30 | 31 | StyledToolTip { 32 | text: tooltipText 33 | extraVisibleCondition: tooltipText.length > 0 34 | } 35 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dashboard/weather/WeatherOff.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | import QtQuick.Layouts 3 | import QtQuick.Controls 4 | import qs.modules.common 5 | import qs.modules.common.widgets 6 | import qs.services 7 | 8 | Rectangle { 9 | id: weatherRoot 10 | anchors.horizontalCenterOffset: -2 11 | color: "transparent" 12 | 13 | Rectangle { 14 | id: card 15 | anchors.fill: parent 16 | color: "transparent" 17 | 18 | ColumnLayout { 19 | anchors.fill: parent 20 | Text { 21 | text: "Weather disabled" 22 | color: Appearance.colors.colOnLayer1 23 | font.pixelSize: Appearance.font.pixelSize.title 24 | Layout.fillWidth: true 25 | horizontalAlignment: Text.AlignHCenter 26 | } 27 | // Separator line 28 | Rectangle { 29 | width: parent.width 30 | height: 1 31 | color: Appearance.colors.colLayer2 32 | Layout.fillWidth: true 33 | Layout.topMargin: 2 34 | Layout.bottomMargin: 2 35 | } 36 | Text { 37 | text: "The weather service is disabled.\nEnable it in the policy page of the Sleex settings." 38 | color: Appearance.colors.colOnLayer1 39 | font.pixelSize: Appearance.font.pixelSize.normal 40 | horizontalAlignment: Text.AlignHCenter 41 | wrapMode: Text.Wrap 42 | Layout.fillWidth: true 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/dock/DockButton.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.modules.common 3 | import qs.modules.common.widgets 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | 8 | RippleButton { 9 | Layout.fillHeight: true 10 | Layout.topMargin: Appearance.sizes.elevationMargin - Appearance.sizes.hyprlandGapsOut 11 | implicitWidth: implicitHeight - topInset - bottomInset 12 | buttonRadius: Appearance.rounding.normal 13 | 14 | topInset: Appearance.sizes.hyprlandGapsOut + dockRow.padding 15 | bottomInset: Appearance.sizes.hyprlandGapsOut + dockRow.padding 16 | } 17 | -------------------------------------------------------------------------------- /src/share/sleex/modules/dock/DockSeparator.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.modules.common 3 | import QtQuick 4 | import QtQuick.Controls 5 | import QtQuick.Layouts 6 | 7 | Rectangle { 8 | Layout.topMargin: Appearance.sizes.elevationMargin + dockRow.padding + Appearance.rounding.normal 9 | Layout.bottomMargin: Appearance.sizes.hyprlandGapsOut + dockRow.padding + Appearance.rounding.normal 10 | Layout.fillHeight: true 11 | implicitWidth: 1 12 | color: Appearance.colors.colOutlineVariant 13 | } 14 | -------------------------------------------------------------------------------- /src/share/sleex/modules/lockscreen/pam/password.conf: -------------------------------------------------------------------------------- 1 | auth sufficient pam_fprintd.so 2 | auth required pam_unix.so 3 | -------------------------------------------------------------------------------- /src/share/sleex/modules/notificationPopup/NotificationPopup.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.modules.common 3 | import qs.modules.common.widgets 4 | import qs.services 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | import Quickshell 9 | import Quickshell.Wayland 10 | import Quickshell.Hyprland 11 | 12 | Scope { 13 | id: notificationPopup 14 | 15 | PanelWindow { 16 | id: root 17 | visible: (Notifications.popupList.length > 0) 18 | screen: Quickshell.screens.find(s => s.name === Hyprland.focusedMonitor?.name) ?? null 19 | 20 | WlrLayershell.namespace: "quickshell:notificationPopup" 21 | WlrLayershell.layer: WlrLayer.Overlay 22 | exclusiveZone: 0 23 | 24 | anchors { 25 | top: true 26 | bottom: true 27 | } 28 | 29 | mask: Region { 30 | item: listview.contentItem 31 | } 32 | 33 | color: "transparent" 34 | implicitWidth: Appearance.sizes.notificationPopupWidth 35 | 36 | NotificationListView { 37 | id: listview 38 | anchors.top: parent.top 39 | anchors.bottom: parent.bottom 40 | anchors.horizontalCenter: parent.horizontalCenter 41 | anchors.topMargin: 5 42 | implicitWidth: parent.width - Appearance.sizes.elevationMargin * 2 43 | popup: true 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/share/sleex/modules/session/SessionActionButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import QtQuick 5 | import QtQuick.Controls 6 | import QtQuick.Layouts 7 | import Quickshell 8 | import Quickshell.Io 9 | 10 | RippleButton { 11 | id: button 12 | 13 | property string buttonIcon 14 | property string buttonText 15 | property bool keyboardDown: false 16 | property real size: 120 17 | 18 | buttonRadius: (button.focus || button.down) ? size / 2 : Appearance.rounding.verylarge 19 | colBackground: button.keyboardDown ? Appearance.colors.colSecondaryContainerActive : 20 | button.focus ? Appearance.colors.colPrimary : 21 | Appearance.colors.colSecondaryContainer 22 | colBackgroundHover: Appearance.colors.colPrimary 23 | colRipple: Appearance.colors.colPrimaryActive 24 | property color colText: (button.down || button.keyboardDown || button.focus || button.hovered) ? 25 | Appearance.m3colors.m3onPrimary : Appearance.colors.colOnLayer0 26 | 27 | Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter 28 | background.implicitHeight: size 29 | background.implicitWidth: size 30 | 31 | Behavior on buttonRadius { 32 | animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this) 33 | } 34 | 35 | Keys.onPressed: (event) => { 36 | if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { 37 | keyboardDown = true 38 | button.clicked() 39 | event.accepted = true; 40 | } 41 | } 42 | Keys.onReleased: (event) => { 43 | if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { 44 | keyboardDown = false 45 | event.accepted = true; 46 | } 47 | } 48 | 49 | contentItem: MaterialSymbol { 50 | id: icon 51 | anchors.fill: parent 52 | color: button.colText 53 | horizontalAlignment: Text.AlignHCenter 54 | iconSize: 45 55 | text: buttonIcon 56 | } 57 | 58 | StyledToolTip { 59 | text: buttonText 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /src/share/sleex/modules/sidebarLeft/ApiCommandButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import QtQuick 4 | 5 | GroupButton { 6 | id: button 7 | property string buttonText 8 | 9 | horizontalPadding: 8 10 | verticalPadding: 6 11 | 12 | baseWidth: contentItem.implicitWidth + horizontalPadding * 2 13 | clickedWidth: baseWidth + 20 14 | baseHeight: contentItem.implicitHeight + verticalPadding * 2 15 | buttonRadius: down ? Appearance.rounding.verysmall : Appearance.rounding.small 16 | 17 | colBackground: Appearance.colors.colLayer2 18 | colBackgroundHover: Appearance.colors.colLayer2Hover 19 | colBackgroundActive: Appearance.colors.colLayer2Active 20 | 21 | contentItem: StyledText { 22 | horizontalAlignment: Text.AlignHCenter 23 | text: buttonText 24 | color: Appearance.m3colors.m3onSurface 25 | } 26 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/sidebarLeft/ApiInputBoxIndicator.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | import QtQuick.Layouts 6 | 7 | Item { // Model indicator 8 | id: root 9 | property string icon: "api" 10 | property string text: "" 11 | property string tooltipText: "" 12 | implicitHeight: rowLayout.implicitHeight + 4 * 2 13 | implicitWidth: rowLayout.implicitWidth + 4 * 2 14 | 15 | RowLayout { 16 | id: rowLayout 17 | anchors.centerIn: parent 18 | 19 | MaterialSymbol { 20 | text: root.icon 21 | iconSize: Appearance.font.pixelSize.normal 22 | } 23 | StyledText { 24 | id: providerName 25 | font.pixelSize: Appearance.font.pixelSize.smaller 26 | color: Appearance.m3colors.m3onSurface 27 | elide: Text.ElideRight 28 | text: root.text 29 | animateChange: true 30 | } 31 | } 32 | 33 | Loader { 34 | active: root.tooltipText?.length > 0 35 | anchors.fill: parent 36 | sourceComponent: MouseArea { 37 | id: mouseArea 38 | hoverEnabled: true 39 | 40 | StyledToolTip { 41 | id: toolTip 42 | extraVisibleCondition: false 43 | alternativeVisibleCondition: mouseArea.containsMouse // Show tooltip when hovered 44 | text: root.tooltipText 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/share/sleex/modules/sidebarLeft/DescriptionBox.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.services 3 | import qs.modules.common 4 | import qs.modules.common.widgets 5 | import QtQuick 6 | import QtQuick.Layouts 7 | 8 | Item { // Tag suggestion description 9 | id: root 10 | property alias text: tagDescriptionText.text 11 | property bool showArrows: true 12 | property bool showTab: true 13 | 14 | visible: tagDescriptionText.text.length > 0 15 | Layout.fillWidth: true 16 | implicitHeight: tagDescriptionBackground.implicitHeight 17 | 18 | Rectangle { 19 | id: tagDescriptionBackground 20 | color: Appearance.colors.colLayer2 21 | anchors.fill: parent 22 | radius: Appearance.rounding.verysmall 23 | implicitHeight: descriptionRow.implicitHeight + 5 * 2 24 | 25 | RowLayout { 26 | id: descriptionRow 27 | spacing: 4 28 | anchors { 29 | fill: parent 30 | leftMargin: 10 31 | rightMargin: 10 32 | } 33 | 34 | StyledText { 35 | id: tagDescriptionText 36 | Layout.fillWidth: true 37 | font.pixelSize: Appearance.font.pixelSize.smaller 38 | color: Appearance.colors.colOnLayer2 39 | wrapMode: Text.Wrap 40 | } 41 | KeyboardKey { 42 | visible: root.showArrows 43 | key: "↑" 44 | } 45 | KeyboardKey { 46 | visible: root.showArrows 47 | key: "↓" 48 | } 49 | StyledText { 50 | visible: root.showArrows && root.showTab 51 | text: "or" 52 | font.pixelSize: Appearance.font.pixelSize.smaller 53 | } 54 | KeyboardKey { 55 | id: tagDescriptionKey 56 | visible: root.showTab 57 | key: "Tab" 58 | Layout.alignment: Qt.AlignVCenter 59 | } 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/sidebarLeft/SidebarLeftContent.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.services 3 | import qs.modules.common 4 | import qs.modules.common.widgets 5 | import QtQuick 6 | import QtQuick.Controls 7 | import QtQuick.Layouts 8 | import QtQuick.Effects 9 | import Qt5Compat.GraphicalEffects 10 | import Quickshell.Io 11 | import Quickshell 12 | import Quickshell.Widgets 13 | import Quickshell.Wayland 14 | import Quickshell.Hyprland 15 | 16 | Item { 17 | id: root 18 | required property var scopeRoot 19 | anchors.fill: parent 20 | 21 | ColumnLayout { 22 | anchors.fill: parent 23 | anchors.margins: sidebarPadding 24 | 25 | spacing: sidebarPadding 26 | 27 | SwipeView { // Content pages 28 | id: swipeView 29 | Layout.topMargin: 5 30 | Layout.fillWidth: true 31 | Layout.fillHeight: true 32 | spacing: 10 33 | 34 | contentChildren: [ 35 | aiChat.createObject() 36 | ] 37 | } 38 | 39 | Component { 40 | id: aiChat 41 | AiChat {} 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /src/share/sleex/modules/sidebarLeft/aiChat/AiMessageControlButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.services 4 | import QtQuick 5 | 6 | GroupButton { 7 | id: button 8 | property string buttonIcon 9 | property bool activated: false 10 | toggled: activated 11 | 12 | baseWidth: height 13 | 14 | contentItem: MaterialSymbol { 15 | horizontalAlignment: Text.AlignHCenter 16 | iconSize: Appearance.font.pixelSize.larger 17 | text: buttonIcon 18 | color: button.activated ? Appearance.m3colors.m3onPrimary : 19 | button.enabled ? Appearance.m3colors.m3onSurface : 20 | Appearance.colors.colOnLayer1Inactive 21 | 22 | Behavior on color { 23 | animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this) 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/share/sleex/modules/sidebarLeft/aiChat/AnnotationSourceButton.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.modules.common.widgets 3 | import qs.modules.common.functions 4 | import qs.services 5 | import QtQuick 6 | import QtQuick.Layouts 7 | import Quickshell.Hyprland 8 | 9 | RippleButton { 10 | id: root 11 | property string displayText 12 | property string url 13 | 14 | property real faviconSize: 20 15 | implicitHeight: 30 16 | leftPadding: (implicitHeight - faviconSize) / 2 17 | rightPadding: 10 18 | buttonRadius: Appearance.rounding.full 19 | colBackground: Appearance.colors.colSurfaceContainerHighest 20 | colBackgroundHover: Appearance.colors.colSurfaceContainerHighestHover 21 | colRipple: Appearance.colors.colSurfaceContainerHighestActive 22 | 23 | PointingHandInteraction {} 24 | onClicked: { 25 | if (url) { 26 | Qt.openUrlExternally(url) 27 | GlobalStates.sidebarLeftOpen = false 28 | } 29 | } 30 | 31 | contentItem: Item { 32 | anchors.centerIn: parent 33 | implicitWidth: rowLayout.implicitWidth 34 | implicitHeight: rowLayout.implicitHeight 35 | RowLayout { 36 | id: rowLayout 37 | anchors.fill: parent 38 | spacing: 5 39 | Favicon { 40 | url: root.url 41 | size: root.faviconSize 42 | displayText: root.displayText 43 | } 44 | StyledText { 45 | id: text 46 | horizontalAlignment: Text.AlignHCenter 47 | text: displayText 48 | color: Appearance.m3colors.m3onSurface 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/share/sleex/modules/sidebarLeft/aiChat/SearchQueryButton.qml: -------------------------------------------------------------------------------- 1 | import qs 2 | import qs.modules.common 3 | import qs.modules.common.widgets 4 | import qs.services 5 | import qs.modules.common.functions 6 | import QtQuick 7 | import QtQuick.Layouts 8 | import Quickshell.Hyprland 9 | 10 | RippleButton { 11 | id: root 12 | property string query 13 | 14 | implicitHeight: 30 15 | leftPadding: 6 16 | rightPadding: 10 17 | buttonRadius: Appearance.rounding.verysmall 18 | colBackground: Appearance.colors.colSurfaceContainerHighest 19 | colBackgroundHover: Appearance.colors.colSurfaceContainerHighestHover 20 | colRipple: Appearance.colors.colSurfaceContainerHighestActive 21 | 22 | PointingHandInteraction {} 23 | onClicked: { 24 | let url = Config.options.search.engineBaseUrl + root.query; 25 | for (let site of (Config?.options?.search.excludedSites ?? [])) { 26 | url += ` -site:${site}`; 27 | } 28 | Qt.openUrlExternally(url); 29 | GlobalStates.sidebarLeftOpen = false; 30 | } 31 | 32 | contentItem: Item { 33 | anchors.centerIn: parent 34 | implicitWidth: rowLayout.implicitWidth 35 | implicitHeight: rowLayout.implicitHeight 36 | RowLayout { 37 | id: rowLayout 38 | anchors.centerIn: parent 39 | spacing: 5 40 | MaterialSymbol { 41 | text: "search" 42 | iconSize: 20 43 | color: Appearance.m3colors.m3onSurface 44 | } 45 | StyledText { 46 | id: text 47 | horizontalAlignment: Text.AlignHCenter 48 | text: root.query 49 | color: Appearance.m3colors.m3onSurface 50 | } 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/share/sleex/plugins/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(src/Sleex) -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | find_package(Qt6 REQUIRED COMPONENTS Core Qml Gui Quick Concurrent Sql Network DBus Bluetooth) 2 | find_package(PkgConfig REQUIRED) 3 | 4 | set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/qml") 5 | qt_standard_project_setup(REQUIRES 6.9) 6 | 7 | function(qml_module arg_TARGET) 8 | cmake_parse_arguments(PARSE_ARGV 1 arg "" "URI" "SOURCES;LIBRARIES") 9 | 10 | qt_add_qml_module(${arg_TARGET} 11 | URI ${arg_URI} 12 | VERSION ${VERSION} 13 | SOURCES ${arg_SOURCES} 14 | ) 15 | 16 | qt_query_qml_module(${arg_TARGET} 17 | URI module_uri 18 | VERSION module_version 19 | PLUGIN_TARGET module_plugin_target 20 | TARGET_PATH module_target_path 21 | QMLDIR module_qmldir 22 | TYPEINFO module_typeinfo 23 | ) 24 | 25 | message(STATUS "Created QML module ${module_uri}, version ${module_version}") 26 | 27 | set(module_dir "${INSTALL_QMLDIR}/${module_target_path}") 28 | install(TARGETS ${arg_TARGET} LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}") 29 | install(TARGETS "${module_plugin_target}" LIBRARY DESTINATION "${module_dir}" RUNTIME DESTINATION "${module_dir}") 30 | install(FILES "${module_qmldir}" DESTINATION "${module_dir}") 31 | install(FILES "${module_typeinfo}" DESTINATION "${module_dir}") 32 | 33 | target_link_libraries(${arg_TARGET} PRIVATE Qt::Core Qt::Qml ${arg_LIBRARIES}) 34 | endfunction() 35 | 36 | add_subdirectory(services) 37 | -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | pkg_check_modules(LIBNM REQUIRED libnm) 2 | pkg_check_modules(GLIB REQUIRED glib-2.0 gobject-2.0 gio-2.0) 3 | 4 | qml_module(sleex-services 5 | URI Sleex.Services 6 | SOURCES 7 | resourceUsage.cpp resourceUsage.hpp 8 | network.cpp network.hpp 9 | bluetooth.cpp bluetooth.hpp 10 | plugin.cpp 11 | DEPENDENCIES 12 | Qt::Bluetooth 13 | ) 14 | 15 | target_include_directories(sleex-services PRIVATE 16 | ${LIBNM_INCLUDE_DIRS} 17 | ${GLIB_INCLUDE_DIRS} 18 | ) 19 | 20 | target_link_libraries(sleex-services PRIVATE 21 | ${LIBNM_LIBRARIES} 22 | ${GLIB_LIBRARIES} 23 | ) 24 | 25 | target_compile_options(sleex-services PRIVATE 26 | ${LIBNM_CFLAGS_OTHER} 27 | ${GLIB_CFLAGS_OTHER} 28 | ) 29 | 30 | target_link_libraries(sleex-services 31 | PRIVATE 32 | Qt6::Core 33 | Qt6::Qml 34 | Qt6::Bluetooth 35 | ) -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/bluetooth.cpp: -------------------------------------------------------------------------------- 1 | #include "bluetooth.hpp" 2 | 3 | BluetoothService::BluetoothService(QObject *parent) 4 | : QObject(parent) 5 | { 6 | // Check for Bluetooth adapters 7 | const auto adapters = QBluetoothLocalDevice::allDevices(); 8 | if (!adapters.isEmpty()) { 9 | m_localDevice = new QBluetoothLocalDevice(adapters.first().address(), this); 10 | m_available = true; 11 | 12 | connect(m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged, this, [this](QBluetoothLocalDevice::HostMode mode) { 13 | bool enabled = (mode != QBluetoothLocalDevice::HostPoweredOff); 14 | if (m_enabled != enabled) { 15 | m_enabled = enabled; 16 | emit bluetoothEnabledChanged(); 17 | } 18 | }); 19 | } else { 20 | // No adapters at all 21 | m_available = false; 22 | } 23 | } 24 | 25 | void BluetoothService::update() 26 | { 27 | if (!m_available || !m_localDevice) { 28 | // Reset state if no adapter 29 | if (m_enabled) { m_enabled = false; emit bluetoothEnabledChanged(); } 30 | if (m_connected) { m_connected = false; emit bluetoothConnectedChanged(); } 31 | if (!m_deviceName.isEmpty()) { m_deviceName.clear(); emit bluetoothDeviceNameChanged(); } 32 | if (!m_deviceAddress.isEmpty()) { m_deviceAddress.clear(); emit bluetoothDeviceAddressChanged(); } 33 | return; 34 | } 35 | 36 | // Update enabled state 37 | bool enabled = (m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff); 38 | if (m_enabled != enabled) { 39 | m_enabled = enabled; 40 | emit bluetoothEnabledChanged(); 41 | } 42 | 43 | // If enabled, fetch connected device info (stubbed here, needs device discovery logic) 44 | // For now, just reset connected state 45 | if (!m_connected) { 46 | m_connected = false; 47 | emit bluetoothConnectedChanged(); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/bluetooth.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class BluetoothService : public QObject { 9 | Q_OBJECT 10 | QML_SINGLETON 11 | QML_NAMED_ELEMENT(BluetoothService) 12 | 13 | Q_PROPERTY(bool bluetoothAvailable READ bluetoothAvailable NOTIFY bluetoothAvailableChanged FINAL) 14 | Q_PROPERTY(bool bluetoothEnabled READ bluetoothEnabled NOTIFY bluetoothEnabledChanged FINAL) 15 | Q_PROPERTY(bool bluetoothConnected READ bluetoothConnected NOTIFY bluetoothConnectedChanged FINAL) 16 | Q_PROPERTY(QString bluetoothDeviceName READ bluetoothDeviceName NOTIFY bluetoothDeviceNameChanged FINAL) 17 | Q_PROPERTY(QString bluetoothDeviceAddress READ bluetoothDeviceAddress NOTIFY bluetoothDeviceAddressChanged FINAL) 18 | 19 | public: 20 | explicit BluetoothService(QObject *parent = nullptr); 21 | 22 | bool bluetoothAvailable() const { return m_available; } 23 | bool bluetoothEnabled() const { return m_enabled; } 24 | bool bluetoothConnected() const { return m_connected; } 25 | QString bluetoothDeviceName() const { return m_deviceName; } 26 | QString bluetoothDeviceAddress() const { return m_deviceAddress; } 27 | 28 | Q_INVOKABLE void update(); 29 | 30 | signals: 31 | void bluetoothAvailableChanged(); 32 | void bluetoothEnabledChanged(); 33 | void bluetoothConnectedChanged(); 34 | void bluetoothDeviceNameChanged(); 35 | void bluetoothDeviceAddressChanged(); 36 | 37 | private: 38 | QBluetoothLocalDevice *m_localDevice = nullptr; 39 | bool m_available = false; 40 | bool m_enabled = false; 41 | bool m_connected = false; 42 | QString m_deviceName; 43 | QString m_deviceAddress; 44 | }; 45 | -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/brightness.cpp: -------------------------------------------------------------------------------- 1 | #include "brightness.hpp" 2 | #include 3 | #include 4 | #include 5 | 6 | namespace sleex::services { 7 | 8 | Brightness::Brightness(QObject *parent): QObject(parent), m_value(50) { 9 | // Initialize with current brightness 10 | updateCurrentBrightness(); 11 | } 12 | 13 | int Brightness::value() const { 14 | return m_value; 15 | } 16 | 17 | void Brightness::setValue(int val) { 18 | // Clamp value between 1 and 100 19 | val = qBound(1, val, 100); 20 | 21 | if (m_value == val) 22 | return; 23 | 24 | // Try to set brightness using brightnessctl 25 | QProcess process; 26 | process.start("brightnessctl", QStringList() << "s" << QString("%1%").arg(val) << "--quiet"); 27 | 28 | if (process.waitForFinished(1000)) { 29 | if (process.exitCode() == 0) { 30 | m_value = val; 31 | emit valueChanged(); 32 | return; 33 | } 34 | } 35 | 36 | qWarning() << "Failed to set brightness. Install 'brightnessctl'"; 37 | } 38 | 39 | void Brightness::updateCurrentBrightness() { 40 | QProcess process; 41 | process.start("sh", QStringList() << "-c" << "echo \"$(brightnessctl g) $(brightnessctl m)\""); 42 | 43 | if (process.waitForFinished(1000) && process.exitCode() == 0) { 44 | QString output = QString::fromUtf8(process.readAllStandardOutput()).trimmed(); 45 | QStringList parts = output.split(' '); 46 | 47 | if (parts.size() >= 2) { 48 | bool okCurrent, okMax; 49 | int current = parts[0].toInt(&okCurrent); 50 | int max = parts[1].toInt(&okMax); 51 | 52 | if (okCurrent && okMax && max > 0) { 53 | m_value = qRound((current * 100.0) / max); 54 | emit valueChanged(); 55 | return; 56 | } 57 | } 58 | } 59 | 60 | qWarning() << "Could not read current brightness. Install 'brightnessctl'"; 61 | } 62 | 63 | } // namespace sleex::services -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/brightness.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace sleex::services { 6 | 7 | class Brightness : public QObject { 8 | Q_OBJECT 9 | QML_ELEMENT 10 | QML_SINGLETON 11 | Q_PROPERTY(int value READ value NOTIFY valueChanged) 12 | 13 | public: 14 | explicit Brightness(QObject *parent = nullptr); 15 | 16 | int value() const; 17 | Q_INVOKABLE void setValue(int v); 18 | 19 | signals: 20 | void valueChanged(); 21 | 22 | private: 23 | void updateCurrentBrightness(); 24 | int m_value; 25 | }; 26 | 27 | } // namespace sleex::services -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/displays.hpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/plugins/src/Sleex/services/displays.hpp -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/meta_types/qt6sleex-services_metatypes.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/plugins/src/Sleex/services/meta_types/qt6sleex-services_metatypes.json -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/monitor.cpp: -------------------------------------------------------------------------------- 1 | #include "service.hpp" 2 | #include 3 | 4 | namespace sleex::services { 5 | 6 | Service::Service(QObject* parent) 7 | : QObject(parent) {} 8 | 9 | void Service::ref(QObject* sender) { 10 | if (!sender) { 11 | qWarning() << "Service::ref() called with null sender"; 12 | return; 13 | } 14 | 15 | if (m_refs.contains(sender)) { 16 | qWarning() << "Service::ref() called multiple times for same sender"; 17 | return; 18 | } 19 | 20 | if (m_refs.isEmpty()) { 21 | start(); 22 | } 23 | 24 | // Connect to destroyed signal to auto-cleanup 25 | connect(sender, &QObject::destroyed, this, &Service::onRefDestroyed); 26 | m_refs.insert(sender); 27 | } 28 | 29 | void Service::unref(QObject* sender) { 30 | if (!sender) { 31 | qWarning() << "Service::unref() called with null sender"; 32 | return; 33 | } 34 | 35 | if (!m_refs.contains(sender)) { 36 | qWarning() << "Service::unref() called for non-referenced sender"; 37 | return; 38 | } 39 | 40 | // Disconnect to avoid double-unreferencing 41 | disconnect(sender, &QObject::destroyed, this, &Service::onRefDestroyed); 42 | 43 | m_refs.remove(sender); 44 | 45 | if (m_refs.isEmpty()) { 46 | stop(); 47 | } 48 | } 49 | 50 | void Service::onRefDestroyed() { 51 | QObject* sender = QObject::sender(); 52 | if (!sender) return; 53 | 54 | // Don't call unref() here to avoid recursion/disconnect issues 55 | // Just remove from set and check if empty 56 | if (m_refs.remove(sender) && m_refs.isEmpty()) { 57 | stop(); 58 | } 59 | } 60 | 61 | } // namespace sleex::services -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/monitor.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "service.hpp" 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace sleex::services { 9 | 10 | struct Monitor { 11 | Q_GADGET 12 | Q_PROPERTY(int id MEMBER id) 13 | Q_PROPERTY(QString name MEMBER name) 14 | Q_PROPERTY(bool connected MEMBER connected) 15 | 16 | public: 17 | int id; 18 | QString name; 19 | bool connected; 20 | }; 21 | 22 | class MonitorService : public Service { 23 | Q_OBJECT 24 | QML_ELEMENT 25 | 26 | Q_PROPERTY(QList monitors READ monitors NOTIFY monitorsChanged) 27 | 28 | public: 29 | explicit MonitorService(QObject* parent = nullptr); 30 | 31 | QList monitors() const; 32 | Q_INVOKABLE void refresh(); 33 | 34 | signals: 35 | void monitorsChanged(); 36 | void error(const QString& message); 37 | 38 | private: 39 | QList m_monitors; 40 | void scanMonitors(); 41 | }; 42 | 43 | } -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/plugin.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class SleexServicesPlugin : public QQmlExtensionPlugin { 4 | Q_OBJECT 5 | Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) 6 | 7 | public: 8 | void registerTypes(const char *uri) override { 9 | // QML_ELEMENT and QML_SINGLETON macros handle registration automatically 10 | Q_UNUSED(uri) 11 | } 12 | }; 13 | 14 | #include "plugin.moc" -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/qmltypes/sleex-services_foreign_types.txt: -------------------------------------------------------------------------------- 1 | --foreign-types=/usr/lib/qt6/metatypes/qt6qml_relwithdebinfo_metatypes.json,/usr/lib/qt6/metatypes/qt6core_relwithdebinfo_metatypes.json,/usr/lib/qt6/metatypes/qt6network_relwithdebinfo_metatypes.json -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/sleex-servicesplugin_Sleex_ServicesPlugin.cpp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by CMake. Do not edit. 2 | 3 | #include 4 | #include 5 | 6 | 7 | 8 | 9 | QT_DECLARE_EXTERN_SYMBOL_VOID(qml_register_types_Sleex_Services) 10 | 11 | class Sleex_ServicesPlugin : public QQmlEngineExtensionPlugin 12 | { 13 | Q_OBJECT 14 | Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid) 15 | 16 | public: 17 | Sleex_ServicesPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) 18 | { 19 | 20 | QT_KEEP_SYMBOL(qml_register_types_Sleex_Services) 21 | } 22 | }; 23 | 24 | 25 | 26 | #include "sleex-servicesplugin_Sleex_ServicesPlugin.moc" 27 | -------------------------------------------------------------------------------- /src/share/sleex/plugins/src/Sleex/services/sleex-servicesplugin_Sleex_ServicesPlugin_in.cpp: -------------------------------------------------------------------------------- 1 | // This file is autogenerated by CMake. Do not edit. 2 | 3 | #include 4 | #include 5 | 6 | 7 | 8 | 9 | $<$:QT_DECLARE_EXTERN_SYMBOL_VOID($)> 11 | 12 | class Sleex_ServicesPlugin : public QQmlEngineExtensionPlugin 13 | { 14 | Q_OBJECT 15 | Q_PLUGIN_METADATA(IID QQmlEngineExtensionInterface_iid) 16 | 17 | public: 18 | Sleex_ServicesPlugin(QObject *parent = nullptr) : QQmlEngineExtensionPlugin(parent) 19 | { 20 | 21 | $<$:QT_KEEP_SYMBOL($)> 23 | } 24 | }; 25 | 26 | 27 | 28 | #include "sleex-servicesplugin_Sleex_ServicesPlugin.moc" 29 | -------------------------------------------------------------------------------- /src/share/sleex/qml/Sleex/Services/qmldir: -------------------------------------------------------------------------------- 1 | module Sleex.Services 2 | linktarget sleex-servicesplugin 3 | optional plugin sleex-servicesplugin 4 | classname Sleex_ServicesPlugin 5 | typeinfo sleex-services.qmltypes 6 | prefer :/qt/qml/Sleex/Services/ 7 | 8 | -------------------------------------------------------------------------------- /src/share/sleex/qml/Sleex/Services/sleex-services_qml_module_dir_map.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | /usr/share/sleex/qml/Sleex/Services 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/ai/show-installed-ollama-models.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Get the list, skip the header, and extract the first column (model names) 4 | model_names=$(ollama list | tail -n +2 | awk '{print $1}') 5 | 6 | # Build a JSON array 7 | json_array="[" 8 | for name in $model_names; do 9 | json_array+="\"$name\"," 10 | done 11 | 12 | # Remove trailing comma and close the array 13 | json_array="${json_array%,}]" 14 | 15 | # Output the JSON array 16 | echo "$json_array" -------------------------------------------------------------------------------- /src/share/sleex/scripts/cava/raw_output_config.txt: -------------------------------------------------------------------------------- 1 | [general] 2 | mode = waves 3 | framerate = 60 4 | autosens = 1 5 | bars = 50 6 | 7 | [output] 8 | method = raw 9 | raw_target = /dev/stdout 10 | data_format = ascii 11 | channels = mono 12 | mono_option = average 13 | 14 | [smoothing] 15 | noise_reduction = 20 16 | 17 | 18 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/colors/scheme_for_image.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | import sys 3 | import cv2 4 | import numpy as np 5 | 6 | # Allowed scheme types 7 | SCHEMES = [ 8 | "scheme-content", 9 | "scheme-expressive", 10 | "scheme-fidelity", 11 | "scheme-fruit-salad", 12 | "scheme-monochrome", 13 | "scheme-neutral", 14 | "scheme-rainbow", 15 | "scheme-tonal-spot" 16 | ] 17 | 18 | def image_colorfulness(image): 19 | # Based on Hasler and Süsstrunk's colorfulness metric 20 | (B, G, R) = cv2.split(image.astype("float")) 21 | rg = np.absolute(R - G) 22 | yb = np.absolute(0.5 * (R + G) - B) 23 | std_rg = np.std(rg) 24 | std_yb = np.std(yb) 25 | mean_rg = np.mean(rg) 26 | mean_yb = np.mean(yb) 27 | colorfulness = np.sqrt(std_rg ** 2 + std_yb ** 2) + (0.3 * np.sqrt(mean_rg ** 2 + mean_yb ** 2)) 28 | return colorfulness 29 | 30 | # scheme-content respects the image's colors very well, but it might 31 | # look too saturated, so we only use it for not very colorful images to be safe 32 | def pick_scheme(colorfulness): 33 | if colorfulness < 10: 34 | # return "scheme-monochrome" 35 | return "scheme-content" 36 | elif colorfulness < 20: 37 | return "scheme-content" 38 | elif colorfulness < 50: 39 | return "scheme-neutral" 40 | else: 41 | return "scheme-tonal-spot" 42 | 43 | def main(): 44 | colorfulness_mode = False 45 | args = sys.argv[1:] 46 | if '--colorfulness' in args: 47 | colorfulness_mode = True 48 | args.remove('--colorfulness') 49 | if len(args) < 1: 50 | print("scheme-tonal-spot") 51 | sys.exit(1) 52 | img_path = args[0] 53 | img = cv2.imread(img_path) 54 | if img is None: 55 | print("scheme-tonal-spot") 56 | sys.exit(1) 57 | colorfulness = image_colorfulness(img) 58 | if colorfulness_mode: 59 | print(f"{colorfulness}") 60 | else: 61 | scheme = pick_scheme(colorfulness) 62 | print(scheme) 63 | 64 | if __name__ == "__main__": 65 | main() -------------------------------------------------------------------------------- /src/share/sleex/scripts/firstRun.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # This script is run the first time the user logs in after installing Sleex. 4 | # It sets up the user's environment to use Sleex. 5 | 6 | CONFIG_FILE="$HOME/.config/hypr/custom/general.conf" 7 | KEYBINDS_DIR="$HOME/.config/hypr/hyprland" 8 | VC_KEYMAP=$(grep -i KEYMAP /etc/vconsole.conf | cut -d= -f2 | tr -d '"') 9 | LAYOUT=$(echo "$VC_KEYMAP" | awk '{print tolower($0)}') 10 | 11 | echo "Setting keyboard layout to '$LAYOUT' in $CONFIG_FILE." 12 | 13 | if grep -q "^input:kb_layout" "$CONFIG_FILE"; then 14 | sed -i "s/^input:kb_layout.*/input:kb_layout = $LAYOUT/" "$CONFIG_FILE" 15 | else 16 | echo "input:kb_layout = $LAYOUT" >> "$CONFIG_FILE" 17 | fi 18 | 19 | echo "Applying keybinds configuration in $KEYBINDS_DIR." 20 | 21 | if [[ "$LAYOUT" == "us" ]]; then 22 | mv -f "$KEYBINDS_DIR/keybinds_us.conf" "$KEYBINDS_DIR/keybinds.conf" 23 | echo "Switched to US keybinds." 24 | elif [[ "$LAYOUT" == "fr" ]]; then 25 | mv -f "$KEYBINDS_DIR/keybinds_fr.conf" "$KEYBINDS_DIR/keybinds.conf" 26 | echo "Switched to FR keybinds." 27 | else 28 | echo "Unknown layout: $LAYOUT – applying US keybinds." 29 | mv -f "$KEYBINDS_DIR/keybinds_us.conf" "$KEYBINDS_DIR/keybinds.conf" 30 | fi 31 | 32 | if lsmod | grep -q '^nvidia'; then 33 | echo "Nvidia GPU found" 34 | { 35 | echo "env = LIBVA_DRIVER_NAME,nvidia" 36 | echo "env = __GLX_VENDOR_LIBRARY_NAME,nvidia" 37 | } >> ~/.config/hypr/custom/env.conf 38 | fi 39 | 40 | hyprctl reload 41 | 42 | echo 'Complete!' -------------------------------------------------------------------------------- /src/share/sleex/scripts/hyprland/workspace_action.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | hyprctl dispatch "$1" $(((($(hyprctl activeworkspace -j | jq -r .id) - 1) / 10) * 10 + $2)) -------------------------------------------------------------------------------- /src/share/sleex/scripts/kvantum/materialQT.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-$HOME/.config}" 4 | XDG_CACHE_HOME="${XDG_CACHE_HOME:-$HOME/.cache}" 5 | XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}" 6 | CONFIG_DIR="/usr/share/sleex" 7 | CACHE_DIR="$XDG_CACHE_HOME/sleex" 8 | STATE_DIR="$XDG_STATE_HOME/sleex" 9 | 10 | get_light_dark() { 11 | current_mode=$(gsettings get org.gnome.desktop.interface color-scheme 2>/dev/null | tr -d "'") 12 | if [[ "$current_mode" == "prefer-dark" ]]; then 13 | echo "dark" 14 | else 15 | echo "light" 16 | fi 17 | } 18 | 19 | apply_qt() { 20 | # Check if the theme exists 21 | FOLDER_PATH="$XDG_CONFIG_HOME/Kvantum/Colloid/" 22 | 23 | if [ ! -d "$FOLDER_PATH" ]; then 24 | # Send a notification 25 | notify-send "Colloid-kde theme required" " The folder '$FOLDER_PATH' does not exist." 26 | exit 1 # Exit the function if the folder does not exist 27 | fi 28 | 29 | lightdark=$(get_light_dark) 30 | if [ "$lightdark" = "light" ]; then 31 | # apply ligght colors 32 | cp "$XDG_CONFIG_HOME/Kvantum/Colloid/Colloid.kvconfig" "$XDG_CONFIG_HOME/Kvantum/MaterialAdw/MaterialAdw.kvconfig" 33 | python "$CONFIG_DIR/scripts/kvantum/adwsvg.py" 34 | 35 | else 36 | #apply dark colors 37 | cp "$XDG_CONFIG_HOME/Kvantum/Colloid/ColloidDark.kvconfig" "$XDG_CONFIG_HOME/Kvantum/MaterialAdw/MaterialAdw.kvconfig" 38 | python "$CONFIG_DIR/scripts/kvantum/adwsvgDark.py" 39 | fi 40 | } 41 | 42 | apply_qt 43 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/record-script.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | getdate() { 4 | date '+%Y-%m-%d_%H.%M.%S' 5 | } 6 | getaudiooutput() { 7 | pactl list sources | grep 'Name' | grep 'monitor' | cut -d ' ' -f2 8 | } 9 | getactivemonitor() { 10 | hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name' 11 | } 12 | 13 | xdgvideo="$(xdg-user-dir VIDEOS)" 14 | if [[ $xdgvideo = "$HOME" ]]; then 15 | unset xdgvideo 16 | fi 17 | mkdir -p "${xdgvideo:-$HOME/Videos}" 18 | cd "${xdgvideo:-$HOME/Videos}" || exit 19 | 20 | if pgrep wf-recorder > /dev/null; then 21 | notify-send "Recording Stopped" "Stopped" -a 'Recorder' & 22 | pkill wf-recorder & 23 | else 24 | if [[ "$1" == "--fullscreen-sound" ]]; then 25 | notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' 26 | wf-recorder -o $(getactivemonitor) --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --audio="$(getaudiooutput)" & disown 27 | elif [[ "$1" == "--fullscreen" ]]; then 28 | notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' 29 | wf-recorder -o $(getactivemonitor) --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t & disown 30 | else 31 | if ! region="$(slurp 2>&1)"; then 32 | notify-send "Recording cancelled" "Selection was cancelled" -a 'Recorder' 33 | exit 1 34 | fi 35 | notify-send "Starting recording" 'recording_'"$(getdate)"'.mp4' -a 'Recorder' 36 | if [[ "$1" == "--sound" ]]; then 37 | wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" --audio="$(getaudiooutput)" & disown 38 | else 39 | wf-recorder --pixel-format yuv420p -f './recording_'"$(getdate)"'.mp4' -t --geometry "$region" & disown 40 | fi 41 | fi 42 | fi -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/gtk/gtk-colors.css: -------------------------------------------------------------------------------- 1 | /* 2 | * GTK Colors 3 | */ 4 | 5 | @define-color accent_color {{ $primary }}; 6 | @define-color accent_fg_color {{ $onPrimary }}; 7 | @define-color accent_bg_color {{ $primary }}; 8 | @define-color window_bg_color {{ $background }}; 9 | @define-color window_fg_color {{ $onBackground }}; 10 | @define-color headerbar_bg_color {{ $surfaceDim }}; 11 | @define-color headerbar_fg_color {{ $onSurface }}; 12 | @define-color popover_bg_color {{ $surfaceDim }}; 13 | @define-color popover_fg_color {{ $onSurface }}; 14 | @define-color view_bg_color {{ $surface }}; 15 | @define-color view_fg_color {{ $onSurface }}; 16 | @define-color card_bg_color {{ $surface }}; 17 | @define-color card_fg_color {{ $onSurface }}; 18 | @define-color sidebar_bg_color @window_bg_color; 19 | @define-color sidebar_fg_color @window_fg_color; 20 | @define-color sidebar_border_color @window_bg_color; 21 | @define-color sidebar_backdrop_color @window_bg_color; -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/term_emus/alacritty.tpl: -------------------------------------------------------------------------------- 1 | [colors.primary] 2 | background = "{background}" 3 | foreground = "{onBackground}" 4 | 5 | [colors.cursor] 6 | text = "{background}" 7 | cursor = "{onBackground}" 8 | 9 | [colors.vi_mode_cursor] 10 | text = "{background}" 11 | cursor = "{onBackground}" 12 | 13 | [colors.search.matches] 14 | foreground = "{term0}" 15 | background = "{term15}" 16 | 17 | [colors.search.focused_match] 18 | foreground = "CellBackground" 19 | background = "CellForeground" 20 | 21 | [colors.line_indicator] 22 | foreground = "None" 23 | background = "None" 24 | 25 | [colors.footer_bar] 26 | foreground = "{term8}" 27 | background = "{term7}" 28 | 29 | [colors.selection] 30 | text = "CellBackground" 31 | background = "CellForeground" 32 | 33 | [colors.normal] 34 | black = "{term0}" 35 | red = "{term1}" 36 | green = "{term2}" 37 | yellow = "{term3}" 38 | blue = "{term4}" 39 | magenta = "{term5}" 40 | cyan = "{term6}" 41 | white = "{term7}" 42 | 43 | [colors.bright] 44 | black = "{term8}" 45 | red = "{term9}" 46 | green = "{term10}" 47 | yellow = "{term11}" 48 | blue = "{term12}" 49 | magenta = "{term13}" 50 | cyan = "{term14}" 51 | white = "{term15}" 52 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/term_emus/foot.tpl: -------------------------------------------------------------------------------- 1 | [colors] 2 | background={background} 3 | foreground={onBackground} 4 | regular0={term0} 5 | regular1={term1} 6 | regular2={term2} 7 | regular3={term3} 8 | regular4={term4} 9 | regular5={term5} 10 | regular6={term6} 11 | regular7={term7} 12 | bright0={term8} 13 | bright1={term9} 14 | bright2={term10} 15 | bright3={term11} 16 | bright4={term12} 17 | bright5={term13} 18 | bright6={term14} 19 | bright7={term15} 20 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/term_emus/ghostty.tpl: -------------------------------------------------------------------------------- 1 | # pywal theme for ghostty 2 | 3 | background = {background} 4 | foreground = {onBackground} 5 | cursor-color = {onBackground} 6 | selection-background = {onBackground} 7 | selection-foreground = {background} 8 | 9 | palette = 0={term0} 10 | palette = 1={term1} 11 | palette = 2={term2} 12 | palette = 3={term3} 13 | palette = 4={term4} 14 | palette = 5={term5} 15 | palette = 6={term6} 16 | palette = 7={term7} 17 | palette = 8={term8} 18 | palette = 9={term9} 19 | palette = 10={term10} 20 | palette = 11={term11} 21 | palette = 12={term12} 22 | palette = 13={term13} 23 | palette = 14={term14} 24 | palette = 15={term15} 25 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/term_emus/kitty.tpl: -------------------------------------------------------------------------------- 1 | foreground {onBackground} 2 | background {background} 3 | cursor {onBackground} 4 | 5 | active_tab_foreground {background} 6 | active_tab_background {onBackground} 7 | inactive_tab_foreground {onBackground} 8 | inactive_tab_background {background} 9 | background_opacity 0.7 10 | 11 | active_border_color {onBackground} 12 | inactive_border_color {background} 13 | bell_border_color {term1} 14 | 15 | color0 {term0} 16 | color8 {term8} 17 | color1 {term1} 18 | color9 {term9} 19 | color2 {term2} 20 | color10 {term10} 21 | color3 {term3} 22 | color11 {term11} 23 | color4 {term4} 24 | color12 {term12} 25 | color5 {term5} 26 | color13 {term13} 27 | color6 {term6} 28 | color14 {term14} 29 | color7 {term7} 30 | color15 {term15} 31 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/term_emus/wezterm.tpl: -------------------------------------------------------------------------------- 1 | [colors] 2 | foreground = "{onBackground}" 3 | background = "{background}" 4 | cursor_bg = "{background}" 5 | cursor_border = "{term0}" 6 | cursor_fg = "{onBackground}" 7 | 8 | ansi = ["{term0}", "{term1}", "{term2}", "{term3}", 9 | "{term4}", "{term5}", "{term6}", "{term7}"] 10 | 11 | brights = ["{term8}", "{term9}", "{term10}", "{term11}", 12 | "{term12}", "{term13}", "{term14}", "{term15}"] 13 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/term_emus/zellij.tpl: -------------------------------------------------------------------------------- 1 | themes { 2 | py-matyou-wal-zellij { 3 | fg "{onBackground}" 4 | bg "{background}" 5 | black "{term0}" 6 | red "{term1}" 7 | green "{term2}" 8 | yellow "{term3}" 9 | blue "{term4}" 10 | magenta "{term5}" 11 | cyan "{term6}" 12 | white "{term7}" 13 | orange "{term9}" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/terminal/scheme-base.json: -------------------------------------------------------------------------------- 1 | { 2 | "dark": { 3 | "term0" : "#282828", 4 | "term1" : "#CC241D", 5 | "term2" : "#98971A", 6 | "term3" : "#D79921", 7 | "term4" : "#458588", 8 | "term5" : "#B16286", 9 | "term6" : "#689D6A", 10 | "term7" : "#A89984", 11 | "term8" : "#928374", 12 | "term9" : "#FB4934", 13 | "term10" : "#B8BB26", 14 | "term11" : "#FABD2F", 15 | "term12" : "#83A598", 16 | "term13" : "#D3869B", 17 | "term14" : "#8EC07C", 18 | "term15" : "#EBDBB2" 19 | }, 20 | "light": { 21 | "term0" : "#FDF9F3", 22 | "term1" : "#FF6188", 23 | "term2" : "#A9DC76", 24 | "term3" : "#FC9867", 25 | "term4" : "#FFD866", 26 | "term5" : "#F47FD4", 27 | "term6" : "#78DCE8", 28 | "term7" : "#333034", 29 | "term8" : "#121212", 30 | "term9" : "#FF6188", 31 | "term10" : "#A9DC76", 32 | "term11" : "#FC9867", 33 | "term12" : "#FFD866", 34 | "term13" : "#F47FD4", 35 | "term14" : "#78DCE8", 36 | "term15" : "#333034" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/terminal/scheme-monochrome.json: -------------------------------------------------------------------------------- 1 | { 2 | "dark": { 3 | "term0": "#000000", 4 | "term1": "#FFFFFF", 5 | "term2": "#CCCCCC", 6 | "term3": "#8f8f8f", 7 | "term4": "#FFFFFF", 8 | "term5": "#111111", 9 | "term6": "#CCCCCC", 10 | "term7": "#FFFFFF", 11 | "term8": "#404040", 12 | "term9": "#CCCCCC", 13 | "term10": "#FFFFFF", 14 | "term11": "#909090", 15 | "term12": "#CCCCCC", 16 | "term13": "#808080", 17 | "term14": "#CCCCCC", 18 | "term15": "#FFFFFF" 19 | }, 20 | "light": { 21 | "term0": "#EAE9EA", 22 | "term1": "#777777", 23 | "term2": "#000000", 24 | "term3": "#000000", 25 | "term4": "#000000", 26 | "term5": "#000000", 27 | "term6": "#000000", 28 | "term7": "#202020", 29 | "term8": "#000000", 30 | "term9": "#000000", 31 | "term10": "#CCCCCC", 32 | "term11": "#808080", 33 | "term12": "#CCCCCC", 34 | "term13": "#FFFFFF" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/templates/terminal/sequences.txt: -------------------------------------------------------------------------------- 1 | ]4;0;#$term0 #\]4;1;#$term1 #\]4;2;#$term2 #\]4;3;#$term3 #\]4;4;#$term4 #\]4;5;#$term5 #\]4;6;#$term6 #\]4;7;#$term7 #\]4;8;#$term8 #\]4;9;#$term9 #\]4;10;#$term10 #\]4;11;#$term11 #\]4;12;#$term12 #\]4;13;#$term13 #\]4;14;#$term14 #\]4;15;#$term15 #\]10;#$term7 #\]11;[$alpha]#$term0 #\]12;#$term7 #\]13;#$term7 #\]17;#$term7 #\]19;#$term0 #\]4;232;#$term7 #\]4;256;#$term7 #\]708;[$alpha]#$term0 #\ 2 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/terminal/scheme-base.json: -------------------------------------------------------------------------------- 1 | { 2 | "dark": { 3 | "term0" : "#282828", 4 | "term1" : "#CC241D", 5 | "term2" : "#98971A", 6 | "term3" : "#D79921", 7 | "term4" : "#458588", 8 | "term5" : "#B16286", 9 | "term6" : "#689D6A", 10 | "term7" : "#A89984", 11 | "term8" : "#928374", 12 | "term9" : "#FB4934", 13 | "term10" : "#B8BB26", 14 | "term11" : "#FABD2F", 15 | "term12" : "#83A598", 16 | "term13" : "#D3869B", 17 | "term14" : "#8EC07C", 18 | "term15" : "#EBDBB2" 19 | }, 20 | "light": { 21 | "term0" : "#FDF9F3", 22 | "term1" : "#FF6188", 23 | "term2" : "#A9DC76", 24 | "term3" : "#FC9867", 25 | "term4" : "#FFD866", 26 | "term5" : "#F47FD4", 27 | "term6" : "#78DCE8", 28 | "term7" : "#333034", 29 | "term8" : "#121212", 30 | "term9" : "#FF6188", 31 | "term10" : "#A9DC76", 32 | "term11" : "#FC9867", 33 | "term12" : "#FFD866", 34 | "term13" : "#F47FD4", 35 | "term14" : "#78DCE8", 36 | "term15" : "#333034" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/share/sleex/scripts/terminal/sequences.txt: -------------------------------------------------------------------------------- 1 | ]4;0;#$term0 #\]1;0;#$term0 #\]4;1;#$term1 #\]4;2;#$term2 #\]4;3;#$term3 #\]4;4;#$term4 #\]4;5;#$term5 #\]4;6;#$term6 #\]4;7;#$term7 #\]4;8;#$term8 #\]4;9;#$term9 #\]4;10;#$term10 #\]4;11;#$term11 #\]4;12;#$term12 #\]4;13;#$term13 #\]4;14;#$term14 #\]4;15;#$term15 #\]10;#$term7 #\]11;[100]#$term0 #\]12;#$term7 #\]13;#$term7 #\]17;#$term7 #\]19;#$term0 #\]4;232;#$term7 #\]4;256;#$term7 #\]708;[100]#$term0 #\]11;#$term0 #\ -------------------------------------------------------------------------------- /src/share/sleex/services/AiMessageData.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick; 3 | 4 | /** 5 | * Represents a message in an AI conversation. (Kind of) follows the OpenAI API message structure. 6 | */ 7 | QtObject { 8 | property string role 9 | property string content 10 | property string model 11 | property bool thinking: true 12 | property bool done: false 13 | property var annotations: [] 14 | property var annotationSources: [] 15 | property string functionName 16 | property string functionCall 17 | property string functionResponse 18 | property bool visibleToUser: true 19 | } 20 | -------------------------------------------------------------------------------- /src/share/sleex/services/Emojis.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | pragma ComponentBehavior: Bound 3 | 4 | import qs.modules.common.functions 5 | import qs.modules.common 6 | import QtQuick 7 | import Quickshell 8 | import Quickshell.Io 9 | 10 | /** 11 | * Emojis. 12 | */ 13 | Singleton { 14 | id: root 15 | property string emojiScriptPath: `/bin/fuzzel-emoji` 16 | property string lineBeforeData: "### DATA ###" 17 | property list list 18 | readonly property var preparedEntries: list.map(a => ({ 19 | name: Fuzzy.prepare(`${a}`), 20 | entry: a 21 | })) 22 | function fuzzyQuery(search: string): var { 23 | if (root.sloppySearch) { 24 | const results = entries.slice(0, 100).map(str => ({ 25 | entry: str, 26 | score: Levendist.computeTextMatchScore(str.toLowerCase(), search.toLowerCase()) 27 | })).filter(item => item.score > root.scoreThreshold) 28 | .sort((a, b) => b.score - a.score) 29 | return results 30 | .map(item => item.entry) 31 | } 32 | 33 | return Fuzzy.go(search, preparedEntries, { 34 | all: true, 35 | key: "name" 36 | }).map(r => { 37 | return r.obj.entry 38 | }); 39 | } 40 | 41 | function load() { 42 | emojiFileView.reload() 43 | } 44 | 45 | function updateEmojis(fileContent) { 46 | const lines = fileContent.split("\n") 47 | const dataIndex = lines.indexOf(root.lineBeforeData) 48 | if (dataIndex === -1) { 49 | console.warn("No data section found in emoji script file.") 50 | return 51 | } 52 | const emojis = lines.slice(dataIndex + 1).filter(line => line.trim() !== "") 53 | root.list = emojis.map(line => line.trim()) 54 | } 55 | 56 | FileView { 57 | id: emojiFileView 58 | path: Qt.resolvedUrl(root.emojiScriptPath) 59 | onLoadedChanged: { 60 | const fileContent = emojiFileView.text() 61 | root.updateEmojis(fileContent) 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/share/sleex/services/FirstRunExperience.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | 3 | import qs.modules.common.functions 4 | import qs.modules.common 5 | import Quickshell 6 | import Quickshell.Io 7 | import Quickshell.Hyprland 8 | 9 | Singleton { 10 | id: root 11 | property string firstRunFilePath: `${Directories.state}/sleex/user/first_run.txt` 12 | property string firstRunScriptPath: `/usr/share/sleex/scripts/firstRun.sh` 13 | property string firstRunFileContent: "This file is just here to confirm you've been greeted :>" 14 | property string defaultWallpaperPath: FileUtils.trimFileProtocol(`/usr/share/sleex/wallpapers/SleexOne.png`) 15 | property string welcomeNotifTitle: "Welcome to Sleex!" 16 | property string welcomeNotifBody: "First run? 👀 For a list of keybinds, hit Super + F1" 17 | 18 | function load() { 19 | firstRunFileView.reload() 20 | } 21 | 22 | function enableNextTime() { 23 | Quickshell.execDetached(["bash", "-c", `rm -f ${root.firstRunFilePath}`]) 24 | } 25 | function disableNextTime() { 26 | Quickshell.execDetached(["bash", "-c", `echo ${root.firstRunFileContent} > ${root.firstRunFilePath}`]) 27 | } 28 | 29 | function handleFirstRun() { 30 | Quickshell.execDetached(["bash", "-c", `${Directories.wallpaperSwitchScriptPath} ${root.defaultWallpaperPath} --mode dark`]) 31 | Quickshell.execDetached(["sh", `${root.firstRunScriptPath}`]) 32 | Quickshell.execDetached(['bash', '-c', `sleep 0.5; notify-send '${root.welcomeNotifTitle}' '${root.welcomeNotifBody}' -a 'Sleex' &`]) 33 | //Quickshell.reload(true) 34 | } 35 | 36 | 37 | FileView { 38 | id: firstRunFileView 39 | path: Qt.resolvedUrl(firstRunFilePath) 40 | onLoadFailed: (error) => { 41 | if (error == FileViewError.FileNotFound) { 42 | root.handleFirstRun() 43 | firstRunFileView.setText(root.firstRunFileContent) 44 | } 45 | } 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/share/sleex/services/Github.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.services 3 | import QtQuick 4 | import Quickshell 5 | import Quickshell.Io 6 | pragma Singleton 7 | pragma ComponentBehavior: Bound 8 | 9 | Singleton { 10 | id: root 11 | property int contribution_number 12 | property string author: Config.options.dashboard.ghUsername 13 | property var contributions: [] 14 | 15 | Timer { 16 | interval: 600000 // 10 minutes 17 | running: true 18 | repeat: true 19 | onTriggered: getContributions.running = true 20 | } 21 | 22 | Process { 23 | id: getContributions 24 | running: true 25 | command: ["curl", `https://github-contributions-api.jogruber.de/v4/${root.author}`] 26 | stdout: StdioCollector { 27 | onStreamFinished: { 28 | const json = JSON.parse(text) 29 | const year = DateTime.year 30 | // Calculate total contributions in the last 365 days 31 | const oneYearAgo = new Date(); 32 | oneYearAgo.setDate(oneYearAgo.getDate() - 365); 33 | root.contribution_number = json.contributions 34 | .filter(c => new Date(c.date) >= oneYearAgo) 35 | .reduce((sum, c) => sum + c.count, 0); 36 | 37 | const allContribs = json.contributions; 38 | const today = new Date(); 39 | const cutoff = new Date(today); 40 | cutoff.setDate(cutoff.getDate() - 280); 41 | 42 | const recentContribs = allContribs 43 | .filter(c => new Date(c.date) >= cutoff) 44 | .sort((a, b) => new Date(a.date) - new Date(b.date)); 45 | 46 | root.contributions = recentContribs; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/share/sleex/services/MaterialThemeLoader.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | pragma ComponentBehavior: Bound 3 | 4 | import qs.modules.common 5 | import QtQuick 6 | import Quickshell 7 | import Quickshell.Io 8 | 9 | /** 10 | * Automatically reloads generated material colors. 11 | * It is necessary to run reapplyTheme() on startup because Singletons are lazily loaded. 12 | */ 13 | Singleton { 14 | id: root 15 | property string filePath: Directories.generatedMaterialThemePath 16 | 17 | function reapplyTheme() { 18 | themeFileView.reload() 19 | } 20 | 21 | function applyColors(fileContent) { 22 | const json = JSON.parse(fileContent) 23 | for (const key in json) { 24 | if (json.hasOwnProperty(key)) { 25 | // Convert snake_case to CamelCase 26 | const camelCaseKey = key.replace(/_([a-z])/g, (g) => g[1].toUpperCase()) 27 | const m3Key = `m3${camelCaseKey}` 28 | Appearance.m3colors[m3Key] = json[key] 29 | } 30 | } 31 | 32 | Appearance.m3colors.darkmode = (Appearance.m3colors.m3background.hslLightness < 0.5) 33 | } 34 | 35 | Timer { 36 | id: delayedFileRead 37 | interval: Config.options?.hacks?.arbitraryRaceConditionDelay ?? 100 38 | repeat: false 39 | running: false 40 | onTriggered: { 41 | root.applyColors(themeFileView.text()) 42 | } 43 | } 44 | 45 | FileView { 46 | id: themeFileView 47 | path: Qt.resolvedUrl(root.filePath) 48 | watchChanges: true 49 | onFileChanged: { 50 | this.reload() 51 | delayedFileRead.start() 52 | } 53 | onLoadedChanged: { 54 | const fileContent = themeFileView.text() 55 | root.applyColors(fileContent) 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/share/sleex/services/Quotes.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import qs.services 3 | import QtQuick 4 | import Quickshell 5 | import Quickshell.Io 6 | pragma Singleton 7 | pragma ComponentBehavior: Bound 8 | 9 | Singleton { 10 | id: root 11 | property string quote 12 | property string author 13 | 14 | Process { 15 | id: getQuote 16 | running: true 17 | command: ["curl", "https://quotes-api-self.vercel.app/quote"] 18 | stdout: StdioCollector { 19 | onStreamFinished: { 20 | const json = JSON.parse(text) 21 | root.quote = json.quote 22 | root.author = json.author 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/share/sleex/services/Wallpapers.qml: -------------------------------------------------------------------------------- 1 | import qs.modules.common 2 | import QtQuick 3 | import Quickshell 4 | import Quickshell.Io 5 | pragma Singleton 6 | pragma ComponentBehavior: Bound 7 | 8 | Singleton { 9 | id: root 10 | property var wallpaperList: [] 11 | 12 | property string wallpaperPath: Config.options.background.wallpaperSelectorPath.lenght != 0 ? Config.options.background.wallpaperSelectorPath : Directories.wallpaperPath 13 | 14 | Process { 15 | id: listWallpapers 16 | running: true 17 | command: [ 18 | "bash", "-c", 19 | "find " + root.wallpaperPath + " -type f \\( -iname '*.jpg' -o -iname '*.png' -o -iname '*.webp' \\) -printf '%P\\n'" 20 | ] 21 | stdout: StdioCollector { 22 | onStreamFinished: { 23 | root.wallpaperList = text.split('\n').filter(function(item) { return item.length > 0; }); 24 | } 25 | } 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /src/share/sleex/services/Ydotool.qml: -------------------------------------------------------------------------------- 1 | pragma Singleton 2 | 3 | import qs.modules.common 4 | import Quickshell 5 | import Quickshell.Io 6 | import Quickshell.Hyprland 7 | 8 | Singleton { 9 | id: root 10 | property int shiftMode: 0 // 0: off, 1: on, 2: lock 11 | property list shiftKeys: [42, 54] // Keycodes for Shift keys (left and right) 12 | property list altKeys: [56, 100] // Keycodes for Alt keys (left and right) 13 | property list ctrlKeys: [29, 97] // Keycodes for Ctrl keys (left and right) 14 | 15 | onShiftModeChanged: { 16 | if (shiftMode === 0) { 17 | 18 | } 19 | } 20 | 21 | function releaseAllKeys() { 22 | const keycodes = Array.from(Array(249).keys()); 23 | const releaseCommand = `ydotool key --key-delay 0 ${keycodes.map(keycode => `${keycode}:0`).join(" ")}` 24 | Quickshell.execDetached(["bash", "-c", `${releaseCommand}`]) 25 | root.shiftMode = 0; // Reset shift mode 26 | } 27 | 28 | function releaseShiftKeys() { 29 | const releaseCommand = `ydotool key --key-delay 0 ${root.shiftKeys.map(keycode => `${keycode}:0`).join(" ")}` 30 | Quickshell.execDetached(["bash", "-c", `${releaseCommand}`]) 31 | root.shiftMode = 0; // Reset shift mode 32 | } 33 | 34 | function press(keycode) { 35 | Quickshell.execDetached(["bash", "-c", `ydotool key --key-delay 0 ${keycode}:1`]); 36 | } 37 | 38 | function release(keycode) { 39 | Quickshell.execDetached(["bash", "-c", `ydotool key --key-delay 0 ${keycode}:0`]); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/share/sleex/services/ai/AiMessageData.qml: -------------------------------------------------------------------------------- 1 | import QtQuick; 2 | 3 | /** 4 | * Represents a message in an AI conversation. (Kind of) follows the OpenAI API message structure. 5 | */ 6 | QtObject { 7 | property string role 8 | property string content 9 | property string rawContent 10 | property string fileMimeType 11 | property string fileUri 12 | property string localFilePath 13 | property string model 14 | property bool thinking: true 15 | property bool done: false 16 | property var annotations: [] 17 | property var annotationSources: [] 18 | property list searchQueries: [] 19 | property string functionName 20 | property var functionCall 21 | property string functionResponse 22 | property bool functionPending: false 23 | property bool visibleToUser: true 24 | } 25 | -------------------------------------------------------------------------------- /src/share/sleex/services/ai/AiModel.qml: -------------------------------------------------------------------------------- 1 | import QtQuick; 2 | 3 | /** 4 | * An AI model representation. 5 | * - name: Friendly name of the model 6 | * - icon: Icon name of the model 7 | * - description: Description of the model 8 | * - endpoint: Endpoint of the model 9 | * - model: Model code (like gpt-4.1 or gemini-2.5-flash) 10 | * - requires_key: Whether the model requires an API key 11 | * - key_id: The identifier of the API key. Use the same identifier for models that can be accessed with the same key. 12 | * - key_get_link: Link to get an API key 13 | * - key_get_description: Description of pricing and how to get an API key 14 | * - api_format: The API format of the model. Can be "openai" or "gemini". Default is "openai". 15 | * - extraParams: Extra parameters to be passed to the model. This is a JSON object. 16 | */ 17 | 18 | QtObject { 19 | property string name 20 | property string icon 21 | property string description 22 | property string homepage 23 | property string endpoint 24 | property string model 25 | property bool requires_key: true 26 | property string key_id 27 | property string key_get_link 28 | property string key_get_description 29 | property string api_format: "openai" 30 | property var tools 31 | property var extraParams: ({}) 32 | } 33 | -------------------------------------------------------------------------------- /src/share/sleex/services/ai/ApiStrategy.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2 | 3 | QtObject { 4 | function buildEndpoint(model: AiModel): string { throw new Error("Not implemented") } 5 | function buildRequestData(model: AiModel, messages, systemPrompt: string, temperature: real, tools: list, filePath: string) { throw new Error("Not implemented") } 6 | function buildAuthorizationHeader(apiKeyEnvVarName: string): string { throw new Error("Not implemented") } 7 | function parseResponseLine(line: string, message: AiMessageData) { throw new Error("Not implemented") } 8 | function onRequestFinished(message: AiMessageData): var { return {} } // Default: no special handling 9 | function reset() { } // Reset any internal state if needed 10 | function buildScriptFileSetup(filePath) { return "" } // Default: no setup 11 | function finalizeScriptContent(scriptContent: string): string { return scriptContent } // Optionally modify/finalize script 12 | } 13 | -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/Glooe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/Glooe.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/Gloow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/Gloow.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/RenderBall.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/RenderBall.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/Robohand.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/Robohand.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexBlackSE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexBlackSE.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexFour.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexFour.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexFourB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexFourB.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexFourSE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexFourSE.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexOne.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexOne.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexThree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexThree.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexThreeSE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexThreeSE.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexTwo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexTwo.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/SleexTwoSE.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/SleexTwoSE.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/sakura.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/sakura.png -------------------------------------------------------------------------------- /src/share/sleex/wallpapers/skyline.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AxOS-project/Sleex/a5dbc03abf47ff415d292bfbcdcbdec9fbb49077/src/share/sleex/wallpapers/skyline.jpg -------------------------------------------------------------------------------- /src/share/wayland-sessions/sleex.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Sleex 3 | Comment=AxOS's third desktop environment 4 | Exec=sleex 5 | Icon= 6 | Type=Application --------------------------------------------------------------------------------