From b84ec175e5fd190a7a19b6a8418f8e1dfde30816 Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Thu, 3 Sep 2015 01:20:30 +0200 Subject: [PATCH 1/7] Added upstream signing key and use it in watch file --- debian/changelog | 19 ++++------ debian/upstream/signing-key.asc | 63 +++++++++++++++++++++++++++++++++ debian/watch | 3 +- 3 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 debian/upstream/signing-key.asc diff --git a/debian/changelog b/debian/changelog index 7c439f5..a4825ec 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,20 +1,13 @@ +lxqt-qtplugin (0.9.0+20150819-2) unstable; urgency=medium + + * add upstream signing key and use it in watch file + + -- Alf Gaida Thu, 03 Sep 2015 01:19:58 +0200 + lxqt-qtplugin (0.9.0+20150819-1) unstable; urgency=medium [ Alf Gaida ] * Initial debian files - * Rebuild only. - - Upstream version 0.8.0. - - Min Qt version 5.3.2. - - Min liblxqt-qt5-dev version 0.8.0. - - removed build dependency libegl1-mesa-dev, as the Qt - bug is fixed. - - bump standards to 3.9.6. - - Short descriptions fixed - * new version 0.9.0 packages renamed debian $foo fixed added - source/options. - * Some cleanup in debian $foo. - * Some changes in debian $foo. - * Drop transitional packages. [ ChangZhuo Chen (陳昌倬) ] * Initial release. (Closes: #747604) diff --git a/debian/upstream/signing-key.asc b/debian/upstream/signing-key.asc new file mode 100644 index 0000000..05cd1df --- /dev/null +++ b/debian/upstream/signing-key.asc @@ -0,0 +1,63 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v2.0.22 (GNU/Linux) + +mQINBFJevCYBEACx+Hvy+Vsuf+V5jeLUnzjAmHoy8DfTeGWr3ts30IapLHrfi0+U +WpzNnISO77yTr4VNboVZH+GHM/rnPfieODfB4ZW6CZLlInMSKUXcgQsEqXpyBZhA +Ib/SPy2bOfHly1uRJes0uRDsH5+v/hD74sByfnjQlrvI68O6wvGZmDFMNNPVO8+/ +OWBSBNkBuVrrZOMSPsLwQGJ4UtUQ4whburaPJG4VZJc5DLbzJGbEuACc0IAEYJS3 +7AfXVXn4j4Gc9F3o1xTUnbOBnwGPquWwUIm3FM7Ec2OdkvMt3EwvnkMAfeVrq3iE +FDD/KZTxdL0BZH3QD8gB7Jm4v4f3Nkobg6JCvCbcH3wBdZW4mASbwWzfRaDC2zHb +ErTglD7PpShLKZZ0pr9okWZEGw4Ku3q8ALi1JXK/ePTmsBlvkVskOJ3Nnd0avgH4 ++Q/vZoKfH8EhNY745rI+8CE9iv6V9XiSUt4CKEWAENt4A8hq6U2vV+jZv3B6AgD7 +ZjiI59yD4YuYubu8rCnNizTgh1voVw3ietknn/x2H5yH8fByWZ5uL87C0ky/uma6 +ZGbiiAtM4kdkyDMrfRV5nlEG9EKAGPVu5mjeSCrfkETwZ9OFPz1AuDye4ZEXrrcC +iRQ7RX6/GtW18aHER0kzGnfwx5KJzkDrRBY8A2PdXLBcrsN4WpK9EX01PQARAQAB +tCNKZXJvbWUgTGVjbGFuY2hlIDxqZXJvbWVAbGVjbGFuLmNoPokCPwQTAQIAKQUC +Ul68JgIbAwUJAeEzgAcLCQgHAwIBBhUIAgkKCwQWAgMBAh4BAheAAAoJEDfgrx/a +SPNzSHIP/1ewXcC0TFBcvDD7MrIP7anyNfiWfW7cxkR8GSamkg6HTa6Ndyr1FFjJ +OoDFUP37jWhu59CsHxs2D0zRWJktezfvElscRgqbHcdpIznqsGdI8hXCZafhBGVb +sdAB2LRawcXGxnXt7XajPcSVwLWRE62caBqohznU2iWvI780WNjEbZoA0LhZwaFF +UUPJm8ea9v0IkZVKUyg9WONZ1U7FEG9SaEiSpI8kJdx1fvCwZVDV/NRO5GqnJaho +P1LCne4YdwS6pt1/fRgk32IHxxZfHlLzLHxb6v1JmIg72x28qCmGyK9oFBDbbnYu +6Aq8XbHogOrD5vJM2Pfm2IhV0+JHOjfQbddv8tsAH1M+LI+tToXmg5st1AU3wnTn +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 +=fF8P +-----END PGP PUBLIC KEY BLOCK----- diff --git a/debian/watch b/debian/watch index 88b56dc..51d59f3 100644 --- a/debian/watch +++ b/debian/watch @@ -1,2 +1,3 @@ version=3 -https://github.com/lxde/lxqt-qtplugin/releases .*/([\d\.]+).tar.gz +opts="pgpsigurlmangle=s/$/.asc/" \ + https://github.com/lxde/lxqt-qtplugin/releases .*/([\d\.]+).tar.gz From 87cb84945df0cf7384a50ec62352a6abbcdbdc4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ChangZhuo=20Chen=20=28=E9=99=B3=E6=98=8C=E5=80=AC=29?= Date: Sat, 12 Sep 2015 23:53:50 +0800 Subject: [PATCH 2/7] Update maintainer email --- debian/control | 2 +- debian/copyright | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/control b/debian/control index 991046e..352d6cc 100644 --- a/debian/control +++ b/debian/control @@ -1,7 +1,7 @@ Source: lxqt-qtplugin Maintainer: LXQt Packaging Team Uploaders: Alf Gaida , - ChangZhuo Chen (陳昌倬) , + ChangZhuo Chen (陳昌倬) , Yukiharu YABUKI Section: x11 Priority: optional diff --git a/debian/copyright b/debian/copyright index f016243..93ee9bb 100644 --- a/debian/copyright +++ b/debian/copyright @@ -15,7 +15,7 @@ License: LGPL-2.1-or-3-with-Digia-1.1-exception Files: debian/* Copyright: 2014-2015 Alf Gaida - 2015 ChangZhuo Chen (陳昌倬) + 2015 ChangZhuo Chen (陳昌倬) 2015 Yukiharu YABUKI License: LGPL-2.1+ From 5932b6960b2b82eff437e3c89e25521cc4065bbf Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Fri, 25 Sep 2015 19:35:42 +0200 Subject: [PATCH 3/7] Cherry-picking upstream version 0.9.0+20150924. Cleaned up debian/.gitignore Switched to experimental because of LXQt namespace change Added minimum version for liblxqt0-dev (>= 0.9.0+20150911) --- .gitignore | 2 - CMakeLists.txt | 2 + debian/.gitignore | 2 - debian/changelog | 10 +- debian/control | 4 +- src/CMakeLists.txt | 21 +- src/lxqtplatformtheme.h | 14 + src/lxqtsystemtrayicon.cpp | 382 ++++++++++++++++++ src/lxqtsystemtrayicon.h | 124 ++++++ src/statusnotifieritem/dbustypes.cpp | 75 ++++ src/statusnotifieritem/dbustypes.h | 60 +++ .../org.kde.StatusNotifierItem.xml | 69 ++++ src/statusnotifieritem/statusnotifieritem.cpp | 299 ++++++++++++++ src/statusnotifieritem/statusnotifieritem.h | 177 ++++++++ 14 files changed, 1231 insertions(+), 10 deletions(-) delete mode 100644 .gitignore create mode 100644 src/lxqtsystemtrayicon.cpp create mode 100644 src/lxqtsystemtrayicon.h create mode 100644 src/statusnotifieritem/dbustypes.cpp create mode 100644 src/statusnotifieritem/dbustypes.h create mode 100644 src/statusnotifieritem/org.kde.StatusNotifierItem.xml create mode 100644 src/statusnotifieritem/statusnotifieritem.cpp create mode 100644 src/statusnotifieritem/statusnotifieritem.h diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 513eaeb..0000000 --- a/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -build -*.kdev4 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4123d62..6c3bcb7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ set(CMAKE_AUTOMOC ON) find_package(Qt5Widgets REQUIRED QUIET) find_package(Qt5LinguistTools REQUIRED QUIET) +find_package(Qt5DBus REQUIRED QUIET) +find_package(dbusmenu-qt5 REQUIRED QUIET) find_package(lxqt REQUIRED QUIET) diff --git a/debian/.gitignore b/debian/.gitignore index 7502a9f..469769b 100644 --- a/debian/.gitignore +++ b/debian/.gitignore @@ -5,5 +5,3 @@ /lxqt-qtplugin/ /lxqt-qtplugin-dbg/ -/lxqt-qtplugin-qt5/ -/lxqt-qtplugin-qt5-dbg/ diff --git a/debian/changelog b/debian/changelog index a4825ec..a7e4e04 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,12 @@ -lxqt-qtplugin (0.9.0+20150819-2) unstable; urgency=medium +lxqt-qtplugin (0.9.0+20150924-1) experimental; urgency=medium + * Cherry-picked upstream version 0.9.0+20150924. * add upstream signing key and use it in watch file - - -- Alf Gaida Thu, 03 Sep 2015 01:19:58 +0200 + * Cleaned up debian/.gitignore + * Switched to experimental because of LXQt namespace change + * Added minimum version for liblxqt0-dev (>= 0.9.0+20150911) + + -- Alf Gaida Fri, 25 Sep 2015 19:35:21 +0200 lxqt-qtplugin (0.9.0+20150819-1) unstable; urgency=medium diff --git a/debian/control b/debian/control index 352d6cc..c2eb43f 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Priority: optional Build-Depends: debhelper (>= 9), cmake (>= 3.0.2), libkf5windowsystem-dev, - liblxqt0-dev, + liblxqt0-dev (>= 0.9.0+20150911), libqt5x11extras5-dev, libqt5xdg-dev, libx11-dev, @@ -29,7 +29,7 @@ Description: LXQt system integration plugin for Qt With this plugin, all Qt-based programs can adopt settings of LXQt, such as the icon theme. . - This package provides the lxqt qtplugin interface. + This package provides the lxqt qtplugin interface. Package: lxqt-qtplugin-dbg Architecture: any diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d65d813..7922b83 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,15 +3,34 @@ include_directories( "${CMAKE_CURRENT_BINARY_DIR}" ) +set(qtlxqt_HDRS + lxqtplatformtheme.h + lxqtsystemtrayicon.h + statusnotifieritem/statusnotifieritem.h + statusnotifieritem/dbustypes.h +) + set(qtlxqt_SRCS main.cpp lxqtplatformtheme.cpp + lxqtsystemtrayicon.cpp + statusnotifieritem/statusnotifieritem.cpp + statusnotifieritem/dbustypes.cpp +) + +qt5_add_dbus_adaptor(qtlxqt_SRCS + statusnotifieritem/org.kde.StatusNotifierItem.xml + statusnotifieritem/statusnotifieritem.h + StatusNotifierItem ) -add_library(qtlxqt SHARED ${qtlxqt_SRCS}) +add_library(qtlxqt SHARED ${qtlxqt_HDRS} ${qtlxqt_SRCS}) target_link_libraries(qtlxqt Qt5::Widgets + Qt5::DBus + dbusmenu-qt5 + lxqt ) # there is no standard way to get the plugin dir of Qt5 with cmake diff --git a/src/lxqtplatformtheme.h b/src/lxqtplatformtheme.h index 42f8ccf..5ad6d34 100644 --- a/src/lxqtplatformtheme.h +++ b/src/lxqtplatformtheme.h @@ -28,6 +28,8 @@ #ifndef LXQTPLATFORMTHEME_H #define LXQTPLATFORMTHEME_H +#include "lxqtsystemtrayicon.h" + #include // this private header is subject to changes #include #include @@ -54,6 +56,18 @@ public: virtual QVariant themeHint(ThemeHint hint) const; + QPlatformSystemTrayIcon *createPlatformSystemTrayIcon() const + { + auto trayIcon = new LXQtSystemTrayIcon; + if (trayIcon->isSystemTrayAvailable()) + return trayIcon; + else + { + delete trayIcon; + return nullptr; + } + } + // virtual QPixmap standardPixmap(StandardPixmap sp, const QSizeF &size) const; // virtual QPixmap fileIconPixmap(const QFileInfo &fileInfo, const QSizeF &size, // QPlatformTheme::IconOptions iconOptions = 0) const; diff --git a/src/lxqtsystemtrayicon.cpp b/src/lxqtsystemtrayicon.cpp new file mode 100644 index 0000000..1df4dd0 --- /dev/null +++ b/src/lxqtsystemtrayicon.cpp @@ -0,0 +1,382 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org/ + * + * Copyright: 2015 LXQt team + * Authors: + * Paulo Lieuthier + * + * This program or 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.1 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; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "lxqtsystemtrayicon.h" +#include +#include +#include +#include +#include +#include +#include + +SystemTrayMenu::SystemTrayMenu() + : QPlatformMenu(), + m_tag(0), + m_menu(new QMenu()) +{ + connect(m_menu.data(), &QMenu::aboutToShow, this, &QPlatformMenu::aboutToShow); + connect(m_menu.data(), &QMenu::aboutToHide, this, &QPlatformMenu::aboutToHide); +} + +SystemTrayMenu::~SystemTrayMenu() +{ + if (m_menu) + m_menu->deleteLater(); +} + +QPlatformMenuItem *SystemTrayMenu::createMenuItem() const +{ + return new SystemTrayMenuItem(); +} + +void SystemTrayMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) +{ + if (SystemTrayMenuItem *ours = qobject_cast(menuItem)) + { + bool inserted = false; + + if (SystemTrayMenuItem *oursBefore = qobject_cast(before)) + { + for (auto it = m_items.begin(); it != m_items.end(); ++it) + { + if (*it == oursBefore) + { + m_items.insert(it, ours); + if (m_menu) + m_menu->insertAction(oursBefore->action(), ours->action()); + + inserted = true; + break; + } + } + } + + if (!inserted) + { + m_items.append(ours); + if (m_menu) + m_menu->addAction(ours->action()); + } + } +} + +QPlatformMenuItem *SystemTrayMenu::menuItemAt(int position) const +{ + if (position < m_items.size()) + return m_items.at(position); + + return nullptr; +} + +QPlatformMenuItem *SystemTrayMenu::menuItemForTag(quintptr tag) const +{ + auto it = std::find_if(m_items.constBegin(), m_items.constEnd(), [tag] (SystemTrayMenuItem *item) + { + return item->tag() == tag; + }); + + if (it != m_items.constEnd()) + return *it; + + return nullptr; +} + +void SystemTrayMenu::removeMenuItem(QPlatformMenuItem *menuItem) +{ + if (SystemTrayMenuItem *ours = qobject_cast(menuItem)) + { + m_items.removeOne(ours); + if (ours->action() && m_menu) + m_menu->removeAction(ours->action()); + } +} + +void SystemTrayMenu::setEnabled(bool enabled) +{ + if (!m_menu) + return; + + m_menu->setEnabled(enabled); +} + +void SystemTrayMenu::setIcon(const QIcon &icon) +{ + if (!m_menu) + return; + + m_menu->setIcon(icon); +} + +void SystemTrayMenu::setTag(quintptr tag) +{ + m_tag = tag; +} + +void SystemTrayMenu::setText(const QString &text) +{ + if (!m_menu) + return; + + m_menu->setTitle(text); +} + +void SystemTrayMenu::setVisible(bool visible) +{ + if (!m_menu) + return; + + m_menu->setVisible(visible); +} + +void SystemTrayMenu::syncMenuItem(QPlatformMenuItem *) +{ + // Nothing to do +} + +void SystemTrayMenu::syncSeparatorsCollapsible(bool enable) +{ + if (!m_menu) + return; + + m_menu->setSeparatorsCollapsible(enable); +} + +quintptr SystemTrayMenu::tag() const +{ + return m_tag; +} + +QMenu *SystemTrayMenu::menu() const +{ + return m_menu.data(); +} + +SystemTrayMenuItem::SystemTrayMenuItem() + : QPlatformMenuItem(), + m_tag(0), + m_action(new QAction(this)) +{ + connect(m_action, &QAction::triggered, this, &QPlatformMenuItem::activated); + connect(m_action, &QAction::hovered, this, &QPlatformMenuItem::hovered); +} + +SystemTrayMenuItem::~SystemTrayMenuItem() +{ +} + +void SystemTrayMenuItem::setCheckable(bool checkable) +{ + m_action->setCheckable(checkable); +} + +void SystemTrayMenuItem::setChecked(bool isChecked) +{ + m_action->setChecked(isChecked); +} + +void SystemTrayMenuItem::setEnabled(bool enabled) +{ + m_action->setEnabled(enabled); +} + +void SystemTrayMenuItem::setFont(const QFont &font) +{ + m_action->setFont(font); +} + +void SystemTrayMenuItem::setIcon(const QIcon &icon) +{ + m_action->setIcon(icon); +} + +void SystemTrayMenuItem::setIsSeparator(bool isSeparator) +{ + m_action->setSeparator(isSeparator); +} + +void SystemTrayMenuItem::setMenu(QPlatformMenu *menu) +{ + if (SystemTrayMenu *ourMenu = qobject_cast(menu)) + m_action->setMenu(ourMenu->menu()); +} + +void SystemTrayMenuItem::setRole(QPlatformMenuItem::MenuRole) +{ +} + +void SystemTrayMenuItem::setShortcut(const QKeySequence &shortcut) +{ + m_action->setShortcut(shortcut); +} + +void SystemTrayMenuItem::setTag(quintptr tag) +{ + m_tag = tag; +} + +void SystemTrayMenuItem::setText(const QString &text) +{ + m_action->setText(text); +} + +void SystemTrayMenuItem::setVisible(bool isVisible) +{ + m_action->setVisible(isVisible); +} + +void SystemTrayMenuItem::setIconSize(int) +{ +} + +quintptr SystemTrayMenuItem::tag() const +{ + return m_tag; +} + +QAction *SystemTrayMenuItem::action() const +{ + return m_action; +} + +LXQtSystemTrayIcon::LXQtSystemTrayIcon() + : QPlatformSystemTrayIcon(), + mSni(nullptr) +{ + // register types + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); + qDBusRegisterMetaType(); +} + +LXQtSystemTrayIcon::~LXQtSystemTrayIcon() +{ +} + +void LXQtSystemTrayIcon::init() +{ + if (!mSni) + { + mSni = new StatusNotifierItem(QString::number(QCoreApplication::applicationPid()), this); + mSni->setTitle(QApplication::applicationDisplayName()); + + // default menu + QPlatformMenu *menu = createMenu(); + menu->setParent(this); + QPlatformMenuItem *menuItem = menu->createMenuItem(); + menuItem->setParent(menu); + menuItem->setText(tr("Quit")); + menuItem->setIcon(QIcon::fromTheme("application-exit")); + connect(menuItem, &QPlatformMenuItem::activated, qApp, &QApplication::quit); + menu->insertMenuItem(menuItem, nullptr); + updateMenu(menu); + + connect(mSni, &StatusNotifierItem::activateRequested, [this](const QPoint &) + { + emit activated(QPlatformSystemTrayIcon::Trigger); + }); + + connect(mSni, &StatusNotifierItem::secondaryActivateRequested, [this](const QPoint &) + { + emit activated(QPlatformSystemTrayIcon::MiddleClick); + }); + } +} + +void LXQtSystemTrayIcon::cleanup() +{ + delete mSni; + mSni = nullptr; +} + +void LXQtSystemTrayIcon::updateIcon(const QIcon &icon) +{ + if (!mSni) + return; + + if (icon.name().isEmpty()) + { + mSni->setIconByPixmap(icon); + mSni->setToolTipIconByPixmap(icon); + } + else + { + mSni->setIconByName(icon.name()); + mSni->setToolTipIconByName(icon.name()); + } +} + +void LXQtSystemTrayIcon::updateToolTip(const QString &tooltip) +{ + if (!mSni) + return; + + mSni->setToolTipTitle(tooltip); +} + +void LXQtSystemTrayIcon::updateMenu(QPlatformMenu *menu) +{ + if (!mSni) + return; + + if (SystemTrayMenu *ourMenu = qobject_cast(menu)) + mSni->setContextMenu(ourMenu->menu()); +} + +QPlatformMenu *LXQtSystemTrayIcon::createMenu() const +{ + return new SystemTrayMenu(); +} + +QRect LXQtSystemTrayIcon::geometry() const +{ + // StatusNotifierItem doesn't provide the geometry + return QRect(); +} + +void LXQtSystemTrayIcon::showMessage(const QString &title, const QString &msg, + const QIcon &icon, MessageIcon, int secs) +{ + if (!mSni) + return; + + mSni->showMessage(title, msg, icon.name(), secs); +} + +bool LXQtSystemTrayIcon::isSystemTrayAvailable() const +{ + QDBusInterface systrayHost("org.kde.StatusNotifierWatcher", + "/StatusNotifierWatcher", + "org.kde.StatusNotifierWatcher"); + + return systrayHost.isValid() && systrayHost.property("IsStatusNotifierHostRegistered").toBool(); +} + +bool LXQtSystemTrayIcon::supportsMessages() const +{ + return true; +} diff --git a/src/lxqtsystemtrayicon.h b/src/lxqtsystemtrayicon.h new file mode 100644 index 0000000..4aed10c --- /dev/null +++ b/src/lxqtsystemtrayicon.h @@ -0,0 +1,124 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org/ + * + * Copyright: 2015 LXQt team + * Authors: + * Paulo Lieuthier + * + * This program or 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.1 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; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#ifndef LXQTSYSTEMTRAYICON_H +#define LXQTSYSTEMTRAYICON_H + +#include +#include + +#include "statusnotifieritem/statusnotifieritem.h" + +class SystemTrayMenuItem; +class QAction; +class QMenu; + +class SystemTrayMenu : public QPlatformMenu +{ + Q_OBJECT +public: + SystemTrayMenu(); + ~SystemTrayMenu() Q_DECL_OVERRIDE; + void insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) Q_DECL_OVERRIDE; + QPlatformMenuItem *menuItemAt(int position) const Q_DECL_OVERRIDE; + QPlatformMenuItem *menuItemForTag(quintptr tag) const Q_DECL_OVERRIDE; + void removeMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void setEnabled(bool enabled) Q_DECL_OVERRIDE; + void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void setTag(quintptr tag) Q_DECL_OVERRIDE; + void setText(const QString &text) Q_DECL_OVERRIDE; + void setVisible(bool visible) Q_DECL_OVERRIDE; + void syncMenuItem(QPlatformMenuItem *menuItem) Q_DECL_OVERRIDE; + void syncSeparatorsCollapsible(bool enable) Q_DECL_OVERRIDE; + quintptr tag() const Q_DECL_OVERRIDE; + QPlatformMenuItem *createMenuItem() const Q_DECL_OVERRIDE; + + QMenu *menu() const; + +private: + quintptr m_tag; + QPointer m_menu; + QList m_items; +}; + +class SystemTrayMenuItem : public QPlatformMenuItem +{ + Q_OBJECT +public: + SystemTrayMenuItem(); + ~SystemTrayMenuItem() Q_DECL_OVERRIDE; + void setCheckable(bool checkable) Q_DECL_OVERRIDE; + void setChecked(bool isChecked) Q_DECL_OVERRIDE; + void setEnabled(bool enabled) Q_DECL_OVERRIDE; + void setFont(const QFont &font) Q_DECL_OVERRIDE; + void setIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void setIsSeparator(bool isSeparator) Q_DECL_OVERRIDE; + void setMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + void setRole(MenuRole role) Q_DECL_OVERRIDE; + void setShortcut(const QKeySequence &shortcut) Q_DECL_OVERRIDE; + void setTag(quintptr tag) Q_DECL_OVERRIDE; + void setText(const QString &text) Q_DECL_OVERRIDE; + void setVisible(bool isVisible) Q_DECL_OVERRIDE; + quintptr tag() const Q_DECL_OVERRIDE; + void setIconSize(int size) + #if (QT_VERSION >= QT_VERSION_CHECK(5, 4, 0)) + Q_DECL_OVERRIDE + #endif + ; + + QAction *action() const; + +private: + quintptr m_tag; + QAction *m_action; +}; + +class LXQtSystemTrayIcon : public QPlatformSystemTrayIcon +{ +public: + LXQtSystemTrayIcon(); + ~LXQtSystemTrayIcon() Q_DECL_OVERRIDE; + + void init() Q_DECL_OVERRIDE; + void cleanup() Q_DECL_OVERRIDE; + void updateIcon(const QIcon &icon) Q_DECL_OVERRIDE; + void updateToolTip(const QString &tooltip) Q_DECL_OVERRIDE; + void updateMenu(QPlatformMenu *menu) Q_DECL_OVERRIDE; + QRect geometry() const Q_DECL_OVERRIDE; + void showMessage(const QString &title, const QString &msg, + const QIcon &icon, MessageIcon iconType, int secs) Q_DECL_OVERRIDE; + + bool isSystemTrayAvailable() const Q_DECL_OVERRIDE; + bool supportsMessages() const Q_DECL_OVERRIDE; + + QPlatformMenu *createMenu() const Q_DECL_OVERRIDE; + +private: + StatusNotifierItem *mSni; +}; + +#endif diff --git a/src/statusnotifieritem/dbustypes.cpp b/src/statusnotifieritem/dbustypes.cpp new file mode 100644 index 0000000..758bfed --- /dev/null +++ b/src/statusnotifieritem/dbustypes.cpp @@ -0,0 +1,75 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXDE-Qt - a lightweight, Qt based, desktop toolset + * http://lxqt.org + * + * Copyright: 2015 LXQt team + * Authors: + * Balázs Béla + * Paulo Lieuthier + * + * This program or 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.1 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; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "dbustypes.h" + +// Marshall the IconPixmap data into a D-Bus argument +QDBusArgument &operator<<(QDBusArgument &argument, const IconPixmap &icon) +{ + argument.beginStructure(); + argument << icon.width; + argument << icon.height; + argument << icon.bytes; + argument.endStructure(); + return argument; +} + +// Retrieve the ImageStruct data from the D-Bus argument +const QDBusArgument &operator>>(const QDBusArgument &argument, IconPixmap &icon) +{ + argument.beginStructure(); + argument >> icon.width; + argument >> icon.height; + argument >> icon.bytes; + argument.endStructure(); + return argument; +} + +// Marshall the ToolTip data into a D-Bus argument +QDBusArgument &operator<<(QDBusArgument &argument, const ToolTip &toolTip) +{ + argument.beginStructure(); + argument << toolTip.iconName; + argument << toolTip.iconPixmap; + argument << toolTip.title; + argument << toolTip.description; + argument.endStructure(); + return argument; +} + +// Retrieve the ToolTip data from the D-Bus argument +const QDBusArgument &operator>>(const QDBusArgument &argument, ToolTip &toolTip) +{ + argument.beginStructure(); + argument >> toolTip.iconName; + argument >> toolTip.iconPixmap; + argument >> toolTip.title; + argument >> toolTip.description; + argument.endStructure(); + return argument; +} diff --git a/src/statusnotifieritem/dbustypes.h b/src/statusnotifieritem/dbustypes.h new file mode 100644 index 0000000..cc6f9a5 --- /dev/null +++ b/src/statusnotifieritem/dbustypes.h @@ -0,0 +1,60 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXDE-Qt - a lightweight, Qt based, desktop toolset + * http://lxqt.org + * + * Copyright: 2015 LXQt team + * Authors: + * Balázs Béla + * Paulo Lieuthier + * + * This program or 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.1 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; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include + +#ifndef DBUSTYPES_H +#define DBUSTYPES_H + +struct IconPixmap { + int width; + int height; + QByteArray bytes; +}; + +typedef QList IconPixmapList; + +Q_DECLARE_METATYPE(IconPixmap) +Q_DECLARE_METATYPE(IconPixmapList) + +struct ToolTip { + QString iconName; + QList iconPixmap; + QString title; + QString description; +}; + +Q_DECLARE_METATYPE(ToolTip) + +QDBusArgument &operator<<(QDBusArgument &argument, const IconPixmap &icon); +const QDBusArgument &operator>>(const QDBusArgument &argument, IconPixmap &icon); + +QDBusArgument &operator<<(QDBusArgument &argument, const ToolTip &toolTip); +const QDBusArgument &operator>>(const QDBusArgument &argument, ToolTip &toolTip); + +#endif // DBUSTYPES_H diff --git a/src/statusnotifieritem/org.kde.StatusNotifierItem.xml b/src/statusnotifieritem/org.kde.StatusNotifierItem.xml new file mode 100644 index 0000000..0a563c5 --- /dev/null +++ b/src/statusnotifieritem/org.kde.StatusNotifierItem.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/statusnotifieritem/statusnotifieritem.cpp b/src/statusnotifieritem/statusnotifieritem.cpp new file mode 100644 index 0000000..8d24f97 --- /dev/null +++ b/src/statusnotifieritem/statusnotifieritem.cpp @@ -0,0 +1,299 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org/ + * + * Copyright: 2015 LXQt team + * Authors: + * Paulo Lieuthier + * + * This program or 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.1 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; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + +#include "statusnotifieritem.h" +#include "statusnotifieritemadaptor.h" +#include +#include +#include + +int StatusNotifierItem::mServiceCounter = 0; + +StatusNotifierItem::StatusNotifierItem(QString id, QObject *parent) + : QObject(parent), + mAdaptor(new StatusNotifierItemAdaptor(this)), + mService(QString("org.freedesktop.StatusNotifierItem-%1-%2") + .arg(QCoreApplication::applicationPid()) + .arg(++mServiceCounter)), + mId(id), + mTitle("Test"), + mStatus("Active"), + mMenu(nullptr) +{ + // register service + QDBusConnection::sessionBus().registerService(mService); + QDBusConnection::sessionBus().registerObject("/StatusNotifierItem", this); + + registerToHost(); + + // monitor the watcher service in case the host restarts + QDBusServiceWatcher *watcher = new QDBusServiceWatcher("org.kde.StatusNotifierWatcher", + QDBusConnection::sessionBus(), + QDBusServiceWatcher::WatchForOwnerChange, + this); + connect(watcher, &QDBusServiceWatcher::serviceOwnerChanged, + this, &StatusNotifierItem::onServiceOwnerChanged); +} + +StatusNotifierItem::~StatusNotifierItem() +{ + QDBusConnection::sessionBus().unregisterObject("/StatusNotifierItem"); + QDBusConnection::sessionBus().unregisterService(mService); + QDBusConnection::sessionBus().disconnectFromBus(mService); + + delete mMenu; +} + +void StatusNotifierItem::registerToHost() +{ + QDBusInterface interface("org.kde.StatusNotifierWatcher", + "/StatusNotifierWatcher", + "org.kde.StatusNotifierWatcher", + QDBusConnection::sessionBus()); + interface.asyncCall("RegisterStatusNotifierItem", mService); +} + +void StatusNotifierItem::onServiceOwnerChanged(const QString& service, const QString& oldOwner, + const QString& newOwner) +{ + if (!newOwner.isEmpty()) + registerToHost(); +} + +void StatusNotifierItem::setTitle(const QString &title) +{ + if (mTitle == title) + return; + + mTitle = title; + emit mAdaptor->NewTitle(); +} + +void StatusNotifierItem::setStatus(const QString &status) +{ + if (mStatus == status) + return; + + mStatus = status; + emit mAdaptor->NewStatus(mStatus); +} + +void StatusNotifierItem::setMenuPath(const QString& path) +{ + mMenuPath.setPath(path); +} + +void StatusNotifierItem::setIconByName(const QString &name) +{ + if (mIconName == name) + return; + + mIconName = name; + emit mAdaptor->NewIcon(); +} + +void StatusNotifierItem::setIconByPixmap(const QIcon &icon) +{ + if (mIconCacheKey == icon.cacheKey()) + return; + + mIconCacheKey = icon.cacheKey(); + mIcon = iconToPixmapList(icon); + mIconName.clear(); + emit mAdaptor->NewIcon(); +} + +void StatusNotifierItem::setOverlayIconByName(const QString &name) +{ + if (mOverlayIconName == name) + return; + + mOverlayIconName = name; + emit mAdaptor->NewOverlayIcon(); +} + +void StatusNotifierItem::setOverlayIconByPixmap(const QIcon &icon) +{ + if (mOverlayIconCacheKey == icon.cacheKey()) + return; + + mOverlayIconCacheKey = icon.cacheKey(); + mOverlayIcon = iconToPixmapList(icon); + mOverlayIconName.clear(); + emit mAdaptor->NewOverlayIcon(); +} + +void StatusNotifierItem::setAttentionIconByName(const QString &name) +{ + if (mAttentionIconName == name) + return; + + mAttentionIconName = name; + emit mAdaptor->NewAttentionIcon(); +} + +void StatusNotifierItem::setAttentionIconByPixmap(const QIcon &icon) +{ + if (mAttentionIconCacheKey == icon.cacheKey()) + return; + + mAttentionIconCacheKey = icon.cacheKey(); + mAttentionIcon = iconToPixmapList(icon); + mAttentionIconName.clear(); + emit mAdaptor->NewAttentionIcon(); +} + +void StatusNotifierItem::setToolTipTitle(const QString &title) +{ + if (mTooltipTitle == title) + return; + + mTooltipTitle = title; + emit mAdaptor->NewToolTip(); +} + +void StatusNotifierItem::setToolTipSubTitle(const QString &subTitle) +{ + if (mTooltipSubtitle == subTitle) + return; + + mTooltipSubtitle = subTitle; + emit mAdaptor->NewToolTip(); +} + +void StatusNotifierItem::setToolTipIconByName(const QString &name) +{ + if (mTooltipIconName == name) + return; + + mTooltipIconName = name; + emit mAdaptor->NewToolTip(); +} + +void StatusNotifierItem::setToolTipIconByPixmap(const QIcon &icon) +{ + if (mTooltipIconCacheKey == icon.cacheKey()) + return; + + mTooltipIconCacheKey = icon.cacheKey(); + mTooltipIcon = iconToPixmapList(icon); + mTooltipIconName.clear(); + emit mAdaptor->NewToolTip(); +} + +void StatusNotifierItem::setContextMenu(QMenu* menu) +{ + if (mMenu == menu) + return; + + delete mMenu; + mMenu = menu; + mMenu->setParent(nullptr); + + setMenuPath("/MenuBar"); + new DBusMenuExporter(this->menu().path(), mMenu); +} + +void StatusNotifierItem::Activate(int x, int y) +{ + if (mStatus == "NeedsAttention") + mStatus = "Active"; + + emit activateRequested(QPoint(x, y)); +} + +void StatusNotifierItem::SecondaryActivate(int x, int y) +{ + if (mStatus == "NeedsAttention") + mStatus = "Active"; + + emit secondaryActivateRequested(QPoint(x, y)); +} + +void StatusNotifierItem::ContextMenu(int x, int y) +{ + if (mMenu) + { + if (mMenu->isVisible()) + mMenu->popup(QPoint(x, y)); + else + mMenu->hide(); + } +} + +void StatusNotifierItem::Scroll(int delta, const QString &orientation) +{ + Qt::Orientation orient = Qt::Vertical; + if (orientation.toLower() == "horizontal") + orient = Qt::Horizontal; + + emit scrollRequested(delta, orient); +} + +void StatusNotifierItem::showMessage(const QString& title, const QString& msg, + const QString& iconName, int secs) +{ + QDBusInterface interface("org.freedesktop.Notifications", "/org/freedesktop/Notifications", + "org.freedesktop.Notifications", QDBusConnection::sessionBus()); + interface.call("Notify", mTitle, (uint) 0, iconName, title, + msg, QStringList(), QVariantMap(), secs); +} + +IconPixmapList StatusNotifierItem::iconToPixmapList(const QIcon& icon) +{ + IconPixmapList pixmapList; + + // long live KDE! + for (const QSize &size : icon.availableSizes()) + { + QImage image = icon.pixmap(size).toImage(); + + IconPixmap pix; + pix.height = image.height(); + pix.width = image.width(); + + if (image.format() != QImage::Format_ARGB32) + image = image.convertToFormat(QImage::Format_ARGB32); + + pix.bytes = QByteArray((char *) image.bits(), image.byteCount()); + + // swap to network byte order if we are little endian + if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) + { + quint32 *uintBuf = (quint32 *) pix.bytes.data(); + for (uint i = 0; i < pix.bytes.size() / sizeof(quint32); ++i) + { + *uintBuf = qToBigEndian(*uintBuf); + ++uintBuf; + } + } + + pixmapList.append(pix); + } + + return pixmapList; +} diff --git a/src/statusnotifieritem/statusnotifieritem.h b/src/statusnotifieritem/statusnotifieritem.h new file mode 100644 index 0000000..e55eedd --- /dev/null +++ b/src/statusnotifieritem/statusnotifieritem.h @@ -0,0 +1,177 @@ +/* BEGIN_COMMON_COPYRIGHT_HEADER + * (c)LGPL2+ + * + * LXQt - a lightweight, Qt based, desktop toolset + * http://lxqt.org/ + * + * Copyright: 2015 LXQt team + * Authors: + * Paulo Lieuthier + * + * This program or 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.1 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; if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + * + * END_COMMON_COPYRIGHT_HEADER */ + + +#ifndef STATUS_NOTIFIER_ITEM_H +#define STATUS_NOTIFIER_ITEM_H + +#include +#include +#include + +#include "dbustypes.h" + +class StatusNotifierItemAdaptor; + +class StatusNotifierItem : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString Title READ title) + Q_PROPERTY(QString Id READ id) + Q_PROPERTY(QString Status READ status) + Q_PROPERTY(QDBusObjectPath Menu READ menu) + + Q_PROPERTY(QString IconName READ iconName) + Q_PROPERTY(IconPixmapList IconPixmap READ iconPixmap) + + Q_PROPERTY(QString OverlayIconName READ overlayIconName) + Q_PROPERTY(IconPixmapList OverlayIconPixmap READ overlayIconPixmap) + + Q_PROPERTY(QString AttentionIconName READ attentionIconName) + Q_PROPERTY(IconPixmapList AttentionIconPixmap READ attentionIconPixmap) + + Q_PROPERTY(ToolTip ToolTip READ toolTip) + +public: + StatusNotifierItem(QString id, QObject *parent = nullptr); + ~StatusNotifierItem(); + + QString id() const + { return mId; } + + QString title() const + { return mTitle; } + void setTitle(const QString &title); + + QString status() const + { return mStatus; } + void setStatus(const QString &status); + + QDBusObjectPath menu() const + { return mMenuPath; } + void setMenuPath(const QString &path); + + QString iconName() const + { return mIconName; } + void setIconByName(const QString &name); + + IconPixmapList iconPixmap() const + { return mIcon; } + void setIconByPixmap(const QIcon &icon); + + QString overlayIconName() const + { return mOverlayIconName; } + void setOverlayIconByName(const QString &name); + + IconPixmapList overlayIconPixmap() const + { return mOverlayIcon; } + void setOverlayIconByPixmap(const QIcon &icon); + + QString attentionIconName() const + { return mAttentionIconName; } + void setAttentionIconByName(const QString &name); + + IconPixmapList attentionIconPixmap() const + { return mAttentionIcon; } + void setAttentionIconByPixmap(const QIcon &icon); + + QString toolTipTitle() const + { return mTooltipTitle; } + void setToolTipTitle(const QString &title); + + QString toolTipSubTitle() const + { return mTooltipSubtitle; } + void setToolTipSubTitle(const QString &subTitle); + + QString toolTipIconName() const + { return mTooltipIconName; } + void setToolTipIconByName(const QString &name); + + IconPixmapList toolTipIconPixmap() const + { return mTooltipIcon; } + void setToolTipIconByPixmap(const QIcon &icon); + + ToolTip toolTip() const + { + ToolTip tt; + tt.title = mTooltipTitle; + tt.description = mTooltipSubtitle; + tt.iconName = mTooltipIconName; + tt.iconPixmap = mTooltipIcon; + return tt; + } + + void setContextMenu(QMenu *menu); + +public slots: + void Activate(int x, int y); + void SecondaryActivate(int x, int y); + void ContextMenu(int x, int y); + void Scroll(int delta, const QString &orientation); + + void showMessage(const QString &title, const QString &msg, const QString &iconName, int secs); + +private: + void registerToHost(); + IconPixmapList iconToPixmapList(const QIcon &icon); + +private slots: + void onServiceOwnerChanged(const QString &service, const QString &oldOwner, + const QString &newOwner); + +signals: + void activateRequested(const QPoint &pos); + void secondaryActivateRequested(const QPoint &pos); + void scrollRequested(int delta, Qt::Orientation orientation); + +private: + StatusNotifierItemAdaptor *mAdaptor; + + QString mService; + QString mId; + QString mTitle; + QString mStatus; + + // icons + QString mIconName, mOverlayIconName, mAttentionIconName; + IconPixmapList mIcon, mOverlayIcon, mAttentionIcon; + qint64 mIconCacheKey, mOverlayIconCacheKey, mAttentionIconCacheKey; + + // tooltip + QString mTooltipTitle, mTooltipSubtitle, mTooltipIconName; + IconPixmapList mTooltipIcon; + qint64 mTooltipIconCacheKey; + + // menu + QMenu *mMenu; + QDBusObjectPath mMenuPath; + + static int mServiceCounter; +}; + +#endif From 94c9dca3c08cf15d9174e0fdfe5ad4f227950fe1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ChangZhuo=20Chen=20=28=E9=99=B3=E6=98=8C=E5=80=AC=29?= Date: Fri, 2 Oct 2015 20:41:09 +0800 Subject: [PATCH 4/7] Add missing Build-Depends --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index c2eb43f..6298dca 100644 --- a/debian/control +++ b/debian/control @@ -7,6 +7,7 @@ Section: x11 Priority: optional Build-Depends: debhelper (>= 9), cmake (>= 3.0.2), + libdbusmenu-qt5-dev, libkf5windowsystem-dev, liblxqt0-dev (>= 0.9.0+20150911), libqt5x11extras5-dev, From dfae352f6a45ab7affb823f8b4cf58b5c1ac8e18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?ChangZhuo=20Chen=20=28=E9=99=B3=E6=98=8C=E5=80=AC=29?= Date: Fri, 2 Oct 2015 20:51:13 +0800 Subject: [PATCH 5/7] Remove trailing space --- debian/changelog | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index a7e4e04..0003d87 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,7 +5,7 @@ lxqt-qtplugin (0.9.0+20150924-1) experimental; urgency=medium * Cleaned up debian/.gitignore * Switched to experimental because of LXQt namespace change * Added minimum version for liblxqt0-dev (>= 0.9.0+20150911) - + -- Alf Gaida Fri, 25 Sep 2015 19:35:21 +0200 lxqt-qtplugin (0.9.0+20150819-1) unstable; urgency=medium From fe0fb5c3863276ca455495f4d7d1daa6b1f164db Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Sat, 31 Oct 2015 01:20:56 +0100 Subject: [PATCH 6/7] Cherry-picking upstream version 0.9.0+20151025. set new minimal versions for liblxqt and libqtxdg --- AUTHORS | 5 ++--- COPYING | 2 +- Digia-Qt-LGPL-Exception-version-1.1 | 25 +++++++++++++++++++++++++ debian/changelog | 8 ++++---- debian/control | 4 ++-- src/lxqtplatformtheme.cpp | 9 +++------ 6 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 Digia-Qt-LGPL-Exception-version-1.1 diff --git a/AUTHORS b/AUTHORS index 8e41b63..06a7892 100644 --- a/AUTHORS +++ b/AUTHORS @@ -5,7 +5,6 @@ Upstream Authors: Copyright: Copyright (c) 2013-2014 LXQt team -License: GPL-2 and LGPL-2.1+ +License: LGPL-2.1+ The full text of the licenses can be found in the 'COPYING' file. - -Based on source code from the Qt 4.8 Project by Digia Plc +src/qiconloader_p.h is under LGPL-2.1 or 3 with Digia Qt LGPL Exception version 1.1 diff --git a/COPYING b/COPYING index a8dd823..ab31941 100644 --- a/COPYING +++ b/COPYING @@ -3,7 +3,7 @@ Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. diff --git a/Digia-Qt-LGPL-Exception-version-1.1 b/Digia-Qt-LGPL-Exception-version-1.1 new file mode 100644 index 0000000..6e6fb3a --- /dev/null +++ b/Digia-Qt-LGPL-Exception-version-1.1 @@ -0,0 +1,25 @@ +Digia Qt LGPL Exception version 1.1 +=================================== + +As an additional permission to the GNU Lesser General Public License version +2.1, the object code form of a "work that uses the Library" may incorporate +material from a header file that is part of the Library. You may distribute +such object code under terms of your choice, provided that: + + (i) the header files of the Library have not been modified; and + (ii) the incorporated material is limited to numerical parameters, data + structure layouts, accessors, macros, inline functions and + templates; and + (iii) you comply with the terms of Section 6 of the GNU Lesser General + Public License version 2.1. + +Moreover, you may apply this exception to a modified version of the Library, +provided that such modification does not involve copying material from the +Library into the modified Library's header files unless such material is +limited to (i) numerical parameters; (ii) data structure layouts; +(iii) accessors; and (iv) small macros, templates and inline functions of +five lines or less in length. + +Furthermore, you are not required to apply this additional permission to a +modified version of the Library. + diff --git a/debian/changelog b/debian/changelog index 0003d87..5d6013c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,12 +1,12 @@ -lxqt-qtplugin (0.9.0+20150924-1) experimental; urgency=medium +lxqt-qtplugin (0.9.0+20151025-1) experimental; urgency=medium - * Cherry-picked upstream version 0.9.0+20150924. + * Cherry-picked upstream version 0.9.0+20151025. * add upstream signing key and use it in watch file * Cleaned up debian/.gitignore * Switched to experimental because of LXQt namespace change - * Added minimum version for liblxqt0-dev (>= 0.9.0+20150911) + * Added minimum version for liblxqt and libqtxdg - -- Alf Gaida Fri, 25 Sep 2015 19:35:21 +0200 + -- Alf Gaida Sat, 31 Oct 2015 01:20:25 +0100 lxqt-qtplugin (0.9.0+20150819-1) unstable; urgency=medium diff --git a/debian/control b/debian/control index 6298dca..d13cd6a 100644 --- a/debian/control +++ b/debian/control @@ -9,9 +9,9 @@ Build-Depends: debhelper (>= 9), cmake (>= 3.0.2), libdbusmenu-qt5-dev, libkf5windowsystem-dev, - liblxqt0-dev (>= 0.9.0+20150911), + liblxqt0-dev (>= 0.9.0+20151026), libqt5x11extras5-dev, - libqt5xdg-dev, + libqt5xdg-dev (>= 1.3.0), libx11-dev, pkg-config, qtbase5-private-dev, diff --git a/src/lxqtplatformtheme.cpp b/src/lxqtplatformtheme.cpp index 51f0166..dedefbb 100644 --- a/src/lxqtplatformtheme.cpp +++ b/src/lxqtplatformtheme.cpp @@ -214,10 +214,10 @@ const QPalette *LXQtPlatformTheme::palette(Palette type) const { } const QFont *LXQtPlatformTheme::font(Font type) const { - // qDebug() << "font()" << type << SystemFont; + // qDebug() << "font()" << type << SystemFont; if(type == SystemFont && !fontStr_.isEmpty()) { - // NOTE: for some reason, this is not called by Qt when program startup. - // So we do QApplication::setFont() manually. + // NOTE: for some reason, this is not called by Qt when program startup. + // So we do QApplication::setFont() manually. return &font_; } else if(type == FixedFont && !fixedFontStr_.isEmpty()) { @@ -291,13 +291,10 @@ QVariant LXQtPlatformTheme::themeHint(ThemeHint hint) const { break; case ContextMenuOnMouseRelease: break; -#if QT_VERSION >= QT_VERSION_CHECK(5, 3, 0) - // this was introduced in Qt 5.3. case MousePressAndHoldInterval: break; case MouseDoubleClickDistance: break; -#endif default: break; } From 070f4b46c2b0f29ce7342b3576370c33cf65e7fe Mon Sep 17 00:00:00 2001 From: Alf Gaida Date: Wed, 4 Nov 2015 17:49:14 +0100 Subject: [PATCH 7/7] Cherry-picking upstream version 0.10.0. Fix debian/docs Set new minimum version for liblxqt --- .gitignore | 2 ++ COPYING => LICENSE | 41 ++++++++++++++++++--------------------- README => README.md | 4 +++- debian/changelog | 8 ++++++++ debian/control | 2 +- debian/docs | 2 +- src/lxqtplatformtheme.cpp | 7 ------- 7 files changed, 34 insertions(+), 32 deletions(-) create mode 100644 .gitignore rename COPYING => LICENSE (96%) rename README => README.md (90%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..513eaeb --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +*.kdev4 diff --git a/COPYING b/LICENSE similarity index 96% rename from COPYING rename to LICENSE index ab31941..20fb9c7 100644 --- a/COPYING +++ b/LICENSE @@ -1,9 +1,8 @@ - GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -23,8 +22,7 @@ specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations -below. +strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that @@ -89,9 +87,9 @@ libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it -becomes a de-facto standard. To achieve this, non-free programs must -be allowed to use the library. A more frequent case is that a free +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. @@ -138,8 +136,8 @@ included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control -compilation and installation of the library. +interface definition files, plus the scripts used to control compilation +and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of @@ -305,10 +303,10 @@ of these things: the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. - c) Accompany the work with a written offer, valid for at least - three years, to give the same user the materials specified in - Subsection 6a, above, for a charge no more than the cost of - performing this distribution. + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above @@ -386,10 +384,9 @@ all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply, and the section as a whole is intended to apply in other -circumstances. +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any @@ -407,11 +404,11 @@ be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License -may add an explicit geographical distribution limitation excluding those -countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. diff --git a/README b/README.md similarity index 90% rename from README rename to README.md index 65f0fbb..47be4e2 100644 --- a/README +++ b/README.md @@ -1,4 +1,6 @@ -libqtlxqt - LXQt system integration plugin for Qt. +# libqtlxqt + +LXQt system integration plugin for Qt. With this plugin, all Qt-based programs can adopt settings of LXQt, such as the icon theme. diff --git a/debian/changelog b/debian/changelog index 5d6013c..9eff377 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +lxqt-qtplugin (0.10.0-1) experimental; urgency=medium + + * Cherry-picking upstream version 0.10.0. + * Fixed debian/docs + * Set new minimum version for liblxqt + + -- Alf Gaida Wed, 04 Nov 2015 17:48:56 +0100 + lxqt-qtplugin (0.9.0+20151025-1) experimental; urgency=medium * Cherry-picked upstream version 0.9.0+20151025. diff --git a/debian/control b/debian/control index d13cd6a..78368d3 100644 --- a/debian/control +++ b/debian/control @@ -9,7 +9,7 @@ Build-Depends: debhelper (>= 9), cmake (>= 3.0.2), libdbusmenu-qt5-dev, libkf5windowsystem-dev, - liblxqt0-dev (>= 0.9.0+20151026), + liblxqt0-dev (>= 0.10.0), libqt5x11extras5-dev, libqt5xdg-dev (>= 1.3.0), libx11-dev, diff --git a/debian/docs b/debian/docs index 6f12db5..0b6e0f3 100644 --- a/debian/docs +++ b/debian/docs @@ -1,2 +1,2 @@ AUTHORS -README +README.md diff --git a/src/lxqtplatformtheme.cpp b/src/lxqtplatformtheme.cpp index dedefbb..679ed2a 100644 --- a/src/lxqtplatformtheme.cpp +++ b/src/lxqtplatformtheme.cpp @@ -49,7 +49,6 @@ LXQtPlatformTheme::LXQtPlatformTheme(): settingsWatcher_(NULL) { - // qDebug() << "LXQT Platform Theme loaded"; // When the plugin is loaded, it seems that the app is not yet running and // QThread environment is not completely set up. So creating filesystem watcher // does not work since it uses QSocketNotifier internally which can only be @@ -106,14 +105,12 @@ void LXQtPlatformTheme::loadSettings() { if(!fontStr_.isEmpty()) { if(font_.fromString(fontStr_)) QApplication::setFont(font_); // it seems that we need to do this manually. - // qDebug() << "font: " << font_.toString(); } // FixedFont fixedFontStr_ = settings.value(QLatin1String("fixedFont")).toString(); if(!fixedFontStr_.isEmpty()) { fixedFont_.fromString(fixedFontStr_); - // qDebug() << "fixedFont: " << fixedFont_.toString(); } // mouse @@ -214,7 +211,6 @@ const QPalette *LXQtPlatformTheme::palette(Palette type) const { } const QFont *LXQtPlatformTheme::font(Font type) const { - // qDebug() << "font()" << type << SystemFont; if(type == SystemFont && !fontStr_.isEmpty()) { // NOTE: for some reason, this is not called by Qt when program startup. // So we do QApplication::setFont() manually. @@ -227,7 +223,6 @@ const QFont *LXQtPlatformTheme::font(Font type) const { } QVariant LXQtPlatformTheme::themeHint(ThemeHint hint) const { - // qDebug() << "themeHint" << hint; switch (hint) { case CursorFlashTime: return cursorFlashTime_; @@ -258,14 +253,12 @@ QVariant LXQtPlatformTheme::themeHint(ThemeHint hint) const { case ItemViewActivateItemOnSingleClick: return QVariant(singleClickActivate_); case SystemIconThemeName: - // qDebug() << "iconTheme" << iconTheme_; return iconTheme_; case SystemIconFallbackThemeName: return "hicolor"; case IconThemeSearchPaths: return xdgIconThemePaths(); case StyleNames: - // qDebug() << "StyleNames"; return QStringList() << style_; case WindowAutoPlacement: break;