[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[vidalia-svn] r3527: Merge in functionality to kill Firefox when Vidalia exits (r (in vidalia/branches/vidalia-0.1: . src/common src/vidalia)



Author: sjmurdoch
Date: 2009-02-16 18:28:41 -0500 (Mon, 16 Feb 2009)
New Revision: 3527

Modified:
   vidalia/branches/vidalia-0.1/
   vidalia/branches/vidalia-0.1/src/common/win32.cpp
   vidalia/branches/vidalia-0.1/src/common/win32.h
   vidalia/branches/vidalia-0.1/src/vidalia/mainwindow.cpp
Log:
Merge in functionality to kill Firefox when Vidalia exits (r3524:3526 on /trunk)


Property changes on: vidalia/branches/vidalia-0.1
___________________________________________________________________
Modified: svn:mergeinfo
   - /vidalia/trunk:3482,3504-3505
   + /vidalia/trunk:3482,3504-3505,3524-3526

Modified: vidalia/branches/vidalia-0.1/src/common/win32.cpp
===================================================================
--- vidalia/branches/vidalia-0.1/src/common/win32.cpp	2009-02-16 22:53:13 UTC (rev 3526)
+++ vidalia/branches/vidalia-0.1/src/common/win32.cpp	2009-02-16 23:28:41 UTC (rev 3527)
@@ -150,6 +150,66 @@
   RegCloseKey(key);
 }
 
+/**
+ * Callback for EnumThreadWindows which sends the WM_QUIT message
+ */
+BOOL CALLBACK quitWindowCallback(HWND hwnd, LPARAM targetPID)
+{
+  DWORD hwndPID = 0;
+
+  /* If the process ID for hwnd matches the target PID, post
+     WM_QUIT to the window */
+  GetWindowThreadProcessId(hwnd, &hwndPID);
+  if (hwndPID == (DWORD)targetPID)
+    PostMessage(hwnd, WM_QUIT, 0, (LPARAM)NULL);
+}
+
+/**
+ * Close process with the specified PID. Sends WM_QUIT to all
+ * top-level windows.
+ */
+void
+win32_end_process_by_pid(DWORD pid)
+{
+  /* Send WM_QUIT to all windows */
+  EnumWindows(&quitWindowCallback, (LPARAM)pid);
+  /* At this point we could kill the main thread, but how do we find
+     the ID of the main thread? We can find the ID of all threads
+     but killing them all seems to cause a problem for Firefox */
+  //PostThreadMessage(thread.th32ThreadID, WM_CLOSE, 0, (LPARAM)NULL);
+}
+
+/**
+ * Close all processes started from the specified filename. Sends
+ * WM_QUIT to all top-level windows. Filename should be given in
+ * lowercase, and comparison is case insensitive. Note: the MSDN
+ * documentation for WM_QUIT states that the message should not be
+ * sent by PostMessage(). However, sending WM_CLOSE leaves Firefox
+ * running, whereas WM_QUIT seems to work.
+ */
+void
+win32_end_process_by_filename(QString filename)
+{
+  /* Get list of running processes */
+  QHash<qint64, QString> procList = win32_process_list();
+
+  /* On old versions of Windows win32_process_list() will return
+     an empty list. In this case, just keep Vidalia open */
+  if (procList.isEmpty()) {
+    return;
+  }
+
+  /* Loop over all processes */
+  QHashIterator<qint64, QString> i(procList);
+  while (i.hasNext()) {
+    i.next();
+    if (i.value().toLower() == filename) {
+      /* Kill this process */
+      win32_end_process_by_pid((DWORD)i.key());
+    }
+  }
+}
+
 /** Returns a list of all currently active processes, including their pid
  * and exe filename. */
 QHash<qint64, QString>

Modified: vidalia/branches/vidalia-0.1/src/common/win32.h
===================================================================
--- vidalia/branches/vidalia-0.1/src/common/win32.h	2009-02-16 22:53:13 UTC (rev 3526)
+++ vidalia/branches/vidalia-0.1/src/common/win32.h	2009-02-16 23:28:41 UTC (rev 3527)
@@ -41,5 +41,15 @@
  * and exe filename. */
 QHash<qint64, QString> win32_process_list();
 
+/**
+ * Close all processes started from the specified filename. Sends
+ * WM_QUIT to all top-level windows. Filename should be given in
+ * lowercase, and comparison is case insensitive. Note: the MSDN
+ * documentation for WM_QUIT states that the message should not be
+ * sent by PostMessage(). However, sending WM_CLOSE leaves Firefox
+ * running, whereas WM_QUIT seems to work.
+ */
+void win32_end_process_by_filename(QString filename);
+
 #endif
 

Modified: vidalia/branches/vidalia-0.1/src/vidalia/mainwindow.cpp
===================================================================
--- vidalia/branches/vidalia-0.1/src/vidalia/mainwindow.cpp	2009-02-16 22:53:13 UTC (rev 3526)
+++ vidalia/branches/vidalia-0.1/src/vidalia/mainwindow.cpp	2009-02-16 23:28:41 UTC (rev 3527)
@@ -273,6 +273,25 @@
     _proxyProcess->kill();
   }
 
+  /* Kill the browser and IM client if using the new launcher */
+  VidaliaSettings vidalia_settings;
+
+  if (! vidalia_settings.getBrowserDirectory().isEmpty()) {
+    /* Disconnect the finished signals so that we won't try to exit Vidalia again */
+    QObject::disconnect(_browserProcess, SIGNAL(finished(int, QProcess::ExitStatus)), 0, 0);
+    QObject::disconnect(_imProcess, SIGNAL(finished(int, QProcess::ExitStatus)), 0, 0);
+
+    /* Use QProcess terminate function */
+    if (_browserProcess->state() == QProcess::Running)
+      _browserProcess->terminate();
+
+    /* Kill any processes which might have been forked off */
+    win32_end_process_by_filename(vidalia_settings.getBrowserExecutable());
+
+    if (_imProcess->state() == QProcess::Running)
+      _imProcess->terminate();    
+  }
+
   /* Disconnect all of the TorControl object's signals */
   QObject::disconnect(_torControl, 0, 0, 0);