forked from quickshell/quickshell
		
	io/process: mask the "QProcess destroyed for running process" warn
This commit is contained in:
		
							parent
							
								
									f681e2016f
								
							
						
					
					
						commit
						86591f122d
					
				
					 5 changed files with 88 additions and 3 deletions
				
			
		| 
						 | 
					@ -27,6 +27,21 @@ Process::Process(QObject* parent): QObject(parent) {
 | 
				
			||||||
	);
 | 
						);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Process::~Process() {
 | 
				
			||||||
 | 
						if (this->process != nullptr && this->process->processId() != 0) {
 | 
				
			||||||
 | 
							// Deleting after the process finishes hides the process destroyed warning in logs
 | 
				
			||||||
 | 
							QObject::connect(this->process, &QProcess::finished, [p = this->process] { delete p; });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->process->setParent(nullptr);
 | 
				
			||||||
 | 
							this->process->kill();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Process::onPostReload() {
 | 
				
			||||||
 | 
						this->postReload = true;
 | 
				
			||||||
 | 
						this->startProcessIfReady();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool Process::isRunning() const { return this->process != nullptr; }
 | 
					bool Process::isRunning() const { return this->process != nullptr; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Process::setRunning(bool running) {
 | 
					void Process::setRunning(bool running) {
 | 
				
			||||||
| 
						 | 
					@ -165,7 +180,9 @@ void Process::setStdinEnabled(bool enabled) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Process::startProcessIfReady() {
 | 
					void Process::startProcessIfReady() {
 | 
				
			||||||
	if (this->process != nullptr || !this->targetRunning || this->mCommand.isEmpty()) return;
 | 
						if (this->process != nullptr || !this->postReload || !this->targetRunning
 | 
				
			||||||
 | 
						    || this->mCommand.isEmpty())
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
	this->targetRunning = false;
 | 
						this->targetRunning = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto& cmd = this->mCommand.first();
 | 
						auto& cmd = this->mCommand.first();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,7 @@
 | 
				
			||||||
#include <qvariant.h>
 | 
					#include <qvariant.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../core/doc.hpp"
 | 
					#include "../core/doc.hpp"
 | 
				
			||||||
 | 
					#include "../core/reload.hpp"
 | 
				
			||||||
#include "datastream.hpp"
 | 
					#include "datastream.hpp"
 | 
				
			||||||
#include "processcore.hpp"
 | 
					#include "processcore.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +31,9 @@
 | 
				
			||||||
///   }
 | 
					///   }
 | 
				
			||||||
/// }
 | 
					/// }
 | 
				
			||||||
/// ```
 | 
					/// ```
 | 
				
			||||||
class Process: public QObject {
 | 
					class Process
 | 
				
			||||||
 | 
					    : public QObject
 | 
				
			||||||
 | 
					    , public PostReloadHook {
 | 
				
			||||||
	Q_OBJECT;
 | 
						Q_OBJECT;
 | 
				
			||||||
	// clang-format off
 | 
						// clang-format off
 | 
				
			||||||
	/// If the process is currently running. Defaults to false.
 | 
						/// If the process is currently running. Defaults to false.
 | 
				
			||||||
| 
						 | 
					@ -136,6 +139,10 @@ class Process: public QObject {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	explicit Process(QObject* parent = nullptr);
 | 
						explicit Process(QObject* parent = nullptr);
 | 
				
			||||||
 | 
						~Process() override;
 | 
				
			||||||
 | 
						Q_DISABLE_COPY_MOVE(Process);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void onPostReload() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// MUST be before exec(ctx) or the other will be called with a default constructed obj.
 | 
						// MUST be before exec(ctx) or the other will be called with a default constructed obj.
 | 
				
			||||||
	QSDOC_HIDE Q_INVOKABLE void exec(QList<QString> command);
 | 
						QSDOC_HIDE Q_INVOKABLE void exec(QList<QString> command);
 | 
				
			||||||
| 
						 | 
					@ -251,4 +258,5 @@ private:
 | 
				
			||||||
	bool targetRunning = false;
 | 
						bool targetRunning = false;
 | 
				
			||||||
	bool mStdinEnabled = false;
 | 
						bool mStdinEnabled = false;
 | 
				
			||||||
	bool mClearEnvironment = false;
 | 
						bool mClearEnvironment = false;
 | 
				
			||||||
 | 
						bool postReload = false;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,8 @@
 | 
				
			||||||
function (qs_test name)
 | 
					function (qs_test name)
 | 
				
			||||||
	add_executable(${name} ${ARGN})
 | 
						add_executable(${name} ${ARGN})
 | 
				
			||||||
	target_link_libraries(${name} PRIVATE Qt::Quick Qt::Network Qt::Test quickshell-io)
 | 
						target_link_libraries(${name} PRIVATE Qt::Quick Qt::Network Qt::Test quickshell-io quickshell-core quickshell-window quickshell-ui)
 | 
				
			||||||
	add_test(NAME ${name} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND $<TARGET_FILE:${name}>)
 | 
						add_test(NAME ${name} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" COMMAND $<TARGET_FILE:${name}>)
 | 
				
			||||||
endfunction()
 | 
					endfunction()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
qs_test(datastream datastream.cpp ../datastream.cpp)
 | 
					qs_test(datastream datastream.cpp ../datastream.cpp)
 | 
				
			||||||
 | 
					qs_test(process process.cpp ../process.cpp ../datastream.cpp ../processcore.cpp)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										47
									
								
								src/io/test/process.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/io/test/process.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,47 @@
 | 
				
			||||||
 | 
					#include "process.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qlist.h>
 | 
				
			||||||
 | 
					#include <qsignalspy.h>
 | 
				
			||||||
 | 
					#include <qtest.h>
 | 
				
			||||||
 | 
					#include <qtestcase.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "../process.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestProcess::startAfterReload() {
 | 
				
			||||||
 | 
						auto process = Process();
 | 
				
			||||||
 | 
						auto startedSpy = QSignalSpy(&process, &Process::started);
 | 
				
			||||||
 | 
						auto exitedSpy = QSignalSpy(&process, &Process::exited);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						process.setCommand({"true"});
 | 
				
			||||||
 | 
						process.setRunning(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(!process.isRunning());
 | 
				
			||||||
 | 
						QCOMPARE(startedSpy.count(), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						process.onPostReload();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(process.isRunning());
 | 
				
			||||||
 | 
						QVERIFY(startedSpy.wait(100));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void TestProcess::testExec() {
 | 
				
			||||||
 | 
						auto process = Process();
 | 
				
			||||||
 | 
						auto startedSpy = QSignalSpy(&process, &Process::started);
 | 
				
			||||||
 | 
						auto exitedSpy = QSignalSpy(&process, &Process::exited);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						process.onPostReload();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						process.setCommand({"sleep", "30"});
 | 
				
			||||||
 | 
						process.setRunning(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(process.isRunning());
 | 
				
			||||||
 | 
						QVERIFY(startedSpy.wait(100));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						process.exec({"true"});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QVERIFY(exitedSpy.wait(100));
 | 
				
			||||||
 | 
						QVERIFY(startedSpy.wait(100));
 | 
				
			||||||
 | 
						QVERIFY(process.isRunning());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QTEST_MAIN(TestProcess);
 | 
				
			||||||
							
								
								
									
										12
									
								
								src/io/test/process.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/io/test/process.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TestProcess: public QObject {
 | 
				
			||||||
 | 
						Q_OBJECT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private slots:
 | 
				
			||||||
 | 
						static void startAfterReload();
 | 
				
			||||||
 | 
						static void testExec();
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue