Warning, file /plasma/wacomtablet/src/kded/tabletdaemon.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * This file is part of the KDE wacomtablet project. For copyright 0003 * information and license terms see the AUTHORS and COPYING files 0004 * in the top-level directory of this distribution. 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU General Public License as 0008 * published by the Free Software Foundation; either version 2 of 0009 * the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 */ 0019 0020 #include "tabletdaemon.h" 0021 0022 #include "../wacomtablet-version.h" 0023 #include "dbustabletservice.h" 0024 #include "globalactions.h" 0025 #include "logging.h" 0026 #include "tabletfinder.h" 0027 #include "tablethandler.h" 0028 #include "wacomadaptor.h" 0029 #include "x11eventnotifier.h" 0030 0031 // common includes 0032 #include "aboutdata.h" 0033 0034 // stdlib includes 0035 #include <memory> 0036 0037 // KDE includes 0038 #include <KIO/ApplicationLauncherJob> 0039 #include <KLocalizedString> 0040 #include <KNotification> 0041 #include <KPluginFactory> 0042 0043 #include <QGuiApplication> 0044 #include <QScreen> 0045 0046 #include "private/qtx11extras_p.h" 0047 0048 using namespace Wacom; 0049 0050 K_PLUGIN_FACTORY_WITH_JSON(WacomTabletFactory, "wacomtablet.json", registerPlugin<TabletDaemon>();) 0051 0052 namespace Wacom 0053 { 0054 /** 0055 * Private class of the TabletDaemon for the d-pointer 0056 */ 0057 class TabletDaemonPrivate 0058 { 0059 public: 0060 TabletDaemonPrivate() 0061 : tabletHandler() 0062 , dbusTabletService(tabletHandler) 0063 { 0064 } 0065 0066 TabletHandler tabletHandler; /**< tablet handler */ 0067 DBusTabletService dbusTabletService; 0068 std::shared_ptr<GlobalActions> actionCollection; /**< Collection of all global actions */ 0069 0070 }; // CLASS 0071 } // NAMESPACE 0072 0073 TabletDaemon::TabletDaemon(QObject *parent, const QVariantList &args) 0074 : KDEDModule(parent) 0075 , d_ptr(new TabletDaemonPrivate) 0076 { 0077 Q_UNUSED(args); 0078 Q_D(TabletDaemon); 0079 0080 setupApplication(); 0081 setupDBus(); 0082 setupEventNotifier(); 0083 setupActions(); 0084 0085 // scan for connected devices 0086 TabletFinder::instance().scan(); 0087 0088 // connect profile changed handler after searching for tablets as this is only used for the global shortcut workaround. 0089 connect(&(d->tabletHandler), &TabletHandler::profileChanged, this, &TabletDaemon::onProfileChanged); 0090 0091 // Connecting this after the device has been set up ensures that no notification is send on startup. 0092 connect(&(d->tabletHandler), &TabletHandler::notify, this, &TabletDaemon::onNotify); 0093 } 0094 0095 TabletDaemon::~TabletDaemon() 0096 { 0097 X11EventNotifier::instance().stop(); 0098 delete this->d_ptr; 0099 } 0100 0101 void TabletDaemon::onNotify(const QString &eventId, const QString &title, const QString &message, bool suggestConfigure) const 0102 { 0103 KNotification *notification = new KNotification(eventId); 0104 notification->setComponentName(QStringLiteral("wacomtablet")); 0105 notification->setTitle(title); 0106 notification->setText(message); 0107 notification->setIconName(QLatin1String("preferences-desktop-tablet")); 0108 0109 if (suggestConfigure) { 0110 #if QT_VERSION_MAJOR == 5 0111 notification->setActions(QStringList{i18nc("Button that shows up in notification of a new tablet being connected", "Configure")}); 0112 connect(notification, &KNotification::action1Activated, this, [notification] { 0113 #else 0114 KNotificationAction *configureAction = 0115 notification->addAction(i18nc("Button that shows up in notification " 0116 "of a new tablet being connected", 0117 "Configure")); 0118 connect(configureAction, &KNotificationAction::activated, this, [notification] { 0119 #endif 0120 auto *job = new KIO::ApplicationLauncherJob(KService::serviceByDesktopName(QStringLiteral("kcm_wacomtablet"))); 0121 job->setStartupId(notification->xdgActivationToken().toUtf8()); 0122 job->start(); 0123 }); 0124 } 0125 0126 notification->sendEvent(); 0127 } 0128 0129 void TabletDaemon::onProfileChanged(const QString &tabletId, const QString &profile) 0130 { 0131 Q_UNUSED(tabletId); 0132 Q_UNUSED(profile); 0133 0134 // When closing the KCM module the KAction destructor disables all global shortcuts. 0135 // Make sure the global shortcuts are restored when a profile changes. This is not 0136 // optimal but at least it will enable the shortcuts again. 0137 qCDebug(KDED) << QLatin1String("Restoring global keyboard shortcuts..."); 0138 setupActions(); 0139 } 0140 0141 void TabletDaemon::setupActions() 0142 { 0143 Q_D(TabletDaemon); 0144 0145 // if someone adds another action also add it to kcmodule/generalwidget.cpp 0146 0147 // This method is called multiple times - make sure the action collection is only created once. 0148 if (!d->actionCollection) { 0149 d->actionCollection = std::shared_ptr<GlobalActions>(new GlobalActions(false, this)); 0150 d->actionCollection->setConfigGlobal(true); 0151 } 0152 0153 connect(d->actionCollection.get(), &GlobalActions::toggleTouchTriggered, &(d->tabletHandler), &TabletHandler::onToggleTouch, Qt::UniqueConnection); 0154 connect(d->actionCollection.get(), &GlobalActions::toggleStylusTriggered, &(d->tabletHandler), &TabletHandler::onTogglePenMode, Qt::UniqueConnection); 0155 connect(d->actionCollection.get(), 0156 &GlobalActions::toggleScreenMapTriggered, 0157 &(d->tabletHandler), 0158 &TabletHandler::onToggleScreenMapping, 0159 Qt::UniqueConnection); 0160 connect(d->actionCollection.get(), &GlobalActions::mapToFullScreenTriggered, &(d->tabletHandler), &TabletHandler::onMapToFullScreen, Qt::UniqueConnection); 0161 connect(d->actionCollection.get(), &GlobalActions::mapToScreen1Triggered, &(d->tabletHandler), &TabletHandler::onMapToScreen1, Qt::UniqueConnection); 0162 connect(d->actionCollection.get(), &GlobalActions::mapToScreen2Triggered, &(d->tabletHandler), &TabletHandler::onMapToScreen2, Qt::UniqueConnection); 0163 connect(d->actionCollection.get(), &GlobalActions::nextProfileTriggered, &(d->tabletHandler), &TabletHandler::onNextProfile, Qt::UniqueConnection); 0164 connect(d->actionCollection.get(), &GlobalActions::previousProfileTriggered, &(d->tabletHandler), &TabletHandler::onPreviousProfile, Qt::UniqueConnection); 0165 } 0166 0167 void TabletDaemon::setupApplication() 0168 { 0169 static AboutData about(QLatin1String("wacomtablet"), 0170 i18n("Graphic Tablet Configuration daemon"), 0171 QLatin1String(WACOMTABLET_VERSION_STRING), 0172 i18n("A Wacom tablet control daemon")); 0173 } 0174 0175 void TabletDaemon::setupDBus() 0176 { 0177 Q_D(TabletDaemon); 0178 0179 // connect tablet handler events to D-Bus 0180 // this is done here and not in the D-Bus tablet service to facilitate unit testing 0181 connect(&(d->tabletHandler), &TabletHandler::profileChanged, &(d->dbusTabletService), &DBusTabletService::onProfileChanged); 0182 connect(&(d->tabletHandler), &TabletHandler::tabletAdded, &(d->dbusTabletService), &DBusTabletService::onTabletAdded); 0183 connect(&(d->tabletHandler), &TabletHandler::tabletRemoved, &(d->dbusTabletService), &DBusTabletService::onTabletRemoved); 0184 } 0185 0186 void TabletDaemon::setupEventNotifier() 0187 { 0188 Q_D(TabletDaemon); 0189 0190 // Set up monitoring for individual screen geometry changes 0191 monitorAllScreensGeometry(); 0192 0193 // Set up monitoring for screens being added, removed or reordered 0194 connect(qApp, &QGuiApplication::primaryScreenChanged, &(d->tabletHandler), &TabletHandler::onScreenAddedRemoved); 0195 connect(qApp, &QGuiApplication::screenAdded, &(d->tabletHandler), &TabletHandler::onScreenAddedRemoved); 0196 connect(qApp, &QGuiApplication::screenRemoved, &(d->tabletHandler), &TabletHandler::onScreenAddedRemoved); 0197 0198 // Set up tablet connected/disconnected signals 0199 connect(&X11EventNotifier::instance(), &X11EventNotifier::tabletAdded, &TabletFinder::instance(), &TabletFinder::onX11TabletAdded); 0200 connect(&X11EventNotifier::instance(), &X11EventNotifier::tabletRemoved, &TabletFinder::instance(), &TabletFinder::onX11TabletRemoved); 0201 0202 connect(&TabletFinder::instance(), &TabletFinder::tabletAdded, &(d->tabletHandler), &TabletHandler::onTabletAdded); 0203 connect(&TabletFinder::instance(), &TabletFinder::tabletRemoved, &(d->tabletHandler), &TabletHandler::onTabletRemoved); 0204 0205 if (QX11Info::isPlatformX11()) { 0206 X11EventNotifier::instance().start(); 0207 } 0208 } 0209 0210 void TabletDaemon::monitorAllScreensGeometry() 0211 { 0212 // Add existing screens 0213 for (const auto &screen : QGuiApplication::screens()) { 0214 monitorScreenGeometry(screen); 0215 } 0216 0217 // Monitor future screens 0218 connect(qApp, &QGuiApplication::screenAdded, this, &TabletDaemon::monitorScreenGeometry); 0219 } 0220 0221 void TabletDaemon::monitorScreenGeometry(QScreen *screen) 0222 { 0223 Q_D(TabletDaemon); 0224 0225 const auto &tabletHandler = &(d->tabletHandler); 0226 0227 connect(screen, &QScreen::orientationChanged, [=](const Qt::ScreenOrientation &newScreenRotation) { 0228 tabletHandler->onScreenRotated(screen->name(), newScreenRotation); 0229 }); 0230 0231 connect(screen, &QScreen::geometryChanged, &(d->tabletHandler), &TabletHandler::onScreenGeometryChanged); 0232 } 0233 0234 #include "tabletdaemon.moc" 0235 0236 #include "moc_tabletdaemon.cpp"