Page 1 of 2

copy information_url to clipboard

Posted: Sat Mar 05, 2016 9:19 am
by Astrobe
OXZ manifests have an information_url field which shows in the package's description. But it's quite tedious to copy it manually in the browser URL bar, especially for the forum URLs. I suggest that this field could be automatically copied to the system's clipboard.

Re: copy information_url to clipboard

Posted: Sat Mar 05, 2016 1:09 pm
by Norby
Good idea imho.

Until then find it in the OXZ list with ctrl+f and click on the title. This page show the same than the expansion manager.

Re: copy information_url to clipboard

Posted: Sat Mar 05, 2016 2:04 pm
by another_commander
Good news and bad news. The bad news is that the SDL version we are using does not have functionality for clipboard handling, so we will need a platform-specific solution to implement this.

The good news is that, at least on Windows, this appears to be very easy. I have already a working piece of code that copies the url of the oxz automatically to clipboard, once we hit the oxz info page. For documentation purposes, below is the snippet that does it. Insert this code in OOOXZManager.m, - (void) processShowInfoKey method, just below the part that reads
// infoURL
[gui setText:[NSString stringWithFormat:DESC(@"oolite-oxzmanager-infopage-infourl-@"),
[manifest oo_stringForKey:kOOManifestInformationURL]]
forRow:25 align:GUI_ALIGN_LEFT];

Code: Select all

#if OOLITE_WINDOWS		
			// copy url info text to clipboard automatically once we are in the oxz info page
			const char *clipboardText = [[manifest oo_stringForKey:kOOManifestInformationURL]
													cStringUsingEncoding:NSUTF8StringEncoding];
			const size_t clipboardTextLength = strlen(clipboardText) + 1;
			HGLOBAL clipboardMem =  GlobalAlloc(GMEM_MOVEABLE, clipboardTextLength);
			memcpy(GlobalLock(clipboardMem), clipboardText, clipboardTextLength);
			GlobalUnlock(clipboardMem);
			OpenClipboard(0);
			EmptyClipboard();
			SetClipboardData(CF_TEXT, clipboardMem);
			CloseClipboard();		
#endif
It would be preferrable if we could have a solution at least also for Linux before pushing this into the mainline. And for Mac too, hopefully, if we could get a Mac maintainer.

Re: copy information_url to clipboard

Posted: Sun Mar 06, 2016 8:16 pm
by another_commander
... but on the other hand, having a requested feature ready and not doing anything about it seems counter-productive at the very least. The feature will be in for tomorrow's nightly for Windows and hopefully implementations for the other two ports will follow soon. Please test as you see fit and let us know in case of problems. The url info link is copied automatically to clipboard once you go to the OXZ info page (highlight the OXZ in the list and press 'i').

Re: copy information_url to clipboard

Posted: Mon Mar 07, 2016 12:14 pm
by Astrobe
I know neither objective-C nor SDL. But if SDL "leaks" X11 windows handlers I can probably find some C code to paste to the clipboard using Xlib in Linux. It may portable to OSX.

Re: copy information_url to clipboard

Posted: Mon Mar 07, 2016 1:12 pm
by another_commander
In case it helps, this is how SDL2 does it for Mac:
SDL2 Cocoa_setClipboardText function
and for Linux:
SDL2 X11_setClipboardText function
It may be a good starting point.

Re: copy information_url to clipboard

Posted: Mon Mar 07, 2016 7:35 pm
by Cody
Works fine, Admiral.

Re: copy information_url to clipboard

Posted: Mon Mar 07, 2016 9:33 pm
by Svengali
Yep, looks good here as well.

Re: copy information_url to clipboard

Posted: Tue Mar 08, 2016 6:38 pm
by kanthoney
I'm completely failing at the Linux version. I tried using X11 cut buffers, which didn't do anything. Then I wondered if GNUstep had a clipboard. And it does - NSPasteboard! Unfortunately the compiler borked on that, so I guess it's in the GUI part of GNUstep that we don't use. Finally I tried blagging the code out of SDL 2. I got it to compile but no dice.

I might have to take the drastic step of reading up on X11. Ewwwwww.

Re: copy information_url to clipboard

Posted: Tue Mar 08, 2016 9:00 pm
by another_commander
kanthoney wrote:
Then I wondered if GNUstep had a clipboard. And it does - NSPasteboard! Unfortunately the compiler borked on that, so I guess it's in the GUI part of GNUstep that we don't use.
This was the first thing I tried as well, hoping for some standard Cocoa portability but, as you say, NSPasteboard is part of GNUstep GUI, so no dice - we'll just have to do one implementation for each OS, I guess - ouch.

Re: copy information_url to clipboard

Posted: Tue Mar 08, 2016 9:52 pm
by Cody
kanthoney wrote:
I might have to take the drastic step of reading up on X11.
Whatever you deem best, Commodore!

Re: copy information_url to clipboard

Posted: Tue Mar 08, 2016 10:21 pm
by kanthoney
Oh, it looks like a lot of fun. Apparently you don't just copy some text to a clipboard and forget about it - that would be far too easy. Instead, the window tells the X server that it's got some text available. If another window wants to paste the text, it asks the X server which window has the current selection, and then passes a message to that window asking for the text. So you've got to implement a message handling system to deal with it.

Sigh. I might be some time!

Re: copy information_url to clipboard

Posted: Wed Mar 09, 2016 12:16 pm
by Astrobe
Below is an extract of the source code of an old cross-platform GUI toolkit. Ignore the app_* functions which are part of the library.
The full source is there: http://enchantia.com/software/graphapp/ ... index.html

Code: Select all

/*
 *  To store text into the clipboard, we just use the
 *  XStoreBytes function, which stores the data onto
 *  XA_CUT_BUFFER0 in the root window of screen 0 of
 *  the X server. To retrieve it, we use XFetchBytes.
 *  This is an old method of storing data, used by
 *  xterm and some other older applications.
 *
 *  More modern X programs use selections, which are
 *  inter-process communications mediated by the
 *  SelectionRequest, SelectionNotify and SelectionClear
 *  X events. We too handle these events in the event
 *  loop, but we cheat. If someone asks our application
 *  what text we currently have selected, we just grab
 *  whatever text is in XA_CUT_BUFFER0 and send that
 *  (even if some other program has since overwritten it).
 *  This produces the desired effect of always pasting
 *  whatever text is in the system clipboard. It also
 *  gives interoperability with xterm.
 *
 *  Other applications usually only send their data
 *  when they see a SelectionRequest. Storing it instead
 *  into a system buffer, at the instant the user selects
 *  "Copy", removes some complications, because none of
 *  our controls need to handle SelectionRequests. Only
 *  the event loop need handle these data transfer requests.
 */

int app_set_clipboard_text(App *app, const char *text)
{
	int n, size, result;
	Window *win;
	char *latin1, *utf8;

	/* Check if we can store an ISO Latin 1 string instead:
	 * This would not be needed if all applications stored
	 * UTF-8 strings into the clipboard, but many still use
	 * ISO Latin 1 strings, so interoperability is important.
	 * Here, we just squash the text into an ISO Latin 1 string
	 * and then unpack it back into a UTF-8 string, and check
	 * if that's the same as the original string. If so, paste
	 * the string as ISO Latin 1 instead.
	 */

	latin1 = NULL;
	n = size = strlen(text);
	if (app_utf8_is_ascii(text, n)) /* ASCII always works */
		;
	else if (app_utf8_is_latin1(text, n)) { /* valid candidate */
		latin1 = app_utf8_to_latin1(text, &n);
		if (latin1 != NULL) {
			utf8 = app_correct_utf8(latin1, &n);
			if ((n == size) && (!memcmp(text, utf8, n))) {
				/* success, text->latin1->utf8==text */
				text = latin1;	/* swap to new string */
				size = strlen(text);
				if (utf8 != latin1)
					app_free(utf8);
			}
			else {
				/* failure, so paste original string */
				if ((utf8 != NULL) && (utf8 != latin1))
					app_free(utf8);
				app_free(latin1);
				latin1 = NULL;
			}
		}
	}

	/* ensure we have the appropriate X Server atom strings */

	app_ensure_atoms(app);

	/* use the old method first */

	XStoreBytes(app_extra(app)->display, text, size);

	/* also use the modern method: owning the selection */

	win = NULL;
	for (n=0; n < app->num_windows; n++) {
		win = app->windows[n];
		if (win_extra(win)->xid)
			break;
	}
	if (! win) {
		if (latin1)
			app_free(latin1);
		return 0; /* no window to use */
	}

	result = 1;

	XSetSelectionOwner(app_extra(app)->display, app_extra(app)->xclip,
		win_extra(win)->xid, app_extra(app)->last_event_time);
	if (XGetSelectionOwner(app_extra(app)->display,
		app_extra(app)->xclip) != win_extra(win)->xid)
		result = 0; /* couldn't obtain selection ownership */

	XSetSelectionOwner(app_extra(app)->display, XA_PRIMARY,
		win_extra(win)->xid, app_extra(app)->last_event_time);
	if (XGetSelectionOwner(app_extra(app)->display,
		XA_PRIMARY) != win_extra(win)->xid)
		result = 0; /* couldn't obtain selection ownership */

	if (latin1)
		app_free(latin1);
	return result;
}

Re: copy information_url to clipboard

Posted: Tue Mar 09, 2021 7:25 pm
by RockDoctor
Would it maybe simpler to just create a file in the default log file location, dump the text into it, then leave the user to fiddle with that. Certainly not as elegant as a proper handling of the clipboard, but better than nothing. The system already handles log files, so the necessary tools exist.
Or is it working now, but not in the Linux version?

Re: copy information_url to clipboard

Posted: Tue Mar 09, 2021 7:59 pm
by another_commander
It is working, but only for Windows and Mac. Linux, not yet.