1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-06-16 16:15:23 -04:00

Compare commits

..

3 Commits

Author SHA1 Message Date
bbedward cd672c341f settings: add DankSpinner, re-org some settings 2026-06-10 18:53:43 -04:00
bbedward 12438d63c2 mango: remove legacy dwl service 2026-06-10 17:01:03 -04:00
Ralph Zhou 35255e4053 fix(lock): bypass IME for password input (#2609) 2026-06-10 16:29:05 -04:00
83 changed files with 5141 additions and 7709 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ func runResolveInclude(cmd *cobra.Command, args []string) {
result, err = checkHyprlandInclude(filename)
case "niri":
result, err = checkNiriInclude(filename)
case "mangowc", "dwl", "mango":
case "mangowc", "mango":
result, err = checkMangoWCInclude(filename)
default:
log.Fatalf("Unknown compositor: %s", compositor)
+2 -2
View File
@@ -39,7 +39,7 @@ Modes:
full - Capture the focused output
all - Capture all outputs combined
output - Capture a specific output by name
window - Capture the focused window (Hyprland/DWL)
window - Capture the focused window (Hyprland/Mango)
last - Capture the last selected region
Output format (--format):
@@ -97,7 +97,7 @@ If no previous region exists, falls back to interactive selection.`,
var ssWindowCmd = &cobra.Command{
Use: "window",
Short: "Capture the focused window",
Long: `Capture the currently focused window. Supported on Hyprland and DWL.`,
Long: `Capture the currently focused window. Supported on Hyprland and Mango.`,
Run: runScreenshotWindow,
}
-791
View File
@@ -1,791 +0,0 @@
// Generated by go-wayland-scanner
// https://github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/cmd/go-wayland-scanner
// XML file : internal/proto/xml/dwl-ipc-unstable-v2.xml
//
// dwl_ipc_unstable_v2 Protocol Copyright:
package dwl_ipc
import "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
// ZdwlIpcManagerV2InterfaceName is the name of the interface as it appears in the [client.Registry].
// It can be used to match the [client.RegistryGlobalEvent.Interface] in the
// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies.
const ZdwlIpcManagerV2InterfaceName = "zdwl_ipc_manager_v2"
// ZdwlIpcManagerV2 : manage dwl state
//
// This interface is exposed as a global in wl_registry.
//
// Clients can use this interface to get a dwl_ipc_output.
// After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events.
// The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client.
type ZdwlIpcManagerV2 struct {
client.BaseProxy
tagsHandler ZdwlIpcManagerV2TagsHandlerFunc
layoutHandler ZdwlIpcManagerV2LayoutHandlerFunc
}
// NewZdwlIpcManagerV2 : manage dwl state
//
// This interface is exposed as a global in wl_registry.
//
// Clients can use this interface to get a dwl_ipc_output.
// After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events.
// The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client.
func NewZdwlIpcManagerV2(ctx *client.Context) *ZdwlIpcManagerV2 {
zdwlIpcManagerV2 := &ZdwlIpcManagerV2{}
ctx.Register(zdwlIpcManagerV2)
return zdwlIpcManagerV2
}
// Release : release dwl_ipc_manager
//
// Indicates that the client will not the dwl_ipc_manager object anymore.
// Objects created through this instance are not affected.
func (i *ZdwlIpcManagerV2) Release() error {
defer i.MarkZombie()
const opcode = 0
const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return err
}
// GetOutput : get a dwl_ipc_outout for a wl_output
//
// Get a dwl_ipc_outout for the specified wl_output.
func (i *ZdwlIpcManagerV2) GetOutput(output *client.Output) (*ZdwlIpcOutputV2, error) {
id := NewZdwlIpcOutputV2(i.Context())
const opcode = 1
const _reqBufLen = 8 + 4 + 4
var _reqBuf [_reqBufLen]byte
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
client.PutUint32(_reqBuf[l:l+4], id.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], output.ID())
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return id, err
}
// ZdwlIpcManagerV2TagsEvent : Announces tag amount
//
// This event is sent after binding.
// A roundtrip after binding guarantees the client recieved all tags.
type ZdwlIpcManagerV2TagsEvent struct {
Amount uint32
}
type ZdwlIpcManagerV2TagsHandlerFunc func(ZdwlIpcManagerV2TagsEvent)
// SetTagsHandler : sets handler for ZdwlIpcManagerV2TagsEvent
func (i *ZdwlIpcManagerV2) SetTagsHandler(f ZdwlIpcManagerV2TagsHandlerFunc) {
i.tagsHandler = f
}
// ZdwlIpcManagerV2LayoutEvent : Announces a layout
//
// This event is sent after binding.
// A roundtrip after binding guarantees the client recieved all layouts.
type ZdwlIpcManagerV2LayoutEvent struct {
Name string
}
type ZdwlIpcManagerV2LayoutHandlerFunc func(ZdwlIpcManagerV2LayoutEvent)
// SetLayoutHandler : sets handler for ZdwlIpcManagerV2LayoutEvent
func (i *ZdwlIpcManagerV2) SetLayoutHandler(f ZdwlIpcManagerV2LayoutHandlerFunc) {
i.layoutHandler = f
}
func (i *ZdwlIpcManagerV2) Dispatch(opcode uint32, fd int, data []byte) {
switch opcode {
case 0:
if i.tagsHandler == nil {
return
}
var e ZdwlIpcManagerV2TagsEvent
l := 0
e.Amount = client.Uint32(data[l : l+4])
l += 4
i.tagsHandler(e)
case 1:
if i.layoutHandler == nil {
return
}
var e ZdwlIpcManagerV2LayoutEvent
l := 0
nameLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
l += 4
e.Name = client.String(data[l : l+nameLen])
l += nameLen
i.layoutHandler(e)
}
}
// ZdwlIpcOutputV2InterfaceName is the name of the interface as it appears in the [client.Registry].
// It can be used to match the [client.RegistryGlobalEvent.Interface] in the
// [Registry.SetGlobalHandler] and can be used in [Registry.Bind] if this applies.
const ZdwlIpcOutputV2InterfaceName = "zdwl_ipc_output_v2"
// ZdwlIpcOutputV2 : control dwl output
//
// Observe and control a dwl output.
//
// Events are double-buffered:
// Clients should cache events and redraw when a dwl_ipc_output.frame event is sent.
//
// Request are not double-buffered:
// The compositor will update immediately upon request.
type ZdwlIpcOutputV2 struct {
client.BaseProxy
toggleVisibilityHandler ZdwlIpcOutputV2ToggleVisibilityHandlerFunc
activeHandler ZdwlIpcOutputV2ActiveHandlerFunc
tagHandler ZdwlIpcOutputV2TagHandlerFunc
layoutHandler ZdwlIpcOutputV2LayoutHandlerFunc
titleHandler ZdwlIpcOutputV2TitleHandlerFunc
appidHandler ZdwlIpcOutputV2AppidHandlerFunc
layoutSymbolHandler ZdwlIpcOutputV2LayoutSymbolHandlerFunc
frameHandler ZdwlIpcOutputV2FrameHandlerFunc
fullscreenHandler ZdwlIpcOutputV2FullscreenHandlerFunc
floatingHandler ZdwlIpcOutputV2FloatingHandlerFunc
xHandler ZdwlIpcOutputV2XHandlerFunc
yHandler ZdwlIpcOutputV2YHandlerFunc
widthHandler ZdwlIpcOutputV2WidthHandlerFunc
heightHandler ZdwlIpcOutputV2HeightHandlerFunc
lastLayerHandler ZdwlIpcOutputV2LastLayerHandlerFunc
kbLayoutHandler ZdwlIpcOutputV2KbLayoutHandlerFunc
keymodeHandler ZdwlIpcOutputV2KeymodeHandlerFunc
scalefactorHandler ZdwlIpcOutputV2ScalefactorHandlerFunc
}
// NewZdwlIpcOutputV2 : control dwl output
//
// Observe and control a dwl output.
//
// Events are double-buffered:
// Clients should cache events and redraw when a dwl_ipc_output.frame event is sent.
//
// Request are not double-buffered:
// The compositor will update immediately upon request.
func NewZdwlIpcOutputV2(ctx *client.Context) *ZdwlIpcOutputV2 {
zdwlIpcOutputV2 := &ZdwlIpcOutputV2{}
ctx.Register(zdwlIpcOutputV2)
return zdwlIpcOutputV2
}
// Release : release dwl_ipc_outout
//
// Indicates to that the client no longer needs this dwl_ipc_output.
func (i *ZdwlIpcOutputV2) Release() error {
defer i.MarkZombie()
const opcode = 0
const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return err
}
// SetTags : Set the active tags of this output
//
// tagmask: bitmask of the tags that should be set.
// toggleTagset: toggle the selected tagset, zero for invalid, nonzero for valid.
func (i *ZdwlIpcOutputV2) SetTags(tagmask, toggleTagset uint32) error {
const opcode = 1
const _reqBufLen = 8 + 4 + 4
var _reqBuf [_reqBufLen]byte
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(tagmask))
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(toggleTagset))
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return err
}
// SetClientTags : Set the tags of the focused client.
//
// The tags are updated as follows:
// new_tags = (current_tags AND and_tags) XOR xor_tags
func (i *ZdwlIpcOutputV2) SetClientTags(andTags, xorTags uint32) error {
const opcode = 2
const _reqBufLen = 8 + 4 + 4
var _reqBuf [_reqBufLen]byte
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(andTags))
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(xorTags))
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return err
}
// SetLayout : Set the layout of this output
//
// index: index of a layout recieved by dwl_ipc_manager.layout
func (i *ZdwlIpcOutputV2) SetLayout(index uint32) error {
const opcode = 3
const _reqBufLen = 8 + 4
var _reqBuf [_reqBufLen]byte
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(index))
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return err
}
// Quit : Quit mango
// This request allows clients to instruct the compositor to quit mango.
func (i *ZdwlIpcOutputV2) Quit() error {
const opcode = 4
const _reqBufLen = 8
var _reqBuf [_reqBufLen]byte
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return err
}
// SendDispatch : Set the active tags of this output
//
// dispatch: dispatch name.
// arg1: arg1.
// arg2: arg2.
// arg3: arg3.
// arg4: arg4.
// arg5: arg5.
func (i *ZdwlIpcOutputV2) SendDispatch(dispatch, arg1, arg2, arg3, arg4, arg5 string) error {
const opcode = 5
dispatchLen := client.PaddedLen(len(dispatch) + 1)
arg1Len := client.PaddedLen(len(arg1) + 1)
arg2Len := client.PaddedLen(len(arg2) + 1)
arg3Len := client.PaddedLen(len(arg3) + 1)
arg4Len := client.PaddedLen(len(arg4) + 1)
arg5Len := client.PaddedLen(len(arg5) + 1)
_reqBufLen := 8 + (4 + dispatchLen) + (4 + arg1Len) + (4 + arg2Len) + (4 + arg3Len) + (4 + arg4Len) + (4 + arg5Len)
_reqBuf := make([]byte, _reqBufLen)
l := 0
client.PutUint32(_reqBuf[l:4], i.ID())
l += 4
client.PutUint32(_reqBuf[l:l+4], uint32(_reqBufLen<<16|opcode&0x0000ffff))
l += 4
client.PutString(_reqBuf[l:l+(4+dispatchLen)], dispatch)
l += (4 + dispatchLen)
client.PutString(_reqBuf[l:l+(4+arg1Len)], arg1)
l += (4 + arg1Len)
client.PutString(_reqBuf[l:l+(4+arg2Len)], arg2)
l += (4 + arg2Len)
client.PutString(_reqBuf[l:l+(4+arg3Len)], arg3)
l += (4 + arg3Len)
client.PutString(_reqBuf[l:l+(4+arg4Len)], arg4)
l += (4 + arg4Len)
client.PutString(_reqBuf[l:l+(4+arg5Len)], arg5)
l += (4 + arg5Len)
err := i.Context().WriteMsg(_reqBuf, nil)
return err
}
type ZdwlIpcOutputV2TagState uint32
// ZdwlIpcOutputV2TagState :
const (
// ZdwlIpcOutputV2TagStateNone : no state
ZdwlIpcOutputV2TagStateNone ZdwlIpcOutputV2TagState = 0
// ZdwlIpcOutputV2TagStateActive : tag is active
ZdwlIpcOutputV2TagStateActive ZdwlIpcOutputV2TagState = 1
// ZdwlIpcOutputV2TagStateUrgent : tag has at least one urgent client
ZdwlIpcOutputV2TagStateUrgent ZdwlIpcOutputV2TagState = 2
)
func (e ZdwlIpcOutputV2TagState) Name() string {
switch e {
case ZdwlIpcOutputV2TagStateNone:
return "none"
case ZdwlIpcOutputV2TagStateActive:
return "active"
case ZdwlIpcOutputV2TagStateUrgent:
return "urgent"
default:
return ""
}
}
func (e ZdwlIpcOutputV2TagState) Value() string {
switch e {
case ZdwlIpcOutputV2TagStateNone:
return "0"
case ZdwlIpcOutputV2TagStateActive:
return "1"
case ZdwlIpcOutputV2TagStateUrgent:
return "2"
default:
return ""
}
}
func (e ZdwlIpcOutputV2TagState) String() string {
return e.Name() + "=" + e.Value()
}
// ZdwlIpcOutputV2ToggleVisibilityEvent : Toggle client visibilty
//
// Indicates the client should hide or show themselves.
// If the client is visible then hide, if hidden then show.
type ZdwlIpcOutputV2ToggleVisibilityEvent struct{}
type ZdwlIpcOutputV2ToggleVisibilityHandlerFunc func(ZdwlIpcOutputV2ToggleVisibilityEvent)
// SetToggleVisibilityHandler : sets handler for ZdwlIpcOutputV2ToggleVisibilityEvent
func (i *ZdwlIpcOutputV2) SetToggleVisibilityHandler(f ZdwlIpcOutputV2ToggleVisibilityHandlerFunc) {
i.toggleVisibilityHandler = f
}
// ZdwlIpcOutputV2ActiveEvent : Update the selected output.
//
// Indicates if the output is active. Zero is invalid, nonzero is valid.
type ZdwlIpcOutputV2ActiveEvent struct {
Active uint32
}
type ZdwlIpcOutputV2ActiveHandlerFunc func(ZdwlIpcOutputV2ActiveEvent)
// SetActiveHandler : sets handler for ZdwlIpcOutputV2ActiveEvent
func (i *ZdwlIpcOutputV2) SetActiveHandler(f ZdwlIpcOutputV2ActiveHandlerFunc) {
i.activeHandler = f
}
// ZdwlIpcOutputV2TagEvent : Update the state of a tag.
//
// Indicates that a tag has been updated.
type ZdwlIpcOutputV2TagEvent struct {
Tag uint32
State uint32
Clients uint32
Focused uint32
}
type ZdwlIpcOutputV2TagHandlerFunc func(ZdwlIpcOutputV2TagEvent)
// SetTagHandler : sets handler for ZdwlIpcOutputV2TagEvent
func (i *ZdwlIpcOutputV2) SetTagHandler(f ZdwlIpcOutputV2TagHandlerFunc) {
i.tagHandler = f
}
// ZdwlIpcOutputV2LayoutEvent : Update the layout.
//
// Indicates a new layout is selected.
type ZdwlIpcOutputV2LayoutEvent struct {
Layout uint32
}
type ZdwlIpcOutputV2LayoutHandlerFunc func(ZdwlIpcOutputV2LayoutEvent)
// SetLayoutHandler : sets handler for ZdwlIpcOutputV2LayoutEvent
func (i *ZdwlIpcOutputV2) SetLayoutHandler(f ZdwlIpcOutputV2LayoutHandlerFunc) {
i.layoutHandler = f
}
// ZdwlIpcOutputV2TitleEvent : Update the title.
//
// Indicates the title has changed.
type ZdwlIpcOutputV2TitleEvent struct {
Title string
}
type ZdwlIpcOutputV2TitleHandlerFunc func(ZdwlIpcOutputV2TitleEvent)
// SetTitleHandler : sets handler for ZdwlIpcOutputV2TitleEvent
func (i *ZdwlIpcOutputV2) SetTitleHandler(f ZdwlIpcOutputV2TitleHandlerFunc) {
i.titleHandler = f
}
// ZdwlIpcOutputV2AppidEvent : Update the appid.
//
// Indicates the appid has changed.
type ZdwlIpcOutputV2AppidEvent struct {
Appid string
}
type ZdwlIpcOutputV2AppidHandlerFunc func(ZdwlIpcOutputV2AppidEvent)
// SetAppidHandler : sets handler for ZdwlIpcOutputV2AppidEvent
func (i *ZdwlIpcOutputV2) SetAppidHandler(f ZdwlIpcOutputV2AppidHandlerFunc) {
i.appidHandler = f
}
// ZdwlIpcOutputV2LayoutSymbolEvent : Update the current layout symbol
//
// Indicates the layout has changed. Since layout symbols are dynamic.
// As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying.
// You can ignore the zdwl_ipc_output.layout event.
type ZdwlIpcOutputV2LayoutSymbolEvent struct {
Layout string
}
type ZdwlIpcOutputV2LayoutSymbolHandlerFunc func(ZdwlIpcOutputV2LayoutSymbolEvent)
// SetLayoutSymbolHandler : sets handler for ZdwlIpcOutputV2LayoutSymbolEvent
func (i *ZdwlIpcOutputV2) SetLayoutSymbolHandler(f ZdwlIpcOutputV2LayoutSymbolHandlerFunc) {
i.layoutSymbolHandler = f
}
// ZdwlIpcOutputV2FrameEvent : The update sequence is done.
//
// Indicates that a sequence of status updates have finished and the client should redraw.
type ZdwlIpcOutputV2FrameEvent struct{}
type ZdwlIpcOutputV2FrameHandlerFunc func(ZdwlIpcOutputV2FrameEvent)
// SetFrameHandler : sets handler for ZdwlIpcOutputV2FrameEvent
func (i *ZdwlIpcOutputV2) SetFrameHandler(f ZdwlIpcOutputV2FrameHandlerFunc) {
i.frameHandler = f
}
// ZdwlIpcOutputV2FullscreenEvent : Update fullscreen status
//
// Indicates if the selected client on this output is fullscreen.
type ZdwlIpcOutputV2FullscreenEvent struct {
IsFullscreen uint32
}
type ZdwlIpcOutputV2FullscreenHandlerFunc func(ZdwlIpcOutputV2FullscreenEvent)
// SetFullscreenHandler : sets handler for ZdwlIpcOutputV2FullscreenEvent
func (i *ZdwlIpcOutputV2) SetFullscreenHandler(f ZdwlIpcOutputV2FullscreenHandlerFunc) {
i.fullscreenHandler = f
}
// ZdwlIpcOutputV2FloatingEvent : Update the floating status
//
// Indicates if the selected client on this output is floating.
type ZdwlIpcOutputV2FloatingEvent struct {
IsFloating uint32
}
type ZdwlIpcOutputV2FloatingHandlerFunc func(ZdwlIpcOutputV2FloatingEvent)
// SetFloatingHandler : sets handler for ZdwlIpcOutputV2FloatingEvent
func (i *ZdwlIpcOutputV2) SetFloatingHandler(f ZdwlIpcOutputV2FloatingHandlerFunc) {
i.floatingHandler = f
}
// ZdwlIpcOutputV2XEvent : Update the x coordinates
//
// Indicates if x coordinates of the selected client.
type ZdwlIpcOutputV2XEvent struct {
X int32
}
type ZdwlIpcOutputV2XHandlerFunc func(ZdwlIpcOutputV2XEvent)
// SetXHandler : sets handler for ZdwlIpcOutputV2XEvent
func (i *ZdwlIpcOutputV2) SetXHandler(f ZdwlIpcOutputV2XHandlerFunc) {
i.xHandler = f
}
// ZdwlIpcOutputV2YEvent : Update the y coordinates
//
// Indicates if y coordinates of the selected client.
type ZdwlIpcOutputV2YEvent struct {
Y int32
}
type ZdwlIpcOutputV2YHandlerFunc func(ZdwlIpcOutputV2YEvent)
// SetYHandler : sets handler for ZdwlIpcOutputV2YEvent
func (i *ZdwlIpcOutputV2) SetYHandler(f ZdwlIpcOutputV2YHandlerFunc) {
i.yHandler = f
}
// ZdwlIpcOutputV2WidthEvent : Update the width
//
// Indicates if width of the selected client.
type ZdwlIpcOutputV2WidthEvent struct {
Width int32
}
type ZdwlIpcOutputV2WidthHandlerFunc func(ZdwlIpcOutputV2WidthEvent)
// SetWidthHandler : sets handler for ZdwlIpcOutputV2WidthEvent
func (i *ZdwlIpcOutputV2) SetWidthHandler(f ZdwlIpcOutputV2WidthHandlerFunc) {
i.widthHandler = f
}
// ZdwlIpcOutputV2HeightEvent : Update the height
//
// Indicates if height of the selected client.
type ZdwlIpcOutputV2HeightEvent struct {
Height int32
}
type ZdwlIpcOutputV2HeightHandlerFunc func(ZdwlIpcOutputV2HeightEvent)
// SetHeightHandler : sets handler for ZdwlIpcOutputV2HeightEvent
func (i *ZdwlIpcOutputV2) SetHeightHandler(f ZdwlIpcOutputV2HeightHandlerFunc) {
i.heightHandler = f
}
// ZdwlIpcOutputV2LastLayerEvent : last map layer.
//
// last map layer.
type ZdwlIpcOutputV2LastLayerEvent struct {
LastLayer string
}
type ZdwlIpcOutputV2LastLayerHandlerFunc func(ZdwlIpcOutputV2LastLayerEvent)
// SetLastLayerHandler : sets handler for ZdwlIpcOutputV2LastLayerEvent
func (i *ZdwlIpcOutputV2) SetLastLayerHandler(f ZdwlIpcOutputV2LastLayerHandlerFunc) {
i.lastLayerHandler = f
}
// ZdwlIpcOutputV2KbLayoutEvent : current keyboard layout.
//
// current keyboard layout.
type ZdwlIpcOutputV2KbLayoutEvent struct {
KbLayout string
}
type ZdwlIpcOutputV2KbLayoutHandlerFunc func(ZdwlIpcOutputV2KbLayoutEvent)
// SetKbLayoutHandler : sets handler for ZdwlIpcOutputV2KbLayoutEvent
func (i *ZdwlIpcOutputV2) SetKbLayoutHandler(f ZdwlIpcOutputV2KbLayoutHandlerFunc) {
i.kbLayoutHandler = f
}
// ZdwlIpcOutputV2KeymodeEvent : current keybind mode.
//
// current keybind mode.
type ZdwlIpcOutputV2KeymodeEvent struct {
Keymode string
}
type ZdwlIpcOutputV2KeymodeHandlerFunc func(ZdwlIpcOutputV2KeymodeEvent)
// SetKeymodeHandler : sets handler for ZdwlIpcOutputV2KeymodeEvent
func (i *ZdwlIpcOutputV2) SetKeymodeHandler(f ZdwlIpcOutputV2KeymodeHandlerFunc) {
i.keymodeHandler = f
}
// ZdwlIpcOutputV2ScalefactorEvent : scale factor of monitor.
//
// scale factor of monitor.
type ZdwlIpcOutputV2ScalefactorEvent struct {
Scalefactor uint32
}
type ZdwlIpcOutputV2ScalefactorHandlerFunc func(ZdwlIpcOutputV2ScalefactorEvent)
// SetScalefactorHandler : sets handler for ZdwlIpcOutputV2ScalefactorEvent
func (i *ZdwlIpcOutputV2) SetScalefactorHandler(f ZdwlIpcOutputV2ScalefactorHandlerFunc) {
i.scalefactorHandler = f
}
func (i *ZdwlIpcOutputV2) Dispatch(opcode uint32, fd int, data []byte) {
switch opcode {
case 0:
if i.toggleVisibilityHandler == nil {
return
}
var e ZdwlIpcOutputV2ToggleVisibilityEvent
i.toggleVisibilityHandler(e)
case 1:
if i.activeHandler == nil {
return
}
var e ZdwlIpcOutputV2ActiveEvent
l := 0
e.Active = client.Uint32(data[l : l+4])
l += 4
i.activeHandler(e)
case 2:
if i.tagHandler == nil {
return
}
var e ZdwlIpcOutputV2TagEvent
l := 0
e.Tag = client.Uint32(data[l : l+4])
l += 4
e.State = client.Uint32(data[l : l+4])
l += 4
e.Clients = client.Uint32(data[l : l+4])
l += 4
e.Focused = client.Uint32(data[l : l+4])
l += 4
i.tagHandler(e)
case 3:
if i.layoutHandler == nil {
return
}
var e ZdwlIpcOutputV2LayoutEvent
l := 0
e.Layout = client.Uint32(data[l : l+4])
l += 4
i.layoutHandler(e)
case 4:
if i.titleHandler == nil {
return
}
var e ZdwlIpcOutputV2TitleEvent
l := 0
titleLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
l += 4
e.Title = client.String(data[l : l+titleLen])
l += titleLen
i.titleHandler(e)
case 5:
if i.appidHandler == nil {
return
}
var e ZdwlIpcOutputV2AppidEvent
l := 0
appidLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
l += 4
e.Appid = client.String(data[l : l+appidLen])
l += appidLen
i.appidHandler(e)
case 6:
if i.layoutSymbolHandler == nil {
return
}
var e ZdwlIpcOutputV2LayoutSymbolEvent
l := 0
layoutLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
l += 4
e.Layout = client.String(data[l : l+layoutLen])
l += layoutLen
i.layoutSymbolHandler(e)
case 7:
if i.frameHandler == nil {
return
}
var e ZdwlIpcOutputV2FrameEvent
i.frameHandler(e)
case 8:
if i.fullscreenHandler == nil {
return
}
var e ZdwlIpcOutputV2FullscreenEvent
l := 0
e.IsFullscreen = client.Uint32(data[l : l+4])
l += 4
i.fullscreenHandler(e)
case 9:
if i.floatingHandler == nil {
return
}
var e ZdwlIpcOutputV2FloatingEvent
l := 0
e.IsFloating = client.Uint32(data[l : l+4])
l += 4
i.floatingHandler(e)
case 10:
if i.xHandler == nil {
return
}
var e ZdwlIpcOutputV2XEvent
l := 0
e.X = int32(client.Uint32(data[l : l+4]))
l += 4
i.xHandler(e)
case 11:
if i.yHandler == nil {
return
}
var e ZdwlIpcOutputV2YEvent
l := 0
e.Y = int32(client.Uint32(data[l : l+4]))
l += 4
i.yHandler(e)
case 12:
if i.widthHandler == nil {
return
}
var e ZdwlIpcOutputV2WidthEvent
l := 0
e.Width = int32(client.Uint32(data[l : l+4]))
l += 4
i.widthHandler(e)
case 13:
if i.heightHandler == nil {
return
}
var e ZdwlIpcOutputV2HeightEvent
l := 0
e.Height = int32(client.Uint32(data[l : l+4]))
l += 4
i.heightHandler(e)
case 14:
if i.lastLayerHandler == nil {
return
}
var e ZdwlIpcOutputV2LastLayerEvent
l := 0
lastLayerLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
l += 4
e.LastLayer = client.String(data[l : l+lastLayerLen])
l += lastLayerLen
i.lastLayerHandler(e)
case 15:
if i.kbLayoutHandler == nil {
return
}
var e ZdwlIpcOutputV2KbLayoutEvent
l := 0
kbLayoutLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
l += 4
e.KbLayout = client.String(data[l : l+kbLayoutLen])
l += kbLayoutLen
i.kbLayoutHandler(e)
case 16:
if i.keymodeHandler == nil {
return
}
var e ZdwlIpcOutputV2KeymodeEvent
l := 0
keymodeLen := client.PaddedLen(int(client.Uint32(data[l : l+4])))
l += 4
e.Keymode = client.String(data[l : l+keymodeLen])
l += keymodeLen
i.keymodeHandler(e)
case 17:
if i.scalefactorHandler == nil {
return
}
var e ZdwlIpcOutputV2ScalefactorEvent
l := 0
e.Scalefactor = client.Uint32(data[l : l+4])
l += 4
i.scalefactorHandler(e)
}
}
@@ -0,0 +1,25 @@
package qmlchecks
import (
"os"
"regexp"
"strings"
"testing"
)
func TestLockScreenPasswordFieldBypassesTextInputIME(t *testing.T) {
data, err := os.ReadFile("../../../quickshell/Modules/Lock/LockScreenContent.qml")
if err != nil {
t.Fatalf("read lock screen QML: %v", err)
}
content := string(data)
textInputPasswordField := regexp.MustCompile(`(?s)TextInput\s*\{[^{}]*id:\s*passwordField`)
if textInputPasswordField.MatchString(content) {
t.Fatalf("passwordField must not be a TextInput because TextInput can route physical keyboard input through IME")
}
if !strings.Contains(content, "Keys.onPressed") || !strings.Contains(content, "event.text") {
t.Fatalf("passwordField should handle physical key text manually instead of relying on a text input control")
}
}
+107 -325
View File
@@ -6,7 +6,6 @@ import (
"os"
"os/exec"
"github.com/AvengeMedia/DankMaterialShell/core/internal/proto/dwl_ipc"
"github.com/AvengeMedia/DankMaterialShell/core/internal/proto/wlr_output_management"
wlhelpers "github.com/AvengeMedia/DankMaterialShell/core/internal/wayland/client"
"github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
@@ -19,9 +18,9 @@ const (
CompositorHyprland
CompositorSway
CompositorNiri
CompositorDWL
CompositorScroll
CompositorMiracle
CompositorMango
)
var detectedCompositor Compositor = -1
@@ -36,8 +35,14 @@ func DetectCompositor() Compositor {
swaySocket := os.Getenv("SWAYSOCK")
scrollSocket := os.Getenv("SCROLLSOCK")
miracleSocket := os.Getenv("MIRACLESOCK")
mangoSocket := os.Getenv("MANGO_INSTANCE_SIGNATURE")
switch {
case mangoSocket != "":
if _, err := os.Stat(mangoSocket); err == nil {
detectedCompositor = CompositorMango
return detectedCompositor
}
case niriSocket != "":
if _, err := os.Stat(niriSocket); err == nil {
detectedCompositor = CompositorNiri
@@ -63,66 +68,29 @@ func DetectCompositor() Compositor {
return detectedCompositor
}
if detectDWLProtocol() {
detectedCompositor = CompositorDWL
return detectedCompositor
}
detectedCompositor = CompositorUnknown
return detectedCompositor
}
func detectDWLProtocol() bool {
display, err := client.Connect("")
if err != nil {
return false
}
ctx := display.Context()
defer ctx.Close()
registry, err := display.GetRegistry()
if err != nil {
return false
}
found := false
registry.SetGlobalHandler(func(e client.RegistryGlobalEvent) {
if e.Interface == dwl_ipc.ZdwlIpcManagerV2InterfaceName {
found = true
}
})
if err := wlhelpers.Roundtrip(display, ctx); err != nil {
return false
}
return found
}
func SetCompositorDWL() {
detectedCompositor = CompositorDWL
}
type WindowGeometry struct {
X int32
Y int32
Width int32
Height int32
Output string
Scale float64
OutputX int32
OutputY int32
OutputTransform int32
X int32
Y int32
Width int32
Height int32
Output string
Scale float64
OutputX int32
OutputY int32
}
func GetActiveWindow() (*WindowGeometry, error) {
switch DetectCompositor() {
case CompositorHyprland:
return getHyprlandActiveWindow()
case CompositorDWL:
return getDWLActiveWindow()
case CompositorMango:
return getMangoActiveWindow()
default:
return nil, fmt.Errorf("window capture requires Hyprland or DWL")
return nil, fmt.Errorf("window capture requires Hyprland or Mango")
}
}
@@ -285,6 +253,93 @@ func getMiracleFocusedMonitor() string {
return ""
}
type mangoMonitor struct {
Name string `json:"name"`
Active bool `json:"active"`
X int32 `json:"x"`
Y int32 `json:"y"`
Scale float64 `json:"scale"`
}
func getMangoMonitors() []mangoMonitor {
output, err := exec.Command("mmsg", "get", "all-monitors").Output()
if err != nil {
return nil
}
var data struct {
Monitors []mangoMonitor `json:"monitors"`
}
if err := json.Unmarshal(output, &data); err != nil {
return nil
}
return data.Monitors
}
func getMangoFocusedMonitor() string {
for _, m := range getMangoMonitors() {
if m.Active {
return m.Name
}
}
return ""
}
type mangoClient struct {
Monitor string `json:"monitor"`
IsFocused bool `json:"is_focused"`
X int32 `json:"x"`
Y int32 `json:"y"`
Width int32 `json:"width"`
Height int32 `json:"height"`
}
func getMangoActiveWindow() (*WindowGeometry, error) {
output, err := exec.Command("mmsg", "get", "all-clients").Output()
if err != nil {
return nil, fmt.Errorf("mmsg get all-clients: %w", err)
}
var data struct {
Clients []mangoClient `json:"clients"`
}
if err := json.Unmarshal(output, &data); err != nil {
return nil, fmt.Errorf("parse all-clients: %w", err)
}
for _, c := range data.Clients {
if !c.IsFocused {
continue
}
if c.Width <= 0 || c.Height <= 0 {
return nil, fmt.Errorf("no active window")
}
geom := &WindowGeometry{
X: c.X,
Y: c.Y,
Width: c.Width,
Height: c.Height,
Output: c.Monitor,
Scale: 1.0,
}
for _, m := range getMangoMonitors() {
if m.Name != c.Monitor {
continue
}
geom.OutputX = m.X
geom.OutputY = m.Y
if m.Scale > 0 {
geom.Scale = m.Scale
}
break
}
return geom, nil
}
return nil, fmt.Errorf("no focused window")
}
type niriWorkspace struct {
Output string `json:"output"`
IsFocused bool `json:"is_focused"`
@@ -309,121 +364,6 @@ func getNiriFocusedMonitor() string {
return ""
}
var dwlActiveOutput string
func SetDWLActiveOutput(name string) {
dwlActiveOutput = name
}
func getDWLFocusedMonitor() string {
if dwlActiveOutput != "" {
return dwlActiveOutput
}
return queryDWLActiveOutput()
}
func queryDWLActiveOutput() string {
display, err := client.Connect("")
if err != nil {
return ""
}
ctx := display.Context()
defer ctx.Close()
registry, err := display.GetRegistry()
if err != nil {
return ""
}
var dwlManager *dwl_ipc.ZdwlIpcManagerV2
outputs := make(map[uint32]*client.Output)
registry.SetGlobalHandler(func(e client.RegistryGlobalEvent) {
switch e.Interface {
case dwl_ipc.ZdwlIpcManagerV2InterfaceName:
mgr := dwl_ipc.NewZdwlIpcManagerV2(ctx)
if err := registry.Bind(e.Name, e.Interface, e.Version, mgr); err == nil {
dwlManager = mgr
}
case client.OutputInterfaceName:
out := client.NewOutput(ctx)
version := e.Version
if version > 4 {
version = 4
}
if err := registry.Bind(e.Name, e.Interface, version, out); err == nil {
outputs[e.Name] = out
}
}
})
if err := wlhelpers.Roundtrip(display, ctx); err != nil {
return ""
}
if dwlManager == nil || len(outputs) == 0 {
return ""
}
outputNames := make(map[uint32]string)
for name, out := range outputs {
n := name
out.SetNameHandler(func(e client.OutputNameEvent) {
outputNames[n] = e.Name
})
}
if err := wlhelpers.Roundtrip(display, ctx); err != nil {
return ""
}
type outputState struct {
name string
active bool
gotFrame bool
}
states := make(map[uint32]*outputState)
for name, out := range outputs {
dwlOut, err := dwlManager.GetOutput(out)
if err != nil {
continue
}
state := &outputState{name: outputNames[name]}
states[name] = state
dwlOut.SetActiveHandler(func(e dwl_ipc.ZdwlIpcOutputV2ActiveEvent) {
state.active = e.Active != 0
})
dwlOut.SetFrameHandler(func(e dwl_ipc.ZdwlIpcOutputV2FrameEvent) {
state.gotFrame = true
})
}
allFramesReceived := func() bool {
for _, s := range states {
if !s.gotFrame {
return false
}
}
return true
}
for !allFramesReceived() {
if err := ctx.Dispatch(); err != nil {
return ""
}
}
for _, state := range states {
if state.active {
return state.name
}
}
return ""
}
func GetFocusedMonitor() string {
switch DetectCompositor() {
case CompositorHyprland:
@@ -436,8 +376,8 @@ func GetFocusedMonitor() string {
return getMiracleFocusedMonitor()
case CompositorNiri:
return getNiriFocusedMonitor()
case CompositorDWL:
return getDWLFocusedMonitor()
case CompositorMango:
return getMangoFocusedMonitor()
}
return ""
}
@@ -534,161 +474,3 @@ func getAllOutputInfos() map[string]*outputInfo {
}
return result
}
func getOutputInfo(outputName string) (*outputInfo, bool) {
infos := getAllOutputInfos()
if infos == nil {
return nil, false
}
info, ok := infos[outputName]
return info, ok
}
func getDWLActiveWindow() (*WindowGeometry, error) {
display, err := client.Connect("")
if err != nil {
return nil, fmt.Errorf("connect: %w", err)
}
ctx := display.Context()
defer ctx.Close()
registry, err := display.GetRegistry()
if err != nil {
return nil, fmt.Errorf("get registry: %w", err)
}
var dwlManager *dwl_ipc.ZdwlIpcManagerV2
outputs := make(map[uint32]*client.Output)
registry.SetGlobalHandler(func(e client.RegistryGlobalEvent) {
switch e.Interface {
case dwl_ipc.ZdwlIpcManagerV2InterfaceName:
mgr := dwl_ipc.NewZdwlIpcManagerV2(ctx)
if err := registry.Bind(e.Name, e.Interface, e.Version, mgr); err == nil {
dwlManager = mgr
}
case client.OutputInterfaceName:
out := client.NewOutput(ctx)
version := e.Version
if version > 4 {
version = 4
}
if err := registry.Bind(e.Name, e.Interface, version, out); err == nil {
outputs[e.Name] = out
}
}
})
if err := wlhelpers.Roundtrip(display, ctx); err != nil {
return nil, fmt.Errorf("roundtrip: %w", err)
}
if dwlManager == nil {
return nil, fmt.Errorf("dwl_ipc_manager not available")
}
if len(outputs) == 0 {
return nil, fmt.Errorf("no outputs found")
}
outputNames := make(map[uint32]string)
for name, out := range outputs {
n := name
out.SetNameHandler(func(e client.OutputNameEvent) {
outputNames[n] = e.Name
})
}
if err := wlhelpers.Roundtrip(display, ctx); err != nil {
return nil, fmt.Errorf("roundtrip: %w", err)
}
type dwlOutputState struct {
output *dwl_ipc.ZdwlIpcOutputV2
name string
active bool
x, y int32
w, h int32
scalefactor uint32
gotFrame bool
}
dwlOutputs := make(map[uint32]*dwlOutputState)
for name, out := range outputs {
dwlOut, err := dwlManager.GetOutput(out)
if err != nil {
continue
}
state := &dwlOutputState{output: dwlOut, name: outputNames[name]}
dwlOutputs[name] = state
dwlOut.SetActiveHandler(func(e dwl_ipc.ZdwlIpcOutputV2ActiveEvent) {
state.active = e.Active != 0
})
dwlOut.SetXHandler(func(e dwl_ipc.ZdwlIpcOutputV2XEvent) {
state.x = e.X
})
dwlOut.SetYHandler(func(e dwl_ipc.ZdwlIpcOutputV2YEvent) {
state.y = e.Y
})
dwlOut.SetWidthHandler(func(e dwl_ipc.ZdwlIpcOutputV2WidthEvent) {
state.w = e.Width
})
dwlOut.SetHeightHandler(func(e dwl_ipc.ZdwlIpcOutputV2HeightEvent) {
state.h = e.Height
})
dwlOut.SetScalefactorHandler(func(e dwl_ipc.ZdwlIpcOutputV2ScalefactorEvent) {
state.scalefactor = e.Scalefactor
})
dwlOut.SetFrameHandler(func(e dwl_ipc.ZdwlIpcOutputV2FrameEvent) {
state.gotFrame = true
})
}
allFramesReceived := func() bool {
for _, s := range dwlOutputs {
if !s.gotFrame {
return false
}
}
return true
}
for !allFramesReceived() {
if err := ctx.Dispatch(); err != nil {
return nil, fmt.Errorf("dispatch: %w", err)
}
}
for _, state := range dwlOutputs {
if !state.active {
continue
}
if state.w <= 0 || state.h <= 0 {
return nil, fmt.Errorf("no active window")
}
scale := float64(state.scalefactor) / 100.0
if scale <= 0 {
scale = 1.0
}
geom := &WindowGeometry{
X: state.x,
Y: state.y,
Width: state.w,
Height: state.h,
Output: state.name,
Scale: scale,
}
if info, ok := getOutputInfo(state.name); ok {
geom.OutputX = info.x
geom.OutputY = info.y
geom.OutputTransform = info.transform
}
return geom, nil
}
return nil, fmt.Errorf("no active output found")
}
+4 -4
View File
@@ -156,14 +156,14 @@ func (s *Screenshoter) captureWindow() (*CaptureResult, error) {
switch DetectCompositor() {
case CompositorHyprland:
return s.captureAndCrop(output, region)
case CompositorDWL:
return s.captureDWLWindow(output, region, geom)
case CompositorMango:
return s.captureMangoWindow(output, region, geom)
default:
return s.captureRegionOnOutput(output, region)
}
}
func (s *Screenshoter) captureDWLWindow(output *WaylandOutput, region Region, geom *WindowGeometry) (*CaptureResult, error) {
func (s *Screenshoter) captureMangoWindow(output *WaylandOutput, region Region, geom *WindowGeometry) (*CaptureResult, error) {
result, err := s.captureWholeOutput(output)
if err != nil {
return nil, err
@@ -628,7 +628,7 @@ func (s *Screenshoter) captureRegionOnOutput(output *WaylandOutput, region Regio
w := int32(float64(region.Width) * scale)
h := int32(float64(region.Height) * scale)
if DetectCompositor() == CompositorDWL {
if DetectCompositor() == CompositorMango {
scaledOutW := int32(float64(output.width) * scale)
scaledOutH := int32(float64(output.height) * scale)
if localX >= scaledOutW {
-138
View File
@@ -1,138 +0,0 @@
package dwl
import (
"encoding/json"
"fmt"
"net"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/models"
)
type SuccessResult struct {
Success bool `json:"success"`
Message string `json:"message"`
}
func HandleRequest(conn net.Conn, req models.Request, manager *Manager) {
if manager == nil {
models.RespondError(conn, req.ID, "dwl manager not initialized")
return
}
switch req.Method {
case "dwl.getState":
handleGetState(conn, req, manager)
case "dwl.setTags":
handleSetTags(conn, req, manager)
case "dwl.setClientTags":
handleSetClientTags(conn, req, manager)
case "dwl.setLayout":
handleSetLayout(conn, req, manager)
case "dwl.subscribe":
handleSubscribe(conn, req, manager)
default:
models.RespondError(conn, req.ID, fmt.Sprintf("unknown method: %s", req.Method))
}
}
func handleGetState(conn net.Conn, req models.Request, manager *Manager) {
state := manager.GetState()
models.Respond(conn, req.ID, state)
}
func handleSetTags(conn net.Conn, req models.Request, manager *Manager) {
output, ok := models.Get[string](req, "output")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'output' parameter")
return
}
tagmask, ok := models.Get[float64](req, "tagmask")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'tagmask' parameter")
return
}
toggleTagset, ok := models.Get[float64](req, "toggleTagset")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'toggleTagset' parameter")
return
}
if err := manager.SetTags(output, uint32(tagmask), uint32(toggleTagset)); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "tags set"})
}
func handleSetClientTags(conn net.Conn, req models.Request, manager *Manager) {
output, ok := models.Get[string](req, "output")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'output' parameter")
return
}
andTags, ok := models.Get[float64](req, "andTags")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'andTags' parameter")
return
}
xorTags, ok := models.Get[float64](req, "xorTags")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'xorTags' parameter")
return
}
if err := manager.SetClientTags(output, uint32(andTags), uint32(xorTags)); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "client tags set"})
}
func handleSetLayout(conn net.Conn, req models.Request, manager *Manager) {
output, ok := models.Get[string](req, "output")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'output' parameter")
return
}
index, ok := models.Get[float64](req, "index")
if !ok {
models.RespondError(conn, req.ID, "missing or invalid 'index' parameter")
return
}
if err := manager.SetLayout(output, uint32(index)); err != nil {
models.RespondError(conn, req.ID, err.Error())
return
}
models.Respond(conn, req.ID, SuccessResult{Success: true, Message: "layout set"})
}
func handleSubscribe(conn net.Conn, req models.Request, manager *Manager) {
clientID := fmt.Sprintf("client-%p", conn)
stateChan := manager.Subscribe(clientID)
defer manager.Unsubscribe(clientID)
initialState := manager.GetState()
if err := json.NewEncoder(conn).Encode(models.Response[State]{
ID: req.ID,
Result: &initialState,
}); err != nil {
return
}
for state := range stateChan {
if err := json.NewEncoder(conn).Encode(models.Response[State]{
Result: &state,
}); err != nil {
return
}
}
}
-522
View File
@@ -1,522 +0,0 @@
package dwl
import (
"fmt"
"time"
wlclient "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
"github.com/AvengeMedia/DankMaterialShell/core/internal/proto/dwl_ipc"
)
func NewManager(display wlclient.WaylandDisplay) (*Manager, error) {
m := &Manager{
display: display,
ctx: display.Context(),
cmdq: make(chan cmd, 128),
outputSetupReq: make(chan uint32, 16),
stopChan: make(chan struct{}),
dirty: make(chan struct{}, 1),
layouts: make([]string, 0),
}
if err := m.setupRegistry(); err != nil {
return nil, err
}
m.updateState()
m.notifierWg.Add(1)
go m.notifier()
m.wg.Add(1)
go m.waylandActor()
return m, nil
}
func (m *Manager) post(fn func()) {
select {
case m.cmdq <- cmd{fn: fn}:
default:
log.Warn("DWL actor command queue full, dropping command")
}
}
func (m *Manager) waylandActor() {
defer m.wg.Done()
for {
select {
case <-m.stopChan:
return
case c := <-m.cmdq:
c.fn()
case outputID := <-m.outputSetupReq:
out, exists := m.outputs.Load(outputID)
if !exists {
log.Warnf("DWL: Output %d no longer exists, skipping setup", outputID)
continue
}
if out.ipcOutput != nil {
continue
}
mgr, ok := m.manager.(*dwl_ipc.ZdwlIpcManagerV2)
if !ok || mgr == nil {
log.Errorf("DWL: Manager not available for output %d setup", outputID)
continue
}
log.Infof("DWL: Setting up ipcOutput for dynamically added output %d", outputID)
if err := m.setupOutput(mgr, out.output); err != nil {
log.Errorf("DWL: Failed to setup output %d: %v", outputID, err)
} else {
m.updateState()
}
}
}
}
func (m *Manager) setupRegistry() error {
log.Info("DWL: starting registry setup")
registry, err := m.display.GetRegistry()
if err != nil {
return fmt.Errorf("failed to get registry: %w", err)
}
m.registry = registry
outputs := make([]*wlclient.Output, 0)
outputRegNames := make(map[uint32]uint32)
var dwlMgr *dwl_ipc.ZdwlIpcManagerV2
registry.SetGlobalHandler(func(e wlclient.RegistryGlobalEvent) {
switch e.Interface {
case dwl_ipc.ZdwlIpcManagerV2InterfaceName:
log.Infof("DWL: found %s", dwl_ipc.ZdwlIpcManagerV2InterfaceName)
manager := dwl_ipc.NewZdwlIpcManagerV2(m.ctx)
version := e.Version
if version > 2 {
version = 2
}
if err := registry.Bind(e.Name, e.Interface, version, manager); err == nil {
dwlMgr = manager
log.Info("DWL: manager bound successfully")
// Set handlers immediately after binding, before roundtrips
manager.SetTagsHandler(func(e dwl_ipc.ZdwlIpcManagerV2TagsEvent) {
log.Infof("DWL: Tags count: %d", e.Amount)
m.tagCount = e.Amount
m.updateState()
})
manager.SetLayoutHandler(func(e dwl_ipc.ZdwlIpcManagerV2LayoutEvent) {
log.Infof("DWL: Layout: %s", e.Name)
m.layouts = append(m.layouts, e.Name)
m.updateState()
})
} else {
log.Errorf("DWL: failed to bind manager: %v", err)
}
case "wl_output":
log.Debugf("DWL: found wl_output (name=%d)", e.Name)
output := wlclient.NewOutput(m.ctx)
outState := &outputState{
registryName: e.Name,
output: output,
tags: make([]TagState, 0),
}
output.SetNameHandler(func(ev wlclient.OutputNameEvent) {
log.Debugf("DWL: Output name: %s (registry=%d)", ev.Name, e.Name)
outState.name = ev.Name
})
output.SetDescriptionHandler(func(ev wlclient.OutputDescriptionEvent) {
log.Debugf("DWL: Output description: %s", ev.Description)
})
version := e.Version
if version > 4 {
version = 4
}
if err := registry.Bind(e.Name, e.Interface, version, output); err == nil {
outputID := output.ID()
outState.id = outputID
log.Infof("DWL: Bound wl_output id=%d registry_name=%d", outputID, e.Name)
outputs = append(outputs, output)
outputRegNames[outputID] = e.Name
m.outputs.Store(outputID, outState)
if m.manager != nil {
select {
case m.outputSetupReq <- outputID:
log.Debugf("DWL: Queued setup for output %d", outputID)
default:
log.Warnf("DWL: Setup queue full, output %d will not be initialized", outputID)
}
}
} else {
log.Errorf("DWL: Failed to bind wl_output: %v", err)
}
}
})
registry.SetGlobalRemoveHandler(func(e wlclient.RegistryGlobalRemoveEvent) {
m.post(func() {
var outToRelease *outputState
m.outputs.Range(func(id uint32, out *outputState) bool {
if out.registryName == e.Name {
log.Infof("DWL: Output %d removed", id)
outToRelease = out
m.outputs.Delete(id)
return false
}
return true
})
if outToRelease != nil {
if ipcOut, ok := outToRelease.ipcOutput.(*dwl_ipc.ZdwlIpcOutputV2); ok && ipcOut != nil {
m.wlMutex.Lock()
ipcOut.Release()
m.wlMutex.Unlock()
log.Debugf("DWL: Released ipcOutput for removed output %d", outToRelease.id)
}
m.updateState()
}
})
})
if err := m.display.Roundtrip(); err != nil {
return fmt.Errorf("first roundtrip failed: %w", err)
}
if err := m.display.Roundtrip(); err != nil {
return fmt.Errorf("second roundtrip failed: %w", err)
}
if dwlMgr == nil {
log.Info("DWL: manager not found in registry")
return fmt.Errorf("dwl_ipc_manager_v2 not available")
}
m.manager = dwlMgr
for _, output := range outputs {
if err := m.setupOutput(dwlMgr, output); err != nil {
log.Warnf("DWL: Failed to setup output %d: %v", output.ID(), err)
}
}
if err := m.display.Roundtrip(); err != nil {
return fmt.Errorf("final roundtrip failed: %w", err)
}
log.Info("DWL: registry setup complete")
return nil
}
func (m *Manager) setupOutput(manager *dwl_ipc.ZdwlIpcManagerV2, output *wlclient.Output) error {
m.wlMutex.Lock()
ipcOutput, err := manager.GetOutput(output)
m.wlMutex.Unlock()
if err != nil {
return fmt.Errorf("failed to get dwl output: %w", err)
}
outState, exists := m.outputs.Load(output.ID())
if !exists {
return fmt.Errorf("output state not found for id %d", output.ID())
}
outState.ipcOutput = ipcOutput
ipcOutput.SetActiveHandler(func(e dwl_ipc.ZdwlIpcOutputV2ActiveEvent) {
outState.active = e.Active
})
ipcOutput.SetTagHandler(func(e dwl_ipc.ZdwlIpcOutputV2TagEvent) {
updated := false
for i, tag := range outState.tags {
if tag.Tag == e.Tag {
outState.tags[i] = TagState{
Tag: e.Tag,
State: e.State,
Clients: e.Clients,
Focused: e.Focused,
}
updated = true
break
}
}
if !updated {
outState.tags = append(outState.tags, TagState{
Tag: e.Tag,
State: e.State,
Clients: e.Clients,
Focused: e.Focused,
})
}
m.updateState()
})
ipcOutput.SetLayoutHandler(func(e dwl_ipc.ZdwlIpcOutputV2LayoutEvent) {
outState.layout = e.Layout
})
ipcOutput.SetTitleHandler(func(e dwl_ipc.ZdwlIpcOutputV2TitleEvent) {
outState.title = e.Title
})
ipcOutput.SetAppidHandler(func(e dwl_ipc.ZdwlIpcOutputV2AppidEvent) {
outState.appID = e.Appid
})
ipcOutput.SetLayoutSymbolHandler(func(e dwl_ipc.ZdwlIpcOutputV2LayoutSymbolEvent) {
outState.layoutSymbol = e.Layout
})
ipcOutput.SetKbLayoutHandler(func(e dwl_ipc.ZdwlIpcOutputV2KbLayoutEvent) {
outState.kbLayout = e.KbLayout
})
ipcOutput.SetKeymodeHandler(func(e dwl_ipc.ZdwlIpcOutputV2KeymodeEvent) {
outState.keymode = e.Keymode
})
ipcOutput.SetFrameHandler(func(e dwl_ipc.ZdwlIpcOutputV2FrameEvent) {
m.updateState()
})
return nil
}
func (m *Manager) updateState() {
outputs := make(map[string]*OutputState)
activeOutput := ""
m.outputs.Range(func(key uint32, out *outputState) bool {
name := out.name
if name == "" {
name = fmt.Sprintf("output-%d", out.id)
}
tagsCopy := make([]TagState, len(out.tags))
copy(tagsCopy, out.tags)
outputs[name] = &OutputState{
Name: name,
Active: out.active,
Tags: tagsCopy,
Layout: out.layout,
LayoutSymbol: out.layoutSymbol,
Title: out.title,
AppID: out.appID,
KbLayout: out.kbLayout,
Keymode: out.keymode,
}
if out.active != 0 {
activeOutput = name
}
return true
})
newState := State{
Outputs: outputs,
TagCount: m.tagCount,
Layouts: m.layouts,
ActiveOutput: activeOutput,
}
m.stateMutex.Lock()
m.state = &newState
m.stateMutex.Unlock()
m.notifySubscribers()
}
func (m *Manager) notifier() {
defer m.notifierWg.Done()
const minGap = 100 * time.Millisecond
timer := time.NewTimer(minGap)
timer.Stop()
var pending bool
for {
select {
case <-m.stopChan:
timer.Stop()
return
case <-m.dirty:
if pending {
continue
}
pending = true
timer.Reset(minGap)
case <-timer.C:
if !pending {
continue
}
currentState := m.GetState()
if m.lastNotified != nil && !stateChanged(m.lastNotified, &currentState) {
pending = false
continue
}
m.subscribers.Range(func(key string, ch chan State) bool {
select {
case ch <- currentState:
default:
log.Warn("DWL: subscriber channel full, dropping update")
}
return true
})
stateCopy := currentState
m.lastNotified = &stateCopy
pending = false
}
}
}
func (m *Manager) ensureOutputSetup(out *outputState) error {
if out.ipcOutput != nil {
return nil
}
return fmt.Errorf("output not yet initialized - setup in progress, retry in a moment")
}
func (m *Manager) SetTags(outputName string, tagmask uint32, toggleTagset uint32) error {
availableOutputs := make([]string, 0)
var targetOut *outputState
m.outputs.Range(func(key uint32, out *outputState) bool {
name := out.name
if name == "" {
name = fmt.Sprintf("output-%d", out.id)
}
availableOutputs = append(availableOutputs, name)
if name == outputName {
targetOut = out
return false
}
return true
})
if targetOut == nil {
return fmt.Errorf("output not found: %s (available: %v)", outputName, availableOutputs)
}
if err := m.ensureOutputSetup(targetOut); err != nil {
return fmt.Errorf("failed to setup output %s: %w", outputName, err)
}
ipcOut, ok := targetOut.ipcOutput.(*dwl_ipc.ZdwlIpcOutputV2)
if !ok {
return fmt.Errorf("output %s has invalid ipcOutput type", outputName)
}
m.wlMutex.Lock()
err := ipcOut.SetTags(tagmask, toggleTagset)
m.wlMutex.Unlock()
return err
}
func (m *Manager) SetClientTags(outputName string, andTags uint32, xorTags uint32) error {
var targetOut *outputState
m.outputs.Range(func(key uint32, out *outputState) bool {
name := out.name
if name == "" {
name = fmt.Sprintf("output-%d", out.id)
}
if name == outputName {
targetOut = out
return false
}
return true
})
if targetOut == nil {
return fmt.Errorf("output not found: %s", outputName)
}
if err := m.ensureOutputSetup(targetOut); err != nil {
return fmt.Errorf("failed to setup output %s: %w", outputName, err)
}
ipcOut, ok := targetOut.ipcOutput.(*dwl_ipc.ZdwlIpcOutputV2)
if !ok {
return fmt.Errorf("output %s has invalid ipcOutput type", outputName)
}
m.wlMutex.Lock()
err := ipcOut.SetClientTags(andTags, xorTags)
m.wlMutex.Unlock()
return err
}
func (m *Manager) SetLayout(outputName string, index uint32) error {
var targetOut *outputState
m.outputs.Range(func(key uint32, out *outputState) bool {
name := out.name
if name == "" {
name = fmt.Sprintf("output-%d", out.id)
}
if name == outputName {
targetOut = out
return false
}
return true
})
if targetOut == nil {
return fmt.Errorf("output not found: %s", outputName)
}
if err := m.ensureOutputSetup(targetOut); err != nil {
return fmt.Errorf("failed to setup output %s: %w", outputName, err)
}
ipcOut, ok := targetOut.ipcOutput.(*dwl_ipc.ZdwlIpcOutputV2)
if !ok {
return fmt.Errorf("output %s has invalid ipcOutput type", outputName)
}
m.wlMutex.Lock()
err := ipcOut.SetLayout(index)
m.wlMutex.Unlock()
return err
}
func (m *Manager) Close() {
close(m.stopChan)
m.wg.Wait()
m.notifierWg.Wait()
m.subscribers.Range(func(key string, ch chan State) bool {
close(ch)
m.subscribers.Delete(key)
return true
})
m.outputs.Range(func(key uint32, out *outputState) bool {
if ipcOut, ok := out.ipcOutput.(*dwl_ipc.ZdwlIpcOutputV2); ok {
ipcOut.Release()
}
m.outputs.Delete(key)
return true
})
if mgr, ok := m.manager.(*dwl_ipc.ZdwlIpcManagerV2); ok {
mgr.Release()
}
}
-366
View File
@@ -1,366 +0,0 @@
package dwl
import (
"errors"
"sync"
"testing"
"time"
"github.com/stretchr/testify/assert"
mocks_wlclient "github.com/AvengeMedia/DankMaterialShell/core/internal/mocks/wlclient"
)
func TestStateChanged_BothNil(t *testing.T) {
assert.True(t, stateChanged(nil, nil))
}
func TestStateChanged_OneNil(t *testing.T) {
s := &State{TagCount: 9}
assert.True(t, stateChanged(s, nil))
assert.True(t, stateChanged(nil, s))
}
func TestStateChanged_TagCountDiffers(t *testing.T) {
a := &State{TagCount: 9, Outputs: make(map[string]*OutputState), Layouts: []string{}}
b := &State{TagCount: 10, Outputs: make(map[string]*OutputState), Layouts: []string{}}
assert.True(t, stateChanged(a, b))
}
func TestStateChanged_LayoutLengthDiffers(t *testing.T) {
a := &State{TagCount: 9, Layouts: []string{"tile"}, Outputs: make(map[string]*OutputState)}
b := &State{TagCount: 9, Layouts: []string{"tile", "monocle"}, Outputs: make(map[string]*OutputState)}
assert.True(t, stateChanged(a, b))
}
func TestStateChanged_ActiveOutputDiffers(t *testing.T) {
a := &State{TagCount: 9, ActiveOutput: "eDP-1", Outputs: make(map[string]*OutputState), Layouts: []string{}}
b := &State{TagCount: 9, ActiveOutput: "HDMI-A-1", Outputs: make(map[string]*OutputState), Layouts: []string{}}
assert.True(t, stateChanged(a, b))
}
func TestStateChanged_OutputCountDiffers(t *testing.T) {
a := &State{
TagCount: 9,
Outputs: map[string]*OutputState{"eDP-1": {}},
Layouts: []string{},
}
b := &State{
TagCount: 9,
Outputs: map[string]*OutputState{},
Layouts: []string{},
}
assert.True(t, stateChanged(a, b))
}
func TestStateChanged_OutputFieldsDiffer(t *testing.T) {
a := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Active: 1, Layout: 0, Title: "Firefox"},
},
}
b := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Active: 0, Layout: 0, Title: "Firefox"},
},
}
assert.True(t, stateChanged(a, b))
b.Outputs["eDP-1"].Active = 1
b.Outputs["eDP-1"].Layout = 1
assert.True(t, stateChanged(a, b))
b.Outputs["eDP-1"].Layout = 0
b.Outputs["eDP-1"].Title = "Code"
assert.True(t, stateChanged(a, b))
}
func TestStateChanged_TagsDiffer(t *testing.T) {
a := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Tags: []TagState{{Tag: 1, State: 1, Clients: 2, Focused: 1}}},
},
}
b := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Tags: []TagState{{Tag: 1, State: 2, Clients: 2, Focused: 1}}},
},
}
assert.True(t, stateChanged(a, b))
b.Outputs["eDP-1"].Tags[0].State = 1
b.Outputs["eDP-1"].Tags[0].Clients = 3
assert.True(t, stateChanged(a, b))
}
func TestStateChanged_Equal(t *testing.T) {
a := &State{
TagCount: 9,
ActiveOutput: "eDP-1",
Layouts: []string{"tile", "monocle"},
Outputs: map[string]*OutputState{
"eDP-1": {
Name: "eDP-1",
Active: 1,
Layout: 0,
LayoutSymbol: "[]=",
Title: "Firefox",
AppID: "firefox",
KbLayout: "us",
Keymode: "",
Tags: []TagState{{Tag: 1, State: 1, Clients: 2, Focused: 1}},
},
},
}
b := &State{
TagCount: 9,
ActiveOutput: "eDP-1",
Layouts: []string{"tile", "monocle"},
Outputs: map[string]*OutputState{
"eDP-1": {
Name: "eDP-1",
Active: 1,
Layout: 0,
LayoutSymbol: "[]=",
Title: "Firefox",
AppID: "firefox",
KbLayout: "us",
Keymode: "",
Tags: []TagState{{Tag: 1, State: 1, Clients: 2, Focused: 1}},
},
},
}
assert.False(t, stateChanged(a, b))
}
func TestManager_ConcurrentGetState(t *testing.T) {
m := &Manager{
state: &State{
TagCount: 9,
Layouts: []string{"tile"},
Outputs: map[string]*OutputState{"eDP-1": {Name: "eDP-1"}},
},
}
var wg sync.WaitGroup
const goroutines = 50
const iterations = 100
for i := 0; i < goroutines/2; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < iterations; j++ {
s := m.GetState()
_ = s.TagCount
_ = s.Outputs
}
}()
}
for i := 0; i < goroutines/2; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
for j := 0; j < iterations; j++ {
m.stateMutex.Lock()
m.state = &State{
TagCount: uint32(j % 10),
Layouts: []string{"tile", "monocle"},
Outputs: map[string]*OutputState{"eDP-1": {Active: uint32(j % 2)}},
}
m.stateMutex.Unlock()
}
}(i)
}
wg.Wait()
}
func TestManager_ConcurrentSubscriberAccess(t *testing.T) {
m := &Manager{
stopChan: make(chan struct{}),
dirty: make(chan struct{}, 1),
}
var wg sync.WaitGroup
const goroutines = 20
for i := 0; i < goroutines; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
subID := string(rune('a' + id))
ch := m.Subscribe(subID)
assert.NotNil(t, ch)
time.Sleep(time.Millisecond)
m.Unsubscribe(subID)
}(i)
}
wg.Wait()
}
func TestManager_SyncmapOutputsConcurrentAccess(t *testing.T) {
m := &Manager{}
var wg sync.WaitGroup
const goroutines = 30
const iterations = 50
for i := 0; i < goroutines; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
key := uint32(id)
for j := 0; j < iterations; j++ {
state := &outputState{
id: key,
name: "test-output",
active: uint32(j % 2),
tags: []TagState{{Tag: uint32(j), State: 1}},
}
m.outputs.Store(key, state)
if loaded, ok := m.outputs.Load(key); ok {
assert.Equal(t, key, loaded.id)
}
m.outputs.Range(func(k uint32, v *outputState) bool {
_ = v.name
_ = v.active
return true
})
}
m.outputs.Delete(key)
}(i)
}
wg.Wait()
}
func TestManager_NotifySubscribersNonBlocking(t *testing.T) {
m := &Manager{
dirty: make(chan struct{}, 1),
}
for i := 0; i < 10; i++ {
m.notifySubscribers()
}
assert.Len(t, m.dirty, 1)
}
func TestManager_PostQueueFull(t *testing.T) {
m := &Manager{
cmdq: make(chan cmd, 2),
stopChan: make(chan struct{}),
}
m.post(func() {})
m.post(func() {})
m.post(func() {})
m.post(func() {})
assert.Len(t, m.cmdq, 2)
}
func TestManager_GetStateNilState(t *testing.T) {
m := &Manager{}
s := m.GetState()
assert.NotNil(t, s.Outputs)
assert.NotNil(t, s.Layouts)
assert.Equal(t, uint32(0), s.TagCount)
}
func TestTagState_Fields(t *testing.T) {
tag := TagState{
Tag: 1,
State: 2,
Clients: 3,
Focused: 1,
}
assert.Equal(t, uint32(1), tag.Tag)
assert.Equal(t, uint32(2), tag.State)
assert.Equal(t, uint32(3), tag.Clients)
assert.Equal(t, uint32(1), tag.Focused)
}
func TestOutputState_Fields(t *testing.T) {
out := OutputState{
Name: "eDP-1",
Active: 1,
Tags: []TagState{{Tag: 1}},
Layout: 0,
LayoutSymbol: "[]=",
Title: "Firefox",
AppID: "firefox",
KbLayout: "us",
Keymode: "",
}
assert.Equal(t, "eDP-1", out.Name)
assert.Equal(t, uint32(1), out.Active)
assert.Len(t, out.Tags, 1)
assert.Equal(t, "[]=", out.LayoutSymbol)
}
func TestStateChanged_NewOutputAppears(t *testing.T) {
a := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Name: "eDP-1"},
},
}
b := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Name: "eDP-1"},
"HDMI-A-1": {Name: "HDMI-A-1"},
},
}
assert.True(t, stateChanged(a, b))
}
func TestStateChanged_TagsLengthDiffers(t *testing.T) {
a := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Tags: []TagState{{Tag: 1}}},
},
}
b := &State{
TagCount: 9,
Layouts: []string{},
Outputs: map[string]*OutputState{
"eDP-1": {Tags: []TagState{{Tag: 1}, {Tag: 2}}},
},
}
assert.True(t, stateChanged(a, b))
}
func TestNewManager_GetRegistryError(t *testing.T) {
mockDisplay := mocks_wlclient.NewMockWaylandDisplay(t)
mockDisplay.EXPECT().Context().Return(nil)
mockDisplay.EXPECT().GetRegistry().Return(nil, errors.New("failed to get registry"))
_, err := NewManager(mockDisplay)
assert.Error(t, err)
assert.Contains(t, err.Error(), "failed to get registry")
}
-176
View File
@@ -1,176 +0,0 @@
package dwl
import (
"sync"
wlclient "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
)
type TagState struct {
Tag uint32 `json:"tag"`
State uint32 `json:"state"`
Clients uint32 `json:"clients"`
Focused uint32 `json:"focused"`
}
type OutputState struct {
Name string `json:"name"`
Active uint32 `json:"active"`
Tags []TagState `json:"tags"`
Layout uint32 `json:"layout"`
LayoutSymbol string `json:"layoutSymbol"`
Title string `json:"title"`
AppID string `json:"appId"`
KbLayout string `json:"kbLayout"`
Keymode string `json:"keymode"`
}
type State struct {
Outputs map[string]*OutputState `json:"outputs"`
TagCount uint32 `json:"tagCount"`
Layouts []string `json:"layouts"`
ActiveOutput string `json:"activeOutput"`
}
type cmd struct {
fn func()
}
type Manager struct {
display wlclient.WaylandDisplay
ctx *wlclient.Context
registry *wlclient.Registry
manager any
outputs syncmap.Map[uint32, *outputState]
tagCount uint32
layouts []string
wlMutex sync.Mutex
cmdq chan cmd
outputSetupReq chan uint32
stopChan chan struct{}
wg sync.WaitGroup
subscribers syncmap.Map[string, chan State]
dirty chan struct{}
notifierWg sync.WaitGroup
lastNotified *State
stateMutex sync.RWMutex
state *State
}
type outputState struct {
id uint32
registryName uint32
output *wlclient.Output
ipcOutput any
name string
active uint32
tags []TagState
layout uint32
layoutSymbol string
title string
appID string
kbLayout string
keymode string
}
func (m *Manager) GetState() State {
m.stateMutex.RLock()
defer m.stateMutex.RUnlock()
if m.state == nil {
return State{
Outputs: make(map[string]*OutputState),
Layouts: []string{},
TagCount: 0,
}
}
stateCopy := *m.state
return stateCopy
}
func (m *Manager) Subscribe(id string) chan State {
ch := make(chan State, 64)
m.subscribers.Store(id, ch)
return ch
}
func (m *Manager) Unsubscribe(id string) {
if val, ok := m.subscribers.LoadAndDelete(id); ok {
close(val)
}
}
func (m *Manager) notifySubscribers() {
select {
case m.dirty <- struct{}{}:
default:
}
}
func stateChanged(old, new *State) bool {
if old == nil || new == nil {
return true
}
if old.TagCount != new.TagCount {
return true
}
if len(old.Layouts) != len(new.Layouts) {
return true
}
if old.ActiveOutput != new.ActiveOutput {
return true
}
if len(old.Outputs) != len(new.Outputs) {
return true
}
for name, newOut := range new.Outputs {
oldOut, exists := old.Outputs[name]
if !exists {
return true
}
if oldOut.Active != newOut.Active {
return true
}
if oldOut.Layout != newOut.Layout {
return true
}
if oldOut.LayoutSymbol != newOut.LayoutSymbol {
return true
}
if oldOut.Title != newOut.Title {
return true
}
if oldOut.AppID != newOut.AppID {
return true
}
if oldOut.KbLayout != newOut.KbLayout {
return true
}
if oldOut.Keymode != newOut.Keymode {
return true
}
if len(oldOut.Tags) != len(newOut.Tags) {
return true
}
for i, newTag := range newOut.Tags {
if i >= len(oldOut.Tags) {
return true
}
oldTag := oldOut.Tags[i]
if oldTag.Tag != newTag.Tag || oldTag.State != newTag.State ||
oldTag.Clients != newTag.Clients || oldTag.Focused != newTag.Focused {
return true
}
}
}
return false
}
-10
View File
@@ -11,7 +11,6 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/clipboard"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/cups"
serverDbus "github.com/AvengeMedia/DankMaterialShell/core/internal/server/dbus"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/dwl"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/evdev"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/freedesktop"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/location"
@@ -125,15 +124,6 @@ func RouteRequest(conn net.Conn, req models.Request) {
return
}
if strings.HasPrefix(req.Method, "dwl.") {
if dwlManager == nil {
models.RespondError(conn, req.ID, "dwl manager not initialized")
return
}
dwl.HandleRequest(conn, req, dwlManager)
return
}
if strings.HasPrefix(req.Method, "brightness.") {
if brightnessManager == nil {
models.RespondError(conn, req.ID, "brightness manager not initialized")
+1 -87
View File
@@ -22,7 +22,6 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/clipboard"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/cups"
serverDbus "github.com/AvengeMedia/DankMaterialShell/core/internal/server/dbus"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/dwl"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/evdev"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/freedesktop"
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/location"
@@ -39,7 +38,7 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
)
const APIVersion = 24
const APIVersion = 25
var CLIVersion = "dev"
@@ -66,7 +65,6 @@ var bluezManager *bluez.Manager
var appPickerManager *apppicker.Manager
var cupsManager *cups.Manager
var tailscaleManager *tailscale.Manager
var dwlManager *dwl.Manager
var brightnessManager *brightness.Manager
var wlrOutputManager *wlroutput.Manager
var evdevManager *evdev.Manager
@@ -252,30 +250,6 @@ func InitializeCupsManager() error {
return nil
}
func InitializeDwlManager() error {
log.Info("Attempting to initialize DWL IPC...")
if wlContext == nil {
ctx, err := wlcontext.New()
if err != nil {
log.Errorf("Failed to create shared Wayland context: %v", err)
return err
}
wlContext = ctx
}
manager, err := dwl.NewManager(wlContext.Display())
if err != nil {
log.Debug("Failed to initialize dwl manager: %v", err)
return err
}
dwlManager = manager
log.Info("DWL IPC initialized successfully")
return nil
}
func InitializeBrightnessManager() error {
manager, err := brightness.NewManager()
if err != nil {
@@ -468,10 +442,6 @@ func getCapabilities() Capabilities {
caps = append(caps, "tailscale")
}
if dwlManager != nil {
caps = append(caps, "dwl")
}
if brightnessManager != nil {
caps = append(caps, "brightness")
}
@@ -538,10 +508,6 @@ func getServerInfo() ServerInfo {
caps = append(caps, "tailscale")
}
if dwlManager != nil {
caps = append(caps, "dwl")
}
if brightnessManager != nil {
caps = append(caps, "brightness")
}
@@ -1046,38 +1012,6 @@ func handleSubscribe(conn net.Conn, req models.Request) {
}()
}
if shouldSubscribe("dwl") && dwlManager != nil {
wg.Add(1)
dwlChan := dwlManager.Subscribe(clientID + "-dwl")
go func() {
defer wg.Done()
defer dwlManager.Unsubscribe(clientID + "-dwl")
initialState := dwlManager.GetState()
select {
case eventChan <- ServiceEvent{Service: "dwl", Data: initialState}:
case <-stopChan:
return
}
for {
select {
case state, ok := <-dwlChan:
if !ok {
return
}
select {
case eventChan <- ServiceEvent{Service: "dwl", Data: state}:
case <-stopChan:
return
}
case <-stopChan:
return
}
}
}()
}
if shouldSubscribe("brightness") && brightnessManager != nil {
wg.Add(2)
brightnessStateChan := brightnessManager.Subscribe(clientID + "-brightness-state")
@@ -1333,9 +1267,6 @@ func cleanupManagers() {
if cupsManager != nil {
cupsManager.Close()
}
if dwlManager != nil {
dwlManager.Close()
}
if brightnessManager != nil {
brightnessManager.Close()
}
@@ -1502,19 +1433,6 @@ func Start(printDocs bool) error {
log.Info(" cups.resumePrinter - Resume printer (params: printerName)")
log.Info(" cups.cancelJob - Cancel job (params: printerName, jobID)")
log.Info(" cups.purgeJobs - Cancel all jobs (params: printerName)")
log.Info("DWL:")
log.Info(" dwl.getState - Get current dwl state (tags, windows, layouts, keyboard)")
log.Info(" dwl.setTags - Set active tags (params: output, tagmask, toggleTagset)")
log.Info(" dwl.setClientTags - Set focused client tags (params: output, andTags, xorTags)")
log.Info(" dwl.setLayout - Set layout (params: output, index)")
log.Info(" dwl.subscribe - Subscribe to dwl state changes (streaming)")
log.Info(" Output state includes:")
log.Info(" - tags : Tag states (active, clients, focused)")
log.Info(" - layoutSymbol : Current layout name")
log.Info(" - title : Focused window title")
log.Info(" - appId : Focused window app ID")
log.Info(" - kbLayout : Current keyboard layout")
log.Info(" - keymode : Current keybind mode")
log.Info("Brightness:")
log.Info(" brightness.getState - Get current brightness state for all devices")
log.Info(" brightness.setBrightness - Set device brightness (params: device, percent)")
@@ -1691,10 +1609,6 @@ func Start(printDocs bool) error {
log.Debugf("AppPicker manager unavailable: %v", err)
}
if err := InitializeDwlManager(); err != nil {
log.Debugf("DWL manager unavailable: %v", err)
}
if err := InitializeWlrOutputManager(); err != nil {
log.Debugf("WlrOutput manager unavailable: %v", err)
}
-9
View File
@@ -489,9 +489,6 @@ Singleton {
"hideOnTouch": false,
"inactiveTimeout": 0
},
"dwl": {
"cursorHideTimeout": 0
},
"mango": {
"cursorHideTimeout": 0
}
@@ -1224,8 +1221,6 @@ Singleton {
NiriService.generateNiriLayoutConfig();
if (CompositorService.isHyprland && typeof HyprlandService !== "undefined")
HyprlandService.generateLayoutConfig();
if (CompositorService.isDwl && typeof DwlService !== "undefined")
DwlService.generateLayoutConfig();
if (CompositorService.isMango && typeof MangoService !== "undefined")
MangoService.generateLayoutConfig();
}
@@ -2451,10 +2446,6 @@ Singleton {
HyprlandService.generateCursorConfig();
return;
}
if (CompositorService.isDwl && typeof DwlService !== "undefined") {
DwlService.generateCursorConfig();
return;
}
if (CompositorService.isMango && typeof MangoService !== "undefined") {
MangoService.generateCursorConfig();
return;
+2 -2
View File
@@ -570,7 +570,7 @@ Singleton {
onExited: exitCode => {
const enabling = root.settingsRoot && root.settingsRoot.greeterAutoLogin;
if (exitCode === 0) {
ToastService.showWarning(enabling ? I18n.tr("Applying auto-login on startup") : I18n.tr("Disabling auto-login on startup"), "", "dms greeter sync --autologin", "greeter-autologin-sync");
ToastService.showWarning(enabling ? I18n.tr("Applying auto-login on startup...") : I18n.tr("Disabling auto-login on startup..."), "", "dms greeter sync --autologin", "greeter-autologin-sync");
root.greeterAutoLoginSyncProcess.running = true;
return;
}
@@ -645,7 +645,7 @@ Singleton {
onExited: exitCode => {
const err = (root.authApplySudoProbeStderr || "").trim();
if (exitCode === 0) {
ToastService.showInfo(I18n.tr("Applying authentication changes"), "", "", "auth-sync");
ToastService.showInfo(I18n.tr("Applying authentication changes..."), "", "", "auth-sync");
root.authApplyProcess.running = true;
return;
}
-3
View File
@@ -337,9 +337,6 @@ Item {
const focusedWs = I3.workspaces.values.find(ws => ws.focused === true);
return focusedWs?.monitor?.name || "";
}
if (CompositorService.isDwl && DwlService.activeOutput) {
return DwlService.activeOutput;
}
if (CompositorService.isMango && MangoService.activeOutput) {
return MangoService.activeOutput;
}
@@ -128,7 +128,7 @@ Item {
}
StyledText {
text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No recent clipboard entries found") : I18n.tr("Connecting to clipboard service")
text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No recent clipboard entries found") : I18n.tr("Connecting to clipboard service...")
anchors.centerIn: parent
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
@@ -202,7 +202,7 @@ Item {
}
StyledText {
text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No saved clipboard entries") : I18n.tr("Connecting to clipboard service")
text: clipboardContent.modal.clipboardAvailable ? I18n.tr("No saved clipboard entries") : I18n.tr("Connecting to clipboard service...")
anchors.centerIn: parent
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
@@ -320,8 +320,6 @@ Item {
url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings";
else if (CompositorService.isHyprland)
url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-1";
else if (CompositorService.isDwl)
url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-2";
else if (CompositorService.isMango)
url = "https://danklinux.com/docs/dankmaterialshell/compositors#dms-keybindings-2";
Qt.openUrlExternally(url);
@@ -130,7 +130,7 @@ Item {
title: I18n.tr("Multi-Monitor", "greeter feature card title")
description: I18n.tr("Per-screen config", "greeter feature card description")
onClicked: {
const hasDisplayConfig = CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango;
const hasDisplayConfig = CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango;
PopoutService.openSettingsWithTab(hasDisplayConfig ? "display_config" : "display_widgets");
}
}
+41 -6
View File
@@ -98,7 +98,7 @@ FocusScope {
visible: active
focus: active
sourceComponent: CompositorTab {}
sourceComponent: WorkspacesTab {}
onActiveChanged: {
if (active && item)
@@ -106,6 +106,44 @@ FocusScope {
}
}
Loader {
id: compositorLayoutLoader
anchors.fill: parent
active: root.currentIndex === 37
visible: active
focus: active
sourceComponent: CompositorLayoutTab {}
onActiveChanged: {
if (active && item)
Qt.callLater(() => item.forceActiveFocus());
}
}
Loader {
id: windowRulesLoader
property bool loadedOnce: false
anchors.fill: parent
active: root.currentIndex === 38 || loadedOnce
visible: root.currentIndex === 38 && status === Loader.Ready
focus: visible
asynchronous: true
sourceComponent: WindowRulesTab {
pageActive: root.currentIndex === 38
}
onLoaded: loadedOnce = true
}
DankSpinner {
anchors.centerIn: parent
visible: root.currentIndex === 38 && windowRulesLoader.status === Loader.Loading
}
Loader {
id: dankBarAppearanceLoader
anchors.fill: parent
@@ -388,7 +426,7 @@ FocusScope {
}
}
Loader {
Loader {
id: defaultAppsLoader
anchors.fill: parent
active: root.currentIndex === 34
@@ -474,12 +512,9 @@ FocusScope {
}
}
StyledText {
DankSpinner {
anchors.centerIn: parent
visible: root.currentIndex === 22 && widgetsLoader.status === Loader.Loading
text: I18n.tr("Loading...", "loading indicator")
color: Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeMedium
}
Loader {
+24 -8
View File
@@ -102,6 +102,13 @@ Rectangle {
"icon": "volume_up",
"tabIndex": 15,
"soundsOnly": true
},
{
"id": "compositor_layout",
"text": CompositorService.isNiri ? "niri" : (CompositorService.isHyprland ? "Hyprland" : "MangoWC"),
"icon": "crop_square",
"tabIndex": 37,
"layoutCapable": true
}
]
},
@@ -128,6 +135,12 @@ Rectangle {
"icon": "widgets",
"tabIndex": 22
},
{
"id": "workspaces",
"text": I18n.tr("Workspaces"),
"icon": "view_module",
"tabIndex": 4
},
{
"id": "frame",
"text": I18n.tr("Frame"),
@@ -188,12 +201,6 @@ Rectangle {
}
]
},
{
"id": "compositor",
"text": I18n.tr("Compositor"),
"icon": "layers",
"tabIndex": 4
},
{
"id": "keybinds",
"text": I18n.tr("Keyboard Shortcuts"),
@@ -259,6 +266,13 @@ Rectangle {
"icon": "line_start",
"tabIndex": 36,
"autostartOnly": true
},
{
"id": "window_rules",
"text": I18n.tr("Window Rules"),
"icon": "select_window",
"tabIndex": 38,
"windowRulesCapable": true
}
]
},
@@ -372,6 +386,8 @@ Rectangle {
return false;
if (item.windowRulesCapable && !CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isMango)
return false;
if (item.layoutCapable && !CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isMango)
return false;
if (item.niriOnly && !CompositorService.isNiri)
return false;
if (item.clipboardOnly && (!DMSService.isConnected || DMSService.apiVersion < 23))
@@ -544,8 +560,8 @@ Rectangle {
return -1;
var normalized = name.toLowerCase().replace(/[_\-\s]/g, "");
if (normalized === "workspaces")
normalized = "compositor";
if (normalized === "compositor")
normalized = "workspaces";
for (var i = 0; i < categoryStructure.length; i++) {
var cat = categoryStructure[i];
@@ -60,7 +60,7 @@ Rectangle {
}
Typography {
text: DgopService.uptime ? I18n.tr("up") + " " + DgopService.uptime.slice(3) : I18n.tr("Unknown")
text: DgopService.uptime ? I18n.tr("up", "uptime prefix, e.g. 'up 4h 2m'") + " " + DgopService.uptime.slice(3) : I18n.tr("Unknown")
style: Typography.Style.Caption
color: Theme.surfaceVariantText
}
-4
View File
@@ -108,8 +108,6 @@ Item {
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
focusedScreenName = focusedWs?.monitor?.name || "";
} else if (CompositorService.isDwl && DwlService.activeOutput) {
focusedScreenName = DwlService.activeOutput;
} else if (CompositorService.isMango && MangoService.activeOutput) {
focusedScreenName = MangoService.activeOutput;
}
@@ -139,8 +137,6 @@ Item {
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
focusedScreenName = focusedWs?.monitor?.name || "";
} else if (CompositorService.isDwl && DwlService.activeOutput) {
focusedScreenName = DwlService.activeOutput;
} else if (CompositorService.isMango && MangoService.activeOutput) {
focusedScreenName = MangoService.activeOutput;
}
+10 -11
View File
@@ -29,7 +29,6 @@ Item {
readonly property real _frameEdgeFloorInset: (SettingsData.frameEnabled && _usesFrameBarChrome) ? Math.max(0, SettingsData.frameThickness - _edgeBaseMargin) : 0
readonly property bool _barIsVertical: _hasBarWindow ? barWindow.isVertical : false
readonly property string _barScreenName: _hasBarWindow ? (barWindow.screenName || "") : ""
readonly property var dwlSvc: CompositorService.isMango ? MangoService : DwlService
readonly property bool hasAdjacentTopBarLive: _hasBarWindow && barWindow.hasAdjacentTopBar
readonly property bool hasAdjacentBottomBarLive: _hasBarWindow && barWindow.hasAdjacentBottomBar
readonly property bool hasAdjacentLeftBarLive: _hasBarWindow && barWindow.hasAdjacentLeftBar
@@ -190,16 +189,16 @@ Item {
}
return monitorWorkspaces.sort((a, b) => a.id - b.id);
} else if (CompositorService.isDwl || CompositorService.isMango) {
if (!dwlSvc.available) {
} else if (CompositorService.isMango) {
if (!MangoService.available) {
return [0];
}
if (SettingsData.dwlShowAllTags) {
return Array.from({
length: dwlSvc.tagCount
length: MangoService.tagCount
}, (_, i) => i);
}
return dwlSvc.getVisibleTags(screenName);
return MangoService.getVisibleTags(screenName);
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
const workspaces = I3.workspaces?.values || [];
if (workspaces.length === 0)
@@ -235,13 +234,13 @@ Item {
const monitors = Hyprland.monitors?.values || [];
const currentMonitor = monitors.find(monitor => monitor.name === screenName);
return currentMonitor?.activeWorkspace?.id ?? 1;
} else if (CompositorService.isDwl || CompositorService.isMango) {
if (!dwlSvc.available)
} else if (CompositorService.isMango) {
if (!MangoService.available)
return 0;
const outputState = dwlSvc.getOutputState(screenName);
const outputState = MangoService.getOutputState(screenName);
if (!outputState || !outputState.tags)
return 0;
const activeTags = dwlSvc.getActiveTags(screenName);
const activeTags = MangoService.getActiveTags(screenName);
return activeTags.length > 0 ? activeTags[0] : 0;
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
if (!screenName || SettingsData.workspaceFollowFocus) {
@@ -283,14 +282,14 @@ Item {
if (nextIndex !== validIndex) {
HyprlandService.focusWorkspace(realWorkspaces[nextIndex].id);
}
} else if (CompositorService.isDwl || CompositorService.isMango) {
} else if (CompositorService.isMango) {
const currentTag = getCurrentWorkspace();
const currentIndex = realWorkspaces.findIndex(tag => tag === currentTag);
const validIndex = currentIndex === -1 ? 0 : currentIndex;
const nextIndex = direction > 0 ? Math.min(validIndex + 1, realWorkspaces.length - 1) : Math.max(validIndex - 1, 0);
if (nextIndex !== validIndex) {
dwlSvc.switchToTag(_barScreenName, realWorkspaces[nextIndex]);
MangoService.switchToTag(_barScreenName, realWorkspaces[nextIndex]);
}
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
const currentWs = getCurrentWorkspace();
@@ -10,9 +10,7 @@ DankPopout {
property var triggerScreen: null
// mango shares dwl's layout model; route to the right service.
readonly property bool isDwlLike: CompositorService.isDwl || CompositorService.isMango
readonly property var dwlSvc: CompositorService.isMango ? MangoService : DwlService
readonly property bool isMango: CompositorService.isMango
function setTriggerPosition(x, y, width, section, screen, barPosition, barThickness, barSpacing, barConfig) {
triggerX = x;
@@ -37,8 +35,8 @@ DankPopout {
onScreenChanged: updateOutputState()
function updateOutputState() {
if (screen && root.dwlSvc.available) {
outputState = root.dwlSvc.getOutputState(screen.name);
if (screen && MangoService.available) {
outputState = MangoService.getOutputState(screen.name);
} else {
outputState = null;
}
@@ -84,7 +82,7 @@ DankPopout {
}
Connections {
target: DwlService
target: MangoService
function onStateChanged() {
updateOutputState();
}
@@ -219,7 +217,7 @@ DankPopout {
spacing: Theme.spacingS
Repeater {
model: root.dwlSvc.layouts
model: MangoService.layouts
delegate: Rectangle {
required property string modelData
@@ -273,11 +271,11 @@ DankPopout {
if (!root.triggerScreen) {
return;
}
if (!root.dwlSvc.available) {
if (!MangoService.available) {
return;
}
root.dwlSvc.setLayout(root.triggerScreen.name, index);
MangoService.setLayout(root.triggerScreen.name, index);
root.close();
}
}
+1 -1
View File
@@ -282,7 +282,7 @@ Loader {
"cpuTemp": dgopAvailable,
"gpuTemp": dgopAvailable,
"network_speed_monitor": dgopAvailable,
"layout": (CompositorService.isDwl && DwlService.dwlAvailable) || (CompositorService.isMango && MangoService.available)
"layout": CompositorService.isMango && MangoService.available
};
return widgetVisibility[widgetId] ?? true;
@@ -13,12 +13,11 @@ BasePill {
signal toggleLayoutPopup
// mango shares dwl's tag/layout model; route to the right service.
readonly property bool isDwlLike: CompositorService.isDwl || CompositorService.isMango
readonly property var dwlSvc: CompositorService.isMango ? MangoService : DwlService
readonly property bool isMango: CompositorService.isMango
visible: layout.isDwlLike && layout.dwlSvc.available
visible: layout.isMango && MangoService.available
property var outputState: parentScreen ? layout.dwlSvc.getOutputState(parentScreen.name) : null
property var outputState: parentScreen ? MangoService.getOutputState(parentScreen.name) : null
property string currentLayoutSymbol: outputState?.layoutSymbol || ""
property int currentLayoutIndex: outputState?.layout || 0
@@ -41,9 +40,9 @@ BasePill {
}
Connections {
target: layout.dwlSvc
target: MangoService
function onStateChanged() {
outputState = parentScreen ? layout.dwlSvc.getOutputState(parentScreen.name) : null;
outputState = parentScreen ? MangoService.getOutputState(parentScreen.name) : null;
}
}
@@ -101,13 +100,13 @@ BasePill {
}
onRightClicked: {
if (!parentScreen || !layout.dwlSvc.available || layout.dwlSvc.layouts.length === 0) {
if (!parentScreen || !MangoService.available || MangoService.layouts.length === 0) {
return;
}
const currentIndex = layout.currentLayoutIndex;
const nextIndex = (currentIndex + 1) % layout.dwlSvc.layouts.length;
const nextIndex = (currentIndex + 1) % MangoService.layouts.length;
layout.dwlSvc.setLayout(parentScreen.name, nextIndex);
MangoService.setLayout(parentScreen.name, nextIndex);
}
}
@@ -112,8 +112,6 @@ BasePill {
property string currentLayout: {
if (CompositorService.isNiri) {
return NiriService.getCurrentKeyboardLayoutName();
} else if (CompositorService.isDwl) {
return DwlService.currentKeyboardLayout;
} else if (CompositorService.isMango) {
return MangoService.currentKeyboardLayout;
}
@@ -209,8 +207,6 @@ BasePill {
NiriService.cycleKeyboardLayout();
} else if (CompositorService.isHyprland) {
Quickshell.execDetached(["hyprctl", "switchxkblayout", root.hyprlandKeyboard, "next"]);
} else if (CompositorService.isDwl) {
Quickshell.execDetached(["mmsg", "dispatch", "switch_keyboard_layout"]);
} else if (CompositorService.isMango) {
MangoService.cycleKeyboardLayout();
}
@@ -55,7 +55,7 @@ BasePill {
}
IconImage {
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle || CompositorService.isLabwc)
visible: SettingsData.launcherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle || CompositorService.isLabwc)
anchors.centerIn: parent
width: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)
height: Theme.barIconSize(root.barThickness, SettingsData.launcherLogoSizeOffset, root.barConfig?.maximizeWidgetIcons, root.barConfig?.iconScale)
@@ -66,8 +66,6 @@ BasePill {
return "file://" + Theme.shellDir + "/assets/niri.svg";
} else if (CompositorService.isHyprland) {
return "file://" + Theme.shellDir + "/assets/hyprland.svg";
} else if (CompositorService.isDwl) {
return "file://" + Theme.shellDir + "/assets/mango.png";
} else if (CompositorService.isMango) {
return "file://" + Theme.shellDir + "/assets/mango.png";
} else if (CompositorService.isSway) {
@@ -22,10 +22,7 @@ Item {
property var hyprlandOverviewLoader: null
property var parentScreen: null
// mango shares dwl's tag model; route to the right service so one set of
// branches serves both.
readonly property bool isDwlLike: CompositorService.isDwl || CompositorService.isMango
readonly property var dwlSvc: CompositorService.isMango ? MangoService : DwlService
readonly property bool isMango: CompositorService.isMango
readonly property real _leftMargin: {
if (isVertical)
@@ -80,9 +77,8 @@ Item {
return NiriService.currentOutput || root.screenName;
case "hyprland":
return Hyprland.focusedWorkspace?.monitor?.name || root.screenName;
case "dwl":
case "mango":
return root.dwlSvc.activeOutput || root.screenName;
return MangoService.activeOutput || root.screenName;
case "sway":
case "scroll":
case "miracle":
@@ -101,7 +97,6 @@ Item {
switch (CompositorService.compositor) {
case "niri":
case "hyprland":
case "dwl":
case "mango":
case "sway":
case "scroll":
@@ -128,7 +123,6 @@ Item {
return getNiriActiveWorkspace();
case "hyprland":
return getHyprlandActiveWorkspace();
case "dwl":
case "mango":
const activeTags = getDwlActiveTags();
return activeTags.length > 0 ? activeTags[0] : -1;
@@ -141,7 +135,7 @@ Item {
}
}
property var dwlActiveTags: {
if (root.isDwlLike) {
if (root.isMango) {
return getDwlActiveTags();
}
return [];
@@ -160,9 +154,6 @@ Item {
case "hyprland":
baseList = getHyprlandWorkspaces();
break;
case "dwl":
baseList = getDwlTags();
break;
case "mango":
if (root.mangoOverviewActive)
return [];
@@ -302,7 +293,7 @@ Item {
}
} else if (CompositorService.isHyprland) {
targetWorkspaceId = ws.id !== undefined ? ws.id : ws;
} else if (root.isDwlLike) {
} else if (root.isMango) {
if (typeof ws !== "object" || ws.tag === undefined) {
return [];
}
@@ -322,8 +313,8 @@ Item {
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
isActiveWs = focusedWs ? (focusedWs.num === targetWorkspaceId) : false;
} else if (root.isDwlLike) {
const output = root.dwlSvc.getOutputState(root.effectiveScreenName);
} else if (root.isMango) {
const output = MangoService.getOutputState(root.effectiveScreenName);
if (output && output.tags) {
const tag = output.tags.find(t => t.tag === targetWorkspaceId);
isActiveWs = tag ? (tag.state === 1) : false;
@@ -411,7 +402,7 @@ Item {
"id": -1,
"name": ""
};
} else if (root.isDwlLike) {
} else if (root.isMango) {
placeholder = {
"tag": -1
};
@@ -493,11 +484,11 @@ Item {
}
function getDwlTags() {
if (!root.dwlSvc.available)
if (!MangoService.available)
return [];
const targetScreen = root.effectiveScreenName;
const output = root.dwlSvc.getOutputState(targetScreen);
const output = MangoService.getOutputState(targetScreen);
if (!output || !output.tags || output.tags.length === 0)
return [];
@@ -510,7 +501,7 @@ Item {
}));
}
const visibleTagIndices = root.dwlSvc.getVisibleTags(targetScreen);
const visibleTagIndices = MangoService.getVisibleTags(targetScreen);
return visibleTagIndices.map(tagIndex => {
const tagData = output.tags.find(t => t.tag === tagIndex);
return {
@@ -523,10 +514,10 @@ Item {
}
function getDwlActiveTags() {
if (!root.dwlSvc.available)
if (!MangoService.available)
return [];
return root.dwlSvc.getActiveTags(root.effectiveScreenName);
return MangoService.getActiveTags(root.effectiveScreenName);
}
function getExtWorkspaceWorkspaces() {
@@ -577,7 +568,7 @@ Item {
return ws && ws.idx !== -1;
if (CompositorService.isHyprland)
return ws && ws.id !== -1;
if (root.isDwlLike)
if (root.isMango)
return ws && ws.tag !== -1;
if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle)
return ws && ws.num !== -1;
@@ -605,10 +596,9 @@ Item {
HyprlandService.focusWorkspace(data.id);
}
break;
case "dwl":
case "mango":
if (data.tag !== undefined)
root.dwlSvc.switchToTag(root.screenName, data.tag);
MangoService.switchToTag(root.screenName, data.tag);
break;
case "sway":
case "scroll":
@@ -694,7 +684,7 @@ Item {
}
HyprlandService.focusWorkspace(realWorkspaces[nextIndex].id);
} else if (root.isDwlLike) {
} else if (root.isMango) {
const realWorkspaces = getRealWorkspaces();
if (realWorkspaces.length < 2) {
return;
@@ -708,7 +698,7 @@ Item {
return;
}
root.dwlSvc.switchToTag(root.screenName, realWorkspaces[nextIndex].tag);
MangoService.switchToTag(root.screenName, realWorkspaces[nextIndex].tag);
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
const realWorkspaces = getRealWorkspaces();
if (realWorkspaces.length < 2) {
@@ -736,7 +726,7 @@ Item {
return (modelData?.idx !== undefined && modelData?.idx !== -1) ? modelData.idx : "";
if (CompositorService.isHyprland)
return modelData?.id || "";
if (root.isDwlLike)
if (root.isMango)
return (modelData?.tag !== undefined) ? (modelData.tag + 1) : "";
if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle)
return modelData?.num || "";
@@ -751,7 +741,7 @@ Item {
isPlaceholder = modelData?.idx === -1;
} else if (CompositorService.isHyprland) {
isPlaceholder = modelData?.id === -1;
} else if (root.isDwlLike) {
} else if (root.isMango) {
isPlaceholder = modelData?.tag === -1;
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
isPlaceholder = modelData?.num === -1;
@@ -786,7 +776,7 @@ Item {
return getWorkspaceIndexFallback(modelData, index);
}
readonly property bool hasNativeWorkspaceSupport: CompositorService.isNiri || CompositorService.isHyprland || root.isDwlLike || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
readonly property bool hasNativeWorkspaceSupport: CompositorService.isNiri || CompositorService.isHyprland || root.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
readonly property bool hasWorkspaces: getRealWorkspaces().length > 0
readonly property bool shouldShow: hasNativeWorkspaceSupport || (useExtWorkspace && hasWorkspaces)
@@ -1051,7 +1041,7 @@ Item {
return !!(modelData && modelData.idx === root.currentWorkspace);
if (CompositorService.isHyprland)
return !!(modelData && modelData.id === root.currentWorkspace);
if (root.isDwlLike)
if (root.isMango)
return !!(modelData && root.dwlActiveTags.includes(modelData.tag));
if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle)
return !!(modelData && modelData.num === root.currentWorkspace);
@@ -1060,7 +1050,7 @@ Item {
property bool isOccupied: {
if (CompositorService.isHyprland)
return Array.from(Hyprland.toplevels?.values || []).some(tl => tl.workspace?.id === modelData?.id);
if (root.isDwlLike)
if (root.isMango)
return modelData.clients > 0;
if (CompositorService.isNiri) {
const workspace = NiriService.allWorkspaces.find(ws => ws.idx + 1 === modelData && ws.output === root.effectiveScreenName);
@@ -1075,7 +1065,7 @@ Item {
return !!(modelData && modelData.idx === -1);
if (CompositorService.isHyprland)
return !!(modelData && modelData.id === -1);
if (root.isDwlLike)
if (root.isMango)
return !!(modelData && modelData.tag === -1);
if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle)
return !!(modelData && modelData.num === -1);
@@ -1092,7 +1082,7 @@ Item {
return modelData?.urgent ?? false;
if (CompositorService.isNiri)
return loadedIsUrgent;
if (root.isDwlLike)
if (root.isMango)
return modelData?.state === 2;
if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle)
return loadedIsUrgent;
@@ -1120,7 +1110,7 @@ Item {
targetWorkspaceId = modelData?.id;
} else if (CompositorService.isHyprland) {
targetWorkspaceId = modelData?.id;
} else if (root.isDwlLike) {
} else if (root.isMango) {
targetWorkspaceId = modelData?.tag;
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
targetWorkspaceId = modelData?.num;
@@ -1383,8 +1373,8 @@ Item {
}
} else if (CompositorService.isHyprland && modelData?.id) {
HyprlandService.focusWorkspace(modelData.id);
} else if (root.isDwlLike && modelData?.tag !== undefined) {
root.dwlSvc.switchToTag(root.screenName, modelData.tag);
} else if (root.isMango && modelData?.tag !== undefined) {
MangoService.switchToTag(root.screenName, modelData.tag);
} else if ((CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) && modelData?.num) {
try {
I3.dispatch(`workspace number ${modelData.num}`);
@@ -1395,8 +1385,8 @@ Item {
NiriService.toggleOverview();
} else if (CompositorService.isHyprland && root.hyprlandOverviewLoader?.item) {
root.hyprlandOverviewLoader.item.overviewOpen = !root.hyprlandOverviewLoader.item.overviewOpen;
} else if (root.isDwlLike && modelData?.tag !== undefined) {
root.dwlSvc.toggleTag(root.screenName, modelData.tag);
} else if (root.isMango && modelData?.tag !== undefined) {
MangoService.toggleTag(root.screenName, modelData.tag);
}
}
}
@@ -1420,7 +1410,7 @@ Item {
wsData = modelData || null;
} else if (CompositorService.isHyprland) {
wsData = modelData;
} else if (root.isDwlLike) {
} else if (root.isMango) {
wsData = modelData;
} else if (CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
wsData = modelData;
@@ -1434,7 +1424,7 @@ Item {
}
if (SettingsData.showWorkspaceApps) {
if (root.isDwlLike || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
if (root.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle) {
delegateRoot.loadedIcons = root.getWorkspaceIcons(modelData);
} else if (CompositorService.isNiri) {
delegateRoot.loadedIcons = root.getWorkspaceIcons(isPlaceholder ? null : modelData);
@@ -1994,8 +1984,8 @@ Item {
}
}
Connections {
target: root.dwlSvc
enabled: root.isDwlLike
target: MangoService
enabled: root.isMango
function onStateChanged() {
delegateRoot.updateAllData();
}
@@ -183,7 +183,7 @@ Rectangle {
text: {
const dateStr = Qt.formatDate(selectedDate, "MMM d");
if (selectedDateEvents && selectedDateEvents.length > 0) {
const eventCount = selectedDateEvents.length === 1 ? I18n.tr("1 task") : selectedDateEvents.length + " " + I18n.tr("tasks");
const eventCount = selectedDateEvents.length === 1 ? I18n.tr("1 task", "task count next to a date") : I18n.tr("%1 tasks", "task count next to a date, %1 is the number of tasks").arg(selectedDateEvents.length);
return dateStr + " • " + eventCount;
}
return dateStr;
@@ -775,7 +775,7 @@ Rectangle {
width: parent.width
text: {
if (!modelData || modelData.allDay) {
return I18n.tr("All day");
return I18n.tr("All day", "calendar task with no specific time");
} else if (modelData.start && modelData.end) {
const timeFormat = SettingsData.use24HourClock ? "HH:mm" : "h:mm AP";
const startTime = Qt.formatTime(modelData.start, timeFormat);
@@ -950,9 +950,8 @@ Rectangle {
selectByMouse: true
clip: true
// Hint placeholder text
Text {
text: I18n.tr("Add a task...")
text: I18n.tr("Add a task...", "placeholder in the new-task input field")
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.4)
visible: !taskInput.text && !taskInput.activeFocus
font.pixelSize: Theme.fontSizeSmall
@@ -67,9 +67,6 @@ Card {
return I18n.tr("on Niri");
if (CompositorService.isHyprland)
return I18n.tr("on Hyprland");
// technically they might not be on mangowc, but its what we support in the docs
if (CompositorService.isDwl)
return I18n.tr("on MangoWC");
if (CompositorService.isMango)
return I18n.tr("on MangoWC");
if (CompositorService.isSway)
@@ -101,9 +98,7 @@ Card {
}
StyledText {
text: DgopService.shortUptime
? I18n.tr("up") + DgopService.shortUptime.slice(2)
: I18n.tr("up")
text: DgopService.shortUptime ? I18n.tr("up", "uptime prefix, e.g. 'up 4h 2m'") + DgopService.shortUptime.slice(2) : I18n.tr("up", "uptime prefix, e.g. 'up 4h 2m'")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
anchors.verticalCenter: parent.verticalCenter
@@ -20,17 +20,25 @@ Card {
spacing: Theme.spacingS
visible: !WeatherService.weather.available
DankSpinner {
size: 24
visible: WeatherService.weather.loading
anchors.horizontalCenter: parent.horizontalCenter
}
DankIcon {
name: "cloud_off"
size: 24
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.5)
visible: !WeatherService.weather.loading
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: WeatherService.weather.loading ? I18n.tr("Loading...") : I18n.tr("No Weather")
text: I18n.tr("No Weather")
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.7)
visible: !WeatherService.weather.loading
anchors.horizontalCenter: parent.horizontalCenter
}
@@ -236,7 +236,7 @@ Item {
}
IconImage {
visible: SettingsData.dockLauncherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle || CompositorService.isLabwc)
visible: SettingsData.dockLauncherLogoMode === "compositor" && (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle || CompositorService.isLabwc)
anchors.centerIn: parent
width: actualIconSize + SettingsData.dockLauncherLogoSizeOffset
height: actualIconSize + SettingsData.dockLauncherLogoSizeOffset
@@ -247,8 +247,6 @@ Item {
return "file://" + Theme.shellDir + "/assets/niri.svg";
} else if (CompositorService.isHyprland) {
return "file://" + Theme.shellDir + "/assets/hyprland.svg";
} else if (CompositorService.isDwl) {
return "file://" + Theme.shellDir + "/assets/mango.png";
} else if (CompositorService.isMango) {
return "file://" + Theme.shellDir + "/assets/mango.png";
} else if (CompositorService.isSway) {
+68 -2
View File
@@ -753,9 +753,46 @@ Item {
}
}
TextInput {
FocusScope {
id: passwordField
property string text: root.passwordBuffer
property int cursorPosition: text.length
signal accepted()
function clampCursorPosition() {
cursorPosition = Math.max(0, Math.min(cursorPosition, text.length));
}
function clear() {
text = "";
cursorPosition = 0;
}
function insertText(value) {
if (value.length === 0)
return;
clampCursorPosition();
text = text.slice(0, cursorPosition) + value + text.slice(cursorPosition);
cursorPosition += value.length;
}
function backspace() {
clampCursorPosition();
if (cursorPosition === 0)
return;
text = text.slice(0, cursorPosition - 1) + text.slice(cursorPosition);
cursorPosition -= 1;
}
function isPrintableText(value) {
if (value.length === 0)
return false;
const code = value.charCodeAt(0);
return code >= 0x20 && code !== 0x7f;
}
anchors.fill: parent
anchors.leftMargin: lockIconContainer.width + Theme.spacingM * 2
anchors.rightMargin: {
@@ -781,7 +818,6 @@ Item {
focus: true
enabled: !demoMode
activeFocusOnTab: !demoMode
echoMode: parent.showPassword ? TextInput.Normal : TextInput.Password
onTextChanged: {
if (!demoMode) {
root.passwordBuffer = text;
@@ -809,6 +845,8 @@ Item {
return;
}
clear();
event.accepted = true;
return;
}
if (pam.passwd.active) {
@@ -816,6 +854,23 @@ Item {
event.accepted = true;
return;
}
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
accepted();
event.accepted = true;
return;
}
if (event.key === Qt.Key_Backspace) {
backspace();
event.accepted = true;
return;
}
if (isPrintableText(event.text)) {
insertText(event.text);
event.accepted = true;
}
}
Component.onCompleted: {
@@ -849,6 +904,17 @@ Item {
});
}
}
Connections {
target: root
function onPasswordBufferChanged() {
if (passwordField.text === root.passwordBuffer)
return;
passwordField.text = root.passwordBuffer;
passwordField.cursorPosition = passwordField.text.length;
}
}
}
KeyboardController {
+10 -10
View File
@@ -15,7 +15,7 @@ Item {
property bool isSway: CompositorService.isSway
property bool isScroll: CompositorService.isScroll
property bool isMiracle: CompositorService.isMiracle
property bool isDwl: CompositorService.isDwl || CompositorService.isMango
property bool isMango: CompositorService.isMango
property bool isLabwc: CompositorService.isLabwc
property string compositorName: {
@@ -27,7 +27,7 @@ Item {
return "scroll";
if (isMiracle)
return "miracle";
if (isDwl)
if (isMango)
return "mangowc";
if (isLabwc)
return "labwc";
@@ -43,7 +43,7 @@ Item {
return "/assets/sway.svg";
if (isMiracle)
return "/assets/miraclewm.svg";
if (isDwl)
if (isMango)
return "/assets/mango.png";
if (isLabwc)
return "/assets/labwc.png";
@@ -59,7 +59,7 @@ Item {
return "https://github.com/dawsers/scroll";
if (isMiracle)
return "https://github.com/miracle-wm-org/miracle-wm";
if (isDwl)
if (isMango)
return "https://github.com/DreamMaoMao/mangowc";
if (isLabwc)
return "https://labwc.github.io/";
@@ -75,7 +75,7 @@ Item {
return I18n.tr("Scroll GitHub");
if (isMiracle)
return I18n.tr("Scroll GitHub");
if (isDwl)
if (isMango)
return I18n.tr("mangowc GitHub");
if (isLabwc)
return I18n.tr("LabWC Website");
@@ -88,7 +88,7 @@ Item {
property string compositorDiscordUrl: {
if (isHyprland)
return "https://discord.com/invite/hQ9XvMUjjr";
if (isDwl)
if (isMango)
return "https://discord.gg/CPjbDxesh5";
return "";
}
@@ -96,7 +96,7 @@ Item {
property string compositorDiscordTooltip: {
if (isHyprland)
return I18n.tr("Hyprland Discord Server");
if (isDwl)
if (isMango)
return I18n.tr("mangowc Discord Server");
return "";
}
@@ -107,9 +107,9 @@ Item {
property string ircUrl: "https://web.libera.chat/gamja/?channels=#labwc"
property string ircTooltip: I18n.tr("LabWC IRC Channel")
property bool showMatrix: isNiri && !isHyprland && !isSway && !isScroll && !isMiracle && !isDwl && !isLabwc
property bool showCompositorDiscord: isHyprland || isDwl
property bool showReddit: isNiri && !isHyprland && !isSway && !isScroll && !isMiracle && !isDwl && !isLabwc
property bool showMatrix: isNiri && !isHyprland && !isSway && !isScroll && !isMiracle && !isMango && !isLabwc
property bool showCompositorDiscord: isHyprland || isMango
property bool showReddit: isNiri && !isHyprland && !isSway && !isScroll && !isMiracle && !isMango && !isLabwc
property bool showIrc: isLabwc
DankFlickable {
@@ -145,7 +145,7 @@ Item {
tags: ["hyprland", "gaps", "override"]
settingKey: "hyprlandLayoutGapsOverride"
text: I18n.tr("Window Gaps")
description: I18n.tr("Space between windows (gaps_in and gaps_out)")
description: I18n.tr("Space between windows") + " (gaps_in/gaps_out)"
visible: SettingsData.hyprlandLayoutGapsOverride >= 0
value: Math.max(0, SettingsData.hyprlandLayoutGapsOverride)
minimum: 0
@@ -159,7 +159,7 @@ Item {
tags: ["hyprland", "radius", "override", "rounding"]
settingKey: "hyprlandLayoutRadiusOverrideEnabled"
text: I18n.tr("Override Corner Radius")
description: I18n.tr("Use custom window rounding instead of theme radius")
description: I18n.tr("Use custom window radius instead of theme radius")
checked: SettingsData.hyprlandLayoutRadiusOverride >= 0
onToggled: checked => {
if (checked) {
@@ -173,8 +173,8 @@ Item {
SettingsSliderRow {
tags: ["hyprland", "radius", "override", "rounding"]
settingKey: "hyprlandLayoutRadiusOverride"
text: I18n.tr("Window Rounding")
description: I18n.tr("Rounded corners for windows (decoration.rounding)")
text: I18n.tr("Window Corner Radius")
description: I18n.tr("Rounded corners for windows") + " (decoration.rounding)"
visible: SettingsData.hyprlandLayoutRadiusOverride >= 0
value: Math.max(0, SettingsData.hyprlandLayoutRadiusOverride)
minimum: 0
@@ -203,7 +203,7 @@ Item {
tags: ["hyprland", "border", "override"]
settingKey: "hyprlandLayoutBorderSize"
text: I18n.tr("Border Size")
description: I18n.tr("Width of window border (general.border_size)")
description: I18n.tr("Width of window border") + " (general.border_size)"
visible: SettingsData.hyprlandLayoutBorderSize >= 0
value: Math.max(0, SettingsData.hyprlandLayoutBorderSize)
minimum: 0
@@ -229,7 +229,7 @@ Item {
title: I18n.tr("MangoWC Layout Overrides")
settingKey: "mangoLayout"
iconName: "crop_square"
visible: CompositorService.isDwl || CompositorService.isMango
visible: CompositorService.isMango
SettingsToggleRow {
tags: ["mangowc", "mango", "gaps", "override"]
@@ -251,7 +251,7 @@ Item {
tags: ["mangowc", "mango", "gaps", "override"]
settingKey: "mangoLayoutGapsOverride"
text: I18n.tr("Window Gaps")
description: I18n.tr("Space between windows (gappih/gappiv/gappoh/gappov)")
description: I18n.tr("Space between windows") + " (gappih/gappiv/gappoh/gappov)"
visible: SettingsData.mangoLayoutGapsOverride >= 0
value: Math.max(0, SettingsData.mangoLayoutGapsOverride)
minimum: 0
@@ -280,7 +280,7 @@ Item {
tags: ["mangowc", "mango", "radius", "override"]
settingKey: "mangoLayoutRadiusOverride"
text: I18n.tr("Window Corner Radius")
description: I18n.tr("Rounded corners for windows (border_radius)")
description: I18n.tr("Rounded corners for windows") + " (border_radius)"
visible: SettingsData.mangoLayoutRadiusOverride >= 0
value: Math.max(0, SettingsData.mangoLayoutRadiusOverride)
minimum: 0
@@ -309,7 +309,7 @@ Item {
tags: ["mangowc", "mango", "border", "override"]
settingKey: "mangoLayoutBorderSize"
text: I18n.tr("Border Size")
description: I18n.tr("Width of window border (borderpx)")
description: I18n.tr("Width of window border") + " (borderpx)"
visible: SettingsData.mangoLayoutBorderSize >= 0
value: Math.max(0, SettingsData.mangoLayoutBorderSize)
minimum: 0
@@ -1,167 +0,0 @@
pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import qs.Common
import qs.Services
import qs.Widgets
Item {
id: root
LayoutMirroring.enabled: I18n.isRtl
LayoutMirroring.childrenInherit: true
property int subTabIndex: 0
readonly property var workspaceSections: ({
"workspaceSettings": true,
"showWorkspaceIndex": true,
"showWorkspaceName": true,
"showWorkspacePadding": true,
"showWorkspaceApps": true,
"groupWorkspaceApps": true,
"groupActiveWorkspaceApps": true,
"workspaceActiveAppHighlightEnabled": true,
"workspaceFollowFocus": true,
"showOccupiedWorkspacesOnly": true,
"reverseScrolling": true,
"workspaceDragReorder": true,
"dwlShowAllTags": true,
"workspaceIcons": true
})
readonly property var layoutSections: ({
"niriLayout": true,
"niriLayoutGapsOverrideEnabled": true,
"niriLayoutGapsOverride": true,
"niriLayoutRadiusOverrideEnabled": true,
"niriLayoutRadiusOverride": true,
"niriLayoutBorderSizeEnabled": true,
"niriLayoutBorderSize": true,
"hyprlandLayout": true,
"hyprlandLayoutGapsOverrideEnabled": true,
"hyprlandLayoutGapsOverride": true,
"hyprlandLayoutRadiusOverrideEnabled": true,
"hyprlandLayoutRadiusOverride": true,
"hyprlandLayoutBorderSizeEnabled": true,
"hyprlandLayoutBorderSize": true,
"hyprlandResizeOnBorder": true,
"mangoLayout": true,
"mangoLayoutGapsOverrideEnabled": true,
"mangoLayoutGapsOverride": true,
"mangoLayoutRadiusOverrideEnabled": true,
"mangoLayoutRadiusOverride": true,
"mangoLayoutBorderSizeEnabled": true,
"mangoLayoutBorderSize": true
})
function routeSearchTarget(target) {
if (!target)
return;
if (workspaceSections[target]) {
subTabIndex = 0;
} else if (layoutSections[target]) {
subTabIndex = 1;
} else if (target === "windowRules" || target.startsWith("windowRule")) {
subTabIndex = 2;
}
}
Component.onCompleted: routeSearchTarget(SettingsSearchService.targetSection)
Connections {
target: SettingsSearchService
function onTargetSectionChanged() {
root.routeSearchTarget(SettingsSearchService.targetSection);
}
}
ColumnLayout {
anchors.fill: parent
spacing: 0
Rectangle {
Layout.fillWidth: true
Layout.preferredHeight: 60
color: "transparent"
DankTabBar {
id: compositorTabBar
width: Math.min(500, parent.width - Theme.spacingL * 2)
height: 45
anchors.centerIn: parent
model: [
{
"text": I18n.tr("Workspaces"),
"icon": "view_module"
},
{
"text": I18n.tr("Window Layout"),
"icon": "crop_square"
},
{
"text": I18n.tr("Window Rules"),
"icon": "select_window"
}
]
currentIndex: root.subTabIndex
onTabClicked: index => root.subTabIndex = index
}
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
y: compositorTabBar.y + compositorTabBar.height + 10
width: compositorTabBar.width
height: 1
color: Theme.surface
opacity: 0.56
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
Loader {
anchors.fill: parent
active: root.subTabIndex === 0
visible: active
sourceComponent: WorkspacesTab {}
}
Loader {
anchors.fill: parent
active: root.subTabIndex === 1
visible: active
sourceComponent: CompositorLayoutTab {}
}
Loader {
id: windowRulesLoader
property bool loadedOnce: false
anchors.fill: parent
active: root.subTabIndex === 2 || loadedOnce
visible: root.subTabIndex === 2 && status === Loader.Ready
asynchronous: true
sourceComponent: WindowRulesTab {
pageActive: root.subTabIndex === 2
}
onLoaded: loadedOnce = true
}
StyledText {
anchors.centerIn: parent
visible: root.subTabIndex === 2 && windowRulesLoader.status === Loader.Loading
text: I18n.tr("Loading...", "loading indicator")
color: Theme.surfaceVariantText
font.pixelSize: Theme.fontSizeMedium
}
}
}
}
+2 -2
View File
@@ -41,8 +41,8 @@ Item {
SettingsData.barConfigs;
const index = SettingsData.barConfigs.findIndex(config => config.id === selectedBarId);
if (index < 0)
return I18n.tr("Bar");
return SettingsData.barConfigs[index].name || I18n.tr("Bar %1").arg(index + 1);
return I18n.tr("Bar", "fallback name for an unnamed bar");
return SettingsData.barConfigs[index].name || I18n.tr("Bar %1", "numbered name for an unnamed bar, %1 is its position").arg(index + 1);
}
property bool selectedBarIsVertical: {
@@ -1023,7 +1023,6 @@ Singleton {
return parseNiriOutputs(content);
case "hyprland":
return parseHyprlandOutputs(content);
case "dwl":
case "mango":
return parseMangoOutputs(content);
default:
@@ -1362,7 +1361,6 @@ Singleton {
"grepPattern": "dms.outputs",
"includeLine": "require(\"dms.outputs\")"
};
case "dwl":
case "mango":
return {
"configFile": configDir + "/mango/config.conf",
@@ -1377,7 +1375,7 @@ Singleton {
function checkIncludeStatus() {
const compositor = CompositorService.compositor;
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "dwl" && compositor !== "mango") {
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
includeStatus = {
"exists": false,
"included": false,
@@ -1388,8 +1386,7 @@ Singleton {
}
const filename = (compositor === "niri") ? "outputs.kdl" : ((compositor === "hyprland") ? "outputs.lua" : "outputs.conf");
// mango and dwl both use outputs.conf under ~/.config/mango
const compositorArg = (compositor === "dwl" || compositor === "mango") ? "mangowc" : compositor;
const compositorArg = (compositor === "mango") ? "mangowc" : compositor;
checkingInclude = true;
Proc.runCommand("check-outputs-include", ["dms", "config", "resolve-include", compositorArg, filename], (output, exitCode) => {
@@ -1589,9 +1586,6 @@ Singleton {
case "mango":
MangoService.generateOutputsConfig(outputsData, finish);
break;
case "dwl":
DwlService.generateOutputsConfig(outputsData, finish);
break;
default:
WlrOutputService.applyOutputsConfig(outputsData, outputs);
finish(true);
@@ -317,7 +317,7 @@ StyledRect {
DankToggle {
width: parent.width
text: I18n.tr("Variable Refresh Rate")
visible: root.isConnected && !root.isDisabled && !CompositorService.isDwl && !CompositorService.isMango && !CompositorService.isHyprland && !CompositorService.isNiri && (DisplayConfigState.outputs[root.outputName]?.vrr_supported ?? false)
visible: root.isConnected && !root.isDisabled && !CompositorService.isMango && !CompositorService.isHyprland && !CompositorService.isNiri && (DisplayConfigState.outputs[root.outputName]?.vrr_supported ?? false)
checked: {
const pendingVrr = DisplayConfigState.getPendingValue(root.outputName, "vrr");
if (pendingVrr !== undefined)
@@ -500,7 +500,7 @@ Item {
Column {
id: displayFormatColumn
visible: !CompositorService.isDwl && !CompositorService.isMango
visible: !CompositorService.isMango
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
-2
View File
@@ -282,8 +282,6 @@ Item {
modes.push("niri");
} else if (CompositorService.isHyprland) {
modes.push("Hyprland");
} else if (CompositorService.isDwl) {
modes.push("mango");
} else if (CompositorService.isMango) {
modes.push("mango");
} else if (CompositorService.isSway) {
+4 -4
View File
@@ -151,7 +151,7 @@ Item {
function runGreeterInstallAction() {
root.greeterPendingAction = !root.greeterInstalled ? "install" : !root.greeterEnabled ? "activate" : "uninstall";
greeterStatusText = I18n.tr("Opening terminal: ") + root.greeterActionLabel + "";
greeterStatusText = I18n.tr("Opening terminal: ") + root.greeterActionLabel + "...";
greeterInstallActionRunning = true;
greeterInstallActionProcess.running = true;
}
@@ -188,7 +188,7 @@ Item {
greeterSudoProbeStderr = "";
greeterTerminalFallbackStderr = "";
greeterTerminalFallbackFromPrecheck = false;
greeterStatusText = I18n.tr("Checking whether sudo authentication is needed");
greeterStatusText = I18n.tr("Checking whether sudo authentication is needed...");
greeterSyncRunning = true;
greeterSudoProbeProcess.running = true;
}
@@ -327,7 +327,7 @@ Item {
onExited: exitCode => {
const err = (root.greeterSudoProbeStderr || "").trim();
if (exitCode === 0) {
root.greeterStatusText = I18n.tr("Running greeter sync");
root.greeterStatusText = I18n.tr("Running greeter sync...");
greeterSyncProcess.running = true;
return;
}
@@ -468,7 +468,7 @@ Item {
id: statusTextArea
anchors.fill: parent
anchors.margins: Theme.spacingM
text: root.greeterStatusRunning ? I18n.tr("Checking", "greeter status loading") : (root.greeterStatusText || I18n.tr("Click Refresh to check status.", "greeter status placeholder"))
text: root.greeterStatusRunning ? I18n.tr("Checking...", "greeter status loading") : (root.greeterStatusText || I18n.tr("Click Refresh to check status.", "greeter status placeholder"))
font.pixelSize: Theme.fontSizeSmall
font.family: "monospace"
color: root.greeterStatusRunning ? Theme.surfaceVariantText : Theme.surfaceText
@@ -304,8 +304,6 @@ Item {
modes.push("niri");
} else if (CompositorService.isHyprland) {
modes.push("Hyprland");
} else if (CompositorService.isDwl) {
modes.push("mango");
} else if (CompositorService.isMango) {
modes.push("mango");
} else if (CompositorService.isSway) {
+6 -102
View File
@@ -643,41 +643,9 @@ Item {
height: NetworkService.networkWiredInfoLoading ? 40 : 0
visible: NetworkService.networkWiredInfoLoading
Row {
DankSpinner {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
id: wiredLoadIcon
name: "sync"
size: 16
color: Theme.surfaceVariantText
SequentialAnimation {
running: NetworkService.networkWiredInfoLoading
loops: Animation.Infinite
OpacityAnimator {
target: wiredLoadIcon
to: 0.3
duration: 400
easing.type: Easing.InOutQuad
}
OpacityAnimator {
target: wiredLoadIcon
to: 1.0
duration: 400
easing.type: Easing.InOutQuad
}
onRunningChanged: if (!running)
wiredLoadIcon.opacity = 1.0
}
}
StyledText {
text: I18n.tr("Loading...")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
size: 20
}
}
}
@@ -1360,41 +1328,9 @@ Item {
height: NetworkService.networkInfoLoading ? 40 : 0
visible: NetworkService.networkInfoLoading
Row {
DankSpinner {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
id: wifiInfoLoadIcon
name: "sync"
size: 16
color: Theme.surfaceVariantText
SequentialAnimation {
running: NetworkService.networkInfoLoading
loops: Animation.Infinite
OpacityAnimator {
target: wifiInfoLoadIcon
to: 0.3
duration: 400
easing.type: Easing.InOutQuad
}
OpacityAnimator {
target: wifiInfoLoadIcon
to: 1.0
duration: 400
easing.type: Easing.InOutQuad
}
onRunningChanged: if (!running)
wifiInfoLoadIcon.opacity = 1.0
}
}
StyledText {
text: I18n.tr("Loading...")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
size: 20
}
}
@@ -1849,41 +1785,9 @@ Item {
height: VPNService.configLoading ? 40 : 0
visible: VPNService.configLoading
Row {
DankSpinner {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
id: vpnLoadIcon
name: "sync"
size: 16
color: Theme.surfaceVariantText
SequentialAnimation {
running: VPNService.configLoading
loops: Animation.Infinite
OpacityAnimator {
target: vpnLoadIcon
to: 0.3
duration: 400
easing.type: Easing.InOutQuad
}
OpacityAnimator {
target: vpnLoadIcon
to: 1.0
duration: 400
easing.type: Easing.InOutQuad
}
onRunningChanged: if (!running)
vpnLoadIcon.opacity = 1.0
}
}
StyledText {
text: I18n.tr("Loading...")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
size: 20
}
}
+34 -35
View File
@@ -33,11 +33,31 @@ FloatingWindow {
}
readonly property var sortChipOptions: [
{ id: "installed", label: I18n.tr("Installed", "plugin browser filter chip"), toggle: true },
{ id: "default", label: I18n.tr("Default", "plugin browser sort option"), toggle: false },
{ id: "name", label: I18n.tr("Name", "plugin browser sort option"), toggle: false },
{ id: "author", label: I18n.tr("Contributor", "plugin browser sort option"), toggle: false },
{ id: "category", label: I18n.tr("Category", "plugin browser sort option"), toggle: false }
{
id: "installed",
label: I18n.tr("Installed", "plugin browser filter chip"),
toggle: true
},
{
id: "default",
label: I18n.tr("Default", "plugin browser sort option"),
toggle: false
},
{
id: "name",
label: I18n.tr("Name", "plugin browser sort option"),
toggle: false
},
{
id: "author",
label: I18n.tr("Contributor", "plugin browser sort option"),
toggle: false
},
{
id: "category",
label: I18n.tr("Category", "plugin browser sort option"),
toggle: false
}
]
function normalizedSortMode(mode) {
@@ -107,11 +127,13 @@ FloatingWindow {
counts[cat] = (counts[cat] || 0) + 1;
}
var keys = Object.keys(counts).sort();
var options = [{
key: "all",
label: I18n.tr("All", "plugin browser category filter"),
count: plugins.length
}];
var options = [
{
key: "all",
label: I18n.tr("All", "plugin browser category filter"),
count: plugins.length
}
];
for (var j = 0; j < keys.length; j++) {
var key = keys[j];
options.push({
@@ -726,32 +748,9 @@ FloatingWindow {
anchors.fill: parent
visible: root.isLoading
Column {
DankSpinner {
anchors.centerIn: parent
spacing: Theme.spacingM
DankIcon {
name: "sync"
size: 48
color: Theme.primary
anchors.horizontalCenter: parent.horizontalCenter
smoothTransform: root.isLoading
RotationAnimator on rotation {
from: 0
to: -360
duration: 1000
loops: Animation.Infinite
running: root.isLoading
}
}
StyledText {
text: I18n.tr("Loading...", "loading indicator")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
running: root.isLoading
}
}
+2 -25
View File
@@ -335,32 +335,9 @@ FloatingWindow {
anchors.fill: parent
visible: root.isLoading
Column {
DankSpinner {
anchors.centerIn: parent
spacing: Theme.spacingM
DankIcon {
name: "sync"
size: 48
color: Theme.primary
anchors.horizontalCenter: parent.horizontalCenter
smoothTransform: root.isLoading
RotationAnimator on rotation {
from: 0
to: 360
duration: 1000
loops: Animation.Infinite
running: root.isLoading
}
}
StyledText {
text: I18n.tr("Loading...", "loading indicator")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
running: root.isLoading
}
}
+4 -11
View File
@@ -48,7 +48,6 @@ Item {
"grepPattern": "dms.cursor",
"includeLine": "require(\"dms.cursor\")"
};
case "dwl":
case "mango":
return {
"configFile": configDir + "/mango/config.conf",
@@ -63,7 +62,7 @@ Item {
function checkCursorIncludeStatus() {
const compositor = CompositorService.compositor;
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "dwl" && compositor !== "mango") {
if (compositor !== "niri" && compositor !== "hyprland" && compositor !== "mango") {
cursorIncludeStatus = {
"exists": false,
"included": false,
@@ -74,7 +73,7 @@ Item {
}
const filename = (compositor === "niri") ? "cursor.kdl" : ((compositor === "hyprland") ? "cursor.lua" : "cursor.conf");
const compositorArg = (compositor === "dwl" || compositor === "mango") ? "mangowc" : compositor;
const compositorArg = (compositor === "mango") ? "mangowc" : compositor;
checkingCursorInclude = true;
Proc.runCommand("check-cursor-include", ["dms", "config", "resolve-include", compositorArg, filename], (output, exitCode) => {
@@ -194,7 +193,7 @@ Item {
themeColorsTab.templateDetection = JSON.parse(output.trim());
} catch (e) {}
});
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango)
if (CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango)
checkCursorIncludeStatus();
}
@@ -2016,7 +2015,7 @@ Item {
title: I18n.tr("Cursor Theme")
settingKey: "cursorTheme"
iconName: "mouse"
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango
Column {
width: parent.width
@@ -2181,8 +2180,6 @@ Item {
return SettingsData.cursorSettings.niri?.hideAfterInactiveMs || 0;
if (CompositorService.isHyprland)
return SettingsData.cursorSettings.hyprland?.inactiveTimeout || 0;
if (CompositorService.isDwl)
return SettingsData.cursorSettings.dwl?.cursorHideTimeout || 0;
if (CompositorService.isMango)
return SettingsData.cursorSettings.mango?.cursorHideTimeout || 0;
return 0;
@@ -2201,10 +2198,6 @@ Item {
if (!updated.hyprland)
updated.hyprland = {};
updated.hyprland.inactiveTimeout = newValue;
} else if (CompositorService.isDwl) {
if (!updated.dwl)
updated.dwl = {};
updated.dwl.cursorHideTimeout = newValue;
} else if (CompositorService.isMango) {
if (!updated.mango)
updated.mango = {};
+2 -2
View File
@@ -139,7 +139,7 @@ Item {
}
StyledText {
text: UsersService.refreshing ? I18n.tr("Refreshing") : ""
text: UsersService.refreshing ? I18n.tr("Refreshing...") : ""
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.verticalCenter: parent.verticalCenter
@@ -474,7 +474,7 @@ Item {
spacing: Theme.spacingM
DankButton {
text: root.operationPending ? I18n.tr("Working") : I18n.tr("Create User")
text: root.operationPending ? I18n.tr("Working...") : I18n.tr("Create User")
iconName: "person_add"
backgroundColor: Theme.primary
textColor: Theme.primaryText
+3 -3
View File
@@ -37,10 +37,10 @@ Item {
{
"id": "layout",
"text": I18n.tr("Layout"),
"description": I18n.tr("Display and switch DWL layouts"),
"description": I18n.tr("Display and switch MangoWC layouts"),
"icon": "view_quilt",
"enabled": (CompositorService.isDwl && DwlService.dwlAvailable) || (CompositorService.isMango && MangoService.available),
"warning": CompositorService.isMango ? (!MangoService.available ? I18n.tr("DWL service not available") : undefined) : (!CompositorService.isDwl ? I18n.tr("Requires DWL compositor") : (!DwlService.dwlAvailable ? I18n.tr("DWL service not available") : undefined))
"enabled": CompositorService.isMango && MangoService.available,
"warning": !CompositorService.isMango ? I18n.tr("Requires MangoWC compositor") : (!MangoService.available ? I18n.tr("Mango service not available") : undefined)
},
{
"id": "launcherButton",
@@ -51,7 +51,7 @@ SettingsCard {
SettingsButtonGroupRow {
text: I18n.tr("Occupied Color")
model: ["none", "sec", "s", "sc", "sch", "schh"]
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango
buttonHeight: 22
minButtonWidth: 36
buttonPadding: Theme.spacingS
@@ -87,7 +87,7 @@ SettingsCard {
height: 1
color: Theme.outline
opacity: 0.15
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango
}
SettingsButtonGroupRow {
@@ -124,12 +124,12 @@ SettingsCard {
height: 1
color: Theme.outline
opacity: 0.15
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
}
SettingsButtonGroupRow {
text: I18n.tr("Urgent Color")
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
model: ["err", "pri", "sec", "s", "sc"]
buttonHeight: 22
minButtonWidth: 36
@@ -153,7 +153,7 @@ Item {
text: I18n.tr("Follow Monitor Focus")
description: I18n.tr("Show workspaces of the currently focused monitor")
checked: SettingsData.workspaceFollowFocus
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango || CompositorService.isSway || CompositorService.isScroll || CompositorService.isMiracle
onToggled: checked => SettingsData.set("workspaceFollowFocus", checked)
}
@@ -193,7 +193,7 @@ Item {
text: I18n.tr("Show All Tags")
description: I18n.tr("Show all 9 tags instead of only occupied tags")
checked: SettingsData.dwlShowAllTags
visible: CompositorService.isDwl || CompositorService.isMango
visible: CompositorService.isMango
onToggled: checked => SettingsData.set("dwlShowAllTags", checked)
}
}
+11 -106
View File
@@ -15,7 +15,6 @@ Singleton {
property bool isHyprland: false
property bool isNiri: false
property bool isDwl: false
property bool isMango: false
property bool isSway: false
property bool isScroll: false
@@ -97,12 +96,6 @@ Singleton {
return hyprlandMonitor.scale;
}
if (isDwl && screen) {
const dwlScale = DwlService.getOutputScale(screen.name);
if (dwlScale !== undefined && dwlScale > 0)
return dwlScale;
}
if (isMango && screen) {
const mangoScale = MangoService.getOutputScale(screen.name);
if (mangoScale !== undefined && mangoScale > 0)
@@ -121,9 +114,7 @@ Singleton {
else if (isSway || isScroll || isMiracle) {
const focusedWs = I3.workspaces?.values?.find(ws => ws.focused === true);
screenName = focusedWs?.monitor?.name || "";
} else if (isDwl && DwlService.activeOutput)
screenName = DwlService.activeOutput;
else if (isMango && MangoService.activeOutput)
} else if (isMango && MangoService.activeOutput)
screenName = MangoService.activeOutput;
if (!screenName)
@@ -192,19 +183,9 @@ Singleton {
Qt.callLater(() => {
NiriService.generateNiriLayoutConfig();
HyprlandService.generateLayoutConfig();
DwlService.generateLayoutConfig();
});
}
Connections {
target: DwlService
function onStateChanged() {
if (isDwl && !isHyprland && !isNiri) {
scheduleSort();
}
}
}
Connections {
target: MangoService
function onStateChanged() {
@@ -271,13 +252,7 @@ Singleton {
function _specialWorkspaceNameFromMonitor(monitor) {
if (!monitor)
return "";
const candidates = [
monitor.activeSpecialWorkspace?.name,
monitor.specialWorkspace?.name,
monitor.lastIpcObject?.specialWorkspace?.name,
monitor.lastIpcObject?.specialWorkspace,
monitor.lastIpcObject?.activeSpecialWorkspace?.name
];
const candidates = [monitor.activeSpecialWorkspace?.name, monitor.specialWorkspace?.name, monitor.lastIpcObject?.specialWorkspace?.name, monitor.lastIpcObject?.specialWorkspace, monitor.lastIpcObject?.activeSpecialWorkspace?.name];
for (let i = 0; i < candidates.length; i++) {
const normalized = _normalizeSpecialWorkspaceName(candidates[i]);
if (normalized)
@@ -860,7 +835,6 @@ Singleton {
Qt.callLater(() => {
NiriService.generateNiriLayoutConfig();
HyprlandService.generateLayoutConfig();
DwlService.generateLayoutConfig();
MangoService.generateLayoutConfig();
});
}
@@ -870,7 +844,6 @@ Singleton {
if (mangoSignature && mangoSignature.length > 0) {
isHyprland = false;
isNiri = false;
isDwl = false;
isMango = true;
isSway = false;
isScroll = false;
@@ -884,7 +857,6 @@ Singleton {
if (hyprlandSignature && hyprlandSignature.length > 0 && !niriSocket && !swaySocket && !scrollSocket && !miracleSocket && !labwcPid) {
isHyprland = true;
isNiri = false;
isDwl = false;
isMango = false;
isSway = false;
isScroll = false;
@@ -900,7 +872,6 @@ Singleton {
if (exitCode === 0) {
isNiri = true;
isHyprland = false;
isDwl = false;
isMango = false;
isSway = false;
isScroll = false;
@@ -919,7 +890,6 @@ Singleton {
if (exitCode === 0) {
isNiri = false;
isHyprland = false;
isDwl = false;
isSway = true;
isScroll = false;
isMiracle = false;
@@ -936,7 +906,6 @@ Singleton {
if (exitCode === 0) {
isNiri = false;
isHyprland = false;
isDwl = false;
isMango = false;
isSway = false;
isScroll = false;
@@ -954,7 +923,6 @@ Singleton {
if (exitCode === 0) {
isNiri = false;
isHyprland = false;
isDwl = false;
isMango = false;
isSway = false;
isScroll = true;
@@ -970,7 +938,6 @@ Singleton {
if (labwcPid && labwcPid.length > 0) {
isHyprland = false;
isNiri = false;
isDwl = false;
isMango = false;
isSway = false;
isScroll = false;
@@ -981,45 +948,15 @@ Singleton {
return;
}
if (DMSService.dmsAvailable) {
Qt.callLater(checkForDwl);
} else {
isHyprland = false;
isNiri = false;
isDwl = false;
isMango = false;
isSway = false;
isScroll = false;
isMiracle = false;
isLabwc = false;
compositor = "unknown";
log.warn("No compositor detected");
}
}
Connections {
target: DMSService
function onCapabilitiesReceived() {
if (!isHyprland && !isNiri && !isDwl && !isMango && !isLabwc) {
checkForDwl();
}
}
}
function checkForDwl() {
if (isMango)
return;
if (DMSService.apiVersion >= 12 && DMSService.capabilities.includes("dwl")) {
isHyprland = false;
isNiri = false;
isDwl = true;
isSway = false;
isScroll = false;
isMiracle = false;
isLabwc = false;
compositor = "dwl";
log.info("Detected DWL via DMS capability");
}
isHyprland = false;
isNiri = false;
isMango = false;
isSway = false;
isScroll = false;
isMiracle = false;
isLabwc = false;
compositor = "unknown";
log.warn("No compositor detected");
}
function powerOffMonitors() {
@@ -1027,8 +964,6 @@ Singleton {
return NiriService.powerOffMonitors();
if (isHyprland)
return HyprlandService.dpmsOff();
if (isDwl)
return _dwlPowerOffMonitors();
if (isMango)
return MangoService.powerOffMonitors();
if (isSway || isScroll || isMiracle) {
@@ -1048,8 +983,6 @@ Singleton {
return NiriService.powerOnMonitors();
if (isHyprland)
return HyprlandService.dpmsOn();
if (isDwl)
return _dwlPowerOnMonitors();
if (isMango)
return MangoService.powerOnMonitors();
if (isSway || isScroll || isMiracle) {
@@ -1063,32 +996,4 @@ Singleton {
}
log.warn("Cannot power on monitors, unknown compositor");
}
function _dwlPowerOffMonitors() {
if (!Quickshell.screens || Quickshell.screens.length === 0) {
log.warn("No screens available for DWL power off");
return;
}
for (let i = 0; i < Quickshell.screens.length; i++) {
const screen = Quickshell.screens[i];
if (screen && screen.name) {
Quickshell.execDetached(["mmsg", "dispatch", "disable_monitor," + screen.name]);
}
}
}
function _dwlPowerOnMonitors() {
if (!Quickshell.screens || Quickshell.screens.length === 0) {
log.warn("No screens available for DWL power on");
return;
}
for (let i = 0; i < Quickshell.screens.length; i++) {
const screen = Quickshell.screens[i];
if (screen && screen.name) {
Quickshell.execDetached(["mmsg", "dispatch", "enable_monitor," + screen.name]);
}
}
}
}
+3 -6
View File
@@ -49,7 +49,6 @@ Singleton {
signal capabilitiesReceived
signal credentialsRequest(var data)
signal bluetoothPairingRequest(var data)
signal dwlStateUpdate(var data)
signal brightnessStateUpdate(var data)
signal brightnessDeviceUpdate(var device)
signal wlrOutputStateUpdate(var data)
@@ -68,7 +67,7 @@ Singleton {
property bool screensaverInhibited: false
property var screensaverInhibitors: []
property var activeSubscriptions: ["network", "network.credentials", "loginctl", "freedesktop", "freedesktop.screensaver", "gamma", "theme.auto", "bluetooth", "bluetooth.pairing", "dwl", "brightness", "wlroutput", "evdev", "browser", "dbus", "clipboard", "location", "sysupdate"]
property var activeSubscriptions: ["network", "network.credentials", "loginctl", "freedesktop", "freedesktop.screensaver", "gamma", "theme.auto", "bluetooth", "bluetooth.pairing", "brightness", "wlroutput", "evdev", "browser", "dbus", "clipboard", "location", "sysupdate"]
Component.onCompleted: {
if (socketPath && socketPath.length > 0) {
@@ -286,7 +285,7 @@ Singleton {
function removeSubscription(service) {
if (activeSubscriptions.includes("all")) {
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "dwl", "brightness", "browser", "location"];
const allServices = ["network", "loginctl", "freedesktop", "gamma", "bluetooth", "brightness", "browser", "location"];
const filtered = allServices.filter(s => s !== service);
subscribe(filtered);
} else {
@@ -308,7 +307,7 @@ Singleton {
excludeServices = [excludeServices];
}
const allServices = ["network", "loginctl", "freedesktop", "gamma", "theme.auto", "bluetooth", "cups", "dwl", "brightness", "browser", "dbus", "location"];
const allServices = ["network", "loginctl", "freedesktop", "gamma", "theme.auto", "bluetooth", "cups", "brightness", "browser", "dbus", "location"];
const filtered = allServices.filter(s => !excludeServices.includes(s));
subscribe(filtered);
}
@@ -354,8 +353,6 @@ Singleton {
bluetoothPairingRequest(data);
} else if (service === "cups") {
cupsStateUpdate(data);
} else if (service === "dwl") {
dwlStateUpdate(data);
} else if (service === "brightness") {
brightnessStateUpdate(data);
} else if (service === "brightness.update") {
-461
View File
@@ -1,461 +0,0 @@
pragma Singleton
pragma ComponentBehavior: Bound
import QtCore
import QtQuick
import Quickshell
import Quickshell.Io
import qs.Common
import qs.Services
Singleton {
id: root
readonly property var log: Log.scoped("DwlService")
readonly property string configDir: Paths.strip(StandardPaths.writableLocation(StandardPaths.ConfigLocation))
readonly property string mangoDmsDir: configDir + "/mango/dms"
readonly property string outputsPath: mangoDmsDir + "/outputs.conf"
readonly property string layoutPath: mangoDmsDir + "/layout.conf"
readonly property string cursorPath: mangoDmsDir + "/cursor.conf"
property int _lastGapValue: -1
property bool dwlAvailable: false
// Alias so consumers can treat DwlService/MangoService uniformly via `.available`.
readonly property bool available: dwlAvailable
property var outputs: ({})
property var tagCount: 9
property var layouts: []
property string activeOutput: ""
property var outputScales: ({})
property string currentKeyboardLayout: {
if (!outputs || !activeOutput)
return "";
const output = outputs[activeOutput];
return (output && output.kbLayout) || "";
}
signal stateChanged
Connections {
target: SettingsData
function onBarConfigsChanged() {
if (!CompositorService.isDwl)
return;
const newGaps = Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4));
if (newGaps === root._lastGapValue)
return;
root._lastGapValue = newGaps;
generateLayoutConfig();
}
}
Connections {
target: CompositorService
function onIsDwlChanged() {
if (CompositorService.isDwl)
generateLayoutConfig();
}
}
Connections {
target: DMSService
function onCapabilitiesReceived() {
checkCapabilities();
}
function onConnectionStateChanged() {
if (DMSService.isConnected) {
checkCapabilities();
} else {
dwlAvailable = false;
}
}
function onDwlStateUpdate(data) {
if (dwlAvailable) {
handleStateUpdate(data);
}
}
}
Component.onCompleted: {
if (DMSService.dmsAvailable)
checkCapabilities();
if (dwlAvailable)
refreshOutputScales();
if (CompositorService.isDwl)
Qt.callLater(generateLayoutConfig);
}
function checkCapabilities() {
if (!DMSService.capabilities || !Array.isArray(DMSService.capabilities)) {
dwlAvailable = false;
return;
}
const hasDwl = DMSService.capabilities.includes("dwl");
if (hasDwl && !dwlAvailable) {
dwlAvailable = true;
log.info("DWL capability detected");
requestState();
refreshOutputScales();
} else if (!hasDwl) {
dwlAvailable = false;
}
}
function requestState() {
if (!DMSService.isConnected || !dwlAvailable) {
return;
}
DMSService.sendRequest("dwl.getState", null, response => {
if (response.result) {
handleStateUpdate(response.result);
}
});
}
function handleStateUpdate(state) {
outputs = state.outputs || {};
tagCount = state.tagCount || 9;
layouts = state.layouts || [];
activeOutput = state.activeOutput || "";
stateChanged();
}
function setTags(outputName, tagmask, toggleTagset) {
if (!DMSService.isConnected || !dwlAvailable) {
return;
}
DMSService.sendRequest("dwl.setTags", {
"output": outputName,
"tagmask": tagmask,
"toggleTagset": toggleTagset
}, response => {
if (response.error) {
log.warn("setTags error:", response.error);
}
});
}
function setClientTags(outputName, andTags, xorTags) {
if (!DMSService.isConnected || !dwlAvailable) {
return;
}
DMSService.sendRequest("dwl.setClientTags", {
"output": outputName,
"andTags": andTags,
"xorTags": xorTags
}, response => {
if (response.error) {
log.warn("setClientTags error:", response.error);
}
});
}
function setLayout(outputName, index) {
if (!DMSService.isConnected || !dwlAvailable) {
return;
}
DMSService.sendRequest("dwl.setLayout", {
"output": outputName,
"index": index
}, response => {
if (response.error) {
log.warn("setLayout error:", response.error);
}
});
}
function getOutputState(outputName) {
if (!outputs || !outputs[outputName]) {
return null;
}
return outputs[outputName];
}
function getActiveTags(outputName) {
const output = getOutputState(outputName);
if (!output || !output.tags) {
return [];
}
return output.tags.filter(tag => tag.state === 1).map(tag => tag.tag);
}
function getTagsWithClients(outputName) {
const output = getOutputState(outputName);
if (!output || !output.tags) {
return [];
}
return output.tags.filter(tag => tag.clients > 0).map(tag => tag.tag);
}
function getUrgentTags(outputName) {
const output = getOutputState(outputName);
if (!output || !output.tags) {
return [];
}
return output.tags.filter(tag => tag.state === 2).map(tag => tag.tag);
}
function switchToTag(outputName, tagIndex) {
const tagmask = 1 << tagIndex;
setTags(outputName, tagmask, 0);
}
function toggleTag(outputName, tagIndex) {
const output = getOutputState(outputName);
if (!output || !output.tags) {
log.debug("toggleTag: no output or tags for", outputName);
return;
}
let currentMask = 0;
output.tags.forEach(tag => {
if (tag.state === 1) {
currentMask |= (1 << tag.tag);
}
});
const clickedMask = 1 << tagIndex;
const newMask = currentMask ^ clickedMask;
log.debug("toggleTag:", outputName, "tag:", tagIndex, "currentMask:", currentMask.toString(2), "clickedMask:", clickedMask.toString(2), "newMask:", newMask.toString(2));
if (newMask === 0) {
log.debug("toggleTag: newMask is 0, switching to tag", tagIndex);
setTags(outputName, 1 << tagIndex, 0);
} else {
log.debug("toggleTag: setting combined mask", newMask);
setTags(outputName, newMask, 0);
}
}
function quit() {
Quickshell.execDetached(["mmsg", "dispatch", "quit"]);
}
Process {
id: scaleQueryProcess
command: ["mmsg", "get", "all-monitors"]
running: false
stdout: StdioCollector {
onStreamFinished: {
try {
const newScales = {};
const data = JSON.parse(text.trim());
const monitors = data.monitors || [];
for (const mon of monitors) {
if (mon.name && typeof mon.scale === "number" && mon.scale > 0) {
newScales[mon.name] = mon.scale;
}
}
outputScales = newScales;
} catch (e) {
log.warn("Failed to parse mmsg output:", e);
}
}
}
onExited: exitCode => {
if (exitCode !== 0) {
log.warn("mmsg failed with exit code:", exitCode);
}
}
}
function refreshOutputScales() {
if (!dwlAvailable)
return;
scaleQueryProcess.running = true;
}
function getOutputScale(outputName) {
return outputScales[outputName];
}
function getVisibleTags(outputName) {
const output = getOutputState(outputName);
if (!output || !output.tags) {
return [];
}
const visibleTags = new Set();
output.tags.forEach(tag => {
if (tag.state === 1 || tag.clients > 0) {
visibleTags.add(tag.tag);
}
});
return Array.from(visibleTags).sort((a, b) => a - b);
}
function generateOutputsConfig(outputsData, callback) {
if (!outputsData || Object.keys(outputsData).length === 0) {
if (callback)
callback(false);
return;
}
let lines = ["# Auto-generated by DMS - do not edit manually", ""];
for (const outputName in outputsData) {
const output = outputsData[outputName];
if (!output)
continue;
let width = 1920;
let height = 1080;
let refreshRate = 60;
if (output.modes && output.current_mode !== undefined) {
const mode = output.modes[output.current_mode];
if (mode) {
width = mode.width || 1920;
height = mode.height || 1080;
refreshRate = Math.round((mode.refresh_rate || 60000) / 1000);
}
}
const x = output.logical?.x ?? 0;
const y = output.logical?.y ?? 0;
const scale = output.logical?.scale ?? 1.0;
const transform = transformToMango(output.logical?.transform ?? "Normal");
const vrr = output.vrr_enabled ? 1 : 0;
const rule = ["name:^" + outputName + "$", "width:" + width, "height:" + height, "refresh:" + refreshRate, "x:" + x, "y:" + y, "scale:" + scale, "rr:" + transform, "vrr:" + vrr].join(",");
lines.push("monitorrule=" + rule);
}
lines.push("");
const content = lines.join("\n");
Proc.runCommand("mango-write-outputs", ["sh", "-c", `mkdir -p "${mangoDmsDir}" && cat > "${outputsPath}" << 'EOF'\n${content}EOF`], (output, exitCode) => {
if (exitCode !== 0) {
log.warn("Failed to write outputs config:", output);
if (callback)
callback(false);
return;
}
log.info("Generated outputs config at", outputsPath);
if (CompositorService.isDwl)
reloadConfig();
if (callback)
callback(true);
});
}
function reloadConfig() {
Proc.runCommand("mango-reload", ["mmsg", "dispatch", "reload_config"], (output, exitCode) => {
if (exitCode !== 0)
log.warn("mmsg reload_config failed:", output);
});
}
function generateLayoutConfig() {
if (!CompositorService.isDwl)
return;
const defaultRadius = typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12;
const defaultGaps = typeof SettingsData !== "undefined" ? Math.max(4, (SettingsData.barConfigs[0]?.spacing ?? 4)) : 4;
const defaultBorderSize = 2;
const cornerRadius = (typeof SettingsData !== "undefined" && SettingsData.mangoLayoutRadiusOverride >= 0) ? SettingsData.mangoLayoutRadiusOverride : defaultRadius;
const gaps = (typeof SettingsData !== "undefined" && SettingsData.mangoLayoutGapsOverride >= 0) ? SettingsData.mangoLayoutGapsOverride : defaultGaps;
const borderSize = (typeof SettingsData !== "undefined" && SettingsData.mangoLayoutBorderSize >= 0) ? SettingsData.mangoLayoutBorderSize : defaultBorderSize;
let content = `# Auto-generated by DMS - do not edit manually
border_radius=${cornerRadius}
gappih=${gaps}
gappiv=${gaps}
gappoh=${gaps}
gappov=${gaps}
borderpx=${borderSize}
`;
Proc.runCommand("mango-write-layout", ["sh", "-c", `mkdir -p "${mangoDmsDir}" && cat > "${layoutPath}" << 'EOF'\n${content}EOF`], (output, exitCode) => {
if (exitCode !== 0) {
log.warn("Failed to write layout config:", output);
return;
}
log.info("Generated layout config at", layoutPath);
reloadConfig();
});
}
function transformToMango(transform) {
switch (transform) {
case "Normal":
return 0;
case "90":
return 1;
case "180":
return 2;
case "270":
return 3;
case "Flipped":
return 4;
case "Flipped90":
return 5;
case "Flipped180":
return 6;
case "Flipped270":
return 7;
default:
return 0;
}
}
function generateCursorConfig() {
if (!CompositorService.isDwl)
return;
log.debug("Generating cursor config...");
const settings = typeof SettingsData !== "undefined" ? SettingsData.cursorSettings : null;
if (!settings) {
Proc.runCommand("mango-write-cursor", ["sh", "-c", `mkdir -p "${mangoDmsDir}" && : > "${cursorPath}"`], (output, exitCode) => {
if (exitCode !== 0)
log.warn("Failed to write cursor config:", output);
});
return;
}
const themeName = settings.theme === "System Default" ? (SettingsData.systemDefaultCursorTheme || "") : settings.theme;
const size = settings.size || 24;
const hideTimeout = settings.dwl?.cursorHideTimeout || 0;
const isDefaultConfig = !themeName && size === 24 && hideTimeout === 0;
if (isDefaultConfig) {
Proc.runCommand("mango-write-cursor", ["sh", "-c", `mkdir -p "${mangoDmsDir}" && : > "${cursorPath}"`], (output, exitCode) => {
if (exitCode !== 0)
log.warn("Failed to write cursor config:", output);
});
return;
}
let content = `# Auto-generated by DMS - do not edit manually
cursor_size=${size}`;
if (themeName)
content += `\ncursor_theme=${themeName}`;
if (hideTimeout > 0)
content += `\ncursor_hide_timeout=${hideTimeout}`;
content += `\n`;
Proc.runCommand("mango-write-cursor", ["sh", "-c", `mkdir -p "${mangoDmsDir}" && cat > "${cursorPath}" << 'EOF'\n${content}EOF`], (output, exitCode) => {
if (exitCode !== 0) {
log.warn("Failed to write cursor config:", output);
return;
}
log.info("Generated cursor config at", cursorPath);
reloadConfig();
});
}
}
+9 -6
View File
@@ -14,13 +14,13 @@ Singleton {
id: root
readonly property var log: Log.scoped("KeybindsService")
property bool available: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isMango
property bool available: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango
property string currentProvider: {
if (CompositorService.isNiri)
return "niri";
if (CompositorService.isHyprland)
return "hyprland";
if (CompositorService.isDwl || CompositorService.isMango)
if (CompositorService.isMango)
return "mangowc";
return "";
}
@@ -30,7 +30,7 @@ Singleton {
return "niri";
if (CompositorService.isHyprland)
return "hyprland";
if (CompositorService.isDwl || CompositorService.isMango)
if (CompositorService.isMango)
return "mangowc";
return "";
}
@@ -290,13 +290,16 @@ Singleton {
configFile: mainConfigPath,
backupFile: backupPath,
fragmentFiles: [compositorConfigDir + "/dms/binds.lua", compositorConfigDir + "/dms/binds-user.lua"],
includes: [{
includes: [
{
grepPattern: "dms.binds",
includeLine: "require(\"dms.binds\")"
}, {
},
{
grepPattern: "dms.binds-user",
includeLine: "require(\"dms.binds-user\")"
}]
}
]
});
break;
case "mangowc":
+3 -4
View File
@@ -10,9 +10,8 @@ import qs.Services
// Native MangoWM IPC client. mango advertises a JSON-over-Unix-socket protocol
// via MANGO_INSTANCE_SIGNATURE; each connection issues one `watch <target>` verb
// and gets a full JSON snapshot followed by newline-delimited updates. Replaces
// the legacy dwl-ipc-v2 path (DwlService) for mango, exposing a
// DwlService-compatible tag API plus a per-client window list.
// and gets a full JSON snapshot followed by newline-delimited updates. Exposes
// a dwl-style tag API plus a per-client window list.
Singleton {
id: root
readonly property var log: Log.scoped("MangoService")
@@ -219,7 +218,7 @@ Singleton {
root.windows = data.clients;
}
// DwlService-compatible tag API
// Tag API (dwl-style tag model)
function getOutputState(outputName) {
return (outputs && outputs[outputName]) ? outputs[outputName] : null;
-6
View File
@@ -4,7 +4,6 @@ pragma ComponentBehavior: Bound
import QtQuick
import Quickshell
import Quickshell.Io
import Quickshell.Hyprland
import Quickshell.I3
import qs.Common
import qs.Services
@@ -314,11 +313,6 @@ Singleton {
return;
}
if (CompositorService.isDwl) {
DwlService.quit();
return;
}
if (CompositorService.isMango) {
MangoService.quit();
return;
@@ -35,8 +35,10 @@ Singleton {
readonly property var conditionMap: ({
"isNiri": () => CompositorService.isNiri,
"isHyprland": () => CompositorService.isHyprland,
"isDwl": () => CompositorService.isDwl,
"isMango": () => CompositorService.isMango,
"isHyprlandOrNiri": () => CompositorService.isHyprland || CompositorService.isNiri,
"windowRulesCapable": () => CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango,
"layoutCapable": () => CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isMango,
"keybindsAvailable": () => KeybindsService.available,
"soundsAvailable": () => AudioService.soundsAvailable,
"cupsAvailable": () => CupsService.cupsAvailable,
+1 -1
View File
@@ -279,7 +279,7 @@ Singleton {
}
// High-level apply matching the generateOutputsConfig() pattern used by
// NiriService, HyprlandService and DwlService. Instead of writing a
// NiriService, HyprlandService and MangoService. Instead of writing a
// config file, the changes are applied directly via the
// wlr-output-management protocol.
function applyOutputsConfig(outputsData, connectedOutputs) {
+108
View File
@@ -0,0 +1,108 @@
import QtQuick
import QtQuick.Shapes
import qs.Common
Item {
id: root
property real size: 48
property real strokeWidth: Math.max(2, size / 12)
property color color: Theme.primary
property bool running: visible
implicitWidth: size
implicitHeight: size
onRunningChanged: {
if (running)
return;
arc.rotation = 0;
arc.startAngle = 0;
arc.sweepAngle = 16;
}
Item {
id: rotator
anchors.fill: parent
RotationAnimator on rotation {
from: 0
to: 360
duration: 1568
loops: Animation.Infinite
running: root.running
}
Shape {
id: arc
property real startAngle: 0
property real sweepAngle: 16
anchors.fill: parent
antialiasing: true
preferredRendererType: Shape.CurveRenderer
ShapePath {
strokeColor: root.color
strokeWidth: root.strokeWidth
fillColor: "transparent"
capStyle: ShapePath.RoundCap
PathAngleArc {
centerX: arc.width / 2
centerY: arc.height / 2
radiusX: Math.max(1, (Math.min(arc.width, arc.height) - root.strokeWidth) / 2)
radiusY: radiusX
startAngle: arc.startAngle
sweepAngle: arc.sweepAngle
}
}
}
SequentialAnimation {
running: root.running
loops: Animation.Infinite
NumberAnimation {
target: arc
property: "sweepAngle"
from: 16
to: 270
duration: 666
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
ParallelAnimation {
NumberAnimation {
target: arc
property: "startAngle"
from: 0
to: 254
duration: 666
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
NumberAnimation {
target: arc
property: "sweepAngle"
from: 270
to: 16
duration: 666
easing.type: Easing.BezierSpline
easing.bezierCurve: Anims.standard
}
}
ScriptAction {
script: {
arc.rotation = (arc.rotation + 254) % 360;
arc.startAngle = 0;
}
}
}
}
}
+2 -14
View File
@@ -211,21 +211,9 @@ Rectangle {
height: VPNService.configLoading ? 40 : 0
visible: VPNService.configLoading
Row {
DankSpinner {
anchors.centerIn: parent
spacing: Theme.spacingS
DankIcon {
name: "sync"
size: 16
color: Theme.surfaceVariantText
}
StyledText {
text: I18n.tr("Loading...")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
}
size: 20
}
}
File diff suppressed because it is too large Load Diff
@@ -62,20 +62,7 @@ CATEGORY_KEYWORDS = {
"Time & Weather": ["clock", "forecast", "date"],
"Keyboard Shortcuts": ["keys", "bindings", "hotkey"],
"Dank Bar": ["panel", "topbar", "statusbar"],
"Compositor": [
"virtual desktops",
"spaces",
"window",
"rules",
"matching",
"floating",
"fullscreen",
"opacity",
"gaps",
"borders",
"corner rounding",
"overrides",
],
"Applications": ["apps", "programs", "window", "rules", "matching", "floating"],
"Dock": ["taskbar", "launcher bar"],
"Network": ["connectivity", "online"],
"System": ["os", "linux"],
@@ -109,10 +96,9 @@ TAB_INDEX_MAP = {
"TimeWeatherTab.qml": 1,
"KeybindsTab.qml": 2,
"DankBarTab.qml": 3,
"CompositorTab.qml": 4,
"CompositorLayoutTab.qml": 4,
"WorkspacesTab.qml": 4,
"WindowRulesTab.qml": 4,
"CompositorLayoutTab.qml": 37,
"WindowRulesTab.qml": 38,
"DockTab.qml": 5,
"DankBarAppearanceTab.qml": 6,
"WorkspaceAppearanceCard.qml": 6,
@@ -152,7 +138,7 @@ TAB_CATEGORY_MAP = {
1: "Time & Weather",
2: "Keyboard Shortcuts",
3: "Dank Bar",
4: "Compositor",
4: "Dank Bar",
5: "Dock",
6: "Dank Bar",
7: "Network",
@@ -184,6 +170,8 @@ TAB_CATEGORY_MAP = {
34: "Default Apps",
35: "Users",
36: "Autostart",
37: "Personalization",
38: "Applications",
}
SEARCHABLE_COMPONENTS = [
@@ -370,6 +358,8 @@ def find_settings_components(content, filename):
condition_key = "isNiri"
elif "CompositorService.isHyprland" in visible_raw:
condition_key = "isHyprland"
elif "CompositorService.isMango" in visible_raw:
condition_key = "isMango"
elif "KeybindsService.available" in visible_raw:
condition_key = "keybindsAvailable"
elif "AudioService.soundsAvailable" in visible_raw:
@@ -436,6 +426,8 @@ def parse_tabs_from_sidebar(sidebar_file):
("hyprlandNiriOnly", "isHyprlandOrNiri"),
("clipboardOnly", "dmsConnected"),
("niriOnly", "isNiri"),
("windowRulesCapable", "windowRulesCapable"),
("layoutCapable", "layoutCapable"),
]:
if f'"{qml_cond}": true' in snippet:
cond = key
@@ -521,16 +513,17 @@ def extract_settings_index(root_dir):
{
"section": "windowRules",
"label": "Window Rules",
"tabIndex": 4,
"category": "Compositor",
"tabIndex": 38,
"category": "Applications",
"keywords": enrich_keywords(
"Window Rules",
"Define compositor rules for window behavior",
"Compositor",
"Applications",
["matching", "floating", "fullscreen", "opacity"],
),
"icon": "select_window",
"description": "Define compositor rules for window behavior",
"conditionKey": "windowRulesCapable",
}
)
File diff suppressed because it is too large Load Diff
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": ""
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": ""
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 dispositivo conectado"
},
"1 event": {
"1 event": "1 evento"
},
"1 hour": {
"1 hour": ""
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 segundo"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 minutos"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": ""
},
"24-hour format": {
"24-hour format": "Formato de 24 horas"
},
"25 seconds": {
"25 seconds": ""
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Añadir un prefijo personalizado a todas las aplicaciones que se ejecutan. Esto puede ser usado para cosas como 'uwsm-app', 'systemd-run', o otro comando envoltorio."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Añade y configura los widgets que aparecen en tu escritorio"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Atrás • F1/I: Información del archivo • F10: Ayuda • Esc: Cerrar+"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "Analizando la configuración..."
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": ""
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Identidad anónima (opcional)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": ""
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Aplicar un tono cálido para disminuir la fatiga visual. Configure abajo la automatización para definir cuándo se activa."
},
"Applying authentication changes": {
"Applying authentication changes": ""
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": ""
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Colores armonizados con acentos definidos (base)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Configuración de barras"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": ""
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": ""
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": ""
},
"Checking…": {
"Checking…": ""
},
"Choose Color": {
"Choose Color": "Elegir color"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Conectando al dispositivo"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": ""
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Conectando..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET no disponible"
},
"DWL service not available": {
"DWL service not available": "Servicio DWL no disponible"
},
"Daily": {
"Daily": ""
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "Desabilitando WiFi..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": ""
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Prioridades visibles sobre apps en pantalla completa"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "Mostrar y cambiar diseños DWL"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Mostrar iconos de aplicaciones en los espacios"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Educación"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Error al actualizar la compartición"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Fallo al escribir archivo temporal para la validacion"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": ""
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": ""
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Ventana enfocada"
},
"Focused monitor only": {
"Focused monitor only": ""
},
"Fog": {
"Fog": ""
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": ""
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "Aplicaciones del espacio de trabajo en grupo"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": ""
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Invertir al cambiar de modo"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": ""
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": ""
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "Sobreescribir opciones de MangoWC"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": ""
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": ""
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": ""
},
"On-Screen Displays": {
"On-Screen Displays": "Indicadores en pantalla"
},
"On-screen Displays": {
"On-screen Displays": "Indicadores en pantalla"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Enchufado"
},
"Plugged in": {
"Plugged in": "Enchufado"
},
"Plugin": {
"Plugin": "Complemento"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Actualizar El Tiempo"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": ""
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": ""
},
"Requires DWL compositor": {
"Requires DWL compositor": "Requiere un compositor DWL"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": ""
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Redimensionar Widget"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Resolución y refresco"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Esquinas redondeadas para ventanas"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "Esquinas de ventana redondeadas (border_radius)"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "Esquinas de ventana redondeadas (decoration.rounding)"
},
"Rule": {
"Rule": ""
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Ajustes de aplicaciones activas"
},
"Running greeter sync": {
"Running greeter sync": ""
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": ""
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Mostrar aplicaciones en el espacio de trabajo"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Mostrar las 9 etiquetas en lugar de solo las ocupadas (solo DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": ""
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Espacio entre ventanas"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": ""
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "Espacio entre ventanas (hueco_in y hueco_ext)"
},
"Spacer": {
"Spacer": "Espaciador"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Seleccionar"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": ""
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Titulo"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": ""
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Usar radio de ventana personalizado en lugar del radio del tema"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": ""
},
"Use desktop wallpaper": {
"Use desktop wallpaper": ""
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "Configuración VPN actualizada"
},
"VPN connections": {
"VPN connections": "Conexiones VPN"
},
"VPN deleted": {
"VPN deleted": "VPN eliminada"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Widgets"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": ""
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": ""
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": ""
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": ""
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": ""
},
"Window Rounding": {
"Window Rounding": ""
},
"Window Rules": {
"Window Rules": ""
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": ""
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Espacio de trabajo"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Espacios de trabajo"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Espacios de trabajo y Widgets"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": ""
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "Eje X"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Eje Y"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": ""
},
"events": {
"events": "eventos"
},
"ext": {
"ext": ""
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl no disponible - integración requiere conexión al socket DMS"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": ""
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": "%1 برخط"
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": "%1 بروزرسانی"
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 دستگاه متصل"
},
"1 event": {
"1 event": "۱ رویداد"
},
"1 hour": {
"1 hour": "۱ ساعت"
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "۱ ثانیه"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "۱۰ دقیقه"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": "24 ساعته"
},
"24-hour format": {
"24-hour format": "قالب ۲۴ ساعته"
},
"25 seconds": {
"25 seconds": "۲۵ ثانیه"
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "یک پیشوند سفارشی به تمام برنامه‌های در حال اجرا اضافه کنید. این می‌تواند برای مواردی مانند «uwsm-app»، «systemd-run» یا سایر بسته‌بندی دستور‌ها استفاده شود."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "افزودن و پیکربندی ابزارک‌هایی که در دسکتاپ شما نمایان می‌شوند"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": "هم‌اکنون در همان نشست هستید"
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: بازگشت • F1/I: اطلاعات فایل • F10: راهنما • Esc: بستن"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "در حال تحلیل پیکربندی..."
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": "مدت زمان انیمیشن"
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "هویت ناشناس (اختیاری)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": "جایگزینی شناسه برنامه‌ها"
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "برای کاهش خستگی چشم دمای رنگ گرم را اعمال کن. از تنظیمات خودکارسازی پایین برای کنترل زمان فعال شدن آن استفاده کنید."
},
"Applying authentication changes": {
"Applying authentication changes": "درحال اعمال تغییرات احراز هویت…"
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": "برنامه‌ها"
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "پالت رنگی متعادل با رنگ تأکیدی متمرکز (پیش‌فرض)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "پیکربندی نوار"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": "بررسی برای بروزرسانی‌ها..."
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": "درحال بررسی نیاز به احراز هویت sudo…"
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": "درحال بررسی..."
},
"Checking…": {
"Checking…": "درحال بررسی..."
},
"Choose Color": {
"Choose Color": "انتخاب رنگ"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "درحال اتصال به دستگاه"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": "درحال اتصال به سرویس کلیپ‌بورد…"
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "درحال اتصال..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET در دسترس نیست"
},
"DWL service not available": {
"DWL service not available": "سرویس DWL در دسترس نیست"
},
"Daily": {
"Daily": "روزانه"
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "غیرفعال‌سازی وای‌فای..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": "دیسک"
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "نمایش همه اولویت‌ها روی برنامه‌های تمام‌صفحه"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "نمایش و تغییر چیدمان‌های DWL"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "آیکون برنامه‌ها را در نشانگر‌های محیط‌کار نمایش بده"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": "ویرایش متن کلیپ‌بورد"
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "آموزش"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "بروزرسانی اشتراک‌گذاری ناموفق بود"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "نوشتن فایل موقت برای اعتبارسنجی ناموفق بود"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": "شناور"
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": "فلوئنت"
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "پنجره فوکوس‌شده"
},
"Focused monitor only": {
"Focused monitor only": "فقط مانیتور فوکوس شده"
},
"Fog": {
"Fog": "مه"
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "گروه"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "گروه‌بندی برنامه‌های محیط‌کار"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": "قابل جلوگیری"
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "معکوس هنگام تغییر حالت"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": "باز کردن چشم"
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": "فایل‌ها و دایرکتوری‌ها را مدیریت می‌کند"
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "جایگزینی‌های چیدمان MangoWC"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": "محلی: نماپرداز سکو (FreeType)."
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": "پیمایش"
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": "هنگام درخواست"
},
"On-Screen Displays": {
"On-Screen Displays": "نمایشگر‌های بر صفحه"
},
"On-screen Displays": {
"On-screen Displays": "نمایشگر‌های بر صفحه (OSD)"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "اتصال به برق"
},
"Plugged in": {
"Plugged in": "اتصال به برق"
},
"Plugin": {
"Plugin": "افزونه"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "تازه‌سازی آب و هوا"
},
"Refreshing": {
"Refreshing": "درحال تازه‌سازی…"
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": "رجکس"
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": ""
},
"Requires DWL compositor": {
"Requires DWL compositor": "به کامپازیتور DWL نیاز دارد"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": "به نسخه جدیدتر Quickshell نیاز دارد"
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "تغییر اندازه ابزارک"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "وضوح و تازه‌سازی"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "گوشه‌های گرد برای پنجره‌ها"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "گوشه‌های گرد برای پنجره‌ها (border_radius)"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "گوشه‌های گرد برای پنجره‌ها (decoration.rounding)"
},
"Rule": {
"Rule": "قاعده"
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "تنظیمات برنامه‌های درحال اجرا"
},
"Running greeter sync": {
"Running greeter sync": "درحال اجرای همگام‌سازی صفحه خوش‌آمدگویی…"
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": "اجرا کردن در ترمینال"
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "نمایش برنامه‌های محیط‌کار"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "نمایش کل ۹ برچسب به جای فقط برچسب‌های اشغال شده (فقط DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": "یک خط بیرونی دور نشانگر محیط‌کار فوکوس شده نشان بده"
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "فاصله بین پنجره‌ها"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "فاصله بین پنجره‌ها (gappih/gappiv/gappoh/gappov)"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "فاصله بین پنجره‌ها (gaps_in و gaps_out)"
},
"Spacer": {
"Spacer": "فاصله دهنده"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: پیمایش • ←→↑↓: پیمایش جدولی • Enter/Space: انتخاب"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": "برچسب‌ها: %1"
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "عنوان"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": "رجکس عنوان (اختیاری)"
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "استفاده از شعاع پنجره سفارشی به جای شعاع تم"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "استفاده از گردی پنجره سفارشی به جای شعاع تم"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": "از تصویر پس‌زمینه دسکتاپ استفاده کن"
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "گذرواژه VPN بروز شد"
},
"VPN connections": {
"VPN connections": "اتصالات VPN"
},
"VPN deleted": {
"VPN deleted": "VPN حذف شد"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "ابزارک‌ها"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "ابزارک‌ها، چیدمان، استایل"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": "پهنای خط دور ابزارک به پیکسل"
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "پهنای حاشیه پنجره (borderpx)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "پهنای حاشیه پنجره (general.border_size)"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": "پهنای حاشیه پنجره و حلقه فوکوس"
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": "باز کردن پنجره"
},
"Window Rounding": {
"Window Rounding": "گردی پنجره"
},
"Window Rules": {
"Window Rules": "قواعد پنجره‌ها"
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": "پاک کردن"
},
"Working": {
"Working": "درحال کار…"
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "محیط‌کار"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "محیط‌کارها"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "محیط‌کارها و ابزارک‌ها"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": "نوشتن:"
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "محور X"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "محور Y"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": "مانند، scratch، /^tmp_.*/، build"
},
"events": {
"events": "رویداد‌ها"
},
"ext": {
"ext": "پسوند"
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl در دسترس نیست - یکپارچه‌سازی قفل به اتصال سوکت DMS نیاز دارد"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": "سرور دیسکورد mangowc"
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": ""
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": "%1 mise à jour"
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 appareil connecté"
},
"1 event": {
"1 event": "1 événement"
},
"1 hour": {
"1 hour": "1 heure"
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 seconde"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 minutes"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": "Horloge 24 heures"
},
"24-hour format": {
"24-hour format": "Format 24 heures"
},
"25 seconds": {
"25 seconds": "25 secondes"
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Ajouter un préfixe personnalisé à tous les lancements dapplications (ex. uwsm-app, systemd-run ou autres wrappers de commandes)."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Ajouter et configurer les widgets affichés sur le bureau"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Retour arrière : Retour • F1/I : Infos fichier • F10 : Aide • Échap : Fermer"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "Analyse de la configuration…"
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": "Durée d'animation"
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Identité anonyme (facultatif)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": "Substitutions didentifiant dapplication"
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Appliquer une température de couleur chaude pour réduire la fatigue visuelle. Utilisez les paramètres dautomatisation ci-dessous pour définir son activation."
},
"Applying authentication changes": {
"Applying authentication changes": ""
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": "Applis"
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Palette équilibrée avec des accents ciblés (par défaut)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Configurations de la barre"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": "Vérification des mises à jour..."
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": "Vérification de la nécessité de l'authentification sudo..."
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": "Vérification..."
},
"Checking…": {
"Checking…": "Vérification..."
},
"Choose Color": {
"Choose Color": "Choisir une couleur"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Connexion au périphérique"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": ""
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Connexion..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET indisponible"
},
"DWL service not available": {
"DWL service not available": "Service DWL indisponible"
},
"Daily": {
"Daily": "Par jour"
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "Désactivation du Wi-Fi..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": "Disc"
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Afficher toutes les priorités au-dessus des applications en plein écran"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "Afficher et changer les dispositions DWL"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Afficher les icônes des applications dans les indicateurs despaces de travail"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Éducation"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Échec de la mise à jour du partage"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Échec de l’écriture du fichier temporaire pour la validation"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": "Flottant"
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": ""
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Fenêtre active"
},
"Focused monitor only": {
"Focused monitor only": "Uniquement l'écran sélectionné"
},
"Fog": {
"Fog": "Brouillard"
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "Groupe"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "Regrouper les applications de l'espace de travail"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": "Inhibable"
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Inverser lors du changement de mode"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": "Floraison Iris"
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": ""
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "Surcharges de disposition MangoWC"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": ""
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": "Naviguer"
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": "Sur demande"
},
"On-Screen Displays": {
"On-Screen Displays": "Affichages à l’écran"
},
"On-screen Displays": {
"On-screen Displays": "Affichages à l’écran"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Branché"
},
"Plugged in": {
"Plugged in": "Branché"
},
"Plugin": {
"Plugin": "Plugin"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Actualiser la météo"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": "Regex"
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": ""
},
"Requires DWL compositor": {
"Requires DWL compositor": "Nécessite un compositeur DWL"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": ""
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Redimensionner le widget"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Résolution et rafraîchissement"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Coins arrondis pour les fenêtres"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "Coins arrondis pour les fenêtres (border_radius)"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "Coins arrondis pour les fenêtres (decoration.rounding)"
},
"Rule": {
"Rule": "Règle"
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Paramètres des applications en cours"
},
"Running greeter sync": {
"Running greeter sync": "Synchro du greeter en cours…"
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": ""
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Afficher les applications de lespace de travail"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Afficher les 9 étiquettes au lieu de seulement celles occupées (DWL uniquement)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": "Afficher un contour autour de lindicateur de lespace actif"
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Espacement entre fenêtres"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "Espacement entre fenêtres (gappih/gappiv/gappoh/gappov)"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "Espacement entre fenêtres (gaps_in et gaps_out)"
},
"Spacer": {
"Spacer": "Espacement"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab : Navigation • ←→↑↓ : Navigation grille • Enter/Espace : Sélectionner"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": ""
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Titre"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": "Regex du titre (optionnelle)"
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Utiliser un rayon de fenêtre personnalisé au lieu du rayon du thème"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "Utiliser un arrondi de fenêtre personnalisé au lieu du rayon du thème"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": "Utiliser le fond d'écran du bureau"
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "Configuration VPN mise à jour"
},
"VPN connections": {
"VPN connections": "Connexions VPN"
},
"VPN deleted": {
"VPN deleted": "VPN supprimée"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Widgets"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "Widgets, disposition, style"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "Largeur de la bordure de la fenêtre (px)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "Largeur de la bordure de la fenêtre (general.border_size)"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": "Largeur de la bordure et de lanneau de focus"
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": "Ouverture de fenêtre"
},
"Window Rounding": {
"Window Rounding": "Arrondi des fenêtres"
},
"Window Rules": {
"Window Rules": "Règles de fenêtre"
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": "Effacer"
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Espace de travail"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Espaces de travail"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Espaces de travail et widgets"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": "Écrire :"
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "Axe X"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Axe Y"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": ""
},
"events": {
"events": "événements"
},
"ext": {
"ext": "ext"
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl non disponible - l'intégration de verrouillage nécessite une connexion au socket DMS"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": "Serveur Discord mangowc"
},
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": "1%オンライン"
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": "更新 %1 件"
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1台接続済み"
},
"1 event": {
"1 event": "1件のイベント"
},
"1 hour": {
"1 hour": "1時間"
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1秒"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10分"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": "24時間時計"
},
"24-hour format": {
"24-hour format": "24 時間形式"
},
"25 seconds": {
"25 seconds": "25秒"
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "すべてのアプリ起動にカスタム接頭辞を追加します。これは 'uwsm-app'、'systemd-run'、その他のコマンドラッパーなどに使用できます。"
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "デスクトップに表示されるウィジェットを追加および設定"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: 戻る • F1/I: ファイル情報 • F10: ヘルプ • Esc: 閉じる"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "設定を解析中..."
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": "アニメーション時間"
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "匿名 ID (オプション)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": "App ID 置換"
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "目の疲れを軽減するために、暖色系の色温度を適用します。以下の自動化設定で、いつアクティブにするか制御できます。"
},
"Applying authentication changes": {
"Applying authentication changes": "認証の変更を適用中…"
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": "アプリ"
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "アクセントに焦点を絞ったバランスの取れたパレット(デフォルト)。"
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "バーの設定"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": "更新を確認中..."
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": "sudo 認証が必要か確認中…"
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": "確認中..."
},
"Checking…": {
"Checking…": "確認中…"
},
"Choose Color": {
"Choose Color": "色を選んでください"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "デバイスに接続中"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": "クリップボードサービスに接続中…"
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "接続中..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKETが利用できません"
},
"DWL service not available": {
"DWL service not available": "DWLサービスが利用できません"
},
"Daily": {
"Daily": "毎日"
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "WiFi を無効化中..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": "ディスク"
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "フルスクリーンアプリよりもすべての優先度を表示する"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "DWL レイアウトの表示と切り替え"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "ワークスペース インジケーターにアプリのアイコンを表示"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "教育"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "共有設定の更新に失敗しました"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "検証用の一時ファイル書き込みに失敗しました"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": "フロート"
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": " Fluent"
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "フォーカスされたウィンドウ"
},
"Focused monitor only": {
"Focused monitor only": "フォーカス中のモニターのみ"
},
"Fog": {
"Fog": "霧"
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "グループ"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "ワークスペースのアプリをグループ化"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": "抑制可能"
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "モード変更時に反転"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": "Iris Bloom"
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": "ファイルとディレクトリを管理します"
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "MangoWC レイアウト上書き"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": "ネイティブ: プラットフォームレンダラー (FreeType)。"
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": "移動"
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": "オンデマンド"
},
"On-Screen Displays": {
"On-Screen Displays": "オンスクリーンディスプレイ"
},
"On-screen Displays": {
"On-screen Displays": "オンスクリーンディスプレイ"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "接続"
},
"Plugged in": {
"Plugged in": "接続中"
},
"Plugin": {
"Plugin": "プラグイン"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "天気を更新"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": "正規表現"
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": "sysupdate 機能に対応した DMS サーバーが必要です"
},
"Requires DWL compositor": {
"Requires DWL compositor": "DWLコンポジターが必要"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": "より新しいバージョンの Quickshell が必要"
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "ウィジェットのサイズを変更"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "解像度とリフレッシュレート"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "ウィンドウの角を丸くする"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "ウィンドウの角を丸くする(border_radius"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "ウィンドウの角を丸くする(decoration.rounding"
},
"Rule": {
"Rule": "ルール"
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "実行中のアプリの設定"
},
"Running greeter sync": {
"Running greeter sync": "Greeter 同期を実行中…"
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": "端末で実行中"
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "ワークスペースアプリを表示"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "占有タグのみではなく、9 つのタグをすべて表示 (DWL のみ)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": "フォーカス中のワークスペースインジケーターの周囲にアウトラインリングを表示"
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "ウィンドウ間の間隔"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "ウィンドウ間の間隔(gappih/gappiv/gappoh/gappov"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "ウィンドウ間の間隔(gaps_in と gaps_out"
},
"Spacer": {
"Spacer": "間隔"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: ナビゲーション • ←→↑↓: グリッドナビゲーション • Enter/Space: 選択"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": "タグ: %1"
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "タイトル"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": "タイトルの正規表現(任意)"
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "テーマ半径の代わりにカスタムウィンドウ半径を使用"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "テーマ半径の代わりにカスタムウィンドウ丸みを使用"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": "デスクトップ壁紙を使用"
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "VPN 設定を更新しました"
},
"VPN connections": {
"VPN connections": "VPN 接続"
},
"VPN deleted": {
"VPN deleted": "VPN を削除しました"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "ウィジェット"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "ウィジェット、レイアウト、スタイル"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "ウィンドウ境界線の幅(borderpx)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "ウィンドウ境界線の幅(general.border_size"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": "ウィンドウ境界線とフォーカスリングの幅"
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": "ウィンドウの開く動作"
},
"Window Rounding": {
"Window Rounding": "ウィンドウの丸み"
},
"Window Rules": {
"Window Rules": "ウィンドウルール"
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": "ワイプ"
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "ワークスペース"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "ワークスペース"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "ワークスペースとウィジェット"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": "書き込み:"
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "X 軸"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Y 軸"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": "例: scratch、/^tmp_.*/、build"
},
"events": {
"events": "イベント"
},
"ext": {
"ext": "ext"
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctlが利用できません- ロック統合のためにDMS socketの接続が必要です。"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": "mangowc Discord サーバー"
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": "%1 online"
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": "%1 update"
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 apparaat verbonden"
},
"1 event": {
"1 event": "1 afspraak"
},
"1 hour": {
"1 hour": "1 uur"
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 seconde"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 minuten"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": "24-uursklok"
},
"24-hour format": {
"24-hour format": "24-uursnotatie"
},
"25 seconds": {
"25 seconds": "25 seconden"
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Voeg een aangepast voorvoegsel toe aan alle applicatiestarts. Dit kan worden gebruikt voor zaken als 'uwsm-app', 'systemd-run' of andere opdrachtwrappers."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Widgets toevoegen en configureren die op uw bureaublad verschijnen"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Terug • F1/I: Bestandsinfo • F10: Hulp • Esc: Sluiten"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "Configuratie analyseren..."
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": "Animatieduur"
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Anonieme identiteit (optioneel)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": "App ID-vervangingen"
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Warme kleurtemperatuur toepassen om oogvermoeidheid te verminderen. Gebruik de automatiseringsinstellingen hieronder om te bepalen wanneer dit activeert."
},
"Applying authentication changes": {
"Applying authentication changes": "Verificatiewijzigingen toepassen…"
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": "Apps"
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Gebalanceerd palet met gerichte accenten (standaard)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Balkconfiguraties"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": "Zoeken naar updates..."
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": "Controleren of sudo-authenticatie vereist is…"
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": "Controleren..."
},
"Checking…": {
"Checking…": "Controleren…"
},
"Choose Color": {
"Choose Color": "Kleur kiezen"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Verbinden met apparaat"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": "Verbinden met klembord-service…"
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Verbinden..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET niet beschikbaar"
},
"DWL service not available": {
"DWL service not available": "DWL-service niet beschikbaar"
},
"Daily": {
"Daily": "Dagelijks"
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "Wifi uitschakelen..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": "Schijf"
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Alle prioriteiten over applicaties op volledig scherm tonen"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "DWL-indelingen tonen en wisselen"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Applicatiepictogrammen tonen in werkbladindicatoren"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Onderwijs"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Bijwerken van delen mislukt"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Schrijven van tijdelijk bestand voor validatie mislukt"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": "Zweven"
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": "Fluent"
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Actieve venster"
},
"Focused monitor only": {
"Focused monitor only": "Alleen op actieve monitor"
},
"Fog": {
"Fog": "Mist"
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "Groep"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "Werkblad-apps groeperen"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": "Onderdrukbaar"
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Omkeren bij moduswisseling"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": "Irisbloei"
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": "Beheert bestanden en mappen"
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "MangoWC-indelingsoverschrijvingen"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": "Native: platform-renderer (FreeType)."
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": "Navigeren"
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": "Op aanvraag"
},
"On-Screen Displays": {
"On-Screen Displays": "On-screen displays"
},
"On-screen Displays": {
"On-screen Displays": "On-screen displays"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Aangesloten"
},
"Plugged in": {
"Plugged in": "Aangesloten"
},
"Plugin": {
"Plugin": "Plug-in"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Weer verversen"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": "Regex"
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": "Vereist DMS-server met sysupdate-functionaliteit"
},
"Requires DWL compositor": {
"Requires DWL compositor": "Vereist DWL-compositor"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": "Vereist een nieuwere versie van Quickshell"
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Widgetgrootte wijzigen"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Resolutie & Verversing"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Afgeronde hoeken voor vensters"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "Afgeronde hoeken voor vensters (border_radius)"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "Afgeronde hoeken voor vensters (decoration.rounding)"
},
"Rule": {
"Rule": "Regel"
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Instellingen actieve apps"
},
"Running greeter sync": {
"Running greeter sync": "Greeter-synchronisatie uitvoeren…"
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": "Wordt uitgevoerd in terminal"
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Werkblad-apps tonen"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Alle 9 tags tonen in plaats van alleen bezette tags (alleen DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": "Toon een omlijningsring rond de indicator van het gefocuste werkblad"
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Ruimte tussen vensters"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "Ruimte tussen vensters (gappih/gappiv/gappoh/gappov)"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "Ruimte tussen vensters (gaps_in en gaps_out)"
},
"Spacer": {
"Spacer": "Afstandhouder"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Nav • ←→↑↓: Raster Nav • Enter/Spatie: Selecteren"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": "Tags: %1"
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Titel"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": "Titel-regex (optioneel)"
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Gebruik aangepaste vensterradius in plaats van themaradius"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "Aangepaste vensterronding gebruiken in plaats van themaradius"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": "Bureaubladachtergrond gebruiken"
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "VPN-configuratie bijgewerkt"
},
"VPN connections": {
"VPN connections": "VPN-verbindingen"
},
"VPN deleted": {
"VPN deleted": "VPN verwijderd"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Widgets"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "Widgets, indeling, stijl"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "Breedte van vensterrand (borderpx)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "Breedte van vensterrand (general.border_size)"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": "Breedte van vensterrand en focusring"
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": "Venster openen"
},
"Window Rounding": {
"Window Rounding": "Vensterronding"
},
"Window Rules": {
"Window Rules": "Vensterregels"
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": "Vegen"
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Werkblad"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Werkbladen"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Werkbladen & Widgets"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": "Schrijven:"
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "X-as"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Y-as"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": "bijv. scratch, /^tmp_.*/, build"
},
"events": {
"events": "afspraken"
},
"ext": {
"ext": "ext"
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl niet beschikbaar - vergrendelintegratie vereist DMS-socketverbinding"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": "mangowc Discord-server"
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": ""
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": ""
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 połączone urządzenie"
},
"1 event": {
"1 event": "1 wydarzenie"
},
"1 hour": {
"1 hour": ""
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 sekunda"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 minut"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": ""
},
"24-hour format": {
"24-hour format": "format 24-godzinny"
},
"25 seconds": {
"25 seconds": ""
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Dodaj niestandardowy prefiks do wszystkich poleceń aplikacji. Można tego użyć do poleceń takich jak 'uwsm-app', 'systemd-run' lub innych wrapperów."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Dodaj i skonfiguruj widżety pulpitu"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Wstecz • F1/I: Informacje o pliku • F10: Pomoc • Esc: Zamknij"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": ""
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": ""
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Tożsamość anonimowa (opcjonalnie)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": ""
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Zastosuj ciepłą temperaturę barwową, aby zmniejszyć zmęczenie oczu. Użyj poniższych ustawień automatyzacji, aby kontrolować, kiedy się aktywuje."
},
"Applying authentication changes": {
"Applying authentication changes": ""
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": ""
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Zrównoważona paleta ze skupionymi akcentami (domyślnie)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Konfiguracje pasków"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": ""
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": ""
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": ""
},
"Checking…": {
"Checking…": ""
},
"Choose Color": {
"Choose Color": "Wybierz kolor"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Łączenie z urządzeniem"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": ""
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Łączenie..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET niedostępny"
},
"DWL service not available": {
"DWL service not available": "Usługa DWL niedostępna"
},
"Daily": {
"Daily": ""
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "Wyłączanie WiFi..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": ""
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Wyświetlaj wszystkie priorytety nad aplikacjami pełnoekranowymi"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "Wyświetlanie i przełączanie układów DWL"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Wyświetlaj ikony aplikacji we wskaźnikach obszaru roboczego"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Edukacja"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Nie udało się zaktualizować udostępniania"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Zapisanie pliku tymczasowego do walidacji nie powiodło się"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": ""
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": ""
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Aktywne okno"
},
"Focused monitor only": {
"Focused monitor only": ""
},
"Fog": {
"Fog": ""
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "Grupy"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "Aplikacje obszaru roboczego grupy"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": ""
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Odwróć przy zmianie trybu"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": ""
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": ""
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": ""
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": ""
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": ""
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": ""
},
"On-Screen Displays": {
"On-Screen Displays": "Wyświetlacze ekranowe"
},
"On-screen Displays": {
"On-screen Displays": "Powiadomienia ekranowe"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Wpięty do zasilania"
},
"Plugged in": {
"Plugged in": "Wpięto"
},
"Plugin": {
"Plugin": "Wtyczka"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Odśwież pogodę"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": ""
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": ""
},
"Requires DWL compositor": {
"Requires DWL compositor": "Wymaga kompozytora DWL"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": ""
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Zmień rozmiar widżetu"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Rozdzielczość i odświeżanie"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Zaokrąglone narożniki okien"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": ""
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": ""
},
"Rule": {
"Rule": ""
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Ustawienia uruchomionych aplikacji"
},
"Running greeter sync": {
"Running greeter sync": ""
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": ""
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Pokaż aplikacje z obszaru roboczego"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Pokaż wszystkie 9 tagów zamiast tylko zajętych (tylko DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": ""
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Przerwa między oknami"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "Odległość pomiędzy oknami (gappih/gappiv/gappoh/gappov)"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "Odległość pomiędzy oknami (gaps_in and gaps_out)"
},
"Spacer": {
"Spacer": "Odstęp"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Nawigacja • ←→↑↓: Nawigacja po siatce • Enter/Spacja: Wybierz"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": ""
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Tytuł"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": ""
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Używaj własnego promienia okna w zamiast ustawień motywu"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "Użyj niestandardowego zaokrąglenia okien zamiast motywowego"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": ""
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "Konfiguracja VPN zaktualizowana"
},
"VPN connections": {
"VPN connections": "Połączenia VPN"
},
"VPN deleted": {
"VPN deleted": "VPN usunięty"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Widżety"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "Wtyczki, układ, styl"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "Szerokość obramowania okna (borderpx)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "Szerokość obramowania okna (general.border_size)"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": ""
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": ""
},
"Window Rounding": {
"Window Rounding": ""
},
"Window Rules": {
"Window Rules": ""
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": ""
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Obszar roboczy"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Przestrzenie robocze"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Obszary robocze i widżety"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": ""
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "Oś X"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Oś Y"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": ""
},
"events": {
"events": "wydarzenia"
},
"ext": {
"ext": ""
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl niedostępny - integracja blokady wymaga połączenia z gniazdem DMS"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": ""
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": ""
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": ""
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 dispositivo conectado"
},
"1 event": {
"1 event": "1 evento"
},
"1 hour": {
"1 hour": "1 hora"
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 segundo"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 minutos"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": ""
},
"24-hour format": {
"24-hour format": "formato de 24 horas"
},
"25 seconds": {
"25 seconds": "25 segundos"
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Adicionar um prefixo personalizado para todos os inicializações de aplicativos. Isso pode ser usado para coisas como 'uwsm-app', 'systemd-run' ou outros invólucros de comandos."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Adicionar e configurar widgets que aparecem na sua área de trabalho"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Voltar • F1/I: Informações de Arquivo • F10: Ajuda • Esc: Fechar"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "Analisando configuração..."
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": "Duração da Animação"
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Identidade Anônima (opcional)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": "Substituições de ID de Aplicativo"
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Aplicar temperatura de cor quente para reduzir a fadiga ocular. Use as configurações de automação abaixo para controlar quando ela será ativada."
},
"Applying authentication changes": {
"Applying authentication changes": ""
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": "Aplicativos"
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Paleta equilibrada com destaques de cor focados (padrão)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Configurações da Barra"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": ""
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": ""
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": ""
},
"Checking…": {
"Checking…": ""
},
"Choose Color": {
"Choose Color": "Escolha a Cor"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Conectando ao Dispositivo"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": ""
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Conectando..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET não está disponível"
},
"DWL service not available": {
"DWL service not available": "Serviço do DWL não disponível"
},
"Daily": {
"Daily": "Diário"
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "Desativando WiFi..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": "Disco"
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Exibir todas as prioridades em aplicativos de tela cheia"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "Mostra e altera layouts do DWL"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Mostrar ícones de aplicativos em indicadores de espaço de trabalho"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Educação"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Falha ao atualizar compartilhamento"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Falha ao salvar arquivo temporário para validação"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": "Flutuante"
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": ""
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Janela Focada"
},
"Focused monitor only": {
"Focused monitor only": ""
},
"Fog": {
"Fog": "Neblina"
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "Grupo"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "Agrupar Aplicativos da Área de Trabalho"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": "Inibível"
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Inverter na mudança de modo"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": "Íris em Flor"
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": ""
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "Substituições de Layout MangoWC"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": ""
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": ""
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": "Por Demanda"
},
"On-Screen Displays": {
"On-Screen Displays": "Displays na Tela (OSDs)"
},
"On-screen Displays": {
"On-screen Displays": "Exibições OSD"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Conectado"
},
"Plugged in": {
"Plugged in": "Conectado"
},
"Plugin": {
"Plugin": "Plugin"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Atualizar Clima"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": "Regex"
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": ""
},
"Requires DWL compositor": {
"Requires DWL compositor": "Requer o compositor DWL"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": ""
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Redimensionar Widget"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Resolução & Taxa de Atualização"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Cantos arredondados para janelas"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "Cantos arredondados para janelas (border_radius)"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "Cantos arredondados para janelas (decoration.rounding)"
},
"Rule": {
"Rule": "Regra"
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Configurações de Apps em Execução"
},
"Running greeter sync": {
"Running greeter sync": ""
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": ""
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Mostrar Aplicativos da Área de Trabalho Virtual"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Mostrar todas as 9 tags ao invés de apenas tags ocupadas (apenas DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": "Mostrar um anel de contorno ao redor do indicador de espaço de trabalho em foco"
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Espaço entre janelas"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "Espaço entre janelas (gappih/gappiv/gappoh/gappov)"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "Espaço entre janelas (gaps_in e gaps_out)"
},
"Spacer": {
"Spacer": "Espaçador"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Navegação • ←→↑↓: Navegação em Grade • Enter/Espaço: Selecionar"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": ""
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Título"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": "Regex de Título (opcional)"
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Usar raio de janela personalizado em vez do raio do tema"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "Usar arredondamento de janela personalizado em vez do raio do tema"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": ""
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "Configuração da VPN atualizada"
},
"VPN connections": {
"VPN connections": "Conexões VPN"
},
"VPN deleted": {
"VPN deleted": "VPN excluída"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Widgets"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "Widgets, layout, estilo"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "Largura da borda da janela (borderpx)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "Largura da borda da janela (general.border_size)"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": "Largura da borda da janela e anel de foco"
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": "Abertura de Janela"
},
"Window Rounding": {
"Window Rounding": "Arredondamento da Janela"
},
"Window Rules": {
"Window Rules": "Regras de Janela"
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": "Limpar"
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Área de Trabalho"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Áreas de Trabalho"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Áreas de Trabalho e Widgets"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": "Escrita:"
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "Eixo X"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Eixo Y"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": ""
},
"events": {
"events": "eventos"
},
"ext": {
"ext": "ext"
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl não disponível - integração com bloqueio requer conexão de socket DMS"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": ""
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": "%1 в сети"
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": "%1 обновление"
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 устройство подключено"
},
"1 event": {
"1 event": "1 событие"
},
"1 hour": {
"1 hour": "1 час"
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 секунда"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 минут"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": "24-часовой формат времени"
},
"24-hour format": {
"24-hour format": "24-часовой формат"
},
"25 seconds": {
"25 seconds": "25 секунд"
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Добавить пользовательский префикс ко всем запускам приложений. Можно использовать для 'uwsm-app', 'systemd-run' или других командных обёрток."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Добавить и настроить виджеты, отображаемые на рабочем столе"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": "Уже в этой сессии"
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Назад • F1/I: Информация о Файле • F10: Справка • Esc: Закрыть"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "Анализ конфигурации..."
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": "Длительность анимации"
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Анонимный идентификатор (необязательно)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": "Подстановки ID приложения"
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Применить тёплую цветовую температуру для снижения нагрузки на глаза. Используйте настройки автоматизации ниже для управления активацией."
},
"Applying authentication changes": {
"Applying authentication changes": "Применение изменений аутентификации…"
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": "Приложения"
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Сбалансированная палитра с фокусными акцентами (по умолчанию)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Конфигурации бара"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": "Проверка обновлений..."
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": "Проверка необходимости аутентификации через sudo…"
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": "Проверка..."
},
"Checking…": {
"Checking…": "Проверка…"
},
"Choose Color": {
"Choose Color": "Выбрать Цвет"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Подключение к устройству"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": "Подключение к службе буфера обмена…"
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Подключение..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET не доступен"
},
"DWL service not available": {
"DWL service not available": "Служба DWL недоступна"
},
"Daily": {
"Daily": "Ежедневно"
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "Отключение Wi-Fi…"
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": "Стирание"
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Отображает все приоритеты в полноэкранных приложениях"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "Отображать и переключать layout DWL"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Отображать значки приложений в индикаторах рабочих пространств"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": "Редактировать текст буфера обмена"
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Обучение"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Не удалось обновить общий доступ"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Не удалось записать временный файл для проверки"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": "Плавающий"
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": "Fluent"
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Используемое Окно"
},
"Focused monitor only": {
"Focused monitor only": "Только активный монитор"
},
"Fog": {
"Fog": "Туман"
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "Группа"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "Группировать приложения рабочего пространства"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": "Блокируемый"
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Инвертировать при смене режима"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": "Стирание"
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": "Управляет файлами и каталогами"
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "Переопределения макета MangoWC"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": "Native: системный рендерер (FreeType)."
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": "Навигация"
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": "По требованию"
},
"On-Screen Displays": {
"On-Screen Displays": "Наэкранные отображения"
},
"On-screen Displays": {
"On-screen Displays": "Наэкранные отображения"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Подключено"
},
"Plugged in": {
"Plugged in": "Подключено"
},
"Plugin": {
"Plugin": "Плагин"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Обновить погоду"
},
"Refreshing": {
"Refreshing": "Обновление…"
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": "Регулярное выражение"
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": "Требуется сервер DMS с поддержкой sysupdate"
},
"Requires DWL compositor": {
"Requires DWL compositor": "Требуется композитор DWL"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": "требуется более новая версия Quickshell"
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Изменить размер виджета"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Разрешение и обновление"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Скруглённые углы для окон"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "Скруглённые углы для окон (border_radius)"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "Скруглённые углы для окон (decoration.rounding)"
},
"Rule": {
"Rule": "Правило"
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Настройка Запущенных Приложений"
},
"Running greeter sync": {
"Running greeter sync": "Выполняется синхронизация экрана приветствия…"
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": "Выполняется в терминале"
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Показать приложения рабочего пространства"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Показать все 9 тегов вместо только занятых (только DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": "Показать контурное кольцо вокруг индикатора сфокусированного рабочего пространства"
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Расстояние между окнами"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "Расстояние между окнами (gappih/gappiv/gappoh/gappov)"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "Расстояние между окнами (gaps_in и gaps_out)"
},
"Spacer": {
"Spacer": "Разделитель"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Навигация • ←→↑↓: Навигация сетки • Enter/Space: Выбрать"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": "Теги: %1"
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Заголовок"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": "Regex заголовка (необязательно)"
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Использовать пользовательский радиус окон вместо радиуса темы"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "Использовать пользовательское скругление окон вместо радиуса темы"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": "Использовать обои рабочего стола"
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "VPN конфигурации updated"
},
"VPN connections": {
"VPN connections": "VPN подключения"
},
"VPN deleted": {
"VPN deleted": "VPN удалён"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Виджеты"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "Виджеты, макет, стиль"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": "Ширина контура виджета в пикселях"
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "Ширина границы окна (borderpx)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "Ширина границы окна (general.border_size)"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": "Ширина границы окна и кольца фокуса"
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": "Открытие окна"
},
"Window Rounding": {
"Window Rounding": "Скругление окон"
},
"Window Rules": {
"Window Rules": "Правила окон"
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": "Стирание"
},
"Working": {
"Working": "Выполнение…"
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Рабочее пространство"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Рабочие пространства"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Рабочие области и виджеты"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": "Запись:"
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "Ось X"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Ось Y"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": "например: scratch, /^tmp_.*/, build"
},
"events": {
"events": "события"
},
"ext": {
"ext": "расш"
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl недоступен — интеграция блокировки требует подключения к сокету DMS"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": "Discord-сервер mangowc"
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": ""
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": "%1 uppdatering"
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": "1 enhet ansluten"
},
"1 event": {
"1 event": "1 händelse"
},
"1 hour": {
"1 hour": "1 timme"
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 sekund"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 minuter"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": "24-timmarsklocka"
},
"24-hour format": {
"24-hour format": "24-timmarsklocka"
},
"25 seconds": {
"25 seconds": "25 sekunder"
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Lägg till ett anpassat prefix på alla programstarter. Detta kan användas för t.ex. 'uwsm-app', 'systemd-run' eller andra kommandoomslag."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Lägg till och konfigurera widgetar som visas på skrivbordet"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backsteg: Gå tillbaka • F1/I: Filinformation • F10: Hjälp • Esc: Stäng"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": "Analyserar konfiguration..."
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": "Animeringstid"
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Anonym identitet (valfritt)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": "App-ID-substitutioner"
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Applicera varm färgtemperatur för att minska ögontrötthet. Använd automatiseringsinställningarna nedan för att styra när det aktiveras."
},
"Applying authentication changes": {
"Applying authentication changes": ""
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": "Appar"
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Balanserad palett med fokuserade accenter (standard)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Menyradskonfigurationer"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": "Söker efter uppdateringar..."
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": "Kontrollerar om sudo-autentisering behövs…"
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": "Kontrollerar..."
},
"Checking…": {
"Checking…": "Kontrollerar…"
},
"Choose Color": {
"Choose Color": "Välj färg"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Ansluter till enhet"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": ""
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Ansluter..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET otillgänglig"
},
"DWL service not available": {
"DWL service not available": "DWL-tjänsten är inte tillgänglig"
},
"Daily": {
"Daily": "Dagligen"
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "Avaktiverar Wi-Fi..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": "Skiva"
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Visa alla prioritetsnotiser ovanpå appar i helskärmsläge"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "Visa och växla DWL-layouter"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Visa appikoner i arbetsytans indikatorer"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Utbildning"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Misslyckades med att uppdatera delning"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Misslyckades med att skriva temporär fil för validering"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": "Flytande"
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": ""
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Fönster i fokus"
},
"Focused monitor only": {
"Focused monitor only": "Bara fokuserad bildskärm"
},
"Fog": {
"Fog": "Dimma"
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": "Grupp"
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": "Gruppera appar i arbetsytor"
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": "Kan inhiberas"
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Invertera vid växling av ljust och mörkt läge"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": "Iris Bloom"
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": ""
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": "MangoWC-layoutöverstyrningar"
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": ""
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": "Navigera"
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": "Vid behov"
},
"On-Screen Displays": {
"On-Screen Displays": "Skärmvisningar"
},
"On-screen Displays": {
"On-screen Displays": "Skärmvisningar"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Inkopplad"
},
"Plugged in": {
"Plugged in": "Inkopplad"
},
"Plugin": {
"Plugin": "Tillägg"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Uppdatera väder"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": "Regex"
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": ""
},
"Requires DWL compositor": {
"Requires DWL compositor": "Kräver DWL-kompositor"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": ""
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Ändra storlek på widget"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Upplösning och uppdateringsfrekvens"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Rundade hörn för fönster"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": "Rundade hörn för fönster (border_radius)"
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": "Rundade hörn för fönster (decoration.rounding)"
},
"Rule": {
"Rule": "Regel"
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Inställningar för aktiva appar"
},
"Running greeter sync": {
"Running greeter sync": "Kör välkomstskärmssynkronisering…"
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": ""
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Visa appar i en arbetsyta"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Visa alla 9 taggar istället för bara aktiva taggar (endast DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": "Visa en konturring runt den fokuserade arbetsytans indikator"
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Mellanrum mellan fönster"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": "Mellanrum mellan fönster (gappih/gappiv/gappoh/gappov)"
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": "Mellanrum mellan fönster (gaps_in och gaps_out)"
},
"Spacer": {
"Spacer": "Mellanrum"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Skift+Tab: Navigering • ←→↑↓: Rutnätsnavigering • Retur/Blanksteg: Välj"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": ""
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Titel"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": "Titelregex (valfritt)"
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Använd anpassad fönsterradie istället för temaradie"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": "Använd anpassad fönsteravrundning istället för temaradie"
},
"Use desktop wallpaper": {
"Use desktop wallpaper": "Använd skrivbordets bakgrundsbild"
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "VPN-konfiguration uppdaterad"
},
"VPN connections": {
"VPN connections": "VPN-anslutningar"
},
"VPN deleted": {
"VPN deleted": "VPN raderat"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Widgetar"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": "Widgetar, layout, stil"
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": "Bredd på fönsterram (borderpx)"
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": "Bredd på fönsterram (general.border_size)"
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": "Bredd på fönsterram och fokusring"
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": "Fönsteröppning"
},
"Window Rounding": {
"Window Rounding": "Fönsteravrundning"
},
"Window Rules": {
"Window Rules": "Fönsterregler"
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": "Sudda"
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Arbetsyta"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Arbetsytor"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Arbetsytor & widgetar"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": "Skrivit:"
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "X-axel"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Y-axel"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": "t.ex. scratch, /^tmp_.*/, build"
},
"events": {
"events": "händelser"
},
"ext": {
"ext": "tillägg"
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl inte tillgänglig låsintegration kräver DMS-socketanslutning"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": "mangowc Discord-server"
},
+111 -81
View File
@@ -80,6 +80,9 @@
"%1 online": {
"%1 online": ""
},
"%1 tasks": {
"%1 tasks": ""
},
"%1 update": {
"%1 update": ""
},
@@ -134,9 +137,6 @@
"1 device connected": {
"1 device connected": ""
},
"1 event": {
"1 event": "1 etkinlik"
},
"1 hour": {
"1 hour": ""
},
@@ -152,6 +152,9 @@
"1 second": {
"1 second": "1 saniye"
},
"1 task": {
"1 task": ""
},
"10 minutes": {
"10 minutes": "10 dakika"
},
@@ -200,9 +203,6 @@
"24-hour clock": {
"24-hour clock": ""
},
"24-hour format": {
"24-hour format": "24-saat biçimi"
},
"25 seconds": {
"25 seconds": ""
},
@@ -440,6 +440,9 @@
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": {
"Add a custom prefix to all application launches. This can be used for things like 'uwsm-app', 'systemd-run', or other command wrappers.": "Tüm uygulama başlatmalarına özel bir önek ekleyin. Bu, 'uwsm-app', 'systemd-run' veya diğer komut sarmalayıcıları gibi şeyler için kullanılabilir."
},
"Add a task...": {
"Add a task...": ""
},
"Add and configure widgets that appear on your desktop": {
"Add and configure widgets that appear on your desktop": "Masaüstünüzde görünen widget'ları ekle ve yapılandır"
},
@@ -509,6 +512,9 @@
"Already on that session": {
"Already on that session": ""
},
"Also group repeated application icons on the active workspace": {
"Also group repeated application icons on the active workspace": ""
},
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": {
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Geri • F1/I: Dosya bilgisi • F10: Yardım • Esc: Kapat"
},
@@ -551,6 +557,9 @@
"Analyzing configuration...": {
"Analyzing configuration...": ""
},
"Anchor": {
"Anchor": ""
},
"Animation Duration": {
"Animation Duration": ""
},
@@ -566,9 +575,6 @@
"Anonymous Identity (optional)": {
"Anonymous Identity (optional)": "Anonim Kimlik (isteğe bağlı)"
},
"Any": {
"Any": ""
},
"Any window": {
"Any window": ""
},
@@ -578,6 +584,9 @@
"App ID": {
"App ID": ""
},
"App ID (e.g. firefox)": {
"App ID (e.g. firefox)": ""
},
"App ID Substitutions": {
"App ID Substitutions": ""
},
@@ -632,11 +641,11 @@
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": {
"Apply warm color temperature to reduce eye strain. Use automation settings below to control when it activates.": "Göz yorgunluğunu azaltmak için sıcak renk sıcaklığı uygulayın. Etkinleştirme zamanını kontrol etmek için aşağıdaki otomasyon ayarlarını kullanın."
},
"Applying authentication changes": {
"Applying authentication changes": ""
"Applying authentication changes...": {
"Applying authentication changes...": ""
},
"Applying auto-login on startup": {
"Applying auto-login on startup": ""
"Applying auto-login on startup...": {
"Applying auto-login on startup...": ""
},
"Apps": {
"Apps": ""
@@ -932,6 +941,12 @@
"Balanced palette with focused accents (default).": {
"Balanced palette with focused accents (default).": "Odaklanmış vurgularla dengeli palet (varsayılan)."
},
"Bar": {
"Bar": ""
},
"Bar %1": {
"Bar %1": ""
},
"Bar Configurations": {
"Bar Configurations": "Bar Ayarları"
},
@@ -1265,15 +1280,12 @@
"Checking for updates...": {
"Checking for updates...": ""
},
"Checking whether sudo authentication is needed": {
"Checking whether sudo authentication is needed": ""
"Checking whether sudo authentication is needed...": {
"Checking whether sudo authentication is needed...": ""
},
"Checking...": {
"Checking...": ""
},
"Checking…": {
"Checking…": ""
},
"Choose Color": {
"Choose Color": "Renk Seç"
},
@@ -1637,8 +1649,8 @@
"Connecting to Device": {
"Connecting to Device": "Cihaza Bağlanma"
},
"Connecting to clipboard service": {
"Connecting to clipboard service": ""
"Connecting to clipboard service...": {
"Connecting to clipboard service...": ""
},
"Connecting...": {
"Connecting...": "Bağlanıyor..."
@@ -1985,9 +1997,6 @@
"DMS_SOCKET not available": {
"DMS_SOCKET not available": "DMS_SOCKET kullanılamıyor"
},
"DWL service not available": {
"DWL service not available": "DWL hizmeti kullanılamıyor"
},
"Daily": {
"Daily": ""
},
@@ -2228,8 +2237,8 @@
"Disabling WiFi...": {
"Disabling WiFi...": "WiFi kapatılıyor..."
},
"Disabling auto-login on startup": {
"Disabling auto-login on startup": ""
"Disabling auto-login on startup...": {
"Disabling auto-login on startup...": ""
},
"Disc": {
"Disc": ""
@@ -2294,8 +2303,8 @@
"Display all priorities over fullscreen apps": {
"Display all priorities over fullscreen apps": "Tam ekran uygulamaların üzerinde tüm öncelikleri göster"
},
"Display and switch DWL layouts": {
"Display and switch DWL layouts": "DWL düzenlerini görüntüle ve değiştir"
"Display and switch MangoWC layouts": {
"Display and switch MangoWC layouts": ""
},
"Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "Çalışma alanı göstergesinde uygulama simgelerini göster"
@@ -2471,6 +2480,9 @@
"Edit clipboard text": {
"Edit clipboard text": ""
},
"Editing changes on %1": {
"Editing changes on %1": ""
},
"Education": {
"Education": "Eğitim"
},
@@ -2975,12 +2987,12 @@
"Failed to update sharing": {
"Failed to update sharing": "Paylaşım güncellenemedi"
},
"Failed to write Hyprland outputs config.": {
"Failed to write Hyprland outputs config.": ""
},
"Failed to write autostart entry": {
"Failed to write autostart entry": ""
},
"Failed to write outputs config.": {
"Failed to write outputs config.": ""
},
"Failed to write temp file for validation": {
"Failed to write temp file for validation": "Doğrulama için geçici dosya yazılmadı"
},
@@ -3101,9 +3113,21 @@
"Float": {
"Float": ""
},
"Float Anchor": {
"Float Anchor": ""
},
"Float X": {
"Float X": ""
},
"Float Y": {
"Float Y": ""
},
"Floating": {
"Floating": ""
},
"Floating Position": {
"Floating Position": ""
},
"Fluent": {
"Fluent": ""
},
@@ -3137,9 +3161,6 @@
"Focused Window": {
"Focused Window": "Odaklanılmış Pencere"
},
"Focused monitor only": {
"Focused monitor only": ""
},
"Fog": {
"Fog": ""
},
@@ -3437,6 +3458,9 @@
"Group": {
"Group": ""
},
"Group Active Workspace": {
"Group Active Workspace": ""
},
"Group Workspace Apps": {
"Group Workspace Apps": ""
},
@@ -3797,6 +3821,9 @@
"Inhibitable": {
"Inhibitable": ""
},
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": {
"Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.": ""
},
"Initialised": {
"Initialised": ""
},
@@ -3899,6 +3926,9 @@
"Invert on mode change": {
"Invert on mode change": "Mod değişikliğinde ters çevir"
},
"Invert touchpad scroll direction": {
"Invert touchpad scroll direction": ""
},
"Iris Bloom": {
"Iris Bloom": ""
},
@@ -4223,6 +4253,12 @@
"Manages files and directories": {
"Manages files and directories": ""
},
"Mango Options": {
"Mango Options": ""
},
"Mango service not available": {
"Mango service not available": ""
},
"MangoWC Layout Overrides": {
"MangoWC Layout Overrides": ""
},
@@ -4604,6 +4640,9 @@
"Native: platform renderer (FreeType).": {
"Native: platform renderer (FreeType).": ""
},
"Natural Touchpad Scrolling": {
"Natural Touchpad Scrolling": ""
},
"Navigate": {
"Navigate": ""
},
@@ -5132,9 +5171,6 @@
"On-Demand": {
"On-Demand": ""
},
"On-Screen Displays": {
"On-Screen Displays": "Ekran Üstü Gösterimler"
},
"On-screen Displays": {
"On-screen Displays": "Ekran Gösterimleri"
},
@@ -5570,9 +5606,6 @@
"Plugged In": {
"Plugged In": "Bağlandı"
},
"Plugged in": {
"Plugged in": "Takılı"
},
"Plugin": {
"Plugin": "Eklenti"
},
@@ -5915,8 +5948,8 @@
"Refresh Weather": {
"Refresh Weather": "Hava Durumunu Yenile"
},
"Refreshing": {
"Refreshing": ""
"Refreshing...": {
"Refreshing...": ""
},
"Regex": {
"Regex": ""
@@ -6041,8 +6074,8 @@
"Requires DMS server with sysupdate capability": {
"Requires DMS server with sysupdate capability": ""
},
"Requires DWL compositor": {
"Requires DWL compositor": "DWL kompozitör gerektirir"
"Requires MangoWC compositor": {
"Requires MangoWC compositor": ""
},
"Requires a newer version of Quickshell": {
"Requires a newer version of Quickshell": ""
@@ -6074,6 +6107,12 @@
"Resize Widget": {
"Resize Widget": "Widgetı Yeniden Boyutlandır"
},
"Resize on Border": {
"Resize on Border": ""
},
"Resize windows by dragging their edges with the mouse": {
"Resize windows by dragging their edges with the mouse": ""
},
"Resolution & Refresh": {
"Resolution & Refresh": "Çözünürlük ve Yenileme"
},
@@ -6146,12 +6185,6 @@
"Rounded corners for windows": {
"Rounded corners for windows": "Pencereler için yuvarlatılmış köşeler"
},
"Rounded corners for windows (border_radius)": {
"Rounded corners for windows (border_radius)": ""
},
"Rounded corners for windows (decoration.rounding)": {
"Rounded corners for windows (decoration.rounding)": ""
},
"Rule": {
"Rule": ""
},
@@ -6188,8 +6221,8 @@
"Running Apps Settings": {
"Running Apps Settings": "Çalışan Uygulamalar Ayarları"
},
"Running greeter sync": {
"Running greeter sync": ""
"Running greeter sync...": {
"Running greeter sync...": ""
},
"Running in terminal": {
"Running in terminal": ""
@@ -6800,8 +6833,8 @@
"Show Workspace Apps": {
"Show Workspace Apps": "Çalışma Alanı Uygulamalarını Göster"
},
"Show all 9 tags instead of only occupied tags (DWL only)": {
"Show all 9 tags instead of only occupied tags (DWL only)": "Sadece dolu etiketleri değil, tüm 9 etiketi göster (sadece DWL)"
"Show all 9 tags instead of only occupied tags": {
"Show all 9 tags instead of only occupied tags": ""
},
"Show an outline ring around the focused workspace indicator": {
"Show an outline ring around the focused workspace indicator": ""
@@ -7007,12 +7040,6 @@
"Space between windows": {
"Space between windows": "Pencereler arası boşluk"
},
"Space between windows (gappih/gappiv/gappoh/gappov)": {
"Space between windows (gappih/gappiv/gappoh/gappov)": ""
},
"Space between windows (gaps_in and gaps_out)": {
"Space between windows (gaps_in and gaps_out)": ""
},
"Spacer": {
"Spacer": "Boşluklandırıcı"
},
@@ -7235,6 +7262,9 @@
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": {
"Tab/Shift+Tab: Nav • ←→↑↓: Grid Nav • Enter/Space: Select": "Tab/Shift+Tab: Yön • ←→↑↓: Izgara Yönü • Enter/Space: Seç"
},
"Tags": {
"Tags": ""
},
"Tags: %1": {
"Tags: %1": ""
},
@@ -7460,6 +7490,9 @@
"Title": {
"Title": "Başlık"
},
"Title (optional)": {
"Title (optional)": ""
},
"Title regex (optional)": {
"Title regex (optional)": ""
},
@@ -7850,9 +7883,6 @@
"Use custom window radius instead of theme radius": {
"Use custom window radius instead of theme radius": "Tema yarıçapı yerine özel pencere yarıçapı kullanın"
},
"Use custom window rounding instead of theme radius": {
"Use custom window rounding instead of theme radius": ""
},
"Use desktop wallpaper": {
"Use desktop wallpaper": ""
},
@@ -7961,9 +7991,6 @@
"VPN configuration updated": {
"VPN configuration updated": "VPN ayarı güncellendi"
},
"VPN connections": {
"VPN connections": "VPN bağlantıları"
},
"VPN deleted": {
"VPN deleted": "VPN silindi"
},
@@ -8177,6 +8204,9 @@
"Widgets": {
"Widgets": "Widgetlar"
},
"Widgets & Notifications": {
"Widgets & Notifications": ""
},
"Widgets, layout, style": {
"Widgets, layout, style": ""
},
@@ -8189,11 +8219,8 @@
"Width of the widget outline in pixels": {
"Width of the widget outline in pixels": ""
},
"Width of window border (borderpx)": {
"Width of window border (borderpx)": ""
},
"Width of window border (general.border_size)": {
"Width of window border (general.border_size)": ""
"Width of window border": {
"Width of window border": ""
},
"Width of window border and focus ring": {
"Width of window border and focus ring": ""
@@ -8222,9 +8249,6 @@
"Window Opening": {
"Window Opening": ""
},
"Window Rounding": {
"Window Rounding": ""
},
"Window Rules": {
"Window Rules": ""
},
@@ -8237,8 +8261,8 @@
"Wipe": {
"Wipe": ""
},
"Working": {
"Working": ""
"Working...": {
"Working...": ""
},
"Workspace": {
"Workspace": "Çalışma Alanı"
@@ -8267,15 +8291,15 @@
"Workspaces": {
"Workspaces": "Çalışma Alanları"
},
"Workspaces & Widgets": {
"Workspaces & Widgets": "Çalışma Alanları & Widgetlar"
},
"Wrap the app command. %command% is replaced with the actual executable": {
"Wrap the app command. %command% is replaced with the actual executable": ""
},
"Write:": {
"Write:": ""
},
"X": {
"X": ""
},
"X Axis": {
"X Axis": "X Ekseni"
},
@@ -8288,6 +8312,9 @@
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": {
"Xray blurs only the wallpaper (efficient) and is the default when Blur is on. Set Xray to Off for regular full blur of everything beneath the window (more expensive).": ""
},
"Y": {
"Y": ""
},
"Y Axis": {
"Y Axis": "Y Ekseni"
},
@@ -8393,9 +8420,6 @@
"e.g., scratch, /^tmp_.*/, build": {
"e.g., scratch, /^tmp_.*/, build": ""
},
"events": {
"events": "etkinlikler"
},
"ext": {
"ext": ""
},
@@ -8414,6 +8438,12 @@
"loginctl not available - lock integration requires DMS socket connection": {
"loginctl not available - lock integration requires DMS socket connection": "loginctl kullanılabilir değil - kilit entegrasyonu DMS soket bağlantısı gerektirir"
},
"mango: config reloaded": {
"mango: config reloaded": ""
},
"mango: failed to reload config": {
"mango: failed to reload config": ""
},
"mangowc Discord Server": {
"mangowc Discord Server": ""
},
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+213 -108
View File
@@ -188,6 +188,13 @@
"reference": "",
"comment": ""
},
{
"term": "%1 tasks",
"translation": "",
"context": "task count next to a date, %1 is the number of tasks",
"reference": "",
"comment": ""
},
{
"term": "%1 update",
"translation": "",
@@ -314,13 +321,6 @@
"reference": "",
"comment": ""
},
{
"term": "1 event",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "1 hour",
"translation": "",
@@ -356,6 +356,13 @@
"reference": "",
"comment": ""
},
{
"term": "1 task",
"translation": "",
"context": "task count next to a date",
"reference": "",
"comment": ""
},
{
"term": "10 minutes",
"translation": "",
@@ -1021,6 +1028,13 @@
"reference": "",
"comment": ""
},
{
"term": "Add a task...",
"translation": "",
"context": "placeholder in the new-task input field",
"reference": "",
"comment": ""
},
{
"term": "Add and configure widgets that appear on your desktop",
"translation": "",
@@ -1136,7 +1150,7 @@
{
"term": "All day",
"translation": "",
"context": "",
"context": "calendar task with no specific time",
"reference": "",
"comment": ""
},
@@ -1182,6 +1196,13 @@
"reference": "",
"comment": ""
},
{
"term": "Also group repeated application icons on the active workspace",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close",
"translation": "",
@@ -1280,6 +1301,13 @@
"reference": "",
"comment": ""
},
{
"term": "Anchor",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Animation Duration",
"translation": "",
@@ -1315,13 +1343,6 @@
"reference": "",
"comment": ""
},
{
"term": "Any",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Any window",
"translation": "",
@@ -1343,6 +1364,13 @@
"reference": "",
"comment": ""
},
{
"term": "App ID (e.g. firefox)",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "App ID Substitutions",
"translation": "",
@@ -1470,14 +1498,14 @@
"comment": ""
},
{
"term": "Applying authentication changes",
"term": "Applying authentication changes...",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Applying auto-login on startup",
"term": "Applying auto-login on startup...",
"translation": "",
"context": "",
"reference": "",
@@ -2169,6 +2197,20 @@
"reference": "",
"comment": ""
},
{
"term": "Bar",
"translation": "",
"context": "fallback name for an unnamed bar",
"reference": "",
"comment": ""
},
{
"term": "Bar %1",
"translation": "",
"context": "numbered name for an unnamed bar, %1 is its position",
"reference": "",
"comment": ""
},
{
"term": "Bar Configurations",
"translation": "",
@@ -2947,7 +2989,7 @@
"comment": ""
},
{
"term": "Checking whether sudo authentication is needed",
"term": "Checking whether sudo authentication is needed...",
"translation": "",
"context": "",
"reference": "",
@@ -2956,13 +2998,6 @@
{
"term": "Checking...",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Checking…",
"translation": "",
"context": "greeter status loading",
"reference": "",
"comment": ""
@@ -3815,7 +3850,7 @@
"comment": ""
},
{
"term": "Connecting to clipboard service",
"term": "Connecting to clipboard service...",
"translation": "",
"context": "",
"reference": "",
@@ -4626,13 +4661,6 @@
"reference": "",
"comment": ""
},
{
"term": "DWL service not available",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Daily",
"translation": "",
@@ -5194,7 +5222,7 @@
"comment": ""
},
{
"term": "Disabling auto-login on startup",
"term": "Disabling auto-login on startup...",
"translation": "",
"context": "",
"reference": "",
@@ -5348,7 +5376,7 @@
"comment": ""
},
{
"term": "Display and switch DWL layouts",
"term": "Display and switch MangoWC layouts",
"translation": "",
"context": "",
"reference": "",
@@ -5760,6 +5788,13 @@
"reference": "",
"comment": ""
},
{
"term": "Editing changes on %1",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Education",
"translation": "",
@@ -6937,14 +6972,14 @@
"comment": ""
},
{
"term": "Failed to write Hyprland outputs config.",
"term": "Failed to write autostart entry",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Failed to write autostart entry",
"term": "Failed to write outputs config.",
"translation": "",
"context": "",
"reference": "",
@@ -7230,6 +7265,27 @@
"reference": "",
"comment": ""
},
{
"term": "Float Anchor",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Float X",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Float Y",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Floating",
"translation": "",
@@ -7237,6 +7293,13 @@
"reference": "",
"comment": ""
},
{
"term": "Floating Position",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Fluent",
"translation": "",
@@ -8007,6 +8070,13 @@
"reference": "",
"comment": ""
},
{
"term": "Group Active Workspace",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Group Workspace Apps",
"translation": "",
@@ -8847,6 +8917,13 @@
"reference": "",
"comment": ""
},
{
"term": "Initial position for floating windows. Set both X and Y; anchor controls which corner/edge they're relative to.",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Initialised",
"translation": "",
@@ -9085,6 +9162,13 @@
"reference": "",
"comment": ""
},
{
"term": "Invert touchpad scroll direction",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Iris Bloom",
"translation": "",
@@ -9564,7 +9648,7 @@
{
"term": "Loading...",
"translation": "",
"context": "loading indicator",
"context": "",
"reference": "",
"comment": ""
},
@@ -9841,6 +9925,20 @@
"reference": "",
"comment": ""
},
{
"term": "Mango Options",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Mango service not available",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "MangoWC Layout Overrides",
"translation": "",
@@ -10730,6 +10828,13 @@
"reference": "",
"comment": ""
},
{
"term": "Natural Touchpad Scrolling",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Navigate",
"translation": "",
@@ -13776,7 +13881,7 @@
"comment": ""
},
{
"term": "Refreshing",
"term": "Refreshing...",
"translation": "",
"context": "",
"reference": "",
@@ -14070,7 +14175,7 @@
"comment": ""
},
{
"term": "Requires DWL compositor",
"term": "Requires MangoWC compositor",
"translation": "",
"context": "",
"reference": "",
@@ -14146,6 +14251,20 @@
"reference": "",
"comment": ""
},
{
"term": "Resize on Border",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Resize windows by dragging their edges with the mouse",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Resolution & Refresh",
"translation": "",
@@ -14314,20 +14433,6 @@
"reference": "",
"comment": ""
},
{
"term": "Rounded corners for windows (border_radius)",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Rounded corners for windows (decoration.rounding)",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Rule",
"translation": "",
@@ -14413,7 +14518,7 @@
"comment": ""
},
{
"term": "Running greeter sync",
"term": "Running greeter sync...",
"translation": "",
"context": "",
"reference": "",
@@ -15841,7 +15946,7 @@
"comment": ""
},
{
"term": "Show all 9 tags instead of only occupied tags (DWL only)",
"term": "Show all 9 tags instead of only occupied tags",
"translation": "",
"context": "",
"reference": "",
@@ -16323,20 +16428,6 @@
"reference": "",
"comment": ""
},
{
"term": "Space between windows (gappih/gappiv/gappoh/gappov)",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Space between windows (gaps_in and gaps_out)",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Spacer",
"translation": "",
@@ -16855,6 +16946,13 @@
"reference": "",
"comment": ""
},
{
"term": "Tags",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Tags: %1",
"translation": "",
@@ -17380,6 +17478,13 @@
"reference": "",
"comment": ""
},
{
"term": "Title (optional)",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Title regex (optional)",
"translation": "",
@@ -18290,13 +18395,6 @@
"reference": "",
"comment": ""
},
{
"term": "Use custom window rounding instead of theme radius",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Use desktop wallpaper",
"translation": "",
@@ -19046,6 +19144,13 @@
"reference": "",
"comment": ""
},
{
"term": "Widgets & Notifications",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Widgets, layout, style",
"translation": "",
@@ -19075,14 +19180,7 @@
"comment": ""
},
{
"term": "Width of window border (borderpx)",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Width of window border (general.border_size)",
"term": "Width of window border",
"translation": "",
"context": "",
"reference": "",
@@ -19151,13 +19249,6 @@
"reference": "",
"comment": ""
},
{
"term": "Window Rounding",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Window Rules",
"translation": "",
@@ -19187,7 +19278,7 @@
"comment": ""
},
{
"term": "Working",
"term": "Working...",
"translation": "",
"context": "",
"reference": "",
@@ -19256,13 +19347,6 @@
"reference": "",
"comment": ""
},
{
"term": "Workspaces & Widgets",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Wrap the app command. %command% is replaced with the actual executable",
"translation": "",
@@ -19277,6 +19361,13 @@
"reference": "",
"comment": ""
},
{
"term": "X",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "X Axis",
"translation": "",
@@ -19305,6 +19396,13 @@
"reference": "",
"comment": ""
},
{
"term": "Y",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Y Axis",
"translation": "",
@@ -19550,13 +19648,6 @@
"reference": "",
"comment": ""
},
{
"term": "events",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "ext",
"translation": "",
@@ -19599,6 +19690,20 @@
"reference": "",
"comment": ""
},
{
"term": "mango: config reloaded",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "mango: failed to reload config",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "mangowc Discord Server",
"translation": "",
@@ -19840,7 +19945,7 @@
{
"term": "up",
"translation": "",
"context": "",
"context": "uptime prefix, e.g. 'up 4h 2m'",
"reference": "",
"comment": ""
},
+29 -20
View File
@@ -195,6 +195,23 @@ def apply_edits(text, edits):
return text
def start_client(qmlls, root):
client = LspClient([qmlls])
client.request("initialize", {
"processId": os.getpid(),
"rootUri": root.as_uri(),
"workspaceFolders": [{"uri": root.as_uri(), "name": root.name}],
"capabilities": {
"textDocument": {
"formatting": {"dynamicRegistration": False},
"synchronization": {"dynamicRegistration": False},
},
},
})
client.notify("initialized", {})
return client
def main():
root = repo_root()
files = staged_qml_files(root)
@@ -219,24 +236,11 @@ def main():
if not qmllint:
print("warning: qmllint with --json not found; skipping unused-import checks", file=sys.stderr)
client = LspClient([qmlls])
client = start_client(qmlls, root)
changed = 0
skipped = 0
unused_by_file = {}
try:
client.request("initialize", {
"processId": os.getpid(),
"rootUri": root.as_uri(),
"workspaceFolders": [{"uri": root.as_uri(), "name": root.name}],
"capabilities": {
"textDocument": {
"formatting": {"dynamicRegistration": False},
"synchronization": {"dynamicRegistration": False},
},
},
})
client.notify("initialized", {})
for file in files:
rel = file.relative_to(root)
print(f" {rel} ... ", end="", flush=True)
@@ -258,16 +262,21 @@ def main():
"textDocument": {"uri": uri},
"options": {"tabSize": TAB_SIZE, "insertSpaces": True},
})
except RuntimeError as exc:
# qmlls (qmlformat's DOM) refuses some valid files — notably
# "Cannot format invalid documents!" on constructs qmllint
# accepts. Don't let one file's formatter bug abort the commit.
except (RuntimeError, OSError) as exc:
# qmlls (qmlformat's DOM) chokes on some valid files: it refuses
# them ("Cannot format invalid documents!") or outright crashes
# (e.g. SIGABRT on a function declaration inside a property
# binding). Don't let one file's formatter bug abort the commit.
skipped += 1
if client.proc.poll() is not None:
print("skipped (qmlls crashed on this file; restarting it)")
client = start_client(qmlls, root)
continue
client.notify("textDocument/didClose", {"textDocument": {"uri": uri}})
if "invalid document" in str(exc).lower():
print("skipped (qmlls rejected as invalid;")
print("skipped (qmlls rejected as invalid)")
else:
print(f"skipped ({exc})")
skipped += 1
continue
client.notify("textDocument/didClose", {"textDocument": {"uri": uri}})