fix: enhance variant handling and logging in portal signal processing

This commit is contained in:
jahruz67
2026-05-19 18:19:35 -07:00
parent fb555ea533
commit 12f314043e
+74 -15
View File
@@ -13,8 +13,20 @@ import (
"time" "time"
"github.com/godbus/dbus/v5" "github.com/godbus/dbus/v5"
"wis-free-v3/internal/logger"
) )
func unwrapVariant(val interface{}) interface{} {
for {
if v, ok := val.(dbus.Variant); ok {
val = v.Value()
} else {
break
}
}
return val
}
const ( const (
portalBusName = "org.freedesktop.portal.Desktop" portalBusName = "org.freedesktop.portal.Desktop"
portalObjectPath = "/org/freedesktop/portal/desktop" portalObjectPath = "/org/freedesktop/portal/desktop"
@@ -162,11 +174,31 @@ func portalWaitRequest(conn *dbus.Conn, reqPath dbus.ObjectPath) (uint32, map[st
if len(sig.Body) < 2 { if len(sig.Body) < 2 {
continue continue
} }
code, ok := sig.Body[0].(uint32) rawCode := unwrapVariant(sig.Body[0])
if !ok { var code uint32
switch x := rawCode.(type) {
case uint32:
code = x
case int:
code = uint32(x)
case int32:
code = uint32(x)
case uint8:
code = uint32(x)
default:
continue continue
} }
results, _ := sig.Body[1].(map[string]dbus.Variant) rawResults := unwrapVariant(sig.Body[1])
var results map[string]dbus.Variant
switch resMap := rawResults.(type) {
case map[string]dbus.Variant:
results = resMap
case map[string]interface{}:
results = make(map[string]dbus.Variant)
for k, val := range resMap {
results[k] = dbus.MakeVariant(val)
}
}
return code, results, nil return code, results, nil
case <-timeout.C: case <-timeout.C:
return 0, nil, fmt.Errorf("portal request timed out") return 0, nil, fmt.Errorf("portal request timed out")
@@ -175,7 +207,8 @@ func portalWaitRequest(conn *dbus.Conn, reqPath dbus.ObjectPath) (uint32, map[st
} }
func variantToObjectPath(v dbus.Variant) (dbus.ObjectPath, bool) { func variantToObjectPath(v dbus.Variant) (dbus.ObjectPath, bool) {
switch x := v.Value().(type) { val := unwrapVariant(v)
switch x := val.(type) {
case dbus.ObjectPath: case dbus.ObjectPath:
return x, true return x, true
case string: case string:
@@ -317,6 +350,14 @@ func (hk *Hotkey) portalSignalLoop() {
return return
} }
sessStr := string(sess)
var token string
if idx := strings.LastIndex(sessStr, "/"); idx != -1 {
token = sessStr[idx+1:]
} else {
token = sessStr
}
ch := make(chan *dbus.Signal, 32) ch := make(chan *dbus.Signal, 32)
conn.Signal(ch) conn.Signal(ch)
defer conn.RemoveSignal(ch) defer conn.RemoveSignal(ch)
@@ -325,11 +366,13 @@ func (hk *Hotkey) portalSignalLoop() {
ifaceGlobalShortcuts, ifaceGlobalShortcuts,
) )
if err := conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule).Store(); err != nil { if err := conn.BusObject().Call("org.freedesktop.DBus.AddMatch", 0, rule).Store(); err != nil {
log.Printf("wis-free-v3 hotkey: AddMatch GlobalShortcuts: %v", err) logger.Error("wis-free-v3 hotkey: AddMatch GlobalShortcuts: %v", err)
return return
} }
defer func() { _ = conn.BusObject().Call("org.freedesktop.DBus.RemoveMatch", 0, rule).Store() }() defer func() { _ = conn.BusObject().Call("org.freedesktop.DBus.RemoveMatch", 0, rule).Store() }()
logger.Info("Listening for global shortcut signals. Session token: %s", token)
for { for {
select { select {
case <-hk.portalStop: case <-hk.portalStop:
@@ -341,22 +384,38 @@ func (hk *Hotkey) portalSignalLoop() {
if len(sig.Body) < 2 { if len(sig.Body) < 2 {
continue continue
} }
sessVar, ok := sig.Body[0].(dbus.ObjectPath) rawSess := unwrapVariant(sig.Body[0])
if !ok { var sessVar dbus.ObjectPath
if s, ok := sig.Body[0].(string); ok { switch x := rawSess.(type) {
sessVar = dbus.ObjectPath(s) case dbus.ObjectPath:
} else { sessVar = x
continue case string:
} sessVar = dbus.ObjectPath(x)
} default:
if sessVar != sess {
continue continue
} }
id, ok := sig.Body[1].(string)
sessVarStr := string(sessVar)
match := false
if sessVar == sess {
match = true
} else if token != "" && (strings.HasSuffix(sessVarStr, "/"+token) || strings.Contains(sessVarStr, token)) {
match = true
}
if !match {
continue
}
rawID := unwrapVariant(sig.Body[1])
id, ok := rawID.(string)
if !ok || id != wisfreeGlobalShortcutID { if !ok || id != wisfreeGlobalShortcutID {
continue continue
} }
name := sig.Name name := sig.Name
logger.Info("Matched global shortcut signal: name=%s", name)
switch { switch {
case name == "Activated" || strings.HasSuffix(name, ".Activated"): case name == "Activated" || strings.HasSuffix(name, ".Activated"):
go func() { hk.keydownIn <- Event{} }() go func() { hk.keydownIn <- Event{} }()