forked from quickshell/quickshell
		
	feat(process): add ways to close stdio channels
This commit is contained in:
		
							parent
							
								
									3f0bd20852
								
							
						
					
					
						commit
						ffa9d02d48
					
				
					 2 changed files with 42 additions and 3 deletions
				
			
		| 
						 | 
					@ -41,6 +41,12 @@ void Process::setStdoutParser(DataStreamParser* parser) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->mStdoutParser != nullptr) {
 | 
						if (this->mStdoutParser != nullptr) {
 | 
				
			||||||
		QObject::disconnect(this->mStdoutParser, nullptr, this, nullptr);
 | 
							QObject::disconnect(this->mStdoutParser, nullptr, this, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this->process != nullptr) {
 | 
				
			||||||
 | 
								this->process->closeReadChannel(QProcess::StandardOutput);
 | 
				
			||||||
 | 
								this->process->readAllStandardOutput(); // discard
 | 
				
			||||||
 | 
								this->stdoutBuffer.clear();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->mStdoutParser = parser;
 | 
						this->mStdoutParser = parser;
 | 
				
			||||||
| 
						 | 
					@ -68,6 +74,12 @@ void Process::setStderrParser(DataStreamParser* parser) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (this->mStderrParser != nullptr) {
 | 
						if (this->mStderrParser != nullptr) {
 | 
				
			||||||
		QObject::disconnect(this->mStderrParser, nullptr, this, nullptr);
 | 
							QObject::disconnect(this->mStderrParser, nullptr, this, nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this->process != nullptr) {
 | 
				
			||||||
 | 
								this->process->closeReadChannel(QProcess::StandardError);
 | 
				
			||||||
 | 
								this->process->readAllStandardError(); // discard
 | 
				
			||||||
 | 
								this->stderrBuffer.clear();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->mStderrParser = parser;
 | 
						this->mStderrParser = parser;
 | 
				
			||||||
| 
						 | 
					@ -88,6 +100,19 @@ void Process::onStderrParserDestroyed() {
 | 
				
			||||||
	emit this->stderrParserChanged();
 | 
						emit this->stderrParserChanged();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool Process::stdinEnabled() const { return this->mStdinEnabled; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void Process::setStdinEnabled(bool enabled) {
 | 
				
			||||||
 | 
						if (enabled == this->mStdinEnabled) return;
 | 
				
			||||||
 | 
						this->mStdinEnabled = enabled;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!enabled && this->process != nullptr) {
 | 
				
			||||||
 | 
							this->process->closeWriteChannel();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						emit this->stdinEnabledChanged();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void Process::startProcessIfReady() {
 | 
					void Process::startProcessIfReady() {
 | 
				
			||||||
	if (this->process != nullptr || !this->targetRunning || this->mCommand.isEmpty()) return;
 | 
						if (this->process != nullptr || !this->targetRunning || this->mCommand.isEmpty()) return;
 | 
				
			||||||
	this->targetRunning = false;
 | 
						this->targetRunning = false;
 | 
				
			||||||
| 
						 | 
					@ -108,6 +133,10 @@ void Process::startProcessIfReady() {
 | 
				
			||||||
	this->stdoutBuffer.clear();
 | 
						this->stdoutBuffer.clear();
 | 
				
			||||||
	this->stderrBuffer.clear();
 | 
						this->stderrBuffer.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (this->mStdoutParser == nullptr) this->process->closeReadChannel(QProcess::StandardOutput);
 | 
				
			||||||
 | 
						if (this->mStderrParser == nullptr) this->process->closeReadChannel(QProcess::StandardError);
 | 
				
			||||||
 | 
						if (!this->mStdinEnabled) this->process->closeWriteChannel();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	this->process->start(cmd, args);
 | 
						this->process->start(cmd, args);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,10 +51,15 @@ class Process: public QObject {
 | 
				
			||||||
	/// > [!INFO] You can use `["sh", "-c", <your command>]` to execute your command with
 | 
						/// > [!INFO] You can use `["sh", "-c", <your command>]` to execute your command with
 | 
				
			||||||
	/// > the system shell.
 | 
						/// > the system shell.
 | 
				
			||||||
	Q_PROPERTY(QList<QString> command READ command WRITE setCommand NOTIFY commandChanged);
 | 
						Q_PROPERTY(QList<QString> command READ command WRITE setCommand NOTIFY commandChanged);
 | 
				
			||||||
	/// The parser for STDOUT. If the parser is null no data will be read.
 | 
						/// The parser for stdout. If the parser is null the process's stdout channel will be closed
 | 
				
			||||||
 | 
						/// and no further data will be read, even if a new parser is attached.
 | 
				
			||||||
	Q_PROPERTY(DataStreamParser* stdout READ stdoutParser WRITE setStdoutParser NOTIFY stdoutParserChanged);
 | 
						Q_PROPERTY(DataStreamParser* stdout READ stdoutParser WRITE setStdoutParser NOTIFY stdoutParserChanged);
 | 
				
			||||||
	/// The parser for STDERR. If the parser is null no data will be read.
 | 
						/// The parser for stderr. If the parser is null the process's stdout channel will be closed
 | 
				
			||||||
 | 
						/// and no further data will be read, even if a new parser is attached.
 | 
				
			||||||
	Q_PROPERTY(DataStreamParser* stderr READ stderrParser WRITE setStderrParser NOTIFY stderrParserChanged);
 | 
						Q_PROPERTY(DataStreamParser* stderr READ stderrParser WRITE setStderrParser NOTIFY stderrParserChanged);
 | 
				
			||||||
 | 
						/// If stdin is enabled. Defaults to true. If this property is set to false the process's stdin channel
 | 
				
			||||||
 | 
						/// will be closed and [write](#func.write) will do nothing, even if set back to true.
 | 
				
			||||||
 | 
						Q_PROPERTY(bool stdinEnabled READ stdinEnabled WRITE setStdinEnabled NOTIFY stdinEnabledChanged);
 | 
				
			||||||
	// clang-format on
 | 
						// clang-format on
 | 
				
			||||||
	QML_ELEMENT;
 | 
						QML_ELEMENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -64,7 +69,7 @@ public:
 | 
				
			||||||
	/// Sends a signal to the process if `running` is true, otherwise does nothing.
 | 
						/// Sends a signal to the process if `running` is true, otherwise does nothing.
 | 
				
			||||||
	Q_INVOKABLE void signal(qint32 signal);
 | 
						Q_INVOKABLE void signal(qint32 signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/// Writes to the process's STDIN. Does nothing if `running` is false.
 | 
						/// Writes to the process's stdin. Does nothing if `running` is false.
 | 
				
			||||||
	Q_INVOKABLE void write(const QString& data);
 | 
						Q_INVOKABLE void write(const QString& data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] bool isRunning() const;
 | 
						[[nodiscard]] bool isRunning() const;
 | 
				
			||||||
| 
						 | 
					@ -81,6 +86,9 @@ public:
 | 
				
			||||||
	[[nodiscard]] DataStreamParser* stderrParser() const;
 | 
						[[nodiscard]] DataStreamParser* stderrParser() const;
 | 
				
			||||||
	void setStderrParser(DataStreamParser* parser);
 | 
						void setStderrParser(DataStreamParser* parser);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						[[nodiscard]] bool stdinEnabled() const;
 | 
				
			||||||
 | 
						void setStdinEnabled(bool enabled);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					signals:
 | 
				
			||||||
	void started();
 | 
						void started();
 | 
				
			||||||
	void exited(qint32 exitCode, QProcess::ExitStatus exitStatus);
 | 
						void exited(qint32 exitCode, QProcess::ExitStatus exitStatus);
 | 
				
			||||||
| 
						 | 
					@ -90,6 +98,7 @@ signals:
 | 
				
			||||||
	void commandChanged();
 | 
						void commandChanged();
 | 
				
			||||||
	void stdoutParserChanged();
 | 
						void stdoutParserChanged();
 | 
				
			||||||
	void stderrParserChanged();
 | 
						void stderrParserChanged();
 | 
				
			||||||
 | 
						void stdinEnabledChanged();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private slots:
 | 
					private slots:
 | 
				
			||||||
	void onStarted();
 | 
						void onStarted();
 | 
				
			||||||
| 
						 | 
					@ -111,4 +120,5 @@ private:
 | 
				
			||||||
	QByteArray stderrBuffer;
 | 
						QByteArray stderrBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool targetRunning = false;
 | 
						bool targetRunning = false;
 | 
				
			||||||
 | 
						bool mStdinEnabled = false;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue