mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-24 13:32:50 -05:00
Compare commits
15 Commits
972fc534a4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03cfa55e0b | ||
|
|
a887e60f40 | ||
|
|
816819bf9f | ||
|
|
78f3bb3812 | ||
|
|
01d7ed5dd8 | ||
|
|
50311db280 | ||
|
|
01b1a276c5 | ||
|
|
6d4c31492c | ||
|
|
f8c5f07e9f | ||
|
|
11e23feb0e | ||
|
|
b4ba2dac37 | ||
|
|
d013c3b718 | ||
|
|
b3ea28c5c4 | ||
|
|
775b381987 | ||
|
|
3a41f2f1ed |
@@ -6,6 +6,8 @@ This file is more of a quick reference so I know what to account for before next
|
|||||||
- dbus API for plugins, KDEConnect
|
- dbus API for plugins, KDEConnect
|
||||||
- new dank16 algorithm
|
- new dank16 algorithm
|
||||||
- launcher actions, customize env, args, name, icon
|
- launcher actions, customize env, args, name, icon
|
||||||
|
- launcher v2 - omega stuff, GIF search, supa powerful
|
||||||
|
- dock on bar
|
||||||
|
|
||||||
# 1.2.0
|
# 1.2.0
|
||||||
|
|
||||||
|
|||||||
@@ -91,6 +91,9 @@ bind = SUPER CTRL, up, movetoworkspace, e-1
|
|||||||
bind = SUPER CTRL, U, movetoworkspace, e+1
|
bind = SUPER CTRL, U, movetoworkspace, e+1
|
||||||
bind = SUPER CTRL, I, movetoworkspace, e-1
|
bind = SUPER CTRL, I, movetoworkspace, e-1
|
||||||
|
|
||||||
|
# === Workspace Management ===
|
||||||
|
bind = CTRL SHIFT, R, exec, dms ipc call workspace-rename open
|
||||||
|
|
||||||
# === Move Workspaces ===
|
# === Move Workspaces ===
|
||||||
bind = SUPER SHIFT, Page_Down, movetoworkspace, e+1
|
bind = SUPER SHIFT, Page_Down, movetoworkspace, e+1
|
||||||
bind = SUPER SHIFT, Page_Up, movetoworkspace, e-1
|
bind = SUPER SHIFT, Page_Up, movetoworkspace, e-1
|
||||||
|
|||||||
@@ -133,6 +133,11 @@ binds {
|
|||||||
Mod+Ctrl+U { move-column-to-workspace-down; }
|
Mod+Ctrl+U { move-column-to-workspace-down; }
|
||||||
Mod+Ctrl+I { move-column-to-workspace-up; }
|
Mod+Ctrl+I { move-column-to-workspace-up; }
|
||||||
|
|
||||||
|
// === Workspace Management ===
|
||||||
|
Ctrl+Shift+R hotkey-overlay-title="Rename Workspace" {
|
||||||
|
spawn "dms" "ipc" "call" "workspace-rename" "open";
|
||||||
|
}
|
||||||
|
|
||||||
// === Move Workspaces ===
|
// === Move Workspaces ===
|
||||||
Mod+Shift+Page_Down { move-workspace-down; }
|
Mod+Shift+Page_Down { move-workspace-down; }
|
||||||
Mod+Shift+Page_Up { move-workspace-up; }
|
Mod+Shift+Page_Up { move-workspace-up; }
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ func init() {
|
|||||||
Register("artix", "#1793D1", FamilyArch, func(config DistroConfig, logChan chan<- string) Distribution {
|
Register("artix", "#1793D1", FamilyArch, func(config DistroConfig, logChan chan<- string) Distribution {
|
||||||
return NewArchDistribution(config, logChan)
|
return NewArchDistribution(config, logChan)
|
||||||
})
|
})
|
||||||
|
Register("XeroLinux", "#888fe2", FamilyArch, func(config DistroConfig, logChan chan<- string) Distribution {
|
||||||
|
return NewArchDistribution(config, logChan)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type ArchDistribution struct {
|
type ArchDistribution struct {
|
||||||
|
|||||||
@@ -502,17 +502,17 @@ func (p *MangoWCParser) handleSource(line, baseDir string, keybinds *[]MangoWCKe
|
|||||||
p.dmsProcessed = true
|
p.dmsProcessed = true
|
||||||
}
|
}
|
||||||
|
|
||||||
fullPath := sourcePath
|
expanded, err := utils.ExpandPath(sourcePath)
|
||||||
if !filepath.IsAbs(sourcePath) {
|
|
||||||
fullPath = filepath.Join(baseDir, sourcePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
expanded, err := utils.ExpandPath(fullPath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
includedBinds, err := p.parseFileWithSource(expanded)
|
fullPath := expanded
|
||||||
|
if !filepath.IsAbs(expanded) {
|
||||||
|
fullPath = filepath.Join(baseDir, expanded)
|
||||||
|
}
|
||||||
|
|
||||||
|
includedBinds, err := p.parseFileWithSource(fullPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -521,33 +521,10 @@ func (p *MangoWCParser) handleSource(line, baseDir string, keybinds *[]MangoWCKe
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *MangoWCParser) parseDMSBindsDirectly(dmsBindsPath string) []MangoWCKeyBinding {
|
func (p *MangoWCParser) parseDMSBindsDirectly(dmsBindsPath string) []MangoWCKeyBinding {
|
||||||
data, err := os.ReadFile(dmsBindsPath)
|
keybinds, err := p.parseFileWithSource(dmsBindsPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
prevSource := p.currentSource
|
|
||||||
p.currentSource = dmsBindsPath
|
|
||||||
|
|
||||||
var keybinds []MangoWCKeyBinding
|
|
||||||
lines := strings.Split(string(data), "\n")
|
|
||||||
|
|
||||||
for lineNum, line := range lines {
|
|
||||||
trimmed := strings.TrimSpace(line)
|
|
||||||
if !strings.HasPrefix(trimmed, "bind") {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
kb := p.getKeybindAtLineContent(line, lineNum)
|
|
||||||
if kb == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
kb.Source = dmsBindsPath
|
|
||||||
p.addBind(kb)
|
|
||||||
keybinds = append(keybinds, *kb)
|
|
||||||
}
|
|
||||||
|
|
||||||
p.currentSource = prevSource
|
|
||||||
p.dmsProcessed = true
|
p.dmsProcessed = true
|
||||||
return keybinds
|
return keybinds
|
||||||
}
|
}
|
||||||
|
|||||||
6
flake.lock
generated
6
flake.lock
generated
@@ -2,11 +2,11 @@
|
|||||||
"nodes": {
|
"nodes": {
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1766651565,
|
"lastModified": 1769018530,
|
||||||
"narHash": "sha256-QEhk0eXgyIqTpJ/ehZKg9IKS7EtlWxF3N7DXy42zPfU=",
|
"narHash": "sha256-MJ27Cy2NtBEV5tsK+YraYr2g851f3Fl1LpNHDzDX15c=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "3e2499d5539c16d0d173ba53552a4ff8547f4539",
|
"rev": "88d3861acdd3d2f0e361767018218e51810df8a1",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
kirigami.unwrapped
|
kirigami.unwrapped
|
||||||
sonnet
|
sonnet
|
||||||
qtmultimedia
|
qtmultimedia
|
||||||
|
qtimageformats
|
||||||
];
|
];
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -100,7 +100,8 @@ const DMS_ACTIONS = [
|
|||||||
{ id: "spawn dms ipc call hypr openOverview", label: "Hyprland: Open Overview", compositor: "hyprland" },
|
{ id: "spawn dms ipc call hypr openOverview", label: "Hyprland: Open Overview", compositor: "hyprland" },
|
||||||
{ id: "spawn dms ipc call hypr closeOverview", label: "Hyprland: Close Overview", compositor: "hyprland" },
|
{ id: "spawn dms ipc call hypr closeOverview", label: "Hyprland: Close Overview", compositor: "hyprland" },
|
||||||
{ id: "spawn dms ipc call wallpaper next", label: "Wallpaper: Next" },
|
{ id: "spawn dms ipc call wallpaper next", label: "Wallpaper: Next" },
|
||||||
{ id: "spawn dms ipc call wallpaper prev", label: "Wallpaper: Previous" }
|
{ id: "spawn dms ipc call wallpaper prev", label: "Wallpaper: Previous" },
|
||||||
|
{ id: "spawn dms ipc call workspace-rename open", label: "Workspace: Rename" }
|
||||||
];
|
];
|
||||||
|
|
||||||
const NIRI_ACTIONS = {
|
const NIRI_ACTIONS = {
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ Singleton {
|
|||||||
|
|
||||||
property bool use24HourClock: true
|
property bool use24HourClock: true
|
||||||
property bool showSeconds: false
|
property bool showSeconds: false
|
||||||
|
property bool padHours12Hour: false
|
||||||
property bool useFahrenheit: false
|
property bool useFahrenheit: false
|
||||||
property string windSpeedUnit: "kmh"
|
property string windSpeedUnit: "kmh"
|
||||||
property bool nightModeEnabled: false
|
property bool nightModeEnabled: false
|
||||||
@@ -273,6 +274,8 @@ Singleton {
|
|||||||
property string spotlightModalViewMode: "list"
|
property string spotlightModalViewMode: "list"
|
||||||
property string browserPickerViewMode: "grid"
|
property string browserPickerViewMode: "grid"
|
||||||
property var browserUsageHistory: ({})
|
property var browserUsageHistory: ({})
|
||||||
|
property string appPickerViewMode: "grid"
|
||||||
|
property var filePickerUsageHistory: ({})
|
||||||
property bool sortAppsAlphabetically: false
|
property bool sortAppsAlphabetically: false
|
||||||
property int appLauncherGridColumns: 4
|
property int appLauncherGridColumns: 4
|
||||||
property bool spotlightCloseNiriOverview: true
|
property bool spotlightCloseNiriOverview: true
|
||||||
@@ -452,6 +455,7 @@ Singleton {
|
|||||||
property bool lockScreenShowDate: true
|
property bool lockScreenShowDate: true
|
||||||
property bool lockScreenShowProfileImage: true
|
property bool lockScreenShowProfileImage: true
|
||||||
property bool lockScreenShowPasswordField: true
|
property bool lockScreenShowPasswordField: true
|
||||||
|
property bool lockScreenShowMediaPlayer: true
|
||||||
property bool lockScreenPowerOffMonitorsOnLock: false
|
property bool lockScreenPowerOffMonitorsOnLock: false
|
||||||
|
|
||||||
property bool enableFprint: false
|
property bool enableFprint: false
|
||||||
@@ -1251,11 +1255,11 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getEffectiveTimeFormat() {
|
function getEffectiveTimeFormat() {
|
||||||
if (use24HourClock) {
|
if (use24HourClock)
|
||||||
return showSeconds ? "hh:mm:ss" : "hh:mm";
|
return showSeconds ? "hh:mm:ss" : "hh:mm";
|
||||||
} else {
|
if (padHours12Hour)
|
||||||
return showSeconds ? "h:mm:ss AP" : "h:mm AP";
|
return showSeconds ? "hh:mm:ss AP" : "hh:mm AP";
|
||||||
}
|
return showSeconds ? "h:mm:ss AP" : "h:mm AP";
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEffectiveClockDateFormat() {
|
function getEffectiveClockDateFormat() {
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ var SPEC = {
|
|||||||
|
|
||||||
use24HourClock: { def: true },
|
use24HourClock: { def: true },
|
||||||
showSeconds: { def: false },
|
showSeconds: { def: false },
|
||||||
|
padHours12Hour: { def: false },
|
||||||
useFahrenheit: { def: false },
|
useFahrenheit: { def: false },
|
||||||
windSpeedUnit: { def: "kmh" },
|
windSpeedUnit: { def: "kmh" },
|
||||||
nightModeEnabled: { def: false },
|
nightModeEnabled: { def: false },
|
||||||
@@ -132,6 +133,10 @@ var SPEC = {
|
|||||||
|
|
||||||
appLauncherViewMode: { def: "list" },
|
appLauncherViewMode: { def: "list" },
|
||||||
spotlightModalViewMode: { def: "list" },
|
spotlightModalViewMode: { def: "list" },
|
||||||
|
browserPickerViewMode: { def: "grid" },
|
||||||
|
browserUsageHistory: { def: {} },
|
||||||
|
appPickerViewMode: { def: "grid" },
|
||||||
|
filePickerUsageHistory: { def: {} },
|
||||||
sortAppsAlphabetically: { def: false },
|
sortAppsAlphabetically: { def: false },
|
||||||
appLauncherGridColumns: { def: 4 },
|
appLauncherGridColumns: { def: 4 },
|
||||||
spotlightCloseNiriOverview: { def: true },
|
spotlightCloseNiriOverview: { def: true },
|
||||||
@@ -276,6 +281,7 @@ var SPEC = {
|
|||||||
lockScreenShowDate: { def: true },
|
lockScreenShowDate: { def: true },
|
||||||
lockScreenShowProfileImage: { def: true },
|
lockScreenShowProfileImage: { def: true },
|
||||||
lockScreenShowPasswordField: { def: true },
|
lockScreenShowPasswordField: { def: true },
|
||||||
|
lockScreenShowMediaPlayer: { def: true },
|
||||||
lockScreenPowerOffMonitorsOnLock: { def: false },
|
lockScreenPowerOffMonitorsOnLock: { def: false },
|
||||||
enableFprint: { def: false },
|
enableFprint: { def: false },
|
||||||
maxFprintTries: { def: 15 },
|
maxFprintTries: { def: 15 },
|
||||||
|
|||||||
@@ -550,6 +550,11 @@ Item {
|
|||||||
AppPickerModal {
|
AppPickerModal {
|
||||||
id: filePickerModal
|
id: filePickerModal
|
||||||
title: I18n.tr("Open with...")
|
title: I18n.tr("Open with...")
|
||||||
|
viewMode: SettingsData.appPickerViewMode || "grid"
|
||||||
|
|
||||||
|
onViewModeChanged: {
|
||||||
|
SettingsData.set("appPickerViewMode", viewMode)
|
||||||
|
}
|
||||||
|
|
||||||
function shellEscape(str) {
|
function shellEscape(str) {
|
||||||
return "'" + str.replace(/'/g, "'\\''") + "'";
|
return "'" + str.replace(/'/g, "'\\''") + "'";
|
||||||
@@ -644,6 +649,18 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LazyLoader {
|
||||||
|
id: workspaceRenameModalLoader
|
||||||
|
|
||||||
|
active: false
|
||||||
|
|
||||||
|
Component.onCompleted: PopoutService.workspaceRenameModalLoader = workspaceRenameModalLoader
|
||||||
|
|
||||||
|
WorkspaceRenameModal {
|
||||||
|
id: workspaceRenameModal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LazyLoader {
|
LazyLoader {
|
||||||
id: processListModalLoader
|
id: processListModalLoader
|
||||||
|
|
||||||
@@ -769,6 +786,7 @@ Item {
|
|||||||
hyprKeybindsModalLoader: hyprKeybindsModalLoader
|
hyprKeybindsModalLoader: hyprKeybindsModalLoader
|
||||||
dankBarRepeater: dankBarRepeater
|
dankBarRepeater: dankBarRepeater
|
||||||
hyprlandOverviewLoader: hyprlandOverviewLoader
|
hyprlandOverviewLoader: hyprlandOverviewLoader
|
||||||
|
workspaceRenameModalLoader: workspaceRenameModalLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
Variants {
|
Variants {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ Item {
|
|||||||
required property var hyprKeybindsModalLoader
|
required property var hyprKeybindsModalLoader
|
||||||
required property var dankBarRepeater
|
required property var dankBarRepeater
|
||||||
required property var hyprlandOverviewLoader
|
required property var hyprlandOverviewLoader
|
||||||
|
required property var workspaceRenameModalLoader
|
||||||
|
|
||||||
function getFirstBar() {
|
function getFirstBar() {
|
||||||
if (!root.dankBarRepeater || root.dankBarRepeater.count === 0)
|
if (!root.dankBarRepeater || root.dankBarRepeater.count === 0)
|
||||||
@@ -1062,7 +1063,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleQuery(query: string): string {
|
function toggleQuery(query: string): string {
|
||||||
PopoutService.toggleDankLauncherV2();
|
PopoutService.toggleDankLauncherV2WithQuery(query);
|
||||||
return "LAUNCHER_TOGGLE_QUERY_SUCCESS";
|
return "LAUNCHER_TOGGLE_QUERY_SUCCESS";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1106,13 +1107,86 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toggleQuery(query: string): string {
|
function toggleQuery(query: string): string {
|
||||||
PopoutService.toggleDankLauncherV2();
|
PopoutService.toggleDankLauncherV2WithQuery(query);
|
||||||
return "SPOTLIGHT_TOGGLE_QUERY_SUCCESS";
|
return "SPOTLIGHT_TOGGLE_QUERY_SUCCESS";
|
||||||
}
|
}
|
||||||
|
|
||||||
target: "spotlight"
|
target: "spotlight"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
function info(message: string): string {
|
||||||
|
if (!message)
|
||||||
|
return "ERROR: No message specified";
|
||||||
|
|
||||||
|
ToastService.showInfo(message);
|
||||||
|
return "TOAST_INFO_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function infoWith(message: string, details: string, command: string, category: string): string {
|
||||||
|
if (!message)
|
||||||
|
return "ERROR: No message specified";
|
||||||
|
|
||||||
|
ToastService.showInfo(message, details, command, category);
|
||||||
|
return "TOAST_INFO_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function warn(message: string): string {
|
||||||
|
if (!message)
|
||||||
|
return "ERROR: No message specified";
|
||||||
|
|
||||||
|
ToastService.showWarning(message);
|
||||||
|
return "TOAST_WARN_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function warnWith(message: string, details: string, command: string, category: string): string {
|
||||||
|
if (!message)
|
||||||
|
return "ERROR: No message specified";
|
||||||
|
|
||||||
|
ToastService.showWarning(message, details, command, category);
|
||||||
|
return "TOAST_WARN_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function error(message: string): string {
|
||||||
|
if (!message)
|
||||||
|
return "ERROR: No message specified";
|
||||||
|
|
||||||
|
ToastService.showError(message);
|
||||||
|
return "TOAST_ERROR_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorWith(message: string, details: string, command: string, category: string): string {
|
||||||
|
if (!message)
|
||||||
|
return "ERROR: No message specified";
|
||||||
|
|
||||||
|
ToastService.showError(message, details, command, category);
|
||||||
|
return "TOAST_ERROR_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function hide(): string {
|
||||||
|
ToastService.hideToast();
|
||||||
|
return "TOAST_HIDE_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function dismiss(category: string): string {
|
||||||
|
if (!category)
|
||||||
|
return "ERROR: No category specified";
|
||||||
|
|
||||||
|
ToastService.dismissCategory(category);
|
||||||
|
return "TOAST_DISMISS_SUCCESS";
|
||||||
|
}
|
||||||
|
|
||||||
|
function status(): string {
|
||||||
|
if (!ToastService.toastVisible)
|
||||||
|
return "hidden";
|
||||||
|
|
||||||
|
const levels = ["info", "warn", "error"];
|
||||||
|
return `visible:${levels[ToastService.currentLevel]}:${ToastService.currentMessage}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
target: "toast"
|
||||||
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
function open(): string {
|
function open(): string {
|
||||||
FirstLaunchService.showWelcome();
|
FirstLaunchService.showWelcome();
|
||||||
@@ -1292,4 +1366,40 @@ Item {
|
|||||||
|
|
||||||
target: "desktopWidget"
|
target: "desktopWidget"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
function open(): string {
|
||||||
|
root.workspaceRenameModalLoader.active = true;
|
||||||
|
if (root.workspaceRenameModalLoader.item) {
|
||||||
|
const ws = NiriService.workspaces[NiriService.focusedWorkspaceId];
|
||||||
|
root.workspaceRenameModalLoader.item.show(ws?.name || "");
|
||||||
|
return "WORKSPACE_RENAME_MODAL_OPENED";
|
||||||
|
}
|
||||||
|
return "WORKSPACE_RENAME_MODAL_NOT_FOUND";
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(): string {
|
||||||
|
if (root.workspaceRenameModalLoader.item) {
|
||||||
|
root.workspaceRenameModalLoader.item.hide();
|
||||||
|
return "WORKSPACE_RENAME_MODAL_CLOSED";
|
||||||
|
}
|
||||||
|
return "WORKSPACE_RENAME_MODAL_NOT_FOUND";
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggle(): string {
|
||||||
|
root.workspaceRenameModalLoader.active = true;
|
||||||
|
if (root.workspaceRenameModalLoader.item) {
|
||||||
|
if (root.workspaceRenameModalLoader.item.visible) {
|
||||||
|
root.workspaceRenameModalLoader.item.hide();
|
||||||
|
return "WORKSPACE_RENAME_MODAL_CLOSED";
|
||||||
|
}
|
||||||
|
const ws = NiriService.workspaces[NiriService.focusedWorkspaceId];
|
||||||
|
root.workspaceRenameModalLoader.item.show(ws?.name || "");
|
||||||
|
return "WORKSPACE_RENAME_MODAL_OPENED";
|
||||||
|
}
|
||||||
|
return "WORKSPACE_RENAME_MODAL_NOT_FOUND";
|
||||||
|
}
|
||||||
|
|
||||||
|
target: "workspace-rename"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ Rectangle {
|
|||||||
result.push(selectedItem.primaryAction);
|
result.push(selectedItem.primaryAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedItem?.type === "plugin") {
|
switch (selectedItem?.type) {
|
||||||
|
case "plugin":
|
||||||
var pluginActions = getPluginContextMenuActions();
|
var pluginActions = getPluginContextMenuActions();
|
||||||
for (var i = 0; i < pluginActions.length; i++) {
|
for (var i = 0; i < pluginActions.length; i++) {
|
||||||
var act = pluginActions[i];
|
var act = pluginActions[i];
|
||||||
@@ -44,24 +45,45 @@ Rectangle {
|
|||||||
pluginAction: act.action
|
pluginAction: act.action
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (selectedItem?.type === "app" && !selectedItem?.isCore) {
|
break;
|
||||||
|
case "plugin_browse":
|
||||||
if (selectedItem?.actions) {
|
if (selectedItem?.actions) {
|
||||||
for (var i = 0; i < selectedItem.actions.length; i++) {
|
for (var i = 0; i < selectedItem.actions.length; i++) {
|
||||||
result.push(selectedItem.actions[i]);
|
result.push(selectedItem.actions[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
case "app":
|
||||||
|
if (selectedItem?.isCore)
|
||||||
|
break;
|
||||||
|
if (selectedItem?.actions) {
|
||||||
|
for (var i = 0; i < selectedItem.actions.length; i++) {
|
||||||
|
result.push(selectedItem.actions[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (SessionService.nvidiaCommand) {
|
||||||
|
result.push({
|
||||||
|
name: I18n.tr("Launch on dGPU"),
|
||||||
|
icon: "memory",
|
||||||
|
action: "launch_dgpu"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property bool hasActions: {
|
readonly property bool hasActions: {
|
||||||
if (selectedItem?.type === "app" && !selectedItem?.isCore)
|
switch (selectedItem?.type) {
|
||||||
return true;
|
case "app":
|
||||||
if (selectedItem?.type === "plugin") {
|
return !selectedItem?.isCore;
|
||||||
var pluginActions = getPluginContextMenuActions();
|
case "plugin":
|
||||||
return pluginActions.length > 0;
|
return getPluginContextMenuActions().length > 0;
|
||||||
|
case "plugin_browse":
|
||||||
|
return selectedItem?.actions?.length > 0;
|
||||||
|
default:
|
||||||
|
return actions.length > 1;
|
||||||
}
|
}
|
||||||
return actions.length > 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
width: parent?.width ?? 200
|
width: parent?.width ?? 200
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ import Quickshell.Io
|
|||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Services
|
import qs.Services
|
||||||
import "Scorer.js" as Scorer
|
import "Scorer.js" as Scorer
|
||||||
|
import "ControllerUtils.js" as Utils
|
||||||
|
import "NavigationHelpers.js" as Nav
|
||||||
|
import "ItemTransformers.js" as Transform
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: root
|
id: root
|
||||||
@@ -147,6 +150,10 @@ Item {
|
|||||||
if (sectionDefinitions[i].id === sectionId)
|
if (sectionDefinitions[i].id === sectionId)
|
||||||
return sectionDefinitions[i].defaultViewMode || "list";
|
return sectionDefinitions[i].defaultViewMode || "list";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pluginViewPreferences[sectionId]?.mode)
|
||||||
|
return pluginViewPreferences[sectionId].mode;
|
||||||
|
|
||||||
return "list";
|
return "list";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,9 +320,23 @@ Item {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function preserveSelectionAfterUpdate() {
|
||||||
|
var previousSelectedId = selectedItem?.id || "";
|
||||||
|
return function (newFlatModel) {
|
||||||
|
if (!previousSelectedId)
|
||||||
|
return getFirstItemIndex();
|
||||||
|
for (var i = 0; i < newFlatModel.length; i++) {
|
||||||
|
if (!newFlatModel[i].isHeader && newFlatModel[i].item?.id === previousSelectedId)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return getFirstItemIndex();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
function performSearch() {
|
function performSearch() {
|
||||||
var currentVersion = _searchVersion;
|
var currentVersion = _searchVersion;
|
||||||
isSearching = true;
|
isSearching = true;
|
||||||
|
var restoreSelection = preserveSelectionAfterUpdate();
|
||||||
|
|
||||||
var cachedSections = AppSearchService.getCachedDefaultSections();
|
var cachedSections = AppSearchService.getCachedDefaultSections();
|
||||||
if (cachedSections && !searchQuery && searchMode === "all" && !pluginFilter) {
|
if (cachedSections && !searchQuery && searchMode === "all" && !pluginFilter) {
|
||||||
@@ -331,7 +352,7 @@ Item {
|
|||||||
return copy;
|
return copy;
|
||||||
});
|
});
|
||||||
flatModel = Scorer.flattenSections(sections);
|
flatModel = Scorer.flattenSections(sections);
|
||||||
selectedFlatIndex = getFirstItemIndex();
|
selectedFlatIndex = restoreSelection(flatModel);
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
isSearching = false;
|
isSearching = false;
|
||||||
searchCompleted();
|
searchCompleted();
|
||||||
@@ -370,7 +391,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flatModel = Scorer.flattenSections(sections);
|
flatModel = Scorer.flattenSections(sections);
|
||||||
selectedFlatIndex = getFirstItemIndex();
|
selectedFlatIndex = restoreSelection(flatModel);
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
|
|
||||||
isSearching = false;
|
isSearching = false;
|
||||||
@@ -409,7 +430,7 @@ Item {
|
|||||||
return copy;
|
return copy;
|
||||||
});
|
});
|
||||||
flatModel = Scorer.flattenSections(sections);
|
flatModel = Scorer.flattenSections(sections);
|
||||||
selectedFlatIndex = getFirstItemIndex();
|
selectedFlatIndex = restoreSelection(flatModel);
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
isSearching = false;
|
isSearching = false;
|
||||||
searchCompleted();
|
searchCompleted();
|
||||||
@@ -434,7 +455,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flatModel = Scorer.flattenSections(sections);
|
flatModel = Scorer.flattenSections(sections);
|
||||||
selectedFlatIndex = getFirstItemIndex();
|
selectedFlatIndex = restoreSelection(flatModel);
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
|
|
||||||
isSearching = false;
|
isSearching = false;
|
||||||
@@ -489,7 +510,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flatModel = Scorer.flattenSections(sections);
|
flatModel = Scorer.flattenSections(sections);
|
||||||
selectedFlatIndex = getFirstItemIndex();
|
selectedFlatIndex = restoreSelection(flatModel);
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
|
|
||||||
isSearching = false;
|
isSearching = false;
|
||||||
@@ -573,7 +594,7 @@ Item {
|
|||||||
AppSearchService.setCachedDefaultSections(sections, flatModel);
|
AppSearchService.setCachedDefaultSections(sections, flatModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedFlatIndex = getFirstItemIndex();
|
selectedFlatIndex = restoreSelection(flatModel);
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
|
|
||||||
isSearching = false;
|
isSearching = false;
|
||||||
@@ -674,249 +695,26 @@ Item {
|
|||||||
function transformApp(app) {
|
function transformApp(app) {
|
||||||
var appId = app.id || app.execString || app.exec || "";
|
var appId = app.id || app.execString || app.exec || "";
|
||||||
var override = SessionData.getAppOverride(appId);
|
var override = SessionData.getAppOverride(appId);
|
||||||
|
return Transform.transformApp(app, override, [], I18n.tr("Launch"));
|
||||||
var actions = [];
|
|
||||||
if (app.actions && app.actions.length > 0) {
|
|
||||||
for (var i = 0; i < app.actions.length; i++) {
|
|
||||||
actions.push({
|
|
||||||
name: app.actions[i].name,
|
|
||||||
icon: "play_arrow",
|
|
||||||
actionData: app.actions[i]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SessionService.nvidiaCommand) {
|
|
||||||
actions.push({
|
|
||||||
name: I18n.tr("Launch on dGPU"),
|
|
||||||
icon: "memory",
|
|
||||||
action: "launch_dgpu"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: appId,
|
|
||||||
type: "app",
|
|
||||||
name: override?.name || app.name || "",
|
|
||||||
subtitle: override?.comment || app.comment || "",
|
|
||||||
icon: override?.icon || app.icon || "application-x-executable",
|
|
||||||
iconType: "image",
|
|
||||||
section: "apps",
|
|
||||||
data: app,
|
|
||||||
keywords: app.keywords || [],
|
|
||||||
actions: actions,
|
|
||||||
primaryAction: {
|
|
||||||
name: I18n.tr("Launch"),
|
|
||||||
icon: "open_in_new",
|
|
||||||
action: "launch"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformCoreApp(app) {
|
function transformCoreApp(app) {
|
||||||
var iconName = "apps";
|
return Transform.transformCoreApp(app, I18n.tr("Open"));
|
||||||
var iconType = "material";
|
|
||||||
|
|
||||||
if (app.icon) {
|
|
||||||
if (app.icon.startsWith("svg+corner:")) {
|
|
||||||
iconType = "composite";
|
|
||||||
} else if (app.icon.startsWith("material:")) {
|
|
||||||
iconName = app.icon.substring(9);
|
|
||||||
} else {
|
|
||||||
iconName = app.icon;
|
|
||||||
iconType = "image";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: app.builtInPluginId || app.action || "",
|
|
||||||
type: "app",
|
|
||||||
name: app.name || "",
|
|
||||||
subtitle: app.comment || "",
|
|
||||||
icon: iconName,
|
|
||||||
iconType: iconType,
|
|
||||||
iconFull: app.icon,
|
|
||||||
section: "apps",
|
|
||||||
data: app,
|
|
||||||
isCore: true,
|
|
||||||
actions: [],
|
|
||||||
primaryAction: {
|
|
||||||
name: I18n.tr("Open"),
|
|
||||||
icon: "open_in_new",
|
|
||||||
action: "launch"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformBuiltInLauncherItem(item, pluginId) {
|
function transformBuiltInLauncherItem(item, pluginId) {
|
||||||
var rawIcon = item.icon || "extension";
|
return Transform.transformBuiltInLauncherItem(item, pluginId, I18n.tr("Open"));
|
||||||
var icon = stripIconPrefix(rawIcon);
|
|
||||||
var iconType = item.iconType;
|
|
||||||
if (!iconType) {
|
|
||||||
if (rawIcon.startsWith("material:"))
|
|
||||||
iconType = "material";
|
|
||||||
else if (rawIcon.startsWith("unicode:"))
|
|
||||||
iconType = "unicode";
|
|
||||||
else
|
|
||||||
iconType = "image";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: item.action || "",
|
|
||||||
type: "plugin",
|
|
||||||
name: item.name || "",
|
|
||||||
subtitle: item.comment || "",
|
|
||||||
icon: icon,
|
|
||||||
iconType: iconType,
|
|
||||||
section: "plugin_" + pluginId,
|
|
||||||
data: item,
|
|
||||||
pluginId: pluginId,
|
|
||||||
isBuiltInLauncher: true,
|
|
||||||
keywords: item.keywords || [],
|
|
||||||
actions: [],
|
|
||||||
primaryAction: {
|
|
||||||
name: I18n.tr("Open"),
|
|
||||||
icon: "open_in_new",
|
|
||||||
action: "execute"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function transformFileResult(file) {
|
function transformFileResult(file) {
|
||||||
var filename = file.path ? file.path.split("/").pop() : "";
|
return Transform.transformFileResult(file, I18n.tr("Open"), I18n.tr("Open folder"), I18n.tr("Copy path"));
|
||||||
var dirname = file.path ? file.path.substring(0, file.path.lastIndexOf("/")) : "";
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: file.path || "",
|
|
||||||
type: "file",
|
|
||||||
name: filename,
|
|
||||||
subtitle: dirname,
|
|
||||||
icon: getFileIcon(filename),
|
|
||||||
iconType: "material",
|
|
||||||
section: "files",
|
|
||||||
data: file,
|
|
||||||
actions: [
|
|
||||||
{
|
|
||||||
name: I18n.tr("Open folder"),
|
|
||||||
icon: "folder_open",
|
|
||||||
action: "open_folder"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: I18n.tr("Copy path"),
|
|
||||||
icon: "content_copy",
|
|
||||||
action: "copy_path"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
primaryAction: {
|
|
||||||
name: I18n.tr("Open"),
|
|
||||||
icon: "open_in_new",
|
|
||||||
action: "open"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getFileIcon(filename) {
|
|
||||||
var ext = filename.lastIndexOf(".") > 0 ? filename.substring(filename.lastIndexOf(".") + 1).toLowerCase() : "";
|
|
||||||
|
|
||||||
var iconMap = {
|
|
||||||
"pdf": "picture_as_pdf",
|
|
||||||
"doc": "description",
|
|
||||||
"docx": "description",
|
|
||||||
"odt": "description",
|
|
||||||
"xls": "table_chart",
|
|
||||||
"xlsx": "table_chart",
|
|
||||||
"ods": "table_chart",
|
|
||||||
"ppt": "slideshow",
|
|
||||||
"pptx": "slideshow",
|
|
||||||
"odp": "slideshow",
|
|
||||||
"txt": "article",
|
|
||||||
"md": "article",
|
|
||||||
"rst": "article",
|
|
||||||
"jpg": "image",
|
|
||||||
"jpeg": "image",
|
|
||||||
"png": "image",
|
|
||||||
"gif": "image",
|
|
||||||
"svg": "image",
|
|
||||||
"webp": "image",
|
|
||||||
"mp3": "audio_file",
|
|
||||||
"wav": "audio_file",
|
|
||||||
"flac": "audio_file",
|
|
||||||
"ogg": "audio_file",
|
|
||||||
"mp4": "video_file",
|
|
||||||
"mkv": "video_file",
|
|
||||||
"avi": "video_file",
|
|
||||||
"webm": "video_file",
|
|
||||||
"zip": "folder_zip",
|
|
||||||
"tar": "folder_zip",
|
|
||||||
"gz": "folder_zip",
|
|
||||||
"7z": "folder_zip",
|
|
||||||
"rar": "folder_zip",
|
|
||||||
"js": "code",
|
|
||||||
"ts": "code",
|
|
||||||
"py": "code",
|
|
||||||
"rs": "code",
|
|
||||||
"go": "code",
|
|
||||||
"java": "code",
|
|
||||||
"c": "code",
|
|
||||||
"cpp": "code",
|
|
||||||
"h": "code",
|
|
||||||
"html": "web",
|
|
||||||
"css": "web",
|
|
||||||
"htm": "web",
|
|
||||||
"json": "data_object",
|
|
||||||
"xml": "data_object",
|
|
||||||
"yaml": "data_object",
|
|
||||||
"yml": "data_object",
|
|
||||||
"sh": "terminal",
|
|
||||||
"bash": "terminal",
|
|
||||||
"zsh": "terminal"
|
|
||||||
};
|
|
||||||
|
|
||||||
return iconMap[ext] || "insert_drive_file";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function evaluateCalculator(query) {
|
function evaluateCalculator(query) {
|
||||||
if (!query || query.length === 0)
|
var calc = Utils.evaluateCalculator(query);
|
||||||
|
if (!calc)
|
||||||
return null;
|
return null;
|
||||||
|
return Transform.createCalculatorItem(calc, query, I18n.tr("Copy"));
|
||||||
var mathExpr = query.replace(/[^0-9+\-*/().%\s^]/g, "");
|
|
||||||
if (mathExpr.length < 2)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
var hasMath = /[+\-*/^%]/.test(query) && /\d/.test(query);
|
|
||||||
if (!hasMath)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
var sanitized = mathExpr.replace(/\^/g, "**");
|
|
||||||
var result = Function('"use strict"; return (' + sanitized + ')')();
|
|
||||||
|
|
||||||
if (typeof result === "number" && isFinite(result)) {
|
|
||||||
var displayResult = Number.isInteger(result) ? result.toString() : result.toFixed(6).replace(/\.?0+$/, "");
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: "calculator_result",
|
|
||||||
type: "calculator",
|
|
||||||
name: displayResult,
|
|
||||||
subtitle: query + " =",
|
|
||||||
icon: "calculate",
|
|
||||||
iconType: "material",
|
|
||||||
section: "calculator",
|
|
||||||
data: {
|
|
||||||
expression: query,
|
|
||||||
result: result
|
|
||||||
},
|
|
||||||
actions: [],
|
|
||||||
primaryAction: {
|
|
||||||
name: I18n.tr("Copy"),
|
|
||||||
icon: "content_copy",
|
|
||||||
action: "copy"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectTrigger(query) {
|
function detectTrigger(query) {
|
||||||
@@ -988,17 +786,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sortPluginIdsByOrder(pluginIds) {
|
function sortPluginIdsByOrder(pluginIds) {
|
||||||
var order = SettingsData.launcherPluginOrder || [];
|
return Utils.sortPluginIdsByOrder(pluginIds, SettingsData.launcherPluginOrder || []);
|
||||||
if (order.length === 0)
|
|
||||||
return pluginIds;
|
|
||||||
var orderMap = {};
|
|
||||||
for (var i = 0; i < order.length; i++)
|
|
||||||
orderMap[order[i]] = i;
|
|
||||||
return pluginIds.slice().sort(function (a, b) {
|
|
||||||
var aOrder = orderMap[a] !== undefined ? orderMap[a] : 9999;
|
|
||||||
var bOrder = orderMap[b] !== undefined ? orderMap[b] : 9999;
|
|
||||||
return aOrder - bOrder;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getAllVisiblePluginsOrdered() {
|
function getAllVisiblePluginsOrdered() {
|
||||||
@@ -1019,17 +807,7 @@ Item {
|
|||||||
isBuiltIn: true
|
isBuiltIn: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var order = SettingsData.launcherPluginOrder || [];
|
return Utils.sortPluginsOrdered(all, SettingsData.launcherPluginOrder || []);
|
||||||
if (order.length === 0)
|
|
||||||
return all;
|
|
||||||
var orderMap = {};
|
|
||||||
for (var i = 0; i < order.length; i++)
|
|
||||||
orderMap[order[i]] = i;
|
|
||||||
return all.sort(function (a, b) {
|
|
||||||
var aOrder = orderMap[a.id] !== undefined ? orderMap[a.id] : 9999;
|
|
||||||
var bOrder = orderMap[b.id] !== undefined ? orderMap[b.id] : 9999;
|
|
||||||
return aOrder - bOrder;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getEmptyTriggerPluginsOrdered() {
|
function getEmptyTriggerPluginsOrdered() {
|
||||||
@@ -1052,72 +830,27 @@ Item {
|
|||||||
isBuiltIn: true
|
isBuiltIn: true
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
var order = SettingsData.launcherPluginOrder || [];
|
return Utils.sortPluginsOrdered(all, SettingsData.launcherPluginOrder || []);
|
||||||
if (order.length === 0)
|
|
||||||
return all;
|
|
||||||
var orderMap = {};
|
|
||||||
for (var i = 0; i < order.length; i++)
|
|
||||||
orderMap[order[i]] = i;
|
|
||||||
return all.sort(function (a, b) {
|
|
||||||
var aOrder = orderMap[a.id] !== undefined ? orderMap[a.id] : 9999;
|
|
||||||
var bOrder = orderMap[b.id] !== undefined ? orderMap[b.id] : 9999;
|
|
||||||
return aOrder - bOrder;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPluginBrowseItems() {
|
function getPluginBrowseItems() {
|
||||||
var items = [];
|
var items = [];
|
||||||
|
var browseLabel = I18n.tr("Browse");
|
||||||
|
var triggerLabel = I18n.tr("Trigger: %1");
|
||||||
|
var noTriggerLabel = I18n.tr("No trigger");
|
||||||
|
|
||||||
var launchers = PluginService.getLauncherPlugins();
|
var launchers = PluginService.getLauncherPlugins();
|
||||||
for (var pluginId in launchers) {
|
for (var pluginId in launchers) {
|
||||||
var plugin = launchers[pluginId];
|
|
||||||
var trigger = PluginService.getPluginTrigger(pluginId);
|
var trigger = PluginService.getPluginTrigger(pluginId);
|
||||||
var rawIcon = plugin.icon || "extension";
|
var isAllowed = SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||||
items.push({
|
items.push(Transform.createPluginBrowseItem(pluginId, launchers[pluginId], trigger, false, isAllowed, browseLabel, triggerLabel, noTriggerLabel));
|
||||||
id: "browse_" + pluginId,
|
|
||||||
type: "plugin_browse",
|
|
||||||
name: plugin.name || pluginId,
|
|
||||||
subtitle: trigger ? I18n.tr("Trigger: %1").arg(trigger) : I18n.tr("No trigger"),
|
|
||||||
icon: stripIconPrefix(rawIcon),
|
|
||||||
iconType: detectIconType(rawIcon),
|
|
||||||
section: "browse_plugins",
|
|
||||||
data: {
|
|
||||||
pluginId: pluginId,
|
|
||||||
plugin: plugin
|
|
||||||
},
|
|
||||||
actions: [],
|
|
||||||
primaryAction: {
|
|
||||||
name: I18n.tr("Browse"),
|
|
||||||
icon: "arrow_forward",
|
|
||||||
action: "browse_plugin"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var builtInLaunchers = AppSearchService.getBuiltInLauncherPlugins();
|
var builtInLaunchers = AppSearchService.getBuiltInLauncherPlugins();
|
||||||
for (var pluginId in builtInLaunchers) {
|
for (var pluginId in builtInLaunchers) {
|
||||||
var plugin = builtInLaunchers[pluginId];
|
|
||||||
var trigger = AppSearchService.getBuiltInPluginTrigger(pluginId);
|
var trigger = AppSearchService.getBuiltInPluginTrigger(pluginId);
|
||||||
items.push({
|
var isAllowed = SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||||
id: "browse_" + pluginId,
|
items.push(Transform.createPluginBrowseItem(pluginId, builtInLaunchers[pluginId], trigger, true, isAllowed, browseLabel, triggerLabel, noTriggerLabel));
|
||||||
type: "plugin_browse",
|
|
||||||
name: plugin.name || pluginId,
|
|
||||||
subtitle: trigger ? I18n.tr("Trigger: %1").arg(trigger) : I18n.tr("No trigger"),
|
|
||||||
icon: plugin.cornerIcon || "extension",
|
|
||||||
iconType: "material",
|
|
||||||
section: "browse_plugins",
|
|
||||||
data: {
|
|
||||||
pluginId: pluginId,
|
|
||||||
plugin: plugin,
|
|
||||||
isBuiltIn: true
|
|
||||||
},
|
|
||||||
actions: [],
|
|
||||||
primaryAction: {
|
|
||||||
name: I18n.tr("Browse"),
|
|
||||||
icon: "arrow_forward",
|
|
||||||
action: "browse_plugin"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
@@ -1142,34 +875,6 @@ Item {
|
|||||||
return transformed;
|
return transformed;
|
||||||
}
|
}
|
||||||
|
|
||||||
function detectIconType(iconName) {
|
|
||||||
if (!iconName)
|
|
||||||
return "material";
|
|
||||||
if (iconName.startsWith("unicode:"))
|
|
||||||
return "unicode";
|
|
||||||
if (iconName.startsWith("material:"))
|
|
||||||
return "material";
|
|
||||||
if (iconName.startsWith("image:"))
|
|
||||||
return "image";
|
|
||||||
if (iconName.indexOf("/") >= 0 || iconName.indexOf(".") >= 0)
|
|
||||||
return "image";
|
|
||||||
if (/^[a-z]+-[a-z]/.test(iconName.toLowerCase()))
|
|
||||||
return "image";
|
|
||||||
return "material";
|
|
||||||
}
|
|
||||||
|
|
||||||
function stripIconPrefix(iconName) {
|
|
||||||
if (!iconName)
|
|
||||||
return "extension";
|
|
||||||
if (iconName.startsWith("unicode:"))
|
|
||||||
return iconName.substring(8);
|
|
||||||
if (iconName.startsWith("material:"))
|
|
||||||
return iconName.substring(9);
|
|
||||||
if (iconName.startsWith("image:"))
|
|
||||||
return iconName.substring(6);
|
|
||||||
return iconName;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getPluginName(pluginId, isBuiltIn) {
|
function getPluginName(pluginId, isBuiltIn) {
|
||||||
if (isBuiltIn) {
|
if (isBuiltIn) {
|
||||||
var plugin = AppSearchService.builtInPlugins[pluginId];
|
var plugin = AppSearchService.builtInPlugins[pluginId];
|
||||||
@@ -1195,7 +900,7 @@ Item {
|
|||||||
var rawIcon = launchers[pluginId].icon || "extension";
|
var rawIcon = launchers[pluginId].icon || "extension";
|
||||||
return {
|
return {
|
||||||
name: launchers[pluginId].name || pluginId,
|
name: launchers[pluginId].name || pluginId,
|
||||||
icon: stripIconPrefix(rawIcon)
|
icon: Utils.stripIconPrefix(rawIcon)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
@@ -1227,9 +932,8 @@ Item {
|
|||||||
defaultViewMode: viewPref.mode || "list"
|
defaultViewMode: viewPref.mode || "list"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (viewPref.enforced) {
|
if (viewPref.mode)
|
||||||
setPluginViewPreference(section, viewPref.mode, true);
|
setPluginViewPreference(section, viewPref.mode, viewPref.enforced);
|
||||||
}
|
|
||||||
|
|
||||||
basePriority += 0.01;
|
basePriority += 0.01;
|
||||||
}
|
}
|
||||||
@@ -1265,36 +969,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function transformPluginItem(item, pluginId) {
|
function transformPluginItem(item, pluginId) {
|
||||||
var rawIcon = item.icon || "extension";
|
return Transform.transformPluginItem(item, pluginId, I18n.tr("Select"));
|
||||||
var icon = stripIconPrefix(rawIcon);
|
|
||||||
var iconType = item.iconType;
|
|
||||||
if (!iconType) {
|
|
||||||
if (rawIcon.startsWith("material:"))
|
|
||||||
iconType = "material";
|
|
||||||
else if (rawIcon.startsWith("unicode:"))
|
|
||||||
iconType = "unicode";
|
|
||||||
else
|
|
||||||
iconType = "image";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: item.id || item.name || "",
|
|
||||||
type: "plugin",
|
|
||||||
name: item.name || "",
|
|
||||||
subtitle: item.comment || item.description || "",
|
|
||||||
icon: icon,
|
|
||||||
iconType: iconType,
|
|
||||||
section: "plugin_" + pluginId,
|
|
||||||
data: item,
|
|
||||||
pluginId: pluginId,
|
|
||||||
keywords: item.keywords || [],
|
|
||||||
actions: item.actions || [],
|
|
||||||
primaryAction: item.primaryAction || {
|
|
||||||
name: I18n.tr("Select"),
|
|
||||||
icon: "check",
|
|
||||||
action: "execute"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFrecencyForItem(item) {
|
function getFrecencyForItem(item) {
|
||||||
@@ -1320,11 +995,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFirstItemIndex() {
|
function getFirstItemIndex() {
|
||||||
for (var i = 0; i < flatModel.length; i++) {
|
return Nav.getFirstItemIndex(flatModel);
|
||||||
if (!flatModel[i].isHeader)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateSelectedItem() {
|
function updateSelectedItem() {
|
||||||
@@ -1345,266 +1016,67 @@ Item {
|
|||||||
return getSectionViewMode(entry.sectionId);
|
return getSectionViewMode(entry.sectionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function findNextNonHeaderIndex(startIndex) {
|
|
||||||
for (var i = startIndex; i < flatModel.length; i++) {
|
|
||||||
if (!flatModel[i].isHeader)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function findPrevNonHeaderIndex(startIndex) {
|
|
||||||
for (var i = startIndex; i >= 0; i--) {
|
|
||||||
if (!flatModel[i].isHeader)
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSectionBounds(sectionId) {
|
|
||||||
var start = -1, end = -1;
|
|
||||||
for (var i = 0; i < flatModel.length; i++) {
|
|
||||||
if (flatModel[i].isHeader && flatModel[i].section?.id === sectionId) {
|
|
||||||
start = i + 1;
|
|
||||||
} else if (start >= 0 && !flatModel[i].isHeader && flatModel[i].sectionId === sectionId) {
|
|
||||||
end = i;
|
|
||||||
} else if (start >= 0 && end >= 0 && flatModel[i].sectionId !== sectionId) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
start: start,
|
|
||||||
end: end,
|
|
||||||
count: end >= start ? end - start + 1 : 0
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function getGridColumns(sectionId) {
|
function getGridColumns(sectionId) {
|
||||||
var mode = getSectionViewMode(sectionId);
|
return Nav.getGridColumns(getSectionViewMode(sectionId), gridColumns);
|
||||||
if (mode === "tile")
|
|
||||||
return 3;
|
|
||||||
if (mode === "grid")
|
|
||||||
return gridColumns;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectNext() {
|
function selectNext() {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
if (flatModel.length === 0)
|
var newIndex = Nav.calculateNextIndex(flatModel, selectedFlatIndex, null, null, gridColumns, getSectionViewMode);
|
||||||
return;
|
if (newIndex !== selectedFlatIndex) {
|
||||||
var entry = flatModel[selectedFlatIndex];
|
selectedFlatIndex = newIndex;
|
||||||
if (!entry || entry.isHeader) {
|
|
||||||
var next = findNextNonHeaderIndex(selectedFlatIndex + 1);
|
|
||||||
if (next !== -1) {
|
|
||||||
selectedFlatIndex = next;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewMode = getSectionViewMode(entry.sectionId);
|
|
||||||
if (viewMode === "list") {
|
|
||||||
var next = findNextNonHeaderIndex(selectedFlatIndex + 1);
|
|
||||||
if (next !== -1) {
|
|
||||||
selectedFlatIndex = next;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bounds = getSectionBounds(entry.sectionId);
|
|
||||||
var cols = getGridColumns(entry.sectionId);
|
|
||||||
var posInSection = selectedFlatIndex - bounds.start;
|
|
||||||
var newPosInSection = posInSection + cols;
|
|
||||||
|
|
||||||
if (newPosInSection < bounds.count) {
|
|
||||||
selectedFlatIndex = bounds.start + newPosInSection;
|
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
} else {
|
|
||||||
var nextSection = findNextNonHeaderIndex(bounds.end + 1);
|
|
||||||
if (nextSection !== -1) {
|
|
||||||
selectedFlatIndex = nextSection;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPrevious() {
|
function selectPrevious() {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
if (flatModel.length === 0)
|
var newIndex = Nav.calculatePrevIndex(flatModel, selectedFlatIndex, null, null, gridColumns, getSectionViewMode);
|
||||||
return;
|
if (newIndex !== selectedFlatIndex) {
|
||||||
var entry = flatModel[selectedFlatIndex];
|
selectedFlatIndex = newIndex;
|
||||||
if (!entry || entry.isHeader) {
|
|
||||||
var prev = findPrevNonHeaderIndex(selectedFlatIndex - 1);
|
|
||||||
if (prev !== -1) {
|
|
||||||
selectedFlatIndex = prev;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewMode = getSectionViewMode(entry.sectionId);
|
|
||||||
if (viewMode === "list") {
|
|
||||||
var prev = findPrevNonHeaderIndex(selectedFlatIndex - 1);
|
|
||||||
if (prev !== -1) {
|
|
||||||
selectedFlatIndex = prev;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bounds = getSectionBounds(entry.sectionId);
|
|
||||||
var cols = getGridColumns(entry.sectionId);
|
|
||||||
var posInSection = selectedFlatIndex - bounds.start;
|
|
||||||
var newPosInSection = posInSection - cols;
|
|
||||||
|
|
||||||
if (newPosInSection >= 0) {
|
|
||||||
selectedFlatIndex = bounds.start + newPosInSection;
|
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
} else {
|
|
||||||
var prevItem = findPrevNonHeaderIndex(bounds.start - 1);
|
|
||||||
if (prevItem !== -1) {
|
|
||||||
selectedFlatIndex = prevItem;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectRight() {
|
function selectRight() {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
if (flatModel.length === 0)
|
var newIndex = Nav.calculateRightIndex(flatModel, selectedFlatIndex, getSectionViewMode);
|
||||||
return;
|
if (newIndex !== selectedFlatIndex) {
|
||||||
var entry = flatModel[selectedFlatIndex];
|
selectedFlatIndex = newIndex;
|
||||||
if (!entry || entry.isHeader) {
|
|
||||||
var next = findNextNonHeaderIndex(selectedFlatIndex + 1);
|
|
||||||
if (next !== -1) {
|
|
||||||
selectedFlatIndex = next;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewMode = getSectionViewMode(entry.sectionId);
|
|
||||||
if (viewMode === "list") {
|
|
||||||
var next = findNextNonHeaderIndex(selectedFlatIndex + 1);
|
|
||||||
if (next !== -1) {
|
|
||||||
selectedFlatIndex = next;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bounds = getSectionBounds(entry.sectionId);
|
|
||||||
var posInSection = selectedFlatIndex - bounds.start;
|
|
||||||
if (posInSection + 1 < bounds.count) {
|
|
||||||
selectedFlatIndex = bounds.start + posInSection + 1;
|
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectLeft() {
|
function selectLeft() {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
if (flatModel.length === 0)
|
var newIndex = Nav.calculateLeftIndex(flatModel, selectedFlatIndex, getSectionViewMode);
|
||||||
return;
|
if (newIndex !== selectedFlatIndex) {
|
||||||
var entry = flatModel[selectedFlatIndex];
|
selectedFlatIndex = newIndex;
|
||||||
if (!entry || entry.isHeader) {
|
|
||||||
var prev = findPrevNonHeaderIndex(selectedFlatIndex - 1);
|
|
||||||
if (prev !== -1) {
|
|
||||||
selectedFlatIndex = prev;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var viewMode = getSectionViewMode(entry.sectionId);
|
|
||||||
if (viewMode === "list") {
|
|
||||||
var prev = findPrevNonHeaderIndex(selectedFlatIndex - 1);
|
|
||||||
if (prev !== -1) {
|
|
||||||
selectedFlatIndex = prev;
|
|
||||||
updateSelectedItem();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var bounds = getSectionBounds(entry.sectionId);
|
|
||||||
var posInSection = selectedFlatIndex - bounds.start;
|
|
||||||
if (posInSection > 0) {
|
|
||||||
selectedFlatIndex = bounds.start + posInSection - 1;
|
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectNextSection() {
|
function selectNextSection() {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
var currentSection = null;
|
var newIndex = Nav.calculateNextSectionIndex(flatModel, selectedFlatIndex);
|
||||||
if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) {
|
if (newIndex !== selectedFlatIndex) {
|
||||||
currentSection = flatModel[selectedFlatIndex].sectionId;
|
selectedFlatIndex = newIndex;
|
||||||
}
|
updateSelectedItem();
|
||||||
|
|
||||||
var foundCurrent = false;
|
|
||||||
for (var i = 0; i < flatModel.length; i++) {
|
|
||||||
if (flatModel[i].isHeader) {
|
|
||||||
if (foundCurrent) {
|
|
||||||
for (var j = i + 1; j < flatModel.length; j++) {
|
|
||||||
if (!flatModel[j].isHeader) {
|
|
||||||
selectedFlatIndex = j;
|
|
||||||
updateSelectedItem();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (flatModel[i].section.id === currentSection) {
|
|
||||||
foundCurrent = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPreviousSection() {
|
function selectPreviousSection() {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
var currentSection = null;
|
var newIndex = Nav.calculatePrevSectionIndex(flatModel, selectedFlatIndex);
|
||||||
if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) {
|
if (newIndex !== selectedFlatIndex) {
|
||||||
currentSection = flatModel[selectedFlatIndex].sectionId;
|
selectedFlatIndex = newIndex;
|
||||||
}
|
updateSelectedItem();
|
||||||
|
|
||||||
var lastSectionStart = -1;
|
|
||||||
var prevSectionStart = -1;
|
|
||||||
|
|
||||||
for (var i = 0; i < flatModel.length; i++) {
|
|
||||||
if (flatModel[i].isHeader) {
|
|
||||||
if (flatModel[i].section.id === currentSection) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
prevSectionStart = lastSectionStart;
|
|
||||||
lastSectionStart = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevSectionStart >= 0) {
|
|
||||||
for (var j = prevSectionStart + 1; j < flatModel.length; j++) {
|
|
||||||
if (!flatModel[j].isHeader) {
|
|
||||||
selectedFlatIndex = j;
|
|
||||||
updateSelectedItem();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectPageDown(visibleItems) {
|
function selectPageDown(visibleItems) {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
if (flatModel.length === 0)
|
var newIndex = Nav.calculatePageDownIndex(flatModel, selectedFlatIndex, visibleItems);
|
||||||
return;
|
|
||||||
var itemsToSkip = visibleItems || 8;
|
|
||||||
var newIndex = selectedFlatIndex;
|
|
||||||
|
|
||||||
for (var i = 0; i < itemsToSkip; i++) {
|
|
||||||
var next = findNextNonHeaderIndex(newIndex + 1);
|
|
||||||
if (next === -1)
|
|
||||||
break;
|
|
||||||
newIndex = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIndex !== selectedFlatIndex) {
|
if (newIndex !== selectedFlatIndex) {
|
||||||
selectedFlatIndex = newIndex;
|
selectedFlatIndex = newIndex;
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
@@ -1613,18 +1085,7 @@ Item {
|
|||||||
|
|
||||||
function selectPageUp(visibleItems) {
|
function selectPageUp(visibleItems) {
|
||||||
keyboardNavigationActive = true;
|
keyboardNavigationActive = true;
|
||||||
if (flatModel.length === 0)
|
var newIndex = Nav.calculatePageUpIndex(flatModel, selectedFlatIndex, visibleItems);
|
||||||
return;
|
|
||||||
var itemsToSkip = visibleItems || 8;
|
|
||||||
var newIndex = selectedFlatIndex;
|
|
||||||
|
|
||||||
for (var i = 0; i < itemsToSkip; i++) {
|
|
||||||
var prev = findPrevNonHeaderIndex(newIndex - 1);
|
|
||||||
if (prev === -1)
|
|
||||||
break;
|
|
||||||
newIndex = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIndex !== selectedFlatIndex) {
|
if (newIndex !== selectedFlatIndex) {
|
||||||
selectedFlatIndex = newIndex;
|
selectedFlatIndex = newIndex;
|
||||||
updateSelectedItem();
|
updateSelectedItem();
|
||||||
@@ -1755,6 +1216,14 @@ Item {
|
|||||||
launchAppWithNvidia(item.data);
|
launchAppWithNvidia(item.data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "toggle_all_visibility":
|
||||||
|
if (item.type === "plugin_browse" && item.data?.pluginId) {
|
||||||
|
var pluginId = item.data.pluginId;
|
||||||
|
var currentState = SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||||
|
SettingsData.setPluginAllowWithoutTrigger(pluginId, !currentState);
|
||||||
|
performSearch();
|
||||||
|
}
|
||||||
|
return;
|
||||||
default:
|
default:
|
||||||
if (item.type === "app" && action.actionData) {
|
if (item.type === "app" && action.actionData) {
|
||||||
launchAppAction({
|
launchAppAction({
|
||||||
|
|||||||
157
quickshell/Modals/DankLauncherV2/ControllerUtils.js
Normal file
157
quickshell/Modals/DankLauncherV2/ControllerUtils.js
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
.pragma library
|
||||||
|
|
||||||
|
function getFileIcon(filename) {
|
||||||
|
var ext = filename.lastIndexOf(".") > 0 ? filename.substring(filename.lastIndexOf(".") + 1).toLowerCase() : "";
|
||||||
|
|
||||||
|
switch (ext) {
|
||||||
|
case "pdf":
|
||||||
|
return "picture_as_pdf";
|
||||||
|
case "doc":
|
||||||
|
case "docx":
|
||||||
|
case "odt":
|
||||||
|
return "description";
|
||||||
|
case "xls":
|
||||||
|
case "xlsx":
|
||||||
|
case "ods":
|
||||||
|
return "table_chart";
|
||||||
|
case "ppt":
|
||||||
|
case "pptx":
|
||||||
|
case "odp":
|
||||||
|
return "slideshow";
|
||||||
|
case "txt":
|
||||||
|
case "md":
|
||||||
|
case "rst":
|
||||||
|
return "article";
|
||||||
|
case "jpg":
|
||||||
|
case "jpeg":
|
||||||
|
case "png":
|
||||||
|
case "gif":
|
||||||
|
case "svg":
|
||||||
|
case "webp":
|
||||||
|
return "image";
|
||||||
|
case "mp3":
|
||||||
|
case "wav":
|
||||||
|
case "flac":
|
||||||
|
case "ogg":
|
||||||
|
return "audio_file";
|
||||||
|
case "mp4":
|
||||||
|
case "mkv":
|
||||||
|
case "avi":
|
||||||
|
case "webm":
|
||||||
|
return "video_file";
|
||||||
|
case "zip":
|
||||||
|
case "tar":
|
||||||
|
case "gz":
|
||||||
|
case "7z":
|
||||||
|
case "rar":
|
||||||
|
return "folder_zip";
|
||||||
|
case "js":
|
||||||
|
case "ts":
|
||||||
|
case "py":
|
||||||
|
case "rs":
|
||||||
|
case "go":
|
||||||
|
case "java":
|
||||||
|
case "c":
|
||||||
|
case "cpp":
|
||||||
|
case "h":
|
||||||
|
return "code";
|
||||||
|
case "html":
|
||||||
|
case "css":
|
||||||
|
case "htm":
|
||||||
|
return "web";
|
||||||
|
case "json":
|
||||||
|
case "xml":
|
||||||
|
case "yaml":
|
||||||
|
case "yml":
|
||||||
|
return "data_object";
|
||||||
|
case "sh":
|
||||||
|
case "bash":
|
||||||
|
case "zsh":
|
||||||
|
return "terminal";
|
||||||
|
default:
|
||||||
|
return "insert_drive_file";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function stripIconPrefix(iconName) {
|
||||||
|
if (!iconName)
|
||||||
|
return "extension";
|
||||||
|
if (iconName.startsWith("unicode:"))
|
||||||
|
return iconName.substring(8);
|
||||||
|
if (iconName.startsWith("material:"))
|
||||||
|
return iconName.substring(9);
|
||||||
|
if (iconName.startsWith("image:"))
|
||||||
|
return iconName.substring(6);
|
||||||
|
return iconName;
|
||||||
|
}
|
||||||
|
|
||||||
|
function detectIconType(iconName) {
|
||||||
|
if (!iconName)
|
||||||
|
return "material";
|
||||||
|
if (iconName.startsWith("unicode:"))
|
||||||
|
return "unicode";
|
||||||
|
if (iconName.startsWith("material:"))
|
||||||
|
return "material";
|
||||||
|
if (iconName.startsWith("image:"))
|
||||||
|
return "image";
|
||||||
|
if (iconName.indexOf("/") >= 0 || iconName.indexOf(".") >= 0)
|
||||||
|
return "image";
|
||||||
|
if (/^[a-z]+-[a-z]/.test(iconName.toLowerCase()))
|
||||||
|
return "image";
|
||||||
|
return "material";
|
||||||
|
}
|
||||||
|
|
||||||
|
function evaluateCalculator(query) {
|
||||||
|
if (!query || query.length === 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var mathExpr = query.replace(/[^0-9+\-*/().%\s^]/g, "");
|
||||||
|
if (mathExpr.length < 2)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var hasMath = /[+\-*/^%]/.test(query) && /\d/.test(query);
|
||||||
|
if (!hasMath)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
var sanitized = mathExpr.replace(/\^/g, "**");
|
||||||
|
var result = Function('"use strict"; return (' + sanitized + ')')();
|
||||||
|
|
||||||
|
if (typeof result === "number" && isFinite(result)) {
|
||||||
|
var displayResult = Number.isInteger(result) ? result.toString() : result.toFixed(6).replace(/\.?0+$/, "");
|
||||||
|
return {
|
||||||
|
expression: query,
|
||||||
|
result: result,
|
||||||
|
displayResult: displayResult
|
||||||
|
};
|
||||||
|
}
|
||||||
|
} catch (e) { }
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortPluginIdsByOrder(pluginIds, order) {
|
||||||
|
if (!order || order.length === 0)
|
||||||
|
return pluginIds;
|
||||||
|
var orderMap = {};
|
||||||
|
for (var i = 0; i < order.length; i++)
|
||||||
|
orderMap[order[i]] = i;
|
||||||
|
return pluginIds.slice().sort(function (a, b) {
|
||||||
|
var aOrder = orderMap[a] !== undefined ? orderMap[a] : 9999;
|
||||||
|
var bOrder = orderMap[b] !== undefined ? orderMap[b] : 9999;
|
||||||
|
return aOrder - bOrder;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortPluginsOrdered(plugins, order) {
|
||||||
|
if (!order || order.length === 0)
|
||||||
|
return plugins;
|
||||||
|
var orderMap = {};
|
||||||
|
for (var i = 0; i < order.length; i++)
|
||||||
|
orderMap[order[i]] = i;
|
||||||
|
return plugins.sort(function (a, b) {
|
||||||
|
var aOrder = orderMap[a.id] !== undefined ? orderMap[a.id] : 9999;
|
||||||
|
var bOrder = orderMap[b.id] !== undefined ? orderMap[b.id] : 9999;
|
||||||
|
return aOrder - bOrder;
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -186,6 +186,14 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleWithQuery(query) {
|
||||||
|
if (spotlightOpen) {
|
||||||
|
hide();
|
||||||
|
} else {
|
||||||
|
showWithQuery(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: closeCleanupTimer
|
id: closeCleanupTimer
|
||||||
interval: Theme.expressiveDurations.expressiveFastSpatial + 50
|
interval: Theme.expressiveDurations.expressiveFastSpatial + 50
|
||||||
|
|||||||
223
quickshell/Modals/DankLauncherV2/ItemTransformers.js
Normal file
223
quickshell/Modals/DankLauncherV2/ItemTransformers.js
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
.pragma library
|
||||||
|
|
||||||
|
.import "ControllerUtils.js" as Utils
|
||||||
|
|
||||||
|
function transformApp(app, override, defaultActions, primaryActionLabel) {
|
||||||
|
var appId = app.id || app.execString || app.exec || "";
|
||||||
|
|
||||||
|
var actions = [];
|
||||||
|
if (app.actions && app.actions.length > 0) {
|
||||||
|
for (var i = 0; i < app.actions.length; i++) {
|
||||||
|
actions.push({
|
||||||
|
name: app.actions[i].name,
|
||||||
|
icon: "play_arrow",
|
||||||
|
actionData: app.actions[i]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: appId,
|
||||||
|
type: "app",
|
||||||
|
name: override?.name || app.name || "",
|
||||||
|
subtitle: override?.comment || app.comment || "",
|
||||||
|
icon: override?.icon || app.icon || "application-x-executable",
|
||||||
|
iconType: "image",
|
||||||
|
section: "apps",
|
||||||
|
data: app,
|
||||||
|
keywords: app.keywords || [],
|
||||||
|
actions: actions,
|
||||||
|
primaryAction: {
|
||||||
|
name: primaryActionLabel,
|
||||||
|
icon: "open_in_new",
|
||||||
|
action: "launch"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformCoreApp(app, openLabel) {
|
||||||
|
var iconName = "apps";
|
||||||
|
var iconType = "material";
|
||||||
|
|
||||||
|
if (app.icon) {
|
||||||
|
if (app.icon.startsWith("svg+corner:")) {
|
||||||
|
iconType = "composite";
|
||||||
|
} else if (app.icon.startsWith("material:")) {
|
||||||
|
iconName = app.icon.substring(9);
|
||||||
|
} else {
|
||||||
|
iconName = app.icon;
|
||||||
|
iconType = "image";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: app.builtInPluginId || app.action || "",
|
||||||
|
type: "app",
|
||||||
|
name: app.name || "",
|
||||||
|
subtitle: app.comment || "",
|
||||||
|
icon: iconName,
|
||||||
|
iconType: iconType,
|
||||||
|
iconFull: app.icon,
|
||||||
|
section: "apps",
|
||||||
|
data: app,
|
||||||
|
isCore: true,
|
||||||
|
actions: [],
|
||||||
|
primaryAction: {
|
||||||
|
name: openLabel,
|
||||||
|
icon: "open_in_new",
|
||||||
|
action: "launch"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformBuiltInLauncherItem(item, pluginId, openLabel) {
|
||||||
|
var rawIcon = item.icon || "extension";
|
||||||
|
var icon = Utils.stripIconPrefix(rawIcon);
|
||||||
|
var iconType = item.iconType;
|
||||||
|
if (!iconType) {
|
||||||
|
if (rawIcon.startsWith("material:"))
|
||||||
|
iconType = "material";
|
||||||
|
else if (rawIcon.startsWith("unicode:"))
|
||||||
|
iconType = "unicode";
|
||||||
|
else
|
||||||
|
iconType = "image";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: item.action || "",
|
||||||
|
type: "plugin",
|
||||||
|
name: item.name || "",
|
||||||
|
subtitle: item.comment || "",
|
||||||
|
icon: icon,
|
||||||
|
iconType: iconType,
|
||||||
|
section: "plugin_" + pluginId,
|
||||||
|
data: item,
|
||||||
|
pluginId: pluginId,
|
||||||
|
isBuiltInLauncher: true,
|
||||||
|
keywords: item.keywords || [],
|
||||||
|
actions: [],
|
||||||
|
primaryAction: {
|
||||||
|
name: openLabel,
|
||||||
|
icon: "open_in_new",
|
||||||
|
action: "execute"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformFileResult(file, openLabel, openFolderLabel, copyPathLabel) {
|
||||||
|
var filename = file.path ? file.path.split("/").pop() : "";
|
||||||
|
var dirname = file.path ? file.path.substring(0, file.path.lastIndexOf("/")) : "";
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: file.path || "",
|
||||||
|
type: "file",
|
||||||
|
name: filename,
|
||||||
|
subtitle: dirname,
|
||||||
|
icon: Utils.getFileIcon(filename),
|
||||||
|
iconType: "material",
|
||||||
|
section: "files",
|
||||||
|
data: file,
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
name: openFolderLabel,
|
||||||
|
icon: "folder_open",
|
||||||
|
action: "open_folder"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: copyPathLabel,
|
||||||
|
icon: "content_copy",
|
||||||
|
action: "copy_path"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
primaryAction: {
|
||||||
|
name: openLabel,
|
||||||
|
icon: "open_in_new",
|
||||||
|
action: "open"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function transformPluginItem(item, pluginId, selectLabel) {
|
||||||
|
var rawIcon = item.icon || "extension";
|
||||||
|
var icon = Utils.stripIconPrefix(rawIcon);
|
||||||
|
var iconType = item.iconType;
|
||||||
|
if (!iconType) {
|
||||||
|
if (rawIcon.startsWith("material:"))
|
||||||
|
iconType = "material";
|
||||||
|
else if (rawIcon.startsWith("unicode:"))
|
||||||
|
iconType = "unicode";
|
||||||
|
else
|
||||||
|
iconType = "image";
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: item.id || item.name || "",
|
||||||
|
type: "plugin",
|
||||||
|
name: item.name || "",
|
||||||
|
subtitle: item.comment || item.description || "",
|
||||||
|
icon: icon,
|
||||||
|
iconType: iconType,
|
||||||
|
section: "plugin_" + pluginId,
|
||||||
|
data: item,
|
||||||
|
pluginId: pluginId,
|
||||||
|
keywords: item.keywords || [],
|
||||||
|
actions: item.actions || [],
|
||||||
|
primaryAction: item.primaryAction || {
|
||||||
|
name: selectLabel,
|
||||||
|
icon: "check",
|
||||||
|
action: "execute"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCalculatorItem(calc, query, copyLabel) {
|
||||||
|
return {
|
||||||
|
id: "calculator_result",
|
||||||
|
type: "calculator",
|
||||||
|
name: calc.displayResult,
|
||||||
|
subtitle: query + " =",
|
||||||
|
icon: "calculate",
|
||||||
|
iconType: "material",
|
||||||
|
section: "calculator",
|
||||||
|
data: {
|
||||||
|
expression: calc.expression,
|
||||||
|
result: calc.result
|
||||||
|
},
|
||||||
|
actions: [],
|
||||||
|
primaryAction: {
|
||||||
|
name: copyLabel,
|
||||||
|
icon: "content_copy",
|
||||||
|
action: "copy"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function createPluginBrowseItem(pluginId, plugin, trigger, isBuiltIn, isAllowed, browseLabel, triggerLabel, noTriggerLabel) {
|
||||||
|
var rawIcon = isBuiltIn ? (plugin.cornerIcon || "extension") : (plugin.icon || "extension");
|
||||||
|
return {
|
||||||
|
id: "browse_" + pluginId,
|
||||||
|
type: "plugin_browse",
|
||||||
|
name: plugin.name || pluginId,
|
||||||
|
subtitle: trigger ? triggerLabel.replace("%1", trigger) : noTriggerLabel,
|
||||||
|
icon: isBuiltIn ? rawIcon : Utils.stripIconPrefix(rawIcon),
|
||||||
|
iconType: isBuiltIn ? "material" : Utils.detectIconType(rawIcon),
|
||||||
|
section: "browse_plugins",
|
||||||
|
data: {
|
||||||
|
pluginId: pluginId,
|
||||||
|
plugin: plugin,
|
||||||
|
isBuiltIn: isBuiltIn
|
||||||
|
},
|
||||||
|
actions: [
|
||||||
|
{
|
||||||
|
name: "All",
|
||||||
|
icon: isAllowed ? "visibility" : "visibility_off",
|
||||||
|
action: "toggle_all_visibility"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
primaryAction: {
|
||||||
|
name: browseLabel,
|
||||||
|
icon: "arrow_forward",
|
||||||
|
action: "browse_plugin"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -131,6 +131,16 @@ Popup {
|
|||||||
items.push({
|
items.push({
|
||||||
type: "separator"
|
type: "separator"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (isRegularApp && SessionService.nvidiaCommand) {
|
||||||
|
items.push({
|
||||||
|
type: "item",
|
||||||
|
icon: "memory",
|
||||||
|
text: I18n.tr("Launch on dGPU"),
|
||||||
|
action: launchWithNvidia
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
items.push({
|
items.push({
|
||||||
type: "item",
|
type: "item",
|
||||||
icon: "launch",
|
icon: "launch",
|
||||||
|
|||||||
245
quickshell/Modals/DankLauncherV2/NavigationHelpers.js
Normal file
245
quickshell/Modals/DankLauncherV2/NavigationHelpers.js
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
.pragma library
|
||||||
|
|
||||||
|
function getFirstItemIndex(flatModel) {
|
||||||
|
for (var i = 0; i < flatModel.length; i++) {
|
||||||
|
if (!flatModel[i].isHeader)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findNextNonHeaderIndex(flatModel, startIndex) {
|
||||||
|
for (var i = startIndex; i < flatModel.length; i++) {
|
||||||
|
if (!flatModel[i].isHeader)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function findPrevNonHeaderIndex(flatModel, startIndex) {
|
||||||
|
for (var i = startIndex; i >= 0; i--) {
|
||||||
|
if (!flatModel[i].isHeader)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSectionBounds(flatModel, sectionId) {
|
||||||
|
var start = -1, end = -1;
|
||||||
|
for (var i = 0; i < flatModel.length; i++) {
|
||||||
|
if (flatModel[i].isHeader && flatModel[i].section?.id === sectionId) {
|
||||||
|
start = i + 1;
|
||||||
|
} else if (start >= 0 && !flatModel[i].isHeader && flatModel[i].sectionId === sectionId) {
|
||||||
|
end = i;
|
||||||
|
} else if (start >= 0 && end >= 0 && flatModel[i].sectionId !== sectionId) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
start: start,
|
||||||
|
end: end,
|
||||||
|
count: end >= start ? end - start + 1 : 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGridColumns(viewMode, gridColumns) {
|
||||||
|
switch (viewMode) {
|
||||||
|
case "tile":
|
||||||
|
return 3;
|
||||||
|
case "grid":
|
||||||
|
return gridColumns;
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateNextIndex(flatModel, selectedFlatIndex, sectionId, viewMode, gridColumns, getSectionViewModeFn) {
|
||||||
|
if (flatModel.length === 0)
|
||||||
|
return selectedFlatIndex;
|
||||||
|
|
||||||
|
var entry = flatModel[selectedFlatIndex];
|
||||||
|
if (!entry || entry.isHeader) {
|
||||||
|
var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
|
||||||
|
return next !== -1 ? next : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var actualViewMode = viewMode || getSectionViewModeFn(entry.sectionId);
|
||||||
|
if (actualViewMode === "list") {
|
||||||
|
var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
|
||||||
|
return next !== -1 ? next : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bounds = getSectionBounds(flatModel, entry.sectionId);
|
||||||
|
var cols = getGridColumns(actualViewMode, gridColumns);
|
||||||
|
var posInSection = selectedFlatIndex - bounds.start;
|
||||||
|
var newPosInSection = posInSection + cols;
|
||||||
|
|
||||||
|
if (newPosInSection < bounds.count) {
|
||||||
|
return bounds.start + newPosInSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
var nextSection = findNextNonHeaderIndex(flatModel, bounds.end + 1);
|
||||||
|
return nextSection !== -1 ? nextSection : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculatePrevIndex(flatModel, selectedFlatIndex, sectionId, viewMode, gridColumns, getSectionViewModeFn) {
|
||||||
|
if (flatModel.length === 0)
|
||||||
|
return selectedFlatIndex;
|
||||||
|
|
||||||
|
var entry = flatModel[selectedFlatIndex];
|
||||||
|
if (!entry || entry.isHeader) {
|
||||||
|
var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
|
||||||
|
return prev !== -1 ? prev : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var actualViewMode = viewMode || getSectionViewModeFn(entry.sectionId);
|
||||||
|
if (actualViewMode === "list") {
|
||||||
|
var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
|
||||||
|
return prev !== -1 ? prev : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bounds = getSectionBounds(flatModel, entry.sectionId);
|
||||||
|
var cols = getGridColumns(actualViewMode, gridColumns);
|
||||||
|
var posInSection = selectedFlatIndex - bounds.start;
|
||||||
|
var newPosInSection = posInSection - cols;
|
||||||
|
|
||||||
|
if (newPosInSection >= 0) {
|
||||||
|
return bounds.start + newPosInSection;
|
||||||
|
}
|
||||||
|
|
||||||
|
var prevItem = findPrevNonHeaderIndex(flatModel, bounds.start - 1);
|
||||||
|
return prevItem !== -1 ? prevItem : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateRightIndex(flatModel, selectedFlatIndex, getSectionViewModeFn) {
|
||||||
|
if (flatModel.length === 0)
|
||||||
|
return selectedFlatIndex;
|
||||||
|
|
||||||
|
var entry = flatModel[selectedFlatIndex];
|
||||||
|
if (!entry || entry.isHeader) {
|
||||||
|
var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
|
||||||
|
return next !== -1 ? next : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewMode = getSectionViewModeFn(entry.sectionId);
|
||||||
|
if (viewMode === "list") {
|
||||||
|
var next = findNextNonHeaderIndex(flatModel, selectedFlatIndex + 1);
|
||||||
|
return next !== -1 ? next : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bounds = getSectionBounds(flatModel, entry.sectionId);
|
||||||
|
var posInSection = selectedFlatIndex - bounds.start;
|
||||||
|
if (posInSection + 1 < bounds.count) {
|
||||||
|
return bounds.start + posInSection + 1;
|
||||||
|
}
|
||||||
|
return selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateLeftIndex(flatModel, selectedFlatIndex, getSectionViewModeFn) {
|
||||||
|
if (flatModel.length === 0)
|
||||||
|
return selectedFlatIndex;
|
||||||
|
|
||||||
|
var entry = flatModel[selectedFlatIndex];
|
||||||
|
if (!entry || entry.isHeader) {
|
||||||
|
var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
|
||||||
|
return prev !== -1 ? prev : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var viewMode = getSectionViewModeFn(entry.sectionId);
|
||||||
|
if (viewMode === "list") {
|
||||||
|
var prev = findPrevNonHeaderIndex(flatModel, selectedFlatIndex - 1);
|
||||||
|
return prev !== -1 ? prev : selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bounds = getSectionBounds(flatModel, entry.sectionId);
|
||||||
|
var posInSection = selectedFlatIndex - bounds.start;
|
||||||
|
if (posInSection > 0) {
|
||||||
|
return bounds.start + posInSection - 1;
|
||||||
|
}
|
||||||
|
return selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculateNextSectionIndex(flatModel, selectedFlatIndex) {
|
||||||
|
var currentSection = null;
|
||||||
|
if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) {
|
||||||
|
currentSection = flatModel[selectedFlatIndex].sectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
var foundCurrent = false;
|
||||||
|
for (var i = 0; i < flatModel.length; i++) {
|
||||||
|
if (flatModel[i].isHeader) {
|
||||||
|
if (foundCurrent) {
|
||||||
|
for (var j = i + 1; j < flatModel.length; j++) {
|
||||||
|
if (!flatModel[j].isHeader)
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flatModel[i].section.id === currentSection) {
|
||||||
|
foundCurrent = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculatePrevSectionIndex(flatModel, selectedFlatIndex) {
|
||||||
|
var currentSection = null;
|
||||||
|
if (selectedFlatIndex >= 0 && selectedFlatIndex < flatModel.length) {
|
||||||
|
currentSection = flatModel[selectedFlatIndex].sectionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
var lastSectionStart = -1;
|
||||||
|
var prevSectionStart = -1;
|
||||||
|
|
||||||
|
for (var i = 0; i < flatModel.length; i++) {
|
||||||
|
if (flatModel[i].isHeader) {
|
||||||
|
if (flatModel[i].section.id === currentSection) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
prevSectionStart = lastSectionStart;
|
||||||
|
lastSectionStart = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevSectionStart >= 0) {
|
||||||
|
for (var j = prevSectionStart + 1; j < flatModel.length; j++) {
|
||||||
|
if (!flatModel[j].isHeader)
|
||||||
|
return j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return selectedFlatIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculatePageDownIndex(flatModel, selectedFlatIndex, visibleItems) {
|
||||||
|
if (flatModel.length === 0)
|
||||||
|
return selectedFlatIndex;
|
||||||
|
|
||||||
|
var itemsToSkip = visibleItems || 8;
|
||||||
|
var newIndex = selectedFlatIndex;
|
||||||
|
|
||||||
|
for (var i = 0; i < itemsToSkip; i++) {
|
||||||
|
var next = findNextNonHeaderIndex(flatModel, newIndex + 1);
|
||||||
|
if (next === -1)
|
||||||
|
break;
|
||||||
|
newIndex = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calculatePageUpIndex(flatModel, selectedFlatIndex, visibleItems) {
|
||||||
|
if (flatModel.length === 0)
|
||||||
|
return selectedFlatIndex;
|
||||||
|
|
||||||
|
var itemsToSkip = visibleItems || 8;
|
||||||
|
var newIndex = selectedFlatIndex;
|
||||||
|
|
||||||
|
for (var i = 0; i < itemsToSkip; i++) {
|
||||||
|
var prev = findPrevNonHeaderIndex(flatModel, newIndex - 1);
|
||||||
|
if (prev === -1)
|
||||||
|
break;
|
||||||
|
newIndex = prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
return newIndex;
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ Rectangle {
|
|||||||
|
|
||||||
property var item: null
|
property var item: null
|
||||||
property bool isSelected: false
|
property bool isSelected: false
|
||||||
property bool isHovered: itemArea.containsMouse
|
property bool isHovered: itemArea.containsMouse || allModeToggleArea.containsMouse
|
||||||
property var controller: null
|
property var controller: null
|
||||||
property int flatIndex: -1
|
property int flatIndex: -1
|
||||||
|
|
||||||
@@ -38,6 +38,29 @@ Rectangle {
|
|||||||
color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryPressed : "transparent"
|
color: isSelected ? Theme.primaryPressed : isHovered ? Theme.primaryPressed : "transparent"
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: itemArea
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.rightMargin: root.item?.type === "plugin_browse" ? 40 : 0
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
||||||
|
|
||||||
|
onClicked: mouse => {
|
||||||
|
if (mouse.button === Qt.RightButton) {
|
||||||
|
var scenePos = mapToItem(null, mouse.x, mouse.y);
|
||||||
|
root.rightClicked(scenePos.x, scenePos.y);
|
||||||
|
} else {
|
||||||
|
root.clicked();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onPositionChanged: {
|
||||||
|
if (root.controller)
|
||||||
|
root.controller.keyboardNavigationActive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.leftMargin: Theme.spacingM
|
anchors.leftMargin: Theme.spacingM
|
||||||
@@ -86,7 +109,47 @@ Rectangle {
|
|||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
visible: root.item?.type && root.item.type !== "app"
|
id: allModeToggle
|
||||||
|
visible: root.item?.type === "plugin_browse"
|
||||||
|
width: 28
|
||||||
|
height: 28
|
||||||
|
radius: 14
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
color: allModeToggleArea.containsMouse ? Theme.surfaceHover : "transparent"
|
||||||
|
|
||||||
|
property bool isAllowed: {
|
||||||
|
if (root.item?.type !== "plugin_browse")
|
||||||
|
return false;
|
||||||
|
var pluginId = root.item?.data?.pluginId;
|
||||||
|
if (!pluginId)
|
||||||
|
return false;
|
||||||
|
SettingsData.launcherPluginVisibility;
|
||||||
|
return SettingsData.getPluginAllowWithoutTrigger(pluginId);
|
||||||
|
}
|
||||||
|
|
||||||
|
DankIcon {
|
||||||
|
anchors.centerIn: parent
|
||||||
|
name: allModeToggle.isAllowed ? "visibility" : "visibility_off"
|
||||||
|
size: 18
|
||||||
|
color: allModeToggle.isAllowed ? Theme.primary : Theme.surfaceVariantText
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: allModeToggleArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: {
|
||||||
|
var pluginId = root.item?.data?.pluginId;
|
||||||
|
if (!pluginId)
|
||||||
|
return;
|
||||||
|
SettingsData.setPluginAllowWithoutTrigger(pluginId, !allModeToggle.isAllowed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: root.item?.type && root.item.type !== "app" && root.item.type !== "plugin_browse"
|
||||||
width: typeBadge.implicitWidth + Theme.spacingS * 2
|
width: typeBadge.implicitWidth + Theme.spacingS * 2
|
||||||
height: 20
|
height: 20
|
||||||
radius: 10
|
radius: 10
|
||||||
@@ -116,27 +179,4 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
id: itemArea
|
|
||||||
anchors.fill: parent
|
|
||||||
hoverEnabled: true
|
|
||||||
cursorShape: Qt.PointingHandCursor
|
|
||||||
acceptedButtons: Qt.LeftButton | Qt.RightButton
|
|
||||||
|
|
||||||
onClicked: mouse => {
|
|
||||||
if (mouse.button === Qt.RightButton) {
|
|
||||||
var scenePos = mapToItem(null, mouse.x, mouse.y);
|
|
||||||
root.rightClicked(scenePos.x, scenePos.y);
|
|
||||||
} else {
|
|
||||||
root.clicked();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onPositionChanged: {
|
|
||||||
if (root.controller) {
|
|
||||||
root.controller.keyboardNavigationActive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const Weights = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function tokenize(text) {
|
function tokenize(text) {
|
||||||
return text.toLowerCase().trim().split(/[\s\-_]+/).filter(function(w) { return w.length > 0 })
|
return text.toLowerCase().trim().split(/[\s\-_]+/).filter(function (w) { return w.length > 0 })
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasWordBoundaryMatch(text, query) {
|
function hasWordBoundaryMatch(text, query) {
|
||||||
@@ -164,7 +164,7 @@ function scoreItems(items, query, getFrecencyFn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scored.sort(function(a, b) {
|
scored.sort(function (a, b) {
|
||||||
return b.score - a.score
|
return b.score - a.score
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ function groupBySection(scoredItems, sectionOrder, sortAlphabetically, maxPerSec
|
|||||||
var section = sections[sectionOrder[i].id]
|
var section = sections[sectionOrder[i].id]
|
||||||
if (section && section.items.length > 0) {
|
if (section && section.items.length > 0) {
|
||||||
if (sortAlphabetically && section.id === "apps") {
|
if (sortAlphabetically && section.id === "apps") {
|
||||||
section.items.sort(function(a, b) {
|
section.items.sort(function (a, b) {
|
||||||
return (a.name || "").localeCompare(b.name || "")
|
return (a.name || "").localeCompare(b.name || "")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
import qs.Widgets
|
import qs.Widgets
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -21,9 +23,22 @@ Rectangle {
|
|||||||
border.width: isSelected ? 2 : 0
|
border.width: isSelected ? 2 : 0
|
||||||
border.color: Theme.primary
|
border.color: Theme.primary
|
||||||
|
|
||||||
|
readonly property string toplevelId: item?.data?.toplevelId ?? ""
|
||||||
|
readonly property var waylandToplevel: {
|
||||||
|
if (!toplevelId || !item?.pluginId)
|
||||||
|
return null;
|
||||||
|
const pluginInstance = PluginService.pluginInstances[item.pluginId];
|
||||||
|
if (!pluginInstance?.getToplevelById)
|
||||||
|
return null;
|
||||||
|
return pluginInstance.getToplevelById(toplevelId);
|
||||||
|
}
|
||||||
|
readonly property bool hasScreencopy: waylandToplevel !== null
|
||||||
|
|
||||||
readonly property string iconValue: {
|
readonly property string iconValue: {
|
||||||
if (!item)
|
if (!item)
|
||||||
return "";
|
return "";
|
||||||
|
if (hasScreencopy)
|
||||||
|
return "";
|
||||||
var data = item.data;
|
var data = item.data;
|
||||||
if (data?.imageUrl)
|
if (data?.imageUrl)
|
||||||
return "image:" + data.imageUrl;
|
return "image:" + data.imageUrl;
|
||||||
@@ -63,12 +78,26 @@ Rectangle {
|
|||||||
color: Theme.surfaceContainerHigh
|
color: Theme.surfaceContainerHigh
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
|
ScreencopyView {
|
||||||
|
id: screencopyView
|
||||||
|
anchors.fill: parent
|
||||||
|
captureSource: root.waylandToplevel
|
||||||
|
live: root.hasScreencopy
|
||||||
|
visible: root.hasScreencopy
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: root.isHovered ? Theme.withAlpha(Theme.surfaceVariant, 0.2) : "transparent"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AppIconRenderer {
|
AppIconRenderer {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
iconValue: root.iconValue
|
iconValue: root.iconValue
|
||||||
iconSize: Math.min(parent.width, parent.height)
|
iconSize: Math.min(parent.width, parent.height)
|
||||||
fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
|
fallbackText: (root.item?.name?.length > 0) ? root.item.name.charAt(0).toUpperCase() : "?"
|
||||||
materialIconSizeAdjustment: iconSize * 0.3
|
materialIconSizeAdjustment: iconSize * 0.3
|
||||||
|
visible: !root.hasScreencopy
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -110,16 +139,26 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Rectangle {
|
||||||
|
id: attributionBadge
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.margins: Theme.spacingXS
|
anchors.margins: Theme.spacingXS
|
||||||
width: 40
|
width: root.hasScreencopy ? 28 : 40
|
||||||
height: 16
|
height: root.hasScreencopy ? 28 : 16
|
||||||
fillMode: Image.PreserveAspectFit
|
radius: root.hasScreencopy ? 14 : 4
|
||||||
source: root.item?.data?.attribution || ""
|
color: root.hasScreencopy ? Theme.surfaceContainer : "transparent"
|
||||||
visible: source !== ""
|
visible: attributionImage.status === Image.Ready
|
||||||
opacity: 0.9
|
opacity: 0.95
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: attributionImage
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: root.hasScreencopy ? 4 : 0
|
||||||
|
fillMode: Image.PreserveAspectFit
|
||||||
|
source: root.item?.data?.attribution || ""
|
||||||
|
mipmap: true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
229
quickshell/Modals/WorkspaceRenameModal.qml
Normal file
229
quickshell/Modals/WorkspaceRenameModal.qml
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
import QtQuick
|
||||||
|
import Quickshell
|
||||||
|
import Quickshell.Io
|
||||||
|
import qs.Common
|
||||||
|
import qs.Services
|
||||||
|
import qs.Widgets
|
||||||
|
|
||||||
|
FloatingWindow {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property int inputFieldHeight: Theme.fontSizeMedium + Theme.spacingL * 2
|
||||||
|
|
||||||
|
objectName: "workspaceRenameModal"
|
||||||
|
title: I18n.tr("Rename Workspace")
|
||||||
|
minimumSize: Qt.size(400, 160)
|
||||||
|
maximumSize: Qt.size(400, 160)
|
||||||
|
color: Theme.surfaceContainer
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
function show(name) {
|
||||||
|
nameInput.text = name;
|
||||||
|
visible = true;
|
||||||
|
Qt.callLater(() => nameInput.forceActiveFocus());
|
||||||
|
}
|
||||||
|
|
||||||
|
function hide() {
|
||||||
|
visible = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitAndClose() {
|
||||||
|
renameWorkspace(nameInput.text);
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
function renameWorkspace(name) {
|
||||||
|
if (CompositorService.isNiri) {
|
||||||
|
NiriService.renameWorkspace(name);
|
||||||
|
} else if (CompositorService.isHyprland) {
|
||||||
|
HyprlandService.renameWorkspace(name);
|
||||||
|
} else {
|
||||||
|
console.warn("WorkspaceRenameModal: rename not supported for this compositor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
if (visible) {
|
||||||
|
Qt.callLater(() => nameInput.forceActiveFocus());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nameInput.text = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusScope {
|
||||||
|
id: contentFocusScope
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
Keys.onEscapePressed: event => {
|
||||||
|
hide();
|
||||||
|
event.accepted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: contentCol
|
||||||
|
anchors.centerIn: parent
|
||||||
|
width: parent.width - Theme.spacingL * 2
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: contentCol.width
|
||||||
|
height: Math.max(headerText.height, buttonRow.height)
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: buttonRow.left
|
||||||
|
anchors.rightMargin: Theme.spacingM
|
||||||
|
height: parent.height
|
||||||
|
onPressed: windowControls.tryStartMove()
|
||||||
|
onDoubleClicked: windowControls.tryToggleMaximize()
|
||||||
|
}
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: headerText
|
||||||
|
text: I18n.tr("Enter a new name for this workspace")
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceTextMedium
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
width: parent.width - buttonRow.width - Theme.spacingM
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: buttonRow
|
||||||
|
anchors.right: parent.right
|
||||||
|
spacing: Theme.spacingXS
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
visible: windowControls.supported && windowControls.canMaximize
|
||||||
|
iconName: root.maximized ? "fullscreen_exit" : "fullscreen"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
onClicked: windowControls.tryToggleMaximize()
|
||||||
|
}
|
||||||
|
|
||||||
|
DankActionButton {
|
||||||
|
iconName: "close"
|
||||||
|
iconSize: Theme.iconSize - 4
|
||||||
|
iconColor: Theme.surfaceText
|
||||||
|
onClicked: hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: parent.width
|
||||||
|
height: inputFieldHeight
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: Theme.surfaceHover
|
||||||
|
border.color: nameInput.activeFocus ? Theme.primary : Theme.outlineStrong
|
||||||
|
border.width: nameInput.activeFocus ? 2 : 1
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: nameInput.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
DankTextField {
|
||||||
|
id: nameInput
|
||||||
|
|
||||||
|
anchors.fill: parent
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
textColor: Theme.surfaceText
|
||||||
|
placeholderText: I18n.tr("Workspace name")
|
||||||
|
backgroundColor: "transparent"
|
||||||
|
enabled: root.visible
|
||||||
|
onAccepted: submitAndClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: parent.width
|
||||||
|
height: 40
|
||||||
|
|
||||||
|
Row {
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
spacing: Theme.spacingM
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: Math.max(70, cancelText.contentWidth + Theme.spacingM * 2)
|
||||||
|
height: 36
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: cancelArea.containsMouse ? Theme.surfaceTextHover : "transparent"
|
||||||
|
border.color: Theme.surfaceVariantAlpha
|
||||||
|
border.width: 1
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: cancelText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: I18n.tr("Cancel")
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.surfaceText
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: cancelArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: Math.max(80, renameText.contentWidth + Theme.spacingM * 2)
|
||||||
|
height: 36
|
||||||
|
radius: Theme.cornerRadius
|
||||||
|
color: renameArea.containsMouse ? Qt.darker(Theme.primary, 1.1) : Theme.primary
|
||||||
|
|
||||||
|
StyledText {
|
||||||
|
id: renameText
|
||||||
|
anchors.centerIn: parent
|
||||||
|
text: I18n.tr("Rename")
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
color: Theme.background
|
||||||
|
font.weight: Font.Medium
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: renameArea
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
cursorShape: Qt.PointingHandCursor
|
||||||
|
onClicked: submitAndClose()
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on color {
|
||||||
|
ColorAnimation {
|
||||||
|
duration: Theme.shortDuration
|
||||||
|
easing.type: Theme.standardEasing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FloatingWindowControls {
|
||||||
|
id: windowControls
|
||||||
|
targetWindow: root
|
||||||
|
}
|
||||||
|
|
||||||
|
IpcHandler {
|
||||||
|
target: "workspace-rename"
|
||||||
|
|
||||||
|
function open(): string {
|
||||||
|
const ws = NiriService.workspaces[NiriService.focusedWorkspaceId];
|
||||||
|
show(ws?.name || "");
|
||||||
|
return "WORKSPACE_RENAME_MODAL_OPENED";
|
||||||
|
}
|
||||||
|
|
||||||
|
function close(): string {
|
||||||
|
hide();
|
||||||
|
return "WORKSPACE_RENAME_MODAL_CLOSED";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,13 +30,13 @@ BasePill {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
if (SettingsData.use24HourClock) {
|
const hours = systemClock?.date?.getHours();
|
||||||
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(0);
|
if (SettingsData.use24HourClock)
|
||||||
} else {
|
return String(hours).padStart(2, '0').charAt(0);
|
||||||
const hours = systemClock?.date?.getHours();
|
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
||||||
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
if (SettingsData.padHours12Hour)
|
||||||
return String(display).padStart(2, '0').charAt(0);
|
return String(display).padStart(2, '0').charAt(0);
|
||||||
}
|
return display >= 10 ? String(display).charAt(0) : "";
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
|
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
|
||||||
color: Theme.widgetTextColor
|
color: Theme.widgetTextColor
|
||||||
@@ -47,13 +47,13 @@ BasePill {
|
|||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
text: {
|
text: {
|
||||||
if (SettingsData.use24HourClock) {
|
const hours = systemClock?.date?.getHours();
|
||||||
return String(systemClock?.date?.getHours()).padStart(2, '0').charAt(1);
|
if (SettingsData.use24HourClock)
|
||||||
} else {
|
return String(hours).padStart(2, '0').charAt(1);
|
||||||
const hours = systemClock?.date?.getHours();
|
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
||||||
const display = hours === 0 ? 12 : hours > 12 ? hours - 12 : hours;
|
if (SettingsData.padHours12Hour)
|
||||||
return String(display).padStart(2, '0').charAt(1);
|
return String(display).padStart(2, '0').charAt(1);
|
||||||
}
|
return display >= 10 ? String(display).charAt(1) : String(display);
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
|
font.pixelSize: Theme.barTextSize(root.barThickness, root.barConfig?.fontScale)
|
||||||
color: Theme.widgetTextColor
|
color: Theme.widgetTextColor
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ Singleton {
|
|||||||
property string matugenScheme: "scheme-tonal-spot"
|
property string matugenScheme: "scheme-tonal-spot"
|
||||||
property bool use24HourClock: true
|
property bool use24HourClock: true
|
||||||
property bool showSeconds: false
|
property bool showSeconds: false
|
||||||
|
property bool padHours12Hour: false
|
||||||
property bool useFahrenheit: false
|
property bool useFahrenheit: false
|
||||||
property bool nightModeEnabled: false
|
property bool nightModeEnabled: false
|
||||||
property string weatherLocation: "New York, NY"
|
property string weatherLocation: "New York, NY"
|
||||||
@@ -39,6 +40,7 @@ Singleton {
|
|||||||
property string widgetBackgroundColor: "sch"
|
property string widgetBackgroundColor: "sch"
|
||||||
property string lockDateFormat: ""
|
property string lockDateFormat: ""
|
||||||
property bool lockScreenShowPowerActions: true
|
property bool lockScreenShowPowerActions: true
|
||||||
|
property bool lockScreenShowProfileImage: true
|
||||||
property var screenPreferences: ({})
|
property var screenPreferences: ({})
|
||||||
property int animationSpeed: 2
|
property int animationSpeed: 2
|
||||||
property string wallpaperFillMode: "Fill"
|
property string wallpaperFillMode: "Fill"
|
||||||
@@ -52,6 +54,7 @@ Singleton {
|
|||||||
matugenScheme = settings.matugenScheme !== undefined ? settings.matugenScheme : "scheme-tonal-spot";
|
matugenScheme = settings.matugenScheme !== undefined ? settings.matugenScheme : "scheme-tonal-spot";
|
||||||
use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true;
|
use24HourClock = settings.use24HourClock !== undefined ? settings.use24HourClock : true;
|
||||||
showSeconds = settings.showSeconds !== undefined ? settings.showSeconds : false;
|
showSeconds = settings.showSeconds !== undefined ? settings.showSeconds : false;
|
||||||
|
padHours12Hour = settings.padHours12Hour !== undefined ? settings.padHours12Hour : false;
|
||||||
useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false;
|
useFahrenheit = settings.useFahrenheit !== undefined ? settings.useFahrenheit : false;
|
||||||
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false;
|
nightModeEnabled = settings.nightModeEnabled !== undefined ? settings.nightModeEnabled : false;
|
||||||
weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY";
|
weatherLocation = settings.weatherLocation !== undefined ? settings.weatherLocation : "New York, NY";
|
||||||
@@ -71,6 +74,7 @@ Singleton {
|
|||||||
widgetBackgroundColor = settings.widgetBackgroundColor !== undefined ? settings.widgetBackgroundColor : "sch";
|
widgetBackgroundColor = settings.widgetBackgroundColor !== undefined ? settings.widgetBackgroundColor : "sch";
|
||||||
lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : "";
|
lockDateFormat = settings.lockDateFormat !== undefined ? settings.lockDateFormat : "";
|
||||||
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true;
|
lockScreenShowPowerActions = settings.lockScreenShowPowerActions !== undefined ? settings.lockScreenShowPowerActions : true;
|
||||||
|
lockScreenShowProfileImage = settings.lockScreenShowProfileImage !== undefined ? settings.lockScreenShowProfileImage : true;
|
||||||
screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({});
|
screenPreferences = settings.screenPreferences !== undefined ? settings.screenPreferences : ({});
|
||||||
animationSpeed = settings.animationSpeed !== undefined ? settings.animationSpeed : 2;
|
animationSpeed = settings.animationSpeed !== undefined ? settings.animationSpeed : 2;
|
||||||
wallpaperFillMode = settings.wallpaperFillMode !== undefined ? settings.wallpaperFillMode : "Fill";
|
wallpaperFillMode = settings.wallpaperFillMode !== undefined ? settings.wallpaperFillMode : "Fill";
|
||||||
@@ -88,6 +92,14 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getEffectiveTimeFormat() {
|
||||||
|
if (use24HourClock)
|
||||||
|
return showSeconds ? "hh:mm:ss" : "hh:mm";
|
||||||
|
if (padHours12Hour)
|
||||||
|
return showSeconds ? "hh:mm:ss AP" : "hh:mm AP";
|
||||||
|
return showSeconds ? "h:mm:ss AP" : "h:mm AP";
|
||||||
|
}
|
||||||
|
|
||||||
function getEffectiveLockDateFormat() {
|
function getEffectiveLockDateFormat() {
|
||||||
return lockDateFormat && lockDateFormat.length > 0 ? lockDateFormat : Locale.LongFormat;
|
return lockDateFormat && lockDateFormat.length > 0 ? lockDateFormat : Locale.LongFormat;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ Item {
|
|||||||
|
|
||||||
readonly property string xdgDataDirs: Quickshell.env("XDG_DATA_DIRS")
|
readonly property string xdgDataDirs: Quickshell.env("XDG_DATA_DIRS")
|
||||||
property string screenName: ""
|
property string screenName: ""
|
||||||
property string randomFact: ""
|
|
||||||
property string hyprlandCurrentLayout: ""
|
property string hyprlandCurrentLayout: ""
|
||||||
property string hyprlandKeyboard: ""
|
property string hyprlandKeyboard: ""
|
||||||
property int hyprlandLayoutCount: 0
|
property int hyprlandLayoutCount: 0
|
||||||
@@ -31,10 +30,6 @@ Item {
|
|||||||
|
|
||||||
signal launchRequested
|
signal launchRequested
|
||||||
|
|
||||||
function pickRandomFact() {
|
|
||||||
randomFact = Facts.getRandomFact();
|
|
||||||
}
|
|
||||||
|
|
||||||
property bool weatherInitialized: false
|
property bool weatherInitialized: false
|
||||||
|
|
||||||
function initWeatherService() {
|
function initWeatherService() {
|
||||||
@@ -58,7 +53,6 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
pickRandomFact();
|
|
||||||
initWeatherService();
|
initWeatherService();
|
||||||
|
|
||||||
if (isPrimaryScreen)
|
if (isPrimaryScreen)
|
||||||
@@ -223,7 +217,7 @@ Item {
|
|||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
||||||
property string fullTimeStr: {
|
property string fullTimeStr: {
|
||||||
const format = GreetdSettings.use24HourClock ? (GreetdSettings.showSeconds ? "HH:mm:ss" : "HH:mm") : (GreetdSettings.showSeconds ? "h:mm:ss AP" : "h:mm AP");
|
const format = GreetdSettings.getEffectiveTimeFormat();
|
||||||
return systemClock.date.toLocaleTimeString(Qt.locale(), format);
|
return systemClock.date.toLocaleTimeString(Qt.locale(), format);
|
||||||
}
|
}
|
||||||
property var timeParts: fullTimeStr.split(':')
|
property var timeParts: fullTimeStr.split(':')
|
||||||
@@ -369,6 +363,7 @@ Item {
|
|||||||
return PortalService.profileImage;
|
return PortalService.profileImage;
|
||||||
}
|
}
|
||||||
fallbackIcon: "person"
|
fallbackIcon: "person"
|
||||||
|
visible: GreetdSettings.lockScreenShowProfileImage
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -961,20 +956,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
width: Math.min(parent.width - Theme.spacingXL * 2, implicitWidth)
|
|
||||||
text: root.randomFact
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: "white"
|
|
||||||
opacity: 0.8
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
visible: root.randomFact !== ""
|
|
||||||
}
|
|
||||||
|
|
||||||
DankActionButton {
|
DankActionButton {
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ Item {
|
|||||||
property string screenName: ""
|
property string screenName: ""
|
||||||
property bool unlocking: false
|
property bool unlocking: false
|
||||||
property string pamState: ""
|
property string pamState: ""
|
||||||
property string randomFact: ""
|
|
||||||
property string hyprlandCurrentLayout: ""
|
property string hyprlandCurrentLayout: ""
|
||||||
property string hyprlandKeyboard: ""
|
property string hyprlandKeyboard: ""
|
||||||
property int hyprlandLayoutCount: 0
|
property int hyprlandLayoutCount: 0
|
||||||
@@ -41,15 +40,7 @@ Item {
|
|||||||
pamState = "";
|
pamState = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
function pickRandomFact() {
|
|
||||||
randomFact = Facts.getRandomFact();
|
|
||||||
}
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (demoMode) {
|
|
||||||
pickRandomFact();
|
|
||||||
}
|
|
||||||
|
|
||||||
WeatherService.addRef();
|
WeatherService.addRef();
|
||||||
UserInfoService.getUserInfo();
|
UserInfoService.getUserInfo();
|
||||||
|
|
||||||
@@ -61,11 +52,6 @@ Item {
|
|||||||
lockerReadyArmed = true;
|
lockerReadyArmed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
onDemoModeChanged: {
|
|
||||||
if (demoMode) {
|
|
||||||
pickRandomFact();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Component.onDestruction: {
|
Component.onDestruction: {
|
||||||
WeatherService.removeRef();
|
WeatherService.removeRef();
|
||||||
if (CompositorService.isHyprland) {
|
if (CompositorService.isHyprland) {
|
||||||
@@ -1195,12 +1181,12 @@ Item {
|
|||||||
height: 24
|
height: 24
|
||||||
color: Qt.rgba(255, 255, 255, 0.2)
|
color: Qt.rgba(255, 255, 255, 0.2)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: MprisController.activePlayer
|
visible: MprisController.activePlayer && SettingsData.lockScreenShowMediaPlayer
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
spacing: Theme.spacingS
|
spacing: Theme.spacingS
|
||||||
visible: MprisController.activePlayer
|
visible: MprisController.activePlayer && SettingsData.lockScreenShowMediaPlayer
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
@@ -1369,7 +1355,7 @@ Item {
|
|||||||
height: 24
|
height: 24
|
||||||
color: Qt.rgba(255, 255, 255, 0.2)
|
color: Qt.rgba(255, 255, 255, 0.2)
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
visible: MprisController.activePlayer && WeatherService.weather.available
|
visible: MprisController.activePlayer && SettingsData.lockScreenShowMediaPlayer && WeatherService.weather.available
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
@@ -1606,20 +1592,6 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
|
||||||
anchors.margins: Theme.spacingL
|
|
||||||
width: Math.min(parent.width - Theme.spacingXL * 2, implicitWidth)
|
|
||||||
text: root.randomFact
|
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
|
||||||
color: "white"
|
|
||||||
opacity: 0.8
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
visible: root.randomFact !== ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Pam {
|
Pam {
|
||||||
|
|||||||
@@ -42,8 +42,6 @@ DankPopout {
|
|||||||
if (!shouldBeVisible) {
|
if (!shouldBeVisible) {
|
||||||
searchText = "";
|
searchText = "";
|
||||||
expandedPid = "";
|
expandedPid = "";
|
||||||
if (processesView)
|
|
||||||
processesView.reset();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,8 +106,11 @@ DankPopout {
|
|||||||
Connections {
|
Connections {
|
||||||
target: processListPopout
|
target: processListPopout
|
||||||
function onShouldBeVisibleChanged() {
|
function onShouldBeVisibleChanged() {
|
||||||
if (processListPopout.shouldBeVisible)
|
if (processListPopout.shouldBeVisible) {
|
||||||
Qt.callLater(() => processListContent.forceActiveFocus());
|
Qt.callLater(() => processListContent.forceActiveFocus());
|
||||||
|
} else {
|
||||||
|
processesView.reset();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,14 @@ Item {
|
|||||||
onToggled: checked => SettingsData.set("lockScreenShowPasswordField", checked)
|
onToggled: checked => SettingsData.set("lockScreenShowPasswordField", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
settingKey: "lockScreenShowMediaPlayer"
|
||||||
|
tags: ["lock", "screen", "media", "player", "music", "mpris"]
|
||||||
|
text: I18n.tr("Show Media Player", "Enable media player controls on the lock screen window")
|
||||||
|
checked: SettingsData.lockScreenShowMediaPlayer
|
||||||
|
onToggled: checked => SettingsData.set("lockScreenShowMediaPlayer", checked)
|
||||||
|
}
|
||||||
|
|
||||||
SettingsDropdownRow {
|
SettingsDropdownRow {
|
||||||
settingKey: "lockScreenNotificationMode"
|
settingKey: "lockScreenNotificationMode"
|
||||||
tags: ["lock", "screen", "notification", "notifications", "privacy"]
|
tags: ["lock", "screen", "notification", "notifications", "privacy"]
|
||||||
|
|||||||
@@ -49,6 +49,17 @@ Item {
|
|||||||
checked: SettingsData.showSeconds
|
checked: SettingsData.showSeconds
|
||||||
onToggled: checked => SettingsData.set("showSeconds", checked)
|
onToggled: checked => SettingsData.set("showSeconds", checked)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
tab: "time"
|
||||||
|
tags: ["time", "12hour", "format", "padding", "leading", "zero"]
|
||||||
|
settingKey: "padHours12Hour"
|
||||||
|
text: I18n.tr("Pad Hours")
|
||||||
|
description: "02:31 PM vs 2:31 PM"
|
||||||
|
checked: SettingsData.padHours12Hour
|
||||||
|
onToggled: checked => SettingsData.set("padHours12Hour", checked)
|
||||||
|
visible: !SettingsData.use24HourClock
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
|||||||
@@ -737,4 +737,10 @@ Singleton {
|
|||||||
if (callback) callback(response);
|
if (callback) callback(response);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renameWorkspace(name, callback) {
|
||||||
|
sendRequest("extworkspace.renameWorkspace", {
|
||||||
|
"name": name
|
||||||
|
}, callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,4 +308,18 @@ decoration {
|
|||||||
reloadConfig();
|
reloadConfig();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renameWorkspace(newName) {
|
||||||
|
if (!Hyprland.focusedWorkspace)
|
||||||
|
return;
|
||||||
|
const wsId = Hyprland.focusedWorkspace.id;
|
||||||
|
if (!wsId)
|
||||||
|
return;
|
||||||
|
const fullName = wsId + " " + newName;
|
||||||
|
Proc.runCommand("hyprland-rename-ws", ["hyprctl", "dispatch", "renameworkspace", String(wsId), fullName], (output, exitCode) => {
|
||||||
|
if (exitCode !== 0) {
|
||||||
|
console.warn("HyprlandService: Failed to rename workspace:", output);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1422,6 +1422,17 @@ Singleton {
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renameWorkspace(name) {
|
||||||
|
return send({
|
||||||
|
"Action": {
|
||||||
|
"SetWorkspaceName": {
|
||||||
|
"name": name,
|
||||||
|
"workspace": null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
IpcHandler {
|
IpcHandler {
|
||||||
function screenshot(): string {
|
function screenshot(): string {
|
||||||
if (!CompositorService.isNiri) {
|
if (!CompositorService.isNiri) {
|
||||||
|
|||||||
@@ -416,6 +416,17 @@ Singleton {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleDankLauncherV2WithQuery(query: string) {
|
||||||
|
if (dankLauncherV2Modal) {
|
||||||
|
dankLauncherV2Modal.toggleWithQuery(query);
|
||||||
|
} else if (dankLauncherV2ModalLoader) {
|
||||||
|
_dankLauncherV2PendingQuery = query;
|
||||||
|
_dankLauncherV2WantsOpen = true;
|
||||||
|
_dankLauncherV2WantsToggle = false;
|
||||||
|
dankLauncherV2ModalLoader.active = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function _onDankLauncherV2ModalLoaded() {
|
function _onDankLauncherV2ModalLoaded() {
|
||||||
if (_dankLauncherV2WantsOpen) {
|
if (_dankLauncherV2WantsOpen) {
|
||||||
_dankLauncherV2WantsOpen = false;
|
_dankLauncherV2WantsOpen = false;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/**
|
/**
|
||||||
* @name dms-midnight
|
* @name midnight
|
||||||
* @description midnight-discord, generated by dms
|
* @description A dark, rounded discord theme.
|
||||||
* @author refact0r
|
* @author refact0r
|
||||||
* @version 1.6.2
|
* @version 1.6.2
|
||||||
* @invite nz87hXyvcy
|
* @invite nz87hXyvcy
|
||||||
@@ -17,13 +17,13 @@
|
|||||||
/* customize things here */
|
/* customize things here */
|
||||||
:root {
|
:root {
|
||||||
/* font, change to 'gg sans' for default discord font*/
|
/* font, change to 'gg sans' for default discord font*/
|
||||||
--font: 'figtree';
|
--font: 'gg sans';
|
||||||
|
|
||||||
/* top left corner text */
|
/* top left corner text */
|
||||||
--corner-text: 'Midnight';
|
--corner-text: 'Midnight';
|
||||||
|
|
||||||
/* color of status indicators and window controls */
|
/* color of status indicators and window controls */
|
||||||
--online-indicator: {{colors.inverse_primary.default.hex}}; /* change to #23a55a for default green */
|
--online-indicator: {{colors.inverse_primary.default.hex}}; /* change to #23a55a for default green */
|
||||||
--dnd-indicator: {{colors.error.default.hex}}; /* change to #f13f43 for default red */
|
--dnd-indicator: {{colors.error.default.hex}}; /* change to #f13f43 for default red */
|
||||||
--idle-indicator: {{colors.tertiary_container.default.hex}}; /* change to #f0b232 for default yellow */
|
--idle-indicator: {{colors.tertiary_container.default.hex}}; /* change to #f0b232 for default yellow */
|
||||||
--streaming-indicator: {{colors.on_primary.default.hex}}; /* change to #593695 for default purple */
|
--streaming-indicator: {{colors.on_primary.default.hex}}; /* change to #593695 for default purple */
|
||||||
@@ -34,11 +34,11 @@
|
|||||||
--accent-3: {{colors.primary.default.hex}}; /* accent buttons */
|
--accent-3: {{colors.primary.default.hex}}; /* accent buttons */
|
||||||
--accent-4: {{colors.surface_bright.default.hex}}; /* accent buttons when hovered */
|
--accent-4: {{colors.surface_bright.default.hex}}; /* accent buttons when hovered */
|
||||||
--accent-5: {{colors.primary_fixed_dim.default.hex}}; /* accent buttons when clicked */
|
--accent-5: {{colors.primary_fixed_dim.default.hex}}; /* accent buttons when clicked */
|
||||||
--mention: {{colors.background.default.hex}}; /* mentions & mention messages */
|
--mention: {{colors.surface.default.hex}}; /* mentions & mention messages */
|
||||||
--mention-hover: {{colors.surface_bright.default.hex}}; /* mentions & mention messages when hovered */
|
--mention-hover: {{colors.surface_bright.default.hex}}; /* mentions & mention messages when hovered */
|
||||||
|
|
||||||
/* text colors */
|
/* text colors */
|
||||||
--text-0: {{colors.background.default.hex}}; /* text on colored elements */
|
--text-0: {{colors.surface.default.hex}}; /* text on colored elements */
|
||||||
--text-1: {{colors.on_surface.default.hex}}; /* other normally white text */
|
--text-1: {{colors.on_surface.default.hex}}; /* other normally white text */
|
||||||
--text-2: {{colors.on_surface.default.hex}}; /* headings and important text */
|
--text-2: {{colors.on_surface.default.hex}}; /* headings and important text */
|
||||||
--text-3: {{colors.on_surface_variant.default.hex}}; /* normal text */
|
--text-3: {{colors.on_surface_variant.default.hex}}; /* normal text */
|
||||||
@@ -46,10 +46,10 @@
|
|||||||
--text-5: {{colors.outline.default.hex}}; /* muted channels/chats and timestamps */
|
--text-5: {{colors.outline.default.hex}}; /* muted channels/chats and timestamps */
|
||||||
|
|
||||||
/* background and dark colors */
|
/* background and dark colors */
|
||||||
--bg-1: {{colors.primary.default.hex}}; /* dark buttons when clicked */
|
--bg-1: {{colors.surface_variant.default.hex}}; /* dark buttons when clicked */
|
||||||
--bg-2: {{colors.surface_container.default.hex}}; /* dark buttons */
|
--bg-2: {{colors.surface_container_high.default.hex}}; /* dark buttons */
|
||||||
--bg-3: {{colors.surface_container_low.default.hex}}; /* spacing, secondary elements */
|
--bg-3: {{colors.surface_container_low.default.hex}}; /* spacing, secondary elements */
|
||||||
--bg-4: {{colors.background.default.hex}}; /* main background color */
|
--bg-4: {{colors.surface.default.hex}}; /* main background color */
|
||||||
--hover: {{colors.surface_bright.default.hex}}; /* channels and buttons when hovered */
|
--hover: {{colors.surface_bright.default.hex}}; /* channels and buttons when hovered */
|
||||||
--active: {{colors.surface_bright.default.hex}}; /* channels and buttons when clicked or selected */
|
--active: {{colors.surface_bright.default.hex}}; /* channels and buttons when clicked or selected */
|
||||||
--message-hover: {{colors.surface_bright.default.hex}}; /* messages when hovered */
|
--message-hover: {{colors.surface_bright.default.hex}}; /* messages when hovered */
|
||||||
|
|||||||
Reference in New Issue
Block a user