diff --git a/.gitignore b/.gitignore
index 43a43f4..d274f67 100644
--- a/.gitignore
+++ b/.gitignore
@@ -51,3 +51,8 @@ compile_commands.json
# QtCreator local machine specific files for imported projects
*creator.user*
+
+.idea
+CMakeFiles
+cmake_install.cmake
+*_autogen
diff --git a/frontend/CMakeLists.txt b/frontend/CMakeLists.txt
index c414d0b..75773a4 100644
--- a/frontend/CMakeLists.txt
+++ b/frontend/CMakeLists.txt
@@ -49,6 +49,13 @@ set(UKUI_SEARCH_SRC
view/result-view.cpp view/result-view.h
view/result-view-delegate.cpp view/result-view-delegate.h
)
+if(COMMAND qt_add_dbus_adaptor)
+ qt_add_dbus_adaptor(UKUI_SEARCH_SRC org.ukui.search.service.xml ukui-search-dbus-service.h UkuiSearch::UkuiSearchDbusServices)
+ qt_add_dbus_interface(UKUI_SEARCH_SRC org.ukui.search.service.xml service_interface)
+else()
+ qt5_add_dbus_adaptor(UKUI_SEARCH_SRC org.ukui.search.service.xml ukui-search-dbus-service.h UkuiSearch::UkuiSearchDbusServices)
+ qt5_add_dbus_interface(UKUI_SEARCH_SRC org.ukui.search.service.xml service_interface)
+endif()
set(QRC_FILES resource.qrc)
diff --git a/frontend/main.cpp b/frontend/main.cpp
index ebe1ffb..88508f9 100644
--- a/frontend/main.cpp
+++ b/frontend/main.cpp
@@ -64,12 +64,17 @@ int main(int argc, char *argv[]) {
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
QString display;
- if(KWindowSystem::isPlatformWayland()) {
+ QString sessionType;
+ if(QString(getenv("XDG_SESSION_TYPE")) == "wayland") {
+ sessionType = "wayland";
display = getenv("WAYLAND_DISPLAY");
- } else if (KWindowSystem::isPlatformX11()) {
+ } else {
+ sessionType = "x11";
display = getenv("DISPLAY");
}
- UkuiSearchGui app(argc, argv, QString("ukui-search-gui-%1").arg(display));
+ qDebug() << "Current DISPLAY: " << display;
+ UkuiSearchGui app(argc, argv, display, sessionType);
+
if (app.isRunning())
return 0;
diff --git a/frontend/org.ukui.search.service.xml b/frontend/org.ukui.search.service.xml
new file mode 100644
index 0000000..c0bb900
--- /dev/null
+++ b/frontend/org.ukui.search.service.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/frontend/ukui-search-dbus-service.cpp b/frontend/ukui-search-dbus-service.cpp
index 9d79e93..f6a4ddc 100644
--- a/frontend/ukui-search-dbus-service.cpp
+++ b/frontend/ukui-search-dbus-service.cpp
@@ -18,42 +18,193 @@
*
*/
#include "ukui-search-dbus-service.h"
+#include
+#include
+#include "serviceadaptor.h"
using namespace UkuiSearch;
-void UkuiSearchDbusServices::showWindow(){
- qDebug() << "showWindow called";
- m_mainWindow->bootOptionsFilter("-s");
+void UkuiSearchDbusServices::showWindow()
+{
+ QString display = checkDisplay();
+ qDebug() << "showWindow called, from display:" << display << "current display: " << m_display;
+ if(!display.isEmpty() && display != m_display) {
+ Q_EMIT showWindowSignal(display);
+ return;
+ }
+ onShowWindow(m_display);
}
void UkuiSearchDbusServices::searchKeyword(QString keyword)
{
- showWindow();
- m_mainWindow->setText(keyword);
+ QString display = checkDisplay();
+ qDebug() << "searchKeyword called, from display:" << display << "current display: " << m_display;
+ if(!display.isEmpty() && display != m_display) {
+ Q_EMIT searchKeywordSignal(display, keyword);
+ return;
+ }
+ onSearchKeyword(m_display, keyword);
}
void UkuiSearchDbusServices::mainWindowSwitch()
{
- if (m_mainWindow->isActiveWindow()) {
- m_mainWindow->tryHide();
+ QString display = checkDisplay();
+ qDebug() << "mainWindowSwitch called, from display:" << display << "current display: " << m_display;
+ if(!display.isEmpty() && display != m_display) {
+ Q_EMIT mainWindowSwitchSignal(display);
+ return;
+ }
+ onMainWindowSwitch(m_display);
+}
+
+UkuiSearchDbusServices::UkuiSearchDbusServices(MainWindow *m, QObject *parent):
+ QObject(parent),
+ m_mainWindow(m)
+{
+ m_mainWindow = m;
+ m_display = qApp->property("display").toString();
+ //注册服务
+ bool isServiceRegistered = QDBusConnection::sessionBus().interface()->isServiceRegistered(QStringLiteral("com.ukui.search.service"));
+ if(isServiceRegistered) {
+ initWatcher();
} else {
+ if(!registerService()) {
+ initWatcher();
+ }
+ }
+}
+
+UkuiSearchDbusServices::~UkuiSearchDbusServices()
+{
+ if(m_watcher) {
+ delete m_watcher;
+ m_watcher = nullptr;
+ }
+ if(m_serviceIface) {
+ delete m_serviceIface;
+ m_serviceIface = nullptr;
+ }
+}
+
+void UkuiSearchDbusServices::initWatcher()
+{
+ m_watcher = new QDBusServiceWatcher(QStringLiteral("com.ukui.search.service"),QDBusConnection::sessionBus(), QDBusServiceWatcher::WatchForOwnerChange);
+ connect(m_watcher, &QDBusServiceWatcher::serviceOwnerChanged, this, &UkuiSearchDbusServices::onServiceOwnerChanged);
+ connectToService();
+}
+
+bool UkuiSearchDbusServices::registerService()
+{
+ if(!m_adaptor) {
+ m_adaptor = new ServiceAdaptor(this);
+ }
+ QDBusConnection conn = QDBusConnection::sessionBus();
+ auto reply = conn.interface()->registerService(QStringLiteral("com.ukui.search.service"),
+ QDBusConnectionInterface::ReplaceExistingService,
+ QDBusConnectionInterface::DontAllowReplacement);
+ if (reply.value() == QDBusConnectionInterface::ServiceNotRegistered) {
+ return false;
+ }
+
+ bool res = QDBusConnection::sessionBus().registerObject("/", this);
+ if (!res) {
+ QDBusConnection::sessionBus().interface()->unregisterService(QStringLiteral("com.ukui.search.service"));
+ }
+ return res;
+}
+
+void
+UkuiSearchDbusServices::onServiceOwnerChanged(const QString &service, const QString &oldOwner, const QString &newOwner)
+{
+ if (newOwner.isEmpty()) {
+ bool success = registerService();
+ if (success) {
+ disConnectToService();
+ m_watcher->deleteLater();
+ }
+ qDebug() << "try to register service:" << success;
+ return;
+ }
+
+ uint newOwnerPid = QDBusConnection::sessionBus().interface()->servicePid(newOwner);
+ qDebug() << "newOwnerPid:" << newOwnerPid << ", myPid:" << QCoreApplication::applicationPid() << ", display:" << m_display;
+}
+
+void UkuiSearchDbusServices::connectToService()
+{
+ if(!m_serviceIface) {
+ m_serviceIface = new OrgUkuiSearchServiceInterface(QStringLiteral("com.ukui.search.service"), "/", QDBusConnection::sessionBus());
+ }
+ connect(m_serviceIface, &OrgUkuiSearchServiceInterface::showWindowSignal, this, &UkuiSearchDbusServices::onShowWindow);
+ connect(m_serviceIface, &OrgUkuiSearchServiceInterface::searchKeywordSignal, this, &UkuiSearchDbusServices::onSearchKeyword);
+ connect(m_serviceIface, &OrgUkuiSearchServiceInterface::mainWindowSwitchSignal, this, &UkuiSearchDbusServices::onMainWindowSwitch);
+}
+
+void UkuiSearchDbusServices::disConnectToService()
+{
+ if(m_serviceIface) {
+ m_serviceIface->disconnect();
+ delete m_serviceIface;
+ m_serviceIface = nullptr;
+ }
+}
+
+void UkuiSearchDbusServices::onShowWindow(const QString &display)
+{
+ if(m_display == display) {
m_mainWindow->bootOptionsFilter("-s");
}
}
-UkuiSearchDbusServices::UkuiSearchDbusServices(MainWindow *m)
+void UkuiSearchDbusServices::onSearchKeyword(const QString &display, const QString &keyword)
{
- m_mainWindow = m;
- //注册服务
- QDBusConnection sessionBus = QDBusConnection::sessionBus();
- QDBusConnection::sessionBus().unregisterService("com.ukui.search.service");
- if(!sessionBus.registerService("com.ukui.search.service")){
- qWarning() << "ukui-search dbus register service failed reason:" << sessionBus.lastError();
- }
-
- if(!sessionBus.registerObject("/", this, QDBusConnection::ExportAllSlots)){
- qWarning() << "ukui-search dbus register object failed reason:" << sessionBus.lastError();
+ if(m_display == display) {
+ m_mainWindow->bootOptionsFilter("-s");
+ m_mainWindow->setText(keyword);
}
}
-UkuiSearchDbusServices::~UkuiSearchDbusServices(){
+void UkuiSearchDbusServices::onMainWindowSwitch(const QString &display)
+{
+ if(m_display == display) {
+ if (m_mainWindow->isActiveWindow()) {
+ m_mainWindow->tryHide();
+ } else {
+ m_mainWindow->bootOptionsFilter("-s");
+ }
+ }
+}
+
+QString UkuiSearchDbusServices::checkDisplay()
+{
+ uint pid = 0;
+ QDBusReply pidReply = connection().interface()->servicePid(message().service());
+ qDebug() << "caller pid: " << pidReply.value();
+ if(pidReply.isValid()) {
+ pid = pidReply.value();
+ } else {
+ return {};
+ }
+ return UkuiSearchDbusServices::displayFromPid(pid);;
+}
+
+QString UkuiSearchDbusServices::displayFromPid(uint pid)
+{
+ QFile environFile(QStringLiteral("/proc/%1/environ").arg(QString::number(pid)));
+ if (environFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ const QByteArray DISPLAY = qApp->property("sessionType").toString() == "wayland" ? QByteArrayLiteral("WAYLAND_DISPLAY")
+ : QByteArrayLiteral("DISPLAY");
+ const auto lines = environFile.readAll().split('\0');
+ for (const QByteArray &line : lines) {
+ const int equalsIdx = line.indexOf('=');
+ if (equalsIdx <= 0) {
+ continue;
+ }
+ const QByteArray key = line.left(equalsIdx);
+ if (key == DISPLAY) {
+ const QByteArray value = line.mid(equalsIdx + 1);
+ return value;
+ }
+ }
+ }
+ return {};
}
diff --git a/frontend/ukui-search-dbus-service.h b/frontend/ukui-search-dbus-service.h
index 8e33da0..329c4a6 100644
--- a/frontend/ukui-search-dbus-service.h
+++ b/frontend/ukui-search-dbus-service.h
@@ -22,18 +22,21 @@
#include
#include
+#include
#include "mainwindow.h"
+#include "service_interface.h"
+class ServiceAdaptor;
namespace UkuiSearch {
-class UkuiSearchDbusServices: public QObject{
+class UkuiSearchDbusServices: public QObject, public QDBusContext
+{
Q_OBJECT
-
Q_CLASSINFO("D-Bus Interface","org.ukui.search.service")
public:
- explicit UkuiSearchDbusServices(MainWindow *m);
+ explicit UkuiSearchDbusServices(MainWindow *m, QObject *parent = nullptr);
~UkuiSearchDbusServices();
public Q_SLOTS:
@@ -41,8 +44,32 @@ public Q_SLOTS:
void searchKeyword(QString keyword);
void mainWindowSwitch();
+Q_SIGNALS:
+ void showWindowSignal(const QString &display);
+ void searchKeywordSignal(const QString &display, QString keyword);
+ void mainWindowSwitchSignal(const QString &display);
+
+private Q_SLOTS:
+ void onShowWindow(const QString &display);
+ void onSearchKeyword(const QString &display, const QString &keyword);
+ void onMainWindowSwitch(const QString &display);
+
private:
+ void initWatcher();
+ bool registerService();
+ void onServiceOwnerChanged(const QString &service, const QString &oldOwner, const QString &newOwner);
+ void connectToService();
+ void disConnectToService();
+ QString checkDisplay();
+ QString displayFromPid(uint pid);
+
MainWindow *m_mainWindow = nullptr;
+ QDBusServiceWatcher *m_watcher = nullptr;
+ QString m_display;
+ OrgUkuiSearchServiceInterface *m_serviceIface = nullptr;
+ ServiceAdaptor * m_adaptor = nullptr;
+
+
};
}
diff --git a/frontend/ukui-search-gui.cpp b/frontend/ukui-search-gui.cpp
index 4b6e747..9cd0da3 100644
--- a/frontend/ukui-search-gui.cpp
+++ b/frontend/ukui-search-gui.cpp
@@ -24,13 +24,19 @@
#include
#include
#include "plugin-manager.h"
-#include "search-plugin-manager.h"
#include "icon-loader.h"
using namespace UkuiSearch;
-UkuiSearchGui::UkuiSearchGui(int &argc, char *argv[], const QString &applicationName): QtSingleApplication (applicationName, argc, argv)
+UkuiSearchGui::UkuiSearchGui(int &argc,
+ char *argv[],
+ const QString &display,
+ const QString &sessionType,
+ const QString &applicationName):
+ QtSingleApplication (applicationName + display, argc, argv)
{
- qDebug()<<"ukui search gui constructor start" << applicationName;
+ qDebug()<<"ukui search gui constructor start, session type:" << sessionType << "display:" << display;
+ qApp->setProperty("display", display);
+ qApp->setProperty("sessionType", sessionType);
setApplicationVersion(QString("v%1").arg(VERSION));
if (!this->isRunning()) {
connect(this, &QtSingleApplication::messageReceived, [=](QString msg) {
@@ -39,10 +45,6 @@ UkuiSearchGui::UkuiSearchGui(int &argc, char *argv[], const QString &application
setQuitOnLastWindowClosed(false);
-// qRegisterMetaType>("QPair");
-// qRegisterMetaType("Document");
-
-
//load translations.
QTranslator *translator = new QTranslator(this);
try {
@@ -73,7 +75,7 @@ UkuiSearchGui::UkuiSearchGui(int &argc, char *argv[], const QString &application
PluginManager::getInstance();
m_mainWindow = new UkuiSearch::MainWindow();
- m_dbusService = new UkuiSearch::UkuiSearchDbusServices(m_mainWindow);
+ m_dbusService = new UkuiSearch::UkuiSearchDbusServices(m_mainWindow, this);
qApp->setWindowIcon(IconLoader::loadIconQt("kylin-search"));
this->setActivationWindow(m_mainWindow);
}
diff --git a/frontend/ukui-search-gui.h b/frontend/ukui-search-gui.h
index cafdd83..04dac42 100644
--- a/frontend/ukui-search-gui.h
+++ b/frontend/ukui-search-gui.h
@@ -31,7 +31,7 @@ class UkuiSearchGui : public QtSingleApplication
{
Q_OBJECT
public:
- UkuiSearchGui(int &argc, char *argv[], const QString &applicationName = "ukui-search-gui");
+ UkuiSearchGui(int &argc, char *argv[] , const QString &display, const QString &sessionType, const QString &applicationName = "ukui-search-gui");
~UkuiSearchGui();
protected Q_SLOTS:
diff --git a/translations/ukui-search/appwidget/search_bo_CN.ts b/translations/ukui-search/appwidget/search_bo_CN.ts
index 52f9a29..b0ba42a 100644
--- a/translations/ukui-search/appwidget/search_bo_CN.ts
+++ b/translations/ukui-search/appwidget/search_bo_CN.ts
@@ -22,22 +22,27 @@
-
-
+
+
-
+
+
+
+
+
+
-
+
-
+
@@ -66,32 +71,32 @@
UkuiSearch::UkuiSearchGui
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/translations/ukui-search/appwidget/search_mn.ts b/translations/ukui-search/appwidget/search_mn.ts
index 7763ed3..63cabce 100644
--- a/translations/ukui-search/appwidget/search_mn.ts
+++ b/translations/ukui-search/appwidget/search_mn.ts
@@ -22,22 +22,27 @@
-
-
+
+
-
+
+
+
+
+
+
-
+
-
+
@@ -66,32 +71,32 @@
UkuiSearch::UkuiSearchGui
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/translations/ukui-search/appwidget/search_zh_CN.ts b/translations/ukui-search/appwidget/search_zh_CN.ts
index f8a5697..f26856f 100644
--- a/translations/ukui-search/appwidget/search_zh_CN.ts
+++ b/translations/ukui-search/appwidget/search_zh_CN.ts
@@ -18,10 +18,6 @@
-
-
-
-
@@ -34,6 +30,14 @@
+
+
+
+
+
+
+
+
UkuiSearch::MainWindow
diff --git a/translations/ukui-search/bo_CN.ts b/translations/ukui-search/bo_CN.ts
index 67a206c..9bcea0a 100644
--- a/translations/ukui-search/bo_CN.ts
+++ b/translations/ukui-search/bo_CN.ts
@@ -205,32 +205,32 @@
UkuiSearch::UkuiSearchGui
-
+
ཉེར་སྤྱོད་གོ་རིམ་ལས་ཕྱིར་འཐེན་བྱ།
-
+
སྒེའུ་ཁུང་གཙོ་བོ་མངོན་པ།
-
+
-
+
-
+
-
+
diff --git a/translations/ukui-search/mn.ts b/translations/ukui-search/mn.ts
index 76c47fc..82e2288 100644
--- a/translations/ukui-search/mn.ts
+++ b/translations/ukui-search/mn.ts
@@ -205,32 +205,32 @@
UkuiSearch::UkuiSearchGui
-
+
ᠬᠠᠢᠯᠲᠠᠶᠢᠨ ᠬᠡᠷᠡᠭᠯᠡᠯᠳᠡᠡᠴᠡ ᠪᠤᠴᠠᠵᠤ ᠭᠠᠷᠬᠤ
-
+
ᠭᠤᠤᠯ ᠨᠢᠭᠤᠷ ᠬᠠᠭᠤᠳᠠᠰᠤᠶᠢ ᠢᠯᠡᠷᠡᠬᠦᠯᠬᠦ᠌
-
+
-
+
-
+
-
+
diff --git a/translations/ukui-search/tr.ts b/translations/ukui-search/tr.ts
index 9823aa4..2602e94 100644
--- a/translations/ukui-search/tr.ts
+++ b/translations/ukui-search/tr.ts
@@ -541,32 +541,32 @@
UkuiSearch::UkuiSearchGui
-
+
-
+
-
+
-
+
-
+
-
+
diff --git a/translations/ukui-search/zh_CN.ts b/translations/ukui-search/zh_CN.ts
index 19b8e69..56d4c51 100644
--- a/translations/ukui-search/zh_CN.ts
+++ b/translations/ukui-search/zh_CN.ts
@@ -351,32 +351,32 @@
UkuiSearch::UkuiSearchGui
-
+
退出搜索应用
-
+
显示主页面
-
+
-
+
-
+
-
+