Index | Thread | Search

From:
Kirill A. Korinsky <kirill@korins.ky>
Subject:
net/tdesktop: fix scroll on X11
To:
OpenBSD ports <ports@openbsd.org>
Cc:
Klemens Nanni <kn@openbsd.org>, Andrew Krasavin <noiseless-ak@yandex.ru>
Date:
Wed, 12 Aug 2026 19:14:32 +0200

Download raw body.

Thread
prots@, Klemens, Andrew,

since last update of net/tdesktop scroll via touchpad makes it almost
usless.

Here my attemp to fix it in X11.

I do not tried to ship that diff to upstream, probably it can be OpenBSD
specific.

Anyway, I'd like ask to test it for users who has no scroll issue and has
one.

Also, OK to commit it welcome, because at my case it make use of tdesktop
possible again.


Index: Makefile
===================================================================
RCS file: /home/cvs/ports/net/tdesktop/Makefile,v
diff -u -p -r1.225 Makefile
--- Makefile	1 Aug 2026 02:00:56 -0000	1.225
+++ Makefile	12 Aug 2026 13:07:17 -0000
@@ -6,6 +6,7 @@ NOT_FOR_ARCHS =		${BE_ARCHS} i386
 COMMENT =		Telegram Desktop messenger
 PORTROACH =		limit:-full$$
 V =			7.0.6
+REVISION =		0
 DISTNAME =		tdesktop-${V}-full
 PKGNAME =		${DISTNAME:-full=}
 CATEGORIES =		net
Index: patches/patch-Telegram_SourceFiles_platform_linux_specific_linux_cpp
===================================================================
RCS file: /home/cvs/ports/net/tdesktop/patches/patch-Telegram_SourceFiles_platform_linux_specific_linux_cpp,v
diff -u -p -r1.11 patch-Telegram_SourceFiles_platform_linux_specific_linux_cpp
--- patches/patch-Telegram_SourceFiles_platform_linux_specific_linux_cpp	12 Jun 2026 10:30:43 -0000	1.11
+++ patches/patch-Telegram_SourceFiles_platform_linux_specific_linux_cpp	12 Aug 2026 12:32:04 -0000
@@ -1,9 +1,11 @@
 /usr/ports/pobj/tdesktop-6.2.5/tdesktop-6.2.5-full/Telegram/SourceFiles/platform/linux/specific_linux.cpp:71:7: error: reference to 'GObject' is ambiguous
 
+plus fix scroll on X11
+
 Index: Telegram/SourceFiles/platform/linux/specific_linux.cpp
 --- Telegram/SourceFiles/platform/linux/specific_linux.cpp.orig
 +++ Telegram/SourceFiles/platform/linux/specific_linux.cpp
-@@ -68,7 +68,7 @@ void PortalAutostart(bool enabled, Fn<void(bool)> done
+@@ -66,7 +66,7 @@ void PortalAutostart(bool enabled, Fn<void(bool)> done
  		Gio::DBusProxyFlags::NONE_,
  		base::Platform::XDP::kService,
  		base::Platform::XDP::kObjectPath,
@@ -12,7 +14,7 @@ Index: Telegram/SourceFiles/platform/lin
  			auto proxy = XdpBackground::BackgroundProxy::new_for_bus_finish(
  				res);
  
-@@ -121,7 +121,7 @@ void PortalAutostart(bool enabled, Fn<void(bool)> done
+@@ -119,7 +119,7 @@ void PortalAutostart(bool enabled, Fn<void(bool)> done
  					+ '/'
  					+ handleToken,
  				nullptr,
@@ -21,7 +23,7 @@ Index: Telegram/SourceFiles/platform/lin
  					auto requestProxy = XdpRequest::RequestProxy::new_finish(
  						res);
  
-@@ -196,7 +196,7 @@ void PortalAutostart(bool enabled, Fn<void(bool)> done
+@@ -194,7 +194,7 @@ void PortalAutostart(bool enabled, Fn<void(bool)> done
  								GLib::Variant::new_variant(
  									GLib::Variant::new_boolean(false))),
  						}),
@@ -30,7 +32,7 @@ Index: Telegram/SourceFiles/platform/lin
  							auto &sandbox = Core::Sandbox::Instance();
  							sandbox.customEnterFromEventLoop([&] {
  								const auto result =
-@@ -451,7 +451,7 @@ bool GenerateServiceFile(bool silent = false) {
+@@ -449,7 +449,7 @@ bool GenerateServiceFile(bool silent = false) {
  		Gio::DBusProxyFlags::NONE_,
  		base::Platform::DBus::kService,
  		base::Platform::DBus::kObjectPath,
@@ -39,7 +41,7 @@ Index: Telegram/SourceFiles/platform/lin
  			auto interface = XdgDBus::DBus(
  				XdgDBus::DBusProxy::new_for_bus_finish(res, nullptr));
  
-@@ -552,7 +552,7 @@ void PortalCheckScheme(
+@@ -550,7 +550,7 @@ void PortalCheckScheme(
  		Gio::DBusProxyFlags::NONE_,
  		base::Platform::XDP::kService,
  		base::Platform::XDP::kObjectPath,
@@ -48,7 +50,7 @@ Index: Telegram/SourceFiles/platform/lin
  			auto interface = XdpOpenURI::OpenURI(
  				XdpOpenURI::OpenURIProxy::new_for_bus_finish(res, nullptr));
  
-@@ -566,7 +566,7 @@ void PortalCheckScheme(
+@@ -564,7 +564,7 @@ void PortalCheckScheme(
  				GLib::Variant::new_array(
  					GLib::VariantType::new_("{sv}"),
  					{}),
Index: patches/patch-Telegram_lib_ui_ui_ui_utility_cpp
===================================================================
RCS file: patches/patch-Telegram_lib_ui_ui_ui_utility_cpp
diff -N patches/patch-Telegram_lib_ui_ui_ui_utility_cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-Telegram_lib_ui_ui_ui_utility_cpp	12 Aug 2026 12:32:30 -0000
@@ -0,0 +1,56 @@
+fix scroll on X11
+
+Index: Telegram/lib_ui/ui/ui_utility.cpp
+--- Telegram/lib_ui/ui/ui_utility.cpp.orig
++++ Telegram/lib_ui/ui/ui_utility.cpp
+@@ -7,6 +7,7 @@
+ #include "ui/ui_utility.h"
+ 
+ #include "base/platform/base_platform_info.h"
++#include "base/qt/qt_common_adapters.h"
+ #include "ui/integration.h"
+ #include "ui/style/style_core.h"
+ 
+@@ -22,6 +23,7 @@ namespace {
+ 
+ constexpr auto kDefaultWheelScrollLines = 3;
+ constexpr auto kMagicScrollMultiplier = 2.5;
++constexpr auto kX11SmoothScrollMultiplier = 5.;
+ 
+ class WidgetCreator : public QWidget {
+ public:
+@@ -272,13 +274,31 @@ QPointF ScrollDeltaF(not_null<QWheelEvent*> e, bool to
+ 			style::ConvertScaleExact(point.x()),
+ 			style::ConvertScaleExact(point.y()));
+ 	};
+-	if (!e->pixelDelta().isNull()) {
+-		return convert(e->pixelDelta())
++	const auto pixelDelta = e->pixelDelta();
++	auto x11Touchpad = false;
++#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
++	x11Touchpad = e->device()
++		&& e->device()->type() == base::TouchDevice::TouchPad;
++#endif // Qt >= 6.0.0
++	const auto x11Smooth = !touch
++		&& ::Platform::IsX11()
++		&& (!pixelDelta.isNull() || x11Touchpad);
++	const auto angleDelta = e->angleDelta();
++	if (x11Smooth && !angleDelta.isNull()) {
++		return (convert(angleDelta)
++			* QApplication::wheelScrollLines()
++			* kX11SmoothScrollMultiplier)
++			/ float64(QWheelEvent::DefaultDeltasPerStep);
++	}
++	if (!pixelDelta.isNull()) {
++		return (::Platform::IsX11() && !touch
++			? QPointF(pixelDelta)
++			: convert(pixelDelta))
+ 			* ((::Platform::IsWayland() && !touch)
+ 				? kMagicScrollMultiplier
+ 				: 1.);
+ 	}
+-	return (convert(e->angleDelta()) * QApplication::wheelScrollLines())
++	return (convert(angleDelta) * QApplication::wheelScrollLines())
+ 		/ float64(kPixelToAngleDelta * kDefaultWheelScrollLines);
+ }
+ 
Index: patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_cpp
===================================================================
RCS file: patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_cpp
diff -N patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_cpp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_cpp	12 Aug 2026 12:32:27 -0000
@@ -0,0 +1,61 @@
+fix scroll on X11
+
+Index: Telegram/lib_ui/ui/widgets/elastic_scroll.cpp
+--- Telegram/lib_ui/ui/widgets/elastic_scroll.cpp.orig
++++ Telegram/lib_ui/ui/widgets/elastic_scroll.cpp
+@@ -867,7 +867,7 @@ bool ElasticScroll::eventHook(QEvent *e) {
+ 	switch (e->type()) {
+ 	case QEvent::ScrollPrepare: {
+ 		QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e);
+-		se->setViewportSize(QSizeF(viewport()->size()));
++		se->setViewportSize(QSizeF(size()));
+ 		se->setContentPosRange(QRectF(
+ 			0,
+ 			0,
+@@ -1029,21 +1029,29 @@ bool ElasticScroll::handleWheelEvent(not_null<QWheelEv
+ 	const auto guard = gsl::finally([&] {
+ 		_lastScroll = now;
+ 	});
+-	auto unmultiplied = ScrollDelta(e, touch);
++	if (phase == Qt::ScrollBegin) {
++		_wheelDeltaRemainder = {};
++	}
++	auto exactPixels = ScrollDeltaF(e, touch);
+ 	if (ownAxisLocked) {
+ 		if (_vertical) {
+-			unmultiplied.setX(0);
++			exactPixels.setX(0.);
++			_wheelDeltaRemainder.setX(0.);
+ 		} else {
+-			unmultiplied.setY(0);
++			exactPixels.setY(0.);
++			_wheelDeltaRemainder.setY(0.);
+ 		}
+ 	}
+ 	const auto multiply = e->modifiers()
+ 		& (Qt::ControlModifier | Qt::ShiftModifier);
+-	const auto pixels = multiply
+-		? QPoint(
+-			(unmultiplied.x() * std::max(width(), 120) / 120.),
+-			(unmultiplied.y() * std::max(height(), 120) / 120.))
+-		: unmultiplied;
++	if (multiply) {
++		exactPixels = QPointF(
++			exactPixels.x() * std::max(width(), 120) / 120.,
++			exactPixels.y() * std::max(height(), 120) / 120.);
++	}
++	exactPixels += _wheelDeltaRemainder;
++	const auto pixels = exactPixels.toPoint();
++	_wheelDeltaRemainder = exactPixels - QPointF(pixels);
+ 	auto ignore = false;
+ 	auto delta = _vertical ? -pixels.y() : -pixels.x();
+ 	if (!ownAxisLocked
+@@ -1092,7 +1100,7 @@ bool ElasticScroll::handleWheelEvent(not_null<QWheelEv
+ 		case Qt::ScrollBegin:
+ 		case Qt::ScrollUpdate: {
+ 			if (phase == Qt::ScrollBegin
+-				&& !pixels.isNull()
++				&& !exactPixels.isNull()
+ 				&& _scroller->state() == QScroller::Scrolling) {
+ 				// On macOS, when Qt loses the race detecting that a
+ 				// momentum phase follows the finger lift, the OS momentum
Index: patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_h
===================================================================
RCS file: patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_h
diff -N patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ patches/patch-Telegram_lib_ui_ui_widgets_elastic_scroll_h	12 Aug 2026 12:32:15 -0000
@@ -0,0 +1,13 @@
+fix scroll on X11
+
+Index: Telegram/lib_ui/ui/widgets/elastic_scroll.h
+--- Telegram/lib_ui/ui/widgets/elastic_scroll.h.orig
++++ Telegram/lib_ui/ui/widgets/elastic_scroll.h
+@@ -334,6 +334,7 @@ class ElasticScroll : public RpWidget { (private)
+ 
+ 	QPointer<QScroller> _scroller;
+ 	QPoint _wheelPos;
++	QPointF _wheelDeltaRemainder;
+ 
+ 	base::Timer _touchTimer;
+ 	base::Timer _touchScrollTimer;


-- 
wbr, Kirill