Lazarus

Programming => Operating Systems => Linux => Topic started by: Hartmut on August 01, 2019, 10:38:22 am

Title: Clipboard (with plain text) does not work as expected on Linux (SOLVED)
Post by: Hartmut on August 01, 2019, 10:38:22 am
I have the following console program:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses Interfaces, // needs package LCL
  4.      clipbrd;    // needs package LCLbase and unit Interfaces
  5.  
  6. begin
  7. writeln('"', Clipboard.AsText, '"');
  8. Clipboard.AsText:='Hello world';
  9. writeln('"', Clipboard.AsText, '"');
  10. end.  
On Windows 7 (32 bit) it works as expected:
 - it shows the text which was in the clipboard before the program was started
 - then it shows "Hello World"
 - after this the clipboard contains "Hello World"
 
On Linux (Ubuntu 18.04 64 bit) I have the following behaviour:
 - it shows "" instead of the text which was in the clipboard before the program was started
 - then it shows "Hello World"
 - after this the contents of the clipboard have not been changed
 
An example:
 - I select "some text" in the Lazarus text editor and copy it to the clipboard
 - after starting my program it shows:
   ""
   "Hello world"
 - after this I paste the clipboard into the Lazarus text editor and get again "some text"
 
I use Lazarus 1.8.4 with FPC 3.0.4. What am I doing wrong?
I attached my little project. Thanks in advance.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: dbannon on August 01, 2019, 10:48:58 am
Hmm, your problem sounds a bit like -

https://wiki.freepascal.org/Clipboard#How_to_fix_empty_GTK2_clipboard_on_exit

When you use lazarus to copy something into the clipboard, do you then exit Lazarus or just switch to another window ?

Davo
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 01, 2019, 11:08:27 am
When you use lazarus to copy something into the clipboard, do you then exit Lazarus or just switch to another window ?
I did not exit Lazarus, just switched to a console window and back. But it makes no difference, if I exit Lazarus and start it again after running my program from a console window, the result is the same.

Your link sounds very interesting. I will work through it and report then. But as far as I saw, it would only solve 1 of my 2 problems: passing something from my program to the clipboard, not vice versa.

Thanks for your help.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 01, 2019, 11:43:32 am
Unfortunately unit 'fix_gtk_clipboard' did not help in my case. There is no difference in the behaviour of my program with this unit. Now it is:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses Interfaces, // needs package LCL
  4.      fix_gtk_clipboard,
  5.      clipbrd;    // needs package LCLbase and unit Interfaces
  6.  
  7. begin
  8. writeln('"', Clipboard.AsText, '"');
  9. Clipboard.AsText:='Hello world';
  10. writeln('"', Clipboard.AsText, '"');
  11. end.
       
In the link from dbannon there is a second code example dealing with procedure TMainForm.FormClose(). If I understand the describing text correctly, this does not matter in my case, because I have only a console program without a Form. Correct?
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: dbannon on August 02, 2019, 02:02:46 am
Hmm, it does not matter where you call the extra code, in a GUI based app, convienant to call in formClose() but you can call it yourself.

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. uses gtk2, gdk2,
  3.   Interfaces, // needs package LCL
  4.      clipbrd;    // needs package LCLbase and unit Interfaces
  5.  
  6. procedure MungeClipboard;
  7. var
  8.   c: PGtkClipboard;
  9.   t: string;
  10. begin
  11.   c := gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
  12.   t := Clipboard.AsText;
  13.   gtk_clipboard_set_text(c, PChar(t), Length(t));
  14.   gtk_clipboard_store(c);
  15. end;
  16.  
  17. begin
  18. writeln('"', Clipboard.AsText, '"');
  19. Clipboard.AsText:='Hello world';
  20. writeln('"', Clipboard.AsText, '"');
  21. MungeClipboard;
  22. end.            

But that only solves half your problem, now, when you app exits, the clipboard does hold "Hello World" but I am afraid it does not correctly pick up what was in the clipboard before your app starts.

I don't have that issue in my GUI app, will have to look through code and see if there is something happening I don't remember. I am currently travelling through central Australia, internet access is very flucky, so am not a reliable help.....

Davo
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 02, 2019, 05:49:03 pm
Thank you Davo for your new program. Enjoy your trip to Australia. Unfortunately procedure MungeClipboard() did not help in my case. There is no difference in the behaviour of my program with it.

Then I changed your program into:
Code: Pascal  [Select][+][-]
  1. begin
  2. Clipboard.AsText:='Hello world';
  3. readln;
  4. MungeClipboard;
  5. end.
When the program waits for the readln, the clipboard does not contain "Hello world", but contains that, what was in the clipboard, before my program started. So 'Clipboard.AsText' seems not to work in this console program...

I use Lazarus 1.8.4 with FPC 3.0.4 on Ubuntu 18.04.02 (64 bit). As a replacement I installed the KDE-Plasma desktop with "sudo apt install kubuntu-desktop". This is 11 month ago. I never had any problems with the clipboard in none of my Linux programs (gedit, firefox, thunderbird, lazarus, terminal console and many more). Can KDE-Plasma desktop be the reason for this problem?

Can somebody else verify this? Do others have the same clipboard problems in a console program (or not)? Thanks for your help.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Thaddy on August 02, 2019, 05:58:05 pm
Sorry never use KDE. But see if my previous posting helps, or wait for xiniman to reply: he is perfectly capable to interpret what I mean.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 02, 2019, 06:31:23 pm
I created a small GUI program (attached) to test 'Clipboard.AsText' there:
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  9.  Clipbrd;
  10.  
  11. type
  12.  TForm1 = class(TForm)
  13.   Button1: TButton;
  14.   procedure Button1Click(Sender: TObject);
  15.  private
  16.  public
  17.  end;
  18.  
  19. var Form1: TForm1;
  20.  
  21. implementation
  22.  
  23. {$R *.lfm}
  24.  
  25. procedure TForm1.Button1Click(Sender: TObject);
  26.    begin
  27.    Clipboard.AsText:='Hello world';
  28.    end;
  29.  
  30. end.  
It works perfectly on Windows and Ubuntu. As soon as you press the button, the clipboard contains "Hello world" and keeps it after the program has terminated. So the problem seems not to be my KDE-Plasma Desktop, but my small console program.

What must I change that it works? Thanks for any help.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Thaddy on August 02, 2019, 06:37:23 pm
It is not the matter that it works. It works. But eventually you run out of resources, because memory is leaking somewhere..
That is the bug!

Repeat your code 1000 times and look at your memory use.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 02, 2019, 07:32:16 pm
Hello Thaddy, I modified my program to:
Code: Pascal  [Select][+][-]
  1. begin
  2. for n:=1 to 1000 do
  3.    Clipboard.AsText:='Hello world';
  4. readln;
  5. end.
When the program waits for readln, on Windows the memory usage is 1072 kb. On Linux I had to do some research (I'm a beginner on Linux) how to check the used memory. KSysGuard system monitor shows 2704 KB memory plus 20 MB common memory.

top -p <PID> shows:
Code: Text  [Select][+][-]
  1.   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     ZEIT+ BEFEHL                
  2.  2024 hg6       20   0  172588  23180  20476 S   0,0  0,3   0:00.02 test4      
   
For me 0.3% MEM does not look like a resources problem. What do you say?
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: wp on August 02, 2019, 07:36:31 pm
So the problem seems not to be my KDE-Plasma Desktop, but my small console program.
Could it be that the clipboard system is not correctly initialized for a console program on Linux? Unit clipbrd belongs to the LCL, and a console program normally does not require the LCL.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Thaddy on August 02, 2019, 07:53:09 pm
Did you make sure you did release trhe clipboard in a finally section?
pseudo code
Code: Pascal  [Select][+][-]
  1. var:Clipboard:TClipBoard;
  2. begin
  3.    ClipBoard := TClipBoard.create(nil);
  4.   try
  5.      // work with the clipboard
  6.   finally
  7.     Clipboard.free;
  8.   end;
  9. end.

In a console program you usually program like that. Dunno if it helps.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 02, 2019, 07:54:18 pm
Could it be that the clipboard system is not correctly initialized for a console program on Linux?
I can imagine that very well...

Unit clipbrd belongs to the LCL, and a console program normally does not require the LCL.
Does this mean, a console program on Linux cannot access the clipboard? That would be a pity. On Windows it works perfectly...

Thanks for your help.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Thaddy on August 02, 2019, 07:58:43 pm
Try my tip. Our posts crossed. If it does not work I have another possible solution.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 02, 2019, 08:26:56 pm
Hello Thaddy, your suggestion sounds a very good idea. But unfortunately I have no change in the behaviour. This is my program:
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses Interfaces, // needs package LCL
  4.      clipbrd,    // needs package LCLbase and unit Interfaces
  5.      LCLType;    // for 'ctPrimarySelection'
  6.  
  7. var Clipboard: TClipBoard;
  8.  
  9. begin
  10. ClipBoard:=TClipBoard.create(ctPrimarySelection);
  11. try
  12.    Clipboard.AsText:='Hello world';
  13. finally
  14.    Clipboard.free;
  15. end;
  16. readln;
  17. end.

I had to change your TClipBoard.create() command because it did not compile. After some research I tried ctPrimarySelection, ctSecondarySelection and ctClipboard. But the behaviour is always the same, the content of the clipboard is not changed to "Hello world". You said you have more ideas? Thanks for your help.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: dbannon on August 03, 2019, 02:39:34 am
Did you make sure you did release trhe clipboard in a finally section?

I don't have access to any coding right now but pretty sure including clipbrd both creates and frees the clipboard.  Not from memory, the Primary* one though.

Sounds to me, like WP suggested, that as clipBrd, sort of belongs in LCL its dependent on some initialization that happens in a real GUI app. Strange than including LCL is not enough ....

That sample I posted back up this thread did set the system clipboard to whatever the app set it to (ie, solved half your problem).   I'm using Lazarus Fixes, 2.0.3, I doubt thats an issue but maybe ?  Other wise, I don't see how you got a different answer to me. Your use of 1.8.4 is probably not a great idea....

Davo

Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Thaddy on August 03, 2019, 08:05:18 am
Just to be sure: It can be that the clipboard is already created in an initialization section and released in a finalization section.
You can also install a different clipboard manager and see if that helps (not the component, but the underlying X-server.
See https://www.cyberciti.biz/faq/xclip-linux-insert-files-command-output-intoclipboard/
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 03, 2019, 03:49:40 pm
Hello Davo and Thaddy, thanks for your replies. First I followed Thaddy's link in this way:
 - installed the different clipboard manager by "sudo apt-get install xclip"
 - run my program from reply #14
 - displayed the clipboard contents with "xclip -o"
 - unfortunately there was no difference then before: when my program was waiting for the readln and when my program had finished, both the clipboard did not contain "Hello world", but contains that, what was in the clipboard, before my program started :-(

Then I expanded my program by calling procedure MungeClipboard() from reply #4 after "Clipboard.AsText:='Hello world'", but no difference.

For me the problem seems to be, that the LCL, which is used by unit Clipbrd, needs more initialization, which is missing in a console program on Linux (on Windows it works perfectly). Is this a bug? What do you think?
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: dbannon on August 04, 2019, 01:37:29 am
Yes Hartmut, sounds like a bug to me !

I just tried you trick of using xclip, after running my version of your app, xclip -o says clipboard is empty, pressing ,shift-ctrl-v gives me a "hello world".   How about that ?

That says to me its something to do with how the data in the clipboard is being described. The clipboard can hold data in a range of formats, an app asks the clipboard for a list of those formats and picks one, if it cannot find a format it likes, it spits out nothing.   This comment applies to the 'post app' phenomena, not why we see nothing in there as your app starts up.

At startup, we have to assume LCL is doing something to get the clipboard contents and make it available, your console version is not doing that and that is, apparently, a bug.  Might take a bit of work finding out what that something is :-(

I have some code somewhere I used to debug another aspect of clipboard on linux, when I get a chance I'll see if I still have it. Useful to describe the clipboard contents.

Davo
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: lucamar on August 04, 2019, 02:26:40 am
I just tried you trick of using xclip, after running my version of your app, xclip -o says clipboard is empty, pressing ,shift-ctrl-v gives me a "hello world".   How about that ?

There is no "Linux clipboard"; in Linux he clipboard is a function of the Window Manager and is available only to GUI (X) applications.

When you press Shift+Ctrl+V you're invo¡king a, let's call it, method of the terminal emulation application which, in turn, sents the appropiate"keys" to the console app to "paste" the clipboard contents. Conversely, when you press Shift+Ctrl+C the terminal emulator copies from its "screen buffer" to the clipboard. Think of it like a Lazarus program handling TProcess's in/out pipes.

IIRC, it's possible to connect a terminal application running under an X session to the session's clipboard, though I don't remember how. What I do kind of remember is that the process was a rather convoluted one and not apt for the faint of heart. :)

A googling for "console clipboard Linux" should turn back some answers. Or look into the source of xclip to see how it works (incidentally, the fact that this utility exists should tell you something ;)).
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: dbannon on August 04, 2019, 11:33:40 am
... There is no "Linux clipboard"; in Linux he clipboard is a function of the Window Manager and is available only to GUI (X) applications.

OK lucamar thats technically true. But our friend, and most desktop linux users are using a terminal session under some Desktop and most expect std copy and paste to work. Most terminal apps have a menu item Edit->paste etc. Personally, I prefer the traditional primary selection and paste model but I am an traditionalist !   I agree that a unix box booted to only command line would not be expected to support copy and paste but it would not support xclip either.

Hmm.... my version of vim does not support the 'system' clipboard. Thats surprises me but as I said, I use primary selection. But I am pretty sure I remember having used a version of vi that would paste the system (ie GTK) clipboard. So a fpc app that does not 'import' (for lack of a better word) the Desktop clipboard has a bug IMHO.

Hartmut - its looking like yours is a hard problem !  Should you consider making it a gui app that does not actually show its main window ?  As Lucamar pointed out, thats probably not going to work in a pure terminal session, even if you ssh into a box for example. But it will work in any likely terminal emulator session.

Davo

Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Abelisto on August 04, 2019, 12:12:02 pm
@Hartmut

You need to move the call of MungeClipboard just after clipboard assigning to initialize GTK clipboard by assigned value immediately:
Code: Pascal  [Select][+][-]
  1. ...
  2. Clipboard.AsText:='Hello world';
  3. MungeClipboard;
  4. ...
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 04, 2019, 06:33:57 pm
I just tried you trick of using xclip, after running my version of your app, xclip -o says clipboard is empty, pressing ,shift-ctrl-v gives me a "hello world".   How about that ?
Sounds strange. I always tested with having some pure text in the clipboard, before I started my program, to see if it is changed or not.

That says to me its something to do with how the data in the clipboard is being described. The clipboard can hold data in a range of formats, an app asks the clipboard for a list of those formats and picks one, if it cannot find a format it likes, it spits out nothing.   
To avoid that problems, I always had some pure text in the clipboard, before I started my program.

There is no "Linux clipboard"; in Linux he clipboard is a function of the Window Manager and is available only to GUI (X) applications.
How does 'xclip' access the clipboard? For me xclip does not look like a GUI application, or am I wrong?

A googling for "console clipboard Linux" should turn back some answers.
I tried and got lots of "matches", but the only one I found, how to do it in Free Pascal, was:

Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2.  
  3. uses Interfaces, Forms, Clipbrd;    
  4.  
  5. begin
  6. Application.Initialize;
  7. Clipboard.AsText:='Hello world';
  8. end.  

But unfortunately it did not work (it made no difference).

Should you consider making it a gui app that does not actually show its main window? 
Hmm, sounds interesting, but GUI programs normally are big, and I wanted to use the clipboard in some small console applications...

@Abelisto: I tested your suggestion, unfortunately it did not work. Does it work on your installation? If yes, please write your OS-Version and Lazarus/FPC Version.

So my main questions are:
1) Can anybody else access the clipboard (pure text) in a console program on a Linux system? Which version of Linux / Lazarus / FPC do you use?
2) Is it a bug, that it does not work? (Davo tends to yes)
3) Is there a workaround to add the missing "initialization" manually?

Thanks to all for your help!
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: dbannon on August 05, 2019, 02:40:53 am
[gui app] Hmm, sounds interesting, but GUI programs normally are big, and I wanted to use the clipboard in some small console applications...

Well, once striped of debugging, a basic gui app is about 4meg. And grows quite slowly as you add things to it.

While I do agree its wrong you 'have' to do this, its worth noting that the the clipbrd unit is an LCL unit not a fpc unit.  That might well be key to the argument ....

Davo
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 06, 2019, 05:22:16 pm
Hello Davo, congratulations to your 600th posting. You are right, a minimal GUI application would be a solution, if I don't find a better one. I have an idea for that from your MungeClipboard() procedure. I opened a new topic for that in https://forum.lazarus.freepascal.org/index.php/topic,46308.0.html

Thanks a lot to all who have helped me!
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Abelisto on August 06, 2019, 07:33:17 pm
Note that there is no such thing as "clipboard" in Linux console (classic) applications. Some applications supports so-called "buffers" (vim, tmux etc) but it is application-wide, not system-wide feature. Windows-like clipboard was introduced in X Window System (as I remember) so it is the part of the GUI extension of the classic (console-based) *nix. And it is supported by terminal emulators, not by console applications itself.

So be ready for problems with "clipboard" if you will to use some remote access (SSH for example) ore even virtual terminals (Ctrl+Alt+Fn) on your local device.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 06, 2019, 08:02:20 pm
Hello Abelisto, thanks for your reply. In general I don't need remote access (SSH for example) or virtual terminals (Ctrl+Alt+Fn). But if I understand you correctly, then accessing the clipboard in a console program is not possible on Linux. I already opened another topic for this (see link in reply #24). If this brings no success, I will create a minimal GUI application, even though I wanted a smaller program.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Abelisto on August 07, 2019, 09:15:01 am
Hope that it is helpful.

There is xsel utility allows to manipulate by x-server clipboards (in terminal type man xsel)

The simple example how to save some text in the x clipboard:

Code: Bash  [Select][+][-]
  1. echo -n "Hello World!" | xsel --clipboard

After that you able to paste "Hello World!" everywhere in your x-based OS.

Surely you can to explore the xsel source code to learn more about x window clipboards :)
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Thaddy on August 07, 2019, 09:21:40 am
... There is no "Linux clipboard"; in Linux he clipboard is a function of the Window Manager and is available only to GUI (X) applications.

OK lucamar thats technically true.

Well. No. It is actually very easy to have a text-based clipboard. A small Daemon and a file. Loads of example code.
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: Hartmut on August 07, 2019, 08:23:18 pm
Thanks to Abelisto and Thaddy for your replies.

@Thaddy: This sounds very interesting. I tried to find something but with the very small information you provided I was not successful.

@Abelisto: 'xsel' seems to be a good solution for my current program, because this must not run on foreign computers, where xsel is not installed.

Here are some informations about xsel:
 - it's not part of Ubuntu, you must install it via "sudo apt install xsel"
 - it can process German special characters like Ä Ö Ü ä ö ü ß
 - it can process LineFeeds via e.g. echo -n -e "Hello \n World" | xsel -b
 - if your text can contain characters like " $ \ (and probably some more) and you want them to pass without changes, you must escape them by "\"
 - to send the clipboard to STDOUT you can use command "xsel -b"
Probably tool 'xclip' (see link in Thaddy's reply #16) can do the same as 'xsel'.

Puhh, I have a solution :-)) Thanks a lot to all who helped me!
Title: Re: Clipboard (with plain text) does not work as expected on Linux
Post by: trev on August 08, 2019, 12:11:42 pm
So be ready for problems with "clipboard" if you will to use some remote access (SSH for example) ore even virtual terminals (Ctrl+Alt+Fn) on your local device.

Curiously, there are no such problems in FreeBSD with remote access (eg SSH) or virtual terminals. I have copy and pasted between virtual terminals locally (just confirmed again that it works in case I was imagining it). I can also copy and paste between a local system console (FreeBSD) and a remote system xterm (macOS) when logged in via SSH.

On FreeBSD it looks like it's a feature of the mouse daemon: [man moused yields] "The moused utility and the console driver work together to support mouse operation in the text console and user programs."

Maybe something more to pursue on Linux...
TinyPortal © 2005-2018