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

List:       kde-panel-devel
Subject:    [PATCH] fix plasma and Qt monitor-hotplug issues
From:       Aike J Sommer <dev () aikesommer ! name>
Date:       2008-03-28 12:16:15
Message-ID: 200803281316.15764.dev () aikesommer ! name
[Download RAW message or body]

Attached are 2 patches to fix issues with monitor hotplug.
The patch to qt-copy fixes:
- screenResized not beeing emitted on some changes
- screenResized always reporting screen 0 to have changed

This is a little hacky... Qt uses Xinerama to query for screens, so listening 
to XRandR 1.2 events doesnt really work... So this patch will cause 
ResizeEvents beeing triggered even if it might not be necessary to make 
QDesktopWidget recalc the geometry!
Where should i go with that from here?? :-)

The patch to kdebase basically only calls view->show() after creating it... 
The rest just reduces some iterations over all screens, which are not needed 
anymore!

One thing left: Should views be destroyed if a monitor is disconnected? And if 
so i guess using screenOwnerChanged or a (new) signal containmentRemoved 
wouldnt be right, since containments should stay associated with the 
screen... Maybe in DesktopCorona::adjustSize()?

:-)

["qt-copy-patch-01.diff" (text/x-diff)]

--- src/gui/kernel/qapplication_x11.cpp.applied_patches	2008-03-28 12:01:01.000000000 +0100
+++ src/gui/kernel/qapplication_x11.cpp	2008-03-28 12:22:06.000000000 +0100
@@ -3053,8 +3053,40 @@
         w->data->crect.setWidth(DisplayWidth(X11->display, scr));
         w->data->crect.setHeight(DisplayHeight(X11->display, scr));
         if (w->size() != oldSize) {
+#ifndef QT_NO_XINERAMA
+        }
+        int oldNumScreens = desktop()->numScreens();
+        bool oldIsVirtualDesktop = desktop()->isVirtualDesktop();
+        QRect * oldScreens = new QRect[oldNumScreens];
+        for (int i = 0; i < oldNumScreens; ++i) {
+            oldScreens[i] = desktop()->screenGeometry(i);
+        }
+        {
+#endif //QT_NO_XINERAMA
             QResizeEvent e(w->size(), oldSize);
             QApplication::sendEvent(w, &e);
+#ifndef QT_NO_XINERAMA
+        }
+        int numScreens = desktop()->numScreens();
+        if (oldIsVirtualDesktop || desktop()->isVirtualDesktop()) {
+            for (int i = 0; i < oldNumScreens; ++i) {
+                if (i >= numScreens) {
+                    emit desktop()->resized(i);
+                } else {
+                    QRect geo = desktop()->screenGeometry(i);
+                    if (geo != oldScreens[i]) {
+                        emit desktop()->resized(i);
+                    }
+                }
+            }
+            delete [] oldScreens;
+            
+            for (int i = oldNumScreens; i < numScreens; ++i) {
+                emit desktop()->resized(i);
+            }
+        } else if (w->size() != oldSize) {
+            delete [] oldScreens;
+#endif //QT_NO_XINERAMA
             emit desktop()->resized(scr);
         }
     }

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

Index: workspace/plasma/plasma/desktopcorona.cpp
===================================================================
--- workspace/plasma/plasma/desktopcorona.cpp	(Revision 789503)
+++ workspace/plasma/plasma/desktopcorona.cpp	(Arbeitskopie)
@@ -57,28 +57,36 @@
     // quick sanity check to ensure we have containments for each screen!
     int numScreens = QApplication::desktop()->numScreens();
     for (int i = 0; i < numScreens; ++i) {
-        if (!containmentForScreen(i)) {
-            //TODO: should we look for containments that aren't asigned but already exist?
-            Plasma::Containment* c = addContainment("desktop");
-            c->setScreen(i);
-            c->setFormFactor(Plasma::Planar);
-            c->flushUpdatedConstraints();
-        }
+        checkScreen(i);
     }
+}
 
-    // now ensure that if our screen count changed we actually get views
-    // for them, even if the Containment already existed for that screen
-    // so we "lie" and emit a containmentAdded signal for every new screen
-    // regardless of whether it actually already existed, or just got added
-    // and therefore had this signal emitted. plasma can handle such
-    // multiple emissions of the signal, and this is simply the most
-    // straightforward way of accomplishing this
-    for (int i = m_numScreens; i < numScreens; ++i) {
-        kDebug() << "Notifying of new screen: " << i;
-        emit containmentAdded(containmentForScreen(i));
+void DesktopCorona::checkScreen(int screen)
+{
+    // this is only needed if new screens appear out of order.
+    // this should never happen though!
+    if (screen > m_numScreens && screen > 0)
+        checkScreen(screen - 1);
+    
+    if (!containmentForScreen(screen)) {
+        //TODO: should we look for containments that aren't asigned but already exist?
+        Plasma::Containment* c = addContainment("desktop");
+        c->setScreen(screen);
+        c->setFormFactor(Plasma::Planar);
+        c->flushUpdatedConstraints();
+    } else if (screen >= m_numScreens) {
+        // now ensure that if our screen count changed we actually get views
+        // for them, even if the Containment already existed for that screen
+        // so we "lie" and emit a containmentAdded signal for every new screen
+        // regardless of whether it actually already existed, or just got added
+        // and therefore had this signal emitted. plasma can handle such
+        // multiple emissions of the signal, and this is simply the most
+        // straightforward way of accomplishing this
+        kDebug() << "Notifying of new screen: " << screen;
+        emit containmentAdded(containmentForScreen(screen));
+
+        m_numScreens = screen + 1;
     }
-
-    m_numScreens = numScreens;
 }
 
 void DesktopCorona::loadDefaultSetup()
@@ -131,18 +139,17 @@
 
 void DesktopCorona::screenResized(int screen)
 {
-    bool desktopFound = false;
     foreach (Plasma::Containment *c, containments()) {
         if (c->screen() == screen) {
             // trigger a relayout
             c->setScreen(screen);
-            desktopFound = desktopFound ||
-                           c->containmentType() == Plasma::Containment::DesktopContainment ||
-                           c->containmentType() == Plasma::Containment::CustomContainment;
         }
     }
 
-    checkScreens(); // ensure we have containments for every screen
+    // screenResized will also be emitted for removed screens,
+    // we dont need to check on those.
+    if (screen < QApplication::desktop()->numScreens())
+        checkScreen(screen); // ensure we have containments for every screen
 }
 
 #include "desktopcorona.moc"
Index: workspace/plasma/plasma/desktopcorona.h
===================================================================
--- workspace/plasma/plasma/desktopcorona.h	(Revision 789503)
+++ workspace/plasma/plasma/desktopcorona.h	(Arbeitskopie)
@@ -51,6 +51,7 @@
 
 private:
     void init();
+    void checkScreen(int screen);
 
     int m_numScreens;
 };
Index: workspace/plasma/plasma/rootwidget.cpp
===================================================================
--- workspace/plasma/plasma/rootwidget.cpp	(Revision 789503)
+++ workspace/plasma/plasma/rootwidget.cpp	(Arbeitskopie)
@@ -138,6 +138,7 @@
     DesktopView *view = new DesktopView(containment, this);
     view->setGeometry(QApplication::desktop()->screenGeometry(containment->screen()));
     m_desktops.append(view);
+    view->show();
 }
 
 void RootWidget::screenOwnerChanged(int wasScreen, int isScreen, Plasma::Containment* containment)


_______________________________________________
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