瀏覽代碼

Handling empty clipboard without waiting for nothing.

David Piuva 2 年之前
父節點
當前提交
359b87d35a

+ 2 - 2
Source/DFPSR/api/guiAPI.cpp

@@ -508,9 +508,9 @@ String dsr::window_getTitle(Window& window) {
 	MUST_EXIST(window, window_getTitle);
 	return window->backend->getTitle();
 }
-String window_loadFromClipboard(Window& window, int64_t timeoutInMilliseconds) {
+String window_loadFromClipboard(Window& window, double timeoutInSeconds) {
 	MUST_EXIST(window, window_loadFromClipboard);
-	return window->backend->loadFromClipboard(timeoutInMilliseconds);
+	return window->backend->loadFromClipboard(timeoutInSeconds);
 }
 
 void window_saveToClipboard(Window& window, const ReadableString &text) {

+ 1 - 1
Source/DFPSR/api/guiAPI.h

@@ -61,7 +61,7 @@ namespace dsr {
 	//   because a key combination commonly associated with pasting text was pressed before the request was made.
 	// Returns content from an internal or extenal clipboard.
 	//   The internal clipboard within the application is used when the system specific backend has not implemented clipboard access.
-	String window_loadFromClipboard(Window& window, int64_t timeoutInMilliseconds);
+	String window_loadFromClipboard(Window& window, double timeoutInSeconds);
 	// Stores the text argument to an internal or extenal clipboard.
 	//   The internal clipboard within the application is used when the system specific backend has not implemented clipboard access.
 	void window_saveToClipboard(Window& window, const ReadableString &text);

+ 1 - 1
Source/DFPSR/gui/BackendWindow.cpp

@@ -28,7 +28,7 @@ using namespace dsr;
 // Used when access to the external clipboard is not implemented.
 static String backupClipboard;
 
-ReadableString BackendWindow::loadFromClipboard(int64_t timeoutInMilliseconds) {
+ReadableString BackendWindow::loadFromClipboard(double timeoutInSeconds) {
 	sendWarning(U"loadFromClipboard is not implemented! Simulating clipboard using a variable within the same application.");
 	return backupClipboard;
 }

+ 1 - 1
Source/DFPSR/gui/BackendWindow.h

@@ -91,7 +91,7 @@ public:
 	//   If both are implemented, the system's clipboard should be accessed.
 	//   Partial implementations with only loadFromClipboard or saveToClipboard are not allowed.
 	// Load from the clipboard, waiting at most timeoutInMilliseconds milliseconds.
-	virtual ReadableString loadFromClipboard(int64_t timeoutInMilliseconds = 500);
+	virtual ReadableString loadFromClipboard(double timeoutInSeconds = 0.5);
 	// Save text to the clipboard.
 	virtual void saveToClipboard(const ReadableString &text);
 public:

+ 16 - 19
Source/windowManagers/X11Window.cpp

@@ -107,7 +107,7 @@ public:
 	void listContentInClipboard();
 	void initializeClipboard();
 	void terminateClipboard();		
-	dsr::ReadableString loadFromClipboard(int64_t timeoutInMilliseconds);
+	dsr::ReadableString loadFromClipboard(double timeoutInSeconds);
 	void saveToClipboard(const dsr::ReadableString &text);
 };
 
@@ -122,24 +122,18 @@ void X11Window::terminateClipboard() {
 	// TODO: Send ownership to the clipboard to allow pasting after terminating the program it was copied from.
 }
 
-dsr::ReadableString X11Window::loadFromClipboard(int64_t timeoutInMilliseconds) {
-	// TODO: Can the old request be aborted if it takes too long?
-	if (!this->loadingFromClipboard) {
-		// Request text to paste and wait some time for an application to respond.
-		// TODO: How can old content be ignored after a timeout if the time is too short?
-		XConvertSelection(this->display, this->clipboardAtom, this->targetsAtom, this->clipboardAtom, this->window, CurrentTime);
-		this->loadingFromClipboard = true;
-		// TODO: Implement timeout without drifting time.
-		int64_t time = 0;
-		while (this->loadingFromClipboard && time < timeoutInMilliseconds) {
-			this->prefetchEvents();
-			dsr::time_sleepSeconds(0.001);
-			time++;
-		}
-		return this->textFromClipboard;
-	} else {
-		return U"";
+dsr::ReadableString X11Window::loadFromClipboard(double timeoutInSeconds) {
+	// The timeout needs to be at least 10 milliseconds to give it a fair chance.
+	if (timeoutInSeconds < 0.01) timeoutInSeconds = 0.01;
+	// Request text to paste and wait some time for an application to respond.
+	XConvertSelection(this->display, this->clipboardAtom, this->targetsAtom, this->clipboardAtom, this->window, CurrentTime);
+	this->loadingFromClipboard = true;
+	double deadline = dsr::time_getSeconds() + timeoutInSeconds;
+	while (this->loadingFromClipboard && dsr::time_getSeconds() < deadline) {
+		this->prefetchEvents();
+		dsr::time_sleepSeconds(0.001);
 	}
+	return this->loadingFromClipboard ? U"" : this->textFromClipboard;
 }
 
 void X11Window::listContentInClipboard() {
@@ -687,7 +681,10 @@ void X11Window::prefetchEvents() {
 					// You previously requested access to a program's clipboard content and here it is giving the data to you.
 					// Based on: https://handmade.network/forums/articles/t/8544-implementing_copy_paste_in_x11
 					XSelectionEvent selection = currentEvent.xselection;
-					if (selection.property != None) {
+					if (selection.property == None) {
+						// If we got an empty notification, we can avoid waiting for a timeout.
+						this->loadingFromClipboard = false;
+					} else {
 						Atom actualType;
 						int actualFormat;
 						unsigned long bytesAfter;