From 9e1f9d2837d201e789ea67782a0ec450c18f5cec Mon Sep 17 00:00:00 2001
From: mia <>
Date: Nov 07 2023 20:37:45 +0000
Subject: Update picom to version 10.2 / rev 8 via SR 1123689


https://build.opensuse.org/request/show/1123689
by user mia + anag+factory
- Add patch to Picom spamming Xlib: ignoring invalid extension event 161 errors.
  gh#yshui/picom#1096
  Backport patch from next branch
  0001-core-expand-X-error-handling.patch
  0002-core-added-proper-event-handling-for-XESetWireToEven.patch
  0003-core-event-code-refactoring.patch

---

diff --git a/.files b/.files
index 04d45b5..7057658 100644
Binary files a/.files and b/.files differ
diff --git a/.rev b/.rev
index 3844dbe..628d9ca 100644
--- a/.rev
+++ b/.rev
@@ -137,4 +137,17 @@ Fixes:
     gh#yshui/picom#950</comment>
     <requestid>1044090</requestid>
   </revision>
+  <revision rev="8" vrev="2">
+    <srcmd5>b04a1487e26f1d8d4d2d0be7796cb936</srcmd5>
+    <version>10.2</version>
+    <time>1699388771</time>
+    <user>anag+factory</user>
+    <comment>- Add patch to Picom spamming Xlib: ignoring invalid extension event 161 errors.
+  gh#yshui/picom#1096
+  Backport patch from next branch
+  0001-core-expand-X-error-handling.patch
+  0002-core-added-proper-event-handling-for-XESetWireToEven.patch
+  0003-core-event-code-refactoring.patch</comment>
+    <requestid>1123689</requestid>
+  </revision>
 </revisionlist>
diff --git a/0001-core-expand-X-error-handling.patch b/0001-core-expand-X-error-handling.patch
new file mode 100644
index 0000000..87c290e
--- /dev/null
+++ b/0001-core-expand-X-error-handling.patch
@@ -0,0 +1,301 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Yuxuan Shui <yshuiv7@gmail.com>
+Date: Wed, 14 Dec 2022 14:23:55 +0000
+Subject: [PATCH] core: expand X error handling
+
+We used to have a list of X errors we should ignore in case they do
+occur. This commit expands that functionality to also allow us aborting
+on certain errors.
+
+Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
+---
+ src/common.h | 38 ++++++++++++++++----------
+ src/event.c  |  2 +-
+ src/picom.c  | 75 ++++++++++++++++++++++++++++++++--------------------
+ src/picom.h  |  2 +-
+ src/x.c      | 10 ++++++-
+ src/x.h      |  2 ++
+ 6 files changed, 84 insertions(+), 45 deletions(-)
+
+diff --git a/src/common.h b/src/common.h
+index 8f8b8dd8afad9cb1183d44a1018e347f57bc21f4..863e14ee7570a7b56f32b8823c12cbc9445610ed 100644
+--- a/src/common.h
++++ b/src/common.h
+@@ -83,10 +83,17 @@ struct glx_session;
+ struct atom;
+ struct conv;
+ 
+-typedef struct _ignore {
+-	struct _ignore *next;
++enum pending_reply_action {
++	PENDING_REPLY_ACTION_IGNORE,
++	PENDING_REPLY_ACTION_ABORT,
++	PENDING_REPLY_ACTION_DEBUG_ABORT,
++};
++
++typedef struct pending_reply {
++	struct pending_reply *next;
+ 	unsigned long sequence;
+-} ignore_t;
++	enum pending_reply_action action;
++} pending_reply_t;
+ 
+ #ifdef CONFIG_OPENGL
+ #ifdef DEBUG_GLX_DEBUG_CONTEXT
+@@ -256,18 +263,18 @@ typedef struct session {
+ 	/// Time of last fading. In milliseconds.
+ 	long long fade_time;
+ 	/// Head pointer of the error ignore linked list.
+-	ignore_t *ignore_head;
++	pending_reply_t *pending_reply_head;
+ 	/// Pointer to the <code>next</code> member of tail element of the error
+ 	/// ignore linked list.
+-	ignore_t **ignore_tail;
++	pending_reply_t **pending_reply_tail;
+ 	// Cached blur convolution kernels.
+ 	struct x_convolution_kernel **blur_kerns_cache;
+ 	/// If we should quit
+-	bool quit:1;
++	bool quit : 1;
+ 	// TODO(yshui) use separate flags for dfferent kinds of updates so we don't
+ 	// waste our time.
+ 	/// Whether there are pending updates, like window creation, etc.
+-	bool pending_updates:1;
++	bool pending_updates : 1;
+ 
+ 	// === Expose event related ===
+ 	/// Pointer to an array of <code>XRectangle</code>-s of exposed region.
+@@ -468,18 +475,21 @@ static inline bool bkend_use_glx(session_t *ps) {
+ 	return BKEND_GLX == ps->o.backend || BKEND_XR_GLX_HYBRID == ps->o.backend;
+ }
+ 
+-static void set_ignore(session_t *ps, unsigned long sequence) {
+-	if (ps->o.show_all_xerrors)
++static void set_ignore(session_t *ps, uint32_t sequence) {
++	if (ps->o.show_all_xerrors) {
+ 		return;
++	}
+ 
+-	auto i = cmalloc(ignore_t);
+-	if (!i)
+-		return;
++	auto i = cmalloc(pending_reply_t);
++	if (!i) {
++		abort();
++	}
+ 
+ 	i->sequence = sequence;
+ 	i->next = 0;
+-	*ps->ignore_tail = i;
+-	ps->ignore_tail = &i->next;
++	i->action = PENDING_REPLY_ACTION_IGNORE;
++	*ps->pending_reply_tail = i;
++	ps->pending_reply_tail = &i->next;
+ }
+ 
+ /**
+diff --git a/src/event.c b/src/event.c
+index e6052f1de1f4e9d84117c6abcda225d4da794006..53da76a9e5ae5bc4361157c2ee15732511aa9c38 100644
+--- a/src/event.c
++++ b/src/event.c
+@@ -663,7 +663,7 @@ ev_selection_clear(session_t *ps, xcb_selection_clear_event_t attr_unused *ev) {
+ 
+ void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
+ 	if ((ev->response_type & 0x7f) != KeymapNotify) {
+-		discard_ignore(ps, ev->full_sequence);
++		discard_pending(ps, ev->full_sequence);
+ 	}
+ 
+ 	xcb_window_t wid = ev_window(ps, ev);
+diff --git a/src/picom.c b/src/picom.c
+index ecd09078e898a0fc1467ee8592ea7796faf05e04..461822b387da651f1400d5fcbbedef1a691b8bf6 100644
+--- a/src/picom.c
++++ b/src/picom.c
+@@ -282,14 +282,14 @@ static bool run_fade(session_t *ps, struct managed_win **_w, long long steps) {
+ 
+ // === Error handling ===
+ 
+-void discard_ignore(session_t *ps, unsigned long sequence) {
+-	while (ps->ignore_head) {
+-		if (sequence > ps->ignore_head->sequence) {
+-			ignore_t *next = ps->ignore_head->next;
+-			free(ps->ignore_head);
+-			ps->ignore_head = next;
+-			if (!ps->ignore_head) {
+-				ps->ignore_tail = &ps->ignore_head;
++void discard_pending(session_t *ps, uint32_t sequence) {
++	while (ps->pending_reply_head) {
++		if (sequence > ps->pending_reply_head->sequence) {
++			auto next = ps->pending_reply_head->next;
++			free(ps->pending_reply_head);
++			ps->pending_reply_head = next;
++			if (!ps->pending_reply_head) {
++				ps->pending_reply_tail = &ps->pending_reply_head;
+ 			}
+ 		} else {
+ 			break;
+@@ -297,13 +297,28 @@ void discard_ignore(session_t *ps, unsigned long sequence) {
+ 	}
+ }
+ 
+-static int should_ignore(session_t *ps, unsigned long sequence) {
++static void handle_error(session_t *ps, xcb_generic_error_t *ev) {
+ 	if (ps == NULL) {
+ 		// Do not ignore errors until the session has been initialized
+-		return false;
++		return;
++	}
++	discard_pending(ps, ev->full_sequence);
++	if (ps->pending_reply_head && ps->pending_reply_head->sequence == ev->full_sequence) {
++		if (ps->pending_reply_head->action != PENDING_REPLY_ACTION_IGNORE) {
++			x_log_error(LOG_LEVEL_ERROR, ev->full_sequence, ev->major_code,
++			            ev->minor_code, ev->error_code);
++		}
++		switch (ps->pending_reply_head->action) {
++		case PENDING_REPLY_ACTION_ABORT:
++			log_fatal("An unrecoverable X error occurred, aborting...");
++			abort();
++		case PENDING_REPLY_ACTION_DEBUG_ABORT: assert(false); break;
++		case PENDING_REPLY_ACTION_IGNORE: break;
++		}
++		return;
+ 	}
+-	discard_ignore(ps, sequence);
+-	return ps->ignore_head && ps->ignore_head->sequence == sequence;
++	x_log_error(LOG_LEVEL_WARN, ev->full_sequence, ev->major_code, ev->minor_code,
++	            ev->error_code);
+ }
+ 
+ // === Windows ===
+@@ -964,9 +979,13 @@ void root_damaged(session_t *ps) {
+  * Xlib error handler function.
+  */
+ static int xerror(Display attr_unused *dpy, XErrorEvent *ev) {
+-	if (!should_ignore(ps_g, ev->serial)) {
+-		x_print_error(ev->serial, ev->request_code, ev->minor_code, ev->error_code);
+-	}
++	// Fake a xcb error, fill in just enough information
++	xcb_generic_error_t xcb_err;
++	xcb_err.full_sequence = (uint32_t)ev->serial;
++	xcb_err.major_code = ev->request_code;
++	xcb_err.minor_code = ev->minor_code;
++	xcb_err.error_code = ev->error_code;
++	handle_error(ps_g, &xcb_err);
+ 	return 0;
+ }
+ 
+@@ -974,9 +993,7 @@ static int xerror(Display attr_unused *dpy, XErrorEvent *ev) {
+  * XCB error handler function.
+  */
+ void ev_xcb_error(session_t *ps, xcb_generic_error_t *err) {
+-	if (!should_ignore(ps, err->sequence)) {
+-		x_print_error(err->sequence, err->major_code, err->minor_code, err->error_code);
+-	}
++	handle_error(ps, err);
+ }
+ 
+ /**
+@@ -1677,8 +1694,8 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
+ 	    .redirected = false,
+ 	    .alpha_picts = NULL,
+ 	    .fade_time = 0L,
+-	    .ignore_head = NULL,
+-	    .ignore_tail = NULL,
++	    .pending_reply_head = NULL,
++	    .pending_reply_tail = NULL,
+ 	    .quit = false,
+ 
+ 	    .expose_rects = NULL,
+@@ -1740,7 +1757,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
+ 	ps->loop = EV_DEFAULT;
+ 	pixman_region32_init(&ps->screen_reg);
+ 
+-	ps->ignore_tail = &ps->ignore_head;
++	ps->pending_reply_tail = &ps->pending_reply_head;
+ 
+ 	ps->o.show_all_xerrors = all_xerrors;
+ 
+@@ -2329,26 +2346,28 @@ static void session_destroy(session_t *ps) {
+ 
+ 	// Free ignore linked list
+ 	{
+-		ignore_t *next = NULL;
+-		for (ignore_t *ign = ps->ignore_head; ign; ign = next) {
++		pending_reply_t *next = NULL;
++		for (auto ign = ps->pending_reply_head; ign; ign = next) {
+ 			next = ign->next;
+ 
+ 			free(ign);
+ 		}
+ 
+ 		// Reset head and tail
+-		ps->ignore_head = NULL;
+-		ps->ignore_tail = &ps->ignore_head;
++		ps->pending_reply_head = NULL;
++		ps->pending_reply_tail = &ps->pending_reply_head;
+ 	}
+ 
+ 	// Free tgt_{buffer,picture} and root_picture
+-	if (ps->tgt_buffer.pict == ps->tgt_picture)
++	if (ps->tgt_buffer.pict == ps->tgt_picture) {
+ 		ps->tgt_buffer.pict = XCB_NONE;
++	}
+ 
+-	if (ps->tgt_picture == ps->root_picture)
++	if (ps->tgt_picture == ps->root_picture) {
+ 		ps->tgt_picture = XCB_NONE;
+-	else
++	} else {
+ 		free_picture(ps->c, &ps->tgt_picture);
++	}
+ 
+ 	free_picture(ps->c, &ps->root_picture);
+ 	free_paint(ps, &ps->tgt_buffer);
+diff --git a/src/picom.h b/src/picom.h
+index 7ee289bd00d61528225ff587ef7ca0965c76bda1..b5a1e8a7b61dc6eaad9417b24edf3112237806a1 100644
+--- a/src/picom.h
++++ b/src/picom.h
+@@ -46,7 +46,7 @@ void cxinerama_upd_scrs(session_t *ps);
+ 
+ void queue_redraw(session_t *ps);
+ 
+-void discard_ignore(session_t *ps, unsigned long sequence);
++void discard_pending(session_t *ps, uint32_t sequence);
+ 
+ void set_root_flags(session_t *ps, uint64_t flags);
+ 
+diff --git a/src/x.c b/src/x.c
+index 795211dbccfc82eb6f63b2ae604c5a56fc065eb9..7b3dc368537c07ce9e68de8eec79b25f26d67b0b 100644
+--- a/src/x.c
++++ b/src/x.c
+@@ -527,8 +527,16 @@ _x_strerror(unsigned long serial, uint8_t major, uint16_t minor, uint8_t error_c
+ /**
+  * Log a X11 error
+  */
++void x_log_error(enum log_level level, unsigned long serial, uint8_t major,
++                 uint16_t minor, uint8_t error_code) {
++	if (unlikely(level >= log_get_level_tls())) {
++		log_printf(tls_logger, level, __func__, "%s",
++		           _x_strerror(serial, major, minor, error_code));
++	}
++}
++
+ void x_print_error(unsigned long serial, uint8_t major, uint16_t minor, uint8_t error_code) {
+-	log_debug("%s", _x_strerror(serial, major, minor, error_code));
++	x_log_error(LOG_LEVEL_DEBUG, serial, major, minor, error_code);
+ }
+ 
+ /*
+diff --git a/src/x.h b/src/x.h
+index 3b8787c7c554524165ed4d69c9dfd3042ce67287..91fc8bdbdaeaf5bba043d21d0da24bd6c1795033 100644
+--- a/src/x.h
++++ b/src/x.h
+@@ -225,6 +225,8 @@ void x_clear_picture_clip_region(xcb_connection_t *, xcb_render_picture_t pict);
+  * Log a X11 error
+  */
+ void x_print_error(unsigned long serial, uint8_t major, uint16_t minor, uint8_t error_code);
++void x_log_error(enum log_level level, unsigned long serial, uint8_t major,
++                 uint16_t minor, uint8_t error_code);
+ 
+ /*
+  * Convert a xcb_generic_error_t to a string that describes the error
diff --git a/0002-core-added-proper-event-handling-for-XESetWireToEven.patch b/0002-core-added-proper-event-handling-for-XESetWireToEven.patch
new file mode 100644
index 0000000..7d35a0d
--- /dev/null
+++ b/0002-core-added-proper-event-handling-for-XESetWireToEven.patch
@@ -0,0 +1,47 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Nikolay Borodin <monsterovich@gmail.com>
+Date: Fri, 16 Jun 2023 23:50:20 +0200
+Subject: [PATCH] core: added proper event handling for XESetWireToEvent
+
+---
+ src/event.c     | 5 +++--
+ src/meson.build | 2 ++
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+diff --git a/src/event.c b/src/event.c
+index 53da76a9e5ae5bc4361157c2ee15732511aa9c38..c4f3cefe4aac9a7a42ade0e5949160efa36adf59 100644
+--- a/src/event.c
++++ b/src/event.c
+@@ -7,6 +7,7 @@
+ #include <X11/extensions/sync.h>
+ #include <xcb/damage.h>
+ #include <xcb/randr.h>
++#include <xcb/xcb_event.h>
+ 
+ #include "atom.h"
+ #include "common.h"
+@@ -684,9 +685,9 @@ void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
+ 	// For even more details, see:
+ 	// https://bugs.freedesktop.org/show_bug.cgi?id=35945
+ 	// https://lists.freedesktop.org/archives/xcb/2011-November/007337.html
+-	auto proc = XESetWireToEvent(ps->dpy, ev->response_type, 0);
++	auto proc = XESetWireToEvent(ps->dpy, XCB_EVENT_RESPONSE_TYPE(ev), 0);
+ 	if (proc) {
+-		XESetWireToEvent(ps->dpy, ev->response_type, proc);
++		XESetWireToEvent(ps->dpy, XCB_EVENT_RESPONSE_TYPE(ev), proc);
+ 		XEvent dummy;
+ 
+ 		// Stop Xlib from complaining about lost sequence numbers.
+diff --git a/src/meson.build b/src/meson.build
+index 60d83a891f03a3850df1f23d53a195936f1f56ea..1d4c3072ee96948ef11c30b84055a758319a55e8 100644
+--- a/src/meson.build
++++ b/src/meson.build
+@@ -31,6 +31,8 @@ foreach i : required_xcb_packages
+ 	base_deps += [dependency(i, version: '>=1.12.0', required: true)]
+ endforeach
+ 
++base_deps += [dependency('xcb-util', version: '>=0.4.0', required: true)]
++
+ if not cc.has_header('uthash.h')
+   error('Dependency uthash not found')
+ endif
diff --git a/0003-core-event-code-refactoring.patch b/0003-core-event-code-refactoring.patch
new file mode 100644
index 0000000..8c22032
--- /dev/null
+++ b/0003-core-event-code-refactoring.patch
@@ -0,0 +1,52 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Nikolay Borodin <monsterovich@gmail.com>
+Date: Sat, 17 Jun 2023 01:08:47 +0200
+Subject: [PATCH] core: event code refactoring
+
+---
+ src/event.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/src/event.c b/src/event.c
+index c4f3cefe4aac9a7a42ade0e5949160efa36adf59..20a3cf0ab560b1ee94e938b7fff97170b048fa4b 100644
+--- a/src/event.c
++++ b/src/event.c
+@@ -107,7 +107,7 @@ static inline xcb_window_t attr_pure ev_window(session_t *ps, xcb_generic_event_
+ 
+ static inline const char *ev_name(session_t *ps, xcb_generic_event_t *ev) {
+ 	static char buf[128];
+-	switch (ev->response_type & 0x7f) {
++	switch (XCB_EVENT_RESPONSE_TYPE(ev)) {
+ 		CASESTRRET(FocusIn);
+ 		CASESTRRET(FocusOut);
+ 		CASESTRRET(CreateNotify);
+@@ -663,7 +663,7 @@ ev_selection_clear(session_t *ps, xcb_selection_clear_event_t attr_unused *ev) {
+ }
+ 
+ void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
+-	if ((ev->response_type & 0x7f) != KeymapNotify) {
++	if (XCB_EVENT_RESPONSE_TYPE(ev) != KeymapNotify) {
+ 		discard_pending(ps, ev->full_sequence);
+ 	}
+ 
+@@ -685,9 +685,10 @@ void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
+ 	// For even more details, see:
+ 	// https://bugs.freedesktop.org/show_bug.cgi?id=35945
+ 	// https://lists.freedesktop.org/archives/xcb/2011-November/007337.html
+-	auto proc = XESetWireToEvent(ps->dpy, XCB_EVENT_RESPONSE_TYPE(ev), 0);
++	auto response_type = XCB_EVENT_RESPONSE_TYPE(ev);
++	auto proc = XESetWireToEvent(ps->dpy, response_type, 0);
+ 	if (proc) {
+-		XESetWireToEvent(ps->dpy, XCB_EVENT_RESPONSE_TYPE(ev), proc);
++		XESetWireToEvent(ps->dpy, response_type, proc);
+ 		XEvent dummy;
+ 
+ 		// Stop Xlib from complaining about lost sequence numbers.
+@@ -703,6 +704,7 @@ void ev_handle(session_t *ps, xcb_generic_event_t *ev) {
+ 	// XXX redraw needs to be more fine grained
+ 	queue_redraw(ps);
+ 
++	// the events sent from SendEvent will be ignored
+ 	switch (ev->response_type) {
+ 	case FocusIn: ev_focus_in(ps, (xcb_focus_in_event_t *)ev); break;
+ 	case FocusOut: ev_focus_out(ps, (xcb_focus_out_event_t *)ev); break;
diff --git a/picom.changes b/picom.changes
index e866798..82e8fa1 100644
--- a/picom.changes
+++ b/picom.changes
@@ -1,4 +1,14 @@
 -------------------------------------------------------------------
+Tue Oct 17 16:40:34 UTC 2023 - Björn Bidar <bjorn.bidar@thaodan.de>
+
+- Add patch to Picom spamming Xlib: ignoring invalid extension event 161 errors.
+  gh#yshui/picom#1096
+  Backport patch from next branch
+  0001-core-expand-X-error-handling.patch
+  0002-core-added-proper-event-handling-for-XESetWireToEven.patch
+  0003-core-event-code-refactoring.patch
+
+-------------------------------------------------------------------
 Wed Dec 21 14:31:20 UTC 2022 - Mia Herkt <mia@0x0.st>
 
 - Update to version 10.2
diff --git a/picom.spec b/picom.spec
index 2c6c194..ac15322 100644
--- a/picom.spec
+++ b/picom.spec
@@ -1,7 +1,7 @@
 #
 # spec file for package picom
 #
-# Copyright (c) 2022 SUSE LLC
+# Copyright (c) 2023 SUSE LLC
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -24,6 +24,13 @@ License:        MIT AND MPL-2.0
 Group:          System/X11/Utilities
 URL:            https://github.com/yshui/picom
 Source0:        https://github.com/yshui/picom/archive/v%{version}.tar.gz
+# Patch-FIX-UPSTREAM core: expand X error handling based on
+# aca3fdcef7bfcb1c3ce65cf87413fa6ab280d183
+# Required for the fix further below
+Patch1:         0001-core-expand-X-error-handling.patch
+# PATCH-FIX-UPSTREAM added proper event handling for XESetWireToEvent -- based on PR 123
+Patch2:         0002-core-added-proper-event-handling-for-XESetWireToEven.patch
+Patch3:         0003-core-event-code-refactoring.patch
 BuildRequires:  asciidoc
 BuildRequires:  c_compiler
 BuildRequires:  hicolor-icon-theme
@@ -50,6 +57,7 @@ BuildRequires:  pkgconfig(xcb-render)
 BuildRequires:  pkgconfig(xcb-renderutil)
 BuildRequires:  pkgconfig(xcb-shape)
 BuildRequires:  pkgconfig(xcb-sync)
+BuildRequires:  pkgconfig(xcb-util)
 BuildRequires:  pkgconfig(xcb-xfixes)
 BuildRequires:  pkgconfig(xcb-xinerama)
 BuildRequires:  pkgconfig(xext)
@@ -62,7 +70,7 @@ XRender backends and has various options to control shadows, blur
 and fade animations.
 
 %prep
-%setup -q
+%autosetup -p1
 
 %build
 %meson -Dwith_docs=true -Dcompton=false -Dvsync_drm=true