Branch: master

68cba853 2014-11-23 15:50:32 Timothy Pearson
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
M kdesktop/krootwm.cc
M kdesktop/krootwm.h
M tdmlib/dmctl.cpp
M tdmlib/dmctl.h
M twin/compton-tde/compton.c
M twin/workspace.cpp
diff --git a/kdesktop/krootwm.cc b/kdesktop/krootwm.cc
index e200366..677c81f 100644
--- a/kdesktop/krootwm.cc
+++ b/kdesktop/krootwm.cc
@@ -52,6 +52,8 @@
 #include <tdemessagebox.h>
 #include <kuser.h>
 #include <tqfile.h>
+#include <ntqthread.h>
+#include <tqeventloop.h>
 
 #include "krootwm.h"
 #include "kdiconview.h"
@@ -71,6 +73,15 @@
 
 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()
 {
+  terminateHelperThread();
+  m_helperThread->wait();
+  delete m_threadHelperObject;
+  delete m_helperThread;
+
   delete m_actionCollection;
   delete desktopMenu;
   delete windowListMenu;
@@ -820,7 +836,7 @@
 
 
 void KRootWm::slotLock() {
-    kapp->dcopClient()->send(kdesktop_name, "KScreensaverIface", "lock()", TQString(""));
+	asyncLock();
 }
 
 
@@ -864,10 +880,40 @@
         }
 }
 
+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 @@
     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 dabe5ac..eb6bd9f 100644
--- a/kdesktop/krootwm.h
+++ b/kdesktop/krootwm.h
@@ -56,6 +56,9 @@
   ITEM_LOGOUT
 };
 
+class TQEventLoopThread;
+class KRootWmThreadHelperObject;
+
 /**
  * This class is the handler for the menus (root popup menu and desktop menubar)
  */
@@ -123,6 +126,12 @@
   void slotOpenTerminal();
   void slotLockNNewSession();
 
+signals:
+  void terminateHelperThread();
+  void asyncLock();
+  void asyncLockAndDoNewSession();
+  void asyncSlotSessionActivated(int vt);
+
 private:
   KDesktop* m_pDesktop;
 
@@ -166,6 +175,9 @@
 
   static KRootWm * s_rootWm;
 
+  TQEventLoopThread* m_helperThread;
+  KRootWmThreadHelperObject* m_threadHelperObject;
+
 
 private slots:
 
@@ -175,4 +187,15 @@
   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 6fea12b..cc9535a 100644
--- a/tdmlib/dmctl.cpp
+++ b/tdmlib/dmctl.cpp
@@ -393,15 +393,15 @@
 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 @@
 }
 
 #endif // Q_WS_X11
+
+#include "dmctl.moc"
\ No newline at end of file
diff --git a/tdmlib/dmctl.h b/tdmlib/dmctl.h
index f50f72f..90928e2 100644
--- a/tdmlib/dmctl.h
+++ b/tdmlib/dmctl.h
@@ -32,10 +32,10 @@
 typedef TQValueList<SessEnt> 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 e9097a7..aa7fbba 100644
--- a/twin/compton-tde/compton.c
+++ b/twin/compton-tde/compton.c
@@ -196,7 +196,6 @@
         my_exit_code=3;
         setuid(uidnum);
         write_pid_file(getpid());
-
     }
     else {
         uidnum = getuid();
diff --git a/twin/workspace.cpp b/twin/workspace.cpp
index 14ab22e..77b6bc4 100644
--- a/twin/workspace.cpp
+++ b/twin/workspace.cpp
@@ -225,60 +225,73 @@
     }
 
     // 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!
 ** Diff limit reached (max: 250 lines) **