Dear all, Thanks for your reviews and Seigo's encouragements!
According to your discussion, I make another two patches based on Seigo's patch. 1 kdelibs-palsma-tooltip-previewclick-aseigo-modified.patch It should apply to the directory kdelibs/plasma/ 2 kdebase-workspace-plasma-tasks-previewclick-aseigo-modified.patch It should apply to the directory kdebase/workspace/plasma/applets/tasks/ Best regards pwp
Index: taskgroupitem.cpp =================================================================== --- taskgroupitem.cpp ï¼çæ¬ 979277ï¼ +++ taskgroupitem.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -45,7 +45,6 @@ #include <Plasma/Theme> #include <Plasma/FrameSvg> -#include <Plasma/ToolTipManager> #include <Plasma/Corona> #include <Plasma/Containment> #include <Plasma/Dialog> @@ -251,7 +250,7 @@ return; } - Plasma::ToolTipContent data(m_group->name(), + ToolTipContent data(m_group->name(), i18nc("Which virtual desktop a window is currently on", "On %1", KWindowSystem::desktopName(m_group->desktop()))); // data.image = m_group->icon().pixmap(QSize::small); @@ -273,9 +272,11 @@ } data.setWindowsToPreview(windows); + data.setClickable(true); + connect(ToolTipManager::self(), SIGNAL(clicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant)), this, SLOT(toolTipClicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant))); - Plasma::ToolTipManager::self()->setContent(this, data); + ToolTipManager::self()->setContent(this, data); } @@ -1236,5 +1237,34 @@ return m_popupDialog; } +void TaskGroupItem::toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data) +{ + if (clickTarget != ToolTipManager::WindowPreviewClicked) + return; + + if (event->button() != Qt::LeftButton) + return; + + bool ok = false; + WId wid = data.toInt(&ok); + + if (ok == false) + return; + + if (wid <= 0) + return; + + foreach (AbstractGroupableItem *item, m_group->members()) + { + TaskManager::TaskItem *taskItem = qobject_cast<TaskManager::TaskItem *>(item); + + if ((taskItem != NULL) && (taskItem->task()->window() == wid)) + { + taskItem->task()->activateRaiseOrIconify(); + break; + } + } +} + #include "taskgroupitem.moc" Index: taskgroupitem.h =================================================================== --- taskgroupitem.h ï¼çæ¬ 979277ï¼ +++ taskgroupitem.h ï¼å·¥ä½å¯æ¬ï¼ @@ -130,6 +130,7 @@ public slots: void updateActive(AbstractTaskItem *); + void toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data); protected: AbstractTaskItem *taskItemForWId(WId id); Index: windowtaskitem.cpp =================================================================== --- windowtaskitem.cpp ï¼çæ¬ 979277ï¼ +++ windowtaskitem.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -45,7 +45,6 @@ #include <Plasma/Theme> #include <Plasma/FrameSvg> -#include <Plasma/ToolTipManager> #include <Plasma/Corona> #include <Plasma/Containment> @@ -193,12 +192,15 @@ Qt::KeepAspectRatio, Qt::SmoothTransformation); } - Plasma::ToolTipContent data(m_task->name(), + ToolTipContent data(m_task->name(), i18nc("Which virtual desktop a window is currently on", "On %1", KWindowSystem::desktopName(m_task->desktop())), p); data.setWindowToPreview(m_task->task()->window()); + data.setClickable(true); - Plasma::ToolTipManager::self()->setContent(this, data); + connect(ToolTipManager::self(), SIGNAL(clicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant)), this, SLOT(toolTipClicked(ToolTipManager::ClickTarget, QMouseEvent *, QVariant))); + + ToolTipManager::self()->setContent(this, data); } void WindowTaskItem::setStartupTask(TaskItem *task) @@ -317,5 +319,25 @@ } } +void WindowTaskItem::toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data) +{ + if (clickTarget != ToolTipManager::WindowPreviewClicked) + return; + + if (event->button() != Qt::LeftButton) + return; + + bool ok = false; + WId wid = data.toInt(&ok); + + if (ok == false) + return; + + if (wid != m_task->task()->window()) + return; + + activate(); +} + #include "windowtaskitem.moc" Index: abstracttaskitem.h =================================================================== --- abstracttaskitem.h ï¼çæ¬ 979277ï¼ +++ abstracttaskitem.h ï¼å·¥ä½å¯æ¬ï¼ @@ -25,6 +25,7 @@ // KDE #include <KColorScheme> +#include <Plasma/ToolTipManager> // Own #include <taskmanager/taskgroup.h> @@ -37,13 +38,13 @@ class QTextLayout; class QString; - // Plasma #include <Plasma/Animator> class Tasks; class TaskGroupItem; class LayoutWidget; +using namespace Plasma; /** * A baseclass for a task @@ -138,6 +139,7 @@ virtual void activate() = 0; void toolTipAboutToShow(); void toolTipHidden(); + virtual void toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data) = 0; protected: void dragEnterEvent(QGraphicsSceneDragDropEvent *event); Index: windowtaskitem.h =================================================================== --- windowtaskitem.h ï¼çæ¬ 979277ï¼ +++ windowtaskitem.h ï¼å·¥ä½å¯æ¬ï¼ @@ -24,7 +24,6 @@ #include "abstracttaskitem.h" // Own -#include <taskmanager/taskmanager.h> #include <taskmanager/taskitem.h> /** @@ -62,6 +61,7 @@ public slots: void activate(); void close(); + void toolTipClicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data); protected: void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); Index: tasks.cpp =================================================================== --- tasks.cpp ï¼çæ¬ 979277ï¼ +++ tasks.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -62,7 +62,6 @@ resize(500, 58); setAcceptDrops(true); - } Tasks::~Tasks() @@ -405,7 +404,6 @@ return m_rootGroupItem; } - K_EXPORT_PLASMA_APPLET(tasks, Tasks) #include "tasks.moc" Index: tasks.h =================================================================== --- tasks.h ï¼çæ¬ 979277ï¼ +++ tasks.h ï¼å·¥ä½å¯æ¬ï¼ @@ -108,7 +108,6 @@ void needsVisualFocus(); - signals: /** * emitted whenever we receive a constraintsEvent
Index: tooltipmanager.cpp =================================================================== --- tooltipmanager.cpp ï¼çæ¬ 979276ï¼ +++ tooltipmanager.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -62,9 +62,10 @@ tipWidget(new ToolTip(0)), state(ToolTipManager::Activated), isShown(false), - delayedHide(false) + delayedHide(false), + clickable(false) { - + QObject::connect(tipWidget, SIGNAL(windowPreviewClicked(WId, QMouseEvent *)), q, SLOT(windowPreviewClicked(WId, QMouseEvent *))); } ~ToolTipManagerPrivate() @@ -81,9 +82,10 @@ * called when a widget inside the tooltip manager is deleted */ void onWidgetDestroyed(QObject * object); - void removeWidget(QGraphicsWidget *w); + void removeWidget(QGraphicsWidget *w, bool canSafelyAccess = true); void clearTips(); void doDelayedHide(); + void windowPreviewClicked(WId wid, QMouseEvent *event); ToolTipManager *q; QGraphicsWidget *currentWidget; @@ -94,6 +96,7 @@ ToolTipManager::State state; bool isShown : 1; bool delayedHide : 1; + bool clickable : 1; }; //TOOLTIP IMPLEMENTATION @@ -137,6 +140,10 @@ return; } + if (d->currentWidget) { + disconnect(this, 0, d->currentWidget, 0); + } + d->hideTimer->stop(); d->delayedHide = false; d->showTimer->stop(); @@ -160,7 +167,13 @@ { showTimer->stop(); // stop the timer to show the tooltip delayedHide = true; - hideTimer->start(250); + + if (isShown && clickable) { + // leave enough time for user to choose + hideTimer->start(1000); + } else { + hideTimer->start(250); + } } void ToolTipManager::hide(QGraphicsWidget *widget) @@ -169,6 +182,10 @@ return; } + if (d->currentWidget) { + disconnect(this, 0, d->currentWidget, 0); + } + d->currentWidget = 0; d->showTimer->stop(); // stop the timer to show the tooltip d->delayedHide = false; @@ -205,6 +222,7 @@ registerWidget(widget); d->tooltips.insert(widget, data); + d->clickable = data.isClickable(); if (d->currentWidget == widget) { if (data.isEmpty()) { @@ -267,13 +285,16 @@ // NOTE: DO NOT USE THE w VARIABLE FOR ANYTHING OTHER THAN COMPARING // THE ADDRESS! ACTUALLY USING THE OBJECT WILL RESULT IN A CRASH!!! QGraphicsWidget *w = static_cast<QGraphicsWidget*>(object); - removeWidget(w); + removeWidget(w, false); } -void ToolTipManagerPrivate::removeWidget(QGraphicsWidget *w) +void ToolTipManagerPrivate::removeWidget(QGraphicsWidget *w, bool canSafelyAccess) { - // DO NOT ACCESS w HERE!! IT MAY BE IN THE PROCESS OF DELETION! - if (currentWidget == w) { + if (currentWidget == w && currentWidget) { + if (canSafelyAccess) { + QObject::disconnect(q, 0, currentWidget, 0); + } + currentWidget = 0; showTimer->stop(); // stop the timer to show the tooltip tipWidget->setContent(0, ToolTipContent()); @@ -296,6 +317,7 @@ //One might have moused out and back in again delayedHide = false; isShown = false; + QObject::disconnect(q, 0, currentWidget, 0); currentWidget = 0; tipWidget->hide(); } @@ -353,6 +375,11 @@ } } +void ToolTipManagerPrivate::windowPreviewClicked(WId wid, QMouseEvent *event) +{ + emit q->clicked(ToolTipManager::WindowPreviewClicked, event, QVariant::fromValue(wid)); +} + bool ToolTipManager::eventFilter(QObject *watched, QEvent *event) { QGraphicsWidget * widget = dynamic_cast<QGraphicsWidget *>(watched); @@ -399,6 +426,7 @@ case QEvent::GraphicsSceneMousePress: hide(widget); + break; case QEvent::GraphicsSceneWheel: default: Index: tooltipcontent.h =================================================================== --- tooltipcontent.h ï¼çæ¬ 979276ï¼ +++ tooltipcontent.h ï¼å·¥ä½å¯æ¬ï¼ @@ -48,79 +48,135 @@ public: enum ResourceType { ImageResource = 0, HtmlResource, CssResource }; - /** Creates an empty Content */ + /** + * Creates an empty Content + */ ToolTipContent(); ~ToolTipContent(); - /** Copy constructor */ + /** + * Copy constructor + */ ToolTipContent(const ToolTipContent &other); - /** Constructor that sets the common fields */ + /** + * Constructor that sets the common fields + */ ToolTipContent(const QString &mainText, const QString &subText, const QPixmap &image = QPixmap()); - /** Constructor that sets the common fields */ + /** + * Constructor that sets the common fields + */ ToolTipContent(const QString &mainText, const QString &subText, const QIcon &icon); ToolTipContent &operator=(const ToolTipContent &other); - /** @return true if all the fields are empty */ + /** + * @return true if all the fields are empty + */ bool isEmpty() const; - /** Sets the main text which containts important information, e.g. the title */ + /** + * Sets the main text which containts important information, e.g. the title + */ void setMainText(const QString &text); - /** Important information, e.g. the title */ + /** + * Important information, e.g. the title + */ QString mainText() const; - /** Sets text which elaborates on the @p mainText */ + /** + * Sets text which elaborates on the @p mainText + */ void setSubText(const QString &text) ; - /** Elaborates on the @p mainText */ + /** + * Elaborates on the @p mainText + */ QString subText() const; - /** Sets the icon to show **/ + /** + * Sets the icon to show + */ void setImage(const QPixmap &image); - /** Sets the icon to show **/ + /** + * Sets the icon to show + */ void setImage(const QIcon &icon); - /** An icon to display */ + /** + * An icon to display + */ QPixmap image() const; - //BIC FIXME: remove when we can break BC - /** Sets the ID of the window to show a preview for */ + /** + * Sets the ID of the window to show a preview for. + * @deprecated + * @see setWindowsToPreview + */ void setWindowToPreview(WId id); - //BIC FIXME: remove when we can break BC - /** Id of a window if you want to show a preview */ + /** + * Id of a window if you want to show a preview + * @deprecated + * @see windowsToPreview + */ WId windowToPreview() const; - /** Sets the IDS of the windows to show a preview for - @since 4.3*/ + /** + * Sets the IDS of the windows to show a preview for + * @since 4.3 + */ void setWindowsToPreview(const QList<WId> &ids); - /** Ids of a windows if you want to show a preview - @since 4.3*/ + /** + * Ids of a windows if you want to show a preview + * @since 4.3 + */ QList<WId> windowsToPreview() const; - /** Sets whether or not to autohide the tooltip, defaults to true */ + /** Sets whether or not to autohide the tooltip, defaults to true + */ void setAutohide(bool autohide); - /** Whether or not to autohide the tooltip, defaults to true */ + /** + * Whether or not to autohide the tooltip, defaults to true + */ bool autohide() const; - /** Adds a resource that can then be referenced from the text elements - using rich text **/ + /** + * Adds a resource that can then be referenced from the text elements + * using rich text + */ void addResource(ResourceType type, const QUrl &path, const QVariant &resource); - /** Registers all resources with a given document */ + /** + * Registers all resources with a given document + */ void registerResources(QTextDocument *document) const; + /** + * Sets whether or not the tooltip contains clickable content, such as + * window previews. Defaults to false, or not clickable. + * + * @since 4.3 + */ + void setClickable(bool clickable); + + /** + * @return true if the tooltip is clickabel + * + * @since 4.3 + */ + bool isClickable() const; + private: ToolTipContentPrivate * const d; }; Index: tooltipcontent.cpp =================================================================== --- tooltipcontent.cpp ï¼çæ¬ 979276ï¼ +++ tooltipcontent.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -47,7 +47,8 @@ { public: ToolTipContentPrivate() - : autohide(true) + : autohide(true), + clickable(false) { } @@ -56,7 +57,8 @@ QPixmap image; QList<WId> windowsToPreview; QHash<QString, ToolTipResource> resources; - bool autohide; + bool autohide : 1; + bool clickable : 1; }; ToolTipContent::ToolTipContent() @@ -211,6 +213,16 @@ } } +void ToolTipContent::setClickable(bool clickable) +{ + d->clickable = clickable; +} + +bool ToolTipContent::isClickable() const +{ + return d->clickable; +} + } // namespace Plasma Index: private/tooltip_p.h =================================================================== --- private/tooltip_p.h ï¼çæ¬ 979276ï¼ +++ private/tooltip_p.h ï¼å·¥ä½å¯æ¬ï¼ @@ -43,6 +43,9 @@ bool autohide() const; void setDirection(Plasma::Direction); +signals: + void windowPreviewClicked(WId wid, QMouseEvent *event); + protected: void checkSize(); void adjustPosition(const QSize &previous, const QSize ¤t); Index: private/windowpreview.cpp =================================================================== --- private/windowpreview.cpp ï¼çæ¬ 979276ï¼ +++ private/windowpreview.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -22,6 +22,7 @@ #include <QPainter> #include <QVarLengthArray> +#include <QMouseEvent> #include <kwindowsystem.h> #include <kdebug.h> @@ -224,6 +225,23 @@ #endif } +void WindowPreview::mousePressEvent(QMouseEvent *event) +{ + QPoint p = event->pos(); + WId wid = 0; + + for (int i = 0; i < m_thumbnailRects.size(); ++i) { + if (m_thumbnailRects[i].contains(p)) { + wid = ids[i]; + break; + } + } + + if (wid) { + emit windowPreviewClicked(wid, event); + } +} + } // namespace Plasma #include "windowpreview_p.moc" Index: private/tooltip.cpp =================================================================== --- private/tooltip.cpp ï¼çæ¬ 979276ï¼ +++ private/tooltip.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -165,6 +165,7 @@ d->background->setEnabledBorders(FrameSvg::AllBorders); updateTheme(); connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(updateTheme())); + connect(d->preview, SIGNAL(windowPreviewClicked(WId, QMouseEvent *)), this, SIGNAL(windowPreviewClicked(WId, QMouseEvent *))); l->addWidget(d->preview, 0, 0, 1, 2); l->addWidget(d->imageLabel, 1, 0); Index: private/windowpreview_p.h =================================================================== --- private/windowpreview_p.h ï¼çæ¬ 979276ï¼ +++ private/windowpreview_p.h ï¼å·¥ä½å¯æ¬ï¼ @@ -50,8 +50,12 @@ bool isEmpty() const; virtual QSize sizeHint() const; +signals: + void windowPreviewClicked(WId wid, QMouseEvent *event); + protected: void paintEvent(QPaintEvent *e); + void mousePressEvent(QMouseEvent *event); private: void readWindowSizes() const; Index: containment.cpp =================================================================== --- containment.cpp ï¼çæ¬ 979276ï¼ +++ containment.cpp ï¼å·¥ä½å¯æ¬ï¼ @@ -144,20 +144,32 @@ //fix the text of the actions that need name() //btw, do we really want to use name() when it's a desktopcontainment? - QAction *closeApplet = d->actions()->action("remove"); - closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", name())); - QAction *configAction = d->actions()->action("configure"); - configAction->setText(i18nc("%1 is the name of the applet", "%1 Settings", name())); + QAction *closeApplet = action("remove"); + if (closeApplet) { + closeApplet->setText(i18nc("%1 is the name of the applet", "Remove this %1", name())); + } + QAction *configAction = action("configure"); + if (configAction) { + configAction->setText(i18nc("%1 is the name of the applet", "%1 Settings", name())); + } + QAction *appletBrowserAction = action("add widgets"); - appletBrowserAction->setVisible(unlocked); - appletBrowserAction->setEnabled(unlocked); - connect(appletBrowserAction, SIGNAL(triggered()), this, SLOT(triggerShowAddWidgets())); + if (appletBrowserAction) { + appletBrowserAction->setVisible(unlocked); + appletBrowserAction->setEnabled(unlocked); + connect(appletBrowserAction, SIGNAL(triggered()), this, SLOT(triggerShowAddWidgets())); + } QAction *act = action("next applet"); - connect(act, SIGNAL(triggered()), this, SLOT(focusNextApplet())); + if (act) { + connect(act, SIGNAL(triggered()), this, SLOT(focusNextApplet())); + } + act = action("previous applet"); - connect(act, SIGNAL(triggered()), this, SLOT(focusPreviousApplet())); + if (act) { + connect(act, SIGNAL(triggered()), this, SLOT(focusPreviousApplet())); + } if (immutability() != SystemImmutable && corona()) { QAction *lockDesktopAction = corona()->action("lock widgets"); @@ -169,7 +181,7 @@ if (d->type == PanelContainment || d->type == CustomPanelContainment) { - d->actions()->removeAction(d->actions()->action("zoom in")); + d->actions()->removeAction(action("zoom in")); } else { QAction *zoomAction = action("zoom in"); connect(zoomAction, SIGNAL(triggered()), this, SLOT(zoomIn())); Index: tooltipmanager.h =================================================================== --- tooltipmanager.h ï¼çæ¬ 979276ï¼ +++ tooltipmanager.h ï¼å·¥ä½å¯æ¬ï¼ @@ -22,6 +22,8 @@ #ifndef PLASMA_TOOLTIP_MANAGER_H #define PLASMA_TOOLTIP_MANAGER_H +#include <QMouseEvent> + //plasma #include <plasma/plasma.h> #include <plasma/plasma_export.h> @@ -76,6 +78,13 @@ Deactivated /**<< Will discard tooltip data, and not attempt to show them */ }; + enum ClickTarget { + NothingClicked = 0, + WindowPreviewClicked = 1, + LinkClicked = 2, + IconClicked = 3 + }; + /** * @return The singleton instance of the manager. */ @@ -164,6 +173,17 @@ */ ToolTipManager::State state() const; +signals: + /** + * This signal is emitted when something in the tooltip is clicked. + * @arg clickTarget what kind of item was clicked @see ClickTarget + * @arg event QMouseEvent infomation + * @arg data what was clicked, such as a url in the case of a hyperlink, + * or a window id in the case of a window preview. + * @since 4.3 + */ + void clicked(ToolTipManager::ClickTarget clickTarget, QMouseEvent *event, QVariant data); + private: /** * Default constructor. @@ -188,6 +208,7 @@ Q_PRIVATE_SLOT(d, void showToolTip()) Q_PRIVATE_SLOT(d, void resetShownState()) Q_PRIVATE_SLOT(d, void onWidgetDestroyed(QObject*)) + Q_PRIVATE_SLOT(d, void windowPreviewClicked(WId wid, QMouseEvent *event)) }; } // namespace Plasma
_______________________________________________ Plasma-devel mailing list Plasma-devel@kde.org https://mail.kde.org/mailman/listinfo/plasma-devel