split into multiple files
This commit is contained in:
parent
a4077a3d8b
commit
86dc6b8f54
9 changed files with 309 additions and 280 deletions
23
cache.go
Normal file
23
cache.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package main
|
||||
|
||||
import "sync"
|
||||
|
||||
const (
|
||||
// cache key definitions
|
||||
CACHE_BT_CONNECTED = "bt_connected"
|
||||
CACHE_BT_BATTERY = "bt_battery"
|
||||
CACHE_MEDIA = "media"
|
||||
CACHE_LAYOUT = "kbd_layout"
|
||||
)
|
||||
|
||||
var CACHE = sync.Map{}
|
||||
|
||||
func getC[T comparable](c sync.Map, id string, fallback func() T) T {
|
||||
val, ok := c.Load(id)
|
||||
if !ok {
|
||||
val = fallback()
|
||||
c.Store(id, val)
|
||||
}
|
||||
|
||||
return val.(T)
|
||||
}
|
54
connections.go
Normal file
54
connections.go
Normal file
|
@ -0,0 +1,54 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
sway "github.com/joshuarubin/go-sway"
|
||||
"github.com/noisetorch/pulseaudio"
|
||||
)
|
||||
|
||||
var CONN Connections
|
||||
|
||||
type Connections struct {
|
||||
dbusSession, dbusSystem *dbus.Conn
|
||||
paClient *pulseaudio.Client
|
||||
swayClient sway.Client
|
||||
}
|
||||
|
||||
func init_connections() (Connections, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
dbusSession, err := dbus.ConnectSessionBus()
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
dbusSystem, err := dbus.ConnectSystemBus()
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
paClient, err := pulseaudio.NewClient()
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
swayClient, err := sway.New(ctx)
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
return Connections{
|
||||
dbusSession: dbusSession,
|
||||
dbusSystem: dbusSystem,
|
||||
paClient: paClient,
|
||||
swayClient: swayClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c Connections) close_all() {
|
||||
c.dbusSession.Close()
|
||||
c.dbusSystem.Close()
|
||||
c.paClient.Close()
|
||||
}
|
7
consts.go
Normal file
7
consts.go
Normal file
|
@ -0,0 +1,7 @@
|
|||
package main
|
||||
|
||||
const (
|
||||
SEPARATOR = " | "
|
||||
BATTERY = "BAT0"
|
||||
HEADSET = "94:DB:56:6B:E3:8A"
|
||||
)
|
6
go.mod
6
go.mod
|
@ -4,10 +4,12 @@ go 1.19
|
|||
|
||||
require github.com/godbus/dbus/v5 v5.1.0
|
||||
|
||||
require github.com/noisetorch/pulseaudio v0.0.0-20220603053345-9303200c3861
|
||||
require (
|
||||
github.com/joshuarubin/go-sway v1.2.0
|
||||
github.com/noisetorch/pulseaudio v0.0.0-20220603053345-9303200c3861
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/joshuarubin/go-sway v1.2.0 // indirect
|
||||
github.com/joshuarubin/lifecycle v1.0.0 // indirect
|
||||
go.uber.org/atomic v1.3.2 // indirect
|
||||
go.uber.org/multierr v1.1.0 // indirect
|
||||
|
|
3
go.sum
3
go.sum
|
@ -1,3 +1,4 @@
|
|||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
|
||||
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
|
@ -7,8 +8,10 @@ github.com/joshuarubin/lifecycle v1.0.0 h1:N/lPEC8f+dBZ1Tn99vShqp36LwB+LI7XNAiNa
|
|||
github.com/joshuarubin/lifecycle v1.0.0/go.mod h1:sRy++ATvR9Ee21tkRdFkQeywAWvDsue66V70K0Dnl54=
|
||||
github.com/noisetorch/pulseaudio v0.0.0-20220603053345-9303200c3861 h1:Xng5X+MlNK7Y/Ede75B86wJgaFMFvuey1K4Suh9k2E4=
|
||||
github.com/noisetorch/pulseaudio v0.0.0-20220603053345-9303200c3861/go.mod h1:/zosM8PSkhuVyfJ9c/qzBhPSm3k06m9U4y4SDfH0jeA=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
go.uber.org/atomic v1.3.2 h1:2Oa65PReHzfn29GpvgsYwloV9AVFHPDk8tYxt2c2tr4=
|
||||
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
|
||||
|
|
113
module_dbus.go
Normal file
113
module_dbus.go
Normal file
|
@ -0,0 +1,113 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
)
|
||||
|
||||
var HEADSET_PATH = dbus.ObjectPath("/org/bluez/hci0/dev_" + strings.ReplaceAll(HEADSET, ":", "_"))
|
||||
|
||||
func dbus_system_handler(feedback chan bool) {
|
||||
// watches for BT headset connections
|
||||
headsetObjectPath := "/org/bluez/hci0/dev_" + strings.ReplaceAll(HEADSET, ":", "_")
|
||||
|
||||
err := CONN.dbusSystem.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(headsetObjectPath)),
|
||||
dbus.WithMatchInterface("org.freedesktop.DBus.Properties"),
|
||||
)
|
||||
if err != nil {
|
||||
warn("Failed to add match signal", err)
|
||||
return
|
||||
}
|
||||
|
||||
sigs := make(chan *dbus.Signal, 1)
|
||||
CONN.dbusSystem.Signal(sigs)
|
||||
|
||||
for range sigs {
|
||||
CACHE.Delete(CACHE_BT_CONNECTED)
|
||||
CACHE.Delete(CACHE_BT_BATTERY)
|
||||
feedback <- true
|
||||
}
|
||||
}
|
||||
|
||||
func dbus_session_handler(feedback chan bool) {
|
||||
// watches for media changes
|
||||
err := CONN.dbusSession.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath("/org/mpris/MediaPlayer2"),
|
||||
dbus.WithMatchInterface("org.freedesktop.DBus.Properties"),
|
||||
)
|
||||
if err != nil {
|
||||
warn("Failed to add match signal", err)
|
||||
return
|
||||
}
|
||||
|
||||
sigs := make(chan *dbus.Signal, 1)
|
||||
CONN.dbusSession.Signal(sigs)
|
||||
|
||||
for range sigs {
|
||||
CACHE.Delete(CACHE_MEDIA)
|
||||
feedback <- true
|
||||
}
|
||||
}
|
||||
|
||||
func get_bt_headset_connected() bool {
|
||||
obj := CONN.dbusSystem.Object("org.bluez", HEADSET_PATH)
|
||||
|
||||
status, err := obj.GetProperty("org.bluez.Device1.Connected")
|
||||
if err == nil {
|
||||
if status.String() == "true" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func get_bt_headset_battery() string {
|
||||
obj := CONN.dbusSystem.Object("org.bluez", HEADSET_PATH)
|
||||
|
||||
status, err := obj.GetProperty("org.bluez.Battery1.Percentage")
|
||||
if err == nil {
|
||||
return fmt.Sprintf("%v", status.Value())
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func get_playing_spotify_media() string {
|
||||
var output strings.Builder
|
||||
obj := CONN.dbusSession.Object("org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2")
|
||||
|
||||
metadata, err := obj.GetProperty("org.mpris.MediaPlayer2.Player.Metadata")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
status, err := obj.GetProperty("org.mpris.MediaPlayer2.Player.PlaybackStatus")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if status.String() != "\"Playing\"" {
|
||||
output.WriteString("‖ ")
|
||||
}
|
||||
|
||||
metadataMap := metadata.Value().(map[string]dbus.Variant)
|
||||
artists := make([]string, 1)
|
||||
metadataMap["xesam:artist"].Store(&artists)
|
||||
title := metadataMap["xesam:title"].String()
|
||||
|
||||
if title == "\"\"" {
|
||||
return ""
|
||||
}
|
||||
|
||||
output.WriteString(fmt.Sprintf(
|
||||
"%s - %s",
|
||||
strings.Join(artists, ", "),
|
||||
title[1:len(title)-1],
|
||||
))
|
||||
|
||||
return output.String()
|
||||
}
|
42
module_pulseaudio.go
Normal file
42
module_pulseaudio.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package main
|
||||
|
||||
import "math"
|
||||
|
||||
func pulseaudio_handler(feedback chan bool) {
|
||||
vol, muted := get_default_sink_volume()
|
||||
|
||||
sigs, err := CONN.paClient.Updates()
|
||||
if err != nil {
|
||||
warn("Failed to create PulseAudio update listener!", err)
|
||||
return
|
||||
}
|
||||
|
||||
for range sigs {
|
||||
nVol, nMuted := get_default_sink_volume()
|
||||
if nVol != vol || nMuted != muted {
|
||||
feedback <- true
|
||||
vol = nVol
|
||||
muted = nMuted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func get_default_sink_volume() (int, bool) {
|
||||
si, err := CONN.paClient.ServerInfo()
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
sinks, err := CONN.paClient.Sinks()
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
for i := range sinks {
|
||||
if sinks[i].Name == si.DefaultSink {
|
||||
return int(math.Round(float64(sinks[i].Cvolume[0]) / float64(sinks[i].BaseVolume) * 100)), sinks[i].Muted
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
63
module_sway.go
Normal file
63
module_sway.go
Normal file
|
@ -0,0 +1,63 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
sway "github.com/joshuarubin/go-sway"
|
||||
)
|
||||
|
||||
type sway_handler struct {
|
||||
sway.EventHandler
|
||||
feedback chan bool
|
||||
}
|
||||
|
||||
func (h sway_handler) Input(ctx context.Context, ev sway.InputEvent) {
|
||||
if ev.Change != "xkb_layout" || ev.Input.Type != "keyboard" {
|
||||
return
|
||||
}
|
||||
|
||||
oldval, _ := CACHE.Load(CACHE_LAYOUT)
|
||||
if oldval == *ev.Input.XKBActiveLayoutName {
|
||||
return
|
||||
}
|
||||
|
||||
CACHE.Store(CACHE_LAYOUT, *ev.Input.XKBActiveLayoutName)
|
||||
h.feedback <- true
|
||||
}
|
||||
|
||||
func sway_input_handler(feedback chan bool) {
|
||||
ctx := context.Background()
|
||||
|
||||
var h sway.EventHandler = sway_handler{feedback: feedback}
|
||||
|
||||
sway.Subscribe(ctx, h, sway.EventTypeInput)
|
||||
}
|
||||
|
||||
func get_current_layout() string {
|
||||
ctx := context.Background()
|
||||
inputs, err := CONN.swayClient.GetInputs(ctx)
|
||||
if err != nil {
|
||||
warn("Failed to get Sway inputs!", err)
|
||||
}
|
||||
|
||||
for _, input := range inputs {
|
||||
if input.Type != "keyboard" {
|
||||
continue
|
||||
}
|
||||
|
||||
return *input.XKBActiveLayoutName
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func long_layout_to_short(layout string) string {
|
||||
switch layout {
|
||||
case "English (US)":
|
||||
return "US"
|
||||
case "Estonian":
|
||||
return "ET"
|
||||
}
|
||||
|
||||
return layout
|
||||
}
|
278
statusbar.go
278
statusbar.go
|
@ -1,94 +1,14 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"sync"
|
||||
|
||||
sway "github.com/joshuarubin/go-sway"
|
||||
|
||||
"github.com/godbus/dbus/v5"
|
||||
"github.com/noisetorch/pulseaudio"
|
||||
)
|
||||
|
||||
const (
|
||||
SEPARATOR = " | "
|
||||
BATTERY = "BAT0"
|
||||
HEADSET = "94:DB:56:6B:E3:8A"
|
||||
|
||||
// cache key definitions
|
||||
CACHE_BT_CONNECTED = "bt_connected"
|
||||
CACHE_BT_BATTERY = "bt_battery"
|
||||
CACHE_MEDIA = "media"
|
||||
CACHE_LAYOUT = "kbd_layout"
|
||||
)
|
||||
|
||||
var (
|
||||
CONN Connections
|
||||
CACHE = sync.Map{}
|
||||
HEADSET_PATH = dbus.ObjectPath("/org/bluez/hci0/dev_" + strings.ReplaceAll(HEADSET, ":", "_"))
|
||||
)
|
||||
|
||||
func getC[T comparable](c sync.Map, id string, fallback func() T) T {
|
||||
val, ok := c.Load(id)
|
||||
if !ok {
|
||||
val = fallback()
|
||||
c.Store(id, val)
|
||||
}
|
||||
|
||||
return val.(T)
|
||||
}
|
||||
|
||||
type Connections struct {
|
||||
dbusSession, dbusSystem *dbus.Conn
|
||||
paClient *pulseaudio.Client
|
||||
swayClient sway.Client
|
||||
}
|
||||
|
||||
func init_connections() (Connections, error) {
|
||||
ctx := context.Background()
|
||||
|
||||
dbusSession, err := dbus.ConnectSessionBus()
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
dbusSystem, err := dbus.ConnectSystemBus()
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
paClient, err := pulseaudio.NewClient()
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
swayClient, err := sway.New(ctx)
|
||||
if err != nil {
|
||||
return Connections{}, err
|
||||
}
|
||||
|
||||
return Connections{
|
||||
dbusSession: dbusSession,
|
||||
dbusSystem: dbusSystem,
|
||||
paClient: paClient,
|
||||
swayClient: swayClient,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c Connections) close_all() {
|
||||
c.dbusSession.Close()
|
||||
c.dbusSystem.Close()
|
||||
c.paClient.Close()
|
||||
}
|
||||
|
||||
func main() {
|
||||
update := make(chan bool, 1)
|
||||
var err error // so assigning the global works
|
||||
|
@ -185,66 +105,6 @@ func produce_output() string {
|
|||
return output.String()
|
||||
}
|
||||
|
||||
func get_bt_headset_connected() bool {
|
||||
obj := CONN.dbusSystem.Object("org.bluez", HEADSET_PATH)
|
||||
|
||||
status, err := obj.GetProperty("org.bluez.Device1.Connected")
|
||||
if err == nil {
|
||||
if status.String() == "true" {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func get_bt_headset_battery() string {
|
||||
obj := CONN.dbusSystem.Object("org.bluez", HEADSET_PATH)
|
||||
|
||||
status, err := obj.GetProperty("org.bluez.Battery1.Percentage")
|
||||
if err == nil {
|
||||
return fmt.Sprintf("%v", status.Value())
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func get_playing_spotify_media() string {
|
||||
var output strings.Builder
|
||||
obj := CONN.dbusSession.Object("org.mpris.MediaPlayer2.spotify", "/org/mpris/MediaPlayer2")
|
||||
|
||||
metadata, err := obj.GetProperty("org.mpris.MediaPlayer2.Player.Metadata")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
status, err := obj.GetProperty("org.mpris.MediaPlayer2.Player.PlaybackStatus")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if status.String() != "\"Playing\"" {
|
||||
output.WriteString("‖ ")
|
||||
}
|
||||
|
||||
metadataMap := metadata.Value().(map[string]dbus.Variant)
|
||||
artists := make([]string, 1)
|
||||
metadataMap["xesam:artist"].Store(&artists)
|
||||
title := metadataMap["xesam:title"].String()
|
||||
|
||||
if title == "\"\"" {
|
||||
return ""
|
||||
}
|
||||
|
||||
output.WriteString(fmt.Sprintf(
|
||||
"%s - %s",
|
||||
strings.Join(artists, ", "),
|
||||
title[1:len(title)-1],
|
||||
))
|
||||
|
||||
return output.String()
|
||||
}
|
||||
|
||||
func signal_handler(feedback chan bool) {
|
||||
// SIGUSR1 can be sent to manually trigger a reprint
|
||||
sigs := make(chan os.Signal, 1)
|
||||
|
@ -269,141 +129,3 @@ func time_handler(feedback chan bool) {
|
|||
feedback <- true
|
||||
}
|
||||
}
|
||||
|
||||
func dbus_system_handler(feedback chan bool) {
|
||||
// watches for BT headset connections
|
||||
headsetObjectPath := "/org/bluez/hci0/dev_" + strings.ReplaceAll(HEADSET, ":", "_")
|
||||
|
||||
err := CONN.dbusSystem.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath(dbus.ObjectPath(headsetObjectPath)),
|
||||
dbus.WithMatchInterface("org.freedesktop.DBus.Properties"),
|
||||
)
|
||||
if err != nil {
|
||||
warn("Failed to add match signal", err)
|
||||
return
|
||||
}
|
||||
|
||||
sigs := make(chan *dbus.Signal, 1)
|
||||
CONN.dbusSystem.Signal(sigs)
|
||||
|
||||
for range sigs {
|
||||
CACHE.Delete(CACHE_BT_CONNECTED)
|
||||
CACHE.Delete(CACHE_BT_BATTERY)
|
||||
feedback <- true
|
||||
}
|
||||
}
|
||||
|
||||
func dbus_session_handler(feedback chan bool) {
|
||||
// watches for media changes
|
||||
err := CONN.dbusSession.AddMatchSignal(
|
||||
dbus.WithMatchObjectPath("/org/mpris/MediaPlayer2"),
|
||||
dbus.WithMatchInterface("org.freedesktop.DBus.Properties"),
|
||||
)
|
||||
if err != nil {
|
||||
warn("Failed to add match signal", err)
|
||||
return
|
||||
}
|
||||
|
||||
sigs := make(chan *dbus.Signal, 1)
|
||||
CONN.dbusSession.Signal(sigs)
|
||||
|
||||
for range sigs {
|
||||
CACHE.Delete(CACHE_MEDIA)
|
||||
feedback <- true
|
||||
}
|
||||
}
|
||||
|
||||
func get_default_sink_volume() (int, bool) {
|
||||
si, err := CONN.paClient.ServerInfo()
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
sinks, err := CONN.paClient.Sinks()
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
for i := range sinks {
|
||||
if sinks[i].Name == si.DefaultSink {
|
||||
return int(math.Round(float64(sinks[i].Cvolume[0]) / float64(sinks[i].BaseVolume) * 100)), sinks[i].Muted
|
||||
}
|
||||
}
|
||||
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func pulseaudio_handler(feedback chan bool) {
|
||||
vol, muted := get_default_sink_volume()
|
||||
|
||||
sigs, err := CONN.paClient.Updates()
|
||||
if err != nil {
|
||||
warn("Failed to create PulseAudio update listener!", err)
|
||||
return
|
||||
}
|
||||
|
||||
for range sigs {
|
||||
nVol, nMuted := get_default_sink_volume()
|
||||
if nVol != vol || nMuted != muted {
|
||||
feedback <- true
|
||||
vol = nVol
|
||||
muted = nMuted
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func get_current_layout() string {
|
||||
ctx := context.Background()
|
||||
inputs, err := CONN.swayClient.GetInputs(ctx)
|
||||
if err != nil {
|
||||
warn("Failed to get Sway inputs!", err)
|
||||
}
|
||||
|
||||
for _, input := range inputs {
|
||||
if input.Type != "keyboard" {
|
||||
continue
|
||||
}
|
||||
|
||||
return *input.XKBActiveLayoutName
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func long_layout_to_short(layout string) string {
|
||||
switch layout {
|
||||
case "English (US)":
|
||||
return "US"
|
||||
case "Estonian":
|
||||
return "ET"
|
||||
}
|
||||
|
||||
return layout
|
||||
}
|
||||
|
||||
type sway_handler struct {
|
||||
sway.EventHandler
|
||||
feedback chan bool
|
||||
}
|
||||
|
||||
func (h sway_handler) Input(ctx context.Context, ev sway.InputEvent) {
|
||||
if ev.Change != "xkb_layout" || ev.Input.Type != "keyboard" {
|
||||
return
|
||||
}
|
||||
|
||||
oldval, _ := CACHE.Load(CACHE_LAYOUT)
|
||||
if oldval == *ev.Input.XKBActiveLayoutName {
|
||||
return
|
||||
}
|
||||
|
||||
CACHE.Store(CACHE_LAYOUT, *ev.Input.XKBActiveLayoutName)
|
||||
h.feedback <- true
|
||||
}
|
||||
|
||||
func sway_input_handler(feedback chan bool) {
|
||||
ctx := context.Background()
|
||||
|
||||
var h sway.EventHandler = sway_handler{feedback: feedback}
|
||||
|
||||
sway.Subscribe(ctx, h, sway.EventTypeInput)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue