Commit 6e03b6f5 authored by Xuetian Weng's avatar Xuetian Weng
Browse files

kimpanel: add a ibus panel launcher.

Launcher will wait for ibus start and launch the panel then quit.
Launcher is started by dataengine. Also this change make kimpanel's
panel quit when dataengine disappears (applet removable will trigger
it). DBus magic will actually be able to fallback it to the running gtk3
panel.

BUG: 378342
FIXED-IN: 5.10
parent 45bea58f
add_subdirectory(scim)
add_subdirectory(ibus)
......@@ -3,6 +3,7 @@ find_package(GLIB2)
find_package(GIO)
find_package(GObject)
if(IBUS_FOUND AND GLIB2_FOUND AND GIO_FOUND AND GOBJECT_FOUND)
configure_file(config-kimpanel.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kimpanel.h)
include_directories(${IBUS_INCLUDE_DIR})
include_directories(${GLIB2_INCLUDE_DIR})
include_directories(${GIO_INCLUDE_DIR})
......@@ -12,7 +13,6 @@ if(IBUS_FOUND AND GLIB2_FOUND AND GIO_FOUND AND GOBJECT_FOUND)
set(kimpanel_ibus_panel_SRCS ibus14/panel.c ibus14/main.c)
add_executable(kimpanel-ibus-panel ${kimpanel_ibus_panel_SRCS})
target_link_libraries(kimpanel-ibus-panel ${IBUS_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO_LIBRARIES} ${GOBJECT_LIBRARIES})
install(TARGETS kimpanel-ibus-panel DESTINATION ${LIBEXEC_INSTALL_DIR})
# configure_file(${CMAKE_CURRENT_SOURCE_DIR}/kimpanel.xml.in ${CMAKE_CURRENT_BINARY_DIR}/kimpanel.xml @ONLY)
# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kimpanel.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/ibus/component)
else()
......@@ -34,10 +34,19 @@ if(IBUS_FOUND AND GLIB2_FOUND AND GIO_FOUND AND GOBJECT_FOUND)
add_definitions(-DQT_NO_KEYWORDS)
add_executable(kimpanel-ibus-panel ${kimpanel_ibus_panel_SRCS})
target_link_libraries(kimpanel-ibus-panel ${IBUS_LIBRARIES} ${GLIB2_LIBRARIES} ${GIO_LIBRARIES} ${GOBJECT_LIBRARIES} Qt5::Core Qt5::DBus Qt5::Gui Qt5::X11Extras XCB::KEYSYMS)
install(TARGETS kimpanel-ibus-panel DESTINATION ${LIBEXEC_INSTALL_DIR})
# configure_file(${CMAKE_CURRENT_SOURCE_DIR}/kimpanel.xml.in ${CMAKE_CURRENT_BINARY_DIR}/kimpanel.xml @ONLY)
# install(FILES ${CMAKE_CURRENT_BINARY_DIR}/kimpanel.xml DESTINATION ${CMAKE_INSTALL_PREFIX}/share/ibus/component)
endif()
endif()
if (TARGET kimpanel-ibus-panel)
target_include_directories(kimpanel-ibus-panel PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
add_executable(kimpanel-ibus-panel-launcher launcher.cpp)
set_target_properties(kimpanel-ibus-panel-launcher PROPERTIES AUTOMOC TRUE)
target_link_libraries(kimpanel-ibus-panel-launcher Qt5::Core Qt5::DBus)
target_include_directories(kimpanel-ibus-panel-launcher PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
install(TARGETS kimpanel-ibus-panel kimpanel-ibus-panel-launcher DESTINATION ${LIBEXEC_INSTALL_DIR})
endif()
endif()
#ifndef _KIMPANEL_CONFIG_KIMPANEL_H_CMAKE_
#define _KIMPANEL_CONFIG_KIMPANEL_H_CMAKE_
#define KIMPANEL_LIBEXEC_DIR "${KDE_INSTALL_FULL_LIBEXECDIR}"
#endif // _KIMPANEL_CONFIG_KIMPANEL_H_CMAKE_
......@@ -24,6 +24,8 @@
#include <QTimer>
#include <QDebug>
#include <QX11Info>
#include <QDBusServiceWatcher>
#include <QDBusConnection>
#include <xcb/xcb_keysyms.h>
#define USED_MASK (XCB_MOD_MASK_SHIFT | XCB_MOD_MASK_CONTROL | XCB_MOD_MASK_1 | XCB_MOD_MASK_4)
......@@ -184,7 +186,11 @@ App::App(int argc, char** argv): QGuiApplication(argc, argv)
,m_keyboardGrabbed(false)
,m_doGrab(false)
,m_syms(0)
,m_watcher(new QDBusServiceWatcher(this))
{
m_watcher->setConnection(QDBusConnection::sessionBus());
m_watcher->addWatchedService("org.kde.impanel");
connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &App::finalize);
m_syms = xcb_key_symbols_alloc(QX11Info::connection());
installNativeEventFilter(m_eventFilter.data());
ibus_init ();
......@@ -329,6 +335,7 @@ void App::nameAcquired()
void App::nameLost()
{
setDoGrab(false);
if (m_impanel) {
g_object_unref(m_impanel);
}
......@@ -375,7 +382,7 @@ void App::grabKey()
uint modifiers = key.second;
xcb_keycode_t* keycode = xcb_key_symbols_get_keycode(m_syms, sym);
if (!keycode) {
g_warning ("Can not convert keyval=%lu to keycode!", sym);
g_warning ("Can not convert keyval=%u to keycode!", sym);
} else {
xcb_grab_key(QX11Info::connection(), true, QX11Info::appRootWindow(),
modifiers, keycode[0], XCB_GRAB_MODE_ASYNC, XCB_GRAB_MODE_ASYNC);
......@@ -395,7 +402,7 @@ void App::ungrabKey()
uint modifiers = key.second;
xcb_keycode_t* keycode = xcb_key_symbols_get_keycode(m_syms, sym);
if (!keycode) {
g_warning ("Can not convert keyval=%lu to keycode!", sym);
g_warning ("Can not convert keyval=%u to keycode!", sym);
} else {
xcb_ungrab_key(QX11Info::connection(), keycode[0], QX11Info::appRootWindow(), modifiers);
if ((modifiers & XCB_MOD_MASK_SHIFT) == 0) {
......
......@@ -30,6 +30,7 @@
#include <QByteArray>
#include <QPair>
#include "panel.h"
class QDBusServiceWatcher;
class XcbEventFilter : public QAbstractNativeEventFilter
{
......@@ -43,7 +44,6 @@ public:
typedef QPair< uint, uint > TriggerKey;
App(int argc, char** argv);
virtual ~App();
void finalize();
void setTriggerKeys(QList< TriggerKey > triggersList);
void setDoGrab(bool doGrab);
bool keyboardGrabbed() { return m_keyboardGrabbed; }
......@@ -52,7 +52,8 @@ public:
void nameAcquired();
void nameLost();
QByteArray normalizeIconName(const QByteArray& icon) const;
private Q_SLOTS:
public Q_SLOTS:
void finalize();
void clean();
void grabKey();
void ungrabKey();
......@@ -71,6 +72,7 @@ private:
bool m_doGrab;
xcb_key_symbols_t* m_syms;
QMap<QByteArray, QByteArray> m_iconMap;
QDBusServiceWatcher *m_watcher;
};
#endif // APP_H
/*
* Copyright (C) 2017~2017 by CSSlayer
* wengxt@gmail.com
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; see the file COPYING. If not,
* see <http://www.gnu.org/licenses/>.
*/
#include <QCoreApplication>
#include <QDBusServiceWatcher>
#include <QDBusConnection>
#include <QDBusConnectionInterface>
#include <QProcess>
#include "config-kimpanel.h"
class IBusPanelLauncher : public QCoreApplication {
Q_OBJECT
public:
IBusPanelLauncher(int argc, char *argv[]) : QCoreApplication(argc, argv), m_watcher(new QDBusServiceWatcher(this)) {
m_watcher->setConnection(QDBusConnection::sessionBus());
QMetaObject::invokeMethod(this, "init", Qt::QueuedConnection);
}
public Q_SLOTS:
void init() {
// already a launcher running
if (!QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.impanel.IBusPanelLauncher"))) {
quit();
return;
}
// Check if applet is still there.
connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered, this, &IBusPanelLauncher::serviceUnregistered);
connect(m_watcher, &QDBusServiceWatcher::serviceRegistered, this, &IBusPanelLauncher::serviceRegistered);
m_watcher->addWatchedService("org.kde.impanel");
m_watcher->addWatchedService("org.freedesktop.IBus");
// check if panel is already created
QDBusConnection::sessionBus().connect("org.kde.impanel", "/org/kde/impanel", "org.kde.impanel2", "PanelRegistered", this, SLOT(quit()));
if (!QDBusConnection::sessionBus().interface()->isServiceRegistered("org.kde.impanel")) {
quit();
return;
}
if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.freedesktop.IBus")) {
serviceRegistered("org.freedesktop.IBus");
}
}
void serviceRegistered(const QString &service) {
if (service == "org.freedesktop.IBus") {
launchIBusPanel();
}
}
void serviceUnregistered(const QString &service) {
if (service == "org.kde.impanel") {
quit();
}
}
private:
void launchIBusPanel() {
const QString panelPath = QStringLiteral(KIMPANEL_LIBEXEC_DIR"/kimpanel-ibus-panel");
QProcess::startDetached(panelPath);
quit();
}
private:
QDBusServiceWatcher *m_watcher;
};
int main(int argc, char *argv[]) {
IBusPanelLauncher app(argc, argv);
return app.exec();
}
#include "launcher.moc"
add_definitions(-DTRANSLATION_DOMAIN="plasma_engine_kimpanel")
configure_file(config-kimpanel.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-kimpanel.h)
set(plasma_engine_kimpanel_SRCS
kimpaneldataengine.cpp
kimpanelagent.cpp
......@@ -15,6 +17,7 @@ QT5_ADD_DBUS_ADAPTOR(plasma_engine_kimpanel_SRCS
add_library(plasma_engine_kimpanel ${plasma_engine_kimpanel_SRCS})
target_include_directories(plasma_engine_kimpanel PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
set_target_properties(plasma_engine_kimpanel PROPERTIES PREFIX "")
target_link_libraries(plasma_engine_kimpanel
KF5::Plasma
......
#ifndef _KIMPANEL_CONFIG_KIMPANEL_H_CMAKE_
#define _KIMPANEL_CONFIG_KIMPANEL_H_CMAKE_
#define KIMPANEL_LIBEXEC_DIR "${KDE_INSTALL_FULL_LIBEXECDIR}"
#endif // _KIMPANEL_CONFIG_KIMPANEL_H_CMAKE_
......@@ -253,6 +253,9 @@ void PanelAgent::RegisterProperties(const QStringList &props)
const QDBusMessage& msg = message();
if (msg.service() != m_currentService) {
watcher->removeWatchedService(m_currentService);
if (m_currentService.isEmpty()) {
emit PanelRegistered();
}
m_currentService = msg.service();
watcher->addWatchedService(m_currentService);
}
......
......@@ -79,6 +79,7 @@ Q_SIGNALS:
void TriggerProperty(const QString &key);
void PanelCreated();
void PanelCreated2();
void PanelRegistered();
void Exit();
void ReloadConfig();
......
......@@ -22,6 +22,10 @@
#include "kimpanelservice.h"
#include "kimpanelinputpanelcontainer.h"
#include "kimpanelstatusbarcontainer.h"
#include "config-kimpanel.h"
#include <QProcess>
#include <QFile>
// Plasma
#include <Plasma/DataContainer>
......@@ -32,6 +36,14 @@ KimpanelEngine::KimpanelEngine(QObject* parent, const QVariantList& args)
init();
}
static void ibusPanelLauncher() {
// lets just blindly start the launcher. no need to use ifdef
const QString path = QStringLiteral(KIMPANEL_LIBEXEC_DIR"/kimpanel-ibus-panel-launcher");
if (QFile::exists(path)) {
QProcess::startDetached(path);
}
}
void KimpanelEngine::init()
{
m_panelAgent = new PanelAgent(this);
......@@ -42,6 +54,8 @@ void KimpanelEngine::init()
addSource(inputpanelSource);
addSource(statusbarSource);
this->m_panelAgent->created();
ibusPanelLauncher();
}
Plasma::Service* KimpanelEngine::serviceForSource(const QString& source)
......
......@@ -34,5 +34,6 @@
<arg type="i" name="cursor" direction="in" />
<arg type="i" name="layout" direction="in" />
</method>
<signal name="PanelRegistered"></signal>
</interface>
</node>
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment