[SOLVED] How to hide a Form but display a TPopupNotifier? (LCL problem on Linux) lazarus / 31-LCL ---------------------------------------------------------------------- Hartmut · 2022-02-21 09:09 As so often FPC and LCL work easily on Windows, but on Linux I have endless pain. Again I need your help. I want to write a little program which shows a PopupNotifier for some seconds, but I don't want to see the Form of the program meanwhile. It should completely hide. I reduced it to a small demo: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit Unit1; {$mode objfpc}{$H+} interface uses Classes, SysUtils, Forms, Controls, Graphics, Dialogs, PopupNotifier, StdCtrls; type  { TForm1 }  TForm1 = class(TForm)  Button1: TButton;  procedure Button1Click(Sender: TObject); private public end; var Form1: TForm1; implementation {$R *.lfm} var PN1: TPopupNotifier; procedure popNotifyOn(x0,y0, xb,yh: integer; title,msg: ansistring);   {displays a PopupNotifier until popNotifyOff() is called}   begin   PN1:=TPopupNotifier.Create(nil);   PN1.Title:=title;   PN1.Text:=msg;   PN1.Color:=TColor($C0FFFF); {Background-color}   PN1.vNotifierForm.Width:=xb;   PN1.vNotifierForm.Height:=yh; writeln('ShowAtPos: ', x0, ' / ', y0);   PN1.ShowAtPos(x0,y0);   Application.ProcessMessages;   sleep(2000); // this line is only for testing purposes to demonstrate   end;       // that the PopupNotifier is definitely visible procedure popNotifyOff;   {hides the PopupNotifier which was enabled by popNotifyOn()}   begin   PN1.Hide;   PN1.Free;   end; { TForm1 } procedure TForm1.Button1Click(Sender: TObject);   var n: integer;   begin   self.Hide;   Application.ProcessMessages;// sleep(1500);    popNotifyOn(300,800,300,100, 'Title', 'This is a message');   writeln('Start Loop...'); // deleting this line doesn't help    for n:=1 to 40 do {wait 4 seconds: }      begin      Application.ProcessMessages;      sleep(100);      end;   writeln('Hide PopupNotifier now');   popNotifyOff;   Close;   end; end. On Windows everything works perfectly: the Form is hidden (line 57) and the PopupNotifier is displayed (line 40), until popNotifyOff() is called (line 70). But on Linux the PopupNotifier is visible only for 2 seconds (line 42). As soon as "Start Loop..." is displayed (line 62), the PopupNotifier disappears! So during the following loop (4 seconds) I don't see the PopupNotifier... What I don't understand: in line 41 Application.ProcessMessages() and sleep() dont't disturb, but in line 66 exactly the same commands hide the PopupNotifier. I'm on Linux Ubuntu 18.04 and tried with Lazarus 2.0.10 and 2.0.6 and 1.8.4 with all the same result. What do I do wrong? I attached a compilable demo. Thanks in advance. ---------------------------------------------------------------------- Handoko · 2022-02-21 11:45 Tested on Lazarus 2.2.0 64-bit GTK2 Ubuntu Mate 21.10, and this is what I found: If the system detects that the application has no visible form, the TPopupNotifier will be automatically closed. I don't say there is no workaround, you may able to 'hack' into the GTK and change the behavior but it may or may not work on other GTK versions. So I think the best you can do is, write a custom form and use it as a popup notifier. How making a form to show but hide the previous one, you can try to search how to do splash form, that should give you the idea. ---------------------------------------------------------------------- Hartmut · 2022-02-21 14:58 Hello Handoko, thank you for helping me again. Quote from: Handoko on February 21, 2022, 12:45:19 pmSo I think the best you can do is, write a custom form and use it as a popup notifier. How making a form to show but hide the previous one, you can try to search how to do splash form, that should give you the idea. This would be far beyond my capabilities... QuoteTested on Lazarus 2.2.0 64-bit GTK2 Ubuntu Mate 21.10, and this is what I found: If the system detects that the application has no visible form, the TPopupNotifier will be automatically closed. Do I understand you right, that GTK3 or QT might work? I'm a bloody beginner to that stuff... I tried to compile my program with GTK3 and got: /usr/bin/ld: -lgtk-3 cannot be found /usr/bin/ld: -lgdk-3 cannot be found project1.lpr(27,1) Error: Error while linking I tried to compile my program with qt and got: linker: /usr/bin/ld: -lQt4Pas cannot be found I tried to compile my program with qt5 and got: linker: /usr/bin/ld: -lQt5Pas cannot be found Does this mean, that I must only install 1 or 2 libraries and then I could compile and run my demo on my Ubuntu 18.04 64-bit with KDE Plasma desktop using GTK3 or QT? Without damaging my system that way? If yes, I would like to try it, but in Packet Managers Synapse/Muon I did not find libraries with exactly the mentioned names, but dozens of similar names. Could someone please tell me the correct library names which I had to install? Thanks. ---------------------------------------------------------------------- Zvoni · 2022-02-21 15:04 search for libqt5pas and libqt5pas-dev ---------------------------------------------------------------------- AlexTP · 2022-02-21 16:46 Quote>search for libqt5pas https://wiki.freepascal.org/CudaText#Linux_Qt5_build ---------------------------------------------------------------------- Hartmut · 2022-02-21 16:48 Thanks Zvoni for that info. I could install both libraries, but now I get another linker error: Code: Text  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i Free Pascal Compiler version 3.2.0-r45643 [2020/12/20] for x86_64Copyright (c) 1993-2020 by Florian Klaempfl and others(1002) Target OS: Linux for x86-64(3104) Compiling project1.lpr(3104) Compiling unit1.pas (9015) Linking /hg/utis/project1/opt/lazarus_210/lazarus/lcl/units/x86_64- linux/qt5/qtwidgets.o: in function »SETTEXTHINT«:/opt/lazarus_210/laza rus/lcl/interfaces//qt5/qtwidgets.pas:10167: Warning: undefined Link to »QTextEdit_setPlaceholderText«/media/H/Progs/Lazarus/work/Experimen te/Forum17_BalloonTip/project1.lpr(27,1) Error: (9013) Error while lin king/media/H/Progs/Lazarus/work/Experimente/Forum17_BalloonTip/project 1.lpr(27,1) Fatal: (10026) There were 1 errors compiling module, stoppingFatal: (1018) Compilation abortedError: /opt/lazarus_210/fpc/bin/x86_64-linux/ppcx64 returned an error exitcode  I get this linker error with Lazarus 2.0.10 and 2.0.6. With Lazarus 1.8.4 I get no linker error, but the program crashes immediately when started: [FORMS.PP] ExceptionOccurred   Sender=EAccessViolation   Exception=Access violation   Stack trace:   $0000000000435908   $00000000006D9B17   $00000000006CD65E ... Quote from: Alextp on February 21, 2022, 05:46:26 pmQuote>search for libqt5pas https://wiki.freepascal.org/CudaText#Linux_Qt5_build Thanks Alextp, I installed ver 2.6-4 Can anybody help to get the small demo running with qt5? Or does someone know the neccessary libraries (see reply #2) for GTK3 and qt4? ---------------------------------------------------------------------- Handoko · 2022-02-21 17:16 Quote from: Hartmut on February 21, 2022, 03:58:15 pmQuote from: Handoko on February 21, 2022, 12:45:19 pmSo I think the best you can do is, write a custom form and use it as a popup notifier. How making a form to show but hide the previous one, you can try to search how to do splash form, that should give you the idea. This would be far beyond my capabilities... I quickly written a demo, it should give you the idea how to write yourself a custom popup. It is tested on Ubuntu Mate GTK2, the font, size and position may need to readjust if you want to run it on other platforms. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i unit frmCustomPopup; {$mode ObjFPC}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls; type   { TCustomPopup }   TCustomPopup = class(TForm)    Label1: TLabel;    Label2: TLabel;    Timer1: TTimer;    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);    procedure FormCreate(Sender: TObject);    procedure FormShow(Sender: TObject);  procedure Timer1Timer(Sender: TObject);  private    FAutoClose:   Boolean;    FPosX, FPosY: Integer;    FCaller:      TForm;    FCounter:     Integer;  public    procedure SetLine(const S: string);    procedure SetAutoClose(Autoclose: Boolean);    procedure SetAutoCenter(Autocenter: Boolean);    procedure SetFormColor(aColor: TColor);    procedure Show(TheCaller: TForm); overload;  end; var  CustomPopup: TCustomPopup; implementation {$R *.lfm} { TCustomPopup } procedure TCustomPopup.FormCreate(Sender: TObject);begin  FAutoClose           := False;  FPosX                := Left;  FPosY              := Top;  FCaller              := nil;  FCounter             := 0;  Label2.Anchors       := [akLeft] + [akBottom];  Timer1.Enabled       := False;  BorderStyle          := bsDialog;  Constraints.MinWidth := 220;end; procedure TCustomPopup.FormClose(Sender: TObject; var CloseAction: TCloseAction  );begin  if Assigned(FCaller) then    FCaller.Visible := True;end; procedure TCustomPopup.FormShow(Sender: TObject);begin  Label2.Visible := FAutoClose;  case FAutoClose of    True:      begin        Height         := Label1.Height + 65;        FCounter       := 6;        Timer1.Enabled := True;        Timer1Timer(Self);      end;    False:      Height := Label1.Height + 50;  end;  Width := Label1.Width + 40;end; procedure TCustomPopup.Timer1Timer(Sender: TObject);var  S: string;begin   Dec(FCounter);  if FCounter <= 0 then    Timer1.Enabled := False;   S := FCounter.ToString + ' second';  if FCounter > 1 then    S := S + 's';  Label2.Caption := 'Will be close in ' + S;   if FAutoClose and (FCounter <= 0) then Close; end; procedure TCustomPopup.SetLine(const S: string);begin  Label1.Caption := S;end; procedure TCustomPopup.SetAutoClose(Autoclose: Boolean);begin  FAutoClose := Autoclose;end; procedure TCustomPopup.SetAutoCenter(Autocenter: Boolean);begin  case Autocenter of    True:      Position := poDesktopCenter;    False:      begin        Position := poDesigned;      Left     := FPosX;        Top      := FPosY;      end;  end;end; procedure TCustomPopup.SetFormColor(aColor: TColor);begin  Color := aColor;end; procedure TCustomPopup.Show(TheCaller: TForm);begin  FCaller := TheCaller;  if Assigned(TheCaller) then    TheCaller.Visible := False;  Show;end; end. ---------------------------------------------------------------------- Hartmut · 2022-02-21 18:06 Thank you very, very much Handoko for that great Unit and for your demo! It works perfectly on my system, even if the main Form is hidden. That is exactly what I was for. I'm optimistic now, that my capabilities are enough to make some minor changes for my needs. This is a great Forum!