diff --git a/kcontrol/screensaver/CMakeLists.txt b/kcontrol/screensaver/CMakeLists.txt index 8a91df6696..d7136d0d5c 100644 --- a/kcontrol/screensaver/CMakeLists.txt +++ b/kcontrol/screensaver/CMakeLists.txt @@ -1,40 +1,40 @@ configure_file (config-screensaver.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-screensaver.h ) ########### next target ############### set(kcm_screensaver_PART_SRCS scrnsave.cpp testwin.cpp saverlist.cpp saverconfig.cpp advanceddialog.cpp kswidget.cpp ) -set(screensaver_xml ${CMAKE_SOURCE_DIR}/workspace/krunner/org.kde.ScreenSaver.xml) +set(screensaver_xml ${CMAKE_SOURCE_DIR}/workspace/krunner/org.freedesktop.ScreenSaver.xml) QT4_ADD_DBUS_INTERFACE( kcm_screensaver_PART_SRCS ${screensaver_xml} screensaver_interface ) kde4_automoc(${kcm_screensaver_PART_SRCS}) kde4_add_ui_files(kcm_screensaver_PART_SRCS advanceddialogimpl.ui ) kde4_add_plugin(kcm_screensaver ${kcm_screensaver_PART_SRCS}) target_link_libraries(kcm_screensaver ${KDE4_KDE3SUPPORT_LIBS}) if(HAVE_GLXCHOOSEVISUAL) target_link_libraries(kcm_screensaver GL) endif(HAVE_GLXCHOOSEVISUAL) install(TARGETS kcm_screensaver DESTINATION ${PLUGIN_INSTALL_DIR} ) ########### install files ############### install( FILES screensaver.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) kde4_install_icons( ${ICON_INSTALL_DIR} ) diff --git a/kcontrol/screensaver/scrnsave.cpp b/kcontrol/screensaver/scrnsave.cpp index 454e89baac..4083e46585 100644 --- a/kcontrol/screensaver/scrnsave.cpp +++ b/kcontrol/screensaver/scrnsave.cpp @@ -1,883 +1,883 @@ //----------------------------------------------------------------------------- // // KDE Display screen saver setup module // // Copyright (c) Martin R. Jones 1996,1999,2002 // // Converted to a kcc module by Matthias Hoelzer 1997 // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //Added by qt3to4: #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "scrnsave.h" #include #include #include #include template class QList; const uint widgetEventMask = // X event mask (uint)( ExposureMask | PropertyChangeMask | StructureNotifyMask ); //=========================================================================== // DLL Interface for kcontrol typedef KGenericFactory KSSFactory; K_EXPORT_COMPONENT_FACTORY (screensaver, KSSFactory("kcmscreensaver") ) static QString findExe(const QString &exe) { QString result = KStandardDirs::locate("exe", exe); if (result.isEmpty()) result = KStandardDirs::findExe(exe); return result; } KScreenSaver::KScreenSaver(QWidget *parent, const QStringList&) : KCModule(KSSFactory::componentData(), parent) { mSetupProc = 0; mPreviewProc = 0; mTestWin = 0; mTestProc = 0; mPrevSelected = -2; mMonitor = 0; mTesting = false; // Add non-KDE path KGlobal::dirs()->addResourceType("scrsav", KGlobal::dirs()->kde_default("apps") + "apps/ScreenSavers/"); setQuickHelp( i18n("

Screen Saver

This module allows you to enable and" " configure a screen saver. Note that you can enable a screen saver" " even if you have power saving features enabled for your display.

" " Besides providing an endless variety of entertainment and" " preventing monitor burn-in, a screen saver also gives you a simple" " way to lock your display if you are going to leave it unattended" " for a while. If you want the screen saver to lock the session, make sure you enable" " the \"Require password\" feature of the screen saver; if you do not, you can still" " explicitly lock the session using the desktop's \"Lock Session\" action.")); setButtons( KCModule::Help | KCModule::Default | KCModule::Apply ); readSettings(); mSetupProc = new KProcess; connect(mSetupProc, SIGNAL(processExited(KProcess *)), this, SLOT(slotSetupDone(KProcess *))); mPreviewProc = new KProcess; connect(mPreviewProc, SIGNAL(processExited(KProcess *)), this, SLOT(slotPreviewExited(KProcess *))); QBoxLayout *topLayout = new QHBoxLayout(this); topLayout->setSpacing(KDialog::spacingHint()); topLayout->setMargin(0); // left column QVBoxLayout *leftColumnLayout = new QVBoxLayout( ); topLayout->addItem( leftColumnLayout ); leftColumnLayout->setSpacing( KDialog::spacingHint() ); QBoxLayout *vLayout = new QVBoxLayout(); leftColumnLayout->addItem( vLayout ); vLayout->setSpacing( KDialog::spacingHint() ); mSaverGroup = new Q3GroupBox(i18n("Screen Saver"), this ); mSaverGroup->setColumnLayout( 0, Qt::Horizontal ); vLayout->addWidget(mSaverGroup); vLayout->setStretchFactor( mSaverGroup, 10 ); QBoxLayout *groupLayout = new QVBoxLayout(); mSaverGroup->layout()->addItem( groupLayout ); groupLayout->setSpacing( KDialog::spacingHint() ); mSaverListView = new Q3ListView( mSaverGroup ); mSaverListView->setMinimumHeight( 120 ); mSaverListView->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding); mSaverListView->addColumn(""); mSaverListView->header()->hide(); mSelected = -1; groupLayout->addWidget( mSaverListView, 10 ); connect( mSaverListView, SIGNAL(doubleClicked ( Q3ListViewItem *)), this, SLOT( slotSetup())); mSaverListView->setWhatsThis( i18n("Select the screen saver to use.") ); QBoxLayout* hlay = new QHBoxLayout(); groupLayout->addItem(hlay); hlay->setSpacing(KDialog::spacingHint()); mSetupBt = new QPushButton( i18n("&Setup..."), mSaverGroup ); connect( mSetupBt, SIGNAL( clicked() ), SLOT( slotSetup() ) ); mSetupBt->setEnabled(false); hlay->addWidget( mSetupBt ); mSetupBt->setWhatsThis( i18n("Configure the screen saver's options, if any.") ); mTestBt = new QPushButton( i18n("&Test"), mSaverGroup ); connect( mTestBt, SIGNAL( clicked() ), SLOT( slotTest() ) ); mTestBt->setEnabled(false); hlay->addWidget( mTestBt ); mTestBt->setWhatsThis( i18n("Show a full screen preview of the screen saver.") ); mSettingsGroup = new Q3GroupBox( i18n("Settings"), this ); mSettingsGroup->setColumnLayout( 0, Qt::Vertical ); leftColumnLayout->addWidget( mSettingsGroup ); groupLayout = new QVBoxLayout(); mSettingsGroup->layout()->addItem( groupLayout ); groupLayout->setSpacing( KDialog::spacingHint() ); mEnabledCheckBox = new QCheckBox(i18n( "Start a&utomatically"), mSettingsGroup); mEnabledCheckBox->setChecked(mEnabled); mEnabledCheckBox->setWhatsThis( i18n( "Automatically start the screen saver after a period of inactivity.") ); connect(mEnabledCheckBox, SIGNAL(toggled(bool)), this, SLOT(slotEnable(bool))); groupLayout->addWidget(mEnabledCheckBox); QBoxLayout *hbox = new QHBoxLayout(); groupLayout->addLayout(hbox); hbox->addSpacing(30); mActivateLbl = new QLabel(i18n("After:"), mSettingsGroup); mActivateLbl->setEnabled(mEnabled); hbox->addWidget(mActivateLbl); mWaitEdit = new QSpinBox(mSettingsGroup); //mWaitEdit->setSteps(1, 10); mWaitEdit->setRange(1, INT_MAX); mWaitEdit->setSuffix(i18n(" min")); mWaitEdit->setValue(mTimeout/60); mWaitEdit->setEnabled(mEnabled); connect(mWaitEdit, SIGNAL(valueChanged(int)), this, SLOT(slotTimeoutChanged(int))); mActivateLbl->setBuddy(mWaitEdit); hbox->addWidget(mWaitEdit); hbox->addStretch(1); QString wtstr = i18n( "The period of inactivity " "after which the screen saver should start."); mActivateLbl->setWhatsThis( wtstr ); mWaitEdit->setWhatsThis( wtstr ); mLockCheckBox = new QCheckBox( i18n( "&Require password to stop"), mSettingsGroup ); mLockCheckBox->setEnabled( mEnabled ); mLockCheckBox->setChecked( mLock ); connect( mLockCheckBox, SIGNAL( toggled( bool ) ), this, SLOT( slotLock( bool ) ) ); groupLayout->addWidget(mLockCheckBox); mLockCheckBox->setWhatsThis( i18n( "Prevent potential unauthorized use by requiring a password" " to stop the screen saver.") ); hbox = new QHBoxLayout(); groupLayout->addLayout(hbox); hbox->addSpacing(30); mLockLbl = new QLabel(i18n("After:"), mSettingsGroup); mLockLbl->setEnabled(mEnabled && mLock); mLockLbl->setWhatsThis( i18n( "The amount of time, after the screen saver has started, to ask for the unlock password.") ); hbox->addWidget(mLockLbl); mWaitLockEdit = new QSpinBox(mSettingsGroup); //mWaitLockEdit->setSteps(1, 10); mWaitLockEdit->setRange(1, 1800); mWaitLockEdit->setSuffix(i18n(" sec")); mWaitLockEdit->setValue(mLockTimeout/1000); mWaitLockEdit->setEnabled(mEnabled && mLock); if ( mWaitLockEdit->sizeHint().width() < mWaitEdit->sizeHint().width() ) { mWaitLockEdit->setFixedWidth( mWaitEdit->sizeHint().width() ); mWaitEdit->setFixedWidth( mWaitEdit->sizeHint().width() ); } else { mWaitEdit->setFixedWidth( mWaitLockEdit->sizeHint().width() ); mWaitLockEdit->setFixedWidth( mWaitLockEdit->sizeHint().width() ); } connect(mWaitLockEdit, SIGNAL(valueChanged(int)), this, SLOT(slotLockTimeoutChanged(int))); mLockLbl->setBuddy(mWaitLockEdit); hbox->addWidget(mWaitLockEdit); hbox->addStretch(1); QString wltstr = i18n( "Choose the period " "after which the display will be locked. "); mLockLbl->setWhatsThis( wltstr ); mWaitLockEdit->setWhatsThis( wltstr ); // right column QBoxLayout* rightColumnLayout = new QVBoxLayout(); topLayout->addItem( rightColumnLayout ); rightColumnLayout->setSpacing( KDialog::spacingHint() ); mMonitorLabel = new QLabel( this ); mMonitorLabel->setAlignment( Qt::AlignCenter ); mMonitorLabel->setPixmap( QPixmap(KStandardDirs::locate("data", "kcontrol/pics/monitor.png"))); rightColumnLayout->addWidget(mMonitorLabel, 0); mMonitorLabel->setWhatsThis( i18n("A preview of the selected screen saver.") ); QBoxLayout* advancedLayout = new QHBoxLayout(); rightColumnLayout->addItem( advancedLayout ); advancedLayout->setSpacing( 3 ); advancedLayout->addWidget( new QWidget( this ) ); QPushButton* advancedBt = new QPushButton( i18n( "Advanced &Options" ), this ); advancedBt->setObjectName("advancedBtn"); advancedBt->setSizePolicy( QSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed) ); connect( advancedBt, SIGNAL( clicked() ), this, SLOT( slotAdvanced() ) ); advancedLayout->addWidget( advancedBt ); advancedLayout->addWidget( new QWidget( this ) ); rightColumnLayout->addStretch(); if (mImmutable) { setButtons(buttons() & ~Default); mSettingsGroup->setEnabled(false); mSaverGroup->setEnabled(false); } // finding the savers can take some time, so defer loading until // we've started up. mNumLoaded = 0; mLoadTimer = new QTimer( this ); connect( mLoadTimer, SIGNAL(timeout()), SLOT(findSavers()) ); mLoadTimer->start( 100 ); mChanged = false; emit changed(false); KAboutData *about = new KAboutData(I18N_NOOP("kcmscreensaver"), I18N_NOOP("KDE Screen Saver Control Module"), 0, 0, KAboutData::License_GPL, I18N_NOOP("(c) 1997-2002 Martin R. Jones\n" "(c) 2003-2004 Chris Howells")); about->addAuthor("Chris Howells", 0, "howells@kde.org"); about->addAuthor("Martin R. Jones", 0, "jones@kde.org"); setAboutData( about ); } //--------------------------------------------------------------------------- // void KScreenSaver::resizeEvent( QResizeEvent * ) { if (mMonitor) { mMonitor->setGeometry( (mMonitorLabel->width()-200)/2+23, (mMonitorLabel->height()-186)/2+14, 151, 115 ); } } //--------------------------------------------------------------------------- // void KScreenSaver::mousePressEvent( QMouseEvent *) { if ( mTesting ) slotStopTest(); } //--------------------------------------------------------------------------- // void KScreenSaver::keyPressEvent( QKeyEvent *) { if ( mTesting ) slotStopTest(); } //--------------------------------------------------------------------------- // KScreenSaver::~KScreenSaver() { if (mPreviewProc) { if (mPreviewProc->isRunning()) { int pid = mPreviewProc->pid(); mPreviewProc->kill( ); waitpid(pid, (int *) 0,0); } delete mPreviewProc; } delete mTestProc; delete mSetupProc; delete mTestWin; qDeleteAll(mSaverList); } //--------------------------------------------------------------------------- // void KScreenSaver::load() { readSettings(); //with the following line, the Test and Setup buttons are not enabled correctly //if no saver was selected, the "Reset" and the "Enable screensaver", it is only called when starting and when pressing reset, aleXXX // mSelected = -1; int i = 0; Q3ListViewItem *selectedItem = 0; Q_FOREACH( SaverConfig* saver, mSaverList ){ if (saver->file() == mSaver) { selectedItem = mSaverListView->findItem ( saver->name(), 0 ); if (selectedItem) { mSelected = i; break; } } i++; } if ( selectedItem ) { mSaverListView->setSelected( selectedItem, true ); mSaverListView->setCurrentItem( selectedItem ); slotScreenSaver( selectedItem ); } updateValues(); mChanged = false; emit changed(false); } //------------------------------------------------------------After--------------- // void KScreenSaver::readSettings() { KConfigGroup config( KSharedConfig::openConfig( "kscreensaverrc"), "ScreenSaver" ); mImmutable = config.groupIsImmutable(); mEnabled = config.readEntry("Enabled", false); mTimeout = config.readEntry("Timeout", 300); mLockTimeout = config.readEntry("LockGrace", 60000); mLock = config.readEntry("Lock", false); mSaver = config.readEntry("Saver"); if (mTimeout < 60) mTimeout = 60; if (mLockTimeout < 0) mLockTimeout = 0; if (mLockTimeout > 1800000) mLockTimeout = 1800000; mChanged = false; } //--------------------------------------------------------------------------- // void KScreenSaver::updateValues() { if (mEnabled) { mWaitEdit->setValue(mTimeout/60); } else { mWaitEdit->setValue(0); } mWaitLockEdit->setValue(mLockTimeout/1000); mLockCheckBox->setChecked(mLock); } //--------------------------------------------------------------------------- // void KScreenSaver::defaults() { if (mImmutable) return; slotScreenSaver( 0 ); Q3ListViewItem *item = mSaverListView->firstChild(); if (item) { mSaverListView->setSelected( item, true ); mSaverListView->setCurrentItem( item ); mSaverListView->ensureItemVisible( item ); } slotTimeoutChanged( 5 ); slotLockTimeoutChanged( 60 ); slotLock( false ); updateValues(); emit changed(true); } //--------------------------------------------------------------------------- // void KScreenSaver::save() { if ( !mChanged ) return; KConfigGroup config(KSharedConfig::openConfig( "kscreensaverrc"), "ScreenSaver" ); config.writeEntry("Enabled", mEnabled); config.writeEntry("Timeout", mTimeout); config.writeEntry("LockGrace", mLockTimeout); config.writeEntry("Lock", mLock); if ( !mSaver.isEmpty() ) config.writeEntry("Saver", mSaver); config.sync(); // TODO (GJ): When you changed anything, these two lines will give a segfault // on exit. I don't know why yet. - org::kde::ScreenSaver desktop("org.kde.screensaver", "/Screensaver", QDBusConnection::sessionBus()); + org::freedesktop::ScreenSaver desktop("org.freedesktop.ScreenSaver", "/Screensaver", QDBusConnection::sessionBus()); desktop.configure(); mChanged = false; emit changed(false); } //--------------------------------------------------------------------------- // void KScreenSaver::findSavers() { if ( !mNumLoaded ) { mSaverServices = KServiceTypeTrader::self()->query( "ScreenSaver"); new Q3ListViewItem ( mSaverListView, i18n("Loading...") ); if ( mSaverServices.isEmpty() ) mLoadTimer->stop(); else mLoadTimer->start( 50 ); } for( KService::List::const_iterator it = mSaverServices.begin(); it != mSaverServices.end(); it++,mNumLoaded++) { SaverConfig *saver = new SaverConfig; QString file = KStandardDirs::locate("services", (*it)->desktopEntryPath()); if (saver->read(file)) { mSaverList.append(saver); } else delete saver; } if ( mNumLoaded == mSaverServices.count() ) { Q3ListViewItem *selectedItem = 0; int categoryCount = 0; int indx = 0; mLoadTimer->stop(); delete mLoadTimer; qSort(mSaverList.begin(), mSaverList.end()); mSelected = -1; mSaverListView->clear(); Q_FOREACH( SaverConfig *s, mSaverList ) { Q3ListViewItem *item; if (s->category().isEmpty()) item = new Q3ListViewItem ( mSaverListView, s->name(), '2' + s->name() ); else { Q3ListViewItem *categoryItem = mSaverListView->findItem( s->category(), 0 ); if ( !categoryItem ) { categoryItem = new Q3ListViewItem ( mSaverListView, s->category(), '1' + s->category() ); categoryItem->setPixmap ( 0, SmallIcon ( "kscreensaver" ) ); } item = new Q3ListViewItem ( categoryItem, s->name(), s->name() ); categoryCount++; } if (s->file() == mSaver) { mSelected = indx; selectedItem = item; } indx++; } // Delete categories with only one item Q3ListViewItemIterator it ( mSaverListView ); for ( ; it.current(); it++ ) if ( it.current()->childCount() == 1 ) { Q3ListViewItem *item = it.current()->firstChild(); it.current()->takeItem( item ); mSaverListView->insertItem ( item ); delete it.current(); categoryCount--; } mSaverListView->setRootIsDecorated ( categoryCount > 0 ); mSaverListView->setSorting ( 1 ); if ( mSelected > -1 ) { mSaverListView->setSelected(selectedItem, true); mSaverListView->setCurrentItem(selectedItem); mSaverListView->ensureItemVisible(selectedItem); mSetupBt->setEnabled(!mSaverList.at(mSelected)->setup().isEmpty()); mTestBt->setEnabled(true); } connect( mSaverListView, SIGNAL( currentChanged( Q3ListViewItem * ) ), this, SLOT( slotScreenSaver( Q3ListViewItem * ) ) ); setMonitor(); } } //--------------------------------------------------------------------------- // void KScreenSaver::setMonitor() { if (mPreviewProc->isRunning()) // CC: this will automatically cause a "slotPreviewExited" // when the viewer exits mPreviewProc->kill(); else slotPreviewExited(mPreviewProc); } //--------------------------------------------------------------------------- // void KScreenSaver::slotPreviewExited(KProcess *) { // Ugly hack to prevent continual respawning of savers that crash if (mSelected == mPrevSelected) return; if ( mSaverList.isEmpty() ) // safety check return; // Some xscreensaver hacks do something nasty to the window that // requires a new one to be created (or proper investigation of the // problem). delete mMonitor; mMonitor = new KSSMonitor(mMonitorLabel); QPalette palette; palette.setColor(mMonitor->backgroundRole(), Qt::black); mMonitor->setPalette(palette); mMonitor->setGeometry((mMonitorLabel->width()-200)/2+23, (mMonitorLabel->height()-186)/2+14, 151, 115); mMonitor->show(); // So that hacks can XSelectInput ButtonPressMask XSelectInput(QX11Info::display(), mMonitor->winId(), widgetEventMask ); if (mSelected >= 0) { mPreviewProc->clearArguments(); QString saver = mSaverList.at(mSelected)->saver(); QTextStream ts(&saver, QIODevice::ReadOnly); QString word; ts >> word; QString path = findExe(word); if (!path.isEmpty()) { (*mPreviewProc) << path; while (!ts.atEnd()) { ts >> word; if (word == "%w") { word = word.setNum(mMonitor->winId()); } (*mPreviewProc) << word; } mPreviewProc->start(); } } mPrevSelected = mSelected; } //--------------------------------------------------------------------------- // void KScreenSaver::slotEnable(bool e) { mEnabled = e; mActivateLbl->setEnabled( e ); mWaitEdit->setEnabled( e ); mLockCheckBox->setEnabled( e ); mLockLbl->setEnabled( e && mLock ); mWaitLockEdit->setEnabled( e && mLock ); mChanged = true; emit changed(true); } //--------------------------------------------------------------------------- // void KScreenSaver::slotScreenSaver(Q3ListViewItem *item) { if (!item) return; int i = 0, indx = -1; Q_FOREACH( SaverConfig* saver , mSaverList ){ if ( item->parent() ) { if ( item->parent()->text( 0 ) == saver->category() && saver->name() == item->text (0)) { indx = i; break; } } else { if ( saver->name() == item->text (0) ) { indx = i; break; } } i++; } if (indx == -1) { mSelected = -1; return; } bool bChanged = (indx != mSelected); if (!mSetupProc->isRunning()) mSetupBt->setEnabled(!mSaverList.at(indx)->setup().isEmpty()); mTestBt->setEnabled(true); mSaver = mSaverList.at(indx)->file(); mSelected = indx; setMonitor(); if (bChanged) { mChanged = true; emit changed(true); } } //--------------------------------------------------------------------------- // void KScreenSaver::slotSetup() { if ( mSelected < 0 ) return; if (mSetupProc->isRunning()) return; mSetupProc->clearArguments(); QString saver = mSaverList.at(mSelected)->setup(); if( saver.isEmpty()) return; QTextStream ts(&saver, QIODevice::ReadOnly); QString word; ts >> word; bool kxsconfig = word == "kxsconfig"; QString path = findExe(word); if (!path.isEmpty()) { (*mSetupProc) << path; // Add caption and icon to about dialog if (!kxsconfig) { word = "-caption"; (*mSetupProc) << word; word = mSaverList.at(mSelected)->name(); (*mSetupProc) << word; word = "-icon"; (*mSetupProc) << word; word = "kscreensaver"; (*mSetupProc) << word; } while (!ts.atEnd()) { ts >> word; (*mSetupProc) << word; } // Pass translated name to kxsconfig if (kxsconfig) { word = mSaverList.at(mSelected)->name(); (*mSetupProc) << word; } mSetupBt->setEnabled( false ); kapp->flush(); mSetupProc->start(); } } //--------------------------------------------------------------------------- // void KScreenSaver::slotAdvanced() { KScreenSaverAdvancedDialog dlg( topLevelWidget() ); if ( dlg.exec() ) { mChanged = true; emit changed(true); } } //--------------------------------------------------------------------------- // void KScreenSaver::slotTest() { if ( mSelected == -1 ) return; if (!mTestProc) { mTestProc = new KProcess; } mTestProc->clearArguments(); QString saver = mSaverList.at(mSelected)->saver(); QTextStream ts(&saver, QIODevice::ReadOnly); QString word; ts >> word; QString path = findExe(word); if (!path.isEmpty()) { (*mTestProc) << path; if (!mTestWin) { mTestWin = new TestWin(); mTestWin->setAttribute(Qt::WA_NoSystemBackground, true); mTestWin->setGeometry(0, 0, qApp->desktop()->width(), qApp->desktop()->height()); } mTestWin->show(); mTestWin->raise(); mTestWin->setFocus(); // So that hacks can XSelectInput ButtonPressMask XSelectInput(QX11Info::display(), mTestWin->winId(), widgetEventMask ); grabMouse(); grabKeyboard(); mTestBt->setEnabled( false ); mPreviewProc->kill(); while (!ts.atEnd()) { ts >> word; if (word == "%w") { word = word.setNum(mTestWin->winId()); } (*mTestProc) << word; } mTesting = true; mTestProc->start(KProcess::NotifyOnExit); } } //--------------------------------------------------------------------------- // void KScreenSaver::slotStopTest() { if (mTestProc->isRunning()) { mTestProc->kill(); } releaseMouse(); releaseKeyboard(); mTestWin->hide(); mTestBt->setEnabled(true); mPrevSelected = -1; setMonitor(); mTesting = false; } //--------------------------------------------------------------------------- // void KScreenSaver::slotTimeoutChanged(int to ) { mTimeout = to * 60; mChanged = true; emit changed(true); } //----------------------------------------------------------------------- // void KScreenSaver::slotLockTimeoutChanged(int to ) { mLockTimeout = to * 1000; mChanged = true; emit changed(true); } //--------------------------------------------------------------------------- // void KScreenSaver::slotLock( bool l ) { mLock = l; mLockLbl->setEnabled( l ); mWaitLockEdit->setEnabled( l ); mChanged = true; emit changed(true); } //--------------------------------------------------------------------------- // void KScreenSaver::slotSetupDone(KProcess *) { mPrevSelected = -1; // see ugly hack in slotPreviewExited() setMonitor(); mSetupBt->setEnabled( true ); emit changed(true); } #include "scrnsave.moc" diff --git a/kicker/applets/launcher/CMakeLists.txt b/kicker/applets/launcher/CMakeLists.txt index a4522c1ac8..f916a8186f 100644 --- a/kicker/applets/launcher/CMakeLists.txt +++ b/kicker/applets/launcher/CMakeLists.txt @@ -1,43 +1,43 @@ include_directories( ${CMAKE_SOURCE_DIR}/libkonq ${CMAKE_SOURCE_DIR}/workspace/kicker/kicker/buttons ${CMAKE_SOURCE_DIR}/workspace/kicker/kicker/core ${CMAKE_SOURCE_DIR}/kicker/kicker/ui ${CMAKE_SOURCE_DIR}/workspace/kicker/kicker/ui ${CMAKE_BINARY_DIR}/workspace/kicker/kicker ) ########### next target ############### #### ****** So many sources? This is recompiling all of kicker! This needs to be fixed! ****** #### set(launcher_panelapplet_PART_SRCS ${libkicker_core_SRCS} ${libkicker_buttons_SRCS} ${libkicker_ui_SRCS} quicklauncher.cpp quickbutton.cpp quickaddappsmenu.cpp flowgridmanager.cpp popularity.cpp configdlg.cpp ) -qt4_add_dbus_interface(launcher_panelapplet_PART_SRCS ../../../krunner/org.kde.ScreenSaver.xml screensaver_interface ) +qt4_add_dbus_interface(launcher_panelapplet_PART_SRCS ../../../krunner/org.freedesktop.ScreenSaver.xml screensaver_interface ) qt4_add_dbus_interface(launcher_panelapplet_PART_SRCS ../../../kdesktop/org.kde.kdesktop.Desktop.xml kdesktop_interface ) qt4_add_dbus_interface(launcher_panelapplet_PART_SRCS ../../../krunner/org.kde.krunner.Interface.xml krunner_interface ) kde4_add_ui3_files(launcher_panelapplet_PART_SRCS ${CMAKE_SOURCE_DIR}/workspace/kicker/kicker/ui/appletview.ui ${CMAKE_SOURCE_DIR}/workspace/kicker/kicker/ui/nonKDEButtonSettings.ui) kde4_automoc(${launcher_panelapplet_PART_SRCS}) kde4_add_ui3_files(launcher_panelapplet_PART_SRCS configdlgbase.ui ) kde4_add_kcfg_files(launcher_panelapplet_PART_SRCS prefs.kcfgc ) kde4_add_plugin(launcher_panelapplet ${launcher_panelapplet_PART_SRCS}) target_link_libraries(launcher_panelapplet ${KDE4_KDE3SUPPORT_LIBS} kworkspace konq kickermain ) install(TARGETS launcher_panelapplet DESTINATION ${PLUGIN_INSTALL_DIR} ) ########### install files ############### install( FILES launcherapplet.kcfg DESTINATION ${KCFG_INSTALL_DIR} ) install( FILES quicklauncher.desktop DESTINATION ${DATA_INSTALL_DIR}/kicker/applets ) diff --git a/kicker/kicker/CMakeLists.txt b/kicker/kicker/CMakeLists.txt index 77d43fb99c..9b14bf6351 100644 --- a/kicker/kicker/CMakeLists.txt +++ b/kicker/kicker/CMakeLists.txt @@ -1,52 +1,52 @@ add_subdirectory( core ) add_subdirectory( buttons ) include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/buttons ${CMAKE_SOURCE_DIR}/libkonq ${CMAKE_CURRENT_SOURCE_DIR}/core ${CMAKE_CURRENT_SOURCE_DIR}/ui ) ########### next target ############### kde4_add_ui3_files(libkicker_ui_SRCS ui/nonKDEButtonSettings.ui) kde4_add_ui_files(libkicker_ui_SRCS ui/appletview.ui) qt4_add_dbus_interface(libkicker_ui_SRCS ../../krunner/org.kde.krunner.Interface.xml krunner_interface ) -qt4_add_dbus_interface(libkicker_ui_SRCS ../../krunner/org.kde.ScreenSaver.xml screensaver_interface ) +qt4_add_dbus_interface(libkicker_ui_SRCS ../../krunner/org.freedesktop.ScreenSaver.xml screensaver_interface ) set(kicker_KDEINIT_SRCS ${libkicker_buttons_SRCS} ${libkicker_ui_SRCS} ${libkicker_core_SRCS} ) kde4_automoc(${kicker_KDEINIT_SRCS}) kde4_add_kdeinit_executable( kicker ${kicker_KDEINIT_SRCS}) target_link_libraries(kdeinit_kicker ${KDE4_KIO_LIBS} kickermain ${KDE4_KUTILS_LIBS} kworkspace konq ) install(TARGETS kdeinit_kicker DESTINATION ${LIB_INSTALL_DIR} ) target_link_libraries( kicker kdeinit_kicker ) install(TARGETS kicker DESTINATION ${BIN_INSTALL_DIR}) ########### next target ############### set(kicker_reverseLayout_SRCS kicker-3.4-reverseLayout.cpp) kde4_automoc(${kicker_reverseLayout_SRCS}) kde4_add_executable( kicker-3.4-reverseLayout ${kicker_reverseLayout_SRCS}) target_link_libraries( kicker-3.4-reverseLayout ${KDE4_KDEUI_LIBS}) install(TARGETS kicker-3.4-reverseLayout DESTINATION ${LIB_INSTALL_DIR}/kconf_update_bin/ ) ########### install files ############### install( FILES kcmkicker.desktop DESTINATION ${SERVICES_INSTALL_DIR} ) install( FILES panel.desktop DESTINATION ${AUTOSTART_INSTALL_DIR} ) install( FILES kickerrc.upd DESTINATION ${KCONF_UPDATE_INSTALL_DIR} ) install(PROGRAMS kicker-3.1-properSizeSetting.pl kicker-3.5-taskbarEnums.pl kicker-3.5-kconfigXTize.pl DESTINATION ${KCONF_UPDATE_INSTALL_DIR} ) diff --git a/kicker/kicker/ui/k_mnu.cpp b/kicker/kicker/ui/k_mnu.cpp index 2d74cdf902..1947b4b085 100644 --- a/kicker/kicker/ui/k_mnu.cpp +++ b/kicker/kicker/ui/k_mnu.cpp @@ -1,709 +1,709 @@ /***************************************************************** Copyright (c) 1996-2000 the kicker authors. See file AUTHORS. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "utils.h" #include "container_base.h" #include "kicker.h" #include "kickerSettings.h" #include "konqbookmarkmanager.h" #include "menuinfo.h" #include "quickbrowser_mnu.h" #include "recentapps.h" #include "k_mnu.h" #include "krunner_interface.h" #include "screensaver_interface.h" #include "k_mnu.moc" PanelKMenu::PanelKMenu() : PanelServiceMenu(QString(), QString(), 0, "KMenu") , bookmarkMenu(0) { // set the first client id to some arbitrarily large value. client_id = 10000; // Don't automatically clear the main menu. disableAutoClear(); actionCollection = new KActionCollection(this); setWindowTitle(i18n("K Menu")); connect(Kicker::self(), SIGNAL(configurationChanged()), this, SLOT(configChanged())); /* FIXME: we need a proper way to file recent app/doc usage DCOPClient *dcopClient = KApplication::dcopClient(); dcopClient->connectDCOPSignal(0, "appLauncher", "serviceStartedByStorageId(QString,QString)", dcopObjId, "slotServiceStartedByStorageId(QString,QString)", false); */ } PanelKMenu::~PanelKMenu() { clearSubmenus(); delete bookmarkMenu; } #if 0 void PanelKMenu::slotServiceStartedByStorageId(QString starter, QString storageId) { if (starter != "kmenu") { kDebug() << "KMenu - updating recently used applications: " << storageId << endl; KService::Ptr service = KService::serviceByStorageId(storageId); RecentlyLaunchedApps::self().updateRecentlyUsedApps(service); } } #endif bool PanelKMenu::loadSidePixmap() { if (!KickerSettings::useSidePixmap()) { return false; } QString sideName = KickerSettings::sidePixmapName(); QString sideTileName = KickerSettings::sideTileName(); QImage image; image.load(KStandardDirs::locate("data", "kicker/pics/" + sideName)); if (image.isNull()) { kDebug(1210) << "Can't find a side pixmap" << endl; return false; } Plasma::colorize(image); sidePixmap = QPixmap::fromImage(image); image.load(KStandardDirs::locate("data", "kicker/pics/" + sideTileName)); if (image.isNull()) { kDebug(1210) << "Can't find a side tile pixmap" << endl; return false; } Plasma::colorize(image); sideTilePixmap = QPixmap::fromImage(image); if (sidePixmap.width() != sideTilePixmap.width()) { kDebug(1210) << "Pixmaps have to be the same size" << endl; return false; } // pretile the pixmap to a height of at least 100 pixels if (sideTilePixmap.height() < 100) { int tiles = (int)(100 / sideTilePixmap.height()) + 1; QPixmap preTiledPixmap(sideTilePixmap.width(), sideTilePixmap.height() * tiles); QPainter p(&preTiledPixmap); p.drawTiledPixmap(preTiledPixmap.rect(), sideTilePixmap); sideTilePixmap = preTiledPixmap; } return true; } void PanelKMenu::paletteChanged() { if (!loadSidePixmap()) { sidePixmap = sideTilePixmap = QPixmap(); setMinimumSize( sizeHint() ); } } void PanelKMenu::initialize() { // kDebug(1210) << "PanelKMenu::initialize()" << endl; updateRecent(); if (initialized()) { return; } if (loadSidePixmap()) { // in case we've been through here before, let's disconnect disconnect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(paletteChanged())); connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(paletteChanged())); } else { sidePixmap = sideTilePixmap = QPixmap(); } // add services PanelServiceMenu::initialize(); /* FIXME: no more insertTitle! now what? if (KickerSettings::showMenuTitles()) { int id; id = insertTitle(i18n("All Applications"), -1, 0); setItemEnabled( id, false ); id = insertTitle(i18n("Actions"), -1 , -1); setItemEnabled( id, false ); } */ // create recent menu section createRecentMenuItems(); bool need_separator = false; // insert bookmarks if (KickerSettings::useBookmarks() && KAuthorized::authorizeKAction("bookmarks")) { // Need to create a new popup each time, it's deleted by subMenus.clear() KMenu * bookmarkParent = new KMenu(this); bookmarkParent->setObjectName("bookmarks" ); delete bookmarkMenu; // can't reuse old one, the popup has been deleted bookmarkMenu = new KBookmarkMenu( KonqBookmarkManager::self(), 0, bookmarkParent, actionCollection ); insertItem(Plasma::menuIconSet("bookmark"), i18n("Bookmarks"), bookmarkParent); subMenus.append(bookmarkParent); need_separator = true; } // insert quickbrowser if (KickerSettings::useBrowser()) { PanelQuickBrowser *browserMnu = new PanelQuickBrowser(this); browserMnu->initialize(); insertItem(Plasma::menuIconSet("kdisknav"), i18n("Quick Browser"), Plasma::reduceMenu(browserMnu)); subMenus.append(browserMnu); need_separator = true; } // insert dynamic menus QStringList menu_ext = KickerSettings::menuExtensions(); if (!menu_ext.isEmpty()) { for (QStringList::ConstIterator it=menu_ext.begin(); it!=menu_ext.end(); ++it) { MenuInfo info(*it); if (!info.isValid()) continue; KPanelMenu *menu = info.load(); if (menu) { insertItem(Plasma::menuIconSet(info.icon()), info.name(), menu); dynamicSubMenus.append(menu); need_separator = true; } } } if (need_separator) addSeparator(); // run command if (KAuthorized::authorizeKAction("run_command")) { insertItem(Plasma::menuIconSet("run"), i18n("Run Command..."), this, SLOT( slotRunCommand())); addSeparator(); } if (DM().isSwitchable() && KAuthorized::authorizeKAction("switch_user")) { sessionsMenu = new QMenu( this ); insertItem(Plasma::menuIconSet("switchuser"), i18n("Switch User"), sessionsMenu); connect( sessionsMenu, SIGNAL(aboutToShow()), SLOT(slotPopulateSessions()) ); connect( sessionsMenu, SIGNAL(activated(int)), SLOT(slotSessionActivated(int)) ); } /* If the user configured ksmserver to */ KConfig ksmserver("ksmserverrc", KConfig::NoGlobals); if (ksmserver.group("General").readEntry( "loginMode" ) == "restoreSavedSession") { insertItem(Plasma::menuIconSet("filesave"), i18n("Save Session"), this, SLOT(slotSaveSession())); } if (KAuthorized::authorizeKAction("lock_screen")) { insertItem(Plasma::menuIconSet("lock"), i18n("Lock Session"), this, SLOT(slotLock())); } if (KAuthorized::authorizeKAction("logout")) { insertItem(Plasma::menuIconSet("exit"), i18n("Log Out..."), this, SLOT(slotLogout())); } #if 0 // WABA: tear off handles don't work together with dynamically updated // menus. We can't update the menu while torn off, and we don't know // when it is torn off. if (KGlobalSettings::insertTearOffHandle()) insertTearOffHandle(); #endif setInitialized(true); } extern int kicker_screen_number; void PanelKMenu::slotLock() { - QString interface( "org.kde.screensaver" ); - org::kde::ScreenSaver screenSaverInterface( interface, "/ScreenSaver", QDBusConnection::sessionBus() ); + QString interface( "org.freedesktop.ScreenSaver" ); + org::freedesktop::ScreenSaver screenSaverInterface( interface, "/ScreenSaver", QDBusConnection::sessionBus() ); if ( screenSaverInterface.isValid() ) screenSaverInterface.lock(); } void PanelKMenu::slotLogout() { KWorkSpace::requestShutDown(); } void PanelKMenu::slotPopulateSessions() { int p = 0; DM dm; sessionsMenu->clear(); if (KAuthorized::authorizeKAction("start_new_session") && (p = dm.numReserve()) >= 0) { if (KAuthorized::authorizeKAction("lock_screen")) sessionsMenu->insertItem(/*KIcon("lockfork"),*/ i18n("Lock Current && Start New Session"), 100 ); sessionsMenu->insertItem(KIcon("fork"), i18n("Start New Session"), 101 ); if (!p) { sessionsMenu->setItemEnabled( 100, false ); sessionsMenu->setItemEnabled( 101, false ); } sessionsMenu->addSeparator(); } SessList sess; if (dm.localSessions( sess )) for (SessList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { int id = sessionsMenu->insertItem( DM::sess2Str( *it ), (*it).vt ); if (!(*it).vt) sessionsMenu->setItemEnabled( id, false ); if ((*it).self) sessionsMenu->setItemChecked( id, true ); } } void PanelKMenu::slotSessionActivated( int ent ) { if (ent == 100) doNewSession( true ); else if (ent == 101) doNewSession( false ); else if (!sessionsMenu->isItemChecked( ent )) DM().lockSwitchVT( ent ); } void PanelKMenu::doNewSession( bool lock ) { int result = KMessageBox::warningContinueCancel( kapp->desktop()->screen(kapp->desktop()->screenNumber(this)), i18n("

You have chosen to open another desktop session.
" "The current session will be hidden " "and a new login screen will be displayed.
" "An F-key is assigned to each session; " "F%1 is usually assigned to the first session, " "F%2 to the second session and so on. " "You can switch between sessions by pressing " "Ctrl, Alt and the appropriate F-key at the same time. " "Additionally, the KDE Panel and Desktop menus have " "actions for switching between sessions.

", 7, 8), i18n("Warning - New Session"), KGuiItem(i18n("&Start New Session"), "fork"), ":confirmNewSession", KMessageBox::PlainCaption | KMessageBox::Notify); if (result==KMessageBox::Cancel) return; if (lock) slotLock(); DM().startReserve(); } void PanelKMenu::slotSaveSession() { QDBusInterface ksmserver("org.kde.ksmserver", "/ksmserver", "org.kde.KSMServerInterface"); ksmserver.call("saveCurrentSession"); } void PanelKMenu::slotRunCommand() { QString interface( "org.kde.krunner" ); org::kde::krunner::Interface desktopInterface( interface, "/Interface", QDBusConnection::sessionBus() ); desktopInterface.display(); } void PanelKMenu::slotEditUserContact() { } void PanelKMenu::setMinimumSize(const QSize & s) { KPanelMenu::setMinimumSize(s.width() + sidePixmap.width(), s.height()); } void PanelKMenu::setMaximumSize(const QSize & s) { KPanelMenu::setMaximumSize(s.width() + sidePixmap.width(), s.height()); } void PanelKMenu::setMinimumSize(int w, int h) { KPanelMenu::setMinimumSize(w + sidePixmap.width(), h); } void PanelKMenu::setMaximumSize(int w, int h) { KPanelMenu::setMaximumSize(w + sidePixmap.width(), h); } QRect PanelKMenu::sideImageRect() { return QStyle::visualRect( layoutDirection(), rect(), QRect( frameWidth(), frameWidth(), sidePixmap.width(), height() - 2*frameWidth() ) ); } void PanelKMenu::resizeEvent(QResizeEvent * e) { // kDebug(1210) << "PanelKMenu::resizeEvent():" << endl; // kDebug(1210) << geometry().width() << ", " << geometry().height() << endl; PanelServiceMenu::resizeEvent(e); #ifdef __GNUC__ #warning "KDE4: Qt4 doesn't seem to provide a way of doing this, will need different impl. for side image" #endif // setFrameRect( QStyle::visualRect( layoutDirection(), rect(), QRect( sidePixmap.width(), 0, // width() - sidePixmap.width(), height() ) ) ); } //Workaround Qt3.3.x sizing bug, by ensuring we're always wide enough. void PanelKMenu::resize(int width, int height) { width = qMax(width, maximumSize().width()); PanelServiceMenu::resize(width, height); } QSize PanelKMenu::sizeHint() const { QSize s = PanelServiceMenu::sizeHint(); // kDebug(1210) << "PanelKMenu::sizeHint()" << endl; // kDebug(1210) << s.width() << ", " << s.height() << endl; return s; } void PanelKMenu::paintEvent(QPaintEvent * e) { if (sidePixmap.isNull()) { PanelServiceMenu::paintEvent(e); return; } QPainter p(this); p.setClipRegion(e->region()); QStyleOptionFrame frOpt; frOpt.init(this); frOpt.lineWidth = frameWidth(); frOpt.midLineWidth = 0; style()->drawPrimitive( QStyle::PE_FrameMenu, &frOpt, &p, this); QRect r = sideImageRect(); r.setBottom( r.bottom() - sidePixmap.height() ); if ( r.intersects( e->rect() ) ) { p.drawTiledPixmap( r, sideTilePixmap ); } r = sideImageRect(); r.setTop( r.bottom() - sidePixmap.height() ); if ( r.intersects( e->rect() ) ) { QRect drawRect = r.intersect( e->rect() ); QRect pixRect = drawRect; pixRect.translate( -r.left(), -r.top() ); p.drawPixmap( drawRect.topLeft(), sidePixmap, pixRect ); } PanelServiceMenu::paintEvent( e ); } QMouseEvent PanelKMenu::translateMouseEvent( QMouseEvent* e ) { QRect side = sideImageRect(); if ( !side.contains( e->pos() ) ) return *e; QPoint newpos( e->pos() ); QApplication::isRightToLeft() ? newpos.setX( newpos.x() - side.width() ) : newpos.setX( newpos.x() + side.width() ); QPoint newglobal( e->globalPos() ); QApplication::isRightToLeft() ? newglobal.setX( newpos.x() - side.width() ) : newglobal.setX( newpos.x() + side.width() ); return QMouseEvent( e->type(), newpos, newglobal, e->button(), e->state() ); } void PanelKMenu::mousePressEvent(QMouseEvent * e) { QMouseEvent newEvent = translateMouseEvent(e); PanelServiceMenu::mousePressEvent( &newEvent ); } void PanelKMenu::mouseReleaseEvent(QMouseEvent *e) { QMouseEvent newEvent = translateMouseEvent(e); PanelServiceMenu::mouseReleaseEvent( &newEvent ); } void PanelKMenu::mouseMoveEvent(QMouseEvent *e) { QMouseEvent newEvent = translateMouseEvent(e); PanelServiceMenu::mouseMoveEvent( &newEvent ); } void PanelKMenu::configChanged() { RecentlyLaunchedApps::self().m_bNeedToUpdate = false; RecentlyLaunchedApps::self().configChanged(); PanelServiceMenu::configChanged(); } // create and fill "recent" section at first void PanelKMenu::createRecentMenuItems() { RecentlyLaunchedApps::self().init(); RecentlyLaunchedApps::self().m_nNumMenuItems = 0; QStringList RecentApps; RecentlyLaunchedApps::self().getRecentApps(RecentApps); if (RecentApps.count() > 0) { bool bSeparator = KickerSettings::showMenuTitles(); int nId = serviceMenuEndId() + 1; int nIndex = KickerSettings::showMenuTitles() ? 1 : 0; for (QList::iterator it = RecentApps.fromLast(); /*nop*/; --it) { KService::Ptr s = KService::serviceByDesktopPath(*it); if (!s) { RecentlyLaunchedApps::self().removeItem(*it); } else { if (bSeparator) { bSeparator = false; /* FIXME: no more titles! int id = insertTitle( RecentlyLaunchedApps::self().caption(), serviceMenuEndId(), 0); setItemEnabled( id, false ); */ addSeparator(); } insertMenuItem(s, nId++, nIndex); RecentlyLaunchedApps::self().m_nNumMenuItems++; } if (it == RecentApps.begin()) { break; } } if (!KickerSettings::showMenuTitles()) { insertSeparator(RecentlyLaunchedApps::self().m_nNumMenuItems); } } } void PanelKMenu::clearSubmenus() { // we don't need to delete these on the way out since the libloader // handles them for us if (QApplication::closingDown()) { return; } for (PopupMenuList::const_iterator it = dynamicSubMenus.constBegin(); it != dynamicSubMenus.constEnd(); ++it) { delete *it; } dynamicSubMenus.clear(); PanelServiceMenu::clearSubmenus(); } void PanelKMenu::updateRecent() { if (!RecentlyLaunchedApps::self().m_bNeedToUpdate) { return; } RecentlyLaunchedApps::self().m_bNeedToUpdate = false; int nId = serviceMenuEndId() + 1; // remove previous items if (RecentlyLaunchedApps::self().m_nNumMenuItems > 0) { // -1 --> menu title int i = KickerSettings::showMenuTitles() ? -1 : 0; for (; i < RecentlyLaunchedApps::self().m_nNumMenuItems; i++) { removeItem(nId + i); entryMap_.remove(nId + i); } RecentlyLaunchedApps::self().m_nNumMenuItems = 0; if (!KickerSettings::showMenuTitles()) { removeItemAt(0); } } // insert new items QStringList RecentApps; RecentlyLaunchedApps::self().getRecentApps(RecentApps); if (RecentApps.count() > 0) { bool bNeedSeparator = KickerSettings::showMenuTitles(); for (QList::iterator it = RecentApps.fromLast(); /*nop*/; --it) { KService::Ptr s = KService::serviceByDesktopPath(*it); if (!s) { RecentlyLaunchedApps::self().removeItem(*it); } else { if (bNeedSeparator) { bNeedSeparator = false; addSeparator(); /* FIXME: no more titles! int id = insertTitle( RecentlyLaunchedApps::self().caption(), nId - 1, 0); setItemEnabled( id, false ); */ } insertMenuItem(s, nId++, KickerSettings::showMenuTitles() ? 1 : 0); RecentlyLaunchedApps::self().m_nNumMenuItems++; } if (it == RecentApps.begin()) break; } if (!KickerSettings::showMenuTitles()) { insertSeparator(RecentlyLaunchedApps::self().m_nNumMenuItems); } } } void PanelKMenu::clearRecentMenuItems() { RecentlyLaunchedApps::self().clearRecentApps(); RecentlyLaunchedApps::self().save(); RecentlyLaunchedApps::self().m_bNeedToUpdate = true; updateRecent(); } diff --git a/krunner/CMakeLists.txt b/krunner/CMakeLists.txt index a1dbdee525..902190fad7 100644 --- a/krunner/CMakeLists.txt +++ b/krunner/CMakeLists.txt @@ -1,49 +1,49 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR} ) project(krunner) configure_file(config-xautolock.h.cmake config-xautolock.h) set(krunner_KCFG_SRCS kscreensaversettings.kcfgc klaunchsettings.kcfgc) set(krunner_dbusXML org.kde.krunner.Interface.xml) -set(screensaver_dbusXML org.kde.ScreenSaver.xml) +set(screensaver_dbusXML org.freedesktop.ScreenSaver.xml) set(krunner_BGIMAGES images/background/dialog.svg) include_directories(${CMAKE_SOURCE_DIR}/workspace/plasma/lib ${CMAKE_SOURCE_DIR}/workspace/lib) set(krunner_SRCS collapsiblewidget.cpp interface.cpp krunnerapp.cpp restartingapplication.cpp main.cpp runners/services/servicerunner.cpp runners/sessions/sessionrunner.cpp runners/shell/shellrunner.cpp saverengine.cpp startupid.cpp xautolock.cpp xautolock_diy.c xautolock_engine.c) kde4_add_kcfg_files(krunner_SRCS ${krunner_KCFG_SRCS}) qt4_add_dbus_adaptor(krunner_SRCS ${krunner_dbusXML} interface.h Interface) qt4_add_dbus_adaptor(krunner_SRCS ${screensaver_dbusXML} saverengine.h SaverEngine) kde4_automoc(${krunner_SRCS}) kde4_add_executable(krunner ${krunner_SRCS}) target_link_libraries(krunner plasma kworkspace ${KDE4_KDEUI_LIBS}) if(X11_Xss_LIB) target_link_libraries(krunner ${X11_Xss_LIB}) endif(X11_Xss_LIB) add_subdirectory( lock ) add_subdirectory( runners ) install(TARGETS krunner DESTINATION ${BIN_INSTALL_DIR}) install(FILES krunner.desktop DESTINATION ${AUTOSTART_INSTALL_DIR}) install(FILES kscreensaversettings.kcfg DESTINATION ${KCFG_INSTALL_DIR}) install(FILES klaunch.kcfg DESTINATION ${KCFG_INSTALL_DIR}) install(FILES ${krunner_BGIMAGES} DESTINATION ${DATA_INSTALL_DIR}/desktoptheme/default/background) install(FILES ${krunner_dbusXML} ${screensaver_dbusXML} DESTINATION ${DBUS_INTERFACES_DIR} ) diff --git a/krunner/README b/krunner/README index fb09916206..c8b9740a72 100644 --- a/krunner/README +++ b/krunner/README @@ -1,34 +1,34 @@ KRunner provides a set of desktop services including: - a launch or "Run Command" dialog - screensaver activation and screen locking - application startup notification control Launch Dialog ============= The launch dialog accepts user input and passes that input through a series of "runners". Each runner is a subclass of the Runner class and provides three essential facilities: 1) whether or not it has matches for the given text input 2) providing a widget containing options associated with the runner, if any 3) activating a match Runners may also be provided via plugins. See runners/search/ for an example. Screensaver and screen locking ============================== This functionality is provided by the D-Bus service described in -org.kde.ScreenSaver.xml and is made available on the session bus under the -service name org.kde.screensaver, path /ScreenSaver +org.freedesktop.ScreenSaver.xml and is made available on the session bus under the +service name org.freedesktop.ScreenSaver, path /ScreenSaver The locking is managed by a small app found in lock/ Other Tidbits ============= A restarting application so even a crash won't result in no krunner A window for accepting search input, implemented in the Interface class TODO ==== Please read http://techbase.kde.org/Projects/Plasma/Tasks for further information. diff --git a/krunner/lock/CMakeLists.txt b/krunner/lock/CMakeLists.txt index b2b9261d55..545808e7bc 100644 --- a/krunner/lock/CMakeLists.txt +++ b/krunner/lock/CMakeLists.txt @@ -1,51 +1,51 @@ include_directories( ${CMAKE_SOURCE_DIR}/workspace/krunner ${CMAKE_SOURCE_DIR}/workspace/kcheckpass ${CMAKE_SOURCE_DIR}/workspace/kdmlib ) ########### next target ############### configure_file(config-krunner-lock.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-krunner-lock.h) set(krunner_lock_SRCS lockprocess.cc lockdlg.cc autologout.cc main.cc ) set(ksmserver_xml ${CMAKE_SOURCE_DIR}/workspace/ksmserver/org.kde.KSMServerInterface.xml) QT4_ADD_DBUS_INTERFACE(krunner_lock_SRCS ${ksmserver_xml} ksmserver_interface) -set(krunner_xml ${CMAKE_SOURCE_DIR}/workspace/krunner/org.kde.ScreenSaver.xml) +set(krunner_xml ${CMAKE_SOURCE_DIR}/workspace/krunner/org.freedesktop.ScreenSaver.xml) QT4_ADD_DBUS_INTERFACE(krunner_lock_SRCS ${krunner_xml} krunner_interface) set(kxkb_adaptor ${CMAKE_SOURCE_DIR}/workspace/kcontrol/kxkb/kxkb_adaptor.h) set(kxkb_xml ${CMAKE_CURRENT_BINARY_DIR}/org.kde.KXKB.xml) ADD_CUSTOM_COMMAND(OUTPUT ${kxkb_xml} COMMAND ${QT_DBUSCPP2XML_EXECUTABLE} ${kxkb_adaptor} > ${kxkb_xml} DEPENDS ${kxkb_adaptor}) QT4_ADD_DBUS_INTERFACE( krunner_lock_SRCS ${kxkb_xml} kxkb_interface ) kde4_add_kcfg_files(krunner_lock_SRCS ${CMAKE_SOURCE_DIR}/workspace/krunner/kscreensaversettings.kcfgc) kde4_automoc(${krunner_lock_SRCS}) kde4_add_executable(krunner_lock ${krunner_lock_SRCS} ) target_link_libraries(krunner_lock ${KDE4_KIO_LIBS} kworkspace ) if (HAVE_XF86MISC) target_link_libraries(krunner_lock Xxf86misc) endif (HAVE_XF86MISC) if(HAVE_GLXCHOOSEVISUAL) target_link_libraries(krunner_lock GL) endif(HAVE_GLXCHOOSEVISUAL) install(TARGETS krunner_lock DESTINATION ${BIN_INSTALL_DIR}) install_pam_service(kscreensaver) ########### install files ############### diff --git a/krunner/lock/main.cc b/krunner/lock/main.cc index b6e760215f..50eafe624a 100644 --- a/krunner/lock/main.cc +++ b/krunner/lock/main.cc @@ -1,175 +1,175 @@ /* This file is part of the KDE project Copyright (C) 1999 David Faure Copyright (c) 2003 Oswald Buddenhagen This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "lockprocess.h" #include "main.h" #include "kscreensaversettings.h" #include #include #include #include #include #include #include "krunner_interface.h" #include #include #include #include #include bool MyApp::x11EventFilter( XEvent *ev ) { if (ev->type == XKeyPress || ev->type == ButtonPress) emit activity(); else if (ev->type == MotionNotify) { time_t tick = time( 0 ); if (tick != lastTick) { lastTick = tick; emit activity(); } } return KApplication::x11EventFilter( ev ); } static KCmdLineOptions options[] = { { "forcelock", I18N_NOOP("Force session locking"), 0 }, { "dontlock", I18N_NOOP("Only start screensaver"), 0 }, { "blank", I18N_NOOP("Only use the blank screensaver"), 0 }, KCmdLineLastOption }; // ----------------------------------------------------------------------------- int main( int argc, char **argv ) { KLocale::setMainCatalog("krunner"); KCmdLineArgs::init( argc, argv, "krunner_lock", I18N_NOOP("KRunner Locker"), I18N_NOOP("Session Locker for KRunner"), "2.0" ); KCmdLineArgs::addCmdLineOptions( options ); KCmdLineArgs *args = KCmdLineArgs::parsedArgs(); putenv(strdup("SESSION_MANAGER=")); //KApplication::disableAutoDcopRegistration(); int kdesktop_screen_number = 0; int starting_screen = 0; bool child = false; int parent_connection = 0; // socket to the parent saver QList child_sockets; if (KGlobalSettings::isMultiHead()) { Display *dpy = XOpenDisplay(NULL); if (! dpy) { fprintf(stderr, "%s: FATAL ERROR: couldn't open display '%s'\n", argv[0], XDisplayName(NULL)); exit(1); } int number_of_screens = ScreenCount(dpy); starting_screen = kdesktop_screen_number = DefaultScreen(dpy); int pos; QByteArray display_name = XDisplayString(dpy); XCloseDisplay(dpy); kDebug() << "screen " << number_of_screens << " " << kdesktop_screen_number << " " << display_name << " " << starting_screen << endl; dpy = 0; if ((pos = display_name.lastIndexOf('.')) != -1) display_name.remove(pos, 10); QString env; if (number_of_screens != 1) { for (int i = 0; i < number_of_screens; i++) { if (i != starting_screen) { int fd[2]; if (pipe(fd)) { perror("pipe"); break; } if (fork() == 0) { child = true; kdesktop_screen_number = i; parent_connection = fd[0]; // break here because we are the child process, we don't // want to fork() anymore break; } else { child_sockets.append(fd[1]); } } } env.sprintf("DISPLAY=%s.%d", display_name.data(), kdesktop_screen_number); kDebug() << "env " << env << endl; if (putenv(strdup(env.toLatin1().data()))) { fprintf(stderr, "%s: WARNING: unable to set DISPLAY environment variable\n", argv[0]); perror("putenv()"); } } } MyApp app; kDebug() << "app " << kdesktop_screen_number << " " << starting_screen << " " << child << " " << child_sockets.count() << " " << parent_connection << endl; app.disableSessionManagement(); KGlobal::locale()->insertCatalog("libdmctl"); LockProcess process(child, args->isSet( "blank" )); if (!child) process.setChildren(child_sockets); else process.setParent(parent_connection); bool rt; bool sig = false; if( !child && args->isSet( "forcelock" )) { rt = process.lock(); sig = true; } else if( child || args->isSet( "dontlock" )) rt = process.dontLock(); else rt = process.defaultSave(); if (!rt) return 1; if( sig ) { - org::kde::ScreenSaver runner("org.kde.screensaver", "/ScreenSaver", QDBusConnection::sessionBus()); + org::freedesktop::ScreenSaver runner("org.freedesktop.ScreenSaver", "/ScreenSaver", QDBusConnection::sessionBus()); runner.saverLockReady(); } return app.exec(); } #include "main.moc" diff --git a/krunner/org.kde.ScreenSaver.xml b/krunner/org.freedesktop.ScreenSaver.xml similarity index 56% rename from krunner/org.kde.ScreenSaver.xml rename to krunner/org.freedesktop.ScreenSaver.xml index 18a69de8a7..cdc06055e2 100644 --- a/krunner/org.kde.ScreenSaver.xml +++ b/krunner/org.freedesktop.ScreenSaver.xml @@ -1,62 +1,45 @@ - - + + + - - - - - - - + - - - - + - + - + - + - - - - + - - - - - - - + - + - + - + diff --git a/krunner/runners/sessions/sessionrunner.cpp b/krunner/runners/sessions/sessionrunner.cpp index e96e8d73ff..f97127c81e 100644 --- a/krunner/runners/sessions/sessionrunner.cpp +++ b/krunner/runners/sessions/sessionrunner.cpp @@ -1,123 +1,123 @@ /* * Copyright (C) 2006 Aaron Seigo * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Library General Public License version 2 as * published by the Free Software Foundation * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details * * You should have received a copy of the GNU Library General Public * License along with this program; if not, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include "krunnerapp.h" #include "saverengine.h" #include "sessionrunner.h" SessionRunner::SessionRunner( QObject* parent ) : Plasma::Runner( parent ) { setObjectName( i18n( "Sessions" ) ); } SessionRunner::~SessionRunner() { } QAction* SessionRunner::accepts(const QString& term) { Q_UNUSED(term); return 0; } bool SessionRunner::exec(const QString& command) { Q_UNUSED(command); return true; } void SessionRunner::fillMatches(KActionCollection* actions, const QString& term, int max, int offset) { Q_UNUSED(max); Q_UNUSED(offset); //TODO: ugh, magic strings. if ( term != "SESSIONS") { return; } DM dm; if ( KAuthorized::authorizeKAction("start_new_session") && dm.isSwitchable() && dm.numReserve() >= 0 ) { QAction *action = actions->addAction( "newsession" ); action->setIcon( KIcon("fork") ); action->setText( i18n( "New Session" ) ); connect( action, SIGNAL(triggered(bool)), SLOT(newSession()) ); } // now add the active sessions SessList sessions; if ( !dm.localSessions( sessions ) ) { return; } foreach (const SessEnt& session, sessions) { if ( !session.vt || session.self ) { continue; } QAction* action = actions->addAction( DM::sess2Str( session ) ); action->setIcon( KIcon( "user" ) ); action->setText( DM::sess2Str( session ) ); } } void SessionRunner::newSession() { //TODO: this message is too verbose and too technical. int result = KMessageBox::warningContinueCancel( 0, i18n("

You have chosen to open another desktop session.
" "The current session will be hidden " "and a new login screen will be displayed.
" "An F-key is assigned to each session; " "F%1 is usually assigned to the first session, " "F%2 to the second session and so on. " "You can switch between sessions by pressing " "Ctrl, Alt and the appropriate F-key at the same time. " "Additionally, the KDE Panel and Desktop menus have " "actions for switching between sessions.

", 7, 8), i18n("Warning - New Session"), KGuiItem(i18n("&Start New Session"), "fork"), ":confirmNewSession", KMessageBox::PlainCaption | KMessageBox::Notify); if ( result == KMessageBox::Cancel ) { return; } - static_cast(qApp)->screensaver().lock(); + static_cast(qApp)->screensaver().Lock(); DM().startReserve(); } #include "sessionrunner.moc" diff --git a/krunner/saverengine.cpp b/krunner/saverengine.cpp index 85b17fb3d0..3efc1fcf50 100644 --- a/krunner/saverengine.cpp +++ b/krunner/saverengine.cpp @@ -1,512 +1,505 @@ //=========================================================================== // // This file is part of the KDE project // // Copyright (c) 1999 Martin R. Jones // #include #include "saverengine.h" #include "kscreensaversettings.h" #include "screensaveradaptor.h" #include #include #include #include #include #include #include #include #include #include #include #include "xautolock_c.h" extern xautolock_corner_t xautolock_corners[ 4 ]; //=========================================================================== // // Screen saver engine. Doesn't handle the actual screensaver window, // starting screensaver hacks, or password entry. That's done by // a newly started process. // SaverEngine::SaverEngine() : QWidget(), - mBlankOnly(false), screensaverService( QDBusConnection::connectToBus( QDBusConnection::SessionBus, - "org.kde.screensaver" ) ) + "org.freedesktop.ScreenSaver" ) ) { (void) new ScreenSaverAdaptor( this ); - screensaverService.registerService( "org.kde.screensaver" ) ; + screensaverService.registerService( "org.freedesktop.ScreenSaver" ) ; screensaverService.registerObject( "/ScreenSaver", this ); // Save X screensaver parameters XGetScreenSaver(QX11Info::display(), &mXTimeout, &mXInterval, &mXBlanking, &mXExposures); mState = Waiting; mXAutoLock = 0; mEnabled = false; m_nr_throttled = 0; m_nr_inhibited = 0; m_actived_time = -1; connect(&mLockProcess, SIGNAL(processExited(KProcess *)), SLOT(lockProcessExited())); QObject::connect(QDBusConnection::sessionBus().interface(), SIGNAL(serviceOwnerChanged(QString,QString,QString)), SLOT(serviceOwnerChanged(QString,QString,QString))); // I make it a really random number to avoid // some assumptions in clients, but just increase // while gnome-ss creates a random number every time m_next_cookie = KRandom::random() % 20000; configure(); } //--------------------------------------------------------------------------- // // Destructor - usual cleanups. // SaverEngine::~SaverEngine() { mLockProcess.detach(); // don't kill it if we crash delete mXAutoLock; // Restore X screensaver parameters XSetScreenSaver(QX11Info::display(), mXTimeout, mXInterval, mXBlanking, mXExposures); } //--------------------------------------------------------------------------- // This should be called only using DBus. -void SaverEngine::lock() +void SaverEngine::Lock() { bool ok = true; if (mState == Waiting) { ok = startLockProcess( ForceLock ); // It takes a while for krunner_lock to start and lock the screen. // Therefore delay the DBus call until it tells krunner that the locking is in effect. // This is done only for --forcelock . if( ok && mState != Saving ) { #ifdef __GNUC__ #warning port dcop transactions to dbus #endif #if 0 DCOPClientTransaction* trans = kapp->dcopClient()->beginTransaction(); mLockTransactions.append( trans ); #endif } } else { mLockProcess.kill( SIGHUP ); } } void SaverEngine::processLockTransactions() { #ifdef __GNUC__ #warning port dcop transactions to dbus #endif #if 0 for( QVector< DCOPClientTransaction* >::ConstIterator it = mLockTransactions.begin(); it != mLockTransactions.end(); ++it ) { DCOPCString replyType = "void"; QByteArray arr; kapp->dcopClient()->endTransaction( *it, replyType, arr ); } mLockTransactions.clear(); #endif } void SaverEngine::saverLockReady() { if( mState != Preparing ) { kDebug() << "Got unexpected saverReady()" << endl; } kDebug() << "Saver Lock Ready" << endl; processLockTransactions(); } -void SaverEngine::poke() +void SaverEngine::SimulateUserActivity() { if ( mState == Waiting ) { // disable XSetScreenSaver(QX11Info::display(), 0, mXInterval, mXBlanking, mXExposures); mXAutoLock->resetTrigger(); // reenable XSetScreenSaver(QX11Info::display(), mTimeout + 10, mXInterval, mXBlanking, mXExposures); } } //--------------------------------------------------------------------------- -void SaverEngine::save() +bool SaverEngine::save() { if (mState == Waiting) { - startLockProcess( DefaultLock ); + return startLockProcess( DefaultLock ); } + return false; } //--------------------------------------------------------------------------- -void SaverEngine::quit() +bool SaverEngine::quit() { if (mState == Saving || mState == Preparing) { stopLockProcess(); + return true; } + return false; } //--------------------------------------------------------------------------- bool SaverEngine::isEnabled() { return mEnabled; } //--------------------------------------------------------------------------- bool SaverEngine::enable( bool e ) { if ( e == mEnabled ) return true; // If we aren't in a suitable state, we will not reconfigure. if (mState != Waiting) return false; mEnabled = e; if (mEnabled) { if ( !mXAutoLock ) { mXAutoLock = new XAutoLock(); connect(mXAutoLock, SIGNAL(timeout()), SLOT(idleTimeout())); } mXAutoLock->setTimeout(mTimeout); mXAutoLock->setDPMS(mDPMS); //mXAutoLock->changeCornerLockStatus( mLockCornerTopLeft, mLockCornerTopRight, mLockCornerBottomLeft, mLockCornerBottomRight); // We'll handle blanking XSetScreenSaver(QX11Info::display(), mTimeout + 10, mXInterval, mXBlanking, mXExposures); mXAutoLock->start(); kDebug() << "Saver Engine started, timeout: " << mTimeout << endl; } else { if (mXAutoLock) { delete mXAutoLock; mXAutoLock = 0; } XSetScreenSaver(QX11Info::display(), 0, mXInterval, mXBlanking, mXExposures); kDebug() << "Saver Engine disabled" << endl; } return true; } //--------------------------------------------------------------------------- bool SaverEngine::isBlanked() { return (mState != Waiting); } //--------------------------------------------------------------------------- // // Read and apply configuration. // void SaverEngine::configure() { // If we aren't in a suitable state, we will not reconfigure. if (mState != Waiting) return; // create a new config obj to ensure we read the latest options KScreenSaverSettings::self()->readConfig(); bool e = KScreenSaverSettings::screenSaverEnabled(); kDebug() << "enabled " << e << endl; mTimeout = KScreenSaverSettings::timeout(); mDPMS = KScreenSaverSettings::dpmsDependent(); mEnabled = !e; // force the enable() int action; action = KScreenSaverSettings::actionTopLeft(); xautolock_corners[0] = applyManualSettings(action); action = KScreenSaverSettings::actionTopRight(); xautolock_corners[1] = applyManualSettings(action); action = KScreenSaverSettings::actionBottomLeft(); xautolock_corners[2] = applyManualSettings(action); action = KScreenSaverSettings::actionBottomRight(); xautolock_corners[3] = applyManualSettings(action); enable( e ); } -//--------------------------------------------------------------------------- -// -// Set a variable to indicate only using the blanker and not the saver. -// -void SaverEngine::setBlankOnly( bool blankOnly ) -{ - mBlankOnly = blankOnly; - // FIXME: if running, stop and restart? What about security - // implications of this? -} - //--------------------------------------------------------------------------- // // Start the screen saver. // bool SaverEngine::startLockProcess( LockType lock_type ) { if (mState != Waiting) return true; kDebug() << "SaverEngine: starting saver" << endl; - emit screenSaverStarted(); // DBus signal + emit ActiveChanged(true); // DBus signal if (mLockProcess.isRunning()) { stopLockProcess(); } mLockProcess.clearArguments(); QString path = KStandardDirs::findExe( "krunner_lock" ); if( path.isEmpty()) { kDebug() << "Can't find krunner_lock!" << endl; return false; } mLockProcess << path; switch( lock_type ) { case ForceLock: mLockProcess << QString( "--forcelock" ); break; case DontLock: mLockProcess << QString( "--dontlock" ); break; default: break; } - if (mBlankOnly) - mLockProcess << QString( "--blank" ); + if (m_nr_throttled) + mLockProcess << QString( "--blank" ); m_actived_time = time( 0 ); if (mLockProcess.start() == false ) { kDebug() << "Failed to start krunner_lock!" << endl; m_actived_time = -1; return false; } mState = Preparing; if (mXAutoLock) { mXAutoLock->stop(); } return true; } //--------------------------------------------------------------------------- // // Stop the screen saver. // void SaverEngine::stopLockProcess() { m_actived_time = -1; if (mState == Waiting) { kWarning() << "SaverEngine::stopSaver() saver not active" << endl; return; } kDebug() << "SaverEngine: stopping lock" << endl; - emit screenSaverStopped(); // DBus signal + emit ActiveChanged(false); // DBus signal mLockProcess.kill(); if (mXAutoLock) { mXAutoLock->start(); } processLockTransactions(); mState = Waiting; XSetScreenSaver(QX11Info::display(), mTimeout + 10, mXInterval, mXBlanking, mXExposures); } void SaverEngine::lockProcessExited() { m_actived_time = -1; kDebug() << "SaverEngine: lock exited" << endl; if( mState == Waiting ) return; - emit screenSaverStopped(); // DBus signal + emit ActiveChanged(false); // DBus signal if (mXAutoLock) { mXAutoLock->start(); } processLockTransactions(); mState = Waiting; XSetScreenSaver(QX11Info::display(), mTimeout + 10, mXInterval, mXBlanking, mXExposures); } //--------------------------------------------------------------------------- // // XAutoLock has detected the required idle time. // void SaverEngine::idleTimeout() { // disable X screensaver XSetScreenSaver(QX11Info::display(), 0, mXInterval, mXBlanking, mXExposures); startLockProcess( DefaultLock ); } xautolock_corner_t SaverEngine::applyManualSettings(int action) { if (action == 0) { kDebug() << "no lock" << endl; return ca_nothing; } else if (action == 1) { kDebug() << "lock screen" << endl; return ca_forceLock; } else if (action == 2) { kDebug() << "prevent lock" << endl; return ca_dontLock; } else { kDebug() << "no lock nothing" << endl; return ca_nothing; } } -uint SaverEngine::getSessionIdleTime() +uint SaverEngine::GetSessionIdleTime() { return mXAutoLock->idleTime(); } -bool SaverEngine::getSessionIdle() +bool SaverEngine::GetSessionIdle() { // pointless? - return ( getSessionIdleTime() > 0 ); + return ( GetSessionIdleTime() > 0 ); } -uint SaverEngine::getActiveTime() +uint SaverEngine::GetActiveTime() { if ( m_actived_time == -1 ) return 0; return time( 0 ) - m_actived_time; } -bool SaverEngine::getActive() +bool SaverEngine::GetActive() { return ( mState != Waiting ); } -void SaverEngine::setActive(bool state) +bool SaverEngine::SetActive(bool state) { if ( state ) - save(); + return save(); else - quit(); + return quit(); } -uint SaverEngine::inhibit(const QString &application_name, const QString &reason_for_inhibit) +uint SaverEngine::Inhibit(const QString &application_name, const QString &reason_for_inhibit) { ScreenSaverRequest sr; sr.appname = application_name; sr.reasongiven = reason_for_inhibit; sr.cookie = m_next_cookie++; sr.dbusid = "unknown"; // see below for throttle sr.type = ScreenSaverRequest::Inhibit; m_requests.append( sr ); m_nr_inhibited++; enable( false ); return sr.cookie; } -void SaverEngine::unInhibit(uint cookie) +void SaverEngine::UnInhibit(uint cookie) { QMutableListIterator it( m_requests ); while ( it.hasNext() ) { if ( it.next().cookie == cookie ) { it.remove(); m_nr_inhibited--; if ( m_nr_inhibited <= 0 ) enable( true ); } } } -uint SaverEngine::throttle(const QString &application_name, const QString &reason_for_inhibit) +uint SaverEngine::Throttle(const QString &application_name, const QString &reason_for_inhibit) { ScreenSaverRequest sr; sr.appname = application_name; sr.reasongiven = reason_for_inhibit; sr.cookie = m_next_cookie++; sr.type = ScreenSaverRequest::Throttle; #warning thiago says Qt 4.3 can query the dbus connection id in adaptors - waiting sr.dbusid = "unknown"; // see above for inhibit m_requests.append( sr ); m_nr_throttled++; mLockProcess.suspend(); return sr.cookie; } -void SaverEngine::unThrottle(uint cookie) +void SaverEngine::UnThrottle(uint cookie) { QMutableListIterator it( m_requests ); while ( it.hasNext() ) { if ( it.next().cookie == cookie ) { it.remove(); m_nr_throttled--; if ( m_nr_throttled <= 0 ) mLockProcess.resume(); } } } void SaverEngine::serviceOwnerChanged(const QString& name,const QString &oldOwner,const QString &newOwner) { + Q_UNUSED( oldOwner ); + if ( !newOwner.isEmpty() ) // looking for deaths return; QListIterator it( m_requests ); while ( it.hasNext() ) { ScreenSaverRequest r = it.next(); if ( r.dbusid == name ) { if ( r.type == ScreenSaverRequest::Throttle ) - unThrottle( r.cookie ); + UnThrottle( r.cookie ); else - unInhibit( r.cookie ); + UnInhibit( r.cookie ); } } } #include "saverengine.moc" diff --git a/krunner/saverengine.h b/krunner/saverengine.h index 8f8ec0a92d..f42ccfe161 100644 --- a/krunner/saverengine.h +++ b/krunner/saverengine.h @@ -1,191 +1,182 @@ //=========================================================================== // // This file is part of the KDE project // // Copyright (c) 1999 Martin R. Jones // #ifndef __SAVERENGINE_H__ #define __SAVERENGINE_H__ #include #include #include #include #include "xautolock.h" #include "xautolock_c.h" class ScreenSaverRequest { public: QString appname; QString reasongiven; QString dbusid; uint cookie; enum { Inhibit,Throttle } type; }; //=========================================================================== /** * Screen saver engine. Handles screensaver window, starting screensaver * hacks, and password entry. */ class SaverEngine : public QWidget { Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.kde.ScreenSaver") + Q_CLASSINFO("D-Bus Interface", "org.freedesktop.ScreenSaver") public: SaverEngine(); ~SaverEngine(); public Q_SLOTS: /** * Lock the screen now even if the screensaver does not lock by default. */ - void lock(); + void Lock(); /** * Save the screen now. If the user has locking enabled, the screen is locked also. */ - void save(); + bool save(); /** * Quit the screensaver if it is running */ - void quit(); + bool quit(); /** * Simulate user activity */ - void poke(); + void SimulateUserActivity(); /** * Return true if the screensaver is enabled */ bool isEnabled(); /** * Enable/disable the screensaver * @return true if the action succeeded */ bool enable( bool e ); /** * Return true if the screen is currently blanked */ bool isBlanked(); /** * Read and apply configuration. */ void configure(); - /** - * Enable or disable "blank only" mode. This is useful for - * laptops where one might not want a cpu thirsty screensaver - * draining the battery. - */ - void setBlankOnly( bool blankOnly ); - /** * Called by krunner_lock when locking is in effect. */ void saverLockReady(); /** * Request a change in the state of the screensaver. * Set to TRUE to request that the screensaver activate. * Active means that the screensaver has blanked the * screen and may run a graphical theme. This does * not necessary mean that the screen is locked. */ - void setActive( bool state ); + bool SetActive( bool state ); /// Returns the value of the current state of activity (See setActive) - bool getActive(); + bool GetActive(); /** * Returns the number of seconds that the screensaver has * been active. Returns zero if the screensaver is not active. */ - uint getActiveTime(); + uint GetActiveTime(); /// Returns the value of the current state of session idleness. - bool getSessionIdle(); + bool GetSessionIdle(); /** * Returns the number of seconds that the session has * been idle. Returns zero if the session is not idle. */ - uint getSessionIdleTime(); + uint GetSessionIdleTime(); /** * Request that saving the screen due to system idleness * be blocked until UnInhibit is called or the * calling process exits. * The cookie is a random number used to identify the request */ - uint inhibit(const QString &application_name, const QString &reason_for_inhibit); + uint Inhibit(const QString &application_name, const QString &reason_for_inhibit); /// Cancel a previous call to Inhibit() identified by the cookie. - void unInhibit(uint cookie); + void UnInhibit(uint cookie); /** * Request that running themes while the screensaver is active * be blocked until UnThrottle is called or the * calling process exits. * The cookie is a random number used to identify the request */ - uint throttle(const QString &application_name, const QString &reason_for_inhibit); + uint Throttle(const QString &application_name, const QString &reason_for_inhibit); /// Cancel a previous call to Throttle() identified by the cookie. - void unThrottle(uint cookie); + void UnThrottle(uint cookie); Q_SIGNALS: // DBus signals - void screenSaverStarted(); - void screenSaverStopped(); + void ActiveChanged(bool state); protected Q_SLOTS: void idleTimeout(); void lockProcessExited(); void serviceOwnerChanged(const QString&,const QString&,const QString&); protected: enum LockType { DontLock, DefaultLock, ForceLock }; bool startLockProcess( LockType lock_type ); void stopLockProcess(); bool handleKeyPress(XKeyEvent *xke); void processLockTransactions(); xautolock_corner_t applyManualSettings(int); private: enum State { Waiting, Preparing, Saving }; bool mEnabled; bool mDPMS; State mState; XAutoLock *mXAutoLock; KProcess mLockProcess; int mTimeout; // the original X screensaver parameters int mXTimeout; int mXInterval; int mXBlanking; int mXExposures; time_t m_actived_time; - bool mBlankOnly; // only use the blanker, not the defined saver QDBusConnection screensaverService; QList m_requests; uint m_next_cookie; int m_nr_throttled; int m_nr_inhibited; // QVector< DCOPClientTransaction* > mLockTransactions; }; #endif diff --git a/lib/dmctl.cpp b/lib/dmctl.cpp index 1d0df4f051..dcd4cbaae8 100644 --- a/lib/dmctl.cpp +++ b/lib/dmctl.cpp @@ -1,440 +1,440 @@ /* Copyright (C) 2004 Oswald Buddenhagen This program is free software; you can redistribute it and/or modify it under the terms of the Lesser GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the Lesser GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "dmctl.h" #ifdef Q_WS_X11 #include #include #include #include #include #include #include #include #include #include #include #include #include #include static enum { Dunno, NoDM, NewKDM, OldKDM, GDM } DMType = Dunno; static const char *ctl, *dpy; DM::DM() : fd( -1 ) { const char *ptr; struct sockaddr_un sa; if (DMType == Dunno) { if (!(dpy = ::getenv( "DISPLAY" ))) DMType = NoDM; else if ((ctl = ::getenv( "DM_CONTROL" ))) DMType = NewKDM; else if ((ctl = ::getenv( "XDM_MANAGED" )) && ctl[0] == '/') DMType = OldKDM; else if (::getenv( "GDMSESSION" )) DMType = GDM; else DMType = NoDM; } switch (DMType) { default: return; case NewKDM: case GDM: if ((fd = ::socket( PF_UNIX, SOCK_STREAM, 0 )) < 0) return; sa.sun_family = AF_UNIX; if (DMType == GDM) strcpy( sa.sun_path, "/tmp/.gdm_socket" ); else { if ((ptr = strchr( dpy, ':' ))) ptr = strchr( ptr, '.' ); snprintf( sa.sun_path, sizeof(sa.sun_path), "%s/dmctl-%.*s/socket", ctl, ptr ? int(ptr - dpy) : 512, dpy ); } if (::connect( fd, (struct sockaddr *)&sa, sizeof(sa) )) { ::close( fd ); fd = -1; } if (DMType == GDM) GDMAuthenticate(); break; case OldKDM: { QString tf( ctl ); tf.truncate( tf.indexOf( ',' ) ); fd = ::open( tf.toLatin1(), O_WRONLY ); } break; } } DM::~DM() { if (fd >= 0) close( fd ); } bool DM::exec( const char *cmd ) { QByteArray buf; return exec( cmd, buf ); } /** * Execute a KDM/GDM remote control command. * @param cmd the command to execute. FIXME: undocumented yet. * @param buf the result buffer. * @return result: * @li If true, the command was successfully executed. * @p ret might contain addional results. * @li If false and @p ret is empty, a communication error occurred * (most probably KDM is not running). * @li If false and @p ret is non-empty, it contains the error message * from KDM. */ bool DM::exec( const char *cmd, QByteArray &buf ) { bool ret = false; int tl; int len = 0; if (fd < 0) goto busted; tl = strlen( cmd ); if (::write( fd, cmd, tl ) != tl) { bust: ::close( fd ); fd = -1; busted: buf.resize( 0 ); return false; } if (DMType == OldKDM) { buf.resize( 0 ); return true; } for (;;) { if (buf.size() < 128) buf.resize( 128 ); else if (buf.size() < len * 2) buf.resize( len * 2 ); if ((tl = ::read( fd, buf.data() + len, buf.size() - len)) <= 0) { if (tl < 0 && errno == EINTR) continue; goto bust; } len += tl; if (buf[len - 1] == '\n') { buf[len - 1] = 0; if (len > 2 && (buf[0] == 'o' || buf[0] == 'O') && (buf[1] == 'k' || buf[1] == 'K') && buf[2] <= ' ') ret = true; break; } } return ret; } bool DM::canShutdown() { if (DMType == OldKDM) return strstr( ctl, ",maysd" ) != 0; QByteArray re; if (DMType == GDM) return exec( "QUERY_LOGOUT_ACTION\n", re ) && re.indexOf( "HALT" ) >= 0; return exec( "caps\n", re ) && re.indexOf( "\tshutdown" ) >= 0; } void DM::shutdown( KWorkSpace::ShutdownType shutdownType, KWorkSpace::ShutdownMode shutdownMode, /* NOT Default */ const QString &bootOption ) { if (shutdownType == KWorkSpace::ShutdownTypeNone) return; bool cap_ask; if (DMType == NewKDM) { QByteArray re; cap_ask = exec( "caps\n", re ) && re.indexOf( "\tshutdown ask" ) >= 0; } else { if (!bootOption.isEmpty()) return; cap_ask = false; } if (!cap_ask && shutdownMode == KWorkSpace::ShutdownModeInteractive) shutdownMode = KWorkSpace::ShutdownModeForceNow; QByteArray cmd; if (DMType == GDM) { cmd.append( shutdownMode == KWorkSpace::ShutdownModeForceNow ? "SET_LOGOUT_ACTION " : "SET_SAFE_LOGOUT_ACTION " ); cmd.append( shutdownType == KWorkSpace::ShutdownTypeReboot ? "REBOOT\n" : "HALT\n" ); } else { cmd.append( "shutdown\t" ); cmd.append( shutdownType == KWorkSpace::ShutdownTypeReboot ? "reboot\t" : "halt\t" ); if (!bootOption.isNull()) cmd.append( "=" ).append( bootOption.toLocal8Bit() ).append( "\t" ); cmd.append( shutdownMode == KWorkSpace::ShutdownModeInteractive ? "ask\n" : shutdownMode == KWorkSpace::ShutdownModeForceNow ? "forcenow\n" : shutdownMode == KWorkSpace::ShutdownModeTryNow ? "trynow\n" : "schedule\n" ); } exec( cmd.data() ); } bool DM::bootOptions( QStringList &opts, int &defopt, int ¤t ) { if (DMType != NewKDM) return false; QByteArray re; if (!exec( "listbootoptions\n", re )) return false; opts = QString::fromLocal8Bit( re.data() ).split( '\t', QString::SkipEmptyParts ); if (opts.size() < 4) return false; bool ok; defopt = opts[2].toInt( &ok ); if (!ok) return false; current = opts[3].toInt( &ok ); if (!ok) return false; opts = opts[1].split( ' ', QString::SkipEmptyParts ); for (QStringList::Iterator it = opts.begin(); it != opts.end(); ++it) (*it).replace( "\\s", " " ); return true; } void DM::setLock( bool on ) { if (DMType != GDM) exec( on ? "lock\n" : "unlock\n" ); } bool DM::isSwitchable() { if (DMType == OldKDM) return dpy[0] == ':'; if (DMType == GDM) return exec( "QUERY_VT\n" ); QByteArray re; return exec( "caps\n", re ) && re.indexOf( "\tlocal" ) >= 0; } int DM::numReserve() { if (DMType == GDM) return 1; /* Bleh */ if (DMType == OldKDM) return strstr( ctl, ",rsvd" ) ? 1 : -1; QByteArray re; int p; if (!(exec( "caps\n", re ) && (p = re.indexOf( "\treserve " )) >= 0)) return -1; return atoi( re.data() + p + 9 ); } void DM::startReserve() { if (DMType == GDM) exec("FLEXI_XSERVER\n"); else exec("reserve\n"); } bool DM::localSessions( SessList &list ) { if (DMType == OldKDM) return false; QByteArray re; if (DMType == GDM) { if (!exec( "CONSOLE_SERVERS\n", re )) return false; QStringList sess = QString(re.data() +3).split( QChar(';'), QString::SkipEmptyParts); for (QStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { QStringList ts = (*it).split( QChar(',') ); SessEnt se; se.display = ts[0]; se.user = ts[1]; se.vt = ts[2].toInt(); se.session = ""; se.self = ts[0] == ::getenv( "DISPLAY" ); /* Bleh */ se.tty = false; list.append( se ); } } else { if (!exec( "list\talllocal\n", re )) return false; QStringList sess = QString(re.data() + 3).split(QChar('\t'), QString::SkipEmptyParts ); for (QStringList::ConstIterator it = sess.begin(); it != sess.end(); ++it) { QStringList ts = (*it).split( QChar(',') ); SessEnt se; se.display = ts[0]; if (ts[1][0] == '@') se.from = ts[1].mid( 1 ), se.vt = 0; else se.vt = ts[1].mid( 2 ).toInt(); se.user = ts[2]; se.session = ts[3]; se.self = (ts[4].indexOf( '*' ) >= 0); se.tty = (ts[4].indexOf( 't' ) >= 0); list.append( se ); } } return true; } void DM::sess2Str2( const SessEnt &se, QString &user, QString &loc ) { if (se.tty) { user = i18nc("user: ...", "%1: TTY login", se.user ); loc = se.vt ? QString("vt%1").arg( se.vt ) : se.display ; } else { user = se.user.isEmpty() ? se.session.isEmpty() ? i18n("Unused") : se.session == "" ? i18n("X login on remote host") : i18nc("... host", "X login on %1", se.session ) : se.session == "" ? se.user : i18nc("user: session type", "%1: %2", se.user, se.session ); loc = se.vt ? QString("%1, vt%2").arg( se.display ).arg( se.vt ) : se.display; } } QString DM::sess2Str( const SessEnt &se ) { QString user, loc; sess2Str2( se, user, loc ); return i18nc("session (location)", "%1 (%2)", user, loc ); } bool DM::switchVT( int vt ) { if (DMType == GDM) return exec( QString("SET_VT %1\n").arg(vt).toLatin1() ); return exec( QString("activate\tvt%1\n").arg(vt).toLatin1() ); } void DM::lockSwitchVT( int vt ) { if (switchVT( vt )) { - QDBusInterface screensaver("org.kde.screensaver", "/ScreenSaver", "org.kde.ScreenSaver"); - screensaver.call( "lock" ); + QDBusInterface screensaver("org.freedesktop.ScreenSaver", "/ScreenSaver", "org.freedesktop.ScreenSaver"); + screensaver.call( "Lock" ); } } void DM::GDMAuthenticate() { FILE *fp; const char *dpy, *dnum, *dne; int dnl; Xauth *xau; dpy = DisplayString( QPaintDevice::x11AppDisplay() ); if (!dpy) { dpy = ::getenv( "DISPLAY" ); if (!dpy) return; } dnum = strchr( dpy, ':' ) + 1; dne = strchr( dpy, '.' ); dnl = dne ? dne - dnum : strlen( dnum ); /* XXX should do locking */ if (!(fp = fopen( XauFileName(), "r" ))) return; while ((xau = XauReadAuth( fp ))) { if (xau->family == FamilyLocal && xau->number_length == dnl && !memcmp( xau->number, dnum, dnl ) && xau->data_length == 16 && xau->name_length == 18 && !memcmp( xau->name, "MIT-MAGIC-COOKIE-1", 18 )) { QString cmd( "AUTH_LOCAL " ); for (int i = 0; i < 16; i++) cmd += QString::number( (uchar)xau->data[i], 16 ).rightJustified( 2, '0'); cmd += '\n'; if (exec( cmd.toLatin1() )) { XauDisposeAuth( xau ); break; } } XauDisposeAuth( xau ); } fclose (fp); } #endif // Q_WS_X11