Recent

Author Topic: How to not wipe out the graphical clipboard at program end? (gtk2 + KDE)  (Read 9137 times)

Hartmut

  • Hero Member
  • *****
  • Posts: 893
I hope I found the correct subforum. My program saves some graphic file into the clipboard:
Code: Pascal  [Select][+][-]
  1. procedure TForm2.Button1Click(Sender: TObject);
  2.    var Picture1: TPicture;
  3.    begin
  4.    Picture1:=TPicture.Create;
  5.    Picture1.LoadFromFile('demo.bmp');
  6.    Clipboard.Assign(Picture1);
  7.    Picture1.Free;
  8.    end;

This works, but when my program terminates, the clipboard content is wiped out. I want to have the graphical content inside the clipboard also after my program had terminated.

In another subforum jeremiah posted this code for a similar purpose, but this works only for text strings, not for graphical content:

Code: Pascal  [Select][+][-]
  1. // Usually when your GTK2 app exits, it's clipboard becomes empty. Bad for usual user.
  2. // This unit is a dirty fix, add it to "uses" somewhere.
  3. // this must be first in uses clause {$ifdef LCLGTK2} fix_gtk_clipboard, {$endif}
  4.  
  5. unit fix_gtk_clipboard;
  6.  
  7. {$mode objfpc}{$H+}
  8.  
  9. interface
  10.  
  11. uses
  12.   gtk2, gdk2, Clipbrd;
  13.  
  14. implementation
  15.  
  16. var
  17.   c: PGtkClipboard;
  18.   t: string;
  19.  
  20. finalization
  21. // writeln('fix_gtk_clipboard');
  22.   c := gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
  23.   t := Clipboard.AsText;
  24.   gtk_clipboard_set_text(c, PChar(t), Length(t));
  25.   gtk_clipboard_store(c);
  26. end.

He wrote for it:
Quote
Also note that on Cinnamon (perhaps other GTK DTs too, no idea) when your application closes the clipboard is wiped so if you want it to remain search the source in Lazarus for "gtk_clipboard_set_image" (I think this is correct) then make a routine to put it back. The GTK text unit is provided.

Is there someone who can improve unit 'fix_gtk_clipboard' so that the *graphical* content inside the clipboard is preserved?

I'm on Linux Ubuntu 22.04 with Lazarus 3.4.0 gtk2. Thanks in advance.
« Last Edit: December 25, 2024, 07:02:11 pm by Hartmut »

Bart

  • Hero Member
  • *****
  • Posts: 5538
    • Bart en Mariska's Webstek
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #1 on: December 17, 2024, 04:50:22 pm »
There are utilities on *nix that keep the clipboard persistent.
The behaviour you see is the normal behaviour of GTK.

Bart

MarkMLl

  • Hero Member
  • *****
  • Posts: 8334
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #2 on: December 17, 2024, 05:12:50 pm »
I think "it's the way X11 works"... something to do with ICE if memory serves correctly.

Running on Debian 12's KDE, I've just compiled a program I'd got to hand for gtk2 and qt5: both work the same in that if they copy a graphic to the clipboard it's accessible to Gimp while they run but not afterwards. Perhaps most significant is that KDE's own toolbar "Clipboard Contents" doesn't show the graphical image at any time, only text from earlier in the day... same behaviour if I copy something from Gimp.

So it's basically down to the desktop environment (AKA Window Manager etc.) which quite possibly doesn't know about non-text formats (as distinct from needing to be told explicitly that something's going onto the clipboard which needs to be saved).

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Logitech, TopSpeed & FTL Modula-2 on bare metal (Z80, '286 protected mode).
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Hartmut

  • Hero Member
  • *****
  • Posts: 893
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #3 on: December 18, 2024, 04:09:43 pm »
There are utilities on *nix that keep the clipboard persistent.
The behaviour you see is the normal behaviour of GTK.
Bart

Thank you Bart for your reply. If I install an utility for that purpose on my computer, then this would not help other users of my program. So I would prefer a solution, which is inside my program - if this is possible - like I understood jeremiah.



Thanks MarkMLl for this infos.



Meanwhile I saw that above post from jeremiah was taken from the wiki in https://wiki.freepascal.org/Clipboard#How_to_fix_empty_GTK2_clipboard_on_exit

I started to follow his hint
Quote
so if you want it [the clipboard] to remain search the source in Lazarus for "gtk_clipboard_set_image" (I think this is correct) then make a routine to put it back. The GTK text unit is provided.

and with some guessing and fantasy I created this procedure (which does not work):

Code: Pascal  [Select][+][-]
  1. uses gtk2, gdk2, gdk2pixbuf;
  2.  
  3. procedure keep_graphical_clipboard;
  4.    var c: PGtkClipboard;
  5.        pixbuf: PGdkPixbuf; {this is a normal pointer}
  6.    begin
  7.    writeln('keep_graphical_clipboard');
  8.    c := gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
  9.    pixbuf:=gtk_clipboard_wait_for_image(c);            
  10.    if assigned(pixbuf) then writeln('assigned'); // 'assigned' is shown
  11.    gtk_clipboard_set_image(c,pixbuf);
  12.    gtk_clipboard_store(c);
  13.    end;

It uses gtk_clipboard_set_image() as told by jeremiah. With gtk_clipboard_wait_for_image() I am very unsure, but I didn't find something better and used the only thing I could find which returned type 'PGdkPixbuf'.

My question is: is this attempt only nonsense or is there someone who is able to modify this code so that it works? Thanks in advance.

jeremiah

  • New Member
  • *
  • Posts: 18
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #4 on: December 19, 2024, 06:57:19 am »
I kept this with the main form hidden and set clipboard in main form close event. From form 2 button click you can set path to file. There is probably various ways to accomplish this even using a "fix_gtk_pix_clipboard.pas" but I leave all that up to you, all the "fun" stuff haha.  ;)

Hope it gets you going...

Hartmut

  • Hero Member
  • *****
  • Posts: 893
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #5 on: December 19, 2024, 03:19:52 pm »
Thank you jeremiah for that demo. Unfortunately it does not work:

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  2. var
  3.  c: PGtkClipboard;
  4.  pixbuf: PGdkPixbuf; {this is a normal pointer}
  5. begin
  6.  c := gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
  7.  pixbuf := gdk_pixbuf_new_from_file(PChar(UnitClip.aFile), nil);
  8.  
  9.  if Assigned(pixbuf) then
  10.   begin
  11.    writeln('assigned');
  12.    gtk_clipboard_set_image(c, pixbuf);
  13.    gtk_clipboard_store(c);
  14.   end;
  15. end;

I proceeded this way:
 - started the program
 - pressed Button 'Clipboard'
 - exited the program via the "X" in the upper right corner
 - the message 'assigned' was displayed
 - checked the clipboard via GIMP, but the clipboard was empty...
 - checked that variable 'c' is not nil

Versions: Linux Ubuntu 22.04 with Lazarus 3.4.0 gtk2.

If your demo would work there would be a disadvantage for me, because this way you need a file to read from. In my real project I only have a 'TPicture', which had been loaded from a file some time before and then can be changed in different ways. So there exists no file to load from, only the current contents of a 'TPicture'. Is this possible?

But better would be a common solution, which reads the *current* graphical content from the clipboard and stores this into a 'pixbuf' (analog to how it is done in unit 'fix_gtk_clipboard' for text contents), because that could be used in any projects.

Can you help?

LV

  • Full Member
  • ***
  • Posts: 239
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #6 on: December 19, 2024, 04:41:46 pm »
@Bart suggested that Linux utilities are available. Integrate them into your program. Maybe TProcess can handle it?

jeremiah

  • New Member
  • *
  • Posts: 18
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #7 on: December 19, 2024, 06:47:48 pm »
I am grabbing Ubuntu 22.04 now to run in a virtual machine, strange it is not on the clipboard there. I 'have' to know what it is lol, mysteries are fun. Give me a couple of days to keep poking around and maybe I can do it quickly.  :)

Hartmut

  • Hero Member
  • *****
  • Posts: 893
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #8 on: December 19, 2024, 07:22:06 pm »
@Bart suggested that Linux utilities are available. Integrate them into your program. Maybe TProcess can handle it?

I have absolutely no idea how to "integrate" such an utility into my program. And I want to deliver only my executable and not install something else on foreign computers. And I assume that such an utility must run continuously in the background to do it's work. That is absolutely not the direction I'd like to go.

As I wrote, instead I would much more prefer a solution like unit 'fix_gtk_clipboard' but for graphical contents. This would be a *common* solution and very easy to use in every project.



I am grabbing Ubuntu 22.04 now to run in a virtual machine, strange it is not on the clipboard there. I 'have' to know what it is lol, mysteries are fun. Give me a couple of days to keep poking around and maybe I can do it quickly.  :)

Thank you jeremiah, I will wait.

jeremiah

  • New Member
  • *
  • Posts: 18
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #9 on: December 19, 2024, 07:28:33 pm »
I just installed Ubuntu 22.04 in virtual machine and Gimp can indeed paste the clipboard contents as a new image. Something is up on your machine perhaps? I'm off to start searching for a solution for what you shared in your last post.

jeremiah

  • New Member
  • *
  • Posts: 18
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #10 on: December 20, 2024, 02:19:04 am »
This is just to show how to save your picture to temp file then store the clipboard. I know you said not what you want but stare at it for a while and see if you can use it else just throw it away. Works on Ubuntu here also as does the previous.

jeremiah

  • New Member
  • *
  • Posts: 18
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #11 on: December 20, 2024, 04:17:49 am »
Well, I wanted to use gdk_pixbuf_new_from_stream in the gtk_fix pas but it is not implemented yet in Lazarus/FP.  :(
So I just used the previous in the gtk_fix pas and while it works it needs to be enhanced. ie, instead of only looking for bmp it should check the format on the clipboard then perhaps a case statement for different image types.

Guess all this doesn't help though since you do not want to save/load a file?

Maybe some stream expert on here can come up with a plan? Hope so... I will continue myself.

jeremiah

  • New Member
  • *
  • Posts: 18
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #12 on: December 20, 2024, 08:02:28 am »
Started anew. One form not hidden and in close event clipboard is preserved. However, using the same code in fix_gtk_pix_clipboard.pas does not. No mess with files this time Hartmut so that's good. Works in Ubuntu as long as gtk is initialized, comment out and fails.

At least can close and preserve now and once more eyes look it will be better. There is cli app also to check clipboard.

LV

  • Full Member
  • ***
  • Posts: 239
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #13 on: December 20, 2024, 10:01:20 am »
I proceeded this way:
 - started the program
 - pressed Button 'Clipboard'
 - exited the program via the "X" in the upper right corner
 - the message 'assigned' was displayed
 - checked the clipboard via GIMP, but the clipboard was empty...
 - checked that variable 'c' is not nil

I am attaching a program.
- Start the program
- Press Button 'Clipboard'
- The message 'Click the "X" and see Clipboard' will displayed
- Exit via the "X" in the upper right corner
- Check the clipboard  ;)

« Last Edit: December 20, 2024, 10:03:09 am by LV »

Hartmut

  • Hero Member
  • *****
  • Posts: 893
Re: How to not wipe out the graphical clipboard at program end? (gtk2)
« Reply #14 on: December 20, 2024, 03:40:01 pm »
I am attaching a program.

Thanks LV for your demo. You did the "trick", that you do not terminate the program, instead you minimize it to the System-Tray:

Code: Pascal  [Select][+][-]
  1. procedure TForm2.FormClose(Sender: TObject; var CloseAction: TCloseAction);
  2. var
  3.   i: integer;
  4. begin
  5.   Form2.Hide;
  6.   Form1.Hide;
  7.   Form1.TrayIcon1.Show;
  8. end;

This way the user must always click twice to end the program really which is quite uncomfortable. And I had to tell the user, that he may not click the System-Tray, as long as he does not want to loose the clipboard. Then it would be easier for all, that I implement nothing and tell the user, that he may not exit my program, as long as he does not want to loose the clipboard...

Another common problem is, that an Icon in the System-Tray on Linux is often not displayed. E.g. on my computer I see no Icon from your demo, although I enabled it. Then the user can't click on it to stop the program. There are several "solutions" out there, but it depends on the target, whether they work or not. So I would "solve" one problem by opening a second one.

That's not what I asked for, sorry. As I wrote, I search for a solution like unit 'fix_gtk_clipboard' but for graphical contents - or some kind of procedure FormClose() for the same purpose. This would be a *common* solution and very easy to use in every project :-)) That was the intention, why I started this Topic.

 

TinyPortal © 2005-2018