mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-30 08:22:51 -05:00
feat: add scroll compositor support (#959)
* added scroll support * import QuickShell.i3 * update scroll provider registration logic * improve scroll support for workspace switcher * update title for scroll keybinds * add scroll to dms-greeter * fix: formatting & sway keybind provider * readme update --------- Co-authored-by: bbedward <bbedward@gmail.com>
This commit is contained in:
13
README.md
13
README.md
@@ -5,21 +5,21 @@
|
|||||||
<img src="assets/danklogo.svg" alt="DankMaterialShell" width="200">
|
<img src="assets/danklogo.svg" alt="DankMaterialShell" width="200">
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
### A modern desktop shell for Wayland
|
### A modern desktop shell for Wayland
|
||||||
|
|
||||||
Built with [Quickshell](https://quickshell.org/) and [Go](https://go.dev/)
|
Built with [Quickshell](https://quickshell.org/) and [Go](https://go.dev/)
|
||||||
|
|
||||||
[](https://danklinux.com/docs)
|
[](https://danklinux.com/docs)
|
||||||
[](https://github.com/AvengeMedia/DankMaterialShell/stargazers)
|
[](https://github.com/AvengeMedia/DankMaterialShell/stargazers)
|
||||||
[](https://github.com/AvengeMedia/DankMaterialShell/blob/master/LICENSE)
|
[](https://github.com/AvengeMedia/DankMaterialShell/blob/master/LICENSE)
|
||||||
[](https://github.com/AvengeMedia/DankMaterialShell/releases)
|
[](https://github.com/AvengeMedia/DankMaterialShell/releases)
|
||||||
[](https://aur.archlinux.org/packages/dms-shell-bin)
|
[](https://aur.archlinux.org/packages/dms-shell-bin)
|
||||||
[)](https://aur.archlinux.org/packages/dms-shell-git)
|
[>)](https://aur.archlinux.org/packages/dms-shell-git)
|
||||||
[](https://ko-fi.com/danklinux)
|
[](https://ko-fi.com/danklinux)
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
DankMaterialShell is a complete desktop shell for [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [MangoWC](https://github.com/DreamMaoMao/mangowc), [Sway](https://swaywm.org), [labwc](https://labwc.github.io/), and other Wayland compositors. It replaces waybar, swaylock, swayidle, mako, fuzzel, polkit, and everything else you'd normally stitch together to make a desktop.
|
DankMaterialShell is a complete desktop shell for [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [MangoWC](https://github.com/DreamMaoMao/mangowc), [Sway](https://swaywm.org), [labwc](https://labwc.github.io/), [Scroll](https://github.com/dawsers/scroll), and other Wayland compositors. It replaces waybar, swaylock, swayidle, mako, fuzzel, polkit, and everything else you'd normally stitch together to make a desktop.
|
||||||
|
|
||||||
## Repository Structure
|
## Repository Structure
|
||||||
|
|
||||||
@@ -105,7 +105,7 @@ Extend functionality with the [plugin registry](https://plugins.danklinux.com).
|
|||||||
|
|
||||||
## Supported Compositors
|
## Supported Compositors
|
||||||
|
|
||||||
Works best with [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [Sway](https://swaywm.org/), [MangoWC](https://github.com/DreamMaoMao/mangowc), and [labwc](https://labwc.github.io/) with full workspace switching, overview integration, and monitor management. Other Wayland compositors work with reduced features.
|
Works best with [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [Sway](https://swaywm.org/), [MangoWC](https://github.com/DreamMaoMao/mangowc), [labwc](https://labwc.github.io/), and [Scroll](https://github.com/dawsers/scroll) with full workspace switching, overview integration, and monitor management. Other Wayland compositors work with reduced features.
|
||||||
|
|
||||||
[Compositor configuration guide](https://danklinux.com/docs/dankmaterialshell/compositors)
|
[Compositor configuration guide](https://danklinux.com/docs/dankmaterialshell/compositors)
|
||||||
|
|
||||||
@@ -143,6 +143,7 @@ See component-specific documentation:
|
|||||||
### Building from Source
|
### Building from Source
|
||||||
|
|
||||||
**Core + Dankinstall:**
|
**Core + Dankinstall:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd core
|
cd core
|
||||||
make # Build dms CLI
|
make # Build dms CLI
|
||||||
@@ -150,11 +151,13 @@ make dankinstall # Build installer
|
|||||||
```
|
```
|
||||||
|
|
||||||
**Shell:**
|
**Shell:**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
quickshell -p quickshell/
|
quickshell -p quickshell/
|
||||||
```
|
```
|
||||||
|
|
||||||
**NixOS:**
|
**NixOS:**
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
inputs.dms.url = "github:AvengeMedia/DankMaterialShell";
|
inputs.dms.url = "github:AvengeMedia/DankMaterialShell";
|
||||||
|
|||||||
@@ -89,6 +89,11 @@ func initializeProviders() {
|
|||||||
log.Warnf("Failed to register MangoWC provider: %v", err)
|
log.Warnf("Failed to register MangoWC provider: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scrollProvider := providers.NewSwayProvider("$HOME/.config/scroll")
|
||||||
|
if err := registry.Register(scrollProvider); err != nil {
|
||||||
|
log.Warnf("Failed to register Scroll provider: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
swayProvider := providers.NewSwayProvider("$HOME/.config/sway")
|
swayProvider := providers.NewSwayProvider("$HOME/.config/sway")
|
||||||
if err := registry.Register(swayProvider); err != nil {
|
if err := registry.Register(swayProvider); err != nil {
|
||||||
log.Warnf("Failed to register Sway provider: %v", err)
|
log.Warnf("Failed to register Sway provider: %v", err)
|
||||||
@@ -125,6 +130,8 @@ func makeProviderWithPath(name, path string) keybinds.Provider {
|
|||||||
return providers.NewMangoWCProvider(path)
|
return providers.NewMangoWCProvider(path)
|
||||||
case "sway":
|
case "sway":
|
||||||
return providers.NewSwayProvider(path)
|
return providers.NewSwayProvider(path)
|
||||||
|
case "scroll":
|
||||||
|
return providers.NewSwayProvider(path)
|
||||||
case "niri":
|
case "niri":
|
||||||
return providers.NewNiriProvider(path)
|
return providers.NewNiriProvider(path)
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package providers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/keybinds"
|
"github.com/AvengeMedia/DankMaterialShell/core/internal/keybinds"
|
||||||
@@ -9,18 +10,38 @@ import (
|
|||||||
|
|
||||||
type SwayProvider struct {
|
type SwayProvider struct {
|
||||||
configPath string
|
configPath string
|
||||||
|
isScroll bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSwayProvider(configPath string) *SwayProvider {
|
func NewSwayProvider(configPath string) *SwayProvider {
|
||||||
|
isScroll := false
|
||||||
|
_, ok := os.LookupEnv("SCROLLSOCK")
|
||||||
|
if ok {
|
||||||
|
isScroll = true
|
||||||
|
}
|
||||||
if configPath == "" {
|
if configPath == "" {
|
||||||
configPath = "$HOME/.config/sway"
|
configPath = "$HOME/.config/sway"
|
||||||
}
|
}
|
||||||
|
if isScroll && configPath == "" {
|
||||||
|
configPath = "$HOME/.config/scroll"
|
||||||
|
}
|
||||||
return &SwayProvider{
|
return &SwayProvider{
|
||||||
configPath: configPath,
|
configPath: configPath,
|
||||||
|
isScroll: isScroll,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SwayProvider) Name() string {
|
func (s *SwayProvider) Name() string {
|
||||||
|
if s != nil && s.isScroll {
|
||||||
|
return "scroll"
|
||||||
|
}
|
||||||
|
if s == nil {
|
||||||
|
_, ok := os.LookupEnv("SCROLLSOCK")
|
||||||
|
if ok {
|
||||||
|
return "scroll"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return "sway"
|
return "sway"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,8 +54,13 @@ func (s *SwayProvider) GetCheatSheet() (*keybinds.CheatSheet, error) {
|
|||||||
categorizedBinds := make(map[string][]keybinds.Keybind)
|
categorizedBinds := make(map[string][]keybinds.Keybind)
|
||||||
s.convertSection(section, "", categorizedBinds)
|
s.convertSection(section, "", categorizedBinds)
|
||||||
|
|
||||||
|
cheatSheetTitle := "Sway Keybinds"
|
||||||
|
if s != nil && s.isScroll {
|
||||||
|
cheatSheetTitle = "Scroll Keybinds"
|
||||||
|
}
|
||||||
|
|
||||||
return &keybinds.CheatSheet{
|
return &keybinds.CheatSheet{
|
||||||
Title: "Sway Keybinds",
|
Title: cheatSheetTitle,
|
||||||
Provider: s.Name(),
|
Provider: s.Name(),
|
||||||
Binds: categorizedBinds,
|
Binds: categorizedBinds,
|
||||||
}, nil
|
}, nil
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const (
|
|||||||
CompositorSway
|
CompositorSway
|
||||||
CompositorNiri
|
CompositorNiri
|
||||||
CompositorDWL
|
CompositorDWL
|
||||||
|
CompositorScroll
|
||||||
)
|
)
|
||||||
|
|
||||||
var detectedCompositor Compositor = -1
|
var detectedCompositor Compositor = -1
|
||||||
@@ -32,6 +33,7 @@ func DetectCompositor() Compositor {
|
|||||||
hyprlandSig := os.Getenv("HYPRLAND_INSTANCE_SIGNATURE")
|
hyprlandSig := os.Getenv("HYPRLAND_INSTANCE_SIGNATURE")
|
||||||
niriSocket := os.Getenv("NIRI_SOCKET")
|
niriSocket := os.Getenv("NIRI_SOCKET")
|
||||||
swaySocket := os.Getenv("SWAYSOCK")
|
swaySocket := os.Getenv("SWAYSOCK")
|
||||||
|
scrollSocket := os.Getenv("SCROLLSOCK")
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case niriSocket != "":
|
case niriSocket != "":
|
||||||
@@ -39,6 +41,12 @@ func DetectCompositor() Compositor {
|
|||||||
detectedCompositor = CompositorNiri
|
detectedCompositor = CompositorNiri
|
||||||
return detectedCompositor
|
return detectedCompositor
|
||||||
}
|
}
|
||||||
|
case scrollSocket != "":
|
||||||
|
if _, err := os.Stat(scrollSocket); err == nil {
|
||||||
|
detectedCompositor = CompositorScroll
|
||||||
|
return detectedCompositor
|
||||||
|
}
|
||||||
|
|
||||||
case swaySocket != "":
|
case swaySocket != "":
|
||||||
if _, err := os.Stat(swaySocket); err == nil {
|
if _, err := os.Stat(swaySocket); err == nil {
|
||||||
detectedCompositor = CompositorSway
|
detectedCompositor = CompositorSway
|
||||||
@@ -233,6 +241,25 @@ func getSwayFocusedMonitor() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getScrollFocusedMonitor() string {
|
||||||
|
output, err := exec.Command("scrollmsg", "-t", "get_workspaces").Output()
|
||||||
|
if err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
var workspaces []swayWorkspace
|
||||||
|
if err := json.Unmarshal(output, &workspaces); err != nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ws := range workspaces {
|
||||||
|
if ws.Focused {
|
||||||
|
return ws.Output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
type niriWorkspace struct {
|
type niriWorkspace struct {
|
||||||
Output string `json:"output"`
|
Output string `json:"output"`
|
||||||
IsFocused bool `json:"is_focused"`
|
IsFocused bool `json:"is_focused"`
|
||||||
@@ -378,6 +405,8 @@ func GetFocusedMonitor() string {
|
|||||||
return getHyprlandFocusedMonitor()
|
return getHyprlandFocusedMonitor()
|
||||||
case CompositorSway:
|
case CompositorSway:
|
||||||
return getSwayFocusedMonitor()
|
return getSwayFocusedMonitor()
|
||||||
|
case CompositorScroll:
|
||||||
|
return getScrollFocusedMonitor()
|
||||||
case CompositorNiri:
|
case CompositorNiri:
|
||||||
return getNiriFocusedMonitor()
|
return getNiriFocusedMonitor()
|
||||||
case CompositorDWL:
|
case CompositorDWL:
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ in {
|
|||||||
options.programs.dankMaterialShell.greeter = {
|
options.programs.dankMaterialShell.greeter = {
|
||||||
enable = lib.mkEnableOption "DankMaterialShell greeter";
|
enable = lib.mkEnableOption "DankMaterialShell greeter";
|
||||||
compositor.name = lib.mkOption {
|
compositor.name = lib.mkOption {
|
||||||
type = types.enum ["niri" "hyprland" "sway"];
|
type = types.enum ["niri" "hyprland" "sway" "scroll"];
|
||||||
description = "Compositor to run greeter in";
|
description = "Compositor to run greeter in";
|
||||||
};
|
};
|
||||||
compositor.customConfig = lib.mkOption {
|
compositor.customConfig = lib.mkOption {
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ Item {
|
|||||||
focusedScreenName = Hyprland.focusedWorkspace.monitor.name;
|
focusedScreenName = Hyprland.focusedWorkspace.monitor.name;
|
||||||
} else if (CompositorService.isNiri && NiriService.currentOutput) {
|
} else if (CompositorService.isNiri && NiriService.currentOutput) {
|
||||||
focusedScreenName = NiriService.currentOutput;
|
focusedScreenName = NiriService.currentOutput;
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
||||||
focusedScreenName = focusedWs?.monitor?.name || "";
|
focusedScreenName = focusedWs?.monitor?.name || "";
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ Item {
|
|||||||
focusedScreenName = Hyprland.focusedWorkspace.monitor.name;
|
focusedScreenName = Hyprland.focusedWorkspace.monitor.name;
|
||||||
} else if (CompositorService.isNiri && NiriService.currentOutput) {
|
} else if (CompositorService.isNiri && NiriService.currentOutput) {
|
||||||
focusedScreenName = NiriService.currentOutput;
|
focusedScreenName = NiriService.currentOutput;
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
||||||
focusedScreenName = focusedWs?.monitor?.name || "";
|
focusedScreenName = focusedWs?.monitor?.name || "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ Item {
|
|||||||
}, (_, i) => i);
|
}, (_, i) => i);
|
||||||
}
|
}
|
||||||
return DwlService.getVisibleTags(barWindow.screenName);
|
return DwlService.getVisibleTags(barWindow.screenName);
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
const workspaces = I3.workspaces?.values || [];
|
const workspaces = I3.workspaces?.values || [];
|
||||||
if (workspaces.length === 0)
|
if (workspaces.length === 0)
|
||||||
return [
|
return [
|
||||||
@@ -124,7 +124,7 @@ Item {
|
|||||||
return 0;
|
return 0;
|
||||||
const activeTags = DwlService.getActiveTags(barWindow.screenName);
|
const activeTags = DwlService.getActiveTags(barWindow.screenName);
|
||||||
return activeTags.length > 0 ? activeTags[0] : 0;
|
return activeTags.length > 0 ? activeTags[0] : 0;
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
if (!barWindow.screenName || !SettingsData.workspacesPerMonitor) {
|
if (!barWindow.screenName || !SettingsData.workspacesPerMonitor) {
|
||||||
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
||||||
return focusedWs ? focusedWs.num : 1;
|
return focusedWs ? focusedWs.num : 1;
|
||||||
@@ -169,7 +169,7 @@ Item {
|
|||||||
if (nextIndex !== validIndex) {
|
if (nextIndex !== validIndex) {
|
||||||
DwlService.switchToTag(barWindow.screenName, realWorkspaces[nextIndex]);
|
DwlService.switchToTag(barWindow.screenName, realWorkspaces[nextIndex]);
|
||||||
}
|
}
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
const currentWs = getCurrentWorkspace();
|
const currentWs = getCurrentWorkspace();
|
||||||
const currentIndex = realWorkspaces.findIndex(ws => ws.num === currentWs);
|
const currentIndex = realWorkspaces.findIndex(ws => ws.num === currentWs);
|
||||||
const validIndex = currentIndex === -1 ? 0 : currentIndex;
|
const validIndex = currentIndex === -1 ? 0 : currentIndex;
|
||||||
@@ -534,7 +534,7 @@ Item {
|
|||||||
section: topBarContent.getWidgetSection(parent)
|
section: topBarContent.getWidgetSection(parent)
|
||||||
parentScreen: barWindow.screen
|
parentScreen: barWindow.screen
|
||||||
onClicked: {
|
onClicked: {
|
||||||
clipboardHistoryModalPopup.toggle()
|
clipboardHistoryModalPopup.toggle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -550,9 +550,9 @@ Item {
|
|||||||
parentScreen: barWindow.screen
|
parentScreen: barWindow.screen
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (powerMenuModalLoader) {
|
if (powerMenuModalLoader) {
|
||||||
powerMenuModalLoader.active = true
|
powerMenuModalLoader.active = true;
|
||||||
if (powerMenuModalLoader.item) {
|
if (powerMenuModalLoader.item) {
|
||||||
powerMenuModalLoader.item.openCentered()
|
powerMenuModalLoader.item.openCentered();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Effects
|
import QtQuick.Effects
|
||||||
import Quickshell
|
|
||||||
import Quickshell.Widgets
|
import Quickshell.Widgets
|
||||||
import qs.Common
|
import qs.Common
|
||||||
import qs.Modules.Plugins
|
import qs.Modules.Plugins
|
||||||
@@ -56,7 +55,7 @@ BasePill {
|
|||||||
}
|
}
|
||||||
|
|
||||||
IconImage {
|
IconImage {
|
||||||
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway || CompositorService.isLabwc)
|
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway || CompositorService.isScroll || CompositorService.isLabwc)
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset)
|
||||||
@@ -64,17 +63,19 @@ BasePill {
|
|||||||
asynchronous: true
|
asynchronous: true
|
||||||
source: {
|
source: {
|
||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
return "file://" + Theme.shellDir + "/assets/niri.svg"
|
return "file://" + Theme.shellDir + "/assets/niri.svg";
|
||||||
} else if (CompositorService.isHyprland) {
|
} else if (CompositorService.isHyprland) {
|
||||||
return "file://" + Theme.shellDir + "/assets/hyprland.svg"
|
return "file://" + Theme.shellDir + "/assets/hyprland.svg";
|
||||||
} else if (CompositorService.isDwl) {
|
} else if (CompositorService.isDwl) {
|
||||||
return "file://" + Theme.shellDir + "/assets/mango.png"
|
return "file://" + Theme.shellDir + "/assets/mango.png";
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway) {
|
||||||
return "file://" + Theme.shellDir + "/assets/sway.svg"
|
return "file://" + Theme.shellDir + "/assets/sway.svg";
|
||||||
|
} else if (CompositorService.isScroll) {
|
||||||
|
return "file://" + Theme.shellDir + "/assets/sway.svg";
|
||||||
} else if (CompositorService.isLabwc) {
|
} else if (CompositorService.isLabwc) {
|
||||||
return "file://" + Theme.shellDir + "/assets/labwc.png"
|
return "file://" + Theme.shellDir + "/assets/labwc.png";
|
||||||
}
|
}
|
||||||
return ""
|
return "";
|
||||||
}
|
}
|
||||||
layer.enabled: Theme.effectiveLogoColor !== ""
|
layer.enabled: Theme.effectiveLogoColor !== ""
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
@@ -82,10 +83,10 @@ BasePill {
|
|||||||
colorization: 1
|
colorization: 1
|
||||||
colorizationColor: Theme.effectiveLogoColor
|
colorizationColor: Theme.effectiveLogoColor
|
||||||
brightness: {
|
brightness: {
|
||||||
SettingsData.launcherLogoBrightness
|
SettingsData.launcherLogoBrightness;
|
||||||
}
|
}
|
||||||
contrast: {
|
contrast: {
|
||||||
SettingsData.launcherLogoContrast
|
SettingsData.launcherLogoContrast;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,9 +113,9 @@ BasePill {
|
|||||||
|
|
||||||
onRightClicked: {
|
onRightClicked: {
|
||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
NiriService.toggleOverview()
|
NiriService.toggleOverview();
|
||||||
} else if (root.hyprlandOverviewLoader?.item) {
|
} else if (root.hyprlandOverviewLoader?.item) {
|
||||||
root.hyprlandOverviewLoader.item.overviewOpen = !root.hyprlandOverviewLoader.item.overviewOpen
|
root.hyprlandOverviewLoader.item.overviewOpen = !root.hyprlandOverviewLoader.item.overviewOpen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Item {
|
|||||||
return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, screenName);
|
return CompositorService.filterCurrentWorkspace(CompositorService.sortedToplevels, screenName);
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property bool useExtWorkspace: DMSService.forceExtWorkspace || (!CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isDwl && !CompositorService.isSway && ExtWorkspaceService.extWorkspaceAvailable)
|
readonly property bool useExtWorkspace: DMSService.forceExtWorkspace || (!CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isDwl && !CompositorService.isSway && !CompositorService.isScroll && ExtWorkspaceService.extWorkspaceAvailable)
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: DesktopEntries
|
target: DesktopEntries
|
||||||
@@ -45,6 +45,7 @@ Item {
|
|||||||
const activeTags = getDwlActiveTags();
|
const activeTags = getDwlActiveTags();
|
||||||
return activeTags.length > 0 ? activeTags[0] : -1;
|
return activeTags.length > 0 ? activeTags[0] : -1;
|
||||||
case "sway":
|
case "sway":
|
||||||
|
case "scroll":
|
||||||
return getSwayActiveWorkspace();
|
return getSwayActiveWorkspace();
|
||||||
default:
|
default:
|
||||||
return 1;
|
return 1;
|
||||||
@@ -74,6 +75,7 @@ Item {
|
|||||||
baseList = getDwlTags();
|
baseList = getDwlTags();
|
||||||
break;
|
break;
|
||||||
case "sway":
|
case "sway":
|
||||||
|
case "scroll":
|
||||||
baseList = getSwayWorkspaces();
|
baseList = getSwayWorkspaces();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -192,7 +194,7 @@ Item {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
targetWorkspaceId = ws.tag;
|
targetWorkspaceId = ws.tag;
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
targetWorkspaceId = ws.num !== undefined ? ws.num : ws;
|
targetWorkspaceId = ws.num !== undefined ? ws.num : ws;
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
@@ -204,7 +206,7 @@ Item {
|
|||||||
let isActiveWs = false;
|
let isActiveWs = false;
|
||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
isActiveWs = NiriService.allWorkspaces.some(ws => ws.id === targetWorkspaceId && ws.is_active);
|
isActiveWs = NiriService.allWorkspaces.some(ws => ws.id === targetWorkspaceId && ws.is_active);
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
||||||
isActiveWs = focusedWs ? (focusedWs.num === targetWorkspaceId) : false;
|
isActiveWs = focusedWs ? (focusedWs.num === targetWorkspaceId) : false;
|
||||||
} else if (CompositorService.isDwl) {
|
} else if (CompositorService.isDwl) {
|
||||||
@@ -225,7 +227,7 @@ Item {
|
|||||||
let winWs = null;
|
let winWs = null;
|
||||||
if (CompositorService.isNiri) {
|
if (CompositorService.isNiri) {
|
||||||
winWs = w.workspace_id;
|
winWs = w.workspace_id;
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
winWs = w.workspace?.num;
|
winWs = w.workspace?.num;
|
||||||
} else {
|
} else {
|
||||||
const hyprlandToplevels = Array.from(Hyprland.toplevels?.values || []);
|
const hyprlandToplevels = Array.from(Hyprland.toplevels?.values || []);
|
||||||
@@ -283,7 +285,7 @@ Item {
|
|||||||
placeholder = {
|
placeholder = {
|
||||||
"tag": -1
|
"tag": -1
|
||||||
};
|
};
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
placeholder = {
|
placeholder = {
|
||||||
"num": -1
|
"num": -1
|
||||||
};
|
};
|
||||||
@@ -453,7 +455,7 @@ Item {
|
|||||||
return ws && ws.id !== -1;
|
return ws && ws.id !== -1;
|
||||||
if (CompositorService.isDwl)
|
if (CompositorService.isDwl)
|
||||||
return ws && ws.tag !== -1;
|
return ws && ws.tag !== -1;
|
||||||
if (CompositorService.isSway)
|
if (CompositorService.isSway || CompositorService.isScroll)
|
||||||
return ws && ws.num !== -1;
|
return ws && ws.num !== -1;
|
||||||
return ws !== -1;
|
return ws !== -1;
|
||||||
});
|
});
|
||||||
@@ -521,7 +523,7 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DwlService.switchToTag(root.screenName, realWorkspaces[nextIndex].tag);
|
DwlService.switchToTag(root.screenName, realWorkspaces[nextIndex].tag);
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
const realWorkspaces = getRealWorkspaces();
|
const realWorkspaces = getRealWorkspaces();
|
||||||
if (realWorkspaces.length < 2) {
|
if (realWorkspaces.length < 2) {
|
||||||
return;
|
return;
|
||||||
@@ -549,7 +551,7 @@ Item {
|
|||||||
isPlaceholder = modelData?.id === -1;
|
isPlaceholder = modelData?.id === -1;
|
||||||
} else if (CompositorService.isDwl) {
|
} else if (CompositorService.isDwl) {
|
||||||
isPlaceholder = modelData?.tag === -1;
|
isPlaceholder = modelData?.tag === -1;
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
isPlaceholder = modelData?.num === -1;
|
isPlaceholder = modelData?.num === -1;
|
||||||
} else {
|
} else {
|
||||||
isPlaceholder = modelData === -1;
|
isPlaceholder = modelData === -1;
|
||||||
@@ -564,12 +566,12 @@ Item {
|
|||||||
return modelData?.id || "";
|
return modelData?.id || "";
|
||||||
if (CompositorService.isDwl)
|
if (CompositorService.isDwl)
|
||||||
return (modelData?.tag !== undefined) ? (modelData.tag + 1) : "";
|
return (modelData?.tag !== undefined) ? (modelData.tag + 1) : "";
|
||||||
if (CompositorService.isSway)
|
if (CompositorService.isSway || CompositorService.isScroll)
|
||||||
return modelData?.num || "";
|
return modelData?.num || "";
|
||||||
return modelData - 1;
|
return modelData - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property bool hasNativeWorkspaceSupport: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway
|
readonly property bool hasNativeWorkspaceSupport: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway || CompositorService.isScroll
|
||||||
readonly property bool hasWorkspaces: getRealWorkspaces().length > 0
|
readonly property bool hasWorkspaces: getRealWorkspaces().length > 0
|
||||||
readonly property bool shouldShow: hasNativeWorkspaceSupport || (useExtWorkspace && hasWorkspaces)
|
readonly property bool shouldShow: hasNativeWorkspaceSupport || (useExtWorkspace && hasWorkspaces)
|
||||||
|
|
||||||
@@ -675,7 +677,7 @@ Item {
|
|||||||
return !!(modelData && modelData.id === root.currentWorkspace);
|
return !!(modelData && modelData.id === root.currentWorkspace);
|
||||||
if (CompositorService.isDwl)
|
if (CompositorService.isDwl)
|
||||||
return !!(modelData && root.dwlActiveTags.includes(modelData.tag));
|
return !!(modelData && root.dwlActiveTags.includes(modelData.tag));
|
||||||
if (CompositorService.isSway)
|
if (CompositorService.isSway || CompositorService.isScroll)
|
||||||
return !!(modelData && modelData.num === root.currentWorkspace);
|
return !!(modelData && modelData.num === root.currentWorkspace);
|
||||||
return modelData === root.currentWorkspace;
|
return modelData === root.currentWorkspace;
|
||||||
}
|
}
|
||||||
@@ -686,7 +688,7 @@ Item {
|
|||||||
return !!(modelData && modelData.id === -1);
|
return !!(modelData && modelData.id === -1);
|
||||||
if (CompositorService.isDwl)
|
if (CompositorService.isDwl)
|
||||||
return !!(modelData && modelData.tag === -1);
|
return !!(modelData && modelData.tag === -1);
|
||||||
if (CompositorService.isSway)
|
if (CompositorService.isSway || CompositorService.isScroll)
|
||||||
return !!(modelData && modelData.num === -1);
|
return !!(modelData && modelData.num === -1);
|
||||||
return modelData === -1;
|
return modelData === -1;
|
||||||
}
|
}
|
||||||
@@ -703,7 +705,7 @@ Item {
|
|||||||
return loadedIsUrgent;
|
return loadedIsUrgent;
|
||||||
if (CompositorService.isDwl)
|
if (CompositorService.isDwl)
|
||||||
return modelData?.state === 2;
|
return modelData?.state === 2;
|
||||||
if (CompositorService.isSway)
|
if (CompositorService.isSway || CompositorService.isScroll)
|
||||||
return loadedIsUrgent;
|
return loadedIsUrgent;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -767,7 +769,7 @@ Item {
|
|||||||
console.log("Calling switchToTag");
|
console.log("Calling switchToTag");
|
||||||
DwlService.switchToTag(root.screenName, modelData.tag);
|
DwlService.switchToTag(root.screenName, modelData.tag);
|
||||||
}
|
}
|
||||||
} else if (CompositorService.isSway && modelData?.num) {
|
} else if ((CompositorService.isSway || CompositorService.isScroll) && modelData?.num) {
|
||||||
try {
|
try {
|
||||||
I3.dispatch(`workspace number ${modelData.num}`);
|
I3.dispatch(`workspace number ${modelData.num}`);
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
@@ -797,7 +799,7 @@ Item {
|
|||||||
wsData = modelData;
|
wsData = modelData;
|
||||||
} else if (CompositorService.isDwl) {
|
} else if (CompositorService.isDwl) {
|
||||||
wsData = modelData;
|
wsData = modelData;
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
wsData = modelData;
|
wsData = modelData;
|
||||||
}
|
}
|
||||||
delegateRoot.loadedWorkspaceData = wsData;
|
delegateRoot.loadedWorkspaceData = wsData;
|
||||||
@@ -811,7 +813,7 @@ Item {
|
|||||||
delegateRoot.loadedHasIcon = icData !== null;
|
delegateRoot.loadedHasIcon = icData !== null;
|
||||||
|
|
||||||
if (SettingsData.showWorkspaceApps) {
|
if (SettingsData.showWorkspaceApps) {
|
||||||
if (CompositorService.isDwl || CompositorService.isSway) {
|
if (CompositorService.isDwl || CompositorService.isSway || CompositorService.isScroll) {
|
||||||
delegateRoot.loadedIcons = root.getWorkspaceIcons(modelData);
|
delegateRoot.loadedIcons = root.getWorkspaceIcons(modelData);
|
||||||
} else {
|
} else {
|
||||||
delegateRoot.loadedIcons = root.getWorkspaceIcons(CompositorService.isHyprland ? modelData : (modelData === -1 ? null : modelData));
|
delegateRoot.loadedIcons = root.getWorkspaceIcons(CompositorService.isHyprland ? modelData : (modelData === -1 ? null : modelData));
|
||||||
@@ -1192,7 +1194,7 @@ Item {
|
|||||||
}
|
}
|
||||||
Connections {
|
Connections {
|
||||||
target: I3.workspaces
|
target: I3.workspaces
|
||||||
enabled: CompositorService.isSway
|
enabled: (CompositorService.isSway || CompositorService.isScroll)
|
||||||
function onValuesChanged() {
|
function onValuesChanged() {
|
||||||
delegateRoot.updateAllData();
|
delegateRoot.updateAllData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ Card {
|
|||||||
return "on MangoWC";
|
return "on MangoWC";
|
||||||
if (CompositorService.isSway)
|
if (CompositorService.isSway)
|
||||||
return "on Sway";
|
return "on Sway";
|
||||||
|
if (CompositorService.isScroll)
|
||||||
|
return "on Scroll";
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ dms-greeter - DankMaterialShell greeter launcher
|
|||||||
Usage: dms-greeter --command COMPOSITOR [OPTIONS]
|
Usage: dms-greeter --command COMPOSITOR [OPTIONS]
|
||||||
|
|
||||||
Required:
|
Required:
|
||||||
--command COMPOSITOR Compositor to use (niri, hyprland, sway, or mangowc)
|
--command COMPOSITOR Compositor to use (niri, hyprland, sway, scroll or mangowc)
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
-C, --config PATH Custom compositor config file
|
-C, --config PATH Custom compositor config file
|
||||||
@@ -30,6 +30,7 @@ Examples:
|
|||||||
dms-greeter --command niri
|
dms-greeter --command niri
|
||||||
dms-greeter --command hyprland -C /etc/greetd/custom-hypr.conf
|
dms-greeter --command hyprland -C /etc/greetd/custom-hypr.conf
|
||||||
dms-greeter --command sway -p /home/user/.config/quickshell/custom-dms
|
dms-greeter --command sway -p /home/user/.config/quickshell/custom-dms
|
||||||
|
dms-greeter --command scroll -p /home/user/.config/quickshell/custom-dms
|
||||||
dms-greeter --command niri --cache-dir /tmp/dmsgreeter
|
dms-greeter --command niri --cache-dir /tmp/dmsgreeter
|
||||||
dms-greeter --command mangowc
|
dms-greeter --command mangowc
|
||||||
EOF
|
EOF
|
||||||
@@ -207,6 +208,25 @@ SWAY_EOF
|
|||||||
exec sway -c "$COMPOSITOR_CONFIG"
|
exec sway -c "$COMPOSITOR_CONFIG"
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
scroll)
|
||||||
|
if [[ -z "$COMPOSITOR_CONFIG" ]]; then
|
||||||
|
TEMP_CONFIG=$(mktemp)
|
||||||
|
cat > "$TEMP_CONFIG" << SCROLL_EOF
|
||||||
|
exec "$QS_CMD; scrollmsg exit"
|
||||||
|
SCROLL_EOF
|
||||||
|
COMPOSITOR_CONFIG="$TEMP_CONFIG"
|
||||||
|
else
|
||||||
|
TEMP_CONFIG=$(mktemp)
|
||||||
|
cat "$COMPOSITOR_CONFIG" > "$TEMP_CONFIG"
|
||||||
|
cat >> "$TEMP_CONFIG" << SCROLL_EOF
|
||||||
|
|
||||||
|
exec "$QS_CMD; scrollmsg exit"
|
||||||
|
SCROLL_EOF
|
||||||
|
COMPOSITOR_CONFIG="$TEMP_CONFIG"
|
||||||
|
fi
|
||||||
|
exec scroll -c "$COMPOSITOR_CONFIG"
|
||||||
|
;;
|
||||||
|
|
||||||
mangowc)
|
mangowc)
|
||||||
if [[ -n "$COMPOSITOR_CONFIG" ]]; then
|
if [[ -n "$COMPOSITOR_CONFIG" ]]; then
|
||||||
exec mango -c "$COMPOSITOR_CONFIG" -s "$QS_CMD && mmsg -d quit"
|
exec mango -c "$COMPOSITOR_CONFIG" -s "$QS_CMD && mmsg -d quit"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ Item {
|
|||||||
property bool isHyprland: CompositorService.isHyprland
|
property bool isHyprland: CompositorService.isHyprland
|
||||||
property bool isNiri: CompositorService.isNiri
|
property bool isNiri: CompositorService.isNiri
|
||||||
property bool isSway: CompositorService.isSway
|
property bool isSway: CompositorService.isSway
|
||||||
|
property bool isScroll: CompositorService.isScroll
|
||||||
property bool isDwl: CompositorService.isDwl
|
property bool isDwl: CompositorService.isDwl
|
||||||
property bool isLabwc: CompositorService.isLabwc
|
property bool isLabwc: CompositorService.isLabwc
|
||||||
|
|
||||||
@@ -18,6 +19,8 @@ Item {
|
|||||||
return "hyprland";
|
return "hyprland";
|
||||||
if (isSway)
|
if (isSway)
|
||||||
return "sway";
|
return "sway";
|
||||||
|
if (isScroll)
|
||||||
|
return "scroll";
|
||||||
if (isDwl)
|
if (isDwl)
|
||||||
return "mangowc";
|
return "mangowc";
|
||||||
if (isLabwc)
|
if (isLabwc)
|
||||||
@@ -30,6 +33,8 @@ Item {
|
|||||||
return "/assets/hyprland.svg";
|
return "/assets/hyprland.svg";
|
||||||
if (isSway)
|
if (isSway)
|
||||||
return "/assets/sway.svg";
|
return "/assets/sway.svg";
|
||||||
|
if (isScroll)
|
||||||
|
return "/assets/sway.svg";
|
||||||
if (isDwl)
|
if (isDwl)
|
||||||
return "/assets/mango.png";
|
return "/assets/mango.png";
|
||||||
if (isLabwc)
|
if (isLabwc)
|
||||||
@@ -42,6 +47,8 @@ Item {
|
|||||||
return "https://hypr.land";
|
return "https://hypr.land";
|
||||||
if (isSway)
|
if (isSway)
|
||||||
return "https://swaywm.org";
|
return "https://swaywm.org";
|
||||||
|
if (isScroll)
|
||||||
|
return "https://github.com/dawsers/scroll";
|
||||||
if (isDwl)
|
if (isDwl)
|
||||||
return "https://github.com/DreamMaoMao/mangowc";
|
return "https://github.com/DreamMaoMao/mangowc";
|
||||||
if (isLabwc)
|
if (isLabwc)
|
||||||
@@ -54,6 +61,8 @@ Item {
|
|||||||
return "Hyprland Website";
|
return "Hyprland Website";
|
||||||
if (isSway)
|
if (isSway)
|
||||||
return "Sway Website";
|
return "Sway Website";
|
||||||
|
if (isScroll)
|
||||||
|
return "Scroll Github";
|
||||||
if (isDwl)
|
if (isDwl)
|
||||||
return "mangowc GitHub";
|
return "mangowc GitHub";
|
||||||
if (isLabwc)
|
if (isLabwc)
|
||||||
@@ -86,9 +95,9 @@ Item {
|
|||||||
property string ircUrl: "https://web.libera.chat/gamja/?channels=#labwc"
|
property string ircUrl: "https://web.libera.chat/gamja/?channels=#labwc"
|
||||||
property string ircTooltip: "LabWC IRC Channel"
|
property string ircTooltip: "LabWC IRC Channel"
|
||||||
|
|
||||||
property bool showMatrix: isNiri && !isHyprland && !isSway && !isDwl && !isLabwc
|
property bool showMatrix: isNiri && !isHyprland && !isSway && !isScroll && !isDwl && !isLabwc
|
||||||
property bool showCompositorDiscord: isHyprland || isDwl
|
property bool showCompositorDiscord: isHyprland || isDwl
|
||||||
property bool showReddit: isNiri && !isHyprland && !isSway && !isDwl && !isLabwc
|
property bool showReddit: isNiri && !isHyprland && !isSway && !isScroll && !isDwl && !isLabwc
|
||||||
property bool showIrc: isLabwc
|
property bool showIrc: isLabwc
|
||||||
|
|
||||||
DankFlickable {
|
DankFlickable {
|
||||||
|
|||||||
@@ -63,6 +63,8 @@ Item {
|
|||||||
modes.push("mango");
|
modes.push("mango");
|
||||||
} else if (CompositorService.isSway) {
|
} else if (CompositorService.isSway) {
|
||||||
modes.push("Sway");
|
modes.push("Sway");
|
||||||
|
} else if (CompositorService.isScroll) {
|
||||||
|
modes.push("Scroll");
|
||||||
} else {
|
} else {
|
||||||
modes.push(I18n.tr("Compositor"));
|
modes.push(I18n.tr("Compositor"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
pragma Singleton
|
pragma Singleton
|
||||||
pragma ComponentBehavior: Bound
|
pragma ComponentBehavior: Bound
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
@@ -65,7 +66,7 @@ Singleton {
|
|||||||
return Hyprland.focusedWorkspace.monitor.name;
|
return Hyprland.focusedWorkspace.monitor.name;
|
||||||
if (CompositorService.isNiri && NiriService.currentOutput)
|
if (CompositorService.isNiri && NiriService.currentOutput)
|
||||||
return NiriService.currentOutput;
|
return NiriService.currentOutput;
|
||||||
if (CompositorService.isSway) {
|
if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
||||||
return focusedWs?.monitor?.name || "";
|
return focusedWs?.monitor?.name || "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ pragma ComponentBehavior: Bound
|
|||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import Quickshell
|
import Quickshell
|
||||||
|
import Quickshell.I3
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import Quickshell.Hyprland
|
import Quickshell.Hyprland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
@@ -14,6 +15,7 @@ Singleton {
|
|||||||
property bool isNiri: false
|
property bool isNiri: false
|
||||||
property bool isDwl: false
|
property bool isDwl: false
|
||||||
property bool isSway: false
|
property bool isSway: false
|
||||||
|
property bool isScroll: false
|
||||||
property bool isLabwc: false
|
property bool isLabwc: false
|
||||||
property string compositor: "unknown"
|
property string compositor: "unknown"
|
||||||
readonly property bool useHyprlandFocusGrab: isHyprland && Quickshell.env("DMS_HYPRLAND_EXCLUSIVE_FOCUS") !== "1"
|
readonly property bool useHyprlandFocusGrab: isHyprland && Quickshell.env("DMS_HYPRLAND_EXCLUSIVE_FOCUS") !== "1"
|
||||||
@@ -21,6 +23,7 @@ Singleton {
|
|||||||
readonly property string hyprlandSignature: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")
|
readonly property string hyprlandSignature: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")
|
||||||
readonly property string niriSocket: Quickshell.env("NIRI_SOCKET")
|
readonly property string niriSocket: Quickshell.env("NIRI_SOCKET")
|
||||||
readonly property string swaySocket: Quickshell.env("SWAYSOCK")
|
readonly property string swaySocket: Quickshell.env("SWAYSOCK")
|
||||||
|
readonly property string scrollSocket: Quickshell.env("SWAYSOCK")
|
||||||
readonly property string labwcPid: Quickshell.env("LABWC_PID")
|
readonly property string labwcPid: Quickshell.env("LABWC_PID")
|
||||||
property bool useNiriSorting: isNiri && NiriService
|
property bool useNiriSorting: isNiri && NiriService
|
||||||
|
|
||||||
@@ -71,7 +74,7 @@ Singleton {
|
|||||||
screenName = Hyprland.focusedWorkspace.monitor.name;
|
screenName = Hyprland.focusedWorkspace.monitor.name;
|
||||||
else if (isNiri && NiriService.currentOutput)
|
else if (isNiri && NiriService.currentOutput)
|
||||||
screenName = NiriService.currentOutput;
|
screenName = NiriService.currentOutput;
|
||||||
else if (isSway) {
|
else if (isSway || isScroll) {
|
||||||
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
|
||||||
screenName = focusedWs?.monitor?.name || "";
|
screenName = focusedWs?.monitor?.name || "";
|
||||||
} else if (isDwl && DwlService.activeOutput)
|
} else if (isDwl && DwlService.activeOutput)
|
||||||
@@ -398,11 +401,12 @@ Singleton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function detectCompositor() {
|
function detectCompositor() {
|
||||||
if (hyprlandSignature && hyprlandSignature.length > 0 && !niriSocket && !swaySocket && !labwcPid) {
|
if (hyprlandSignature && hyprlandSignature.length > 0 && !niriSocket && !swaySocket && !scrollSocket && !labwcPid) {
|
||||||
isHyprland = true;
|
isHyprland = true;
|
||||||
isNiri = false;
|
isNiri = false;
|
||||||
isDwl = false;
|
isDwl = false;
|
||||||
isSway = false;
|
isSway = false;
|
||||||
|
isScroll = false;
|
||||||
isLabwc = false;
|
isLabwc = false;
|
||||||
compositor = "hyprland";
|
compositor = "hyprland";
|
||||||
console.info("CompositorService: Detected Hyprland");
|
console.info("CompositorService: Detected Hyprland");
|
||||||
@@ -416,6 +420,7 @@ Singleton {
|
|||||||
isHyprland = false;
|
isHyprland = false;
|
||||||
isDwl = false;
|
isDwl = false;
|
||||||
isSway = false;
|
isSway = false;
|
||||||
|
isScroll = false;
|
||||||
isLabwc = false;
|
isLabwc = false;
|
||||||
compositor = "niri";
|
compositor = "niri";
|
||||||
console.info("CompositorService: Detected Niri with socket:", niriSocket);
|
console.info("CompositorService: Detected Niri with socket:", niriSocket);
|
||||||
@@ -425,13 +430,14 @@ Singleton {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (swaySocket && swaySocket.length > 0) {
|
if (swaySocket && swaySocket.length > 0 && !scrollSocket && scrollSocket.length == 0) {
|
||||||
Proc.runCommand("swaySocketCheck", ["test", "-S", swaySocket], (output, exitCode) => {
|
Proc.runCommand("swaySocketCheck", ["test", "-S", swaySocket], (output, exitCode) => {
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
isNiri = false;
|
isNiri = false;
|
||||||
isHyprland = false;
|
isHyprland = false;
|
||||||
isDwl = false;
|
isDwl = false;
|
||||||
isSway = true;
|
isSway = true;
|
||||||
|
isScroll = false;
|
||||||
isLabwc = false;
|
isLabwc = false;
|
||||||
compositor = "sway";
|
compositor = "sway";
|
||||||
console.info("CompositorService: Detected Sway with socket:", swaySocket);
|
console.info("CompositorService: Detected Sway with socket:", swaySocket);
|
||||||
@@ -440,11 +446,28 @@ Singleton {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (scrollSocket && scrollSocket.length > 0) {
|
||||||
|
Proc.runCommand("scrollSocketCheck", ["test", "-S", scrollSocket], (output, exitCode) => {
|
||||||
|
if (exitCode === 0) {
|
||||||
|
isNiri = false;
|
||||||
|
isHyprland = false;
|
||||||
|
isDwl = false;
|
||||||
|
isSway = false;
|
||||||
|
isScroll = true;
|
||||||
|
isLabwc = false;
|
||||||
|
compositor = "scroll";
|
||||||
|
console.info("CompositorService: Detected Scroll with socket:", scrollSocket);
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (labwcPid && labwcPid.length > 0) {
|
if (labwcPid && labwcPid.length > 0) {
|
||||||
isHyprland = false;
|
isHyprland = false;
|
||||||
isNiri = false;
|
isNiri = false;
|
||||||
isDwl = false;
|
isDwl = false;
|
||||||
isSway = false;
|
isSway = false;
|
||||||
|
isScroll = false;
|
||||||
isLabwc = true;
|
isLabwc = true;
|
||||||
compositor = "labwc";
|
compositor = "labwc";
|
||||||
console.info("CompositorService: Detected LabWC with PID:", labwcPid);
|
console.info("CompositorService: Detected LabWC with PID:", labwcPid);
|
||||||
@@ -458,6 +481,7 @@ Singleton {
|
|||||||
isNiri = false;
|
isNiri = false;
|
||||||
isDwl = false;
|
isDwl = false;
|
||||||
isSway = false;
|
isSway = false;
|
||||||
|
isScroll = false;
|
||||||
isLabwc = false;
|
isLabwc = false;
|
||||||
compositor = "unknown";
|
compositor = "unknown";
|
||||||
console.warn("CompositorService: No compositor detected");
|
console.warn("CompositorService: No compositor detected");
|
||||||
@@ -479,6 +503,7 @@ Singleton {
|
|||||||
isNiri = false;
|
isNiri = false;
|
||||||
isDwl = true;
|
isDwl = true;
|
||||||
isSway = false;
|
isSway = false;
|
||||||
|
isScroll = false;
|
||||||
isLabwc = false;
|
isLabwc = false;
|
||||||
compositor = "dwl";
|
compositor = "dwl";
|
||||||
console.info("CompositorService: Detected DWL via DMS capability");
|
console.info("CompositorService: Detected DWL via DMS capability");
|
||||||
@@ -492,7 +517,7 @@ Singleton {
|
|||||||
return Hyprland.dispatch("dpms off");
|
return Hyprland.dispatch("dpms off");
|
||||||
if (isDwl)
|
if (isDwl)
|
||||||
return _dwlPowerOffMonitors();
|
return _dwlPowerOffMonitors();
|
||||||
if (isSway) {
|
if (isSway || isScroll) {
|
||||||
try {
|
try {
|
||||||
I3.dispatch("output * dpms off");
|
I3.dispatch("output * dpms off");
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
@@ -511,7 +536,7 @@ Singleton {
|
|||||||
return Hyprland.dispatch("dpms on");
|
return Hyprland.dispatch("dpms on");
|
||||||
if (isDwl)
|
if (isDwl)
|
||||||
return _dwlPowerOnMonitors();
|
return _dwlPowerOnMonitors();
|
||||||
if (isSway) {
|
if (isSway || isScroll) {
|
||||||
try {
|
try {
|
||||||
I3.dispatch("output * dpms on");
|
I3.dispatch("output * dpms on");
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|||||||
@@ -15,81 +15,82 @@ Singleton {
|
|||||||
property string activeOutput: ""
|
property string activeOutput: ""
|
||||||
property var outputScales: ({})
|
property var outputScales: ({})
|
||||||
property string currentKeyboardLayout: {
|
property string currentKeyboardLayout: {
|
||||||
if (!outputs || !activeOutput) return ""
|
if (!outputs || !activeOutput)
|
||||||
const output = outputs[activeOutput]
|
return "";
|
||||||
return (output && output.kbLayout) || ""
|
const output = outputs[activeOutput];
|
||||||
|
return (output && output.kbLayout) || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
signal stateChanged()
|
signal stateChanged
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: DMSService
|
target: DMSService
|
||||||
function onCapabilitiesReceived() {
|
function onCapabilitiesReceived() {
|
||||||
checkCapabilities()
|
checkCapabilities();
|
||||||
}
|
}
|
||||||
function onConnectionStateChanged() {
|
function onConnectionStateChanged() {
|
||||||
if (DMSService.isConnected) {
|
if (DMSService.isConnected) {
|
||||||
checkCapabilities()
|
checkCapabilities();
|
||||||
} else {
|
} else {
|
||||||
dwlAvailable = false
|
dwlAvailable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function onDwlStateUpdate(data) {
|
function onDwlStateUpdate(data) {
|
||||||
if (dwlAvailable) {
|
if (dwlAvailable) {
|
||||||
handleStateUpdate(data)
|
handleStateUpdate(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
if (DMSService.dmsAvailable) {
|
if (DMSService.dmsAvailable) {
|
||||||
checkCapabilities()
|
checkCapabilities();
|
||||||
}
|
}
|
||||||
if (dwlAvailable) {
|
if (dwlAvailable) {
|
||||||
refreshOutputScales()
|
refreshOutputScales();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkCapabilities() {
|
function checkCapabilities() {
|
||||||
if (!DMSService.capabilities || !Array.isArray(DMSService.capabilities)) {
|
if (!DMSService.capabilities || !Array.isArray(DMSService.capabilities)) {
|
||||||
dwlAvailable = false
|
dwlAvailable = false;
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hasDwl = DMSService.capabilities.includes("dwl")
|
const hasDwl = DMSService.capabilities.includes("dwl");
|
||||||
if (hasDwl && !dwlAvailable) {
|
if (hasDwl && !dwlAvailable) {
|
||||||
dwlAvailable = true
|
dwlAvailable = true;
|
||||||
console.info("DwlService: DWL capability detected")
|
console.info("DwlService: DWL capability detected");
|
||||||
requestState()
|
requestState();
|
||||||
refreshOutputScales()
|
refreshOutputScales();
|
||||||
} else if (!hasDwl) {
|
} else if (!hasDwl) {
|
||||||
dwlAvailable = false
|
dwlAvailable = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function requestState() {
|
function requestState() {
|
||||||
if (!DMSService.isConnected || !dwlAvailable) {
|
if (!DMSService.isConnected || !dwlAvailable) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DMSService.sendRequest("dwl.getState", null, response => {
|
DMSService.sendRequest("dwl.getState", null, response => {
|
||||||
if (response.result) {
|
if (response.result) {
|
||||||
handleStateUpdate(response.result)
|
handleStateUpdate(response.result);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleStateUpdate(state) {
|
function handleStateUpdate(state) {
|
||||||
outputs = state.outputs || {}
|
outputs = state.outputs || {};
|
||||||
tagCount = state.tagCount || 9
|
tagCount = state.tagCount || 9;
|
||||||
layouts = state.layouts || []
|
layouts = state.layouts || [];
|
||||||
activeOutput = state.activeOutput || ""
|
activeOutput = state.activeOutput || "";
|
||||||
stateChanged()
|
stateChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
function setTags(outputName, tagmask, toggleTagset) {
|
function setTags(outputName, tagmask, toggleTagset) {
|
||||||
if (!DMSService.isConnected || !dwlAvailable) {
|
if (!DMSService.isConnected || !dwlAvailable) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DMSService.sendRequest("dwl.setTags", {
|
DMSService.sendRequest("dwl.setTags", {
|
||||||
@@ -98,14 +99,14 @@ Singleton {
|
|||||||
"toggleTagset": toggleTagset
|
"toggleTagset": toggleTagset
|
||||||
}, response => {
|
}, response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.warn("DwlService: setTags error:", response.error)
|
console.warn("DwlService: setTags error:", response.error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setClientTags(outputName, andTags, xorTags) {
|
function setClientTags(outputName, andTags, xorTags) {
|
||||||
if (!DMSService.isConnected || !dwlAvailable) {
|
if (!DMSService.isConnected || !dwlAvailable) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DMSService.sendRequest("dwl.setClientTags", {
|
DMSService.sendRequest("dwl.setClientTags", {
|
||||||
@@ -114,14 +115,14 @@ Singleton {
|
|||||||
"xorTags": xorTags
|
"xorTags": xorTags
|
||||||
}, response => {
|
}, response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.warn("DwlService: setClientTags error:", response.error)
|
console.warn("DwlService: setClientTags error:", response.error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLayout(outputName, index) {
|
function setLayout(outputName, index) {
|
||||||
if (!DMSService.isConnected || !dwlAvailable) {
|
if (!DMSService.isConnected || !dwlAvailable) {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DMSService.sendRequest("dwl.setLayout", {
|
DMSService.sendRequest("dwl.setLayout", {
|
||||||
@@ -129,77 +130,77 @@ Singleton {
|
|||||||
"index": index
|
"index": index
|
||||||
}, response => {
|
}, response => {
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
console.warn("DwlService: setLayout error:", response.error)
|
console.warn("DwlService: setLayout error:", response.error);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOutputState(outputName) {
|
function getOutputState(outputName) {
|
||||||
if (!outputs || !outputs[outputName]) {
|
if (!outputs || !outputs[outputName]) {
|
||||||
return null
|
return null;
|
||||||
}
|
}
|
||||||
return outputs[outputName]
|
return outputs[outputName];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getActiveTags(outputName) {
|
function getActiveTags(outputName) {
|
||||||
const output = getOutputState(outputName)
|
const output = getOutputState(outputName);
|
||||||
if (!output || !output.tags) {
|
if (!output || !output.tags) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
return output.tags.filter(tag => tag.state === 1).map(tag => tag.tag)
|
return output.tags.filter(tag => tag.state === 1).map(tag => tag.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTagsWithClients(outputName) {
|
function getTagsWithClients(outputName) {
|
||||||
const output = getOutputState(outputName)
|
const output = getOutputState(outputName);
|
||||||
if (!output || !output.tags) {
|
if (!output || !output.tags) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
return output.tags.filter(tag => tag.clients > 0).map(tag => tag.tag)
|
return output.tags.filter(tag => tag.clients > 0).map(tag => tag.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getUrgentTags(outputName) {
|
function getUrgentTags(outputName) {
|
||||||
const output = getOutputState(outputName)
|
const output = getOutputState(outputName);
|
||||||
if (!output || !output.tags) {
|
if (!output || !output.tags) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
return output.tags.filter(tag => tag.state === 2).map(tag => tag.tag)
|
return output.tags.filter(tag => tag.state === 2).map(tag => tag.tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
function switchToTag(outputName, tagIndex) {
|
function switchToTag(outputName, tagIndex) {
|
||||||
const tagmask = 1 << tagIndex
|
const tagmask = 1 << tagIndex;
|
||||||
setTags(outputName, tagmask, 0)
|
setTags(outputName, tagmask, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleTag(outputName, tagIndex) {
|
function toggleTag(outputName, tagIndex) {
|
||||||
const output = getOutputState(outputName)
|
const output = getOutputState(outputName);
|
||||||
if (!output || !output.tags) {
|
if (!output || !output.tags) {
|
||||||
console.log("toggleTag: no output or tags for", outputName)
|
console.log("toggleTag: no output or tags for", outputName);
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let currentMask = 0
|
let currentMask = 0;
|
||||||
output.tags.forEach(tag => {
|
output.tags.forEach(tag => {
|
||||||
if (tag.state === 1) {
|
if (tag.state === 1) {
|
||||||
currentMask |= (1 << tag.tag)
|
currentMask |= (1 << tag.tag);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
const clickedMask = 1 << tagIndex
|
const clickedMask = 1 << tagIndex;
|
||||||
const newMask = currentMask ^ clickedMask
|
const newMask = currentMask ^ clickedMask;
|
||||||
|
|
||||||
console.log("toggleTag:", outputName, "tag:", tagIndex, "currentMask:", currentMask.toString(2), "clickedMask:", clickedMask.toString(2), "newMask:", newMask.toString(2))
|
console.log("toggleTag:", outputName, "tag:", tagIndex, "currentMask:", currentMask.toString(2), "clickedMask:", clickedMask.toString(2), "newMask:", newMask.toString(2));
|
||||||
|
|
||||||
if (newMask === 0) {
|
if (newMask === 0) {
|
||||||
console.log("toggleTag: newMask is 0, switching to tag", tagIndex)
|
console.log("toggleTag: newMask is 0, switching to tag", tagIndex);
|
||||||
setTags(outputName, 1 << tagIndex, 0)
|
setTags(outputName, 1 << tagIndex, 0);
|
||||||
} else {
|
} else {
|
||||||
console.log("toggleTag: setting combined mask", newMask)
|
console.log("toggleTag: setting combined mask", newMask);
|
||||||
setTags(outputName, newMask, 0)
|
setTags(outputName, newMask, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function quit() {
|
function quit() {
|
||||||
Quickshell.execDetached(["mmsg", "-d", "quit"])
|
Quickshell.execDetached(["mmsg", "-d", "quit"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Process {
|
Process {
|
||||||
@@ -210,55 +211,56 @@ Singleton {
|
|||||||
stdout: StdioCollector {
|
stdout: StdioCollector {
|
||||||
onStreamFinished: {
|
onStreamFinished: {
|
||||||
try {
|
try {
|
||||||
const newScales = {}
|
const newScales = {};
|
||||||
const lines = text.trim().split('\n')
|
const lines = text.trim().split('\n');
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
const parts = line.trim().split(/\s+/)
|
const parts = line.trim().split(/\s+/);
|
||||||
if (parts.length >= 3 && parts[1] === "scale_factor") {
|
if (parts.length >= 3 && parts[1] === "scale_factor") {
|
||||||
const outputName = parts[0]
|
const outputName = parts[0];
|
||||||
const scale = parseFloat(parts[2])
|
const scale = parseFloat(parts[2]);
|
||||||
if (!isNaN(scale)) {
|
if (!isNaN(scale)) {
|
||||||
newScales[outputName] = scale
|
newScales[outputName] = scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
outputScales = newScales
|
outputScales = newScales;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.warn("DwlService: Failed to parse mmsg output:", e)
|
console.warn("DwlService: Failed to parse mmsg output:", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onExited: exitCode => {
|
onExited: exitCode => {
|
||||||
if (exitCode !== 0) {
|
if (exitCode !== 0) {
|
||||||
console.warn("DwlService: mmsg failed with exit code:", exitCode)
|
console.warn("DwlService: mmsg failed with exit code:", exitCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function refreshOutputScales() {
|
function refreshOutputScales() {
|
||||||
if (!dwlAvailable) return
|
if (!dwlAvailable)
|
||||||
scaleQueryProcess.running = true
|
return;
|
||||||
|
scaleQueryProcess.running = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getOutputScale(outputName) {
|
function getOutputScale(outputName) {
|
||||||
return outputScales[outputName]
|
return outputScales[outputName];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getVisibleTags(outputName) {
|
function getVisibleTags(outputName) {
|
||||||
const output = getOutputState(outputName)
|
const output = getOutputState(outputName);
|
||||||
if (!output || !output.tags) {
|
if (!output || !output.tags) {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const visibleTags = new Set()
|
const visibleTags = new Set();
|
||||||
|
|
||||||
output.tags.forEach(tag => {
|
output.tags.forEach(tag => {
|
||||||
if (tag.state === 1 || tag.clients > 0) {
|
if (tag.state === 1 || tag.clients > 0) {
|
||||||
visibleTags.add(tag.tag)
|
visibleTags.add(tag.tag);
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
return Array.from(visibleTags).sort((a, b) => a - b)
|
return Array.from(visibleTags).sort((a, b) => a - b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ Singleton {
|
|||||||
const hasExtWorkspace = DMSService.capabilities.includes("extworkspace")
|
const hasExtWorkspace = DMSService.capabilities.includes("extworkspace")
|
||||||
if (hasExtWorkspace && !extWorkspaceAvailable) {
|
if (hasExtWorkspace && !extWorkspaceAvailable) {
|
||||||
if (typeof CompositorService !== "undefined") {
|
if (typeof CompositorService !== "undefined") {
|
||||||
const useExtWorkspace = DMSService.forceExtWorkspace || (!CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isDwl && !CompositorService.isSway)
|
const useExtWorkspace = DMSService.forceExtWorkspace || (!CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isDwl && !CompositorService.isSway && !CompositorService.isScroll)
|
||||||
if (!useExtWorkspace) {
|
if (!useExtWorkspace) {
|
||||||
console.info("ExtWorkspaceService: ext-workspace available but compositor has native support")
|
console.info("ExtWorkspaceService: ext-workspace available but compositor has native support")
|
||||||
extWorkspaceAvailable = false
|
extWorkspaceAvailable = false
|
||||||
|
|||||||
@@ -110,9 +110,9 @@ Singleton {
|
|||||||
|
|
||||||
onExited: function (exitCode) {
|
onExited: function (exitCode) {
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
nvidiaCommand = "prime-run"
|
nvidiaCommand = "prime-run";
|
||||||
} else {
|
} else {
|
||||||
detectNvidiaOffloadProcess.running = true
|
detectNvidiaOffloadProcess.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ Singleton {
|
|||||||
|
|
||||||
onExited: function (exitCode) {
|
onExited: function (exitCode) {
|
||||||
if (exitCode === 0) {
|
if (exitCode === 0) {
|
||||||
nvidiaCommand = "nvidia-offload"
|
nvidiaCommand = "nvidia-offload";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,7 +243,7 @@ Singleton {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (CompositorService.isSway) {
|
if (CompositorService.isSway || CompositorService.isScroll) {
|
||||||
try {
|
try {
|
||||||
I3.dispatch("exit");
|
I3.dispatch("exit");
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user