diff -Nru ukui-sni-4.10.0.5/debian/changelog ukui-sni-4.10.0.5/debian/changelog
--- ukui-sni-4.10.0.5/debian/changelog	2024-11-19 14:01:03.000000000 +0800
+++ ukui-sni-4.10.0.5/debian/changelog	2024-12-27 16:02:15.000000000 +0800
@@ -1,3 +1,16 @@
+ukui-sni (4.10.0.5-ok1.2) nile; urgency=medium
+
+  * Issues: 无
+  * 其他改动:
+    - 为后台进程增加日志打印机制
+    - xembed部分同步上游提交
+    - 修改折叠区弹窗收起tooltip仍然显示的bug
+    - 修改添加版本号异常的bug
+  * 其他改动影响域:
+    - 任务栏,托盘
+
+ -- youdiansaodongxi <guojiaqi@kylinos.cn>  Fri, 27 Dec 2024 16:02:15 +0800
+
 ukui-sni (4.10.0.5-ok1.1) nile; urgency=medium
 
   * Issues: 无
diff -Nru ukui-sni-4.10.0.5/debian/patches/0003-update-changelog-for-4.10.0.5-ok1.2.patch ukui-sni-4.10.0.5/debian/patches/0003-update-changelog-for-4.10.0.5-ok1.2.patch
--- ukui-sni-4.10.0.5/debian/patches/0003-update-changelog-for-4.10.0.5-ok1.2.patch	1970-01-01 08:00:00.000000000 +0800
+++ ukui-sni-4.10.0.5/debian/patches/0003-update-changelog-for-4.10.0.5-ok1.2.patch	2024-12-27 16:02:15.000000000 +0800
@@ -0,0 +1,743 @@
+From: youdiansaodongxi <guojiaqi@kylinos.cn>
+Date: Fri, 27 Dec 2024 16:09:17 +0800
+Subject: update changelog for: 4.10.0.5-ok1.2
+
+---
+ CMakeLists.txt                               |   2 +-
+ log-utils.cpp                                | 138 +++++++++++++++++++++++++++
+ log-utils.h                                  |  41 ++++++++
+ status-notifier-watcher/CMakeLists.txt       |   2 +
+ status-notifier-watcher/main.cpp             |   3 +
+ ukui-system-tray/plugin/tray-items-model.cpp |   2 +-
+ ukui-system-tray/widget/ui/FoldArea.qml      |   4 +-
+ ukui-system-tray/widget/ui/TrayView.qml      |   1 +
+ xembed-sni-proxy/CMakeLists.txt              |   8 +-
+ xembed-sni-proxy/c_ptr.h                     |  22 +++++
+ xembed-sni-proxy/fdo-selection-manager.cpp   |  16 +---
+ xembed-sni-proxy/main.cpp                    |   3 +
+ xembed-sni-proxy/sni-proxy.cpp               | 121 +++++++++++++++--------
+ xembed-sni-proxy/sni-proxy.h                 |   3 +-
+ xembed-sni-proxy/xcb-utils.h                 |   5 +-
+ 15 files changed, 308 insertions(+), 63 deletions(-)
+ create mode 100644 log-utils.cpp
+ create mode 100644 log-utils.h
+ create mode 100644 xembed-sni-proxy/c_ptr.h
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 2bddbb5..6a3a25f 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -16,8 +16,8 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core DBus Network Gui Widgets Quic
+ 
+ add_subdirectory(status-notifier-watcher)
+ add_subdirectory(status-notifier-host)
+-add_subdirectory(xembed-sni-proxy)
+ add_subdirectory(ukui-system-tray)
++add_subdirectory(xembed-sni-proxy)
+ if(BUILD_TEST)
+     add_subdirectory(test)
+ endif()
+diff --git a/log-utils.cpp b/log-utils.cpp
+new file mode 100644
+index 0000000..6d612e1
+--- /dev/null
++++ b/log-utils.cpp
+@@ -0,0 +1,138 @@
++/*
++ * Copyright (C) 2024, KylinSoft Co., Ltd.
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
++ *
++ * Authors: iaom <zhangpengfei@kylinos.cn>
++ *
++ */
++
++#include "log-utils.h"
++#include <QFile>
++#include <QDebug>
++#include <QDir>
++#include <QDateTime>
++#include <QStandardPaths>
++
++#define LOG_FILE_COUNT         2
++#define MAX_LOG_FILE_SIZE      4194304
++#define MAX_LOG_CHECK_INTERVAL 43200000
++
++quint64 LogUtils::m_startUpTime = 0;
++int LogUtils::m_logFileId = -1;
++QString LogUtils::m_logFileName;
++QString LogUtils::m_currentLogFile;
++static QString logFilePath = QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.log/ukui-sni/";
++
++void LogUtils::messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
++{
++    checkLogFile();
++
++    QByteArray localMsg = msg.toLocal8Bit();
++    QByteArray currentTime = QTime::currentTime().toString().toLocal8Bit();
++    const char *file = context.file ? context.file : "";
++    const char *function = context.function ? context.function : "";
++
++    FILE *log_file = fopen(m_currentLogFile.toLocal8Bit().constData(), "a+");
++
++    switch (type) {
++    case QtDebugMsg:
++        if (!log_file) {
++            break;
++        }
++        fprintf(log_file, "Debug: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
++        break;
++    case QtInfoMsg:
++        fprintf(log_file? log_file: stdout, "Info: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
++        break;
++    case QtWarningMsg:
++        fprintf(log_file? log_file: stderr, "Warning: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
++        break;
++    case QtCriticalMsg:
++        fprintf(log_file? log_file: stderr, "Critical: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
++        break;
++    case QtFatalMsg:
++        fprintf(log_file? log_file: stderr, "Fatal: %s: %s (%s:%u, %s)\n", currentTime.constData(), localMsg.constData(), file, context.line, function);
++        break;
++    }
++
++    if (log_file) {
++        fclose(log_file);
++    }
++}
++
++void LogUtils::initLogFile(const QString &fileName)
++{
++    QDir dir;
++    if (!dir.exists(logFilePath)) {
++        if (!dir.mkpath(logFilePath)) {
++            qWarning() << "Unable to create" << logFilePath;
++            return;
++        }
++    }
++    m_logFileName = logFilePath + fileName + "-%1.log";
++
++    for (int i = 0; i < LOG_FILE_COUNT; ++i) {
++        m_currentLogFile = m_logFileName.arg(i);
++        if (QFile::exists(m_currentLogFile)) {
++            if (checkFileSize(m_currentLogFile)) {
++                m_logFileId = i;
++                break;
++            }
++        } else {
++            QFile file(m_currentLogFile);
++            file.open(QIODevice::WriteOnly);
++            file.close();
++        }
++    }
++
++
++    if (m_logFileId < 0) {
++        m_logFileId = 0;
++        m_currentLogFile = m_logFileName.arg(m_logFileId);
++        clearFile(m_currentLogFile);
++    }
++
++    qInfo() << "Current log file:" << m_currentLogFile;
++}
++
++void LogUtils::checkLogFile()
++{
++    quint64 logTime = QDateTime::currentDateTime().toMSecsSinceEpoch();
++    quint64 spacing = std::max(logTime, m_startUpTime) - std::min(logTime, m_startUpTime);
++
++    if (spacing <= MAX_LOG_CHECK_INTERVAL || checkFileSize(m_currentLogFile)) {
++        return;
++    }
++
++    m_logFileId = ((m_logFileId + 1) % LOG_FILE_COUNT);
++    m_currentLogFile = m_logFileName.arg(m_logFileId);
++    if (!checkFileSize(m_currentLogFile)) {
++        clearFile(m_currentLogFile);
++    }
++}
++
++bool LogUtils::checkFileSize(const QString &fileName)
++{
++    return QFile(fileName).size() < MAX_LOG_FILE_SIZE;
++}
++
++void LogUtils::clearFile(const QString &fileName)
++{
++    QFile file(fileName);
++    file.open(QIODevice::WriteOnly);
++    file.write("");
++    file.flush();
++    file.close();
++}
+diff --git a/log-utils.h b/log-utils.h
+new file mode 100644
+index 0000000..dccf1d0
+--- /dev/null
++++ b/log-utils.h
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (C) 2024, KylinSoft Co., Ltd.
++ *
++ * This program is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program.  If not, see <https://www.gnu.org/licenses/>.
++ *
++ * Authors: iaom <zhangpengfei@kylinos.cn>
++ *
++ */
++
++#ifndef LOGUTILS_H
++#define LOGUTILS_H
++#include <QtMessageHandler>
++
++class LogUtils
++{
++public:
++    static void initLogFile(const QString &fileName);
++    static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
++
++private:
++    static void checkLogFile();
++    static bool checkFileSize(const QString &fileName);
++    static void clearFile(const QString &fileName);
++    static quint64 m_startUpTime;
++    static int m_logFileId;
++    static QString m_logFileName;
++    static QString m_currentLogFile;
++};
++
++#endif // LOGUTILS_H
+diff --git a/status-notifier-watcher/CMakeLists.txt b/status-notifier-watcher/CMakeLists.txt
+index 80600ca..b7f3206 100644
+--- a/status-notifier-watcher/CMakeLists.txt
++++ b/status-notifier-watcher/CMakeLists.txt
+@@ -6,6 +6,7 @@ set(UKUI_SNI_WATCHER_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_MICRO})
+ set(3rdParties_DIR  ../3rd-parties/qtsingleapplication/src/)
+ configure_file (ukui-sni-watcher-config.h.in ukui-sni-watcher-config.h @ONLY)
+ include_directories(../common)
++include_directories(../)
+ set(ukuiSNIWatcher_SRCS
+         ${3rdParties_DIR}qtsinglecoreapplication.h
+         ${3rdParties_DIR}qtsinglecoreapplication.cpp
+@@ -16,6 +17,7 @@ set(ukuiSNIWatcher_SRCS
+         watcher-private.h
+         status-notifier-watcher-application.cpp
+         status-notifier-watcher-application.h
++        ../log-utils.cpp ../log-utils.h
+         main.cpp)
+ set_source_files_properties(../dbus/org.kde.StatusNotifierWatcher.xml PROPERTIES
+         NO_NAMESPACE false
+diff --git a/status-notifier-watcher/main.cpp b/status-notifier-watcher/main.cpp
+index e355cf3..e2e10f6 100644
+--- a/status-notifier-watcher/main.cpp
++++ b/status-notifier-watcher/main.cpp
+@@ -17,8 +17,11 @@
+  * Authors: iaom <zhangpengfei@kylinos.cn>
+  */
+ #include "status-notifier-watcher-application.h"
++#include "log-utils.h"
+ int main(int argc, char *argv[])
+ {
++    LogUtils::initLogFile("ukui-sni-watcher");
++    qInstallMessageHandler(LogUtils::messageOutput);
+     StatusNotifierWatcherApplication app(argc, argv);
+     if(app.isRunning()) {
+         return 0;
+diff --git a/ukui-system-tray/plugin/tray-items-model.cpp b/ukui-system-tray/plugin/tray-items-model.cpp
+index 4acc2fa..11e1dec 100644
+--- a/ukui-system-tray/plugin/tray-items-model.cpp
++++ b/ukui-system-tray/plugin/tray-items-model.cpp
+@@ -51,7 +51,7 @@ TrayItemsModel::TrayItemsModel(QObject *parent) : QAbstractListModel(parent)
+     }
+     //showed items
+     if (!data.contains(QStringLiteral("version"))) {
+-        m_config->setValue(QStringLiteral("orderedItems"), QStringLiteral("1.0"));
++        m_config->setValue(QStringLiteral("version"), QStringLiteral("1.0"));
+         m_orderList = DEFAULT_ORDERED_ITEMS;
+         m_config->setValue(QStringLiteral("orderedItems"), DEFAULT_ORDERED_ITEMS);
+     } else {
+diff --git a/ukui-system-tray/widget/ui/FoldArea.qml b/ukui-system-tray/widget/ui/FoldArea.qml
+index 654a9dd..f296f74 100644
+--- a/ukui-system-tray/widget/ui/FoldArea.qml
++++ b/ukui-system-tray/widget/ui/FoldArea.qml
+@@ -9,6 +9,7 @@ import org.ukui.quick.platform 1.0 as Platform
+ DropArea {
+     property bool isEmpty: foldModel.count > 0 ? false : true
+     property int sourceIndex
++    property bool foldWindowVisible: false
+     signal foldAreaDragFinshed(int selectIndex)
+     width: foldModel.count > 5 ? foldView.cellWidth * 5 + 8 : foldModel.count * foldView.cellWidth + 8
+     height: (foldModel.count % 5) === 0 ?
+@@ -106,8 +107,9 @@ DropArea {
+                             UkuiItems.Tooltip {
+                                 id: tooltip
+                                 anchors.fill: parent
+-                                mainText: model.ToolTipTitle.length == 0 ? model.Title : model.ToolTipTitle
++                                mainText: model.ToolTipTitle.length === 0 ? model.Title : model.ToolTipTitle
+                                 posFollowCursor: false
++                                active: foldWindowVisible
+                                 location: {
+                                     switch (dropArea.panelPos) {
+                                         case UkuiItems.Types.Bottom:
+diff --git a/ukui-system-tray/widget/ui/TrayView.qml b/ukui-system-tray/widget/ui/TrayView.qml
+index 1d9d64f..af6f285 100644
+--- a/ukui-system-tray/widget/ui/TrayView.qml
++++ b/ukui-system-tray/widget/ui/TrayView.qml
+@@ -184,6 +184,7 @@ DropArea {
+ 
+                     FoldArea {
+                         id: foldBase
++                        foldWindowVisible: foldWindow.visible
+                         onFoldAreaDragFinshed: fromIndex => {
+                                                    if (dropArea.inserted) {
+                                                        if (dropArea.dragType === 1) {
+diff --git a/xembed-sni-proxy/CMakeLists.txt b/xembed-sni-proxy/CMakeLists.txt
+index 5bb9bed..ea47dc9 100644
+--- a/xembed-sni-proxy/CMakeLists.txt
++++ b/xembed-sni-proxy/CMakeLists.txt
+@@ -1,6 +1,4 @@
+-add_definitions(-DQT_NO_CAST_TO_ASCII
+--DQT_NO_CAST_FROM_ASCII
+--DQT_NO_CAST_FROM_BYTEARRAY)
++set(CMAKE_CXX_STANDARD 20)
+ include(../cmake/find-modules/FindXCB.cmake)
+ set(XCB_LIBS
+         xcb
+@@ -13,6 +11,7 @@ set(XCB_LIBS
+ find_package(KF5WindowSystem)
+ 
+ include_directories(../common)
++include_directories(../)
+ set(XEMBED_SNI_PROXY_SOURCES
+         main.cpp
+         fdo-selection-manager.cpp
+@@ -25,6 +24,9 @@ set(XEMBED_SNI_PROXY_SOURCES
+         ../common/dbus-types.cpp
+         ../common/dbus-types.h
+         ../common/typedefs.h
++        c_ptr.h
++        ../log-utils.cpp
++        ../log-utils.h
+         )
+ 
+ qt_add_dbus_adaptor(XEMBED_SNI_PROXY_SOURCES ../dbus/org.kde.StatusNotifierItem.xml sni-proxy.h SNIProxy)
+diff --git a/xembed-sni-proxy/c_ptr.h b/xembed-sni-proxy/c_ptr.h
+new file mode 100644
+index 0000000..20bc6dd
+--- /dev/null
++++ b/xembed-sni-proxy/c_ptr.h
+@@ -0,0 +1,22 @@
++/*
++    SPDX-FileCopyrightText: 2022 Xaver Hugl <xaver.hugl@gmail.com>
++    SPDX-FileCopyrightText: 2024 iaom <zhangpengfei@kylinos.cn>
++
++    SPDX-License-Identifier: LGPL-2.1-or-later
++*/
++#pragma once
++#include <memory>
++
++struct CDeleter {
++    template<typename T>
++    void operator()(T *ptr)
++    {
++        if (ptr) {
++            free(ptr);
++        }
++    }
++};
++
++template<typename T>
++using UniqueCPointer = std::unique_ptr<T, CDeleter>;
++
+diff --git a/xembed-sni-proxy/fdo-selection-manager.cpp b/xembed-sni-proxy/fdo-selection-manager.cpp
+index c616a0d..de99e3b 100644
+--- a/xembed-sni-proxy/fdo-selection-manager.cpp
++++ b/xembed-sni-proxy/fdo-selection-manager.cpp
+@@ -19,6 +19,7 @@
+ 
+ #include "sni-proxy.h"
+ #include "xcb-utils.h"
++#include "c_ptr.h"
+ 
+ #define SYSTEM_TRAY_REQUEST_DOCK 0
+ #define SYSTEM_TRAY_BEGIN_MESSAGE 1
+@@ -75,8 +76,8 @@ bool FdoSelectionManager::addDamageWatch(xcb_window_t client)
+     xcb_damage_create(c, damageId, client, XCB_DAMAGE_REPORT_LEVEL_NON_EMPTY);
+ 
+     xcb_generic_error_t *error = nullptr;
+-    QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> attr(xcb_get_window_attributes_reply(c, attribsCookie, &error));
+-    QScopedPointer<xcb_generic_error_t, QScopedPointerPodDeleter> getAttrError(error);
++    UniqueCPointer<xcb_get_window_attributes_reply_t> attr(xcb_get_window_attributes_reply(c, attribsCookie, &error));
++    UniqueCPointer<xcb_generic_error_t> getAttrError(error);
+     uint32_t events = XCB_EVENT_MASK_STRUCTURE_NOTIFY;
+     if (attr) {
+         events = events | attr->your_event_mask;
+@@ -88,7 +89,7 @@ bool FdoSelectionManager::addDamageWatch(xcb_window_t client)
+     // the event mask will not be removed again. We cannot track whether another component also needs STRUCTURE_NOTIFY (e.g. KWindowSystem).
+     // if we would remove the event mask again, other areas will break.
+     const auto changeAttrCookie = xcb_change_window_attributes_checked(c, client, XCB_CW_EVENT_MASK, &events);
+-    QScopedPointer<xcb_generic_error_t, QScopedPointerPodDeleter> changeAttrError(xcb_request_check(c, changeAttrCookie));
++    UniqueCPointer<xcb_generic_error_t> changeAttrError(xcb_request_check(c, changeAttrCookie));
+     // if window is gone by this point, it will be caught by eventFilter, so no need to check later errors.
+     if (changeAttrError && changeAttrError->error_code == XCB_WINDOW) {
+         return false;
+@@ -146,15 +147,6 @@ bool FdoSelectionManager::nativeEventFilter(const QByteArray &eventType, void *m
+                 sniProxy->resizeWindow(event->width, event->height);
+             }
+         }
+-    } else if (responseType == XCB_VISIBILITY_NOTIFY) {
+-        const auto event = reinterpret_cast<xcb_visibility_notify_event_t *>(ev);
+-        // it's possible that something showed our container window, we have to hide it
+-        // workaround for BUG 357443: when KWin is restarted, container window is shown on top
+-        if (event->state == XCB_VISIBILITY_UNOBSCURED) {
+-            for (auto sniProxy : m_proxies.values()) {
+-                sniProxy->hideContainerWindow(event->window);
+-            }
+-        }
+     }
+ 
+     return false;
+diff --git a/xembed-sni-proxy/main.cpp b/xembed-sni-proxy/main.cpp
+index 132dd3e..47d50ae 100644
+--- a/xembed-sni-proxy/main.cpp
++++ b/xembed-sni-proxy/main.cpp
+@@ -16,6 +16,7 @@
+ #include <QDBusMetaType>
+ 
+ #include <KWindowSystem>
++#include <log-utils.h>
+ 
+ namespace Xcb
+ {
+@@ -24,6 +25,8 @@ Xcb::Atoms *atoms;
+ 
+ int main(int argc, char **argv)
+ {
++    LogUtils::initLogFile("xembed-sni-proxy");
++    qInstallMessageHandler(LogUtils::messageOutput);
+     // the whole point of this is to interact with X, if we are in any other session, force trying to connect to X
+     // if the QPA can't load xcb, this app is useless anyway.
+     qputenv("QT_QPA_PLATFORM", "xcb");
+diff --git a/xembed-sni-proxy/sni-proxy.cpp b/xembed-sni-proxy/sni-proxy.cpp
+index 7ca1704..250f04a 100644
+--- a/xembed-sni-proxy/sni-proxy.cpp
++++ b/xembed-sni-proxy/sni-proxy.cpp
+@@ -10,6 +10,7 @@
+ #include "sni-proxy.h"
+ 
+ #include <algorithm>
++#include <span>
+ #include <xcb/xcb_atom.h>
+ #include <xcb/xcb_event.h>
+ 
+@@ -29,6 +30,7 @@
+ #include "statusnotifierwatcher_interface.h"
+ 
+ #include "xtest-sender.h"
++#include "c_ptr.h"
+ 
+ // #define VISUAL_DEBUG
+ 
+@@ -56,6 +58,26 @@ void xembed_message_send(xcb_window_t towin, long message, long d1, long d2, lon
+     xcb_send_event(QX11Info::connection(), false, towin, XCB_EVENT_MASK_NO_EVENT, (char *)&ev);
+ }
+ 
++static bool checkWindowOrDescendantWantButtonEvents(xcb_window_t window)
++{
++    auto connection = QX11Info::connection();
++    auto waCookie = xcb_get_window_attributes(connection, window);
++    UniqueCPointer<xcb_get_window_attributes_reply_t> windowAttributes(xcb_get_window_attributes_reply(connection, waCookie, nullptr));
++    if (windowAttributes && windowAttributes->all_event_masks & XCB_EVENT_MASK_BUTTON_PRESS) {
++        return true;
++    }
++    if (windowAttributes && windowAttributes->do_not_propagate_mask & XCB_EVENT_MASK_BUTTON_PRESS) {
++        return false;
++    }
++    auto treeCookie = xcb_query_tree(connection, window);
++    UniqueCPointer<xcb_query_tree_reply_t> tree(xcb_query_tree_reply(connection, treeCookie, nullptr));
++    if (!tree) {
++        return false;
++    }
++    std::span<xcb_window_t> children(xcb_query_tree_children(tree.get()), xcb_query_tree_children_length(tree.get()));
++    return std::ranges::any_of(children, &checkWindowOrDescendantWantButtonEvents);
++}
++
+ SNIProxy::SNIProxy(xcb_window_t wid, QObject *parent)
+     : QObject(parent)
+     ,
+@@ -64,7 +86,6 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject *parent)
+     // service closing instead lets use one DBus connection per SNI
+     m_dbus(QDBusConnection::connectToBus(QDBusConnection::SessionBus, QStringLiteral("XembedSniProxy%1").arg(s_serviceCount++)))
+     , m_windowId(wid)
+-    , sendingClickEvent(false)
+     , m_injectMode(Direct)
+ {
+     new StatusNotifierItemAdaptor(this);
+@@ -101,9 +122,8 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject *parent)
+     uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
+     values[0] = screen->black_pixel; // draw a solid background so the embedded icon doesn't get garbage in it
+     values[1] = true; // bypass wM
+-    values[2] = XCB_EVENT_MASK_VISIBILITY_CHANGE | // receive visibility change, to handle KWin restart #357443
+-                                                   // Redirect and handle structure (size, position) requests from the embedded window.
+-        XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
++    values[2] = XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT;
++
+     xcb_create_window(c, /* connection    */
+                       XCB_COPY_FROM_PARENT, /* depth         */
+                       m_containerWid, /* window Id     */
+@@ -124,15 +144,13 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject *parent)
+         We also need it to exist in the right place to get the clicks working as GTK will check sendEvent locations to see if our window is in the right place.
+        So even though our contents are drawn via compositing we still put this window in the right place
+ 
+-        We can't composite it away anything parented owned by the root window (apparently)
+-        Stack Under works in the non composited case, but it doesn't seem to work in kwin's composited case (probably need set relevant NETWM hint)
+-
+-        As a last resort set opacity to 0 just to make sure this container never appears
++        Set opacity to 0 just to make sure this container never appears
++        And set the input region to null so everything just clicks through
+     */
+ 
+-#ifndef VISUAL_DEBUG
+-    stackContainerWindow(XCB_STACK_MODE_BELOW);
++    setActiveForInput(false);
+ 
++#ifndef VISUAL_DEBUG
+     NETWinInfo wm(c, m_containerWid, screen->root, NET::Properties(), NET::Properties2());
+     wm.setOpacity(0);
+ #endif
+@@ -178,8 +196,8 @@ SNIProxy::SNIProxy(xcb_window_t wid, QObject *parent)
+     // we query if the client selected button presses in the event mask
+     // if the client does supports that we send directly, otherwise we'll use xtest
+     auto waCookie = xcb_get_window_attributes(c, wid);
+-    QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> windowAttributes(xcb_get_window_attributes_reply(c, waCookie, nullptr));
+-    if (windowAttributes && !(windowAttributes->all_event_masks & XCB_EVENT_MASK_BUTTON_PRESS)) {
++    UniqueCPointer<xcb_get_window_attributes_reply_t> windowAttributes(xcb_get_window_attributes_reply(c, waCookie, nullptr));
++    if (!checkWindowOrDescendantWantButtonEvents(wid)) {
+         m_injectMode = XTest;
+     }
+ 
+@@ -230,20 +248,12 @@ void SNIProxy::resizeWindow(const uint16_t width, const uint16_t height) const
+     xcb_flush(connection);
+ }
+ 
+-void SNIProxy::hideContainerWindow(xcb_window_t windowId) const
+-{
+-    if (m_containerWid == windowId && !sendingClickEvent) {
+-        qDebug() << "Container window visible, stack below";
+-        stackContainerWindow(XCB_STACK_MODE_BELOW);
+-    }
+-}
+-
+ QSize SNIProxy::calculateClientWindowSize() const
+ {
+     auto c = QX11Info::connection();
+ 
+     auto cookie = xcb_get_geometry(c, m_windowId);
+-    QScopedPointer<xcb_get_geometry_reply_t, QScopedPointerPodDeleter> clientGeom(xcb_get_geometry_reply(c, cookie, nullptr));
++    UniqueCPointer<xcb_get_geometry_reply_t> clientGeom(xcb_get_geometry_reply(c, cookie, nullptr));
+ 
+     QSize clientWindowSize;
+     if (clientGeom) {
+@@ -369,9 +379,8 @@ QImage SNIProxy::convertFromNative(xcb_image_t *xcbImage) const
+ 
+     if (format == QImage::Format_RGB32 && xcbImage->bpp == 32) {
+         QImage m = image.createHeuristicMask();
+-        QBitmap mask(QPixmap::fromImage(m));
+-        QPixmap p = QPixmap::fromImage(image);
+-        p.setMask(mask);
++        QPixmap p = QPixmap::fromImage(std::move(image));
++        p.setMask(QBitmap::fromImage(std::move(m)));
+         image = p.toImage();
+     }
+ 
+@@ -391,7 +400,9 @@ QImage SNIProxy::convertFromNative(xcb_image_t *xcbImage) const
+ */
+ QPoint SNIProxy::calculateClickPoint() const
+ {
+-    QPoint clickPoint = QPoint(0, 0);
++    QSize clientSize = calculateClientWindowSize();
++    QPoint clickPoint = QPoint(clientSize.width() / 2, clientSize.height() / 2);
++
+ 
+     auto c = QX11Info::connection();
+ 
+@@ -400,8 +411,8 @@ QPoint SNIProxy::calculateClickPoint() const
+     // at the same time make the request for rectangles (even if this request isn't needed)
+     xcb_shape_get_rectangles_cookie_t rectaglesCookie = xcb_shape_get_rectangles(c, m_windowId, XCB_SHAPE_SK_BOUNDING);
+ 
+-    QScopedPointer<xcb_shape_query_extents_reply_t, QScopedPointerPodDeleter> extentsReply(xcb_shape_query_extents_reply(c, extentsCookie, nullptr));
+-    QScopedPointer<xcb_shape_get_rectangles_reply_t, QScopedPointerPodDeleter> rectanglesReply(xcb_shape_get_rectangles_reply(c, rectaglesCookie, nullptr));
++    UniqueCPointer<xcb_shape_query_extents_reply_t> extentsReply(xcb_shape_query_extents_reply(c, extentsCookie, nullptr));
++    UniqueCPointer<xcb_shape_get_rectangles_reply_t> rectanglesReply(xcb_shape_get_rectangles_reply(c, rectaglesCookie, nullptr));
+ 
+     if (!extentsReply || !rectanglesReply || !extentsReply->bounding_shaped) {
+         return clickPoint;
+@@ -428,11 +439,30 @@ QPoint SNIProxy::calculateClickPoint() const
+     return clickPoint;
+ }
+ 
+-void SNIProxy::stackContainerWindow(const uint32_t stackMode) const
++void SNIProxy::setActiveForInput(bool active) const
+ {
+     auto c = QX11Info::connection();
+-    const uint32_t stackData[] = {stackMode};
+-    xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackData);
++    if (active) {
++        xcb_rectangle_t rectangle;
++        rectangle.x = 0;
++        rectangle.y = 0;
++        rectangle.width = s_embedSize;
++        rectangle.height = s_embedSize;
++        xcb_shape_rectangles(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, 0, m_containerWid, 0, 0, 1, &rectangle);
++
++        const uint32_t stackData[] = {XCB_STACK_MODE_ABOVE};
++        xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackData);
++    } else {
++        xcb_rectangle_t rectangle;
++        rectangle.x = 0;
++        rectangle.y = 0;
++        rectangle.width = 0;
++        rectangle.height = 0;
++        xcb_shape_rectangles(c, XCB_SHAPE_SO_SET, XCB_SHAPE_SK_INPUT, 0, m_containerWid, 0, 0, 1, &rectangle);
++
++        const uint32_t stackData[] = {XCB_STACK_MODE_BELOW};
++        xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_STACK_MODE, stackData);
++    }
+ }
+ 
+ //____________properties__________
+@@ -520,12 +550,11 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y)
+     // ideally we should make this match the plasmoid hit area
+ 
+     qDebug() << "Received click" << mouseButton << "with passed x*y" << x << y;
+-    sendingClickEvent = true;
+ 
+     auto c = QX11Info::connection();
+ 
+     auto cookieSize = xcb_get_geometry(c, m_windowId);
+-    QScopedPointer<xcb_get_geometry_reply_t, QScopedPointerPodDeleter> clientGeom(xcb_get_geometry_reply(c, cookieSize, nullptr));
++    UniqueCPointer<xcb_get_geometry_reply_t> clientGeom(xcb_get_geometry_reply(c, cookieSize, nullptr));
+ 
+     if (!clientGeom) {
+         return;
+@@ -537,7 +566,7 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y)
+     if (mouseButton >= XCB_BUTTON_INDEX_4) {
+         // scroll event, take pointer position
+         auto cookie = xcb_query_pointer(c, m_windowId);
+-        QScopedPointer<xcb_query_pointer_reply_t, QScopedPointerPodDeleter> pointer(xcb_query_pointer_reply(c, cookie, nullptr));
++        UniqueCPointer<xcb_query_pointer_reply_t> pointer(xcb_query_pointer_reply(c, cookie, nullptr));
+         configVals[0] = pointer->root_x;
+         configVals[1] = pointer->root_y;
+     } else {
+@@ -547,8 +576,11 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y)
+     qDebug() << configVals[0] << configVals[1];
+     xcb_configure_window(c, m_containerWid, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, configVals);
+ 
+-    // pull window up
+-    stackContainerWindow(XCB_STACK_MODE_ABOVE);
++    setActiveForInput(true);
++
++    if (qgetenv("XDG_SESSION_TYPE") == "wayland") {
++        xcb_warp_pointer(c, XCB_NONE, m_windowId, 0, 0, 0, 0, clickPoint.x(), clickPoint.y());
++    }
+ 
+     // mouse down
+     if (m_injectMode == Direct) {
+@@ -596,11 +628,20 @@ void SNIProxy::sendClick(uint8_t mouseButton, int x, int y)
+         sendXTestReleased(QX11Info::display(), mouseButton);
+     }
+ 
+-#ifndef VISUAL_DEBUG
+-    stackContainerWindow(XCB_STACK_MODE_BELOW);
+-#endif
+-
+-    sendingClickEvent = false;
++    if (m_injectMode == Direct) {
++        setActiveForInput(false);
++    } else {
++        // delayed because on xwayland with the new libei path it will go to XWayland
++        // then kwin, then back to X
++        // we need to delay slightly until that happens
++        if (qgetenv("XDG_SESSION_TYPE") == QByteArrayLiteral("wayland")) {
++            QTimer::singleShot(300, this, [this]() {
++                setActiveForInput(false);
++            });
++        } else {
++            setActiveForInput(false);
++        }
++    }
+ }
+ 
+ uint SNIProxy::getPid(const xcb_window_t windowId)
+diff --git a/xembed-sni-proxy/sni-proxy.h b/xembed-sni-proxy/sni-proxy.h
+index b5128d3..4b729db 100644
+--- a/xembed-sni-proxy/sni-proxy.h
++++ b/xembed-sni-proxy/sni-proxy.h
+@@ -39,7 +39,6 @@ public:
+ 
+     void update();
+     void resizeWindow(const uint16_t width, const uint16_t height) const;
+-    void hideContainerWindow(xcb_window_t windowId) const;
+ 
+     /**
+      * @return the category of the application associated to this item
+@@ -146,7 +145,7 @@ private:
+     bool isTransparentImage(const QImage &image) const;
+     QImage convertFromNative(xcb_image_t *xcbImage) const;
+     QPoint calculateClickPoint() const;
+-    void stackContainerWindow(const uint32_t stackMode) const;
++    void setActiveForInput(bool active) const;
+     uint getPid(const xcb_window_t windowId);
+ 
+     QDBusConnection m_dbus;
+diff --git a/xembed-sni-proxy/xcb-utils.h b/xembed-sni-proxy/xcb-utils.h
+index fb7e4e6..af425e9 100644
+--- a/xembed-sni-proxy/xcb-utils.h
++++ b/xembed-sni-proxy/xcb-utils.h
+@@ -18,6 +18,7 @@
+ 
+ #include <QVector>
+ #include <QX11Info>
++#include <c_ptr.h>
+ 
+ /** XEMBED messages */
+ #define XEMBED_EMBEDDED_NOTIFY 0
+@@ -31,8 +32,6 @@
+ 
+ namespace Xcb
+ {
+-typedef xcb_window_t WindowId;
+-template <typename T> using ScopedCPointer = QScopedPointer<T, QScopedPointerPodDeleter>;
+ class Atom
+ {
+ public:
+@@ -81,7 +80,7 @@ private:
+         if (m_retrieved || !m_cookie.sequence) {
+             return;
+         }
+-        ScopedCPointer<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(m_connection, m_cookie, nullptr));
++        UniqueCPointer<xcb_intern_atom_reply_t> reply(xcb_intern_atom_reply(m_connection, m_cookie, nullptr));
+         if (reply) {
+             m_atom = reply->atom;
+         }
diff -Nru ukui-sni-4.10.0.5/debian/patches/series ukui-sni-4.10.0.5/debian/patches/series
--- ukui-sni-4.10.0.5/debian/patches/series	2024-11-19 14:01:03.000000000 +0800
+++ ukui-sni-4.10.0.5/debian/patches/series	2024-12-27 16:02:15.000000000 +0800
@@ -1,2 +1,3 @@
 0001-update-changelog-for-4.10.0.5-ok1.patch
 0002-update-changelog-for-4.10.0.5-ok1.1.patch
+0003-update-changelog-for-4.10.0.5-ok1.2.patch