Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package bluetuith for openSUSE:Factory 
checked in at 2023-11-06 21:14:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/bluetuith (Old)
 and      /work/SRC/openSUSE:Factory/.bluetuith.new.17445 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "bluetuith"

Mon Nov  6 21:14:16 2023 rev:6 rq:1123506 version:0.1.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/bluetuith/bluetuith.changes      2023-10-25 
18:06:12.553276691 +0200
+++ /work/SRC/openSUSE:Factory/.bluetuith.new.17445/bluetuith.changes   
2023-11-06 21:14:29.331729623 +0100
@@ -1,0 +2,9 @@
+Mon Nov  6 08:04:00 UTC 2023 - Michael Vetter <mvet...@suse.com>
+
+- Update to 0.1.9:
+  * bluez: Assert single/multiple property types safely
+  * ui: progress: Do not close page when no transfers are in progress
+  * ui: modal: Set width and height appropriately with the provided message
+  * ui: modal: Set width and height appropriately with the provided message
+
+-------------------------------------------------------------------

Old:
----
  bluetuith-0.1.8.tar.gz

New:
----
  bluetuith-0.1.9.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ bluetuith.spec ++++++
--- /var/tmp/diff_new_pack.PZuUIQ/_old  2023-11-06 21:14:30.223762458 +0100
+++ /var/tmp/diff_new_pack.PZuUIQ/_new  2023-11-06 21:14:30.227762606 +0100
@@ -17,7 +17,7 @@
 
 
 Name:           bluetuith
-Version:        0.1.8
+Version:        0.1.9
 Release:        0
 Summary:        A TUI bluetooth manager for Linux
 License:        MIT

++++++ _service ++++++
--- /var/tmp/diff_new_pack.PZuUIQ/_old  2023-11-06 21:14:30.255763636 +0100
+++ /var/tmp/diff_new_pack.PZuUIQ/_new  2023-11-06 21:14:30.255763636 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/darkhz/bluetuith.git</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v0.1.8</param>
+    <param name="revision">v0.1.9</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
   </service>

++++++ bluetuith-0.1.8.tar.gz -> bluetuith-0.1.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/README.md 
new/bluetuith-0.1.9/README.md
--- old/bluetuith-0.1.8/README.md       2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/README.md       2023-11-05 11:46:26.000000000 +0100
@@ -10,6 +10,8 @@
 
 This project is currently in the alpha stage.
 
+[![Packaging 
status](https://repology.org/badge/vertical-allrepos/bluetuith.svg)](https://repology.org/project/bluetuith/versions)
+
 ## Features
 - Transfer and receive files via OBEX.
 - Perform pairing with authentication.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/bluez/adapter.go 
new/bluetuith-0.1.9/bluez/adapter.go
--- old/bluetuith-0.1.8/bluez/adapter.go        2023-10-25 03:42:21.000000000 
+0200
+++ new/bluetuith-0.1.9/bluez/adapter.go        2023-11-05 11:46:26.000000000 
+0100
@@ -117,7 +117,7 @@
 }
 
 // ConvertToAdapters converts a map of dbus objects to a common Adapter 
structure.
-func (b *Bluez) ConvertToAdapters(path string, values 
map[string]map[string]dbus.Variant) []Adapter {
+func (b *Bluez) ConvertToAdapter(path string, values map[string]dbus.Variant, 
adapters *[]Adapter) error {
        /*
                /org/bluez/hci0
                        org.bluez.Adapter1
@@ -135,25 +135,21 @@
                                        Alias => 
dbus.Variant{sig:dbus.Signature{str:"s"}, value:"jonathan-Blade"}
 
        */
-       adapters := []Adapter{}
-       for k1, v1 := range values {
-               switch k1 {
-               case dbusBluezAdapterIface:
-                       adapters = append(adapters, Adapter{
-                               Path:         path,
-                               Name:         v1["Name"].Value().(string),
-                               Alias:        v1["Alias"].Value().(string),
-                               Address:      v1["Address"].Value().(string),
-                               Discoverable: v1["Discoverable"].Value().(bool),
-                               Pairable:     v1["Pairable"].Value().(bool),
-                               Powered:      v1["Powered"].Value().(bool),
-                               Discovering:  v1["Discovering"].Value().(bool),
-                               Lock:         semaphore.NewWeighted(1),
-                       })
-               }
+
+       var adapter Adapter
+
+       if err := DecodeVariantMap(values, &adapter, "Address"); err != nil {
+               return err
+       }
+
+       adapter.Path = path
+       adapter.Lock = semaphore.NewWeighted(1)
+
+       if adapters != nil {
+               *adapters = append(*adapters, adapter)
        }
 
-       return adapters
+       return nil
 }
 
 // GetAdapterProperties gathers all the properties for a bluetooth adapter.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/bluez/bluez.go 
new/bluetuith-0.1.9/bluez/bluez.go
--- old/bluetuith-0.1.8/bluez/bluez.go  2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/bluez/bluez.go  2023-11-05 11:46:26.000000000 +0100
@@ -75,21 +75,38 @@
        b.StoreLock.Lock()
        defer b.StoreLock.Unlock()
 
-       var store StoreObject
-
        results, err := b.ManagedObjects()
        if err != nil {
                return err
        }
 
-       devices := []Device{}
-       adapters := []Adapter{}
-       for k, v := range results {
-               adapters = append(adapters, b.ConvertToAdapters(string(k), 
v)...)
-               devices = append(devices, b.ConvertToDevices(string(k), v)...)
+       return b.ConvertAndStoreObjects(results)
+}
+
+func (b *Bluez) ConvertAndStoreObjects(objects 
map[dbus.ObjectPath]map[string]map[string]dbus.Variant) error {
+       var adapters []Adapter
+       var devices []Device
+
+       for path, object := range objects {
+               for iface, values := range object {
+                       var err error
+
+                       switch iface {
+                       case dbusBluezAdapterIface:
+                               err = b.ConvertToAdapter(string(path), values, 
&adapters)
+
+                       case dbusBluezDeviceIface:
+                               err = b.ConvertToDevice(string(path), values, 
&devices)
+                       }
+                       if err != nil {
+                               return err
+                       }
+               }
        }
 
        for _, adapter := range adapters {
+               var store StoreObject
+
                if adapter == (Adapter{}) {
                        continue
                }
@@ -153,20 +170,8 @@
                                return nil
                        }
 
-                       for prop, value := range objMap {
-                               switch prop {
-                               case "Powered":
-                                       adapter.Powered = value.Value().(bool)
-
-                               case "Discoverable":
-                                       adapter.Discoverable = 
value.Value().(bool)
-
-                               case "Pairable":
-                                       adapter.Pairable = value.Value().(bool)
-
-                               case "Discovering":
-                                       adapter.Discovering = 
value.Value().(bool)
-                               }
+                       if err := DecodeVariantMap(objMap, &adapter); err != 
nil {
+                               return nil
                        }
 
                        b.addAdapterToStore(adapter)
@@ -179,26 +184,8 @@
                                return nil
                        }
 
-                       for prop, value := range objMap {
-                               switch prop {
-                               case "Connected":
-                                       device.Connected = value.Value().(bool)
-
-                               case "Paired":
-                                       device.Paired = value.Value().(bool)
-
-                               case "Trusted":
-                                       device.Trusted = value.Value().(bool)
-
-                               case "Bonded":
-                                       device.Bonded = value.Value().(bool)
-
-                               case "Blocked":
-                                       device.Blocked = value.Value().(bool)
-
-                               case "RSSI":
-                                       device.RSSI = value.Value().(int16)
-                               }
+                       if err := DecodeVariantMap(objMap, &device); err != nil 
{
+                               return nil
                        }
 
                        b.addDeviceToStore(device)
@@ -206,20 +193,7 @@
                        return device
 
                case dbusBluezMediaPlayerIface:
-                       var media MediaProperties
-
-                       for prop, value := range objMap {
-                               switch prop {
-                               case "Status":
-                                       media.Status = value.Value().(string)
-
-                               case "Position":
-                                       media.Position = value.Value().(uint32)
-
-                               case "Track":
-                                       media.Track = 
getTrackProperties(value.Value().(map[string]dbus.Variant))
-                               }
-                       }
+                       media, _ := b.GetMediaProperties(objMap)
 
                        return media
 
@@ -229,8 +203,12 @@
                                return nil
                        }
 
-                       device.Percentage = 
int(objMap["Percentage"].Value().(byte))
-                       b.addDeviceToStore(device)
+                       if v, ok := objMap["Percentage"]; ok {
+                               if p, ok := v.Value().(byte); ok {
+                                       device.Percentage = int(p)
+                                       b.addDeviceToStore(device)
+                               }
+                       }
 
                        return device
                }
@@ -252,9 +230,15 @@
                for iftype := range objMap {
                        switch iftype {
                        case dbusBluezAdapterIface:
+                               var adapters []Adapter
+
                                adapterPath := string(objPath)
 
-                               adapters := b.ConvertToAdapters(adapterPath, 
objMap)
+                               for _, values := range objMap {
+                                       if err := 
b.ConvertToAdapter(adapterPath, values, &adapters); err != nil {
+                                               continue
+                                       }
+                               }
                                for _, adapter := range adapters {
                                        b.addAdapterToStore(adapter)
                                }
@@ -262,9 +246,15 @@
                                return adapters
 
                        case dbusBluezDeviceIface:
+                               var devices []Device
+
                                devicePath := string(objPath)
 
-                               devices := b.ConvertToDevices(devicePath, 
objMap)
+                               for _, values := range objMap {
+                                       if err := b.ConvertToDevice(devicePath, 
values, &devices); err != nil {
+                                               continue
+                                       }
+                               }
                                for _, device := range devices {
                                        b.addDeviceToStore(device)
                                }
@@ -282,8 +272,12 @@
                                        return nil
                                }
 
-                               device.Percentage = 
int(objMap[iftype]["Percentage"].Value().(byte))
-                               b.addDeviceToStore(device)
+                               if v, ok := objMap[iftype]["Percentage"]; ok {
+                                       if p, ok := v.Value().(byte); ok {
+                                               device.Percentage = int(p)
+                                               b.addDeviceToStore(device)
+                                       }
+                               }
 
                                return map[string][]Device{devicePath: {device}}
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/bluez/device.go 
new/bluetuith-0.1.9/bluez/device.go
--- old/bluetuith-0.1.8/bluez/device.go 2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/bluez/device.go 2023-11-05 11:46:26.000000000 +0100
@@ -119,7 +119,7 @@
 }
 
 // ConvertToDevices converts a map of dbus objects to a common Device 
structure.
-func (b *Bluez) ConvertToDevices(path string, values 
map[string]map[string]dbus.Variant) []Device {
+func (b *Bluez) ConvertToDevice(path string, values map[string]dbus.Variant, 
devices *[]Device) error {
        /*
                org.bluez.Device1
                        Icon => dbus.Variant{sig:dbus.Signature{str:"s"}, 
value:"audio-card"}
@@ -138,65 +138,23 @@
                        Class => dbus.Variant{sig:dbus.Signature{str:"u"}, 
value:0x240418}
 
        */
-       devices := []Device{}
-       for k, v := range values {
-               var name, modalias string
-               var uuids []string
-               var rssi int16
-               var class uint32
-               var percentage int
-
-               if n, ok := v["Name"].Value().(string); ok {
-                       name = n
-               }
-
-               if i, ok := v["RSSI"].Value().(int16); ok {
-                       rssi = i
-               }
-
-               if c, ok := v["Class"].Value().(uint32); ok {
-                       class = c
-               }
-
-               if u, ok := v["UUIDs"].Value().([]string); ok {
-                       uuids = u
-               }
-
-               if m, ok := v["Modalias"].Value().(string); ok {
-                       modalias = m
-               }
-
-               if p, err := b.GetBatteryPercentage(path); err == nil {
-                       percentage = int(p)
-               }
-
-               switch k {
-               case dbusBluezDeviceIface:
-                       adapter, _ := v["Adapter"].Value().(dbus.ObjectPath)
-                       devices = append(devices, Device{
-                               Path:          path,
-                               Name:          name,
-                               Class:         class,
-                               RSSI:          rssi,
-                               UUIDs:         uuids,
-                               Modalias:      modalias,
-                               Percentage:    percentage,
-                               Type:          GetDeviceType(class),
-                               Alias:         v["Alias"].Value().(string),
-                               Address:       v["Address"].Value().(string),
-                               AddressType:   
v["AddressType"].Value().(string),
-                               Adapter:       string(adapter),
-                               Paired:        v["Paired"].Value().(bool),
-                               Connected:     v["Connected"].Value().(bool),
-                               Trusted:       v["Trusted"].Value().(bool),
-                               Blocked:       v["Blocked"].Value().(bool),
-                               Bonded:        v["Bonded"].Value().(bool),
-                               LegacyPairing: 
v["LegacyPairing"].Value().(bool),
-                       })
-               }
+       var device Device
+
+       if err := DecodeVariantMap(values, &device, "Name", "Address"); err != 
nil {
+               return err
+       }
+
+       device.Path = path
+       device.Type = GetDeviceType(device.Class)
+       if p, err := b.GetBatteryPercentage(path); err == nil {
+               device.Percentage = int(p)
+       }
+
+       if devices != nil {
+               *devices = append(*devices, device)
        }
 
-       return devices
+       return nil
 }
 
 // GetDeviceType parses the device class and returns its type.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/bluez/media.go 
new/bluetuith-0.1.9/bluez/media.go
--- old/bluetuith-0.1.8/bluez/media.go  2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/bluez/media.go  2023-11-05 11:46:26.000000000 +0100
@@ -104,25 +104,39 @@
 }
 
 // GetMediaProperties gets the media properties of the currently playing track.
-func (b *Bluez) GetMediaProperties() (MediaProperties, error) {
-       var track map[string]dbus.Variant
-
-       mediaPlayer, err := b.GetMediaPlayerProperties()
-       if err != nil {
-               return MediaProperties{}, err
+func (b *Bluez) GetMediaProperties(values ...map[string]dbus.Variant) 
(MediaProperties, error) {
+       var props MediaProperties
+       var mediaPlayer map[string]dbus.Variant
+
+       if values != nil {
+               mediaPlayer = values[0]
+       } else {
+               mp, err := b.GetMediaPlayerProperties()
+               if err != nil {
+                       return MediaProperties{}, err
+               }
+
+               mediaPlayer = mp
+       }
+
+       track := TrackProperties{
+               Artist: "<Unknown Artist>",
+               Album:  "<Unknown Album>",
        }
-
        if t, ok := mediaPlayer["Track"].Value().(map[string]dbus.Variant); ok {
-               track = t
-       }
+               if err := DecodeVariantMap(t, &track); err != nil {
+                       return MediaProperties{}, err
+               }
 
-       props := MediaProperties{
-               Status:   mediaPlayer["Status"].Value().(string),
-               Position: mediaPlayer["Position"].Value().(uint32),
-               Track:    getTrackProperties(track),
+               if track.TrackNumber > 0 && track.TotalTracks == 0 {
+                       track.TotalTracks = track.TrackNumber
+               }
        }
+       delete(mediaPlayer, "Track")
 
-       return props, nil
+       props.Track = track
+
+       return props, DecodeVariantMap(mediaPlayer, &props)
 }
 
 // GetMediaPlayerProperties gets the media player properties.
@@ -202,49 +216,3 @@
                Call(dbusBluezMediaPlayerIface+"."+command, 0).
                Store()
 }
-
-// getTrackProperties returns the track properties.
-func getTrackProperties(props map[string]dbus.Variant) TrackProperties {
-       var title, album, artist string
-       var number, total, duration uint32
-
-       artist = "<Unknown Artist>"
-       album = "<Unknown Album>"
-
-       if props == nil {
-               return TrackProperties{}
-       }
-
-       if t, ok := props["Title"].Value().(string); ok {
-               title = t
-       }
-
-       if b, ok := props["Album"].Value().(string); ok {
-               album = b
-       }
-
-       if a, ok := props["Artist"].Value().(string); ok {
-               artist = a
-       }
-
-       if d, ok := props["Duration"].Value().(uint32); ok {
-               duration = d
-       }
-
-       if n, ok := props["TrackNumber"].Value().(uint32); ok {
-               number = n
-       }
-
-       if s, ok := props["NumberOfTracks"].Value().(uint32); ok {
-               total = s
-       }
-
-       return TrackProperties{
-               Title:       title,
-               Album:       album,
-               Artist:      artist,
-               Duration:    duration,
-               TrackNumber: number,
-               TotalTracks: total,
-       }
-}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/bluez/obex.go 
new/bluetuith-0.1.9/bluez/obex.go
--- old/bluetuith-0.1.8/bluez/obex.go   2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/bluez/obex.go   2023-11-05 11:46:26.000000000 +0100
@@ -39,7 +39,7 @@
        Size        uint64
        Transferred uint64
 
-       Session dbus.ObjectPath
+       Session string
 }
 
 // ObexProperties stores the session and transfer paths of
@@ -129,10 +129,10 @@
                return "", ObexTransferProperties{}, err
        }
 
-       transferProperties := o.GetTransferProperties(transferPropertyMap)
+       transferProperties, err := o.GetTransferProperties(transferPropertyMap)
        o.addTransferPropertiesToStore(transferPath, transferProperties)
 
-       return transferPath, transferProperties, nil
+       return transferPath, transferProperties, err
 }
 
 // ReceiveFile returns a path where the OBEX daemon (obexd) will receive the 
file, along with
@@ -154,7 +154,11 @@
                                        continue
                                }
 
-                               sessionProperty, _ = 
o.GetSessionProperties(sessionPath, value)
+                               sessionProperty, err = 
o.GetSessionProperties(sessionPath, value)
+                               if err != nil {
+                                       return "", "", 
ObexTransferProperties{}, errors.New("Session error")
+                               }
+
                                o.addSessionPropertiesToStore(sessionPath, 
sessionProperty)
                        }
 
@@ -164,8 +168,8 @@
                                        continue
                                }
 
-                               transferProperty = 
o.GetTransferProperties(value)
-                               if transferProperty.Status == "error" {
+                               transferProperty, err = 
o.GetTransferProperties(value)
+                               if err != nil || transferProperty.Status == 
"error" {
                                        return "", "", 
ObexTransferProperties{}, errors.New("Transfer error")
                                }
 
@@ -204,7 +208,6 @@
 
 // GetSessionProperties converts a map of OBEX session properties to 
ObexSessionProperties.
 func (o *Obex) GetSessionProperties(sessionPath dbus.ObjectPath, sprop 
...map[string]dbus.Variant) (ObexSessionProperties, error) {
-       var root, source, target string
        var sessionProperties ObexSessionProperties
 
        props := make(map[string]dbus.Variant)
@@ -216,64 +219,14 @@
                props = sprop[0]
        }
 
-       if t, ok := props["Root"].Value().(string); ok {
-               root = t
-       }
-
-       if s, ok := props["Source"].Value().(string); ok {
-               source = s
-       }
-
-       if t, ok := props["Target"].Value().(string); ok {
-               target = t
-       }
-
-       sessionProperties = ObexSessionProperties{
-               Root:        root,
-               Target:      target,
-               Source:      source,
-               Destination: props["Destination"].Value().(string),
-       }
-
-       return sessionProperties, nil
+       return sessionProperties, DecodeVariantMap(props, &sessionProperties)
 }
 
 // GetTransferProperties converts a map of transfer properties to 
ObexTransferProperties.
-func (o *Obex) GetTransferProperties(props map[string]dbus.Variant) 
ObexTransferProperties {
-       var size, transferred uint64
-       var name, ftype, fname string
-
-       if n, ok := props["Name"].Value().(string); ok {
-               name = n
-       }
+func (o *Obex) GetTransferProperties(props map[string]dbus.Variant) 
(ObexTransferProperties, error) {
+       var obexTransferProperties ObexTransferProperties
 
-       if t, ok := props["Type"].Value().(string); ok {
-               ftype = t
-       }
-
-       if f, ok := props["Filename"].Value().(string); ok {
-               fname = f
-       }
-
-       if s, ok := props["Size"].Value().(uint64); ok {
-               size = s
-       }
-
-       if t, ok := props["Transferred"].Value().(uint64); ok {
-               transferred = t
-       }
-
-       return ObexTransferProperties{
-               Name:     name,
-               Type:     ftype,
-               Status:   props["Status"].Value().(string),
-               Filename: fname,
-
-               Size:        size,
-               Transferred: transferred,
-
-               Session: props["Session"].Value().(dbus.ObjectPath),
-       }
+       return obexTransferProperties, DecodeVariantMap(props, 
&obexTransferProperties)
 }
 
 // ManagedObjects gets the currently managed objects from the OBEX DBus.
@@ -321,10 +274,10 @@
                        for prop, value := range objMap {
                                switch prop {
                                case "Status":
-                                       props.TransferProperties.Status = 
value.Value().(string)
+                                       props.TransferProperties.Status, _ = 
value.Value().(string)
 
                                case "Transferred":
-                                       props.TransferProperties.Transferred = 
value.Value().(uint64)
+                                       props.TransferProperties.Transferred, _ 
= value.Value().(uint64)
                                }
                        }
 
@@ -374,11 +327,13 @@
        o.StoreLock.Lock()
        defer o.StoreLock.Unlock()
 
-       obexProperties := o.Store[transferProperties.Session]
+       transferObjectPath := dbus.ObjectPath(transferProperties.Session)
+
+       obexProperties := o.Store[transferObjectPath]
        obexProperties.TransferPath = transferPath
        obexProperties.TransferProperties = transferProperties
 
-       o.Store[transferProperties.Session] = obexProperties
+       o.Store[transferObjectPath] = obexProperties
 }
 
 // getPropertiesFromStore gets the ObexProperties from the store.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/bluez/resolver.go 
new/bluetuith-0.1.9/bluez/resolver.go
--- old/bluetuith-0.1.8/bluez/resolver.go       1970-01-01 01:00:00.000000000 
+0100
+++ new/bluetuith-0.1.9/bluez/resolver.go       2023-11-05 11:46:26.000000000 
+0100
@@ -0,0 +1,62 @@
+package bluez
+
+import (
+       "fmt"
+       "sync"
+
+       "github.com/godbus/dbus/v5"
+       "github.com/ugorji/go/codec"
+)
+
+// Resolver holds an encoder and decoder.
+type Resolver struct {
+       check bool
+
+       encoder *codec.Encoder
+       decoder *codec.Decoder
+       data    []byte
+
+       lock sync.Mutex
+}
+
+var resolver Resolver
+
+// DecodeVariantMap decodes a map of variants into the provided data.
+func DecodeVariantMap(
+       variants map[string]dbus.Variant, data interface{},
+       checkProps ...string,
+) error {
+       resolver.lock.Lock()
+       defer resolver.lock.Unlock()
+
+       if !resolver.check {
+               resolver.encoder = codec.NewEncoderBytes(&resolver.data, 
&codec.SimpleHandle{})
+               resolver.decoder = codec.NewDecoderBytes(resolver.data, 
&codec.SimpleHandle{})
+
+               resolver.check = true
+       }
+
+       props := make(map[string]interface{}, len(variants))
+       for key, value := range variants {
+               for _, prop := range checkProps {
+                       if prop == key && value.Signature().Empty() {
+                               return fmt.Errorf("No signature found for 
property '%s'", prop)
+                       }
+               }
+
+               val := value.Value()
+               if v, ok := val.(dbus.ObjectPath); ok {
+                       val = string(v)
+               }
+
+               props[key] = val
+       }
+
+       resolver.encoder.ResetBytes(&resolver.data)
+       if err := resolver.encoder.Encode(props); err != nil {
+               return err
+       }
+
+       resolver.decoder.ResetBytes(resolver.data)
+       return resolver.decoder.Decode(data)
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/go.mod new/bluetuith-0.1.9/go.mod
--- old/bluetuith-0.1.8/go.mod  2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/go.mod  2023-11-05 11:46:26.000000000 +0100
@@ -5,11 +5,11 @@
 require (
        github.com/Wifx/gonetworkmanager v0.5.0
        github.com/alexeyco/simpletable v1.0.0
-       github.com/darkhz/tview v0.0.0-20231024170842-8ad8aa98b6bf
+       github.com/darkhz/tview v0.0.0-20231104100140-47fe281832ee
        github.com/fatih/color v1.15.0
        github.com/gdamore/tcell/v2 v2.6.1-0.20230827060410-08c7757cd1c9
        github.com/godbus/dbus/v5 v5.1.0
-       github.com/google/uuid v1.3.1
+       github.com/google/uuid v1.4.0
        github.com/hjson/hjson-go/v4 v4.3.1
        github.com/knadh/koanf/parsers/hjson v0.1.0
        github.com/knadh/koanf/providers/file v0.1.0
@@ -20,8 +20,9 @@
        github.com/pkg/errors v0.9.1
        github.com/schollz/progressbar/v3 v3.13.1
        github.com/spf13/pflag v1.0.5
-       golang.org/x/sync v0.4.0
-       golang.org/x/text v0.13.0
+       github.com/ugorji/go/codec v1.2.11
+       golang.org/x/sync v0.5.0
+       golang.org/x/text v0.14.0
 )
 
 require (
@@ -36,6 +37,6 @@
        github.com/mitchellh/mapstructure v1.5.0 // indirect
        github.com/mitchellh/reflectwalk v1.0.2 // indirect
        github.com/rivo/uniseg v0.4.4 // indirect
-       golang.org/x/sys v0.13.0 // indirect
+       golang.org/x/sys v0.14.0 // indirect
        golang.org/x/term v0.13.0 // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/go.sum new/bluetuith-0.1.9/go.sum
--- old/bluetuith-0.1.8/go.sum  2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/go.sum  2023-11-05 11:46:26.000000000 +0100
@@ -2,38 +2,28 @@
 github.com/Wifx/gonetworkmanager v0.5.0/go.mod 
h1:EdhHf2O00IZXfMv9LC6CS6SgTwcMTg/ZSDhGvch0cs8=
 github.com/alexeyco/simpletable v1.0.0 
h1:ZQ+LvJ4bmoeHb+dclF64d0LX+7QAi7awsfCrptZrpHk=
 github.com/alexeyco/simpletable v1.0.0/go.mod 
h1:VJWVTtGUnW7EKbMRH8cE13SigKGx/1fO2SeeOiGeBkk=
-github.com/darkhz/tview v0.0.0-20221222105743-b326fa380384 
h1:PGz8338YGcARCfDBD2aKNc/22c0jAMtvUJfkt83w7L8=
-github.com/darkhz/tview v0.0.0-20221222105743-b326fa380384/go.mod 
h1:8/QAL80tE9kMnlxevgPLegYJRAbcgsOrTXvAEIDjoF4=
-github.com/darkhz/tview v0.0.0-20230720044103-bb5a57216ca9 
h1:yF3vS+n1VO4yZHZShlkg68ExCG8er7XjK6p1i3OX5bQ=
-github.com/darkhz/tview v0.0.0-20230720044103-bb5a57216ca9/go.mod 
h1:AMVvDCpcWG8IEqVuFSM7wKSeSHNpupJUkDAaWFokdnA=
-github.com/darkhz/tview v0.0.0-20230828105912-31c010050650 
h1:1BujOs8J2+XG6Wdhh56sYiRwpSvM7k214t+OgGvgo3s=
-github.com/darkhz/tview v0.0.0-20230828105912-31c010050650/go.mod 
h1:AMVvDCpcWG8IEqVuFSM7wKSeSHNpupJUkDAaWFokdnA=
 github.com/darkhz/tview v0.0.0-20231024170842-8ad8aa98b6bf 
h1:IaxHiM9/fNOL/E+bnKioAhzV29e8vH4C2SKZiPhYZfE=
 github.com/darkhz/tview v0.0.0-20231024170842-8ad8aa98b6bf/go.mod 
h1:AMVvDCpcWG8IEqVuFSM7wKSeSHNpupJUkDAaWFokdnA=
+github.com/darkhz/tview v0.0.0-20231104100140-47fe281832ee 
h1:tbjT27OmRzFEn7ocqxhd0q1w9BUqocPiO+zsWjNPG7E=
+github.com/darkhz/tview v0.0.0-20231104100140-47fe281832ee/go.mod 
h1:AMVvDCpcWG8IEqVuFSM7wKSeSHNpupJUkDAaWFokdnA=
 github.com/davecgh/go-spew v1.1.0/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
 github.com/fatih/color v1.15.0/go.mod 
h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
-github.com/fsnotify/fsnotify v1.6.0 
h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
-github.com/fsnotify/fsnotify v1.6.0/go.mod 
h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
 github.com/fsnotify/fsnotify v1.7.0 
h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
 github.com/fsnotify/fsnotify v1.7.0/go.mod 
h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
 github.com/gdamore/encoding v1.0.0 
h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
 github.com/gdamore/encoding v1.0.0/go.mod 
h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
-github.com/gdamore/tcell/v2 v2.6.0 
h1:OKbluoP9VYmJwZwq/iLb4BxwKcwGthaa1YNBJIyCySg=
-github.com/gdamore/tcell/v2 v2.6.0/go.mod 
h1:be9omFATkdr0D9qewWW3d+MEvl5dha+Etb5y65J2H8Y=
 github.com/gdamore/tcell/v2 v2.6.1-0.20230827060410-08c7757cd1c9 
h1:oGyNIr88gcXXMdFQCVH800dCUv8Cr4QwquxYPJ634DQ=
 github.com/gdamore/tcell/v2 v2.6.1-0.20230827060410-08c7757cd1c9/go.mod 
h1:pwzJMyH4Hd0AZMJkWQ+/g01dDvYWEvmJuaiRU71Xl8k=
 github.com/godbus/dbus/v5 v5.0.2/go.mod 
h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.1.0 
h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
 github.com/godbus/dbus/v5 v5.1.0/go.mod 
h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
 github.com/google/uuid v1.3.1/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/hjson/hjson-go/v4 v4.3.0 
h1:dyrzJdqqFGhHt+FSrs5n9s6b0fPM8oSJdWo+oS3YnJw=
-github.com/hjson/hjson-go/v4 v4.3.0/go.mod 
h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
+github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
+github.com/google/uuid v1.4.0/go.mod 
h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/hjson/hjson-go/v4 v4.3.1 
h1:wfmDwHGxjzmYKXRFL0Qr9nonY/Xxe5y7IalwjlY7ekA=
 github.com/hjson/hjson-go/v4 v4.3.1/go.mod 
h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E=
 github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod 
h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
@@ -54,14 +44,10 @@
 github.com/mattn/go-colorable v0.1.13 
h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
 github.com/mattn/go-colorable v0.1.13/go.mod 
h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
 github.com/mattn/go-isatty v0.0.16/go.mod 
h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.17 
h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
 github.com/mattn/go-isatty v0.0.17/go.mod 
h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
-github.com/mattn/go-isatty v0.0.19 
h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
-github.com/mattn/go-isatty v0.0.19/go.mod 
h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-isatty v0.0.20 
h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
 github.com/mattn/go-isatty v0.0.20/go.mod 
h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
 github.com/mattn/go-runewidth v0.0.12/go.mod 
h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
-github.com/mattn/go-runewidth v0.0.14 
h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
 github.com/mattn/go-runewidth v0.0.14/go.mod 
h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mattn/go-runewidth v0.0.15 
h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
 github.com/mattn/go-runewidth v0.0.15/go.mod 
h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
@@ -89,6 +75,8 @@
 github.com/stretchr/objx v0.1.0/go.mod 
h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.3.0/go.mod 
h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.8.1 
h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/ugorji/go/codec v1.2.11 
h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
+github.com/ugorji/go/codec v1.2.11/go.mod 
h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
 github.com/yuin/goldmark v1.4.13/go.mod 
h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod 
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -101,43 +89,40 @@
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
-golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
 golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
+golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod 
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
 golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
 golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
+golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod 
h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
-golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
 golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
-golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
-golang.org/x/term v0.11.0/go.mod 
h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
 golang.org/x/term v0.13.0/go.mod 
h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
 golang.org/x/text v0.12.0/go.mod 
h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
 golang.org/x/text v0.13.0/go.mod 
h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod 
h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.1.12/go.mod 
h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/ui/device.go 
new/bluetuith-0.1.9/ui/device.go
--- old/bluetuith-0.1.8/ui/device.go    2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/ui/device.go    2023-11-05 11:46:26.000000000 +0100
@@ -40,7 +40,7 @@
                return ignoreDefaultEvent(event)
        })
        DeviceTable.SetMouseCapture(func(action tview.MouseAction, event 
*tcell.EventMouse) (tview.MouseAction, *tcell.EventMouse) {
-               if action == tview.MouseRightClick {
+               if action == tview.MouseRightClick && DeviceTable.HasFocus() {
                        device := getDeviceFromSelection(false)
                        if device.Path == "" {
                                return action, event
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/ui/menubar.go 
new/bluetuith-0.1.9/ui/menubar.go
--- old/bluetuith-0.1.8/ui/menubar.go   2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/ui/menubar.go   2023-11-05 11:46:26.000000000 +0100
@@ -247,6 +247,7 @@
        var width, skipped int
 
        modal := menu.modal
+       modal.Table.SetSelectorWrap(false)
        modal.Table.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey 
{
                switch cmd.KeyOperation(event) {
                case cmd.KeyClose:
@@ -369,9 +370,7 @@
        })
        modal.Table.SetMouseCapture(func(action tview.MouseAction, event 
*tcell.EventMouse) (tview.MouseAction, *tcell.EventMouse) {
                if action == tview.MouseLeftClick && 
modal.Table.InRect(event.Position()) {
-                       if selected != nil {
-                               
modal.Table.InputHandler()(tcell.NewEventKey(tcell.KeyEnter, ' ', 
tcell.ModNone), nil)
-                       }
+                       exitMenu()
                }
 
                return action, event
@@ -455,7 +454,7 @@
                return
        }
 
-       key := cmd.KeyOperation(event, UI.pageContext)
+       key := cmd.KeyOperation(event, UI.pageContext, cmd.KeyContextProgress)
 
        for _, options := range menu.options {
                for menuKey, option := range options {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/ui/modal.go 
new/bluetuith-0.1.9/ui/modal.go
--- old/bluetuith-0.1.8/ui/modal.go     2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/ui/modal.go     2023-11-05 11:46:26.000000000 +0100
@@ -1,8 +1,6 @@
 package ui
 
 import (
-       "strings"
-
        "github.com/darkhz/bluetuith/cmd"
        "github.com/darkhz/bluetuith/theme"
        "github.com/darkhz/tview"
@@ -134,12 +132,7 @@
 func NewDisplayModal(name, title, message string) {
        message += "\n\nPress any key or click the 'X' button to close this 
dialog."
 
-       width := len(strings.Split(message, "\n")[0])
-       if width > 100 {
-               width = 100
-       }
-
-       height := len(tview.WordWrap(message, width)) * 4
+       width, height := getModalDimensions(message, "")
 
        textview := tview.NewTextView()
        textview.SetText(message)
@@ -148,7 +141,7 @@
        textview.SetTextColor(theme.GetColor(theme.ThemeText))
        textview.SetBackgroundColor(theme.GetColor(theme.ThemeBackground))
 
-       modal := NewModal(name, title, textview, height, width)
+       modal := NewModal(name, title, textview, width, height)
        textview.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
                modal.Exit(false)
 
@@ -156,6 +149,10 @@
        })
 
        go UI.QueueUpdateDraw(func() {
+               if m, ok := ModalExists(name); ok {
+                       m.Exit(false)
+               }
+
                modal.Show()
        })
 }
@@ -165,6 +162,7 @@
        var modal *Modal
 
        message += "\n\nPress y/n to Confirm/Cancel, click the required button 
or click the 'X' button to close this dialog."
+       buttonsText := `["confirm"][::b][Confirm[] ["cancel"][::b][Cancel[]`
 
        reply := make(chan string, 10)
 
@@ -176,20 +174,15 @@
                }
        }
 
-       width := len(strings.Split(message, "\n")[0])
-       if width > 100 {
-               width = 100
-       }
-
-       height := len(tview.WordWrap(message, width)) * 4
+       width, height := getModalDimensions(message, buttonsText)
 
        buttons := tview.NewTextView()
        buttons.SetRegions(true)
+       buttons.SetText(buttonsText)
        buttons.SetDynamicColors(true)
        buttons.SetTextAlign(tview.AlignCenter)
        buttons.SetTextColor(theme.GetColor(theme.ThemeText))
        buttons.SetBackgroundColor(theme.GetColor(theme.ThemeBackground))
-       buttons.SetText(`["confirm"][::b][Confirm[] ["cancel"][::b][Cancel[]`)
        buttons.SetHighlightedFunc(func(added, removed, remaining []string) {
                if added == nil {
                        return
@@ -236,6 +229,10 @@
        })
 
        go UI.QueueUpdateDraw(func() {
+               if m, ok := ModalExists(name); ok {
+                       m.Exit(false)
+               }
+
                modal.Show()
        })
 
@@ -402,8 +399,6 @@
                case tview.MouseRightClick:
                        if menu.bar.InRect(x, y) {
                                return nil, action
-                       } else if DeviceTable.InRect(x, y) {
-                               menu.bar.Highlight("")
                        }
 
                case tview.MouseLeftClick:
@@ -422,3 +417,23 @@
 
        return event, action
 }
+
+// getModalDimensions returns the height and width to set for the modal
+// according to the provided text.
+// Adapted from: 
https://github.com/rivo/tview/blob/1b91b8131c43011d923fe59855b4de3571dac997/modal.go#L156
+func getModalDimensions(text, buttons string) (int, int) {
+       _, _, screenWidth, _ := UI.Pages.GetRect()
+       buttonWidth := tview.TaggedStringWidth(buttons) - 2
+
+       width := screenWidth / 3
+       if width < buttonWidth {
+               width = buttonWidth
+       }
+
+       padding := 6
+       if buttonWidth < 0 {
+               padding -= 2
+       }
+
+       return width + 4, len(tview.WordWrap(text, width)) + padding
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/bluetuith-0.1.8/ui/progress.go 
new/bluetuith-0.1.9/ui/progress.go
--- old/bluetuith-0.1.8/ui/progress.go  2023-10-25 03:42:21.000000000 +0200
+++ new/bluetuith-0.1.9/ui/progress.go  2023-11-05 11:46:26.000000000 +0100
@@ -221,18 +221,6 @@
                                break
                        }
                }
-
-               if getProgressCount() == 0 {
-                       if pg, _ := UI.Status.GetFrontPage(); pg == 
"progressview" {
-                               UI.Status.RemovePage("progressview")
-                       }
-
-                       if pg, _ := UI.Pages.GetFrontPage(); pg == 
"progressview" {
-                               UI.Pages.RemovePage("progressview")
-                       }
-
-                       UI.Status.SwitchToPage("messages")
-               }
        })
 
        if path != nil && p.status == "complete" {

++++++ vendor.tar.gz ++++++
++++ 36267 lines of diff (skipped)

Reply via email to