Skip to content

Commit

Permalink
xrender: ensure that the clip mask is always updated
Browse files Browse the repository at this point in the history
Previously the clip-mask and the server value were compared with EQL when the
picture was synchronized, and the clip-mask was assigned to the server-value.
This approach breaks when the client (preasumbly to avoid consing) modifies
the vector directly. In that case the new value and the server value are EQ
while the clip still needs to be updated.

To avoid this problem when the clip-mask is a sequence, then we ensure that it
is a distinct vector.

Fixes #201.
  • Loading branch information
dkochmanski authored and scymtym committed Mar 31, 2023
1 parent 3840045 commit 610f23f
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions extensions/xrender.lisp
Original file line number Diff line number Diff line change
Expand Up @@ -593,15 +593,27 @@ by every function, which attempts to generate RENDER requests."
(aref (picture-%server-values picture) ,index)))
(setf (aref (picture-%server-values picture) ,index)
(aref (picture-%values picture) ,index))))))))
;; Ensure that the picture clip rectangles are updated when
;; it is necessary. It is important to copy the mask values
;; when it is a sequence (instead of assigning it), because
;; the client may modify the sequence without changing its
;; identity. We still test for EQUALP to avoid a roundtrip.
;; -- jd 2023-03-31
,(let ((index (position 'clip-mask specs :key #'second)))
`(unless (eql (aref (picture-%values picture) ,index)
(aref (picture-%server-values picture)
,index))
(%render-change-picture-clip-rectangles
picture (aref (picture-%values picture) ,index))
(setf (aref (picture-%server-values picture) ,index)
(aref (picture-%values picture) ,index))))

`(let ((clip-mask (aref (picture-%values picture) ,index))
(serv-mask (aref (picture-%server-values picture) ,index)))
(unless (equalp clip-mask serv-mask)
(if (typep clip-mask 'sequence)
(let ((clip-length (length clip-mask)))
(if (and (typep serv-mask 'sequence)
(= (length serv-mask) clip-length))
(replace serv-mask clip-mask)
(setf (aref (picture-%server-values picture) ,index)
(make-array clip-length
:initial-contents clip-mask)))
(%render-change-picture-clip-rectangles picture clip-mask))
(setf (aref (picture-%server-values picture) ,index)
clip-mask)))))
(setf (picture-%changed-p picture) nil)))

(defun render-create-picture
Expand Down

0 comments on commit 610f23f

Please sign in to comment.