summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kwin/kcmkwin/kwinoptions/windows.cpp4
-rw-r--r--kwin/kompmgr/kompmgr.c99
-rw-r--r--kwin/workspace.cpp142
3 files changed, 194 insertions, 51 deletions
diff --git a/kwin/kcmkwin/kwinoptions/windows.cpp b/kwin/kcmkwin/kwinoptions/windows.cpp
index 9e81bc053..f3de197d5 100644
--- a/kwin/kcmkwin/kwinoptions/windows.cpp
+++ b/kwin/kcmkwin/kwinoptions/windows.cpp
@@ -1491,6 +1491,7 @@ KTranslucencyConfig::KTranslucencyConfig (bool _standAlone, KConfig *_config, TQ
connect(shadowTopOffset, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(resetKompmgr()));
connect(shadowLeftOffset, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(resetKompmgr()));
connect(shadowColor, TQT_SIGNAL(changed(const TQColor&)), TQT_SLOT(resetKompmgr()));
+ connect(fadeInWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr()));
connect(fadeInMenuWindows, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr()));
connect(fadeOnOpacityChange, TQT_SIGNAL(toggled(bool)), TQT_SLOT(resetKompmgr()));
connect(fadeInSpeed, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(resetKompmgr()));
@@ -1695,8 +1696,7 @@ void KTranslucencyConfig::startKompmgr()
bool ret;
KProcess proc;
proc << "kompmgr";
- ret = proc.start(KProcess::DontCare, KProcess::AllOutput);
- proc.detach();
+ ret = proc.start(KProcess::DontCare);
}
void KTranslucencyConfig::showWarning(bool alphaActivated)
diff --git a/kwin/kompmgr/kompmgr.c b/kwin/kompmgr/kompmgr.c
index ceea0ac30..910622d73 100644
--- a/kwin/kompmgr/kompmgr.c
+++ b/kwin/kompmgr/kompmgr.c
@@ -34,8 +34,10 @@
* CHANGELOG:
* http://patchwork.freedesktop.org/patch/1049/ [Add default background color option] 08/11/2011
* http://patchwork.freedesktop.org/patch/1052/ [Prevent flicker on root pixmap change] 08/11/2011
- * Added SIGUSER1 handler to change process UID [Prevent flicker on login] 08/12/2011
+ * Added SIGUSR1 handler to change process UID [Prevent flicker on login] 08/12/2011
* Added ability to write PID of process to home directory 08/14/2011
+ * Added SIGUSR2 handler to reload settings [Prevent flicker on settings change] 08/14/2011
+ * Added SIGTERM handler to clean up stale PID files on exit 08/14/2011
*
* TODO:
* http://patchwork.freedesktop.org/patch/1053/ [Fix window mapping with re-used window ids]
@@ -76,7 +78,7 @@ check baghira.sf.net for more infos
#define _LEFTWIDTH_(x) (x & 0xff)
/* #define USE_ENV_HOME 1 */
-/* #define WRITE_PID_FILE 1 */
+#define WRITE_PID_FILE 1
#ifndef USE_ENV_HOME
#include <pwd.h>
@@ -297,7 +299,7 @@ void write_pid_file(pid_t pid)
home = getenv("HOME");
#endif
const char *filename;
- const char *configfile = "/.kompmgr.pid";
+ const char *configfile = "/.kompmgr.pid";
int n = strlen(home)+strlen(configfile)+1;
filename = (char*)malloc(n*sizeof(char));
memset(filename,0,n);
@@ -311,8 +313,10 @@ void write_pid_file(pid_t pid)
char buffer[255];
sprintf(buffer, "%d", pid);
pFile = fopen(filename, "w");
- fwrite(buffer,1,strlen(buffer), pFile);
- fclose(pFile);
+ if (pFile) {
+ fwrite(buffer,1,strlen(buffer), pFile);
+ fclose(pFile);
+ }
free(filename);
filename = NULL;
@@ -353,46 +357,59 @@ void delete_pid_file()
void handle_siguser (int sig)
{
- char newuid[1024];
+ int uidnum;
+ if (sig == SIGTERM) {
+ delete_pid_file();
+ exit(0);
+ return;
+ }
+ if (sig == SIGUSR1) {
+ char newuid[1024];
#ifndef NDEBUG
- printf("Enter the new user ID:\n\r"); fflush(stdout);
+ printf("Enter the new user ID:\n\r"); fflush(stdout);
#endif
- char *eof;
- newuid[0] = '\0';
- newuid[sizeof(newuid)-1] = '\0';
- eof = fgets(newuid, sizeof(newuid), stdin);
- int uidnum = atoi(newuid);
+ char *eof;
+ newuid[0] = '\0';
+ newuid[sizeof(newuid)-1] = '\0';
+ eof = fgets(newuid, sizeof(newuid), stdin);
+ uidnum = atoi(newuid);
#ifndef NDEBUG
- printf("Setting kompmgr process uid to %d...\n\r", uidnum); fflush(stdout);
+ printf("Setting kompmgr process uid to %d...\n\r", uidnum); fflush(stdout);
#endif
- delete_pid_file();
- setuid(uidnum);
- write_pid_file(getpid());
+ delete_pid_file();
+ setuid(uidnum);
+ write_pid_file(getpid());
+ }
+ else {
+ uidnum = getuid();
+ }
+ if ((sig == SIGUSR1) || (sig == SIGUSR2)) {
#ifdef USE_ENV_HOME
- const char *home = getenv("HOME");
+ const char *home = getenv("HOME");
#else
- const char *home;
- struct passwd *p;
- p = getpwuid(uidnum);
- if (p)
- home = p->pw_dir;
- else
- home = getenv("HOME");
+ const char *home;
+ struct passwd *p;
+ p = getpwuid(uidnum);
+ if (p)
+ home = p->pw_dir;
+ else
+ home = getenv("HOME");
#endif
- const char *filename;
- const char *configfile = "/.xcompmgrrc";
- int n = strlen(home)+strlen(configfile)+1;
- filename = (char*)malloc(n*sizeof(char));
- memset(filename,0,n);
- strcat(filename, home);
- strcat(filename, configfile);
-
- loadConfig(filename); /* reload the configuration file */
-
- free(filename);
- filename = NULL;
+ const char *filename;
+ const char *configfile = "/.xcompmgrrc";
+ int n = strlen(home)+strlen(configfile)+1;
+ filename = (char*)malloc(n*sizeof(char));
+ memset(filename,0,n);
+ strcat(filename, home);
+ strcat(filename, configfile);
+
+ loadConfig(filename); /* reload the configuration file */
+
+ free(filename);
+ filename = NULL;
+ }
}
fade *
@@ -2712,9 +2729,8 @@ main (int argc, char **argv)
usr_action.sa_mask = block_mask;
usr_action.sa_flags = 0;
sigaction(SIGUSR1, &usr_action, NULL);
-
- // atexit(delete_pid_file); // [FIXME] For some reason this gets confused and deletes the file early
- write_pid_file(getpid());
+ sigaction(SIGUSR2, &usr_action, NULL);
+ sigaction(SIGTERM, &usr_action, NULL);
loadConfig(NULL); /*we do that before cmdline-parsing, so config-values can be overridden*/
/*used for shadow colors*/
@@ -2931,6 +2947,11 @@ main (int argc, char **argv)
ufd.events = POLLIN;
if (!autoRedirect)
paint_all (dpy, None);
+
+ /* Under no circumstances should these two lines EVER be moved earlier in main() than this point */
+ atexit(delete_pid_file);
+ write_pid_file(getpid());
+
for (;;)
{
/* dump_wins (); */
diff --git a/kwin/workspace.cpp b/kwin/workspace.cpp
index 4d3199a18..77e22af6f 100644
--- a/kwin/workspace.cpp
+++ b/kwin/workspace.cpp
@@ -45,6 +45,8 @@ License. See the file "COPYING" for the exact licensing terms.
#include <X11/keysymdef.h>
#include <X11/cursorfont.h>
+#include <pwd.h>
+
namespace KWinInternal
{
@@ -221,6 +223,57 @@ Workspace::Workspace( bool restore )
*kompmgr << "kompmgr";
startKompmgr();
}
+ else
+ {
+ // If kompmgr is already running, send it SIGTERM
+ // Attempt to load the kompmgr pid file
+ const char *home;
+ struct passwd *p;
+ p = getpwuid(getuid());
+ if (p)
+ home = p->pw_dir;
+ else
+ home = getenv("HOME");
+ char *filename;
+ const char *configfile = "/.kompmgr.pid";
+ int n = strlen(home)+strlen(configfile)+1;
+ filename = (char*)malloc(n*sizeof(char));
+ memset(filename,0,n);
+ strcat(filename, home);
+ strcat(filename, configfile);
+
+ printf("reading '%s' as kompmgr pidfile\n\n", filename);
+
+ // 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)
+ {
+ // 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 (kompmgrpid)
+ {
+ kill(kompmgrpid, SIGTERM);
+ }
+ else
+ {
+ stopKompmgr();
+ }
+ }
}
@@ -1023,9 +1076,70 @@ void Workspace::slotReconfigure()
if (options->resetKompmgr) // need restart
{
bool tmp = options->useTranslucency;
- stopKompmgr();
+
+ // If kompmgr is already running, sending SIGUSR2 will force a reload of its settings
+ // Attempt to load the kompmgr pid file
+ const char *home;
+ struct passwd *p;
+ p = getpwuid(getuid());
+ if (p)
+ home = p->pw_dir;
+ else
+ home = getenv("HOME");
+ char *filename;
+ const char *configfile = "/.kompmgr.pid";
+ int n = strlen(home)+strlen(configfile)+1;
+ filename = (char*)malloc(n*sizeof(char));
+ memset(filename,0,n);
+ strcat(filename, home);
+ strcat(filename, configfile);
+
+ printf("reading '%s' as kompmgr pidfile\n\n", filename);
+
+ // 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)
+ {
+ // 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 (tmp)
- TQTimer::singleShot( 200, this, TQT_SLOT(startKompmgr()) ); // wait some time to ensure system's ready for restart
+ {
+ if (kompmgrpid)
+ {
+ kill(kompmgrpid, SIGUSR2);
+ }
+ else
+ {
+ stopKompmgr();
+ TQTimer::singleShot( 200, this, TQT_SLOT(startKompmgr()) ); // wait some time to ensure system's ready for restart
+ }
+ }
+ else
+ {
+ if (kompmgrpid)
+ {
+ kill(kompmgrpid, SIGTERM);
+ }
+ else
+ {
+ stopKompmgr();
+ }
+ }
}
}
@@ -2620,8 +2734,9 @@ void Workspace::startKompmgr()
void Workspace::stopKompmgr()
{
- if (!kompmgr || !kompmgr->isRunning())
+ if (!kompmgr || !kompmgr->isRunning()) {
return;
+ }
delete kompmgr_selection;
kompmgr_selection = NULL;
kompmgr->disconnect(this, TQT_SLOT(restartKompmgr()));
@@ -2647,21 +2762,28 @@ void Workspace::unblockKompmgrRestart()
void Workspace::restartKompmgr( KProcess *proc )
// this is for inernal purpose (crashhandling) only, usually you want to use workspace->stopKompmgr(); TQTimer::singleShot(200, workspace, TQT_SLOT(startKompmgr()));
{
+ bool crashed;
if (proc->signalled()) { // looks like kompmgr may have crashed
int exit_signal_number = proc->exitSignal();
if ( (exit_signal_number == SIGILL) || (exit_signal_number == SIGTRAP) || (exit_signal_number == SIGABRT) || (exit_signal_number == SIGSYS) || (exit_signal_number == SIGFPE) || (exit_signal_number == SIGBUS) || (exit_signal_number == SIGSEGV) ) {
- if (!allowKompmgrRestart) // uh oh, it crashed recently already
- {
- delete kompmgr_selection;
- kompmgr_selection = NULL;
- options->useTranslucency = FALSE;
+ crashed = true;
+ }
+ else {
+ crashed = false;
+ }
+ if (!allowKompmgrRestart) // uh oh, it exited recently already
+ {
+ delete kompmgr_selection;
+ kompmgr_selection = NULL;
+ options->useTranslucency = FALSE;
+ if (crashed) {
KProcess proc;
proc << "kdialog" << "--error"
<< i18n( "The Composite Manager crashed twice within a minute and is therefore disabled for this session.")
<< "--title" << i18n("Composite Manager Failure");
proc.start(KProcess::DontCare);
- return;
- }
+ }
+ return;
}
if (!kompmgr)
return;