Compare commits
	
		
			No commits in common. "master" and "d94633b7b4e479b63566a643c31f33652102a275" have entirely different histories.
		
	
	
		
			master
			...
			d94633b7b4
		
	
		
					 10 changed files with 53 additions and 351 deletions
				
			
		| 
						 | 
					@ -2,8 +2,8 @@ cmake_minimum_required(VERSION 2.4)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
project(sigstoped)
 | 
					project(sigstoped)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(SRC_FILES main.cpp process.cpp xinstance.cpp CppTimer.cpp)
 | 
					set(SRC_FILES main.cpp process.cpp xinstance.cpp)
 | 
				
			||||||
set(LIBS -lX11 -lrt)
 | 
					set(LIBS -lX11)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_executable(${PROJECT_NAME} ${SRC_FILES})
 | 
					add_executable(${PROJECT_NAME} ${SRC_FILES})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										97
									
								
								CppTimer.cpp
									
										
									
									
									
								
							
							
						
						
									
										97
									
								
								CppTimer.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -1,97 +0,0 @@
 | 
				
			||||||
#include "CppTimer.h"
 | 
					 | 
				
			||||||
#include <fcntl.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * GNU GENERAL PUBLIC LICENSE
 | 
					 | 
				
			||||||
 * Version 3, 29 June 2007
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * (C) 2020, Bernd Porr <mail@bernporr.me.uk>
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This is inspired by the timer_create man page.
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CppTimer::CppTimer() {
 | 
					 | 
				
			||||||
	// We create a static handler catches the signal SIG
 | 
					 | 
				
			||||||
	sa.sa_flags = SA_SIGINFO;
 | 
					 | 
				
			||||||
	sa.sa_sigaction = handler;
 | 
					 | 
				
			||||||
	sigemptyset(&sa.sa_mask);
 | 
					 | 
				
			||||||
	if (sigaction(SIG, &sa, NULL) == -1)
 | 
					 | 
				
			||||||
		throw("Could not create signal handler");
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	if(pipe(pipeFd) < 0)
 | 
					 | 
				
			||||||
		throw("Could not create pipe");
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	// Create the timer
 | 
					 | 
				
			||||||
	sev.sigev_notify = SIGEV_SIGNAL;
 | 
					 | 
				
			||||||
	sev.sigev_signo = SIG;
 | 
					 | 
				
			||||||
	// Cruical is that the signal carries the pointer to this class instance here
 | 
					 | 
				
			||||||
	// because the handler just handles anything that comes in!
 | 
					 | 
				
			||||||
	sev.sigev_value.sival_ptr = this;
 | 
					 | 
				
			||||||
	// create the timer
 | 
					 | 
				
			||||||
	if (timer_create(CLOCKID, &sev, &timerid) == -1)
 | 
					 | 
				
			||||||
		throw("Could not create timer");
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void CppTimer::start(long secs, long nanosecs,std::function<void()> callbackIn, int type) {
 | 
					 | 
				
			||||||
	switch(type){
 | 
					 | 
				
			||||||
		case(PERIODIC):
 | 
					 | 
				
			||||||
			//starts after specified period of nanoseconds
 | 
					 | 
				
			||||||
			its.it_value.tv_sec = secs;
 | 
					 | 
				
			||||||
			its.it_value.tv_nsec = nanosecs;
 | 
					 | 
				
			||||||
			its.it_interval.tv_sec = secs;
 | 
					 | 
				
			||||||
			its.it_interval.tv_nsec = nanosecs;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case(ONESHOT):
 | 
					 | 
				
			||||||
			//fires once after specified period of nanoseconds
 | 
					 | 
				
			||||||
			its.it_value.tv_sec = secs;
 | 
					 | 
				
			||||||
			its.it_value.tv_nsec = nanosecs;
 | 
					 | 
				
			||||||
			its.it_interval.tv_sec = 0;
 | 
					 | 
				
			||||||
			its.it_interval.tv_nsec = 0;
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	callback = callbackIn;
 | 
					 | 
				
			||||||
	if (timer_settime(timerid, 0, &its, NULL) == -1)
 | 
					 | 
				
			||||||
		throw("Could not start timer");
 | 
					 | 
				
			||||||
	discardPipe();
 | 
					 | 
				
			||||||
	running = true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void CppTimer::discardPipe() {
 | 
					 | 
				
			||||||
	char buf;
 | 
					 | 
				
			||||||
	fcntl(pipeFd[0], F_SETFL, O_NONBLOCK);
 | 
					 | 
				
			||||||
	while(read(pipeFd[0], &buf, 1) > 0);
 | 
					 | 
				
			||||||
	fcntl(pipeFd[0], F_SETFL, 0);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void CppTimer::block()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if(running)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		char buf;
 | 
					 | 
				
			||||||
		read(pipeFd[0], &buf, 1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void CppTimer::stop() {
 | 
					 | 
				
			||||||
	// disarm
 | 
					 | 
				
			||||||
	struct itimerspec itsnew;
 | 
					 | 
				
			||||||
	itsnew.it_value.tv_sec = 0;
 | 
					 | 
				
			||||||
	itsnew.it_value.tv_nsec = 0;
 | 
					 | 
				
			||||||
	itsnew.it_interval.tv_sec = 0;
 | 
					 | 
				
			||||||
	itsnew.it_interval.tv_nsec = 0;
 | 
					 | 
				
			||||||
	timer_settime(timerid, 0, &itsnew, &its);
 | 
					 | 
				
			||||||
	running = false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool CppTimer::isRunning()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	return running;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
CppTimer::~CppTimer() {
 | 
					 | 
				
			||||||
	stop();
 | 
					 | 
				
			||||||
	// delete the timer
 | 
					 | 
				
			||||||
	timer_delete(timerid);
 | 
					 | 
				
			||||||
	// default action for signal handling
 | 
					 | 
				
			||||||
	signal(SIG, SIG_IGN);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										85
									
								
								CppTimer.h
									
										
									
									
									
								
							
							
						
						
									
										85
									
								
								CppTimer.h
									
										
									
									
									
								
							| 
						 | 
					@ -1,85 +0,0 @@
 | 
				
			||||||
#ifndef __CPP_TIMER_H_
 | 
					 | 
				
			||||||
#define __CPP_TIMER_H_
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * GNU GENERAL PUBLIC LICENSE
 | 
					 | 
				
			||||||
 * Version 3, 29 June 2007
 | 
					 | 
				
			||||||
 *
 | 
					 | 
				
			||||||
 * (C) 2020, Bernd Porr <mail@bernporr.me.uk>
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * This is inspired by the timer_create man page.
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <stdlib.h>
 | 
					 | 
				
			||||||
#include <unistd.h>
 | 
					 | 
				
			||||||
#include <stdio.h>
 | 
					 | 
				
			||||||
#include <signal.h>
 | 
					 | 
				
			||||||
#include <time.h>
 | 
					 | 
				
			||||||
#include <functional>
 | 
					 | 
				
			||||||
#include <atomic>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#define CLOCKID CLOCK_MONOTONIC
 | 
					 | 
				
			||||||
#define SIG SIGRTMIN
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/**
 | 
					 | 
				
			||||||
 * Timer class which repeatedly fires. It's wrapper around the
 | 
					 | 
				
			||||||
 * POSIX per-process timer.
 | 
					 | 
				
			||||||
 **/
 | 
					 | 
				
			||||||
class CppTimer {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	static constexpr int PERIODIC = 0;
 | 
					 | 
				
			||||||
	static constexpr int ONESHOT  = 1;
 | 
					 | 
				
			||||||
	static constexpr long MS_TO_NS  = 1000000;
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Creates an instance of the timer and connects the
 | 
					 | 
				
			||||||
	 * signal handler to the timer.
 | 
					 | 
				
			||||||
	 **/
 | 
					 | 
				
			||||||
	CppTimer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Starts the timer. The timer fires first after
 | 
					 | 
				
			||||||
	 * the specified time in nanoseconds and then at
 | 
					 | 
				
			||||||
	 * that interval in PERIODIC mode. In ONESHOT mode
 | 
					 | 
				
			||||||
	 * the timer fires once after the specified time in
 | 
					 | 
				
			||||||
	 * nanoseconds.
 | 
					 | 
				
			||||||
	 **/
 | 
					 | 
				
			||||||
	virtual void start(long secs, long nanosecs, std::function<void()> callbackIn, int type = PERIODIC); 
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	* Stops the timer by disarming it. It can be re-started
 | 
					 | 
				
			||||||
	* with start().
 | 
					 | 
				
			||||||
	**/
 | 
					 | 
				
			||||||
	virtual void stop();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/**
 | 
					 | 
				
			||||||
	 * Destructor disarms the timer, deletes it and
 | 
					 | 
				
			||||||
	 * disconnect the signal handler.
 | 
					 | 
				
			||||||
	 **/
 | 
					 | 
				
			||||||
	virtual ~CppTimer();
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	bool isRunning();
 | 
					 | 
				
			||||||
	
 | 
					 | 
				
			||||||
	void block();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	timer_t timerid = 0;
 | 
					 | 
				
			||||||
	struct sigevent sev;
 | 
					 | 
				
			||||||
	struct sigaction sa;
 | 
					 | 
				
			||||||
	struct itimerspec its;
 | 
					 | 
				
			||||||
	int pipeFd[2];
 | 
					 | 
				
			||||||
	std::atomic<bool> running = false;
 | 
					 | 
				
			||||||
	std::function<void()> callback;
 | 
					 | 
				
			||||||
	void discardPipe();
 | 
					 | 
				
			||||||
		
 | 
					 | 
				
			||||||
	static void handler(int sig, siginfo_t *si, void *uc ) {
 | 
					 | 
				
			||||||
		CppTimer *timer = reinterpret_cast<CppTimer *> (si->si_value.sival_ptr);
 | 
					 | 
				
			||||||
		timer->callback();
 | 
					 | 
				
			||||||
		char buf = '\n'; 
 | 
					 | 
				
			||||||
		write(timer->pipeFd[1], &buf, 1);
 | 
					 | 
				
			||||||
		timer->running = false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
| 
						 | 
					@ -23,10 +23,9 @@
 | 
				
			||||||
struct Config
 | 
					struct Config
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    bool ignoreClientMachine = false;
 | 
					    bool ignoreClientMachine = false;
 | 
				
			||||||
    int  timeoutSecs = 10;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *argp_program_version = "1.0.6";
 | 
					const char *argp_program_version = "1.0.2";
 | 
				
			||||||
const char *argp_program_bug_address = "<carl@uvos.xyz>";
 | 
					const char *argp_program_bug_address = "<carl@uvos.xyz>";
 | 
				
			||||||
static char doc[] = "Deamon that stops programms via SIGSTOP when their X11 windows lose focus.";
 | 
					static char doc[] = "Deamon that stops programms via SIGSTOP when their X11 windows lose focus.";
 | 
				
			||||||
static char args_doc[] = "";
 | 
					static char args_doc[] = "";
 | 
				
			||||||
| 
						 | 
					@ -34,7 +33,6 @@ static char args_doc[] = "";
 | 
				
			||||||
static struct argp_option options[] = 
 | 
					static struct argp_option options[] = 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  {"ignore-client-machine",  'i', 0,      0,  "Also stop programs associated with windows that fail to set WM_CLIENT_MACHINE" },
 | 
					  {"ignore-client-machine",  'i', 0,      0,  "Also stop programs associated with windows that fail to set WM_CLIENT_MACHINE" },
 | 
				
			||||||
  {"timout", 't', "seconds",      0,  "Timeout to give program to close its last window before stoping it" },
 | 
					 | 
				
			||||||
  { 0 }
 | 
					  { 0 }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,9 +45,6 @@ error_t parse_opt (int key, char *arg, struct argp_state *state)
 | 
				
			||||||
        case 'i':
 | 
					        case 'i':
 | 
				
			||||||
        config->ignoreClientMachine = true;
 | 
					        config->ignoreClientMachine = true;
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
        case 't':
 | 
					 | 
				
			||||||
        config->timeoutSecs = atol(arg);
 | 
					 | 
				
			||||||
        break;
 | 
					 | 
				
			||||||
        default:
 | 
					        default:
 | 
				
			||||||
        return ARGP_ERR_UNKNOWN;
 | 
					        return ARGP_ERR_UNKNOWN;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										18
									
								
								debian/changelog
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										18
									
								
								debian/changelog
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,21 +1,3 @@
 | 
				
			||||||
sigstoped (1.0.6) unstable; urgency=medium
 | 
					 | 
				
			||||||
  Fix Timer overflow on 32bit devices
 | 
					 | 
				
			||||||
-- Uvos <carl@uvos.xyz>  Sat, 04 Jul 2020 11:47:00 +0100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sigstoped (1.0.5) unstable; urgency=medium
 | 
					 | 
				
			||||||
  Configureable timout for applications to close their windows.
 | 
					 | 
				
			||||||
  Fix 5sec stall when switching from an application to be stopped to an application that was stopped before.
 | 
					 | 
				
			||||||
  Make Xinstance thread safe
 | 
					 | 
				
			||||||
-- Uvos <carl@uvos.xyz>  Mon, 16 Jun 2020 09:47:00 +0100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sigstoped (1.0.4) unstable; urgency=medium
 | 
					 | 
				
			||||||
  Fix memory leak in XInstance::getTopLevelWindows()
 | 
					 | 
				
			||||||
 -- Uvos <carl@uvos.xyz>  Mon, 16 Jun 2020 09:47:00 +0100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sigstoped (1.0.3) unstable; urgency=medium
 | 
					 | 
				
			||||||
  Ignore BadWindow errors caused by faulty __NET_ACTIVE_WINDOW events
 | 
					 | 
				
			||||||
 -- Uvos <carl@uvos.xyz>  Mon, 15 Jun 2020 23:47:00 +0100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
sigstoped (1.0.2) unstable; urgency=medium
 | 
					sigstoped (1.0.2) unstable; urgency=medium
 | 
				
			||||||
  Inital version
 | 
					  Inital version
 | 
				
			||||||
 -- Uvos <carl@uvos.xyz>  Mon, 10 Jun 2020 15:00:00 +0100
 | 
					 -- Uvos <carl@uvos.xyz>  Mon, 10 Jun 2020 15:00:00 +0100
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								debian/copywrite
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								debian/copywrite
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,2 +0,0 @@
 | 
				
			||||||
Unless stated otherwise, all files are:
 | 
					 | 
				
			||||||
Copyright 2020 Carl Klemm and are licensed under the GPLv3
 | 
					 | 
				
			||||||
							
								
								
									
										120
									
								
								main.cpp
									
										
									
									
									
								
							
							
						
						
									
										120
									
								
								main.cpp
									
										
									
									
									
								
							| 
						 | 
					@ -39,27 +39,23 @@
 | 
				
			||||||
#include "split.h"
 | 
					#include "split.h"
 | 
				
			||||||
#include "debug.h"
 | 
					#include "debug.h"
 | 
				
			||||||
#include "argpopt.h"
 | 
					#include "argpopt.h"
 | 
				
			||||||
#include "CppTimer.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Window intraCommesWindow;
 | 
					Window intraCommesWindow;
 | 
				
			||||||
volatile bool configStale = false;
 | 
					 | 
				
			||||||
XInstance xinstance;
 | 
					XInstance xinstance;
 | 
				
			||||||
 | 
					volatile bool stop = false;
 | 
				
			||||||
 | 
					volatile bool configStale = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
constexpr char configPrefix[] = "/.config/sigstoped/";
 | 
					constexpr char configPrefix[] = "/.config/sigstoped/";
 | 
				
			||||||
constexpr char STOP_EVENT = 65;
 | 
					 | 
				
			||||||
constexpr char PROC_STOP_EVENT = 1;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
void sigTerm(int dummy) 
 | 
					void sigTerm(int dummy) 
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    XClientMessageEvent event;
 | 
					    stop = true;
 | 
				
			||||||
    memset(&event, 0, sizeof(XClientMessageEvent));
 | 
					    XClientMessageEvent dummyEvent;
 | 
				
			||||||
    event.type = ClientMessage;
 | 
					    memset(&dummyEvent, 0, sizeof(XClientMessageEvent));
 | 
				
			||||||
    event.window = intraCommesWindow;
 | 
					    dummyEvent.type = ClientMessage;
 | 
				
			||||||
    event.format = 8;
 | 
					    dummyEvent.window = intraCommesWindow;
 | 
				
			||||||
    event.data.b[0] = STOP_EVENT;
 | 
					    dummyEvent.format = 32;
 | 
				
			||||||
    XLockDisplay(xinstance.display);
 | 
					    XSendEvent(xinstance.display, intraCommesWindow, 0, 0, (XEvent*)&dummyEvent);
 | 
				
			||||||
    XSendEvent(xinstance.display, intraCommesWindow, 0, 0, (XEvent*)&event);
 | 
					 | 
				
			||||||
    XUnlockDisplay(xinstance.display);
 | 
					 | 
				
			||||||
    xinstance.flush();
 | 
					    xinstance.flush();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -125,7 +121,7 @@ bool createPidFile(const std::string& fileName)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            std::cerr<<"Only one "
 | 
					            std::cerr<<"Only one "
 | 
				
			||||||
                     <<sigstopedName
 | 
					                     <<sigstopedName
 | 
				
			||||||
                     <<" process exists, either sigstoped died or you have several diferently named binarys\n";
 | 
					                     <<" process exists, either sigstoped died or you have severl diferently named binarys\n";
 | 
				
			||||||
                     
 | 
					                     
 | 
				
			||||||
            std::filesystem::remove(fileName);
 | 
					            std::filesystem::remove(fileName);
 | 
				
			||||||
            return createPidFile(fileName);
 | 
					            return createPidFile(fileName);
 | 
				
			||||||
| 
						 | 
					@ -149,53 +145,8 @@ bool createPidFile(const std::string& fileName)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
void sendEventProcStop()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    XClientMessageEvent event;
 | 
					 | 
				
			||||||
    memset(&event, 0, sizeof(XClientMessageEvent));
 | 
					 | 
				
			||||||
    event.type = ClientMessage;
 | 
					 | 
				
			||||||
    event.window = intraCommesWindow;
 | 
					 | 
				
			||||||
    event.format = 8;
 | 
					 | 
				
			||||||
    event.data.b[0] = PROC_STOP_EVENT;
 | 
					 | 
				
			||||||
    XLockDisplay(xinstance.display);
 | 
					 | 
				
			||||||
    XSendEvent(xinstance.display, intraCommesWindow, 0, 0, (XEvent*)&event);
 | 
					 | 
				
			||||||
    XUnlockDisplay(xinstance.display);
 | 
					 | 
				
			||||||
    xinstance.flush();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool stopProcess(Process process, XInstance* xinstance)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    bool hasTopLevelWindow = false;
 | 
					 | 
				
			||||||
    std::vector<Window> tlWindows = xinstance->getTopLevelWindows();
 | 
					 | 
				
			||||||
    for(auto& window : tlWindows) 
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if(xinstance->getPid(window) == process.getPid()) hasTopLevelWindow = true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if(hasTopLevelWindow)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        process.stop(true);
 | 
					 | 
				
			||||||
        std::cout<<"Stoping pid: "+std::to_string(process.getPid())+" name: "+process.getName()<<'\n';
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else  
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        std::cout<<"not Stoping pid: "+std::to_string(process.getPid())+" name: "+process.getName()<<'\n';
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int main(int argc, char* argv[])
 | 
					int main(int argc, char* argv[])
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char* xDisplayName = std::getenv( "DISPLAY" );
 | 
					 | 
				
			||||||
    if(xDisplayName == nullptr) 
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        std::cerr<<"DISPLAY enviroment variable must be set.\n";
 | 
					 | 
				
			||||||
        return 1;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if(!xinstance.open(xDisplayName)) exit(1);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Config config;
 | 
					    Config config;
 | 
				
			||||||
    argp_parse(&argp, argc, argv, 0, 0, &config);
 | 
					    argp_parse(&argp, argc, argv, 0, 0, &config);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -208,7 +159,7 @@ int main(int argc, char* argv[])
 | 
				
			||||||
    std::string confDir = getConfdir();
 | 
					    std::string confDir = getConfdir();
 | 
				
			||||||
    if(confDir.size() == 0) return 1;
 | 
					    if(confDir.size() == 0) return 1;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if(!createPidFile(confDir+"pidfile")) return 1;
 | 
					    if(!createPidFile(confDir+"pidfile"));
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    std::vector<std::string> applicationNames = getApplicationlist(confDir+"blacklist");
 | 
					    std::vector<std::string> applicationNames = getApplicationlist(confDir+"blacklist");
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -220,8 +171,17 @@ int main(int argc, char* argv[])
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    char* xDisplayName = std::getenv( "DISPLAY" );
 | 
				
			||||||
 | 
					    if(xDisplayName == nullptr) 
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cerr<<"DISPLAY enviroment variable must be set.\n";
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    std::list<Process> stoppedProcs;
 | 
					    std::list<Process> stoppedProcs;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
 | 
					    if(!xinstance.open(xDisplayName)) exit(1);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    intraCommesWindow = XCreateSimpleWindow(xinstance.display, 
 | 
					    intraCommesWindow = XCreateSimpleWindow(xinstance.display, 
 | 
				
			||||||
                                            RootWindow(xinstance.display, xinstance.screen),
 | 
					                                            RootWindow(xinstance.display, xinstance.screen),
 | 
				
			||||||
                                            10, 10, 10, 10, 0, 0, 0);
 | 
					                                            10, 10, 10, 10, 0, 0, 0);
 | 
				
			||||||
| 
						 | 
					@ -230,7 +190,6 @@ int main(int argc, char* argv[])
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    XEvent event;
 | 
					    XEvent event;
 | 
				
			||||||
    Process prevProcess;
 | 
					    Process prevProcess;
 | 
				
			||||||
    Process qeuedToStop;
 | 
					 | 
				
			||||||
    Window prevWindow = 0;
 | 
					    Window prevWindow = 0;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    signal(SIGINT, sigTerm);
 | 
					    signal(SIGINT, sigTerm);
 | 
				
			||||||
| 
						 | 
					@ -238,13 +197,11 @@ int main(int argc, char* argv[])
 | 
				
			||||||
    signal(SIGHUP, sigTerm);
 | 
					    signal(SIGHUP, sigTerm);
 | 
				
			||||||
    signal(SIGUSR1, sigUser1);
 | 
					    signal(SIGUSR1, sigUser1);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    CppTimer timer;
 | 
					    while(!stop)
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    while(true)
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        XNextEvent(xinstance.display, &event);
 | 
					        XNextEvent(xinstance.display, &event);
 | 
				
			||||||
        if (event.type == DestroyNotify) break;
 | 
					        if (event.type == DestroyNotify) break;
 | 
				
			||||||
        else if (event.type == PropertyNotify && event.xproperty.atom == xinstance.atoms.netActiveWindow)
 | 
					        if (event.type == PropertyNotify && event.xproperty.atom == xinstance.atoms.netActiveWindow)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Window wid = xinstance.getActiveWindow();
 | 
					            Window wid = xinstance.getActiveWindow();
 | 
				
			||||||
            if(wid != 0 && wid != prevWindow)
 | 
					            if(wid != 0 && wid != prevWindow)
 | 
				
			||||||
| 
						 | 
					@ -266,12 +223,6 @@ int main(int argc, char* argv[])
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if(process.getName() == applicationNames[i] &&  wid != 0 && process.getPid() > 0 && process.getName() != "") 
 | 
					                        if(process.getName() == applicationNames[i] &&  wid != 0 && process.getPid() > 0 && process.getName() != "") 
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            if(process == qeuedToStop)
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                std::cout<<"Canceling stop of wid: "+std::to_string(wid)+" pid: "+std::to_string(process.getPid())+" name: "+process.getName()<<'\n';
 | 
					 | 
				
			||||||
                                timer.stop();
 | 
					 | 
				
			||||||
                                qeuedToStop = Process();
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            process.resume(true);
 | 
					                            process.resume(true);
 | 
				
			||||||
                            stoppedProcs.remove(process);
 | 
					                            stoppedProcs.remove(process);
 | 
				
			||||||
                            std::cout<<"Resumeing wid: "+std::to_string(wid)+" pid: "+std::to_string(process.getPid())+" name: "+process.getName()<<'\n';
 | 
					                            std::cout<<"Resumeing wid: "+std::to_string(wid)+" pid: "+std::to_string(process.getPid())+" name: "+process.getName()<<'\n';
 | 
				
			||||||
| 
						 | 
					@ -281,28 +232,27 @@ int main(int argc, char* argv[])
 | 
				
			||||||
                                prevProcess.getName() != "" && 
 | 
					                                prevProcess.getName() != "" && 
 | 
				
			||||||
                                prevProcess.getPid() > 0) 
 | 
					                                prevProcess.getPid() > 0) 
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            timer.block();
 | 
					                            sleep(5); //give the process some time to close its other windows
 | 
				
			||||||
                            std::cout<<"Will stop pid: "<<prevProcess.getPid()<<" name: "<<prevProcess.getName()<<'\n';
 | 
					                            bool hasTopLevelWindow = false;
 | 
				
			||||||
                            qeuedToStop = prevProcess;
 | 
					                            std::vector<Window> tlWindows = xinstance.getTopLevelWindows();
 | 
				
			||||||
                            timer.start(config.timeoutSecs, 0, sendEventProcStop, CppTimer::ONESHOT);
 | 
					                            for(auto& window : tlWindows) 
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                if(xinstance.getPid(window) == prevProcess.getPid()) hasTopLevelWindow = true;
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            if(hasTopLevelWindow)
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                prevProcess.stop(true);
 | 
				
			||||||
 | 
					                                std::cout<<"Stoping wid: "+std::to_string(prevWindow)+" pid: "+std::to_string(prevProcess.getPid())+" name: "+prevProcess.getName()<<'\n';
 | 
				
			||||||
                                stoppedProcs.push_back(prevProcess);
 | 
					                                stoppedProcs.push_back(prevProcess);
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
 | 
					                            else  std::cout<<"not Stoping wid: "+std::to_string(prevWindow)+" pid: "+std::to_string(prevProcess.getPid())+" name: "+prevProcess.getName()<<'\n';
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                prevProcess = process;
 | 
					                prevProcess = process;
 | 
				
			||||||
                prevWindow = wid;
 | 
					                prevWindow = wid;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else if (event.type == ClientMessage && ((XClientMessageEvent*)&event)->window == intraCommesWindow)
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XClientMessageEvent* clientEvent = (XClientMessageEvent*)&event;
 | 
					 | 
				
			||||||
            if (clientEvent->data.b[0] == STOP_EVENT) break;
 | 
					 | 
				
			||||||
            if (clientEvent->data.b[0] == PROC_STOP_EVENT)
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
               stopProcess(qeuedToStop, &xinstance);
 | 
					 | 
				
			||||||
               qeuedToStop = Process();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    for(auto& process : stoppedProcs) process.resume(true);
 | 
					    for(auto& process : stoppedProcs) process.resume(true);
 | 
				
			||||||
    std::filesystem::remove(confDir+"pidfile");
 | 
					    std::filesystem::remove(confDir+"pidfile");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -42,15 +42,12 @@ pid_t Process::getPid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Process::stop(bool children)
 | 
					void Process::stop(bool children)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if(pid_ > 0)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    kill(pid_, SIGSTOP);
 | 
					    kill(pid_, SIGSTOP);
 | 
				
			||||||
    if(children)
 | 
					    if(children)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::vector<Process> children = getChildren();
 | 
					        std::vector<Process> children = getChildren();
 | 
				
			||||||
        for(auto& child : children) child.stop(true);
 | 
					        for(auto& child : children) child.stop(true);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Process::resume(bool children)
 | 
					void Process::resume(bool children)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,6 @@ unsigned long XInstance::readProparty(Window wid, Atom atom, unsigned char** pro
 | 
				
			||||||
    unsigned long nitems;
 | 
					    unsigned long nitems;
 | 
				
			||||||
    unsigned long bytes_after;
 | 
					    unsigned long bytes_after;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
    XLockDisplay(display);
 | 
					 | 
				
			||||||
    int ret = XGetWindowProperty(
 | 
					    int ret = XGetWindowProperty(
 | 
				
			||||||
        display, 
 | 
					        display, 
 | 
				
			||||||
        wid, 
 | 
					        wid, 
 | 
				
			||||||
| 
						 | 
					@ -43,7 +42,6 @@ unsigned long XInstance::readProparty(Window wid, Atom atom, unsigned char** pro
 | 
				
			||||||
        &nitems, 
 | 
					        &nitems, 
 | 
				
			||||||
        &bytes_after,
 | 
					        &bytes_after,
 | 
				
			||||||
        prop);
 | 
					        prop);
 | 
				
			||||||
    XUnlockDisplay(display);
 | 
					 | 
				
			||||||
    if (ret != Success) 
 | 
					    if (ret != Success) 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::cerr<<"XGetWindowProperty failed!\n";
 | 
					        std::cerr<<"XGetWindowProperty failed!\n";
 | 
				
			||||||
| 
						 | 
					@ -54,12 +52,11 @@ unsigned long XInstance::readProparty(Window wid, Atom atom, unsigned char** pro
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
Atom XInstance::getAtom(const std::string& atomName)
 | 
					Atom XInstance::getAtom(const std::string& atomName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return XInternAtom(display, atomName.c_str(), true);;
 | 
					    return XInternAtom(display, atomName.c_str(), true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
bool XInstance::open(const std::string& xDisplayName)
 | 
					bool XInstance::open(const std::string& xDisplayName)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    XInitThreads();
 | 
					 | 
				
			||||||
    display = XOpenDisplay(xDisplayName.c_str());
 | 
					    display = XOpenDisplay(xDisplayName.c_str());
 | 
				
			||||||
    if (display == nullptr) 
 | 
					    if (display == nullptr) 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
| 
						 | 
					@ -99,9 +96,7 @@ Window XInstance::getActiveWindow()
 | 
				
			||||||
    unsigned long length = readProparty(RootWindow(display, screen), atoms.netActiveWindow, &data, &format);
 | 
					    unsigned long length = readProparty(RootWindow(display, screen), atoms.netActiveWindow, &data, &format);
 | 
				
			||||||
    Window wid = 0;
 | 
					    Window wid = 0;
 | 
				
			||||||
    if(format == 32 && length == 4)  wid = *reinterpret_cast<Window*>(data);
 | 
					    if(format == 32 && length == 4)  wid = *reinterpret_cast<Window*>(data);
 | 
				
			||||||
    XLockDisplay(display);
 | 
					 | 
				
			||||||
    XFree(data);
 | 
					    XFree(data);
 | 
				
			||||||
    XUnlockDisplay(display);
 | 
					 | 
				
			||||||
    return wid;
 | 
					    return wid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -111,46 +106,33 @@ std::vector<Window> XInstance::getTopLevelWindows()
 | 
				
			||||||
    Window parent_return;
 | 
					    Window parent_return;
 | 
				
			||||||
    Window* windows = nullptr;
 | 
					    Window* windows = nullptr;
 | 
				
			||||||
    unsigned int nwindows;
 | 
					    unsigned int nwindows;
 | 
				
			||||||
    XLockDisplay(display);
 | 
					 | 
				
			||||||
    XQueryTree(display, RootWindow(display, screen), &root_return, &parent_return, &windows, &nwindows);
 | 
					    XQueryTree(display, RootWindow(display, screen), &root_return, &parent_return, &windows, &nwindows);
 | 
				
			||||||
    XUnlockDisplay(display);
 | 
					    
 | 
				
			||||||
    std::vector<Window> out;
 | 
					    std::vector<Window> out;
 | 
				
			||||||
    out.reserve(nwindows);
 | 
					    out.reserve(nwindows);
 | 
				
			||||||
    for(unsigned int i = 0; i < nwindows; ++i)
 | 
					    for(unsigned int i; i < nwindows; ++i)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        out.push_back(windows[i]);
 | 
					        out.push_back(windows[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    XLockDisplay(display);
 | 
					 | 
				
			||||||
    if(windows != nullptr) XFree(windows); 
 | 
					 | 
				
			||||||
    XUnlockDisplay(display);
 | 
					 | 
				
			||||||
    return out;
 | 
					    return out;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void XInstance::flush()
 | 
					void XInstance::flush()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    XLockDisplay(display);
 | 
					 | 
				
			||||||
     XFlush(display);
 | 
					     XFlush(display);
 | 
				
			||||||
    XUnlockDisplay(display);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pid_t XInstance::getPid(Window wid)
 | 
					pid_t XInstance::getPid(Window wid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    defaultHandler = XSetErrorHandler(ignoreErrorHandler);
 | 
					 | 
				
			||||||
    XTextProperty xWidHostNameTextProperty;
 | 
					    XTextProperty xWidHostNameTextProperty;
 | 
				
			||||||
    bool ret;
 | 
					    bool ret;
 | 
				
			||||||
    XLockDisplay(display);
 | 
					 | 
				
			||||||
    ret = XGetTextProperty(display, wid, &xWidHostNameTextProperty, atoms.wmClientMachine); 
 | 
					    ret = XGetTextProperty(display, wid, &xWidHostNameTextProperty, atoms.wmClientMachine); 
 | 
				
			||||||
    XUnlockDisplay(display);
 | 
					 | 
				
			||||||
    if (!ret) 
 | 
					    if (!ret) 
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        char errorString[1024];
 | 
					        char errorString[1024];
 | 
				
			||||||
        XGetErrorText(display, ret, errorString, 1024);
 | 
					        XGetErrorText(display, ret, errorString, 1024);
 | 
				
			||||||
        debug("XGetWMClientMachine failed! " + std::string(errorString));
 | 
					        debug("XGetWMClientMachine failed! " + std::string(errorString));
 | 
				
			||||||
        if(!ignoreClientMachine) 
 | 
					        if(!ignoreClientMachine) return -1;
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XSetErrorHandler(defaultHandler);
 | 
					 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    char** xWidHostNameStringList = nullptr;
 | 
					    char** xWidHostNameStringList = nullptr;
 | 
				
			||||||
    int nStrings;
 | 
					    int nStrings;
 | 
				
			||||||
| 
						 | 
					@ -160,21 +142,13 @@ pid_t XInstance::getPid(Window wid)
 | 
				
			||||||
        char errorString[1024];
 | 
					        char errorString[1024];
 | 
				
			||||||
        XGetErrorText(display, ret, errorString, 1024);
 | 
					        XGetErrorText(display, ret, errorString, 1024);
 | 
				
			||||||
        debug("XTextPropertyToStringList failed! " + std::string(errorString));
 | 
					        debug("XTextPropertyToStringList failed! " + std::string(errorString));
 | 
				
			||||||
        if(!ignoreClientMachine) 
 | 
					        if(!ignoreClientMachine) return -1;
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XSetErrorHandler(defaultHandler);
 | 
					 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    char hostName[HOST_NAME_MAX+1]={0};
 | 
					    char hostName[HOST_NAME_MAX+1]={0};
 | 
				
			||||||
    if(gethostname(hostName, HOST_NAME_MAX) != 0)
 | 
					    if(gethostname(hostName, HOST_NAME_MAX) != 0)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        debug("Can't get host name");
 | 
					        debug("Can't get host name");
 | 
				
			||||||
        if(!ignoreClientMachine) 
 | 
					        if(!ignoreClientMachine) return -1;
 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
            XSetErrorHandler(defaultHandler);
 | 
					 | 
				
			||||||
            return -1;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    pid_t pid = -1;
 | 
					    pid_t pid = -1;
 | 
				
			||||||
    if(ignoreClientMachine || strcmp(hostName, xWidHostNameStringList[0]) == 0 )
 | 
					    if(ignoreClientMachine || strcmp(hostName, xWidHostNameStringList[0]) == 0 )
 | 
				
			||||||
| 
						 | 
					@ -191,20 +165,10 @@ pid_t XInstance::getPid(Window wid)
 | 
				
			||||||
        debug("Window "+std::to_string(wid)+" is a remote window");
 | 
					        debug("Window "+std::to_string(wid)+" is a remote window");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if(xWidHostNameStringList) XFreeStringList(xWidHostNameStringList);
 | 
					    if(xWidHostNameStringList) XFreeStringList(xWidHostNameStringList);
 | 
				
			||||||
    XSetErrorHandler(defaultHandler);
 | 
					 | 
				
			||||||
    return pid;
 | 
					    return pid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int XInstance::ignoreErrorHandler(Display* display, XErrorEvent* xerror)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    std::cerr<<"Ignoring: error code"<<xerror->error_code<<" request code "<<xerror->request_code<<'\n'
 | 
					 | 
				
			||||||
             <<"this error most likely occured because of a bug in your WM\n";
 | 
					 | 
				
			||||||
    return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 XInstance::~XInstance()
 | 
					 XInstance::~XInstance()
 | 
				
			||||||
 {
 | 
					 {
 | 
				
			||||||
     XLockDisplay(display);
 | 
					 | 
				
			||||||
     if(display) XCloseDisplay(display);
 | 
					     if(display) XCloseDisplay(display);
 | 
				
			||||||
     XUnlockDisplay(display);
 | 
					 | 
				
			||||||
 }
 | 
					 }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,6 @@ class XInstance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    inline static XErrorHandler defaultHandler;
 | 
					 | 
				
			||||||
    static constexpr unsigned long MAX_BYTES = 1048576;
 | 
					    static constexpr unsigned long MAX_BYTES = 1048576;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    inline static bool ignoreClientMachine = false;
 | 
					    inline static bool ignoreClientMachine = false;
 | 
				
			||||||
| 
						 | 
					@ -47,7 +46,6 @@ private:
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    unsigned long readProparty(Window wid, Atom atom, unsigned char** prop, int* format);
 | 
					    unsigned long readProparty(Window wid, Atom atom, unsigned char** prop, int* format);
 | 
				
			||||||
    Atom getAtom(const std::string& atomName);
 | 
					    Atom getAtom(const std::string& atomName);
 | 
				
			||||||
    static int ignoreErrorHandler(Display* display, XErrorEvent* xerror);
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue