From 68cba853735b2d8a266367f47fe11040966ce85c Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Sun, 23 Nov 2014 15:50:32 -0600 Subject: [PATCH] Fix twin deleting comptontdepidfile when compton-tde already running on startup Fix long-standing bug in calling desktop lock methods over DCOP from within kdesktop process --- kdesktop/krootwm.cc | 62 +++++++++++++++++++++--- kdesktop/krootwm.h | 23 +++++++++ tdmlib/dmctl.cpp | 16 +++--- tdmlib/dmctl.h | 2 +- twin/compton-tde/compton.c | 1 - twin/workspace.cpp | 99 +++++++++++++++++++++----------------- 6 files changed, 144 insertions(+), 59 deletions(-) diff --git a/kdesktop/krootwm.cc b/kdesktop/krootwm.cc index e200366f7..677c81f65 100644 --- a/kdesktop/krootwm.cc +++ b/kdesktop/krootwm.cc @@ -52,6 +52,8 @@ #include #include #include +#include +#include #include "krootwm.h" #include "kdiconview.h" @@ -71,6 +73,15 @@ extern TQCString kdesktop_name, kicker_name, twin_name; KRootWm::KRootWm(KDesktop* _desktop) : TQObject(_desktop), startup(FALSE) { + m_helperThread = new TQEventLoopThread; + m_helperThread->start(); + m_threadHelperObject = new KRootWmThreadHelperObject; + m_threadHelperObject->moveToThread(m_helperThread); + connect(this, TQT_SIGNAL(terminateHelperThread()), m_threadHelperObject, TQT_SLOT(terminateThread())); + connect(this, TQT_SIGNAL(asyncLock()), m_threadHelperObject, TQT_SLOT(slotLock())); + connect(this, TQT_SIGNAL(asyncLockAndDoNewSession()), m_threadHelperObject, TQT_SLOT(lockAndDoNewSession())); + connect(this, TQT_SIGNAL(asyncSlotSessionActivated(int)), m_threadHelperObject, TQT_SLOT(slotSessionActivated(int))); + s_rootWm = this; m_actionCollection = new TDEActionCollection(_desktop, this, "KRootWm::m_actionCollection"); m_pDesktop = _desktop; @@ -213,6 +224,11 @@ KRootWm::KRootWm(KDesktop* _desktop) : TQObject(_desktop), startup(FALSE) KRootWm::~KRootWm() { + terminateHelperThread(); + m_helperThread->wait(); + delete m_threadHelperObject; + delete m_helperThread; + delete m_actionCollection; delete desktopMenu; delete windowListMenu; @@ -820,7 +836,7 @@ void KRootWm::slotCascadeWindows() { void KRootWm::slotLock() { - kapp->dcopClient()->send(kdesktop_name, "KScreensaverIface", "lock()", TQString("")); + asyncLock(); } @@ -864,10 +880,40 @@ void KRootWm::slotPopulateSessions() } } +void KRootWmThreadHelperObject::terminateThread() { + TQEventLoop* eventLoop = TQApplication::eventLoop(); + if (eventLoop) { + eventLoop->exit(0); + } +} + +void KRootWmThreadHelperObject::slotLock() { + // Block here until lock is complete + // If this is not done the desktop of the locked session will be shown after VT switch until the lock fully engages! + // Force remote call to ensure that blocking is enforced even though this call is being made from inside the kdesktop_name application... + // If this is not done DCOP will translate the call into a send and the desktop of the locked session will be shown after VT switch as above + system("dcop kdesktop KScreensaverIface lock"); +} + +void KRootWmThreadHelperObject::lockAndDoNewSession() { + // Block here until lock is complete + // If this is not done the desktop of the locked session will be shown after VT switch until the lock fully engages! + // Force remote call to ensure that blocking is enforced even though this call is being made from inside the kdesktop_name application... + // If this is not done DCOP will translate the call into a send and the desktop of the locked session will be shown after VT switch as above + if (system("dcop kdesktop KScreensaverIface lock") == 0) { + DM().startReserve(); + } +} + +void KRootWmThreadHelperObject::slotSessionActivated(int vt) { + DM().lockSwitchVT( vt ); +} + void KRootWm::slotSessionActivated( int ent ) { - if (ent > 0 && !sessionsMenu->isItemChecked( ent )) - DM().lockSwitchVT( ent ); + if (ent > 0 && !sessionsMenu->isItemChecked( ent )) { + asyncSlotSessionActivated( ent ); + } } void KRootWm::slotNewSession() @@ -903,10 +949,12 @@ void KRootWm::doNewSession( bool lock ) if (result==KMessageBox::Cancel) return; - if (lock) - slotLock(); - - DM().startReserve(); + if (lock) { + asyncLockAndDoNewSession(); + } + else { + DM().startReserve(); + } } void KRootWm::slotMenuItemActivated(int /* item */ ) diff --git a/kdesktop/krootwm.h b/kdesktop/krootwm.h index dabe5ac23..eb6bd9f55 100644 --- a/kdesktop/krootwm.h +++ b/kdesktop/krootwm.h @@ -56,6 +56,9 @@ enum { ITEM_LOGOUT }; +class TQEventLoopThread; +class KRootWmThreadHelperObject; + /** * This class is the handler for the menus (root popup menu and desktop menubar) */ @@ -123,6 +126,12 @@ public slots: void slotOpenTerminal(); void slotLockNNewSession(); +signals: + void terminateHelperThread(); + void asyncLock(); + void asyncLockAndDoNewSession(); + void asyncSlotSessionActivated(int vt); + private: KDesktop* m_pDesktop; @@ -166,6 +175,9 @@ private: static KRootWm * s_rootWm; + TQEventLoopThread* m_helperThread; + KRootWmThreadHelperObject* m_threadHelperObject; + private slots: @@ -175,4 +187,15 @@ private slots: void slotConfigClosed(); }; +class KRootWmThreadHelperObject : public TQObject +{ + TQ_OBJECT + + public slots: + void terminateThread(); + void slotLock(); + void lockAndDoNewSession(); + void slotSessionActivated(int vt); +}; + #endif diff --git a/tdmlib/dmctl.cpp b/tdmlib/dmctl.cpp index 6fea12b5a..cc9535ab4 100644 --- a/tdmlib/dmctl.cpp +++ b/tdmlib/dmctl.cpp @@ -393,15 +393,15 @@ void DM::lockSwitchVT( int vt ) { if (isSwitchable()) { - TQByteArray data; - TQCString replyType; - TQByteArray replyData; // Block here until lock is complete // If this is not done the desktop of the locked session will be shown after VT switch until the lock fully engages! - kapp->dcopClient()->call("kdesktop", "KScreensaverIface", "lock()", data, replyType, replyData); - if (!switchVT( vt )) { - // Switching VT failed; unlock... - // kapp->dcopClient()->call("kdesktop", "KScreensaverIface", "unlock()", data, replyType, replyData); + // Force remote call to ensure that blocking is enforced even if this call is being made from inside the "kdesktop" application... + // If this is not done DCOP will translate the call into a send and the desktop of the locked session will be shown after VT switch as above + if (system("dcop kdesktop KScreensaverIface lock") == 0) { + if (!switchVT( vt )) { + // Switching VT failed; unlock... + // system("dcop kdesktop KScreensaverIface unlock") + } } } } @@ -484,3 +484,5 @@ DM::type() } #endif // Q_WS_X11 + +#include "dmctl.moc" \ No newline at end of file diff --git a/tdmlib/dmctl.h b/tdmlib/dmctl.h index f50f72f6c..90928e2e3 100644 --- a/tdmlib/dmctl.h +++ b/tdmlib/dmctl.h @@ -32,10 +32,10 @@ struct SessEnt { typedef TQValueList SessList; class DM { - #ifdef Q_WS_X11 public: + DM(); ~DM(); diff --git a/twin/compton-tde/compton.c b/twin/compton-tde/compton.c index e9097a736..aa7fbba0c 100644 --- a/twin/compton-tde/compton.c +++ b/twin/compton-tde/compton.c @@ -196,7 +196,6 @@ void handle_siguser (int sig) my_exit_code=3; setuid(uidnum); write_pid_file(getpid()); - } else { uidnum = getuid(); diff --git a/twin/workspace.cpp b/twin/workspace.cpp index 14ab22efb..77b6bc42b 100644 --- a/twin/workspace.cpp +++ b/twin/workspace.cpp @@ -225,60 +225,73 @@ Workspace::Workspace( bool restore ) } // start kompmgr - i wanted to put this into main.cpp, but that would prevent dcop support, as long as Application was no dcop_object + + // If compton-tde is already running, send it SIGTERM + // Attempt to load the compton-tde pid file + char *filename; + const char *pidfile = "compton-tde.pid"; + char uidstr[sizeof(uid_t)*8+1]; + sprintf(uidstr, "%d", getuid()); + int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3; + filename = (char*)malloc(n*sizeof(char)+1); + memset(filename,0,n); + strcat(filename, P_tmpdir); + strcat(filename, "/."); + strcat(filename, uidstr); + strcat(filename, "-"); + strcat(filename, pidfile); + + // Now that we did all that by way of introduction...read the file! + FILE *pFile; + char buffer[255]; + pFile = fopen(filename, "r"); + int kompmgrpid = 0; + if (pFile) + { + printf("[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename); + // obtain file size + fseek (pFile , 0 , SEEK_END); + unsigned long lSize = ftell (pFile); + if (lSize > 254) + lSize = 254; + rewind (pFile); + size_t result = fread (buffer, 1, lSize, pFile); + fclose(pFile); + kompmgrpid = atoi(buffer); + } + + free(filename); + filename = NULL; + if (options->useTranslucency) { kompmgr = new TDEProcess; connect(kompmgr, TQT_SIGNAL(receivedStderr(TDEProcess*, char*, int)), TQT_SLOT(handleKompmgrOutput(TDEProcess*, char*, int))); *kompmgr << TDE_COMPOSITOR_BINARY; - startKompmgr(); + if (kompmgrpid) + { + if (kill(kompmgrpid, 0) < 0) + { + // Stale PID file detected; (re)start compositor! + startKompmgr(); + } + } + else + { + startKompmgr(); + } } else if (!disable_twin_composition_manager) { - // If compton-tde is already running, send it SIGTERM - // Attempt to load the compton-tde pid file - char *filename; - const char *pidfile = "compton-tde.pid"; - char uidstr[sizeof(uid_t)*8+1]; - sprintf(uidstr, "%d", getuid()); - int n = strlen(P_tmpdir)+strlen(uidstr)+strlen(pidfile)+3; - filename = (char*)malloc(n*sizeof(char)+1); - memset(filename,0,n); - strcat(filename, P_tmpdir); - strcat(filename, "/."); - strcat(filename, uidstr); - strcat(filename, "-"); - strcat(filename, pidfile); - // Now that we did all that by way of introduction...read the file! - FILE *pFile; - char buffer[255]; - pFile = fopen(filename, "r"); - int kompmgrpid = 0; - if (pFile) + if (kompmgrpid) { - printf("[twin-workspace] Using '%s' as compton-tde pidfile\n\n", filename); - // obtain file size - fseek (pFile , 0 , SEEK_END); - unsigned long lSize = ftell (pFile); - if (lSize > 254) - lSize = 254; - rewind (pFile); - size_t result = fread (buffer, 1, lSize, pFile); - fclose(pFile); - kompmgrpid = atoi(buffer); + kill(kompmgrpid, SIGTERM); + } + else + { + stopKompmgr(); } - - free(filename); - filename = NULL; - - if (kompmgrpid) - { - kill(kompmgrpid, SIGTERM); - } - else - { - stopKompmgr(); - } } }