mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-23 10:22:49 +00:00
kcontrol: do not change the window manager until the next session
for various reasons Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
aa239e5701
commit
e637b6dcdb
2 changed files with 18 additions and 173 deletions
|
@ -16,67 +16,14 @@
|
|||
#include "componentchooserwm.h"
|
||||
#include "moc_componentchooserwm.cpp"
|
||||
|
||||
#include <kdebug.h>
|
||||
#include <kdesktopfile.h>
|
||||
#include <kmessagebox.h>
|
||||
#include <kstandarddirs.h>
|
||||
#include <ktimerdialog.h>
|
||||
#include <kselectionowner.h>
|
||||
#include <kprocess.h>
|
||||
#include <kshell.h>
|
||||
#include <qthread.h>
|
||||
#include <kconfiggroup.h>
|
||||
#include <kdebug.h>
|
||||
#include <qfileinfo.h>
|
||||
#include <qdbusinterface.h>
|
||||
#include <qdbusconnectioninterface.h>
|
||||
#include <qprocess.h>
|
||||
#include <netwm.h>
|
||||
#include <qx11info_x11.h>
|
||||
|
||||
static const int s_eventstime = 500;
|
||||
static const int s_sleeptime = 500;
|
||||
|
||||
// TODO: kill and start WM on each screen?
|
||||
static int getWMScreen()
|
||||
{
|
||||
return QX11Info::appScreen();
|
||||
}
|
||||
|
||||
static QByteArray getWMAtom()
|
||||
{
|
||||
char snprintfbuff[30];
|
||||
::memset(snprintfbuff, '\0', sizeof(snprintfbuff));
|
||||
::sprintf(snprintfbuff, "WM_S%d", getWMScreen());
|
||||
return QByteArray(snprintfbuff);
|
||||
}
|
||||
|
||||
void killWM()
|
||||
{
|
||||
const QByteArray wmatom = getWMAtom();
|
||||
KSelectionOwner kselectionowner(wmatom.constData(), getWMScreen());
|
||||
kselectionowner.claim(true);
|
||||
kselectionowner.release();
|
||||
}
|
||||
|
||||
bool startWM(const QString &wmexec)
|
||||
{
|
||||
// HACK: openbox crashes shortly after it is started if started from this process so start it
|
||||
// via klauncher
|
||||
if (wmexec.contains(QLatin1String("openbox"))) {
|
||||
QDBusInterface klauncher(
|
||||
"org.kde.klauncher", "/KLauncher","org.kde.KLauncher",
|
||||
QDBusConnection::sessionBus()
|
||||
);
|
||||
QStringList wmcommand = KShell::splitArgs(wmexec);
|
||||
if (wmcommand.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
const QString wmprog = wmcommand.takeFirst();
|
||||
QDBusReply<void> reply = klauncher.call("exec_blind", wmprog, wmcommand);
|
||||
return reply.isValid();
|
||||
}
|
||||
KProcess kproc;
|
||||
kproc.setShellCommand(wmexec);
|
||||
return (kproc.startDetached() > 0);
|
||||
}
|
||||
|
||||
CfgWm::CfgWm(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
|
@ -131,121 +78,17 @@ bool CfgWm::saveAndConfirm()
|
|||
if (oldwm == currentWm()) {
|
||||
return true;
|
||||
}
|
||||
if (tryWmLaunch()) {
|
||||
oldwm = currentWm();
|
||||
cfg.sync();
|
||||
KMessageBox::information(
|
||||
window(),
|
||||
i18n("A new window manager is running.\n"
|
||||
"It is still recommended to restart this KDE session to make sure "
|
||||
"all running applications adjust for this change."),
|
||||
i18n("Window Manager Replaced"),
|
||||
i18n(
|
||||
"The change will take effect on the next KDE session."
|
||||
),
|
||||
i18n("Window Manager Changed"),
|
||||
"restartafterwmchange"
|
||||
);
|
||||
return true;
|
||||
} else {
|
||||
// revert config
|
||||
emit changed(true);
|
||||
c.writeEntry("windowManager", oldwm);
|
||||
if (oldwm == "kwin") {
|
||||
kwinRB->setChecked(true);
|
||||
wmCombo->setEnabled(false);
|
||||
} else {
|
||||
differentRB->setChecked(true);
|
||||
wmCombo->setEnabled(true);
|
||||
for (QHash< QString, WmData >::ConstIterator it = wms.constBegin(); it != wms.constEnd(); ++it) {
|
||||
if ((*it).internalName == oldwm) {
|
||||
// make it selected
|
||||
wmCombo->setCurrentIndex(wmCombo->findText(it.key()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CfgWm::tryWmLaunch()
|
||||
{
|
||||
if (currentWm() == "kwin"
|
||||
&& qstrcmp(NETRootInfo(QX11Info::display(), NET::SupportingWMCheck).wmName(), "KWin") == 0) {
|
||||
// it is already running, don't necessarily restart e.g. after a failure with other WM
|
||||
return true;
|
||||
}
|
||||
KMessageBox::information(
|
||||
window(),
|
||||
i18n("Your running window manager will be now replaced with the configured one."),
|
||||
i18n("Window Manager Change"),
|
||||
"windowmanagerchange"
|
||||
);
|
||||
|
||||
bool ret = false;
|
||||
setEnabled(false);
|
||||
killWM();
|
||||
if (startWM(currentWmData().exec)) {
|
||||
// it's forked into background
|
||||
ret = true;
|
||||
|
||||
// NOTE: wait for the WM to be operational otherwise the timer dialog may not
|
||||
// show up and the configuration window becomes non-interactive until the timeout is
|
||||
// reached
|
||||
const QByteArray wmatom = getWMAtom();
|
||||
KSelectionOwner kselectionowner(wmatom.constData(), getWMScreen());
|
||||
ushort counter = 0;
|
||||
while (counter < 10 && kselectionowner.currentOwnerWindow() == XNone) {
|
||||
QCoreApplication::processEvents(QEventLoop::AllEvents, s_eventstime);
|
||||
QThread::msleep(s_sleeptime);
|
||||
counter++;
|
||||
}
|
||||
|
||||
KTimerDialog* wmDialog = new KTimerDialog(
|
||||
20000, KTimerDialog::CountDown, window(),
|
||||
i18n("Config Window Manager Change"),
|
||||
KTimerDialog::Ok | KTimerDialog::Cancel, KTimerDialog::Cancel
|
||||
);
|
||||
wmDialog->setButtonGuiItem(KDialog::Ok, KGuiItem(i18n("&Accept Change"), "dialog-ok"));
|
||||
wmDialog->setButtonGuiItem(KDialog::Cancel, KGuiItem(i18n("&Revert to Previous"), "dialog-cancel"));
|
||||
QLabel *label = new QLabel(
|
||||
i18n( "The configured window manager is being launched.\n"
|
||||
"Please check it has started properly and confirm the change.\n"
|
||||
"The launch will be automatically reverted in 20 seconds." ), wmDialog );
|
||||
label->setWordWrap(true);
|
||||
wmDialog->setMainWidget(label);
|
||||
|
||||
if (wmDialog->exec() != QDialog::Accepted ) {
|
||||
// cancelled for some reason
|
||||
ret = false;
|
||||
|
||||
KMessageBox::sorry(
|
||||
window(),
|
||||
i18n("The running window manager has been reverted to the previous window manager.")
|
||||
);
|
||||
}
|
||||
|
||||
delete wmDialog;
|
||||
wmDialog = NULL;
|
||||
} else {
|
||||
ret = false;
|
||||
|
||||
KMessageBox::sorry(
|
||||
window(),
|
||||
i18n("The new window manager has failed to start.\nThe running window manager has been reverted to the previous window manager.")
|
||||
);
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
// case-insensitive search
|
||||
foreach (const QString &wmkey, wms.keys()) {
|
||||
if (wmkey.toLower() == oldwm) {
|
||||
WmData oldwmdata = wms.value(wmkey);
|
||||
killWM();
|
||||
startWM(oldwmdata.exec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setEnabled(true);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CfgWm::loadWMs(const QString ¤t)
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
|
||||
class CfgWm: public QWidget, public Ui::WmConfig_UI, public CfgPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
CfgWm(QWidget *parent);
|
||||
virtual ~CfgWm();
|
||||
|
@ -36,18 +36,20 @@ protected Q_SLOTS:
|
|||
|
||||
Q_SIGNALS:
|
||||
void changed(bool);
|
||||
|
||||
private:
|
||||
bool tryWmLaunch();
|
||||
void loadWMs( const QString& current );
|
||||
QString currentWm() const;
|
||||
bool saveAndConfirm();
|
||||
struct WmData {
|
||||
QString internalName;
|
||||
QString exec;
|
||||
QString configureCommand;
|
||||
QString parentArgument;
|
||||
};
|
||||
|
||||
void loadWMs(const QString ¤t);
|
||||
QString currentWm() const;
|
||||
bool saveAndConfirm();
|
||||
WmData currentWmData() const;
|
||||
|
||||
QHash<QString, WmData> wms; // i18n text -> data
|
||||
QString oldwm; // the original value
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue