1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-01-29 07:52:50 -05:00

Compare commits

..

22 Commits

Author SHA1 Message Date
bbedward
ccb4da3cd8 extws: fix force option 2025-11-17 10:08:06 -05:00
bbedward
46e96b49f0 extws: fix capability check & don't show names 2025-11-17 09:50:06 -05:00
bbedward
984cfe7f98 labwc: use dms dpms off/on for idle service 2025-11-17 09:12:38 -05:00
bbedward
d769300137 core/cli: add dpms off/on via wlr-output-power-management 2025-11-17 00:31:00 -05:00
Hikiru
d175d66828 Add NixOS module (#734)
* default.nix: fix "wavelength" typo

* Add nixos module

typo

fix

* nix: refactor and fix nix modules

* nix: fix NixOS module import

* nix: revert quickshell option change

* nix: fix nixosModules dmsPkgs definition

---------

Co-authored-by: LuckShiba <luckshiba@protonmail.com>
2025-11-16 21:12:01 -05:00
bbedward
c1a314332e wallpaper: rename blur layer option 2025-11-16 19:50:19 -05:00
bbedward
046ac59d21 core/extworkspace: only register outputs on name received 2025-11-16 19:40:46 -05:00
bbedward
00c06f07d0 workspace: fix ext-ws hiding 2025-11-16 18:52:12 -05:00
bbedward
3e2ab40c6a ws: 0 width when 0 workspaces, restore labwc to README 2025-11-16 17:53:50 -05:00
bbedward
350ffd0052 i18n: update terms 2025-11-16 16:33:55 -05:00
bbedward
ecd1a622d2 display: fix wallpaper when using monitor model 2025-11-16 16:33:21 -05:00
bbedward
f13968aa61 osd: configurable position 2025-11-16 16:27:01 -05:00
bbedward
4d1ffde54c launcher: allow launch prefix to run in shell 2025-11-16 16:14:19 -05:00
bbedward
d69017a706 also update per-monitor wallpaper to accout for display setting 2025-11-16 16:01:11 -05:00
bbedward
f2deaeccdb scaling: snap value reported by wlr-output 2025-11-16 15:56:59 -05:00
bbedward
ea9b0d2a79 powermenu: use consistent new-style on locker + greeter
fixes #739
2025-11-16 15:05:06 -05:00
bbedward
2e6dbedb8b dwl/mango: support keyboard layout 2025-11-16 14:24:56 -05:00
bbedward
6f359df8f9 displays: allow filtering by model over name 2025-11-16 13:58:53 -05:00
claymorwan
f6db20cd06 confirm-modal:add layer namespace (#743) 2025-11-16 13:09:44 -05:00
bbedward
6287fae065 running apps: don't wrap on scroll wheel
fixes #740
2025-11-16 13:06:40 -05:00
bbedward
e441607ce3 colorpicker: don't include line break in copy
fixes #741
2025-11-16 13:00:13 -05:00
bbedward
b5379a95fa qs/dankbar/meta: add a mask region to the bar
- Allows bar items to be clickable evn when popouts open
- Add state machines to manage state across monitors
- change focuses to ondemand on hyprland
2025-11-16 12:52:13 -05:00
54 changed files with 3704 additions and 1498 deletions

View File

@@ -19,7 +19,7 @@
</div> </div>
DankMaterialShell is a complete desktop shell for [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [MangoWC](https://github.com/DreamMaoMao/mangowc), [Sway](https://swaywm.org), and other Wayland compositors. It replaces waybar, swaylock, swayidle, mako, fuzzel, polkit, and everything else you'd normally stitch together to make a desktop. DankMaterialShell is a complete desktop shell for [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [MangoWC](https://github.com/DreamMaoMao/mangowc), [Sway](https://swaywm.org), [labwc](https://labwc.github.io/), and other Wayland compositors. It replaces waybar, swaylock, swayidle, mako, fuzzel, polkit, and everything else you'd normally stitch together to make a desktop.
## Repository Structure ## Repository Structure
@@ -105,7 +105,7 @@ Extend functionality with the [plugin registry](https://plugins.danklinux.com).
## Supported Compositors ## Supported Compositors
Works best with [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [Sway](https://swaywm.org/), and [MangoWC](https://github.com/DreamMaoMao/mangowc) with full workspace switching, overview integration, and monitor management. Other Wayland compositors work with reduced features. Works best with [niri](https://github.com/YaLTeR/niri), [Hyprland](https://hyprland.org/), [Sway](https://swaywm.org/), [MangoWC](https://github.com/DreamMaoMao/mangowc), and [labwc](https://labwc.github.io/) with full workspace switching, overview integration, and monitor management. Other Wayland compositors work with reduced features.
[Compositor configuration guide](https://danklinux.com/docs/dankmaterialshell/compositors) [Compositor configuration guide](https://danklinux.com/docs/dankmaterialshell/compositors)

View File

@@ -368,6 +368,7 @@ func getCommonCommands() []*cobra.Command {
pluginsCmd, pluginsCmd,
dank16Cmd, dank16Cmd,
brightnessCmd, brightnessCmd,
dpmsCmd,
keybindsCmd, keybindsCmd,
greeterCmd, greeterCmd,
setupCmd, setupCmd,

View File

@@ -0,0 +1,84 @@
package main
import (
"fmt"
"github.com/AvengeMedia/DankMaterialShell/core/internal/log"
"github.com/spf13/cobra"
)
var dpmsCmd = &cobra.Command{
Use: "dpms",
Short: "Control display power management",
}
var dpmsOnCmd = &cobra.Command{
Use: "on [output]",
Short: "Turn display(s) on",
Args: cobra.MaximumNArgs(1),
Run: runDPMSOn,
}
var dpmsOffCmd = &cobra.Command{
Use: "off [output]",
Short: "Turn display(s) off",
Args: cobra.MaximumNArgs(1),
Run: runDPMSOff,
}
var dpmsListCmd = &cobra.Command{
Use: "list",
Short: "List outputs",
Args: cobra.NoArgs,
Run: runDPMSList,
}
func init() {
dpmsCmd.AddCommand(dpmsOnCmd, dpmsOffCmd, dpmsListCmd)
}
func runDPMSOn(cmd *cobra.Command, args []string) {
outputName := ""
if len(args) > 0 {
outputName = args[0]
}
client, err := newDPMSClient()
if err != nil {
log.Fatalf("%v", err)
}
defer client.Close()
if err := client.SetDPMS(outputName, true); err != nil {
log.Fatalf("%v", err)
}
}
func runDPMSOff(cmd *cobra.Command, args []string) {
outputName := ""
if len(args) > 0 {
outputName = args[0]
}
client, err := newDPMSClient()
if err != nil {
log.Fatalf("%v", err)
}
defer client.Close()
if err := client.SetDPMS(outputName, false); err != nil {
log.Fatalf("%v", err)
}
}
func runDPMSList(cmd *cobra.Command, args []string) {
client, err := newDPMSClient()
if err != nil {
log.Fatalf("%v", err)
}
defer client.Close()
for _, output := range client.ListOutputs() {
fmt.Println(output)
}
}

345
core/cmd/dms/dpms_client.go Normal file
View File

@@ -0,0 +1,345 @@
package main
import (
"fmt"
"sync"
"time"
"github.com/AvengeMedia/DankMaterialShell/core/internal/proto/wlr_output_power"
wlclient "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
)
type cmd struct {
fn func()
done chan error
}
type dpmsClient struct {
display *wlclient.Display
ctx *wlclient.Context
powerMgr *wlr_output_power.ZwlrOutputPowerManagerV1
outputs map[string]*outputState
mu sync.Mutex
syncRound int
done bool
err error
cmdq chan cmd
stopChan chan struct{}
wg sync.WaitGroup
}
type outputState struct {
wlOutput *wlclient.Output
powerCtrl *wlr_output_power.ZwlrOutputPowerV1
name string
mode uint32
failed bool
waitCh chan struct{}
wantMode *uint32
}
func (c *dpmsClient) post(fn func()) {
done := make(chan error, 1)
select {
case c.cmdq <- cmd{fn: fn, done: done}:
<-done
case <-c.stopChan:
}
}
func (c *dpmsClient) waylandActor() {
defer c.wg.Done()
for {
select {
case <-c.stopChan:
return
case cmd := <-c.cmdq:
cmd.fn()
close(cmd.done)
}
}
}
func newDPMSClient() (*dpmsClient, error) {
display, err := wlclient.Connect("")
if err != nil {
return nil, fmt.Errorf("failed to connect to Wayland: %w", err)
}
c := &dpmsClient{
display: display,
ctx: display.Context(),
outputs: make(map[string]*outputState),
cmdq: make(chan cmd, 128),
stopChan: make(chan struct{}),
}
c.wg.Add(1)
go c.waylandActor()
registry, err := display.GetRegistry()
if err != nil {
display.Context().Close()
return nil, fmt.Errorf("failed to get registry: %w", err)
}
registry.SetGlobalHandler(func(e wlclient.RegistryGlobalEvent) {
switch e.Interface {
case wlr_output_power.ZwlrOutputPowerManagerV1InterfaceName:
powerMgr := wlr_output_power.NewZwlrOutputPowerManagerV1(c.ctx)
version := e.Version
if version > 1 {
version = 1
}
if err := registry.Bind(e.Name, e.Interface, version, powerMgr); err == nil {
c.powerMgr = powerMgr
}
case "wl_output":
output := wlclient.NewOutput(c.ctx)
version := e.Version
if version > 4 {
version = 4
}
if err := registry.Bind(e.Name, e.Interface, version, output); err == nil {
outputID := fmt.Sprintf("output-%d", output.ID())
state := &outputState{
wlOutput: output,
name: outputID,
}
c.mu.Lock()
c.outputs[outputID] = state
c.mu.Unlock()
output.SetNameHandler(func(ev wlclient.OutputNameEvent) {
c.mu.Lock()
delete(c.outputs, state.name)
state.name = ev.Name
c.outputs[ev.Name] = state
c.mu.Unlock()
})
}
}
})
syncCallback, err := display.Sync()
if err != nil {
c.Close()
return nil, fmt.Errorf("failed to sync display: %w", err)
}
syncCallback.SetDoneHandler(func(e wlclient.CallbackDoneEvent) {
c.handleSync()
})
for !c.done {
if err := c.ctx.Dispatch(); err != nil {
c.Close()
return nil, fmt.Errorf("dispatch error: %w", err)
}
}
if c.err != nil {
c.Close()
return nil, c.err
}
return c, nil
}
func (c *dpmsClient) handleSync() {
c.syncRound++
switch c.syncRound {
case 1:
if c.powerMgr == nil {
c.err = fmt.Errorf("wlr-output-power-management protocol not supported by compositor")
c.done = true
return
}
c.mu.Lock()
for _, state := range c.outputs {
powerCtrl, err := c.powerMgr.GetOutputPower(state.wlOutput)
if err != nil {
continue
}
state.powerCtrl = powerCtrl
powerCtrl.SetModeHandler(func(e wlr_output_power.ZwlrOutputPowerV1ModeEvent) {
c.mu.Lock()
defer c.mu.Unlock()
if state.powerCtrl == nil {
return
}
state.mode = e.Mode
if state.wantMode != nil && e.Mode == *state.wantMode && state.waitCh != nil {
close(state.waitCh)
state.wantMode = nil
}
})
powerCtrl.SetFailedHandler(func(e wlr_output_power.ZwlrOutputPowerV1FailedEvent) {
c.mu.Lock()
defer c.mu.Unlock()
if state.powerCtrl == nil {
return
}
state.failed = true
if state.waitCh != nil {
close(state.waitCh)
state.wantMode = nil
}
})
}
c.mu.Unlock()
syncCallback, err := c.display.Sync()
if err != nil {
c.err = fmt.Errorf("failed to sync display: %w", err)
c.done = true
return
}
syncCallback.SetDoneHandler(func(e wlclient.CallbackDoneEvent) {
c.handleSync()
})
default:
c.done = true
}
}
func (c *dpmsClient) ListOutputs() []string {
c.mu.Lock()
defer c.mu.Unlock()
names := make([]string, 0, len(c.outputs))
for name := range c.outputs {
names = append(names, name)
}
return names
}
func (c *dpmsClient) SetDPMS(outputName string, on bool) error {
var mode uint32
if on {
mode = uint32(wlr_output_power.ZwlrOutputPowerV1ModeOn)
} else {
mode = uint32(wlr_output_power.ZwlrOutputPowerV1ModeOff)
}
var setErr error
c.post(func() {
c.mu.Lock()
var waitStates []*outputState
if outputName == "" || outputName == "all" {
if len(c.outputs) == 0 {
c.mu.Unlock()
setErr = fmt.Errorf("no outputs found")
return
}
for _, state := range c.outputs {
if state.powerCtrl == nil {
continue
}
state.wantMode = &mode
state.waitCh = make(chan struct{})
state.failed = false
waitStates = append(waitStates, state)
state.powerCtrl.SetMode(mode)
}
} else {
state, ok := c.outputs[outputName]
if !ok {
c.mu.Unlock()
setErr = fmt.Errorf("output not found: %s", outputName)
return
}
if state.powerCtrl == nil {
c.mu.Unlock()
setErr = fmt.Errorf("output %s has nil powerCtrl", outputName)
return
}
state.wantMode = &mode
state.waitCh = make(chan struct{})
state.failed = false
waitStates = append(waitStates, state)
state.powerCtrl.SetMode(mode)
}
c.mu.Unlock()
deadline := time.Now().Add(10 * time.Second)
for _, state := range waitStates {
c.mu.Lock()
ch := state.waitCh
c.mu.Unlock()
done := false
for !done {
if err := c.ctx.Dispatch(); err != nil {
setErr = fmt.Errorf("dispatch error: %w", err)
return
}
select {
case <-ch:
c.mu.Lock()
if state.failed {
setErr = fmt.Errorf("compositor reported failed for %s", state.name)
c.mu.Unlock()
return
}
c.mu.Unlock()
done = true
default:
if time.Now().After(deadline) {
setErr = fmt.Errorf("timeout waiting for mode change on %s", state.name)
return
}
time.Sleep(10 * time.Millisecond)
}
}
}
c.mu.Lock()
for _, state := range waitStates {
if state.powerCtrl != nil {
state.powerCtrl.Destroy()
state.powerCtrl = nil
}
}
c.mu.Unlock()
c.display.Roundtrip()
})
return setErr
}
func (c *dpmsClient) Close() {
close(c.stopChan)
c.wg.Wait()
c.mu.Lock()
defer c.mu.Unlock()
for _, state := range c.outputs {
if state.powerCtrl != nil {
state.powerCtrl.Destroy()
}
}
c.outputs = nil
if c.powerMgr != nil {
c.powerMgr.Destroy()
c.powerMgr = nil
}
if c.display != nil {
c.ctx.Close()
c.display = nil
}
}

View File

@@ -157,6 +157,16 @@ type ZdwlIpcOutputV2 struct {
appidHandler ZdwlIpcOutputV2AppidHandlerFunc appidHandler ZdwlIpcOutputV2AppidHandlerFunc
layoutSymbolHandler ZdwlIpcOutputV2LayoutSymbolHandlerFunc layoutSymbolHandler ZdwlIpcOutputV2LayoutSymbolHandlerFunc
frameHandler ZdwlIpcOutputV2FrameHandlerFunc 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 // NewZdwlIpcOutputV2 : control dwl output
@@ -251,6 +261,60 @@ func (i *ZdwlIpcOutputV2) SetLayout(index uint32) error {
return err 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 type ZdwlIpcOutputV2TagState uint32
// ZdwlIpcOutputV2TagState : // ZdwlIpcOutputV2TagState :
@@ -399,6 +463,136 @@ func (i *ZdwlIpcOutputV2) SetFrameHandler(f ZdwlIpcOutputV2FrameHandlerFunc) {
i.frameHandler = f 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) { func (i *ZdwlIpcOutputV2) Dispatch(opcode uint32, fd int, data []byte) {
switch opcode { switch opcode {
case 0: case 0:
@@ -487,5 +681,111 @@ func (i *ZdwlIpcOutputV2) Dispatch(opcode uint32, fd int, data []byte) {
var e ZdwlIpcOutputV2FrameEvent var e ZdwlIpcOutputV2FrameEvent
i.frameHandler(e) 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)
} }
} }

View File

@@ -0,0 +1,283 @@
// Generated by go-wayland-scanner
// https://github.com/yaslama/go-wayland/cmd/go-wayland-scanner
// XML file : internal/proto/xml/wlr-output-power-management-unstable-v1.xml
//
// wlr_output_power_management_unstable_v1 Protocol Copyright:
//
// Copyright © 2019 Purism SPC
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice (including the next
// paragraph) shall be included in all copies or substantial portions of the
// Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
package wlr_output_power
import "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
// ZwlrOutputPowerManagerV1InterfaceName 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 ZwlrOutputPowerManagerV1InterfaceName = "zwlr_output_power_manager_v1"
// ZwlrOutputPowerManagerV1 : manager to create per-output power management
//
// This interface is a manager that allows creating per-output power
// management mode controls.
type ZwlrOutputPowerManagerV1 struct {
client.BaseProxy
}
// NewZwlrOutputPowerManagerV1 : manager to create per-output power management
//
// This interface is a manager that allows creating per-output power
// management mode controls.
func NewZwlrOutputPowerManagerV1(ctx *client.Context) *ZwlrOutputPowerManagerV1 {
zwlrOutputPowerManagerV1 := &ZwlrOutputPowerManagerV1{}
ctx.Register(zwlrOutputPowerManagerV1)
return zwlrOutputPowerManagerV1
}
// GetOutputPower : get a power management for an output
//
// Create an output power management mode control that can be used to
// adjust the power management mode for a given output.
func (i *ZwlrOutputPowerManagerV1) GetOutputPower(output *client.Output) (*ZwlrOutputPowerV1, error) {
id := NewZwlrOutputPowerV1(i.Context())
const opcode = 0
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
}
// Destroy : destroy the manager
//
// All objects created by the manager will still remain valid, until their
// appropriate destroy request has been called.
func (i *ZwlrOutputPowerManagerV1) Destroy() error {
defer i.Context().Unregister(i)
const opcode = 1
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
}
// ZwlrOutputPowerV1InterfaceName 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 ZwlrOutputPowerV1InterfaceName = "zwlr_output_power_v1"
// ZwlrOutputPowerV1 : adjust power management mode for an output
//
// This object offers requests to set the power management mode of
// an output.
type ZwlrOutputPowerV1 struct {
client.BaseProxy
modeHandler ZwlrOutputPowerV1ModeHandlerFunc
failedHandler ZwlrOutputPowerV1FailedHandlerFunc
}
// NewZwlrOutputPowerV1 : adjust power management mode for an output
//
// This object offers requests to set the power management mode of
// an output.
func NewZwlrOutputPowerV1(ctx *client.Context) *ZwlrOutputPowerV1 {
zwlrOutputPowerV1 := &ZwlrOutputPowerV1{}
ctx.Register(zwlrOutputPowerV1)
return zwlrOutputPowerV1
}
// SetMode : Set an outputs power save mode
//
// Set an output's power save mode to the given mode. The mode change
// is effective immediately. If the output does not support the given
// mode a failed event is sent.
//
// mode: the power save mode to set
func (i *ZwlrOutputPowerV1) SetMode(mode uint32) error {
const opcode = 0
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(mode))
l += 4
err := i.Context().WriteMsg(_reqBuf[:], nil)
return err
}
// Destroy : destroy this power management
//
// Destroys the output power management mode control object.
func (i *ZwlrOutputPowerV1) Destroy() error {
defer i.Context().Unregister(i)
const opcode = 1
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
}
type ZwlrOutputPowerV1Mode uint32
// ZwlrOutputPowerV1Mode :
const (
// ZwlrOutputPowerV1ModeOff : Output is turned off.
ZwlrOutputPowerV1ModeOff ZwlrOutputPowerV1Mode = 0
// ZwlrOutputPowerV1ModeOn : Output is turned on, no power saving
ZwlrOutputPowerV1ModeOn ZwlrOutputPowerV1Mode = 1
)
func (e ZwlrOutputPowerV1Mode) Name() string {
switch e {
case ZwlrOutputPowerV1ModeOff:
return "off"
case ZwlrOutputPowerV1ModeOn:
return "on"
default:
return ""
}
}
func (e ZwlrOutputPowerV1Mode) Value() string {
switch e {
case ZwlrOutputPowerV1ModeOff:
return "0"
case ZwlrOutputPowerV1ModeOn:
return "1"
default:
return ""
}
}
func (e ZwlrOutputPowerV1Mode) String() string {
return e.Name() + "=" + e.Value()
}
type ZwlrOutputPowerV1Error uint32
// ZwlrOutputPowerV1Error :
const (
// ZwlrOutputPowerV1ErrorInvalidMode : nonexistent power save mode
ZwlrOutputPowerV1ErrorInvalidMode ZwlrOutputPowerV1Error = 1
)
func (e ZwlrOutputPowerV1Error) Name() string {
switch e {
case ZwlrOutputPowerV1ErrorInvalidMode:
return "invalid_mode"
default:
return ""
}
}
func (e ZwlrOutputPowerV1Error) Value() string {
switch e {
case ZwlrOutputPowerV1ErrorInvalidMode:
return "1"
default:
return ""
}
}
func (e ZwlrOutputPowerV1Error) String() string {
return e.Name() + "=" + e.Value()
}
// ZwlrOutputPowerV1ModeEvent : Report a power management mode change
//
// Report the power management mode change of an output.
//
// The mode event is sent after an output changed its power
// management mode. The reason can be a client using set_mode or the
// compositor deciding to change an output's mode.
// This event is also sent immediately when the object is created
// so the client is informed about the current power management mode.
type ZwlrOutputPowerV1ModeEvent struct {
Mode uint32
}
type ZwlrOutputPowerV1ModeHandlerFunc func(ZwlrOutputPowerV1ModeEvent)
// SetModeHandler : sets handler for ZwlrOutputPowerV1ModeEvent
func (i *ZwlrOutputPowerV1) SetModeHandler(f ZwlrOutputPowerV1ModeHandlerFunc) {
i.modeHandler = f
}
// ZwlrOutputPowerV1FailedEvent : object no longer valid
//
// This event indicates that the output power management mode control
// is no longer valid. This can happen for a number of reasons,
// including:
// - The output doesn't support power management
// - Another client already has exclusive power management mode control
// for this output
// - The output disappeared
//
// Upon receiving this event, the client should destroy this object.
type ZwlrOutputPowerV1FailedEvent struct{}
type ZwlrOutputPowerV1FailedHandlerFunc func(ZwlrOutputPowerV1FailedEvent)
// SetFailedHandler : sets handler for ZwlrOutputPowerV1FailedEvent
func (i *ZwlrOutputPowerV1) SetFailedHandler(f ZwlrOutputPowerV1FailedHandlerFunc) {
i.failedHandler = f
}
func (i *ZwlrOutputPowerV1) Dispatch(opcode uint32, fd int, data []byte) {
switch opcode {
case 0:
if i.modeHandler == nil {
return
}
var e ZwlrOutputPowerV1ModeEvent
l := 0
e.Mode = client.Uint32(data[l : l+4])
l += 4
i.modeHandler(e)
case 1:
if i.failedHandler == nil {
return
}
var e ZwlrOutputPowerV1FailedEvent
i.failedHandler(e)
}
}

View File

@@ -19,7 +19,7 @@ I would probably just submit raphi's patchset but I don't think that would be po
reset. reset.
</description> </description>
<interface name="zdwl_ipc_manager_v2" version="1"> <interface name="zdwl_ipc_manager_v2" version="2">
<description summary="manage dwl state"> <description summary="manage dwl state">
This interface is exposed as a global in wl_registry. This interface is exposed as a global in wl_registry.
@@ -60,7 +60,7 @@ I would probably just submit raphi's patchset but I don't think that would be po
</event> </event>
</interface> </interface>
<interface name="zdwl_ipc_output_v2" version="1"> <interface name="zdwl_ipc_output_v2" version="2">
<description summary="control dwl output"> <description summary="control dwl output">
Observe and control a dwl output. Observe and control a dwl output.
@@ -162,5 +162,91 @@ I would probably just submit raphi's patchset but I don't think that would be po
<description summary="Set the layout of this output"/> <description summary="Set the layout of this output"/>
<arg name="index" type="uint" summary="index of a layout recieved by dwl_ipc_manager.layout"/> <arg name="index" type="uint" summary="index of a layout recieved by dwl_ipc_manager.layout"/>
</request> </request>
<request name="quit" since="2">
<description summary="Quit mango">This request allows clients to instruct the compositor to quit mango.</description>
</request>
<request name="dispatch" since="2">
<description summary="Set the active tags of this output"/>
<arg name="dispatch" type="string" summary="dispatch name."/>
<arg name="arg1" type="string" summary="arg1."/>
<arg name="arg2" type="string" summary="arg2."/>
<arg name="arg3" type="string" summary="arg3."/>
<arg name="arg4" type="string" summary="arg4."/>
<arg name="arg5" type="string" summary="arg5."/>
</request>
<!-- Version 2 -->
<event name="fullscreen" since="2">
<description summary="Update fullscreen status">
Indicates if the selected client on this output is fullscreen.
</description>
<arg name="is_fullscreen" type="uint" summary="If the selected client is fullscreen. Nonzero is valid, zero invalid"/>
</event>
<event name="floating" since="2">
<description summary="Update the floating status">
Indicates if the selected client on this output is floating.
</description>
<arg name="is_floating" type="uint" summary="If the selected client is floating. Nonzero is valid, zero invalid"/>
</event>
<event name="x" since="2">
<description summary="Update the x coordinates">
Indicates if x coordinates of the selected client.
</description>
<arg name="x" type="int" summary="x coordinate of the selected client"/>
</event>
<event name="y" since="2">
<description summary="Update the y coordinates">
Indicates if y coordinates of the selected client.
</description>
<arg name="y" type="int" summary="y coordinate of the selected client"/>
</event>
<event name="width" since="2">
<description summary="Update the width">
Indicates if width of the selected client.
</description>
<arg name="width" type="int" summary="width of the selected client"/>
</event>
<event name="height" since="2">
<description summary="Update the height">
Indicates if height of the selected client.
</description>
<arg name="height" type="int" summary="height of the selected client"/>
</event>
<event name="last_layer" since="2">
<description summary="last map layer.">
last map layer.
</description>
<arg name="last_layer" type="string" summary="last map layer."/>
</event>
<event name="kb_layout" since="2">
<description summary="current keyboard layout.">
current keyboard layout.
</description>
<arg name="kb_layout" type="string" summary="current keyboard layout."/>
</event>
<event name="keymode" since="2">
<description summary="current keybind mode.">
current keybind mode.
</description>
<arg name="keymode" type="string" summary="current keybind mode."/>
</event>
<event name="scalefactor" since="2">
<description summary="scale factor of monitor.">
scale factor of monitor.
</description>
<arg name="scalefactor" type="uint" summary="scale factor of monitor."/>
</event>
</interface> </interface>
</protocol> </protocol>

View File

@@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?>
<protocol name="wlr_output_power_management_unstable_v1">
<copyright>
Copyright © 2019 Purism SPC
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation
the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next
paragraph) shall be included in all copies or substantial portions of the
Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
</copyright>
<description summary="Control power management modes of outputs">
This protocol allows clients to control power management modes
of outputs that are currently part of the compositor space. The
intent is to allow special clients like desktop shells to power
down outputs when the system is idle.
To modify outputs not currently part of the compositor space see
wlr-output-management.
Warning! The protocol described in this file is experimental and
backward incompatible changes may be made. Backward compatible changes
may be added together with the corresponding interface version bump.
Backward incompatible changes are done by bumping the version number in
the protocol and interface names and resetting the interface version.
Once the protocol is to be declared stable, the 'z' prefix and the
version number in the protocol and interface names are removed and the
interface version number is reset.
</description>
<interface name="zwlr_output_power_manager_v1" version="1">
<description summary="manager to create per-output power management">
This interface is a manager that allows creating per-output power
management mode controls.
</description>
<request name="get_output_power">
<description summary="get a power management for an output">
Create an output power management mode control that can be used to
adjust the power management mode for a given output.
</description>
<arg name="id" type="new_id" interface="zwlr_output_power_v1"/>
<arg name="output" type="object" interface="wl_output"/>
</request>
<request name="destroy" type="destructor">
<description summary="destroy the manager">
All objects created by the manager will still remain valid, until their
appropriate destroy request has been called.
</description>
</request>
</interface>
<interface name="zwlr_output_power_v1" version="1">
<description summary="adjust power management mode for an output">
This object offers requests to set the power management mode of
an output.
</description>
<enum name="mode">
<entry name="off" value="0"
summary="Output is turned off."/>
<entry name="on" value="1"
summary="Output is turned on, no power saving"/>
</enum>
<enum name="error">
<entry name="invalid_mode" value="1" summary="nonexistent power save mode"/>
</enum>
<request name="set_mode">
<description summary="Set an outputs power save mode">
Set an output's power save mode to the given mode. The mode change
is effective immediately. If the output does not support the given
mode a failed event is sent.
</description>
<arg name="mode" type="uint" enum="mode" summary="the power save mode to set"/>
</request>
<event name="mode">
<description summary="Report a power management mode change">
Report the power management mode change of an output.
The mode event is sent after an output changed its power
management mode. The reason can be a client using set_mode or the
compositor deciding to change an output's mode.
This event is also sent immediately when the object is created
so the client is informed about the current power management mode.
</description>
<arg name="mode" type="uint" enum="mode"
summary="the output's new power management mode"/>
</event>
<event name="failed">
<description summary="object no longer valid">
This event indicates that the output power management mode control
is no longer valid. This can happen for a number of reasons,
including:
- The output doesn't support power management
- Another client already has exclusive power management mode control
for this output
- The output disappeared
Upon receiving this event, the client should destroy this object.
</description>
</event>
<request name="destroy" type="destructor">
<description summary="destroy this power management">
Destroys the output power management mode control object.
</description>
</request>
</interface>
</protocol>

View File

@@ -100,8 +100,8 @@ func (m *Manager) setupRegistry() error {
log.Infof("DWL: found %s", dwl_ipc.ZdwlIpcManagerV2InterfaceName) log.Infof("DWL: found %s", dwl_ipc.ZdwlIpcManagerV2InterfaceName)
manager := dwl_ipc.NewZdwlIpcManagerV2(m.ctx) manager := dwl_ipc.NewZdwlIpcManagerV2(m.ctx)
version := e.Version version := e.Version
if version > 1 { if version > 2 {
version = 1 version = 2
} }
if err := registry.Bind(e.Name, e.Interface, version, manager); err == nil { if err := registry.Bind(e.Name, e.Interface, version, manager); err == nil {
dwlMgr = manager dwlMgr = manager
@@ -282,6 +282,14 @@ func (m *Manager) setupOutput(manager *dwl_ipc.ZdwlIpcManagerV2, output *wlclien
outState.layoutSymbol = e.Layout 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) { ipcOutput.SetFrameHandler(func(e dwl_ipc.ZdwlIpcOutputV2FrameEvent) {
m.updateState() m.updateState()
}) })
@@ -310,6 +318,8 @@ func (m *Manager) updateState() {
LayoutSymbol: out.layoutSymbol, LayoutSymbol: out.layoutSymbol,
Title: out.title, Title: out.title,
AppID: out.appID, AppID: out.appID,
KbLayout: out.kbLayout,
Keymode: out.keymode,
} }
if out.active != 0 { if out.active != 0 {

View File

@@ -22,6 +22,8 @@ type OutputState struct {
LayoutSymbol string `json:"layoutSymbol"` LayoutSymbol string `json:"layoutSymbol"`
Title string `json:"title"` Title string `json:"title"`
AppID string `json:"appId"` AppID string `json:"appId"`
KbLayout string `json:"kbLayout"`
Keymode string `json:"keymode"`
} }
type State struct { type State struct {
@@ -73,6 +75,8 @@ type outputState struct {
layoutSymbol string layoutSymbol string
title string title string
appID string appID string
kbLayout string
keymode string
} }
func (m *Manager) GetState() State { func (m *Manager) GetState() State {
@@ -147,6 +151,12 @@ func stateChanged(old, new *State) bool {
if oldOut.AppID != newOut.AppID { if oldOut.AppID != newOut.AppID {
return true return true
} }
if oldOut.KbLayout != newOut.KbLayout {
return true
}
if oldOut.Keymode != newOut.Keymode {
return true
}
if len(oldOut.Tags) != len(newOut.Tags) { if len(oldOut.Tags) != len(newOut.Tags) {
return true return true
} }

View File

@@ -9,6 +9,35 @@ import (
wlclient "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client" wlclient "github.com/AvengeMedia/DankMaterialShell/core/pkg/go-wayland/wayland/client"
) )
func CheckCapability() bool {
display, err := wlclient.Connect("")
if err != nil {
return false
}
defer display.Destroy()
registry, err := display.GetRegistry()
if err != nil {
return false
}
defer registry.Destroy()
found := false
registry.SetGlobalHandler(func(e wlclient.RegistryGlobalEvent) {
if e.Interface == ext_workspace.ExtWorkspaceManagerV1InterfaceName {
found = true
}
})
// Roundtrip to ensure all registry events are processed
if err := display.Roundtrip(); err != nil {
return false
}
return found
}
func NewManager(display *wlclient.Display) (*Manager, error) { func NewManager(display *wlclient.Display) (*Manager, error) {
m := &Manager{ m := &Manager{
display: display, display: display,
@@ -75,6 +104,9 @@ func (m *Manager) setupRegistry() error {
output.SetNameHandler(func(ev wlclient.OutputNameEvent) { output.SetNameHandler(func(ev wlclient.OutputNameEvent) {
m.outputNames.Store(outputID, ev.Name) m.outputNames.Store(outputID, ev.Name)
log.Debugf("ExtWorkspace: Output %d (%s) name received", outputID, ev.Name) log.Debugf("ExtWorkspace: Output %d (%s) name received", outputID, ev.Name)
m.post(func() {
m.updateState()
})
}) })
} }
return return
@@ -295,14 +327,8 @@ func (m *Manager) updateState() {
outputs := make([]string, 0) outputs := make([]string, 0)
for outputID := range group.outputIDs { for outputID := range group.outputIDs {
if name, ok := m.outputNames.Load(outputID); ok { if name, ok := m.outputNames.Load(outputID); ok && name != "" {
if name != "" { outputs = append(outputs, name)
outputs = append(outputs, name)
} else {
outputs = append(outputs, fmt.Sprintf("output-%d", outputID))
}
} else {
outputs = append(outputs, fmt.Sprintf("output-%d", outputID))
} }
} }

View File

@@ -140,8 +140,20 @@ func RouteRequest(conn net.Conn, req models.Request) {
if strings.HasPrefix(req.Method, "extworkspace.") { if strings.HasPrefix(req.Method, "extworkspace.") {
if extWorkspaceManager == nil { if extWorkspaceManager == nil {
models.RespondError(conn, req.ID, "extworkspace manager not initialized") if extWorkspaceAvailable.Load() {
return extWorkspaceInitMutex.Lock()
if extWorkspaceManager == nil {
if err := InitializeExtWorkspaceManager(); err != nil {
extWorkspaceInitMutex.Unlock()
models.RespondError(conn, req.ID, "extworkspace manager not available")
return
}
}
extWorkspaceInitMutex.Unlock()
} else {
models.RespondError(conn, req.ID, "extworkspace manager not initialized")
return
}
} }
extWorkspaceReq := extworkspace.Request{ extWorkspaceReq := extworkspace.Request{
ID: req.ID, ID: req.ID,

View File

@@ -31,7 +31,7 @@ import (
"github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap" "github.com/AvengeMedia/DankMaterialShell/core/pkg/syncmap"
) )
const APIVersion = 18 const APIVersion = 19
type Capabilities struct { type Capabilities struct {
Capabilities []string `json:"capabilities"` Capabilities []string `json:"capabilities"`
@@ -63,6 +63,8 @@ var wlContext *wlcontext.SharedContext
var capabilitySubscribers syncmap.Map[string, chan ServerInfo] var capabilitySubscribers syncmap.Map[string, chan ServerInfo]
var cupsSubscribers syncmap.Map[string, bool] var cupsSubscribers syncmap.Map[string, bool]
var cupsSubscriberCount atomic.Int32 var cupsSubscriberCount atomic.Int32
var extWorkspaceAvailable atomic.Bool
var extWorkspaceInitMutex sync.Mutex
func getSocketDir() string { func getSocketDir() string {
if runtime := os.Getenv("XDG_RUNTIME_DIR"); runtime != "" { if runtime := os.Getenv("XDG_RUNTIME_DIR"); runtime != "" {
@@ -361,7 +363,7 @@ func getCapabilities() Capabilities {
caps = append(caps, "dwl") caps = append(caps, "dwl")
} }
if extWorkspaceManager != nil { if extWorkspaceAvailable.Load() {
caps = append(caps, "extworkspace") caps = append(caps, "extworkspace")
} }
@@ -411,7 +413,7 @@ func getServerInfo() ServerInfo {
caps = append(caps, "dwl") caps = append(caps, "dwl")
} }
if extWorkspaceManager != nil { if extWorkspaceAvailable.Load() {
caps = append(caps, "extworkspace") caps = append(caps, "extworkspace")
} }
@@ -810,12 +812,14 @@ func handleSubscribe(conn net.Conn, req models.Request) {
} }
if shouldSubscribe("extworkspace") { if shouldSubscribe("extworkspace") {
if extWorkspaceManager == nil { if extWorkspaceManager == nil && extWorkspaceAvailable.Load() {
if err := InitializeExtWorkspaceManager(); err != nil { extWorkspaceInitMutex.Lock()
log.Warnf("Failed to initialize ExtWorkspace manager for subscription: %v", err) if extWorkspaceManager == nil {
} else { if err := InitializeExtWorkspaceManager(); err != nil {
notifyCapabilityChange() log.Warnf("Failed to initialize ExtWorkspace manager for subscription: %v", err)
}
} }
extWorkspaceInitMutex.Unlock()
} }
if extWorkspaceManager != nil { if extWorkspaceManager != nil {
@@ -1141,11 +1145,18 @@ func Start(printDocs bool) error {
log.Info(" cups.cancelJob - Cancel job (params: printerName, jobID)") log.Info(" cups.cancelJob - Cancel job (params: printerName, jobID)")
log.Info(" cups.purgeJobs - Cancel all jobs (params: printerName)") log.Info(" cups.purgeJobs - Cancel all jobs (params: printerName)")
log.Info("DWL:") log.Info("DWL:")
log.Info(" dwl.getState - Get current dwl state (tags, windows, layouts)") 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.setTags - Set active tags (params: output, tagmask, toggleTagset)")
log.Info(" dwl.setClientTags - Set focused client tags (params: output, andTags, xorTags)") log.Info(" dwl.setClientTags - Set focused client tags (params: output, andTags, xorTags)")
log.Info(" dwl.setLayout - Set layout (params: output, index)") log.Info(" dwl.setLayout - Set layout (params: output, index)")
log.Info(" dwl.subscribe - Subscribe to dwl state changes (streaming)") 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("ExtWorkspace:") log.Info("ExtWorkspace:")
log.Info(" extworkspace.getState - Get current workspace state (groups, workspaces)") log.Info(" extworkspace.getState - Get current workspace state (groups, workspaces)")
log.Info(" extworkspace.activateWorkspace - Activate workspace (params: groupID, workspaceID)") log.Info(" extworkspace.activateWorkspace - Activate workspace (params: groupID, workspaceID)")
@@ -1241,6 +1252,14 @@ func Start(printDocs bool) error {
log.Debugf("DWL manager unavailable: %v", err) log.Debugf("DWL manager unavailable: %v", err)
} }
if extworkspace.CheckCapability() {
extWorkspaceAvailable.Store(true)
log.Info("ExtWorkspace capability detected and will be available on subscription")
} else {
log.Debug("ExtWorkspace capability not available")
extWorkspaceAvailable.Store(false)
}
if err := InitializeWlrOutputManager(); err != nil { if err := InitializeWlrOutputManager(); err != nil {
log.Debugf("WlrOutput manager unavailable: %v", err) log.Debugf("WlrOutput manager unavailable: %v", err)
} }

33
distro/nix/common.nix Normal file
View File

@@ -0,0 +1,33 @@
{
config,
lib,
pkgs,
dmsPkgs,
...
}: let
cfg = config.programs.dankMaterialShell;
in {
qmlPath = "${dmsPkgs.dankMaterialShell}/etc/xdg/quickshell/dms";
packages =
[
pkgs.material-symbols
pkgs.inter
pkgs.fira-code
pkgs.ddcutil
pkgs.libsForQt5.qt5ct
pkgs.kdePackages.qt6ct
dmsPkgs.dmsCli
]
++ lib.optional cfg.enableSystemMonitoring dmsPkgs.dgop
++ lib.optionals cfg.enableClipboard [pkgs.cliphist pkgs.wl-clipboard]
++ lib.optionals cfg.enableVPN [pkgs.glib pkgs.networkmanager]
++ lib.optional cfg.enableBrightnessControl pkgs.brightnessctl
++ lib.optional cfg.enableColorPicker pkgs.hyprpicker
++ lib.optional cfg.enableDynamicTheming pkgs.matugen
++ lib.optional cfg.enableAudioWavelength pkgs.cava
++ lib.optional cfg.enableCalendarEvents pkgs.khal
++ lib.optional cfg.enableSystemSound pkgs.kdePackages.qtmultimedia;
}

View File

@@ -1,170 +0,0 @@
{
config,
pkgs,
lib,
dmsPkgs,
...
}: let
cfg = config.programs.dankMaterialShell;
jsonFormat = pkgs.formats.json { };
in {
imports = [
(lib.mkRemovedOptionModule ["programs" "dankMaterialShell" "enableNightMode"] "Night mode is now always available.")
(lib.mkRenamedOptionModule ["programs" "dankMaterialShell" "enableSystemd"] ["programs" "dankMaterialShell" "systemd" "enable"])
];
options.programs.dankMaterialShell = with lib.types; {
enable = lib.mkEnableOption "DankMaterialShell";
systemd = {
enable = lib.mkEnableOption "DankMaterialShell systemd startup";
restartIfChanged = lib.mkOption {
type = bool;
default = true;
description = "Auto-restart dms.service when dankMaterialShell changes";
};
};
enableSystemMonitoring = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to use system monitoring widgets";
};
enableClipboard = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to use the clipboard widget";
};
enableVPN = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to use the VPN widget";
};
enableBrightnessControl = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to have brightness/backlight support";
};
enableColorPicker = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to have color picking support";
};
enableDynamicTheming = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to have dynamic theming support";
};
enableAudioWavelength = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to have audio waveleng support";
};
enableCalendarEvents = lib.mkOption {
type = bool;
default = true;
description = "Add calendar events support via khal";
};
enableSystemSound = lib.mkOption {
type = bool;
default = true;
description = "Add needed dependencies to have system sound support";
};
quickshell = {
package = lib.mkPackageOption pkgs "quickshell" {};
};
default = {
settings = lib.mkOption {
type = jsonFormat.type;
default = { };
description = "The default settings are only read if the settings.json file don't exist";
};
session = lib.mkOption {
type = jsonFormat.type;
default = { };
description = "The default session are only read if the session.json file don't exist";
};
};
plugins = lib.mkOption {
type = attrsOf (types.submodule ({ config, ... }: {
options = {
enable = lib.mkOption {
type = types.bool;
default = true;
description = "Whether to link this plugin";
};
src = lib.mkOption {
type = types.path;
description = "Source to link to DMS plugins directory";
};
};
}));
default = {};
description = "DMS Plugins to install";
};
};
config = lib.mkIf cfg.enable
{
programs.quickshell = {
enable = true;
package = cfg.quickshell.package;
configs.dms = "${dmsPkgs.dankMaterialShell}/etc/xdg/quickshell/dms";
};
systemd.user.services.dms = lib.mkIf cfg.systemd.enable {
Unit = {
Description = "DankMaterialShell";
PartOf = [ config.wayland.systemd.target ];
After = [ config.wayland.systemd.target ];
X-Restart-Triggers = lib.optional cfg.systemd.restartIfChanged config.programs.quickshell.configs.dms;
};
Service = {
ExecStart = lib.getExe dmsPkgs.dmsCli + " run --session";
Restart = "on-failure";
};
Install.WantedBy = [ config.wayland.systemd.target ];
};
xdg.stateFile."DankMaterialShell/default-session.json" = lib.mkIf (cfg.default.session != { }) {
source = jsonFormat.generate "default-session.json" cfg.default.session;
};
xdg.configFile = lib.mkMerge [
(lib.mapAttrs' (name: plugin: {
name = "DankMaterialShell/plugins/${name}";
value.source = plugin.src;
}) (lib.filterAttrs (n: v: v.enable) cfg.plugins))
{
"DankMaterialShell/default-settings.json" = lib.mkIf (cfg.default.settings != { }) {
source = jsonFormat.generate "default-settings.json" cfg.default.settings;
};
}
];
home.packages =
[
pkgs.material-symbols
pkgs.inter
pkgs.fira-code
pkgs.ddcutil
pkgs.libsForQt5.qt5ct
pkgs.kdePackages.qt6ct
dmsPkgs.dmsCli
]
++ lib.optional cfg.enableSystemMonitoring dmsPkgs.dgop
++ lib.optionals cfg.enableClipboard [pkgs.cliphist pkgs.wl-clipboard]
++ lib.optionals cfg.enableVPN [pkgs.glib pkgs.networkmanager]
++ lib.optional cfg.enableBrightnessControl pkgs.brightnessctl
++ lib.optional cfg.enableColorPicker pkgs.hyprpicker
++ lib.optional cfg.enableDynamicTheming pkgs.matugen
++ lib.optional cfg.enableAudioWavelength pkgs.cava
++ lib.optional cfg.enableCalendarEvents pkgs.khal
++ lib.optional cfg.enableSystemSound pkgs.kdePackages.qtmultimedia;
};
}

View File

@@ -11,7 +11,7 @@
user = config.services.greetd.settings.default_session.user; user = config.services.greetd.settings.default_session.user;
greeterScript = pkgs.writeShellScriptBin "dms-greeter" '' greeterScript = pkgs.writeShellScriptBin "dms-greeter" ''
export PATH=$PATH:${lib.makeBinPath [ cfg.quickshell.package config.programs.${cfg.compositor.name}.package ]} export PATH=$PATH:${lib.makeBinPath [cfg.quickshell.package config.programs.${cfg.compositor.name}.package]}
${lib.escapeShellArgs ([ ${lib.escapeShellArgs ([
"sh" "sh"
"${../../quickshell/Modules/Greetd/assets/dms-greeter}" "${../../quickshell/Modules/Greetd/assets/dms-greeter}"
@@ -28,11 +28,9 @@
])} ${lib.optionalString cfg.logs.save "> ${cfg.logs.path} 2>&1"} ])} ${lib.optionalString cfg.logs.save "> ${cfg.logs.path} 2>&1"}
''; '';
in { in {
imports = imports = let
let msg = "The option 'programs.dankMaterialShell.greeter.compositor.extraConfig' is deprecated. Please use 'programs.dankMaterialShell.greeter.compositor.customConfig' instead.";
msg = "The option 'programs.dankMaterialShell.greeter.compositor.extraConfig' is deprecated. Please use 'programs.dankMaterialShell.greeter.compositor.customConfig' instead."; in [(lib.mkRemovedOptionModule ["programs" "dankMaterialShell" "greeter" "compositor" "extraConfig"] msg)];
in
[ (lib.mkRemovedOptionModule [ "programs" "dankMaterialShell" "greeter" "compositor" "extraConfig" ] msg) ];
options.programs.dankMaterialShell.greeter = { options.programs.dankMaterialShell.greeter = {
enable = lib.mkEnableOption "DankMaterialShell greeter"; enable = lib.mkEnableOption "DankMaterialShell greeter";
@@ -77,7 +75,7 @@ in {
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
assertions = [ assertions = [
{ {
assertion = (config.users.users.${user} or { }) != { }; assertion = (config.users.users.${user} or {}) != {};
message = '' message = ''
dmsgreeter: user set for greetd default_session ${user} does not exist. Please create it before referencing it. dmsgreeter: user set for greetd default_session ${user} does not exist. Please create it before referencing it.
''; '';
@@ -95,8 +93,10 @@ in {
systemd.tmpfiles.settings."10-dmsgreeter" = { systemd.tmpfiles.settings."10-dmsgreeter" = {
"/var/lib/dmsgreeter".d = { "/var/lib/dmsgreeter".d = {
user = user; user = user;
group = if config.users.users.${user}.group != "" group =
then config.users.users.${user}.group else "greeter"; if config.users.users.${user}.group != ""
then config.users.users.${user}.group
else "greeter";
mode = "0755"; mode = "0755";
}; };
}; };
@@ -106,7 +106,8 @@ in {
if [ -f "${f}" ]; then if [ -f "${f}" ]; then
cp "${f}" . cp "${f}" .
fi fi
'') cfg.configFiles)} '')
cfg.configFiles)}
if [ -f session.json ]; then if [ -f session.json ]; then
if cp "$(${lib.getExe pkgs.jq} -r '.wallpaperPath' session.json)" wallpaper.jpg; then if cp "$(${lib.getExe pkgs.jq} -r '.wallpaperPath' session.json)" wallpaper.jpg; then

94
distro/nix/home.nix Normal file
View File

@@ -0,0 +1,94 @@
{
config,
pkgs,
lib,
dmsPkgs,
...
}: let
cfg = config.programs.dankMaterialShell;
jsonFormat = pkgs.formats.json {};
common = import ./common.nix {inherit config pkgs lib dmsPkgs;};
in {
imports = [
./options.nix
(lib.mkRemovedOptionModule ["programs" "dankMaterialShell" "enableNightMode"] "Night mode is now always available.")
(lib.mkRenamedOptionModule ["programs" "dankMaterialShell" "enableSystemd"] ["programs" "dankMaterialShell" "systemd" "enable"])
];
options.programs.dankMaterialShell = with lib.types; {
default = {
settings = lib.mkOption {
type = jsonFormat.type;
default = {};
description = "The default settings are only read if the settings.json file don't exist";
};
session = lib.mkOption {
type = jsonFormat.type;
default = {};
description = "The default session are only read if the session.json file don't exist";
};
};
plugins = lib.mkOption {
type = attrsOf (types.submodule ({config, ...}: {
options = {
enable = lib.mkOption {
type = types.bool;
default = true;
description = "Whether to link this plugin";
};
src = lib.mkOption {
type = types.path;
description = "Source to link to DMS plugins directory";
};
};
}));
default = {};
description = "DMS Plugins to install";
};
};
config = lib.mkIf cfg.enable
{
programs.quickshell = {
enable = true;
package = cfg.quickshell.package;
configs.dms = common.qmlPath;
};
systemd.user.services.dms = lib.mkIf cfg.systemd.enable {
Unit = {
Description = "DankMaterialShell";
PartOf = [config.wayland.systemd.target];
After = [config.wayland.systemd.target];
X-Restart-Triggers = lib.optional cfg.systemd.restartIfChanged common.qmlPath;
};
Service = {
ExecStart = lib.getExe dmsPkgs.dmsCli + " run --session";
Restart = "on-failure";
};
Install.WantedBy = [config.wayland.systemd.target];
};
xdg.stateFile."DankMaterialShell/default-session.json" = lib.mkIf (cfg.default.session != {}) {
source = jsonFormat.generate "default-session.json" cfg.default.session;
};
xdg.configFile = lib.mkMerge [
(lib.mapAttrs' (name: plugin: {
name = "DankMaterialShell/plugins/${name}";
value.source = plugin.src;
}) (lib.filterAttrs (n: v: v.enable) cfg.plugins))
{
"DankMaterialShell/default-settings.json" = lib.mkIf (cfg.default.settings != {}) {
source = jsonFormat.generate "default-settings.json" cfg.default.settings;
};
}
];
home.packages = common.packages;
};
}

36
distro/nix/nixos.nix Normal file
View File

@@ -0,0 +1,36 @@
{
config,
pkgs,
lib,
dmsPkgs,
...
}: let
cfg = config.programs.dankMaterialShell;
common = import ./common.nix {inherit config pkgs lib dmsPkgs;};
in {
imports = [
./options.nix
];
config = lib.mkIf cfg.enable
{
environment.etc."xdg/quickshell/dms".source = "${dmsPkgs.dankMaterialShell}/etc/xdg/quickshell/dms";
systemd.user.services.dms = lib.mkIf cfg.systemd.enable {
description = "DankMaterialShell";
path = [cfg.quickshell.package];
partOf = ["graphical-session.target"];
after = ["graphical-session.target"];
wantedBy = ["graphical-session.target"];
restartTriggers = lib.optional cfg.systemd.restartIfChanged common.qmlPath;
serviceConfig = {
ExecStart = lib.getExe dmsPkgs.dmsCli + " run --session";
Restart = "on-failure";
};
};
environment.systemPackages = [cfg.quickshell.package] ++ common.packages;
};
}

68
distro/nix/options.nix Normal file
View File

@@ -0,0 +1,68 @@
{
pkgs,
lib,
...
}: let
inherit (lib) types;
in {
options.programs.dankMaterialShell = {
enable = lib.mkEnableOption "DankMaterialShell";
systemd = {
enable = lib.mkEnableOption "DankMaterialShell systemd startup";
restartIfChanged = lib.mkOption {
type = types.bool;
default = true;
description = "Auto-restart dms.service when dankMaterialShell changes";
};
};
enableSystemMonitoring = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to use system monitoring widgets";
};
enableClipboard = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to use the clipboard widget";
};
enableVPN = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to use the VPN widget";
};
enableBrightnessControl = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to have brightness/backlight support";
};
enableColorPicker = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to have color picking support";
};
enableDynamicTheming = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to have dynamic theming support";
};
enableAudioWavelength = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to have audio wavelength support";
};
enableCalendarEvents = lib.mkOption {
type = types.bool;
default = true;
description = "Add calendar events support via khal";
};
enableSystemSound = lib.mkOption {
type = types.bool;
default = true;
description = "Add needed dependencies to have system sound support";
};
quickshell = {
package = lib.mkPackageOption pkgs "quickshell" {};
};
};
}

View File

@@ -24,6 +24,11 @@
dgop = dgop.packages.${pkgs.stdenv.hostPlatform.system}.dgop; dgop = dgop.packages.${pkgs.stdenv.hostPlatform.system}.dgop;
dankMaterialShell = self.packages.${pkgs.stdenv.hostPlatform.system}.dankMaterialShell; dankMaterialShell = self.packages.${pkgs.stdenv.hostPlatform.system}.dankMaterialShell;
}; };
mkModuleWithDmsPkgs = path: args @ {pkgs, ...}: {
imports = [
(import path (args // {dmsPkgs = buildDmsPkgs pkgs;}))
];
};
in { in {
formatter = forEachSystem (_: pkgs: pkgs.alejandra); formatter = forEachSystem (_: pkgs: pkgs.alejandra);
@@ -81,20 +86,12 @@
} }
); );
homeModules.dankMaterialShell.default = {pkgs, ...}: let homeModules.dankMaterialShell.default = mkModuleWithDmsPkgs ./distro/nix/home.nix;
dmsPkgs = buildDmsPkgs pkgs;
in {
imports = [./distro/nix/default.nix];
_module.args.dmsPkgs = dmsPkgs;
};
homeModules.dankMaterialShell.niri = import ./distro/nix/niri.nix; homeModules.dankMaterialShell.niri = import ./distro/nix/niri.nix;
nixosModules.greeter = {pkgs, ...}: let nixosModules.dankMaterialShell = mkModuleWithDmsPkgs ./distro/nix/nixos.nix;
dmsPkgs = buildDmsPkgs pkgs;
in { nixosModules.greeter = mkModuleWithDmsPkgs ./distro/nix/greeter.nix;
imports = [./distro/nix/greeter.nix];
_module.args.dmsPkgs = dmsPkgs;
};
}; };
} }

View File

@@ -422,29 +422,59 @@ Singleton {
} }
function setMonitorWallpaper(screenName, path) { function setMonitorWallpaper(screenName, path) {
var newMonitorWallpapers = Object.assign({}, monitorWallpapers) var screen = null
if (path && path !== "") { var screens = Quickshell.screens
newMonitorWallpapers[screenName] = path for (var i = 0; i < screens.length; i++) {
} else { if (screens[i].name === screenName) {
delete newMonitorWallpapers[screenName] screen = screens[i]
break
}
} }
if (!screen) {
console.warn("SessionData: Screen not found:", screenName)
return
}
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name
var newMonitorWallpapers = {}
for (var key in monitorWallpapers) {
var isThisScreen = key === screen.name || (screen.model && key === screen.model)
if (!isThisScreen) {
newMonitorWallpapers[key] = monitorWallpapers[key]
}
}
if (path && path !== "") {
newMonitorWallpapers[identifier] = path
}
monitorWallpapers = newMonitorWallpapers monitorWallpapers = newMonitorWallpapers
if (perModeWallpaper) { if (perModeWallpaper) {
if (isLightMode) { if (isLightMode) {
var newLight = Object.assign({}, monitorWallpapersLight) var newLight = {}
for (var key in monitorWallpapersLight) {
var isThisScreen = key === screen.name || (screen.model && key === screen.model)
if (!isThisScreen) {
newLight[key] = monitorWallpapersLight[key]
}
}
if (path && path !== "") { if (path && path !== "") {
newLight[screenName] = path newLight[identifier] = path
} else {
delete newLight[screenName]
} }
monitorWallpapersLight = newLight monitorWallpapersLight = newLight
} else { } else {
var newDark = Object.assign({}, monitorWallpapersDark) var newDark = {}
for (var key in monitorWallpapersDark) {
var isThisScreen = key === screen.name || (screen.model && key === screen.model)
if (!isThisScreen) {
newDark[key] = monitorWallpapersDark[key]
}
}
if (path && path !== "") { if (path && path !== "") {
newDark[screenName] = path newDark[identifier] = path
} else {
delete newDark[screenName]
} }
monitorWallpapersDark = newDark monitorWallpapersDark = newDark
} }
@@ -489,61 +519,153 @@ Singleton {
} }
function setMonitorCyclingEnabled(screenName, enabled) { function setMonitorCyclingEnabled(screenName, enabled) {
var newSettings = Object.assign({}, monitorCyclingSettings) var screen = null
if (!newSettings[screenName]) { var screens = Quickshell.screens
newSettings[screenName] = { for (var i = 0; i < screens.length; i++) {
if (screens[i].name === screenName) {
screen = screens[i]
break
}
}
if (!screen) {
console.warn("SessionData: Screen not found:", screenName)
return
}
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name
var newSettings = {}
for (var key in monitorCyclingSettings) {
var isThisScreen = key === screen.name || (screen.model && key === screen.model)
if (!isThisScreen) {
newSettings[key] = monitorCyclingSettings[key]
}
}
if (!newSettings[identifier]) {
newSettings[identifier] = {
"enabled": false, "enabled": false,
"mode": "interval", "mode": "interval",
"interval": 300, "interval": 300,
"time": "06:00" "time": "06:00"
} }
} }
newSettings[screenName].enabled = enabled newSettings[identifier].enabled = enabled
monitorCyclingSettings = newSettings monitorCyclingSettings = newSettings
saveSettings() saveSettings()
} }
function setMonitorCyclingMode(screenName, mode) { function setMonitorCyclingMode(screenName, mode) {
var newSettings = Object.assign({}, monitorCyclingSettings) var screen = null
if (!newSettings[screenName]) { var screens = Quickshell.screens
newSettings[screenName] = { for (var i = 0; i < screens.length; i++) {
if (screens[i].name === screenName) {
screen = screens[i]
break
}
}
if (!screen) {
console.warn("SessionData: Screen not found:", screenName)
return
}
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name
var newSettings = {}
for (var key in monitorCyclingSettings) {
var isThisScreen = key === screen.name || (screen.model && key === screen.model)
if (!isThisScreen) {
newSettings[key] = monitorCyclingSettings[key]
}
}
if (!newSettings[identifier]) {
newSettings[identifier] = {
"enabled": false, "enabled": false,
"mode": "interval", "mode": "interval",
"interval": 300, "interval": 300,
"time": "06:00" "time": "06:00"
} }
} }
newSettings[screenName].mode = mode newSettings[identifier].mode = mode
monitorCyclingSettings = newSettings monitorCyclingSettings = newSettings
saveSettings() saveSettings()
} }
function setMonitorCyclingInterval(screenName, interval) { function setMonitorCyclingInterval(screenName, interval) {
var newSettings = Object.assign({}, monitorCyclingSettings) var screen = null
if (!newSettings[screenName]) { var screens = Quickshell.screens
newSettings[screenName] = { for (var i = 0; i < screens.length; i++) {
if (screens[i].name === screenName) {
screen = screens[i]
break
}
}
if (!screen) {
console.warn("SessionData: Screen not found:", screenName)
return
}
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name
var newSettings = {}
for (var key in monitorCyclingSettings) {
var isThisScreen = key === screen.name || (screen.model && key === screen.model)
if (!isThisScreen) {
newSettings[key] = monitorCyclingSettings[key]
}
}
if (!newSettings[identifier]) {
newSettings[identifier] = {
"enabled": false, "enabled": false,
"mode": "interval", "mode": "interval",
"interval": 300, "interval": 300,
"time": "06:00" "time": "06:00"
} }
} }
newSettings[screenName].interval = interval newSettings[identifier].interval = interval
monitorCyclingSettings = newSettings monitorCyclingSettings = newSettings
saveSettings() saveSettings()
} }
function setMonitorCyclingTime(screenName, time) { function setMonitorCyclingTime(screenName, time) {
var newSettings = Object.assign({}, monitorCyclingSettings) var screen = null
if (!newSettings[screenName]) { var screens = Quickshell.screens
newSettings[screenName] = { for (var i = 0; i < screens.length; i++) {
if (screens[i].name === screenName) {
screen = screens[i]
break
}
}
if (!screen) {
console.warn("SessionData: Screen not found:", screenName)
return
}
var identifier = typeof SettingsData !== "undefined" ? SettingsData.getScreenDisplayName(screen) : screen.name
var newSettings = {}
for (var key in monitorCyclingSettings) {
var isThisScreen = key === screen.name || (screen.model && key === screen.model)
if (!isThisScreen) {
newSettings[key] = monitorCyclingSettings[key]
}
}
if (!newSettings[identifier]) {
newSettings[identifier] = {
"enabled": false, "enabled": false,
"mode": "interval", "mode": "interval",
"interval": 300, "interval": 300,
"time": "06:00" "time": "06:00"
} }
} }
newSettings[screenName].time = time newSettings[identifier].time = time
monitorCyclingSettings = newSettings monitorCyclingSettings = newSettings
saveSettings() saveSettings()
} }
@@ -770,11 +892,57 @@ Singleton {
if (!perMonitorWallpaper) { if (!perMonitorWallpaper) {
return wallpaperPath return wallpaperPath
} }
return monitorWallpapers[screenName] || wallpaperPath
var screen = null
var screens = Quickshell.screens
for (var i = 0; i < screens.length; i++) {
if (screens[i].name === screenName) {
screen = screens[i]
break
}
}
if (!screen) {
return monitorWallpapers[screenName] || wallpaperPath
}
if (monitorWallpapers[screen.name]) {
return monitorWallpapers[screen.name]
}
if (screen.model && monitorWallpapers[screen.model]) {
return monitorWallpapers[screen.model]
}
return wallpaperPath
} }
function getMonitorCyclingSettings(screenName) { function getMonitorCyclingSettings(screenName) {
return monitorCyclingSettings[screenName] || { var screen = null
var screens = Quickshell.screens
for (var i = 0; i < screens.length; i++) {
if (screens[i].name === screenName) {
screen = screens[i]
break
}
}
if (!screen) {
return monitorCyclingSettings[screenName] || {
"enabled": false,
"mode": "interval",
"interval": 300,
"time": "06:00"
}
}
if (monitorCyclingSettings[screen.name]) {
return monitorCyclingSettings[screen.name]
}
if (screen.model && monitorCyclingSettings[screen.model]) {
return monitorCyclingSettings[screen.model]
}
return {
"enabled": false, "enabled": false,
"mode": "interval", "mode": "interval",
"interval": 300, "interval": 300,

View File

@@ -23,7 +23,9 @@ Singleton {
Top, Top,
Bottom, Bottom,
Left, Left,
Right Right,
TopCenter,
BottomCenter
} }
enum AnimationSpeed { enum AnimationSpeed {
@@ -305,6 +307,7 @@ Singleton {
property int notificationPopupPosition: SettingsData.Position.Top property int notificationPopupPosition: SettingsData.Position.Top
property bool osdAlwaysShowValue: false property bool osdAlwaysShowValue: false
property int osdPosition: SettingsData.Position.BottomCenter
property bool osdVolumeEnabled: true property bool osdVolumeEnabled: true
property bool osdBrightnessEnabled: true property bool osdBrightnessEnabled: true
property bool osdIdleInhibitorEnabled: true property bool osdIdleInhibitorEnabled: true
@@ -327,6 +330,7 @@ Singleton {
property string updaterCustomCommand: "" property string updaterCustomCommand: ""
property string updaterTerminalAdditionalParams: "" property string updaterTerminalAdditionalParams: ""
property string displayNameMode: "system"
property var screenPreferences: ({}) property var screenPreferences: ({})
property var showOnLastDisplay: ({}) property var showOnLastDisplay: ({})
@@ -637,12 +641,35 @@ rm -rf '${home}'/.cache/icon-cache '${home}'/.cache/thumbnails 2>/dev/null || tr
return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 } return { "x": 0, "y": 0, "width": 0, "height": 0, "wingSize": 0 }
} }
function getScreenDisplayName(screen) {
if (!screen) return ""
if (displayNameMode === "model" && screen.model) {
return screen.model
}
return screen.name
}
function isScreenInPreferences(screen, prefs) {
if (!screen) return false
return prefs.some(pref => {
if (typeof pref === "string") {
return pref === "all" || pref === screen.name || pref === screen.model
}
if (displayNameMode === "model") {
return pref.model && screen.model && pref.model === screen.model
}
return pref.name === screen.name
})
}
function getFilteredScreens(componentId) { function getFilteredScreens(componentId) {
var prefs = screenPreferences && screenPreferences[componentId] || ["all"] var prefs = screenPreferences && screenPreferences[componentId] || ["all"]
if (prefs.includes("all")) { if (prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all")) {
return Quickshell.screens return Quickshell.screens
} }
var filtered = Quickshell.screens.filter(screen => prefs.includes(screen.name)) var filtered = Quickshell.screens.filter(screen => isScreenInPreferences(screen, prefs))
if (filtered.length === 0 && showOnLastDisplay && showOnLastDisplay[componentId] && Quickshell.screens.length === 1) { if (filtered.length === 0 && showOnLastDisplay && showOnLastDisplay[componentId] && Quickshell.screens.length === 1) {
return Quickshell.screens return Quickshell.screens
} }

View File

@@ -421,15 +421,44 @@ Singleton {
} }
return typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12 return typeof SettingsData !== "undefined" ? SettingsData.cornerRadius : 12
} }
property string fontFamily: {
if (typeof SessionData !== "undefined" && SessionData.isGreeterMode && typeof GreetdSettings !== "undefined") {
return GreetdSettings.fontFamily
}
return typeof SettingsData !== "undefined" ? SettingsData.fontFamily : "Inter Variable"
}
property string monoFontFamily: {
if (typeof SessionData !== "undefined" && SessionData.isGreeterMode && typeof GreetdSettings !== "undefined") {
return GreetdSettings.monoFontFamily
}
return typeof SettingsData !== "undefined" ? SettingsData.monoFontFamily : "Fira Code"
}
property int fontWeight: {
if (typeof SessionData !== "undefined" && SessionData.isGreeterMode && typeof GreetdSettings !== "undefined") {
return GreetdSettings.fontWeight
}
return typeof SettingsData !== "undefined" ? SettingsData.fontWeight : Font.Normal
}
property real fontScale: {
if (typeof SessionData !== "undefined" && SessionData.isGreeterMode && typeof GreetdSettings !== "undefined") {
return GreetdSettings.fontScale
}
return typeof SettingsData !== "undefined" ? SettingsData.fontScale : 1.0
}
property real spacingXS: 4 property real spacingXS: 4
property real spacingS: 8 property real spacingS: 8
property real spacingM: 12 property real spacingM: 12
property real spacingL: 16 property real spacingL: 16
property real spacingXL: 24 property real spacingXL: 24
property real fontSizeSmall: (typeof SettingsData !== "undefined" ? SettingsData.fontScale : 1.0) * 12 property real fontSizeSmall: Math.round(fontScale * 12)
property real fontSizeMedium: (typeof SettingsData !== "undefined" ? SettingsData.fontScale : 1.0) * 14 property real fontSizeMedium: Math.round(fontScale * 14)
property real fontSizeLarge: (typeof SettingsData !== "undefined" ? SettingsData.fontScale : 1.0) * 16 property real fontSizeLarge: Math.round(fontScale * 16)
property real fontSizeXLarge: (typeof SettingsData !== "undefined" ? SettingsData.fontScale : 1.0) * 20 property real fontSizeXLarge: Math.round(fontScale * 20)
property real barHeight: 48 property real barHeight: 48
property real iconSize: 24 property real iconSize: 24
property real iconSizeSmall: 16 property real iconSizeSmall: 16
@@ -650,10 +679,10 @@ Singleton {
const scale = barThickness / 48 const scale = barThickness / 48
const dankBarScale = (typeof SettingsData !== "undefined" ? SettingsData.dankBarFontScale : 1.0) const dankBarScale = (typeof SettingsData !== "undefined" ? SettingsData.dankBarFontScale : 1.0)
if (scale <= 0.75) if (scale <= 0.75)
return fontSizeSmall * 0.9 * dankBarScale return Math.round(fontSizeSmall * 0.9 * dankBarScale)
if (scale >= 1.25) if (scale >= 1.25)
return fontSizeMedium * dankBarScale return Math.round(fontSizeMedium * dankBarScale)
return fontSizeSmall * dankBarScale return Math.round(fontSizeSmall * dankBarScale)
} }
function getBatteryIcon(level, isCharging, batteryAvailable) { function getBatteryIcon(level, isCharging, batteryAvailable) {

View File

@@ -215,6 +215,7 @@ var SPEC = {
notificationPopupPosition: { def: 0 }, notificationPopupPosition: { def: 0 },
osdAlwaysShowValue: { def: false }, osdAlwaysShowValue: { def: false },
osdPosition: { def: 5 },
osdVolumeEnabled: { def: true }, osdVolumeEnabled: { def: true },
osdBrightnessEnabled: { def: true }, osdBrightnessEnabled: { def: true },
osdIdleInhibitorEnabled: { def: true }, osdIdleInhibitorEnabled: { def: true },
@@ -237,6 +238,7 @@ var SPEC = {
updaterCustomCommand: { def: "" }, updaterCustomCommand: { def: "" },
updaterTerminalAdditionalParams: { def: "" }, updaterTerminalAdditionalParams: { def: "" },
displayNameMode: { def: "system" },
screenPreferences: { def: {} }, screenPreferences: { def: {} },
showOnLastDisplay: { def: {} } showOnLastDisplay: { def: {} }
}; };

View File

@@ -297,48 +297,6 @@ Item {
} }
} }
LazyLoader {
id: powerMenuLoader
active: false
PowerMenu {
id: powerMenu
onPowerActionRequested: (action, title, message) => {
if (SettingsData.powerActionConfirm) {
powerConfirmModalLoader.active = true
if (powerConfirmModalLoader.item) {
powerConfirmModalLoader.item.confirmButtonColor = action === "poweroff" ? Theme.error : action === "reboot" ? Theme.warning : Theme.primary
powerConfirmModalLoader.item.show(title, message, () => actionApply(action), function () {})
}
} else {
actionApply(action)
}
}
function actionApply(action) {
switch (action) {
case "logout":
SessionService.logout()
break
case "suspend":
SessionService.suspend()
break
case "hibernate":
SessionService.hibernate()
break
case "reboot":
SessionService.reboot()
break
case "poweroff":
SessionService.poweroff()
break
}
}
}
}
LazyLoader { LazyLoader {
id: powerConfirmModalLoader id: powerConfirmModalLoader

View File

@@ -6,6 +6,8 @@ import qs.Widgets
DankModal { DankModal {
id: root id: root
layerNamespace: "dms:confirm-modal"
property string confirmTitle: "" property string confirmTitle: ""
property string confirmMessage: "" property string confirmMessage: ""
property string confirmButtonText: "Confirm" property string confirmButtonText: "Confirm"

View File

@@ -60,7 +60,7 @@ DankModal {
} }
function copyColorToClipboard(colorValue) { function copyColorToClipboard(colorValue) {
Quickshell.execDetached(["sh", "-c", `echo "${colorValue}" | wl-copy`]) Quickshell.execDetached(["sh", "-c", `echo -n "${colorValue}" | wl-copy`])
ToastService.showInfo(`Color ${colorValue} copied`) ToastService.showInfo(`Color ${colorValue} copied`)
SessionData.addRecentColor(currentColor) SessionData.addRecentColor(currentColor)
} }
@@ -571,7 +571,7 @@ DankModal {
} else { } else {
rgbString = `rgb(${r}, ${g}, ${b})` rgbString = `rgb(${r}, ${g}, ${b})`
} }
Quickshell.execDetached(["sh", "-c", `echo "${rgbString}" | wl-copy`]) Quickshell.execDetached(["sh", "-c", `echo -n "${rgbString}" | wl-copy`])
ToastService.showInfo(`${rgbString} copied`) ToastService.showInfo(`${rgbString} copied`)
} }
} }
@@ -635,7 +635,7 @@ DankModal {
} else { } else {
hsvString = `${h}, ${s}, ${v}` hsvString = `${h}, ${s}, ${v}`
} }
Quickshell.execDetached(["sh", "-c", `echo "${hsvString}" | wl-copy`]) Quickshell.execDetached(["sh", "-c", `echo -n "${hsvString}" | wl-copy`])
ToastService.showInfo(`HSV ${hsvString} copied`) ToastService.showInfo(`HSV ${hsvString} copied`)
} }
} }

View File

@@ -72,6 +72,13 @@ DankPopout {
screen: triggerScreen screen: triggerScreen
shouldBeVisible: false shouldBeVisible: false
WlrLayershell.keyboardFocus: {
if (!shouldBeVisible) return WlrKeyboardFocus.None
if (powerMenuOpen) return WlrKeyboardFocus.None
if (CompositorService.isHyprland) return WlrKeyboardFocus.OnDemand
return WlrKeyboardFocus.Exclusive
}
onBackgroundClicked: close() onBackgroundClicked: close()
onShouldBeVisibleChanged: { onShouldBeVisibleChanged: {

View File

@@ -1,316 +0,0 @@
import QtQuick
import QtQuick.Controls
import Quickshell
import Quickshell.Io
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Widgets
PanelWindow {
id: root
readonly property string powerOptionsText: I18n.tr("Power Options")
readonly property string logOutText: I18n.tr("Log Out")
readonly property string suspendText: I18n.tr("Suspend")
readonly property string rebootText: I18n.tr("Reboot")
readonly property string powerOffText: I18n.tr("Power Off")
property bool powerMenuVisible: false
signal powerActionRequested(string action, string title, string message)
visible: powerMenuVisible
implicitWidth: 400
implicitHeight: 320
WlrLayershell.layer: WlrLayershell.Overlay
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
color: "transparent"
anchors {
top: true
left: true
right: true
bottom: true
}
MouseArea {
anchors.fill: parent
onClicked: {
powerMenuVisible = false
}
}
Rectangle {
width: Math.min(320, parent.width - Theme.spacingL * 2)
height: 320 // Fixed height to prevent cropping
x: Math.max(Theme.spacingL, parent.width - width - Theme.spacingL)
y: Theme.barHeight + Theme.spacingXS
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g,
Theme.outline.b, 0.08)
border.width: 0
opacity: powerMenuVisible ? 1 : 0
scale: powerMenuVisible ? 1 : 0.85
MouseArea {
anchors.fill: parent
onClicked: {
}
}
Column {
anchors.fill: parent
anchors.margins: Theme.spacingL
spacing: Theme.spacingM
Row {
width: parent.width
StyledText {
text: root.powerOptionsText
font.pixelSize: Theme.fontSizeLarge
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
Item {
width: parent.width - 150
height: 1
}
DankActionButton {
iconName: "close"
iconSize: Theme.iconSize - 4
iconColor: Theme.surfaceText
onClicked: {
powerMenuVisible = false
}
}
}
Column {
width: parent.width
spacing: Theme.spacingS
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: logoutArea.containsMouse ? Qt.rgba(Theme.primary.r,
Theme.primary.g,
Theme.primary.b,
0.08) : Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.08)
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "logout"
size: Theme.iconSize
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.logOutText
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: logoutArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
powerMenuVisible = false
root.powerActionRequested(
"logout", "Log Out",
"Are you sure you want to log out?")
}
}
}
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: suspendArea.containsMouse ? Qt.rgba(Theme.primary.r,
Theme.primary.g,
Theme.primary.b,
0.08) : Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.08)
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "bedtime"
size: Theme.iconSize
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.suspendText
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: suspendArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
powerMenuVisible = false
root.powerActionRequested(
"suspend", "Suspend",
"Are you sure you want to suspend the system?")
}
}
}
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: rebootArea.containsMouse ? Qt.rgba(Theme.warning.r,
Theme.warning.g,
Theme.warning.b,
0.08) : Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.08)
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "restart_alt"
size: Theme.iconSize
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.rebootText
font.pixelSize: Theme.fontSizeMedium
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: rebootArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
powerMenuVisible = false
root.powerActionRequested(
"reboot", "Reboot",
"Are you sure you want to reboot the system?")
}
}
}
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: powerOffArea.containsMouse ? Qt.rgba(Theme.error.r,
Theme.error.g,
Theme.error.b,
0.08) : Qt.rgba(
Theme.surfaceVariant.r,
Theme.surfaceVariant.g,
Theme.surfaceVariant.b,
0.08)
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "power_settings_new"
size: Theme.iconSize
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: root.powerOffText
font.pixelSize: Theme.fontSizeMedium
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: powerOffArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
powerMenuVisible = false
root.powerActionRequested(
"poweroff", "Power Off",
"Are you sure you want to power off the system?")
}
}
}
}
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
}

View File

@@ -19,7 +19,7 @@ BasePill {
id: clockColumn id: clockColumn
visible: root.isVerticalOrientation visible: root.isVerticalOrientation
anchors.centerIn: parent anchors.centerIn: parent
spacing: -2 spacing: 0
Row { Row {
spacing: 0 spacing: 0
@@ -37,7 +37,6 @@ BasePill {
} }
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText color: Theme.surfaceText
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -54,7 +53,6 @@ BasePill {
} }
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText color: Theme.surfaceText
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -68,7 +66,6 @@ BasePill {
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0) text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(0)
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText color: Theme.surfaceText
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -77,7 +74,6 @@ BasePill {
text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1) text: String(systemClock?.date?.getMinutes()).padStart(2, '0').charAt(1)
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText color: Theme.surfaceText
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -92,7 +88,6 @@ BasePill {
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(0) text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(0)
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText color: Theme.surfaceText
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -101,19 +96,18 @@ BasePill {
text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(1) text: String(systemClock?.date?.getSeconds()).padStart(2, '0').charAt(1)
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.surfaceText color: Theme.surfaceText
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
} }
Item { Item {
width: 12 width: parent.width
height: Theme.spacingM height: Theme.spacingM
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
Rectangle { Rectangle {
width: 12 width: parent.width * 0.6
height: 1 height: 1
color: Theme.outlineButton color: Theme.outlineButton
anchors.centerIn: parent anchors.centerIn: parent
@@ -134,7 +128,6 @@ BasePill {
} }
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.primary color: Theme.primary
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -149,7 +142,6 @@ BasePill {
} }
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.primary color: Theme.primary
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -169,7 +161,6 @@ BasePill {
} }
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.primary color: Theme.primary
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }
@@ -184,7 +175,6 @@ BasePill {
} }
font.pixelSize: Theme.barTextSize(root.barThickness) font.pixelSize: Theme.barTextSize(root.barThickness)
color: Theme.primary color: Theme.primary
width: 9
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignBottom verticalAlignment: Text.AlignBottom
} }

View File

@@ -13,7 +13,14 @@ BasePill {
id: root id: root
property bool compactMode: SettingsData.keyboardLayoutNameCompactMode property bool compactMode: SettingsData.keyboardLayoutNameCompactMode
property string currentLayout: CompositorService.isNiri ? NiriService.getCurrentKeyboardLayoutName() : "" property string currentLayout: {
if (CompositorService.isNiri) {
return NiriService.getCurrentKeyboardLayoutName()
} else if (CompositorService.isDwl) {
return DwlService.currentKeyboardLayout
}
return ""
}
property string hyprlandKeyboard: "" property string hyprlandKeyboard: ""
content: Component { content: Component {
@@ -79,6 +86,8 @@ BasePill {
root.hyprlandKeyboard, root.hyprlandKeyboard,
"next" "next"
]) ])
} else if (CompositorService.isDwl) {
Quickshell.execDetached(["mmsg", "-d", "switch_keyboard_layout"])
} }
} }
} }

View File

@@ -149,13 +149,13 @@ Item {
if (currentIndex === -1) { if (currentIndex === -1) {
nextIndex = 0 nextIndex = 0
} else { } else {
nextIndex = (currentIndex + 1) % windows.length nextIndex = Math.min(currentIndex + 1, windows.length - 1)
} }
} else { } else {
if (currentIndex === -1) { if (currentIndex === -1) {
nextIndex = windows.length - 1 nextIndex = windows.length - 1
} else { } else {
nextIndex = (currentIndex - 1 + windows.length) % windows.length nextIndex = Math.max(currentIndex - 1, 0)
} }
} }
@@ -181,13 +181,13 @@ Item {
if (currentIndex === -1) { if (currentIndex === -1) {
nextIndex = 0 nextIndex = 0
} else { } else {
nextIndex = (currentIndex + 1) % windows.length nextIndex = Math.min(currentIndex + 1, windows.length - 1)
} }
} else { } else {
if (currentIndex === -1) { if (currentIndex === -1) {
nextIndex = windows.length - 1 nextIndex = windows.length - 1
} else { } else {
nextIndex = (currentIndex - 1 + windows.length) % windows.length nextIndex = Math.max(currentIndex - 1, 0)
} }
} }

View File

@@ -316,12 +316,19 @@ Item {
return [{"id": "1", "name": "1", "active": false}] return [{"id": "1", "name": "1", "active": false}]
} }
const visible = group.workspaces.filter(ws => !ws.hidden).sort((a, b) => { let visible = group.workspaces.filter(ws => !ws.hidden)
const coordsA = a.coordinates || [0, 0]
const coordsB = b.coordinates || [0, 0] const hasValidCoordinates = visible.some(ws => ws.coordinates && ws.coordinates.length > 0)
if (coordsA[0] !== coordsB[0]) return coordsA[0] - coordsB[0] if (hasValidCoordinates) {
return coordsA[1] - coordsB[1] visible = visible.sort((a, b) => {
}).map(ws => ({ const coordsA = a.coordinates || [0, 0]
const coordsB = b.coordinates || [0, 0]
if (coordsA[0] !== coordsB[0]) return coordsA[0] - coordsB[0]
return coordsA[1] - coordsB[1]
})
}
visible = visible.map(ws => ({
id: ws.id, id: ws.id,
name: ws.name, name: ws.name,
coordinates: ws.coordinates, coordinates: ws.coordinates,
@@ -350,7 +357,7 @@ Item {
function getRealWorkspaces() { function getRealWorkspaces() {
return root.workspaceList.filter(ws => { return root.workspaceList.filter(ws => {
if (useExtWorkspace) return ws && ws.id !== "" && !ws.hidden if (useExtWorkspace) return ws && (ws.id !== "" || ws.name !== "") && !ws.hidden
if (CompositorService.isHyprland) return ws && ws.id !== -1 if (CompositorService.isHyprland) return ws && ws.id !== -1
if (CompositorService.isDwl) return ws && ws.tag !== -1 if (CompositorService.isDwl) return ws && ws.tag !== -1
if (CompositorService.isSway) return ws && ws.num !== -1 if (CompositorService.isSway) return ws && ws.num !== -1
@@ -438,9 +445,13 @@ Item {
} }
} }
width: isVertical ? barThickness : visualWidth readonly property bool hasNativeWorkspaceSupport: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway
height: isVertical ? visualHeight : barThickness readonly property bool hasWorkspaces: getRealWorkspaces().length > 0
visible: CompositorService.isNiri || CompositorService.isHyprland || CompositorService.isDwl || CompositorService.isSway || useExtWorkspace readonly property bool shouldShow: hasNativeWorkspaceSupport || (useExtWorkspace && hasWorkspaces)
width: shouldShow ? (isVertical ? barThickness : visualWidth) : 0
height: shouldShow ? (isVertical ? visualHeight : barThickness) : 0
visible: shouldShow
Rectangle { Rectangle {
id: visualBackground id: visualBackground
@@ -889,7 +900,7 @@ Item {
if (isPlaceholder) return index + 1 if (isPlaceholder) return index + 1
if (root.useExtWorkspace) return modelData?.name || modelData?.id || "" if (root.useExtWorkspace) return index + 1
if (CompositorService.isHyprland) return modelData?.id || "" if (CompositorService.isHyprland) return modelData?.id || ""
if (CompositorService.isDwl) return (modelData?.tag !== undefined) ? (modelData.tag + 1) : "" if (CompositorService.isDwl) return (modelData?.tag !== undefined) ? (modelData.tag + 1) : ""
if (CompositorService.isSway) return modelData?.num || "" if (CompositorService.isSway) return modelData?.num || ""

View File

@@ -11,25 +11,123 @@ Rectangle {
property bool isVisible: false property bool isVisible: false
property bool showLogout: true property bool showLogout: true
property int selectedIndex: 0 property int selectedIndex: 0
property int optionCount: { property int selectedRow: 0
let count = 0 property int selectedCol: 0
if (showLogout) count++ property var visibleActions: []
count++ property int gridColumns: 3
if (SessionService.hibernateSupported) count++ property int gridRows: 2
count += 2 property bool useGridLayout: false
return count
}
signal closed() signal closed()
function show() { function updateVisibleActions() {
isVisible = true const allActions = (typeof SettingsData !== "undefined" && SettingsData.powerMenuActions)
selectedIndex = 0 ? SettingsData.powerMenuActions
Qt.callLater(() => { : ["logout", "suspend", "hibernate", "reboot", "poweroff"]
if (powerMenuFocusScope && powerMenuFocusScope.forceActiveFocus) { const hibernateSupported = (typeof SessionService !== "undefined" && SessionService.hibernateSupported) || false
powerMenuFocusScope.forceActiveFocus() let filtered = allActions.filter(action => {
} if (action === "hibernate" && !hibernateSupported) return false
if (action === "lock") return false
if (action === "restart") return false
if (action === "logout" && !showLogout) return false
return true
}) })
visibleActions = filtered
useGridLayout = (typeof SettingsData !== "undefined" && SettingsData.powerMenuGridLayout !== undefined)
? SettingsData.powerMenuGridLayout
: false
if (!useGridLayout) return
const count = visibleActions.length
if (count === 0) {
gridColumns = 1
gridRows = 1
return
}
if (count <= 3) {
gridColumns = 1
gridRows = count
return
}
if (count === 4) {
gridColumns = 2
gridRows = 2
return
}
gridColumns = 3
gridRows = Math.ceil(count / 3)
}
function getDefaultActionIndex() {
const defaultAction = (typeof SettingsData !== "undefined" && SettingsData.powerMenuDefaultAction)
? SettingsData.powerMenuDefaultAction
: "suspend"
const index = visibleActions.indexOf(defaultAction)
return index >= 0 ? index : 0
}
function getActionAtIndex(index) {
if (index < 0 || index >= visibleActions.length) return ""
return visibleActions[index]
}
function getActionData(action) {
switch (action) {
case "reboot":
return { "icon": "restart_alt", "label": I18n.tr("Reboot"), "key": "R" }
case "logout":
return { "icon": "logout", "label": I18n.tr("Log Out"), "key": "X" }
case "poweroff":
return { "icon": "power_settings_new", "label": I18n.tr("Power Off"), "key": "P" }
case "suspend":
return { "icon": "bedtime", "label": I18n.tr("Suspend"), "key": "S" }
case "hibernate":
return { "icon": "ac_unit", "label": I18n.tr("Hibernate"), "key": "H" }
default:
return { "icon": "help", "label": action, "key": "?" }
}
}
function selectOption(action) {
if (!action) return
if (typeof SessionService === "undefined") return
hide()
switch (action) {
case "logout":
SessionService.logout()
break
case "suspend":
SessionService.suspend()
break
case "hibernate":
SessionService.hibernate()
break
case "reboot":
SessionService.reboot()
break
case "poweroff":
SessionService.poweroff()
break
}
}
function show() {
updateVisibleActions()
const defaultIndex = getDefaultActionIndex()
if (useGridLayout) {
selectedRow = Math.floor(defaultIndex / gridColumns)
selectedCol = defaultIndex % gridColumns
selectedIndex = defaultIndex
} else {
selectedIndex = defaultIndex
}
isVisible = true
Qt.callLater(() => powerMenuFocusScope.forceActiveFocus())
} }
function hide() { function hide() {
@@ -37,6 +135,148 @@ Rectangle {
closed() closed()
} }
function handleListNavigation(event) {
switch (event.key) {
case Qt.Key_Up:
case Qt.Key_Backtab:
selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length
event.accepted = true
break
case Qt.Key_Down:
case Qt.Key_Tab:
selectedIndex = (selectedIndex + 1) % visibleActions.length
event.accepted = true
break
case Qt.Key_Return:
case Qt.Key_Enter:
selectOption(getActionAtIndex(selectedIndex))
event.accepted = true
break
case Qt.Key_N:
if (event.modifiers & Qt.ControlModifier) {
selectedIndex = (selectedIndex + 1) % visibleActions.length
event.accepted = true
}
break
case Qt.Key_P:
if (!(event.modifiers & Qt.ControlModifier)) {
selectOption("poweroff")
event.accepted = true
} else {
selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length
event.accepted = true
}
break
case Qt.Key_J:
if (event.modifiers & Qt.ControlModifier) {
selectedIndex = (selectedIndex + 1) % visibleActions.length
event.accepted = true
}
break
case Qt.Key_K:
if (event.modifiers & Qt.ControlModifier) {
selectedIndex = (selectedIndex - 1 + visibleActions.length) % visibleActions.length
event.accepted = true
}
break
case Qt.Key_R:
selectOption("reboot")
event.accepted = true
break
case Qt.Key_X:
selectOption("logout")
event.accepted = true
break
case Qt.Key_S:
selectOption("suspend")
event.accepted = true
break
case Qt.Key_H:
selectOption("hibernate")
event.accepted = true
break
}
}
function handleGridNavigation(event) {
switch (event.key) {
case Qt.Key_Left:
selectedCol = (selectedCol - 1 + gridColumns) % gridColumns
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
break
case Qt.Key_Right:
selectedCol = (selectedCol + 1) % gridColumns
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
break
case Qt.Key_Up:
case Qt.Key_Backtab:
selectedRow = (selectedRow - 1 + gridRows) % gridRows
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
break
case Qt.Key_Down:
case Qt.Key_Tab:
selectedRow = (selectedRow + 1) % gridRows
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
break
case Qt.Key_Return:
case Qt.Key_Enter:
selectOption(getActionAtIndex(selectedIndex))
event.accepted = true
break
case Qt.Key_N:
if (event.modifiers & Qt.ControlModifier) {
selectedCol = (selectedCol + 1) % gridColumns
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
}
break
case Qt.Key_P:
if (!(event.modifiers & Qt.ControlModifier)) {
selectOption("poweroff")
event.accepted = true
} else {
selectedCol = (selectedCol - 1 + gridColumns) % gridColumns
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
}
break
case Qt.Key_J:
if (event.modifiers & Qt.ControlModifier) {
selectedRow = (selectedRow + 1) % gridRows
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
}
break
case Qt.Key_K:
if (event.modifiers & Qt.ControlModifier) {
selectedRow = (selectedRow - 1 + gridRows) % gridRows
selectedIndex = selectedRow * gridColumns + selectedCol
event.accepted = true
}
break
case Qt.Key_R:
selectOption("reboot")
event.accepted = true
break
case Qt.Key_X:
selectOption("logout")
event.accepted = true
break
case Qt.Key_S:
selectOption("suspend")
event.accepted = true
break
case Qt.Key_H:
selectOption("hibernate")
event.accepted = true
break
}
}
anchors.fill: parent anchors.fill: parent
color: Qt.rgba(0, 0, 0, 0.5) color: Qt.rgba(0, 0, 0, 0.5)
visible: isVisible visible: isVisible
@@ -53,102 +293,39 @@ Rectangle {
focus: root.isVisible focus: root.isVisible
onVisibleChanged: { onVisibleChanged: {
if (visible) { if (visible) Qt.callLater(() => forceActiveFocus())
Qt.callLater(() => forceActiveFocus())
}
}
Keys.onEscapePressed: {
root.hide()
} }
Keys.onEscapePressed: root.hide()
Keys.onPressed: event => { Keys.onPressed: event => {
switch (event.key) { if (useGridLayout) {
case Qt.Key_Up: handleGridNavigation(event)
case Qt.Key_Backtab: } else {
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount handleListNavigation(event)
event.accepted = true
break
case Qt.Key_Down:
case Qt.Key_Tab:
selectedIndex = (selectedIndex + 1) % optionCount
event.accepted = true
break
case Qt.Key_Return:
case Qt.Key_Enter:
const actions = []
if (showLogout) actions.push("logout")
actions.push("suspend")
if (SessionService.hibernateSupported) actions.push("hibernate")
actions.push("reboot", "poweroff")
if (selectedIndex < actions.length) {
const action = actions[selectedIndex]
hide()
switch (action) {
case "logout":
SessionService.logout()
break
case "suspend":
SessionService.suspend()
break
case "hibernate":
SessionService.hibernate()
break
case "reboot":
SessionService.reboot()
break
case "poweroff":
SessionService.poweroff()
break
}
}
event.accepted = true
break
case Qt.Key_N:
if (event.modifiers & Qt.ControlModifier) {
selectedIndex = (selectedIndex + 1) % optionCount
event.accepted = true
}
break
case Qt.Key_P:
if (event.modifiers & Qt.ControlModifier) {
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount
event.accepted = true
}
break
case Qt.Key_J:
if (event.modifiers & Qt.ControlModifier) {
selectedIndex = (selectedIndex + 1) % optionCount
event.accepted = true
}
break
case Qt.Key_K:
if (event.modifiers & Qt.ControlModifier) {
selectedIndex = (selectedIndex - 1 + optionCount) % optionCount
event.accepted = true
}
break
} }
} }
Rectangle { Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
width: 320 width: useGridLayout
implicitHeight: mainColumn.implicitHeight + Theme.spacingL * 2 ? Math.min(550, gridColumns * 180 + Theme.spacingS * (gridColumns - 1) + Theme.spacingL * 2)
height: implicitHeight : 320
height: contentItem.implicitHeight + Theme.spacingL * 2
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: Theme.surfaceContainer color: Theme.surfaceContainer
border.color: Theme.outlineMedium border.color: Theme.outlineMedium
border.width: 1 border.width: 1
Column { Item {
id: mainColumn id: contentItem
anchors.fill: parent anchors.fill: parent
anchors.margins: Theme.spacingL anchors.margins: Theme.spacingL
spacing: Theme.spacingM implicitHeight: headerRow.height + Theme.spacingM + (useGridLayout ? buttonGrid.implicitHeight : buttonColumn.implicitHeight)
Row { Row {
id: headerRow
width: parent.width width: parent.width
height: 30
StyledText { StyledText {
text: I18n.tr("Power Options") text: I18n.tr("Power Options")
@@ -171,289 +348,199 @@ Rectangle {
} }
} }
Column { Grid {
id: buttonGrid
visible: useGridLayout
anchors.top: headerRow.bottom
anchors.topMargin: Theme.spacingM
anchors.horizontalCenter: parent.horizontalCenter
columns: root.gridColumns
columnSpacing: Theme.spacingS
rowSpacing: Theme.spacingS
width: parent.width width: parent.width
spacing: Theme.spacingS
Rectangle { Repeater {
width: parent.width model: root.visibleActions
height: 50
radius: Theme.cornerRadius Rectangle {
visible: showLogout required property int index
color: { required property string modelData
if (selectedIndex === 0) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) readonly property var actionData: root.getActionData(modelData)
} else if (logoutArea.containsMouse) { readonly property bool isSelected: root.selectedIndex === index
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08) readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff"
} else {
width: (contentItem.width - Theme.spacingS * (root.gridColumns - 1)) / root.gridColumns
height: 100
radius: Theme.cornerRadius
color: {
if (isSelected) return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
if (mouseArea.containsMouse) return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08) return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
} }
} border.color: isSelected ? Theme.primary : "transparent"
border.color: selectedIndex === 0 ? Theme.primary : "transparent" border.width: isSelected ? 2 : 0
border.width: selectedIndex === 0 ? 1 : 0
Row { Column {
anchors.left: parent.left anchors.centerIn: parent
anchors.leftMargin: Theme.spacingM spacing: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon { DankIcon {
name: "logout" name: parent.parent.actionData.icon
size: Theme.iconSize size: Theme.iconSize + 8
color: Theme.surfaceText color: {
anchors.verticalCenter: parent.verticalCenter if (parent.parent.showWarning && mouseArea.containsMouse) {
return parent.parent.modelData === "poweroff" ? Theme.error : Theme.warning
}
return Theme.surfaceText
}
anchors.horizontalCenter: parent.horizontalCenter
}
StyledText {
text: parent.parent.actionData.label
font.pixelSize: Theme.fontSizeMedium
color: {
if (parent.parent.showWarning && mouseArea.containsMouse) {
return parent.parent.modelData === "poweroff" ? Theme.error : Theme.warning
}
return Theme.surfaceText
}
font.weight: Font.Medium
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
width: 20
height: 16
radius: 4
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1)
anchors.horizontalCenter: parent.horizontalCenter
StyledText {
text: parent.parent.parent.actionData.key
font.pixelSize: Theme.fontSizeSmall - 1
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
font.weight: Font.Medium
anchors.centerIn: parent
}
}
} }
StyledText { MouseArea {
text: I18n.tr("Log Out") id: mouseArea
font.pixelSize: Theme.fontSizeMedium anchors.fill: parent
color: Theme.surfaceText hoverEnabled: true
font.weight: Font.Medium cursorShape: Qt.PointingHandCursor
anchors.verticalCenter: parent.verticalCenter onClicked: {
} root.selectedRow = Math.floor(index / root.gridColumns)
} root.selectedCol = index % root.gridColumns
root.selectOption(modelData)
MouseArea { }
id: logoutArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.hide()
SessionService.logout()
}
}
}
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: {
const suspendIdx = showLogout ? 1 : 0
if (selectedIndex === suspendIdx) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
} else if (suspendArea.containsMouse) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
} else {
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
}
}
border.color: selectedIndex === (showLogout ? 1 : 0) ? Theme.primary : "transparent"
border.width: selectedIndex === (showLogout ? 1 : 0) ? 1 : 0
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "bedtime"
size: Theme.iconSize
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Suspend")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: suspendArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.hide()
SessionService.suspend()
}
}
}
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: {
const hibernateIdx = showLogout ? 2 : 1
if (selectedIndex === hibernateIdx) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
} else if (hibernateArea.containsMouse) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
} else {
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
}
}
border.color: selectedIndex === (showLogout ? 2 : 1) ? Theme.primary : "transparent"
border.width: selectedIndex === (showLogout ? 2 : 1) ? 1 : 0
visible: SessionService.hibernateSupported
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "ac_unit"
size: Theme.iconSize
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Hibernate")
font.pixelSize: Theme.fontSizeMedium
color: Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: hibernateArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.hide()
SessionService.hibernate()
}
}
}
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: {
let rebootIdx = showLogout ? 3 : 2
if (!SessionService.hibernateSupported) rebootIdx--
if (selectedIndex === rebootIdx) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
} else if (rebootArea.containsMouse) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
} else {
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
}
}
border.color: {
let rebootIdx = showLogout ? 3 : 2
if (!SessionService.hibernateSupported) rebootIdx--
return selectedIndex === rebootIdx ? Theme.primary : "transparent"
}
border.width: {
let rebootIdx = showLogout ? 3 : 2
if (!SessionService.hibernateSupported) rebootIdx--
return selectedIndex === rebootIdx ? 1 : 0
}
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "restart_alt"
size: Theme.iconSize
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Reboot")
font.pixelSize: Theme.fontSizeMedium
color: rebootArea.containsMouse ? Theme.warning : Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: rebootArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.hide()
SessionService.reboot()
}
}
}
Rectangle {
width: parent.width
height: 50
radius: Theme.cornerRadius
color: {
let powerOffIdx = showLogout ? 4 : 3
if (!SessionService.hibernateSupported) powerOffIdx--
if (selectedIndex === powerOffIdx) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
} else if (powerOffArea.containsMouse) {
return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
} else {
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
}
}
border.color: {
let powerOffIdx = showLogout ? 4 : 3
if (!SessionService.hibernateSupported) powerOffIdx--
return selectedIndex === powerOffIdx ? Theme.primary : "transparent"
}
border.width: {
let powerOffIdx = showLogout ? 4 : 3
if (!SessionService.hibernateSupported) powerOffIdx--
return selectedIndex === powerOffIdx ? 1 : 0
}
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: "power_settings_new"
size: Theme.iconSize
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: I18n.tr("Power Off")
font.pixelSize: Theme.fontSizeMedium
color: powerOffArea.containsMouse ? Theme.error : Theme.surfaceText
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: powerOffArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.hide()
SessionService.poweroff()
} }
} }
} }
} }
Item { Column {
height: Theme.spacingS id: buttonColumn
visible: !useGridLayout
anchors.top: headerRow.bottom
anchors.topMargin: Theme.spacingM
anchors.left: parent.left
anchors.right: parent.right
spacing: Theme.spacingS
Repeater {
model: root.visibleActions
Rectangle {
required property int index
required property string modelData
readonly property var actionData: root.getActionData(modelData)
readonly property bool isSelected: root.selectedIndex === index
readonly property bool showWarning: modelData === "reboot" || modelData === "poweroff"
width: parent.width
height: 50
radius: Theme.cornerRadius
color: {
if (isSelected) return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12)
if (listMouseArea.containsMouse) return Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.08)
return Qt.rgba(Theme.surfaceVariant.r, Theme.surfaceVariant.g, Theme.surfaceVariant.b, 0.08)
}
border.color: isSelected ? Theme.primary : "transparent"
border.width: isSelected ? 2 : 0
Row {
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: Theme.spacingM
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingM
DankIcon {
name: parent.parent.actionData.icon
size: Theme.iconSize + 4
color: {
if (parent.parent.showWarning && listMouseArea.containsMouse) {
return parent.parent.modelData === "poweroff" ? Theme.error : Theme.warning
}
return Theme.surfaceText
}
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: parent.parent.actionData.label
font.pixelSize: Theme.fontSizeMedium
color: {
if (parent.parent.showWarning && listMouseArea.containsMouse) {
return parent.parent.modelData === "poweroff" ? Theme.error : Theme.warning
}
return Theme.surfaceText
}
font.weight: Font.Medium
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
width: 28
height: 20
radius: 4
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.1)
anchors.right: parent.right
anchors.rightMargin: Theme.spacingM
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: parent.parent.actionData.key
font.pixelSize: Theme.fontSizeSmall
color: Qt.rgba(Theme.surfaceText.r, Theme.surfaceText.g, Theme.surfaceText.b, 0.6)
font.weight: Font.Medium
anchors.centerIn: parent
}
}
MouseArea {
id: listMouseArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.selectedIndex = index
root.selectOption(modelData)
}
}
}
}
} }
} }
} }
} }
Component.onCompleted: updateVisibleActions()
} }

View File

@@ -40,7 +40,8 @@ DankListView {
NotificationEmptyState { NotificationEmptyState {
visible: listView.count === 0 visible: listView.count === 0
anchors.centerIn: parent y: 20
anchors.horizontalCenter: parent.horizontalCenter
} }
onModelChanged: { onModelChanged: {

View File

@@ -111,13 +111,20 @@ DankPopout {
implicitHeight: { implicitHeight: {
let baseHeight = Theme.spacingL * 2 let baseHeight = Theme.spacingL * 2
baseHeight += cachedHeaderHeight baseHeight += cachedHeaderHeight
baseHeight += (notificationSettings.expanded ? notificationSettings.contentHeight : 0)
baseHeight += Theme.spacingM * 2 baseHeight += Theme.spacingM * 2
const settingsHeight = notificationSettings.expanded ? notificationSettings.contentHeight : 0
let listHeight = notificationList.listContentHeight let listHeight = notificationList.listContentHeight
if (NotificationService.groupedNotifications.length === 0) { if (NotificationService.groupedNotifications.length === 0) {
listHeight = 200 listHeight = 200
} }
baseHeight += Math.min(listHeight, 600)
const maxContentArea = 600
const availableListSpace = Math.max(200, maxContentArea - settingsHeight)
baseHeight += settingsHeight
baseHeight += Math.min(listHeight, availableListSpace)
const maxHeight = root.screen ? root.screen.height * 0.8 : Screen.height * 0.8 const maxHeight = root.screen ? root.screen.height * 0.8 : Screen.height * 0.8
return Math.max(300, Math.min(baseHeight, maxHeight)) return Math.max(300, Math.min(baseHeight, maxHeight))
} }
@@ -198,13 +205,6 @@ DankPopout {
showHints: (externalKeyboardController && externalKeyboardController.showKeyboardHints) || false showHints: (externalKeyboardController && externalKeyboardController.showKeyboardHints) || false
z: 200 z: 200
} }
Behavior on implicitHeight {
NumberAnimation {
duration: 180
easing.type: Easing.OutQuart
}
}
} }
} }
} }

View File

@@ -542,11 +542,57 @@ Item {
width: parent.width width: parent.width
spacing: Theme.spacingS spacing: Theme.spacingS
StyledText { Column {
text: I18n.tr("Available Screens (") + Quickshell.screens.length + ")" width: parent.width
font.pixelSize: Theme.fontSizeMedium spacing: Theme.spacingXS
font.weight: Font.Medium
color: Theme.surfaceText Row {
width: parent.width
spacing: Theme.spacingM
StyledText {
text: I18n.tr("Available Screens (") + Quickshell.screens.length + ")"
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium
color: Theme.surfaceText
}
Item {
width: 1
height: 1
Layout.fillWidth: true
}
Column {
spacing: Theme.spacingXS
anchors.verticalCenter: parent.verticalCenter
StyledText {
text: I18n.tr("Display Name Format")
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText
anchors.horizontalCenter: parent.horizontalCenter
}
DankButtonGroup {
id: displayModeGroup
model: [I18n.tr("Name"), I18n.tr("Model")]
currentIndex: SettingsData.displayNameMode === "model" ? 1 : 0
onSelectionChanged: (index, selected) => {
if (!selected) return
SettingsData.displayNameMode = index === 1 ? "model" : "system"
SettingsData.saveSettings()
}
Connections {
target: SettingsData
function onDisplayNameModeChanged() {
displayModeGroup.currentIndex = SettingsData.displayNameMode === "model" ? 1 : 0
}
}
}
}
}
} }
Repeater { Repeater {
@@ -580,7 +626,7 @@ Item {
spacing: Theme.spacingXS / 2 spacing: Theme.spacingXS / 2
StyledText { StyledText {
text: modelData.name text: SettingsData.getScreenDisplayName(modelData)
font.pixelSize: Theme.fontSizeMedium font.pixelSize: Theme.fontSizeMedium
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.surfaceText color: Theme.surfaceText
@@ -602,7 +648,7 @@ Item {
} }
StyledText { StyledText {
text: modelData.model || "Unknown Model" text: SettingsData.displayNameMode === "system" ? (modelData.model || "Unknown Model") : modelData.name
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceVariantText color: Theme.surfaceVariantText
} }
@@ -701,14 +747,17 @@ Item {
width: parent.width width: parent.width
text: I18n.tr("All displays") text: I18n.tr("All displays")
description: I18n.tr("Show on all connected displays") description: I18n.tr("Show on all connected displays")
checked: displaysTab.getScreenPreferences(parent.componentId).includes("all") checked: {
var prefs = displaysTab.getScreenPreferences(parent.componentId)
return prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all")
}
onToggled: (checked) => { onToggled: (checked) => {
if (checked) { if (checked) {
displaysTab.setScreenPreferences(parent.componentId, ["all"]); displaysTab.setScreenPreferences(parent.componentId, ["all"])
} else { } else {
displaysTab.setScreenPreferences(parent.componentId, []); displaysTab.setScreenPreferences(parent.componentId, [])
if (["dankBar", "dock", "notifications", "osd", "toast"].includes(parent.componentId)) { if (["dankBar", "dock", "notifications", "osd", "toast"].includes(parent.componentId)) {
displaysTab.setShowOnLastDisplay(parent.componentId, true); displaysTab.setShowOnLastDisplay(parent.componentId, true)
} }
} }
} }
@@ -719,9 +768,13 @@ Item {
text: I18n.tr("Show on Last Display") text: I18n.tr("Show on Last Display")
description: I18n.tr("Always show when there's only one connected display") description: I18n.tr("Always show when there's only one connected display")
checked: displaysTab.getShowOnLastDisplay(parent.componentId) checked: displaysTab.getShowOnLastDisplay(parent.componentId)
visible: !displaysTab.getScreenPreferences(parent.componentId).includes("all") && ["dankBar", "dock", "notifications", "osd", "toast", "notepad", "systemTray"].includes(parent.componentId) visible: {
var prefs = displaysTab.getScreenPreferences(parent.componentId)
var isAll = prefs.includes("all") || (typeof prefs[0] === "string" && prefs[0] === "all")
return !isAll && ["dankBar", "dock", "notifications", "osd", "toast", "notepad", "systemTray"].includes(parent.componentId)
}
onToggled: (checked) => { onToggled: (checked) => {
displaysTab.setShowOnLastDisplay(parent.componentId, checked); displaysTab.setShowOnLastDisplay(parent.componentId, checked)
} }
} }
@@ -730,45 +783,54 @@ Item {
height: 1 height: 1
color: Theme.outline color: Theme.outline
opacity: 0.2 opacity: 0.2
visible: !displaysTab.getScreenPreferences(parent.componentId).includes("all") visible: {
var prefs = displaysTab.getScreenPreferences(parent.componentId)
return !prefs.includes("all") && !(typeof prefs[0] === "string" && prefs[0] === "all")
}
} }
Column { Column {
width: parent.width width: parent.width
spacing: Theme.spacingXS spacing: Theme.spacingXS
visible: !displaysTab.getScreenPreferences(parent.componentId).includes("all") visible: {
var prefs = displaysTab.getScreenPreferences(parent.componentId)
return !prefs.includes("all") && !(typeof prefs[0] === "string" && prefs[0] === "all")
}
Repeater { Repeater {
model: Quickshell.screens model: Quickshell.screens
delegate: DankToggle { delegate: DankToggle {
property string screenName: modelData.name property var screenData: modelData
property string componentId: parent.parent.componentId property string componentId: parent.parent.componentId
width: parent.width width: parent.width
text: screenName text: SettingsData.getScreenDisplayName(screenData)
description: modelData.width + "×" + modelData.height + " • " + (modelData.model || "Unknown Model") description: screenData.width + "×" + screenData.height + " • " + (SettingsData.displayNameMode === "system" ? (screenData.model || "Unknown Model") : screenData.name)
checked: { checked: {
var prefs = displaysTab.getScreenPreferences(componentId); var prefs = displaysTab.getScreenPreferences(componentId)
return !prefs.includes("all") && prefs.includes(screenName); if (typeof prefs[0] === "string" && prefs[0] === "all") return false
return SettingsData.isScreenInPreferences(screenData, prefs)
} }
onToggled: (checked) => { onToggled: (checked) => {
var currentPrefs = displaysTab.getScreenPreferences(componentId); var currentPrefs = displaysTab.getScreenPreferences(componentId)
if (currentPrefs.includes("all")) if (typeof currentPrefs[0] === "string" && currentPrefs[0] === "all") {
currentPrefs = []; currentPrefs = []
var newPrefs = currentPrefs.slice();
if (checked) {
if (!newPrefs.includes(screenName))
newPrefs.push(screenName);
} else {
var index = newPrefs.indexOf(screenName);
if (index > -1)
newPrefs.splice(index, 1);
} }
displaysTab.setScreenPreferences(componentId, newPrefs);
var newPrefs = currentPrefs.filter(pref => {
if (typeof pref === "string") return false
return pref.name !== screenData.name || pref.model !== screenData.model
})
if (checked) {
newPrefs.push({
name: screenData.name,
model: screenData.model || ""
})
}
displaysTab.setScreenPreferences(componentId, newPrefs)
} }
} }

View File

@@ -1007,18 +1007,32 @@ Item {
text: I18n.tr("Wallpaper Monitor") text: I18n.tr("Wallpaper Monitor")
description: I18n.tr("Select monitor to configure wallpaper") description: I18n.tr("Select monitor to configure wallpaper")
currentValue: selectedMonitorName || "No monitors" currentValue: {
var screens = Quickshell.screens
for (var i = 0; i < screens.length; i++) {
if (screens[i].name === selectedMonitorName) {
return SettingsData.getScreenDisplayName(screens[i])
}
}
return "No monitors"
}
options: { options: {
var screenNames = [] var screenNames = []
var screens = Quickshell.screens var screens = Quickshell.screens
for (var i = 0; i < screens.length; i++) { for (var i = 0; i < screens.length; i++) {
screenNames.push(screens[i].name) screenNames.push(SettingsData.getScreenDisplayName(screens[i]))
} }
return screenNames return screenNames
} }
onValueChanged: value => { onValueChanged: value => {
selectedMonitorName = value var screens = Quickshell.screens
} for (var i = 0; i < screens.length; i++) {
if (SettingsData.getScreenDisplayName(screens[i]) === value) {
selectedMonitorName = screens[i].name
return
}
}
}
} }
DankDropdown { DankDropdown {
@@ -1027,9 +1041,14 @@ Item {
text: I18n.tr("Matugen Target Monitor") text: I18n.tr("Matugen Target Monitor")
description: I18n.tr("Monitor whose wallpaper drives dynamic theming colors") description: I18n.tr("Monitor whose wallpaper drives dynamic theming colors")
currentValue: { currentValue: {
var screens = Quickshell.screens
if (!SettingsData.matugenTargetMonitor || SettingsData.matugenTargetMonitor === "") { if (!SettingsData.matugenTargetMonitor || SettingsData.matugenTargetMonitor === "") {
var screens = Quickshell.screens return screens.length > 0 ? SettingsData.getScreenDisplayName(screens[0]) + " (Default)" : "No monitors"
return screens.length > 0 ? screens[0].name + " (Default)" : "No monitors" }
for (var i = 0; i < screens.length; i++) {
if (screens[i].name === SettingsData.matugenTargetMonitor) {
return SettingsData.getScreenDisplayName(screens[i])
}
} }
return SettingsData.matugenTargetMonitor return SettingsData.matugenTargetMonitor
} }
@@ -1037,7 +1056,7 @@ Item {
var screenNames = [] var screenNames = []
var screens = Quickshell.screens var screens = Quickshell.screens
for (var i = 0; i < screens.length; i++) { for (var i = 0; i < screens.length; i++) {
var label = screens[i].name var label = SettingsData.getScreenDisplayName(screens[i])
if (i === 0 && (!SettingsData.matugenTargetMonitor || SettingsData.matugenTargetMonitor === "")) { if (i === 0 && (!SettingsData.matugenTargetMonitor || SettingsData.matugenTargetMonitor === "")) {
label += " (Default)" label += " (Default)"
} }
@@ -1046,9 +1065,15 @@ Item {
return screenNames return screenNames
} }
onValueChanged: value => { onValueChanged: value => {
var cleanValue = value.replace(" (Default)", "") var cleanValue = value.replace(" (Default)", "")
SettingsData.setMatugenTargetMonitor(cleanValue) var screens = Quickshell.screens
} for (var i = 0; i < screens.length; i++) {
if (SettingsData.getScreenDisplayName(screens[i]) === cleanValue) {
SettingsData.setMatugenTargetMonitor(screens[i].name)
return
}
}
}
} }
} }
} }
@@ -1439,7 +1464,7 @@ Item {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
StyledText { StyledText {
text: I18n.tr("Blur Layer") text: I18n.tr("Duplicate Wallpaper with Blur")
font.pixelSize: Theme.fontSizeLarge font.pixelSize: Theme.fontSizeLarge
font.weight: Font.Medium font.weight: Font.Medium
color: Theme.surfaceText color: Theme.surfaceText

View File

@@ -736,6 +736,60 @@ Item {
} }
} }
Column {
width: parent.width
spacing: 0
leftPadding: Theme.spacingM
rightPadding: Theme.spacingM
DankDropdown {
width: parent.width - parent.leftPadding - parent.rightPadding
text: I18n.tr("OSD Position")
description: I18n.tr("Choose where on-screen displays appear on screen")
currentValue: {
switch (SettingsData.osdPosition) {
case SettingsData.Position.Top:
return "Top Right"
case SettingsData.Position.Left:
return "Top Left"
case SettingsData.Position.TopCenter:
return "Top Center"
case SettingsData.Position.Right:
return "Bottom Right"
case SettingsData.Position.Bottom:
return "Bottom Left"
case SettingsData.Position.BottomCenter:
return "Bottom Center"
default:
return "Bottom Center"
}
}
options: ["Top Right", "Top Left", "Top Center", "Bottom Right", "Bottom Left", "Bottom Center"]
onValueChanged: value => {
switch (value) {
case "Top Right":
SettingsData.set("osdPosition", SettingsData.Position.Top)
break
case "Top Left":
SettingsData.set("osdPosition", SettingsData.Position.Left)
break
case "Top Center":
SettingsData.set("osdPosition", SettingsData.Position.TopCenter)
break
case "Bottom Right":
SettingsData.set("osdPosition", SettingsData.Position.Right)
break
case "Bottom Left":
SettingsData.set("osdPosition", SettingsData.Position.Bottom)
break
case "Bottom Center":
SettingsData.set("osdPosition", SettingsData.Position.BottomCenter)
break
}
}
}
}
DankToggle { DankToggle {
width: parent.width width: parent.width
text: I18n.tr("Volume OSD") text: I18n.tr("Volume OSD")

View File

@@ -38,7 +38,7 @@ Singleton {
if (WlrOutputService.wlrOutputAvailable && screen) { if (WlrOutputService.wlrOutputAvailable && screen) {
const wlrOutput = WlrOutputService.getOutput(screen.name) const wlrOutput = WlrOutputService.getOutput(screen.name)
if (wlrOutput?.enabled && wlrOutput.scale !== undefined && wlrOutput.scale > 0) { if (wlrOutput?.enabled && wlrOutput.scale !== undefined && wlrOutput.scale > 0) {
return wlrOutput.scale return Math.round(wlrOutput.scale * 20) / 20
} }
} }
@@ -441,6 +441,7 @@ Singleton {
if (isHyprland) return Hyprland.dispatch("dpms off") if (isHyprland) return Hyprland.dispatch("dpms off")
if (isDwl) return _dwlPowerOffMonitors() if (isDwl) return _dwlPowerOffMonitors()
if (isSway) { try { I3.dispatch("output * dpms off") } catch(_){} return } if (isSway) { try { I3.dispatch("output * dpms off") } catch(_){} return }
if (isLabwc) { Quickshell.execDetached(["dms", "dpms", "off"]) }
console.warn("CompositorService: Cannot power off monitors, unknown compositor") console.warn("CompositorService: Cannot power off monitors, unknown compositor")
} }
@@ -449,6 +450,7 @@ Singleton {
if (isHyprland) return Hyprland.dispatch("dpms on") if (isHyprland) return Hyprland.dispatch("dpms on")
if (isDwl) return _dwlPowerOnMonitors() if (isDwl) return _dwlPowerOnMonitors()
if (isSway) { try { I3.dispatch("output * dpms on") } catch(_){} return } if (isSway) { try { I3.dispatch("output * dpms on") } catch(_){} return }
if (isLabwc) { Quickshell.execDetached(["dms", "dpms", "on"]) }
console.warn("CompositorService: Cannot power on monitors, unknown compositor") console.warn("CompositorService: Cannot power on monitors, unknown compositor")
} }

View File

@@ -14,6 +14,11 @@ Singleton {
property var layouts: [] property var layouts: []
property string activeOutput: "" property string activeOutput: ""
property var outputScales: ({}) property var outputScales: ({})
property string currentKeyboardLayout: {
if (!outputs || !activeOutput) return ""
const output = outputs[activeOutput]
return (output && output.kbLayout) || ""
}
signal stateChanged() signal stateChanged()

View File

@@ -46,8 +46,17 @@ Singleton {
const hasExtWorkspace = DMSService.capabilities.includes("extworkspace") const hasExtWorkspace = DMSService.capabilities.includes("extworkspace")
if (hasExtWorkspace && !extWorkspaceAvailable) { if (hasExtWorkspace && !extWorkspaceAvailable) {
if (typeof CompositorService !== "undefined") {
const useExtWorkspace = DMSService.forceExtWorkspace || (!CompositorService.isNiri && !CompositorService.isHyprland && !CompositorService.isDwl && !CompositorService.isSway)
if (!useExtWorkspace) {
console.info("ExtWorkspaceService: ext-workspace available but compositor has native support")
extWorkspaceAvailable = false
return
}
}
extWorkspaceAvailable = true extWorkspaceAvailable = true
console.info("ExtWorkspaceService: ext-workspace capability detected") console.info("ExtWorkspaceService: ext-workspace capability detected")
DMSService.addSubscription("extworkspace")
requestState() requestState()
} else if (!hasExtWorkspace) { } else if (!hasExtWorkspace) {
extWorkspaceAvailable = false extWorkspaceAvailable = false
@@ -181,12 +190,17 @@ Singleton {
function getVisibleWorkspaces(outputName) { function getVisibleWorkspaces(outputName) {
const workspaces = getWorkspacesForOutput(outputName) const workspaces = getWorkspacesForOutput(outputName)
const visible = workspaces.filter(ws => !ws.hidden).sort((a, b) => { let visible = workspaces.filter(ws => !ws.hidden)
const coordsA = a.coordinates || [0, 0]
const coordsB = b.coordinates || [0, 0] const hasValidCoordinates = visible.some(ws => ws.coordinates && ws.coordinates.length > 0)
if (coordsA[0] !== coordsB[0]) return coordsA[0] - coordsB[0] if (hasValidCoordinates) {
return coordsA[1] - coordsB[1] visible = visible.sort((a, b) => {
}) const coordsA = a.coordinates || [0, 0]
const coordsB = b.coordinates || [0, 0]
if (coordsA[0] !== coordsB[0]) return coordsA[0] - coordsB[0]
return coordsA[1] - coordsB[1]
})
}
const cacheKey = outputName const cacheKey = outputName
if (!_cachedWorkspaces[cacheKey]) { if (!_cachedWorkspaces[cacheKey]) {

View File

@@ -137,21 +137,42 @@ Singleton {
} }
} }
// * Apps function escapeShellArg(arg) {
return "'" + arg.replace(/'/g, "'\\''") + "'"
}
function needsShellExecution(prefix) {
if (!prefix || prefix.length === 0) return false
return /[;&|<>()$`\\"']/.test(prefix)
}
function launchDesktopEntry(desktopEntry, usePrimeRun) { function launchDesktopEntry(desktopEntry, usePrimeRun) {
let cmd = desktopEntry.command let cmd = desktopEntry.command
if (usePrimeRun && hasPrimeRun) { if (usePrimeRun && hasPrimeRun) {
cmd = ["prime-run"].concat(cmd) cmd = ["prime-run"].concat(cmd)
} }
if (SettingsData.launchPrefix && SettingsData.launchPrefix.length > 0) {
const launchPrefix = SettingsData.launchPrefix.trim().split(" ")
cmd = launchPrefix.concat(cmd)
}
Quickshell.execDetached({ const prefix = SettingsData.launchPrefix?.trim() || ""
command: cmd,
workingDirectory: desktopEntry.workingDirectory || Quickshell.env("HOME"), if (prefix.length > 0 && needsShellExecution(prefix)) {
}); const escapedCmd = cmd.map(arg => escapeShellArg(arg)).join(" ")
const shellCmd = `${prefix} ${escapedCmd}`
Quickshell.execDetached({
command: ["sh", "-c", shellCmd],
workingDirectory: desktopEntry.workingDirectory || Quickshell.env("HOME"),
})
} else {
if (prefix.length > 0) {
const launchPrefix = prefix.split(" ")
cmd = launchPrefix.concat(cmd)
}
Quickshell.execDetached({
command: cmd,
workingDirectory: desktopEntry.workingDirectory || Quickshell.env("HOME"),
})
}
} }
function launchDesktopAction(desktopEntry, action, usePrimeRun) { function launchDesktopAction(desktopEntry, action, usePrimeRun) {
@@ -159,15 +180,28 @@ Singleton {
if (usePrimeRun && hasPrimeRun) { if (usePrimeRun && hasPrimeRun) {
cmd = ["prime-run"].concat(cmd) cmd = ["prime-run"].concat(cmd)
} }
if (SettingsData.launchPrefix && SettingsData.launchPrefix.length > 0) {
const launchPrefix = SettingsData.launchPrefix.trim().split(" ")
cmd = launchPrefix.concat(cmd)
}
Quickshell.execDetached({ const prefix = SettingsData.launchPrefix?.trim() || ""
command: cmd,
workingDirectory: desktopEntry.workingDirectory || Quickshell.env("HOME"), if (prefix.length > 0 && needsShellExecution(prefix)) {
}); const escapedCmd = cmd.map(arg => escapeShellArg(arg)).join(" ")
const shellCmd = `${prefix} ${escapedCmd}`
Quickshell.execDetached({
command: ["sh", "-c", shellCmd],
workingDirectory: desktopEntry.workingDirectory || Quickshell.env("HOME"),
})
} else {
if (prefix.length > 0) {
const launchPrefix = prefix.split(" ")
cmd = launchPrefix.concat(cmd)
}
Quickshell.execDetached({
command: cmd,
workingDirectory: desktopEntry.workingDirectory || Quickshell.env("HOME"),
})
}
} }
// * Session management // * Session management

View File

@@ -74,16 +74,55 @@ PanelWindow {
readonly property real screenHeight: screen.height readonly property real screenHeight: screen.height
readonly property real alignedWidth: Theme.px(osdWidth, dpr) readonly property real alignedWidth: Theme.px(osdWidth, dpr)
readonly property real alignedHeight: Theme.px(osdHeight, dpr) readonly property real alignedHeight: Theme.px(osdHeight, dpr)
readonly property real alignedX: Theme.snap((screenWidth - alignedWidth) / 2, dpr)
readonly property real barOffsetWhenBottom: { readonly property real barThickness: {
if (SettingsData.dankBarPosition === SettingsData.Position.Bottom && SettingsData.dankBarVisible) { if (!SettingsData.dankBarVisible) return 0
const widgetThickness = Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6) const widgetThickness = Math.max(20, 26 + SettingsData.dankBarInnerPadding * 0.6)
const effectiveBarThickness = Math.max(widgetThickness + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding)) return Math.max(widgetThickness + SettingsData.dankBarInnerPadding + 4, Theme.barHeight - 4 - (8 - SettingsData.dankBarInnerPadding))
return effectiveBarThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap }
}
return 0 readonly property real barOffset: {
if (!SettingsData.dankBarVisible) return 0
return barThickness + SettingsData.dankBarSpacing + SettingsData.dankBarBottomGap
}
readonly property real alignedX: {
const margin = Theme.spacingM
const centerX = (screenWidth - alignedWidth) / 2
switch (SettingsData.osdPosition) {
case SettingsData.Position.Left:
case SettingsData.Position.Bottom:
const leftOffset = SettingsData.dankBarPosition === SettingsData.Position.Left ? barOffset : 0
return Theme.snap(margin + leftOffset, dpr)
case SettingsData.Position.Top:
case SettingsData.Position.Right:
const rightOffset = SettingsData.dankBarPosition === SettingsData.Position.Right ? barOffset : 0
return Theme.snap(screenWidth - alignedWidth - margin - rightOffset, dpr)
case SettingsData.Position.TopCenter:
case SettingsData.Position.BottomCenter:
default:
return Theme.snap(centerX, dpr)
}
}
readonly property real alignedY: {
const margin = Theme.spacingM
switch (SettingsData.osdPosition) {
case SettingsData.Position.Top:
case SettingsData.Position.Left:
case SettingsData.Position.TopCenter:
const topOffset = SettingsData.dankBarPosition === SettingsData.Position.Top ? barOffset : 0
return Theme.snap(margin + topOffset, dpr)
case SettingsData.Position.Right:
case SettingsData.Position.Bottom:
case SettingsData.Position.BottomCenter:
default:
const bottomOffset = SettingsData.dankBarPosition === SettingsData.Position.Bottom ? barOffset : 0
return Theme.snap(screenHeight - alignedHeight - margin - bottomOffset, dpr)
}
} }
readonly property real alignedY: Theme.snap(screenHeight - alignedHeight - Theme.spacingM - barOffsetWhenBottom, dpr)
anchors { anchors {
top: true top: true

View File

@@ -38,7 +38,7 @@ Text {
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
elide: Text.ElideRight elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
antialiasing: true //renderType: Text.NativeRendering
Behavior on opacity { Behavior on opacity {
NumberAnimation { NumberAnimation {

File diff suppressed because it is too large Load Diff

View File

@@ -275,6 +275,9 @@
"Brightness": { "Brightness": {
"Brightness": "Luminosità" "Brightness": "Luminosità"
}, },
"Brightness OSD": {
"Brightness OSD": ""
},
"Browse": { "Browse": {
"Browse": "Sfoglia" "Browse": "Sfoglia"
}, },
@@ -314,6 +317,9 @@
"Caps Lock Indicator": { "Caps Lock Indicator": {
"Caps Lock Indicator": "Indicatore Maiuscolo" "Caps Lock Indicator": "Indicatore Maiuscolo"
}, },
"Caps Lock OSD": {
"Caps Lock OSD": ""
},
"Center Section": { "Center Section": {
"Center Section": "Sezione Centrale" "Center Section": "Sezione Centrale"
}, },
@@ -341,6 +347,9 @@
"Choose where notification popups appear on screen": { "Choose where notification popups appear on screen": {
"Choose where notification popups appear on screen": "Scegli dove i popup delle notifiche appaiono sullo schermo" "Choose where notification popups appear on screen": "Scegli dove i popup delle notifiche appaiono sullo schermo"
}, },
"Choose where on-screen displays appear on screen": {
"Choose where on-screen displays appear on screen": ""
},
"Clear": { "Clear": {
"Clear": "Pulisci" "Clear": "Pulisci"
}, },
@@ -617,6 +626,9 @@
"Dismiss": { "Dismiss": {
"Dismiss": "Dismetti" "Dismiss": "Dismetti"
}, },
"Display Name Format": {
"Display Name Format": ""
},
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": { "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": {
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Visualizza una dock con applicazioni pinnate ed in esecuzione che possono essere posizionate nell'angolo superiore, inferiore, sinistro o destro dello schermo" "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Visualizza una dock con applicazioni pinnate ed in esecuzione che possono essere posizionate nell'angolo superiore, inferiore, sinistro o destro dello schermo"
}, },
@@ -674,6 +686,9 @@
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": { "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": {
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Trascina i widget per riordinarli nelle sezioni. Usa l'icona occhio per nascondere/mostrare i widget (mantenendo la spaziatura), o X per rimuoverli completamente." "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Trascina i widget per riordinarli nelle sezioni. Usa l'icona occhio per nascondere/mostrare i widget (mantenendo la spaziatura), o X per rimuoverli completamente."
}, },
"Duplicate Wallpaper with Blur": {
"Duplicate Wallpaper with Blur": ""
},
"Duration": { "Duration": {
"Duration": "Durata" "Duration": "Durata"
}, },
@@ -959,6 +974,9 @@
"Idle Inhibitor": { "Idle Inhibitor": {
"Idle Inhibitor": "Inibitore Riposo" "Idle Inhibitor": "Inibitore Riposo"
}, },
"Idle Inhibitor OSD": {
"Idle Inhibitor OSD": ""
},
"Idle Settings": { "Idle Settings": {
"Idle Settings": "Impostazioni Riposo" "Idle Settings": "Impostazioni Riposo"
}, },
@@ -1175,6 +1193,9 @@
"Microphone": { "Microphone": {
"Microphone": "" "Microphone": ""
}, },
"Microphone Mute OSD": {
"Microphone Mute OSD": ""
},
"Minimal palette built around a single hue.": { "Minimal palette built around a single hue.": {
"Minimal palette built around a single hue.": "Tavolozza minima costruita attorno a una singola tonalità." "Minimal palette built around a single hue.": "Tavolozza minima costruita attorno a una singola tonalità."
}, },
@@ -1187,6 +1208,9 @@
"Mode: ": { "Mode: ": {
"Mode: ": "Modalità:" "Mode: ": "Modalità:"
}, },
"Model": {
"Model": ""
},
"Monitor Selection:": { "Monitor Selection:": {
"Monitor Selection:": "Selezione Monitor:" "Monitor Selection:": "Selezione Monitor:"
}, },
@@ -1211,6 +1235,9 @@
"NM not supported": { "NM not supported": {
"NM not supported": "NM non supportato" "NM not supported": "NM non supportato"
}, },
"Name": {
"Name": ""
},
"Named Workspace Icons": { "Named Workspace Icons": {
"Named Workspace Icons": "Icone Workspace con Nome" "Named Workspace Icons": "Icone Workspace con Nome"
}, },
@@ -1337,6 +1364,9 @@
"OS Logo": { "OS Logo": {
"OS Logo": "Logo OS" "OS Logo": "Logo OS"
}, },
"OSD Position": {
"OSD Position": ""
},
"Office": { "Office": {
"Office": "Ufficio" "Office": "Ufficio"
}, },
@@ -1346,6 +1376,9 @@
"On-Screen Displays": { "On-Screen Displays": {
"On-Screen Displays": "Visualizzazione A Schermo" "On-Screen Displays": "Visualizzazione A Schermo"
}, },
"On-screen Displays": {
"On-screen Displays": ""
},
"Only adjust gamma based on time or location rules.": { "Only adjust gamma based on time or location rules.": {
"Only adjust gamma based on time or location rules.": "Regolare gamma solo in base alle regole di tempo o di posizione." "Only adjust gamma based on time or location rules.": "Regolare gamma solo in base alle regole di tempo o di posizione."
}, },
@@ -1493,6 +1526,9 @@
"Power Profile Degradation": { "Power Profile Degradation": {
"Power Profile Degradation": "Degradamento profilo energetico" "Power Profile Degradation": "Degradamento profilo energetico"
}, },
"Power Profile OSD": {
"Power Profile OSD": ""
},
"Pressure": { "Pressure": {
"Pressure": "Pressione" "Pressure": "Pressione"
}, },
@@ -1781,6 +1817,24 @@
"Show on screens:": { "Show on screens:": {
"Show on screens:": "Mostra sullo schermo:" "Show on screens:": "Mostra sullo schermo:"
}, },
"Show on-screen display when brightness changes": {
"Show on-screen display when brightness changes": ""
},
"Show on-screen display when caps lock state changes": {
"Show on-screen display when caps lock state changes": ""
},
"Show on-screen display when idle inhibitor state changes": {
"Show on-screen display when idle inhibitor state changes": ""
},
"Show on-screen display when microphone is muted/unmuted": {
"Show on-screen display when microphone is muted/unmuted": ""
},
"Show on-screen display when power profile changes": {
"Show on-screen display when power profile changes": ""
},
"Show on-screen display when volume changes": {
"Show on-screen display when volume changes": ""
},
"Show only apps running in current workspace": { "Show only apps running in current workspace": {
"Show only apps running in current workspace": "Mostra solo apps eseguite nel workspace attuale" "Show only apps running in current workspace": "Mostra solo apps eseguite nel workspace attuale"
}, },
@@ -2141,6 +2195,9 @@
"Volume Changed": { "Volume Changed": {
"Volume Changed": "Volume Cambiato" "Volume Changed": "Volume Cambiato"
}, },
"Volume OSD": {
"Volume OSD": ""
},
"Volume, brightness, and other system OSDs": { "Volume, brightness, and other system OSDs": {
"Volume, brightness, and other system OSDs": "Volume, luminosità, e altri OSD di sistema" "Volume, brightness, and other system OSDs": "Volume, luminosità, e altri OSD di sistema"
}, },

View File

@@ -57,7 +57,7 @@
"Add a VPN in NetworkManager": "NetworkManagerでVPNを追加" "Add a VPN in NetworkManager": "NetworkManagerでVPNを追加"
}, },
"Adjust the number of columns in grid view mode.": { "Adjust the number of columns in grid view mode.": {
"Adjust the number of columns in grid view mode.": "" "Adjust the number of columns in grid view mode.": "グリッド表示モードでの列数を調整します。"
}, },
"All": { "All": {
"All": "全て" "All": "全て"
@@ -75,7 +75,7 @@
"Always Show OSD Percentage": "常に OSD パーセンテージを表示" "Always Show OSD Percentage": "常に OSD パーセンテージを表示"
}, },
"Always on icons": { "Always on icons": {
"Always on icons": "" "Always on icons": "常時表示アイコン"
}, },
"Always show a minimum of 3 workspaces, even if fewer are available": { "Always show a minimum of 3 workspaces, even if fewer are available": {
"Always show a minimum of 3 workspaces, even if fewer are available": "使用可能なワークスペースが少ない場合でも、常に最低 3 つを表示" "Always show a minimum of 3 workspaces, even if fewer are available": "使用可能なワークスペースが少ない場合でも、常に最低 3 つを表示"
@@ -275,6 +275,9 @@
"Brightness": { "Brightness": {
"Brightness": "明るさ" "Brightness": "明るさ"
}, },
"Brightness OSD": {
"Brightness OSD": "明るさOSD"
},
"Browse": { "Browse": {
"Browse": "ブラウズ" "Browse": "ブラウズ"
}, },
@@ -303,7 +306,7 @@
"CUPS Missing Filter Warning": "CUPS の欠落フィルターの警告" "CUPS Missing Filter Warning": "CUPS の欠落フィルターの警告"
}, },
"Camera": { "Camera": {
"Camera": "" "Camera": "カメラ"
}, },
"Cancel": { "Cancel": {
"Cancel": "キャンセル" "Cancel": "キャンセル"
@@ -314,6 +317,9 @@
"Caps Lock Indicator": { "Caps Lock Indicator": {
"Caps Lock Indicator": "Caps Lock インジケーター" "Caps Lock Indicator": "Caps Lock インジケーター"
}, },
"Caps Lock OSD": {
"Caps Lock OSD": "Caps Lock OSD"
},
"Center Section": { "Center Section": {
"Center Section": "センターセクション" "Center Section": "センターセクション"
}, },
@@ -341,6 +347,9 @@
"Choose where notification popups appear on screen": { "Choose where notification popups appear on screen": {
"Choose where notification popups appear on screen": "通知ポップアップが画面に表示される場所を選ぶ" "Choose where notification popups appear on screen": "通知ポップアップが画面に表示される場所を選ぶ"
}, },
"Choose where on-screen displays appear on screen": {
"Choose where on-screen displays appear on screen": ""
},
"Clear": { "Clear": {
"Clear": "クリア" "Clear": "クリア"
}, },
@@ -617,6 +626,9 @@
"Dismiss": { "Dismiss": {
"Dismiss": "解除" "Dismiss": "解除"
}, },
"Display Name Format": {
"Display Name Format": ""
},
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": { "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": {
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "画面の上、下、左、右の端に配置できる、ピン留めされた実行中のアプリケーションを含むドックを表示します" "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "画面の上、下、左、右の端に配置できる、ピン留めされた実行中のアプリケーションを含むドックを表示します"
}, },
@@ -674,6 +686,9 @@
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": { "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": {
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "ウィジェットをドラッグしてセクション内で順序を変更できます。目のアイコンでウィジェットを表示/非表示にスペースは維持、Xで完全に削除できます。" "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "ウィジェットをドラッグしてセクション内で順序を変更できます。目のアイコンでウィジェットを表示/非表示にスペースは維持、Xで完全に削除できます。"
}, },
"Duplicate Wallpaper with Blur": {
"Duplicate Wallpaper with Blur": ""
},
"Duration": { "Duration": {
"Duration": "期間" "Duration": "期間"
}, },
@@ -900,7 +915,7 @@
"Grid": "グリッド" "Grid": "グリッド"
}, },
"Grid Columns": { "Grid Columns": {
"Grid Columns": "" "Grid Columns": "グリッド列"
}, },
"Group by App": { "Group by App": {
"Group by App": "アプリ別にグループ化" "Group by App": "アプリ別にグループ化"
@@ -924,7 +939,7 @@
"Hibernate": "休止状態" "Hibernate": "休止状態"
}, },
"Hide Delay (ms)": { "Hide Delay (ms)": {
"Hide Delay (ms)": "" "Hide Delay (ms)": "遅延を隠す (ms)"
}, },
"Hide the dock when not in use and reveal it when hovering near the dock area": { "Hide the dock when not in use and reveal it when hovering near the dock area": {
"Hide the dock when not in use and reveal it when hovering near the dock area": "使用していないときはドックを非表示にし、ドックエリアの近くにホバーすると表示されます" "Hide the dock when not in use and reveal it when hovering near the dock area": "使用していないときはドックを非表示にし、ドックエリアの近くにホバーすると表示されます"
@@ -959,6 +974,9 @@
"Idle Inhibitor": { "Idle Inhibitor": {
"Idle Inhibitor": "アイドルインヒビター" "Idle Inhibitor": "アイドルインヒビター"
}, },
"Idle Inhibitor OSD": {
"Idle Inhibitor OSD": "アイドルインヒビターOSD"
},
"Idle Settings": { "Idle Settings": {
"Idle Settings": "アイドル設定" "Idle Settings": "アイドル設定"
}, },
@@ -1173,7 +1191,10 @@
"Memory usage indicator": "メモリ使用率インジケーター" "Memory usage indicator": "メモリ使用率インジケーター"
}, },
"Microphone": { "Microphone": {
"Microphone": "" "Microphone": "マイク"
},
"Microphone Mute OSD": {
"Microphone Mute OSD": "マイクミュートOSD"
}, },
"Minimal palette built around a single hue.": { "Minimal palette built around a single hue.": {
"Minimal palette built around a single hue.": "単一の色相を中心に構築された最小限のパレット。" "Minimal palette built around a single hue.": "単一の色相を中心に構築された最小限のパレット。"
@@ -1187,6 +1208,9 @@
"Mode: ": { "Mode: ": {
"Mode: ": "モード: " "Mode: ": "モード: "
}, },
"Model": {
"Model": ""
},
"Monitor Selection:": { "Monitor Selection:": {
"Monitor Selection:": "モニターの選択:" "Monitor Selection:": "モニターの選択:"
}, },
@@ -1211,6 +1235,9 @@
"NM not supported": { "NM not supported": {
"NM not supported": "NMが利用できません" "NM not supported": "NMが利用できません"
}, },
"Name": {
"Name": ""
},
"Named Workspace Icons": { "Named Workspace Icons": {
"Named Workspace Icons": "名前付きワークスペースアイコン" "Named Workspace Icons": "名前付きワークスペースアイコン"
}, },
@@ -1337,6 +1364,9 @@
"OS Logo": { "OS Logo": {
"OS Logo": "OSロゴ" "OS Logo": "OSロゴ"
}, },
"OSD Position": {
"OSD Position": ""
},
"Office": { "Office": {
"Office": "オフィス" "Office": "オフィス"
}, },
@@ -1346,6 +1376,9 @@
"On-Screen Displays": { "On-Screen Displays": {
"On-Screen Displays": "オンスクリーンディスプレイ" "On-Screen Displays": "オンスクリーンディスプレイ"
}, },
"On-screen Displays": {
"On-screen Displays": "オンスクリーンディスプレイ"
},
"Only adjust gamma based on time or location rules.": { "Only adjust gamma based on time or location rules.": {
"Only adjust gamma based on time or location rules.": "ガンマは、時間または場所のルールに基づいてのみ調整します。" "Only adjust gamma based on time or location rules.": "ガンマは、時間または場所のルールに基づいてのみ調整します。"
}, },
@@ -1493,6 +1526,9 @@
"Power Profile Degradation": { "Power Profile Degradation": {
"Power Profile Degradation": "電源プロファイルの劣化" "Power Profile Degradation": "電源プロファイルの劣化"
}, },
"Power Profile OSD": {
"Power Profile OSD": "電源プロファイルOSD"
},
"Pressure": { "Pressure": {
"Pressure": "プレッシャー" "Pressure": "プレッシャー"
}, },
@@ -1647,7 +1683,7 @@
"Science": "科学" "Science": "科学"
}, },
"Screen sharing": { "Screen sharing": {
"Screen sharing": "" "Screen sharing": "画面共有"
}, },
"Scrolling": { "Scrolling": {
"Scrolling": "スクロール" "Scrolling": "スクロール"
@@ -1781,6 +1817,24 @@
"Show on screens:": { "Show on screens:": {
"Show on screens:": "画面に表示:" "Show on screens:": "画面に表示:"
}, },
"Show on-screen display when brightness changes": {
"Show on-screen display when brightness changes": "明るさが変化した時にOSDを表示"
},
"Show on-screen display when caps lock state changes": {
"Show on-screen display when caps lock state changes": "Caps Lock の状態が変化した時にOSDを表示"
},
"Show on-screen display when idle inhibitor state changes": {
"Show on-screen display when idle inhibitor state changes": "アイドルインヒビターの状態が変化した時にOSDを表示"
},
"Show on-screen display when microphone is muted/unmuted": {
"Show on-screen display when microphone is muted/unmuted": "マイクがミュート/ミュート解除された時にOSDを表示"
},
"Show on-screen display when power profile changes": {
"Show on-screen display when power profile changes": "電源プロファイルが変化した時にOSDを表示"
},
"Show on-screen display when volume changes": {
"Show on-screen display when volume changes": "音量が変化したときにOSDを表示"
},
"Show only apps running in current workspace": { "Show only apps running in current workspace": {
"Show only apps running in current workspace": "現在のワークスペースで実行されているアプリのみを表示" "Show only apps running in current workspace": "現在のワークスペースで実行されているアプリのみを表示"
}, },
@@ -2141,6 +2195,9 @@
"Volume Changed": { "Volume Changed": {
"Volume Changed": "音量変更" "Volume Changed": "音量変更"
}, },
"Volume OSD": {
"Volume OSD": "音量OSD"
},
"Volume, brightness, and other system OSDs": { "Volume, brightness, and other system OSDs": {
"Volume, brightness, and other system OSDs": "音量、明るさ、その他のシステム OSD" "Volume, brightness, and other system OSDs": "音量、明るさ、その他のシステム OSD"
}, },

View File

@@ -30,7 +30,7 @@
"A file with this name already exists. Do you want to overwrite it?": "Plik o takiej nazwie już istnieje. Czy chcesz go nadpisać?" "A file with this name already exists. Do you want to overwrite it?": "Plik o takiej nazwie już istnieje. Czy chcesz go nadpisać?"
}, },
"About": { "About": {
"About": "O..." "About": "O programie"
}, },
"Access clipboard history": { "Access clipboard history": {
"Access clipboard history": "Dostęp do historii schowka" "Access clipboard history": "Dostęp do historii schowka"
@@ -57,7 +57,7 @@
"Add a VPN in NetworkManager": "Dodaj sieć VPN w NetworkManager" "Add a VPN in NetworkManager": "Dodaj sieć VPN w NetworkManager"
}, },
"Adjust the number of columns in grid view mode.": { "Adjust the number of columns in grid view mode.": {
"Adjust the number of columns in grid view mode.": "" "Adjust the number of columns in grid view mode.": "Dostosuj liczbę kolumn w widoku siatki."
}, },
"All": { "All": {
"All": "Wszystkie" "All": "Wszystkie"
@@ -66,16 +66,16 @@
"All day": "Cały dzień" "All day": "Cały dzień"
}, },
"All displays": { "All displays": {
"All displays": "Wszystkie wyświetlacze" "All displays": "Wszystkie ekrany"
}, },
"Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": { "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" "Alt+←/Backspace: Back • F1/I: File Info • F10: Help • Esc: Close": "Alt+←/Backspace: Wstecz • F1/I: Informacje o pliku • F10: Pomoc • Esc: Zamknij"
}, },
"Always Show OSD Percentage": { "Always Show OSD Percentage": {
"Always Show OSD Percentage": "Zawsze pokazuj procent OSD" "Always Show OSD Percentage": "Zawsze pokazuj procent w OSD"
}, },
"Always on icons": { "Always on icons": {
"Always on icons": "" "Always on icons": "Ikony zawsze włączone"
}, },
"Always show a minimum of 3 workspaces, even if fewer are available": { "Always show a minimum of 3 workspaces, even if fewer are available": {
"Always show a minimum of 3 workspaces, even if fewer are available": "Zawsze pokazuj co najmniej 3 obszary robocze, nawet jeśli jest ich mniej." "Always show a minimum of 3 workspaces, even if fewer are available": "Zawsze pokazuj co najmniej 3 obszary robocze, nawet jeśli jest ich mniej."
@@ -87,7 +87,7 @@
"Anonymous Identity (optional)": "Tożsamość anonimowa (opcjonalnie)" "Anonymous Identity (optional)": "Tożsamość anonimowa (opcjonalnie)"
}, },
"App Launcher": { "App Launcher": {
"App Launcher": "App Launcher" "App Launcher": "Program Uruchamiający"
}, },
"Application Dock": { "Application Dock": {
"Application Dock": "Aplikacja Dok" "Application Dock": "Aplikacja Dok"
@@ -171,7 +171,7 @@
"Auto-hide Dock": "Automatyczne ukrywanie doku" "Auto-hide Dock": "Automatyczne ukrywanie doku"
}, },
"Auto-saving...": { "Auto-saving...": {
"Auto-saving...": "Automatyczne zapisywanie..." "Auto-saving...": "Automatyczny zapis..."
}, },
"Autoconnect disabled": { "Autoconnect disabled": {
"Autoconnect disabled": "Automatyczne łączenie wyłączone" "Autoconnect disabled": "Automatyczne łączenie wyłączone"
@@ -183,13 +183,13 @@
"Automatic Control": "Automatyczna kontrola" "Automatic Control": "Automatyczna kontrola"
}, },
"Automatic Cycling": { "Automatic Cycling": {
"Automatic Cycling": "Automatyczne przełączanie" "Automatic Cycling": "Automatyczne cykl"
}, },
"Automatically calculate popup distance from bar edge.": { "Automatically calculate popup distance from bar edge.": {
"Automatically calculate popup distance from bar edge.": "Automatycznie obliczaj odległość wyskakującego okienka od krawędzi paska." "Automatically calculate popup distance from bar edge.": "Automatycznie obliczaj odległość wyskakującego okienka od krawędzi paska."
}, },
"Automatically cycle through wallpapers in the same folder": { "Automatically cycle through wallpapers in the same folder": {
"Automatically cycle through wallpapers in the same folder": "Automatycznie zmieniaj tapety z tego samego folderu" "Automatically cycle through wallpapers in the same folder": "Automatycznie zmieniaj tapety z tego samego katalogu"
}, },
"Automatically detect location based on IP address": { "Automatically detect location based on IP address": {
"Automatically detect location based on IP address": "Automatycznie wykrywaj lokalizację na podstawie adresu IP" "Automatically detect location based on IP address": "Automatycznie wykrywaj lokalizację na podstawie adresu IP"
@@ -198,7 +198,7 @@
"Automatically determine your location using your IP address": "Automatycznie określ swoją lokalizację na podstawie adresu IP" "Automatically determine your location using your IP address": "Automatycznie określ swoją lokalizację na podstawie adresu IP"
}, },
"Automatically extract colors from wallpaper": { "Automatically extract colors from wallpaper": {
"Automatically extract colors from wallpaper": "Automatycznie dopasuj kolory z tapety" "Automatically extract colors from wallpaper": "Automatycznie wyciągnij kolory z tapety"
}, },
"Automatically hide the top bar to expand screen real estate": { "Automatically hide the top bar to expand screen real estate": {
"Automatically hide the top bar to expand screen real estate": "Automatycznie ukryj górny pasek, aby zwiększyć powierzchnię ekranu" "Automatically hide the top bar to expand screen real estate": "Automatycznie ukryj górny pasek, aby zwiększyć powierzchnię ekranu"
@@ -252,7 +252,7 @@
"Blur wallpaper when niri overview is open": "Rozmyj tapetę, gdy podgląd niri jest otwarty" "Blur wallpaper when niri overview is open": "Rozmyj tapetę, gdy podgląd niri jest otwarty"
}, },
"Border": { "Border": {
"Border": "Obramowanie" "Border": "Ramka"
}, },
"Border Color": { "Border Color": {
"Border Color": "Kolor obramowania" "Border Color": "Kolor obramowania"
@@ -275,6 +275,9 @@
"Brightness": { "Brightness": {
"Brightness": "Jasność" "Brightness": "Jasność"
}, },
"Brightness OSD": {
"Brightness OSD": "OSD Jasności"
},
"Browse": { "Browse": {
"Browse": "Przeglądaj" "Browse": "Przeglądaj"
}, },
@@ -291,7 +294,7 @@
"CPU Usage": "Użycie CPU" "CPU Usage": "Użycie CPU"
}, },
"CPU temperature display": { "CPU temperature display": {
"CPU temperature display": "Temperatura CPU" "CPU temperature display": "Wskaźnik temperatury procesora"
}, },
"CPU usage indicator": { "CPU usage indicator": {
"CPU usage indicator": "Wskaźnik użycia procesora" "CPU usage indicator": "Wskaźnik użycia procesora"
@@ -303,7 +306,7 @@
"CUPS Missing Filter Warning": "CUPS: Ostrzeżenie o brakującym filtrze" "CUPS Missing Filter Warning": "CUPS: Ostrzeżenie o brakującym filtrze"
}, },
"Camera": { "Camera": {
"Camera": "" "Camera": "Kamera"
}, },
"Cancel": { "Cancel": {
"Cancel": "Anuluj" "Cancel": "Anuluj"
@@ -312,7 +315,10 @@
"Capacity": "Pojemność" "Capacity": "Pojemność"
}, },
"Caps Lock Indicator": { "Caps Lock Indicator": {
"Caps Lock Indicator": "" "Caps Lock Indicator": "Wskaźnik caps locka"
},
"Caps Lock OSD": {
"Caps Lock OSD": "OSD Caps Lock"
}, },
"Center Section": { "Center Section": {
"Center Section": "Sekcja środkowa" "Center Section": "Sekcja środkowa"
@@ -339,7 +345,10 @@
"Choose the logo displayed on the launcher button in DankBar": "Wybierz logo wyświetlane na przycisku launchera w DankBar" "Choose the logo displayed on the launcher button in DankBar": "Wybierz logo wyświetlane na przycisku launchera w DankBar"
}, },
"Choose where notification popups appear on screen": { "Choose where notification popups appear on screen": {
"Choose where notification popups appear on screen": "Wybierz, gdzie na ekranie mają pojawiać się wyskakujące powiadomienia" "Choose where notification popups appear on screen": "Wybierz, gdzie na ekranie mają pojawiać się powiadomienia"
},
"Choose where on-screen displays appear on screen": {
"Choose where on-screen displays appear on screen": ""
}, },
"Clear": { "Clear": {
"Clear": "Wyczyść" "Clear": "Wyczyść"
@@ -435,7 +444,7 @@
"Connect to Wi-Fi": "Połącz z siecią Wi-Fi" "Connect to Wi-Fi": "Połącz z siecią Wi-Fi"
}, },
"Connected Displays": { "Connected Displays": {
"Connected Displays": "Podłączone wyświetlacze" "Connected Displays": "Podłączone ekrany"
}, },
"Connecting to Device": { "Connecting to Device": {
"Connecting to Device": "Łączenie z urządzeniem" "Connecting to Device": "Łączenie z urządzeniem"
@@ -447,7 +456,7 @@
"Control Center": "Centrum sterowania" "Control Center": "Centrum sterowania"
}, },
"Control currently playing media": { "Control currently playing media": {
"Control currently playing media": "Steruj aktualnie odtwarzanymi mediami" "Control currently playing media": "Steruj aktualnie odtwarzanymi multimediami"
}, },
"Controls opacity of all popouts, modals, and their content layers (DankDash, Settings, App Drawer, Control Center, etc.)": { "Controls opacity of all popouts, modals, and their content layers (DankDash, Settings, App Drawer, Control Center, etc.)": {
"Controls opacity of all popouts, modals, and their content layers (DankDash, Settings, App Drawer, Control Center, etc.)": "Kontroluje przezroczystość wszystkich wyskakujących okienek, okien modalnych i ich warstw zawartości (DankDash, Ustawienia, Szuflada aplikacji, Centrum sterowania itp.)" "Controls opacity of all popouts, modals, and their content layers (DankDash, Settings, App Drawer, Control Center, etc.)": "Kontroluje przezroczystość wszystkich wyskakujących okienek, okien modalnych i ich warstw zawartości (DankDash, Ustawienia, Szuflada aplikacji, Centrum sterowania itp.)"
@@ -617,6 +626,9 @@
"Dismiss": { "Dismiss": {
"Dismiss": "Odrzuć" "Dismiss": "Odrzuć"
}, },
"Display Name Format": {
"Display Name Format": ""
},
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": { "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": {
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Wyświetla dok z przypiętymi i uruchomionymi aplikacjami, który można umieścić na górze, na dole, po lewej lub po prawej stronie ekranu." "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Wyświetla dok z przypiętymi i uruchomionymi aplikacjami, który można umieścić na górze, na dole, po lewej lub po prawej stronie ekranu."
}, },
@@ -633,7 +645,7 @@
"Display currently focused application title": "Wyświetlaj tytuł aktywnej aplikacji" "Display currently focused application title": "Wyświetlaj tytuł aktywnej aplikacji"
}, },
"Display power menu actions in a grid instead of a list": { "Display power menu actions in a grid instead of a list": {
"Display power menu actions in a grid instead of a list": "" "Display power menu actions in a grid instead of a list": "Wyświetl elementy menu zasilania w siatce zamiast listy"
}, },
"Display settings for ": { "Display settings for ": {
"Display settings for ": "Ustawienia wyświetlania dla " "Display settings for ": "Ustawienia wyświetlania dla "
@@ -642,7 +654,7 @@
"Display volume and brightness percentage values by default in OSD popups": "Domyślnie wyświetlaj wartości procentowe głośności i jasności w wyskakujących okienkach OSD" "Display volume and brightness percentage values by default in OSD popups": "Domyślnie wyświetlaj wartości procentowe głośności i jasności w wyskakujących okienkach OSD"
}, },
"Displays": { "Displays": {
"Displays": "Wyświetlacze" "Displays": "Ekrany"
}, },
"Displays the active keyboard layout and allows switching": { "Displays the active keyboard layout and allows switching": {
"Displays the active keyboard layout and allows switching": "Wyświetla aktywny układ klawiatury i umożliwia przełączanie" "Displays the active keyboard layout and allows switching": "Wyświetla aktywny układ klawiatury i umożliwia przełączanie"
@@ -674,6 +686,9 @@
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": { "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": {
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Przeciągnij widżety, aby zmienić kolejność w sekcjach. Użyj ikony oka, aby ukryć/pokazać widżety (zachowując odstępy), lub X, aby je całkowicie usunąć." "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Przeciągnij widżety, aby zmienić kolejność w sekcjach. Użyj ikony oka, aby ukryć/pokazać widżety (zachowując odstępy), lub X, aby je całkowicie usunąć."
}, },
"Duplicate Wallpaper with Blur": {
"Duplicate Wallpaper with Blur": ""
},
"Duration": { "Duration": {
"Duration": "Czas trwania" "Duration": "Czas trwania"
}, },
@@ -828,13 +843,13 @@
"Focused Window": "Aktywne okno" "Focused Window": "Aktywne okno"
}, },
"Font Family": { "Font Family": {
"Font Family": "Rodzina czcionek" "Font Family": "Rodzina czcionki"
}, },
"Font Scale": { "Font Scale": {
"Font Scale": "Skala czcionki" "Font Scale": "Skala czcionki"
}, },
"Font Settings": { "Font Settings": {
"Font Settings": "Ustawienia czcionek" "Font Settings": "Ustawienia czcionki"
}, },
"Font Size": { "Font Size": {
"Font Size": "Rozmiar czcionki" "Font Size": "Rozmiar czcionki"
@@ -846,7 +861,7 @@
"Force Kill Process": "Wymuś zamknięcie procesu" "Force Kill Process": "Wymuś zamknięcie procesu"
}, },
"Force terminal applications to always use dark color schemes": { "Force terminal applications to always use dark color schemes": {
"Force terminal applications to always use dark color schemes": "" "Force terminal applications to always use dark color schemes": "Wymuś ciemny motyw na aplikacjach terminala"
}, },
"Forget Device": { "Forget Device": {
"Forget Device": "Zapomnij urządzenie" "Forget Device": "Zapomnij urządzenie"
@@ -870,7 +885,7 @@
"GPU Temperature": "Temperatura GPU" "GPU Temperature": "Temperatura GPU"
}, },
"GPU temperature display": { "GPU temperature display": {
"GPU temperature display": "Wyświetlanie temperatury GPU" "GPU temperature display": "Wskaźnik temperatury GPU"
}, },
"Games": { "Games": {
"Games": "Gry" "Games": "Gry"
@@ -900,7 +915,7 @@
"Grid": "Siatka" "Grid": "Siatka"
}, },
"Grid Columns": { "Grid Columns": {
"Grid Columns": "" "Grid Columns": "Kolumny siatki"
}, },
"Group by App": { "Group by App": {
"Group by App": "Grupuj według aplikacji" "Group by App": "Grupuj według aplikacji"
@@ -924,7 +939,7 @@
"Hibernate": "Hibernacja" "Hibernate": "Hibernacja"
}, },
"Hide Delay (ms)": { "Hide Delay (ms)": {
"Hide Delay (ms)": "" "Hide Delay (ms)": "Opóźnienie ukrycia (ms)"
}, },
"Hide the dock when not in use and reveal it when hovering near the dock area": { "Hide the dock when not in use and reveal it when hovering near the dock area": {
"Hide the dock when not in use and reveal it when hovering near the dock area": "Ukryj dok, gdy nie jest używany, i odkryj go po najechaniu kursorem w jego pobliże" "Hide the dock when not in use and reveal it when hovering near the dock area": "Ukryj dok, gdy nie jest używany, i odkryj go po najechaniu kursorem w jego pobliże"
@@ -959,6 +974,9 @@
"Idle Inhibitor": { "Idle Inhibitor": {
"Idle Inhibitor": "Inhibitor bezczynności" "Idle Inhibitor": "Inhibitor bezczynności"
}, },
"Idle Inhibitor OSD": {
"Idle Inhibitor OSD": "OSD Inhibitora Bezczynności"
},
"Idle Settings": { "Idle Settings": {
"Idle Settings": "Ustawienia bezczynności" "Idle Settings": "Ustawienia bezczynności"
}, },
@@ -1074,7 +1092,7 @@
"Location Search": "Wyszukiwanie lokalizacji" "Location Search": "Wyszukiwanie lokalizacji"
}, },
"Lock": { "Lock": {
"Lock": "Zamek" "Lock": "Zablokuj"
}, },
"Lock Screen": { "Lock Screen": {
"Lock Screen": "Ekran blokady" "Lock Screen": "Ekran blokady"
@@ -1173,7 +1191,10 @@
"Memory usage indicator": "Wskaźnik zużycia pamięci" "Memory usage indicator": "Wskaźnik zużycia pamięci"
}, },
"Microphone": { "Microphone": {
"Microphone": "" "Microphone": "Mikrofon"
},
"Microphone Mute OSD": {
"Microphone Mute OSD": "OSD Wyciszenia Mikrofonu"
}, },
"Minimal palette built around a single hue.": { "Minimal palette built around a single hue.": {
"Minimal palette built around a single hue.": "Minimalna paleta zbudowana wokół jednego odcienia." "Minimal palette built around a single hue.": "Minimalna paleta zbudowana wokół jednego odcienia."
@@ -1187,6 +1208,9 @@
"Mode: ": { "Mode: ": {
"Mode: ": "Tryb: " "Mode: ": "Tryb: "
}, },
"Model": {
"Model": ""
},
"Monitor Selection:": { "Monitor Selection:": {
"Monitor Selection:": "Wybór monitora:" "Monitor Selection:": "Wybór monitora:"
}, },
@@ -1211,6 +1235,9 @@
"NM not supported": { "NM not supported": {
"NM not supported": "NM nie jest obsługiwany" "NM not supported": "NM nie jest obsługiwany"
}, },
"Name": {
"Name": ""
},
"Named Workspace Icons": { "Named Workspace Icons": {
"Named Workspace Icons": "Ikony nazwanych obszarów roboczych" "Named Workspace Icons": "Ikony nazwanych obszarów roboczych"
}, },
@@ -1337,6 +1364,9 @@
"OS Logo": { "OS Logo": {
"OS Logo": "Logo OS" "OS Logo": "Logo OS"
}, },
"OSD Position": {
"OSD Position": ""
},
"Office": { "Office": {
"Office": "Biuro" "Office": "Biuro"
}, },
@@ -1346,6 +1376,9 @@
"On-Screen Displays": { "On-Screen Displays": {
"On-Screen Displays": "Wyświetlacze ekranowe" "On-Screen Displays": "Wyświetlacze ekranowe"
}, },
"On-screen Displays": {
"On-screen Displays": "Powiadomienia ekranowe"
},
"Only adjust gamma based on time or location rules.": { "Only adjust gamma based on time or location rules.": {
"Only adjust gamma based on time or location rules.": "Dostosuj gamma tylko na podstawie reguł czasu lub lokalizacji." "Only adjust gamma based on time or location rules.": "Dostosuj gamma tylko na podstawie reguł czasu lub lokalizacji."
}, },
@@ -1493,6 +1526,9 @@
"Power Profile Degradation": { "Power Profile Degradation": {
"Power Profile Degradation": "Pogorszenie profilu zasilania" "Power Profile Degradation": "Pogorszenie profilu zasilania"
}, },
"Power Profile OSD": {
"Power Profile OSD": "OSD Profilu Zasilania"
},
"Pressure": { "Pressure": {
"Pressure": "Ciśnienie" "Pressure": "Ciśnienie"
}, },
@@ -1647,7 +1683,7 @@
"Science": "Nauka" "Science": "Nauka"
}, },
"Screen sharing": { "Screen sharing": {
"Screen sharing": "" "Screen sharing": "Udostępnianie ekranu"
}, },
"Scrolling": { "Scrolling": {
"Scrolling": "Przewijanie" "Scrolling": "Przewijanie"
@@ -1781,6 +1817,24 @@
"Show on screens:": { "Show on screens:": {
"Show on screens:": "Pokaż na ekranach:" "Show on screens:": "Pokaż na ekranach:"
}, },
"Show on-screen display when brightness changes": {
"Show on-screen display when brightness changes": "Wyświetlaj powiadomienie ekranowe przy zmianie jasności"
},
"Show on-screen display when caps lock state changes": {
"Show on-screen display when caps lock state changes": "Wyświetlaj powiadomienie ekranowe przy zmianie stanu Caps Lock"
},
"Show on-screen display when idle inhibitor state changes": {
"Show on-screen display when idle inhibitor state changes": "Wyświetlaj powiadomienie ekranowe przy zmianie stanu inhibitora bezczynności"
},
"Show on-screen display when microphone is muted/unmuted": {
"Show on-screen display when microphone is muted/unmuted": "Wyświetlaj powiadomienie ekranowe przy wyciszaniu/włączaniu mikrofonu"
},
"Show on-screen display when power profile changes": {
"Show on-screen display when power profile changes": "Wyświetlaj powiadomienie ekranowe przy zmianie profilu zasilania"
},
"Show on-screen display when volume changes": {
"Show on-screen display when volume changes": "Wyświetlaj powiadomienie ekranowe przy zmianie głośności"
},
"Show only apps running in current workspace": { "Show only apps running in current workspace": {
"Show only apps running in current workspace": "Pokaż tylko aplikacje uruchomione w bieżącym obszarze roboczym" "Show only apps running in current workspace": "Pokaż tylko aplikacje uruchomione w bieżącym obszarze roboczym"
}, },
@@ -1809,7 +1863,7 @@
"Shows current workspace and allows switching": "Pokazuje bieżący obszar roboczy i pozwala na przełączanie" "Shows current workspace and allows switching": "Pokazuje bieżący obszar roboczy i pozwala na przełączanie"
}, },
"Shows when caps lock is active": { "Shows when caps lock is active": {
"Shows when caps lock is active": "" "Shows when caps lock is active": "Pojawia się gdy 'Caps Lock' jest aktywny"
}, },
"Shows when microphone, camera, or screen sharing is active": { "Shows when microphone, camera, or screen sharing is active": {
"Shows when microphone, camera, or screen sharing is active": "Pokazuje, gdy mikrofon, kamera lub udostępnianie ekranu są aktywne" "Shows when microphone, camera, or screen sharing is active": "Pokazuje, gdy mikrofon, kamera lub udostępnianie ekranu są aktywne"
@@ -1938,7 +1992,7 @@
"Terminal custom additional parameters": "Niestandardowe dodatkowe parametry terminala" "Terminal custom additional parameters": "Niestandardowe dodatkowe parametry terminala"
}, },
"Terminals - Always use Dark Theme": { "Terminals - Always use Dark Theme": {
"Terminals - Always use Dark Theme": "" "Terminals - Always use Dark Theme": "Terminal - Zawsze używaj ciemnego motywu"
}, },
"Text": { "Text": {
"Text": "Tekst" "Text": "Tekst"
@@ -2055,16 +2109,16 @@
"Use Fahrenheit instead of Celsius for temperature": "Użyj Fahrenheita zamiast Celsjusza dla temperatury" "Use Fahrenheit instead of Celsius for temperature": "Użyj Fahrenheita zamiast Celsjusza dla temperatury"
}, },
"Use Grid Layout": { "Use Grid Layout": {
"Use Grid Layout": "" "Use Grid Layout": "Użyj układu siatki"
}, },
"Use IP Location": { "Use IP Location": {
"Use IP Location": "Użyj lokalizacji IP" "Use IP Location": "Użyj lokalizacji IP"
}, },
"Use Imperial Units": { "Use Imperial Units": {
"Use Imperial Units": "" "Use Imperial Units": "Użyj imperialnych jednostek"
}, },
"Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": { "Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": {
"Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": "" "Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": "Użyj imperialnych jednostek (°F, mph, inHg) zamiast metrycznych (°C, km/h, hPa)"
}, },
"Use Monospace Font": { "Use Monospace Font": {
"Use Monospace Font": "Użyj czcionki o stałej szerokości" "Use Monospace Font": "Użyj czcionki o stałej szerokości"
@@ -2141,6 +2195,9 @@
"Volume Changed": { "Volume Changed": {
"Volume Changed": "Zmieniony wolumen" "Volume Changed": "Zmieniony wolumen"
}, },
"Volume OSD": {
"Volume OSD": "OSD Głośności"
},
"Volume, brightness, and other system OSDs": { "Volume, brightness, and other system OSDs": {
"Volume, brightness, and other system OSDs": "Głośność, jasność i inne systemowe menu ekranowe" "Volume, brightness, and other system OSDs": "Głośność, jasność i inne systemowe menu ekranowe"
}, },

View File

@@ -275,6 +275,9 @@
"Brightness": { "Brightness": {
"Brightness": "Brilho" "Brightness": "Brilho"
}, },
"Brightness OSD": {
"Brightness OSD": ""
},
"Browse": { "Browse": {
"Browse": "Navegar" "Browse": "Navegar"
}, },
@@ -314,6 +317,9 @@
"Caps Lock Indicator": { "Caps Lock Indicator": {
"Caps Lock Indicator": "" "Caps Lock Indicator": ""
}, },
"Caps Lock OSD": {
"Caps Lock OSD": ""
},
"Center Section": { "Center Section": {
"Center Section": "Seção Central" "Center Section": "Seção Central"
}, },
@@ -341,6 +347,9 @@
"Choose where notification popups appear on screen": { "Choose where notification popups appear on screen": {
"Choose where notification popups appear on screen": "Escolher onde as notificações irão aparecer na tela" "Choose where notification popups appear on screen": "Escolher onde as notificações irão aparecer na tela"
}, },
"Choose where on-screen displays appear on screen": {
"Choose where on-screen displays appear on screen": ""
},
"Clear": { "Clear": {
"Clear": "Limpar" "Clear": "Limpar"
}, },
@@ -617,6 +626,9 @@
"Dismiss": { "Dismiss": {
"Dismiss": "Descartar" "Dismiss": "Descartar"
}, },
"Display Name Format": {
"Display Name Format": ""
},
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": { "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": {
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Exibir um dock com aplicativos que estão sendo utilizados, e que pode ser posicionada no superior, inferior, esquerda ou direita dos cantos da tela" "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Exibir um dock com aplicativos que estão sendo utilizados, e que pode ser posicionada no superior, inferior, esquerda ou direita dos cantos da tela"
}, },
@@ -674,6 +686,9 @@
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": { "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": {
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Arraste Widgets para reordená-los nas seções. Use o ícone de olho para esconder ou mostrá-los (manter o espaçamento), ou clique no X para removê-los por completo." "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Arraste Widgets para reordená-los nas seções. Use o ícone de olho para esconder ou mostrá-los (manter o espaçamento), ou clique no X para removê-los por completo."
}, },
"Duplicate Wallpaper with Blur": {
"Duplicate Wallpaper with Blur": ""
},
"Duration": { "Duration": {
"Duration": "Duração" "Duration": "Duração"
}, },
@@ -959,6 +974,9 @@
"Idle Inhibitor": { "Idle Inhibitor": {
"Idle Inhibitor": "Inibitor de inatividade" "Idle Inhibitor": "Inibitor de inatividade"
}, },
"Idle Inhibitor OSD": {
"Idle Inhibitor OSD": ""
},
"Idle Settings": { "Idle Settings": {
"Idle Settings": "Configurações de inatividade" "Idle Settings": "Configurações de inatividade"
}, },
@@ -1175,6 +1193,9 @@
"Microphone": { "Microphone": {
"Microphone": "" "Microphone": ""
}, },
"Microphone Mute OSD": {
"Microphone Mute OSD": ""
},
"Minimal palette built around a single hue.": { "Minimal palette built around a single hue.": {
"Minimal palette built around a single hue.": "Paleta mínima construída ao redor de um único tom." "Minimal palette built around a single hue.": "Paleta mínima construída ao redor de um único tom."
}, },
@@ -1187,6 +1208,9 @@
"Mode: ": { "Mode: ": {
"Mode: ": "" "Mode: ": ""
}, },
"Model": {
"Model": ""
},
"Monitor Selection:": { "Monitor Selection:": {
"Monitor Selection:": "Seleção de Monitor:" "Monitor Selection:": "Seleção de Monitor:"
}, },
@@ -1211,6 +1235,9 @@
"NM not supported": { "NM not supported": {
"NM not supported": "NM não suportado" "NM not supported": "NM não suportado"
}, },
"Name": {
"Name": ""
},
"Named Workspace Icons": { "Named Workspace Icons": {
"Named Workspace Icons": "Ícones de Áreas de Trabalho Nomeadas" "Named Workspace Icons": "Ícones de Áreas de Trabalho Nomeadas"
}, },
@@ -1337,6 +1364,9 @@
"OS Logo": { "OS Logo": {
"OS Logo": "Logo do SO" "OS Logo": "Logo do SO"
}, },
"OSD Position": {
"OSD Position": ""
},
"Office": { "Office": {
"Office": "Escritório" "Office": "Escritório"
}, },
@@ -1346,6 +1376,9 @@
"On-Screen Displays": { "On-Screen Displays": {
"On-Screen Displays": "Displays na Tela (OSDs)" "On-Screen Displays": "Displays na Tela (OSDs)"
}, },
"On-screen Displays": {
"On-screen Displays": ""
},
"Only adjust gamma based on time or location rules.": { "Only adjust gamma based on time or location rules.": {
"Only adjust gamma based on time or location rules.": "Apenas ajustar gama baseada em regras de tempo ou localização." "Only adjust gamma based on time or location rules.": "Apenas ajustar gama baseada em regras de tempo ou localização."
}, },
@@ -1493,6 +1526,9 @@
"Power Profile Degradation": { "Power Profile Degradation": {
"Power Profile Degradation": "Degradação do Perfil de Energia" "Power Profile Degradation": "Degradação do Perfil de Energia"
}, },
"Power Profile OSD": {
"Power Profile OSD": ""
},
"Pressure": { "Pressure": {
"Pressure": "Pressão" "Pressure": "Pressão"
}, },
@@ -1781,6 +1817,24 @@
"Show on screens:": { "Show on screens:": {
"Show on screens:": "Mostrar nas telas:" "Show on screens:": "Mostrar nas telas:"
}, },
"Show on-screen display when brightness changes": {
"Show on-screen display when brightness changes": ""
},
"Show on-screen display when caps lock state changes": {
"Show on-screen display when caps lock state changes": ""
},
"Show on-screen display when idle inhibitor state changes": {
"Show on-screen display when idle inhibitor state changes": ""
},
"Show on-screen display when microphone is muted/unmuted": {
"Show on-screen display when microphone is muted/unmuted": ""
},
"Show on-screen display when power profile changes": {
"Show on-screen display when power profile changes": ""
},
"Show on-screen display when volume changes": {
"Show on-screen display when volume changes": ""
},
"Show only apps running in current workspace": { "Show only apps running in current workspace": {
"Show only apps running in current workspace": "Mostrar apenas aplicativos rodando na área de trabalho atual" "Show only apps running in current workspace": "Mostrar apenas aplicativos rodando na área de trabalho atual"
}, },
@@ -2141,6 +2195,9 @@
"Volume Changed": { "Volume Changed": {
"Volume Changed": "Volume Alterado" "Volume Changed": "Volume Alterado"
}, },
"Volume OSD": {
"Volume OSD": ""
},
"Volume, brightness, and other system OSDs": { "Volume, brightness, and other system OSDs": {
"Volume, brightness, and other system OSDs": "Volume, brilho, e outros OSDs do sistema" "Volume, brightness, and other system OSDs": "Volume, brilho, e outros OSDs do sistema"
}, },

View File

@@ -57,7 +57,7 @@
"Add a VPN in NetworkManager": "NetworkManager'da VPN ekle" "Add a VPN in NetworkManager": "NetworkManager'da VPN ekle"
}, },
"Adjust the number of columns in grid view mode.": { "Adjust the number of columns in grid view mode.": {
"Adjust the number of columns in grid view mode.": "" "Adjust the number of columns in grid view mode.": "Izgara görünümü modunda sütun sayısını ayarla"
}, },
"All": { "All": {
"All": "Tümü" "All": "Tümü"
@@ -75,7 +75,7 @@
"Always Show OSD Percentage": "OSD Yüzdesini Her Zaman Göster" "Always Show OSD Percentage": "OSD Yüzdesini Her Zaman Göster"
}, },
"Always on icons": { "Always on icons": {
"Always on icons": "" "Always on icons": "Her zaman açık simgeler"
}, },
"Always show a minimum of 3 workspaces, even if fewer are available": { "Always show a minimum of 3 workspaces, even if fewer are available": {
"Always show a minimum of 3 workspaces, even if fewer are available": "Her zaman en az 3 çalışma alanı göster, daha azı kullanılabilir olsa da" "Always show a minimum of 3 workspaces, even if fewer are available": "Her zaman en az 3 çalışma alanı göster, daha azı kullanılabilir olsa da"
@@ -275,6 +275,9 @@
"Brightness": { "Brightness": {
"Brightness": "Parlaklık" "Brightness": "Parlaklık"
}, },
"Brightness OSD": {
"Brightness OSD": ""
},
"Browse": { "Browse": {
"Browse": "Göz at" "Browse": "Göz at"
}, },
@@ -303,7 +306,7 @@
"CUPS Missing Filter Warning": "CUPS Eksik Filtre Uyarısı" "CUPS Missing Filter Warning": "CUPS Eksik Filtre Uyarısı"
}, },
"Camera": { "Camera": {
"Camera": "" "Camera": "Kamera"
}, },
"Cancel": { "Cancel": {
"Cancel": "İptal" "Cancel": "İptal"
@@ -312,7 +315,10 @@
"Capacity": "Kapasite" "Capacity": "Kapasite"
}, },
"Caps Lock Indicator": { "Caps Lock Indicator": {
"Caps Lock Indicator": "" "Caps Lock Indicator": "Caps Lock Göstergesi"
},
"Caps Lock OSD": {
"Caps Lock OSD": ""
}, },
"Center Section": { "Center Section": {
"Center Section": "Orta Bölüm" "Center Section": "Orta Bölüm"
@@ -341,6 +347,9 @@
"Choose where notification popups appear on screen": { "Choose where notification popups appear on screen": {
"Choose where notification popups appear on screen": "Bildirim açılır pencerelerinin ekranda nerede görüneceğini seçin" "Choose where notification popups appear on screen": "Bildirim açılır pencerelerinin ekranda nerede görüneceğini seçin"
}, },
"Choose where on-screen displays appear on screen": {
"Choose where on-screen displays appear on screen": ""
},
"Clear": { "Clear": {
"Clear": "Temizle" "Clear": "Temizle"
}, },
@@ -617,6 +626,9 @@
"Dismiss": { "Dismiss": {
"Dismiss": "Reddet" "Dismiss": "Reddet"
}, },
"Display Name Format": {
"Display Name Format": ""
},
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": { "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": {
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Ekranın üst, alt, sol veya sağ kenarına yerleştirilebilen, sabitlenmiş ve çalışan uygulamaları içeren bir dock görüntüleyin." "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "Ekranın üst, alt, sol veya sağ kenarına yerleştirilebilen, sabitlenmiş ve çalışan uygulamaları içeren bir dock görüntüleyin."
}, },
@@ -633,7 +645,7 @@
"Display currently focused application title": "Şu anda odaklanmış uygulamanın başlığını göster" "Display currently focused application title": "Şu anda odaklanmış uygulamanın başlığını göster"
}, },
"Display power menu actions in a grid instead of a list": { "Display power menu actions in a grid instead of a list": {
"Display power menu actions in a grid instead of a list": "" "Display power menu actions in a grid instead of a list": "Güç menüsü eylemlerini liste yerine ızgara şeklinde göster"
}, },
"Display settings for ": { "Display settings for ": {
"Display settings for ": "Ekran ayarları: " "Display settings for ": "Ekran ayarları: "
@@ -674,6 +686,9 @@
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": { "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": {
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Widget'ları sürükleyerek bölümler içinde yeniden sıralayın. Göz simgesini kullanarak widget'ları gizleyin/gösterin (aralıkları korur) veya X simgesini kullanarak tamamen kaldırın." "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "Widget'ları sürükleyerek bölümler içinde yeniden sıralayın. Göz simgesini kullanarak widget'ları gizleyin/gösterin (aralıkları korur) veya X simgesini kullanarak tamamen kaldırın."
}, },
"Duplicate Wallpaper with Blur": {
"Duplicate Wallpaper with Blur": ""
},
"Duration": { "Duration": {
"Duration": "Süre" "Duration": "Süre"
}, },
@@ -846,7 +861,7 @@
"Force Kill Process": "Süreci Zorla Kapat" "Force Kill Process": "Süreci Zorla Kapat"
}, },
"Force terminal applications to always use dark color schemes": { "Force terminal applications to always use dark color schemes": {
"Force terminal applications to always use dark color schemes": "" "Force terminal applications to always use dark color schemes": "Terminal uygulamalarının her zaman koyu renk şemalarını kullanmasını zorla"
}, },
"Forget Device": { "Forget Device": {
"Forget Device": "Aygıtı Unut" "Forget Device": "Aygıtı Unut"
@@ -900,7 +915,7 @@
"Grid": "Izgara" "Grid": "Izgara"
}, },
"Grid Columns": { "Grid Columns": {
"Grid Columns": "" "Grid Columns": "Izgara Sütunları"
}, },
"Group by App": { "Group by App": {
"Group by App": "Uygulamaya Göre Gruplandır" "Group by App": "Uygulamaya Göre Gruplandır"
@@ -924,7 +939,7 @@
"Hibernate": "Hazırda Beklet" "Hibernate": "Hazırda Beklet"
}, },
"Hide Delay (ms)": { "Hide Delay (ms)": {
"Hide Delay (ms)": "" "Hide Delay (ms)": "Gizleme Gecikmesi (ms)"
}, },
"Hide the dock when not in use and reveal it when hovering near the dock area": { "Hide the dock when not in use and reveal it when hovering near the dock area": {
"Hide the dock when not in use and reveal it when hovering near the dock area": "Kullanılmadığında dock'u gizle ve dock alanının yakınına geldiğinizde göster" "Hide the dock when not in use and reveal it when hovering near the dock area": "Kullanılmadığında dock'u gizle ve dock alanının yakınına geldiğinizde göster"
@@ -959,6 +974,9 @@
"Idle Inhibitor": { "Idle Inhibitor": {
"Idle Inhibitor": "Boşta Kalma Engelleyici" "Idle Inhibitor": "Boşta Kalma Engelleyici"
}, },
"Idle Inhibitor OSD": {
"Idle Inhibitor OSD": ""
},
"Idle Settings": { "Idle Settings": {
"Idle Settings": "Boşta Kalma Ayarları" "Idle Settings": "Boşta Kalma Ayarları"
}, },
@@ -1173,7 +1191,10 @@
"Memory usage indicator": "Bellek kullanım göstergesi" "Memory usage indicator": "Bellek kullanım göstergesi"
}, },
"Microphone": { "Microphone": {
"Microphone": "" "Microphone": "Mikrofon"
},
"Microphone Mute OSD": {
"Microphone Mute OSD": ""
}, },
"Minimal palette built around a single hue.": { "Minimal palette built around a single hue.": {
"Minimal palette built around a single hue.": "Tek bir renk tonu etrafında oluşturulmuş minimal palet." "Minimal palette built around a single hue.": "Tek bir renk tonu etrafında oluşturulmuş minimal palet."
@@ -1187,6 +1208,9 @@
"Mode: ": { "Mode: ": {
"Mode: ": "Mod: " "Mode: ": "Mod: "
}, },
"Model": {
"Model": ""
},
"Monitor Selection:": { "Monitor Selection:": {
"Monitor Selection:": "Monitör Seçimi:" "Monitor Selection:": "Monitör Seçimi:"
}, },
@@ -1211,6 +1235,9 @@
"NM not supported": { "NM not supported": {
"NM not supported": "NM desteklenmiyor" "NM not supported": "NM desteklenmiyor"
}, },
"Name": {
"Name": ""
},
"Named Workspace Icons": { "Named Workspace Icons": {
"Named Workspace Icons": "Adlandırılmış Çalışma Alanı Simgeleri" "Named Workspace Icons": "Adlandırılmış Çalışma Alanı Simgeleri"
}, },
@@ -1337,6 +1364,9 @@
"OS Logo": { "OS Logo": {
"OS Logo": "OS Logo" "OS Logo": "OS Logo"
}, },
"OSD Position": {
"OSD Position": ""
},
"Office": { "Office": {
"Office": "Ofis" "Office": "Ofis"
}, },
@@ -1346,6 +1376,9 @@
"On-Screen Displays": { "On-Screen Displays": {
"On-Screen Displays": "Ekran Üstü Gösterimler" "On-Screen Displays": "Ekran Üstü Gösterimler"
}, },
"On-screen Displays": {
"On-screen Displays": ""
},
"Only adjust gamma based on time or location rules.": { "Only adjust gamma based on time or location rules.": {
"Only adjust gamma based on time or location rules.": "Gamayı yalnızca zaman veya konum kurallarına göre ayarlayın." "Only adjust gamma based on time or location rules.": "Gamayı yalnızca zaman veya konum kurallarına göre ayarlayın."
}, },
@@ -1493,6 +1526,9 @@
"Power Profile Degradation": { "Power Profile Degradation": {
"Power Profile Degradation": "Güç Profili Dejenerasyonu" "Power Profile Degradation": "Güç Profili Dejenerasyonu"
}, },
"Power Profile OSD": {
"Power Profile OSD": ""
},
"Pressure": { "Pressure": {
"Pressure": "Basınç" "Pressure": "Basınç"
}, },
@@ -1647,7 +1683,7 @@
"Science": "Bilim" "Science": "Bilim"
}, },
"Screen sharing": { "Screen sharing": {
"Screen sharing": "" "Screen sharing": "Ekran paylaşımı"
}, },
"Scrolling": { "Scrolling": {
"Scrolling": "Kaydırma" "Scrolling": "Kaydırma"
@@ -1781,6 +1817,24 @@
"Show on screens:": { "Show on screens:": {
"Show on screens:": "Şu ekranda göster:" "Show on screens:": "Şu ekranda göster:"
}, },
"Show on-screen display when brightness changes": {
"Show on-screen display when brightness changes": ""
},
"Show on-screen display when caps lock state changes": {
"Show on-screen display when caps lock state changes": ""
},
"Show on-screen display when idle inhibitor state changes": {
"Show on-screen display when idle inhibitor state changes": ""
},
"Show on-screen display when microphone is muted/unmuted": {
"Show on-screen display when microphone is muted/unmuted": ""
},
"Show on-screen display when power profile changes": {
"Show on-screen display when power profile changes": ""
},
"Show on-screen display when volume changes": {
"Show on-screen display when volume changes": ""
},
"Show only apps running in current workspace": { "Show only apps running in current workspace": {
"Show only apps running in current workspace": "Yalnızca mevcut çalışma alanında çalışan uygulamaları göster" "Show only apps running in current workspace": "Yalnızca mevcut çalışma alanında çalışan uygulamaları göster"
}, },
@@ -1809,7 +1863,7 @@
"Shows current workspace and allows switching": "Mevcut çalışma alanı gösterir ve değiştirmeye izin verir" "Shows current workspace and allows switching": "Mevcut çalışma alanı gösterir ve değiştirmeye izin verir"
}, },
"Shows when caps lock is active": { "Shows when caps lock is active": {
"Shows when caps lock is active": "" "Shows when caps lock is active": "Caps Lock tuşunun etkin olduğunu gösterir"
}, },
"Shows when microphone, camera, or screen sharing is active": { "Shows when microphone, camera, or screen sharing is active": {
"Shows when microphone, camera, or screen sharing is active": "Mikrofon, kamera veya ekran paylaşımı aktif olduğunda gösterir" "Shows when microphone, camera, or screen sharing is active": "Mikrofon, kamera veya ekran paylaşımı aktif olduğunda gösterir"
@@ -1938,7 +1992,7 @@
"Terminal custom additional parameters": "Terminal özel ek parametreleri" "Terminal custom additional parameters": "Terminal özel ek parametreleri"
}, },
"Terminals - Always use Dark Theme": { "Terminals - Always use Dark Theme": {
"Terminals - Always use Dark Theme": "" "Terminals - Always use Dark Theme": "Terminaller - Her zaman Karanlı Tema kullan"
}, },
"Text": { "Text": {
"Text": "Metin" "Text": "Metin"
@@ -2055,16 +2109,16 @@
"Use Fahrenheit instead of Celsius for temperature": "Sıcaklık için Celsius yerine Fahrenhayt kullan" "Use Fahrenheit instead of Celsius for temperature": "Sıcaklık için Celsius yerine Fahrenhayt kullan"
}, },
"Use Grid Layout": { "Use Grid Layout": {
"Use Grid Layout": "" "Use Grid Layout": "Izgara Düzeni Kullan"
}, },
"Use IP Location": { "Use IP Location": {
"Use IP Location": "IP Konumunu Kullan" "Use IP Location": "IP Konumunu Kullan"
}, },
"Use Imperial Units": { "Use Imperial Units": {
"Use Imperial Units": "" "Use Imperial Units": "İngiliz Ölçü Birimini Kullan"
}, },
"Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": { "Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": {
"Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": "" "Use Imperial units (°F, mph, inHg) instead of Metric (°C, km/h, hPa)": "Metrik birimler (°C, km/h, hPa) yerine İngiliz birimleri (°F, mph, inHg) kullan"
}, },
"Use Monospace Font": { "Use Monospace Font": {
"Use Monospace Font": "Sabit Aralıklı Yazı Tipi Kullan" "Use Monospace Font": "Sabit Aralıklı Yazı Tipi Kullan"
@@ -2141,6 +2195,9 @@
"Volume Changed": { "Volume Changed": {
"Volume Changed": "Ses Seviyesi Değişti" "Volume Changed": "Ses Seviyesi Değişti"
}, },
"Volume OSD": {
"Volume OSD": ""
},
"Volume, brightness, and other system OSDs": { "Volume, brightness, and other system OSDs": {
"Volume, brightness, and other system OSDs": "Ses, parlaklık ve diğer sistem ekran üstü gösterimleri" "Volume, brightness, and other system OSDs": "Ses, parlaklık ve diğer sistem ekran üstü gösterimleri"
}, },

View File

@@ -57,7 +57,7 @@
"Add a VPN in NetworkManager": "在 NetworkManager 中添加 VPN" "Add a VPN in NetworkManager": "在 NetworkManager 中添加 VPN"
}, },
"Adjust the number of columns in grid view mode.": { "Adjust the number of columns in grid view mode.": {
"Adjust the number of columns in grid view mode.": "" "Adjust the number of columns in grid view mode.": "在网格模式中按需调整列的数量。"
}, },
"All": { "All": {
"All": "全部" "All": "全部"
@@ -75,7 +75,7 @@
"Always Show OSD Percentage": "始终显示 OSD 百分比" "Always Show OSD Percentage": "始终显示 OSD 百分比"
}, },
"Always on icons": { "Always on icons": {
"Always on icons": "" "Always on icons": "总显示的图标"
}, },
"Always show a minimum of 3 workspaces, even if fewer are available": { "Always show a minimum of 3 workspaces, even if fewer are available": {
"Always show a minimum of 3 workspaces, even if fewer are available": "即使不足也总是显示至少三个工作区" "Always show a minimum of 3 workspaces, even if fewer are available": "即使不足也总是显示至少三个工作区"
@@ -275,6 +275,9 @@
"Brightness": { "Brightness": {
"Brightness": "亮度" "Brightness": "亮度"
}, },
"Brightness OSD": {
"Brightness OSD": "OSD亮度"
},
"Browse": { "Browse": {
"Browse": "浏览" "Browse": "浏览"
}, },
@@ -303,7 +306,7 @@
"CUPS Missing Filter Warning": "CUPS 警告:缺少打印过滤器" "CUPS Missing Filter Warning": "CUPS 警告:缺少打印过滤器"
}, },
"Camera": { "Camera": {
"Camera": "" "Camera": "摄像头"
}, },
"Cancel": { "Cancel": {
"Cancel": "取消" "Cancel": "取消"
@@ -314,6 +317,9 @@
"Caps Lock Indicator": { "Caps Lock Indicator": {
"Caps Lock Indicator": "大小写指示灯" "Caps Lock Indicator": "大小写指示灯"
}, },
"Caps Lock OSD": {
"Caps Lock OSD": "OSD大小写"
},
"Center Section": { "Center Section": {
"Center Section": "中间区域" "Center Section": "中间区域"
}, },
@@ -341,6 +347,9 @@
"Choose where notification popups appear on screen": { "Choose where notification popups appear on screen": {
"Choose where notification popups appear on screen": "设置通知弹窗的出现位置" "Choose where notification popups appear on screen": "设置通知弹窗的出现位置"
}, },
"Choose where on-screen displays appear on screen": {
"Choose where on-screen displays appear on screen": ""
},
"Clear": { "Clear": {
"Clear": "清除" "Clear": "清除"
}, },
@@ -531,7 +540,7 @@
"DMS_SOCKET not available": "DMS_SOCKET 不可用" "DMS_SOCKET not available": "DMS_SOCKET 不可用"
}, },
"DWL service not available": { "DWL service not available": {
"DWL service not available": "DWL服务不可用" "DWL service not available": "DWL 服务不可用"
}, },
"Daily at:": { "Daily at:": {
"Daily at:": "在每日:" "Daily at:": "在每日:"
@@ -617,6 +626,9 @@
"Dismiss": { "Dismiss": {
"Dismiss": "忽略" "Dismiss": "忽略"
}, },
"Display Name Format": {
"Display Name Format": ""
},
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": { "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": {
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "显示一个包含固定和运行中应用的程序坞,可放置在屏幕四边任意位置" "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "显示一个包含固定和运行中应用的程序坞,可放置在屏幕四边任意位置"
}, },
@@ -624,7 +636,7 @@
"Display all priorities over fullscreen apps": "应用全屏时仍显示所有优先级的通知" "Display all priorities over fullscreen apps": "应用全屏时仍显示所有优先级的通知"
}, },
"Display and switch DWL layouts": { "Display and switch DWL layouts": {
"Display and switch DWL layouts": "显示与切换DWL布局" "Display and switch DWL layouts": "显示与切换 DWL 布局"
}, },
"Display application icons in workspace indicators": { "Display application icons in workspace indicators": {
"Display application icons in workspace indicators": "在工作区指示器中显示应用程序图标" "Display application icons in workspace indicators": "在工作区指示器中显示应用程序图标"
@@ -674,6 +686,9 @@
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": { "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": {
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "拖动组件以在各区块内重新排序。点击眼睛图标可隐藏/显示组件(保留间距),点击 X 可彻底移除。" "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "拖动组件以在各区块内重新排序。点击眼睛图标可隐藏/显示组件(保留间距),点击 X 可彻底移除。"
}, },
"Duplicate Wallpaper with Blur": {
"Duplicate Wallpaper with Blur": ""
},
"Duration": { "Duration": {
"Duration": "持续时间" "Duration": "持续时间"
}, },
@@ -846,7 +861,7 @@
"Force Kill Process": "强制结束进程" "Force Kill Process": "强制结束进程"
}, },
"Force terminal applications to always use dark color schemes": { "Force terminal applications to always use dark color schemes": {
"Force terminal applications to always use dark color schemes": "强制终端应用使用暗色" "Force terminal applications to always use dark color schemes": "强制终端应用使用暗色"
}, },
"Forget Device": { "Forget Device": {
"Forget Device": "取消配对" "Forget Device": "取消配对"
@@ -900,7 +915,7 @@
"Grid": "网格" "Grid": "网格"
}, },
"Grid Columns": { "Grid Columns": {
"Grid Columns": "" "Grid Columns": "网格列"
}, },
"Group by App": { "Group by App": {
"Group by App": "按应用分组" "Group by App": "按应用分组"
@@ -924,7 +939,7 @@
"Hibernate": "休眠" "Hibernate": "休眠"
}, },
"Hide Delay (ms)": { "Hide Delay (ms)": {
"Hide Delay (ms)": "" "Hide Delay (ms)": "隐藏延迟 (ms)"
}, },
"Hide the dock when not in use and reveal it when hovering near the dock area": { "Hide the dock when not in use and reveal it when hovering near the dock area": {
"Hide the dock when not in use and reveal it when hovering near the dock area": "在未使用时隐藏程序坞,鼠标悬停到程序坞区域时显示" "Hide the dock when not in use and reveal it when hovering near the dock area": "在未使用时隐藏程序坞,鼠标悬停到程序坞区域时显示"
@@ -959,6 +974,9 @@
"Idle Inhibitor": { "Idle Inhibitor": {
"Idle Inhibitor": "待机抑制器" "Idle Inhibitor": "待机抑制器"
}, },
"Idle Inhibitor OSD": {
"Idle Inhibitor OSD": "OSD空闲抑制"
},
"Idle Settings": { "Idle Settings": {
"Idle Settings": "待机设置" "Idle Settings": "待机设置"
}, },
@@ -1020,13 +1038,13 @@
"Last launched %1": "上次启动于 %1" "Last launched %1": "上次启动于 %1"
}, },
"Last launched %1 day%2 ago": { "Last launched %1 day%2 ago": {
"Last launched %1 day%2 ago": "上次启动于 %1 天%2 前" "Last launched %1 day%2 ago": "上次启动于 %1 天 前"
}, },
"Last launched %1 hour%2 ago": { "Last launched %1 hour%2 ago": {
"Last launched %1 hour%2 ago": "上次启动于 %1 小时%2 前" "Last launched %1 hour%2 ago": "上次启动于 %1 小时 前"
}, },
"Last launched %1 minute%2 ago": { "Last launched %1 minute%2 ago": {
"Last launched %1 minute%2 ago": "上次启动于 %1 分钟%2 前" "Last launched %1 minute%2 ago": "上次启动于 %1 分钟 前"
}, },
"Last launched just now": { "Last launched just now": {
"Last launched just now": "刚刚启动" "Last launched just now": "刚刚启动"
@@ -1173,7 +1191,10 @@
"Memory usage indicator": "内存占用情况" "Memory usage indicator": "内存占用情况"
}, },
"Microphone": { "Microphone": {
"Microphone": "" "Microphone": "麦克风"
},
"Microphone Mute OSD": {
"Microphone Mute OSD": "OSD麦克风静音"
}, },
"Minimal palette built around a single hue.": { "Minimal palette built around a single hue.": {
"Minimal palette built around a single hue.": "围绕单一色调构建的简约配色。" "Minimal palette built around a single hue.": "围绕单一色调构建的简约配色。"
@@ -1187,6 +1208,9 @@
"Mode: ": { "Mode: ": {
"Mode: ": "模式: " "Mode: ": "模式: "
}, },
"Model": {
"Model": ""
},
"Monitor Selection:": { "Monitor Selection:": {
"Monitor Selection:": "选择显示器:" "Monitor Selection:": "选择显示器:"
}, },
@@ -1211,6 +1235,9 @@
"NM not supported": { "NM not supported": {
"NM not supported": "不支持 NM" "NM not supported": "不支持 NM"
}, },
"Name": {
"Name": ""
},
"Named Workspace Icons": { "Named Workspace Icons": {
"Named Workspace Icons": "已命名工作区图标" "Named Workspace Icons": "已命名工作区图标"
}, },
@@ -1337,6 +1364,9 @@
"OS Logo": { "OS Logo": {
"OS Logo": "系统 Logo" "OS Logo": "系统 Logo"
}, },
"OSD Position": {
"OSD Position": ""
},
"Office": { "Office": {
"Office": "办公" "Office": "办公"
}, },
@@ -1346,6 +1376,9 @@
"On-Screen Displays": { "On-Screen Displays": {
"On-Screen Displays": "屏幕显示" "On-Screen Displays": "屏幕显示"
}, },
"On-screen Displays": {
"On-screen Displays": "屏上显示"
},
"Only adjust gamma based on time or location rules.": { "Only adjust gamma based on time or location rules.": {
"Only adjust gamma based on time or location rules.": "根据时间或位置调节伽马值。" "Only adjust gamma based on time or location rules.": "根据时间或位置调节伽马值。"
}, },
@@ -1493,6 +1526,9 @@
"Power Profile Degradation": { "Power Profile Degradation": {
"Power Profile Degradation": "电源配置性能下降" "Power Profile Degradation": "电源配置性能下降"
}, },
"Power Profile OSD": {
"Power Profile OSD": "OSD电源配置"
},
"Pressure": { "Pressure": {
"Pressure": "气压" "Pressure": "气压"
}, },
@@ -1575,7 +1611,7 @@
"Request confirmation on power off, restart, suspend, hibernate and logout actions": "关机、重启、挂起、休眠和注销前请求确认" "Request confirmation on power off, restart, suspend, hibernate and logout actions": "关机、重启、挂起、休眠和注销前请求确认"
}, },
"Requires DWL compositor": { "Requires DWL compositor": {
"Requires DWL compositor": "需要DWL合成器" "Requires DWL compositor": "需要 DWL 合成器"
}, },
"Reset": { "Reset": {
"Reset": "重置" "Reset": "重置"
@@ -1587,10 +1623,10 @@
"Restart": "重启" "Restart": "重启"
}, },
"Restart DMS": { "Restart DMS": {
"Restart DMS": "重启DMS" "Restart DMS": "重启 DMS"
}, },
"Restart the DankMaterialShell": { "Restart the DankMaterialShell": {
"Restart the DankMaterialShell": "重启DankMaterialShell" "Restart the DankMaterialShell": "重启 DankMaterialShell"
}, },
"Resume": { "Resume": {
"Resume": "恢复" "Resume": "恢复"
@@ -1611,7 +1647,7 @@
"Right Tiling": "右侧平铺" "Right Tiling": "右侧平铺"
}, },
"Right-click bar widget to cycle": { "Right-click bar widget to cycle": {
"Right-click bar widget to cycle": "点击bar上小部件以轮换" "Right-click bar widget to cycle": "点击 bar 上小部件以轮换"
}, },
"Run User Templates": { "Run User Templates": {
"Run User Templates": "运行用户模板" "Run User Templates": "运行用户模板"
@@ -1647,7 +1683,7 @@
"Science": "科学" "Science": "科学"
}, },
"Screen sharing": { "Screen sharing": {
"Screen sharing": "" "Screen sharing": "屏幕分享"
}, },
"Scrolling": { "Scrolling": {
"Scrolling": "滚动" "Scrolling": "滚动"
@@ -1755,7 +1791,7 @@
"Show Reboot": "显示重启" "Show Reboot": "显示重启"
}, },
"Show Restart DMS": { "Show Restart DMS": {
"Show Restart DMS": "显示重启DMS" "Show Restart DMS": "显示重启 DMS"
}, },
"Show Suspend": { "Show Suspend": {
"Show Suspend": "显示挂起" "Show Suspend": "显示挂起"
@@ -1781,6 +1817,24 @@
"Show on screens:": { "Show on screens:": {
"Show on screens:": "选择显示的屏幕:" "Show on screens:": "选择显示的屏幕:"
}, },
"Show on-screen display when brightness changes": {
"Show on-screen display when brightness changes": "当亮度改变时显示OSD"
},
"Show on-screen display when caps lock state changes": {
"Show on-screen display when caps lock state changes": "当大小写状态变化时显示OSD"
},
"Show on-screen display when idle inhibitor state changes": {
"Show on-screen display when idle inhibitor state changes": "当空闲抑制状态改变时显示OSD"
},
"Show on-screen display when microphone is muted/unmuted": {
"Show on-screen display when microphone is muted/unmuted": "当麦克风静音状态切换时显示OSD"
},
"Show on-screen display when power profile changes": {
"Show on-screen display when power profile changes": "当电源配置改变时显示OSD"
},
"Show on-screen display when volume changes": {
"Show on-screen display when volume changes": "当音量变化时显示OSD"
},
"Show only apps running in current workspace": { "Show only apps running in current workspace": {
"Show only apps running in current workspace": "仅显示当前工作区中的活动应用" "Show only apps running in current workspace": "仅显示当前工作区中的活动应用"
}, },
@@ -2115,7 +2169,7 @@
"VRR: ": "可变刷新率: " "VRR: ": "可变刷新率: "
}, },
"Vertical Deck": { "Vertical Deck": {
"Vertical Deck": "垂直Deck" "Vertical Deck": "垂直 Deck"
}, },
"Vertical Grid": { "Vertical Grid": {
"Vertical Grid": "垂直网格" "Vertical Grid": "垂直网格"
@@ -2141,6 +2195,9 @@
"Volume Changed": { "Volume Changed": {
"Volume Changed": "音量变化" "Volume Changed": "音量变化"
}, },
"Volume OSD": {
"Volume OSD": "OSD音量"
},
"Volume, brightness, and other system OSDs": { "Volume, brightness, and other system OSDs": {
"Volume, brightness, and other system OSDs": "音量、亮度和其他系统屏幕显示" "Volume, brightness, and other system OSDs": "音量、亮度和其他系统屏幕显示"
}, },

View File

@@ -275,6 +275,9 @@
"Brightness": { "Brightness": {
"Brightness": "亮度" "Brightness": "亮度"
}, },
"Brightness OSD": {
"Brightness OSD": ""
},
"Browse": { "Browse": {
"Browse": "瀏覽" "Browse": "瀏覽"
}, },
@@ -314,6 +317,9 @@
"Caps Lock Indicator": { "Caps Lock Indicator": {
"Caps Lock Indicator": "" "Caps Lock Indicator": ""
}, },
"Caps Lock OSD": {
"Caps Lock OSD": ""
},
"Center Section": { "Center Section": {
"Center Section": "中間區塊" "Center Section": "中間區塊"
}, },
@@ -341,6 +347,9 @@
"Choose where notification popups appear on screen": { "Choose where notification popups appear on screen": {
"Choose where notification popups appear on screen": "選擇通知彈出視窗在螢幕上出現的位置" "Choose where notification popups appear on screen": "選擇通知彈出視窗在螢幕上出現的位置"
}, },
"Choose where on-screen displays appear on screen": {
"Choose where on-screen displays appear on screen": ""
},
"Clear": { "Clear": {
"Clear": "清除" "Clear": "清除"
}, },
@@ -617,6 +626,9 @@
"Dismiss": { "Dismiss": {
"Dismiss": "忽略" "Dismiss": "忽略"
}, },
"Display Name Format": {
"Display Name Format": ""
},
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": { "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": {
"Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "顯示一個帶有固定和正在運行的應用程式的 Dock這些應用程式可以放置在螢幕的頂部、底部、左側或右側邊緣" "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen": "顯示一個帶有固定和正在運行的應用程式的 Dock這些應用程式可以放置在螢幕的頂部、底部、左側或右側邊緣"
}, },
@@ -674,6 +686,9 @@
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": { "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": {
"Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "拖曳部件即可在版塊內重新排序。使用眼睛圖示隱藏/顯示部件 (會保持間距),或使用 X 將其完全移除。" "Drag widgets to reorder within sections. Use the eye icon to hide/show widgets (maintains spacing), or X to remove them completely.": "拖曳部件即可在版塊內重新排序。使用眼睛圖示隱藏/顯示部件 (會保持間距),或使用 X 將其完全移除。"
}, },
"Duplicate Wallpaper with Blur": {
"Duplicate Wallpaper with Blur": ""
},
"Duration": { "Duration": {
"Duration": "持續時間" "Duration": "持續時間"
}, },
@@ -959,6 +974,9 @@
"Idle Inhibitor": { "Idle Inhibitor": {
"Idle Inhibitor": "空閒抑制器" "Idle Inhibitor": "空閒抑制器"
}, },
"Idle Inhibitor OSD": {
"Idle Inhibitor OSD": ""
},
"Idle Settings": { "Idle Settings": {
"Idle Settings": "閒置設定" "Idle Settings": "閒置設定"
}, },
@@ -1175,6 +1193,9 @@
"Microphone": { "Microphone": {
"Microphone": "" "Microphone": ""
}, },
"Microphone Mute OSD": {
"Microphone Mute OSD": ""
},
"Minimal palette built around a single hue.": { "Minimal palette built around a single hue.": {
"Minimal palette built around a single hue.": "圍繞單一色調構建的最小調色板。" "Minimal palette built around a single hue.": "圍繞單一色調構建的最小調色板。"
}, },
@@ -1187,6 +1208,9 @@
"Mode: ": { "Mode: ": {
"Mode: ": "模式:" "Mode: ": "模式:"
}, },
"Model": {
"Model": ""
},
"Monitor Selection:": { "Monitor Selection:": {
"Monitor Selection:": "螢幕選擇:" "Monitor Selection:": "螢幕選擇:"
}, },
@@ -1211,6 +1235,9 @@
"NM not supported": { "NM not supported": {
"NM not supported": "NM 不支援" "NM not supported": "NM 不支援"
}, },
"Name": {
"Name": ""
},
"Named Workspace Icons": { "Named Workspace Icons": {
"Named Workspace Icons": "命名工作區圖示" "Named Workspace Icons": "命名工作區圖示"
}, },
@@ -1337,6 +1364,9 @@
"OS Logo": { "OS Logo": {
"OS Logo": "發行版 Logo" "OS Logo": "發行版 Logo"
}, },
"OSD Position": {
"OSD Position": ""
},
"Office": { "Office": {
"Office": "辦公" "Office": "辦公"
}, },
@@ -1346,6 +1376,9 @@
"On-Screen Displays": { "On-Screen Displays": {
"On-Screen Displays": "螢幕顯示" "On-Screen Displays": "螢幕顯示"
}, },
"On-screen Displays": {
"On-screen Displays": ""
},
"Only adjust gamma based on time or location rules.": { "Only adjust gamma based on time or location rules.": {
"Only adjust gamma based on time or location rules.": "僅根據時間或位置規則調整 gamma。" "Only adjust gamma based on time or location rules.": "僅根據時間或位置規則調整 gamma。"
}, },
@@ -1493,6 +1526,9 @@
"Power Profile Degradation": { "Power Profile Degradation": {
"Power Profile Degradation": "電源配置降級" "Power Profile Degradation": "電源配置降級"
}, },
"Power Profile OSD": {
"Power Profile OSD": ""
},
"Pressure": { "Pressure": {
"Pressure": "氣壓" "Pressure": "氣壓"
}, },
@@ -1781,6 +1817,24 @@
"Show on screens:": { "Show on screens:": {
"Show on screens:": "在螢幕上顯示:" "Show on screens:": "在螢幕上顯示:"
}, },
"Show on-screen display when brightness changes": {
"Show on-screen display when brightness changes": ""
},
"Show on-screen display when caps lock state changes": {
"Show on-screen display when caps lock state changes": ""
},
"Show on-screen display when idle inhibitor state changes": {
"Show on-screen display when idle inhibitor state changes": ""
},
"Show on-screen display when microphone is muted/unmuted": {
"Show on-screen display when microphone is muted/unmuted": ""
},
"Show on-screen display when power profile changes": {
"Show on-screen display when power profile changes": ""
},
"Show on-screen display when volume changes": {
"Show on-screen display when volume changes": ""
},
"Show only apps running in current workspace": { "Show only apps running in current workspace": {
"Show only apps running in current workspace": "僅顯示目前工作區中正在執行的應用程式" "Show only apps running in current workspace": "僅顯示目前工作區中正在執行的應用程式"
}, },
@@ -2141,6 +2195,9 @@
"Volume Changed": { "Volume Changed": {
"Volume Changed": "音量改變" "Volume Changed": "音量改變"
}, },
"Volume OSD": {
"Volume OSD": ""
},
"Volume, brightness, and other system OSDs": { "Volume, brightness, and other system OSDs": {
"Volume, brightness, and other system OSDs": "音量、亮度及其他系統OSD" "Volume, brightness, and other system OSDs": "音量、亮度及其他系統OSD"
}, },

View File

@@ -566,13 +566,6 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Blur Layer",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Blur on Overview", "term": "Blur on Overview",
"translation": "", "translation": "",
@@ -643,6 +636,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Brightness OSD",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Browse", "term": "Browse",
"translation": "", "translation": "",
@@ -734,6 +734,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Caps Lock OSD",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Center Section", "term": "Center Section",
"translation": "", "translation": "",
@@ -797,6 +804,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Choose where on-screen displays appear on screen",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Clear", "term": "Clear",
"translation": "", "translation": "",
@@ -1441,6 +1455,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Display Name Format",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen", "term": "Display a dock with pinned and running applications that can be positioned at the top, bottom, left, or right edge of the screen",
"translation": "", "translation": "",
@@ -1574,6 +1595,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Duplicate Wallpaper with Blur",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Duration", "term": "Duration",
"translation": "", "translation": "",
@@ -2232,6 +2260,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Idle Inhibitor OSD",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Idle Settings", "term": "Idle Settings",
"translation": "", "translation": "",
@@ -2736,6 +2771,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Microphone Mute OSD",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Minimal palette built around a single hue.", "term": "Minimal palette built around a single hue.",
"translation": "", "translation": "",
@@ -2764,6 +2806,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Model",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Monitor Selection:", "term": "Monitor Selection:",
"translation": "", "translation": "",
@@ -2820,6 +2869,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Name",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Named Workspace Icons", "term": "Named Workspace Icons",
"translation": "", "translation": "",
@@ -3114,6 +3170,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "OSD Position",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Office", "term": "Office",
"translation": "", "translation": "",
@@ -3135,6 +3198,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "On-screen Displays",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Only adjust gamma based on time or location rules.", "term": "Only adjust gamma based on time or location rules.",
"translation": "", "translation": "",
@@ -3478,6 +3548,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Power Profile OSD",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Pressure", "term": "Pressure",
"translation": "", "translation": "",
@@ -4143,6 +4220,48 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Show on-screen display when brightness changes",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Show on-screen display when caps lock state changes",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Show on-screen display when idle inhibitor state changes",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Show on-screen display when microphone is muted/unmuted",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Show on-screen display when power profile changes",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{
"term": "Show on-screen display when volume changes",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Show only apps running in current workspace", "term": "Show only apps running in current workspace",
"translation": "", "translation": "",
@@ -4969,6 +5088,13 @@
"reference": "", "reference": "",
"comment": "" "comment": ""
}, },
{
"term": "Volume OSD",
"translation": "",
"context": "",
"reference": "",
"comment": ""
},
{ {
"term": "Volume, brightness, and other system OSDs", "term": "Volume, brightness, and other system OSDs",
"translation": "", "translation": "",