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"
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