emacs-exwm / xelb

X protocol Emacs Lisp Binding
https://elpa.gnu.org/packages/xelb.html
GNU General Public License v3.0
26 stars 4 forks source link

Fix assertion #27

Open andruska opened 5 months ago

andruska commented 5 months ago

(xcb:+request+reply connection
                   (make-instance 'xcb:ewmh:get-_NET_ACTIVE_WINDOW
                                  :window root)))

Error message:

Debugger entered--Lisp error: (cl-assertion-failed ((= 1 (length value)) nil))

Some debugging:

(slot-value connection 'reply-plist)
→ (96 (xcb:ewmh:get-_NET_ACTIVE_WINDOW [1 32 96 0 2 0 0 0 33 0 0 0 0 0 0 0 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 154 1 64 5 0 0 0 0]))

(setq reply-plist (slot-value connection 'reply-plist))
→ (96 (xcb:ewmh:get-_NET_ACTIVE_WINDOW [1 32 96 0 2 0 0 0 33 0 0 0 ...]))

(setq reply-data (plist-get reply-plist 96))
→ (xcb:ewmh:get-_NET_ACTIVE_WINDOW [1 32 96 0 2 0 0 0 33 0 0 0 ...])

(setq class-name (xcb:-request-class->reply-class (car reply-data)))
→ xcb:ewmh:get-_NET_ACTIVE_WINDOW~reply

(setq reply-data (cadr reply-data)
      replies (make-instance class-name))

(xcb:unmarshal replies reply-data)
→ error

(cl-assert (= 1 (length (slot-value replies 'value))))
→ error

(length (slot-value replies 'value))
→ 2
(slot-value replies 'type)
→ 33
(slot-value replies 'format)
→ 32
(slot-value replies 'bytes-after)
→ 0
(slot-value replies 'value-len)
→ 2
(slot-value replies 'value)
→ [88080794 0]
Stebalien commented 5 months ago

This is asserting that you're actually getting a single reply for a single-value property. It's supposed to error if you receive multiple replies. In this case, the window manager should never return two values.

How did you run into this?

andruska commented 5 months ago

I can always reproduce it when the reply is cached. I mean (slot-value connection 'reply-plist) gives something other than nil. If you try to call it out asynchronously first.

(xcb:+request connection
make-instance 'xcb:ewmh:get-_NET_ACTIVE_WINDOW
:window root)))

(xcb:flush connection)

and then to try unmarshal this reply.

Stebalien commented 5 months ago

This returns 1 for me:

(slot-value 
  (car (xcb:+request+reply exwm--connection
         (make-instance 'xcb:ewmh:get-_NET_ACTIVE_WINDOW :window exwm--root)))
  'value-len)
Stebalien commented 5 months ago

Again, what window manager?

andruska commented 5 months ago

Most often (eq value-len 2) and xelb assert error happens when manually evaluating the code by C-x C-e or C-j in the scratch buffer. While as a standalone code,(eq value-len 1) mostly works. It feels like the code can't make a final decision.

When I check xprop in terminal, it nevertheless always shows me 2 values:

# xprop -root -notype | grep _NET_ACTIVE_WINDOW
_NET_ACTIVE_WINDOW: window id # 0x480000b, 0x0

Seems to me that asserting to value-len could be a compatible solution.

Emacs 29.2 xfwm4 4.18.0-2

Stebalien commented 5 months ago

Hm. XFCE seems to differ from i3 and EXWM. It's recording a timestamp:

https://gitlab.xfce.org/xfce/xfwm4/-/blob/0bb79a2b15775236d839234dabfac80a2d2931fd/src/netwm.c#L1410-1429

Looking at the reference XCB library, XFWM4 looks incorrect:

https://cgit.freedesktop.org/xcb/util-wm/tree/ewmh/ewmh.c.m4

Can you report a bug here and see what they say? This looks like an old bug and I'm guessing that XELB is just a bit pickier than most tools.