commit:     5b58dba63e2ed5241a71d394d43901f00ef50d5a
Author:     Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 10 04:29:01 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Thu Jul 10 04:35:23 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=5b58dba6

x11-misc/copyq: fix build w/ qt-6.9

Closes: https://bugs.gentoo.org/958277
Signed-off-by: Sam James <sam <AT> gentoo.org>

 x11-misc/copyq/copyq-9.1.0-r1.ebuild          | 104 +++++++
 x11-misc/copyq/files/copyq-9.1.0-qt-6.9.patch | 413 ++++++++++++++++++++++++++
 2 files changed, 517 insertions(+)

diff --git a/x11-misc/copyq/copyq-9.1.0-r1.ebuild 
b/x11-misc/copyq/copyq-9.1.0-r1.ebuild
new file mode 100644
index 000000000000..1f329cbc2b3d
--- /dev/null
+++ b/x11-misc/copyq/copyq-9.1.0-r1.ebuild
@@ -0,0 +1,104 @@
+# Copyright 1999-2025 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+inherit cmake optfeature virtualx xdg
+
+DESCRIPTION="Clipboard manager with advanced features"
+HOMEPAGE="https://hluk.github.io/CopyQ/ https://github.com/hluk/CopyQ/";
+SRC_URI="https://github.com/hluk/${PN}/archive/v${PV}.tar.gz -> ${P}.tar.gz"
+S="${WORKDIR}/CopyQ-${PV}"
+
+LICENSE="GPL-3+"
+SLOT="0"
+KEYWORDS="~amd64 ~arm64 ~x86 ~amd64-linux ~x86-linux"
+IUSE="notification test X"
+
+RESTRICT="!test? ( test )"
+
+RDEPEND="
+       dev-libs/wayland
+       dev-qt/qtbase:6[gui,network,widgets,xml(+)]
+       dev-qt/qtdeclarative:6
+       dev-qt/qtsvg:6
+       dev-qt/qtwayland:6
+       X? (
+               dev-qt/qtbase:6=[X]
+               x11-libs/libX11
+               x11-libs/libXfixes
+               x11-libs/libXtst
+       )
+       notification? (
+               kde-frameworks/knotifications:6
+               kde-frameworks/kstatusnotifieritem:6
+       )
+"
+DEPEND="${RDEPEND}
+       X? ( x11-base/xorg-proto )
+"
+BDEPEND="
+       kde-frameworks/extra-cmake-modules:0
+       dev-qt/qttools:6[linguist]
+       dev-util/wayland-scanner
+       test? (
+               app-crypt/gnupg
+               x11-wm/openbox
+       )
+"
+
+PATCHES=(
+       # used in tests
+       "${FILESDIR}/${PN}-7.1.0-support-plugin-dir-envvar-r1.patch"
+       #
+       "${FILESDIR}/${PN}-9.1.0-qt-6.9.patch"
+)
+
+src_configure() {
+       local mycmakeargs=(
+               -DWITH_QT6=ON
+               
-DPLUGIN_INSTALL_PREFIX="${EPREFIX}/usr/$(get_libdir)/${PN}/plugins"
+               -DWITH_NATIVE_NOTIFICATIONS=$(usex notification)
+               -DWITH_TESTS=$(usex test)
+               -DWITH_X11=$(usex X)
+       )
+
+       cmake_src_configure
+}
+
+my_src_test() {
+       # Don't rerun tests and more logs
+       local -x COPYQ_TESTS_RERUN_FAILED=0
+       local -x COPYQ_LOG_LEVEL=DEBUG
+
+       # Skip test that require network
+       local -x COPYQ_TESTS_NO_NETWORK=1
+
+       # Less noise from trying the wayland plugin
+       local -x QT_QPA_PLATFORM=xcb
+
+       # Make sure copyq doesn't use system installed plugins which may be 
incompatible.
+       local -x COPYQ_PLUGIN_DIR="${BUILD_DIR}/plugins"
+
+       # In case the users current system confuses the notification integration
+       unset KDE_FULL_SESSION XDG_CURRENT_DESKTOP
+
+       mkdir "${HOME}"/.gnupg || die
+
+       ebegin "Starting Openbox"
+       openbox & # upstream uses Openbox and it doesn't fail like IceWM
+       sleep 5
+       eend 0
+
+       "${BUILD_DIR}"/copyq tests
+}
+
+src_test() {
+       # local -x QT_QPA_PLATFORM=offscreen # TODO: make it work
+       virtx my_src_test
+}
+
+pkg_postinst() {
+       xdg_pkg_postinst
+       optfeature "encryption support" app-crypt/gnupg
+}

diff --git a/x11-misc/copyq/files/copyq-9.1.0-qt-6.9.patch 
b/x11-misc/copyq/files/copyq-9.1.0-qt-6.9.patch
new file mode 100644
index 000000000000..d1753a93bad9
--- /dev/null
+++ b/x11-misc/copyq/files/copyq-9.1.0-qt-6.9.patch
@@ -0,0 +1,413 @@
+https://github.com/hluk/CopyQ/commit/f08c0d46a239362c5d3525ef9c3ba943bb00f734
+https://bugs.gentoo.org/958277#c5
+
+commit 7f1de919d2f6c3a84041d8f8afeff02a17290e16
+Author: Lukas Holecek <[email protected]>
+Date:   Mon Apr 7 11:50:05 2025 +0200
+
+    Fix QChar construction for Qt 6.9
+
+diff --git a/plugins/itemencrypted/itemencrypted.cpp 
b/plugins/itemencrypted/itemencrypted.cpp
+index 666dedde..73f47017 100644
+--- a/plugins/itemencrypted/itemencrypted.cpp
++++ b/plugins/itemencrypted/itemencrypted.cpp
+@@ -13,6 +13,7 @@
+ #include "common/textdata.h"
+ #include "gui/icons.h"
+ #include "gui/iconwidget.h"
++#include "gui/fromiconid.h"
+ #include "item/serialize.h"
+ 
+ #ifdef HAS_TESTS
+@@ -859,7 +860,7 @@ QVector<Command> ItemEncryptedLoader::commands() const
+     Command c;
+     c.internalId = QStringLiteral("copyq_encrypted_encrypt");
+     c.name = ItemEncryptedLoader::tr("Encrypt (needs GnuPG)");
+-    c.icon = QString(QChar(IconLock));
++    c.icon = fromIconId(IconLock);
+     c.input = "!OUTPUT";
+     c.output = mimeEncryptedData;
+     c.inMenu = true;
+@@ -870,7 +871,7 @@ QVector<Command> ItemEncryptedLoader::commands() const
+     c = Command();
+     c.internalId = QStringLiteral("copyq_encrypted_decrypt");
+     c.name = ItemEncryptedLoader::tr("Decrypt");
+-    c.icon = QString(QChar(IconUnlock));
++    c.icon = fromIconId(IconUnlock);
+     c.input = mimeEncryptedData;
+     c.output = mimeItems;
+     c.inMenu = true;
+@@ -881,7 +882,7 @@ QVector<Command> ItemEncryptedLoader::commands() const
+     c = Command();
+     c.internalId = QStringLiteral("copyq_encrypted_decrypt_and_copy");
+     c.name = ItemEncryptedLoader::tr("Decrypt and Copy");
+-    c.icon = QString(QChar(IconUnlockKeyhole));
++    c.icon = fromIconId(IconUnlockKeyhole);
+     c.input = mimeEncryptedData;
+     c.inMenu = true;
+     c.cmd = "copyq: plugins.itemencrypted.copyEncryptedItems()";
+@@ -891,7 +892,7 @@ QVector<Command> ItemEncryptedLoader::commands() const
+     c = Command();
+     c.internalId = QStringLiteral("copyq_encrypted_decrypt_and_paste");
+     c.name = ItemEncryptedLoader::tr("Decrypt and Paste");
+-    c.icon = QString(QChar(IconUnlockKeyhole));
++    c.icon = fromIconId(IconUnlockKeyhole);
+     c.input = mimeEncryptedData;
+     c.inMenu = true;
+     c.cmd = "copyq: plugins.itemencrypted.pasteEncryptedItems()";
+diff --git a/plugins/itemfakevim/fakevim/fakevimhandler.cpp 
b/plugins/itemfakevim/fakevim/fakevimhandler.cpp
+index c28d2504..4205b1cc 100644
+--- a/plugins/itemfakevim/fakevim/fakevimhandler.cpp
++++ b/plugins/itemfakevim/fakevim/fakevimhandler.cpp
+@@ -1033,7 +1033,7 @@ QString quoteUnprintable(const QString &ba)
+         else if (cc == '\n')
+             res += "<CR>";
+         else
+-            res += QString("\\x%1").arg(c.unicode(), 2, 16, QLatin1Char('0'));
++            res += QString("\\x%1").arg(cc, 2, 16, QLatin1Char('0'));
+     }
+     return res;
+ }
+diff --git a/plugins/itempinned/itempinned.cpp 
b/plugins/itempinned/itempinned.cpp
+index eb2518d1..19098149 100644
+--- a/plugins/itempinned/itempinned.cpp
++++ b/plugins/itempinned/itempinned.cpp
+@@ -5,6 +5,7 @@
+ #include "common/command.h"
+ #include "common/contenttype.h"
+ #include "common/display.h"
++#include "gui/fromiconid.h"
+ 
+ #ifdef HAS_TESTS
+ #   include "tests/itempinnedtests.h"
+@@ -32,7 +33,7 @@ bool isPinned(const QModelIndex &index)
+ Command dummyPinCommand()
+ {
+     Command c;
+-    c.icon = QString(QChar(IconThumbtack));
++    c.icon = fromIconId(IconThumbtack);
+     c.inMenu = true;
+     return c;
+ }
+diff --git a/plugins/itemsync/itemsync.cpp b/plugins/itemsync/itemsync.cpp
+index 8d3466d7..77c73bea 100644
+--- a/plugins/itemsync/itemsync.cpp
++++ b/plugins/itemsync/itemsync.cpp
+@@ -15,6 +15,7 @@
+ #include "gui/icons.h"
+ #include "gui/iconfont.h"
+ #include "gui/iconwidget.h"
++#include "gui/fromiconid.h"
+ #include "item/itemfilter.h"
+ 
+ #ifdef HAS_TESTS
+@@ -100,7 +101,7 @@ void writeConfiguration(QIODevice *file, const QStringList 
&savedFiles)
+ 
+ QString iconFromId(int id)
+ {
+-    return id != -1 ? QString(QChar(id)) : QString();
++    return id != -1 ? fromIconId(id) : QString();
+ }
+ 
+ QPushButton *createBrowseButton()
+diff --git a/plugins/itemtags/itemtags.cpp b/plugins/itemtags/itemtags.cpp
+index fe2a2f4c..d86dd908 100644
+--- a/plugins/itemtags/itemtags.cpp
++++ b/plugins/itemtags/itemtags.cpp
+@@ -10,6 +10,7 @@
+ #include "common/textdata.h"
+ #include "gui/iconfont.h"
+ #include "gui/iconselectbutton.h"
++#include "gui/fromiconid.h"
+ #include "gui/pixelratio.h"
+ #include "item/itemfilter.h"
+ 
+@@ -153,7 +154,7 @@ QString removeTagText()
+ Command dummyTagCommand()
+ {
+     Command c;
+-    c.icon = QString(QChar(IconTag));
++    c.icon = fromIconId(IconTag);
+     c.inMenu = true;
+     return c;
+ }
+diff --git a/src/common/globalshortcutcommands.cpp 
b/src/common/globalshortcutcommands.cpp
+index 4bb8b756..d0b7eeeb 100644
+--- a/src/common/globalshortcutcommands.cpp
++++ b/src/common/globalshortcutcommands.cpp
+@@ -3,6 +3,7 @@
+ #include "globalshortcutcommands.h"
+ 
+ #include "common/command.h"
++#include "gui/fromiconid.h"
+ 
+ #include <QCoreApplication>
+ #include <QLocale>
+@@ -50,7 +51,7 @@ Command createGlobalShortcut(const QString &name, const 
QString &script, IconId
+     c.internalId = internalId;
+     c.name = name;
+     c.cmd = "copyq: " + script;
+-    c.icon = QString(QChar(icon));
++    c.icon = fromIconId(icon);
+     c.isGlobalShortcut = true;
+     return c;
+ }
+diff --git a/src/common/predefinedcommands.cpp 
b/src/common/predefinedcommands.cpp
+index 236755aa..08ab0ffb 100644
+--- a/src/common/predefinedcommands.cpp
++++ b/src/common/predefinedcommands.cpp
+@@ -8,6 +8,7 @@
+ #include "common/shortcuts.h"
+ #include "common/textdata.h"
+ #include "gui/icons.h"
++#include "gui/fromiconid.h"
+ #include "platform/platformnativeinterface.h"
+ 
+ #include <QCoreApplication>
+@@ -38,14 +39,14 @@ QVector<Command> predefinedCommands()
+     commands.prepend(Command());
+     c = &commands.first();
+     c->name = AddCommandDialog::tr("New command");
+-    c->icon = QString(QChar(IconFile));
++    c->icon = fromIconId(IconFile);
+     c->input = c->output = QString();
+     c->wait = c->automatic = c->remove = false;
+     c->sep = QLatin1String("\\n");
+ 
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Ignore items with no or single 
character");
+-    c->icon = QString(QChar(IconCircleExclamation));
++    c->icon = fromIconId(IconCircleExclamation);
+     c->cmd  = R"(function hasEmptyOrSingleCharText() {
+     if (dataFormats().includes(mimeText)) {
+         var text = str(data(mimeText));
+@@ -83,7 +84,7 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Open in &Browser");
+     c->re   = reURL;
+-    c->icon = QString(QChar(IconGlobe));
++    c->icon = fromIconId(IconGlobe);
+     c->cmd  = QStringLiteral("copyq open %1");
+     c->hideWindow = true;
+     c->inMenu = true;
+@@ -91,7 +92,7 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Paste as Plain Text");
+     c->input = mimeText;
+-    c->icon = QString(QChar(IconPaste));
++    c->icon = fromIconId(IconPaste);
+     c->cmd  = QStringLiteral("copyq:") + pasteAsPlainTextScript("input()");
+     c->hideWindow = true;
+     c->inMenu = true;
+@@ -99,7 +100,7 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Autoplay videos");
+     c->re   = QRegularExpression("^http://.*\\.(mp4|avi|mkv|wmv|flv|ogv)$");
+-    c->icon = QString(QChar(IconCirclePlay));
++    c->icon = fromIconId(IconCirclePlay);
+     c->cmd  = QStringLiteral("copyq open %1");
+     c->automatic = true;
+     c->hideWindow = true;
+@@ -108,13 +109,13 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Copy URL (web address) to other tab");
+     c->re   = reURL;
+-    c->icon = QString(QChar(IconCopy));
++    c->icon = fromIconId(IconCopy);
+     c->tab  = QStringLiteral("&web");
+     c->automatic = true;
+ 
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Create thumbnail (needs ImageMagick)");
+-    c->icon = QString(QChar(IconImage));
++    c->icon = fromIconId(IconImage);
+     c->cmd  = QStringLiteral("convert - -resize 92x92 png:-");
+     c->input = QStringLiteral("image/png");
+     c->output = QStringLiteral("image/png");
+@@ -123,7 +124,7 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Create QR Code from URL (needs 
qrencode)");
+     c->re   = reURL;
+-    c->icon = QString(QChar(IconQrcode));
++    c->icon = fromIconId(IconQrcode);
+     c->cmd  = QStringLiteral("qrencode -o - -t PNG -s 6");
+     c->input = mimeText;
+     c->output = QStringLiteral("image/png");
+@@ -134,7 +135,7 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Add to %1 tab", "%1 is quoted Tasks tab 
name")
+             .arg(todoTabQuoted);
+-    c->icon = QString(QChar(IconShare));
++    c->icon = fromIconId(IconShare);
+     c->tab  = todoTab;
+     c->input = mimeText;
+     c->inMenu = true;
+@@ -142,7 +143,7 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Move to %1 tab", "%1 is quoted Tasks tab 
name")
+             .arg(todoTabQuoted);
+-    c->icon = QString(QChar(IconShare));
++    c->icon = fromIconId(IconShare);
+     c->tab  = todoTab;
+     c->remove = true;
+     c->inMenu = true;
+@@ -150,7 +151,7 @@ synchronizeToSelection = function() {
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Ignore copied files");
+     c->re   = reNotURL;
+-    c->icon = QString(QChar(IconCircleExclamation));
++    c->icon = fromIconId(IconCircleExclamation);
+     c->input = mimeUriList;
+     c->remove = true;
+     c->automatic = true;
+@@ -159,7 +160,7 @@ synchronizeToSelection = function() {
+         c = newCommand(&commands);
+         c->name = AddCommandDialog::tr("Ignore *\"Password\"* window");
+         c->wndre = QRegularExpression(AddCommandDialog::tr("Password"));
+-        c->icon = QString(QChar(IconAsterisk));
++        c->icon = fromIconId(IconAsterisk);
+         c->remove = true;
+         c->automatic = true;
+         c->cmd = QStringLiteral("copyq ignore");
+@@ -167,14 +168,14 @@ synchronizeToSelection = function() {
+ 
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Move to Trash");
+-    c->icon = QString(QChar(IconTrash));
++    c->icon = fromIconId(IconTrash);
+     c->inMenu = true;
+     c->tab  = AddCommandDialog::tr("(trash)");
+     c->remove = true;
+ 
+     c = newCommand(&commands);
+     c->name = AddCommandDialog::tr("Clear Current Tab");
+-    c->icon = QString(QChar(IconBroom));
++    c->icon = fromIconId(IconBroom);
+     c->inMenu = true;
+     c->cmd = QStringLiteral("copyq: 
ItemSelection(selectedTab()).selectRemovable().removeAll()");
+     c->matchCmd = QStringLiteral("copyq: tab(selectedTab()); if (size() == 0) 
fail()");
+diff --git a/src/gui/commanddialog.cpp b/src/gui/commanddialog.cpp
+index 2ac1355e..86dd29b1 100644
+--- a/src/gui/commanddialog.cpp
++++ b/src/gui/commanddialog.cpp
+@@ -13,6 +13,7 @@
+ #include "gui/commandwidget.h"
+ #include "gui/iconfactory.h"
+ #include "gui/icons.h"
++#include "gui/fromiconid.h"
+ #include "platform/platformclipboard.h"
+ #include "platform/platformnativeinterface.h"
+ 
+@@ -48,7 +49,7 @@ QIcon getCommandIcon(const QString &iconString, int 
commandType)
+           : commandType & CommandType::Menu ? QColor(100,220,255)
+           : QColor(255,100,100);
+ 
+-    return iconFromFile(iconString, QString(QChar(icon)), color);
++    return iconFromFile(iconString, fromIconId(icon), color);
+ }
+ 
+ bool hasCommandsToPaste(const QString &text)
+diff --git a/src/gui/fromiconid.h b/src/gui/fromiconid.h
+new file mode 100644
+index 00000000..e00104b2
+--- /dev/null
++++ b/src/gui/fromiconid.h
+@@ -0,0 +1,9 @@
++// SPDX-License-Identifier: GPL-3.0-or-later
++#pragma once
++
++#include <QChar>
++#include <QString>
++
++inline QString fromIconId(int id) {
++    return QString(QChar(id));
++}
+diff --git a/src/gui/iconfactory.cpp b/src/gui/iconfactory.cpp
+index b0cfcf3b..df28a4f4 100644
+--- a/src/gui/iconfactory.cpp
++++ b/src/gui/iconfactory.cpp
+@@ -3,8 +3,8 @@
+ #include "iconfactory.h"
+ 
+ #include "gui/fix_icon_id.h"
+-#include "gui/icons.h"
+ #include "gui/iconfont.h"
++#include "gui/fromiconid.h"
+ #include "gui/pixelratio.h"
+ 
+ #include <QBitmap>
+@@ -265,7 +265,7 @@ QPixmap drawFontIcon(ushort id, int w, int h, const QColor 
&color)
+ 
+     // Center the icon to whole pixels so it stays sharp.
+     const auto flags = Qt::AlignTop | Qt::AlignLeft;
+-    const auto iconText = QString(QChar(id));
++    const auto iconText = fromIconId(id);
+     auto boundingRect = painter.boundingRect(0, 0, w, h, flags, iconText);
+     const auto x = w - boundingRect.width();
+     // If icon is wider, assume that a tag will be rendered and align image 
to the right.
+diff --git a/src/gui/iconselectbutton.cpp b/src/gui/iconselectbutton.cpp
+index e26eaeff..4fc8c0fb 100644
+--- a/src/gui/iconselectbutton.cpp
++++ b/src/gui/iconselectbutton.cpp
+@@ -7,7 +7,7 @@
+ #include "gui/fix_icon_id.h"
+ #include "gui/iconfont.h"
+ #include "gui/iconselectdialog.h"
+-#include "gui/icons.h"
++#include "gui/fromiconid.h"
+ 
+ #include <QApplication>
+ #include <QIcon>
+@@ -40,7 +40,7 @@ void IconSelectButton::setCurrentIcon(const QString 
&iconString)
+     if ( iconString.size() == 1 ) {
+         const QChar c = iconString[0];
+         const ushort id = fixIconId( c.unicode() );
+-        m_currentIcon = QString(QChar(id));
++        m_currentIcon = fromIconId(id);
+         setFont(iconFont());
+         setText(m_currentIcon);
+     } else if ( !iconString.isEmpty() ) {
+diff --git a/src/gui/notificationbasic.cpp b/src/gui/notificationbasic.cpp
+index ed688f39..13a98528 100644
+--- a/src/gui/notificationbasic.cpp
++++ b/src/gui/notificationbasic.cpp
+@@ -8,7 +8,7 @@
+ #include "common/textdata.h"
+ #include "common/timer.h"
+ #include "gui/iconfactory.h"
+-#include "gui/icons.h"
++#include "gui/fromiconid.h"
+ #include "gui/pixelratio.h"
+ 
+ #include <QApplication>
+@@ -230,7 +230,7 @@ void NotificationBasicWidget::setIcon(const QString &icon)
+ 
+ void NotificationBasicWidget::setIcon(ushort icon)
+ {
+-    m_icon = QString(QChar(icon));
++    m_icon = fromIconId(icon);
+ }
+ 
+ void NotificationBasicWidget::setInterval(int msec)
+diff --git a/src/scriptable/scriptable.cpp b/src/scriptable/scriptable.cpp
+index 8893140c..7d5fd294 100644
+--- a/src/scriptable/scriptable.cpp
++++ b/src/scriptable/scriptable.cpp
+@@ -14,6 +14,7 @@
+ #include "common/textdata.h"
+ #include "gui/clipboardspy.h"
+ #include "gui/icons.h"
++#include "gui/fromiconid.h"
+ #include "item/itemfactory.h"
+ #include "item/serialize.h"
+ #include "platform/platformclipboard.h"
+@@ -2912,7 +2913,7 @@ void Scriptable::showExceptionMessage(const QString 
&message)
+     QtPrivate::QHashCombine hash;
+     const auto id = hash(hash(0, title), message);
+     const auto notificationId = QString::number(id);
+-    m_proxy->showMessage(title, message, 
QString(QChar(IconCircleExclamation)), 8000, notificationId);
++    m_proxy->showMessage(title, message, fromIconId(IconCircleExclamation), 
8000, notificationId);
+ }
+ 
+ QVector<int> Scriptable::getRows() const
+

Reply via email to