I added support to plasma-overlay for multiple screens. For now only tested on 
a TwinView setup.

I am not sure if the work done on lockprocess.cc will work on non Xinerama 
setups.

To let the plasma app work with multiple views I (ab)use signals/slots.

Related bugs:

Bug 193020: Screensaver widgets can't be moved to second monitor
** (not fixed yet)

Bug 197299: screensaver overlay assumes screen starts at (0,0)  screensaver 
overlay assumes screen starts at (0,0)
** (fixed)
Index: krunner/lock/lockprocess.cc
===================================================================
--- krunner/lock/lockprocess.cc	(revisión: 1044119)
+++ krunner/lock/lockprocess.cc	(copia de trabajo)
@@ -1410,8 +1410,31 @@
             {
                 //kDebug() << "forward to plasma";
                 XEvent ev2 = *event;
-                ev2.xkey.window = ev2.xkey.subwindow = mForeignInputWindows.first();
-                XSendEvent(QX11Info::display(), ev2.xkey.window, False, NoEventMask, &ev2);
+                Window root_return;
+                int x_return, y_return;
+                unsigned int width_return, height_return, border_width_return, depth_return;
+                WId targetWindow = 0;
+                kDebug() << "root is" << winId();
+                kDebug() << "search window under pointer with" << mForeignInputWindows.size() << "windows";
+                foreach(WId window, mForeignInputWindows)
+                {
+                    XGetGeometry(QX11Info::display(), window, &root_return,
+                                &x_return, &y_return,
+                                &width_return, &height_return,
+                                &border_width_return, &depth_return);
+                    if( (event->xkey.x>=x_return && event->xkey.x<=x_return+(int)width_return)
+                        &&
+                        (event->xkey.y>=y_return && event->xkey.y<=y_return+(int)height_return) )
+                    {
+                        kDebug() << "found window" << window;
+                        targetWindow = window;
+                        ev2.xkey.window = ev2.xkey.subwindow = targetWindow;
+                        ev2.xkey.x = event->xkey.x - x_return;
+                        ev2.xkey.y = event->xkey.y - y_return;
+                        break;
+                    }
+                }
+                XSendEvent(QX11Info::display(), targetWindow, False, NoEventMask, &ev2);
                 ret = true;
             }
         default:
Index: plasma/screensaver/shell/plasmaapp.cpp
===================================================================
--- plasma/screensaver/shell/plasmaapp.cpp	(revisión: 1044119)
+++ plasma/screensaver/shell/plasmaapp.cpp	(copia de trabajo)
@@ -126,7 +126,6 @@
 PlasmaApp::PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap)
     : KUniqueApplication(display, visual, colormap),
       m_corona(0),
-      m_view(0),
       m_configDialog(0)
 {
     //load translations for libplasma
@@ -142,7 +141,9 @@
     // Add 10% so that other (smaller) pixmaps can also be cached.
     int cacheSize = 0;
     QDesktopWidget *desktop = QApplication::desktop();
-    for (int i = 0; i < desktop->numScreens(); i++) {
+    int numScreens = desktop->numScreens();
+    m_views.resize(numScreens);
+    for (int i = 0; i < numScreens; i++) {
         QRect geometry = desktop->screenGeometry(i);
         cacheSize += 4 * geometry.width() * geometry.height() / 1024;
     }
@@ -226,8 +227,8 @@
         m_corona->saveLayout();
     }
 
-    delete m_view;
-    delete m_corona;
+    //delete m_view; //should not be needed
+    delete m_corona; //should not be needed?
 
     KGlobal::config()->sync();
 }
@@ -238,10 +239,7 @@
         return;
     }
     m_activeOpacity = opacity;
-    if (m_view) {
-        //assume it's active, since things are happening
-        m_view->setWindowOpacity(opacity);
-    }
+    emit setViewOpacity(opacity);
     KConfigGroup cg(KGlobal::config(), "General");
     cg.writeEntry("activeOpacity", opacity);
     m_corona->requestConfigSync();
@@ -271,41 +269,33 @@
 
 void PlasmaApp::setActive(bool activate)
 {
-    if (!m_view) {
-        return;
-    }
-
     if (activate) {
-        m_view->setWindowOpacity(m_activeOpacity);
-        m_view->showView();
-        m_view->containment()->openToolBox();
-    } else if (m_view->isVisible()) {
+        emit setViewOpacity(m_activeOpacity);
+        emit showViews();
+        emit openToolBox(); //TODO slot in Containment?
+    } else {
         if (qFuzzyCompare(m_idleOpacity + qreal(1.0), qreal(1.0))) {
             //opacity is 0
-            m_view->hideView();
+            emit hideViews();
         } else {
             lock();
-            m_view->setWindowOpacity(m_idleOpacity);
-            m_view->containment()->closeToolBox();
+            emit setViewOpacity(m_idleOpacity);
+            emit showViews();
+            emit closeToolBox(); //TODO slot in Containment?
         }
-    } else {
-        if (m_idleOpacity > 0) {
-            m_view->setWindowOpacity(m_idleOpacity);
-            m_view->showView();
-        }
-        lock();
     }
 }
 
 void PlasmaApp::adjustSize(int screen)
 {
-    if (! m_view) {
+    SaverView *view = viewForScreen(screen);
+    if (!view) {
         return;
     }
     //FIXME someone needs to tell us what size to use if we've got >1 screen
     QDesktopWidget *desktop = QApplication::desktop();
-    QRect geom = desktop->screenGeometry(0);
-    m_view->setGeometry(geom);
+    QRect geom = desktop->screenGeometry(screen);
+    view->setGeometry(geom);
 }
 
 void PlasmaApp::syncConfig()
@@ -354,51 +344,53 @@
              <<  "| screen:" << containment->screen()
              << "| geometry:" << containment->geometry()
              << "| zValue:" << containment->zValue();
-
-    if (m_view) {
+    int screen = containment->screen();
+    /*if (m_views.at(screen)) { //why would it come more than once?
         // we already have a view for this screen
-        return;
-    }
+        //return; //actually, the containment comes with an invalid screen
+    }*/
 
     kDebug() << "creating a view for" << containment->screen() << "and we have"
         << QApplication::desktop()->numScreens() << "screens";
 
     // we have a new screen. neat.
-    m_view = new SaverView(containment, 0);
+    SaverView *view = new SaverView(containment, 0);
                 /*if (m_corona) {
                     connect(m_corona, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)),
                             view, SLOT(screenOwnerChanged(int,int,Plasma::Containment*)));
                 }*/
-    //FIXME is this the right geometry for multi-screen?
-    m_view->setGeometry(QApplication::desktop()->screenGeometry(containment->screen()));
+    view->setGeometry(QApplication::desktop()->screenGeometry(containment->screen()));
 
     //FIXME why do I get BadWindow?
     //unsigned char data = VIEW;
-    //XChangeProperty(QX11Info::display(), m_view->effectiveWinId(), tag, tag, 8, PropModeReplace, &data, 1);
+    //XChangeProperty(QX11Info::display(), view->effectiveWinId(), tag, tag, 8, PropModeReplace, &data, 1);
 
     connect(containment, SIGNAL(configureRequested(Plasma::Containment*)),
             this, SLOT(configureContainment(Plasma::Containment*)));
 
     //a hack to make sure the keyboard shortcut works
-    m_view->addAction(corona()->action("unlock desktop"));
-    m_view->addAction(corona()->action("unlock widgets"));
+    view->addAction(corona()->action("unlock desktop"));
+    view->addAction(corona()->action("unlock widgets"));
+    m_views.insert(screen, view);
+    connect(view, SIGNAL(hidden()), SLOT(lock()));
+    connect(view, SIGNAL(hidden()), SIGNAL(hidden()));
+    connect(this, SIGNAL(showViews()), view, SLOT(show()));
+    connect(this, SIGNAL(hideViews()), view, SLOT(hide()));
+    connect(this, SIGNAL(setViewOpacity(qreal)), view, SLOT(setOpacity(qreal)));
+    connect(this, SIGNAL(enableSetupMode()), view, SLOT(disableSetupMode()));
+    connect(this, SIGNAL(disableSetupMode()), view, SLOT(disableSetupMode()));
+    connect(this, SIGNAL(openToolBox()), view, SLOT(openToolBox()));
+    connect(this, SIGNAL(closeToolBox()), view, SLOT(closeToolBox()));
 
-    connect(m_view, SIGNAL(hidden()), SLOT(lock()));
-    connect(m_view, SIGNAL(hidden()), SIGNAL(hidden()));
-
     kDebug() << "view created";
 }
 
 void PlasmaApp::setup(bool setupMode)
 {
-    kDebug() << setupMode;
-    if (! m_view) {
-        kDebug() << "too soon!!";
-        return;
-    }
+    kDebug() << "setup mode:" << setupMode;
 
     if (setupMode) {
-        m_view->enableSetupMode();
+        emit enableSetupMode();
         if (m_corona->immutability() == Plasma::UserImmutable) {
             m_corona->setImmutability(Plasma::Mutable);
         }
@@ -440,6 +432,7 @@
                     //we force-disable window management and frames to cut off access to wm-y stuff
                     //and to make it easy to check the tag (frames are a pain)
                     kDebug() << "!!!!!!!setting flags on!!!!!" << widget;
+                    QDesktopWidget *desktop = QApplication::desktop(); //should this be a member?
                     if (qobject_cast<Plasma::Dialog*>(widget)) {
                         //this is a terrible horrible hack that breaks extenders but it mostly works
                         //weird thing is, it sometimes makes the calendar popup too small.
@@ -449,8 +442,12 @@
                         //but configdialogs need it
                         m_dialogs.append(widget);
                         connect(widget, SIGNAL(destroyed(QObject*)), SLOT(dialogDestroyed(QObject*)));
+                        connect(this, SIGNAL(showDialogs()), widget, SLOT(show()));
+                        connect(this, SIGNAL(hideDialogs()), widget, SLOT(hide()));
                     }
                     widget->setWindowFlags(newFlags);
+                    QRect availableGeometry = desktop->availableGeometry();
+                    widget->move(availableGeometry.x(), availableGeometry.y());
                     widget->show(); //setting the flags hid it :(
                     //qApp->setActiveWindow(widget); //gives kbd but not mouse events
                     //kDebug() << "parent" << widget->parentWidget();
@@ -473,10 +470,11 @@
 {
     m_dialogs.removeAll(qobject_cast<QWidget*>(obj));
     if (m_dialogs.isEmpty()) {
-        if (m_view) {
+        //FIXME multiview
+        //if (m_view) {
             //this makes qactions work again
-            m_view->activateWindow();
-        }
+            //m_view->activateWindow();
+        //}
     /*} else { failed attempt to fix kbd input after a subdialog closes
         QWidget *top = m_dialogs.last();
         top->activateWindow();
@@ -484,29 +482,10 @@
     }
 }
 
-void PlasmaApp::hideDialogs()
-{
-    foreach (QWidget *w, m_dialogs) {
-        w->hide();
-    }
-
-    if (m_view) {
-        m_view->hideWidgetExplorer();
-    }
-    //FIXME where does the focus go?
-}
-
-void PlasmaApp::showDialogs()
-{
-    foreach (QWidget *w, m_dialogs) {
-        w->show();
-    }
-    //FIXME where does the focus go?
-}
-
 void PlasmaApp::configureContainment(Plasma::Containment *containment)
 {
-    if (!m_view) {
+    SaverView *view = viewForScreen(containment->screen());
+    if (!view) {
         return;
     }
 
@@ -515,7 +494,7 @@
     } else {
         const QSize resolution = QApplication::desktop()->screenGeometry(containment->screen()).size();
 
-        m_configDialog = new BackgroundDialog(resolution, containment, m_view);
+        m_configDialog = new BackgroundDialog(resolution, containment, view);
         m_configDialog->setAttribute(Qt::WA_DeleteOnClose);
         connect(m_configDialog, SIGNAL(destroyed(QObject*)),
                 this, SLOT(configDialogRemoved(QObject*)));
@@ -532,6 +511,7 @@
 
 void PlasmaApp::lock()
 {
+    kDebug() << "lock";
     if (corona() && corona()->immutability() == Plasma::Mutable) {
         corona()->setImmutability(Plasma::UserImmutable);
     }
@@ -545,13 +525,17 @@
 void PlasmaApp::immutabilityChanged(Plasma::ImmutabilityType immutability)
 {
     if (immutability == Plasma::Mutable) {
-        showDialogs();
+        emit showDialogs();
     } else {
-        hideDialogs();
-        if (m_view) {
-            m_view->disableSetupMode();
-        }
+        emit hideDialogs();
+        emit hideWidgetExplorer();
+        emit disableSetupMode();
     }
 }
 
+SaverView *PlasmaApp::viewForScreen(int screen)
+{
+    return m_views.at(screen);
+}
+
 #include "plasmaapp.moc"
Index: plasma/screensaver/shell/saverview.h
===================================================================
--- plasma/screensaver/shell/saverview.h	(revisión: 1044119)
+++ plasma/screensaver/shell/saverview.h	(copia de trabajo)
@@ -54,6 +54,7 @@
 public slots:
     void showView();
     void hideView();
+    void setOpacity(qreal opacity);
 
     /**
      * Sets the containment for this view, which will also cause the view
@@ -70,6 +71,8 @@
 protected slots:
     void showWidgetExplorer(); //FIXME actually this is toggle
     void suppressShowTimeout();
+    void openToolBox();
+    void closeToolBox();
 
 private:
     QWeakPointer<Plasma::WidgetExplorer> m_widgetExplorer;
Index: plasma/screensaver/shell/savercorona.cpp
===================================================================
--- plasma/screensaver/shell/savercorona.cpp	(revisión: 1044119)
+++ plasma/screensaver/shell/savercorona.cpp	(copia de trabajo)
@@ -45,10 +45,8 @@
 void SaverCorona::init()
 {
     QDesktopWidget *desktop = QApplication::desktop();
+    connect(desktop,SIGNAL(screenCountChanged(int)), SLOT(numScreensUpdated(int)));
     m_numScreens = desktop->numScreens();
-    if (m_numScreens > 1) {
-        kDebug() << "maybe someone should implement multiple screen support";
-    }
 
     bool unlocked = immutability() == Plasma::Mutable;
 
@@ -80,6 +78,7 @@
 {
     kDebug();
     QString defaultConfig = KStandardDirs::locate("appdata", "plasma-overlay-default-layoutrc");
+
     if (!defaultConfig.isEmpty()) {
         kDebug() << "attempting to load the default layout from:" << defaultConfig;
         loadLayout(defaultConfig);
@@ -88,27 +87,31 @@
 
     QDesktopWidget *desktop = QApplication::desktop();
 
-    // create a containment for the screen
-    QRect g = desktop->screenGeometry(0);
-    kDebug() << "     screen geometry is" << g;
-    Plasma::Containment *c = addContainment("saverdesktop");
-    c->setScreen(0);
-    c->setFormFactor(Plasma::Planar);
-    c->flushPendingConstraintsEvents();
+    // create a containment for the screens
+    Plasma::Containment *c;
+    for(int screen=0; screen<m_numScreens; ++screen)
+    {
+      QRect g = desktop->screenGeometry(screen);
+      kDebug() << "     screen" << screen << "geometry is" << g;
+      c = addContainment("saverdesktop");
+      c->setScreen(screen);
+      c->setFormFactor(Plasma::Planar);
+      c->flushPendingConstraintsEvents();
+    }
 
     // a default clock
-    Plasma::Applet *clock =  Plasma::Applet::load("clock", c->id() + 1);
+    c = containmentForScreen(desktop->primaryScreen());
+    Plasma::Applet *clock =  Plasma::Applet::load("clock"/*, c->id() + 1*/);
     c->addApplet(clock, QPointF(KDialog::spacingHint(), KDialog::spacingHint()), true);
     clock->init();
     clock->flushPendingConstraintsEvents();
 
-    emit containmentAdded(c);
-
+    //emit containmentAdded(c);
 }
 
 int SaverCorona::numScreens() const
 {
-    return QApplication::desktop()->numScreens();
+    return m_numScreens;
 }
 
 QRect SaverCorona::screenGeometry(int id) const
@@ -186,6 +189,12 @@
     }
 }
 
+void SaverCorona::numScreensUpdated(int newCount)
+{
+    m_numScreens = newCount;
+    //do something?
+}
 
+
 #include "savercorona.moc"
 
Index: plasma/screensaver/shell/plasmaapp.h
===================================================================
--- plasma/screensaver/shell/plasmaapp.h	(revisión: 1044119)
+++ plasma/screensaver/shell/plasmaapp.h	(copia de trabajo)
@@ -22,6 +22,7 @@
 #define PLASMA_APP_H
 
 #include <QList>
+#include <QVector>
 
 #include <KUniqueApplication>
 
@@ -97,21 +98,32 @@
     void createView(Plasma::Containment *containment);
     void adjustSize(int screen);
     void dialogDestroyed(QObject *obj);
-    void hideDialogs();
-    void showDialogs();
     void configureContainment(Plasma::Containment*);
     void configDialogRemoved(QObject* dialog);
     void syncConfig();
     void immutabilityChanged(Plasma::ImmutabilityType immutability);
 
+Q_SIGNALS:
+    void showViews();
+    void hideViews();
+    void setViewOpacity(qreal opacity);
+    void showDialogs();
+    void hideDialogs();
+    void hideWidgetExplorer();
+    void enableSetupMode();
+    void disableSetupMode();
+    void openToolBox();
+    void closeToolBox();
+
 protected:
     bool eventFilter(QObject *obj, QEvent *event);
 
 private:
     PlasmaApp(Display* display, Qt::HANDLE visual, Qt::HANDLE colormap);
+    SaverView *viewForScreen(int screen);
 
     Plasma::Corona *m_corona;
-    SaverView *m_view;
+    QVector<SaverView*> m_views;
     QList<QWidget*> m_dialogs;
     BackgroundDialog *m_configDialog;
 
Index: plasma/screensaver/shell/savercorona.h
===================================================================
--- plasma/screensaver/shell/savercorona.h	(revisión: 1044119)
+++ plasma/screensaver/shell/savercorona.h	(copia de trabajo)
@@ -52,6 +52,7 @@
     void unlock(QDBusMessage reply);
     void dbusError(QDBusError error);
     void unlockDesktop();
+    void numScreensUpdated(int newCount);
 
 private:
     void init();
Index: plasma/screensaver/shell/saverview.cpp
===================================================================
--- plasma/screensaver/shell/saverview.cpp	(revisión: 1044119)
+++ plasma/screensaver/shell/saverview.cpp	(copia de trabajo)
@@ -267,5 +267,23 @@
     Plasma::View::keyPressEvent(event);
 }
 
+void SaverView::setOpacity(qreal opacity)
+{
+    setWindowOpacity(opacity);
+}
+
+void SaverView::openToolBox()
+{
+    kDebug() << "close toolbox";
+    containment()->openToolBox();
+}
+
+void SaverView::closeToolBox()
+{
+    kDebug() << "close toolbox";
+    containment()->closeToolBox();
+}
+
+
 #include "saverview.moc"
 

Attachment: 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

Reply via email to