From 8fe794b3122bff2349bb5d2987bb5545fe20c64c Mon Sep 17 00:00:00 2001 From: Pascal Nowack Date: Mon, 9 Aug 2021 11:48:19 +0200 Subject: [PATCH] winpr/clipboard: Omit last line ending for gnome-copied-files Every uri in the x-special/gnome-copied-files mime type is separated by a '\n' char. However, not every line ends with '\n'. The last line MUST not include the new line character. --- winpr/libwinpr/clipboard/posix.c | 39 ++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/winpr/libwinpr/clipboard/posix.c b/winpr/libwinpr/clipboard/posix.c index da228d55a..fdbdf2357 100644 --- a/winpr/libwinpr/clipboard/posix.c +++ b/winpr/libwinpr/clipboard/posix.c @@ -609,7 +609,7 @@ static char* stop_at_special_chars(const char* str) static void* convert_filedescriptors_to_file_list(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize, const char* header, const char* lineprefix, - const char* lineending) + const char* lineending, BOOL skip_last_lineending) { const FILEDESCRIPTORW* descriptors; UINT32 nrDescriptors = 0; @@ -661,7 +661,10 @@ static void* convert_filedescriptors_to_file_list(wClipboard* clipboard, UINT32 NULL, NULL); /* # (1 char) -> %23 (3 chars) , the first char is replaced inplace */ alloc += count_special_chars(descriptors[x].cFileName) * 2; - alloc += decoration_len; + if (skip_last_lineending && x == count - 1) + alloc += decoration_len - lineending_len; + else + alloc += decoration_len; } } @@ -730,7 +733,11 @@ static void* convert_filedescriptors_to_file_list(wClipboard* clipboard, UINT32 previous_at = stop_at + 1; } - rc = _snprintf(&dst[pos], alloc - pos, "%s%s", previous_at, lineending); + if (skip_last_lineending && x == count - 1) + rc = _snprintf(&dst[pos], alloc - pos, "%s", previous_at); + else + rc = _snprintf(&dst[pos], alloc - pos, "%s%s", previous_at, lineending); + if (rc < 0) { free(dst); @@ -753,7 +760,7 @@ static void* convert_filedescriptors_to_uri_list(wClipboard* clipboard, UINT32 f const void* data, UINT32* pSize) { return convert_filedescriptors_to_file_list(clipboard, formatId, data, pSize, "", - "file:", "\r\n"); + "file:", "\r\n", FALSE); } /* Prepend header of common gnome format to file list*/ @@ -761,23 +768,31 @@ static void* convert_filedescriptors_to_gnome_copied_files(wClipboard* clipboard const void* data, UINT32* pSize) { return convert_filedescriptors_to_file_list(clipboard, formatId, data, pSize, "copy\n", - "file://", "\n"); + "file://", "\n", TRUE); } /* Prepend header of nautilus based filemanager's format to file list*/ static void* convert_filedescriptors_to_nautilus_clipboard(wClipboard* clipboard, UINT32 formatId, const void* data, UINT32* pSize) { - /* Here Nemo (and Caja) have different behavior. They encounter error with the last \n . but + /* Here Nemo (and Caja) have different behavior. They encounter error with the last \n . but nautilus needs it. So user have to skip Nemo's error dialog to continue. Caja has different TARGET , so it's easy to fix. see convert_filedescriptors_to_mate_copied_files - */ + + The text based "x-special/nautilus-clipboard" type was introduced with GNOME 3.30 and + was necessary for the desktop icons extension, as gnome-shell at that time only + supported text based mime types for gnome extensions. With GNOME 3.38, gnome-shell got + support for non-text based mime types for gnome extensions. With GNOME 40, nautilus reverted + the mime type change to "x-special/gnome-copied-files" and removed support for the text based + mime type. So, in the near future, change this behaviour in favor for Nemo and Caja. + */ /* see nautilus/src/nautilus-clipboard.c:convert_selection_data_to_str_list see nemo/libnemo-private/nemo-clipboard.c:nemo_clipboard_get_uri_list_from_selection_data */ - return convert_filedescriptors_to_file_list( - clipboard, formatId, data, pSize, "x-special/nautilus-clipboard\ncopy\n", "file://", "\n"); + return convert_filedescriptors_to_file_list(clipboard, formatId, data, pSize, + "x-special/nautilus-clipboard\ncopy\n", "file://", + "\n", FALSE); } static void* convert_filedescriptors_to_mate_copied_files(wClipboard* clipboard, UINT32 formatId, @@ -785,7 +800,7 @@ static void* convert_filedescriptors_to_mate_copied_files(wClipboard* clipboard, { char* pDstData = (char*)convert_filedescriptors_to_file_list(clipboard, formatId, data, pSize, - "copy\n", "file://", "\n"); + "copy\n", "file://", "\n", FALSE); if (!pDstData) { return pDstData; @@ -812,13 +827,13 @@ static BOOL register_file_formats_and_synthesizers(wClipboard* clipboard) local_file_format_id = ClipboardRegisterFormat(clipboard, "text/uri-list"); /* - 1. Gnome Nautilus based file manager: + 1. Gnome Nautilus based file manager (Nautilus only with version >= 3.30 AND < 40): TARGET: UTF8_STRING format: x-special/nautilus-clipboard\copy\n\file://path\n\0 2. Kde Dolpin: TARGET: text/uri-list format: file:path\n\0 - 3. Gnome others (Unity/XFCE): + 3. Gnome and others (Unity/XFCE/Nautilus < 3.30/Nautilus >= 40): TARGET: x-special/gnome-copied-files format: copy\nfile://path\n\0 4. Mate Caja: