On Saturday 06 June 2009, 潘卫平 wrote: > Hi, <br><br> I found that when kwin enables taskbarthumbnail effect, > the tooltip can show the preview of windows, but we can't click these > preview to activate or iconify the corresponding window. > <br> <br> I made two patches.<br>1
thanks for the patches; i've modified them a bit to fix a few issues, but nothing significant. i appreciate the contribution from you and Red Flag Linux and am glad to accept this improvement from you. my updated patch to kdelibs is attached: can others on plasma-devel give it a quick API review please? thank you. -- Aaron J. Seigo humru othro a kohnu se GPG Fingerprint: 8B8B 2209 0C6F 7C47 B1EA EE75 D6B7 2EB1 A7F1 DB43 KDE core developer sponsored by Qt Software
Index: tooltipmanager.cpp =================================================================== --- tooltipmanager.cpp (revision 978920) +++ tooltipmanager.cpp (working copy) @@ -62,9 +62,11 @@ tipWidget(new ToolTip(0)), state(ToolTipManager::Activated), isShown(false), - delayedHide(false) + delayedHide(false), + clickable(false) { - + QObject::connect(tipWidget, SIGNAL(activateWindowByWId(WId)), + q, SLOT(activateWindowByWId(WId))); } ~ToolTipManagerPrivate() @@ -81,9 +83,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 activateWindowByWId(WId wid); ToolTipManager *q; QGraphicsWidget *currentWidget; @@ -94,6 +97,7 @@ ToolTipManager::State state; bool isShown : 1; bool delayedHide : 1; + bool clickable : 1; }; //TOOLTIP IMPLEMENTATION @@ -137,6 +141,10 @@ return; } + if (d->currentWidget) { + disconnect(this, 0, d->currentWidget, 0); + } + d->hideTimer->stop(); d->delayedHide = false; d->showTimer->stop(); @@ -160,7 +168,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 +183,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; @@ -211,6 +229,7 @@ hide(widget); } else { d->delayedHide = data.autohide(); + d->clickable = data.isClickable(); if (d->delayedHide) { //kDebug() << "starting authoide"; d->hideTimer->start(3000); @@ -267,13 +286,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 +318,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 +376,11 @@ } } +void ToolTipManagerPrivate::activateWindowByWId(WId wid) +{ + emit q->clicked(ToolTipManager::WindowPreviewClicked, QVariant::fromValue(wid)); +} + bool ToolTipManager::eventFilter(QObject *watched, QEvent *event) { QGraphicsWidget * widget = dynamic_cast<QGraphicsWidget *>(watched); @@ -399,6 +427,7 @@ case QEvent::GraphicsSceneMousePress: hide(widget); + break; case QEvent::GraphicsSceneWheel: default: Index: tooltipcontent.h =================================================================== --- tooltipcontent.h (revision 978920) +++ tooltipcontent.h (working copy) @@ -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 setIsClickable(bool clickable); + + /** + * @return true if the tooltip is clickabel + * + * @since 4.3 + */ + bool isClickable() const; + private: ToolTipContentPrivate * const d; }; Index: tooltipcontent.cpp =================================================================== --- tooltipcontent.cpp (revision 978920) +++ tooltipcontent.cpp (working copy) @@ -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::setIsClickable(bool clickable) +{ + d->clickable = clickable; +} + +bool ToolTipContent::isClickable() const +{ + return d->clickable; +} + } // namespace Plasma Index: private/tooltip_p.h =================================================================== --- private/tooltip_p.h (revision 978920) +++ private/tooltip_p.h (working copy) @@ -43,6 +43,9 @@ bool autohide() const; void setDirection(Plasma::Direction); +signals: + void activateWindowByWId(WId wid); + protected: void checkSize(); void adjustPosition(const QSize &previous, const QSize ¤t); Index: private/windowpreview.cpp =================================================================== --- private/windowpreview.cpp (revision 978920) +++ private/windowpreview.cpp (working copy) @@ -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); + } +} + } // namespace Plasma #include "windowpreview_p.moc" Index: private/tooltip.cpp =================================================================== --- private/tooltip.cpp (revision 978920) +++ private/tooltip.cpp (working copy) @@ -165,7 +165,7 @@ d->background->setEnabledBorders(FrameSvg::AllBorders); updateTheme(); connect(d->background, SIGNAL(repaintNeeded()), this, SLOT(updateTheme())); - + connect(d->preview, SIGNAL(windowPreviewClicked(WId)), this, SIGNAL(activateWindowByWId(WId))); l->addWidget(d->preview, 0, 0, 1, 2); l->addWidget(d->imageLabel, 1, 0); l->addWidget(d->text, 1, 1); Index: private/windowpreview_p.h =================================================================== --- private/windowpreview_p.h (revision 978920) +++ private/windowpreview_p.h (working copy) @@ -50,8 +50,12 @@ bool isEmpty() const; virtual QSize sizeHint() const; +signals: + void windowPreviewClicked(WId wid); + protected: void paintEvent(QPaintEvent *e); + void mousePressEvent(QMouseEvent *event); private: void readWindowSizes() const; Index: containment.cpp =================================================================== --- containment.cpp (revision 978920) +++ containment.cpp (working copy) @@ -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 (revision 978920) +++ tooltipmanager.h (working copy) @@ -76,6 +76,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 +171,17 @@ */ ToolTipManager::State state() const; +signals: + /** + * This signal is emitted when something in the tooltip is clicked. + * @arg clicked what kind of item was clicked @see ClickTarget + * @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 clicked, QVariant data); + + private: /** * Default constructor. @@ -188,6 +206,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 activateWindowByWId(WId wid)) }; } // namespace Plasma
signature.asc
Description: This is a digitally signed message part.
_______________________________________________ Plasma-devel mailing list Plasma-devel@kde.org https://mail.kde.org/mailman/listinfo/plasma-devel