summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app-darktable/package.use/30-app-darktable2
-rw-r--r--app-fava/sets/app-fava (renamed from app-fava/sets/fava)0
-rw-r--r--app-quasselclient/package.use/30-app-quasselclient4
-rw-r--r--app-tex/sets/app-tex (renamed from app-tex/sets/tex)0
-rw-r--r--desktop-plasma/package.accept_keywords/09-desktop-plasma8
-rw-r--r--desktop-plasma/package.use/09-desktop-plasma19
-rw-r--r--desktop-plasma/patches/kde-apps/dolphin/0001-Ignore-trailing-slashes-when-comparing-place-URLs.patch73
-rw-r--r--desktop-plasma/patches/kde-apps/dolphin/0001-Kitemlistcontroller-only-accept-doubleclick-for-left.patch106
-rw-r--r--desktop-plasma/patches/kde-apps/dolphin/0001-TerminalPanel-Send-End-instead-of-Ctrl-E-to-move-to-.patch33
-rw-r--r--desktop-plasma/patches/kde-apps/dolphin/0002-Only-accept-left-mouse-button-for-double-click-actio.patch32
-rw-r--r--desktop-plasma/patches/kde-apps/dolphin/0003-Fix-double-click-view-background-feature.patch30
-rw-r--r--desktop-plasma/patches/kde-apps/dolphin/0004-kitemlistcontroller-process-forward-back-buttons-whe.patch47
-rw-r--r--desktop-plasma/patches/kde-frameworks/kio/0001-Pass-arguments-to-weltschmerz-correctly.patch8
-rw-r--r--desktop-plasma/patches/kde-frameworks/kio:6/0001-TrashSizeCache-Use-correct-iterator-flags.patch29
-rw-r--r--desktop-plasma/patches/kde-plasma/plasma-workspace/0001-weather-dwd-fix-icon-for-condition-2.patch69
-rw-r--r--desktop-plasma/patches/kde-plasma/plasma-workspace/0002-weather-dwd-Use-more-robust-parsing-for-timestamps.patch66
-rw-r--r--desktop-plasma/patches/kde-plasma/plasma-workspace/0003-weather-dwd-Add-support-for-night-time-icons.patch182
-rw-r--r--desktop-plasma/sets/desktop-plasma (renamed from desktop-plasma/sets/plasma-desktop)2
-rw-r--r--desktop-sway/package.use/09-desktop-sway4
-rw-r--r--desktop-sway/sets/desktop-sway (renamed from desktop-sway/sets/sway-desktop)0
-rw-r--r--group-base/env/ccache2
-rw-r--r--group-base/package.accept_keywords/00-group-base5
-rw-r--r--group-base/package.use/00-group-base11
-rw-r--r--group-base/sets/base20
-rw-r--r--group-base/sets/base-ebuild3
-rw-r--r--group-desktop/package.accept_keywords/01-group-desktop6
-rw-r--r--group-desktop/package.use/01-group-desktop24
-rw-r--r--group-desktop/sets/desktop-cdrip (renamed from group-desktop/sets/cdrip)0
-rw-r--r--group-desktop/sets/desktop-fonts (renamed from group-desktop/sets/fonts)0
-rw-r--r--group-desktop/sets/desktop-music (renamed from group-desktop/sets/music)0
-rw-r--r--group-desktop/sets/desktop-thunar (renamed from group-desktop/sets/thunar)0
-rw-r--r--host-coleridge/make.conf2
-rw-r--r--host-coleridge/package.use/90-host-coleridge2
-rw-r--r--kernel-6.8/package.accept_keywords/70-kernel-6.81
-rw-r--r--kernel-6.8/package.mask/70-kernel-6.82
-rw-r--r--lang-base/sets/lang-base (renamed from lang-base/sets/devel)1
-rw-r--r--lang-cpp/package.use/10-lang-cpp1
-rw-r--r--lang-cpp/sets/lang-cpp1
-rw-r--r--lang-python/package.accept_keywords/10-lang-python2
-rw-r--r--lang-python/sets/lang-python (renamed from lang-python/sets/python-devel)2
-rw-r--r--service-cups/package.use/20-service-cups5
-rw-r--r--service-prosody/package.use/20-service-prosody2
-rw-r--r--service-qbittorrent/package.use/20-service-qbittorrent1
-rw-r--r--service-quasselcore/package.accept_keywords/20-service-quasselcore1
-rw-r--r--service-quasselcore/package.use/20-service-quasselcore2
45 files changed, 675 insertions, 135 deletions
diff --git a/app-darktable/package.use/30-app-darktable b/app-darktable/package.use/30-app-darktable
index 0ef880b..3f1902d 100644
--- a/app-darktable/package.use/30-app-darktable
+++ b/app-darktable/package.use/30-app-darktable
@@ -1,3 +1,3 @@
-media-gfx/darktable geolocation heif
+media-gfx/darktable geolocation
sys-devel/gcc graphite
diff --git a/app-fava/sets/fava b/app-fava/sets/app-fava
index 9f3a3fc..9f3a3fc 100644
--- a/app-fava/sets/fava
+++ b/app-fava/sets/app-fava
diff --git a/app-quasselclient/package.use/30-app-quasselclient b/app-quasselclient/package.use/30-app-quasselclient
deleted file mode 100644
index fb8f6b2..0000000
--- a/app-quasselclient/package.use/30-app-quasselclient
+++ /dev/null
@@ -1,4 +0,0 @@
-net-irc/quarg postgres
-net-irc/quassel -crypt -server bundled-icons dbus gui
-
-dev-db/postgresql -server
diff --git a/app-tex/sets/tex b/app-tex/sets/app-tex
index 77d1bd4..77d1bd4 100644
--- a/app-tex/sets/tex
+++ b/app-tex/sets/app-tex
diff --git a/desktop-plasma/package.accept_keywords/09-desktop-plasma b/desktop-plasma/package.accept_keywords/09-desktop-plasma
index add3081..1683b65 100644
--- a/desktop-plasma/package.accept_keywords/09-desktop-plasma
+++ b/desktop-plasma/package.accept_keywords/09-desktop-plasma
@@ -1 +1,7 @@
-kde-apps/krdc
+kde-apps/*
+kde-frameworks/*
+kde-misc/*
+kde-plasma/*
+
+media-gfx/kio-ps-thumbnailer
+dev-libs/plasma-wayland-protocols
diff --git a/desktop-plasma/package.use/09-desktop-plasma b/desktop-plasma/package.use/09-desktop-plasma
index 8e88c5e..5e786ed 100644
--- a/desktop-plasma/package.use/09-desktop-plasma
+++ b/desktop-plasma/package.use/09-desktop-plasma
@@ -1,29 +1,32 @@
*/* activities
*/* declarative
+*/* kde
*/* kf6compat
+*/* kwallet
*/* policykit
*/* qml
*/* qt5
*/* qt6
+*/* screencast
+*/* semantic-desktop
*/* -handbook
kde-plasma/plasma-meta bluetooth gtk -browser-integration -crash-handler -crypt -firewall -networkmanager -xwayland
-kde-plasma/kwin screencast
-kde-plasma/plasma-desktop screencast
-kde-plasma/plasma-workspace screencast
-
app-accessibility/speech-dispatcher -espeak
+app-arch/p7zip -kde
dev-build/cmake -qt6
kde-apps/ark zip
-kde-apps/dolphin semantic-desktop
-kde-apps/gwenview semantic-desktop -mpris
+kde-apps/gwenview -mpris
+kde-apps/thumbnailers pdf video
kde-frameworks/kwallet gpg
kde-frameworks/sonnet -hunspell
media-libs/opencv -python
media-libs/phonon minimal
-net-irc/quassel kde spell
-virtual/notification-daemon kde
+net-irc/quassel -bundled-icons spell
+
+# qml enables the mobile app, which we really don't need
+kde-apps/okular -qml
# required by kde-plasma/plasma-meta
dev-qt/qtbase libproxy cups X
diff --git a/desktop-plasma/patches/kde-apps/dolphin/0001-Ignore-trailing-slashes-when-comparing-place-URLs.patch b/desktop-plasma/patches/kde-apps/dolphin/0001-Ignore-trailing-slashes-when-comparing-place-URLs.patch
deleted file mode 100644
index 385da80..0000000
--- a/desktop-plasma/patches/kde-apps/dolphin/0001-Ignore-trailing-slashes-when-comparing-place-URLs.patch
+++ /dev/null
@@ -1,73 +0,0 @@
-From 046ddcf5607e597cd6290147bf7ee10c08e526dd Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
-Date: Thu, 19 Sep 2024 11:46:09 +0200
-Subject: [PATCH] Ignore trailing slashes when comparing place URLs
-
-There's two locations where place URLs are compared in Dolphin. One
-is in DolphinContextMenu::placeExists, which determines whether or not
-to show an "Add to Places" context menu entry. The other one is in
-DolphinViewContainer::caption, which provides the place name for use in
-the window title, if applicable.
-
-Neither of these functions correctly normalize the URL to account for
-trailing slashes. Whilst placeExists() does not even attempt it,
-caption() was changed in 681d8bb6c (Fix wrong window titles, 2019-09-15)
-to support this using a regular expression.
-
-However, caption() fails to escape the URL before incorporating it in
-the regular expression, leading to failed matches and errors like the
-following when browsing to directories that do not happen to make up a
-valid regular expression:
-
- QString(View)::contains(): called on an invalid QRegularExpression
- object (pattern is '\A(?:file:///home/foo/[Z-A]/?)\z')
-
-Instead of relying on complex and possibly brittle regular expressions,
-use KFilePlacesModel's closestItem() function to find the closest
-matching URL and then finally check whether the normalized URLs match
-exactly.
----
- src/dolphincontextmenu.cpp | 5 ++---
- src/dolphinviewcontainer.cpp | 9 ++++-----
- 2 files changed, 6 insertions(+), 8 deletions(-)
-
-diff --git a/src/dolphincontextmenu.cpp b/src/dolphincontextmenu.cpp
-index 68f6dbd21..3ce1d1d51 100644
---- a/src/dolphincontextmenu.cpp
-+++ b/src/dolphincontextmenu.cpp
-@@ -381,9 +381,8 @@ bool DolphinContextMenu::placeExists(const QUrl &url) const
- {
- const KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
-
-- const auto &matchedPlaces = placesModel->match(placesModel->index(0, 0), KFilePlacesModel::UrlRole, url, 1, Qt::MatchExactly);
--
-- return !matchedPlaces.isEmpty();
-+ QModelIndex url_index = placesModel->closestItem(url);
-+ return url_index.isValid() && placesModel->url(url_index).matches(url, QUrl::StripTrailingSlash);
- }
-
- QAction *DolphinContextMenu::createPasteAction()
-diff --git a/src/dolphinviewcontainer.cpp b/src/dolphinviewcontainer.cpp
-index ef76042b8..e55519d04 100644
---- a/src/dolphinviewcontainer.cpp
-+++ b/src/dolphinviewcontainer.cpp
-@@ -552,12 +552,11 @@ QString DolphinViewContainer::caption() const
- }
-
- KFilePlacesModel *placesModel = DolphinPlacesModelSingleton::instance().placesModel();
-- const QString pattern = url().adjusted(QUrl::StripTrailingSlash).toString(QUrl::FullyEncoded).append("/?");
-- const auto &matchedPlaces =
-- placesModel->match(placesModel->index(0, 0), KFilePlacesModel::UrlRole, QRegularExpression::anchoredPattern(pattern), 1, Qt::MatchRegularExpression);
-
-- if (!matchedPlaces.isEmpty()) {
-- return placesModel->text(matchedPlaces.first());
-+ QModelIndex url_index = placesModel->closestItem(url());
-+
-+ if (url_index.isValid() && placesModel->url(url_index).matches(url(), QUrl::StripTrailingSlash)) {
-+ return placesModel->text(url_index);
- }
-
- if (!url().isLocalFile()) {
---
-2.46.0
-
diff --git a/desktop-plasma/patches/kde-apps/dolphin/0001-Kitemlistcontroller-only-accept-doubleclick-for-left.patch b/desktop-plasma/patches/kde-apps/dolphin/0001-Kitemlistcontroller-only-accept-doubleclick-for-left.patch
new file mode 100644
index 0000000..b8a53a1
--- /dev/null
+++ b/desktop-plasma/patches/kde-apps/dolphin/0001-Kitemlistcontroller-only-accept-doubleclick-for-left.patch
@@ -0,0 +1,106 @@
+From 531244611f11bfee9f6b9f2efd98ed418d860b3d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?M=C3=A9ven=20Car?= <meven@kde.org>
+Date: Wed, 31 Jul 2024 11:00:32 +0200
+Subject: [PATCH 1/4] Kitemlistcontroller: only accept doubleclick for left
+ mouse button
+
+Add test for double-click activation.
+
+BUG: 485295
+---
+ src/kitemviews/kitemlistcontroller.cpp | 2 +-
+ src/tests/kitemlistcontrollertest.cpp | 58 ++++++++++++++++++++++++++
+ 2 files changed, 59 insertions(+), 1 deletion(-)
+
+diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
+index 392dc410e..997e6623b 100644
+--- a/src/kitemviews/kitemlistcontroller.cpp
++++ b/src/kitemviews/kitemlistcontroller.cpp
+@@ -713,7 +713,7 @@ bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event,
+ }
+ }
+
+- if (event->button() & Qt::RightButton) {
++ if (event->button() & ~Qt::LeftButton) {
+ return false;
+ }
+
+diff --git a/src/tests/kitemlistcontrollertest.cpp b/src/tests/kitemlistcontrollertest.cpp
+index cb921781d..18ad1186d 100644
+--- a/src/tests/kitemlistcontrollertest.cpp
++++ b/src/tests/kitemlistcontrollertest.cpp
+@@ -620,6 +620,41 @@ void KItemListControllerTest::testMouseClickActivation()
+ mouseReleaseEvent.setButton(Qt::LeftButton);
+ mouseReleaseEvent.setButtons(Qt::NoButton);
+
++ QGraphicsSceneMouseEvent mouseDoubleClickEvent(QEvent::GraphicsSceneMouseDoubleClick);
++ mouseDoubleClickEvent.setPos(pos);
++ mouseDoubleClickEvent.setButton(Qt::LeftButton);
++ mouseDoubleClickEvent.setButtons(Qt::LeftButton);
++
++ QGraphicsSceneMouseEvent mouseRightPressEvent(QEvent::GraphicsSceneMousePress);
++ mouseRightPressEvent.setPos(pos);
++ mouseRightPressEvent.setButton(Qt::RightButton);
++ mouseRightPressEvent.setButtons(Qt::RightButton);
++
++ QGraphicsSceneMouseEvent mouseRightReleaseEvent(QEvent::GraphicsSceneMouseRelease);
++ mouseRightReleaseEvent.setPos(pos);
++ mouseRightReleaseEvent.setButton(Qt::RightButton);
++ mouseRightReleaseEvent.setButtons(Qt::NoButton);
++
++ QGraphicsSceneMouseEvent mouseRightDoubleClickEvent(QEvent::GraphicsSceneMouseDoubleClick);
++ mouseRightDoubleClickEvent.setPos(pos);
++ mouseRightDoubleClickEvent.setButton(Qt::RightButton);
++ mouseRightDoubleClickEvent.setButtons(Qt::RightButton);
++
++ QGraphicsSceneMouseEvent mouseBackPressEvent(QEvent::GraphicsSceneMousePress);
++ mouseBackPressEvent.setPos(pos);
++ mouseBackPressEvent.setButton(Qt::BackButton);
++ mouseBackPressEvent.setButtons(Qt::BackButton);
++
++ QGraphicsSceneMouseEvent mouseBackReleaseEvent(QEvent::GraphicsSceneMouseRelease);
++ mouseBackReleaseEvent.setPos(pos);
++ mouseBackReleaseEvent.setButton(Qt::BackButton);
++ mouseBackReleaseEvent.setButtons(Qt::NoButton);
++
++ QGraphicsSceneMouseEvent mouseBackDoubleClickEvent(QEvent::GraphicsSceneMouseDoubleClick);
++ mouseBackDoubleClickEvent.setPos(pos);
++ mouseBackDoubleClickEvent.setButton(Qt::BackButton);
++ mouseBackDoubleClickEvent.setButtons(Qt::BackButton);
++
+ QSignalSpy spyItemActivated(m_controller, &KItemListController::itemActivated);
+
+ // Default setting: single click activation.
+@@ -638,6 +673,29 @@ void KItemListControllerTest::testMouseClickActivation()
+ spyItemActivated.clear();
+ QVERIFY(m_view->controller()->selectionManager()->hasSelection());
+
++ // emulation of double click according to https://doc.qt.io/qt-6/qgraphicsscene.html#mouseDoubleClickEvent
++ m_view->event(&mousePressEvent);
++ m_view->event(&mouseReleaseEvent);
++ m_view->event(&mouseDoubleClickEvent);
++ m_view->event(&mouseReleaseEvent);
++ QCOMPARE(spyItemActivated.count(), 1);
++ spyItemActivated.clear();
++ QVERIFY2(!m_view->controller()->selectionManager()->hasSelection(), "An item should not be implicitly selected during activation. @see bug 424723");
++
++ // right mouse button should not trigger activation
++ m_view->event(&mouseRightPressEvent);
++ m_view->event(&mouseRightReleaseEvent);
++ m_view->event(&mouseRightDoubleClickEvent);
++ m_view->event(&mouseRightReleaseEvent);
++ QCOMPARE(spyItemActivated.count(), 0);
++
++ // back mouse button should not trigger activation
++ m_view->event(&mouseBackPressEvent);
++ m_view->event(&mouseBackReleaseEvent);
++ m_view->event(&mouseBackDoubleClickEvent);
++ m_view->event(&mouseBackReleaseEvent);
++ QCOMPARE(spyItemActivated.count(), 0);
++
+ // Enforce single click activation in the controller.
+ m_controller->setSingleClickActivationEnforced(true);
+ m_view->event(&mousePressEvent);
+--
+2.47.0
+
diff --git a/desktop-plasma/patches/kde-apps/dolphin/0001-TerminalPanel-Send-End-instead-of-Ctrl-E-to-move-to-.patch b/desktop-plasma/patches/kde-apps/dolphin/0001-TerminalPanel-Send-End-instead-of-Ctrl-E-to-move-to-.patch
new file mode 100644
index 0000000..6b11063
--- /dev/null
+++ b/desktop-plasma/patches/kde-apps/dolphin/0001-TerminalPanel-Send-End-instead-of-Ctrl-E-to-move-to-.patch
@@ -0,0 +1,33 @@
+From b65e53ac65c265dad3dca5c6687873f035d7c949 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
+Date: Tue, 8 Oct 2024 15:36:33 +0200
+Subject: [PATCH] TerminalPanel: Send End instead of Ctrl-E to move to the end
+ of the line
+
+When using fish in vi mode it does not have Ctrl-E mapped to go to the
+end of the line. Instead use the End key, which should be mapped in all
+modes.
+---
+ src/panels/terminal/terminalpanel.cpp | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/panels/terminal/terminalpanel.cpp b/src/panels/terminal/terminalpanel.cpp
+index 5b17023a3..dfdc896ff 100644
+--- a/src/panels/terminal/terminalpanel.cpp
++++ b/src/panels/terminal/terminalpanel.cpp
+@@ -251,10 +251,10 @@ void TerminalPanel::sendCdToTerminal(const QString &dir, HistoryPolicy addToHist
+ return;
+ }
+
+- // Send prior Ctrl-E, Ctrl-U to ensure the line is empty. This is
++ // Send prior End, Ctrl-U to ensure the line is empty. This is
+ // mandatory, otherwise sending a 'cd x\n' to a prompt with 'rm -rf *'
+ // would result in data loss.
+- m_terminal->sendInput(QStringLiteral("\x05\x15"));
++ m_terminal->sendInput(QStringLiteral("\x1B[F\x15"));
+
+ // We want to ignore the currentDirectoryChanged(QString) signal, which we will receive after
+ // the directory change, because this directory change is not caused by a "cd" command that the
+--
+2.46.2
+
diff --git a/desktop-plasma/patches/kde-apps/dolphin/0002-Only-accept-left-mouse-button-for-double-click-actio.patch b/desktop-plasma/patches/kde-apps/dolphin/0002-Only-accept-left-mouse-button-for-double-click-actio.patch
new file mode 100644
index 0000000..9fd79a6
--- /dev/null
+++ b/desktop-plasma/patches/kde-apps/dolphin/0002-Only-accept-left-mouse-button-for-double-click-actio.patch
@@ -0,0 +1,32 @@
+From fbdbe93e3d6b25fc4a40af4c9c3fe337794452ba Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?M=C3=A9ven=20Car?= <meven@kde.org>
+Date: Tue, 13 Aug 2024 11:01:43 +0200
+Subject: [PATCH 2/4] Only accept left mouse button for double click actions
+
+Such
+ * double click background
+
+BUG: 485295
+---
+ src/dolphinmainwindow.cpp | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp
+index 8bc066455..bf605fa96 100644
+--- a/src/dolphinmainwindow.cpp
++++ b/src/dolphinmainwindow.cpp
+@@ -2922,7 +2922,10 @@ bool DolphinMainWindow::isItemVisibleInAnyView(const QString &urlOfItem)
+
+ void DolphinMainWindow::slotDoubleClickViewBackground(Qt::MouseButton button)
+ {
+- Q_UNUSED(button) // might be of use later
++ if (button == Qt::MouseButton::LeftButton) {
++ // only handle left mouse button for now
++ return;
++ }
+
+ GeneralSettings *settings = GeneralSettings::self();
+ QString clickAction = settings->doubleClickViewAction();
+--
+2.47.0
+
diff --git a/desktop-plasma/patches/kde-apps/dolphin/0003-Fix-double-click-view-background-feature.patch b/desktop-plasma/patches/kde-apps/dolphin/0003-Fix-double-click-view-background-feature.patch
new file mode 100644
index 0000000..ee6c343
--- /dev/null
+++ b/desktop-plasma/patches/kde-apps/dolphin/0003-Fix-double-click-view-background-feature.patch
@@ -0,0 +1,30 @@
+From 123eec787f0198b91c3bfdb17262df0c5e9a8c28 Mon Sep 17 00:00:00 2001
+From: Felix Ernst <felixernst@zohomail.eu>
+Date: Mon, 14 Oct 2024 14:44:47 +0200
+Subject: [PATCH 3/4] Fix double-click view background feature
+
+c934e803647674b4692668f047b6ffa18121982a was meant to change the
+double-click view background feature to only allow double-clicks
+with the left mouse button. However, it mistakenly did the exact
+opposite and allowed every double-click except ones with the left
+mouse button to trigger the feature. This one-liner fixes this.
+---
+ src/dolphinmainwindow.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp
+index bf605fa96..9b2c0f97e 100644
+--- a/src/dolphinmainwindow.cpp
++++ b/src/dolphinmainwindow.cpp
+@@ -2922,7 +2922,7 @@ bool DolphinMainWindow::isItemVisibleInAnyView(const QString &urlOfItem)
+
+ void DolphinMainWindow::slotDoubleClickViewBackground(Qt::MouseButton button)
+ {
+- if (button == Qt::MouseButton::LeftButton) {
++ if (button != Qt::MouseButton::LeftButton) {
+ // only handle left mouse button for now
+ return;
+ }
+--
+2.47.0
+
diff --git a/desktop-plasma/patches/kde-apps/dolphin/0004-kitemlistcontroller-process-forward-back-buttons-whe.patch b/desktop-plasma/patches/kde-apps/dolphin/0004-kitemlistcontroller-process-forward-back-buttons-whe.patch
new file mode 100644
index 0000000..d0fa8eb
--- /dev/null
+++ b/desktop-plasma/patches/kde-apps/dolphin/0004-kitemlistcontroller-process-forward-back-buttons-whe.patch
@@ -0,0 +1,47 @@
+From dd38c471458760b1795ac2cc0017bc5b5924b70b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
+Date: Mon, 14 Oct 2024 18:43:28 +0200
+Subject: [PATCH 4/4] kitemlistcontroller: process forward/back buttons when
+ double-clicking
+
+Tapping the forward or back mouse buttons quickly enough makes Dolphin
+interpret the action as a double-click of the button in question and
+handle it in mouseDoubleClickEvent() instead of its normal button
+handler. This means that certain button presses might seem delayed or
+"swallowed" when quickly navigating forwards or backwards through the
+history.
+
+Since a double-click of the forward or back button is currently
+meaningless, fix this by emitting a normal mouseButtonPressed event for
+those buttons in the double-click handler and skipping any further event
+processing.
+
+Co-authored-by: Felix Ernst <felixernst@zohomail.eu>
+CCBUG: 485295
+---
+ src/kitemviews/kitemlistcontroller.cpp | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp
+index 997e6623b..821e1b75f 100644
+--- a/src/kitemviews/kitemlistcontroller.cpp
++++ b/src/kitemviews/kitemlistcontroller.cpp
+@@ -700,6 +700,15 @@ bool KItemListController::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event,
+ const QPointF pos = transform.map(event->pos());
+ const std::optional<int> index = m_view->itemAt(pos);
+
++ if (event->button() & (Qt::ForwardButton | Qt::BackButton)) {
++ // "Forward" and "Back" are reserved for quickly navigating through the
++ // history. Double-clicking those buttons should be interpreted as two
++ // separate button presses. We arrive here for the second click, which
++ // we now react to just as we would for a singular click
++ Q_EMIT mouseButtonPressed(index.value_or(-1), event->button());
++ return false;
++ }
++
+ if (!index.has_value()) {
+ Q_EMIT doubleClickViewBackground(event->button());
+ return false;
+--
+2.47.0
+
diff --git a/desktop-plasma/patches/kde-frameworks/kio/0001-Pass-arguments-to-weltschmerz-correctly.patch b/desktop-plasma/patches/kde-frameworks/kio/0001-Pass-arguments-to-weltschmerz-correctly.patch
index b7e19fb..087c21b 100644
--- a/desktop-plasma/patches/kde-frameworks/kio/0001-Pass-arguments-to-weltschmerz-correctly.patch
+++ b/desktop-plasma/patches/kde-frameworks/kio/0001-Pass-arguments-to-weltschmerz-correctly.patch
@@ -1,4 +1,4 @@
-From 532a7c03a4c5cc26a1f06ce4882b1d2010b6c44d Mon Sep 17 00:00:00 2001
+From 5dee62540628f2bebbe783bae0cf5a564d1c333f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
Date: Tue, 10 Sep 2024 23:11:02 +0200
Subject: [PATCH] Pass arguments to weltschmerz correctly
@@ -34,7 +34,7 @@ index 63c924737..b2851077e 100644
KShell::Errors err;
diff --git a/src/gui/kterminallauncherjob.cpp b/src/gui/kterminallauncherjob.cpp
-index edd99327b..beb80b090 100644
+index edd99327b..1feca99c3 100644
--- a/src/gui/kterminallauncherjob.cpp
+++ b/src/gui/kterminallauncherjob.cpp
@@ -136,7 +136,11 @@ void KTerminalLauncherJob::determineFullCommand(bool fallbackToKonsoleService /*
@@ -43,7 +43,7 @@ index edd99327b..beb80b090 100644
if (!d->m_command.isEmpty()) {
- exec += QLatin1String(" -e ") + d->m_command;
+ if (exec == QLatin1String("weltschmerz")) {
-+ exec += d->m_command;
++ exec += QLatin1String(" ") + d->m_command;
+ } else {
+ exec += QLatin1String(" -e ") + d->m_command;
+ }
@@ -51,5 +51,5 @@ index edd99327b..beb80b090 100644
#else
const QString windowsTerminal = QStringLiteral("wt.exe");
--
-2.46.0
+2.46.2
diff --git a/desktop-plasma/patches/kde-frameworks/kio:6/0001-TrashSizeCache-Use-correct-iterator-flags.patch b/desktop-plasma/patches/kde-frameworks/kio:6/0001-TrashSizeCache-Use-correct-iterator-flags.patch
new file mode 100644
index 0000000..a24e1c0
--- /dev/null
+++ b/desktop-plasma/patches/kde-frameworks/kio:6/0001-TrashSizeCache-Use-correct-iterator-flags.patch
@@ -0,0 +1,29 @@
+From 241eb504801bc4ee12555fa2c8737b409383ba5c Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
+Date: Fri, 4 Oct 2024 16:27:40 +0200
+Subject: [PATCH] TrashSizeCache: Use correct flags for QDirIterator
+
+When calculating the size of the trash we walk through all files in the
+trash path using QDirIterator. In 0ab81b6ba (trashimpl: optimize
+TrashSizeCache::calculateSize, 2023-09-05) its invocation was changed to
+include the QDir::NoDotAndDotDot filter.
+---
+ src/kioworkers/trash/trashsizecache.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/kioworkers/trash/trashsizecache.cpp b/src/kioworkers/trash/trashsizecache.cpp
+index 81e71f4b9..e67618554 100644
+--- a/src/kioworkers/trash/trashsizecache.cpp
++++ b/src/kioworkers/trash/trashsizecache.cpp
+@@ -146,7 +146,7 @@ TrashSizeCache::SizeAndModTime TrashSizeCache::scanFilesInTrash(ScanFilesInTrash
+
+ // Iterate over the actual trashed files.
+ // Orphan items (no .fileinfo) still take space.
+- QDirIterator it(mTrashPath + QLatin1String("/files/"), QDir::NoDotAndDotDot);
++ QDirIterator it(mTrashPath + QLatin1String("/files/"), QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot);
+ qint64 sum = 0;
+ qint64 max_mtime = 0;
+ const auto checkMaxTime = [&max_mtime](const qint64 lastModTime) {
+--
+2.46.2
+
diff --git a/desktop-plasma/patches/kde-plasma/plasma-workspace/0001-weather-dwd-fix-icon-for-condition-2.patch b/desktop-plasma/patches/kde-plasma/plasma-workspace/0001-weather-dwd-fix-icon-for-condition-2.patch
new file mode 100644
index 0000000..382ac00
--- /dev/null
+++ b/desktop-plasma/patches/kde-plasma/plasma-workspace/0001-weather-dwd-fix-icon-for-condition-2.patch
@@ -0,0 +1,69 @@
+From 2af745e41bf2639a3a4a81855f500ce147a3a731 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
+Date: Tue, 15 Oct 2024 18:38:57 +0200
+Subject: [PATCH 1/3] weather/dwd: fix icon for condition 2
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Condition 2, "Sonne, leicht bewölkt", indicates a sunny day with few
+clouds. Use the more specific FewCloudsDay condition icon instead of
+PartlyCloudyDay, which is already correctly used for condition 3.
+---
+ dataengines/weather/ions/dwd/ion_dwd.cpp | 40 ++++++------------------
+ 1 file changed, 10 insertions(+), 30 deletions(-)
+
+diff --git a/dataengines/weather/ions/dwd/ion_dwd.cpp b/dataengines/weather/ions/dwd/ion_dwd.cpp
+index 83e193d70b..5909b5f5e9 100644
+--- a/dataengines/weather/ions/dwd/ion_dwd.cpp
++++ b/dataengines/weather/ions/dwd/ion_dwd.cpp
+@@ -86,36 +86,16 @@ QMap<QString, IonInterface::ConditionIcons> DWDIon::setupDayIconMappings() const
+ {
+ // DWD supplies it's own icon number which we can use to determine a condition
+
+- return QMap<QString, ConditionIcons>{{QStringLiteral("1"), ClearDay},
+- {QStringLiteral("2"), PartlyCloudyDay},
+- {QStringLiteral("3"), PartlyCloudyDay},
+- {QStringLiteral("4"), Overcast},
+- {QStringLiteral("5"), Mist},
+- {QStringLiteral("6"), Mist},
+- {QStringLiteral("7"), LightRain},
+- {QStringLiteral("8"), Rain},
+- {QStringLiteral("9"), Rain},
+- {QStringLiteral("10"), LightRain},
+- {QStringLiteral("11"), Rain},
+- {QStringLiteral("12"), Flurries},
+- {QStringLiteral("13"), RainSnow},
+- {QStringLiteral("14"), LightSnow},
+- {QStringLiteral("15"), Snow},
+- {QStringLiteral("16"), Snow},
+- {QStringLiteral("17"), Hail},
+- {QStringLiteral("18"), LightRain},
+- {QStringLiteral("19"), Rain},
+- {QStringLiteral("20"), Flurries},
+- {QStringLiteral("21"), RainSnow},
+- {QStringLiteral("22"), LightSnow},
+- {QStringLiteral("23"), Snow},
+- {QStringLiteral("24"), Hail},
+- {QStringLiteral("25"), Hail},
+- {QStringLiteral("26"), Thunderstorm},
+- {QStringLiteral("27"), Thunderstorm},
+- {QStringLiteral("28"), Thunderstorm},
+- {QStringLiteral("29"), Thunderstorm},
+- {QStringLiteral("30"), Thunderstorm},
++ return QMap<QString, ConditionIcons>{{QStringLiteral("1"), ClearDay}, {QStringLiteral("2"), FewCloudsDay}, {QStringLiteral("3"), PartlyCloudyDay},
++ {QStringLiteral("4"), Overcast}, {QStringLiteral("5"), Mist}, {QStringLiteral("6"), Mist},
++ {QStringLiteral("7"), LightRain}, {QStringLiteral("8"), Rain}, {QStringLiteral("9"), Rain},
++ {QStringLiteral("10"), LightRain}, {QStringLiteral("11"), Rain}, {QStringLiteral("12"), Flurries},
++ {QStringLiteral("13"), RainSnow}, {QStringLiteral("14"), LightSnow}, {QStringLiteral("15"), Snow},
++ {QStringLiteral("16"), Snow}, {QStringLiteral("17"), Hail}, {QStringLiteral("18"), LightRain},
++ {QStringLiteral("19"), Rain}, {QStringLiteral("20"), Flurries}, {QStringLiteral("21"), RainSnow},
++ {QStringLiteral("22"), LightSnow}, {QStringLiteral("23"), Snow}, {QStringLiteral("24"), Hail},
++ {QStringLiteral("25"), Hail}, {QStringLiteral("26"), Thunderstorm}, {QStringLiteral("27"), Thunderstorm},
++ {QStringLiteral("28"), Thunderstorm}, {QStringLiteral("29"), Thunderstorm}, {QStringLiteral("30"), Thunderstorm},
+ {QStringLiteral("31"), ClearWindyDay}};
+ }
+
+--
+2.47.0
+
diff --git a/desktop-plasma/patches/kde-plasma/plasma-workspace/0002-weather-dwd-Use-more-robust-parsing-for-timestamps.patch b/desktop-plasma/patches/kde-plasma/plasma-workspace/0002-weather-dwd-Use-more-robust-parsing-for-timestamps.patch
new file mode 100644
index 0000000..22b9713
--- /dev/null
+++ b/desktop-plasma/patches/kde-plasma/plasma-workspace/0002-weather-dwd-Use-more-robust-parsing-for-timestamps.patch
@@ -0,0 +1,66 @@
+From 85f11eeabd8d0a7cef8ef76a129e1b4ec4c82f3e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
+Date: Thu, 17 Oct 2024 13:50:47 +0200
+Subject: [PATCH 2/3] weather/dwd: Use more robust parsing for timestamps
+
+When parsing the observationDateTime from the DWD API, we directly
+convert a QMap lookup by using toLongLong(). For invalid values, or when
+the map lookup returns QVariant() for a missing key, this will return 0,
+creating a valid date at millisecond offset 0. Later in the code there
+is a check for observationDateTime.isNull() which will therefore never
+return true.
+
+For a more robust check, use a helper function parseDateFromMSecs()
+which will make sure the conversion to qint64 succeeded before creating
+the QDateTime instance. If the conversion fails for any reason, we
+instead return a null datetime by simply calling the empty QDateTime()
+constructor. These null datetimes will indicate isNull() correctly.
+---
+ dataengines/weather/ions/dwd/ion_dwd.cpp | 11 +++++++++--
+ dataengines/weather/ions/dwd/ion_dwd.h | 1 +
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/dataengines/weather/ions/dwd/ion_dwd.cpp b/dataengines/weather/ions/dwd/ion_dwd.cpp
+index 5909b5f5e9..9ab9ce5a0b 100644
+--- a/dataengines/weather/ions/dwd/ion_dwd.cpp
++++ b/dataengines/weather/ions/dwd/ion_dwd.cpp
+@@ -498,8 +498,7 @@ void DWDIon::parseMeasureData(const QString source, QJsonDocument doc)
+ QVariantMap weatherMap = doc.object().toVariantMap();
+
+ if (!weatherMap.isEmpty()) {
+- QDateTime time = QDateTime::fromMSecsSinceEpoch(weatherMap[QStringLiteral("time")].toLongLong());
+- weatherData.observationDateTime = time;
++ weatherData.observationDateTime = parseDateFromMSecs(weatherMap[QStringLiteral("time")]);
+
+ QString condIconNumber = weatherMap[QStringLiteral("icon")].toString();
+ if (condIconNumber != QLatin1String("")) {
+@@ -669,6 +668,14 @@ float DWDIon::parseNumber(QVariant number)
+ return static_cast<float>(intValue) / 10;
+ }
+
++QDateTime DWDIon::parseDateFromMSecs(QVariant timestamp)
++{
++ bool isValid = false;
++ const qint64 msecs = timestamp.toLongLong(&isValid);
++
++ return isValid ? QDateTime::fromMSecsSinceEpoch(msecs) : QDateTime();
++}
++
+ QString DWDIon::roundWindDirections(int windDirection)
+ {
+ QString roundedWindDirection = QString::number(qRound(((float)windDirection) / 100) * 10);
+diff --git a/dataengines/weather/ions/dwd/ion_dwd.h b/dataengines/weather/ions/dwd/ion_dwd.h
+index dc86bd43ce..38b9ce3cac 100644
+--- a/dataengines/weather/ions/dwd/ion_dwd.h
++++ b/dataengines/weather/ions/dwd/ion_dwd.h
+@@ -135,6 +135,7 @@ private:
+ QString extractString(QByteArray array, int start, int length);
+ QString roundWindDirections(int windDirection);
+ float parseNumber(QVariant number);
++ QDateTime parseDateFromMSecs(QVariant timestamp);
+
+ private:
+ // Key dicts
+--
+2.47.0
+
diff --git a/desktop-plasma/patches/kde-plasma/plasma-workspace/0003-weather-dwd-Add-support-for-night-time-icons.patch b/desktop-plasma/patches/kde-plasma/plasma-workspace/0003-weather-dwd-Add-support-for-night-time-icons.patch
new file mode 100644
index 0000000..45d1330
--- /dev/null
+++ b/desktop-plasma/patches/kde-plasma/plasma-workspace/0003-weather-dwd-Add-support-for-night-time-icons.patch
@@ -0,0 +1,182 @@
+From 63a5abc6b1eb409ca5cdb06a96860af2d1d74994 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Wolfgang=20M=C3=BCller?= <wolf@oriole.systems>
+Date: Thu, 17 Oct 2024 17:36:41 +0200
+Subject: [PATCH 3/3] weather/dwd: Add support for night-time icons
+
+The DWD Ion currently shows only day-time icons which feels a bit off
+when checking the weather after dusk or at night. Implement the missing
+night-time icons and use sunrise and sunset times from DWD's forecast
+endpoint to accurately determine when to switch. This will only affect
+the display of the current conditions, the forecast icons will continue
+to be displayed as day-time only.
+
+Since we need to have both observation data (for the current observation
+time) and forecast data (for sunrise and sunset times), only determine
+the icon at a very late stage in updateWeather(). Additionally, make
+sure to safely fall back to day-time only icons if we could not fetch
+sunrise or sunset times.
+---
+ dataengines/weather/ions/dwd/ion_dwd.cpp | 70 ++++++++++++++++++------
+ dataengines/weather/ions/dwd/ion_dwd.h | 8 ++-
+ 2 files changed, 59 insertions(+), 19 deletions(-)
+
+diff --git a/dataengines/weather/ions/dwd/ion_dwd.cpp b/dataengines/weather/ions/dwd/ion_dwd.cpp
+index 9ab9ce5a0b..e4a1c1dc74 100644
+--- a/dataengines/weather/ions/dwd/ion_dwd.cpp
++++ b/dataengines/weather/ions/dwd/ion_dwd.cpp
+@@ -82,21 +82,38 @@ void DWDIon::deleteForecasts()
+ }
+ }
+
++QMap<QString, IonInterface::ConditionIcons> DWDIon::getUniversalIcons() const
++{
++ return QMap<QString, ConditionIcons>{
++ {QStringLiteral("4"), Overcast}, {QStringLiteral("5"), Mist}, {QStringLiteral("6"), Mist}, {QStringLiteral("7"), LightRain},
++ {QStringLiteral("8"), Rain}, {QStringLiteral("9"), Rain}, {QStringLiteral("10"), LightRain}, {QStringLiteral("11"), Rain},
++ {QStringLiteral("12"), Flurries}, {QStringLiteral("13"), RainSnow}, {QStringLiteral("14"), LightSnow}, {QStringLiteral("15"), Snow},
++ {QStringLiteral("16"), Snow}, {QStringLiteral("17"), Hail}, {QStringLiteral("18"), LightRain}, {QStringLiteral("19"), Rain},
++ {QStringLiteral("20"), Flurries}, {QStringLiteral("21"), RainSnow}, {QStringLiteral("22"), LightSnow}, {QStringLiteral("23"), Snow},
++ {QStringLiteral("24"), Hail}, {QStringLiteral("25"), Hail}, {QStringLiteral("26"), Thunderstorm}, {QStringLiteral("27"), Thunderstorm},
++ {QStringLiteral("28"), Thunderstorm}, {QStringLiteral("29"), Thunderstorm}, {QStringLiteral("30"), Thunderstorm}};
++}
++
+ QMap<QString, IonInterface::ConditionIcons> DWDIon::setupDayIconMappings() const
+ {
+- // DWD supplies it's own icon number which we can use to determine a condition
++ QMap<QString, ConditionIcons> universalIcons = getUniversalIcons();
++ QMap<QString, ConditionIcons> dayIcons = {{QStringLiteral("1"), ClearDay},
++ {QStringLiteral("2"), FewCloudsDay},
++ {QStringLiteral("3"), PartlyCloudyDay},
++ {QStringLiteral("31"), ClearWindyDay}};
++ dayIcons.insert(universalIcons);
++ return dayIcons;
++}
+
+- return QMap<QString, ConditionIcons>{{QStringLiteral("1"), ClearDay}, {QStringLiteral("2"), FewCloudsDay}, {QStringLiteral("3"), PartlyCloudyDay},
+- {QStringLiteral("4"), Overcast}, {QStringLiteral("5"), Mist}, {QStringLiteral("6"), Mist},
+- {QStringLiteral("7"), LightRain}, {QStringLiteral("8"), Rain}, {QStringLiteral("9"), Rain},
+- {QStringLiteral("10"), LightRain}, {QStringLiteral("11"), Rain}, {QStringLiteral("12"), Flurries},
+- {QStringLiteral("13"), RainSnow}, {QStringLiteral("14"), LightSnow}, {QStringLiteral("15"), Snow},
+- {QStringLiteral("16"), Snow}, {QStringLiteral("17"), Hail}, {QStringLiteral("18"), LightRain},
+- {QStringLiteral("19"), Rain}, {QStringLiteral("20"), Flurries}, {QStringLiteral("21"), RainSnow},
+- {QStringLiteral("22"), LightSnow}, {QStringLiteral("23"), Snow}, {QStringLiteral("24"), Hail},
+- {QStringLiteral("25"), Hail}, {QStringLiteral("26"), Thunderstorm}, {QStringLiteral("27"), Thunderstorm},
+- {QStringLiteral("28"), Thunderstorm}, {QStringLiteral("29"), Thunderstorm}, {QStringLiteral("30"), Thunderstorm},
+- {QStringLiteral("31"), ClearWindyDay}};
++QMap<QString, IonInterface::ConditionIcons> DWDIon::setupNightIconMappings() const
++{
++ QMap<QString, ConditionIcons> universalIcons = getUniversalIcons();
++ QMap<QString, ConditionIcons> nightIcons = {{QStringLiteral("1"), ClearNight},
++ {QStringLiteral("2"), FewCloudsNight},
++ {QStringLiteral("3"), PartlyCloudyNight},
++ {QStringLiteral("31"), ClearWindyNight}};
++ nightIcons.insert(universalIcons);
++ return nightIcons;
+ }
+
+ QMap<QString, IonInterface::WindDirections> DWDIon::setupWindIconMappings() const
+@@ -119,6 +136,12 @@ QMap<QString, IonInterface::ConditionIcons> const &DWDIon::dayIcons() const
+ return dval;
+ }
+
++QMap<QString, IonInterface::ConditionIcons> const &DWDIon::nightIcons() const
++{
++ static QMap<QString, ConditionIcons> const dval = setupNightIconMappings();
++ return dval;
++}
++
+ QMap<QString, IonInterface::WindDirections> const &DWDIon::windIcons() const
+ {
+ static QMap<QString, WindDirections> const wval = setupWindIconMappings();
+@@ -448,6 +471,10 @@ void DWDIon::parseForecastData(const QString source, QJsonDocument doc)
+ weatherData.gustSpeedAlt = parseNumber(dayMap[QStringLiteral("windGust")]);
+ QString windDirection = roundWindDirections(dayMap[QStringLiteral("windDirection")].toInt());
+ weatherData.windDirectionAlt = getWindDirectionIcon(windIcons(), windDirection);
++
++ // Also fetch today's sunrise and sunset times to determine whether to pick day or night icons
++ weatherData.sunriseTime = parseDateFromMSecs(dayMap[QStringLiteral("sunrise")].toLongLong());
++ weatherData.sunsetTime = parseDateFromMSecs(dayMap[QStringLiteral("sunset")].toLongLong());
+ }
+
+ forecasts.append(forecast);
+@@ -500,10 +527,7 @@ void DWDIon::parseMeasureData(const QString source, QJsonDocument doc)
+ if (!weatherMap.isEmpty()) {
+ weatherData.observationDateTime = parseDateFromMSecs(weatherMap[QStringLiteral("time")]);
+
+- QString condIconNumber = weatherMap[QStringLiteral("icon")].toString();
+- if (condIconNumber != QLatin1String("")) {
+- weatherData.conditionIcon = getWeatherIcon(dayIcons(), condIconNumber);
+- }
++ weatherData.condIconNumber = weatherMap[QStringLiteral("icon")].toString();
+
+ bool windIconValid = false;
+ const int windDirection = weatherMap[QStringLiteral("winddirection")].toInt(&windIconValid);
+@@ -573,8 +597,8 @@ void DWDIon::updateWeather(const QString &source)
+ else
+ data.insert(QStringLiteral("Observation Timestamp"), QDateTime::currentDateTime());
+
+- if (!weatherData.conditionIcon.isEmpty())
+- data.insert(QStringLiteral("Condition Icon"), weatherData.conditionIcon);
++ if (!weatherData.condIconNumber.isEmpty())
++ data.insert(QStringLiteral("Condition Icon"), getWeatherIcon(isNightTime(weatherData) ? nightIcons() : dayIcons(), weatherData.condIconNumber));
+
+ if (!qIsNaN(weatherData.temperature))
+ data.insert(QStringLiteral("Temperature"), weatherData.temperature);
+@@ -717,6 +741,16 @@ QString DWDIon::camelCaseString(const QString text)
+ return result;
+ }
+
++bool DWDIon::isNightTime(const WeatherData &weatherData)
++{
++ if (weatherData.sunriseTime.isNull() || weatherData.sunsetTime.isNull()) {
++ // default to daytime icons if we're missing sunrise/sunset times
++ return false;
++ }
++
++ return weatherData.observationDateTime < weatherData.sunriseTime || weatherData.observationDateTime > weatherData.sunsetTime;
++}
++
+ K_PLUGIN_CLASS_WITH_JSON(DWDIon, "ion-dwd.json")
+
+ #include "ion_dwd.moc"
+diff --git a/dataengines/weather/ions/dwd/ion_dwd.h b/dataengines/weather/ions/dwd/ion_dwd.h
+index 38b9ce3cac..c1ed8651b6 100644
+--- a/dataengines/weather/ions/dwd/ion_dwd.h
++++ b/dataengines/weather/ions/dwd/ion_dwd.h
+@@ -40,8 +40,10 @@ public:
+
+ // Current observation information.
+ QDateTime observationDateTime;
++ QDateTime sunriseTime;
++ QDateTime sunsetTime;
+
+- QString conditionIcon;
++ QString condIconNumber;
+ QString windDirection;
+ float temperature;
+ float humidity;
+@@ -110,10 +112,13 @@ private Q_SLOTS:
+ void forecast_slotJobFinished(KJob *);
+
+ private:
++ QMap<QString, ConditionIcons> getUniversalIcons() const;
+ QMap<QString, ConditionIcons> setupDayIconMappings() const;
++ QMap<QString, ConditionIcons> setupNightIconMappings() const;
+ QMap<QString, WindDirections> setupWindIconMappings() const;
+
+ QMap<QString, ConditionIcons> const &dayIcons() const;
++ QMap<QString, ConditionIcons> const &nightIcons() const;
+ QMap<QString, WindDirections> const &windIcons() const;
+
+ void findPlace(const QString &searchText);
+@@ -134,6 +139,7 @@ private:
+ QString camelCaseString(const QString text);
+ QString extractString(QByteArray array, int start, int length);
+ QString roundWindDirections(int windDirection);
++ bool isNightTime(const WeatherData &weatherData);
+ float parseNumber(QVariant number);
+ QDateTime parseDateFromMSecs(QVariant timestamp);
+
+--
+2.47.0
+
diff --git a/desktop-plasma/sets/plasma-desktop b/desktop-plasma/sets/desktop-plasma
index 1db303f..a6ceef1 100644
--- a/desktop-plasma/sets/plasma-desktop
+++ b/desktop-plasma/sets/desktop-plasma
@@ -1,10 +1,10 @@
app-editors/okteta
kde-apps/ark
kde-apps/dolphin
-kde-apps/ffmpegthumbs
kde-apps/gwenview
kde-apps/krdc
kde-apps/kwalletmanager
kde-apps/okular
kde-apps/spectacle
kde-plasma/plasma-meta
+sci-calculators/qalculate-qt
diff --git a/desktop-sway/package.use/09-desktop-sway b/desktop-sway/package.use/09-desktop-sway
index fe45b5d..b43fab2 100644
--- a/desktop-sway/package.use/09-desktop-sway
+++ b/desktop-sway/package.use/09-desktop-sway
@@ -1,5 +1,9 @@
app-crypt/pinentry gtk
gui-wm/sway -swaybar
+media-gfx/imv -freeimage
+net-misc/remmina rdp vnc -appindicator
+xfce-base/thunar -trash-panel-plugin
+xfce-base/tumbler ffmpeg pdf
# needed for app-crypt/pinentry
app-crypt/gcr gtk
diff --git a/desktop-sway/sets/sway-desktop b/desktop-sway/sets/desktop-sway
index 9f65912..9f65912 100644
--- a/desktop-sway/sets/sway-desktop
+++ b/desktop-sway/sets/desktop-sway
diff --git a/group-base/env/ccache b/group-base/env/ccache
new file mode 100644
index 0000000..cedb851
--- /dev/null
+++ b/group-base/env/ccache
@@ -0,0 +1,2 @@
+FEATURES="ccache"
+CCACHE_DIR="/var/cache/ccache"
diff --git a/group-base/package.accept_keywords/00-group-base b/group-base/package.accept_keywords/00-group-base
index f40185f..452435b 100644
--- a/group-base/package.accept_keywords/00-group-base
+++ b/group-base/package.accept_keywords/00-group-base
@@ -6,3 +6,8 @@ mail-client/neomutt
media-video/mpv
net-misc/yt-dlp
sys-apps/sd
+www-apps/sblg
+www-apps/zola
+
+# needed for our own software
+sec-keys/signify-keys-oriole-systems
diff --git a/group-base/package.use/00-group-base b/group-base/package.use/00-group-base
index d4c2305..b606957 100644
--- a/group-base/package.use/00-group-base
+++ b/group-base/package.use/00-group-base
@@ -1,20 +1,12 @@
-*/* acl
-*/* threads
-*/* iproute2
-*/* fish-completion
*/* caps
+*/* fish-completion
*/* icu
*/* LUA_TARGETS: -lua5-1 lua5-4
*/* -alsa
*/* -bindist
-*/* -bluetooth
*/* -branding
-*/* -cups
-*/* -dbus
-*/* -ldap
-*/* -spell
app-arch/p7zip rar
app-crypt/gnupg -smartcard
@@ -34,5 +26,6 @@ sys-apps/iproute2 -iptables
sys-auth/pambase -nullok -passwdqc
sys-kernel/linux-firmware savedconfig
+# needed in hardened profiles
dev-libs/libpcre jit
dev-libs/libpcre2 jit
diff --git a/group-base/sets/base b/group-base/sets/base
new file mode 100644
index 0000000..edc15a4
--- /dev/null
+++ b/group-base/sets/base
@@ -0,0 +1,20 @@
+app-admin/kern
+app-admin/sudo
+app-editors/neovim
+app-misc/ranger
+app-portage/bosun
+app-portage/eix
+app-portage/gentoolkit
+app-portage/portage-utils
+app-shells/fish
+app-shells/fzf
+app-shells/loksh
+app-text/mandoc
+dev-vcs/git
+net-firewall/nftables
+net-vpn/wireguard-tools
+sys-apps/fd
+sys-apps/ripgrep
+sys-kernel/gentoo-sources
+sys-kernel/installkernel
+sys-process/htop
diff --git a/group-base/sets/base-ebuild b/group-base/sets/base-ebuild
new file mode 100644
index 0000000..5ef372c
--- /dev/null
+++ b/group-base/sets/base-ebuild
@@ -0,0 +1,3 @@
+app-doc/eclass-manpages
+dev-util/pkgcheck
+dev-util/pkgdev
diff --git a/group-desktop/package.accept_keywords/01-group-desktop b/group-desktop/package.accept_keywords/01-group-desktop
index 5723355..569b470 100644
--- a/group-desktop/package.accept_keywords/01-group-desktop
+++ b/group-desktop/package.accept_keywords/01-group-desktop
@@ -7,12 +7,6 @@ media-sound/whipper
media-video/obs-studio
mpv-plugin/mpv-mpris
net-misc/gallery-dl
-xfce-base/thunar
# needed for media-sound/whipper
dev-python/pycdio
-
-# needed for xfce-base/thunar
-xfce-base/exo
-xfce-base/libxfce4ui
-xfce-base/libxfce4util
diff --git a/group-desktop/package.use/01-group-desktop b/group-desktop/package.use/01-group-desktop
index 7f1338e..1854d9e 100644
--- a/group-desktop/package.use/01-group-desktop
+++ b/group-desktop/package.use/01-group-desktop
@@ -1,7 +1,12 @@
+*/* cairo
+*/* dbus
+*/* dbus-broker
+*/* dri
*/* egl
*/* eglfs
*/* exif
*/* gif
+*/* heif
*/* jpeg
*/* ogg
*/* opengl
@@ -14,28 +19,24 @@
*/* vaapi
*/* vulkan
*/* wayland
-*/* dbus
-*/* dbus-broker
+*/* x264
+*/* x265
*/* -X
*/* -gnome
media-fonts/iosevka iosevka-aile iosevka-etoile
-media-gfx/imv heif -freeimage
media-sound/pulseaudio -daemon
media-video/mpv cli luajit -xv
media-video/pipewire sound-server pipewire-alsa
net-analyzer/wireshark adns http2 smi sshdump tfshark
-net-misc/remmina rdp vnc -appindicator
+net-irc/quassel -crypt -server bundled-icons gui
-xfce-base/thunar -trash-panel-plugin
-xfce-base/tumbler ffmpeg pdf
+# freerdp needs X for keyboard input, even on wayland
+net-misc/freerdp X
# needed for x11-misc/xdg-utils
app-text/xmlto text
-# needed for PDF support in xfce-extra/tumbler
-app-text/poppler cairo
-
# needed for x11-terms/weltschmerz
x11-libs/vte vala vanilla
@@ -52,10 +53,7 @@ media-libs/freetype harfbuzz
# needed for sys-auth/AusweisApp2
dev-qt/qtwebsockets qml
-# needed for media-gfx/gimp
-media-libs/gegl cairo
-
-x11-libs/gtk+ X
+x11-libs/gtk+ cups X
# needed for x11-libs/gtk+[X]
media-libs/libepoxy X
diff --git a/group-desktop/sets/cdrip b/group-desktop/sets/desktop-cdrip
index 2651ee2..2651ee2 100644
--- a/group-desktop/sets/cdrip
+++ b/group-desktop/sets/desktop-cdrip
diff --git a/group-desktop/sets/fonts b/group-desktop/sets/desktop-fonts
index 12fd04d..12fd04d 100644
--- a/group-desktop/sets/fonts
+++ b/group-desktop/sets/desktop-fonts
diff --git a/group-desktop/sets/music b/group-desktop/sets/desktop-music
index 69546ed..69546ed 100644
--- a/group-desktop/sets/music
+++ b/group-desktop/sets/desktop-music
diff --git a/group-desktop/sets/thunar b/group-desktop/sets/desktop-thunar
index f9d4178..f9d4178 100644
--- a/group-desktop/sets/thunar
+++ b/group-desktop/sets/desktop-thunar
diff --git a/host-coleridge/make.conf b/host-coleridge/make.conf
index fa719c0..0cb2d94 100644
--- a/host-coleridge/make.conf
+++ b/host-coleridge/make.conf
@@ -18,5 +18,3 @@ FEATURES="clean-logs compress-build-logs downgrade-backup parallel-install split
EMERGE_DEFAULT_OPTS="--color=n --ask --alert --autounmask-write=n --jobs 3 --load-average 4"
INSTALL_MASK="/usr/share/bash-completion /usr/lib/charset.alias"
-
-GENTOO_MIRRORS="http://mirror.manitu.net/gentoo/"
diff --git a/host-coleridge/package.use/90-host-coleridge b/host-coleridge/package.use/90-host-coleridge
index 9871c95..3ffc790 100644
--- a/host-coleridge/package.use/90-host-coleridge
+++ b/host-coleridge/package.use/90-host-coleridge
@@ -1,6 +1,4 @@
media-sound/mpd -* eventfd ffmpeg fifo icu ipv6 unicode
net-misc/netifrc -dhcp
-sys-fs/mdadm static
-
dev-lang/go system-bootstrap
diff --git a/kernel-6.8/package.accept_keywords/70-kernel-6.8 b/kernel-6.8/package.accept_keywords/70-kernel-6.8
deleted file mode 100644
index 0460a1b..0000000
--- a/kernel-6.8/package.accept_keywords/70-kernel-6.8
+++ /dev/null
@@ -1 +0,0 @@
-=sys-kernel/gentoo-sources-6.8*
diff --git a/kernel-6.8/package.mask/70-kernel-6.8 b/kernel-6.8/package.mask/70-kernel-6.8
deleted file mode 100644
index 708c669..0000000
--- a/kernel-6.8/package.mask/70-kernel-6.8
+++ /dev/null
@@ -1,2 +0,0 @@
->=sys-kernel/gentoo-sources-6.9
-<sys-kernel/gentoo-sources-6.8
diff --git a/lang-base/sets/devel b/lang-base/sets/lang-base
index a871dd0..a7cb658 100644
--- a/lang-base/sets/devel
+++ b/lang-base/sets/lang-base
@@ -2,3 +2,4 @@ dev-debug/gdb
dev-debug/strace
dev-debug/valgrind
dev-util/debugedit
+sys-apps/man-pages-posix
diff --git a/lang-cpp/package.use/10-lang-cpp b/lang-cpp/package.use/10-lang-cpp
new file mode 100644
index 0000000..0962638
--- /dev/null
+++ b/lang-cpp/package.use/10-lang-cpp
@@ -0,0 +1 @@
+sys-devel/clang extra static-analyzer
diff --git a/lang-cpp/sets/lang-cpp b/lang-cpp/sets/lang-cpp
new file mode 100644
index 0000000..fdca443
--- /dev/null
+++ b/lang-cpp/sets/lang-cpp
@@ -0,0 +1 @@
+sys-devel/clang
diff --git a/lang-python/package.accept_keywords/10-lang-python b/lang-python/package.accept_keywords/10-lang-python
index c68fa5b..7d47be6 100644
--- a/lang-python/package.accept_keywords/10-lang-python
+++ b/lang-python/package.accept_keywords/10-lang-python
@@ -1 +1,3 @@
+dev-python/poetry
+dev-python/poetry-plugin-export
dev-util/ruff
diff --git a/lang-python/sets/python-devel b/lang-python/sets/lang-python
index d96c0c6..3c16f61 100644
--- a/lang-python/sets/python-devel
+++ b/lang-python/sets/lang-python
@@ -1,3 +1,3 @@
-dev-python/black
dev-python/pip
+dev-python/poetry
dev-util/ruff
diff --git a/service-cups/package.use/20-service-cups b/service-cups/package.use/20-service-cups
deleted file mode 100644
index f166106..0000000
--- a/service-cups/package.use/20-service-cups
+++ /dev/null
@@ -1,5 +0,0 @@
-net-print/cups -X
-x11-libs/gtk+ cups
-
-# needed for net-print/cups
-app-text/ghostscript-gpl cups
diff --git a/service-prosody/package.use/20-service-prosody b/service-prosody/package.use/20-service-prosody
index d1c49f1..272ca6a 100644
--- a/service-prosody/package.use/20-service-prosody
+++ b/service-prosody/package.use/20-service-prosody
@@ -1,4 +1,4 @@
-net-im/prosody -idn -sqlite postgres
+net-im/prosody -idn -sqlite postgres LUA_SINGLE_TARGET: -* lua5-4
# needed for prosody[postgres]
dev-lua/luadbi -sqlite postgres
diff --git a/service-qbittorrent/package.use/20-service-qbittorrent b/service-qbittorrent/package.use/20-service-qbittorrent
new file mode 100644
index 0000000..4a485a5
--- /dev/null
+++ b/service-qbittorrent/package.use/20-service-qbittorrent
@@ -0,0 +1 @@
+net-p2p/qbittorrent -dbus -gui webui
diff --git a/service-quasselcore/package.accept_keywords/20-service-quasselcore b/service-quasselcore/package.accept_keywords/20-service-quasselcore
index 335cb21..6d40e2b 100644
--- a/service-quasselcore/package.accept_keywords/20-service-quasselcore
+++ b/service-quasselcore/package.accept_keywords/20-service-quasselcore
@@ -1 +1,2 @@
+net-irc/quarg
net-irc/quassel
diff --git a/service-quasselcore/package.use/20-service-quasselcore b/service-quasselcore/package.use/20-service-quasselcore
index 849dd17..64a815e 100644
--- a/service-quasselcore/package.use/20-service-quasselcore
+++ b/service-quasselcore/package.use/20-service-quasselcore
@@ -1,4 +1,4 @@
-net-irc/quassel postgres server syslog
+net-irc/quassel -crypt -dbus postgres server syslog
net-irc/quarg postgres
dev-qt/qtsql postgres