[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-panel-devel
Subject:    Re: [Panel-devel] minimization to taskbar
From:       Jason Stubbs <jasonbstubbs () gmail ! com>
Date:       2007-12-06 15:38:03
Message-ID: 200712070038.03485.jasonbstubbs () gmail ! com
[Download RAW message or body]

On Thursday 06 December 2007 01:42:32 Aaron J. Seigo wrote:
> On Wednesday 05 December 2007, Jason Stubbs wrote:
> > On Monday 03 December 2007 02:35:48 Aaron J. Seigo wrote:
> > > that said, i still think it is too expensive to do the bookkeeping in
> > > each widget. if a widget is interested in tracking this information.
> >
> > It's actually not that high. The only (semi-)hot path affected is
> > itemChange's ItemPositionHashChanged event which has this false
> > condition:
>
> there's also memory usage with an extra QList per widget. these things have
> a way of accreting into monsters (see Plasma::Applet ;)

These new patches have no extra members on anything inside libplasma. :)

The premise with these patches is that applets (rather than widgets) are 
notified when their scene-relative position changes. Strictly speaking they 
are only notified with respect to their containment, but that currently 
equates to the same thing.

For the libplasma patch, you should be familiar with the changes in Widget. 
The only thing different is that associatedViews() has become view() based on 
the assumption that any applet that needs to know about views can't deal with 
more than one. The other change is to make the applet handle notify the 
applet when its position changes.

(I just realized that AppletHandle's notifications should probably be done is 
mouseReleaseEvent() so I'll fix that tomorrow.)

Tasks is a little bit longer than the last patch due to the applet sub-class 
needing to propogate position change information to its widget sub-classes.
It's still not much code needed to get the job done though. :)

System tray ended up being a big patch as I've moved a couple of things 
around, but it has similarly ended up being easier to read.

Behaviour in the panel has no problems and behaviour on the desktop is mostly 
ok. The only thing that doesn't work at all is desktop zooming. Given that 
these patches affect much less, I think that's a small price to pay. :)

-- 
Jason Stubbs

["libplasma.patch" (text/x-diff)]

Index: workspace/libs/plasma/applethandle_p.h
===================================================================
--- workspace/libs/plasma/applethandle_p.h	(revision 745102)
+++ workspace/libs/plasma/applethandle_p.h	(working copy)
@@ -52,6 +52,7 @@ class AppletHandle : public QObject, pub
         void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
         void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
         void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
+        QVariant itemChange(GraphicsItemChange change, const QVariant &value);
 
     Q_SIGNALS:
        void disappearDone(AppletHandle *self);
Index: workspace/libs/plasma/widgets/widget.cpp
===================================================================
--- workspace/libs/plasma/widgets/widget.cpp	(revision 745102)
+++ workspace/libs/plasma/widgets/widget.cpp	(working copy)
@@ -25,6 +25,8 @@
 #include <limits>
 
 #include <QApplication>
+#include <QGraphicsScene>
+#include <QGraphicsView>
 #include <QList>
 #include <QPainter>
 #include <QPixmapCache>
@@ -76,6 +78,36 @@ QGraphicsItem* Widget::graphicsItem()
     return this;
 }
 
+QGraphicsView *Widget::view() const
+{
+    // It's assumed that we won't be visible on more than one view here.
+    // Anything that actually needs view() should only really care about
+    // one of them anyway though.
+    if (!scene()) {
+        return 0;
+    }
+    foreach (QGraphicsView *view, scene()->views()) {
+        if (view->sceneRect().intersects(sceneBoundingRect())) {
+            return view;
+        }
+    }
+    return 0;
+}
+
+QRectF Widget::mapFromView(const QGraphicsView *view, const QRect &rect) const
+{
+    // TODO: Confirm that adjusted() is needed and is not covering for some
+    // issue elsewhere
+    return mapFromScene(view->mapToScene(rect)).boundingRect().adjusted(0, 0, 1, 1);
+}
+
+QRect Widget::mapToView(const QGraphicsView *view, const QRectF &rect) const
+{
+    // TODO: Confirm that adjusted() is needed and is not covering for some
+    // issue elsewhere
+    return view->mapFromScene(mapToScene(rect)).boundingRect().adjusted(0, 0, -1, -1);
+}
+
 bool Widget::Private::shouldPaint(QPainter *painter, const QTransform &transform)
 {
     Q_UNUSED(painter)
Index: workspace/libs/plasma/widgets/widget.h
===================================================================
--- workspace/libs/plasma/widgets/widget.h	(revision 745102)
+++ workspace/libs/plasma/widgets/widget.h	(working copy)
@@ -30,6 +30,8 @@
 #include <plasma/layouts/layoutitem.h>
 #include <plasma/plasma_export.h>
 
+class QGraphicsView;
+
 namespace Plasma
 {
 
@@ -242,6 +244,25 @@ TODO: implement once we decide how to ha
 
     virtual QGraphicsItem* graphicsItem();
 
+    /**
+     * Returns the view this widget is visible on
+     */
+    QGraphicsView *view() const;
+
+    /**
+     * Maps a QRect from a view's coordinates to local coordinates.
+     * @param view the view from which rect should be mapped
+     * @param rect the rect to be mapped
+     */
+    QRectF mapFromView(const QGraphicsView *view, const QRect &rect) const;
+
+    /**
+     * Maps a QRectF from local coordinates to a view's coordinates.
+     * @param view the view to which rect should be mapped
+     * @param rect the rect to be mapped
+     */
+    QRect mapToView(const QGraphicsView *view, const QRectF &rect) const;
+
 protected:
     /**
      * Paints the widget
Index: workspace/libs/plasma/applethandle.cpp
===================================================================
--- workspace/libs/plasma/applethandle.cpp	(revision 745102)
+++ workspace/libs/plasma/applethandle.cpp	(working copy)
@@ -335,6 +335,14 @@ void AppletHandle::mouseMoveEvent(QGraph
     }
 }
 
+QVariant AppletHandle::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+    if (change == ItemPositionHasChanged && m_applet) {
+        m_applet->constraintsUpdated(Plasma::LocationConstraint);
+    }
+    return QGraphicsItem::itemChange(change, value);
+}
+
 void AppletHandle::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
 {
     Q_UNUSED(event);

["tasks.patch" (text/x-diff)]

Index: workspace/plasma/applets/tasks/tasks.cpp
===================================================================
--- workspace/plasma/applets/tasks/tasks.cpp	(revision 745102)
+++ workspace/plasma/applets/tasks/tasks.cpp	(working copy)
@@ -29,6 +29,7 @@
 #include <QApplication>
 #include <QGraphicsScene>
 #include <QGraphicsSceneDragDropEvent>
+#include <QGraphicsView>
 #include <QIcon>
 #include <QLinearGradient>
 #include <QTimeLine>
@@ -163,6 +164,20 @@ void Tasks::removeWindowTask(Task::TaskP
     }
 }
 
+void Tasks::constraintsUpdated(Plasma::Constraints constraints)
+{
+    if (constraints & Plasma::LocationConstraint) {
+        foreach (AbstractTaskItem *taskItem, _rootTaskGroup->tasks()) {
+            //TODO: Update this if/when tasks() returns other types
+            WindowTaskItem *windowTaskItem = dynamic_cast<WindowTaskItem *>(taskItem);
+            if (windowTaskItem) {
+                windowTaskItem->publishIconGeometry();
+            }
+        }
+    }
+}
+
+
 
 
 
@@ -789,6 +804,7 @@ void WindowTaskItem::updateTask()
     setIcon(QIcon(iconPixmap));
     setText(_task->visibleName());
 }
+
 void WindowTaskItem::setWindowTask(Task::TaskPtr task)
 {
     if (_task)
@@ -821,5 +837,24 @@ void WindowTaskItem::contextMenuEvent(QG
     TaskRMBMenu menu( windowTask() );
     menu.exec( e->screenPos() );
 }
-#include "tasks.moc"
 
+QVariant WindowTaskItem::itemChange(GraphicsItemChange change, const QVariant &value)
+{
+    if (change == ItemPositionHasChanged) {
+        publishIconGeometry();
+    }
+    return AbstractTaskItem::itemChange(change, value);
+}
+
+void WindowTaskItem::publishIconGeometry()
+{
+    QGraphicsView *parentView = view();
+    if (!parentView || !_task) {
+        return;
+    }
+    QRect rect = mapToView(parentView, boundingRect());
+    rect.moveTopLeft(parentView->mapToGlobal(rect.topLeft()));
+    _task->publishIconGeometry(rect);
+}
+
+#include "tasks.moc"
Index: workspace/plasma/applets/tasks/tasks.h
===================================================================
--- workspace/plasma/applets/tasks/tasks.h	(revision 745102)
+++ workspace/plasma/applets/tasks/tasks.h	(working copy)
@@ -73,6 +73,8 @@ public:
         // a background
         //QRectF boundingRect() const;
 
+        void constraintsUpdated(Plasma::Constraints constraints);
+
 private slots:
         void addWindowTask(Task::TaskPtr);
         void removeWindowTask(Task::TaskPtr);
@@ -289,12 +291,15 @@ public:
     void setWindowTask(Task::TaskPtr task);
     /** Returns the window represented by this task. */
     Task::TaskPtr windowTask() const;
+    /** Tells the window manager the minimized task's geometry. */
+    void publishIconGeometry();
 
     virtual void activate();
     virtual void close();
 
 protected:
     virtual void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);
+    QVariant itemChange(GraphicsItemChange change, const QVariant &value);
 
 private slots:
     void updateTask();


_______________________________________________
Panel-devel mailing list
Panel-devel@kde.org
https://mail.kde.org/mailman/listinfo/panel-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic