mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-25 14:02:53 -05:00
Compare commits
1 Commits
v0.0.30
...
surface-co
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e103d7ba7 |
11
.github/workflows/release.yml
vendored
11
.github/workflows/release.yml
vendored
@@ -17,17 +17,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Fetch full history for changelog generation
|
fetch-depth: 0 # Fetch full history for changelog generation
|
||||||
|
|
||||||
# Create VERSION file
|
|
||||||
- name: Create VERSION file
|
|
||||||
run: |
|
|
||||||
echo "${{ github.ref_name }}" > VERSION
|
|
||||||
git config user.name "github-actions[bot]"
|
|
||||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
git add VERSION
|
|
||||||
git commit -m "Add VERSION file for ${{ github.ref_name }}"
|
|
||||||
git tag -f ${{ github.ref_name }}
|
|
||||||
git push origin ${{ github.ref_name }} --force
|
|
||||||
|
|
||||||
# Generate changelog
|
# Generate changelog
|
||||||
- name: Generate Changelog
|
- name: Generate Changelog
|
||||||
id: changelog
|
id: changelog
|
||||||
|
|||||||
167
CLAUDE.md
167
CLAUDE.md
@@ -63,9 +63,6 @@ quickshell -p shell.qml
|
|||||||
# Or use the shorthand
|
# Or use the shorthand
|
||||||
qs -p .
|
qs -p .
|
||||||
|
|
||||||
# Run with verbose output for debugging
|
|
||||||
qs -v -p shell.qml
|
|
||||||
|
|
||||||
# Code formatting and linting
|
# Code formatting and linting
|
||||||
qmlfmt -t 4 -i 4 -b 250 -w /path/to/file.qml # Format a QML file (requires qmlfmt, do not use qmlformat)
|
qmlfmt -t 4 -i 4 -b 250 -w /path/to/file.qml # Format a QML file (requires qmlfmt, do not use qmlformat)
|
||||||
qmllint **/*.qml # Lint all QML files for syntax errors
|
qmllint **/*.qml # Lint all QML files for syntax errors
|
||||||
@@ -92,7 +89,6 @@ shell.qml # Main entry point (minimal orchestration)
|
|||||||
│ ├── DisplayService.qml
|
│ ├── DisplayService.qml
|
||||||
│ ├── NotificationService.qml
|
│ ├── NotificationService.qml
|
||||||
│ ├── WeatherService.qml
|
│ ├── WeatherService.qml
|
||||||
│ ├── PluginService.qml
|
|
||||||
│ └── [14 more services]
|
│ └── [14 more services]
|
||||||
├── Modules/ # UI components (93 files)
|
├── Modules/ # UI components (93 files)
|
||||||
│ ├── TopBar/ # Panel components (13 files)
|
│ ├── TopBar/ # Panel components (13 files)
|
||||||
@@ -108,21 +104,15 @@ shell.qml # Main entry point (minimal orchestration)
|
|||||||
│ ├── SettingsModal.qml
|
│ ├── SettingsModal.qml
|
||||||
│ ├── ClipboardHistoryModal.qml
|
│ ├── ClipboardHistoryModal.qml
|
||||||
│ ├── ProcessListModal.qml
|
│ ├── ProcessListModal.qml
|
||||||
│ ├── PluginSettingsModal.qml
|
|
||||||
│ └── [7 more modals]
|
│ └── [7 more modals]
|
||||||
├── Widgets/ # Reusable UI controls (19 files)
|
└── Widgets/ # Reusable UI controls (19 files)
|
||||||
│ ├── DankIcon.qml
|
├── DankIcon.qml
|
||||||
│ ├── DankSlider.qml
|
├── DankSlider.qml
|
||||||
│ ├── DankToggle.qml
|
├── DankToggle.qml
|
||||||
│ ├── DankTabBar.qml
|
├── DankTabBar.qml
|
||||||
│ ├── DankGridView.qml
|
├── DankGridView.qml
|
||||||
│ ├── DankListView.qml
|
├── DankListView.qml
|
||||||
│ └── [13 more widgets]
|
└── [13 more widgets]
|
||||||
└── plugins/ # External plugins directory ($CONFIGPATH/DankMaterialShell/plugins/)
|
|
||||||
└── PluginName/ # Example Plugin structure
|
|
||||||
├── plugin.json # Plugin manifest
|
|
||||||
├── PluginNameWidget.qml # Widget component
|
|
||||||
└── PluginNameSettings.qml # Settings UI
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Component Organization
|
### Component Organization
|
||||||
@@ -173,12 +163,6 @@ shell.qml # Main entry point (minimal orchestration)
|
|||||||
- **DankLocationSearch**: Location picker with search
|
- **DankLocationSearch**: Location picker with search
|
||||||
- **SystemLogo**: Animated system branding component
|
- **SystemLogo**: Animated system branding component
|
||||||
|
|
||||||
7. **Plugins/** - External plugin system (`$CONFIGPATH/DankMaterialShell/plugins/`)
|
|
||||||
- **PluginService**: Discovers, loads, and manages plugin lifecycle
|
|
||||||
- **Dynamic Loading**: Plugins loaded at runtime from external directory
|
|
||||||
- **DankBar Integration**: Plugin widgets rendered alongside built-in widgets
|
|
||||||
- **Settings System**: Per-plugin settings with persistence
|
|
||||||
|
|
||||||
### Key Architectural Patterns
|
### Key Architectural Patterns
|
||||||
|
|
||||||
1. **Singleton Services Pattern**:
|
1. **Singleton Services Pattern**:
|
||||||
@@ -424,10 +408,10 @@ When modifying the shell:
|
|||||||
|
|
||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool featureAvailable: false
|
property bool featureAvailable: false
|
||||||
property type currentValue: defaultValue
|
property type currentValue: defaultValue
|
||||||
|
|
||||||
function performAction(param) {
|
function performAction(param) {
|
||||||
// Implementation
|
// Implementation
|
||||||
}
|
}
|
||||||
@@ -438,7 +422,7 @@ When modifying the shell:
|
|||||||
```qml
|
```qml
|
||||||
// In module files
|
// In module files
|
||||||
property alias serviceValue: NewService.currentValue
|
property alias serviceValue: NewService.currentValue
|
||||||
|
|
||||||
SomeControl {
|
SomeControl {
|
||||||
visible: NewService.featureAvailable
|
visible: NewService.featureAvailable
|
||||||
enabled: NewService.featureAvailable
|
enabled: NewService.featureAvailable
|
||||||
@@ -446,134 +430,6 @@ When modifying the shell:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Creating Plugins
|
|
||||||
|
|
||||||
Plugins are external, dynamically-loaded components that extend DankBar functionality. Plugins are stored in `~/.config/DankMaterialShell/plugins/` and have their settings isolated from core DMS settings.
|
|
||||||
|
|
||||||
1. **Create plugin directory**:
|
|
||||||
```bash
|
|
||||||
mkdir -p ~/.config/DankMaterialShell/plugins/YourPlugin
|
|
||||||
```
|
|
||||||
|
|
||||||
2. **Create manifest** (`plugin.json`):
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"id": "yourPlugin",
|
|
||||||
"name": "Your Plugin",
|
|
||||||
"description": "Widget description",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"author": "Your Name",
|
|
||||||
"icon": "extension",
|
|
||||||
"component": "./YourWidget.qml",
|
|
||||||
"settings": "./YourSettings.qml",
|
|
||||||
"permissions": ["settings_read", "settings_write"]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Create widget component** (`YourWidget.qml`):
|
|
||||||
```qml
|
|
||||||
import QtQuick
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool compactMode: false
|
|
||||||
property string section: "center"
|
|
||||||
property real widgetHeight: 30
|
|
||||||
property var pluginService: null
|
|
||||||
|
|
||||||
width: content.implicitWidth + 16
|
|
||||||
height: widgetHeight
|
|
||||||
radius: 8
|
|
||||||
color: "#20FFFFFF"
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
if (pluginService) {
|
|
||||||
var data = pluginService.loadPluginData("yourPlugin", "key", defaultValue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
4. **Create settings component** (`YourSettings.qml`):
|
|
||||||
```qml
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
|
|
||||||
FocusScope {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var pluginService: null
|
|
||||||
|
|
||||||
implicitHeight: settingsColumn.implicitHeight
|
|
||||||
height: implicitHeight
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: settingsColumn
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: 16
|
|
||||||
spacing: 12
|
|
||||||
|
|
||||||
Text {
|
|
||||||
text: "Your Plugin Settings"
|
|
||||||
font.pixelSize: 18
|
|
||||||
font.weight: Font.Bold
|
|
||||||
}
|
|
||||||
|
|
||||||
// Your settings UI here
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveSettings(key, value) {
|
|
||||||
if (pluginService) {
|
|
||||||
pluginService.savePluginData("yourPlugin", key, value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadSettings(key, defaultValue) {
|
|
||||||
if (pluginService) {
|
|
||||||
return pluginService.loadPluginData("yourPlugin", key, defaultValue)
|
|
||||||
}
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
5. **Enable plugin**:
|
|
||||||
- Open Settings → Plugins
|
|
||||||
- Click "Scan for Plugins"
|
|
||||||
- Toggle plugin to enable
|
|
||||||
- Add plugin ID to DankBar widget list
|
|
||||||
|
|
||||||
**Plugin Directory Structure:**
|
|
||||||
```
|
|
||||||
~/.config/DankMaterialShell/
|
|
||||||
├── settings.json # Core DMS settings + plugin settings
|
|
||||||
│ └── pluginSettings: {
|
|
||||||
│ └── yourPlugin: {
|
|
||||||
│ ├── enabled: true,
|
|
||||||
│ └── customData: {...}
|
|
||||||
│ }
|
|
||||||
│ }
|
|
||||||
└── plugins/ # Plugin files directory
|
|
||||||
└── YourPlugin/ # Plugin directory (matches manifest ID)
|
|
||||||
├── plugin.json # Plugin manifest
|
|
||||||
├── YourWidget.qml # Widget component
|
|
||||||
└── YourSettings.qml # Settings UI (optional)
|
|
||||||
```
|
|
||||||
|
|
||||||
**Key Plugin APIs:**
|
|
||||||
- `pluginService.loadPluginData(pluginId, key, default)` - Load persistent data
|
|
||||||
- `pluginService.savePluginData(pluginId, key, value)` - Save persistent data
|
|
||||||
- `PluginService.enablePlugin(pluginId)` - Load plugin
|
|
||||||
- `PluginService.disablePlugin(pluginId)` - Unload plugin
|
|
||||||
|
|
||||||
**Important Notes:**
|
|
||||||
- Plugin settings are automatically injected by the PluginService via `item.pluginService = PluginService`
|
|
||||||
- Settings are stored in the main settings.json but namespaced under `pluginSettings.{pluginId}`
|
|
||||||
- Plugin directories must match the plugin ID in the manifest
|
|
||||||
- Use the injected `pluginService` property in both widget and settings components
|
|
||||||
|
|
||||||
### Debugging Common Issues
|
### Debugging Common Issues
|
||||||
|
|
||||||
1. **Import errors**: Check import paths
|
1. **Import errors**: Check import paths
|
||||||
@@ -598,7 +454,6 @@ Plugins are external, dynamically-loaded components that extend DankBar function
|
|||||||
- **Function Discovery**: Use grep/search tools to find existing utility functions before implementing new ones
|
- **Function Discovery**: Use grep/search tools to find existing utility functions before implementing new ones
|
||||||
- **Modern QML Patterns**: Leverage new widgets like DankTextField, DankDropdown, CachingImage
|
- **Modern QML Patterns**: Leverage new widgets like DankTextField, DankDropdown, CachingImage
|
||||||
- **Structured Organization**: Follow the established Services/Modules/Widgets/Modals separation
|
- **Structured Organization**: Follow the established Services/Modules/Widgets/Modals separation
|
||||||
- **Plugin System**: For user extensions, create plugins instead of modifying core modules - see docs/PLUGINS.md
|
|
||||||
|
|
||||||
### Common Widget Patterns
|
### Common Widget Patterns
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
Contributions are welcome and encouraged.
|
Contributions are welcome and encourages.
|
||||||
|
|
||||||
## Formatting
|
## Formatting
|
||||||
|
|
||||||
@@ -27,4 +27,4 @@ Sometimes it just breaks code though. Like turning `"_\""` into `"_""`, so you m
|
|||||||
|
|
||||||
## Pull request
|
## Pull request
|
||||||
|
|
||||||
Include screenshots/video if applicable in your pull request if applicable, to visualize what your change is affecting.
|
Include screenshots/video if applicable in your pull request if applicable, to visualize what your change is affecting.
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
readonly property var facts: [
|
|
||||||
"A photon takes 100,000 to 200,000 years bouncing through the Sun's dense core, then races to Earth in just 8 minutes 20 seconds.",
|
|
||||||
"A teaspoon of neutron star matter would weigh a billion metric tons here on Earth.",
|
|
||||||
"Right now, 100 trillion solar neutrinos are passing through your body every second.",
|
|
||||||
"The Sun converts 4 million metric tons of matter into pure energy every second—enough to power Earth for 500,000 years.",
|
|
||||||
"The universe still glows with leftover heat from the Big Bang—just 2.7 degrees above absolute zero.",
|
|
||||||
"There's a nebula out there that's actually colder than empty space itself.",
|
|
||||||
"We've detected black holes crashing together by measuring spacetime stretch by less than 1/10,000th the width of a proton.",
|
|
||||||
"Fast radio bursts can release more energy in 5 milliseconds than our Sun produces in 3 days.",
|
|
||||||
"Our galaxy might be crawling with billions of rogue planets drifting alone in the dark.",
|
|
||||||
"Distant galaxies can move away from us faster than light because space itself is stretching.",
|
|
||||||
"The edge of what we can see is 46.5 billion light-years away, even though the universe is only 13.8 billion years old.",
|
|
||||||
"The universe is mostly invisible: 5% regular matter, 27% dark matter, 68% dark energy.",
|
|
||||||
"A day on Venus lasts longer than its entire year around the Sun.",
|
|
||||||
"On Mercury, the time between sunrises is 176 Earth days long.",
|
|
||||||
"In about 4.5 billion years, our galaxy will smash into Andromeda.",
|
|
||||||
"Most of the gold in your jewelry was forged when neutron stars collided somewhere in space.",
|
|
||||||
"PSR J1748-2446ad, the fastest spinning star, rotates 716 times per second—its equator moves at 24% the speed of light.",
|
|
||||||
"Cosmic rays create particles that shouldn't make it to Earth's surface, but time dilation lets them sneak through.",
|
|
||||||
"Jupiter's magnetic field is so huge that if we could see it, it would look bigger than the Moon in our sky.",
|
|
||||||
"Interstellar space is so empty it's like a cube 32 kilometers wide containing just a single grain of sand.",
|
|
||||||
"Voyager 1 is 24 billion kilometers away but won't leave the Sun's gravitational influence for another 30,000 years.",
|
|
||||||
"Counting to a billion at one number per second would take over 31 years.",
|
|
||||||
"Space is so vast, even speeding at light-speed, you'd never return past the cosmic horizon.",
|
|
||||||
"Astronauts on the ISS age about 0.01 seconds less each year than people on Earth.",
|
|
||||||
"Sagittarius B2, a dust cloud near our galaxy's center, contains ethyl formate—the compound that gives raspberries their flavor and rum its smell.",
|
|
||||||
"Beyond 16 billion light-years, the cosmic event horizon marks where space expands too fast for light to ever reach us again.",
|
|
||||||
"Even at light-speed, you'd never catch up to most galaxies—space expands faster.",
|
|
||||||
"Only around 5% of galaxies are ever reachable—even at light-speed.",
|
|
||||||
"If the Sun vanished, we'd still orbit it for 8 minutes before drifting away.",
|
|
||||||
"If a planet 65 million light-years away looked at Earth now, it'd see dinosaurs.",
|
|
||||||
"Our oldest radio signals will reach the Milky Way's center in 26,000 years.",
|
|
||||||
"Every atom in your body heavier than hydrogen was forged in the nuclear furnace of a dying star.",
|
|
||||||
"The Moon moves 3.8 centimeters farther from Earth every year.",
|
|
||||||
"The universe creates 275 million new stars every single day.",
|
|
||||||
"Jupiter's Great Red Spot is a storm twice the size of Earth that has been raging for at least 350 years.",
|
|
||||||
"If you watched someone fall into a black hole, they'd appear frozen at the event horizon forever—time effectively stops from your perspective.",
|
|
||||||
"The Boötes Supervoid is a cosmic desert 1.8 billion light-years across with 60% fewer galaxies than it should have."
|
|
||||||
]
|
|
||||||
|
|
||||||
function getRandomFact() {
|
|
||||||
return facts[Math.floor(Math.random() * facts.length)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -12,19 +12,12 @@ Singleton {
|
|||||||
|
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property bool isGreeterMode: Quickshell.env("DMS_RUN_GREETER") === "1" || Quickshell.env("DMS_RUN_GREETER") === "true"
|
|
||||||
|
|
||||||
property bool isLightMode: false
|
property bool isLightMode: false
|
||||||
property string wallpaperPath: ""
|
property string wallpaperPath: ""
|
||||||
property string wallpaperLastPath: ""
|
property string wallpaperLastPath: ""
|
||||||
property string profileLastPath: ""
|
property string profileLastPath: ""
|
||||||
property bool perMonitorWallpaper: false
|
property bool perMonitorWallpaper: false
|
||||||
property var monitorWallpapers: ({})
|
property var monitorWallpapers: ({})
|
||||||
property bool perModeWallpaper: false
|
|
||||||
property string wallpaperPathLight: ""
|
|
||||||
property string wallpaperPathDark: ""
|
|
||||||
property var monitorWallpapersLight: ({})
|
|
||||||
property var monitorWallpapersDark: ({})
|
|
||||||
property bool doNotDisturb: false
|
property bool doNotDisturb: false
|
||||||
property bool nightModeEnabled: false
|
property bool nightModeEnabled: false
|
||||||
property int nightModeTemperature: 4500
|
property int nightModeTemperature: 4500
|
||||||
@@ -73,17 +66,11 @@ Singleton {
|
|||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (!isGreeterMode) {
|
loadSettings()
|
||||||
loadSettings()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
if (isGreeterMode) {
|
parseSettings(settingsFile.text())
|
||||||
parseSettings(greeterSessionFile.text())
|
|
||||||
} else {
|
|
||||||
parseSettings(settingsFile.text())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseSettings(content) {
|
function parseSettings(content) {
|
||||||
@@ -96,11 +83,6 @@ Singleton {
|
|||||||
profileLastPath = settings.profileLastPath !== undefined ? settings.profileLastPath : ""
|
profileLastPath = settings.profileLastPath !== undefined ? settings.profileLastPath : ""
|
||||||
perMonitorWallpaper = settings.perMonitorWallpaper !== undefined ? settings.perMonitorWallpaper : false
|
perMonitorWallpaper = settings.perMonitorWallpaper !== undefined ? settings.perMonitorWallpaper : false
|
||||||
monitorWallpapers = settings.monitorWallpapers !== undefined ? settings.monitorWallpapers : {}
|
monitorWallpapers = settings.monitorWallpapers !== undefined ? settings.monitorWallpapers : {}
|
||||||
perModeWallpaper = settings.perModeWallpaper !== undefined ? settings.perModeWallpaper : false
|
|
||||||
wallpaperPathLight = settings.wallpaperPathLight !== undefined ? settings.wallpaperPathLight : ""
|
|
||||||
wallpaperPathDark = settings.wallpaperPathDark !== undefined ? settings.wallpaperPathDark : ""
|
|
||||||
monitorWallpapersLight = settings.monitorWallpapersLight !== undefined ? settings.monitorWallpapersLight : {}
|
|
||||||
monitorWallpapersDark = settings.monitorWallpapersDark !== undefined ? settings.monitorWallpapersDark : {}
|
|
||||||
doNotDisturb = settings.doNotDisturb !== undefined ? settings.doNotDisturb : false
|
doNotDisturb = settings.doNotDisturb !== undefined ? settings.doNotDisturb : false
|
||||||
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false
|
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false
|
||||||
nightModeTemperature = settings.nightModeTemperature !== undefined ? settings.nightModeTemperature : 4500
|
nightModeTemperature = settings.nightModeTemperature !== undefined ? settings.nightModeTemperature : 4500
|
||||||
@@ -150,11 +132,10 @@ Singleton {
|
|||||||
batterySuspendTimeout = settings.batterySuspendTimeout !== undefined ? settings.batterySuspendTimeout : 0
|
batterySuspendTimeout = settings.batterySuspendTimeout !== undefined ? settings.batterySuspendTimeout : 0
|
||||||
batteryHibernateTimeout = settings.batteryHibernateTimeout !== undefined ? settings.batteryHibernateTimeout : 0
|
batteryHibernateTimeout = settings.batteryHibernateTimeout !== undefined ? settings.batteryHibernateTimeout : 0
|
||||||
lockBeforeSuspend = settings.lockBeforeSuspend !== undefined ? settings.lockBeforeSuspend : false
|
lockBeforeSuspend = settings.lockBeforeSuspend !== undefined ? settings.lockBeforeSuspend : false
|
||||||
|
|
||||||
if (!isGreeterMode) {
|
// Generate system themes but don't override user's theme choice
|
||||||
if (typeof Theme !== "undefined") {
|
if (typeof Theme !== "undefined") {
|
||||||
Theme.generateSystemThemesFromCurrentTheme()
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -163,7 +144,6 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveSettings() {
|
function saveSettings() {
|
||||||
if (isGreeterMode) return
|
|
||||||
settingsFile.setText(JSON.stringify({
|
settingsFile.setText(JSON.stringify({
|
||||||
"isLightMode": isLightMode,
|
"isLightMode": isLightMode,
|
||||||
"wallpaperPath": wallpaperPath,
|
"wallpaperPath": wallpaperPath,
|
||||||
@@ -171,11 +151,6 @@ Singleton {
|
|||||||
"profileLastPath": profileLastPath,
|
"profileLastPath": profileLastPath,
|
||||||
"perMonitorWallpaper": perMonitorWallpaper,
|
"perMonitorWallpaper": perMonitorWallpaper,
|
||||||
"monitorWallpapers": monitorWallpapers,
|
"monitorWallpapers": monitorWallpapers,
|
||||||
"perModeWallpaper": perModeWallpaper,
|
|
||||||
"wallpaperPathLight": wallpaperPathLight,
|
|
||||||
"wallpaperPathDark": wallpaperPathDark,
|
|
||||||
"monitorWallpapersLight": monitorWallpapersLight,
|
|
||||||
"monitorWallpapersDark": monitorWallpapersDark,
|
|
||||||
"doNotDisturb": doNotDisturb,
|
"doNotDisturb": doNotDisturb,
|
||||||
"nightModeEnabled": nightModeEnabled,
|
"nightModeEnabled": nightModeEnabled,
|
||||||
"nightModeTemperature": nightModeTemperature,
|
"nightModeTemperature": nightModeTemperature,
|
||||||
@@ -216,21 +191,9 @@ Singleton {
|
|||||||
|
|
||||||
function setLightMode(lightMode) {
|
function setLightMode(lightMode) {
|
||||||
isLightMode = lightMode
|
isLightMode = lightMode
|
||||||
syncWallpaperForCurrentMode()
|
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncWallpaperForCurrentMode() {
|
|
||||||
if (!perModeWallpaper) return
|
|
||||||
|
|
||||||
if (perMonitorWallpaper) {
|
|
||||||
monitorWallpapers = isLightMode ? Object.assign({}, monitorWallpapersLight) : Object.assign({}, monitorWallpapersDark)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
wallpaperPath = isLightMode ? wallpaperPathLight : wallpaperPathDark
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDoNotDisturb(enabled) {
|
function setDoNotDisturb(enabled) {
|
||||||
doNotDisturb = enabled
|
doNotDisturb = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
@@ -301,32 +264,24 @@ Singleton {
|
|||||||
|
|
||||||
function setWallpaper(imagePath) {
|
function setWallpaper(imagePath) {
|
||||||
wallpaperPath = imagePath
|
wallpaperPath = imagePath
|
||||||
if (perModeWallpaper) {
|
|
||||||
if (isLightMode) {
|
|
||||||
wallpaperPathLight = imagePath
|
|
||||||
} else {
|
|
||||||
wallpaperPathDark = imagePath
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saveSettings()
|
saveSettings()
|
||||||
|
|
||||||
if (typeof Theme !== "undefined") {
|
if (typeof Theme !== "undefined") {
|
||||||
|
if (Theme.currentTheme === Theme.dynamic) {
|
||||||
|
Theme.extractColors()
|
||||||
|
}
|
||||||
Theme.generateSystemThemesFromCurrentTheme()
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setWallpaperColor(color) {
|
function setWallpaperColor(color) {
|
||||||
wallpaperPath = color
|
wallpaperPath = color
|
||||||
if (perModeWallpaper) {
|
|
||||||
if (isLightMode) {
|
|
||||||
wallpaperPathLight = color
|
|
||||||
} else {
|
|
||||||
wallpaperPathDark = color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saveSettings()
|
saveSettings()
|
||||||
|
|
||||||
if (typeof Theme !== "undefined") {
|
if (typeof Theme !== "undefined") {
|
||||||
|
if (Theme.currentTheme === Theme.dynamic) {
|
||||||
|
Theme.extractColors()
|
||||||
|
}
|
||||||
Theme.generateSystemThemesFromCurrentTheme()
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -471,52 +426,13 @@ Singleton {
|
|||||||
|
|
||||||
function setPerMonitorWallpaper(enabled) {
|
function setPerMonitorWallpaper(enabled) {
|
||||||
perMonitorWallpaper = enabled
|
perMonitorWallpaper = enabled
|
||||||
if (enabled && perModeWallpaper) {
|
|
||||||
syncWallpaperForCurrentMode()
|
|
||||||
}
|
|
||||||
saveSettings()
|
saveSettings()
|
||||||
|
|
||||||
|
// Refresh dynamic theming when per-monitor mode changes
|
||||||
if (typeof Theme !== "undefined") {
|
if (typeof Theme !== "undefined") {
|
||||||
Theme.generateSystemThemesFromCurrentTheme()
|
if (Theme.currentTheme === Theme.dynamic) {
|
||||||
}
|
Theme.extractColors()
|
||||||
}
|
|
||||||
|
|
||||||
function setPerModeWallpaper(enabled) {
|
|
||||||
if (enabled && wallpaperCyclingEnabled) {
|
|
||||||
setWallpaperCyclingEnabled(false)
|
|
||||||
}
|
|
||||||
if (enabled && perMonitorWallpaper) {
|
|
||||||
var monitorCyclingAny = false
|
|
||||||
for (var key in monitorCyclingSettings) {
|
|
||||||
if (monitorCyclingSettings[key].enabled) {
|
|
||||||
monitorCyclingAny = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (monitorCyclingAny) {
|
|
||||||
var newSettings = Object.assign({}, monitorCyclingSettings)
|
|
||||||
for (var screenName in newSettings) {
|
|
||||||
newSettings[screenName].enabled = false
|
|
||||||
}
|
|
||||||
monitorCyclingSettings = newSettings
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
perModeWallpaper = enabled
|
|
||||||
if (enabled) {
|
|
||||||
if (perMonitorWallpaper) {
|
|
||||||
monitorWallpapersLight = Object.assign({}, monitorWallpapers)
|
|
||||||
monitorWallpapersDark = Object.assign({}, monitorWallpapers)
|
|
||||||
} else {
|
|
||||||
wallpaperPathLight = wallpaperPath
|
|
||||||
wallpaperPathDark = wallpaperPath
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
syncWallpaperForCurrentMode()
|
|
||||||
}
|
|
||||||
saveSettings()
|
|
||||||
|
|
||||||
if (typeof Theme !== "undefined") {
|
|
||||||
Theme.generateSystemThemesFromCurrentTheme()
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -529,32 +445,15 @@ Singleton {
|
|||||||
delete newMonitorWallpapers[screenName]
|
delete newMonitorWallpapers[screenName]
|
||||||
}
|
}
|
||||||
monitorWallpapers = newMonitorWallpapers
|
monitorWallpapers = newMonitorWallpapers
|
||||||
|
|
||||||
if (perModeWallpaper) {
|
|
||||||
if (isLightMode) {
|
|
||||||
var newLight = Object.assign({}, monitorWallpapersLight)
|
|
||||||
if (path && path !== "") {
|
|
||||||
newLight[screenName] = path
|
|
||||||
} else {
|
|
||||||
delete newLight[screenName]
|
|
||||||
}
|
|
||||||
monitorWallpapersLight = newLight
|
|
||||||
} else {
|
|
||||||
var newDark = Object.assign({}, monitorWallpapersDark)
|
|
||||||
if (path && path !== "") {
|
|
||||||
newDark[screenName] = path
|
|
||||||
} else {
|
|
||||||
delete newDark[screenName]
|
|
||||||
}
|
|
||||||
monitorWallpapersDark = newDark
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
saveSettings()
|
saveSettings()
|
||||||
|
|
||||||
|
// Trigger dynamic theming if this is the first monitor and dynamic theming is enabled
|
||||||
if (typeof Theme !== "undefined" && typeof Quickshell !== "undefined") {
|
if (typeof Theme !== "undefined" && typeof Quickshell !== "undefined") {
|
||||||
var screens = Quickshell.screens
|
var screens = Quickshell.screens
|
||||||
if (screens.length > 0 && screenName === screens[0].name) {
|
if (screens.length > 0 && screenName === screens[0].name) {
|
||||||
|
if (Theme.currentTheme === Theme.dynamic) {
|
||||||
|
Theme.extractColors()
|
||||||
|
}
|
||||||
Theme.generateSystemThemesFromCurrentTheme()
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -630,43 +529,22 @@ Singleton {
|
|||||||
FileView {
|
FileView {
|
||||||
id: settingsFile
|
id: settingsFile
|
||||||
|
|
||||||
path: isGreeterMode ? "" : StandardPaths.writableLocation(StandardPaths.GenericStateLocation) + "/DankMaterialShell/session.json"
|
path: StandardPaths.writableLocation(StandardPaths.GenericStateLocation) + "/DankMaterialShell/session.json"
|
||||||
blockLoading: isGreeterMode
|
blockLoading: true
|
||||||
blockWrites: true
|
blockWrites: true
|
||||||
watchChanges: !isGreeterMode
|
watchChanges: true
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
if (!isGreeterMode) {
|
parseSettings(settingsFile.text())
|
||||||
parseSettings(settingsFile.text())
|
hasTriedDefaultSession = false
|
||||||
hasTriedDefaultSession = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onLoadFailed: error => {
|
onLoadFailed: error => {
|
||||||
if (!isGreeterMode && !hasTriedDefaultSettings) {
|
if (!hasTriedDefaultSession) {
|
||||||
hasTriedDefaultSettings = true
|
hasTriedDefaultSession = true
|
||||||
defaultSessionCheckProcess.running = true
|
defaultSessionCheckProcess.running = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: greeterSessionFile
|
|
||||||
|
|
||||||
path: {
|
|
||||||
const greetCfgDir = Quickshell.env("DMS_GREET_CFG_DIR") || "/etc/greetd/.dms"
|
|
||||||
return greetCfgDir + "/session.json"
|
|
||||||
}
|
|
||||||
preload: isGreeterMode
|
|
||||||
blockLoading: false
|
|
||||||
blockWrites: true
|
|
||||||
watchChanges: false
|
|
||||||
printErrors: true
|
|
||||||
onLoaded: {
|
|
||||||
if (isGreeterMode) {
|
|
||||||
parseSettings(greeterSessionFile.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: defaultSessionCheckProcess
|
id: defaultSessionCheckProcess
|
||||||
|
|
||||||
|
|||||||
@@ -12,30 +12,13 @@ import qs.Services
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
readonly property bool isGreeterMode: Quickshell.env("DMS_RUN_GREETER") === "1" || Quickshell.env("DMS_RUN_GREETER") === "true"
|
|
||||||
|
|
||||||
enum Position {
|
|
||||||
Top,
|
|
||||||
Bottom,
|
|
||||||
Left,
|
|
||||||
Right
|
|
||||||
}
|
|
||||||
|
|
||||||
enum AnimationSpeed {
|
|
||||||
None,
|
|
||||||
Shortest,
|
|
||||||
Short,
|
|
||||||
Medium,
|
|
||||||
Long
|
|
||||||
}
|
|
||||||
|
|
||||||
// Theme settings
|
// Theme settings
|
||||||
property string currentThemeName: "blue"
|
property string currentThemeName: "blue"
|
||||||
property string customThemeFile: ""
|
property string customThemeFile: ""
|
||||||
property string matugenScheme: "scheme-tonal-spot"
|
property string matugenScheme: "scheme-tonal-spot"
|
||||||
property real dankBarTransparency: 1.0
|
property real topBarTransparency: 0.75
|
||||||
property real dankBarWidgetTransparency: 1.0
|
property real topBarWidgetTransparency: 0.85
|
||||||
property real popupTransparency: 1.0
|
property real popupTransparency: 0.92
|
||||||
property real dockTransparency: 1
|
property real dockTransparency: 1
|
||||||
property bool use24HourClock: true
|
property bool use24HourClock: true
|
||||||
property bool useFahrenheit: false
|
property bool useFahrenheit: false
|
||||||
@@ -87,13 +70,12 @@ Singleton {
|
|||||||
property string clockDateFormat: ""
|
property string clockDateFormat: ""
|
||||||
property string lockDateFormat: ""
|
property string lockDateFormat: ""
|
||||||
property int mediaSize: 1
|
property int mediaSize: 1
|
||||||
property var dankBarLeftWidgets: ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
property var topBarLeftWidgets: ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
||||||
property var dankBarCenterWidgets: ["music", "clock", "weather"]
|
property var topBarCenterWidgets: ["music", "clock", "weather"]
|
||||||
property var dankBarRightWidgets: ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"]
|
property var topBarRightWidgets: ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"]
|
||||||
property var dankBarWidgetOrder: []
|
property alias topBarLeftWidgetsModel: leftWidgetsModel
|
||||||
property alias dankBarLeftWidgetsModel: leftWidgetsModel
|
property alias topBarCenterWidgetsModel: centerWidgetsModel
|
||||||
property alias dankBarCenterWidgetsModel: centerWidgetsModel
|
property alias topBarRightWidgetsModel: rightWidgetsModel
|
||||||
property alias dankBarRightWidgetsModel: rightWidgetsModel
|
|
||||||
property string appLauncherViewMode: "list"
|
property string appLauncherViewMode: "list"
|
||||||
property string spotlightModalViewMode: "list"
|
property string spotlightModalViewMode: "list"
|
||||||
property string networkPreference: "auto"
|
property string networkPreference: "auto"
|
||||||
@@ -135,48 +117,37 @@ Singleton {
|
|||||||
property bool showDock: false
|
property bool showDock: false
|
||||||
property bool dockAutoHide: false
|
property bool dockAutoHide: false
|
||||||
property bool dockGroupByApp: false
|
property bool dockGroupByApp: false
|
||||||
property bool dockOpenOnOverview: false
|
|
||||||
property int dockPosition: SettingsData.Position.Bottom
|
|
||||||
property real dockSpacing: 4
|
|
||||||
property real dockBottomGap: 0
|
|
||||||
property real cornerRadius: 12
|
property real cornerRadius: 12
|
||||||
property bool notificationOverlayEnabled: false
|
property bool notificationOverlayEnabled: false
|
||||||
property bool dankBarAutoHide: false
|
property bool topBarAutoHide: false
|
||||||
property bool dankBarOpenOnOverview: false
|
property bool topBarOpenOnOverview: false
|
||||||
property bool dankBarVisible: true
|
property bool topBarVisible: true
|
||||||
property real dankBarSpacing: 4
|
property real topBarSpacing: 4
|
||||||
property real dankBarBottomGap: 0
|
property real topBarBottomGap: 0
|
||||||
property real dankBarInnerPadding: 4
|
property real topBarInnerPadding: 8
|
||||||
property bool dankBarSquareCorners: false
|
property bool topBarSquareCorners: false
|
||||||
property bool dankBarNoBackground: false
|
property bool topBarNoBackground: false
|
||||||
property bool dankBarGothCornersEnabled: false
|
property bool topBarGothCornersEnabled: false
|
||||||
property int dankBarPosition: SettingsData.Position.Top
|
|
||||||
property bool dankBarIsVertical: dankBarPosition === SettingsData.Position.Left || dankBarPosition === SettingsData.Position.Right
|
|
||||||
property bool lockScreenShowPowerActions: true
|
property bool lockScreenShowPowerActions: true
|
||||||
property bool hideBrightnessSlider: false
|
property bool hideBrightnessSlider: false
|
||||||
property string widgetBackgroundColor: "sch"
|
property string widgetBackgroundColor: "sch"
|
||||||
property string surfaceBase: "s"
|
property string surfaceBase: "sc"
|
||||||
property int notificationTimeoutLow: 5000
|
property int notificationTimeoutLow: 5000
|
||||||
property int notificationTimeoutNormal: 5000
|
property int notificationTimeoutNormal: 5000
|
||||||
property int notificationTimeoutCritical: 0
|
property int notificationTimeoutCritical: 0
|
||||||
property int notificationPopupPosition: SettingsData.Position.Top
|
|
||||||
property var screenPreferences: ({})
|
property var screenPreferences: ({})
|
||||||
property int animationSpeed: SettingsData.AnimationSpeed.Short
|
|
||||||
readonly property string defaultFontFamily: "Inter Variable"
|
readonly property string defaultFontFamily: "Inter Variable"
|
||||||
readonly property string defaultMonoFontFamily: "Fira Code"
|
readonly property string defaultMonoFontFamily: "Fira Code"
|
||||||
readonly property string _homeUrl: StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
readonly property string _homeUrl: StandardPaths.writableLocation(StandardPaths.HomeLocation)
|
||||||
readonly property string _configUrl: StandardPaths.writableLocation(StandardPaths.ConfigLocation)
|
readonly property string _configUrl: StandardPaths.writableLocation(StandardPaths.ConfigLocation)
|
||||||
readonly property string _configDir: Paths.strip(_configUrl)
|
readonly property string _configDir: Paths.strip(_configUrl)
|
||||||
|
|
||||||
signal forceDankBarLayoutRefresh
|
signal forceTopBarLayoutRefresh
|
||||||
signal forceDockLayoutRefresh
|
|
||||||
signal widgetDataChanged
|
signal widgetDataChanged
|
||||||
signal workspaceIconsUpdated
|
signal workspaceIconsUpdated
|
||||||
|
|
||||||
property bool _loading: false
|
property bool _loading: false
|
||||||
|
|
||||||
property var pluginSettings: ({})
|
|
||||||
|
|
||||||
function getEffectiveTimeFormat() {
|
function getEffectiveTimeFormat() {
|
||||||
if (use24HourClock) {
|
if (use24HourClock) {
|
||||||
return Locale.ShortFormat
|
return Locale.ShortFormat
|
||||||
@@ -208,9 +179,9 @@ Singleton {
|
|||||||
centerWidgetsModel.append(dummyItem)
|
centerWidgetsModel.append(dummyItem)
|
||||||
rightWidgetsModel.append(dummyItem)
|
rightWidgetsModel.append(dummyItem)
|
||||||
|
|
||||||
updateListModel(leftWidgetsModel, dankBarLeftWidgets)
|
updateListModel(leftWidgetsModel, topBarLeftWidgets)
|
||||||
updateListModel(centerWidgetsModel, dankBarCenterWidgets)
|
updateListModel(centerWidgetsModel, topBarCenterWidgets)
|
||||||
updateListModel(rightWidgetsModel, dankBarRightWidgets)
|
updateListModel(rightWidgetsModel, topBarRightWidgets)
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadSettings() {
|
function loadSettings() {
|
||||||
@@ -238,9 +209,9 @@ Singleton {
|
|||||||
}
|
}
|
||||||
customThemeFile = settings.customThemeFile !== undefined ? settings.customThemeFile : ""
|
customThemeFile = settings.customThemeFile !== undefined ? settings.customThemeFile : ""
|
||||||
matugenScheme = settings.matugenScheme !== undefined ? settings.matugenScheme : "scheme-tonal-spot"
|
matugenScheme = settings.matugenScheme !== undefined ? settings.matugenScheme : "scheme-tonal-spot"
|
||||||
dankBarTransparency = settings.dankBarTransparency !== undefined ? (settings.dankBarTransparency > 1 ? settings.dankBarTransparency / 100 : settings.dankBarTransparency) : (settings.topBarTransparency !== undefined ? (settings.topBarTransparency > 1 ? settings.topBarTransparency / 100 : settings.topBarTransparency) : 1.0)
|
topBarTransparency = settings.topBarTransparency !== undefined ? (settings.topBarTransparency > 1 ? settings.topBarTransparency / 100 : settings.topBarTransparency) : 0.75
|
||||||
dankBarWidgetTransparency = settings.dankBarWidgetTransparency !== undefined ? (settings.dankBarWidgetTransparency > 1 ? settings.dankBarWidgetTransparency / 100 : settings.dankBarWidgetTransparency) : (settings.topBarWidgetTransparency !== undefined ? (settings.topBarWidgetTransparency > 1 ? settings.topBarWidgetTransparency / 100 : settings.topBarWidgetTransparency) : 1.0)
|
topBarWidgetTransparency = settings.topBarWidgetTransparency !== undefined ? (settings.topBarWidgetTransparency > 1 ? settings.topBarWidgetTransparency / 100 : settings.topBarWidgetTransparency) : 0.85
|
||||||
popupTransparency = settings.popupTransparency !== undefined ? (settings.popupTransparency > 1 ? settings.popupTransparency / 100 : settings.popupTransparency) : 1.0
|
popupTransparency = settings.popupTransparency !== undefined ? (settings.popupTransparency > 1 ? settings.popupTransparency / 100 : settings.popupTransparency) : 0.92
|
||||||
dockTransparency = settings.dockTransparency !== undefined ? (settings.dockTransparency > 1 ? settings.dockTransparency / 100 : settings.dockTransparency) : 1
|
dockTransparency = settings.dockTransparency !== undefined ? (settings.dockTransparency > 1 ? settings.dockTransparency / 100 : settings.dockTransparency) : 1
|
||||||
use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true
|
use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true
|
||||||
useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false
|
useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false
|
||||||
@@ -293,24 +264,23 @@ Singleton {
|
|||||||
clockDateFormat = settings.clockDateFormat !== undefined ? settings.clockDateFormat : ""
|
clockDateFormat = settings.clockDateFormat !== undefined ? settings.clockDateFormat : ""
|
||||||
lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : ""
|
lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : ""
|
||||||
mediaSize = settings.mediaSize !== undefined ? settings.mediaSize : (settings.mediaCompactMode !== undefined ? (settings.mediaCompactMode ? 0 : 1) : 1)
|
mediaSize = settings.mediaSize !== undefined ? settings.mediaSize : (settings.mediaCompactMode !== undefined ? (settings.mediaCompactMode ? 0 : 1) : 1)
|
||||||
if (settings.dankBarWidgetOrder || settings.topBarWidgetOrder) {
|
if (settings.topBarWidgetOrder) {
|
||||||
var widgetOrder = settings.dankBarWidgetOrder || settings.topBarWidgetOrder
|
topBarLeftWidgets = settings.topBarWidgetOrder.filter(w => {
|
||||||
dankBarLeftWidgets = widgetOrder.filter(w => {
|
|
||||||
return ["launcherButton", "workspaceSwitcher", "focusedWindow"].includes(w)
|
return ["launcherButton", "workspaceSwitcher", "focusedWindow"].includes(w)
|
||||||
})
|
})
|
||||||
dankBarCenterWidgets = widgetOrder.filter(w => {
|
topBarCenterWidgets = settings.topBarWidgetOrder.filter(w => {
|
||||||
return ["clock", "music", "weather"].includes(w)
|
return ["clock", "music", "weather"].includes(w)
|
||||||
})
|
})
|
||||||
dankBarRightWidgets = widgetOrder.filter(w => {
|
topBarRightWidgets = settings.topBarWidgetOrder.filter(w => {
|
||||||
return ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"].includes(w)
|
return ["systemTray", "clipboard", "systemResources", "notificationButton", "battery", "controlCenterButton"].includes(w)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
var leftWidgets = settings.dankBarLeftWidgets !== undefined ? settings.dankBarLeftWidgets : (settings.topBarLeftWidgets !== undefined ? settings.topBarLeftWidgets : ["launcherButton", "workspaceSwitcher", "focusedWindow"])
|
var leftWidgets = settings.topBarLeftWidgets !== undefined ? settings.topBarLeftWidgets : ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
||||||
var centerWidgets = settings.dankBarCenterWidgets !== undefined ? settings.dankBarCenterWidgets : (settings.topBarCenterWidgets !== undefined ? settings.topBarCenterWidgets : ["music", "clock", "weather"])
|
var centerWidgets = settings.topBarCenterWidgets !== undefined ? settings.topBarCenterWidgets : ["music", "clock", "weather"]
|
||||||
var rightWidgets = settings.dankBarRightWidgets !== undefined ? settings.dankBarRightWidgets : (settings.topBarRightWidgets !== undefined ? settings.topBarRightWidgets : ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"])
|
var rightWidgets = settings.topBarRightWidgets !== undefined ? settings.topBarRightWidgets : ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"]
|
||||||
dankBarLeftWidgets = leftWidgets
|
topBarLeftWidgets = leftWidgets
|
||||||
dankBarCenterWidgets = centerWidgets
|
topBarCenterWidgets = centerWidgets
|
||||||
dankBarRightWidgets = rightWidgets
|
topBarRightWidgets = rightWidgets
|
||||||
updateListModel(leftWidgetsModel, leftWidgets)
|
updateListModel(leftWidgetsModel, leftWidgets)
|
||||||
updateListModel(centerWidgetsModel, centerWidgets)
|
updateListModel(centerWidgetsModel, centerWidgets)
|
||||||
updateListModel(rightWidgetsModel, rightWidgets)
|
updateListModel(rightWidgetsModel, rightWidgets)
|
||||||
@@ -338,33 +308,25 @@ Singleton {
|
|||||||
showDock = settings.showDock !== undefined ? settings.showDock : false
|
showDock = settings.showDock !== undefined ? settings.showDock : false
|
||||||
dockAutoHide = settings.dockAutoHide !== undefined ? settings.dockAutoHide : false
|
dockAutoHide = settings.dockAutoHide !== undefined ? settings.dockAutoHide : false
|
||||||
dockGroupByApp = settings.dockGroupByApp !== undefined ? settings.dockGroupByApp : false
|
dockGroupByApp = settings.dockGroupByApp !== undefined ? settings.dockGroupByApp : false
|
||||||
dockPosition = settings.dockPosition !== undefined ? settings.dockPosition : SettingsData.Position.Bottom
|
|
||||||
dockSpacing = settings.dockSpacing !== undefined ? settings.dockSpacing : 4
|
|
||||||
dockBottomGap = settings.dockBottomGap !== undefined ? settings.dockBottomGap : 0
|
|
||||||
cornerRadius = settings.cornerRadius !== undefined ? settings.cornerRadius : 12
|
cornerRadius = settings.cornerRadius !== undefined ? settings.cornerRadius : 12
|
||||||
notificationOverlayEnabled = settings.notificationOverlayEnabled !== undefined ? settings.notificationOverlayEnabled : false
|
notificationOverlayEnabled = settings.notificationOverlayEnabled !== undefined ? settings.notificationOverlayEnabled : false
|
||||||
dankBarAutoHide = settings.dankBarAutoHide !== undefined ? settings.dankBarAutoHide : (settings.topBarAutoHide !== undefined ? settings.topBarAutoHide : false)
|
topBarAutoHide = settings.topBarAutoHide !== undefined ? settings.topBarAutoHide : false
|
||||||
dankBarOpenOnOverview = settings.dankBarOpenOnOverview !== undefined ? settings.dankBarOpenOnOverview : (settings.topBarOpenOnOverview !== undefined ? settings.topBarOpenOnOverview : false)
|
topBarOpenOnOverview = settings.topBarOpenOnOverview !== undefined ? settings.topBarOpenOnOverview : false
|
||||||
dankBarVisible = settings.dankBarVisible !== undefined ? settings.dankBarVisible : (settings.topBarVisible !== undefined ? settings.topBarVisible : true)
|
topBarVisible = settings.topBarVisible !== undefined ? settings.topBarVisible : true
|
||||||
dockOpenOnOverview = settings.dockOpenOnOverview !== undefined ? settings.dockOpenOnOverview : false
|
|
||||||
notificationTimeoutLow = settings.notificationTimeoutLow !== undefined ? settings.notificationTimeoutLow : 5000
|
notificationTimeoutLow = settings.notificationTimeoutLow !== undefined ? settings.notificationTimeoutLow : 5000
|
||||||
notificationTimeoutNormal = settings.notificationTimeoutNormal !== undefined ? settings.notificationTimeoutNormal : 5000
|
notificationTimeoutNormal = settings.notificationTimeoutNormal !== undefined ? settings.notificationTimeoutNormal : 5000
|
||||||
notificationTimeoutCritical = settings.notificationTimeoutCritical !== undefined ? settings.notificationTimeoutCritical : 0
|
notificationTimeoutCritical = settings.notificationTimeoutCritical !== undefined ? settings.notificationTimeoutCritical : 0
|
||||||
notificationPopupPosition = settings.notificationPopupPosition !== undefined ? settings.notificationPopupPosition : SettingsData.Position.Top
|
topBarSpacing = settings.topBarSpacing !== undefined ? settings.topBarSpacing : 4
|
||||||
dankBarSpacing = settings.dankBarSpacing !== undefined ? settings.dankBarSpacing : (settings.topBarSpacing !== undefined ? settings.topBarSpacing : 4)
|
topBarBottomGap = settings.topBarBottomGap !== undefined ? settings.topBarBottomGap : 0
|
||||||
dankBarBottomGap = settings.dankBarBottomGap !== undefined ? settings.dankBarBottomGap : (settings.topBarBottomGap !== undefined ? settings.topBarBottomGap : 0)
|
topBarInnerPadding = settings.topBarInnerPadding !== undefined ? settings.topBarInnerPadding : 8
|
||||||
dankBarInnerPadding = settings.dankBarInnerPadding !== undefined ? settings.dankBarInnerPadding : (settings.topBarInnerPadding !== undefined ? settings.topBarInnerPadding : 4)
|
topBarSquareCorners = settings.topBarSquareCorners !== undefined ? settings.topBarSquareCorners : false
|
||||||
dankBarSquareCorners = settings.dankBarSquareCorners !== undefined ? settings.dankBarSquareCorners : (settings.topBarSquareCorners !== undefined ? settings.topBarSquareCorners : false)
|
topBarNoBackground = settings.topBarNoBackground !== undefined ? settings.topBarNoBackground : false
|
||||||
dankBarNoBackground = settings.dankBarNoBackground !== undefined ? settings.dankBarNoBackground : (settings.topBarNoBackground !== undefined ? settings.topBarNoBackground : false)
|
topBarGothCornersEnabled = settings.topBarGothCornersEnabled !== undefined ? settings.topBarGothCornersEnabled : false
|
||||||
dankBarGothCornersEnabled = settings.dankBarGothCornersEnabled !== undefined ? settings.dankBarGothCornersEnabled : (settings.topBarGothCornersEnabled !== undefined ? settings.topBarGothCornersEnabled : false)
|
|
||||||
dankBarPosition = settings.dankBarPosition !== undefined ? settings.dankBarPosition : (settings.dankBarAtBottom !== undefined ? (settings.dankBarAtBottom ? SettingsData.Position.Bottom : SettingsData.Position.Top) : (settings.topBarAtBottom !== undefined ? (settings.topBarAtBottom ? SettingsData.Position.Bottom : SettingsData.Position.Top) : SettingsData.Position.Top))
|
|
||||||
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true
|
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true
|
||||||
hideBrightnessSlider = settings.hideBrightnessSlider !== undefined ? settings.hideBrightnessSlider : false
|
hideBrightnessSlider = settings.hideBrightnessSlider !== undefined ? settings.hideBrightnessSlider : false
|
||||||
widgetBackgroundColor = settings.widgetBackgroundColor !== undefined ? settings.widgetBackgroundColor : "sch"
|
widgetBackgroundColor = settings.widgetBackgroundColor !== undefined ? settings.widgetBackgroundColor : "sch"
|
||||||
surfaceBase = settings.surfaceBase !== undefined ? settings.surfaceBase : "s"
|
surfaceBase = settings.surfaceBase !== undefined ? settings.surfaceBase : "sc"
|
||||||
screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({})
|
screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({})
|
||||||
pluginSettings = settings.pluginSettings !== undefined ? settings.pluginSettings : ({})
|
|
||||||
animationSpeed = settings.animationSpeed !== undefined ? settings.animationSpeed : SettingsData.AnimationSpeed.Short
|
|
||||||
applyStoredTheme()
|
applyStoredTheme()
|
||||||
detectAvailableIconThemes()
|
detectAvailableIconThemes()
|
||||||
detectQtTools()
|
detectQtTools()
|
||||||
@@ -387,8 +349,8 @@ Singleton {
|
|||||||
"currentThemeName": currentThemeName,
|
"currentThemeName": currentThemeName,
|
||||||
"customThemeFile": customThemeFile,
|
"customThemeFile": customThemeFile,
|
||||||
"matugenScheme": matugenScheme,
|
"matugenScheme": matugenScheme,
|
||||||
"dankBarTransparency": dankBarTransparency,
|
"topBarTransparency": topBarTransparency,
|
||||||
"dankBarWidgetTransparency": dankBarWidgetTransparency,
|
"topBarWidgetTransparency": topBarWidgetTransparency,
|
||||||
"popupTransparency": popupTransparency,
|
"popupTransparency": popupTransparency,
|
||||||
"dockTransparency": dockTransparency,
|
"dockTransparency": dockTransparency,
|
||||||
"use24HourClock": use24HourClock,
|
"use24HourClock": use24HourClock,
|
||||||
@@ -433,9 +395,9 @@ Singleton {
|
|||||||
"clockDateFormat": clockDateFormat,
|
"clockDateFormat": clockDateFormat,
|
||||||
"lockDateFormat": lockDateFormat,
|
"lockDateFormat": lockDateFormat,
|
||||||
"mediaSize": mediaSize,
|
"mediaSize": mediaSize,
|
||||||
"dankBarLeftWidgets": dankBarLeftWidgets,
|
"topBarLeftWidgets": topBarLeftWidgets,
|
||||||
"dankBarCenterWidgets": dankBarCenterWidgets,
|
"topBarCenterWidgets": topBarCenterWidgets,
|
||||||
"dankBarRightWidgets": dankBarRightWidgets,
|
"topBarRightWidgets": topBarRightWidgets,
|
||||||
"appLauncherViewMode": appLauncherViewMode,
|
"appLauncherViewMode": appLauncherViewMode,
|
||||||
"spotlightModalViewMode": spotlightModalViewMode,
|
"spotlightModalViewMode": spotlightModalViewMode,
|
||||||
"networkPreference": networkPreference,
|
"networkPreference": networkPreference,
|
||||||
@@ -459,22 +421,17 @@ Singleton {
|
|||||||
"showDock": showDock,
|
"showDock": showDock,
|
||||||
"dockAutoHide": dockAutoHide,
|
"dockAutoHide": dockAutoHide,
|
||||||
"dockGroupByApp": dockGroupByApp,
|
"dockGroupByApp": dockGroupByApp,
|
||||||
"dockOpenOnOverview": dockOpenOnOverview,
|
|
||||||
"dockPosition": dockPosition,
|
|
||||||
"dockSpacing": dockSpacing,
|
|
||||||
"dockBottomGap": dockBottomGap,
|
|
||||||
"cornerRadius": cornerRadius,
|
"cornerRadius": cornerRadius,
|
||||||
"notificationOverlayEnabled": notificationOverlayEnabled,
|
"notificationOverlayEnabled": notificationOverlayEnabled,
|
||||||
"dankBarAutoHide": dankBarAutoHide,
|
"topBarAutoHide": topBarAutoHide,
|
||||||
"dankBarOpenOnOverview": dankBarOpenOnOverview,
|
"topBarOpenOnOverview": topBarOpenOnOverview,
|
||||||
"dankBarVisible": dankBarVisible,
|
"topBarVisible": topBarVisible,
|
||||||
"dankBarSpacing": dankBarSpacing,
|
"topBarSpacing": topBarSpacing,
|
||||||
"dankBarBottomGap": dankBarBottomGap,
|
"topBarBottomGap": topBarBottomGap,
|
||||||
"dankBarInnerPadding": dankBarInnerPadding,
|
"topBarInnerPadding": topBarInnerPadding,
|
||||||
"dankBarSquareCorners": dankBarSquareCorners,
|
"topBarSquareCorners": topBarSquareCorners,
|
||||||
"dankBarNoBackground": dankBarNoBackground,
|
"topBarNoBackground": topBarNoBackground,
|
||||||
"dankBarGothCornersEnabled": dankBarGothCornersEnabled,
|
"topBarGothCornersEnabled": topBarGothCornersEnabled,
|
||||||
"dankBarPosition": dankBarPosition,
|
|
||||||
"lockScreenShowPowerActions": lockScreenShowPowerActions,
|
"lockScreenShowPowerActions": lockScreenShowPowerActions,
|
||||||
"hideBrightnessSlider": hideBrightnessSlider,
|
"hideBrightnessSlider": hideBrightnessSlider,
|
||||||
"widgetBackgroundColor": widgetBackgroundColor,
|
"widgetBackgroundColor": widgetBackgroundColor,
|
||||||
@@ -482,10 +439,7 @@ Singleton {
|
|||||||
"notificationTimeoutLow": notificationTimeoutLow,
|
"notificationTimeoutLow": notificationTimeoutLow,
|
||||||
"notificationTimeoutNormal": notificationTimeoutNormal,
|
"notificationTimeoutNormal": notificationTimeoutNormal,
|
||||||
"notificationTimeoutCritical": notificationTimeoutCritical,
|
"notificationTimeoutCritical": notificationTimeoutCritical,
|
||||||
"notificationPopupPosition": notificationPopupPosition,
|
"screenPreferences": screenPreferences
|
||||||
"screenPreferences": screenPreferences,
|
|
||||||
"pluginSettings": pluginSettings,
|
|
||||||
"animationSpeed": animationSpeed
|
|
||||||
}, null, 2))
|
}, null, 2))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,11 +555,11 @@ Singleton {
|
|||||||
|
|
||||||
function applyStoredTheme() {
|
function applyStoredTheme() {
|
||||||
if (typeof Theme !== "undefined")
|
if (typeof Theme !== "undefined")
|
||||||
Theme.switchTheme(currentThemeName, false, false)
|
Theme.switchTheme(currentThemeName, false)
|
||||||
else
|
else
|
||||||
Qt.callLater(() => {
|
Qt.callLater(() => {
|
||||||
if (typeof Theme !== "undefined")
|
if (typeof Theme !== "undefined")
|
||||||
Theme.switchTheme(currentThemeName, false, false)
|
Theme.switchTheme(currentThemeName, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -628,17 +582,20 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
|
|
||||||
if (typeof Theme !== "undefined") {
|
if (typeof Theme !== "undefined") {
|
||||||
|
if (Theme.currentTheme === Theme.dynamic) {
|
||||||
|
Theme.extractColors()
|
||||||
|
}
|
||||||
Theme.generateSystemThemesFromCurrentTheme()
|
Theme.generateSystemThemesFromCurrentTheme()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarTransparency(transparency) {
|
function setTopBarTransparency(transparency) {
|
||||||
dankBarTransparency = transparency
|
topBarTransparency = transparency
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarWidgetTransparency(transparency) {
|
function setTopBarWidgetTransparency(transparency) {
|
||||||
dankBarWidgetTransparency = transparency
|
topBarWidgetTransparency = transparency
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -773,25 +730,25 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarWidgetOrder(order) {
|
function setTopBarWidgetOrder(order) {
|
||||||
dankBarWidgetOrder = order
|
topBarWidgetOrder = order
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarLeftWidgets(order) {
|
function setTopBarLeftWidgets(order) {
|
||||||
dankBarLeftWidgets = order
|
topBarLeftWidgets = order
|
||||||
updateListModel(leftWidgetsModel, order)
|
updateListModel(leftWidgetsModel, order)
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarCenterWidgets(order) {
|
function setTopBarCenterWidgets(order) {
|
||||||
dankBarCenterWidgets = order
|
topBarCenterWidgets = order
|
||||||
updateListModel(centerWidgetsModel, order)
|
updateListModel(centerWidgetsModel, order)
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarRightWidgets(order) {
|
function setTopBarRightWidgets(order) {
|
||||||
dankBarRightWidgets = order
|
topBarRightWidgets = order
|
||||||
updateListModel(rightWidgetsModel, order)
|
updateListModel(rightWidgetsModel, order)
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
@@ -824,13 +781,13 @@ Singleton {
|
|||||||
widgetDataChanged()
|
widgetDataChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
function resetDankBarWidgetsToDefault() {
|
function resetTopBarWidgetsToDefault() {
|
||||||
var defaultLeft = ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
var defaultLeft = ["launcherButton", "workspaceSwitcher", "focusedWindow"]
|
||||||
var defaultCenter = ["music", "clock", "weather"]
|
var defaultCenter = ["music", "clock", "weather"]
|
||||||
var defaultRight = ["systemTray", "clipboard", "notificationButton", "battery", "controlCenterButton"]
|
var defaultRight = ["systemTray", "clipboard", "notificationButton", "battery", "controlCenterButton"]
|
||||||
dankBarLeftWidgets = defaultLeft
|
topBarLeftWidgets = defaultLeft
|
||||||
dankBarCenterWidgets = defaultCenter
|
topBarCenterWidgets = defaultCenter
|
||||||
dankBarRightWidgets = defaultRight
|
topBarRightWidgets = defaultRight
|
||||||
updateListModel(leftWidgetsModel, defaultLeft)
|
updateListModel(leftWidgetsModel, defaultLeft)
|
||||||
updateListModel(centerWidgetsModel, defaultCenter)
|
updateListModel(centerWidgetsModel, defaultCenter)
|
||||||
updateListModel(rightWidgetsModel, defaultRight)
|
updateListModel(rightWidgetsModel, defaultRight)
|
||||||
@@ -997,24 +954,6 @@ Singleton {
|
|||||||
|
|
||||||
function setShowDock(enabled) {
|
function setShowDock(enabled) {
|
||||||
showDock = enabled
|
showDock = enabled
|
||||||
if (enabled && dockPosition === dankBarPosition) {
|
|
||||||
if (dankBarPosition === SettingsData.Position.Top) {
|
|
||||||
setDockPosition(SettingsData.Position.Bottom)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (dankBarPosition === SettingsData.Position.Bottom) {
|
|
||||||
setDockPosition(SettingsData.Position.Top)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (dankBarPosition === SettingsData.Position.Left) {
|
|
||||||
setDockPosition(SettingsData.Position.Right)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (dankBarPosition === SettingsData.Position.Right) {
|
|
||||||
setDockPosition(SettingsData.Position.Left)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1028,11 +967,6 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setdockOpenOnOverview(enabled) {
|
|
||||||
dockOpenOnOverview = enabled
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
|
|
||||||
function setCornerRadius(radius) {
|
function setCornerRadius(radius) {
|
||||||
cornerRadius = radius
|
cornerRadius = radius
|
||||||
saveSettings()
|
saveSettings()
|
||||||
@@ -1043,23 +977,23 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarAutoHide(enabled) {
|
function setTopBarAutoHide(enabled) {
|
||||||
dankBarAutoHide = enabled
|
topBarAutoHide = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarOpenOnOverview(enabled) {
|
function setTopBarOpenOnOverview(enabled) {
|
||||||
dankBarOpenOnOverview = enabled
|
topBarOpenOnOverview = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarVisible(visible) {
|
function setTopBarVisible(visible) {
|
||||||
dankBarVisible = visible
|
topBarVisible = visible
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleDankBarVisible() {
|
function toggleTopBarVisible() {
|
||||||
dankBarVisible = !dankBarVisible
|
topBarVisible = !topBarVisible
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,162 +1012,36 @@ Singleton {
|
|||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setNotificationPopupPosition(position) {
|
function setTopBarSpacing(spacing) {
|
||||||
notificationPopupPosition = position
|
topBarSpacing = spacing
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendTestNotifications() {
|
function setTopBarBottomGap(gap) {
|
||||||
sendTestNotification(0)
|
topBarBottomGap = gap
|
||||||
testNotifTimer1.start()
|
|
||||||
testNotifTimer2.start()
|
|
||||||
}
|
|
||||||
|
|
||||||
function sendTestNotification(index) {
|
|
||||||
const notifications = [
|
|
||||||
["Notification Position Test", "DMS test notification 1 of 3 ~ Hi there!", "dialog-information"],
|
|
||||||
["Second Test", "DMS Notification 2 of 3 ~ Check it out!", "emblem-default"],
|
|
||||||
["Third Test", "DMS notification 3 of 3 ~ Enjoy!", "emblem-favorite"]
|
|
||||||
]
|
|
||||||
|
|
||||||
if (index < 0 || index >= notifications.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const notif = notifications[index]
|
|
||||||
testNotificationProcess.command = ["notify-send", "-h", "int:transient:1", "-a", "DMS", "-i", notif[2], notif[0], notif[1]]
|
|
||||||
testNotificationProcess.running = true
|
|
||||||
}
|
|
||||||
|
|
||||||
property Process testNotificationProcess
|
|
||||||
|
|
||||||
testNotificationProcess: Process {
|
|
||||||
command: []
|
|
||||||
running: false
|
|
||||||
}
|
|
||||||
|
|
||||||
property Timer testNotifTimer1
|
|
||||||
|
|
||||||
testNotifTimer1: Timer {
|
|
||||||
interval: 400
|
|
||||||
repeat: false
|
|
||||||
onTriggered: sendTestNotification(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
property Timer testNotifTimer2
|
|
||||||
|
|
||||||
testNotifTimer2: Timer {
|
|
||||||
interval: 800
|
|
||||||
repeat: false
|
|
||||||
onTriggered: sendTestNotification(2)
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDankBarSpacing(spacing) {
|
|
||||||
dankBarSpacing = spacing
|
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarBottomGap(gap) {
|
function setTopBarInnerPadding(padding) {
|
||||||
dankBarBottomGap = gap
|
topBarInnerPadding = padding
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarInnerPadding(padding) {
|
function setTopBarSquareCorners(enabled) {
|
||||||
dankBarInnerPadding = padding
|
topBarSquareCorners = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarSquareCorners(enabled) {
|
function setTopBarNoBackground(enabled) {
|
||||||
dankBarSquareCorners = enabled
|
topBarNoBackground = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarNoBackground(enabled) {
|
function setTopBarGothCornersEnabled(enabled) {
|
||||||
dankBarNoBackground = enabled
|
topBarGothCornersEnabled = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setDankBarGothCornersEnabled(enabled) {
|
|
||||||
dankBarGothCornersEnabled = enabled
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDankBarPosition(position) {
|
|
||||||
dankBarPosition = position
|
|
||||||
if (position === SettingsData.Position.Bottom && dockPosition === SettingsData.Position.Bottom && showDock) {
|
|
||||||
setDockPosition(SettingsData.Position.Top)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (position === SettingsData.Position.Top && dockPosition === SettingsData.Position.Top && showDock) {
|
|
||||||
setDockPosition(SettingsData.Position.Bottom)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (position === SettingsData.Position.Left && dockPosition === SettingsData.Position.Left && showDock) {
|
|
||||||
setDockPosition(SettingsData.Position.Right)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (position === SettingsData.Position.Right && dockPosition === SettingsData.Position.Right && showDock) {
|
|
||||||
setDockPosition(SettingsData.Position.Left)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
|
|
||||||
function setDockPosition(position) {
|
|
||||||
dockPosition = position
|
|
||||||
if (position === SettingsData.Position.Bottom && dankBarPosition === SettingsData.Position.Bottom && showDock) {
|
|
||||||
setDankBarPosition(SettingsData.Position.Top)
|
|
||||||
}
|
|
||||||
if (position === SettingsData.Position.Top && dankBarPosition === SettingsData.Position.Top && showDock) {
|
|
||||||
setDankBarPosition(SettingsData.Position.Bottom)
|
|
||||||
}
|
|
||||||
if (position === SettingsData.Position.Left && dankBarPosition === SettingsData.Position.Left && showDock) {
|
|
||||||
setDankBarPosition(SettingsData.Position.Right)
|
|
||||||
}
|
|
||||||
if (position === SettingsData.Position.Right && dankBarPosition === SettingsData.Position.Right && showDock) {
|
|
||||||
setDankBarPosition(SettingsData.Position.Left)
|
|
||||||
}
|
|
||||||
saveSettings()
|
|
||||||
Qt.callLater(() => forceDockLayoutRefresh())
|
|
||||||
}
|
|
||||||
function setDockSpacing(spacing) {
|
|
||||||
dockSpacing = spacing
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
function setDockBottomGap(gap) {
|
|
||||||
dockBottomGap = gap
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
function setDockOpenOnOverview(enabled) {
|
|
||||||
dockOpenOnOverview = enabled
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPopupYPosition(barHeight) {
|
|
||||||
const gothOffset = dankBarGothCornersEnabled ? Theme.cornerRadius : 0
|
|
||||||
return barHeight + dankBarSpacing + dankBarBottomGap - gothOffset + Theme.popupDistance
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPopupTriggerPosition(globalPos, screen, barThickness, widgetWidth) {
|
|
||||||
const screenX = screen ? screen.x : 0
|
|
||||||
const screenY = screen ? screen.y : 0
|
|
||||||
const relativeX = globalPos.x - screenX
|
|
||||||
const relativeY = globalPos.y - screenY
|
|
||||||
|
|
||||||
if (dankBarPosition === SettingsData.Position.Left || dankBarPosition === SettingsData.Position.Right) {
|
|
||||||
return {
|
|
||||||
x: relativeY,
|
|
||||||
y: barThickness + dankBarSpacing + Theme.popupDistance,
|
|
||||||
width: widgetWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
x: relativeX,
|
|
||||||
y: barThickness + dankBarSpacing + dankBarBottomGap + Theme.popupDistance,
|
|
||||||
width: widgetWidth
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLockScreenShowPowerActions(enabled) {
|
function setLockScreenShowPowerActions(enabled) {
|
||||||
lockScreenShowPowerActions = enabled
|
lockScreenShowPowerActions = enabled
|
||||||
saveSettings()
|
saveSettings()
|
||||||
@@ -1270,48 +1078,14 @@ Singleton {
|
|||||||
return Quickshell.screens.filter(screen => prefs.includes(screen.name))
|
return Quickshell.screens.filter(screen => prefs.includes(screen.name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin settings functions
|
|
||||||
function getPluginSetting(pluginId, key, defaultValue) {
|
|
||||||
if (!pluginSettings[pluginId]) {
|
|
||||||
return defaultValue
|
|
||||||
}
|
|
||||||
return pluginSettings[pluginId][key] !== undefined ? pluginSettings[pluginId][key] : defaultValue
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPluginSetting(pluginId, key, value) {
|
|
||||||
if (!pluginSettings[pluginId]) {
|
|
||||||
pluginSettings[pluginId] = {}
|
|
||||||
}
|
|
||||||
pluginSettings[pluginId][key] = value
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
|
|
||||||
function removePluginSettings(pluginId) {
|
|
||||||
if (pluginSettings[pluginId]) {
|
|
||||||
delete pluginSettings[pluginId]
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPluginSettingsForPlugin(pluginId) {
|
|
||||||
return pluginSettings[pluginId] || {}
|
|
||||||
}
|
|
||||||
|
|
||||||
function setAnimationSpeed(speed) {
|
|
||||||
animationSpeed = speed
|
|
||||||
saveSettings()
|
|
||||||
}
|
|
||||||
|
|
||||||
function _shq(s) {
|
function _shq(s) {
|
||||||
return "'" + String(s).replace(/'/g, "'\\''") + "'"
|
return "'" + String(s).replace(/'/g, "'\\''") + "'"
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (!isGreeterMode) {
|
loadSettings()
|
||||||
loadSettings()
|
fontCheckTimer.start()
|
||||||
fontCheckTimer.start()
|
initializeListModels()
|
||||||
initializeListModels()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ListModel {
|
ListModel {
|
||||||
@@ -1352,22 +1126,20 @@ Singleton {
|
|||||||
FileView {
|
FileView {
|
||||||
id: settingsFile
|
id: settingsFile
|
||||||
|
|
||||||
path: isGreeterMode ? "" : StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json"
|
path: StandardPaths.writableLocation(StandardPaths.ConfigLocation) + "/DankMaterialShell/settings.json"
|
||||||
blockLoading: true
|
blockLoading: true
|
||||||
blockWrites: true
|
blockWrites: true
|
||||||
atomicWrites: true
|
atomicWrites: true
|
||||||
watchChanges: !isGreeterMode
|
watchChanges: true
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
if (!isGreeterMode) {
|
parseSettings(settingsFile.text())
|
||||||
parseSettings(settingsFile.text())
|
hasTriedDefaultSettings = false
|
||||||
hasTriedDefaultSettings = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onLoadFailed: error => {
|
onLoadFailed: error => {
|
||||||
if (!isGreeterMode && !hasTriedDefaultSettings) {
|
if (!hasTriedDefaultSettings) {
|
||||||
hasTriedDefaultSettings = true
|
hasTriedDefaultSettings = true
|
||||||
defaultSettingsCheckProcess.running = true
|
defaultSettingsCheckProcess.running = true
|
||||||
} else if (!isGreeterMode) {
|
} else {
|
||||||
applyStoredTheme()
|
applyStoredTheme()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1452,22 +1224,22 @@ Singleton {
|
|||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
function reveal(): string {
|
function reveal(): string {
|
||||||
root.setDankBarVisible(true)
|
root.setTopBarVisible(true)
|
||||||
return "BAR_SHOW_SUCCESS"
|
return "BAR_SHOW_SUCCESS"
|
||||||
}
|
}
|
||||||
|
|
||||||
function hide(): string {
|
function hide(): string {
|
||||||
root.setDankBarVisible(false)
|
root.setTopBarVisible(false)
|
||||||
return "BAR_HIDE_SUCCESS"
|
return "BAR_HIDE_SUCCESS"
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle(): string {
|
function toggle(): string {
|
||||||
root.toggleDankBarVisible()
|
root.toggleTopBarVisible()
|
||||||
return root.dankBarVisible ? "BAR_SHOW_SUCCESS" : "BAR_HIDE_SUCCESS"
|
return topBarVisible ? "BAR_SHOW_SUCCESS" : "BAR_HIDE_SUCCESS"
|
||||||
}
|
}
|
||||||
|
|
||||||
function status(): string {
|
function status(): string {
|
||||||
return root.dankBarVisible ? "visible" : "hidden"
|
return topBarVisible ? "visible" : "hidden"
|
||||||
}
|
}
|
||||||
|
|
||||||
target: "bar"
|
target: "bar"
|
||||||
|
|||||||
@@ -2,101 +2,101 @@
|
|||||||
// Separated from Theme.qml to keep that file clean
|
// Separated from Theme.qml to keep that file clean
|
||||||
|
|
||||||
const CatppuccinMocha = {
|
const CatppuccinMocha = {
|
||||||
surface: "#313244",
|
surface: "#45475a",
|
||||||
surfaceText: "#cdd6f4",
|
surfaceText: "#cdd6f4",
|
||||||
surfaceVariant: "#313244",
|
surfaceVariant: "#45475a",
|
||||||
surfaceVariantText: "#a6adc8",
|
surfaceVariantText: "#a6adc8",
|
||||||
background: "#1e1e2e",
|
background: "#1e1e2e",
|
||||||
backgroundText: "#cdd6f4",
|
backgroundText: "#cdd6f4",
|
||||||
outline: "#6c7086",
|
outline: "#6c7086",
|
||||||
surfaceContainer: "#45475a",
|
surfaceContainer: "#313244",
|
||||||
surfaceContainerHigh: "#585b70",
|
surfaceContainerHigh: "#585b70",
|
||||||
surfaceContainerHighest: "#6c7086"
|
surfaceContainerHighest: "#7f849c"
|
||||||
}
|
}
|
||||||
|
|
||||||
const CatppuccinLatte = {
|
const CatppuccinLatte = {
|
||||||
surface: "#e6e9ef",
|
surface: "#bcc0cc",
|
||||||
surfaceText: "#4c4f69",
|
surfaceText: "#4c4f69",
|
||||||
surfaceVariant: "#e6e9ef",
|
surfaceVariant: "#bcc0cc",
|
||||||
surfaceVariantText: "#6c6f85",
|
surfaceVariantText: "#6c6f85",
|
||||||
background: "#eff1f5",
|
background: "#eff1f5",
|
||||||
backgroundText: "#4c4f69",
|
backgroundText: "#4c4f69",
|
||||||
outline: "#9ca0b0",
|
outline: "#9ca0b0",
|
||||||
surfaceContainer: "#dce0e8",
|
surfaceContainer: "#ccd0da",
|
||||||
surfaceContainerHigh: "#ccd0da",
|
surfaceContainerHigh: "#acb0be",
|
||||||
surfaceContainerHighest: "#bcc0cc"
|
surfaceContainerHighest: "#8c8fa1"
|
||||||
}
|
}
|
||||||
|
|
||||||
const CatppuccinVariants = {
|
const CatppuccinVariants = {
|
||||||
"cat-rosewater": {
|
"cat-rosewater": {
|
||||||
name: "Rosewater",
|
name: "Rosewater",
|
||||||
dark: { primary: "#f5e0dc", secondary: "#f2cdcd", primaryText: "#1e1e2e", primaryContainer: "#7d5d56", surfaceTint: "#f5e0dc" },
|
dark: { primary: "#f5e0dc", secondary: "#f2cdcd", primaryText: "#1e1e2e", primaryContainer: "#8b6b5e", surfaceTint: "#f5e0dc" },
|
||||||
light: { primary: "#dc8a78", secondary: "#dd7878", primaryText: "#ffffff", primaryContainer: "#f6e7e3", surfaceTint: "#dc8a78" }
|
light: { primary: "#dc8a78", secondary: "#dd7878", primaryText: "#ffffff", primaryContainer: "#f4d2ca", surfaceTint: "#dc8a78" }
|
||||||
},
|
},
|
||||||
"cat-flamingo": {
|
"cat-flamingo": {
|
||||||
name: "Flamingo",
|
name: "Flamingo",
|
||||||
dark: { primary: "#f2cdcd", secondary: "#f5e0dc", primaryText: "#1e1e2e", primaryContainer: "#7a555a", surfaceTint: "#f2cdcd" },
|
dark: { primary: "#f2cdcd", secondary: "#f5e0dc", primaryText: "#1e1e2e", primaryContainer: "#885d62", surfaceTint: "#f2cdcd" },
|
||||||
light: { primary: "#dd7878", secondary: "#dc8a78", primaryText: "#ffffff", primaryContainer: "#f6e5e5", surfaceTint: "#dd7878" }
|
light: { primary: "#dd7878", secondary: "#dc8a78", primaryText: "#ffffff", primaryContainer: "#f4caca", surfaceTint: "#dd7878" }
|
||||||
},
|
},
|
||||||
"cat-pink": {
|
"cat-pink": {
|
||||||
name: "Pink",
|
name: "Pink",
|
||||||
dark: { primary: "#f5c2e7", secondary: "#cba6f7", primaryText: "#1e1e2e", primaryContainer: "#7a3f69", surfaceTint: "#f5c2e7" },
|
dark: { primary: "#f5c2e7", secondary: "#cba6f7", primaryText: "#1e1e2e", primaryContainer: "#8b537a", surfaceTint: "#f5c2e7" },
|
||||||
light: { primary: "#ea76cb", secondary: "#8839ef", primaryText: "#ffffff", primaryContainer: "#f7d7ee", surfaceTint: "#ea76cb" }
|
light: { primary: "#ea76cb", secondary: "#8839ef", primaryText: "#ffffff", primaryContainer: "#f7c9e7", surfaceTint: "#ea76cb" }
|
||||||
},
|
},
|
||||||
"cat-mauve": {
|
"cat-mauve": {
|
||||||
name: "Mauve",
|
name: "Mauve",
|
||||||
dark: { primary: "#cba6f7", secondary: "#b4befe", primaryText: "#1e1e2e", primaryContainer: "#55307f", surfaceTint: "#cba6f7" },
|
dark: { primary: "#cba6f7", secondary: "#b4befe", primaryText: "#1e1e2e", primaryContainer: "#61378a", surfaceTint: "#cba6f7" },
|
||||||
light: { primary: "#8839ef", secondary: "#7287fd", primaryText: "#ffffff", primaryContainer: "#eadcff", surfaceTint: "#8839ef" }
|
light: { primary: "#8839ef", secondary: "#7287fd", primaryText: "#ffffff", primaryContainer: "#e4d3ff", surfaceTint: "#8839ef" }
|
||||||
},
|
},
|
||||||
"cat-red": {
|
"cat-red": {
|
||||||
name: "Red",
|
name: "Red",
|
||||||
dark: { primary: "#f38ba8", secondary: "#eba0ac", primaryText: "#1e1e2e", primaryContainer: "#6f2438", surfaceTint: "#f38ba8" },
|
dark: { primary: "#f38ba8", secondary: "#eba0ac", primaryText: "#1e1e2e", primaryContainer: "#891c3b", surfaceTint: "#f38ba8" },
|
||||||
light: { primary: "#d20f39", secondary: "#e64553", primaryText: "#ffffff", primaryContainer: "#f6d0d6", surfaceTint: "#d20f39" }
|
light: { primary: "#d20f39", secondary: "#e64553", primaryText: "#ffffff", primaryContainer: "#f1b8c4", surfaceTint: "#d20f39" }
|
||||||
},
|
},
|
||||||
"cat-maroon": {
|
"cat-maroon": {
|
||||||
name: "Maroon",
|
name: "Maroon",
|
||||||
dark: { primary: "#eba0ac", secondary: "#f38ba8", primaryText: "#1e1e2e", primaryContainer: "#6d3641", surfaceTint: "#eba0ac" },
|
dark: { primary: "#eba0ac", secondary: "#f38ba8", primaryText: "#1e1e2e", primaryContainer: "#81313f", surfaceTint: "#eba0ac" },
|
||||||
light: { primary: "#e64553", secondary: "#d20f39", primaryText: "#ffffff", primaryContainer: "#f7d8dc", surfaceTint: "#e64553" }
|
light: { primary: "#e64553", secondary: "#d20f39", primaryText: "#ffffff", primaryContainer: "#f4c3c8", surfaceTint: "#e64553" }
|
||||||
},
|
},
|
||||||
"cat-peach": {
|
"cat-peach": {
|
||||||
name: "Peach",
|
name: "Peach",
|
||||||
dark: { primary: "#fab387", secondary: "#f9e2af", primaryText: "#1e1e2e", primaryContainer: "#734226", surfaceTint: "#fab387" },
|
dark: { primary: "#fab387", secondary: "#f9e2af", primaryText: "#1e1e2e", primaryContainer: "#90441a", surfaceTint: "#fab387" },
|
||||||
light: { primary: "#fe640b", secondary: "#df8e1d", primaryText: "#ffffff", primaryContainer: "#ffe4d5", surfaceTint: "#fe640b" }
|
light: { primary: "#fe640b", secondary: "#df8e1d", primaryText: "#ffffff", primaryContainer: "#ffddcc", surfaceTint: "#fe640b" }
|
||||||
},
|
},
|
||||||
"cat-yellow": {
|
"cat-yellow": {
|
||||||
name: "Yellow",
|
name: "Yellow",
|
||||||
dark: { primary: "#f9e2af", secondary: "#a6e3a1", primaryText: "#1e1e2e", primaryContainer: "#6e5a2f", surfaceTint: "#f9e2af" },
|
dark: { primary: "#f9e2af", secondary: "#a6e3a1", primaryText: "#1e1e2e", primaryContainer: "#8f7342", surfaceTint: "#f9e2af" },
|
||||||
light: { primary: "#df8e1d", secondary: "#40a02b", primaryText: "#ffffff", primaryContainer: "#fff6d6", surfaceTint: "#df8e1d" }
|
light: { primary: "#df8e1d", secondary: "#40a02b", primaryText: "#ffffff", primaryContainer: "#fff3cc", surfaceTint: "#df8e1d" }
|
||||||
},
|
},
|
||||||
"cat-green": {
|
"cat-green": {
|
||||||
name: "Green",
|
name: "Green",
|
||||||
dark: { primary: "#a6e3a1", secondary: "#94e2d5", primaryText: "#1e1e2e", primaryContainer: "#2f5f36", surfaceTint: "#a6e3a1" },
|
dark: { primary: "#a6e3a1", secondary: "#94e2d5", primaryText: "#1e1e2e", primaryContainer: "#3c7534", surfaceTint: "#a6e3a1" },
|
||||||
light: { primary: "#40a02b", secondary: "#179299", primaryText: "#ffffff", primaryContainer: "#dff4e0", surfaceTint: "#40a02b" }
|
light: { primary: "#40a02b", secondary: "#179299", primaryText: "#ffffff", primaryContainer: "#d4f5d4", surfaceTint: "#40a02b" }
|
||||||
},
|
},
|
||||||
"cat-teal": {
|
"cat-teal": {
|
||||||
name: "Teal",
|
name: "Teal",
|
||||||
dark: { primary: "#94e2d5", secondary: "#89dceb", primaryText: "#1e1e2e", primaryContainer: "#2e5e59", surfaceTint: "#94e2d5" },
|
dark: { primary: "#94e2d5", secondary: "#89dceb", primaryText: "#1e1e2e", primaryContainer: "#2a7468", surfaceTint: "#94e2d5" },
|
||||||
light: { primary: "#179299", secondary: "#04a5e5", primaryText: "#ffffff", primaryContainer: "#daf3f1", surfaceTint: "#179299" }
|
light: { primary: "#179299", secondary: "#04a5e5", primaryText: "#ffffff", primaryContainer: "#ccf2f2", surfaceTint: "#179299" }
|
||||||
},
|
},
|
||||||
"cat-sky": {
|
"cat-sky": {
|
||||||
name: "Sky",
|
name: "Sky",
|
||||||
dark: { primary: "#89dceb", secondary: "#74c7ec", primaryText: "#1e1e2e", primaryContainer: "#24586a", surfaceTint: "#89dceb" },
|
dark: { primary: "#89dceb", secondary: "#74c7ec", primaryText: "#1e1e2e", primaryContainer: "#196e7e", surfaceTint: "#89dceb" },
|
||||||
light: { primary: "#04a5e5", secondary: "#209fb5", primaryText: "#ffffff", primaryContainer: "#dbf1fb", surfaceTint: "#04a5e5" }
|
light: { primary: "#04a5e5", secondary: "#209fb5", primaryText: "#ffffff", primaryContainer: "#ccebff", surfaceTint: "#04a5e5" }
|
||||||
},
|
},
|
||||||
"cat-sapphire": {
|
"cat-sapphire": {
|
||||||
name: "Sapphire",
|
name: "Sapphire",
|
||||||
dark: { primary: "#74c7ec", secondary: "#89b4fa", primaryText: "#1e1e2e", primaryContainer: "#1f4d6f", surfaceTint: "#74c7ec" },
|
dark: { primary: "#74c7ec", secondary: "#89b4fa", primaryText: "#1e1e2e", primaryContainer: "#0a597f", surfaceTint: "#74c7ec" },
|
||||||
light: { primary: "#209fb5", secondary: "#1e66f5", primaryText: "#ffffff", primaryContainer: "#def3f8", surfaceTint: "#209fb5" }
|
light: { primary: "#209fb5", secondary: "#1e66f5", primaryText: "#ffffff", primaryContainer: "#d0f0f5", surfaceTint: "#209fb5" }
|
||||||
},
|
},
|
||||||
"cat-blue": {
|
"cat-blue": {
|
||||||
name: "Blue",
|
name: "Blue",
|
||||||
dark: { primary: "#89b4fa", secondary: "#b4befe", primaryText: "#1e1e2e", primaryContainer: "#243f75", surfaceTint: "#89b4fa" },
|
dark: { primary: "#89b4fa", secondary: "#b4befe", primaryText: "#1e1e2e", primaryContainer: "#19468d", surfaceTint: "#89b4fa" },
|
||||||
light: { primary: "#1e66f5", secondary: "#7287fd", primaryText: "#ffffff", primaryContainer: "#e0e9ff", surfaceTint: "#1e66f5" }
|
light: { primary: "#1e66f5", secondary: "#7287fd", primaryText: "#ffffff", primaryContainer: "#ccd9ff", surfaceTint: "#1e66f5" }
|
||||||
},
|
},
|
||||||
"cat-lavender": {
|
"cat-lavender": {
|
||||||
name: "Lavender",
|
name: "Lavender",
|
||||||
dark: { primary: "#b4befe", secondary: "#cba6f7", primaryText: "#1e1e2e", primaryContainer: "#3f4481", surfaceTint: "#b4befe" },
|
dark: { primary: "#b4befe", secondary: "#cba6f7", primaryText: "#1e1e2e", primaryContainer: "#4a5091", surfaceTint: "#b4befe" },
|
||||||
light: { primary: "#7287fd", secondary: "#8839ef", primaryText: "#ffffff", primaryContainer: "#e5e8ff", surfaceTint: "#7287fd" }
|
light: { primary: "#7287fd", secondary: "#8839ef", primaryText: "#ffffff", primaryContainer: "#dde1ff", surfaceTint: "#7287fd" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,17 +120,17 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#0d47a1",
|
primaryContainer: "#0d47a1",
|
||||||
secondary: "#8ab4f8",
|
secondary: "#8ab4f8",
|
||||||
surface: "#101418",
|
surface: "#1a1c1e",
|
||||||
surfaceText: "#e0e2e8",
|
surfaceText: "#e3e8ef",
|
||||||
surfaceVariant: "#42474e",
|
surfaceVariant: "#44464f",
|
||||||
surfaceVariantText: "#c2c7cf",
|
surfaceVariantText: "#c4c7c5",
|
||||||
surfaceTint: "#8ab4f8",
|
surfaceTint: "#8ab4f8",
|
||||||
background: "#101418",
|
background: "#1a1c1e",
|
||||||
backgroundText: "#e0e2e8",
|
backgroundText: "#e3e8ef",
|
||||||
outline: "#8c9199",
|
outline: "#8e918f",
|
||||||
surfaceContainer: "#1d2024",
|
surfaceContainer: "#1e2023",
|
||||||
surfaceContainerHigh: "#272a2f",
|
surfaceContainerHigh: "#292b2f",
|
||||||
surfaceContainerHighest: "#32353a"
|
surfaceContainerHighest: "#343740"
|
||||||
},
|
},
|
||||||
purple: {
|
purple: {
|
||||||
name: "Purple",
|
name: "Purple",
|
||||||
@@ -138,17 +138,17 @@ const StockThemes = {
|
|||||||
primaryText: "#381E72",
|
primaryText: "#381E72",
|
||||||
primaryContainer: "#4F378B",
|
primaryContainer: "#4F378B",
|
||||||
secondary: "#CCC2DC",
|
secondary: "#CCC2DC",
|
||||||
surface: "#141218",
|
surface: "#10121E",
|
||||||
surfaceText: "#e6e0e9",
|
surfaceText: "#E6E0E9",
|
||||||
surfaceVariant: "#49454e",
|
surfaceVariant: "#49454F",
|
||||||
surfaceVariantText: "#cac4cf",
|
surfaceVariantText: "#CAC4D0",
|
||||||
surfaceTint: "#D0BCFF",
|
surfaceTint: "#D0BCFF",
|
||||||
background: "#141218",
|
background: "#10121E",
|
||||||
backgroundText: "#e6e0e9",
|
backgroundText: "#E6E0E9",
|
||||||
outline: "#948f99",
|
outline: "#938F99",
|
||||||
surfaceContainer: "#211f24",
|
surfaceContainer: "#1D1B20",
|
||||||
surfaceContainerHigh: "#2b292f",
|
surfaceContainerHigh: "#2B2930",
|
||||||
surfaceContainerHighest: "#36343a"
|
surfaceContainerHighest: "#36343B"
|
||||||
},
|
},
|
||||||
green: {
|
green: {
|
||||||
name: "Green",
|
name: "Green",
|
||||||
@@ -156,17 +156,17 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#1b5e20",
|
primaryContainer: "#1b5e20",
|
||||||
secondary: "#81c995",
|
secondary: "#81c995",
|
||||||
surface: "#10140f",
|
surface: "#0f1411",
|
||||||
surfaceText: "#e0e4db",
|
surfaceText: "#e1f5e3",
|
||||||
surfaceVariant: "#424940",
|
surfaceVariant: "#404943",
|
||||||
surfaceVariantText: "#c2c9bd",
|
surfaceVariantText: "#c1cbc4",
|
||||||
surfaceTint: "#81c995",
|
surfaceTint: "#81c995",
|
||||||
background: "#10140f",
|
background: "#0f1411",
|
||||||
backgroundText: "#e0e4db",
|
backgroundText: "#e1f5e3",
|
||||||
outline: "#8c9388",
|
outline: "#8b938c",
|
||||||
surfaceContainer: "#1d211b",
|
surfaceContainer: "#1a1f1b",
|
||||||
surfaceContainerHigh: "#272b25",
|
surfaceContainerHigh: "#252a26",
|
||||||
surfaceContainerHighest: "#323630"
|
surfaceContainerHighest: "#30352f"
|
||||||
},
|
},
|
||||||
orange: {
|
orange: {
|
||||||
name: "Orange",
|
name: "Orange",
|
||||||
@@ -174,17 +174,17 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#3e2723",
|
primaryContainer: "#3e2723",
|
||||||
secondary: "#ffb74d",
|
secondary: "#ffb74d",
|
||||||
surface: "#1a120e",
|
surface: "#1c1410",
|
||||||
surfaceText: "#f0dfd8",
|
surfaceText: "#f5f1ea",
|
||||||
surfaceVariant: "#52443d",
|
surfaceVariant: "#4a453a",
|
||||||
surfaceVariantText: "#d7c2b9",
|
surfaceVariantText: "#cbc5b8",
|
||||||
surfaceTint: "#ffb74d",
|
surfaceTint: "#ffb74d",
|
||||||
background: "#1a120e",
|
background: "#1c1410",
|
||||||
backgroundText: "#f0dfd8",
|
backgroundText: "#f5f1ea",
|
||||||
outline: "#a08d85",
|
outline: "#958f84",
|
||||||
surfaceContainer: "#271e1a",
|
surfaceContainer: "#211e17",
|
||||||
surfaceContainerHigh: "#322824",
|
surfaceContainerHigh: "#2c291f",
|
||||||
surfaceContainerHighest: "#3d332e"
|
surfaceContainerHighest: "#373427"
|
||||||
},
|
},
|
||||||
red: {
|
red: {
|
||||||
name: "Red",
|
name: "Red",
|
||||||
@@ -192,17 +192,17 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#4a0e0e",
|
primaryContainer: "#4a0e0e",
|
||||||
secondary: "#f28b82",
|
secondary: "#f28b82",
|
||||||
surface: "#1a1110",
|
surface: "#1c1011",
|
||||||
surfaceText: "#f1dedc",
|
surfaceText: "#f5e8ea",
|
||||||
surfaceVariant: "#534341",
|
surfaceVariant: "#4a3f41",
|
||||||
surfaceVariantText: "#d8c2be",
|
surfaceVariantText: "#cbc2c4",
|
||||||
surfaceTint: "#f28b82",
|
surfaceTint: "#f28b82",
|
||||||
background: "#1a1110",
|
background: "#1c1011",
|
||||||
backgroundText: "#f1dedc",
|
backgroundText: "#f5e8ea",
|
||||||
outline: "#a08c89",
|
outline: "#958b8d",
|
||||||
surfaceContainer: "#271d1c",
|
surfaceContainer: "#211b1c",
|
||||||
surfaceContainerHigh: "#322826",
|
surfaceContainerHigh: "#2c2426",
|
||||||
surfaceContainerHighest: "#3d3231"
|
surfaceContainerHighest: "#372f30"
|
||||||
},
|
},
|
||||||
cyan: {
|
cyan: {
|
||||||
name: "Cyan",
|
name: "Cyan",
|
||||||
@@ -210,15 +210,15 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#004d5c",
|
primaryContainer: "#004d5c",
|
||||||
secondary: "#4dd0e1",
|
secondary: "#4dd0e1",
|
||||||
surface: "#0e1416",
|
surface: "#0f1617",
|
||||||
surfaceText: "#dee3e5",
|
surfaceText: "#e8f4f5",
|
||||||
surfaceVariant: "#3f484a",
|
surfaceVariant: "#3f474a",
|
||||||
surfaceVariantText: "#bfc8ca",
|
surfaceVariantText: "#c2c9cb",
|
||||||
surfaceTint: "#4dd0e1",
|
surfaceTint: "#4dd0e1",
|
||||||
background: "#0e1416",
|
background: "#0f1617",
|
||||||
backgroundText: "#dee3e5",
|
backgroundText: "#e8f4f5",
|
||||||
outline: "#899295",
|
outline: "#8c9194",
|
||||||
surfaceContainer: "#1b2122",
|
surfaceContainer: "#1a1f20",
|
||||||
surfaceContainerHigh: "#252b2c",
|
surfaceContainerHigh: "#252b2c",
|
||||||
surfaceContainerHighest: "#303637"
|
surfaceContainerHighest: "#303637"
|
||||||
},
|
},
|
||||||
@@ -228,17 +228,17 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#4a0e2f",
|
primaryContainer: "#4a0e2f",
|
||||||
secondary: "#f8bbd9",
|
secondary: "#f8bbd9",
|
||||||
surface: "#191112",
|
surface: "#1a1014",
|
||||||
surfaceText: "#f0dee0",
|
surfaceText: "#f3e8ee",
|
||||||
surfaceVariant: "#524345",
|
surfaceVariant: "#483f45",
|
||||||
surfaceVariantText: "#d6c2c3",
|
surfaceVariantText: "#c9c2c7",
|
||||||
surfaceTint: "#f8bbd9",
|
surfaceTint: "#f8bbd9",
|
||||||
background: "#191112",
|
background: "#1a1014",
|
||||||
backgroundText: "#f0dee0",
|
backgroundText: "#f3e8ee",
|
||||||
outline: "#9f8c8e",
|
outline: "#938a90",
|
||||||
surfaceContainer: "#261d1e",
|
surfaceContainer: "#1f1b1e",
|
||||||
surfaceContainerHigh: "#312829",
|
surfaceContainerHigh: "#2a2428",
|
||||||
surfaceContainerHighest: "#3c3233"
|
surfaceContainerHighest: "#352f32"
|
||||||
},
|
},
|
||||||
amber: {
|
amber: {
|
||||||
name: "Amber",
|
name: "Amber",
|
||||||
@@ -246,17 +246,17 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#4a3c00",
|
primaryContainer: "#4a3c00",
|
||||||
secondary: "#ffd54f",
|
secondary: "#ffd54f",
|
||||||
surface: "#17130b",
|
surface: "#1a1710",
|
||||||
surfaceText: "#ebe1d4",
|
surfaceText: "#f3f0e8",
|
||||||
surfaceVariant: "#4d4639",
|
surfaceVariant: "#49453a",
|
||||||
surfaceVariantText: "#d0c5b4",
|
surfaceVariantText: "#cac5b8",
|
||||||
surfaceTint: "#ffd54f",
|
surfaceTint: "#ffd54f",
|
||||||
background: "#17130b",
|
background: "#1a1710",
|
||||||
backgroundText: "#ebe1d4",
|
backgroundText: "#f3f0e8",
|
||||||
outline: "#998f80",
|
outline: "#949084",
|
||||||
surfaceContainer: "#231f17",
|
surfaceContainer: "#1f1e17",
|
||||||
surfaceContainerHigh: "#2e2921",
|
surfaceContainerHigh: "#2a281f",
|
||||||
surfaceContainerHighest: "#39342b"
|
surfaceContainerHighest: "#353327"
|
||||||
},
|
},
|
||||||
coral: {
|
coral: {
|
||||||
name: "Coral",
|
name: "Coral",
|
||||||
@@ -265,16 +265,16 @@ const StockThemes = {
|
|||||||
primaryContainer: "#8c1d18",
|
primaryContainer: "#8c1d18",
|
||||||
secondary: "#f9dedc",
|
secondary: "#f9dedc",
|
||||||
surface: "#1a1110",
|
surface: "#1a1110",
|
||||||
surfaceText: "#f1dedc",
|
surfaceText: "#f1e8e7",
|
||||||
surfaceVariant: "#534341",
|
surfaceVariant: "#4a4142",
|
||||||
surfaceVariantText: "#d8c2bf",
|
surfaceVariantText: "#cdc2c1",
|
||||||
surfaceTint: "#ffb4ab",
|
surfaceTint: "#ffb4ab",
|
||||||
background: "#1a1110",
|
background: "#1a1110",
|
||||||
backgroundText: "#f1dedc",
|
backgroundText: "#f1e8e7",
|
||||||
outline: "#a08c8a",
|
outline: "#968b8a",
|
||||||
surfaceContainer: "#271d1c",
|
surfaceContainer: "#201a19",
|
||||||
surfaceContainerHigh: "#322826",
|
surfaceContainerHigh: "#2b2221",
|
||||||
surfaceContainerHighest: "#3d3231"
|
surfaceContainerHighest: "#362d29"
|
||||||
},
|
},
|
||||||
monochrome: {
|
monochrome: {
|
||||||
name: "Monochrome",
|
name: "Monochrome",
|
||||||
@@ -290,9 +290,9 @@ const StockThemes = {
|
|||||||
background: "#131315",
|
background: "#131315",
|
||||||
backgroundText: "#e4e2e3",
|
backgroundText: "#e4e2e3",
|
||||||
outline: "#929092",
|
outline: "#929092",
|
||||||
surfaceContainer: "#353535",
|
surfaceContainer: "#2a2a2a",
|
||||||
surfaceContainerHigh: "#424242",
|
surfaceContainerHigh: "#2a2a2b",
|
||||||
surfaceContainerHighest: "#505050",
|
surfaceContainerHighest: "#353535",
|
||||||
error: "#ffb4ab",
|
error: "#ffb4ab",
|
||||||
warning: "#3f4759",
|
warning: "#3f4759",
|
||||||
info: "#595e6c",
|
info: "#595e6c",
|
||||||
@@ -306,17 +306,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#e3f2fd",
|
primaryContainer: "#e3f2fd",
|
||||||
secondary: "#42a5f5",
|
secondary: "#42a5f5",
|
||||||
surface: "#f7f9ff",
|
surface: "#fefefe",
|
||||||
surfaceText: "#181c20",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#dee3eb",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#42474e",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#1976d2",
|
surfaceTint: "#1976d2",
|
||||||
background: "#f7f9ff",
|
background: "#fefefe",
|
||||||
backgroundText: "#181c20",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#72777f",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#eceef4",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#e6e8ee",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#e0e2e8"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
purple: {
|
purple: {
|
||||||
name: "Purple Light",
|
name: "Purple Light",
|
||||||
@@ -324,17 +324,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#EADDFF",
|
primaryContainer: "#EADDFF",
|
||||||
secondary: "#625B71",
|
secondary: "#625B71",
|
||||||
surface: "#fef7ff",
|
surface: "#FFFBFE",
|
||||||
surfaceText: "#1d1b20",
|
surfaceText: "#1C1B1F",
|
||||||
surfaceVariant: "#e7e0eb",
|
surfaceVariant: "#E7E0EC",
|
||||||
surfaceVariantText: "#49454e",
|
surfaceVariantText: "#49454F",
|
||||||
surfaceTint: "#6750A4",
|
surfaceTint: "#6750A4",
|
||||||
background: "#fef7ff",
|
background: "#FFFBFE",
|
||||||
backgroundText: "#1d1b20",
|
backgroundText: "#1C1B1F",
|
||||||
outline: "#7a757f",
|
outline: "#79747E",
|
||||||
surfaceContainer: "#f2ecf4",
|
surfaceContainer: "#F3EDF7",
|
||||||
surfaceContainerHigh: "#ece6ee",
|
surfaceContainerHigh: "#ECE6F0",
|
||||||
surfaceContainerHighest: "#e6e0e9"
|
surfaceContainerHighest: "#E6DFE9"
|
||||||
},
|
},
|
||||||
green: {
|
green: {
|
||||||
name: "Green Light",
|
name: "Green Light",
|
||||||
@@ -342,17 +342,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#e8f5e8",
|
primaryContainer: "#e8f5e8",
|
||||||
secondary: "#4caf50",
|
secondary: "#4caf50",
|
||||||
surface: "#f7fbf1",
|
surface: "#fefefe",
|
||||||
surfaceText: "#191d17",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#dee5d8",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#424940",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#2e7d32",
|
surfaceTint: "#2e7d32",
|
||||||
background: "#f7fbf1",
|
background: "#fefefe",
|
||||||
backgroundText: "#191d17",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#72796f",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#ecefe6",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#e6e9e0",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#e0e4db"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
orange: {
|
orange: {
|
||||||
name: "Orange Light",
|
name: "Orange Light",
|
||||||
@@ -360,17 +360,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#ffecb3",
|
primaryContainer: "#ffecb3",
|
||||||
secondary: "#ff9800",
|
secondary: "#ff9800",
|
||||||
surface: "#fff8f6",
|
surface: "#fefefe",
|
||||||
surfaceText: "#221a16",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#f4ded5",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#52443d",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#e65100",
|
surfaceTint: "#e65100",
|
||||||
background: "#fff8f6",
|
background: "#fefefe",
|
||||||
backgroundText: "#221a16",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#85736c",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#fceae3",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#f6e5de",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#f0dfd8"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
red: {
|
red: {
|
||||||
name: "Red Light",
|
name: "Red Light",
|
||||||
@@ -378,17 +378,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#ffebee",
|
primaryContainer: "#ffebee",
|
||||||
secondary: "#f44336",
|
secondary: "#f44336",
|
||||||
surface: "#fff8f7",
|
surface: "#fefefe",
|
||||||
surfaceText: "#231918",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#f5ddda",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#534341",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#d32f2f",
|
surfaceTint: "#d32f2f",
|
||||||
background: "#fff8f7",
|
background: "#fefefe",
|
||||||
backgroundText: "#231918",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#857370",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#fceae7",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#f7e4e1",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#f1dedc"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
cyan: {
|
cyan: {
|
||||||
name: "Cyan Light",
|
name: "Cyan Light",
|
||||||
@@ -396,17 +396,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#e0f2f1",
|
primaryContainer: "#e0f2f1",
|
||||||
secondary: "#00bcd4",
|
secondary: "#00bcd4",
|
||||||
surface: "#f5fafc",
|
surface: "#fefefe",
|
||||||
surfaceText: "#171d1e",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#dbe4e6",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#3f484a",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#0097a7",
|
surfaceTint: "#0097a7",
|
||||||
background: "#f5fafc",
|
background: "#fefefe",
|
||||||
backgroundText: "#171d1e",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#6f797b",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#e9eff0",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#e3e9eb",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#dee3e5"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
pink: {
|
pink: {
|
||||||
name: "Pink Light",
|
name: "Pink Light",
|
||||||
@@ -414,17 +414,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#fce4ec",
|
primaryContainer: "#fce4ec",
|
||||||
secondary: "#e91e63",
|
secondary: "#e91e63",
|
||||||
surface: "#fff8f7",
|
surface: "#fefefe",
|
||||||
surfaceText: "#22191a",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#f3dddf",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#524345",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#c2185b",
|
surfaceTint: "#c2185b",
|
||||||
background: "#fff8f7",
|
background: "#fefefe",
|
||||||
backgroundText: "#22191a",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#847375",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#fbeaeb",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#f5e4e5",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#f0dee0"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
amber: {
|
amber: {
|
||||||
name: "Amber Light",
|
name: "Amber Light",
|
||||||
@@ -432,17 +432,17 @@ const StockThemes = {
|
|||||||
primaryText: "#000000",
|
primaryText: "#000000",
|
||||||
primaryContainer: "#fff8e1",
|
primaryContainer: "#fff8e1",
|
||||||
secondary: "#ffc107",
|
secondary: "#ffc107",
|
||||||
surface: "#fff8f2",
|
surface: "#fefefe",
|
||||||
surfaceText: "#1f1b13",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#ede1cf",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#4d4639",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#ff8f00",
|
surfaceTint: "#ff8f00",
|
||||||
background: "#fff8f2",
|
background: "#fefefe",
|
||||||
backgroundText: "#1f1b13",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#7f7667",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#f6ecdf",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#f1e7d9",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#ebe1d4"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
coral: {
|
coral: {
|
||||||
name: "Coral Light",
|
name: "Coral Light",
|
||||||
@@ -450,17 +450,17 @@ const StockThemes = {
|
|||||||
primaryText: "#ffffff",
|
primaryText: "#ffffff",
|
||||||
primaryContainer: "#ffdad6",
|
primaryContainer: "#ffdad6",
|
||||||
secondary: "#ff5449",
|
secondary: "#ff5449",
|
||||||
surface: "#fff8f7",
|
surface: "#fefefe",
|
||||||
surfaceText: "#231918",
|
surfaceText: "#1a1c1e",
|
||||||
surfaceVariant: "#f5ddda",
|
surfaceVariant: "#e7e0ec",
|
||||||
surfaceVariantText: "#534341",
|
surfaceVariantText: "#49454f",
|
||||||
surfaceTint: "#8c1d18",
|
surfaceTint: "#8c1d18",
|
||||||
background: "#fff8f7",
|
background: "#fefefe",
|
||||||
backgroundText: "#231918",
|
backgroundText: "#1a1c1e",
|
||||||
outline: "#857371",
|
outline: "#79747e",
|
||||||
surfaceContainer: "#fceae7",
|
surfaceContainer: "#f3f3f3",
|
||||||
surfaceContainerHigh: "#f6e4e2",
|
surfaceContainerHigh: "#ececec",
|
||||||
surfaceContainerHighest: "#f1dedc"
|
surfaceContainerHighest: "#e6e6e6"
|
||||||
},
|
},
|
||||||
monochrome: {
|
monochrome: {
|
||||||
name: "Monochrome Light",
|
name: "Monochrome Light",
|
||||||
@@ -476,9 +476,8 @@ const StockThemes = {
|
|||||||
background: "#ffffff",
|
background: "#ffffff",
|
||||||
backgroundText: "#1a1a1a",
|
backgroundText: "#1a1a1a",
|
||||||
outline: "#757577",
|
outline: "#757577",
|
||||||
surfaceContainer: "#e8e8ea",
|
surfaceContainer: "#f5f5f6",
|
||||||
surfaceContainerHigh: "#dcdcde",
|
surfaceContainerHigh: "#eaeaeb",
|
||||||
surfaceContainerHighest: "#d0d0d2",
|
|
||||||
error: "#ba1a1a",
|
error: "#ba1a1a",
|
||||||
warning: "#f9e79f",
|
warning: "#f9e79f",
|
||||||
info: "#5d6475",
|
info: "#5d6475",
|
||||||
|
|||||||
385
Common/Theme.qml
385
Common/Theme.qml
@@ -16,12 +16,9 @@ Singleton {
|
|||||||
|
|
||||||
readonly property bool envDisableMatugen: Quickshell.env("DMS_DISABLE_MATUGEN") === "1" || Quickshell.env("DMS_DISABLE_MATUGEN") === "true"
|
readonly property bool envDisableMatugen: Quickshell.env("DMS_DISABLE_MATUGEN") === "1" || Quickshell.env("DMS_DISABLE_MATUGEN") === "true"
|
||||||
|
|
||||||
// ! TODO - Synchronize with niri/hyprland gaps?
|
|
||||||
readonly property real popupDistance: 2
|
|
||||||
|
|
||||||
property string currentTheme: "blue"
|
property string currentTheme: "blue"
|
||||||
property string currentThemeCategory: "generic"
|
property string currentThemeCategory: "generic"
|
||||||
property bool isLightMode: typeof SessionData !== "undefined" ? SessionData.isLightMode : false
|
property bool isLightMode: false
|
||||||
|
|
||||||
readonly property string dynamic: "dynamic"
|
readonly property string dynamic: "dynamic"
|
||||||
readonly property string custom : "custom"
|
readonly property string custom : "custom"
|
||||||
@@ -31,8 +28,9 @@ Singleton {
|
|||||||
readonly property string shellDir: Paths.strip(Qt.resolvedUrl(".").toString()).replace("/Common/", "")
|
readonly property string shellDir: Paths.strip(Qt.resolvedUrl(".").toString()).replace("/Common/", "")
|
||||||
readonly property string wallpaperPath: {
|
readonly property string wallpaperPath: {
|
||||||
if (typeof SessionData === "undefined") return ""
|
if (typeof SessionData === "undefined") return ""
|
||||||
|
|
||||||
if (SessionData.perMonitorWallpaper) {
|
if (SessionData.perMonitorWallpaper) {
|
||||||
|
// Use first monitor's wallpaper for dynamic theming
|
||||||
var screens = Quickshell.screens
|
var screens = Quickshell.screens
|
||||||
if (screens.length > 0) {
|
if (screens.length > 0) {
|
||||||
var firstMonitorWallpaper = SessionData.getMonitorWallpaper(screens[0].name)
|
var firstMonitorWallpaper = SessionData.getMonitorWallpaper(screens[0].name)
|
||||||
@@ -74,6 +72,7 @@ Singleton {
|
|||||||
property bool qtThemingEnabled: typeof SettingsData !== "undefined" ? (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable) : false
|
property bool qtThemingEnabled: typeof SettingsData !== "undefined" ? (SettingsData.qt5ctAvailable || SettingsData.qt6ctAvailable) : false
|
||||||
property var workerRunning: false
|
property var workerRunning: false
|
||||||
property var matugenColors: ({})
|
property var matugenColors: ({})
|
||||||
|
property bool extractionRequested: false
|
||||||
property int colorUpdateTrigger: 0
|
property int colorUpdateTrigger: 0
|
||||||
property var customThemeData: null
|
property var customThemeData: null
|
||||||
|
|
||||||
@@ -82,20 +81,11 @@ Singleton {
|
|||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
Quickshell.execDetached(["mkdir", "-p", stateDir])
|
Quickshell.execDetached(["mkdir", "-p", stateDir])
|
||||||
matugenCheck.running = true
|
matugenCheck.running = true
|
||||||
if (typeof SessionData !== "undefined") {
|
if (typeof SessionData !== "undefined")
|
||||||
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
|
SessionData.isLightModeChanged.connect(root.onLightModeChanged)
|
||||||
isLightMode = SessionData.isLightMode
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof SettingsData !== "undefined" && SettingsData.currentThemeName) {
|
if (typeof SettingsData !== "undefined" && SettingsData.currentThemeName) {
|
||||||
switchTheme(SettingsData.currentThemeName, false, false)
|
switchTheme(SettingsData.currentThemeName, false)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function applyGreeterTheme(themeName) {
|
|
||||||
switchTheme(themeName, false, false)
|
|
||||||
if (themeName === dynamic && dynamicColorsFileView.path) {
|
|
||||||
dynamicColorsFileView.reload()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,22 +231,11 @@ Singleton {
|
|||||||
property color shadowMedium: Qt.rgba(0, 0, 0, 0.08)
|
property color shadowMedium: Qt.rgba(0, 0, 0, 0.08)
|
||||||
property color shadowStrong: Qt.rgba(0, 0, 0, 0.3)
|
property color shadowStrong: Qt.rgba(0, 0, 0, 0.3)
|
||||||
|
|
||||||
readonly property var animationDurations: [
|
property int shorterDuration: 100
|
||||||
{ shorter: 0, short: 0, medium: 0, long: 0, extraLong: 0 },
|
property int shortDuration: 150
|
||||||
{ shorter: 50, short: 75, medium: 150, long: 250, extraLong: 500 },
|
property int mediumDuration: 300
|
||||||
{ shorter: 100, short: 150, medium: 300, long: 500, extraLong: 1000 },
|
property int longDuration: 500
|
||||||
{ shorter: 150, short: 225, medium: 450, long: 750, extraLong: 1500 },
|
property int extraLongDuration: 1000
|
||||||
{ shorter: 200, short: 300, medium: 600, long: 1000, extraLong: 2000 }
|
|
||||||
]
|
|
||||||
|
|
||||||
readonly property int currentAnimationSpeed: typeof SettingsData !== "undefined" ? SettingsData.animationSpeed : SettingsData.AnimationSpeed.Short
|
|
||||||
readonly property var currentDurations: animationDurations[currentAnimationSpeed] || animationDurations[SettingsData.AnimationSpeed.Short]
|
|
||||||
|
|
||||||
property int shorterDuration: currentDurations.shorter
|
|
||||||
property int shortDuration: currentDurations.short
|
|
||||||
property int mediumDuration: currentDurations.medium
|
|
||||||
property int longDuration: currentDurations.long
|
|
||||||
property int extraLongDuration: currentDurations.extraLong
|
|
||||||
property int standardEasing: Easing.OutCubic
|
property int standardEasing: Easing.OutCubic
|
||||||
property int emphasizedEasing: Easing.OutQuart
|
property int emphasizedEasing: Easing.OutQuart
|
||||||
|
|
||||||
@@ -276,8 +255,8 @@ Singleton {
|
|||||||
property real iconSizeLarge: 32
|
property real iconSizeLarge: 32
|
||||||
|
|
||||||
property real panelTransparency: 0.85
|
property real panelTransparency: 0.85
|
||||||
property real widgetTransparency: typeof SettingsData !== "undefined" && SettingsData.dankBarWidgetTransparency !== undefined ? SettingsData.dankBarWidgetTransparency : 1.0
|
property real widgetTransparency: typeof SettingsData !== "undefined" && SettingsData.topBarWidgetTransparency !== undefined ? SettingsData.topBarWidgetTransparency : 0.85
|
||||||
property real popupTransparency: typeof SettingsData !== "undefined" && SettingsData.popupTransparency !== undefined ? SettingsData.popupTransparency : 1.0
|
property real popupTransparency: typeof SettingsData !== "undefined" && SettingsData.popupTransparency !== undefined ? SettingsData.popupTransparency : 0.92
|
||||||
|
|
||||||
function screenTransition() {
|
function screenTransition() {
|
||||||
CompositorService.isNiri && NiriService.doScreenTransition()
|
CompositorService.isNiri && NiriService.doScreenTransition()
|
||||||
@@ -286,15 +265,11 @@ Singleton {
|
|||||||
function switchTheme(themeName, savePrefs = true, enableTransition = true) {
|
function switchTheme(themeName, savePrefs = true, enableTransition = true) {
|
||||||
if (enableTransition) {
|
if (enableTransition) {
|
||||||
screenTransition()
|
screenTransition()
|
||||||
themeTransitionTimer.themeName = themeName
|
|
||||||
themeTransitionTimer.savePrefs = savePrefs
|
|
||||||
themeTransitionTimer.restart()
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (themeName === dynamic) {
|
if (themeName === dynamic) {
|
||||||
currentTheme = dynamic
|
currentTheme = dynamic
|
||||||
currentThemeCategory = dynamic
|
currentThemeCategory = dynamic
|
||||||
|
extractColors()
|
||||||
} else if (themeName === custom) {
|
} else if (themeName === custom) {
|
||||||
currentTheme = custom
|
currentTheme = custom
|
||||||
currentThemeCategory = custom
|
currentThemeCategory = custom
|
||||||
@@ -303,45 +278,34 @@ Singleton {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
currentTheme = themeName
|
currentTheme = themeName
|
||||||
|
// Determine category based on theme name
|
||||||
if (StockThemes.isCatppuccinVariant(themeName)) {
|
if (StockThemes.isCatppuccinVariant(themeName)) {
|
||||||
currentThemeCategory = "catppuccin"
|
currentThemeCategory = "catppuccin"
|
||||||
} else {
|
} else {
|
||||||
currentThemeCategory = "generic"
|
currentThemeCategory = "generic"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const isGreeterMode = (typeof SessionData !== "undefined" && SessionData.isGreeterMode)
|
if (savePrefs && typeof SettingsData !== "undefined")
|
||||||
if (savePrefs && typeof SettingsData !== "undefined" && !isGreeterMode)
|
|
||||||
SettingsData.setTheme(currentTheme)
|
SettingsData.setTheme(currentTheme)
|
||||||
|
|
||||||
if (!isGreeterMode) {
|
generateSystemThemesFromCurrentTheme()
|
||||||
generateSystemThemesFromCurrentTheme()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLightMode(light, savePrefs = true, enableTransition = false) {
|
function setLightMode(light, savePrefs = true) {
|
||||||
if (enableTransition) {
|
screenTransition()
|
||||||
screenTransition()
|
|
||||||
lightModeTransitionTimer.lightMode = light
|
|
||||||
lightModeTransitionTimer.savePrefs = savePrefs
|
|
||||||
lightModeTransitionTimer.restart()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const isGreeterMode = (typeof SessionData !== "undefined" && SessionData.isGreeterMode)
|
|
||||||
isLightMode = light
|
isLightMode = light
|
||||||
if (savePrefs && typeof SessionData !== "undefined" && !isGreeterMode)
|
if (savePrefs && typeof SessionData !== "undefined")
|
||||||
SessionData.setLightMode(isLightMode)
|
SessionData.setLightMode(isLightMode)
|
||||||
if (!isGreeterMode) {
|
PortalService.setLightMode(isLightMode)
|
||||||
PortalService.setLightMode(isLightMode)
|
generateSystemThemesFromCurrentTheme()
|
||||||
generateSystemThemesFromCurrentTheme()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleLightMode(savePrefs = true) {
|
function toggleLightMode(savePrefs = true) {
|
||||||
setLightMode(!isLightMode, savePrefs, true)
|
setLightMode(!isLightMode, savePrefs)
|
||||||
}
|
}
|
||||||
|
|
||||||
function forceGenerateSystemThemes() {
|
function forceGenerateSystemThemes() {
|
||||||
|
screenTransition()
|
||||||
if (!matugenAvailable) {
|
if (!matugenAvailable) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -365,10 +329,8 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function switchThemeCategory(category, defaultTheme) {
|
function switchThemeCategory(category, defaultTheme) {
|
||||||
screenTransition()
|
currentThemeCategory = category
|
||||||
themeCategoryTransitionTimer.category = category
|
switchTheme(defaultTheme, true, false)
|
||||||
themeCategoryTransitionTimer.defaultTheme = defaultTheme
|
|
||||||
themeCategoryTransitionTimer.restart()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCatppuccinColor(variantName) {
|
function getCatppuccinColor(variantName) {
|
||||||
@@ -392,6 +354,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadCustomTheme(themeData) {
|
function loadCustomTheme(themeData) {
|
||||||
|
screenTransition()
|
||||||
if (themeData.dark || themeData.light) {
|
if (themeData.dark || themeData.light) {
|
||||||
const colorMode = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "light" : "dark"
|
const colorMode = (typeof SessionData !== "undefined" && SessionData.isLightMode) ? "light" : "dark"
|
||||||
const selectedTheme = themeData[colorMode] || themeData.dark || themeData.light
|
const selectedTheme = themeData[colorMode] || themeData.dark || themeData.light
|
||||||
@@ -563,6 +526,17 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function extractColors() {
|
||||||
|
extractionRequested = true
|
||||||
|
if (matugenAvailable)
|
||||||
|
if (rawWallpaperPath.startsWith("we:")) {
|
||||||
|
fileCheckerTimer.start()
|
||||||
|
} else {
|
||||||
|
fileChecker.running = true
|
||||||
|
}
|
||||||
|
else
|
||||||
|
matugenCheck.running = true
|
||||||
|
}
|
||||||
|
|
||||||
function onLightModeChanged() {
|
function onLightModeChanged() {
|
||||||
if (matugenColors && Object.keys(matugenColors).length > 0) {
|
if (matugenColors && Object.keys(matugenColors).length > 0) {
|
||||||
@@ -611,8 +585,7 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function generateSystemThemesFromCurrentTheme() {
|
function generateSystemThemesFromCurrentTheme() {
|
||||||
const isGreeterMode = (typeof SessionData !== "undefined" && SessionData.isGreeterMode)
|
if (!matugenAvailable)
|
||||||
if (!matugenAvailable || isGreeterMode)
|
|
||||||
return
|
return
|
||||||
|
|
||||||
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode)
|
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode)
|
||||||
@@ -676,10 +649,60 @@ Singleton {
|
|||||||
qtApplier.running = true
|
qtApplier.running = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function withAlpha(c, a) { return Qt.rgba(c.r, c.g, c.b, a); }
|
function extractJsonFromText(text) {
|
||||||
|
if (!text)
|
||||||
|
return null
|
||||||
|
|
||||||
function snap(value, dpr) {
|
const start = text.search(/[{\[]/)
|
||||||
return Math.round(value * dpr) / dpr
|
if (start === -1)
|
||||||
|
return null
|
||||||
|
|
||||||
|
const open = text[start]
|
||||||
|
const pairs = {
|
||||||
|
"{": '}',
|
||||||
|
"[": ']'
|
||||||
|
}
|
||||||
|
const close = pairs[open]
|
||||||
|
if (!close)
|
||||||
|
return null
|
||||||
|
|
||||||
|
let inString = false
|
||||||
|
let escape = false
|
||||||
|
const stack = [open]
|
||||||
|
|
||||||
|
for (var i = start + 1; i < text.length; i++) {
|
||||||
|
const ch = text[i]
|
||||||
|
|
||||||
|
if (inString) {
|
||||||
|
if (escape) {
|
||||||
|
escape = false
|
||||||
|
} else if (ch === '\\') {
|
||||||
|
escape = true
|
||||||
|
} else if (ch === '"') {
|
||||||
|
inString = false
|
||||||
|
}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ch === '"') {
|
||||||
|
inString = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (ch === '{' || ch === '[') {
|
||||||
|
stack.push(ch)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (ch === '}' || ch === ']') {
|
||||||
|
const last = stack.pop()
|
||||||
|
if (!last || pairs[last] !== ch) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
if (stack.length === 0) {
|
||||||
|
return text.slice(start, i + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
@@ -687,11 +710,17 @@ Singleton {
|
|||||||
command: ["which", "matugen"]
|
command: ["which", "matugen"]
|
||||||
onExited: code => {
|
onExited: code => {
|
||||||
matugenAvailable = (code === 0) && !envDisableMatugen
|
matugenAvailable = (code === 0) && !envDisableMatugen
|
||||||
const isGreeterMode = (typeof SessionData !== "undefined" && SessionData.isGreeterMode)
|
if (!matugenAvailable) {
|
||||||
|
console.log("matugen not not available in path or disabled via DMS_DISABLE_MATUGEN")
|
||||||
if (!matugenAvailable || isGreeterMode) {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (extractionRequested) {
|
||||||
|
if (rawWallpaperPath.startsWith("we:")) {
|
||||||
|
fileCheckerTimer.start()
|
||||||
|
} else {
|
||||||
|
fileChecker.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode)
|
const isLight = (typeof SessionData !== "undefined" && SessionData.isLightMode)
|
||||||
const iconTheme = (typeof SettingsData !== "undefined" && SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
|
const iconTheme = (typeof SettingsData !== "undefined" && SettingsData.iconTheme) ? SettingsData.iconTheme : "System Default"
|
||||||
@@ -727,7 +756,128 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: fileChecker
|
||||||
|
command: ["test", "-r", wallpaperPath]
|
||||||
|
onExited: code => {
|
||||||
|
if (code === 0) {
|
||||||
|
matugenProcess.running = true
|
||||||
|
} else if (wallpaperPath.startsWith("#")) {
|
||||||
|
colorMatugenProcess.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: fileCheckerTimer
|
||||||
|
interval: 1000
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
fileChecker.running = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: matugenProcess
|
||||||
|
command: {
|
||||||
|
const scheme = (typeof SettingsData !== "undefined" && SettingsData.matugenScheme) ? SettingsData.matugenScheme : "scheme-tonal-spot"
|
||||||
|
return ["matugen", "image", wallpaperPath, "--json", "hex", "-t", scheme]
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
id: matugenCollector
|
||||||
|
onStreamFinished: {
|
||||||
|
if (!matugenCollector.text) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Wallpaper Processing Failed: Empty JSON extracted from matugen output.")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const extractedJson = extractJsonFromText(matugenCollector.text)
|
||||||
|
if (!extractedJson) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Wallpaper Processing Failed: Invalid JSON extracted from matugen output.")
|
||||||
|
}
|
||||||
|
console.log("Raw matugen output:", matugenCollector.text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
root.matugenColors = JSON.parse(extractedJson)
|
||||||
|
root.colorUpdateTrigger++
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.clearWallpaperError()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Wallpaper processing failed (JSON parse error after extraction)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExited: code => {
|
||||||
|
if (code !== 0) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Matugen command failed with exit code " + code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Process {
|
||||||
|
id: colorMatugenProcess
|
||||||
|
command: {
|
||||||
|
const scheme = (typeof SettingsData !== "undefined" && SettingsData.matugenScheme) ? SettingsData.matugenScheme : "scheme-tonal-spot"
|
||||||
|
return ["matugen", "color", "hex", wallpaperPath, "--json", "hex", "-t", scheme]
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout: StdioCollector {
|
||||||
|
id: colorMatugenCollector
|
||||||
|
onStreamFinished: {
|
||||||
|
if (!colorMatugenCollector.text) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Color Processing Failed: Empty JSON extracted from matugen output.")
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const extractedJson = extractJsonFromText(colorMatugenCollector.text)
|
||||||
|
if (!extractedJson) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Color Processing Failed: Invalid JSON extracted from matugen output.")
|
||||||
|
}
|
||||||
|
console.log("Raw matugen output:", colorMatugenCollector.text)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
root.matugenColors = JSON.parse(extractedJson)
|
||||||
|
root.colorUpdateTrigger++
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.clearWallpaperError()
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Color processing failed (JSON parse error after extraction)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onExited: code => {
|
||||||
|
if (code !== 0) {
|
||||||
|
if (typeof ToastService !== "undefined") {
|
||||||
|
ToastService.wallpaperErrorStatus = "error"
|
||||||
|
ToastService.showError("Matugen color command failed with exit code " + code)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
id: ensureStateDir
|
id: ensureStateDir
|
||||||
@@ -740,7 +890,10 @@ Singleton {
|
|||||||
onExited: exitCode => {
|
onExited: exitCode => {
|
||||||
workerRunning = false
|
workerRunning = false
|
||||||
|
|
||||||
if (exitCode !== 0 && exitCode !== 2) {
|
if (exitCode === 2) {
|
||||||
|
// Exit code 2 means wallpaper/color not found - this is expected on first run
|
||||||
|
console.log("Theme worker: wallpaper/color not found, skipping theme generation")
|
||||||
|
} else if (exitCode !== 0) {
|
||||||
if (typeof ToastService !== "undefined") {
|
if (typeof ToastService !== "undefined") {
|
||||||
ToastService.showError("Theme worker failed (" + exitCode + ")")
|
ToastService.showError("Theme worker failed (" + exitCode + ")")
|
||||||
}
|
}
|
||||||
@@ -827,55 +980,6 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: dynamicColorsFileView
|
|
||||||
path: {
|
|
||||||
const greetCfgDir = Quickshell.env("DMS_GREET_CFG_DIR") || "/etc/greetd/.dms"
|
|
||||||
const colorsPath = SessionData.isGreeterMode
|
|
||||||
? greetCfgDir + "/colors.json"
|
|
||||||
: stateDir + "/dms-colors.json"
|
|
||||||
return colorsPath
|
|
||||||
}
|
|
||||||
watchChanges: currentTheme === dynamic && !SessionData.isGreeterMode
|
|
||||||
|
|
||||||
function parseAndLoadColors() {
|
|
||||||
try {
|
|
||||||
const colorsText = dynamicColorsFileView.text()
|
|
||||||
if (colorsText) {
|
|
||||||
root.matugenColors = JSON.parse(colorsText)
|
|
||||||
root.colorUpdateTrigger++
|
|
||||||
if (typeof ToastService !== "undefined") {
|
|
||||||
ToastService.clearWallpaperError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.error("Theme: Failed to parse dynamic colors:", e)
|
|
||||||
if (typeof ToastService !== "undefined") {
|
|
||||||
ToastService.wallpaperErrorStatus = "error"
|
|
||||||
ToastService.showError("Dynamic colors parse error: " + e.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
if (currentTheme === dynamic) {
|
|
||||||
parseAndLoadColors()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onFileChanged: {
|
|
||||||
if (currentTheme === dynamic) {
|
|
||||||
dynamicColorsFileView.reload()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoadFailed: function (error) {
|
|
||||||
if (currentTheme === dynamic && typeof ToastService !== "undefined") {
|
|
||||||
ToastService.showError("Failed to read dynamic colors: " + error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
target: "theme"
|
target: "theme"
|
||||||
|
|
||||||
@@ -885,12 +989,12 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function light(): string {
|
function light(): string {
|
||||||
root.setLightMode(true, true, true)
|
root.setLightMode(true)
|
||||||
return "light"
|
return "light"
|
||||||
}
|
}
|
||||||
|
|
||||||
function dark(): string {
|
function dark(): string {
|
||||||
root.setLightMode(false, true, true)
|
root.setLightMode(false)
|
||||||
return "dark"
|
return "dark"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -898,35 +1002,4 @@ Singleton {
|
|||||||
return root.isLightMode ? "light" : "dark"
|
return root.isLightMode ? "light" : "dark"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These timers are for screen transitions, since sometimes QML still beats the niri call
|
|
||||||
Timer {
|
|
||||||
id: themeTransitionTimer
|
|
||||||
interval: 50
|
|
||||||
repeat: false
|
|
||||||
property string themeName: ""
|
|
||||||
property bool savePrefs: true
|
|
||||||
onTriggered: root.switchTheme(themeName, savePrefs, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: lightModeTransitionTimer
|
|
||||||
interval: 100
|
|
||||||
repeat: false
|
|
||||||
property bool lightMode: false
|
|
||||||
property bool savePrefs: true
|
|
||||||
onTriggered: root.setLightMode(lightMode, savePrefs, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: themeCategoryTransitionTimer
|
|
||||||
interval: 50
|
|
||||||
repeat: false
|
|
||||||
property string category: ""
|
|
||||||
property string defaultTheme: ""
|
|
||||||
onTriggered: {
|
|
||||||
root.currentThemeCategory = category
|
|
||||||
root.switchTheme(defaultTheme, true, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import Quickshell.Services.Greetd
|
|
||||||
import qs.Common
|
|
||||||
import qs.Modules.Greetd
|
|
||||||
|
|
||||||
ShellRoot {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
WlSessionLock {
|
|
||||||
id: sessionLock
|
|
||||||
locked: false
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
Qt.callLater(() => { locked = true })
|
|
||||||
}
|
|
||||||
|
|
||||||
onLockedChanged: {
|
|
||||||
if (!locked) {
|
|
||||||
console.log("Greetd session unlocked, exiting")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GreeterSurface {
|
|
||||||
lock: sessionLock
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
628
DMSShell.qml
628
DMSShell.qml
@@ -1,628 +0,0 @@
|
|||||||
//@ pragma Env QSG_RENDER_LOOP=threaded
|
|
||||||
//@ pragma UseQApplication
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import qs.Common
|
|
||||||
import qs.Modals
|
|
||||||
import qs.Modals.Clipboard
|
|
||||||
import qs.Modals.Common
|
|
||||||
import qs.Modals.Settings
|
|
||||||
import qs.Modals.Spotlight
|
|
||||||
import qs.Modules
|
|
||||||
import qs.Modules.AppDrawer
|
|
||||||
import qs.Modules.DankDash
|
|
||||||
import qs.Modules.ControlCenter
|
|
||||||
import qs.Modules.Dock
|
|
||||||
import qs.Modules.Lock
|
|
||||||
import qs.Modules.Notepad
|
|
||||||
import qs.Modules.Notifications.Center
|
|
||||||
import qs.Widgets
|
|
||||||
import qs.Modules.Notifications.Popup
|
|
||||||
import qs.Modules.OSD
|
|
||||||
import qs.Modules.ProcessList
|
|
||||||
import qs.Modules.Settings
|
|
||||||
import qs.Modules.DankBar
|
|
||||||
import qs.Modules.DankBar.Popouts
|
|
||||||
import qs.Modules.Plugins
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
|
|
||||||
ShellRoot {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
PortalService.init()
|
|
||||||
// Initialize DisplayService night mode functionality
|
|
||||||
DisplayService.nightModeEnabled
|
|
||||||
// Initialize WallpaperCyclingService
|
|
||||||
WallpaperCyclingService.cyclingActive
|
|
||||||
// Initialize PluginService by accessing its properties
|
|
||||||
PluginService.pluginDirectory
|
|
||||||
}
|
|
||||||
|
|
||||||
WallpaperBackground {}
|
|
||||||
|
|
||||||
Lock {
|
|
||||||
id: lock
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: dankBarLoader
|
|
||||||
asynchronous: false
|
|
||||||
|
|
||||||
property var currentPosition: SettingsData.dankBarPosition
|
|
||||||
|
|
||||||
sourceComponent: DankBar {
|
|
||||||
onColorPickerRequested: colorPickerModal.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
onCurrentPositionChanged: {
|
|
||||||
const component = sourceComponent
|
|
||||||
sourceComponent = null
|
|
||||||
Qt.callLater(() => {
|
|
||||||
sourceComponent = component
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: dockLoader
|
|
||||||
active: true
|
|
||||||
asynchronous: false
|
|
||||||
|
|
||||||
property var currentPosition: SettingsData.dockPosition
|
|
||||||
|
|
||||||
sourceComponent: Dock {
|
|
||||||
contextMenu: dockContextMenuLoader.item ? dockContextMenuLoader.item : null
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
if (item) {
|
|
||||||
dockContextMenuLoader.active = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onCurrentPositionChanged: {
|
|
||||||
console.log("DEBUG: Dock position changed to:", currentPosition, "- recreating dock")
|
|
||||||
const comp = sourceComponent
|
|
||||||
sourceComponent = null
|
|
||||||
Qt.callLater(() => {
|
|
||||||
sourceComponent = comp
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: dankDashPopoutLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
asynchronous: true
|
|
||||||
|
|
||||||
sourceComponent: Component {
|
|
||||||
DankDashPopout {
|
|
||||||
id: dankDashPopout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: dockContextMenuLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
DockContextMenu {
|
|
||||||
id: dockContextMenu
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: notificationCenterLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
NotificationCenterPopout {
|
|
||||||
id: notificationCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: SettingsData.getFilteredScreens("notifications")
|
|
||||||
|
|
||||||
delegate: NotificationPopupManager {
|
|
||||||
modelData: item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: controlCenterLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
property var modalRef: colorPickerModal
|
|
||||||
property LazyLoader powerModalLoaderRef: powerMenuModalLoader
|
|
||||||
|
|
||||||
ControlCenterPopout {
|
|
||||||
id: controlCenterPopout
|
|
||||||
colorPickerModal: controlCenterLoader.modalRef
|
|
||||||
powerMenuModalLoader: controlCenterLoader.powerModalLoaderRef
|
|
||||||
|
|
||||||
onLockRequested: {
|
|
||||||
lock.activate()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: wifiPasswordModalLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
WifiPasswordModal {
|
|
||||||
id: wifiPasswordModal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: networkInfoModalLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
NetworkInfoModal {
|
|
||||||
id: networkInfoModal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: batteryPopoutLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
BatteryPopout {
|
|
||||||
id: batteryPopout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: vpnPopoutLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
VpnPopout {
|
|
||||||
id: vpnPopout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: powerMenuLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
PowerMenu {
|
|
||||||
id: powerMenu
|
|
||||||
|
|
||||||
onPowerActionRequested: (action, title, message) => {
|
|
||||||
powerConfirmModalLoader.active = true
|
|
||||||
if (powerConfirmModalLoader.item) {
|
|
||||||
powerConfirmModalLoader.item.confirmButtonColor = action === "poweroff" ? Theme.error : action === "reboot" ? Theme.warning : Theme.primary
|
|
||||||
powerConfirmModalLoader.item.show(title, message, function () {
|
|
||||||
switch (action) {
|
|
||||||
case "logout":
|
|
||||||
SessionService.logout()
|
|
||||||
break
|
|
||||||
case "suspend":
|
|
||||||
SessionService.suspend()
|
|
||||||
break
|
|
||||||
case "hibernate":
|
|
||||||
SessionService.hibernate()
|
|
||||||
break
|
|
||||||
case "reboot":
|
|
||||||
SessionService.reboot()
|
|
||||||
break
|
|
||||||
case "poweroff":
|
|
||||||
SessionService.poweroff()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}, function () {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: powerConfirmModalLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
ConfirmModal {
|
|
||||||
id: powerConfirmModal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: processListPopoutLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
ProcessListPopout {
|
|
||||||
id: processListPopout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SettingsModal {
|
|
||||||
id: settingsModal
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: appDrawerLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
AppDrawerPopout {
|
|
||||||
id: appDrawerPopout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SpotlightModal {
|
|
||||||
id: spotlightModal
|
|
||||||
}
|
|
||||||
|
|
||||||
ClipboardHistoryModal {
|
|
||||||
id: clipboardHistoryModalPopup
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationModal {
|
|
||||||
id: notificationModal
|
|
||||||
}
|
|
||||||
ColorPickerModal {
|
|
||||||
id: colorPickerModal
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: processListModalLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
ProcessListModal {
|
|
||||||
id: processListModal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: systemUpdateLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
SystemUpdatePopout {
|
|
||||||
id: systemUpdatePopout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
id: notepadSlideoutVariants
|
|
||||||
model: SettingsData.getFilteredScreens("notepad")
|
|
||||||
|
|
||||||
delegate: DankSlideout {
|
|
||||||
id: notepadSlideout
|
|
||||||
modelData: item
|
|
||||||
title: qsTr("Notepad")
|
|
||||||
slideoutWidth: 480
|
|
||||||
expandable: true
|
|
||||||
expandedWidthValue: 960
|
|
||||||
customTransparency: SettingsData.notepadTransparencyOverride
|
|
||||||
|
|
||||||
content: Component {
|
|
||||||
Notepad {
|
|
||||||
onHideRequested: {
|
|
||||||
notepadSlideout.hide()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
if (isVisible) {
|
|
||||||
hide()
|
|
||||||
} else {
|
|
||||||
show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LazyLoader {
|
|
||||||
id: powerMenuModalLoader
|
|
||||||
|
|
||||||
active: false
|
|
||||||
|
|
||||||
PowerMenuModal {
|
|
||||||
id: powerMenuModal
|
|
||||||
|
|
||||||
onPowerActionRequested: (action, title, message) => {
|
|
||||||
powerConfirmModalLoader.active = true
|
|
||||||
if (powerConfirmModalLoader.item) {
|
|
||||||
powerConfirmModalLoader.item.confirmButtonColor = action === "poweroff" ? Theme.error : action === "reboot" ? Theme.warning : Theme.primary
|
|
||||||
powerConfirmModalLoader.item.show(title, message, function () {
|
|
||||||
switch (action) {
|
|
||||||
case "logout":
|
|
||||||
SessionService.logout()
|
|
||||||
break
|
|
||||||
case "suspend":
|
|
||||||
SessionService.suspend()
|
|
||||||
break
|
|
||||||
case "hibernate":
|
|
||||||
SessionService.hibernate()
|
|
||||||
break
|
|
||||||
case "reboot":
|
|
||||||
SessionService.reboot()
|
|
||||||
break
|
|
||||||
case "poweroff":
|
|
||||||
SessionService.poweroff()
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}, function () {})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
function open() {
|
|
||||||
powerMenuModalLoader.active = true
|
|
||||||
if (powerMenuModalLoader.item)
|
|
||||||
powerMenuModalLoader.item.openCentered()
|
|
||||||
|
|
||||||
return "POWERMENU_OPEN_SUCCESS"
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
if (powerMenuModalLoader.item)
|
|
||||||
powerMenuModalLoader.item.close()
|
|
||||||
|
|
||||||
return "POWERMENU_CLOSE_SUCCESS"
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle() {
|
|
||||||
powerMenuModalLoader.active = true
|
|
||||||
if (powerMenuModalLoader.item) {
|
|
||||||
if (powerMenuModalLoader.item.shouldBeVisible) {
|
|
||||||
powerMenuModalLoader.item.close()
|
|
||||||
} else {
|
|
||||||
powerMenuModalLoader.item.openCentered()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "POWERMENU_TOGGLE_SUCCESS"
|
|
||||||
}
|
|
||||||
|
|
||||||
target: "powermenu"
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
function open(): string {
|
|
||||||
processListModalLoader.active = true
|
|
||||||
if (processListModalLoader.item)
|
|
||||||
processListModalLoader.item.show()
|
|
||||||
|
|
||||||
return "PROCESSLIST_OPEN_SUCCESS"
|
|
||||||
}
|
|
||||||
|
|
||||||
function close(): string {
|
|
||||||
if (processListModalLoader.item)
|
|
||||||
processListModalLoader.item.hide()
|
|
||||||
|
|
||||||
return "PROCESSLIST_CLOSE_SUCCESS"
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(): string {
|
|
||||||
processListModalLoader.active = true
|
|
||||||
if (processListModalLoader.item)
|
|
||||||
processListModalLoader.item.toggle()
|
|
||||||
|
|
||||||
return "PROCESSLIST_TOGGLE_SUCCESS"
|
|
||||||
}
|
|
||||||
|
|
||||||
target: "processlist"
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
function open(): string {
|
|
||||||
controlCenterLoader.active = true
|
|
||||||
if (controlCenterLoader.item) {
|
|
||||||
controlCenterLoader.item.open()
|
|
||||||
return "CONTROL_CENTER_OPEN_SUCCESS"
|
|
||||||
}
|
|
||||||
return "CONTROL_CENTER_OPEN_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
function close(): string {
|
|
||||||
if (controlCenterLoader.item) {
|
|
||||||
controlCenterLoader.item.close()
|
|
||||||
return "CONTROL_CENTER_CLOSE_SUCCESS"
|
|
||||||
}
|
|
||||||
return "CONTROL_CENTER_CLOSE_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(): string {
|
|
||||||
controlCenterLoader.active = true
|
|
||||||
if (controlCenterLoader.item) {
|
|
||||||
controlCenterLoader.item.toggle()
|
|
||||||
return "CONTROL_CENTER_TOGGLE_SUCCESS"
|
|
||||||
}
|
|
||||||
return "CONTROL_CENTER_TOGGLE_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
target: "control-center"
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
function open(tab: string): string {
|
|
||||||
dankDashPopoutLoader.active = true
|
|
||||||
if (dankDashPopoutLoader.item) {
|
|
||||||
switch (tab.toLowerCase()) {
|
|
||||||
case "media":
|
|
||||||
dankDashPopoutLoader.item.currentTabIndex = 1
|
|
||||||
break
|
|
||||||
case "weather":
|
|
||||||
dankDashPopoutLoader.item.currentTabIndex = SettingsData.weatherEnabled ? 2 : 0
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
dankDashPopoutLoader.item.currentTabIndex = 0
|
|
||||||
break
|
|
||||||
}
|
|
||||||
dankDashPopoutLoader.item.setTriggerPosition(Screen.width / 2, Theme.barHeight + Theme.spacingS, 100, "center", Screen)
|
|
||||||
dankDashPopoutLoader.item.dashVisible = true
|
|
||||||
return "DASH_OPEN_SUCCESS"
|
|
||||||
}
|
|
||||||
return "DASH_OPEN_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
function close(): string {
|
|
||||||
if (dankDashPopoutLoader.item) {
|
|
||||||
dankDashPopoutLoader.item.dashVisible = false
|
|
||||||
return "DASH_CLOSE_SUCCESS"
|
|
||||||
}
|
|
||||||
return "DASH_CLOSE_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(tab: string): string {
|
|
||||||
dankDashPopoutLoader.active = true
|
|
||||||
if (dankDashPopoutLoader.item) {
|
|
||||||
if (dankDashPopoutLoader.item.dashVisible) {
|
|
||||||
dankDashPopoutLoader.item.dashVisible = false
|
|
||||||
} else {
|
|
||||||
switch (tab.toLowerCase()) {
|
|
||||||
case "media":
|
|
||||||
dankDashPopoutLoader.item.currentTabIndex = 1
|
|
||||||
break
|
|
||||||
case "weather":
|
|
||||||
dankDashPopoutLoader.item.currentTabIndex = SettingsData.weatherEnabled ? 2 : 0
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
dankDashPopoutLoader.item.currentTabIndex = 0
|
|
||||||
break
|
|
||||||
}
|
|
||||||
dankDashPopoutLoader.item.setTriggerPosition(Screen.width / 2, Theme.barHeight + Theme.spacingS, 100, "center", Screen)
|
|
||||||
dankDashPopoutLoader.item.dashVisible = true
|
|
||||||
}
|
|
||||||
return "DASH_TOGGLE_SUCCESS"
|
|
||||||
}
|
|
||||||
return "DASH_TOGGLE_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
target: "dash"
|
|
||||||
}
|
|
||||||
|
|
||||||
IpcHandler {
|
|
||||||
function getFocusedScreenName() {
|
|
||||||
if (CompositorService.isHyprland && Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.monitor) {
|
|
||||||
return Hyprland.focusedWorkspace.monitor.name
|
|
||||||
}
|
|
||||||
if (CompositorService.isNiri && NiriService.currentOutput) {
|
|
||||||
return NiriService.currentOutput
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function getActiveNotepadInstance() {
|
|
||||||
if (notepadSlideoutVariants.instances.length === 0) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (notepadSlideoutVariants.instances.length === 1) {
|
|
||||||
return notepadSlideoutVariants.instances[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
var focusedScreen = getFocusedScreenName()
|
|
||||||
if (focusedScreen && notepadSlideoutVariants.instances.length > 0) {
|
|
||||||
for (var i = 0; i < notepadSlideoutVariants.instances.length; i++) {
|
|
||||||
var slideout = notepadSlideoutVariants.instances[i]
|
|
||||||
if (slideout.modelData && slideout.modelData.name === focusedScreen) {
|
|
||||||
return slideout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = 0; i < notepadSlideoutVariants.instances.length; i++) {
|
|
||||||
var slideout = notepadSlideoutVariants.instances[i]
|
|
||||||
if (slideout.isVisible) {
|
|
||||||
return slideout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return notepadSlideoutVariants.instances[0]
|
|
||||||
}
|
|
||||||
|
|
||||||
function open(): string {
|
|
||||||
var instance = getActiveNotepadInstance()
|
|
||||||
if (instance) {
|
|
||||||
instance.show()
|
|
||||||
return "NOTEPAD_OPEN_SUCCESS"
|
|
||||||
}
|
|
||||||
return "NOTEPAD_OPEN_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
function close(): string {
|
|
||||||
var instance = getActiveNotepadInstance()
|
|
||||||
if (instance) {
|
|
||||||
instance.hide()
|
|
||||||
return "NOTEPAD_CLOSE_SUCCESS"
|
|
||||||
}
|
|
||||||
return "NOTEPAD_CLOSE_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggle(): string {
|
|
||||||
var instance = getActiveNotepadInstance()
|
|
||||||
if (instance) {
|
|
||||||
instance.toggle()
|
|
||||||
return "NOTEPAD_TOGGLE_SUCCESS"
|
|
||||||
}
|
|
||||||
return "NOTEPAD_TOGGLE_FAILED"
|
|
||||||
}
|
|
||||||
|
|
||||||
target: "notepad"
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: SettingsData.getFilteredScreens("toast")
|
|
||||||
|
|
||||||
delegate: Toast {
|
|
||||||
modelData: item
|
|
||||||
visible: ToastService.toastVisible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: SettingsData.getFilteredScreens("osd")
|
|
||||||
|
|
||||||
delegate: VolumeOSD {
|
|
||||||
modelData: item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: SettingsData.getFilteredScreens("osd")
|
|
||||||
|
|
||||||
delegate: MicMuteOSD {
|
|
||||||
modelData: item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: SettingsData.getFilteredScreens("osd")
|
|
||||||
|
|
||||||
delegate: BrightnessOSD {
|
|
||||||
modelData: item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Variants {
|
|
||||||
model: SettingsData.getFilteredScreens("osd")
|
|
||||||
|
|
||||||
delegate: IdleInhibitorOSD {
|
|
||||||
modelData: item
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -77,12 +77,15 @@ Item {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - ClipboardConstants.headerHeight - 70
|
height: parent.height - ClipboardConstants.headerHeight - 70
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: "transparent"
|
color: Theme.surfaceLight
|
||||||
|
border.color: Theme.outlineLight
|
||||||
|
border.width: 1
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
DankListView {
|
DankListView {
|
||||||
id: clipboardListView
|
id: clipboardListView
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.spacingS
|
||||||
model: filteredModel
|
model: filteredModel
|
||||||
|
|
||||||
currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0
|
currentIndex: clipboardContent.modal ? clipboardContent.modal.selectedIndex : 0
|
||||||
|
|||||||
@@ -24,10 +24,17 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: {
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
return Theme.primaryPressed
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2)
|
||||||
}
|
}
|
||||||
return mouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceContainerHigh
|
return mouseArea.containsMouse ? Theme.primaryHover : Theme.primaryBackground
|
||||||
}
|
}
|
||||||
|
border.color: {
|
||||||
|
if (isSelected) {
|
||||||
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.5)
|
||||||
|
}
|
||||||
|
return Theme.outlineStrong
|
||||||
|
}
|
||||||
|
border.width: isSelected ? 1.5 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ QtObject {
|
|||||||
modal.hide()
|
modal.hide()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_Tab) {
|
} else if (event.key === Qt.Key_Down) {
|
||||||
if (!modal.keyboardNavigationActive) {
|
if (!modal.keyboardNavigationActive) {
|
||||||
modal.keyboardNavigationActive = true
|
modal.keyboardNavigationActive = true
|
||||||
modal.selectedIndex = 0
|
modal.selectedIndex = 0
|
||||||
@@ -62,7 +62,7 @@ QtObject {
|
|||||||
selectNext()
|
selectNext()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_Up || event.key === Qt.Key_Backtab) {
|
} else if (event.key === Qt.Key_Up) {
|
||||||
if (!modal.keyboardNavigationActive) {
|
if (!modal.keyboardNavigationActive) {
|
||||||
modal.keyboardNavigationActive = true
|
modal.keyboardNavigationActive = true
|
||||||
modal.selectedIndex = 0
|
modal.selectedIndex = 0
|
||||||
@@ -74,42 +74,6 @@ QtObject {
|
|||||||
selectPrevious()
|
selectPrevious()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!modal.keyboardNavigationActive) {
|
|
||||||
modal.keyboardNavigationActive = true
|
|
||||||
modal.selectedIndex = 0
|
|
||||||
} else {
|
|
||||||
selectNext()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!modal.keyboardNavigationActive) {
|
|
||||||
modal.keyboardNavigationActive = true
|
|
||||||
modal.selectedIndex = 0
|
|
||||||
} else if (modal.selectedIndex === 0) {
|
|
||||||
modal.keyboardNavigationActive = false
|
|
||||||
} else {
|
|
||||||
selectPrevious()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!modal.keyboardNavigationActive) {
|
|
||||||
modal.keyboardNavigationActive = true
|
|
||||||
modal.selectedIndex = 0
|
|
||||||
} else {
|
|
||||||
selectNext()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!modal.keyboardNavigationActive) {
|
|
||||||
modal.keyboardNavigationActive = true
|
|
||||||
modal.selectedIndex = 0
|
|
||||||
} else if (modal.selectedIndex === 0) {
|
|
||||||
modal.keyboardNavigationActive = false
|
|
||||||
} else {
|
|
||||||
selectPrevious()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_Delete && (event.modifiers & Qt.ShiftModifier)) {
|
} else if (event.key === Qt.Key_Delete && (event.modifiers & Qt.ShiftModifier)) {
|
||||||
modal.clearAll()
|
modal.clearAll()
|
||||||
modal.hide()
|
modal.hide()
|
||||||
|
|||||||
@@ -93,48 +93,6 @@ DankModal {
|
|||||||
selectedButton = 1
|
selectedButton = 1
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
break
|
break
|
||||||
case Qt.Key_N:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
keyboardNavigation = true
|
|
||||||
selectedButton = (selectedButton + 1) % 2
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_P:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
keyboardNavigation = true
|
|
||||||
selectedButton = selectedButton === -1 ? 1 : (selectedButton - 1 + 2) % 2
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_J:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
keyboardNavigation = true
|
|
||||||
selectedButton = 1
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_K:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
keyboardNavigation = true
|
|
||||||
selectedButton = 0
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_H:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
keyboardNavigation = true
|
|
||||||
selectedButton = 0
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_L:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
keyboardNavigation = true
|
|
||||||
selectedButton = 1
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_Tab:
|
case Qt.Key_Tab:
|
||||||
keyboardNavigation = true
|
keyboardNavigation = true
|
||||||
selectedButton = selectedButton === -1 ? 0 : (selectedButton + 1) % 2
|
selectedButton = selectedButton === -1 ? 0 : (selectedButton + 1) % 2
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ PanelWindow {
|
|||||||
property bool closeOnEscapeKey: true
|
property bool closeOnEscapeKey: true
|
||||||
property bool closeOnBackgroundClick: true
|
property bool closeOnBackgroundClick: true
|
||||||
property string animationType: "scale"
|
property string animationType: "scale"
|
||||||
property int animationDuration: Theme.shortDuration
|
property int animationDuration: Theme.shorterDuration
|
||||||
property var animationEasing: Theme.emphasizedEasing
|
property var animationEasing: Theme.emphasizedEasing
|
||||||
property color backgroundColor: Theme.surfaceContainer
|
property color backgroundColor: Theme.surfaceContainer
|
||||||
property color borderColor: Theme.outlineMedium
|
property color borderColor: Theme.outlineMedium
|
||||||
@@ -34,7 +34,6 @@ PanelWindow {
|
|||||||
property bool shouldHaveFocus: shouldBeVisible
|
property bool shouldHaveFocus: shouldBeVisible
|
||||||
property bool allowFocusOverride: false
|
property bool allowFocusOverride: false
|
||||||
property bool allowStacking: false
|
property bool allowStacking: false
|
||||||
property bool keepContentLoaded: false
|
|
||||||
|
|
||||||
signal opened
|
signal opened
|
||||||
signal dialogClosed
|
signal dialogClosed
|
||||||
@@ -91,7 +90,7 @@ PanelWindow {
|
|||||||
Timer {
|
Timer {
|
||||||
id: closeTimer
|
id: closeTimer
|
||||||
|
|
||||||
interval: animationDuration + 100
|
interval: animationDuration + 50
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
visible = false
|
visible = false
|
||||||
}
|
}
|
||||||
@@ -157,7 +156,9 @@ PanelWindow {
|
|||||||
radius: root.cornerRadius
|
radius: root.cornerRadius
|
||||||
border.color: root.borderColor
|
border.color: root.borderColor
|
||||||
border.width: root.borderWidth
|
border.width: root.borderWidth
|
||||||
layer.enabled: true
|
layer.enabled: root.enableShadow
|
||||||
|
opacity: root.shouldBeVisible ? 1 : 0
|
||||||
|
scale: root.animationType === "scale" ? (root.shouldBeVisible ? 1 : 0.9) : 1
|
||||||
transform: root.animationType === "slide" ? slideTransform : null
|
transform: root.animationType === "slide" ? slideTransform : null
|
||||||
|
|
||||||
Translate {
|
Translate {
|
||||||
@@ -171,10 +172,26 @@ PanelWindow {
|
|||||||
id: contentLoader
|
id: contentLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.keepContentLoaded || root.shouldBeVisible || root.visible
|
active: root.visible
|
||||||
asynchronous: false
|
asynchronous: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: root.animationDuration
|
||||||
|
easing.type: root.animationEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on scale {
|
||||||
|
enabled: root.animationType === "scale"
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
duration: root.animationDuration
|
||||||
|
easing.type: root.animationEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: true
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
@@ -182,15 +199,6 @@ PanelWindow {
|
|||||||
shadowBlur: 1
|
shadowBlur: 1
|
||||||
shadowColor: Theme.shadowStrong
|
shadowColor: Theme.shadowStrong
|
||||||
shadowOpacity: 0.3
|
shadowOpacity: 0.3
|
||||||
source: contentContainer
|
|
||||||
opacity: root.shouldBeVisible ? 1 : 0
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: animationDuration
|
|
||||||
easing.type: animationEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,8 +207,8 @@ PanelWindow {
|
|||||||
|
|
||||||
objectName: "modalFocusScope"
|
objectName: "modalFocusScope"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: root.shouldBeVisible || root.visible
|
visible: root.visible // Only active when the modal is visible
|
||||||
focus: root.shouldBeVisible
|
focus: root.visible
|
||||||
Keys.onEscapePressed: event => {
|
Keys.onEscapePressed: event => {
|
||||||
if (root.closeOnEscapeKey && shouldHaveFocus) {
|
if (root.closeOnEscapeKey && shouldHaveFocus) {
|
||||||
root.close()
|
root.close()
|
||||||
@@ -215,7 +223,7 @@ PanelWindow {
|
|||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onShouldHaveFocusChanged() {
|
function onShouldHaveFocusChanged() {
|
||||||
if (shouldHaveFocus && shouldBeVisible) {
|
if (shouldHaveFocus && visible) {
|
||||||
Qt.callLater(() => focusScope.forceActiveFocus())
|
Qt.callLater(() => focusScope.forceActiveFocus())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -239,12 +239,7 @@ DankModal {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!keyboardNavigationActive) {
|
if (!keyboardNavigationActive) {
|
||||||
const isInitKey = event.key === Qt.Key_Tab || event.key === Qt.Key_Down || event.key === Qt.Key_Right ||
|
if (event.key === Qt.Key_Tab || event.key === Qt.Key_Down || event.key === Qt.Key_Right) {
|
||||||
(event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) ||
|
|
||||||
(event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) ||
|
|
||||||
(event.key === Qt.Key_L && event.modifiers & Qt.ControlModifier)
|
|
||||||
|
|
||||||
if (isInitKey) {
|
|
||||||
keyboardNavigationActive = true
|
keyboardNavigationActive = true
|
||||||
if (currentPath !== homeDir) {
|
if (currentPath !== homeDir) {
|
||||||
backButtonFocused = true
|
backButtonFocused = true
|
||||||
@@ -286,69 +281,6 @@ DankModal {
|
|||||||
}
|
}
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
break
|
break
|
||||||
case Qt.Key_N:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (backButtonFocused) {
|
|
||||||
backButtonFocused = false
|
|
||||||
selectedIndex = 0
|
|
||||||
} else if (selectedIndex < totalItems - 1) {
|
|
||||||
selectedIndex++
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_P:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (selectedIndex > 0) {
|
|
||||||
selectedIndex--
|
|
||||||
} else if (currentPath !== homeDir) {
|
|
||||||
backButtonFocused = true
|
|
||||||
selectedIndex = -1
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_J:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (selectedIndex < totalItems - 1) {
|
|
||||||
selectedIndex++
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_K:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (selectedIndex > 0) {
|
|
||||||
selectedIndex--
|
|
||||||
} else if (currentPath !== homeDir) {
|
|
||||||
backButtonFocused = true
|
|
||||||
selectedIndex = -1
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_H:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!backButtonFocused && selectedIndex > 0) {
|
|
||||||
selectedIndex--
|
|
||||||
} else if (currentPath !== homeDir) {
|
|
||||||
backButtonFocused = true
|
|
||||||
selectedIndex = -1
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_L:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (backButtonFocused) {
|
|
||||||
backButtonFocused = false
|
|
||||||
selectedIndex = 0
|
|
||||||
} else if (selectedIndex < totalItems - 1) {
|
|
||||||
selectedIndex++
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
}
|
|
||||||
break
|
|
||||||
case Qt.Key_Left:
|
case Qt.Key_Left:
|
||||||
if (backButtonFocused)
|
if (backButtonFocused)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -9,25 +9,9 @@ DankModal {
|
|||||||
|
|
||||||
property int selectedIndex: 0
|
property int selectedIndex: 0
|
||||||
property int optionCount: SessionService.hibernateSupported ? 5 : 4
|
property int optionCount: SessionService.hibernateSupported ? 5 : 4
|
||||||
property rect parentBounds: Qt.rect(0, 0, 0, 0)
|
|
||||||
property var parentScreen: null
|
|
||||||
|
|
||||||
signal powerActionRequested(string action, string title, string message)
|
signal powerActionRequested(string action, string title, string message)
|
||||||
|
|
||||||
function openCentered() {
|
|
||||||
parentBounds = Qt.rect(0, 0, 0, 0)
|
|
||||||
parentScreen = null
|
|
||||||
backgroundOpacity = 0.5
|
|
||||||
open()
|
|
||||||
}
|
|
||||||
|
|
||||||
function openFromControlCenter(bounds, targetScreen) {
|
|
||||||
parentBounds = bounds
|
|
||||||
parentScreen = targetScreen
|
|
||||||
backgroundOpacity = 0
|
|
||||||
open()
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectOption(action) {
|
function selectOption(action) {
|
||||||
close();
|
close();
|
||||||
const actions = {
|
const actions = {
|
||||||
@@ -63,16 +47,6 @@ DankModal {
|
|||||||
width: 320
|
width: 320
|
||||||
height: contentLoader.item ? contentLoader.item.implicitHeight : 300
|
height: contentLoader.item ? contentLoader.item.implicitHeight : 300
|
||||||
enableShadow: true
|
enableShadow: true
|
||||||
screen: parentScreen
|
|
||||||
positioning: parentBounds.width > 0 ? "custom" : "center"
|
|
||||||
customPosition: {
|
|
||||||
if (parentBounds.width > 0) {
|
|
||||||
const centerX = parentBounds.x + (parentBounds.width - width) / 2
|
|
||||||
const centerY = parentBounds.y + (parentBounds.height - height) / 2
|
|
||||||
return Qt.point(centerX, centerY)
|
|
||||||
}
|
|
||||||
return Qt.point(0, 0)
|
|
||||||
}
|
|
||||||
onBackgroundClicked: () => {
|
onBackgroundClicked: () => {
|
||||||
return close();
|
return close();
|
||||||
}
|
}
|
||||||
@@ -83,11 +57,13 @@ DankModal {
|
|||||||
modalFocusScope.Keys.onPressed: (event) => {
|
modalFocusScope.Keys.onPressed: (event) => {
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case Qt.Key_Up:
|
case Qt.Key_Up:
|
||||||
case Qt.Key_Backtab:
|
|
||||||
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount;
|
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount;
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
break;
|
break;
|
||||||
case Qt.Key_Down:
|
case Qt.Key_Down:
|
||||||
|
selectedIndex = (selectedIndex + 1) % optionCount;
|
||||||
|
event.accepted = true;
|
||||||
|
break;
|
||||||
case Qt.Key_Tab:
|
case Qt.Key_Tab:
|
||||||
selectedIndex = (selectedIndex + 1) % optionCount;
|
selectedIndex = (selectedIndex + 1) % optionCount;
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
@@ -102,30 +78,6 @@ DankModal {
|
|||||||
}
|
}
|
||||||
event.accepted = true;
|
event.accepted = true;
|
||||||
break;
|
break;
|
||||||
case Qt.Key_N:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
selectedIndex = (selectedIndex + 1) % optionCount;
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt.Key_P:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount;
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt.Key_J:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
selectedIndex = (selectedIndex + 1) % optionCount;
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case Qt.Key_K:
|
|
||||||
if (event.modifiers & Qt.ControlModifier) {
|
|
||||||
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount;
|
|
||||||
event.accepted = true;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,6 +79,7 @@ Item {
|
|||||||
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
||||||
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
text: "Automatically lock after"
|
text: "Automatically lock after"
|
||||||
options: timeoutOptions
|
options: timeoutOptions
|
||||||
|
|
||||||
@@ -115,6 +116,7 @@ Item {
|
|||||||
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
||||||
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
text: "Turn off monitors after"
|
text: "Turn off monitors after"
|
||||||
options: timeoutOptions
|
options: timeoutOptions
|
||||||
|
|
||||||
@@ -151,6 +153,7 @@ Item {
|
|||||||
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
||||||
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
text: "Suspend system after"
|
text: "Suspend system after"
|
||||||
options: timeoutOptions
|
options: timeoutOptions
|
||||||
|
|
||||||
@@ -187,6 +190,7 @@ Item {
|
|||||||
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
property var timeoutOptions: ["Never", "1 minute", "2 minutes", "3 minutes", "5 minutes", "10 minutes", "15 minutes", "20 minutes", "30 minutes", "1 hour", "1 hour 30 minutes", "2 hours", "3 hours"]
|
||||||
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
property var timeoutValues: [0, 60, 120, 180, 300, 600, 900, 1200, 1800, 3600, 5400, 7200, 10800]
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
text: "Hibernate system after"
|
text: "Hibernate system after"
|
||||||
options: timeoutOptions
|
options: timeoutOptions
|
||||||
visible: SessionService.hibernateSupported
|
visible: SessionService.hibernateSupported
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ Item {
|
|||||||
visible: active
|
visible: active
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
sourceComponent: DankBarTab {
|
sourceComponent: TopBarTab {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -153,24 +153,11 @@ Item {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: pluginsLoader
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
active: root.currentIndex === 10
|
|
||||||
visible: active
|
|
||||||
asynchronous: true
|
|
||||||
|
|
||||||
sourceComponent: PluginsTab {
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: aboutLoader
|
id: aboutLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.currentIndex === 11
|
active: root.currentIndex === 10
|
||||||
visible: active
|
visible: active
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ DankModal {
|
|||||||
|
|
||||||
objectName: "settingsModal"
|
objectName: "settingsModal"
|
||||||
width: 800
|
width: 800
|
||||||
height: 800
|
height: 750
|
||||||
visible: false
|
visible: false
|
||||||
onBackgroundClicked: () => {
|
onBackgroundClicked: () => {
|
||||||
return hide();
|
return hide();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Rectangle {
|
|||||||
"text": "Weather",
|
"text": "Weather",
|
||||||
"icon": "cloud"
|
"icon": "cloud"
|
||||||
}, {
|
}, {
|
||||||
"text": "Dank Bar",
|
"text": "Top Bar",
|
||||||
"icon": "toolbar"
|
"icon": "toolbar"
|
||||||
}, {
|
}, {
|
||||||
"text": "Widgets",
|
"text": "Widgets",
|
||||||
@@ -38,9 +38,6 @@ Rectangle {
|
|||||||
}, {
|
}, {
|
||||||
"text": "Power",
|
"text": "Power",
|
||||||
"icon": "power_settings_new"
|
"icon": "power_settings_new"
|
||||||
}, {
|
|
||||||
"text": "Plugins",
|
|
||||||
"icon": "extension"
|
|
||||||
}, {
|
}, {
|
||||||
"text": "About",
|
"text": "About",
|
||||||
"icon": "info"
|
"icon": "info"
|
||||||
@@ -86,7 +83,7 @@ Rectangle {
|
|||||||
width: parent.width - Theme.spacingS * 2
|
width: parent.width - Theme.spacingS * 2
|
||||||
height: 44
|
height: 44
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: isActive ? Theme.primary : tabMouseArea.containsMouse ? Theme.surfaceHover : "transparent"
|
color: isActive ? Theme.primaryContainer : tabMouseArea.containsMouse ? Theme.surfaceHover : "transparent"
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -97,14 +94,14 @@ Rectangle {
|
|||||||
DankIcon {
|
DankIcon {
|
||||||
name: modelData.icon || ""
|
name: modelData.icon || ""
|
||||||
size: Theme.iconSize - 2
|
size: Theme.iconSize - 2
|
||||||
color: parent.parent.isActive ? Theme.primaryText : Theme.surfaceText
|
color: parent.parent.isActive ? Theme.surfaceText : Theme.surfaceText
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: modelData.text || ""
|
text: modelData.text || ""
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: parent.parent.isActive ? Theme.primaryText : Theme.surfaceText
|
color: parent.parent.isActive ? Theme.surfaceText : Theme.surfaceText
|
||||||
font.weight: parent.parent.isActive ? Font.Medium : Font.Normal
|
font.weight: parent.parent.isActive ? Font.Medium : Font.Normal
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,46 +33,6 @@ Item {
|
|||||||
} else if (event.key === Qt.Key_Left && appLauncher.viewMode === "grid") {
|
} else if (event.key === Qt.Key_Left && appLauncher.viewMode === "grid") {
|
||||||
appLauncher.selectPreviousInRow()
|
appLauncher.selectPreviousInRow()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key == Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectNext()
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key == Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectPrevious()
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key == Qt.Key_L && event.modifiers & Qt.ControlModifier && appLauncher.viewMode === "grid") {
|
|
||||||
appLauncher.selectNextInRow()
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key == Qt.Key_H && event.modifiers & Qt.ControlModifier && appLauncher.viewMode === "grid") {
|
|
||||||
appLauncher.selectPreviousInRow()
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_Tab) {
|
|
||||||
if (appLauncher.viewMode === "grid") {
|
|
||||||
appLauncher.selectNextInRow()
|
|
||||||
} else {
|
|
||||||
appLauncher.selectNext()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_Backtab) {
|
|
||||||
if (appLauncher.viewMode === "grid") {
|
|
||||||
appLauncher.selectPreviousInRow()
|
|
||||||
} else {
|
|
||||||
appLauncher.selectPrevious()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (appLauncher.viewMode === "grid") {
|
|
||||||
appLauncher.selectNextInRow()
|
|
||||||
} else {
|
|
||||||
appLauncher.selectNext()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (appLauncher.viewMode === "grid") {
|
|
||||||
appLauncher.selectPreviousInRow()
|
|
||||||
} else {
|
|
||||||
appLauncher.selectPrevious()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
} else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
|
||||||
appLauncher.launchSelected()
|
appLauncher.launchSelected()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
@@ -99,21 +59,23 @@ Item {
|
|||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingM
|
anchors.margins: Theme.spacingL
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: categorySelector.height + Theme.spacingS * 2
|
height: categorySelector.height + Theme.spacingM * 2
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: "transparent"
|
color: Theme.surfaceVariantAlpha
|
||||||
|
border.color: Theme.outlineMedium
|
||||||
|
border.width: 1
|
||||||
visible: appLauncher.categories.length > 1 || appLauncher.model.count > 0
|
visible: appLauncher.categories.length > 1 || appLauncher.model.count > 0
|
||||||
|
|
||||||
CategorySelector {
|
CategorySelector {
|
||||||
id: categorySelector
|
id: categorySelector
|
||||||
|
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: parent.width - Theme.spacingS * 2
|
width: parent.width - Theme.spacingM * 2
|
||||||
categories: appLauncher.categories
|
categories: appLauncher.categories
|
||||||
selectedCategory: appLauncher.selectedCategory
|
selectedCategory: appLauncher.selectedCategory
|
||||||
compact: false
|
compact: false
|
||||||
@@ -126,12 +88,11 @@ Item {
|
|||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
leftPadding: Theme.spacingS
|
|
||||||
|
|
||||||
DankTextField {
|
DankTextField {
|
||||||
id: searchField
|
id: searchField
|
||||||
|
|
||||||
width: parent.width - 80 - Theme.spacingL
|
width: parent.width - 80 - Theme.spacingM
|
||||||
height: 56
|
height: 56
|
||||||
cornerRadius: Theme.cornerRadius
|
cornerRadius: Theme.cornerRadius
|
||||||
backgroundColor: Theme.surfaceContainerHigh
|
backgroundColor: Theme.surfaceContainerHigh
|
||||||
@@ -164,7 +125,7 @@ Item {
|
|||||||
else if (appLauncher.model.count > 0)
|
else if (appLauncher.model.count > 0)
|
||||||
appLauncher.launchApp(appLauncher.model.get(0))
|
appLauncher.launchApp(appLauncher.model.get(0))
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || event.key === Qt.Key_Left || event.key === Qt.Key_Right || event.key === Qt.Key_Tab || event.key === Qt.Key_Backtab || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) {
|
} else if (event.key === Qt.Key_Down || event.key === Qt.Key_Up || event.key === Qt.Key_Left || event.key === Qt.Key_Right || ((event.key === Qt.Key_Return || event.key === Qt.Key_Enter) && text.length === 0)) {
|
||||||
event.accepted = false
|
event.accepted = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -180,6 +141,8 @@ Item {
|
|||||||
height: 36
|
height: 36
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: appLauncher.viewMode === "list" ? Theme.primaryHover : listViewArea.containsMouse ? Theme.surfaceHover : "transparent"
|
color: appLauncher.viewMode === "list" ? Theme.primaryHover : listViewArea.containsMouse ? Theme.surfaceHover : "transparent"
|
||||||
|
border.color: appLauncher.viewMode === "list" ? Theme.primarySelected : "transparent"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -205,6 +168,8 @@ Item {
|
|||||||
height: 36
|
height: 36
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: appLauncher.viewMode === "grid" ? Theme.primaryHover : gridViewArea.containsMouse ? Theme.surfaceHover : "transparent"
|
color: appLauncher.viewMode === "grid" ? Theme.primaryHover : gridViewArea.containsMouse ? Theme.surfaceHover : "transparent"
|
||||||
|
border.color: appLauncher.viewMode === "grid" ? Theme.primarySelected : "transparent"
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|||||||
@@ -32,7 +32,11 @@ DankModal {
|
|||||||
function hide() {
|
function hide() {
|
||||||
spotlightOpen = false
|
spotlightOpen = false
|
||||||
close()
|
close()
|
||||||
cleanupTimer.restart()
|
if (contentLoader.item && contentLoader.item.appLauncher) {
|
||||||
|
contentLoader.item.appLauncher.searchQuery = ""
|
||||||
|
contentLoader.item.appLauncher.selectedIndex = 0
|
||||||
|
contentLoader.item.appLauncher.setCategory("All")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle() {
|
function toggle() {
|
||||||
@@ -51,7 +55,6 @@ DankModal {
|
|||||||
borderColor: Theme.outlineMedium
|
borderColor: Theme.outlineMedium
|
||||||
borderWidth: 1
|
borderWidth: 1
|
||||||
enableShadow: true
|
enableShadow: true
|
||||||
keepContentLoaded: true
|
|
||||||
onVisibleChanged: () => {
|
onVisibleChanged: () => {
|
||||||
if (visible && !spotlightOpen) {
|
if (visible && !spotlightOpen) {
|
||||||
show()
|
show()
|
||||||
@@ -69,19 +72,6 @@ DankModal {
|
|||||||
}
|
}
|
||||||
content: spotlightContent
|
content: spotlightContent
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: cleanupTimer
|
|
||||||
|
|
||||||
interval: animationDuration + 50
|
|
||||||
onTriggered: {
|
|
||||||
if (contentLoader.item && contentLoader.item.appLauncher) {
|
|
||||||
contentLoader.item.appLauncher.searchQuery = ""
|
|
||||||
contentLoader.item.appLauncher.selectedIndex = 0
|
|
||||||
contentLoader.item.appLauncher.setCategory("All")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onCloseAllModalsExcept(excludedModal) {
|
function onCloseAllModalsExcept(excludedModal) {
|
||||||
if (excludedModal !== spotlightModal && !allowStacking && spotlightOpen) {
|
if (excludedModal !== spotlightModal && !allowStacking && spotlightOpen) {
|
||||||
|
|||||||
@@ -13,7 +13,9 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: parent.height - y
|
height: parent.height - y
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: "transparent"
|
color: Theme.surfaceContainerHigh
|
||||||
|
border.color: Theme.outlineLight
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
DankListView {
|
DankListView {
|
||||||
id: resultsList
|
id: resultsList
|
||||||
@@ -73,7 +75,9 @@ Rectangle {
|
|||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
height: resultsList.itemHeight
|
height: resultsList.itemHeight
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: ListView.isCurrentItem ? Theme.primaryPressed : listMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceContainerHigh
|
color: ListView.isCurrentItem ? Theme.primaryPressed : listMouseArea.containsMouse ? Theme.primaryHoverLight : "transparent"
|
||||||
|
border.color: ListView.isCurrentItem ? Theme.primarySelected : Theme.outlineMedium
|
||||||
|
border.width: ListView.isCurrentItem ? 2 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -234,7 +238,9 @@ Rectangle {
|
|||||||
width: resultsGrid.cellWidth - resultsGrid.cellPadding
|
width: resultsGrid.cellWidth - resultsGrid.cellPadding
|
||||||
height: resultsGrid.cellHeight - resultsGrid.cellPadding
|
height: resultsGrid.cellHeight - resultsGrid.cellPadding
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: resultsGrid.currentIndex === index ? Theme.primaryPressed : gridMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceContainerHigh
|
color: resultsGrid.currentIndex === index ? Theme.primaryPressed : gridMouseArea.containsMouse ? Theme.primaryHoverLight : "transparent"
|
||||||
|
border.color: resultsGrid.currentIndex === index ? Theme.primarySelected : Theme.outlineMedium
|
||||||
|
border.width: resultsGrid.currentIndex === index ? 2 : 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import qs.Widgets
|
|||||||
DankPopout {
|
DankPopout {
|
||||||
id: appDrawerPopout
|
id: appDrawerPopout
|
||||||
|
|
||||||
|
property string triggerSection: "left"
|
||||||
property var triggerScreen: null
|
property var triggerScreen: null
|
||||||
|
|
||||||
// Setting to Exclusive, so virtual keyboards can send input to app drawer
|
// Setting to Exclusive, so virtual keyboards can send input to app drawer
|
||||||
@@ -32,9 +33,9 @@ DankPopout {
|
|||||||
popupWidth: 520
|
popupWidth: 520
|
||||||
popupHeight: 600
|
popupHeight: 600
|
||||||
triggerX: Theme.spacingL
|
triggerX: Theme.spacingL
|
||||||
triggerY: Math.max(26 + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding)) + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap - 2
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
||||||
triggerWidth: 40
|
triggerWidth: 40
|
||||||
positioning: ""
|
positioning: "center"
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
|
|
||||||
onShouldBeVisibleChanged: {
|
onShouldBeVisibleChanged: {
|
||||||
@@ -94,7 +95,7 @@ DankPopout {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
radius: parent.radius + Math.abs(modelData.margin)
|
radius: parent.radius + Math.abs(modelData.margin)
|
||||||
border.color: modelData.color
|
border.color: modelData.color
|
||||||
border.width: 0
|
border.width: 1
|
||||||
z: modelData.z
|
z: modelData.z
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -127,44 +128,6 @@ DankPopout {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectNext()
|
|
||||||
event.accepted = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectPrevious()
|
|
||||||
event.accepted = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectNext()
|
|
||||||
event.accepted = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectPrevious()
|
|
||||||
event.accepted = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (appLauncher.viewMode === "grid") {
|
|
||||||
if (event.key === Qt.Key_L && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectNextInRow()
|
|
||||||
event.accepted = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.key === Qt.Key_H && event.modifiers & Qt.ControlModifier) {
|
|
||||||
appLauncher.selectPreviousInRow()
|
|
||||||
event.accepted = true
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!searchField.activeFocus && event.text && /[a-zA-Z0-9\s]/.test(event.text)) {
|
if (!searchField.activeFocus && event.text && /[a-zA-Z0-9\s]/.test(event.text)) {
|
||||||
searchField.forceActiveFocus()
|
searchField.forceActiveFocus()
|
||||||
searchField.insertText(event.text)
|
searchField.insertText(event.text)
|
||||||
@@ -173,16 +136,15 @@ DankPopout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width - Theme.spacingS * 2
|
width: parent.width - Theme.spacingL * 2
|
||||||
height: parent.height - Theme.spacingS * 2
|
height: parent.height - Theme.spacingL * 2
|
||||||
x: Theme.spacingS
|
x: Theme.spacingL
|
||||||
y: Theme.spacingS
|
y: Theme.spacingL
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 40
|
height: 40
|
||||||
leftPadding: Theme.spacingS
|
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
@@ -208,8 +170,7 @@ DankPopout {
|
|||||||
DankTextField {
|
DankTextField {
|
||||||
id: searchField
|
id: searchField
|
||||||
|
|
||||||
width: parent.width - Theme.spacingS * 2
|
width: parent.width
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
height: 52
|
height: 52
|
||||||
cornerRadius: Theme.cornerRadius
|
cornerRadius: Theme.cornerRadius
|
||||||
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.7)
|
backgroundColor: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, Theme.getContentBackgroundAlpha() * 0.7)
|
||||||
@@ -270,18 +231,14 @@ DankPopout {
|
|||||||
height: 40
|
height: 40
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
visible: searchField.text.length === 0
|
visible: searchField.text.length === 0
|
||||||
leftPadding: Theme.spacingS
|
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
width: 180
|
width: 200
|
||||||
height: 40
|
height: 36
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
text: ""
|
text: ""
|
||||||
dropdownWidth: 180
|
|
||||||
currentValue: appLauncher.selectedCategory
|
currentValue: appLauncher.selectedCategory
|
||||||
options: appLauncher.categories
|
options: appLauncher.categories
|
||||||
optionIcons: appLauncher.categoryIcons
|
optionIcons: appLauncher.categoryIcons
|
||||||
@@ -292,7 +249,7 @@ DankPopout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: parent.width - 290
|
width: parent.width - 300
|
||||||
height: 1
|
height: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -329,13 +286,15 @@ DankPopout {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: {
|
height: {
|
||||||
let usedHeight = 40 + Theme.spacingS
|
let usedHeight = 40 + Theme.spacingL
|
||||||
usedHeight += 52 + Theme.spacingS
|
usedHeight += 52 + Theme.spacingL
|
||||||
usedHeight += (searchField.text.length === 0 ? 40 : 0)
|
usedHeight += (searchField.text.length === 0 ? 40 + Theme.spacingL : 0)
|
||||||
return parent.height - usedHeight
|
return parent.height - usedHeight
|
||||||
}
|
}
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: "transparent"
|
color: Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.1)
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
DankListView {
|
DankListView {
|
||||||
id: appList
|
id: appList
|
||||||
@@ -364,9 +323,7 @@ DankPopout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingS
|
anchors.margins: Theme.spacingS
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.bottomMargin: Theme.spacingS
|
|
||||||
visible: appLauncher.viewMode === "list"
|
visible: appLauncher.viewMode === "list"
|
||||||
model: appLauncher.model
|
model: appLauncher.model
|
||||||
currentIndex: appLauncher.selectedIndex
|
currentIndex: appLauncher.selectedIndex
|
||||||
@@ -396,7 +353,9 @@ DankPopout {
|
|||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
height: appList.itemHeight
|
height: appList.itemHeight
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: ListView.isCurrentItem ? Theme.primaryPressed : listMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceContainerHigh
|
color: ListView.isCurrentItem ? Theme.primaryPressed : listMouseArea.containsMouse ? Theme.primaryHoverLight : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.03)
|
||||||
|
border.color: ListView.isCurrentItem ? Theme.primarySelected : Theme.outlineMedium
|
||||||
|
border.width: ListView.isCurrentItem ? 2 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -412,7 +371,6 @@ DankPopout {
|
|||||||
id: listIconImg
|
id: listIconImg
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Theme.spacingXS
|
|
||||||
source: Quickshell.iconPath(model.icon, true)
|
source: Quickshell.iconPath(model.icon, true)
|
||||||
smooth: true
|
smooth: true
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
@@ -421,13 +379,10 @@ DankPopout {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.bottomMargin: Theme.spacingM
|
|
||||||
visible: !listIconImg.visible
|
visible: !listIconImg.visible
|
||||||
color: Theme.surfaceLight
|
color: Theme.surfaceLight
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 0
|
border.width: 1
|
||||||
border.color: Theme.primarySelected
|
border.color: Theme.primarySelected
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -470,9 +425,6 @@ DankPopout {
|
|||||||
id: listMouseArea
|
id: listMouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.bottomMargin: Theme.spacingM
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
@@ -532,9 +484,7 @@ DankPopout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingS
|
anchors.margins: Theme.spacingS
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.bottomMargin: Theme.spacingS
|
|
||||||
visible: appLauncher.viewMode === "grid"
|
visible: appLauncher.viewMode === "grid"
|
||||||
model: appLauncher.model
|
model: appLauncher.model
|
||||||
clip: true
|
clip: true
|
||||||
@@ -566,7 +516,9 @@ DankPopout {
|
|||||||
width: appGrid.cellWidth - appGrid.cellPadding
|
width: appGrid.cellWidth - appGrid.cellPadding
|
||||||
height: appGrid.cellHeight - appGrid.cellPadding
|
height: appGrid.cellHeight - appGrid.cellPadding
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: appGrid.currentIndex === index ? Theme.primaryPressed : gridMouseArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceContainerHigh
|
color: appGrid.currentIndex === index ? Theme.primaryPressed : gridMouseArea.containsMouse ? Theme.primaryHoverLight : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.03)
|
||||||
|
border.color: appGrid.currentIndex === index ? Theme.primarySelected : Theme.outlineMedium
|
||||||
|
border.width: appGrid.currentIndex === index ? 2 : 1
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -583,9 +535,6 @@ DankPopout {
|
|||||||
id: gridIconImg
|
id: gridIconImg
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.bottomMargin: Theme.spacingS
|
|
||||||
source: Quickshell.iconPath(model.icon, true)
|
source: Quickshell.iconPath(model.icon, true)
|
||||||
smooth: true
|
smooth: true
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
@@ -594,13 +543,10 @@ DankPopout {
|
|||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.bottomMargin: Theme.spacingS
|
|
||||||
visible: !gridIconImg.visible
|
visible: !gridIconImg.visible
|
||||||
color: Theme.surfaceLight
|
color: Theme.surfaceLight
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 0
|
border.width: 1
|
||||||
border.color: Theme.primarySelected
|
border.color: Theme.primarySelected
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -631,9 +577,6 @@ DankPopout {
|
|||||||
id: gridMouseArea
|
id: gridMouseArea
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.bottomMargin: Theme.spacingS
|
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
@@ -710,7 +653,7 @@ DankPopout {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
z: 1000
|
z: 1000
|
||||||
opacity: menuVisible ? 1 : 0
|
opacity: menuVisible ? 1 : 0
|
||||||
scale: menuVisible ? 1 : 0.85
|
scale: menuVisible ? 1 : 0.85
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ Item {
|
|||||||
readonly property int maxCompactItems: 8
|
readonly property int maxCompactItems: 8
|
||||||
readonly property int itemHeight: 36
|
readonly property int itemHeight: 36
|
||||||
readonly property color selectedBorderColor: "transparent"
|
readonly property color selectedBorderColor: "transparent"
|
||||||
readonly property color unselectedBorderColor: "transparent"
|
readonly property color unselectedBorderColor: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.3)
|
||||||
|
|
||||||
function handleCategoryClick(category) {
|
function handleCategoryClick(category) {
|
||||||
selectedCategory = category
|
selectedCategory = category
|
||||||
@@ -42,7 +42,8 @@ Item {
|
|||||||
height: root.itemHeight
|
height: root.itemHeight
|
||||||
width: root.getButtonWidth(itemCount, parent.width)
|
width: root.getButtonWidth(itemCount, parent.width)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: selectedCategory === modelData ? Theme.primary : Theme.surfaceContainerHigh
|
color: selectedCategory === modelData ? Theme.primary : "transparent"
|
||||||
|
border.color: selectedCategory === modelData ? selectedBorderColor : unselectedBorderColor
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -81,7 +82,7 @@ Item {
|
|||||||
height: root.itemHeight
|
height: root.itemHeight
|
||||||
width: root.getButtonWidth(itemCount, parent.width)
|
width: root.getButtonWidth(itemCount, parent.width)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: selectedCategory === modelData ? Theme.primary : Theme.surfaceContainerHigh
|
color: selectedCategory === modelData ? Theme.primary : "transparent"
|
||||||
border.color: selectedCategory === modelData ? selectedBorderColor : unselectedBorderColor
|
border.color: selectedCategory === modelData ? selectedBorderColor : unselectedBorderColor
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -117,7 +118,7 @@ Item {
|
|||||||
height: root.itemHeight
|
height: root.itemHeight
|
||||||
width: root.getButtonWidth(itemCount, parent.width)
|
width: root.getButtonWidth(itemCount, parent.width)
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: selectedCategory === modelData ? Theme.primary : Theme.surfaceContainerHigh
|
color: selectedCategory === modelData ? Theme.primary : "transparent"
|
||||||
border.color: selectedCategory === modelData ? selectedBorderColor : unselectedBorderColor
|
border.color: selectedCategory === modelData ? selectedBorderColor : unselectedBorderColor
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ Rectangle {
|
|||||||
DankIcon {
|
DankIcon {
|
||||||
name: root.iconName
|
name: root.iconName
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: isActive ? Theme.primaryText : Theme.primary
|
color: isActive ? Theme.primaryContainer : Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
text: root.text
|
text: root.text
|
||||||
style: Typography.Style.Body
|
style: Typography.Style.Body
|
||||||
color: isActive ? Theme.primaryText : Theme.surfaceText
|
color: isActive ? Theme.primaryContainer : Theme.surfaceText
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
}
|
}
|
||||||
@@ -86,7 +86,7 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
text: root.secondaryText
|
text: root.secondaryText
|
||||||
style: Typography.Style.Caption
|
style: Typography.Style.Caption
|
||||||
color: isActive ? Theme.primaryText : Theme.surfaceVariantText
|
color: isActive ? Theme.primaryContainer : Theme.surfaceVariantText
|
||||||
visible: text.length > 0
|
visible: text.length > 0
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ Item {
|
|||||||
|
|
||||||
property string expandedSection: ""
|
property string expandedSection: ""
|
||||||
property var expandedWidgetData: null
|
property var expandedWidgetData: null
|
||||||
property var bluetoothCodecSelector: null
|
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -43,17 +42,7 @@ Item {
|
|||||||
|
|
||||||
Component {
|
Component {
|
||||||
id: bluetoothDetailComponent
|
id: bluetoothDetailComponent
|
||||||
BluetoothDetail {
|
BluetoothDetail {}
|
||||||
id: bluetoothDetail
|
|
||||||
onShowCodecSelector: function(device) {
|
|
||||||
if (root.bluetoothCodecSelector) {
|
|
||||||
root.bluetoothCodecSelector.show(device)
|
|
||||||
root.bluetoothCodecSelector.codecSelected.connect(function(deviceAddress, codecName) {
|
|
||||||
bluetoothDetail.updateDeviceCodecDisplay(deviceAddress, codecName)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Component {
|
Component {
|
||||||
|
|||||||
@@ -1,91 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
import qs.Modules.ControlCenter.Details
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string expandedSection: ""
|
|
||||||
property var expandedWidgetData: null
|
|
||||||
|
|
||||||
height: active ? 250 : 0
|
|
||||||
visible: active
|
|
||||||
|
|
||||||
readonly property bool active: expandedSection !== ""
|
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.topMargin: Theme.spacingS
|
|
||||||
sourceComponent: {
|
|
||||||
if (!root.active) return null
|
|
||||||
|
|
||||||
if (expandedSection.startsWith("diskUsage_")) {
|
|
||||||
return diskUsageDetailComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (expandedSection) {
|
|
||||||
case "wifi": return networkDetailComponent
|
|
||||||
case "bluetooth": return bluetoothDetailComponent
|
|
||||||
case "audioOutput": return audioOutputDetailComponent
|
|
||||||
case "audioInput": return audioInputDetailComponent
|
|
||||||
case "battery": return batteryDetailComponent
|
|
||||||
default: return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: networkDetailComponent
|
|
||||||
NetworkDetail {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: bluetoothDetailComponent
|
|
||||||
BluetoothDetail {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: audioOutputDetailComponent
|
|
||||||
AudioOutputDetail {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: audioInputDetailComponent
|
|
||||||
AudioInputDetail {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: batteryDetailComponent
|
|
||||||
BatteryDetail {}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: diskUsageDetailComponent
|
|
||||||
DiskUsageDetail {
|
|
||||||
currentMountPath: root.expandedWidgetData?.mountPath || "/"
|
|
||||||
instanceId: root.expandedWidgetData?.instanceId || ""
|
|
||||||
|
|
||||||
onMountPathChanged: (newMountPath) => {
|
|
||||||
if (root.expandedWidgetData && root.expandedWidgetData.id === "diskUsage") {
|
|
||||||
const widgets = SettingsData.controlCenterWidgets || []
|
|
||||||
const newWidgets = widgets.map(w => {
|
|
||||||
if (w.id === "diskUsage" && w.instanceId === root.expandedWidgetData.instanceId) {
|
|
||||||
const updatedWidget = Object.assign({}, w)
|
|
||||||
updatedWidget.mountPath = newMountPath
|
|
||||||
return updatedWidget
|
|
||||||
}
|
|
||||||
return w
|
|
||||||
})
|
|
||||||
SettingsData.setControlCenterWidgets(newWidgets)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,289 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool editMode: false
|
|
||||||
property var widgetData: null
|
|
||||||
property int widgetIndex: -1
|
|
||||||
property bool isSlider: false
|
|
||||||
property Component widgetComponent: null
|
|
||||||
property real gridCellWidth: 100
|
|
||||||
property real gridCellHeight: 60
|
|
||||||
property int gridColumns: 4
|
|
||||||
property var gridLayout: null
|
|
||||||
|
|
||||||
z: dragArea.drag.active ? 10000 : 1
|
|
||||||
|
|
||||||
signal widgetMoved(int fromIndex, int toIndex)
|
|
||||||
signal removeWidget(int index)
|
|
||||||
signal toggleWidgetSize(int index)
|
|
||||||
|
|
||||||
width: {
|
|
||||||
const widgetWidth = widgetData?.width || 50
|
|
||||||
if (widgetWidth <= 25) return gridCellWidth
|
|
||||||
else if (widgetWidth <= 50) return gridCellWidth * 2
|
|
||||||
else if (widgetWidth <= 75) return gridCellWidth * 3
|
|
||||||
else return gridCellWidth * 4
|
|
||||||
}
|
|
||||||
height: isSlider ? 16 : gridCellHeight
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: dragIndicator
|
|
||||||
anchors.fill: parent
|
|
||||||
color: "transparent"
|
|
||||||
border.color: Theme.primary
|
|
||||||
border.width: dragArea.drag.active ? 2 : 0
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
opacity: dragArea.drag.active ? 0.8 : 1.0
|
|
||||||
z: dragArea.drag.active ? 10000 : 1
|
|
||||||
|
|
||||||
Behavior on border.width {
|
|
||||||
NumberAnimation { duration: 150 }
|
|
||||||
}
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 150 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: widgetLoader
|
|
||||||
anchors.fill: parent
|
|
||||||
sourceComponent: widgetComponent
|
|
||||||
property var widgetData: root.widgetData
|
|
||||||
property int widgetIndex: root.widgetIndex
|
|
||||||
property int globalWidgetIndex: root.widgetIndex
|
|
||||||
property int widgetWidth: root.widgetData?.width || 50
|
|
||||||
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: editModeBlocker
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: root.editMode
|
|
||||||
acceptedButtons: Qt.AllButtons
|
|
||||||
onPressed: function(mouse) { mouse.accepted = true }
|
|
||||||
onWheel: function(wheel) { wheel.accepted = true }
|
|
||||||
z: 100
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: dragArea
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: editMode
|
|
||||||
cursorShape: editMode ? Qt.OpenHandCursor : Qt.PointingHandCursor
|
|
||||||
drag.target: editMode ? root : null
|
|
||||||
drag.axis: Drag.XAndYAxis
|
|
||||||
drag.smoothed: true
|
|
||||||
|
|
||||||
onPressed: function(mouse) {
|
|
||||||
if (editMode) {
|
|
||||||
cursorShape = Qt.ClosedHandCursor
|
|
||||||
if (root.gridLayout && root.gridLayout.moveToTop) {
|
|
||||||
root.gridLayout.moveToTop(root)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onReleased: function(mouse) {
|
|
||||||
if (editMode) {
|
|
||||||
cursorShape = Qt.OpenHandCursor
|
|
||||||
root.snapToGrid()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Drag.active: dragArea.drag.active
|
|
||||||
Drag.hotSpot.x: width / 2
|
|
||||||
Drag.hotSpot.y: height / 2
|
|
||||||
|
|
||||||
function swapIndices(i, j) {
|
|
||||||
if (i === j) return;
|
|
||||||
const arr = SettingsData.controlCenterWidgets;
|
|
||||||
if (!arr || i < 0 || j < 0 || i >= arr.length || j >= arr.length) return;
|
|
||||||
|
|
||||||
const copy = arr.slice();
|
|
||||||
const tmp = copy[i];
|
|
||||||
copy[i] = copy[j];
|
|
||||||
copy[j] = tmp;
|
|
||||||
|
|
||||||
SettingsData.setControlCenterWidgets(copy);
|
|
||||||
}
|
|
||||||
|
|
||||||
function snapToGrid() {
|
|
||||||
if (!editMode || !gridLayout) return
|
|
||||||
|
|
||||||
const globalPos = root.mapToItem(gridLayout, 0, 0)
|
|
||||||
const cellWidth = gridLayout.width / gridColumns
|
|
||||||
const cellHeight = gridCellHeight + Theme.spacingS
|
|
||||||
|
|
||||||
const centerX = globalPos.x + (root.width / 2)
|
|
||||||
const centerY = globalPos.y + (root.height / 2)
|
|
||||||
|
|
||||||
let targetCol = Math.max(0, Math.floor(centerX / cellWidth))
|
|
||||||
let targetRow = Math.max(0, Math.floor(centerY / cellHeight))
|
|
||||||
|
|
||||||
targetCol = Math.min(targetCol, gridColumns - 1)
|
|
||||||
|
|
||||||
const newIndex = findBestInsertionIndex(targetRow, targetCol)
|
|
||||||
|
|
||||||
if (newIndex !== widgetIndex && newIndex >= 0 && newIndex < (SettingsData.controlCenterWidgets?.length || 0)) {
|
|
||||||
swapIndices(widgetIndex, newIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function findBestInsertionIndex(targetRow, targetCol) {
|
|
||||||
const widgets = SettingsData.controlCenterWidgets || [];
|
|
||||||
const n = widgets.length;
|
|
||||||
if (!n || widgetIndex < 0 || widgetIndex >= n) return -1;
|
|
||||||
|
|
||||||
function spanFor(width) {
|
|
||||||
const w = width ?? 50;
|
|
||||||
if (w <= 25) return 1;
|
|
||||||
if (w <= 50) return 2;
|
|
||||||
if (w <= 75) return 3;
|
|
||||||
return 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
const cols = gridColumns || 4;
|
|
||||||
|
|
||||||
let row = 0, col = 0;
|
|
||||||
let draggedOrigKey = null;
|
|
||||||
|
|
||||||
const pos = [];
|
|
||||||
|
|
||||||
for (let i = 0; i < n; i++) {
|
|
||||||
const span = Math.min(spanFor(widgets[i].width), cols);
|
|
||||||
|
|
||||||
if (col + span > cols) {
|
|
||||||
row++;
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const startCol = col;
|
|
||||||
const centerKey = row * cols + (startCol + (span - 1) / 2);
|
|
||||||
|
|
||||||
if (i === widgetIndex) {
|
|
||||||
draggedOrigKey = centerKey;
|
|
||||||
} else {
|
|
||||||
pos.push({ index: i, row, startCol, span, centerKey });
|
|
||||||
}
|
|
||||||
|
|
||||||
col += span;
|
|
||||||
if (col >= cols) {
|
|
||||||
row++;
|
|
||||||
col = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (pos.length === 0) return -1;
|
|
||||||
|
|
||||||
const centerColCoord = targetCol + 0.5;
|
|
||||||
const targetKey = targetRow * cols + centerColCoord;
|
|
||||||
|
|
||||||
for (let k = 0; k < pos.length; k++) {
|
|
||||||
const p = pos[k];
|
|
||||||
if (p.row === targetRow && centerColCoord >= p.startCol && centerColCoord < (p.startCol + p.span)) {
|
|
||||||
return p.index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let lo = 0, hi = pos.length - 1;
|
|
||||||
if (targetKey <= pos[0].centerKey) return pos[0].index;
|
|
||||||
if (targetKey >= pos[hi].centerKey) return pos[hi].index;
|
|
||||||
|
|
||||||
while (lo <= hi) {
|
|
||||||
const mid = (lo + hi) >> 1;
|
|
||||||
const mk = pos[mid].centerKey;
|
|
||||||
if (targetKey < mk) hi = mid - 1;
|
|
||||||
else if (targetKey > mk) lo = mid + 1;
|
|
||||||
else return pos[mid].index;
|
|
||||||
}
|
|
||||||
const movingUp = (draggedOrigKey != null) ? (targetKey < draggedOrigKey) : false;
|
|
||||||
return (movingUp ? pos[lo].index : pos[hi].index);
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
radius: 8
|
|
||||||
color: Theme.error
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.margins: -4
|
|
||||||
visible: editMode
|
|
||||||
z: 10
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "close"
|
|
||||||
size: 12
|
|
||||||
color: Theme.primaryText
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: removeWidget(widgetIndex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SizeControls {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: -6
|
|
||||||
visible: editMode
|
|
||||||
z: 10
|
|
||||||
currentSize: root.widgetData?.width || 50
|
|
||||||
isSlider: root.isSlider
|
|
||||||
widgetIndex: root.widgetIndex
|
|
||||||
onSizeChanged: (newSize) => {
|
|
||||||
var widgets = SettingsData.controlCenterWidgets.slice()
|
|
||||||
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
|
|
||||||
widgets[widgetIndex].width = newSize
|
|
||||||
SettingsData.setControlCenterWidgets(widgets)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: dragHandle
|
|
||||||
width: 16
|
|
||||||
height: 12
|
|
||||||
radius: 2
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.margins: 4
|
|
||||||
visible: editMode
|
|
||||||
z: 15
|
|
||||||
opacity: dragArea.drag.active ? 1.0 : 0.7
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "drag_indicator"
|
|
||||||
size: 10
|
|
||||||
color: Theme.primaryText
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation { duration: 150 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
color: editMode ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : "transparent"
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
border.color: "transparent"
|
|
||||||
border.width: 0
|
|
||||||
z: -1
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation { duration: Theme.shortDuration }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -7,7 +7,6 @@ Row {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property var availableWidgets: []
|
property var availableWidgets: []
|
||||||
property Item popoutContent: null
|
|
||||||
|
|
||||||
signal addWidget(string widgetId)
|
signal addWidget(string widgetId)
|
||||||
signal resetToDefault()
|
signal resetToDefault()
|
||||||
@@ -20,9 +19,7 @@ Row {
|
|||||||
|
|
||||||
Popup {
|
Popup {
|
||||||
id: addWidgetPopup
|
id: addWidgetPopup
|
||||||
parent: popoutContent
|
anchors.centerIn: parent
|
||||||
x: parent ? Math.round((parent.width - width) / 2) : 0
|
|
||||||
y: parent ? Math.round((parent.height - height) / 2) : 0
|
|
||||||
width: 400
|
width: 400
|
||||||
height: 300
|
height: 300
|
||||||
modal: true
|
modal: true
|
||||||
@@ -32,7 +29,7 @@ Row {
|
|||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: Theme.surfaceContainer
|
color: Theme.surfaceContainer
|
||||||
border.color: Theme.primarySelected
|
border.color: Theme.primarySelected
|
||||||
border.width: 0
|
border.width: 1
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +74,7 @@ Row {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: widgetMouseArea.containsMouse ? Theme.primaryHover : Theme.surfaceContainerHigh
|
color: widgetMouseArea.containsMouse ? Theme.primaryHover : Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -141,7 +138,7 @@ Row {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
||||||
border.color: Theme.primary
|
border.color: Theme.primary
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -175,7 +172,7 @@ Row {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.12)
|
color: Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.12)
|
||||||
border.color: Theme.warning
|
border.color: Theme.warning
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -209,7 +206,7 @@ Row {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
||||||
border.color: Theme.error
|
border.color: Theme.error
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
|||||||
241
Modules/ControlCenter/Components/EditModeOverlay.qml
Normal file
241
Modules/ControlCenter/Components/EditModeOverlay.qml
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Common
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool editMode: false
|
||||||
|
property var widgetData: null
|
||||||
|
property int widgetIndex: -1
|
||||||
|
property bool showSizeControls: true
|
||||||
|
property bool isSlider: false
|
||||||
|
|
||||||
|
signal removeWidget(int index)
|
||||||
|
signal toggleWidgetSize(int index)
|
||||||
|
signal moveWidget(int fromIndex, int toIndex)
|
||||||
|
|
||||||
|
// Delete button in top-right
|
||||||
|
Rectangle {
|
||||||
|
width: 16
|
||||||
|
height: 16
|
||||||
|
radius: 8
|
||||||
|
color: Theme.error
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: -4
|
||||||
|
visible: editMode
|
||||||
|
z: 10
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "close"
|
||||||
|
size: 12
|
||||||
|
color: Theme.primaryText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: root.removeWidget(widgetIndex)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Size control buttons in bottom-right
|
||||||
|
Row {
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.margins: -8
|
||||||
|
spacing: 4
|
||||||
|
visible: editMode && showSizeControls
|
||||||
|
z: 10
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
radius: 12
|
||||||
|
color: (widgetData?.width || 50) === 25 ? Theme.primary : Theme.primaryContainer
|
||||||
|
border.color: Theme.primary
|
||||||
|
border.width: 1
|
||||||
|
visible: !isSlider
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "25"
|
||||||
|
font.pixelSize: 10
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: (widgetData?.width || 50) === 25 ? Theme.primaryText : Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
var widgets = SettingsData.controlCenterWidgets.slice()
|
||||||
|
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
|
||||||
|
widgets[widgetIndex].width = 25
|
||||||
|
SettingsData.setControlCenterWidgets(widgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
radius: 12
|
||||||
|
color: (widgetData?.width || 50) === 50 ? Theme.primary : Theme.primaryContainer
|
||||||
|
border.color: Theme.primary
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "50"
|
||||||
|
font.pixelSize: 10
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: (widgetData?.width || 50) === 50 ? Theme.primaryText : Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
var widgets = SettingsData.controlCenterWidgets.slice()
|
||||||
|
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
|
||||||
|
widgets[widgetIndex].width = 50
|
||||||
|
SettingsData.setControlCenterWidgets(widgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
radius: 12
|
||||||
|
color: (widgetData?.width || 50) === 75 ? Theme.primary : Theme.primaryContainer
|
||||||
|
border.color: Theme.primary
|
||||||
|
border.width: 1
|
||||||
|
visible: !isSlider
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "75"
|
||||||
|
font.pixelSize: 10
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: (widgetData?.width || 50) === 75 ? Theme.primaryText : Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
var widgets = SettingsData.controlCenterWidgets.slice()
|
||||||
|
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
|
||||||
|
widgets[widgetIndex].width = 75
|
||||||
|
SettingsData.setControlCenterWidgets(widgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 24
|
||||||
|
height: 24
|
||||||
|
radius: 12
|
||||||
|
color: (widgetData?.width || 50) === 100 ? Theme.primary : Theme.primaryContainer
|
||||||
|
border.color: Theme.primary
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: "100"
|
||||||
|
font.pixelSize: 9
|
||||||
|
font.weight: Font.Medium
|
||||||
|
color: (widgetData?.width || 50) === 100 ? Theme.primaryText : Theme.primary
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
var widgets = SettingsData.controlCenterWidgets.slice()
|
||||||
|
if (widgetIndex >= 0 && widgetIndex < widgets.length) {
|
||||||
|
widgets[widgetIndex].width = 100
|
||||||
|
SettingsData.setControlCenterWidgets(widgets)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Arrow buttons for reordering in top-left
|
||||||
|
Row {
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: 4
|
||||||
|
spacing: 2
|
||||||
|
visible: editMode
|
||||||
|
z: 20
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 16
|
||||||
|
height: 16
|
||||||
|
radius: 8
|
||||||
|
color: Theme.surfaceContainer
|
||||||
|
border.color: Theme.outline
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "keyboard_arrow_left"
|
||||||
|
size: 12
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: widgetIndex > 0
|
||||||
|
opacity: enabled ? 1.0 : 0.5
|
||||||
|
onClicked: root.moveWidget(widgetIndex, widgetIndex - 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: 16
|
||||||
|
height: 16
|
||||||
|
radius: 8
|
||||||
|
color: Theme.surfaceContainer
|
||||||
|
border.color: Theme.outline
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "keyboard_arrow_right"
|
||||||
|
size: 12
|
||||||
|
color: Theme.surfaceText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
enabled: widgetIndex < ((SettingsData.controlCenterWidgets?.length ?? 0) - 1)
|
||||||
|
opacity: enabled ? 1.0 : 0.5
|
||||||
|
onClicked: root.moveWidget(widgetIndex, widgetIndex + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Border highlight
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.1)
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
border.color: Theme.primary
|
||||||
|
border.width: editMode ? 1 : 0
|
||||||
|
visible: editMode
|
||||||
|
z: -1
|
||||||
|
|
||||||
|
Behavior on border.width {
|
||||||
|
NumberAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,10 @@ import qs.Widgets
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
|
property bool powerOptionsExpanded: false
|
||||||
property bool editMode: false
|
property bool editMode: false
|
||||||
|
|
||||||
signal powerButtonClicked()
|
signal powerActionRequested(string action, string title, string message)
|
||||||
signal lockRequested()
|
signal lockRequested()
|
||||||
signal editModeToggled()
|
signal editModeToggled()
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ Rectangle {
|
|||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
Theme.outline.b, 0.08)
|
Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -82,11 +83,13 @@ Rectangle {
|
|||||||
|
|
||||||
DankActionButton {
|
DankActionButton {
|
||||||
buttonSize: 36
|
buttonSize: 36
|
||||||
iconName: "power_settings_new"
|
iconName: root.powerOptionsExpanded ? "expand_less" : "power_settings_new"
|
||||||
iconSize: Theme.iconSize - 4
|
iconSize: Theme.iconSize - 4
|
||||||
iconColor: Theme.surfaceText
|
iconColor: root.powerOptionsExpanded ? Theme.primary : Theme.surfaceText
|
||||||
backgroundColor: "transparent"
|
backgroundColor: "transparent"
|
||||||
onClicked: root.powerButtonClicked()
|
onClicked: {
|
||||||
|
root.powerOptionsExpanded = !root.powerOptionsExpanded
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankActionButton {
|
DankActionButton {
|
||||||
|
|||||||
70
Modules/ControlCenter/Components/PowerOptionsPane.qml
Normal file
70
Modules/ControlCenter/Components/PowerOptionsPane.qml
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import QtQuick
|
||||||
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool expanded: false
|
||||||
|
|
||||||
|
signal powerActionRequested(string action, string title, string message)
|
||||||
|
|
||||||
|
implicitHeight: expanded ? 60 : 0
|
||||||
|
height: implicitHeight
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: 60
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.surfaceContainerHigh
|
||||||
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
|
Theme.outline.b, 0.08)
|
||||||
|
border.width: root.expanded ? 1 : 0
|
||||||
|
opacity: root.expanded ? 1 : 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
spacing: SessionService.hibernateSupported ? Theme.spacingS : Theme.spacingL
|
||||||
|
visible: root.expanded
|
||||||
|
|
||||||
|
PowerButton {
|
||||||
|
width: SessionService.hibernateSupported ? 85 : 100
|
||||||
|
iconName: "logout"
|
||||||
|
text: "Logout"
|
||||||
|
onPressed: root.powerActionRequested("logout", "Logout", "Are you sure you want to logout?")
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerButton {
|
||||||
|
width: SessionService.hibernateSupported ? 85 : 100
|
||||||
|
iconName: "restart_alt"
|
||||||
|
text: "Restart"
|
||||||
|
onPressed: root.powerActionRequested("reboot", "Restart", "Are you sure you want to restart?")
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerButton {
|
||||||
|
width: SessionService.hibernateSupported ? 85 : 100
|
||||||
|
iconName: "bedtime"
|
||||||
|
text: "Suspend"
|
||||||
|
onPressed: root.powerActionRequested("suspend", "Suspend", "Are you sure you want to suspend?")
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerButton {
|
||||||
|
width: SessionService.hibernateSupported ? 85 : 100
|
||||||
|
iconName: "ac_unit"
|
||||||
|
text: "Hibernate"
|
||||||
|
visible: SessionService.hibernateSupported
|
||||||
|
onPressed: root.powerActionRequested("hibernate", "Hibernate", "Are you sure you want to hibernate?")
|
||||||
|
}
|
||||||
|
|
||||||
|
PowerButton {
|
||||||
|
width: SessionService.hibernateSupported ? 85 : 100
|
||||||
|
iconName: "power_settings_new"
|
||||||
|
text: "Shutdown"
|
||||||
|
onPressed: root.powerActionRequested("poweroff", "Shutdown", "Are you sure you want to shutdown?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import qs.Common
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property int currentSize: 50
|
|
||||||
property bool isSlider: false
|
|
||||||
property int widgetIndex: -1
|
|
||||||
|
|
||||||
signal sizeChanged(int newSize)
|
|
||||||
|
|
||||||
readonly property var availableSizes: isSlider ? [50, 100] : [25, 50, 75, 100]
|
|
||||||
|
|
||||||
spacing: 2
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: root.availableSizes
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
radius: 3
|
|
||||||
color: modelData === root.currentSize ? Theme.primary : Theme.surfaceContainer
|
|
||||||
border.color: modelData === root.currentSize ? Theme.primary : Theme.outline
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: modelData.toString()
|
|
||||||
font.pixelSize: 8
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: modelData === root.currentSize ? Theme.primaryText : Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: {
|
|
||||||
root.currentSize = modelData
|
|
||||||
root.sizeChanged(modelData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on color {
|
|
||||||
ColorAnimation { duration: Theme.shortDuration }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,8 +13,6 @@ Column {
|
|||||||
property int expandedWidgetIndex: -1
|
property int expandedWidgetIndex: -1
|
||||||
property var model: null
|
property var model: null
|
||||||
property var expandedWidgetData: null
|
property var expandedWidgetData: null
|
||||||
property var bluetoothCodecSelector: null
|
|
||||||
property bool darkModeTransitionPending: false
|
|
||||||
|
|
||||||
signal expandClicked(var widgetData, int globalIndex)
|
signal expandClicked(var widgetData, int globalIndex)
|
||||||
signal removeWidget(int index)
|
signal removeWidget(int index)
|
||||||
@@ -26,7 +24,6 @@ Column {
|
|||||||
property var currentRowWidgets: []
|
property var currentRowWidgets: []
|
||||||
property real currentRowWidth: 0
|
property real currentRowWidth: 0
|
||||||
property int expandedRowIndex: -1
|
property int expandedRowIndex: -1
|
||||||
property var colorPickerModal: null
|
|
||||||
|
|
||||||
function calculateRowsAndWidgets() {
|
function calculateRowsAndWidgets() {
|
||||||
return LayoutUtils.calculateRowsAndWidgets(root, expandedSection, expandedWidgetIndex)
|
return LayoutUtils.calculateRowsAndWidgets(root, expandedSection, expandedWidgetIndex)
|
||||||
@@ -41,17 +38,6 @@ Column {
|
|||||||
expandedRowIndex = layoutResult.expandedRowIndex
|
expandedRowIndex = layoutResult.expandedRowIndex
|
||||||
}
|
}
|
||||||
|
|
||||||
function moveToTop(item) {
|
|
||||||
const children = root.children
|
|
||||||
for (var i = 0; i < children.length; i++) {
|
|
||||||
if (children[i] === item)
|
|
||||||
continue
|
|
||||||
if (children[i].z)
|
|
||||||
children[i].z = Math.min(children[i].z, 999)
|
|
||||||
}
|
|
||||||
item.z = 1000
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: root.layoutResult.rows
|
model: root.layoutResult.rows
|
||||||
|
|
||||||
@@ -65,8 +51,8 @@ Column {
|
|||||||
if (widgets.length === 0) return false
|
if (widgets.length === 0) return false
|
||||||
return widgets.every(w => w.id === "volumeSlider" || w.id === "brightnessSlider" || w.id === "inputVolumeSlider")
|
return widgets.every(w => w.id === "volumeSlider" || w.id === "brightnessSlider" || w.id === "inputVolumeSlider")
|
||||||
}
|
}
|
||||||
topPadding: isSliderOnlyRow ? (root.editMode ? 4 : -6) : 0
|
topPadding: isSliderOnlyRow ? (root.editMode ? 4 : -12) : 0
|
||||||
bottomPadding: isSliderOnlyRow ? (root.editMode ? 4 : -6) : 0
|
bottomPadding: isSliderOnlyRow ? (root.editMode ? 4 : -12) : 0
|
||||||
|
|
||||||
Flow {
|
Flow {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
@@ -75,8 +61,8 @@ Column {
|
|||||||
Repeater {
|
Repeater {
|
||||||
model: rowWidgets || []
|
model: rowWidgets || []
|
||||||
|
|
||||||
DragDropWidgetWrapper {
|
Item {
|
||||||
widgetData: modelData
|
property var widgetData: modelData
|
||||||
property int globalWidgetIndex: {
|
property int globalWidgetIndex: {
|
||||||
const widgets = SettingsData.controlCenterWidgets || []
|
const widgets = SettingsData.controlCenterWidgets || []
|
||||||
for (var i = 0; i < widgets.length; i++) {
|
for (var i = 0; i < widgets.length; i++) {
|
||||||
@@ -106,43 +92,36 @@ Column {
|
|||||||
return baseWidth
|
return baseWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
height: isSliderOnlyRow ? 48 : 60
|
height: 60
|
||||||
|
|
||||||
editMode: root.editMode
|
Loader {
|
||||||
widgetIndex: globalWidgetIndex
|
id: widgetLoader
|
||||||
gridCellWidth: width
|
anchors.fill: parent
|
||||||
gridCellHeight: height
|
property var widgetData: parent.widgetData
|
||||||
gridColumns: 4
|
property int widgetIndex: parent.globalWidgetIndex
|
||||||
gridLayout: root
|
property int globalWidgetIndex: parent.globalWidgetIndex
|
||||||
isSlider: {
|
property int widgetWidth: parent.widgetWidth
|
||||||
const id = modelData.id || ""
|
|
||||||
return id === "volumeSlider" || id === "brightnessSlider" || id === "inputVolumeSlider"
|
|
||||||
}
|
|
||||||
|
|
||||||
widgetComponent: {
|
sourceComponent: {
|
||||||
const id = modelData.id || ""
|
const id = modelData.id || ""
|
||||||
if (id === "wifi" || id === "bluetooth" || id === "audioOutput" || id === "audioInput") {
|
if (id === "wifi" || id === "bluetooth" || id === "audioOutput" || id === "audioInput") {
|
||||||
return compoundPillComponent
|
return compoundPillComponent
|
||||||
} else if (id === "volumeSlider") {
|
} else if (id === "volumeSlider") {
|
||||||
return audioSliderComponent
|
return audioSliderComponent
|
||||||
} else if (id === "brightnessSlider") {
|
} else if (id === "brightnessSlider") {
|
||||||
return brightnessSliderComponent
|
return brightnessSliderComponent
|
||||||
} else if (id === "inputVolumeSlider") {
|
} else if (id === "inputVolumeSlider") {
|
||||||
return inputAudioSliderComponent
|
return inputAudioSliderComponent
|
||||||
} else if (id === "battery") {
|
} else if (id === "battery") {
|
||||||
return widgetWidth <= 25 ? smallBatteryComponent : batteryPillComponent
|
return widgetWidth <= 25 ? smallBatteryComponent : batteryPillComponent
|
||||||
} else if (id === "diskUsage") {
|
} else if (id === "diskUsage") {
|
||||||
return diskUsagePillComponent
|
return diskUsagePillComponent
|
||||||
} else if (id === "colorPicker") {
|
} else {
|
||||||
return colorPickerPillComponent
|
return widgetWidth <= 25 ? smallToggleComponent : toggleButtonComponent
|
||||||
} else {
|
}
|
||||||
return widgetWidth <= 25 ? smallToggleComponent : toggleButtonComponent
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
onWidgetMoved: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
}
|
||||||
onRemoveWidget: index => root.removeWidget(index)
|
|
||||||
onToggleWidgetSize: index => root.toggleWidgetSize(index)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,7 +142,6 @@ Column {
|
|||||||
visible: active
|
visible: active
|
||||||
expandedSection: root.expandedSection
|
expandedSection: root.expandedSection
|
||||||
expandedWidgetData: root.expandedWidgetData
|
expandedWidgetData: root.expandedWidgetData
|
||||||
bluetoothCodecSelector: root.bluetoothCodecSelector
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -178,198 +156,201 @@ Column {
|
|||||||
height: 60
|
height: 60
|
||||||
iconName: {
|
iconName: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "wifi":
|
case "wifi": {
|
||||||
{
|
if (NetworkService.wifiToggling) {
|
||||||
if (NetworkService.wifiToggling)
|
|
||||||
return "sync"
|
return "sync"
|
||||||
if (NetworkService.networkStatus === "ethernet")
|
}
|
||||||
|
if (NetworkService.networkStatus === "ethernet") {
|
||||||
return "settings_ethernet"
|
return "settings_ethernet"
|
||||||
if (NetworkService.networkStatus === "wifi")
|
}
|
||||||
|
if (NetworkService.networkStatus === "wifi") {
|
||||||
return NetworkService.wifiSignalIcon
|
return NetworkService.wifiSignalIcon
|
||||||
if (NetworkService.wifiEnabled)
|
}
|
||||||
|
if (NetworkService.wifiEnabled) {
|
||||||
return "wifi_off"
|
return "wifi_off"
|
||||||
|
}
|
||||||
return "wifi_off"
|
return "wifi_off"
|
||||||
}
|
}
|
||||||
case "bluetooth":
|
case "bluetooth": {
|
||||||
{
|
if (!BluetoothService.available) {
|
||||||
if (!BluetoothService.available)
|
|
||||||
return "bluetooth_disabled"
|
return "bluetooth_disabled"
|
||||||
if (!BluetoothService.adapter || !BluetoothService.adapter.enabled)
|
}
|
||||||
|
if (!BluetoothService.adapter || !BluetoothService.adapter.enabled) {
|
||||||
return "bluetooth_disabled"
|
return "bluetooth_disabled"
|
||||||
|
}
|
||||||
const primaryDevice = (() => {
|
const primaryDevice = (() => {
|
||||||
if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
|
if (!BluetoothService.adapter || !BluetoothService.adapter.devices) {
|
||||||
return null
|
return null
|
||||||
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
|
}
|
||||||
for (let device of devices) {
|
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
|
||||||
if (device && device.connected)
|
for (let device of devices) {
|
||||||
return device
|
if (device && device.connected) {
|
||||||
}
|
return device
|
||||||
return null
|
}
|
||||||
})()
|
}
|
||||||
if (primaryDevice)
|
return null
|
||||||
|
})()
|
||||||
|
if (primaryDevice) {
|
||||||
return BluetoothService.getDeviceIcon(primaryDevice)
|
return BluetoothService.getDeviceIcon(primaryDevice)
|
||||||
|
}
|
||||||
return "bluetooth"
|
return "bluetooth"
|
||||||
}
|
}
|
||||||
case "audioOutput":
|
case "audioOutput": {
|
||||||
{
|
if (!AudioService.sink) return "volume_off"
|
||||||
if (!AudioService.sink)
|
|
||||||
return "volume_off"
|
|
||||||
let volume = AudioService.sink.audio.volume
|
let volume = AudioService.sink.audio.volume
|
||||||
let muted = AudioService.sink.audio.muted
|
let muted = AudioService.sink.audio.muted
|
||||||
if (muted || volume === 0.0)
|
if (muted || volume === 0.0) return "volume_off"
|
||||||
return "volume_off"
|
if (volume <= 0.33) return "volume_down"
|
||||||
if (volume <= 0.33)
|
if (volume <= 0.66) return "volume_up"
|
||||||
return "volume_down"
|
|
||||||
if (volume <= 0.66)
|
|
||||||
return "volume_up"
|
|
||||||
return "volume_up"
|
return "volume_up"
|
||||||
}
|
}
|
||||||
case "audioInput":
|
case "audioInput": {
|
||||||
{
|
if (!AudioService.source) return "mic_off"
|
||||||
if (!AudioService.source)
|
|
||||||
return "mic_off"
|
|
||||||
let muted = AudioService.source.audio.muted
|
let muted = AudioService.source.audio.muted
|
||||||
return muted ? "mic_off" : "mic"
|
return muted ? "mic_off" : "mic"
|
||||||
}
|
}
|
||||||
default:
|
default: return widgetDef?.icon || "help"
|
||||||
return widgetDef?.icon || "help"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
primaryText: {
|
primaryText: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "wifi":
|
case "wifi": {
|
||||||
{
|
if (NetworkService.wifiToggling) {
|
||||||
if (NetworkService.wifiToggling)
|
|
||||||
return NetworkService.wifiEnabled ? "Disabling WiFi..." : "Enabling WiFi..."
|
return NetworkService.wifiEnabled ? "Disabling WiFi..." : "Enabling WiFi..."
|
||||||
if (NetworkService.networkStatus === "ethernet")
|
}
|
||||||
|
if (NetworkService.networkStatus === "ethernet") {
|
||||||
return "Ethernet"
|
return "Ethernet"
|
||||||
if (NetworkService.networkStatus === "wifi" && NetworkService.currentWifiSSID)
|
}
|
||||||
|
if (NetworkService.networkStatus === "wifi" && NetworkService.currentWifiSSID) {
|
||||||
return NetworkService.currentWifiSSID
|
return NetworkService.currentWifiSSID
|
||||||
if (NetworkService.wifiEnabled)
|
}
|
||||||
|
if (NetworkService.wifiEnabled) {
|
||||||
return "Not connected"
|
return "Not connected"
|
||||||
|
}
|
||||||
return "WiFi off"
|
return "WiFi off"
|
||||||
}
|
}
|
||||||
case "bluetooth":
|
case "bluetooth": {
|
||||||
{
|
if (!BluetoothService.available) {
|
||||||
if (!BluetoothService.available)
|
|
||||||
return "Bluetooth"
|
return "Bluetooth"
|
||||||
if (!BluetoothService.adapter)
|
}
|
||||||
|
if (!BluetoothService.adapter) {
|
||||||
return "No adapter"
|
return "No adapter"
|
||||||
if (!BluetoothService.adapter.enabled)
|
}
|
||||||
|
if (!BluetoothService.adapter.enabled) {
|
||||||
return "Disabled"
|
return "Disabled"
|
||||||
|
}
|
||||||
return "Enabled"
|
return "Enabled"
|
||||||
}
|
}
|
||||||
case "audioOutput":
|
case "audioOutput": return AudioService.sink?.description || "No output device"
|
||||||
return AudioService.sink?.description || "No output device"
|
case "audioInput": return AudioService.source?.description || "No input device"
|
||||||
case "audioInput":
|
default: return widgetDef?.text || "Unknown"
|
||||||
return AudioService.source?.description || "No input device"
|
|
||||||
default:
|
|
||||||
return widgetDef?.text || "Unknown"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
secondaryText: {
|
secondaryText: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "wifi":
|
case "wifi": {
|
||||||
{
|
if (NetworkService.wifiToggling) {
|
||||||
if (NetworkService.wifiToggling)
|
|
||||||
return "Please wait..."
|
return "Please wait..."
|
||||||
if (NetworkService.networkStatus === "ethernet")
|
}
|
||||||
|
if (NetworkService.networkStatus === "ethernet") {
|
||||||
return "Connected"
|
return "Connected"
|
||||||
if (NetworkService.networkStatus === "wifi")
|
}
|
||||||
|
if (NetworkService.networkStatus === "wifi") {
|
||||||
return NetworkService.wifiSignalStrength > 0 ? NetworkService.wifiSignalStrength + "%" : "Connected"
|
return NetworkService.wifiSignalStrength > 0 ? NetworkService.wifiSignalStrength + "%" : "Connected"
|
||||||
if (NetworkService.wifiEnabled)
|
}
|
||||||
|
if (NetworkService.wifiEnabled) {
|
||||||
return "Select network"
|
return "Select network"
|
||||||
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
case "bluetooth":
|
case "bluetooth": {
|
||||||
{
|
if (!BluetoothService.available) {
|
||||||
if (!BluetoothService.available)
|
|
||||||
return "No adapters"
|
return "No adapters"
|
||||||
if (!BluetoothService.adapter || !BluetoothService.adapter.enabled)
|
}
|
||||||
|
if (!BluetoothService.adapter || !BluetoothService.adapter.enabled) {
|
||||||
return "Off"
|
return "Off"
|
||||||
|
}
|
||||||
const primaryDevice = (() => {
|
const primaryDevice = (() => {
|
||||||
if (!BluetoothService.adapter || !BluetoothService.adapter.devices)
|
if (!BluetoothService.adapter || !BluetoothService.adapter.devices) {
|
||||||
return null
|
return null
|
||||||
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
|
}
|
||||||
for (let device of devices) {
|
let devices = [...BluetoothService.adapter.devices.values.filter(dev => dev && (dev.paired || dev.trusted))]
|
||||||
if (device && device.connected)
|
for (let device of devices) {
|
||||||
return device
|
if (device && device.connected) {
|
||||||
}
|
return device
|
||||||
return null
|
}
|
||||||
})()
|
}
|
||||||
if (primaryDevice)
|
return null
|
||||||
|
})()
|
||||||
|
if (primaryDevice) {
|
||||||
return primaryDevice.name || primaryDevice.alias || primaryDevice.deviceName || "Connected Device"
|
return primaryDevice.name || primaryDevice.alias || primaryDevice.deviceName || "Connected Device"
|
||||||
|
}
|
||||||
return "No devices"
|
return "No devices"
|
||||||
}
|
}
|
||||||
case "audioOutput":
|
case "audioOutput": {
|
||||||
{
|
if (!AudioService.sink) {
|
||||||
if (!AudioService.sink)
|
|
||||||
return "Select device"
|
return "Select device"
|
||||||
if (AudioService.sink.audio.muted)
|
}
|
||||||
|
if (AudioService.sink.audio.muted) {
|
||||||
return "Muted"
|
return "Muted"
|
||||||
|
}
|
||||||
return Math.round(AudioService.sink.audio.volume * 100) + "%"
|
return Math.round(AudioService.sink.audio.volume * 100) + "%"
|
||||||
}
|
}
|
||||||
case "audioInput":
|
case "audioInput": {
|
||||||
{
|
if (!AudioService.source) {
|
||||||
if (!AudioService.source)
|
|
||||||
return "Select device"
|
return "Select device"
|
||||||
if (AudioService.source.audio.muted)
|
}
|
||||||
|
if (AudioService.source.audio.muted) {
|
||||||
return "Muted"
|
return "Muted"
|
||||||
|
}
|
||||||
return Math.round(AudioService.source.audio.volume * 100) + "%"
|
return Math.round(AudioService.source.audio.volume * 100) + "%"
|
||||||
}
|
}
|
||||||
default:
|
default: return widgetDef?.description || ""
|
||||||
return widgetDef?.description || ""
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isActive: {
|
isActive: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "wifi":
|
case "wifi": {
|
||||||
{
|
if (NetworkService.wifiToggling) {
|
||||||
if (NetworkService.wifiToggling)
|
|
||||||
return false
|
return false
|
||||||
if (NetworkService.networkStatus === "ethernet")
|
}
|
||||||
|
if (NetworkService.networkStatus === "ethernet") {
|
||||||
return true
|
return true
|
||||||
if (NetworkService.networkStatus === "wifi")
|
}
|
||||||
|
if (NetworkService.networkStatus === "wifi") {
|
||||||
return true
|
return true
|
||||||
|
}
|
||||||
return NetworkService.wifiEnabled
|
return NetworkService.wifiEnabled
|
||||||
}
|
}
|
||||||
case "bluetooth":
|
case "bluetooth": return !!(BluetoothService.available && BluetoothService.adapter && BluetoothService.adapter.enabled)
|
||||||
return !!(BluetoothService.available && BluetoothService.adapter && BluetoothService.adapter.enabled)
|
case "audioOutput": return !!(AudioService.sink && !AudioService.sink.audio.muted)
|
||||||
case "audioOutput":
|
case "audioInput": return !!(AudioService.source && !AudioService.source.audio.muted)
|
||||||
return !!(AudioService.sink && !AudioService.sink.audio.muted)
|
default: return false
|
||||||
case "audioInput":
|
|
||||||
return !!(AudioService.source && !AudioService.source.audio.muted)
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enabled: widgetDef?.enabled ?? true
|
enabled: (widgetDef?.enabled ?? true)
|
||||||
onToggled: {
|
onToggled: {
|
||||||
if (root.editMode) return
|
if (root.editMode) return
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "wifi":
|
case "wifi": {
|
||||||
{
|
|
||||||
if (NetworkService.networkStatus !== "ethernet" && !NetworkService.wifiToggling) {
|
if (NetworkService.networkStatus !== "ethernet" && !NetworkService.wifiToggling) {
|
||||||
NetworkService.toggleWifiRadio()
|
NetworkService.toggleWifiRadio()
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "bluetooth":
|
case "bluetooth": {
|
||||||
{
|
|
||||||
if (BluetoothService.available && BluetoothService.adapter) {
|
if (BluetoothService.available && BluetoothService.adapter) {
|
||||||
BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled
|
BluetoothService.adapter.enabled = !BluetoothService.adapter.enabled
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "audioOutput":
|
case "audioOutput": {
|
||||||
{
|
|
||||||
if (AudioService.sink && AudioService.sink.audio) {
|
if (AudioService.sink && AudioService.sink.audio) {
|
||||||
AudioService.sink.audio.muted = !AudioService.sink.audio.muted
|
AudioService.sink.audio.muted = !AudioService.sink.audio.muted
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "audioInput":
|
case "audioInput": {
|
||||||
{
|
|
||||||
if (AudioService.source && AudioService.source.audio) {
|
if (AudioService.source && AudioService.source.audio) {
|
||||||
AudioService.source.audio.muted = !AudioService.source.audio.muted
|
AudioService.source.audio.muted = !AudioService.source.audio.muted
|
||||||
}
|
}
|
||||||
@@ -382,11 +363,9 @@ Column {
|
|||||||
root.expandClicked(widgetData, widgetIndex)
|
root.expandClicked(widgetData, widgetIndex)
|
||||||
}
|
}
|
||||||
onWheelEvent: function (wheelEvent) {
|
onWheelEvent: function (wheelEvent) {
|
||||||
if (root.editMode) return
|
|
||||||
const id = widgetData.id || ""
|
const id = widgetData.id || ""
|
||||||
if (id === "audioOutput") {
|
if (id === "audioOutput") {
|
||||||
if (!AudioService.sink || !AudioService.sink.audio)
|
if (!AudioService.sink || !AudioService.sink.audio) return
|
||||||
return
|
|
||||||
let delta = wheelEvent.angleDelta.y
|
let delta = wheelEvent.angleDelta.y
|
||||||
let currentVolume = AudioService.sink.audio.volume * 100
|
let currentVolume = AudioService.sink.audio.volume * 100
|
||||||
let newVolume
|
let newVolume
|
||||||
@@ -398,8 +377,7 @@ Column {
|
|||||||
AudioService.sink.audio.volume = newVolume / 100
|
AudioService.sink.audio.volume = newVolume / 100
|
||||||
wheelEvent.accepted = true
|
wheelEvent.accepted = true
|
||||||
} else if (id === "audioInput") {
|
} else if (id === "audioInput") {
|
||||||
if (!AudioService.source || !AudioService.source.audio)
|
if (!AudioService.source || !AudioService.source.audio) return
|
||||||
return
|
|
||||||
let delta = wheelEvent.angleDelta.y
|
let delta = wheelEvent.angleDelta.y
|
||||||
let currentVolume = AudioService.source.audio.volume * 100
|
let currentVolume = AudioService.source.audio.volume * 100
|
||||||
let newVolume
|
let newVolume
|
||||||
@@ -412,6 +390,18 @@ Column {
|
|||||||
wheelEvent.accepted = true
|
wheelEvent.accepted = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: false
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -420,6 +410,7 @@ Column {
|
|||||||
Item {
|
Item {
|
||||||
property var widgetData: parent.widgetData || {}
|
property var widgetData: parent.widgetData || {}
|
||||||
property int widgetIndex: parent.widgetIndex || 0
|
property int widgetIndex: parent.widgetIndex || 0
|
||||||
|
property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 16
|
height: 16
|
||||||
|
|
||||||
@@ -429,6 +420,18 @@ Column {
|
|||||||
height: 14
|
height: 14
|
||||||
property color sliderTrackColor: Theme.surfaceContainerHigh
|
property color sliderTrackColor: Theme.surfaceContainerHigh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: true
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -446,6 +449,18 @@ Column {
|
|||||||
height: 14
|
height: 14
|
||||||
property color sliderTrackColor: Theme.surfaceContainerHigh
|
property color sliderTrackColor: Theme.surfaceContainerHigh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: true
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,6 +478,18 @@ Column {
|
|||||||
height: 14
|
height: 14
|
||||||
property color sliderTrackColor: Theme.surfaceContainerHigh
|
property color sliderTrackColor: Theme.surfaceContainerHigh
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: true
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -479,6 +506,18 @@ Column {
|
|||||||
root.expandClicked(widgetData, widgetIndex)
|
root.expandClicked(widgetData, widgetIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: false
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -495,6 +534,18 @@ Column {
|
|||||||
root.expandClicked(widgetData, widgetIndex)
|
root.expandClicked(widgetData, widgetIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: false
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,99 +554,80 @@ Column {
|
|||||||
ToggleButton {
|
ToggleButton {
|
||||||
property var widgetData: parent.widgetData || {}
|
property var widgetData: parent.widgetData || {}
|
||||||
property int widgetIndex: parent.widgetIndex || 0
|
property int widgetIndex: parent.widgetIndex || 0
|
||||||
|
property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 60
|
height: 60
|
||||||
|
|
||||||
iconName: {
|
iconName: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "nightMode":
|
case "nightMode": return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode"
|
||||||
return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode"
|
case "darkMode": return "contrast"
|
||||||
case "darkMode":
|
case "doNotDisturb": return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"
|
||||||
return "contrast"
|
case "idleInhibitor": return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
|
||||||
case "doNotDisturb":
|
default: return widgetDef?.icon || "help"
|
||||||
return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"
|
|
||||||
case "idleInhibitor":
|
|
||||||
return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
|
|
||||||
default:
|
|
||||||
return "help"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
text: {
|
text: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "nightMode":
|
case "nightMode": return "Night Mode"
|
||||||
return "Night Mode"
|
case "darkMode": return SessionData.isLightMode ? "Light Mode" : "Dark Mode"
|
||||||
case "darkMode":
|
case "doNotDisturb": return "Do Not Disturb"
|
||||||
return SessionData.isLightMode ? "Light Mode" : "Dark Mode"
|
case "idleInhibitor": return SessionService.idleInhibited ? "Keeping Awake" : "Keep Awake"
|
||||||
case "doNotDisturb":
|
default: return widgetDef?.text || "Unknown"
|
||||||
return "Do Not Disturb"
|
|
||||||
case "idleInhibitor":
|
|
||||||
return SessionService.idleInhibited ? "Keeping Awake" : "Keep Awake"
|
|
||||||
default:
|
|
||||||
return "Unknown"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iconRotation: {
|
secondaryText: ""
|
||||||
if (widgetData.id !== "darkMode") return 0
|
|
||||||
if (darkModeTransitionPending) {
|
iconRotation: widgetData.id === "darkMode" && SessionData.isLightMode ? 180 : 0
|
||||||
return SessionData.isLightMode ? 0 : 180
|
|
||||||
}
|
|
||||||
return SessionData.isLightMode ? 180 : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
isActive: {
|
isActive: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "nightMode":
|
case "nightMode": return DisplayService.nightModeEnabled || false
|
||||||
return DisplayService.nightModeEnabled || false
|
case "darkMode": return !SessionData.isLightMode
|
||||||
case "darkMode":
|
case "doNotDisturb": return SessionData.doNotDisturb || false
|
||||||
return !SessionData.isLightMode
|
case "idleInhibitor": return SessionService.idleInhibited || false
|
||||||
case "doNotDisturb":
|
default: return false
|
||||||
return SessionData.doNotDisturb || false
|
|
||||||
case "idleInhibitor":
|
|
||||||
return SessionService.idleInhibited || false
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enabled: !root.editMode
|
enabled: (widgetDef?.enabled ?? true) && !root.editMode
|
||||||
|
|
||||||
onIconRotationCompleted: {
|
|
||||||
if (root.darkModeTransitionPending && widgetData.id === "darkMode") {
|
|
||||||
root.darkModeTransitionPending = false
|
|
||||||
Theme.screenTransition()
|
|
||||||
Theme.toggleLightMode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.editMode)
|
|
||||||
return
|
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "nightMode":
|
case "nightMode": {
|
||||||
{
|
if (DisplayService.automationAvailable) {
|
||||||
if (DisplayService.automationAvailable)
|
|
||||||
DisplayService.toggleNightMode()
|
DisplayService.toggleNightMode()
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "darkMode":
|
case "darkMode": {
|
||||||
{
|
Theme.toggleLightMode()
|
||||||
root.darkModeTransitionPending = true
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "doNotDisturb":
|
case "doNotDisturb": {
|
||||||
{
|
|
||||||
SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "idleInhibitor":
|
case "idleInhibitor": {
|
||||||
{
|
|
||||||
SessionService.toggleIdleInhibit()
|
SessionService.toggleIdleInhibit()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: false
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,84 +636,68 @@ enabled: !root.editMode
|
|||||||
SmallToggleButton {
|
SmallToggleButton {
|
||||||
property var widgetData: parent.widgetData || {}
|
property var widgetData: parent.widgetData || {}
|
||||||
property int widgetIndex: parent.widgetIndex || 0
|
property int widgetIndex: parent.widgetIndex || 0
|
||||||
|
property var widgetDef: root.model?.getWidgetForId(widgetData.id || "")
|
||||||
width: parent.width
|
width: parent.width
|
||||||
height: 48
|
height: 48
|
||||||
|
|
||||||
iconName: {
|
iconName: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "nightMode":
|
case "nightMode": return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode"
|
||||||
return DisplayService.nightModeEnabled ? "nightlight" : "dark_mode"
|
case "darkMode": return "contrast"
|
||||||
case "darkMode":
|
case "doNotDisturb": return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"
|
||||||
return "contrast"
|
case "idleInhibitor": return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
|
||||||
case "doNotDisturb":
|
default: return widgetDef?.icon || "help"
|
||||||
return SessionData.doNotDisturb ? "do_not_disturb_on" : "do_not_disturb_off"
|
|
||||||
case "idleInhibitor":
|
|
||||||
return SessionService.idleInhibited ? "motion_sensor_active" : "motion_sensor_idle"
|
|
||||||
default:
|
|
||||||
return "help"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iconRotation: {
|
iconRotation: widgetData.id === "darkMode" && SessionData.isLightMode ? 180 : 0
|
||||||
if (widgetData.id !== "darkMode") return 0
|
|
||||||
if (darkModeTransitionPending) {
|
|
||||||
return SessionData.isLightMode ? 0 : 180
|
|
||||||
}
|
|
||||||
return SessionData.isLightMode ? 180 : 0
|
|
||||||
}
|
|
||||||
|
|
||||||
isActive: {
|
isActive: {
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "nightMode":
|
case "nightMode": return DisplayService.nightModeEnabled || false
|
||||||
return DisplayService.nightModeEnabled || false
|
case "darkMode": return !SessionData.isLightMode
|
||||||
case "darkMode":
|
case "doNotDisturb": return SessionData.doNotDisturb || false
|
||||||
return !SessionData.isLightMode
|
case "idleInhibitor": return SessionService.idleInhibited || false
|
||||||
case "doNotDisturb":
|
default: return false
|
||||||
return SessionData.doNotDisturb || false
|
|
||||||
case "idleInhibitor":
|
|
||||||
return SessionService.idleInhibited || false
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enabled: !root.editMode
|
enabled: (widgetDef?.enabled ?? true) && !root.editMode
|
||||||
|
|
||||||
onIconRotationCompleted: {
|
|
||||||
if (root.darkModeTransitionPending && widgetData.id === "darkMode") {
|
|
||||||
root.darkModeTransitionPending = false
|
|
||||||
Theme.screenTransition()
|
|
||||||
Theme.toggleLightMode()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (root.editMode)
|
|
||||||
return
|
|
||||||
switch (widgetData.id || "") {
|
switch (widgetData.id || "") {
|
||||||
case "nightMode":
|
case "nightMode": {
|
||||||
{
|
if (DisplayService.automationAvailable) {
|
||||||
if (DisplayService.automationAvailable)
|
|
||||||
DisplayService.toggleNightMode()
|
DisplayService.toggleNightMode()
|
||||||
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "darkMode":
|
case "darkMode": {
|
||||||
{
|
Theme.toggleLightMode()
|
||||||
root.darkModeTransitionPending = true
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "doNotDisturb":
|
case "doNotDisturb": {
|
||||||
{
|
|
||||||
SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
SessionData.setDoNotDisturb(!SessionData.doNotDisturb)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case "idleInhibitor":
|
case "idleInhibitor": {
|
||||||
{
|
|
||||||
SessionService.toggleIdleInhibit()
|
SessionService.toggleIdleInhibit()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: false
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -701,18 +717,18 @@ enabled: !root.editMode
|
|||||||
root.expandClicked(widgetData, widgetIndex)
|
root.expandClicked(widgetData, widgetIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EditModeOverlay {
|
||||||
|
anchors.fill: parent
|
||||||
|
editMode: root.editMode
|
||||||
|
widgetData: parent.widgetData
|
||||||
|
widgetIndex: parent.widgetIndex
|
||||||
|
showSizeControls: true
|
||||||
|
isSlider: false
|
||||||
|
onRemoveWidget: (index) => root.removeWidget(index)
|
||||||
|
onToggleWidgetSize: (index) => root.toggleWidgetSize(index)
|
||||||
|
onMoveWidget: (fromIndex, toIndex) => root.moveWidget(fromIndex, toIndex)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Component {
|
|
||||||
id: colorPickerPillComponent
|
|
||||||
ColorPickerPill {
|
|
||||||
property var widgetData: parent.widgetData || {}
|
|
||||||
property int widgetIndex: parent.widgetIndex || 0
|
|
||||||
width: parent.width
|
|
||||||
height: 60
|
|
||||||
|
|
||||||
colorPickerModal: root.colorPickerModal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -10,7 +10,7 @@ import qs.Common
|
|||||||
import qs.Modules.ControlCenter
|
import qs.Modules.ControlCenter
|
||||||
import qs.Modules.ControlCenter.Widgets
|
import qs.Modules.ControlCenter.Widgets
|
||||||
import qs.Modules.ControlCenter.Details
|
import qs.Modules.ControlCenter.Details
|
||||||
import qs.Modules.DankBar
|
import qs.Modules.TopBar
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
import qs.Modules.ControlCenter.Components
|
import qs.Modules.ControlCenter.Components
|
||||||
@@ -21,11 +21,14 @@ DankPopout {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property string expandedSection: ""
|
property string expandedSection: ""
|
||||||
|
property bool powerOptionsExpanded: false
|
||||||
|
property string triggerSection: "right"
|
||||||
property var triggerScreen: null
|
property var triggerScreen: null
|
||||||
property bool editMode: false
|
property bool editMode: false
|
||||||
property int expandedWidgetIndex: -1
|
property int expandedWidgetIndex: -1
|
||||||
property var expandedWidgetData: null
|
property var expandedWidgetData: null
|
||||||
|
|
||||||
|
signal powerActionRequested(string action, string title, string message)
|
||||||
signal lockRequested
|
signal lockRequested
|
||||||
|
|
||||||
function collapseAll() {
|
function collapseAll() {
|
||||||
@@ -63,9 +66,9 @@ DankPopout {
|
|||||||
popupWidth: 550
|
popupWidth: 550
|
||||||
popupHeight: Math.min((triggerScreen?.height ?? 1080) - 100, contentLoader.item && contentLoader.item.implicitHeight > 0 ? contentLoader.item.implicitHeight + 20 : 400)
|
popupHeight: Math.min((triggerScreen?.height ?? 1080) - 100, contentLoader.item && contentLoader.item.implicitHeight > 0 ? contentLoader.item.implicitHeight + 20 : 400)
|
||||||
triggerX: (triggerScreen?.width ?? 1920) - 600 - Theme.spacingL
|
triggerX: (triggerScreen?.width ?? 1920) - 600 - Theme.spacingL
|
||||||
triggerY: Theme.barHeight - 4 + SettingsData.dankBarSpacing
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
||||||
triggerWidth: 80
|
triggerWidth: 80
|
||||||
positioning: ""
|
positioning: "center"
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
shouldBeVisible: false
|
shouldBeVisible: false
|
||||||
visible: shouldBeVisible
|
visible: shouldBeVisible
|
||||||
@@ -99,14 +102,14 @@ DankPopout {
|
|||||||
property alias bluetoothCodecSelector: bluetoothCodecSelector
|
property alias bluetoothCodecSelector: bluetoothCodecSelector
|
||||||
|
|
||||||
color: {
|
color: {
|
||||||
const transparency = Theme.popupTransparency
|
const transparency = Theme.popupTransparency || 0.92
|
||||||
const surface = Theme.surfaceContainer || Qt.rgba(0.1, 0.1, 0.1, 1)
|
const surface = Theme.surfaceContainer || Qt.rgba(0.1, 0.1, 0.1, 1)
|
||||||
return Qt.rgba(surface.r, surface.g, surface.b, transparency)
|
return Qt.rgba(surface.r, surface.g, surface.b, transparency)
|
||||||
}
|
}
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
Theme.outline.b, 0.08)
|
Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
smooth: true
|
smooth: true
|
||||||
|
|
||||||
@@ -120,25 +123,29 @@ DankPopout {
|
|||||||
HeaderPane {
|
HeaderPane {
|
||||||
id: headerPane
|
id: headerPane
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
powerOptionsExpanded: root.powerOptionsExpanded
|
||||||
editMode: root.editMode
|
editMode: root.editMode
|
||||||
|
onPowerOptionsExpandedChanged: root.powerOptionsExpanded = powerOptionsExpanded
|
||||||
onEditModeToggled: root.editMode = !root.editMode
|
onEditModeToggled: root.editMode = !root.editMode
|
||||||
onPowerButtonClicked: {
|
onPowerActionRequested: (action, title, message) => root.powerActionRequested(action, title, message)
|
||||||
if (powerMenuModalLoader) {
|
|
||||||
powerMenuModalLoader.active = true
|
|
||||||
if (powerMenuModalLoader.item) {
|
|
||||||
const popoutPos = controlContent.mapToItem(null, 0, 0)
|
|
||||||
const bounds = Qt.rect(popoutPos.x, popoutPos.y, controlContent.width, controlContent.height)
|
|
||||||
powerMenuModalLoader.item.openFromControlCenter(bounds, root.triggerScreen)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onLockRequested: {
|
onLockRequested: {
|
||||||
root.close()
|
root.close()
|
||||||
root.lockRequested()
|
root.lockRequested()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DragDropGrid {
|
PowerOptionsPane {
|
||||||
|
id: powerOptionsPane
|
||||||
|
width: parent.width
|
||||||
|
expanded: root.powerOptionsExpanded
|
||||||
|
onPowerActionRequested: (action, title, message) => {
|
||||||
|
root.powerOptionsExpanded = false
|
||||||
|
root.close()
|
||||||
|
root.powerActionRequested(action, title, message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetGrid {
|
||||||
id: widgetGrid
|
id: widgetGrid
|
||||||
width: parent.width
|
width: parent.width
|
||||||
editMode: root.editMode
|
editMode: root.editMode
|
||||||
@@ -146,8 +153,6 @@ DankPopout {
|
|||||||
expandedWidgetIndex: root.expandedWidgetIndex
|
expandedWidgetIndex: root.expandedWidgetIndex
|
||||||
expandedWidgetData: root.expandedWidgetData
|
expandedWidgetData: root.expandedWidgetData
|
||||||
model: widgetModel
|
model: widgetModel
|
||||||
bluetoothCodecSelector: bluetoothCodecSelector
|
|
||||||
colorPickerModal: root.colorPickerModal
|
|
||||||
onExpandClicked: (widgetData, globalIndex) => {
|
onExpandClicked: (widgetData, globalIndex) => {
|
||||||
root.expandedWidgetIndex = globalIndex
|
root.expandedWidgetIndex = globalIndex
|
||||||
root.expandedWidgetData = widgetData
|
root.expandedWidgetData = widgetData
|
||||||
@@ -165,7 +170,6 @@ DankPopout {
|
|||||||
EditControls {
|
EditControls {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: editMode
|
visible: editMode
|
||||||
popoutContent: controlContent
|
|
||||||
availableWidgets: {
|
availableWidgets: {
|
||||||
const existingIds = (SettingsData.controlCenterWidgets || []).map(w => w.id)
|
const existingIds = (SettingsData.controlCenterWidgets || []).map(w => w.id)
|
||||||
return widgetModel.baseWidgetDefinitions.filter(w => w.allowMultiple || !existingIds.includes(w.id))
|
return widgetModel.baseWidgetDefinitions.filter(w => w.allowMultiple || !existingIds.includes(w.id))
|
||||||
@@ -218,7 +222,4 @@ DankPopout {
|
|||||||
id: batteryDetailComponent
|
id: batteryDetailComponent
|
||||||
BatteryDetail {}
|
BatteryDetail {}
|
||||||
}
|
}
|
||||||
|
|
||||||
property var colorPickerModal: null
|
|
||||||
property var powerMenuModalLoader: null
|
|
||||||
}
|
}
|
||||||
@@ -16,7 +16,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: headerRow
|
id: headerRow
|
||||||
@@ -57,6 +57,10 @@ Rectangle {
|
|||||||
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
||||||
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: iconArea
|
id: iconArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -134,9 +138,9 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 50
|
height: 50
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
|
color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHigh
|
||||||
border.color: modelData === AudioService.source ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: modelData === AudioService.source ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: 0
|
border.width: modelData === AudioService.source ? 2 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -194,6 +198,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: headerRow
|
id: headerRow
|
||||||
@@ -57,6 +57,10 @@ Rectangle {
|
|||||||
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
||||||
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: iconArea
|
id: iconArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
@@ -139,9 +143,9 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 50
|
height: 50
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
|
color: deviceMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHigh
|
||||||
border.color: modelData === AudioService.sink ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: modelData === AudioService.sink ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: 0
|
border.width: modelData === AudioService.sink ? 2 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -201,6 +205,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
function isActiveProfile(profile) {
|
function isActiveProfile(profile) {
|
||||||
if (typeof PowerProfiles === "undefined") {
|
if (typeof PowerProfiles === "undefined") {
|
||||||
@@ -209,7 +209,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.12)
|
||||||
border.color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3)
|
border.color: Qt.rgba(Theme.error.r, Theme.error.g, Theme.error.b, 0.3)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
visible: (typeof PowerProfiles !== "undefined") && PowerProfiles.degradationReason !== PerformanceDegradationReason.None
|
visible: (typeof PowerProfiles !== "undefined") && PowerProfiles.degradationReason !== PerformanceDegradationReason.None
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ Item {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainer
|
color: Theme.surfaceContainer
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
opacity: modalVisible ? 1 : 0
|
opacity: modalVisible ? 1 : 0
|
||||||
scale: modalVisible ? 1 : 0.9
|
scale: modalVisible ? 1 : 0.9
|
||||||
|
|
||||||
@@ -206,14 +206,14 @@ Item {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: {
|
color: {
|
||||||
if (modelData.name === currentCodec)
|
if (modelData.name === currentCodec)
|
||||||
return Theme.surfaceContainerHighest;
|
return Theme.surfaceContainerHigh;
|
||||||
else if (codecMouseArea.containsMouse)
|
else if (codecMouseArea.containsMouse)
|
||||||
return Theme.surfaceHover;
|
return Theme.surfaceHover;
|
||||||
else
|
else
|
||||||
return "transparent";
|
return "transparent";
|
||||||
}
|
}
|
||||||
border.color: "transparent"
|
border.color: "transparent"
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -272,6 +272,12 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
property var bluetoothCodecModalRef: null
|
property var bluetoothCodecModalRef: null
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ Rectangle {
|
|||||||
return scanMouseArea.containsMouse ? Theme.surfaceContainerHigh : "transparent"
|
return scanMouseArea.containsMouse ? Theme.surfaceContainerHigh : "transparent"
|
||||||
}
|
}
|
||||||
border.color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: BluetoothService.adapter && BluetoothService.adapter.enabled ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
visible: BluetoothService.adapter && BluetoothService.adapter.enabled
|
visible: BluetoothService.adapter && BluetoothService.adapter.enabled
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -96,6 +96,13 @@ Rectangle {
|
|||||||
BluetoothService.adapter.discovering = !BluetoothService.adapter.discovering
|
BluetoothService.adapter.discovering = !BluetoothService.adapter.discovering
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +159,7 @@ Rectangle {
|
|||||||
return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.12)
|
return Qt.rgba(Theme.warning.r, Theme.warning.g, Theme.warning.b, 0.12)
|
||||||
if (deviceMouseArea.containsMouse)
|
if (deviceMouseArea.containsMouse)
|
||||||
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
|
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
|
||||||
return Theme.surfaceContainerHighest
|
return Theme.surfaceContainerHigh
|
||||||
}
|
}
|
||||||
border.color: {
|
border.color: {
|
||||||
if (modelData.state === BluetoothDeviceState.Connecting)
|
if (modelData.state === BluetoothDeviceState.Connecting)
|
||||||
@@ -161,7 +168,7 @@ Rectangle {
|
|||||||
return Theme.primary
|
return Theme.primary
|
||||||
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
}
|
}
|
||||||
border.width: 0
|
border.width: (modelData.connected || modelData.state === BluetoothDeviceState.Connecting) ? 2 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -277,6 +284,14 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,9 +347,9 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 50
|
height: 50
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: availableMouseArea.containsMouse && !isBusy ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
|
color: availableMouseArea.containsMouse && !isBusy ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
opacity: canConnect ? 1 : 0.6
|
opacity: canConnect ? 1 : 0.6
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -412,6 +427,9 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -440,7 +458,7 @@ Rectangle {
|
|||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 0
|
border.width: 1
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,8 +6,6 @@ import qs.Services
|
|||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: root
|
|
||||||
|
|
||||||
property string currentMountPath: "/"
|
property string currentMountPath: "/"
|
||||||
property string instanceId: ""
|
property string instanceId: ""
|
||||||
|
|
||||||
@@ -17,7 +15,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
DgopService.addRef(["diskmounts"])
|
DgopService.addRef(["diskmounts"])
|
||||||
@@ -78,9 +76,9 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 80
|
height: 80
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHighest
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: modelData.mount === currentMountPath ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: modelData.mount === currentMountPath ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: modelData.mount === currentMountPath ? 2 : 0
|
border.width: modelData.mount === currentMountPath ? 2 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -154,11 +152,16 @@ Rectangle {
|
|||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
currentMountPath = modelData.mount
|
if (modelData.mount !== currentMountPath) {
|
||||||
mountPathChanged(modelData.mount)
|
currentMountPath = modelData.mount
|
||||||
|
mountPathChanged(modelData.mount)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
NetworkService.addRef()
|
NetworkService.addRef()
|
||||||
@@ -27,11 +27,20 @@ Rectangle {
|
|||||||
NetworkService.scanWifi()
|
NetworkService.scanWifi()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
NetworkService.removeRef()
|
NetworkService.removeRef()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var wifiPasswordModalRef: {
|
||||||
|
wifiPasswordModalLoader.active = true
|
||||||
|
return wifiPasswordModalLoader.item
|
||||||
|
}
|
||||||
|
property var networkInfoModalRef: {
|
||||||
|
networkInfoModalLoader.active = true
|
||||||
|
return networkInfoModalLoader.item
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: headerRow
|
id: headerRow
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -149,7 +158,7 @@ Rectangle {
|
|||||||
height: 36
|
height: 36
|
||||||
radius: 18
|
radius: 18
|
||||||
color: enableWifiButton.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
|
color: enableWifiButton.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
border.color: Theme.primary
|
border.color: Theme.primary
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
@@ -168,6 +177,12 @@ Rectangle {
|
|||||||
onClicked: NetworkService.toggleWifiRadio()
|
onClicked: NetworkService.toggleWifiRadio()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,9 +242,9 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
height: 50
|
height: 50
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: networkMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHighest
|
color: networkMouseArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) : Theme.surfaceContainerHigh
|
||||||
border.color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: modelData.ssid === NetworkService.currentWifiSSID ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
border.width: 0
|
border.width: modelData.ssid === NetworkService.currentWifiSSID ? 2 : 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
@@ -317,7 +332,9 @@ Rectangle {
|
|||||||
onClicked: function(event) {
|
onClicked: function(event) {
|
||||||
if (modelData.ssid !== NetworkService.currentWifiSSID) {
|
if (modelData.ssid !== NetworkService.currentWifiSSID) {
|
||||||
if (modelData.secured && !modelData.saved) {
|
if (modelData.secured && !modelData.saved) {
|
||||||
wifiPasswordModal.show(modelData.ssid)
|
if (wifiPasswordModalRef) {
|
||||||
|
wifiPasswordModalRef.show(modelData.ssid)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
NetworkService.connectToWifi(modelData.ssid)
|
NetworkService.connectToWifi(modelData.ssid)
|
||||||
}
|
}
|
||||||
@@ -326,6 +343,13 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,7 +369,7 @@ Rectangle {
|
|||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 0
|
border.width: 1
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,7 +395,9 @@ Rectangle {
|
|||||||
NetworkService.disconnectWifi()
|
NetworkService.disconnectWifi()
|
||||||
} else {
|
} else {
|
||||||
if (networkContextMenu.currentSecured && !networkContextMenu.currentSaved) {
|
if (networkContextMenu.currentSecured && !networkContextMenu.currentSaved) {
|
||||||
wifiPasswordModal.show(networkContextMenu.currentSSID)
|
if (wifiPasswordModalRef) {
|
||||||
|
wifiPasswordModalRef.show(networkContextMenu.currentSSID)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
NetworkService.connectToWifi(networkContextMenu.currentSSID)
|
NetworkService.connectToWifi(networkContextMenu.currentSSID)
|
||||||
}
|
}
|
||||||
@@ -397,8 +423,10 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
let networkData = NetworkService.getNetworkInfo(networkContextMenu.currentSSID)
|
if (networkInfoModalRef) {
|
||||||
networkInfoModal.showNetworkInfo(networkContextMenu.currentSSID, networkData)
|
let networkData = NetworkService.getNetworkInfo(networkContextMenu.currentSSID)
|
||||||
|
networkInfoModalRef.showNetworkInfo(networkContextMenu.currentSSID, networkData)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,12 +454,22 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiPasswordModal {
|
LazyLoader {
|
||||||
id: wifiPasswordModal
|
id: wifiPasswordModalLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
WifiPasswordModal {
|
||||||
|
id: wifiPasswordModal
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkInfoModal {
|
LazyLoader {
|
||||||
id: networkInfoModal
|
id: networkInfoModalLoader
|
||||||
|
active: false
|
||||||
|
|
||||||
|
NetworkInfoModal {
|
||||||
|
id: networkInfoModal
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -116,14 +116,6 @@ QtObject {
|
|||||||
"enabled": DgopService.dgopAvailable,
|
"enabled": DgopService.dgopAvailable,
|
||||||
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined,
|
"warning": !DgopService.dgopAvailable ? "Requires 'dgop' tool" : undefined,
|
||||||
"allowMultiple": true
|
"allowMultiple": true
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "colorPicker",
|
|
||||||
"text": "Color Picker",
|
|
||||||
"description": "Choose colors from palette",
|
|
||||||
"icon": "palette",
|
|
||||||
"type": "action",
|
|
||||||
"enabled": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ PanelWindow {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
|
||||||
Theme.outline.b, 0.08)
|
Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
opacity: powerMenuVisible ? 1 : 0
|
opacity: powerMenuVisible ? 1 : 0
|
||||||
scale: powerMenuVisible ? 1 : 0.85
|
scale: powerMenuVisible ? 1 : 0.85
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ Row {
|
|||||||
height: Theme.iconSize + Theme.spacingS * 2
|
height: Theme.iconSize + Theme.spacingS * 2
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
||||||
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0)
|
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: iconArea
|
id: iconArea
|
||||||
@@ -30,9 +34,7 @@ Row {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (defaultSink) {
|
if (defaultSink) {
|
||||||
AudioService.suppressOSD = true
|
|
||||||
defaultSink.audio.muted = !defaultSink.audio.muted
|
defaultSink.audio.muted = !defaultSink.audio.muted
|
||||||
AudioService.suppressOSD = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -69,9 +71,6 @@ Row {
|
|||||||
valueOverride: actualVolumePercent
|
valueOverride: actualVolumePercent
|
||||||
thumbOutlineColor: Theme.surfaceContainer
|
thumbOutlineColor: Theme.surfaceContainer
|
||||||
trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.surfaceContainerHigh
|
trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.surfaceContainerHigh
|
||||||
onIsDraggingChanged: {
|
|
||||||
AudioService.suppressOSD = isDragging
|
|
||||||
}
|
|
||||||
onSliderValueChanged: function(newValue) {
|
onSliderValueChanged: function(newValue) {
|
||||||
if (defaultSink) {
|
if (defaultSink) {
|
||||||
defaultSink.audio.volume = newValue / 100.0
|
defaultSink.audio.volume = newValue / 100.0
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ CompoundPill {
|
|||||||
if (!BluetoothService.adapter || !BluetoothService.adapter.enabled) {
|
if (!BluetoothService.adapter || !BluetoothService.adapter.enabled) {
|
||||||
return "bluetooth_disabled"
|
return "bluetooth_disabled"
|
||||||
}
|
}
|
||||||
|
if (primaryDevice) {
|
||||||
|
return BluetoothService.getDeviceIcon(primaryDevice)
|
||||||
|
}
|
||||||
return "bluetooth"
|
return "bluetooth"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,13 +18,17 @@ Row {
|
|||||||
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
||||||
color: iconArea.containsMouse
|
color: iconArea.containsMouse
|
||||||
? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
|
||||||
: Theme.withAlpha(Theme.primary, 0)
|
: "transparent"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: iconArea
|
id: iconArea
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
cursorShape: DisplayService.devices.length > 1 ? Qt.PointingHandCursor : Qt.ArrowCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
|
||||||
onClicked: function(event) {
|
onClicked: function(event) {
|
||||||
if (DisplayService.devices.length > 1) {
|
if (DisplayService.devices.length > 1) {
|
||||||
@@ -37,22 +41,6 @@ Row {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onEntered: {
|
|
||||||
tooltipLoader.active = true
|
|
||||||
if (tooltipLoader.item) {
|
|
||||||
const tooltipText = DisplayService.currentDevice ? "bl device: " + DisplayService.currentDevice : "Backlight Control"
|
|
||||||
const p = iconArea.mapToItem(null, iconArea.width / 2, 0)
|
|
||||||
tooltipLoader.item.show(tooltipText, p.x, p.y - 40, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onExited: {
|
|
||||||
if (tooltipLoader.item) {
|
|
||||||
tooltipLoader.item.hide()
|
|
||||||
}
|
|
||||||
tooltipLoader.active = false
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
DankIcon {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
name: {
|
name: {
|
||||||
@@ -103,7 +91,7 @@ Row {
|
|||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 0
|
border.width: 1
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,10 +141,4 @@ Row {
|
|||||||
onObjectRemoved: (index, object) => deviceMenu.removeItem(object)
|
onObjectRemoved: (index, object) => deviceMenu.removeItem(object)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: tooltipLoader
|
|
||||||
active: false
|
|
||||||
sourceComponent: DankTooltip {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Quickshell
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
import qs.Modules.ControlCenter.Widgets
|
|
||||||
|
|
||||||
CompoundPill {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var colorPickerModal: null
|
|
||||||
|
|
||||||
isActive: true
|
|
||||||
iconName: "palette"
|
|
||||||
iconColor: Theme.primary
|
|
||||||
primaryText: "Color Picker"
|
|
||||||
secondaryText: "Choose a color"
|
|
||||||
|
|
||||||
onToggled: {
|
|
||||||
console.log("ColorPickerPill toggled, modal:", colorPickerModal)
|
|
||||||
if (colorPickerModal) {
|
|
||||||
colorPickerModal.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onExpandClicked: {
|
|
||||||
console.log("ColorPickerPill expandClicked, modal:", colorPickerModal)
|
|
||||||
if (colorPickerModal) {
|
|
||||||
colorPickerModal.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,7 @@ Rectangle {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
opacity: enabled ? 1.0 : 0.6
|
opacity: enabled ? 1.0 : 0.6
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
|||||||
@@ -29,19 +29,16 @@ Rectangle {
|
|||||||
|
|
||||||
readonly property color _containerBg: Theme.surfaceContainerHigh
|
readonly property color _containerBg: Theme.surfaceContainerHigh
|
||||||
|
|
||||||
color: {
|
color: _containerBg
|
||||||
const baseColor = bodyMouse.containsMouse ? Theme.widgetBaseHoverColor : _containerBg
|
|
||||||
return baseColor
|
|
||||||
}
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.10)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.10)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
|
|
||||||
readonly property color _labelPrimary: Theme.surfaceText
|
readonly property color _labelPrimary: Theme.surfaceText
|
||||||
readonly property color _labelSecondary: Theme.surfaceVariantText
|
readonly property color _labelSecondary: Theme.surfaceVariantText
|
||||||
readonly property color _tileBgActive: Theme.primary
|
readonly property color _tileBgActive: Theme.primary
|
||||||
readonly property color _tileBgInactive: {
|
readonly property color _tileBgInactive: {
|
||||||
const transparency = Theme.popupTransparency
|
const transparency = Theme.popupTransparency || 0.92
|
||||||
const surface = Theme.surfaceContainer || Qt.rgba(0.1, 0.1, 0.1, 1)
|
const surface = Theme.surfaceContainer || Qt.rgba(0.1, 0.1, 0.1, 1)
|
||||||
return Qt.rgba(surface.r, surface.g, surface.b, transparency)
|
return Qt.rgba(surface.r, surface.g, surface.b, transparency)
|
||||||
}
|
}
|
||||||
@@ -49,7 +46,7 @@ Rectangle {
|
|||||||
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
||||||
readonly property color _tileRingInactive:
|
readonly property color _tileRingInactive:
|
||||||
Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.18)
|
Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.18)
|
||||||
readonly property color _tileIconActive: Theme.primaryText
|
readonly property color _tileIconActive: Theme.primaryContainer
|
||||||
readonly property color _tileIconInactive: Theme.primary
|
readonly property color _tileIconInactive: Theme.primary
|
||||||
|
|
||||||
property int _padH: Theme.spacingS
|
property int _padH: Theme.spacingS
|
||||||
|
|||||||
@@ -20,7 +20,11 @@ Row {
|
|||||||
height: Theme.iconSize + Theme.spacingS * 2
|
height: Theme.iconSize + Theme.spacingS * 2
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
radius: (Theme.iconSize + Theme.spacingS * 2) / 2
|
||||||
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Theme.withAlpha(Theme.primary, 0)
|
color: iconArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation { duration: Theme.shortDuration }
|
||||||
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
id: iconArea
|
id: iconArea
|
||||||
@@ -30,9 +34,7 @@ Row {
|
|||||||
cursorShape: Qt.PointingHandCursor
|
cursorShape: Qt.PointingHandCursor
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (defaultSource) {
|
if (defaultSource) {
|
||||||
AudioService.suppressOSD = true
|
|
||||||
defaultSource.audio.muted = !defaultSource.audio.muted
|
defaultSource.audio.muted = !defaultSource.audio.muted
|
||||||
AudioService.suppressOSD = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -67,9 +69,6 @@ Row {
|
|||||||
valueOverride: actualVolumePercent
|
valueOverride: actualVolumePercent
|
||||||
thumbOutlineColor: Theme.surfaceContainer
|
thumbOutlineColor: Theme.surfaceContainer
|
||||||
trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.surfaceContainerHigh
|
trackColor: root.sliderTrackColor.a > 0 ? root.sliderTrackColor : Theme.surfaceContainerHigh
|
||||||
onIsDraggingChanged: {
|
|
||||||
AudioService.suppressOSD = isDragging
|
|
||||||
}
|
|
||||||
onSliderValueChanged: function(newValue) {
|
onSliderValueChanged: function(newValue) {
|
||||||
if (defaultSource) {
|
if (defaultSource) {
|
||||||
defaultSource.audio.volume = newValue / 100.0
|
defaultSource.audio.volume = newValue / 100.0
|
||||||
|
|||||||
@@ -28,14 +28,10 @@ Rectangle {
|
|||||||
readonly property color _tileBgInactive: Theme.surfaceContainerHigh
|
readonly property color _tileBgInactive: Theme.surfaceContainerHigh
|
||||||
readonly property color _tileRingActive:
|
readonly property color _tileRingActive:
|
||||||
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
||||||
readonly property color _tileIconActive: Theme.primaryText
|
readonly property color _tileIconActive: Theme.primaryContainer
|
||||||
readonly property color _tileIconInactive: Theme.primary
|
readonly property color _tileIconInactive: Theme.primary
|
||||||
|
|
||||||
color: {
|
color: isActive ? _tileBgActive : _tileBgInactive
|
||||||
if (isActive) return _tileBgActive
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : _tileBgInactive
|
|
||||||
return baseColor
|
|
||||||
}
|
|
||||||
border.color: isActive ? _tileRingActive : "transparent"
|
border.color: isActive ? _tileRingActive : "transparent"
|
||||||
border.width: isActive ? 1 : 0
|
border.width: isActive ? 1 : 0
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
@@ -91,6 +87,13 @@ Rectangle {
|
|||||||
onClicked: root.clicked()
|
onClicked: root.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on radius {
|
Behavior on radius {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ Rectangle {
|
|||||||
property real iconRotation: 0
|
property real iconRotation: 0
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
signal iconRotationCompleted()
|
|
||||||
|
|
||||||
width: parent ? ((parent.width - parent.spacing * 3) / 4) : 48
|
width: parent ? ((parent.width - parent.spacing * 3) / 4) : 48
|
||||||
height: 48
|
height: 48
|
||||||
@@ -30,14 +29,10 @@ Rectangle {
|
|||||||
readonly property color _tileBgInactive: Theme.surfaceContainerHigh
|
readonly property color _tileBgInactive: Theme.surfaceContainerHigh
|
||||||
readonly property color _tileRingActive:
|
readonly property color _tileRingActive:
|
||||||
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
||||||
readonly property color _tileIconActive: Theme.primaryText
|
readonly property color _tileIconActive: Theme.primaryContainer
|
||||||
readonly property color _tileIconInactive: Theme.primary
|
readonly property color _tileIconInactive: Theme.primary
|
||||||
|
|
||||||
color: {
|
color: isActive ? _tileBgActive : _tileBgInactive
|
||||||
if (isActive) return _tileBgActive
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : _tileBgInactive
|
|
||||||
return baseColor
|
|
||||||
}
|
|
||||||
border.color: isActive ? _tileRingActive : "transparent"
|
border.color: isActive ? _tileRingActive : "transparent"
|
||||||
border.width: isActive ? 1 : 0
|
border.width: isActive ? 1 : 0
|
||||||
antialiasing: true
|
antialiasing: true
|
||||||
@@ -59,7 +54,6 @@ Rectangle {
|
|||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: isActive ? _tileIconActive : _tileIconInactive
|
color: isActive ? _tileIconActive : _tileIconInactive
|
||||||
rotation: iconRotation
|
rotation: iconRotation
|
||||||
onRotationCompleted: root.iconRotationCompleted()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -71,6 +65,13 @@ Rectangle {
|
|||||||
onClicked: root.clicked()
|
onClicked: root.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on radius {
|
Behavior on radius {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
|
|||||||
@@ -12,9 +12,8 @@ Rectangle {
|
|||||||
property bool enabled: true
|
property bool enabled: true
|
||||||
property string secondaryText: ""
|
property string secondaryText: ""
|
||||||
property real iconRotation: 0
|
property real iconRotation: 0
|
||||||
|
|
||||||
signal clicked()
|
signal clicked()
|
||||||
signal iconRotationCompleted()
|
|
||||||
|
|
||||||
width: parent ? parent.width : 200
|
width: parent ? parent.width : 200
|
||||||
height: 60
|
height: 60
|
||||||
@@ -28,13 +27,9 @@ Rectangle {
|
|||||||
readonly property color _tileRingActive:
|
readonly property color _tileRingActive:
|
||||||
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
Qt.rgba(Theme.primaryText.r, Theme.primaryText.g, Theme.primaryText.b, 0.22)
|
||||||
|
|
||||||
color: {
|
color: isActive ? _tileBgActive : _tileBgInactive
|
||||||
if (isActive) return _tileBgActive
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : _tileBgInactive
|
|
||||||
return baseColor
|
|
||||||
}
|
|
||||||
border.color: isActive ? _tileRingActive : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: isActive ? _tileRingActive : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: isActive ? 1 : 1
|
||||||
opacity: enabled ? 1.0 : 0.6
|
opacity: enabled ? 1.0 : 0.6
|
||||||
|
|
||||||
function hoverTint(base) {
|
function hoverTint(base) {
|
||||||
@@ -47,7 +42,7 @@ Rectangle {
|
|||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: mouseArea.containsMouse ? hoverTint(_containerBg) : Theme.withAlpha(_containerBg, 0)
|
color: mouseArea.containsMouse ? hoverTint(_containerBg) : "transparent"
|
||||||
opacity: mouseArea.containsMouse ? 0.08 : 0.0
|
opacity: mouseArea.containsMouse ? 0.08 : 0.0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
@@ -64,10 +59,9 @@ Rectangle {
|
|||||||
DankIcon {
|
DankIcon {
|
||||||
name: root.iconName
|
name: root.iconName
|
||||||
size: Theme.iconSize
|
size: Theme.iconSize
|
||||||
color: isActive ? Theme.primaryText : Theme.primary
|
color: isActive ? Theme.primaryContainer : Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
rotation: root.iconRotation
|
rotation: root.iconRotation
|
||||||
onRotationCompleted: root.iconRotationCompleted()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -84,7 +78,7 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
text: root.text
|
text: root.text
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
color: isActive ? Theme.primaryText : Theme.surfaceText
|
color: isActive ? Theme.primaryContainer : Theme.surfaceText
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
@@ -94,7 +88,7 @@ Rectangle {
|
|||||||
width: parent.width
|
width: parent.width
|
||||||
text: root.secondaryText
|
text: root.secondaryText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
color: isActive ? Theme.primaryText : Theme.surfaceVariantText
|
color: isActive ? Theme.primaryContainer : Theme.surfaceVariantText
|
||||||
visible: text.length > 0
|
visible: text.length > 0
|
||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
wrapMode: Text.NoWrap
|
wrapMode: Text.NoWrap
|
||||||
@@ -112,6 +106,13 @@ Rectangle {
|
|||||||
onClicked: root.clicked()
|
onClicked: root.clicked()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on radius {
|
Behavior on radius {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
|
|||||||
@@ -1,179 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property var barWindow
|
|
||||||
required property var axis
|
|
||||||
required property var appDrawerLoader
|
|
||||||
required property var dankDashPopoutLoader
|
|
||||||
required property var processListPopoutLoader
|
|
||||||
required property var notificationCenterLoader
|
|
||||||
required property var batteryPopoutLoader
|
|
||||||
required property var vpnPopoutLoader
|
|
||||||
required property var controlCenterLoader
|
|
||||||
required property var clipboardHistoryModalPopup
|
|
||||||
required property var systemUpdateLoader
|
|
||||||
required property var notepadInstance
|
|
||||||
|
|
||||||
property alias reveal: core.reveal
|
|
||||||
property alias autoHide: core.autoHide
|
|
||||||
property alias backgroundTransparency: core.backgroundTransparency
|
|
||||||
property alias hasActivePopout: core.hasActivePopout
|
|
||||||
property alias mouseArea: topBarMouseArea
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: inputMask
|
|
||||||
|
|
||||||
readonly property int barThickness: barWindow.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing)
|
|
||||||
|
|
||||||
readonly property bool showing: SettingsData.dankBarVisible && (core.reveal
|
|
||||||
|| (CompositorService.isNiri && NiriService.inOverview && SettingsData.dankBarOpenOnOverview)
|
|
||||||
|| !core.autoHide)
|
|
||||||
|
|
||||||
readonly property int maskThickness: showing ? barThickness : 1
|
|
||||||
|
|
||||||
x: {
|
|
||||||
if (!axis.isVertical) {
|
|
||||||
return 0
|
|
||||||
} else {
|
|
||||||
switch (SettingsData.dankBarPosition) {
|
|
||||||
case SettingsData.Position.Left: return 0
|
|
||||||
case SettingsData.Position.Right: return parent.width - maskThickness
|
|
||||||
default: return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
y: {
|
|
||||||
if (axis.isVertical) {
|
|
||||||
return 0
|
|
||||||
} else {
|
|
||||||
switch (SettingsData.dankBarPosition) {
|
|
||||||
case SettingsData.Position.Top: return 0
|
|
||||||
case SettingsData.Position.Bottom: return parent.height - maskThickness
|
|
||||||
default: return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
width: axis.isVertical ? maskThickness : parent.width
|
|
||||||
height: axis.isVertical ? parent.height : maskThickness
|
|
||||||
}
|
|
||||||
|
|
||||||
Region {
|
|
||||||
id: mask
|
|
||||||
item: inputMask
|
|
||||||
}
|
|
||||||
|
|
||||||
property alias maskRegion: mask
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: core
|
|
||||||
|
|
||||||
property real backgroundTransparency: SettingsData.dankBarTransparency
|
|
||||||
property bool autoHide: SettingsData.dankBarAutoHide
|
|
||||||
property bool revealSticky: false
|
|
||||||
|
|
||||||
property bool notepadInstanceVisible: notepadInstance?.isVisible ?? false
|
|
||||||
|
|
||||||
readonly property bool hasActivePopout: {
|
|
||||||
const loaders = [{
|
|
||||||
"loader": appDrawerLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}, {
|
|
||||||
"loader": dankDashPopoutLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}, {
|
|
||||||
"loader": processListPopoutLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}, {
|
|
||||||
"loader": notificationCenterLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}, {
|
|
||||||
"loader": batteryPopoutLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}, {
|
|
||||||
"loader": vpnPopoutLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}, {
|
|
||||||
"loader": controlCenterLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}, {
|
|
||||||
"loader": clipboardHistoryModalPopup,
|
|
||||||
"prop": "visible"
|
|
||||||
}, {
|
|
||||||
"loader": systemUpdateLoader,
|
|
||||||
"prop": "shouldBeVisible"
|
|
||||||
}]
|
|
||||||
return notepadInstanceVisible || loaders.some(item => {
|
|
||||||
if (item.loader) {
|
|
||||||
return item.loader?.item?.[item.prop]
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool reveal: {
|
|
||||||
if (CompositorService.isNiri && NiriService.inOverview) {
|
|
||||||
return SettingsData.dankBarOpenOnOverview
|
|
||||||
}
|
|
||||||
return SettingsData.dankBarVisible && (!autoHide || topBarMouseArea.containsMouse || hasActivePopout || revealSticky)
|
|
||||||
}
|
|
||||||
|
|
||||||
onHasActivePopoutChanged: {
|
|
||||||
if (!hasActivePopout && autoHide && !topBarMouseArea.containsMouse) {
|
|
||||||
revealSticky = true
|
|
||||||
revealHold.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: revealHold
|
|
||||||
interval: 250
|
|
||||||
repeat: false
|
|
||||||
onTriggered: core.revealSticky = false
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onDankBarTransparencyChanged() {
|
|
||||||
core.backgroundTransparency = SettingsData.dankBarTransparency
|
|
||||||
}
|
|
||||||
|
|
||||||
target: SettingsData
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: topBarMouseArea
|
|
||||||
function onContainsMouseChanged() {
|
|
||||||
if (topBarMouseArea.containsMouse) {
|
|
||||||
core.revealSticky = true
|
|
||||||
revealHold.stop()
|
|
||||||
} else {
|
|
||||||
if (core.autoHide && !core.hasActivePopout) {
|
|
||||||
revealHold.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: topBarMouseArea
|
|
||||||
y: !barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Bottom ? parent.height - height : 0) : 0
|
|
||||||
x: barWindow.isVertical ? (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.width - width : 0) : 0
|
|
||||||
height: !barWindow.isVertical ? barWindow.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing) : undefined
|
|
||||||
width: barWindow.isVertical ? barWindow.px(barWindow.effectiveBarThickness + SettingsData.dankBarSpacing) : undefined
|
|
||||||
anchors {
|
|
||||||
left: !barWindow.isVertical ? parent.left : (SettingsData.dankBarPosition === SettingsData.Position.Left ? parent.left : undefined)
|
|
||||||
right: !barWindow.isVertical ? parent.right : (SettingsData.dankBarPosition === SettingsData.Position.Right ? parent.right : undefined)
|
|
||||||
top: barWindow.isVertical ? parent.top : undefined
|
|
||||||
bottom: barWindow.isVertical ? parent.bottom : undefined
|
|
||||||
}
|
|
||||||
hoverEnabled: SettingsData.dankBarAutoHide && !core.reveal
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
enabled: SettingsData.dankBarAutoHide && !core.reveal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
|
|
||||||
QtObject {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string edge: "top"
|
|
||||||
|
|
||||||
readonly property string orientation: isVertical ? "vertical" : "horizontal"
|
|
||||||
readonly property bool isVertical: edge === "left" || edge === "right"
|
|
||||||
readonly property bool isHorizontal: !isVertical
|
|
||||||
|
|
||||||
function primarySize(item) {
|
|
||||||
return isVertical ? item.height : item.width
|
|
||||||
}
|
|
||||||
|
|
||||||
function crossSize(item) {
|
|
||||||
return isVertical ? item.width : item.height
|
|
||||||
}
|
|
||||||
|
|
||||||
function setPrimaryPos(item, value) {
|
|
||||||
if (isVertical) {
|
|
||||||
item.y = value
|
|
||||||
} else {
|
|
||||||
item.x = value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPrimaryPos(item) {
|
|
||||||
return isVertical ? item.y : item.x
|
|
||||||
}
|
|
||||||
|
|
||||||
function primaryAnchor(anchors) {
|
|
||||||
return isVertical ? anchors.verticalCenter : anchors.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
function crossAnchor(anchors) {
|
|
||||||
return isVertical ? anchors.horizontalCenter : anchors.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
function outerVisualEdge() {
|
|
||||||
if (edge === "bottom") return "bottom"
|
|
||||||
if (edge === "left") return "right"
|
|
||||||
if (edge === "right") return "left"
|
|
||||||
if (edge === "top") return "top"
|
|
||||||
return "bottom"
|
|
||||||
}
|
|
||||||
|
|
||||||
signal axisEdgeChanged()
|
|
||||||
signal axisOrientationChanged()
|
|
||||||
signal changed() // Single coalesced signal
|
|
||||||
|
|
||||||
onEdgeChanged: {
|
|
||||||
axisEdgeChanged()
|
|
||||||
axisOrientationChanged()
|
|
||||||
changed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property var barWindow
|
|
||||||
required property var axis
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.leftMargin: -(SettingsData.dankBarGothCornersEnabled && axis.isVertical && axis.edge === "right" ? barWindow._wingR : 0)
|
|
||||||
anchors.rightMargin: -(SettingsData.dankBarGothCornersEnabled && axis.isVertical && axis.edge === "left" ? barWindow._wingR : 0)
|
|
||||||
anchors.topMargin: -(SettingsData.dankBarGothCornersEnabled && !axis.isVertical && axis.edge === "bottom" ? barWindow._wingR : 0)
|
|
||||||
anchors.bottomMargin: -(SettingsData.dankBarGothCornersEnabled && !axis.isVertical && axis.edge === "top" ? barWindow._wingR : 0)
|
|
||||||
|
|
||||||
Canvas {
|
|
||||||
id: barShape
|
|
||||||
anchors.fill: parent
|
|
||||||
antialiasing: true
|
|
||||||
renderTarget: Canvas.FramebufferObject
|
|
||||||
renderStrategy: Canvas.Cooperative
|
|
||||||
|
|
||||||
readonly property real correctWidth: root.width
|
|
||||||
readonly property real correctHeight: root.height
|
|
||||||
canvasSize: Qt.size(barWindow.px(correctWidth), barWindow.px(correctHeight))
|
|
||||||
|
|
||||||
property real wing: SettingsData.dankBarGothCornersEnabled ? barWindow._wingR : 0
|
|
||||||
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.cornerRadius
|
|
||||||
|
|
||||||
onWingChanged: requestPaint()
|
|
||||||
onRtChanged: requestPaint()
|
|
||||||
onCorrectWidthChanged: requestPaint()
|
|
||||||
onCorrectHeightChanged: requestPaint()
|
|
||||||
onVisibleChanged: if (visible) requestPaint()
|
|
||||||
Component.onCompleted: requestPaint()
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: barWindow
|
|
||||||
function on_BgColorChanged() { barShape.requestPaint() }
|
|
||||||
function on_DprChanged() { barShape.requestPaint() }
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: Theme
|
|
||||||
function onIsLightModeChanged() { barShape.requestPaint() }
|
|
||||||
}
|
|
||||||
|
|
||||||
onPaint: {
|
|
||||||
const ctx = getContext("2d")
|
|
||||||
const scale = barWindow._dpr
|
|
||||||
const W = barWindow.px(barWindow.isVertical ? correctHeight : correctWidth)
|
|
||||||
const H_raw = barWindow.px(barWindow.isVertical ? correctWidth : correctHeight)
|
|
||||||
const R = barWindow.px(wing)
|
|
||||||
const RT = barWindow.px(rt)
|
|
||||||
const H = H_raw - (R > 0 ? R : 0)
|
|
||||||
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
|
|
||||||
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
|
|
||||||
const isLeft = SettingsData.dankBarPosition === SettingsData.Position.Left
|
|
||||||
const isRight = SettingsData.dankBarPosition === SettingsData.Position.Right
|
|
||||||
|
|
||||||
ctx.scale(scale, scale)
|
|
||||||
|
|
||||||
function drawTopPath() {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.moveTo(RT, 0)
|
|
||||||
ctx.lineTo(W - RT, 0)
|
|
||||||
ctx.arcTo(W, 0, W, RT, RT)
|
|
||||||
ctx.lineTo(W, H)
|
|
||||||
|
|
||||||
if (R > 0) {
|
|
||||||
ctx.lineTo(W, H + R)
|
|
||||||
ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true)
|
|
||||||
ctx.lineTo(R, H)
|
|
||||||
ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true)
|
|
||||||
ctx.lineTo(0, H + R)
|
|
||||||
} else {
|
|
||||||
ctx.lineTo(W, H - RT)
|
|
||||||
ctx.arcTo(W, H, W - RT, H, RT)
|
|
||||||
ctx.lineTo(RT, H)
|
|
||||||
ctx.arcTo(0, H, 0, H - RT, RT)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.lineTo(0, RT)
|
|
||||||
ctx.arcTo(0, 0, RT, 0, RT)
|
|
||||||
ctx.closePath()
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.reset()
|
|
||||||
ctx.clearRect(0, 0, W, H_raw)
|
|
||||||
|
|
||||||
ctx.save()
|
|
||||||
if (isBottom) {
|
|
||||||
ctx.translate(W, H_raw)
|
|
||||||
ctx.rotate(Math.PI)
|
|
||||||
} else if (isLeft) {
|
|
||||||
ctx.translate(0, W)
|
|
||||||
ctx.rotate(-Math.PI / 2)
|
|
||||||
} else if (isRight) {
|
|
||||||
ctx.translate(H_raw, 0)
|
|
||||||
ctx.rotate(Math.PI / 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
drawTopPath()
|
|
||||||
ctx.restore()
|
|
||||||
|
|
||||||
ctx.fillStyle = barWindow._bgColor
|
|
||||||
ctx.fill()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Canvas {
|
|
||||||
id: barTint
|
|
||||||
anchors.fill: parent
|
|
||||||
antialiasing: true
|
|
||||||
renderTarget: Canvas.FramebufferObject
|
|
||||||
renderStrategy: Canvas.Cooperative
|
|
||||||
|
|
||||||
readonly property real correctWidth: root.width
|
|
||||||
readonly property real correctHeight: root.height
|
|
||||||
canvasSize: Qt.size(barWindow.px(correctWidth), barWindow.px(correctHeight))
|
|
||||||
|
|
||||||
property real wing: SettingsData.dankBarGothCornersEnabled ? barWindow._wingR : 0
|
|
||||||
property real rt: SettingsData.dankBarSquareCorners ? 0 : Theme.cornerRadius
|
|
||||||
property real alphaTint: (barWindow._bgColor?.a ?? 1) < 0.99 ? (Theme.stateLayerOpacity ?? 0) : 0
|
|
||||||
|
|
||||||
onWingChanged: requestPaint()
|
|
||||||
onRtChanged: requestPaint()
|
|
||||||
onAlphaTintChanged: requestPaint()
|
|
||||||
onCorrectWidthChanged: requestPaint()
|
|
||||||
onCorrectHeightChanged: requestPaint()
|
|
||||||
onVisibleChanged: if (visible) requestPaint()
|
|
||||||
Component.onCompleted: requestPaint()
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: barWindow
|
|
||||||
function on_BgColorChanged() { barTint.requestPaint() }
|
|
||||||
function on_DprChanged() { barTint.requestPaint() }
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: Theme
|
|
||||||
function onIsLightModeChanged() { barTint.requestPaint() }
|
|
||||||
}
|
|
||||||
|
|
||||||
onPaint: {
|
|
||||||
const ctx = getContext("2d")
|
|
||||||
const scale = barWindow._dpr
|
|
||||||
const W = barWindow.px(barWindow.isVertical ? correctHeight : correctWidth)
|
|
||||||
const H_raw = barWindow.px(barWindow.isVertical ? correctWidth : correctHeight)
|
|
||||||
const R = barWindow.px(wing)
|
|
||||||
const RT = barWindow.px(rt)
|
|
||||||
const H = H_raw - (R > 0 ? R : 0)
|
|
||||||
const isTop = SettingsData.dankBarPosition === SettingsData.Position.Top
|
|
||||||
const isBottom = SettingsData.dankBarPosition === SettingsData.Position.Bottom
|
|
||||||
const isLeft = SettingsData.dankBarPosition === SettingsData.Position.Left
|
|
||||||
const isRight = SettingsData.dankBarPosition === SettingsData.Position.Right
|
|
||||||
|
|
||||||
ctx.scale(scale, scale)
|
|
||||||
|
|
||||||
function drawTopPath() {
|
|
||||||
ctx.beginPath()
|
|
||||||
ctx.moveTo(RT, 0)
|
|
||||||
ctx.lineTo(W - RT, 0)
|
|
||||||
ctx.arcTo(W, 0, W, RT, RT)
|
|
||||||
ctx.lineTo(W, H)
|
|
||||||
|
|
||||||
if (R > 0) {
|
|
||||||
ctx.lineTo(W, H + R)
|
|
||||||
ctx.arc(W - R, H + R, R, 0, -Math.PI / 2, true)
|
|
||||||
ctx.lineTo(R, H)
|
|
||||||
ctx.arc(R, H + R, R, -Math.PI / 2, -Math.PI, true)
|
|
||||||
ctx.lineTo(0, H + R)
|
|
||||||
} else {
|
|
||||||
ctx.lineTo(W, H - RT)
|
|
||||||
ctx.arcTo(W, H, W - RT, H, RT)
|
|
||||||
ctx.lineTo(RT, H)
|
|
||||||
ctx.arcTo(0, H, 0, H - RT, RT)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.lineTo(0, RT)
|
|
||||||
ctx.arcTo(0, 0, RT, 0, RT)
|
|
||||||
ctx.closePath()
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.reset()
|
|
||||||
ctx.clearRect(0, 0, W, H_raw)
|
|
||||||
|
|
||||||
ctx.save()
|
|
||||||
if (isBottom) {
|
|
||||||
ctx.translate(W, H_raw)
|
|
||||||
ctx.rotate(Math.PI)
|
|
||||||
} else if (isLeft) {
|
|
||||||
ctx.translate(0, W)
|
|
||||||
ctx.rotate(-Math.PI / 2)
|
|
||||||
} else if (isRight) {
|
|
||||||
ctx.translate(H_raw, 0)
|
|
||||||
ctx.rotate(Math.PI / 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
drawTopPath()
|
|
||||||
ctx.restore()
|
|
||||||
|
|
||||||
ctx.fillStyle = Qt.rgba(Theme.surface.r, Theme.surface.g, Theme.surface.b, alphaTint)
|
|
||||||
ctx.fill()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,444 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var widgetsModel: null
|
|
||||||
property var components: null
|
|
||||||
property bool noBackground: false
|
|
||||||
required property var axis
|
|
||||||
property string section: "center"
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
|
|
||||||
readonly property bool isVertical: axis?.isVertical ?? false
|
|
||||||
readonly property real spacing: noBackground ? 2 : Theme.spacingXS
|
|
||||||
|
|
||||||
property var centerWidgets: []
|
|
||||||
property int totalWidgets: 0
|
|
||||||
property real totalSize: 0
|
|
||||||
|
|
||||||
function updateLayout() {
|
|
||||||
const containerSize = isVertical ? height : width
|
|
||||||
if (containerSize <= 0 || !visible) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
centerWidgets = []
|
|
||||||
totalWidgets = 0
|
|
||||||
totalSize = 0
|
|
||||||
|
|
||||||
let configuredWidgets = 0
|
|
||||||
for (var i = 0; i < centerRepeater.count; i++) {
|
|
||||||
const item = centerRepeater.itemAt(i)
|
|
||||||
if (item && getWidgetVisible(item.widgetId)) {
|
|
||||||
configuredWidgets++
|
|
||||||
if (item.active && item.item) {
|
|
||||||
centerWidgets.push(item.item)
|
|
||||||
totalWidgets++
|
|
||||||
totalSize += isVertical ? item.item.height : item.item.width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (totalWidgets > 1) {
|
|
||||||
totalSize += spacing * (totalWidgets - 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
positionWidgets(configuredWidgets)
|
|
||||||
}
|
|
||||||
|
|
||||||
function positionWidgets(configuredWidgets) {
|
|
||||||
if (totalWidgets === 0 || (isVertical ? height : width) <= 0) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const parentCenter = (isVertical ? height : width) / 2
|
|
||||||
const isOdd = configuredWidgets % 2 === 1
|
|
||||||
|
|
||||||
centerWidgets.forEach(widget => {
|
|
||||||
if (isVertical) {
|
|
||||||
widget.anchors.verticalCenter = undefined
|
|
||||||
} else {
|
|
||||||
widget.anchors.horizontalCenter = undefined
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (isOdd) {
|
|
||||||
const middleIndex = Math.floor(configuredWidgets / 2)
|
|
||||||
let currentActiveIndex = 0
|
|
||||||
let middleWidget = null
|
|
||||||
|
|
||||||
for (var i = 0; i < centerRepeater.count; i++) {
|
|
||||||
const item = centerRepeater.itemAt(i)
|
|
||||||
if (item && getWidgetVisible(item.widgetId)) {
|
|
||||||
if (currentActiveIndex === middleIndex && item.active && item.item) {
|
|
||||||
middleWidget = item.item
|
|
||||||
break
|
|
||||||
}
|
|
||||||
currentActiveIndex++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (middleWidget) {
|
|
||||||
const middleSize = isVertical ? middleWidget.height : middleWidget.width
|
|
||||||
if (isVertical) {
|
|
||||||
middleWidget.y = parentCenter - (middleSize / 2)
|
|
||||||
} else {
|
|
||||||
middleWidget.x = parentCenter - (middleSize / 2)
|
|
||||||
}
|
|
||||||
|
|
||||||
let leftWidgets = []
|
|
||||||
let rightWidgets = []
|
|
||||||
let foundMiddle = false
|
|
||||||
|
|
||||||
for (var i = 0; i < centerWidgets.length; i++) {
|
|
||||||
if (centerWidgets[i] === middleWidget) {
|
|
||||||
foundMiddle = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
if (!foundMiddle) {
|
|
||||||
leftWidgets.push(centerWidgets[i])
|
|
||||||
} else {
|
|
||||||
rightWidgets.push(centerWidgets[i])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentPos = isVertical ? middleWidget.y : middleWidget.x
|
|
||||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
|
||||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
|
||||||
currentPos -= (spacing + size)
|
|
||||||
if (isVertical) {
|
|
||||||
leftWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
leftWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPos = (isVertical ? middleWidget.y : middleWidget.x) + middleSize
|
|
||||||
for (var i = 0; i < rightWidgets.length; i++) {
|
|
||||||
currentPos += spacing
|
|
||||||
if (isVertical) {
|
|
||||||
rightWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
rightWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let configuredLeftIndex = (configuredWidgets / 2) - 1
|
|
||||||
let configuredRightIndex = configuredWidgets / 2
|
|
||||||
const halfSpacing = spacing / 2
|
|
||||||
|
|
||||||
let leftWidget = null
|
|
||||||
let rightWidget = null
|
|
||||||
let leftWidgets = []
|
|
||||||
let rightWidgets = []
|
|
||||||
|
|
||||||
let currentConfigIndex = 0
|
|
||||||
for (var i = 0; i < centerRepeater.count; i++) {
|
|
||||||
const item = centerRepeater.itemAt(i)
|
|
||||||
if (item && getWidgetVisible(item.widgetId)) {
|
|
||||||
if (item.active && item.item) {
|
|
||||||
if (currentConfigIndex < configuredLeftIndex) {
|
|
||||||
leftWidgets.push(item.item)
|
|
||||||
} else if (currentConfigIndex === configuredLeftIndex) {
|
|
||||||
leftWidget = item.item
|
|
||||||
} else if (currentConfigIndex === configuredRightIndex) {
|
|
||||||
rightWidget = item.item
|
|
||||||
} else {
|
|
||||||
rightWidgets.push(item.item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
currentConfigIndex++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leftWidget && rightWidget) {
|
|
||||||
const leftSize = isVertical ? leftWidget.height : leftWidget.width
|
|
||||||
if (isVertical) {
|
|
||||||
leftWidget.y = parentCenter - halfSpacing - leftSize
|
|
||||||
rightWidget.y = parentCenter + halfSpacing
|
|
||||||
} else {
|
|
||||||
leftWidget.x = parentCenter - halfSpacing - leftSize
|
|
||||||
rightWidget.x = parentCenter + halfSpacing
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentPos = isVertical ? leftWidget.y : leftWidget.x
|
|
||||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
|
||||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
|
||||||
currentPos -= (spacing + size)
|
|
||||||
if (isVertical) {
|
|
||||||
leftWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
leftWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width)
|
|
||||||
for (var i = 0; i < rightWidgets.length; i++) {
|
|
||||||
currentPos += spacing
|
|
||||||
if (isVertical) {
|
|
||||||
rightWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
rightWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
|
||||||
}
|
|
||||||
} else if (leftWidget && !rightWidget) {
|
|
||||||
const leftSize = isVertical ? leftWidget.height : leftWidget.width
|
|
||||||
if (isVertical) {
|
|
||||||
leftWidget.y = parentCenter - halfSpacing - leftSize
|
|
||||||
} else {
|
|
||||||
leftWidget.x = parentCenter - halfSpacing - leftSize
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentPos = isVertical ? leftWidget.y : leftWidget.x
|
|
||||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
|
||||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
|
||||||
currentPos -= (spacing + size)
|
|
||||||
if (isVertical) {
|
|
||||||
leftWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
leftWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPos = (isVertical ? leftWidget.y + leftWidget.height : leftWidget.x + leftWidget.width) + spacing
|
|
||||||
for (var i = 0; i < rightWidgets.length; i++) {
|
|
||||||
currentPos += spacing
|
|
||||||
if (isVertical) {
|
|
||||||
rightWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
rightWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
|
||||||
}
|
|
||||||
} else if (!leftWidget && rightWidget) {
|
|
||||||
if (isVertical) {
|
|
||||||
rightWidget.y = parentCenter + halfSpacing
|
|
||||||
} else {
|
|
||||||
rightWidget.x = parentCenter + halfSpacing
|
|
||||||
}
|
|
||||||
|
|
||||||
let currentPos = (isVertical ? rightWidget.y : rightWidget.x) - spacing
|
|
||||||
for (var i = leftWidgets.length - 1; i >= 0; i--) {
|
|
||||||
const size = isVertical ? leftWidgets[i].height : leftWidgets[i].width
|
|
||||||
currentPos -= size
|
|
||||||
if (isVertical) {
|
|
||||||
leftWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
leftWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
currentPos -= spacing
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPos = (isVertical ? rightWidget.y + rightWidget.height : rightWidget.x + rightWidget.width)
|
|
||||||
for (var i = 0; i < rightWidgets.length; i++) {
|
|
||||||
currentPos += spacing
|
|
||||||
if (isVertical) {
|
|
||||||
rightWidgets[i].y = currentPos
|
|
||||||
} else {
|
|
||||||
rightWidgets[i].x = currentPos
|
|
||||||
}
|
|
||||||
currentPos += isVertical ? rightWidgets[i].height : rightWidgets[i].width
|
|
||||||
}
|
|
||||||
} else if (totalWidgets === 1 && centerWidgets[0]) {
|
|
||||||
const size = isVertical ? centerWidgets[0].height : centerWidgets[0].width
|
|
||||||
if (isVertical) {
|
|
||||||
centerWidgets[0].y = parentCenter - (size / 2)
|
|
||||||
} else {
|
|
||||||
centerWidgets[0].x = parentCenter - (size / 2)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWidgetVisible(widgetId) {
|
|
||||||
const widgetVisibility = {
|
|
||||||
"cpuUsage": DgopService.dgopAvailable,
|
|
||||||
"memUsage": DgopService.dgopAvailable,
|
|
||||||
"cpuTemp": DgopService.dgopAvailable,
|
|
||||||
"gpuTemp": DgopService.dgopAvailable,
|
|
||||||
"network_speed_monitor": DgopService.dgopAvailable
|
|
||||||
}
|
|
||||||
return widgetVisibility[widgetId] ?? true
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWidgetComponent(widgetId) {
|
|
||||||
// Build dynamic component map including plugins
|
|
||||||
let baseMap = {
|
|
||||||
"launcherButton": "launcherButtonComponent",
|
|
||||||
"workspaceSwitcher": "workspaceSwitcherComponent",
|
|
||||||
"focusedWindow": "focusedWindowComponent",
|
|
||||||
"runningApps": "runningAppsComponent",
|
|
||||||
"clock": "clockComponent",
|
|
||||||
"music": "mediaComponent",
|
|
||||||
"weather": "weatherComponent",
|
|
||||||
"systemTray": "systemTrayComponent",
|
|
||||||
"privacyIndicator": "privacyIndicatorComponent",
|
|
||||||
"clipboard": "clipboardComponent",
|
|
||||||
"cpuUsage": "cpuUsageComponent",
|
|
||||||
"memUsage": "memUsageComponent",
|
|
||||||
"diskUsage": "diskUsageComponent",
|
|
||||||
"cpuTemp": "cpuTempComponent",
|
|
||||||
"gpuTemp": "gpuTempComponent",
|
|
||||||
"notificationButton": "notificationButtonComponent",
|
|
||||||
"battery": "batteryComponent",
|
|
||||||
"controlCenterButton": "controlCenterButtonComponent",
|
|
||||||
"idleInhibitor": "idleInhibitorComponent",
|
|
||||||
"spacer": "spacerComponent",
|
|
||||||
"separator": "separatorComponent",
|
|
||||||
"network_speed_monitor": "networkComponent",
|
|
||||||
"keyboard_layout_name": "keyboardLayoutNameComponent",
|
|
||||||
"vpn": "vpnComponent",
|
|
||||||
"notepadButton": "notepadButtonComponent",
|
|
||||||
"colorPicker": "colorPickerComponent",
|
|
||||||
"systemUpdate": "systemUpdateComponent"
|
|
||||||
}
|
|
||||||
|
|
||||||
// For built-in components, get from components property
|
|
||||||
const componentKey = baseMap[widgetId]
|
|
||||||
if (componentKey && root.components[componentKey]) {
|
|
||||||
return root.components[componentKey]
|
|
||||||
}
|
|
||||||
|
|
||||||
// For plugin components, get from PluginService
|
|
||||||
let pluginMap = PluginService.getWidgetComponents()
|
|
||||||
return pluginMap[widgetId] || null
|
|
||||||
}
|
|
||||||
|
|
||||||
height: parent.height
|
|
||||||
width: parent.width
|
|
||||||
anchors.centerIn: parent
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: layoutTimer
|
|
||||||
interval: 0
|
|
||||||
repeat: false
|
|
||||||
onTriggered: root.updateLayout()
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
layoutTimer.restart()
|
|
||||||
}
|
|
||||||
|
|
||||||
onWidthChanged: {
|
|
||||||
if (width > 0) {
|
|
||||||
layoutTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onHeightChanged: {
|
|
||||||
if (height > 0) {
|
|
||||||
layoutTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible && (isVertical ? height : width) > 0) {
|
|
||||||
layoutTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
id: centerRepeater
|
|
||||||
model: root.widgetsModel
|
|
||||||
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
property string widgetId: model.widgetId
|
|
||||||
property var widgetData: model
|
|
||||||
property int spacerSize: model.size || 20
|
|
||||||
|
|
||||||
anchors.verticalCenter: !root.isVertical ? parent.verticalCenter : undefined
|
|
||||||
anchors.horizontalCenter: root.isVertical ? parent.horizontalCenter : undefined
|
|
||||||
active: root.getWidgetVisible(model.widgetId) && (model.widgetId !== "music" || MprisController.activePlayer !== null)
|
|
||||||
sourceComponent: root.getWidgetComponent(model.widgetId)
|
|
||||||
opacity: (model.enabled !== false) ? 1 : 0
|
|
||||||
asynchronous: false
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
if (!item) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
item.widthChanged.connect(() => layoutTimer.restart())
|
|
||||||
item.heightChanged.connect(() => layoutTimer.restart())
|
|
||||||
if (model.widgetId === "spacer") {
|
|
||||||
item.spacerSize = Qt.binding(() => model.size || 20)
|
|
||||||
}
|
|
||||||
if (root.axis && "axis" in item) {
|
|
||||||
item.axis = Qt.binding(() => root.axis)
|
|
||||||
}
|
|
||||||
if (root.axis && "isVertical" in item) {
|
|
||||||
try {
|
|
||||||
item.isVertical = Qt.binding(() => root.axis.isVertical)
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inject properties for plugin widgets
|
|
||||||
if ("section" in item) {
|
|
||||||
item.section = root.section
|
|
||||||
}
|
|
||||||
if ("parentScreen" in item) {
|
|
||||||
item.parentScreen = Qt.binding(() => root.parentScreen)
|
|
||||||
}
|
|
||||||
if ("widgetThickness" in item) {
|
|
||||||
item.widgetThickness = Qt.binding(() => root.widgetThickness)
|
|
||||||
}
|
|
||||||
if ("barThickness" in item) {
|
|
||||||
item.barThickness = Qt.binding(() => root.barThickness)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inject PluginService for plugin widgets
|
|
||||||
if (item.pluginService !== undefined) {
|
|
||||||
if (item.pluginId !== undefined) {
|
|
||||||
item.pluginId = model.widgetId
|
|
||||||
}
|
|
||||||
item.pluginService = PluginService
|
|
||||||
}
|
|
||||||
|
|
||||||
layoutTimer.restart()
|
|
||||||
}
|
|
||||||
|
|
||||||
onActiveChanged: {
|
|
||||||
layoutTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: widgetsModel
|
|
||||||
function onCountChanged() {
|
|
||||||
layoutTimer.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Listen for plugin changes and refresh components
|
|
||||||
Connections {
|
|
||||||
target: PluginService
|
|
||||||
function onPluginLoaded(pluginId) {
|
|
||||||
// Force refresh of component lookups
|
|
||||||
for (var i = 0; i < centerRepeater.count; i++) {
|
|
||||||
var item = centerRepeater.itemAt(i)
|
|
||||||
if (item && item.widgetId === pluginId) {
|
|
||||||
item.sourceComponent = root.getWidgetComponent(pluginId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function onPluginUnloaded(pluginId) {
|
|
||||||
// Force refresh of component lookups
|
|
||||||
for (var i = 0; i < centerRepeater.count; i++) {
|
|
||||||
var item = centerRepeater.itemAt(i)
|
|
||||||
if (item && item.widgetId === pluginId) {
|
|
||||||
item.sourceComponent = root.getWidgetComponent(pluginId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,82 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var widgetsModel: null
|
|
||||||
property var components: null
|
|
||||||
property bool noBackground: false
|
|
||||||
required property var axis
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
|
|
||||||
readonly property bool isVertical: axis?.isVertical ?? false
|
|
||||||
|
|
||||||
implicitHeight: layoutLoader.item ? (layoutLoader.item.implicitHeight || layoutLoader.item.height) : 0
|
|
||||||
implicitWidth: layoutLoader.item ? (layoutLoader.item.implicitWidth || layoutLoader.item.width) : 0
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: layoutLoader
|
|
||||||
anchors.fill: parent
|
|
||||||
sourceComponent: root.isVertical ? columnComp : rowComp
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: rowComp
|
|
||||||
Row {
|
|
||||||
spacing: noBackground ? 2 : Theme.spacingXS
|
|
||||||
Repeater {
|
|
||||||
model: root.widgetsModel
|
|
||||||
Item {
|
|
||||||
width: widgetLoader.item ? widgetLoader.item.width : 0
|
|
||||||
height: widgetLoader.item ? widgetLoader.item.height : 0
|
|
||||||
WidgetHost {
|
|
||||||
id: widgetLoader
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
widgetId: model.widgetId
|
|
||||||
widgetData: model
|
|
||||||
spacerSize: model.size || 20
|
|
||||||
components: root.components
|
|
||||||
isInColumn: false
|
|
||||||
axis: root.axis
|
|
||||||
section: "left"
|
|
||||||
parentScreen: root.parentScreen
|
|
||||||
widgetThickness: root.widgetThickness
|
|
||||||
barThickness: root.barThickness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: columnComp
|
|
||||||
Column {
|
|
||||||
width: Math.max(parent.width, 200)
|
|
||||||
spacing: noBackground ? 2 : Theme.spacingXS
|
|
||||||
Repeater {
|
|
||||||
model: root.widgetsModel
|
|
||||||
Item {
|
|
||||||
width: parent.width
|
|
||||||
height: widgetLoader.item ? widgetLoader.item.height : 0
|
|
||||||
WidgetHost {
|
|
||||||
id: widgetLoader
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
widgetId: model.widgetId
|
|
||||||
widgetData: model
|
|
||||||
spacerSize: model.size || 20
|
|
||||||
components: root.components
|
|
||||||
isInColumn: true
|
|
||||||
axis: root.axis
|
|
||||||
section: "left"
|
|
||||||
parentScreen: root.parentScreen
|
|
||||||
widgetThickness: root.widgetThickness
|
|
||||||
barThickness: root.barThickness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var widgetsModel: null
|
|
||||||
property var components: null
|
|
||||||
property bool noBackground: false
|
|
||||||
required property var axis
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
|
|
||||||
readonly property bool isVertical: axis?.isVertical ?? false
|
|
||||||
|
|
||||||
implicitHeight: layoutLoader.item ? layoutLoader.item.implicitHeight : 0
|
|
||||||
implicitWidth: layoutLoader.item ? layoutLoader.item.implicitWidth : 0
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: layoutLoader
|
|
||||||
width: parent.width
|
|
||||||
height: parent.height
|
|
||||||
sourceComponent: root.isVertical ? columnComp : rowComp
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: rowComp
|
|
||||||
Row {
|
|
||||||
spacing: noBackground ? 2 : Theme.spacingXS
|
|
||||||
anchors.right: parent ? parent.right : undefined
|
|
||||||
Repeater {
|
|
||||||
model: root.widgetsModel
|
|
||||||
Item {
|
|
||||||
width: widgetLoader.item ? widgetLoader.item.width : 0
|
|
||||||
height: widgetLoader.item ? widgetLoader.item.height : 0
|
|
||||||
WidgetHost {
|
|
||||||
id: widgetLoader
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
widgetId: model.widgetId
|
|
||||||
widgetData: model
|
|
||||||
spacerSize: model.size || 20
|
|
||||||
components: root.components
|
|
||||||
isInColumn: false
|
|
||||||
axis: root.axis
|
|
||||||
section: "right"
|
|
||||||
parentScreen: root.parentScreen
|
|
||||||
widgetThickness: root.widgetThickness
|
|
||||||
barThickness: root.barThickness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: columnComp
|
|
||||||
Column {
|
|
||||||
width: parent ? parent.width : 0
|
|
||||||
spacing: noBackground ? 2 : Theme.spacingXS
|
|
||||||
Repeater {
|
|
||||||
model: root.widgetsModel
|
|
||||||
Item {
|
|
||||||
width: parent.width
|
|
||||||
height: widgetLoader.item ? widgetLoader.item.height : 0
|
|
||||||
WidgetHost {
|
|
||||||
id: widgetLoader
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
widgetId: model.widgetId
|
|
||||||
widgetData: model
|
|
||||||
spacerSize: model.size || 20
|
|
||||||
components: root.components
|
|
||||||
isInColumn: true
|
|
||||||
axis: root.axis
|
|
||||||
section: "right"
|
|
||||||
parentScreen: root.parentScreen
|
|
||||||
widgetThickness: root.widgetThickness
|
|
||||||
barThickness: root.barThickness
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,144 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell.Services.Mpris
|
|
||||||
import qs.Services
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string widgetId: ""
|
|
||||||
property var widgetData: null
|
|
||||||
property int spacerSize: 20
|
|
||||||
property var components: null
|
|
||||||
property bool isInColumn: false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "center"
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
|
|
||||||
asynchronous: false
|
|
||||||
|
|
||||||
active: getWidgetVisible(widgetId, DgopService.dgopAvailable) &&
|
|
||||||
(widgetId !== "music" || MprisController.activePlayer !== null)
|
|
||||||
sourceComponent: getWidgetComponent(widgetId, components)
|
|
||||||
opacity: getWidgetEnabled(widgetData?.enabled) ? 1 : 0
|
|
||||||
|
|
||||||
signal contentItemReady(var item)
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: root.item
|
|
||||||
when: root.item && "parentScreen" in root.item
|
|
||||||
property: "parentScreen"
|
|
||||||
value: root.parentScreen
|
|
||||||
restoreMode: Binding.RestoreNone
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: root.item
|
|
||||||
when: root.item && "section" in root.item
|
|
||||||
property: "section"
|
|
||||||
value: root.section
|
|
||||||
restoreMode: Binding.RestoreNone
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: root.item
|
|
||||||
when: root.item && "widgetThickness" in root.item
|
|
||||||
property: "widgetThickness"
|
|
||||||
value: root.widgetThickness
|
|
||||||
restoreMode: Binding.RestoreNone
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: root.item
|
|
||||||
when: root.item && "barThickness" in root.item
|
|
||||||
property: "barThickness"
|
|
||||||
value: root.barThickness
|
|
||||||
restoreMode: Binding.RestoreNone
|
|
||||||
}
|
|
||||||
|
|
||||||
Binding {
|
|
||||||
target: root.item
|
|
||||||
when: root.item && "axis" in root.item
|
|
||||||
property: "axis"
|
|
||||||
value: root.axis
|
|
||||||
restoreMode: Binding.RestoreNone
|
|
||||||
}
|
|
||||||
|
|
||||||
onLoaded: {
|
|
||||||
if (item) {
|
|
||||||
contentItemReady(item)
|
|
||||||
if (widgetId === "spacer") {
|
|
||||||
item.spacerSize = Qt.binding(() => spacerSize)
|
|
||||||
}
|
|
||||||
if (axis && "isVertical" in item) {
|
|
||||||
try {
|
|
||||||
item.isVertical = axis.isVertical
|
|
||||||
} catch (e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.pluginService !== undefined) {
|
|
||||||
if (item.pluginId !== undefined) {
|
|
||||||
item.pluginId = widgetId
|
|
||||||
}
|
|
||||||
item.pluginService = PluginService
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWidgetComponent(widgetId, components) {
|
|
||||||
const componentMap = {
|
|
||||||
"launcherButton": components.launcherButtonComponent,
|
|
||||||
"workspaceSwitcher": components.workspaceSwitcherComponent,
|
|
||||||
"focusedWindow": components.focusedWindowComponent,
|
|
||||||
"runningApps": components.runningAppsComponent,
|
|
||||||
"clock": components.clockComponent,
|
|
||||||
"music": components.mediaComponent,
|
|
||||||
"weather": components.weatherComponent,
|
|
||||||
"systemTray": components.systemTrayComponent,
|
|
||||||
"privacyIndicator": components.privacyIndicatorComponent,
|
|
||||||
"clipboard": components.clipboardComponent,
|
|
||||||
"cpuUsage": components.cpuUsageComponent,
|
|
||||||
"memUsage": components.memUsageComponent,
|
|
||||||
"diskUsage": components.diskUsageComponent,
|
|
||||||
"cpuTemp": components.cpuTempComponent,
|
|
||||||
"gpuTemp": components.gpuTempComponent,
|
|
||||||
"notificationButton": components.notificationButtonComponent,
|
|
||||||
"battery": components.batteryComponent,
|
|
||||||
"controlCenterButton": components.controlCenterButtonComponent,
|
|
||||||
"idleInhibitor": components.idleInhibitorComponent,
|
|
||||||
"spacer": components.spacerComponent,
|
|
||||||
"separator": components.separatorComponent,
|
|
||||||
"network_speed_monitor": components.networkComponent,
|
|
||||||
"keyboard_layout_name": components.keyboardLayoutNameComponent,
|
|
||||||
"vpn": components.vpnComponent,
|
|
||||||
"notepadButton": components.notepadButtonComponent,
|
|
||||||
"colorPicker": components.colorPickerComponent,
|
|
||||||
"systemUpdate": components.systemUpdateComponent
|
|
||||||
}
|
|
||||||
|
|
||||||
if (componentMap[widgetId]) {
|
|
||||||
return componentMap[widgetId]
|
|
||||||
}
|
|
||||||
|
|
||||||
let pluginMap = PluginService.getWidgetComponents()
|
|
||||||
return pluginMap[widgetId] || null
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWidgetVisible(widgetId, dgopAvailable) {
|
|
||||||
const widgetVisibility = {
|
|
||||||
"cpuUsage": dgopAvailable,
|
|
||||||
"memUsage": dgopAvailable,
|
|
||||||
"cpuTemp": dgopAvailable,
|
|
||||||
"gpuTemp": dgopAvailable,
|
|
||||||
"network_speed_monitor": dgopAvailable
|
|
||||||
}
|
|
||||||
|
|
||||||
return widgetVisibility[widgetId] ?? true
|
|
||||||
}
|
|
||||||
|
|
||||||
function getWidgetEnabled(enabled) {
|
|
||||||
return enabled !== false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell.Services.UPower
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: battery
|
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool batteryPopupVisible: false
|
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal toggleBatteryPopup()
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (batteryContent.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (batteryColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = batteryArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
visible: true
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: batteryColumn
|
|
||||||
visible: battery.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: BatteryService.getBatteryIcon()
|
|
||||||
size: Theme.iconSize - 8
|
|
||||||
color: {
|
|
||||||
if (!BatteryService.batteryAvailable) {
|
|
||||||
return Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
|
||||||
return Theme.error
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
|
||||||
return Theme.primary
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText
|
|
||||||
}
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: BatteryService.batteryLevel.toString()
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
visible: BatteryService.batteryAvailable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: batteryContent
|
|
||||||
visible: !battery.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: SettingsData.dankBarNoBackground ? 1 : 2
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: BatteryService.getBatteryIcon()
|
|
||||||
size: Theme.iconSize - 6
|
|
||||||
color: {
|
|
||||||
if (!BatteryService.batteryAvailable) {
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BatteryService.isLowBattery && !BatteryService.isCharging) {
|
|
||||||
return Theme.error;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BatteryService.isCharging || BatteryService.isPluggedIn) {
|
|
||||||
return Theme.primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.surfaceText;
|
|
||||||
}
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: `${BatteryService.batteryLevel}%`
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: BatteryService.batteryAvailable
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: batteryArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onPressed: {
|
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
|
||||||
}
|
|
||||||
toggleBatteryPopup();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool isActive: false
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "right"
|
|
||||||
property var clipboardHistoryModal: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
width: widgetThickness
|
|
||||||
height: widgetThickness
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: clipboardArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
onPressed: {
|
|
||||||
root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: clipboardContent
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = clipboardArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
name: "content_paste"
|
|
||||||
size: Theme.iconSize - 6
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,247 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import qs.Common
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool compactMode: false
|
|
||||||
property string section: "center"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real barThickness: 48
|
|
||||||
property real widgetThickness: 30
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
|
|
||||||
|
|
||||||
signal clockClicked
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (clockRow.implicitWidth + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (clockColumn.implicitHeight + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = clockMouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: clockColumn
|
|
||||||
visible: root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: -2
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (SettingsData.use24HourClock) {
|
|
||||||
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(0)
|
|
||||||
} else {
|
|
||||||
const hours = systemClock?.date?.getHours()
|
|
||||||
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours
|
|
||||||
return String(display).padStart(2, '0').charAt(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (SettingsData.use24HourClock) {
|
|
||||||
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(1)
|
|
||||||
} else {
|
|
||||||
const hours = systemClock?.date?.getHours()
|
|
||||||
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours
|
|
||||||
return String(display).padStart(2, '0').charAt(1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0)
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1)
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
font.weight: Font.Normal
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 12
|
|
||||||
height: Theme.spacingM
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 12
|
|
||||||
height: 1
|
|
||||||
color: Theme.outlineButton
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const locale = Qt.locale()
|
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
|
||||||
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
|
|
||||||
return value.charAt(0)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.primary
|
|
||||||
font.weight: Font.Light
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const locale = Qt.locale()
|
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
|
||||||
const value = dayFirst ? String(systemClock?.date?.getDate()).padStart(2, '0') : String(systemClock?.date?.getMonth() + 1).padStart(2, '0')
|
|
||||||
return value.charAt(1)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.primary
|
|
||||||
font.weight: Font.Light
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const locale = Qt.locale()
|
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
|
||||||
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
|
|
||||||
return value.charAt(0)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.primary
|
|
||||||
font.weight: Font.Light
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const locale = Qt.locale()
|
|
||||||
const dateFormatShort = locale.dateFormat(Locale.ShortFormat)
|
|
||||||
const dayFirst = dateFormatShort.indexOf('d') < dateFormatShort.indexOf('M')
|
|
||||||
const value = dayFirst ? String(systemClock?.date?.getMonth() + 1).padStart(2, '0') : String(systemClock?.date?.getDate()).padStart(2, '0')
|
|
||||||
return value.charAt(1)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.primary
|
|
||||||
font.weight: Font.Light
|
|
||||||
width: 9
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: clockRow
|
|
||||||
|
|
||||||
visible: !root.isVertical
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingS
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
const format = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP"
|
|
||||||
return systemClock?.date?.toLocaleTimeString(Qt.locale(), format)
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeMedium - 1
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "•"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.outlineButton
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !SettingsData.clockCompactMode
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (SettingsData.clockDateFormat && SettingsData.clockDateFormat.length > 0) {
|
|
||||||
return systemClock?.date?.toLocaleDateString(Qt.locale(), SettingsData.clockDateFormat)
|
|
||||||
}
|
|
||||||
|
|
||||||
return systemClock?.date?.toLocaleDateString(Qt.locale(), "ddd d")
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeMedium - 1
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: !SettingsData.clockCompactMode
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SystemClock {
|
|
||||||
id: systemClock
|
|
||||||
precision: SystemClock.Seconds
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: clockMouseArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onPressed: {
|
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
|
||||||
}
|
|
||||||
root.clockClicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell.Hyprland
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "right"
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
readonly property string focusedScreenName: (
|
|
||||||
CompositorService.isHyprland && typeof Hyprland !== "undefined" && Hyprland.focusedWorkspace && Hyprland.focusedWorkspace.monitor ? (Hyprland.focusedWorkspace.monitor.name || "") :
|
|
||||||
CompositorService.isNiri && typeof NiriService !== "undefined" && NiriService.currentOutput ? NiriService.currentOutput : ""
|
|
||||||
)
|
|
||||||
|
|
||||||
function resolveNotepadInstance() {
|
|
||||||
if (typeof notepadSlideoutVariants === "undefined" || !notepadSlideoutVariants || !notepadSlideoutVariants.instances) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
const targetScreen = focusedScreenName
|
|
||||||
if (targetScreen) {
|
|
||||||
for (var i = 0; i < notepadSlideoutVariants.instances.length; i++) {
|
|
||||||
var slideout = notepadSlideoutVariants.instances[i]
|
|
||||||
if (slideout.modelData && slideout.modelData.name === targetScreen) {
|
|
||||||
return slideout
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return notepadSlideoutVariants.instances.length > 0 ? notepadSlideoutVariants.instances[0] : null
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property var notepadInstance: resolveNotepadInstance()
|
|
||||||
readonly property bool isActive: notepadInstance?.isVisible ?? false
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (notepadIcon.width + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (notepadIcon.height + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = notepadArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: notepadIcon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "assignment"
|
|
||||||
size: Theme.iconSize - 6
|
|
||||||
color: notepadArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 6
|
|
||||||
height: 6
|
|
||||||
radius: 3
|
|
||||||
color: Theme.primary
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 4
|
|
||||||
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 4
|
|
||||||
visible: NotepadStorageService.tabs && NotepadStorageService.tabs.length > 0
|
|
||||||
opacity: 0.8
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: notepadArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onPressed: {
|
|
||||||
const inst = root.notepadInstance
|
|
||||||
if (inst) {
|
|
||||||
inst.toggle()
|
|
||||||
}
|
|
||||||
root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,76 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Item {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool hasUnread: false
|
|
||||||
property bool isActive: false
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
width: widgetThickness
|
|
||||||
height: widgetThickness
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: notificationArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
acceptedButtons: Qt.LeftButton
|
|
||||||
onPressed: {
|
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
|
||||||
}
|
|
||||||
root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: notificationContent
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = notificationArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
name: SessionData.doNotDisturb ? "notifications_off" : "notifications"
|
|
||||||
size: Theme.iconSize - 6
|
|
||||||
color: SessionData.doNotDisturb ? Theme.error : (notificationArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText)
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 8
|
|
||||||
height: 8
|
|
||||||
radius: 4
|
|
||||||
color: Theme.error
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
|
||||||
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
|
||||||
visible: root.hasUnread
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,630 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import QtQuick.Controls
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Services.SystemTray
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import Quickshell.Widgets
|
|
||||||
import qs.Common
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property var parentWindow: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property bool isAtBottom: false
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 2 : Theme.spacingS
|
|
||||||
readonly property int calculatedSize: SystemTray.items.values.length > 0 ? SystemTray.items.values.length * 24 + horizontalPadding * 2 : 0
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : calculatedSize
|
|
||||||
height: isVertical ? calculatedSize : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SystemTray.items.values.length === 0) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
visible: SystemTray.items.values.length > 0
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: layoutLoader
|
|
||||||
anchors.centerIn: parent
|
|
||||||
sourceComponent: root.isVertical ? columnComp : rowComp
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: rowComp
|
|
||||||
Row {
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: SystemTray.items.values
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
property var trayItem: modelData
|
|
||||||
property string iconSource: {
|
|
||||||
let icon = trayItem && trayItem.icon;
|
|
||||||
if (typeof icon === 'string' || icon instanceof String) {
|
|
||||||
if (icon === "") {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (icon.includes("?path=")) {
|
|
||||||
const split = icon.split("?path=");
|
|
||||||
if (split.length !== 2) {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = split[0];
|
|
||||||
const path = split[1];
|
|
||||||
const fileName = name.substring(name.lastIndexOf("/") + 1);
|
|
||||||
return `file://${path}/${fileName}`;
|
|
||||||
}
|
|
||||||
if (icon.startsWith("/") && !icon.startsWith("file://")) {
|
|
||||||
return `file://${icon}`;
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 24
|
|
||||||
height: 24
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: trayItemArea.containsMouse ? Theme.primaryHover : "transparent"
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
IconImage {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
source: parent.iconSource
|
|
||||||
asynchronous: true
|
|
||||||
smooth: true
|
|
||||||
mipmap: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: trayItemArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: (mouse) => {
|
|
||||||
if (!trayItem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
|
|
||||||
trayItem.activate();
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (trayItem.hasMenu) {
|
|
||||||
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: columnComp
|
|
||||||
Column {
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: SystemTray.items.values
|
|
||||||
|
|
||||||
delegate: Item {
|
|
||||||
property var trayItem: modelData
|
|
||||||
property string iconSource: {
|
|
||||||
let icon = trayItem && trayItem.icon;
|
|
||||||
if (typeof icon === 'string' || icon instanceof String) {
|
|
||||||
if (icon === "") {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
if (icon.includes("?path=")) {
|
|
||||||
const split = icon.split("?path=");
|
|
||||||
if (split.length !== 2) {
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
const name = split[0];
|
|
||||||
const path = split[1];
|
|
||||||
const fileName = name.substring(name.lastIndexOf("/") + 1);
|
|
||||||
return `file://${path}/${fileName}`;
|
|
||||||
}
|
|
||||||
if (icon.startsWith("/") && !icon.startsWith("file://")) {
|
|
||||||
return `file://${icon}`;
|
|
||||||
}
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 24
|
|
||||||
height: 24
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: trayItemArea.containsMouse ? Theme.primaryHover : "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
IconImage {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
source: parent.iconSource
|
|
||||||
asynchronous: true
|
|
||||||
smooth: true
|
|
||||||
mipmap: true
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: trayItemArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: (mouse) => {
|
|
||||||
if (!trayItem) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
|
|
||||||
trayItem.activate();
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
if (trayItem.hasMenu) {
|
|
||||||
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: trayMenuComponent
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: menuRoot
|
|
||||||
|
|
||||||
property var trayItem: null
|
|
||||||
property var anchorItem: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property bool isAtBottom: false
|
|
||||||
property bool isVertical: false
|
|
||||||
property var axis: null
|
|
||||||
property bool showMenu: false
|
|
||||||
property var menuHandle: null
|
|
||||||
|
|
||||||
ListModel { id: entryStack }
|
|
||||||
function topEntry() {
|
|
||||||
return entryStack.count ? entryStack.get(entryStack.count - 1).handle : null
|
|
||||||
}
|
|
||||||
|
|
||||||
function showForTrayItem(item, anchor, screen, atBottom, vertical, axisObj) {
|
|
||||||
trayItem = item
|
|
||||||
anchorItem = anchor
|
|
||||||
parentScreen = screen
|
|
||||||
isAtBottom = atBottom
|
|
||||||
isVertical = vertical
|
|
||||||
axis = axisObj
|
|
||||||
menuHandle = item?.menu
|
|
||||||
|
|
||||||
if (parentScreen) {
|
|
||||||
for (var i = 0; i < Quickshell.screens.length; i++) {
|
|
||||||
const s = Quickshell.screens[i]
|
|
||||||
if (s === parentScreen) {
|
|
||||||
menuWindow.screen = s
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
showMenu = true
|
|
||||||
}
|
|
||||||
|
|
||||||
function close() {
|
|
||||||
showMenu = false
|
|
||||||
}
|
|
||||||
|
|
||||||
function showSubMenu(entry) {
|
|
||||||
if (!entry || !entry.hasChildren) return;
|
|
||||||
|
|
||||||
entryStack.append({ handle: entry });
|
|
||||||
|
|
||||||
const h = entry.menu || entry;
|
|
||||||
if (h && typeof h.updateLayout === "function") h.updateLayout();
|
|
||||||
|
|
||||||
submenuHydrator.menu = h;
|
|
||||||
submenuHydrator.open();
|
|
||||||
Qt.callLater(() => submenuHydrator.close());
|
|
||||||
}
|
|
||||||
|
|
||||||
function goBack() {
|
|
||||||
if (!entryStack.count) return;
|
|
||||||
entryStack.remove(entryStack.count - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
width: 0
|
|
||||||
height: 0
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
PanelWindow {
|
|
||||||
id: menuWindow
|
|
||||||
visible: menuRoot.showMenu && (menuRoot.trayItem?.hasMenu ?? false)
|
|
||||||
WlrLayershell.layer: WlrLayershell.Overlay
|
|
||||||
WlrLayershell.exclusiveZone: -1
|
|
||||||
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: true
|
|
||||||
left: true
|
|
||||||
right: true
|
|
||||||
bottom: true
|
|
||||||
}
|
|
||||||
|
|
||||||
property point anchorPos: Qt.point(screen.width / 2, screen.height / 2)
|
|
||||||
|
|
||||||
onVisibleChanged: {
|
|
||||||
if (visible) {
|
|
||||||
updatePosition()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updatePosition() {
|
|
||||||
if (!menuRoot.anchorItem || !menuRoot.trayItem) {
|
|
||||||
anchorPos = Qt.point(screen.width / 2, screen.height / 2)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const globalPos = menuRoot.anchorItem.mapToGlobal(0, 0)
|
|
||||||
const screenX = screen.x || 0
|
|
||||||
const screenY = screen.y || 0
|
|
||||||
const relativeX = globalPos.x - screenX
|
|
||||||
const relativeY = globalPos.y - screenY
|
|
||||||
|
|
||||||
const widgetThickness = Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
|
|
||||||
const effectiveBarThickness = Math.max(widgetThickness + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
|
|
||||||
|
|
||||||
if (menuRoot.isVertical) {
|
|
||||||
const edge = menuRoot.axis?.edge
|
|
||||||
let targetX
|
|
||||||
if (edge === "left") {
|
|
||||||
targetX = effectiveBarThickness + SettingsData.dankBarSpacing + Theme.popupDistance
|
|
||||||
} else {
|
|
||||||
const popupX = effectiveBarThickness + SettingsData.dankBarSpacing + Theme.popupDistance
|
|
||||||
targetX = screen.width - popupX
|
|
||||||
}
|
|
||||||
anchorPos = Qt.point(targetX, relativeY + menuRoot.anchorItem.height / 2)
|
|
||||||
} else {
|
|
||||||
let targetY
|
|
||||||
if (menuRoot.isAtBottom) {
|
|
||||||
const popupY = effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap + Theme.popupDistance
|
|
||||||
targetY = screen.height - popupY
|
|
||||||
} else {
|
|
||||||
targetY = effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap + Theme.popupDistance
|
|
||||||
}
|
|
||||||
anchorPos = Qt.point(relativeX + menuRoot.anchorItem.width / 2, targetY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: menuContainer
|
|
||||||
|
|
||||||
width: Math.min(500, Math.max(250, menuColumn.implicitWidth + Theme.spacingS * 2))
|
|
||||||
height: Math.max(40, menuColumn.implicitHeight + Theme.spacingS * 2)
|
|
||||||
|
|
||||||
x: {
|
|
||||||
if (menuRoot.isVertical) {
|
|
||||||
const edge = menuRoot.axis?.edge
|
|
||||||
if (edge === "left") {
|
|
||||||
const targetX = menuWindow.anchorPos.x
|
|
||||||
return Math.min(menuWindow.screen.width - width - 10, targetX)
|
|
||||||
} else {
|
|
||||||
const targetX = menuWindow.anchorPos.x - width
|
|
||||||
return Math.max(10, targetX)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const left = 10
|
|
||||||
const right = menuWindow.width - width - 10
|
|
||||||
const want = menuWindow.anchorPos.x - width / 2
|
|
||||||
return Math.max(left, Math.min(right, want))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
y: {
|
|
||||||
if (menuRoot.isVertical) {
|
|
||||||
const top = 10
|
|
||||||
const bottom = menuWindow.height - height - 10
|
|
||||||
const want = menuWindow.anchorPos.y - height / 2
|
|
||||||
return Math.max(top, Math.min(bottom, want))
|
|
||||||
} else {
|
|
||||||
if (menuRoot.isAtBottom) {
|
|
||||||
const targetY = menuWindow.anchorPos.y - height
|
|
||||||
return Math.max(10, targetY)
|
|
||||||
} else {
|
|
||||||
const targetY = menuWindow.anchorPos.y
|
|
||||||
return Math.min(menuWindow.screen.height - height - 10, targetY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
color: Theme.popupBackground()
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
|
||||||
border.width: 1
|
|
||||||
|
|
||||||
opacity: menuRoot.showMenu ? 1 : 0
|
|
||||||
scale: menuRoot.showMenu ? 1 : 0.85
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.topMargin: 4
|
|
||||||
anchors.leftMargin: 2
|
|
||||||
anchors.rightMargin: -2
|
|
||||||
anchors.bottomMargin: -4
|
|
||||||
radius: parent.radius
|
|
||||||
color: Qt.rgba(0, 0, 0, 0.15)
|
|
||||||
z: parent.z - 1
|
|
||||||
}
|
|
||||||
|
|
||||||
QsMenuAnchor {
|
|
||||||
id: submenuHydrator
|
|
||||||
anchor.window: menuWindow
|
|
||||||
}
|
|
||||||
|
|
||||||
QsMenuOpener {
|
|
||||||
id: rootOpener
|
|
||||||
menu: menuRoot.menuHandle
|
|
||||||
}
|
|
||||||
|
|
||||||
QsMenuOpener {
|
|
||||||
id: subOpener
|
|
||||||
menu: {
|
|
||||||
const e = menuRoot.topEntry();
|
|
||||||
return e ? (e.menu || e) : null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Column {
|
|
||||||
id: menuColumn
|
|
||||||
|
|
||||||
width: parent.width - Theme.spacingS * 2
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.topMargin: Theme.spacingS
|
|
||||||
spacing: 1
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
visible: entryStack.count > 0
|
|
||||||
width: parent.width
|
|
||||||
height: 28
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
color: backArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "arrow_back"
|
|
||||||
size: 16
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: "Back"
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: backArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onClicked: menuRoot.goBack()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
visible: entryStack.count > 0
|
|
||||||
width: parent.width
|
|
||||||
height: 1
|
|
||||||
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
|
||||||
}
|
|
||||||
|
|
||||||
Repeater {
|
|
||||||
model: entryStack.count
|
|
||||||
? (subOpener.children ? subOpener.children
|
|
||||||
: (menuRoot.topEntry()?.children || []))
|
|
||||||
: rootOpener.children
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
property var menuEntry: modelData
|
|
||||||
|
|
||||||
width: menuColumn.width
|
|
||||||
height: menuEntry?.isSeparator ? 1 : 28
|
|
||||||
radius: menuEntry?.isSeparator ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (menuEntry?.isSeparator) {
|
|
||||||
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
|
|
||||||
}
|
|
||||||
return itemArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: itemArea
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: !menuEntry?.isSeparator && (menuEntry?.enabled !== false)
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
if (!menuEntry || menuEntry.isSeparator) return;
|
|
||||||
|
|
||||||
if (menuEntry.hasChildren) {
|
|
||||||
menuRoot.showSubMenu(menuEntry);
|
|
||||||
} else {
|
|
||||||
if (typeof menuEntry.activate === "function") {
|
|
||||||
menuEntry.activate();
|
|
||||||
} else if (typeof menuEntry.triggered === "function") {
|
|
||||||
menuEntry.triggered();
|
|
||||||
}
|
|
||||||
Qt.createQmlObject('import QtQuick; Timer { interval: 80; running: true; repeat: false; onTriggered: menuRoot.close() }', menuRoot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: Theme.spacingS
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.rightMargin: Theme.spacingS
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: !menuEntry?.isSeparator
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: menuEntry?.buttonType !== undefined && menuEntry.buttonType !== 0
|
|
||||||
radius: menuEntry?.buttonType === 2 ? 8 : 2
|
|
||||||
border.width: 1
|
|
||||||
border.color: Theme.outline
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
width: parent.width - 6
|
|
||||||
height: parent.height - 6
|
|
||||||
radius: parent.radius - 3
|
|
||||||
color: Theme.primary
|
|
||||||
visible: menuEntry?.checkState === 2
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "check"
|
|
||||||
size: 10
|
|
||||||
color: Theme.primaryText
|
|
||||||
visible: menuEntry?.buttonType === 1 && menuEntry?.checkState === 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: menuEntry?.icon && menuEntry.icon !== ""
|
|
||||||
|
|
||||||
Image {
|
|
||||||
anchors.fill: parent
|
|
||||||
source: menuEntry?.icon || ""
|
|
||||||
sourceSize.width: 16
|
|
||||||
sourceSize.height: 16
|
|
||||||
fillMode: Image.PreserveAspectFit
|
|
||||||
smooth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: menuEntry?.text || ""
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: (menuEntry?.enabled !== false) ? Theme.surfaceText : Theme.surfaceTextMedium
|
|
||||||
elide: Text.ElideRight
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
width: Math.max(150, parent.width - 64)
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: 16
|
|
||||||
height: 16
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
anchors.centerIn: parent
|
|
||||||
name: "chevron_right"
|
|
||||||
size: 14
|
|
||||||
color: Theme.surfaceText
|
|
||||||
visible: menuEntry?.hasChildren ?? false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on opacity {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on scale {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: Theme.mediumDuration
|
|
||||||
easing.type: Theme.emphasizedEasing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: parent
|
|
||||||
z: -1
|
|
||||||
onClicked: menuRoot.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
property var currentTrayMenu: null
|
|
||||||
|
|
||||||
function showForTrayItem(item, anchor, screen, atBottom, vertical, axisObj) {
|
|
||||||
if (currentTrayMenu) {
|
|
||||||
currentTrayMenu.destroy()
|
|
||||||
}
|
|
||||||
currentTrayMenu = trayMenuComponent.createObject(null)
|
|
||||||
if (currentTrayMenu) {
|
|
||||||
currentTrayMenu.showForTrayItem(item, anchor, screen, atBottom, vertical ?? false, axisObj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property bool isActive: false
|
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
readonly property bool hasUpdates: SystemUpdateService.updateCount > 0
|
|
||||||
readonly property bool isChecking: SystemUpdateService.isChecking
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (updaterIcon.width + horizontalPadding * 2)
|
|
||||||
height: isVertical ? widgetThickness : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = updaterArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: statusIcon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: root.isVertical
|
|
||||||
name: {
|
|
||||||
if (isChecking) return "refresh";
|
|
||||||
if (SystemUpdateService.hasError) return "error";
|
|
||||||
if (hasUpdates) return "system_update_alt";
|
|
||||||
return "check_circle";
|
|
||||||
}
|
|
||||||
size: Theme.iconSize - 6
|
|
||||||
color: {
|
|
||||||
if (SystemUpdateService.hasError) return Theme.error;
|
|
||||||
if (hasUpdates) return Theme.primary;
|
|
||||||
return (updaterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText);
|
|
||||||
}
|
|
||||||
|
|
||||||
RotationAnimation {
|
|
||||||
id: rotationAnimation
|
|
||||||
target: statusIcon
|
|
||||||
property: "rotation"
|
|
||||||
from: 0
|
|
||||||
to: 360
|
|
||||||
duration: 1000
|
|
||||||
running: isChecking
|
|
||||||
loops: Animation.Infinite
|
|
||||||
|
|
||||||
onRunningChanged: {
|
|
||||||
if (!running) {
|
|
||||||
statusIcon.rotation = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 8
|
|
||||||
height: 8
|
|
||||||
radius: 4
|
|
||||||
color: Theme.error
|
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.top: parent.top
|
|
||||||
anchors.rightMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
|
||||||
anchors.topMargin: SettingsData.dankBarNoBackground ? 0 : 6
|
|
||||||
visible: root.isVertical && root.hasUpdates && !root.isChecking
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: updaterIcon
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
spacing: Theme.spacingXS
|
|
||||||
visible: !root.isVertical
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: statusIconHorizontal
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
name: {
|
|
||||||
if (isChecking) return "refresh";
|
|
||||||
if (SystemUpdateService.hasError) return "error";
|
|
||||||
if (hasUpdates) return "system_update_alt";
|
|
||||||
return "check_circle";
|
|
||||||
}
|
|
||||||
size: Theme.iconSize - 6
|
|
||||||
color: {
|
|
||||||
if (SystemUpdateService.hasError) return Theme.error;
|
|
||||||
if (hasUpdates) return Theme.primary;
|
|
||||||
return (updaterArea.containsMouse || root.isActive ? Theme.primary : Theme.surfaceText);
|
|
||||||
}
|
|
||||||
|
|
||||||
RotationAnimation {
|
|
||||||
id: rotationAnimationHorizontal
|
|
||||||
target: statusIconHorizontal
|
|
||||||
property: "rotation"
|
|
||||||
from: 0
|
|
||||||
to: 360
|
|
||||||
duration: 1000
|
|
||||||
running: isChecking
|
|
||||||
loops: Animation.Infinite
|
|
||||||
|
|
||||||
onRunningChanged: {
|
|
||||||
if (!running) {
|
|
||||||
statusIconHorizontal.rotation = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
id: countText
|
|
||||||
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
text: SystemUpdateService.updateCount.toString()
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
font.weight: Font.Medium
|
|
||||||
color: Theme.surfaceText
|
|
||||||
visible: hasUpdates && !isChecking
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: updaterArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onPressed: {
|
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
|
||||||
}
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,103 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property bool isVertical: axis?.isVertical ?? false
|
|
||||||
property var axis: null
|
|
||||||
property int widgetThickness: 28
|
|
||||||
property int barThickness: 32
|
|
||||||
property string section: "right"
|
|
||||||
property var popupTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal toggleVpnPopup()
|
|
||||||
|
|
||||||
width: isVertical ? widgetThickness : (Theme.iconSize + horizontalPadding * 2)
|
|
||||||
height: isVertical ? (Theme.iconSize + horizontalPadding * 2) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent";
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = clickArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor;
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency);
|
|
||||||
}
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
id: icon
|
|
||||||
|
|
||||||
name: VpnService.isBusy ? "sync" : (VpnService.connected ? "vpn_lock" : "vpn_key_off")
|
|
||||||
size: Theme.iconSize - 6
|
|
||||||
color: VpnService.connected ? Theme.primary : Theme.surfaceText
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: tooltipLoader
|
|
||||||
active: false
|
|
||||||
sourceComponent: DankTooltip {}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: clickArea
|
|
||||||
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onPressed: {
|
|
||||||
if (popupTarget && popupTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
|
||||||
popupTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
|
||||||
}
|
|
||||||
root.toggleVpnPopup();
|
|
||||||
}
|
|
||||||
onEntered: {
|
|
||||||
if (root.parentScreen && !(popupTarget && popupTarget.shouldBeVisible)) {
|
|
||||||
tooltipLoader.active = true
|
|
||||||
if (tooltipLoader.item) {
|
|
||||||
let tooltipText = ""
|
|
||||||
if (!VpnService.connected) {
|
|
||||||
tooltipText = "VPN Disconnected"
|
|
||||||
} else {
|
|
||||||
const names = VpnService.activeNames || []
|
|
||||||
if (names.length <= 1) {
|
|
||||||
tooltipText = "VPN Connected • " + (names[0] || "")
|
|
||||||
} else {
|
|
||||||
tooltipText = "VPN Connected • " + names[0] + " +" + (names.length - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (root.isVertical) {
|
|
||||||
const globalPos = mapToGlobal(width / 2, height / 2)
|
|
||||||
const screenX = root.parentScreen ? root.parentScreen.x : 0
|
|
||||||
const screenY = root.parentScreen ? root.parentScreen.y : 0
|
|
||||||
const relativeY = globalPos.y - screenY
|
|
||||||
const tooltipX = root.axis?.edge === "left" ? (Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS) : (root.parentScreen.width - Theme.barHeight - SettingsData.dankBarSpacing - Theme.spacingXS)
|
|
||||||
const isLeft = root.axis?.edge === "left"
|
|
||||||
tooltipLoader.item.show(tooltipText, screenX + tooltipX, relativeY, root.parentScreen, isLeft, !isLeft)
|
|
||||||
} else {
|
|
||||||
const globalPos = mapToGlobal(width / 2, height)
|
|
||||||
const tooltipY = Theme.barHeight + SettingsData.dankBarSpacing + Theme.spacingXS
|
|
||||||
tooltipLoader.item.show(tooltipText, globalPos.x, tooltipY, root.parentScreen, false, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onExited: {
|
|
||||||
if (tooltipLoader.item) {
|
|
||||||
tooltipLoader.item.hide()
|
|
||||||
}
|
|
||||||
tooltipLoader.active = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -13,33 +13,30 @@ DankPopout {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool dashVisible: false
|
property bool dashVisible: false
|
||||||
|
property string triggerSection: "center"
|
||||||
property var triggerScreen: null
|
property var triggerScreen: null
|
||||||
property int currentTabIndex: 0
|
property int currentTabIndex: 0
|
||||||
|
|
||||||
function setTriggerPosition(x, y, width, section, screen) {
|
function setTriggerPosition(x, y, width, section, screen) {
|
||||||
triggerSection = section
|
if (section === "center") {
|
||||||
triggerScreen = screen
|
|
||||||
triggerY = y
|
|
||||||
|
|
||||||
if (section === "center" && (SettingsData.dankBarPosition === SettingsData.Position.Top || SettingsData.dankBarPosition === SettingsData.Position.Bottom)) {
|
|
||||||
const screenWidth = screen ? screen.width : Screen.width
|
const screenWidth = screen ? screen.width : Screen.width
|
||||||
triggerX = (screenWidth - popupWidth) / 2
|
triggerX = (screenWidth - popupWidth) / 2
|
||||||
triggerWidth = popupWidth
|
triggerWidth = popupWidth
|
||||||
} else if (section === "center" && (SettingsData.dankBarPosition === SettingsData.Position.Left || SettingsData.dankBarPosition === SettingsData.Position.Right)) {
|
|
||||||
const screenHeight = screen ? screen.height : Screen.height
|
|
||||||
triggerX = (screenHeight - popupHeight) / 2
|
|
||||||
triggerWidth = popupHeight
|
|
||||||
} else {
|
} else {
|
||||||
triggerX = x
|
triggerX = x
|
||||||
triggerWidth = width
|
triggerWidth = width
|
||||||
}
|
}
|
||||||
|
triggerY = y
|
||||||
|
triggerSection = section
|
||||||
|
triggerScreen = screen
|
||||||
}
|
}
|
||||||
|
|
||||||
popupWidth: 700
|
popupWidth: 700
|
||||||
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 500
|
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 500
|
||||||
triggerX: Screen.width - 620 - Theme.spacingL
|
triggerX: Screen.width - 620 - Theme.spacingL
|
||||||
triggerY: Math.max(26 + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding)) + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap - 2
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingS
|
||||||
triggerWidth: 80
|
triggerWidth: 80
|
||||||
|
positioning: "center"
|
||||||
shouldBeVisible: dashVisible
|
shouldBeVisible: dashVisible
|
||||||
visible: shouldBeVisible
|
visible: shouldBeVisible
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -13,22 +13,83 @@ Card {
|
|||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
spacing: Theme.spacingM
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
DankCircularImage {
|
Item {
|
||||||
id: avatarContainer
|
id: avatarContainer
|
||||||
|
|
||||||
|
property bool hasImage: profileImageLoader.status === Image.Ready
|
||||||
|
|
||||||
width: 77
|
width: 77
|
||||||
height: 77
|
height: 77
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
imageSource: {
|
|
||||||
if (PortalService.profileImage === "")
|
Rectangle {
|
||||||
return ""
|
anchors.fill: parent
|
||||||
|
radius: 36
|
||||||
if (PortalService.profileImage.startsWith("/"))
|
color: Theme.primary
|
||||||
return "file://" + PortalService.profileImage
|
visible: !avatarContainer.hasImage
|
||||||
|
|
||||||
return PortalService.profileImage
|
StyledText {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: UserInfoService.username.length > 0 ? UserInfoService.username.charAt(0).toUpperCase() : "b"
|
||||||
|
font.pixelSize: Theme.fontSizeXLarge + 4
|
||||||
|
font.weight: Font.Bold
|
||||||
|
color: Theme.background
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: profileImageLoader
|
||||||
|
|
||||||
|
source: {
|
||||||
|
if (PortalService.profileImage === "")
|
||||||
|
return ""
|
||||||
|
|
||||||
|
if (PortalService.profileImage.startsWith("/"))
|
||||||
|
return "file://" + PortalService.profileImage
|
||||||
|
|
||||||
|
return PortalService.profileImage
|
||||||
|
}
|
||||||
|
smooth: true
|
||||||
|
asynchronous: true
|
||||||
|
mipmap: true
|
||||||
|
cache: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 2
|
||||||
|
source: profileImageLoader
|
||||||
|
maskEnabled: true
|
||||||
|
maskSource: circularMask
|
||||||
|
visible: avatarContainer.hasImage
|
||||||
|
maskThresholdMin: 0.5
|
||||||
|
maskSpreadAtMin: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: circularMask
|
||||||
|
width: 77 - 4
|
||||||
|
height: 77 - 4
|
||||||
|
layer.enabled: true
|
||||||
|
layer.smooth: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: width / 2
|
||||||
|
color: "black"
|
||||||
|
antialiasing: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "person"
|
||||||
|
size: Theme.iconSize + 8
|
||||||
|
color: Theme.error
|
||||||
|
visible: PortalService.profileImage !== "" && profileImageLoader.status === Image.Error
|
||||||
}
|
}
|
||||||
fallbackIcon: "person"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -43,7 +104,7 @@ Card {
|
|||||||
elide: Text.ElideRight
|
elide: Text.ElideRight
|
||||||
width: parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3
|
width: parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
@@ -67,7 +128,7 @@ Card {
|
|||||||
width: parent.parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3 - 16 - Theme.spacingS
|
width: parent.parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3 - 16 - Theme.spacingS
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
@@ -80,7 +141,7 @@ Card {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
id: uptimeText
|
id: uptimeText
|
||||||
|
|
||||||
property real availableWidth: parent.parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3 - 16 - Theme.spacingS
|
property real availableWidth: parent.parent.parent.parent.width - avatarContainer.width - Theme.spacingM * 3 - 16 - Theme.spacingS
|
||||||
property real longTextWidth: {
|
property real longTextWidth: {
|
||||||
const fontSize = Math.round(Theme.fontSizeSmall || 12)
|
const fontSize = Math.round(Theme.fontSizeSmall || 12)
|
||||||
|
|||||||
@@ -7,59 +7,22 @@ import qs.Common
|
|||||||
import qs.Services
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
pragma ComponentBehavior: Bound
|
PanelWindow {
|
||||||
|
id: dock
|
||||||
|
|
||||||
Variants {
|
WlrLayershell.namespace: "quickshell:dock"
|
||||||
id: dockVariants
|
|
||||||
model: SettingsData.getFilteredScreens("dock")
|
|
||||||
|
|
||||||
|
WlrLayershell.layer: WlrLayershell.Top
|
||||||
|
WlrLayershell.exclusiveZone: -1
|
||||||
|
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
|
||||||
|
|
||||||
|
property var modelData
|
||||||
property var contextMenu
|
property var contextMenu
|
||||||
|
|
||||||
delegate: PanelWindow {
|
|
||||||
id: dock
|
|
||||||
|
|
||||||
WlrLayershell.namespace: "quickshell:dock"
|
|
||||||
|
|
||||||
readonly property bool isVertical: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
|
||||||
|
|
||||||
anchors {
|
|
||||||
top: !isVertical ? (SettingsData.dockPosition === SettingsData.Position.Top) : true
|
|
||||||
bottom: !isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom) : true
|
|
||||||
left: !isVertical ? true : (SettingsData.dockPosition === SettingsData.Position.Left)
|
|
||||||
right: !isVertical ? true : (SettingsData.dockPosition === SettingsData.Position.Right)
|
|
||||||
}
|
|
||||||
|
|
||||||
property var modelData: item
|
|
||||||
property bool autoHide: SettingsData.dockAutoHide
|
property bool autoHide: SettingsData.dockAutoHide
|
||||||
property real backgroundTransparency: SettingsData.dockTransparency
|
property real backgroundTransparency: SettingsData.dockTransparency
|
||||||
property bool groupByApp: SettingsData.dockGroupByApp
|
property bool groupByApp: SettingsData.dockGroupByApp
|
||||||
|
|
||||||
readonly property real widgetHeight: Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
|
property bool contextMenuOpen: (contextMenu && contextMenu.visible && contextMenu.screen === modelData)
|
||||||
readonly property real effectiveBarHeight: Math.max(widgetHeight + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
|
|
||||||
readonly property real barSpacing: {
|
|
||||||
const barIsHorizontal = (SettingsData.dankBarPosition === SettingsData.Position.Top || SettingsData.dankBarPosition === SettingsData.Position.Bottom)
|
|
||||||
const barIsVertical = (SettingsData.dankBarPosition === SettingsData.Position.Left || SettingsData.dankBarPosition === SettingsData.Position.Right)
|
|
||||||
const samePosition = (SettingsData.dockPosition === SettingsData.dankBarPosition)
|
|
||||||
const dockIsHorizontal = !isVertical
|
|
||||||
const dockIsVertical = isVertical
|
|
||||||
|
|
||||||
if (!SettingsData.dankBarVisible) return 0
|
|
||||||
if (dockIsHorizontal && barIsHorizontal && samePosition) {
|
|
||||||
return SettingsData.dankBarSpacing + effectiveBarHeight + SettingsData.dankBarBottomGap
|
|
||||||
}
|
|
||||||
if (dockIsVertical && barIsVertical && samePosition) {
|
|
||||||
return SettingsData.dankBarSpacing + effectiveBarHeight + SettingsData.dankBarBottomGap
|
|
||||||
}
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
readonly property real dockMargin: SettingsData.dockSpacing
|
|
||||||
readonly property real positionSpacing: barSpacing + SettingsData.dockBottomGap
|
|
||||||
readonly property real _dpr: (dock.screen && dock.screen.devicePixelRatio) ? dock.screen.devicePixelRatio : 1
|
|
||||||
function px(v) { return Math.round(v * _dpr) / _dpr }
|
|
||||||
|
|
||||||
|
|
||||||
property bool contextMenuOpen: (dockVariants.contextMenu && dockVariants.contextMenu.visible && dockVariants.contextMenu.screen === modelData)
|
|
||||||
property bool windowIsFullscreen: {
|
property bool windowIsFullscreen: {
|
||||||
if (!ToplevelManager.activeToplevel) {
|
if (!ToplevelManager.activeToplevel) {
|
||||||
return false
|
return false
|
||||||
@@ -68,28 +31,7 @@ Variants {
|
|||||||
const fullscreenApps = ["vlc", "mpv", "kodi", "steam", "lutris", "wine", "dosbox"]
|
const fullscreenApps = ["vlc", "mpv", "kodi", "steam", "lutris", "wine", "dosbox"]
|
||||||
return fullscreenApps.some(app => activeWindow.appId && activeWindow.appId.toLowerCase().includes(app))
|
return fullscreenApps.some(app => activeWindow.appId && activeWindow.appId.toLowerCase().includes(app))
|
||||||
}
|
}
|
||||||
property bool revealSticky: false
|
property bool reveal: (!autoHide || dockMouseArea.containsMouse || dockApps.requestDockShow || contextMenuOpen) && !windowIsFullscreen
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: revealHold
|
|
||||||
interval: 250
|
|
||||||
repeat: false
|
|
||||||
onTriggered: dock.revealSticky = false
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool reveal: {
|
|
||||||
if (CompositorService.isNiri && NiriService.inOverview) {
|
|
||||||
return SettingsData.dockOpenOnOverview
|
|
||||||
}
|
|
||||||
return (!autoHide || dockMouseArea.containsMouse || dockApps.requestDockShow || contextMenuOpen || revealSticky) && !windowIsFullscreen
|
|
||||||
}
|
|
||||||
|
|
||||||
onContextMenuOpenChanged: {
|
|
||||||
if (!contextMenuOpen && autoHide && !dockMouseArea.containsMouse) {
|
|
||||||
revealSticky = true
|
|
||||||
revealHold.restart()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: SettingsData
|
target: SettingsData
|
||||||
@@ -102,253 +44,152 @@ Variants {
|
|||||||
visible: SettingsData.showDock
|
visible: SettingsData.showDock
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
anchors {
|
||||||
exclusiveZone: {
|
bottom: true
|
||||||
if (!SettingsData.showDock || autoHide) return -1
|
left: true
|
||||||
if (barSpacing > 0) return -1
|
right: true
|
||||||
return px(58 + SettingsData.dockSpacing + SettingsData.dockBottomGap)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
margins {
|
||||||
|
left: 0
|
||||||
|
right: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
implicitHeight: 100
|
||||||
|
exclusiveZone: autoHide ? -1 : 65 - 16
|
||||||
|
|
||||||
mask: Region {
|
mask: Region {
|
||||||
item: dockMouseArea
|
item: dockMouseArea
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
MouseArea {
|
||||||
id: appTooltip
|
id: dockMouseArea
|
||||||
z: 1000
|
property real currentScreen: modelData ? modelData : dock.screen
|
||||||
|
property real screenWidth: currentScreen ? currentScreen.geometry.width : 1920
|
||||||
|
property real maxDockWidth: Math.min(screenWidth * 0.8, 1200)
|
||||||
|
|
||||||
property var hoveredButton: {
|
height: dock.reveal ? 65 : 20
|
||||||
if (!dockApps.children[0]) {
|
width: dock.reveal ? Math.min(dockBackground.width + 32, maxDockWidth) : Math.min(Math.max(dockBackground.width + 64, 200), screenWidth * 0.5)
|
||||||
return null
|
anchors {
|
||||||
}
|
bottom: parent.bottom
|
||||||
const layoutItem = dockApps.children[0]
|
horizontalCenter: parent.horizontalCenter
|
||||||
const flowLayout = layoutItem.children[0]
|
|
||||||
let repeater = null
|
|
||||||
for (var i = 0; i < flowLayout.children.length; i++) {
|
|
||||||
const child = flowLayout.children[i]
|
|
||||||
if (child && typeof child.count !== "undefined" && typeof child.itemAt === "function") {
|
|
||||||
repeater = child
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!repeater || !repeater.itemAt) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
for (var i = 0; i < repeater.count; i++) {
|
|
||||||
const item = repeater.itemAt(i)
|
|
||||||
if (item && item.dockButton && item.dockButton.showTooltip) {
|
|
||||||
return item.dockButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
}
|
||||||
|
hoverEnabled: true
|
||||||
|
|
||||||
property string tooltipText: hoveredButton ? hoveredButton.tooltipText : ""
|
Behavior on height {
|
||||||
|
NumberAnimation {
|
||||||
visible: hoveredButton !== null && tooltipText !== ""
|
duration: 200
|
||||||
width: px(tooltipLabel.implicitWidth + 24)
|
easing.type: Easing.OutCubic
|
||||||
height: px(tooltipLabel.implicitHeight + 12)
|
|
||||||
|
|
||||||
color: Theme.surfaceContainer
|
|
||||||
radius: Theme.cornerRadius
|
|
||||||
border.width: 1
|
|
||||||
border.color: Theme.outlineMedium
|
|
||||||
|
|
||||||
x: {
|
|
||||||
if (!hoveredButton) return 0
|
|
||||||
const buttonPos = hoveredButton.mapToItem(dock.contentItem, 0, 0)
|
|
||||||
if (!dock.isVertical) {
|
|
||||||
return buttonPos.x + hoveredButton.width / 2 - width / 2
|
|
||||||
} else {
|
|
||||||
if (SettingsData.dockPosition === SettingsData.Position.Right) {
|
|
||||||
return buttonPos.x - width - Theme.spacingS
|
|
||||||
} else {
|
|
||||||
return buttonPos.x + hoveredButton.width + Theme.spacingS
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
y: {
|
|
||||||
if (!hoveredButton) return 0
|
|
||||||
const buttonPos = hoveredButton.mapToItem(dock.contentItem, 0, 0)
|
|
||||||
if (!dock.isVertical) {
|
|
||||||
if (SettingsData.dockPosition === SettingsData.Position.Bottom) {
|
|
||||||
return buttonPos.y - height - Theme.spacingS
|
|
||||||
} else {
|
|
||||||
return buttonPos.y + hoveredButton.height + Theme.spacingS
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return buttonPos.y + hoveredButton.height / 2 - height / 2
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
Item {
|
||||||
id: tooltipLabel
|
id: dockContainer
|
||||||
anchors.centerIn: parent
|
anchors.fill: parent
|
||||||
text: appTooltip.tooltipText
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: Theme.surfaceText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
transform: Translate {
|
||||||
id: dockCore
|
id: dockSlide
|
||||||
anchors.fill: parent
|
y: dock.reveal ? 0 : 60
|
||||||
|
|
||||||
Connections {
|
Behavior on y {
|
||||||
target: dockMouseArea
|
NumberAnimation {
|
||||||
function onContainsMouseChanged() {
|
duration: 200
|
||||||
if (dockMouseArea.containsMouse) {
|
easing.type: Easing.OutCubic
|
||||||
dock.revealSticky = true
|
|
||||||
revealHold.stop()
|
|
||||||
} else {
|
|
||||||
if (dock.autoHide && !dock.contextMenuOpen) {
|
|
||||||
revealHold.restart()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
Rectangle {
|
||||||
id: dockMouseArea
|
id: dockBackground
|
||||||
property real currentScreen: modelData ? modelData : dock.screen
|
objectName: "dockBackground"
|
||||||
property real screenWidth: currentScreen ? currentScreen.geometry.width : 1920
|
anchors {
|
||||||
property real screenHeight: currentScreen ? currentScreen.geometry.height : 1080
|
top: parent.top
|
||||||
property real maxDockWidth: Math.min(screenWidth * 0.8, 1200)
|
bottom: parent.bottom
|
||||||
property real maxDockHeight: Math.min(screenHeight * 0.8, 1200)
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
height: {
|
|
||||||
if (dock.isVertical) {
|
|
||||||
return dock.reveal ? Math.min(dockBackground.implicitHeight + 32, maxDockHeight) : Math.min(Math.max(dockBackground.implicitHeight + 64, 200), screenHeight * 0.5)
|
|
||||||
} else {
|
|
||||||
return dock.reveal ? px(58 + SettingsData.dockSpacing + SettingsData.dockBottomGap) : 1
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
width: {
|
|
||||||
if (dock.isVertical) {
|
|
||||||
return dock.reveal ? px(58 + SettingsData.dockSpacing + SettingsData.dockBottomGap) : 1
|
|
||||||
} else {
|
|
||||||
return dock.reveal ? Math.min(dockBackground.implicitWidth + 32, maxDockWidth) : Math.min(Math.max(dockBackground.implicitWidth + 64, 200), screenWidth * 0.5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
anchors {
|
|
||||||
top: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? undefined : parent.top) : undefined
|
|
||||||
bottom: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.bottom : undefined) : undefined
|
|
||||||
horizontalCenter: !dock.isVertical ? parent.horizontalCenter : undefined
|
|
||||||
left: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.left) : undefined
|
|
||||||
right: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? parent.right : undefined) : undefined
|
|
||||||
verticalCenter: dock.isVertical ? parent.verticalCenter : undefined
|
|
||||||
}
|
|
||||||
hoverEnabled: true
|
|
||||||
acceptedButtons: Qt.NoButton
|
|
||||||
|
|
||||||
Behavior on height {
|
width: dockApps.implicitWidth + 12
|
||||||
NumberAnimation {
|
height: parent.height - 8
|
||||||
duration: 200
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on width {
|
anchors.topMargin: 4
|
||||||
NumberAnimation {
|
anchors.bottomMargin: 1
|
||||||
duration: 200
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, backgroundTransparency)
|
||||||
id: dockContainer
|
radius: Theme.cornerRadius
|
||||||
anchors.fill: parent
|
border.width: 1
|
||||||
|
border.color: Theme.outlineMedium
|
||||||
transform: Translate {
|
layer.enabled: true
|
||||||
id: dockSlide
|
|
||||||
x: {
|
|
||||||
if (!dock.isVertical) return 0
|
|
||||||
if (dock.reveal) return 0
|
|
||||||
if (SettingsData.dockPosition === SettingsData.Position.Right) {
|
|
||||||
return 60
|
|
||||||
} else {
|
|
||||||
return -60
|
|
||||||
}
|
|
||||||
}
|
|
||||||
y: {
|
|
||||||
if (dock.isVertical) return 0
|
|
||||||
if (dock.reveal) return 0
|
|
||||||
if (SettingsData.dockPosition === SettingsData.Position.Bottom) {
|
|
||||||
return 60
|
|
||||||
} else {
|
|
||||||
return -60
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on x {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 200
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on y {
|
|
||||||
NumberAnimation {
|
|
||||||
duration: 200
|
|
||||||
easing.type: Easing.OutCubic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: dockBackground
|
anchors.fill: parent
|
||||||
objectName: "dockBackground"
|
color: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g, Theme.surfaceTint.b, 0.04)
|
||||||
anchors {
|
radius: parent.radius
|
||||||
top: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? undefined : parent.top) : undefined
|
}
|
||||||
bottom: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.bottom : undefined) : undefined
|
|
||||||
horizontalCenter: !dock.isVertical ? parent.horizontalCenter : undefined
|
|
||||||
left: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.left) : undefined
|
|
||||||
right: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? parent.right : undefined) : undefined
|
|
||||||
verticalCenter: dock.isVertical ? parent.verticalCenter : undefined
|
|
||||||
}
|
|
||||||
anchors.topMargin: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? 0 : barSpacing + 4) : 0
|
|
||||||
anchors.bottomMargin: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? barSpacing + 1 : 0) : 0
|
|
||||||
anchors.leftMargin: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? 0 : barSpacing + 4) : 0
|
|
||||||
anchors.rightMargin: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? barSpacing + 1 : 0) : 0
|
|
||||||
|
|
||||||
implicitWidth: dock.isVertical ? (dockApps.implicitHeight + SettingsData.dockSpacing * 2) : (dockApps.implicitWidth + SettingsData.dockSpacing * 2)
|
DockApps {
|
||||||
implicitHeight: dock.isVertical ? (dockApps.implicitWidth + SettingsData.dockSpacing * 2) : (dockApps.implicitHeight + SettingsData.dockSpacing * 2)
|
id: dockApps
|
||||||
width: implicitWidth
|
|
||||||
height: implicitHeight
|
|
||||||
|
|
||||||
color: Qt.rgba(Theme.surfaceContainer.r, Theme.surfaceContainer.g, Theme.surfaceContainer.b, backgroundTransparency)
|
anchors.top: parent.top
|
||||||
radius: Theme.cornerRadius
|
anchors.bottom: parent.bottom
|
||||||
border.width: 1
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
border.color: Theme.outlineMedium
|
anchors.topMargin: 4
|
||||||
layer.enabled: true
|
anchors.bottomMargin: 4
|
||||||
|
|
||||||
Rectangle {
|
contextMenu: dock.contextMenu
|
||||||
anchors.fill: parent
|
groupByApp: dock.groupByApp
|
||||||
color: Qt.rgba(Theme.surfaceTint.r, Theme.surfaceTint.g, Theme.surfaceTint.b, 0.04)
|
}
|
||||||
radius: parent.radius
|
}
|
||||||
}
|
|
||||||
|
Rectangle {
|
||||||
DockApps {
|
id: appTooltip
|
||||||
id: dockApps
|
|
||||||
|
property var hoveredButton: {
|
||||||
anchors.top: !dock.isVertical ? parent.top : undefined
|
if (!dockApps.children[0]) {
|
||||||
anchors.bottom: !dock.isVertical ? parent.bottom : undefined
|
return null
|
||||||
anchors.horizontalCenter: !dock.isVertical ? parent.horizontalCenter : undefined
|
}
|
||||||
anchors.left: dock.isVertical ? parent.left : undefined
|
const row = dockApps.children[0]
|
||||||
anchors.right: dock.isVertical ? parent.right : undefined
|
let repeater = null
|
||||||
anchors.verticalCenter: dock.isVertical ? parent.verticalCenter : undefined
|
for (var i = 0; i < row.children.length; i++) {
|
||||||
anchors.topMargin: !dock.isVertical ? SettingsData.dockSpacing : 0
|
const child = row.children[i]
|
||||||
anchors.bottomMargin: !dock.isVertical ? SettingsData.dockSpacing : 0
|
if (child && typeof child.count !== "undefined" && typeof child.itemAt === "function") {
|
||||||
anchors.leftMargin: dock.isVertical ? SettingsData.dockSpacing : 0
|
repeater = child
|
||||||
anchors.rightMargin: dock.isVertical ? SettingsData.dockSpacing : 0
|
break
|
||||||
|
}
|
||||||
contextMenu: dockVariants.contextMenu
|
}
|
||||||
groupByApp: dock.groupByApp
|
if (!repeater || !repeater.itemAt) {
|
||||||
isVertical: dock.isVertical
|
return null
|
||||||
}
|
}
|
||||||
|
for (var i = 0; i < repeater.count; i++) {
|
||||||
|
const item = repeater.itemAt(i)
|
||||||
|
if (item && item.dockButton && item.dockButton.showTooltip) {
|
||||||
|
return item.dockButton
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
property string tooltipText: hoveredButton ? hoveredButton.tooltipText : ""
|
||||||
|
|
||||||
|
visible: hoveredButton !== null && tooltipText !== ""
|
||||||
|
width: tooltipLabel.implicitWidth + 24
|
||||||
|
height: tooltipLabel.implicitHeight + 12
|
||||||
|
|
||||||
|
color: Theme.surfaceContainer
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.outlineMedium
|
||||||
|
|
||||||
|
y: -height - 8
|
||||||
|
x: hoveredButton ? hoveredButton.mapToItem(dockContainer, hoveredButton.width / 2, 0).x - width / 2 : 0
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: tooltipLabel
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: appTooltip.tooltipText
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
color: Theme.surfaceText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,27 +25,6 @@ Item {
|
|||||||
property string windowTitle: ""
|
property string windowTitle: ""
|
||||||
property bool isHovered: mouseArea.containsMouse && !dragging
|
property bool isHovered: mouseArea.containsMouse && !dragging
|
||||||
property bool showTooltip: mouseArea.containsMouse && !dragging
|
property bool showTooltip: mouseArea.containsMouse && !dragging
|
||||||
property var cachedDesktopEntry: null
|
|
||||||
|
|
||||||
function updateDesktopEntry() {
|
|
||||||
if (!appData || appData.appId === "__SEPARATOR__") {
|
|
||||||
cachedDesktopEntry = null
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const moddedId = Paths.moddedAppId(appData.appId)
|
|
||||||
cachedDesktopEntry = DesktopEntries.heuristicLookup(moddedId)
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: updateDesktopEntry()
|
|
||||||
|
|
||||||
onAppDataChanged: updateDesktopEntry()
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: DesktopEntries
|
|
||||||
function onApplicationsChanged() {
|
|
||||||
updateDesktopEntry()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
property bool isWindowFocused: {
|
property bool isWindowFocused: {
|
||||||
if (!appData) {
|
if (!appData) {
|
||||||
return false
|
return false
|
||||||
@@ -76,7 +55,8 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((appData.type === "window" && showWindowTitle) || (appData.type === "grouped" && appData.windowTitle)) {
|
if ((appData.type === "window" && showWindowTitle) || (appData.type === "grouped" && appData.windowTitle)) {
|
||||||
const appName = cachedDesktopEntry && cachedDesktopEntry.name ? cachedDesktopEntry.name : appData.appId
|
const desktopEntry = DesktopEntries.heuristicLookup(appData.appId)
|
||||||
|
const appName = desktopEntry && desktopEntry.name ? desktopEntry.name : appData.appId
|
||||||
const title = appData.type === "window" ? windowTitle : appData.windowTitle
|
const title = appData.type === "window" ? windowTitle : appData.windowTitle
|
||||||
return appName + (title ? " • " + title : "")
|
return appName + (title ? " • " + title : "")
|
||||||
}
|
}
|
||||||
@@ -85,7 +65,8 @@ Item {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedDesktopEntry && cachedDesktopEntry.name ? cachedDesktopEntry.name : appData.appId
|
const desktopEntry = DesktopEntries.heuristicLookup(appData.appId)
|
||||||
|
return desktopEntry && desktopEntry.name ? desktopEntry.name : appData.appId
|
||||||
}
|
}
|
||||||
|
|
||||||
width: 40
|
width: 40
|
||||||
@@ -274,7 +255,7 @@ Item {
|
|||||||
if (mouse.button === Qt.LeftButton) {
|
if (mouse.button === Qt.LeftButton) {
|
||||||
if (appData.type === "pinned") {
|
if (appData.type === "pinned") {
|
||||||
if (appData && appData.appId) {
|
if (appData && appData.appId) {
|
||||||
const desktopEntry = cachedDesktopEntry
|
const desktopEntry = DesktopEntries.heuristicLookup(appData.appId)
|
||||||
if (desktopEntry) {
|
if (desktopEntry) {
|
||||||
AppUsageHistoryData.addAppUsage({
|
AppUsageHistoryData.addAppUsage({
|
||||||
"id": appData.appId,
|
"id": appData.appId,
|
||||||
@@ -294,7 +275,7 @@ Item {
|
|||||||
} else if (appData.type === "grouped") {
|
} else if (appData.type === "grouped") {
|
||||||
if (appData.windowCount === 0) {
|
if (appData.windowCount === 0) {
|
||||||
if (appData && appData.appId) {
|
if (appData && appData.appId) {
|
||||||
const desktopEntry = cachedDesktopEntry
|
const desktopEntry = DesktopEntries.heuristicLookup(appData.appId)
|
||||||
if (desktopEntry) {
|
if (desktopEntry) {
|
||||||
AppUsageHistoryData.addAppUsage({
|
AppUsageHistoryData.addAppUsage({
|
||||||
"id": appData.appId,
|
"id": appData.appId,
|
||||||
@@ -324,7 +305,7 @@ Item {
|
|||||||
}
|
}
|
||||||
} else if (mouse.button === Qt.MiddleButton) {
|
} else if (mouse.button === Qt.MiddleButton) {
|
||||||
if (appData && appData.appId) {
|
if (appData && appData.appId) {
|
||||||
const desktopEntry = cachedDesktopEntry
|
const desktopEntry = DesktopEntries.heuristicLookup(appData.appId)
|
||||||
if (desktopEntry) {
|
if (desktopEntry) {
|
||||||
AppUsageHistoryData.addAppUsage({
|
AppUsageHistoryData.addAppUsage({
|
||||||
"id": appData.appId,
|
"id": appData.appId,
|
||||||
@@ -360,7 +341,8 @@ Item {
|
|||||||
if (moddedId.toLowerCase().includes("steam_app")) {
|
if (moddedId.toLowerCase().includes("steam_app")) {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return cachedDesktopEntry && cachedDesktopEntry.icon ? Quickshell.iconPath(cachedDesktopEntry.icon, true) : ""
|
const desktopEntry = DesktopEntries.heuristicLookup(moddedId)
|
||||||
|
return desktopEntry && desktopEntry.icon ? Quickshell.iconPath(desktopEntry.icon, true) : ""
|
||||||
}
|
}
|
||||||
mipmap: true
|
mipmap: true
|
||||||
smooth: true
|
smooth: true
|
||||||
@@ -399,7 +381,7 @@ Item {
|
|||||||
return "?"
|
return "?"
|
||||||
}
|
}
|
||||||
|
|
||||||
const desktopEntry = cachedDesktopEntry
|
const desktopEntry = DesktopEntries.heuristicLookup(appData.appId)
|
||||||
if (desktopEntry && desktopEntry.name) {
|
if (desktopEntry && desktopEntry.name) {
|
||||||
return desktopEntry.name.charAt(0).toUpperCase()
|
return desktopEntry.name.charAt(0).toUpperCase()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ Item {
|
|||||||
property bool requestDockShow: false
|
property bool requestDockShow: false
|
||||||
property int pinnedAppCount: 0
|
property int pinnedAppCount: 0
|
||||||
property bool groupByApp: false
|
property bool groupByApp: false
|
||||||
property bool isVertical: false
|
|
||||||
|
|
||||||
implicitWidth: isVertical ? appLayout.height : appLayout.width
|
implicitWidth: row.width
|
||||||
implicitHeight: isVertical ? appLayout.width : appLayout.height
|
implicitHeight: row.height
|
||||||
|
|
||||||
function movePinnedApp(fromIndex, toIndex) {
|
function movePinnedApp(fromIndex, toIndex) {
|
||||||
if (fromIndex === toIndex) {
|
if (fromIndex === toIndex) {
|
||||||
@@ -34,16 +33,11 @@ Item {
|
|||||||
SessionData.setPinnedApps(currentPinned)
|
SessionData.setPinnedApps(currentPinned)
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Row {
|
||||||
id: appLayout
|
id: row
|
||||||
|
spacing: 2
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: layoutFlow.width
|
height: 40
|
||||||
height: layoutFlow.height
|
|
||||||
|
|
||||||
Flow {
|
|
||||||
id: layoutFlow
|
|
||||||
flow: root.isVertical ? Flow.TopToBottom : Flow.LeftToRight
|
|
||||||
spacing: 8
|
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: repeater
|
id: repeater
|
||||||
@@ -224,7 +218,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|||||||
@@ -92,41 +92,17 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const dockBackground = findDockBackground(dockWindow.contentItem)
|
const dockBackground = findDockBackground(dockWindow.contentItem)
|
||||||
let actualDockWidth = dockWindow.width
|
|
||||||
if (dockBackground) {
|
if (dockBackground) {
|
||||||
actualDockHeight = dockBackground.height
|
actualDockHeight = dockBackground.height
|
||||||
actualDockWidth = dockBackground.width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
const dockBottomMargin = 16
|
||||||
const dockMargin = 16
|
const buttonScreenY = root.screen.height - actualDockHeight - dockBottomMargin - 20
|
||||||
let buttonScreenX, buttonScreenY
|
|
||||||
|
|
||||||
if (isVertical) {
|
const dockContentWidth = dockWindow.width
|
||||||
const dockContentHeight = dockWindow.height
|
const screenWidth = root.screen.width
|
||||||
const screenHeight = root.screen.height
|
const dockLeftMargin = Math.round((screenWidth - dockContentWidth) / 2)
|
||||||
const dockTopMargin = Math.round((screenHeight - dockContentHeight) / 2)
|
const buttonScreenX = dockLeftMargin + buttonPosInDock.x + anchorItem.width / 2
|
||||||
buttonScreenY = dockTopMargin + buttonPosInDock.y + anchorItem.height / 2
|
|
||||||
|
|
||||||
if (SettingsData.dockPosition === SettingsData.Position.Right) {
|
|
||||||
buttonScreenX = root.screen.width - actualDockWidth - dockMargin - 20
|
|
||||||
} else {
|
|
||||||
buttonScreenX = actualDockWidth + dockMargin + 20
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const isDockAtBottom = SettingsData.dockPosition === SettingsData.Position.Bottom
|
|
||||||
|
|
||||||
if (isDockAtBottom) {
|
|
||||||
buttonScreenY = root.screen.height - actualDockHeight - dockMargin - 20
|
|
||||||
} else {
|
|
||||||
buttonScreenY = actualDockHeight + dockMargin + 20
|
|
||||||
}
|
|
||||||
|
|
||||||
const dockContentWidth = dockWindow.width
|
|
||||||
const screenWidth = root.screen.width
|
|
||||||
const dockLeftMargin = Math.round((screenWidth - dockContentWidth) / 2)
|
|
||||||
buttonScreenX = dockLeftMargin + buttonPosInDock.x + anchorItem.width / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
anchorPos = Qt.point(buttonScreenX, buttonScreenY)
|
anchorPos = Qt.point(buttonScreenX, buttonScreenY)
|
||||||
}
|
}
|
||||||
@@ -138,37 +114,12 @@ PanelWindow {
|
|||||||
height: Math.max(60, menuColumn.implicitHeight + Theme.spacingS * 2)
|
height: Math.max(60, menuColumn.implicitHeight + Theme.spacingS * 2)
|
||||||
|
|
||||||
x: {
|
x: {
|
||||||
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
const left = 10
|
||||||
if (isVertical) {
|
const right = root.width - width - 10
|
||||||
const isDockAtRight = SettingsData.dockPosition === SettingsData.Position.Right
|
const want = root.anchorPos.x - width / 2
|
||||||
if (isDockAtRight) {
|
return Math.max(left, Math.min(right, want))
|
||||||
return Math.max(10, root.anchorPos.x - width + 30)
|
|
||||||
} else {
|
|
||||||
return Math.min(root.width - width - 10, root.anchorPos.x - 30)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const left = 10
|
|
||||||
const right = root.width - width - 10
|
|
||||||
const want = root.anchorPos.x - width / 2
|
|
||||||
return Math.max(left, Math.min(right, want))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
y: {
|
|
||||||
const isVertical = SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right
|
|
||||||
if (isVertical) {
|
|
||||||
const top = 10
|
|
||||||
const bottom = root.height - height - 10
|
|
||||||
const want = root.anchorPos.y - height / 2
|
|
||||||
return Math.max(top, Math.min(bottom, want))
|
|
||||||
} else {
|
|
||||||
const isDockAtBottom = SettingsData.dockPosition === SettingsData.Position.Bottom
|
|
||||||
if (isDockAtBottom) {
|
|
||||||
return Math.max(10, root.anchorPos.y - height + 30)
|
|
||||||
} else {
|
|
||||||
return Math.min(root.height - height - 10, root.anchorPos.y - 30)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
y: Math.max(10, root.anchorPos.y - height + 30)
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
|
|||||||
@@ -1,105 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtCore
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import qs.Common
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
readonly property string greetCfgDir: Quickshell.env("DMS_GREET_CFG_DIR") || "/etc/greetd/.dms"
|
|
||||||
readonly property string sessionConfigPath: greetCfgDir + "/session.json"
|
|
||||||
readonly property string memoryFile: greetCfgDir + "/memory.json"
|
|
||||||
|
|
||||||
property string lastSessionId: ""
|
|
||||||
property string lastSuccessfulUser: ""
|
|
||||||
property bool isLightMode: false
|
|
||||||
property bool nightModeEnabled: false
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
|
||||||
Quickshell.execDetached(["mkdir", "-p", greetCfgDir])
|
|
||||||
loadMemory()
|
|
||||||
loadSessionConfig()
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadMemory() {
|
|
||||||
parseMemory(memoryFileView.text())
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadSessionConfig() {
|
|
||||||
parseSessionConfig(sessionConfigFileView.text())
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseSessionConfig(content) {
|
|
||||||
try {
|
|
||||||
if (content && content.trim()) {
|
|
||||||
const config = JSON.parse(content)
|
|
||||||
isLightMode = config.isLightMode !== undefined ? config.isLightMode : false
|
|
||||||
nightModeEnabled = config.nightModeEnabled !== undefined ? config.nightModeEnabled : false
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Failed to parse greeter session config:", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseMemory(content) {
|
|
||||||
try {
|
|
||||||
if (content && content.trim()) {
|
|
||||||
const memory = JSON.parse(content)
|
|
||||||
lastSessionId = memory.lastSessionId !== undefined ? memory.lastSessionId : ""
|
|
||||||
lastSuccessfulUser = memory.lastSuccessfulUser !== undefined ? memory.lastSuccessfulUser : ""
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Failed to parse greetd memory:", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveMemory() {
|
|
||||||
memoryFileView.setText(JSON.stringify({
|
|
||||||
"lastSessionId": lastSessionId,
|
|
||||||
"lastSuccessfulUser": lastSuccessfulUser
|
|
||||||
}, null, 2))
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLastSessionId(id) {
|
|
||||||
lastSessionId = id || ""
|
|
||||||
saveMemory()
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLastSuccessfulUser(username) {
|
|
||||||
lastSuccessfulUser = username || ""
|
|
||||||
saveMemory()
|
|
||||||
}
|
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: memoryFileView
|
|
||||||
path: root.memoryFile
|
|
||||||
blockLoading: false
|
|
||||||
blockWrites: false
|
|
||||||
atomicWrites: true
|
|
||||||
watchChanges: false
|
|
||||||
printErrors: false
|
|
||||||
onLoaded: {
|
|
||||||
parseMemory(memoryFileView.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: sessionConfigFileView
|
|
||||||
path: root.sessionConfigPath
|
|
||||||
blockLoading: false
|
|
||||||
blockWrites: true
|
|
||||||
atomicWrites: false
|
|
||||||
watchChanges: false
|
|
||||||
printErrors: true
|
|
||||||
onLoaded: {
|
|
||||||
parseSessionConfig(sessionConfigFileView.text())
|
|
||||||
}
|
|
||||||
onLoadFailed: error => {
|
|
||||||
console.warn("Could not load greeter session config from", root.sessionConfigPath, "error:", error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
pragma Singleton
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
import QtCore
|
|
||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Io
|
|
||||||
import qs.Common
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
readonly property string configPath: {
|
|
||||||
const greetCfgDir = Quickshell.env("DMS_GREET_CFG_DIR") || "/etc/greetd/.dms"
|
|
||||||
return greetCfgDir + "/settings.json"
|
|
||||||
}
|
|
||||||
|
|
||||||
property string currentThemeName: "blue"
|
|
||||||
property bool settingsLoaded: false
|
|
||||||
property string customThemeFile: ""
|
|
||||||
property string matugenScheme: "scheme-tonal-spot"
|
|
||||||
property bool use24HourClock: true
|
|
||||||
property bool useFahrenheit: false
|
|
||||||
property bool nightModeEnabled: false
|
|
||||||
property string weatherLocation: "New York, NY"
|
|
||||||
property string weatherCoordinates: "40.7128,-74.0060"
|
|
||||||
property bool useAutoLocation: false
|
|
||||||
property bool weatherEnabled: true
|
|
||||||
property string iconTheme: "System Default"
|
|
||||||
property bool useOSLogo: false
|
|
||||||
property string osLogoColorOverride: ""
|
|
||||||
property real osLogoBrightness: 0.5
|
|
||||||
property real osLogoContrast: 1
|
|
||||||
property string fontFamily: "Inter Variable"
|
|
||||||
property string monoFontFamily: "Fira Code"
|
|
||||||
property int fontWeight: Font.Normal
|
|
||||||
property real fontScale: 1.0
|
|
||||||
property real cornerRadius: 12
|
|
||||||
property string widgetBackgroundColor: "sch"
|
|
||||||
property string surfaceBase: "s"
|
|
||||||
property string lockDateFormat: ""
|
|
||||||
property bool lockScreenShowPowerActions: true
|
|
||||||
property var screenPreferences: ({})
|
|
||||||
property int animationSpeed: 2
|
|
||||||
|
|
||||||
readonly property string defaultFontFamily: "Inter Variable"
|
|
||||||
readonly property string defaultMonoFontFamily: "Fira Code"
|
|
||||||
|
|
||||||
function parseSettings(content) {
|
|
||||||
try {
|
|
||||||
if (content && content.trim()) {
|
|
||||||
const settings = JSON.parse(content)
|
|
||||||
currentThemeName = settings.currentThemeName !== undefined ? settings.currentThemeName : "blue"
|
|
||||||
customThemeFile = settings.customThemeFile !== undefined ? settings.customThemeFile : ""
|
|
||||||
matugenScheme = settings.matugenScheme !== undefined ? settings.matugenScheme : "scheme-tonal-spot"
|
|
||||||
use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true
|
|
||||||
useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false
|
|
||||||
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false
|
|
||||||
weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY"
|
|
||||||
weatherCoordinates = settings.weatherCoordinates !== undefined ? settings.weatherCoordinates : "40.7128,-74.0060"
|
|
||||||
useAutoLocation = settings.useAutoLocation !== undefined ? settings.useAutoLocation : false
|
|
||||||
weatherEnabled = settings.weatherEnabled !== undefined ? settings.weatherEnabled : true
|
|
||||||
iconTheme = settings.iconTheme !== undefined ? settings.iconTheme : "System Default"
|
|
||||||
useOSLogo = settings.useOSLogo !== undefined ? settings.useOSLogo : false
|
|
||||||
osLogoColorOverride = settings.osLogoColorOverride !== undefined ? settings.osLogoColorOverride : ""
|
|
||||||
osLogoBrightness = settings.osLogoBrightness !== undefined ? settings.osLogoBrightness : 0.5
|
|
||||||
osLogoContrast = settings.osLogoContrast !== undefined ? settings.osLogoContrast : 1
|
|
||||||
fontFamily = settings.fontFamily !== undefined ? settings.fontFamily : defaultFontFamily
|
|
||||||
monoFontFamily = settings.monoFontFamily !== undefined ? settings.monoFontFamily : defaultMonoFontFamily
|
|
||||||
fontWeight = settings.fontWeight !== undefined ? settings.fontWeight : Font.Normal
|
|
||||||
fontScale = settings.fontScale !== undefined ? settings.fontScale : 1.0
|
|
||||||
cornerRadius = settings.cornerRadius !== undefined ? settings.cornerRadius : 12
|
|
||||||
widgetBackgroundColor = settings.widgetBackgroundColor !== undefined ? settings.widgetBackgroundColor : "sch"
|
|
||||||
surfaceBase = settings.surfaceBase !== undefined ? settings.surfaceBase : "s"
|
|
||||||
lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : ""
|
|
||||||
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true
|
|
||||||
screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({})
|
|
||||||
animationSpeed = settings.animationSpeed !== undefined ? settings.animationSpeed : 2
|
|
||||||
settingsLoaded = true
|
|
||||||
|
|
||||||
if (typeof Theme !== "undefined") {
|
|
||||||
Theme.applyGreeterTheme(currentThemeName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
console.warn("Failed to parse greetd settings:", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function getEffectiveLockDateFormat() {
|
|
||||||
return lockDateFormat && lockDateFormat.length > 0 ? lockDateFormat : Locale.LongFormat
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFilteredScreens(componentId) {
|
|
||||||
const prefs = screenPreferences && screenPreferences[componentId] || ["all"]
|
|
||||||
if (prefs.includes("all")) {
|
|
||||||
return Quickshell.screens
|
|
||||||
}
|
|
||||||
return Quickshell.screens.filter(screen => prefs.includes(screen.name))
|
|
||||||
}
|
|
||||||
|
|
||||||
FileView {
|
|
||||||
id: settingsFile
|
|
||||||
path: root.configPath
|
|
||||||
blockLoading: false
|
|
||||||
blockWrites: true
|
|
||||||
atomicWrites: false
|
|
||||||
watchChanges: false
|
|
||||||
printErrors: true
|
|
||||||
onLoaded: {
|
|
||||||
parseSettings(settingsFile.text())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,29 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
pragma Singleton
|
|
||||||
pragma ComponentBehavior: Bound
|
|
||||||
|
|
||||||
Singleton {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property string passwordBuffer: ""
|
|
||||||
property string username: ""
|
|
||||||
property string usernameInput: ""
|
|
||||||
property bool showPasswordInput: false
|
|
||||||
property string selectedSession: ""
|
|
||||||
property string pamState: ""
|
|
||||||
property bool unlocking: false
|
|
||||||
|
|
||||||
property var sessionList: []
|
|
||||||
property var sessionExecs: []
|
|
||||||
property var sessionPaths: []
|
|
||||||
property int currentSessionIndex: 0
|
|
||||||
|
|
||||||
function reset() {
|
|
||||||
showPasswordInput = false
|
|
||||||
username = ""
|
|
||||||
usernameInput = ""
|
|
||||||
passwordBuffer = ""
|
|
||||||
pamState = ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Wayland
|
|
||||||
import Quickshell.Services.Greetd
|
|
||||||
|
|
||||||
WlSessionLockSurface {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property WlSessionLock lock
|
|
||||||
|
|
||||||
color: "transparent"
|
|
||||||
|
|
||||||
GreeterContent {
|
|
||||||
anchors.fill: parent
|
|
||||||
screenName: root.screen?.name ?? ""
|
|
||||||
sessionLock: root.lock
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
# Dank (dms) Greeter
|
|
||||||
|
|
||||||
A greeter for [greetd](https://github.com/kennylevinsen/greetd) that follows the aesthetics of the dms lock screen.
|
|
||||||
|
|
||||||
## Features
|
|
||||||
|
|
||||||
- **Multi user**: Login with any system user
|
|
||||||
- **dms sync**: Sync settings with dms for consistent styling between shell and greeter
|
|
||||||
- **niri or Hyprland**: Use either niri or Hyprland for the greeter's compositor.
|
|
||||||
- **Custom PAM**: Supports custom PAM configuration in `/etc/pam.d/dankshell`
|
|
||||||
- **Session Memory**: Remembers last selected session and user
|
|
||||||
|
|
||||||
## Installation
|
|
||||||
|
|
||||||
### Automatic
|
|
||||||
|
|
||||||
The easiest thing is to run `dms greeter install` or `dms` for interactive installation.
|
|
||||||
|
|
||||||
### Manual
|
|
||||||
|
|
||||||
1. Install `greetd` (in most distro's standard repositories)
|
|
||||||
2. Copy `assets/dms-niri.kdl` or `assets/dms-hypr.conf` to `/etc/greetd`
|
|
||||||
- niri if you want to run the greeter under niri, hypr if you want to run the greeter under Hyprland
|
|
||||||
3. Copy `assets/greet-niri.sh` or `assets/greet-hyprland.sh` to `/usr/local/bin/start-dms-greetd.sh`
|
|
||||||
4. Edit `/etc/greetd/dms-niri.kdl` or `/etc/greetd/dms-hypr.conf` and replace `_DMS_PATH_` with the absolute path to dms, e.g. `/home/joecool/.config/quickshell/dms`
|
|
||||||
5. Edit or create `/etc/greetd/config.toml`
|
|
||||||
```toml
|
|
||||||
[terminal]
|
|
||||||
# The VT to run the greeter on. Can be "next", "current" or a number
|
|
||||||
# designating the VT.
|
|
||||||
vt = 1
|
|
||||||
|
|
||||||
# The default session, also known as the greeter.
|
|
||||||
[default_session]
|
|
||||||
|
|
||||||
# `agreety` is the bundled agetty/login-lookalike. You can replace `/bin/sh`
|
|
||||||
# with whatever you want started, such as `sway`.
|
|
||||||
|
|
||||||
# The user to run the command as. The privileges this user must have depends
|
|
||||||
# on the greeter. A graphical greeter may for example require the user to be
|
|
||||||
# in the `video` group.
|
|
||||||
user = "greeter"
|
|
||||||
|
|
||||||
command = "/usr/local/bin/start-dms-greetd.sh"
|
|
||||||
```
|
|
||||||
|
|
||||||
Enable the greeter with `sudo systemctl enable greetd`
|
|
||||||
|
|
||||||
### NixOS
|
|
||||||
|
|
||||||
To install the greeter on NixOS add the repo to your flake inputs as described in the readme. Then somewhere in your NixOS config add this to imports:
|
|
||||||
```nix
|
|
||||||
imports = [
|
|
||||||
inputs.dankMaterialShell.nixosModules.greeter
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
Enable the greeter with this in your NixOS config:
|
|
||||||
```nix
|
|
||||||
programs.dankMaterialShell.greeter = {
|
|
||||||
enable = true;
|
|
||||||
compositor = "niri"; # or set to hyprland
|
|
||||||
configHome = "/home/user"; # optionally symlinks that users DMS settings to the greeters data directory
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
To run dms in greeter mode you just need to set `DMS_RUN_GREETER=1` in the environment.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
DMS_RUN_GREETER=1 qs -p /path/to/dms
|
|
||||||
```
|
|
||||||
|
|
||||||
### Configuration
|
|
||||||
|
|
||||||
#### Compositor
|
|
||||||
|
|
||||||
You can configure compositor specific settings such as outputs/displays the same as you would in niri or Hyprland.
|
|
||||||
|
|
||||||
Simply edit `/etc/greetd/dms-niri.kdl` or `/etc/greetd/dms-hypr.conf` to change compositor settings for the greeter
|
|
||||||
|
|
||||||
#### Personalization
|
|
||||||
|
|
||||||
Wallpapers and themes and weather and clock formats and things are a TODO on the documentation, but it's configured exactly the same as dms.
|
|
||||||
|
|
||||||
You can synchronize those configurations with a specific user if you want greeter settings to always mirror the shell.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# For core settings (theme, clock formats, etc)
|
|
||||||
sudo ln -sf ~/.config/DankMaterialShell/settings.json /etc/greetd/.dms/settings.json
|
|
||||||
# For state (mainly you would configure wallpaper in this file)
|
|
||||||
sudo ln -sf ~/.local/state/DankMaterialShell/session.json /etc/greetd/.dms/session.json
|
|
||||||
# For wallpaper based theming
|
|
||||||
sudo ln -sf ~/.cache/quickshell/dankshell/dms-colors.json /etc/greetd/.dms/dms-colors.json
|
|
||||||
```
|
|
||||||
|
|
||||||
You can override the configuration path with the `DMS_GREET_CFG_DIR` environment variable, the default is `/etc/greetd/.dms`
|
|
||||||
|
|
||||||
It should be writable by the greeter user.
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
env = DMS_RUN_GREETER,1
|
|
||||||
|
|
||||||
exec = sh -c "qs -p _DMS_PATH_; hyprctl dispatch exit"
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
hotkey-overlay {
|
|
||||||
skip-at-startup
|
|
||||||
}
|
|
||||||
|
|
||||||
environment {
|
|
||||||
DMS_RUN_GREETER "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
spawn-at-startup "sh" "-c" "qs -p _DMS_PATH_; niri msg action quit --skip-confirmation"
|
|
||||||
|
|
||||||
debug {
|
|
||||||
keep-max-bpc-unchanged
|
|
||||||
}
|
|
||||||
|
|
||||||
gestures {
|
|
||||||
hot-corners {
|
|
||||||
off
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
layout {
|
|
||||||
background-color "#000000"
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export XDG_SESSION_TYPE=wayland
|
|
||||||
export QT_QPA_PLATFORM=wayland
|
|
||||||
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
|
|
||||||
export EGL_PLATFORM=gbm
|
|
||||||
|
|
||||||
exec Hyprland -c /etc/greetd/dms-hypr.conf
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
|
|
||||||
export XDG_SESSION_TYPE=wayland
|
|
||||||
export QT_QPA_PLATFORM=wayland
|
|
||||||
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
|
|
||||||
export EGL_PLATFORM=gbm
|
|
||||||
|
|
||||||
exec niri -c /etc/greetd/dms-niri.kdl
|
|
||||||
@@ -20,9 +20,6 @@ Item {
|
|||||||
property bool unlocking: false
|
property bool unlocking: false
|
||||||
property string pamState: ""
|
property string pamState: ""
|
||||||
property string randomFact: ""
|
property string randomFact: ""
|
||||||
property string hyprlandCurrentLayout: ""
|
|
||||||
property string hyprlandKeyboard: ""
|
|
||||||
property int hyprlandLayoutCount: 0
|
|
||||||
|
|
||||||
signal unlockRequested
|
signal unlockRequested
|
||||||
|
|
||||||
@@ -47,8 +44,10 @@ Item {
|
|||||||
powerDialogVisible = false
|
powerDialogVisible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property var facts: ["A photon takes 100,000 to 200,000 years bouncing through the Sun's dense core, then races to Earth in just 8 minutes 20 seconds.", "A teaspoon of neutron star matter would weigh a billion metric tons here on Earth.", "Right now, 100 trillion solar neutrinos are passing through your body every second.", "The Sun converts 4 million metric tons of matter into pure energy every second—enough to power Earth for 500,000 years.", "The universe still glows with leftover heat from the Big Bang—just 2.7 degrees above absolute zero.", "There's a nebula out there that's actually colder than empty space itself.", "We've detected black holes crashing together by measuring spacetime stretch by less than 1/10,000th the width of a proton.", "Fast radio bursts can release more energy in 5 milliseconds than our Sun produces in 3 days.", "Our galaxy might be crawling with billions of rogue planets drifting alone in the dark.", "Distant galaxies can move away from us faster than light because space itself is stretching.", "The edge of what we can see is 46.5 billion light-years away, even though the universe is only 13.8 billion years old.", "The universe is mostly invisible: 5% regular matter, 27% dark matter, 68% dark energy.", "A day on Venus lasts longer than its entire year around the Sun.", "On Mercury, the time between sunrises is 176 Earth days long.", "In about 4.5 billion years, our galaxy will smash into Andromeda.", "Most of the gold in your jewelry was forged when neutron stars collided somewhere in space.", "PSR J1748-2446ad, the fastest spinning star, rotates 716 times per second—its equator moves at 24% the speed of light.", "Cosmic rays create particles that shouldn't make it to Earth's surface, but time dilation lets them sneak through.", "Jupiter's magnetic field is so huge that if we could see it, it would look bigger than the Moon in our sky.", "Interstellar space is so empty it's like a cube 32 kilometers wide containing just a single grain of sand.", "Voyager 1 is 24 billion kilometers away but won't leave the Sun's gravitational influence for another 30,000 years.", "Counting to a billion at one number per second would take over 31 years.", "Space is so vast, even speeding at light-speed, you'd never return past the cosmic horizon.", "Astronauts on the ISS age about 0.01 seconds less each year than people on Earth.", "Sagittarius B2, a dust cloud near our galaxy's center, contains ethyl formate—the compound that gives raspberries their flavor and rum its smell.", "Beyond 16 billion light-years, the cosmic event horizon marks where space expands too fast for light to ever reach us again.", "Even at light-speed, you'd never catch up to most galaxies—space expands faster.", "Only around 5% of galaxies are ever reachable—even at light-speed.", "If the Sun vanished, we'd still orbit it for 8 minutes before drifting away.", "If a planet 65 million light-years away looked at Earth now, it'd see dinosaurs.", "Our oldest radio signals will reach the Milky Way's center in 26,000 years.", "Every atom in your body heavier than hydrogen was forged in the nuclear furnace of a dying star.", "The Moon moves 3.8 centimeters farther from Earth every year.", "The universe creates 275 million new stars every single day.", "Jupiter's Great Red Spot is a storm twice the size of Earth that has been raging for at least 350 years.", "If you watched someone fall into a black hole, they'd appear frozen at the event horizon forever—time effectively stops from your perspective.", "The Boötes Supervoid is a cosmic desert 1.8 billion light-years across with 60% fewer galaxies than it should have."]
|
||||||
|
|
||||||
function pickRandomFact() {
|
function pickRandomFact() {
|
||||||
randomFact = Facts.getRandomFact()
|
randomFact = facts[Math.floor(Math.random() * facts.length)]
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
@@ -58,11 +57,6 @@ Item {
|
|||||||
|
|
||||||
WeatherService.addRef()
|
WeatherService.addRef()
|
||||||
UserInfoService.refreshUserInfo()
|
UserInfoService.refreshUserInfo()
|
||||||
|
|
||||||
if (CompositorService.isHyprland) {
|
|
||||||
updateHyprlandLayout()
|
|
||||||
hyprlandLayoutUpdateTimer.start()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
onDemoModeChanged: {
|
onDemoModeChanged: {
|
||||||
if (demoMode) {
|
if (demoMode) {
|
||||||
@@ -71,56 +65,6 @@ Item {
|
|||||||
}
|
}
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
WeatherService.removeRef()
|
WeatherService.removeRef()
|
||||||
if (CompositorService.isHyprland) {
|
|
||||||
hyprlandLayoutUpdateTimer.stop()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateHyprlandLayout() {
|
|
||||||
if (CompositorService.isHyprland) {
|
|
||||||
hyprlandLayoutProcess.running = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Process {
|
|
||||||
id: hyprlandLayoutProcess
|
|
||||||
running: false
|
|
||||||
command: ["hyprctl", "-j", "devices"]
|
|
||||||
stdout: StdioCollector {
|
|
||||||
onStreamFinished: {
|
|
||||||
try {
|
|
||||||
const data = JSON.parse(text)
|
|
||||||
const mainKeyboard = data.keyboards.find(kb => kb.main === true)
|
|
||||||
hyprlandKeyboard = mainKeyboard.name
|
|
||||||
if (mainKeyboard && mainKeyboard.active_keymap) {
|
|
||||||
const parts = mainKeyboard.active_keymap.split(" ")
|
|
||||||
if (parts.length > 0) {
|
|
||||||
hyprlandCurrentLayout = parts[0].substring(0, 2).toUpperCase()
|
|
||||||
} else {
|
|
||||||
hyprlandCurrentLayout = mainKeyboard.active_keymap.substring(0, 2).toUpperCase()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
hyprlandCurrentLayout = ""
|
|
||||||
}
|
|
||||||
if (mainKeyboard && mainKeyboard.layout_names) {
|
|
||||||
hyprlandLayoutCount = mainKeyboard.layout_names.length
|
|
||||||
} else {
|
|
||||||
hyprlandLayoutCount = 0
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
hyprlandCurrentLayout = ""
|
|
||||||
hyprlandLayoutCount = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: hyprlandLayoutUpdateTimer
|
|
||||||
interval: 1000
|
|
||||||
running: false
|
|
||||||
repeat: true
|
|
||||||
onTriggered: updateHyprlandLayout()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
@@ -236,21 +180,93 @@ Item {
|
|||||||
spacing: Theme.spacingL
|
spacing: Theme.spacingL
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
DankCircularImage {
|
Item {
|
||||||
|
id: avatarContainer
|
||||||
|
|
||||||
|
property bool hasImage: profileImageLoader.status === Image.Ready
|
||||||
|
|
||||||
Layout.preferredWidth: 60
|
Layout.preferredWidth: 60
|
||||||
Layout.preferredHeight: 60
|
Layout.preferredHeight: 60
|
||||||
imageSource: {
|
|
||||||
if (PortalService.profileImage === "") {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PortalService.profileImage.startsWith("/")) {
|
Rectangle {
|
||||||
return "file://" + PortalService.profileImage
|
anchors.fill: parent
|
||||||
}
|
radius: width / 2
|
||||||
|
color: "transparent"
|
||||||
return PortalService.profileImage
|
border.color: Theme.primary
|
||||||
|
border.width: 1
|
||||||
|
visible: parent.hasImage
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: profileImageLoader
|
||||||
|
|
||||||
|
source: {
|
||||||
|
if (PortalService.profileImage === "") {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PortalService.profileImage.startsWith("/")) {
|
||||||
|
return "file://" + PortalService.profileImage
|
||||||
|
}
|
||||||
|
|
||||||
|
return PortalService.profileImage
|
||||||
|
}
|
||||||
|
smooth: true
|
||||||
|
asynchronous: true
|
||||||
|
mipmap: true
|
||||||
|
cache: true
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiEffect {
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: 5
|
||||||
|
source: profileImageLoader
|
||||||
|
maskEnabled: true
|
||||||
|
maskSource: circularMask
|
||||||
|
visible: avatarContainer.hasImage
|
||||||
|
maskThresholdMin: 0.5
|
||||||
|
maskSpreadAtMin: 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: circularMask
|
||||||
|
|
||||||
|
width: 60 - 10
|
||||||
|
height: 60 - 10
|
||||||
|
layer.enabled: true
|
||||||
|
layer.smooth: true
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: width / 2
|
||||||
|
color: "black"
|
||||||
|
antialiasing: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: width / 2
|
||||||
|
color: Theme.primary
|
||||||
|
visible: !parent.hasImage
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "person"
|
||||||
|
size: Theme.iconSize + 4
|
||||||
|
color: Theme.primaryText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: "warning"
|
||||||
|
size: Theme.iconSize + 4
|
||||||
|
color: Theme.primaryText
|
||||||
|
visible: PortalService.profileImage !== "" && profileImageLoader.status === Image.Error
|
||||||
}
|
}
|
||||||
fallbackIcon: "person"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -578,7 +594,7 @@ Item {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: 20
|
Layout.preferredHeight: root.pamState ? 20 : 0
|
||||||
text: {
|
text: {
|
||||||
if (root.pamState === "error") {
|
if (root.pamState === "error") {
|
||||||
return "Authentication error - try again"
|
return "Authentication error - try again"
|
||||||
@@ -594,6 +610,7 @@ Item {
|
|||||||
color: Theme.error
|
color: Theme.error
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
visible: root.pamState !== ""
|
||||||
opacity: root.pamState !== "" ? 1 : 0
|
opacity: root.pamState !== "" ? 1 : 0
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
@@ -602,6 +619,13 @@ Item {
|
|||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on Layout.preferredHeight {
|
||||||
|
NumberAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,92 +646,6 @@ Item {
|
|||||||
anchors.margins: Theme.spacingXL
|
anchors.margins: Theme.spacingXL
|
||||||
spacing: Theme.spacingL
|
spacing: Theme.spacingL
|
||||||
|
|
||||||
Item {
|
|
||||||
width: keyboardLayoutRow.width
|
|
||||||
height: keyboardLayoutRow.height
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: {
|
|
||||||
if (CompositorService.isNiri) {
|
|
||||||
return NiriService.keyboardLayoutNames.length > 1
|
|
||||||
} else if (CompositorService.isHyprland) {
|
|
||||||
return hyprlandLayoutCount > 1
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
|
||||||
id: keyboardLayoutRow
|
|
||||||
spacing: 4
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: Theme.iconSize
|
|
||||||
height: Theme.iconSize
|
|
||||||
|
|
||||||
DankIcon {
|
|
||||||
name: "keyboard"
|
|
||||||
size: Theme.iconSize
|
|
||||||
color: "white"
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
width: childrenRect.width
|
|
||||||
height: Theme.iconSize
|
|
||||||
|
|
||||||
StyledText {
|
|
||||||
text: {
|
|
||||||
if (CompositorService.isNiri) {
|
|
||||||
const layout = NiriService.getCurrentKeyboardLayoutName()
|
|
||||||
if (!layout) return ""
|
|
||||||
const parts = layout.split(" ")
|
|
||||||
if (parts.length > 0) {
|
|
||||||
return parts[0].substring(0, 2).toUpperCase()
|
|
||||||
}
|
|
||||||
return layout.substring(0, 2).toUpperCase()
|
|
||||||
} else if (CompositorService.isHyprland) {
|
|
||||||
return hyprlandCurrentLayout
|
|
||||||
}
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
|
||||||
font.weight: Font.Light
|
|
||||||
color: "white"
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: keyboardLayoutArea
|
|
||||||
anchors.fill: parent
|
|
||||||
enabled: !demoMode
|
|
||||||
hoverEnabled: enabled
|
|
||||||
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
|
|
||||||
onClicked: {
|
|
||||||
if (CompositorService.isNiri) {
|
|
||||||
NiriService.cycleKeyboardLayout()
|
|
||||||
} else if (CompositorService.isHyprland) {
|
|
||||||
Quickshell.execDetached([
|
|
||||||
"hyprctl",
|
|
||||||
"switchxkblayout",
|
|
||||||
hyprlandKeyboard,
|
|
||||||
"next"
|
|
||||||
])
|
|
||||||
updateHyprlandLayout()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: 1
|
|
||||||
height: 24
|
|
||||||
color: Qt.rgba(255, 255, 255, 0.2)
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
visible: MprisController.activePlayer
|
|
||||||
}
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: MprisController.activePlayer
|
visible: MprisController.activePlayer
|
||||||
@@ -1172,8 +1110,6 @@ Item {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log("Authentication failed:", res)
|
console.log("Authentication failed:", res)
|
||||||
passwordField.text = ""
|
|
||||||
root.passwordBuffer = ""
|
|
||||||
if (res === PamResult.Error)
|
if (res === PamResult.Error)
|
||||||
root.pamState = "error"
|
root.pamState = "error"
|
||||||
else if (res === PamResult.MaxTries)
|
else if (res === PamResult.MaxTries)
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ Item {
|
|||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
id: fontDropdown
|
id: fontDropdown
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.leftMargin: -Theme.spacingM
|
anchors.leftMargin: -Theme.spacingM
|
||||||
width: parent.width + Theme.spacingM
|
width: parent.width + Theme.spacingM
|
||||||
text: "Font Family"
|
text: "Font Family"
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ Column {
|
|||||||
width: calculatedWidth
|
width: calculatedWidth
|
||||||
height: 32
|
height: 32
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: isActive ? Theme.primaryPressed : isHovered ? Theme.primaryHoverLight : Theme.withAlpha(Theme.primaryPressed, 0)
|
color: isActive ? Theme.primaryPressed : isHovered ? Theme.primaryHoverLight : "transparent"
|
||||||
border.width: isActive ? 0 : 1
|
border.width: isActive ? 0 : 1
|
||||||
border.color: Theme.outlineMedium
|
border.color: Theme.outlineMedium
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ Column {
|
|||||||
width: 20
|
width: 20
|
||||||
height: 20
|
height: 20
|
||||||
radius: 10
|
radius: 10
|
||||||
color: closeMouseArea.containsMouse ? Theme.surfaceTextHover : Theme.withAlpha(Theme.surfaceTextHover, 0)
|
color: closeMouseArea.containsMouse ? Theme.surfaceTextHover : "transparent"
|
||||||
visible: NotepadStorageService.tabs.length > 1
|
visible: NotepadStorageService.tabs.length > 1
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,12 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on border.color {
|
Behavior on border.color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
@@ -44,12 +50,12 @@ Rectangle {
|
|||||||
|
|
||||||
color: {
|
color: {
|
||||||
if (isGroupSelected && keyboardNavigationActive) {
|
if (isGroupSelected && keyboardNavigationActive) {
|
||||||
return Theme.primaryPressed
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.2)
|
||||||
}
|
}
|
||||||
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
if (keyboardNavigationActive && expanded && selectedNotificationIndex >= 0) {
|
||||||
return Theme.primaryHoverLight
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.12)
|
||||||
}
|
}
|
||||||
return Theme.surfaceContainerHigh
|
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.1)
|
||||||
}
|
}
|
||||||
border.color: {
|
border.color: {
|
||||||
if (isGroupSelected && keyboardNavigationActive) {
|
if (isGroupSelected && keyboardNavigationActive) {
|
||||||
@@ -344,10 +350,16 @@ Rectangle {
|
|||||||
return baseHeight
|
return baseHeight
|
||||||
}
|
}
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: isSelected ? Theme.primaryPressed : Theme.surfaceContainerHigh
|
color: isSelected ? Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.25) : "transparent"
|
||||||
border.color: isSelected ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05)
|
border.color: isSelected ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.4) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.05)
|
||||||
border.width: isSelected ? 1 : 1
|
border.width: isSelected ? 1 : 1
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Behavior on border.color {
|
Behavior on border.color {
|
||||||
ColorAnimation {
|
ColorAnimation {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ DankPopout {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool notificationHistoryVisible: false
|
property bool notificationHistoryVisible: false
|
||||||
|
property string triggerSection: "right"
|
||||||
property var triggerScreen: null
|
property var triggerScreen: null
|
||||||
|
|
||||||
NotificationKeyboardController {
|
NotificationKeyboardController {
|
||||||
@@ -34,10 +35,10 @@ DankPopout {
|
|||||||
|
|
||||||
popupWidth: 400
|
popupWidth: 400
|
||||||
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 400
|
popupHeight: contentLoader.item ? contentLoader.item.implicitHeight : 400
|
||||||
triggerX: 0
|
triggerX: Screen.width - 400 - Theme.spacingL
|
||||||
triggerY: 0
|
triggerY: Theme.barHeight - 4 + SettingsData.topBarSpacing + Theme.spacingXS
|
||||||
triggerWidth: 40
|
triggerWidth: 40
|
||||||
positioning: ""
|
positioning: "center"
|
||||||
screen: triggerScreen
|
screen: triggerScreen
|
||||||
shouldBeVisible: notificationHistoryVisible
|
shouldBeVisible: notificationHistoryVisible
|
||||||
visible: shouldBeVisible
|
visible: shouldBeVisible
|
||||||
@@ -116,7 +117,7 @@ DankPopout {
|
|||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: 0
|
border.width: 1
|
||||||
focus: true
|
focus: true
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ Item {
|
|||||||
height: 28
|
height: 28
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
visible: NotificationService.notifications.length > 0
|
visible: NotificationService.notifications.length > 0
|
||||||
color: clearArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceContainerHigh
|
color: clearArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.3)
|
||||||
|
border.color: clearArea.containsMouse ? Theme.primary : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
@@ -137,6 +139,19 @@ Item {
|
|||||||
onClicked: NotificationService.clearAllNotifications()
|
onClicked: NotificationService.clearAllNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on border.color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -411,78 +411,6 @@ QtObject {
|
|||||||
selectPrevious()
|
selectPrevious()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
}
|
}
|
||||||
} else if (event.key === Qt.Key_N && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!keyboardNavigationActive) {
|
|
||||||
keyboardNavigationActive = true
|
|
||||||
rebuildFlatNavigation()
|
|
||||||
selectedFlatIndex = 0
|
|
||||||
updateSelectedIdFromIndex()
|
|
||||||
if (listView) {
|
|
||||||
listView.keyboardActive = true
|
|
||||||
}
|
|
||||||
selectionVersion++
|
|
||||||
ensureVisible()
|
|
||||||
} else {
|
|
||||||
selectNext()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_P && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!keyboardNavigationActive) {
|
|
||||||
keyboardNavigationActive = true
|
|
||||||
rebuildFlatNavigation()
|
|
||||||
selectedFlatIndex = 0
|
|
||||||
updateSelectedIdFromIndex()
|
|
||||||
if (listView) {
|
|
||||||
listView.keyboardActive = true
|
|
||||||
}
|
|
||||||
selectionVersion++
|
|
||||||
ensureVisible()
|
|
||||||
} else if (selectedFlatIndex === 0) {
|
|
||||||
keyboardNavigationActive = false
|
|
||||||
if (listView) {
|
|
||||||
listView.keyboardActive = false
|
|
||||||
}
|
|
||||||
selectionVersion++
|
|
||||||
} else {
|
|
||||||
selectPrevious()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_J && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!keyboardNavigationActive) {
|
|
||||||
keyboardNavigationActive = true
|
|
||||||
rebuildFlatNavigation()
|
|
||||||
selectedFlatIndex = 0
|
|
||||||
updateSelectedIdFromIndex()
|
|
||||||
if (listView) {
|
|
||||||
listView.keyboardActive = true
|
|
||||||
}
|
|
||||||
selectionVersion++
|
|
||||||
ensureVisible()
|
|
||||||
} else {
|
|
||||||
selectNext()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_K && event.modifiers & Qt.ControlModifier) {
|
|
||||||
if (!keyboardNavigationActive) {
|
|
||||||
keyboardNavigationActive = true
|
|
||||||
rebuildFlatNavigation()
|
|
||||||
selectedFlatIndex = 0
|
|
||||||
updateSelectedIdFromIndex()
|
|
||||||
if (listView) {
|
|
||||||
listView.keyboardActive = true
|
|
||||||
}
|
|
||||||
selectionVersion++
|
|
||||||
ensureVisible()
|
|
||||||
} else if (selectedFlatIndex === 0) {
|
|
||||||
keyboardNavigationActive = false
|
|
||||||
if (listView) {
|
|
||||||
listView.keyboardActive = false
|
|
||||||
}
|
|
||||||
selectionVersion++
|
|
||||||
} else {
|
|
||||||
selectPrevious()
|
|
||||||
}
|
|
||||||
event.accepted = true
|
|
||||||
} else if (keyboardNavigationActive) {
|
} else if (keyboardNavigationActive) {
|
||||||
if (event.key === Qt.Key_Space) {
|
if (event.key === Qt.Key_Space) {
|
||||||
toggleGroupExpanded()
|
toggleGroupExpanded()
|
||||||
@@ -497,10 +425,7 @@ QtObject {
|
|||||||
clearSelected()
|
clearSelected()
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key === Qt.Key_Tab) {
|
} else if (event.key === Qt.Key_Tab) {
|
||||||
selectNext()
|
selectNextWrapping()
|
||||||
event.accepted = true
|
|
||||||
} else if (event.key === Qt.Key_Backtab) {
|
|
||||||
selectPrevious()
|
|
||||||
event.accepted = true
|
event.accepted = true
|
||||||
} else if (event.key >= Qt.Key_1 && event.key <= Qt.Key_9) {
|
} else if (event.key >= Qt.Key_1 && event.key <= Qt.Key_9) {
|
||||||
const actionIndex = event.key - Qt.Key_1
|
const actionIndex = event.key - Qt.Key_1
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
|
width: parent.width
|
||||||
text: "Low Priority"
|
text: "Low Priority"
|
||||||
description: "Timeout for low priority notifications"
|
description: "Timeout for low priority notifications"
|
||||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutLow)
|
currentValue: getTimeoutText(SettingsData.notificationTimeoutLow)
|
||||||
@@ -172,6 +173,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
|
width: parent.width
|
||||||
text: "Normal Priority"
|
text: "Normal Priority"
|
||||||
description: "Timeout for normal priority notifications"
|
description: "Timeout for normal priority notifications"
|
||||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal)
|
currentValue: getTimeoutText(SettingsData.notificationTimeoutNormal)
|
||||||
@@ -187,6 +189,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DankDropdown {
|
DankDropdown {
|
||||||
|
width: parent.width
|
||||||
text: "Critical Priority"
|
text: "Critical Priority"
|
||||||
description: "Timeout for critical priority notifications"
|
description: "Timeout for critical priority notifications"
|
||||||
currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical)
|
currentValue: getTimeoutText(SettingsData.notificationTimeoutCritical)
|
||||||
|
|||||||
@@ -76,6 +76,7 @@ PanelWindow {
|
|||||||
color: "transparent"
|
color: "transparent"
|
||||||
implicitWidth: 400
|
implicitWidth: 400
|
||||||
implicitHeight: 122
|
implicitHeight: 122
|
||||||
|
onScreenYChanged: margins.top = Theme.barHeight - 4 + SettingsData.topBarSpacing + 4 + screenY
|
||||||
onHasValidDataChanged: {
|
onHasValidDataChanged: {
|
||||||
if (!hasValidData && !exiting && !_isDestroying) {
|
if (!hasValidData && !exiting && !_isDestroying) {
|
||||||
forceExit()
|
forceExit()
|
||||||
@@ -107,94 +108,14 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
property bool isTopCenter: SettingsData.notificationPopupPosition === -1
|
anchors {
|
||||||
|
top: true
|
||||||
anchors.top: isTopCenter || SettingsData.notificationPopupPosition === SettingsData.Position.Top || SettingsData.notificationPopupPosition === SettingsData.Position.Left
|
right: true
|
||||||
anchors.bottom: SettingsData.notificationPopupPosition === SettingsData.Position.Bottom || SettingsData.notificationPopupPosition === SettingsData.Position.Right
|
}
|
||||||
anchors.left: SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
|
|
||||||
anchors.right: SettingsData.notificationPopupPosition === SettingsData.Position.Top || SettingsData.notificationPopupPosition === SettingsData.Position.Right
|
|
||||||
|
|
||||||
margins {
|
margins {
|
||||||
top: getTopMargin()
|
top: Theme.barHeight - 4 + SettingsData.topBarSpacing + 4
|
||||||
bottom: getBottomMargin()
|
right: 12
|
||||||
left: getLeftMargin()
|
|
||||||
right: getRightMargin()
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTopMargin() {
|
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
|
||||||
const barPos = SettingsData.dankBarPosition
|
|
||||||
const isTop = isTopCenter || popupPos === SettingsData.Position.Top || popupPos === SettingsData.Position.Left
|
|
||||||
|
|
||||||
if (!isTop) return 0
|
|
||||||
|
|
||||||
const effectiveBarThickness = Math.max(26 + SettingsData.dankBarInnerPadding * 0.6 + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
|
|
||||||
const exclusiveZone = effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap
|
|
||||||
|
|
||||||
let base = Theme.popupDistance
|
|
||||||
if (barPos === SettingsData.Position.Top) {
|
|
||||||
base = exclusiveZone
|
|
||||||
}
|
|
||||||
|
|
||||||
return base + screenY
|
|
||||||
}
|
|
||||||
|
|
||||||
function getBottomMargin() {
|
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
|
||||||
const barPos = SettingsData.dankBarPosition
|
|
||||||
const isBottom = popupPos === SettingsData.Position.Bottom || popupPos === SettingsData.Position.Right
|
|
||||||
|
|
||||||
if (!isBottom) return 0
|
|
||||||
|
|
||||||
const effectiveBarThickness = Math.max(26 + SettingsData.dankBarInnerPadding * 0.6 + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
|
|
||||||
const exclusiveZone = effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap
|
|
||||||
|
|
||||||
let base = Theme.popupDistance
|
|
||||||
if (barPos === SettingsData.Position.Bottom) {
|
|
||||||
base = exclusiveZone
|
|
||||||
}
|
|
||||||
|
|
||||||
return base + screenY
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLeftMargin() {
|
|
||||||
if (isTopCenter) {
|
|
||||||
return (screen.width - implicitWidth) / 2
|
|
||||||
}
|
|
||||||
|
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
|
||||||
const barPos = SettingsData.dankBarPosition
|
|
||||||
const isLeft = popupPos === SettingsData.Position.Left || popupPos === SettingsData.Position.Bottom
|
|
||||||
|
|
||||||
if (!isLeft) return 0
|
|
||||||
|
|
||||||
const effectiveBarThickness = Math.max(26 + SettingsData.dankBarInnerPadding * 0.6 + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
|
|
||||||
const exclusiveZone = effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap
|
|
||||||
|
|
||||||
if (barPos === SettingsData.Position.Left) {
|
|
||||||
return exclusiveZone
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.popupDistance
|
|
||||||
}
|
|
||||||
|
|
||||||
function getRightMargin() {
|
|
||||||
if (isTopCenter) return 0
|
|
||||||
|
|
||||||
const popupPos = SettingsData.notificationPopupPosition
|
|
||||||
const barPos = SettingsData.dankBarPosition
|
|
||||||
const isRight = popupPos === SettingsData.Position.Top || popupPos === SettingsData.Position.Right
|
|
||||||
|
|
||||||
if (!isRight) return 0
|
|
||||||
|
|
||||||
const effectiveBarThickness = Math.max(26 + SettingsData.dankBarInnerPadding * 0.6 + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
|
|
||||||
const exclusiveZone = effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap
|
|
||||||
|
|
||||||
if (barPos === SettingsData.Position.Right) {
|
|
||||||
return exclusiveZone
|
|
||||||
}
|
|
||||||
|
|
||||||
return Theme.popupDistance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -202,7 +123,7 @@ PanelWindow {
|
|||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: win.hasValidData
|
visible: win.hasValidData
|
||||||
layer.enabled: true
|
layer.enabled: (enterX.running || exitAnim.running)
|
||||||
layer.smooth: true
|
layer.smooth: true
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -213,7 +134,7 @@ PanelWindow {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.popupBackground()
|
color: Theme.popupBackground()
|
||||||
border.color: notificationData && notificationData.urgency === NotificationUrgency.Critical ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
border.color: notificationData && notificationData.urgency === NotificationUrgency.Critical ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.3) : Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
|
||||||
border.width: notificationData && notificationData.urgency === NotificationUrgency.Critical ? 2 : 0
|
border.width: notificationData && notificationData.urgency === NotificationUrgency.Critical ? 2 : 1
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -534,12 +455,7 @@ PanelWindow {
|
|||||||
transform: Translate {
|
transform: Translate {
|
||||||
id: tx
|
id: tx
|
||||||
|
|
||||||
x: {
|
x: Anims.slidePx
|
||||||
if (isTopCenter) return 0
|
|
||||||
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
|
|
||||||
return isLeft ? -Anims.slidePx : Anims.slidePx
|
|
||||||
}
|
|
||||||
y: isTopCenter ? -Anims.slidePx : 0
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -547,23 +463,15 @@ PanelWindow {
|
|||||||
id: enterX
|
id: enterX
|
||||||
|
|
||||||
target: tx
|
target: tx
|
||||||
property: isTopCenter ? "y" : "x"
|
property: "x"
|
||||||
from: {
|
from: Anims.slidePx
|
||||||
if (isTopCenter) return -Anims.slidePx
|
|
||||||
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
|
|
||||||
return isLeft ? -Anims.slidePx : Anims.slidePx
|
|
||||||
}
|
|
||||||
to: 0
|
to: 0
|
||||||
duration: Anims.durMed
|
duration: Anims.durMed
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
easing.bezierCurve: isTopCenter ? Anims.standardDecel : Anims.emphasizedDecel
|
easing.bezierCurve: Anims.emphasizedDecel
|
||||||
onStopped: {
|
onStopped: {
|
||||||
if (!win.exiting && !win._isDestroying) {
|
if (!win.exiting && !win._isDestroying && Math.abs(tx.x) < 0.5) {
|
||||||
if (isTopCenter) {
|
win.entered()
|
||||||
if (Math.abs(tx.y) < 0.5) win.entered()
|
|
||||||
} else {
|
|
||||||
if (Math.abs(tx.x) < 0.5) win.entered()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -575,13 +483,9 @@ PanelWindow {
|
|||||||
|
|
||||||
PropertyAnimation {
|
PropertyAnimation {
|
||||||
target: tx
|
target: tx
|
||||||
property: isTopCenter ? "y" : "x"
|
property: "x"
|
||||||
from: 0
|
from: 0
|
||||||
to: {
|
to: Anims.slidePx
|
||||||
if (isTopCenter) return -Anims.slidePx
|
|
||||||
const isLeft = SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom
|
|
||||||
return isLeft ? -Anims.slidePx : Anims.slidePx
|
|
||||||
}
|
|
||||||
duration: Anims.durShort
|
duration: Anims.durShort
|
||||||
easing.type: Easing.BezierSpline
|
easing.type: Easing.BezierSpline
|
||||||
easing.bezierCurve: Anims.emphasizedAccel
|
easing.bezierCurve: Anims.emphasizedAccel
|
||||||
|
|||||||
@@ -12,24 +12,12 @@ DankOSD {
|
|||||||
enableMouseInteraction: true
|
enableMouseInteraction: true
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: AudioService.sink && AudioService.sink.audio ? AudioService.sink.audio : null
|
target: AudioService
|
||||||
|
|
||||||
function onVolumeChanged() {
|
function onVolumeChanged() {
|
||||||
if (!AudioService.suppressOSD) {
|
root.show()
|
||||||
root.show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onMutedChanged() {
|
|
||||||
if (!AudioService.suppressOSD) {
|
|
||||||
root.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: AudioService
|
|
||||||
|
|
||||||
function onSinkChanged() {
|
function onSinkChanged() {
|
||||||
if (root.shouldBeVisible) {
|
if (root.shouldBeVisible) {
|
||||||
root.show()
|
root.show()
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
import QtQuick
|
|
||||||
import qs.Common
|
|
||||||
import qs.Services
|
|
||||||
import qs.Widgets
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
property var axis: null
|
|
||||||
property string section: "center"
|
|
||||||
property var popoutTarget: null
|
|
||||||
property var parentScreen: null
|
|
||||||
property real widgetThickness: 30
|
|
||||||
property real barThickness: 48
|
|
||||||
property bool isVerticalOrientation: false
|
|
||||||
property alias content: contentLoader.sourceComponent
|
|
||||||
|
|
||||||
readonly property real horizontalPadding: SettingsData.dankBarNoBackground ? 0 : Math.max(Theme.spacingXS, Theme.spacingS * (widgetThickness / 30))
|
|
||||||
|
|
||||||
signal clicked()
|
|
||||||
|
|
||||||
width: isVerticalOrientation ? widgetThickness : contentLoader.item ? (contentLoader.item.implicitWidth + horizontalPadding * 2) : 0
|
|
||||||
height: isVerticalOrientation ? (contentLoader.item ? (contentLoader.item.implicitHeight + horizontalPadding * 2) : 0) : widgetThickness
|
|
||||||
radius: SettingsData.dankBarNoBackground ? 0 : Theme.cornerRadius
|
|
||||||
color: {
|
|
||||||
if (SettingsData.dankBarNoBackground) {
|
|
||||||
return "transparent"
|
|
||||||
}
|
|
||||||
|
|
||||||
const baseColor = mouseArea.containsMouse ? Theme.widgetBaseHoverColor : Theme.widgetBaseBackgroundColor
|
|
||||||
return Qt.rgba(baseColor.r, baseColor.g, baseColor.b, baseColor.a * Theme.widgetTransparency)
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
id: contentLoader
|
|
||||||
anchors.centerIn: parent
|
|
||||||
}
|
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: mouseArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
onPressed: {
|
|
||||||
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
|
||||||
const globalPos = mapToGlobal(0, 0)
|
|
||||||
const currentScreen = parentScreen || Screen
|
|
||||||
const pos = SettingsData.getPopupTriggerPosition(globalPos, currentScreen, barThickness, width)
|
|
||||||
popoutTarget.setTriggerPosition(pos.x, pos.y, pos.width, section, currentScreen)
|
|
||||||
}
|
|
||||||
root.clicked()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user