spk121 / guile-gi

Bindings for GObject Introspection and libgirepository for Guile
GNU General Public License v3.0
58 stars 7 forks source link

get-focus-child always gives a newly allocated reference? #123

Open lshoravi opened 2 years ago

lshoravi commented 2 years ago

Trying to compare two widgets for equal identity:

(define-method (split (container <GtkPaned>)
                      (orientation <symbol>))
  (let* ((focused (get-focus-child container))
         (setter (if (equal? focused (get-start-child container))
                     set-start-child
                     set-end-child)))
                     ...

However, the if-clause will always return #f, because get-focus-child seemingly always gives fresh references which hence are never eq? or equal?

    (display (get-focus-child container)) ; -> #<<GtkTextView> 7fc25c6e0e20>
    (display (get-focus-child container)) ; -> #<<GtkTextView> 7fc25c6e0b70>
    (display (get-focus-child container)) ; -> #<<GtkTextView> 7fc25c6e09b0>
    (display (eq? (get-focus-child container) (get-focus-child container)) ; -> #f

Is this a bug, or expected behaviour?

LordYuuma commented 2 years ago

This is expected behaviour. We don't maintain a mapping of SCM objects to GObjects, because doing so would make the GC<->refcount translation much more tedious. Instead, each time you receive an object from a GI context, we allocate a new SCM pointer, which calls unref upon being freed and depending on the transfer call ref on the structure. If you want to do comparisons, you'll have to compare the value slots.

What is a bug here, though, is that equal? is not defined for <GObject>, perhaps even <GFundamental>. IIUC it should be defined as (equal? (fiddle pointer-address object-a) (fiddle pointer-address object-b)).