Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Michael Van Canneyt via lazarus




On Tue, 28 Mar 2023, Luca Olivetti via lazarus wrote:


El 28/3/23 a les 0:01, Michael Van Canneyt ha escrit:



My bad, I made a typo, it should have been

MyException:=ExceptionClass(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message)


Thank you.

Actually it is

MyException:=TExceptionClass(Exception(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message); 




with ExceptionClass= class of exception;

Actually, I never write it like this in one statement, 


Yep, it's quite a mouthful, I had to break it up to spot the error :-)


I save the class pointer and message
in local variables, do cleanup first and then use the class pointer and
message later to raise an exception. But the effect is the same: you create
a copy with the same class and message as the original.


But not with the same detail (i.e. any extra fields are missing).
Not that I'm really interested in them (usually I just use the message), but 
still...


I am aware of that. But the extra fields are usually only interesting in the
debugger. You will see them if you inspect ut.FatalException. For the user
normally only the message is interesting.

Michael.
--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 28/3/23 a les 0:45, Luca Olivetti via lazarus ha escrit:

El 28/3/23 a les 0:01, Michael Van Canneyt ha escrit:



My bad, I made a typo, it should have been

MyException:=ExceptionClass(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message)


Thank you.

Actually it is

MyException:=TExceptionClass(Exception(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message);


or

MyException:=TExceptionClass(ut.FatalException.ClassType).Create(Exception(ut.FatalException).message)

(TObject already has a ClassType, no need to cast it to Exception).






with ExceptionClass= class of exception;

Actually, I never write it like this in one statement, 


Yep, it's quite a mouthful, I had to break it up to spot the error :-)


I save the class pointer and message
in local variables, do cleanup first and then use the class pointer and
message later to raise an exception. But the effect is the same: you 
create

a copy with the same class and message as the original.


But not with the same detail (i.e. any extra fields are missing).
Not that I'm really interested in them (usually I just use the message), 
but still...



Bye


--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 28/3/23 a les 0:01, Michael Van Canneyt ha escrit:



My bad, I made a typo, it should have been

MyException:=ExceptionClass(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message)


Thank you.

Actually it is

MyException:=TExceptionClass(Exception(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message); 





with ExceptionClass= class of exception;

Actually, I never write it like this in one statement, 


Yep, it's quite a mouthful, I had to break it up to spot the error :-)

I save the class 
pointer and message

in local variables, do cleanup first and then use the class pointer and
message later to raise an exception. But the effect is the same: you create
a copy with the same class and message as the original.


But not with the same detail (i.e. any extra fields are missing).
Not that I'm really interested in them (usually I just use the message), 
but still...



Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Michael Van Canneyt via lazarus



On Mon, 27 Mar 2023, Luca Olivetti via lazarus wrote:


El 27/3/23 a les 17:26, Luca Olivetti via lazarus ha escrit:

El 27/3/23 a les 16:50, Michael Van Canneyt ha escrit:



Ehm. In case of an exception, ut will never be freed ?


That's what I said.
I was looking for a way to free it *and* raise the exception in the 
context of the main thread.
If I move the ut.free before the raise, the exception has already 
been freed and it's invalid, causing a sigsev, if I enclose it in a 
try..finally the exception handler will be called after the finally 
has freed the thread (and the exception, so it's the same problem).


Normally, I'd do

Raise 
Exception(ut.fatalexception.classtype).Create(ut.fatalexception.message);


Actually I'd have to first create the exception, then free ut, then 
raise the exception (keep in mind that FatalException is a TObject and 
it isn't necessarily of class Exception), otherwise a direct raise as 
you wrote would not free ut.


I only gave the line to show that you can raise a second exception object
with the same class and message as the original.



   MyException:=nil;
   if ut.FatalException<>nil then
   begin
  if ut.FatalException is Exception then



MyException:=Exception(ut.FatalException).Create(Exception(ut.FatalException).message)

Ouch, I left out the ClassType, but if I change it to


MyException:=Exception(Exception(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message)

it's an instant segfault.


My bad, I made a typo, it should have been

MyException:=ExceptionClass(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message)

with 
ExceptionClass= class of exception;


Actually, I never write it like this in one statement, I save the class pointer 
and message
in local variables, do cleanup first and then use the class pointer and
message later to raise an exception. But the effect is the same: you create
a copy with the same class and message as the original.

Michael.-- 
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 17:26, Luca Olivetti via lazarus ha escrit:

El 27/3/23 a les 16:50, Michael Van Canneyt ha escrit:



Ehm. In case of an exception, ut will never be freed ?


That's what I said.
I was looking for a way to free it *and* raise the exception in the 
context of the main thread.
If I move the ut.free before the raise, the exception has already 
been freed and it's invalid, causing a sigsev, if I enclose it in a 
try..finally the exception handler will be called after the finally 
has freed the thread (and the exception, so it's the same problem).


Normally, I'd do

Raise 
Exception(ut.fatalexception.classtype).Create(ut.fatalexception.message);


Actually I'd have to first create the exception, then free ut, then 
raise the exception (keep in mind that FatalException is a TObject and 
it isn't necessarily of class Exception), otherwise a direct raise as 
you wrote would not free ut.


   MyException:=nil;
   if ut.FatalException<>nil then
   begin
  if ut.FatalException is Exception then

MyException:=Exception(ut.FatalException).Create(Exception(ut.FatalException).message)


Ouch, I left out the ClassType, but if I change it to


MyException:=Exception(Exception(ut.FatalException).ClassType).Create(Exception(ut.FatalException).message)

it's an instant segfault.

Bye

--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 16:50, Michael Van Canneyt ha escrit:



Ehm. In case of an exception, ut will never be freed ?


That's what I said.
I was looking for a way to free it *and* raise the exception in the 
context of the main thread.
If I move the ut.free before the raise, the exception has already been 
freed and it's invalid, causing a sigsev, if I enclose it in a 
try..finally the exception handler will be called after the finally 
has freed the thread (and the exception, so it's the same problem).


Normally, I'd do

Raise 
Exception(ut.fatalexception.classtype).Create(ut.fatalexception.message);


Actually I'd have to first create the exception, then free ut, then 
raise the exception (keep in mind that FatalException is a TObject and 
it isn't necessarily of class Exception), otherwise a direct raise as 
you wrote would not free ut.


  MyException:=nil;
  if ut.FatalException<>nil then
  begin
 if ut.FatalException is Exception then

MyException:=Exception(ut.FatalException).Create(Exception(ut.FatalException).message)
 else
   MyException:=Exception.create(ut.FatalException.ClassName);
  end;
  ut.free;
  if MyException<>nil then
raise MyException;



But it still doesn't work, since this way MyException is a copy of 
FatalException (i.e. it's no different than 
MyException:=Exception(ut.FatalExcaption), so freeing ut, which in turn 
frees ut.FatalException, makes it invalid and causes a sigsev.


The best I could do is store the exception message and raise a new one.

Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Michael Van Canneyt via lazarus



On Mon, 27 Mar 2023, Luca Olivetti via lazarus wrote:


El 27/3/23 a les 16:13, Michael Van Canneyt via lazarus ha escrit:



On Mon, 27 Mar 2023, Luca Olivetti via lazarus wrote:


El 27/3/23 a les 11:59, Luca Olivetti via lazarus ha escrit:

[*] instead of opening the query I spawn a thread that opens it, wait 
for it to finish while executing Application.ProcessMessages and 
eventually reraise the exception that was generated inside the thread.



Speaking of which, I encapsulated it in a procedure (TWaitForm is the 
spash screen, Aproc is a procedure of object, TExecInThread simply 
calls AProc in its execute method):


procedure ExecWithSplash(AProc:TThreadProc);
var wf:TWaitForm;
   ut:TExecInThread;
begin
 Wf:=TWaitForm.Create(Application);
 WF.Show;
 ut:=TExecInThread.create(AProc);
 while not ut.Finished
   Application.ProcessMessages
 wf.free;
 if ut.FatalException<>nil then
   raise(ut.FatalException);
 ut.free;


Ehm. In case of an exception, ut will never be freed ?


That's what I said.
I was looking for a way to free it *and* raise the exception in the 
context of the main thread.
If I move the ut.free before the raise, the exception has already been 
freed and it's invalid, causing a sigsev, if I enclose it in a 
try..finally the exception handler will be called after the finally has 
freed the thread (and the exception, so it's the same problem).


Normally, I'd do

Raise Exception(ut.fatalexception.classtype).Create(ut.fatalexception.message);

Michael.-- 
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 16:13, Michael Van Canneyt via lazarus ha escrit:



On Mon, 27 Mar 2023, Luca Olivetti via lazarus wrote:


El 27/3/23 a les 11:59, Luca Olivetti via lazarus ha escrit:

[*] instead of opening the query I spawn a thread that opens it, wait 
for it to finish while executing Application.ProcessMessages and 
eventually reraise the exception that was generated inside the thread.



Speaking of which, I encapsulated it in a procedure (TWaitForm is the 
spash screen, Aproc is a procedure of object, TExecInThread simply 
calls AProc in its execute method):


procedure ExecWithSplash(AProc:TThreadProc);
var wf:TWaitForm;
   ut:TExecInThread;
begin
 Wf:=TWaitForm.Create(Application);
 WF.Show;
 ut:=TExecInThread.create(AProc);
 while not ut.Finished
   Application.ProcessMessages
 wf.free;
 if ut.FatalException<>nil then
   raise(ut.FatalException);
 ut.free;


Ehm. In case of an exception, ut will never be freed ?


That's what I said.
I was looking for a way to free it *and* raise the exception in the 
context of the main thread.
If I move the ut.free before the raise, the exception has already been 
freed and it's invalid, causing a sigsev, if I enclose it in a 
try..finally the exception handler will be called after the finally has 
freed the thread (and the exception, so it's the same problem).



Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Michael Van Canneyt via lazarus




On Mon, 27 Mar 2023, Luca Olivetti via lazarus wrote:


El 27/3/23 a les 11:59, Luca Olivetti via lazarus ha escrit:

[*] instead of opening the query I spawn a thread that opens it, wait for 
it to finish while executing Application.ProcessMessages and eventually 
reraise the exception that was generated inside the thread.



Speaking of which, I encapsulated it in a procedure (TWaitForm is the spash 
screen, Aproc is a procedure of object, TExecInThread simply calls AProc in 
its execute method):


procedure ExecWithSplash(AProc:TThreadProc);
var wf:TWaitForm;
   ut:TExecInThread;
begin
 Wf:=TWaitForm.Create(Application);
 WF.Show;
 ut:=TExecInThread.create(AProc);
 while not ut.Finished
   Application.ProcessMessages
 wf.free;
 if ut.FatalException<>nil then
   raise(ut.FatalException);
 ut.free;


Ehm. In case of an exception, ut will never be freed ?

Michael.
--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 15:55, Jean SUZINEAU via lazarus ha escrit:

Le 27/03/2023 à 14:40, Luca Olivetti via lazarus a écrit :
The problem here is, if AProc raises an exception, I cannot free the 
thread causing a leak. 


May be you can create a new exception class specifically for 
ExecWithSplash,
instantiate it and put all the information of ut.FatalException in the 
new exception instance before raising it?


Creating a specific exception class wouldn't solve the problem on how to 
make a deep copy of the original exception.
I can just store the message an raise it again, losing the rest of the 
details, i.e.:


  ExceptionMessage:='';
  if ut.FatalException<>nil then
ExceptionMessage:=Exception(ut.FatalException).Message;
  ut.free;
  if ExceptionMessage<>'' then
raise Exception.create(ExceptionMessage);



The goal is to easily substitute the original code:


  try
dosomething;
dosomethingelse;

  except

  end;


with

  try
ExecWithSplash(@doit);
  except
...
  end;


procedure TMyDatamodule.doit;
begin
  dosomething;
  dosomethingelse;
end;

Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 15:40, Mattias Gaertner via lazarus ha escrit:



procedure ExecWithSplash(AProc:TThreadProc);
var wf:TWaitForm;
  ut:TExecInThread;
begin
Wf:=TWaitForm.Create(Application);
WF.Show;
ut:=TExecInThread.create(AProc);
while not ut.Finished
  Application.ProcessMessages
wf.free;
if ut.FatalException<>nil then
  raise(ut.FatalException);
ut.free;
end;


The problem here is, if AProc raises an exception, I cannot free the
thread causing a leak.


What does TExecInThread.Execute do?


As I said, it just calls AProc (which the constructor stored in FProc)


procedure TExecInThread.Execute;
begin
  FProc()
end;

constructor TExecInThread.create(AProc:TThreadProc);
begin
  FProc:=AProc;
  inherited create(false);
end;


Bye

--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Jean SUZINEAU via lazarus

Le 27/03/2023 à 14:40, Luca Olivetti via lazarus a écrit :
The problem here is, if AProc raises an exception, I cannot free the 
thread causing a leak. 


May be you can create a new exception class specifically for 
ExecWithSplash,
instantiate it and put all the information of ut.FatalException in the 
new exception instance before raising it?


--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Mattias Gaertner via lazarus
On Mon, 27 Mar 2023 14:40:26 +0200
Luca Olivetti via lazarus  wrote:

> El 27/3/23 a les 11:59, Luca Olivetti via lazarus ha escrit:
> 
> > [*] instead of opening the query I spawn a thread that opens it,
> > wait for it to finish while executing Application.ProcessMessages
> > and eventually reraise the exception that was generated inside the
> > thread.  
> 
> 
> Speaking of which, I encapsulated it in a procedure (TWaitForm is the 
> spash screen, Aproc is a procedure of object, TExecInThread simply
> calls AProc in its execute method):
> 
> procedure ExecWithSplash(AProc:TThreadProc);
> var wf:TWaitForm;
>  ut:TExecInThread;
> begin
>Wf:=TWaitForm.Create(Application);
>WF.Show;
>ut:=TExecInThread.create(AProc);
>while not ut.Finished
>  Application.ProcessMessages
>wf.free;
>if ut.FatalException<>nil then
>  raise(ut.FatalException);
>ut.free;
> end;
> 
> 
> The problem here is, if AProc raises an exception, I cannot free the 
> thread causing a leak.

What does TExecInThread.Execute do?

> try
>if ut.FatalException<>nil then
>  raise(ut.FatalException);
> finally
>ut.free;
> end



Mattias

-- 
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 11:59, Luca Olivetti via lazarus ha escrit:

[*] instead of opening the query I spawn a thread that opens it, wait 
for it to finish while executing Application.ProcessMessages and 
eventually reraise the exception that was generated inside the thread.



Speaking of which, I encapsulated it in a procedure (TWaitForm is the 
spash screen, Aproc is a procedure of object, TExecInThread simply calls 
AProc in its execute method):


procedure ExecWithSplash(AProc:TThreadProc);
var wf:TWaitForm;
ut:TExecInThread;
begin
  Wf:=TWaitForm.Create(Application);
  WF.Show;
  ut:=TExecInThread.create(AProc);
  while not ut.Finished
Application.ProcessMessages
  wf.free;
  if ut.FatalException<>nil then
raise(ut.FatalException);
  ut.free;
end;


The problem here is, if AProc raises an exception, I cannot free the 
thread causing a leak.
Since I don't want to expose the thread to the caller, so that it can 
free it in its exception handler, how can I copy FatalException so I can 
free the thread and only then raise the exception?
I cannot simply assign it to a local variable since the TThread 
destructor also frees FatalException.


Encapsulating it in a try..finally block also doesn't work

try
  if ut.FatalException<>nil then
raise(ut.FatalException);
finally
  ut.free;
end

Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 12:07, Giuliano Colla ha escrit:

In a similar scenario my solution has been that of an horrible hack. 
It's a hack, but it works. I've put in a corner of my window a label of 
just one character, and, with a frequent timer (200 ms in my case) I 
update the caption. I'm using a sequence of "-" "\" " |" "/" "-" to 
display a rotating bar. Usually users do not even notice, but if they do 
it's harmless. This way I trigger an event which will force a paint 
operation, and all pending graphic updates are performed.


Maybe this works also for you. You should just tune the timer to the 
speed of your animation.



Thank you, but I don't think it would work (at least under windows I'm 
sure it doesn't), since in order to process the timer events the main 
loop must be processing events, and it's not doing that if the program 
is stuck in a lengthy operation.
As per Sven's indication, I'm now doing all the painting in the main 
thread and delegated the lengthy operation to a thread.


Bye

--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Giuliano Colla via lazarus

Il 27/03/23 09:46, Luca Olivetti via lazarus ha scritto:

Hello,

I'd like to show a splash screen with an animation during a lengthy 
operation.
I cannot rely on a timer to show the animation since the message loop 
isn't running, so I'm using a thread to directly paint over the form, 
i.e.:



WaitForm.Show;
Application.ProcessMessages;

...

procedure TWaitForm.FormShow(Sender: TObject);
begin
  FUpdateThread:=TUpdateThread.Create(self);
end;

...

procedure TUpdateThread.Execute;
begin
  while not Terminated do
  begin
    FWaitForm.ShowProgress;
    Sleep(30);
  end;
end;

...

procedure TWaitForm.ShowProgress;
begin
  PaintBox1.Canvas.Clear;
  //WaitAnimation is an image list
  WaitAnimation.Draw(PaintBox1.Canvas,0,0,FImageIndex);
  FImageIndex:=FImageIndex+1;
  if FImageIndex>=WaitAnimation.Count then
    FImageIndex:=0;
end;


This works wonderfully under windows (which is my intended target, so 
no problem here), but under Linux it doesn't work (tested with gtk2, 
gtk3 and qt5). In fact, even the "Show; Application.ProcessMessages" 
is erratic, sometimes it shows the form, sometimes it doesn't.


Lazarus 2.2.6/fpc 3.2.2

Any idea?

Bye



Yes, it's a known issue.

The difference between Windows and Unix is that Windows generates 
frequently useless mouse events to all windows, which wake up the main 
thread of Delphi/Lazarus, while Unix/X11/Wayland is well behaved and 
sends a mouse event only to the appropriate window, and only if there's 
been a physical mouse event to send.


You may verify if such is the case by moving the mouse over your splash 
screen window. You move the mouse and the image is updated, you stop 
moving and the image freezes.


In a similar scenario my solution has been that of an horrible hack. 
It's a hack, but it works. I've put in a corner of my window a label of 
just one character, and, with a frequent timer (200 ms in my case) I 
update the caption. I'm using a sequence of "-" "\" " |" "/" "-" to 
display a rotating bar. Usually users do not even notice, but if they do 
it's harmless. This way I trigger an event which will force a paint 
operation, and all pending graphic updates are performed.


Maybe this works also for you. You should just tune the timer to the 
speed of your animation.


Hope that it helps,

Giuliano

--
Do not do to others as you would have them do to you.They might have different 
tastes.

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 11:06, Sven Barth via lazarus ha escrit:
Luca Olivetti via lazarus > schrieb am Mo., 27. März 2023, 
10:34:


El 27/3/23 a les 10:13, Jean SUZINEAU via lazarus ha escrit:
 >
 > Le 27/03/2023 à 09:46, Luca Olivetti via lazarus a écrit :
 >> procedure TUpdateThread.Execute;
 >> begin
 >>   while not Terminated do
 >>   begin
 >>     FWaitForm.ShowProgress;
 >>     Sleep(30);
 >>   end;
 >> end;
 >
 > Usually I use TThread.Synchronize to ensure that the graphic code
is run
 > by the main thread.
 >
 > But it won't work if your main thread is blocking.

Exactly

 >
 > May be you should do the inverse move the lengthy operation to a
 > separate thread and keep the main thread for the splash screen ?

Yes, I usually do that, but in this case it's not possible (the lengthy
operation is just a  TSQLQuery.open that I cannot delegate to a
different thread).


You need to find a way then, because the GUI handling *must* be done in 
the main thread.


Opening the query in a thread[*] seems to have no ill effects, so that's 
what I'm doing now.



[*] instead of opening the query I spawn a thread that opens it, wait 
for it to finish while executing Application.ProcessMessages and 
eventually reraise the exception that was generated inside the thread.


Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Sven Barth via lazarus
Luca Olivetti via lazarus  schrieb am Mo.,
27. März 2023, 10:34:

> El 27/3/23 a les 10:13, Jean SUZINEAU via lazarus ha escrit:
> >
> > Le 27/03/2023 à 09:46, Luca Olivetti via lazarus a écrit :
> >> procedure TUpdateThread.Execute;
> >> begin
> >>   while not Terminated do
> >>   begin
> >> FWaitForm.ShowProgress;
> >> Sleep(30);
> >>   end;
> >> end;
> >
> > Usually I use TThread.Synchronize to ensure that the graphic code is run
> > by the main thread.
> >
> > But it won't work if your main thread is blocking.
>
> Exactly
>
> >
> > May be you should do the inverse move the lengthy operation to a
> > separate thread and keep the main thread for the splash screen ?
>
> Yes, I usually do that, but in this case it's not possible (the lengthy
> operation is just a  TSQLQuery.open that I cannot delegate to a
> different thread).
>

You need to find a way then, because the GUI handling *must* be done in the
main thread.

Regards,
Sven

>
-- 
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 10:34, Luca Olivetti via lazarus ha escrit:

El 27/3/23 a les 10:13, Jean SUZINEAU via lazarus ha escrit:


Le 27/03/2023 à 09:46, Luca Olivetti via lazarus a écrit :

procedure TUpdateThread.Execute;
begin
  while not Terminated do
  begin
    FWaitForm.ShowProgress;
    Sleep(30);
  end;
end;


Usually I use TThread.Synchronize to ensure that the graphic code is 
run by the main thread.


But it won't work if your main thread is blocking.


Exactly



May be you should do the inverse move the lengthy operation to a 
separate thread and keep the main thread for the splash screen ?


Yes, I usually do that, but in this case it's not possible (the lengthy 
operation is just a  TSQLQuery.open that I cannot delegate to a 
different thread).


Sorry, in this project I'm using zeos, so it's TZQuery.open.


Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

El 27/3/23 a les 10:13, Jean SUZINEAU via lazarus ha escrit:


Le 27/03/2023 à 09:46, Luca Olivetti via lazarus a écrit :

procedure TUpdateThread.Execute;
begin
  while not Terminated do
  begin
    FWaitForm.ShowProgress;
    Sleep(30);
  end;
end;


Usually I use TThread.Synchronize to ensure that the graphic code is run 
by the main thread.


But it won't work if your main thread is blocking.


Exactly



May be you should do the inverse move the lengthy operation to a 
separate thread and keep the main thread for the splash screen ?


Yes, I usually do that, but in this case it's not possible (the lengthy 
operation is just a  TSQLQuery.open that I cannot delegate to a 
different thread).


Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


Re: [Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Jean SUZINEAU via lazarus


Le 27/03/2023 à 09:46, Luca Olivetti via lazarus a écrit :

procedure TUpdateThread.Execute;
begin
  while not Terminated do
  begin
    FWaitForm.ShowProgress;
    Sleep(30);
  end;
end;


Usually I use TThread.Synchronize to ensure that the graphic code is run 
by the main thread.


But it won't work if your main thread is blocking.

May be you should do the inverse move the lengthy operation to a 
separate thread and keep the main thread for the splash screen ?


As far as I know the graphic code must be run by the main thread.

--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus


[Lazarus] animated splash screen for lengthy operation, works with windows, doesn't with linux

2023-03-27 Thread Luca Olivetti via lazarus

Hello,

I'd like to show a splash screen with an animation during a lengthy 
operation.
I cannot rely on a timer to show the animation since the message loop 
isn't running, so I'm using a thread to directly paint over the form, i.e.:



WaitForm.Show;
Application.ProcessMessages;

...

procedure TWaitForm.FormShow(Sender: TObject);
begin
  FUpdateThread:=TUpdateThread.Create(self);
end;

...

procedure TUpdateThread.Execute;
begin
  while not Terminated do
  begin
FWaitForm.ShowProgress;
Sleep(30);
  end;
end;

...

procedure TWaitForm.ShowProgress;
begin
  PaintBox1.Canvas.Clear;
  //WaitAnimation is an image list
  WaitAnimation.Draw(PaintBox1.Canvas,0,0,FImageIndex);
  FImageIndex:=FImageIndex+1;
  if FImageIndex>=WaitAnimation.Count then
FImageIndex:=0;
end;


This works wonderfully under windows (which is my intended target, so no 
problem here), but under Linux it doesn't work (tested with gtk2, gtk3 
and qt5). In fact, even the "Show; Application.ProcessMessages" is 
erratic, sometimes it shows the form, sometimes it doesn't.


Lazarus 2.2.6/fpc 3.2.2

Any idea?

Bye
--
Luca Olivetti
Wetron Automation Technology http://www.wetron.es/
Tel. +34 93 5883004 (Ext.3010)  Fax +34 93 5883007
--
___
lazarus mailing list
lazarus@lists.lazarus-ide.org
https://lists.lazarus-ide.org/listinfo/lazarus