View Issue Details

IDProjectCategoryView StatusLast Update
0017816LazarusWidgetsetpublic2011-01-21 18:22
ReporterBart BroersmaAssigned ToZeljan Rikalo 
PrioritynormalSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Platformi386OSSuse LinuxOS Version10.0
Product Version0.9.29 (SVN)Product Buildr28055 
Target VersionFixed in Version0.9.31 (SVN) 
Summary0017816: TFloatSpinEdit locks app when setting parent
DescriptionWhen you set the parent property of a TFloatSpinEdit, the application locks up in GTK2 Linux.

As a result you also cannot put a TFloatSpinEdit on a form in the IDE.

In GTK Linux there is no problem.

In previous versions of Lazarus this worked just fine, so it's a regression.
Steps To ReproduceCreate an empty project with just a form.

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormKeyPress(Sender: TObject; var Key: char);
  private
    { private declarations }
    FloatEdit: TFloatSpinEdit;
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.lfm}

uses lclproc;

{ TForm1 }

procedure TForm1.FormCreate(Sender: TObject);
begin
  FloatEdit := TFloatSpinEdit.Create(Self);
end;

procedure TForm1.FormKeyPress(Sender: TObject; var Key: char);
begin
  if Upcase(Key) = 'F' then
  begin
    FloatEdit.Parent := Self;
  end;
end;

Compile and run.
Press 'F'
Additional InformationThe following order of events occur:

FloatEdit.SetParent
FloatEdit.DisableAutoSizing (direct call in FloatEdit.SetParent)
nd FloatEdit.DisableAutoSizing
Form1.DisableAutoSizing Form1:TForm1 0
End Form1.DisableAutoSizing Form1:TForm1 1
  Form1.DisableAutoSizing Form1:TForm1 1
  End Form1.DisableAutoSizing Form1:TForm1 2
    Form1.EnableAutoSizing Form1:TForm1 2
  End Form1.EnableAutoSizing Form1:TForm1 1
  FloatEdit.EnableAutoSizing :TFloatSpinEdit 1 (direct call in FloatEdit.SetParent)
  Form1.EnableAutoSizing Form1:TForm1 1
FloatEdit.DisableAutoSizing :TFloatSpinEdit 0
Form1.DisableAutoSizing Form1:TForm1 0
  End Form1.DisableAutoSizing Form1:TForm1 1
  End FloatEdit.DisableAutoSizing :TFloatSpinEdit 1
  FloatEdit.DisableAutoSizing :TFloatSpinEdit 1
    End FloatEdit.DisableAutoSizing :TFloatSpinEdit 2
    FloatEdit.EnableAutoSizing :TFloatSpinEdit 2
  End FloatEdit.EnableAutoSizing :TFloatSpinEdit 1

After this the following error occurs and this line is printed endlessly on the console:

(foo:7093): GLib-GObject-CRITICAL **: g_closure_ref: assertion `closure->ref_count < CLOSURE_MAX_REF_COUNT' failed

The form now becomes unresposive and can only be killed.

FWIW:
Linux 2.6.13-15 i686
gtk2-2.8.3-4
fpc 2.4.0
TagsNo tags attached.
Fixed in Revision29157
LazTarget-
WidgetsetGTK 2
Attached Files
  • TFloatSpinEdit_SetParent_bug.tgz (2,540 bytes)
  • gtkspinbutton.diff (556 bytes)
    Index: lcl/interfaces/gtk2/gtk2callback.inc
    ===================================================================
    --- lcl/interfaces/gtk2/gtk2callback.inc	(revision 28059)
    +++ lcl/interfaces/gtk2/gtk2callback.inc	(working copy)
    @@ -455,7 +455,10 @@
       Result := CallBackDefaultReturn;
       if LockOnChange(PgtkObject(Widget),0) > 0 then exit;
       if GTK_IS_SPIN_BUTTON(Widget) then
    +  begin
         gtk_spin_button_update(PGtkSpinButton(Widget));
    +    Result := not CallBackDefaultReturn;
    +  end;
     end;
     
     function gtkchanged_editbox_backspace(widget: PGtkWidget;
    
    gtkspinbutton.diff (556 bytes)

Activities

Zeljan Rikalo

2010-11-03 16:01

developer   ~0042724

@Bart please attach an example.

Zeljan Rikalo

2010-11-03 16:04

developer   ~0042725

Works fine here in design time (gtk2-2.12). I guess it's another gtk2-2.8 problem.

2010-11-03 16:07

 

TFloatSpinEdit_SetParent_bug.tgz (2,540 bytes)

Bart Broersma

2010-11-03 17:41

developer   ~0042728

Last edited: 2010-11-03 17:54

Revision 25218 seems to be the culprit.
It causes the behaviour described in my report.

In gtkcallback.inc
function gtkchanged_spinbox(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
is called in an endless loop.

2010-11-03 20:13

 

gtkspinbutton.diff (556 bytes)
Index: lcl/interfaces/gtk2/gtk2callback.inc
===================================================================
--- lcl/interfaces/gtk2/gtk2callback.inc	(revision 28059)
+++ lcl/interfaces/gtk2/gtk2callback.inc	(working copy)
@@ -455,7 +455,10 @@
   Result := CallBackDefaultReturn;
   if LockOnChange(PgtkObject(Widget),0) > 0 then exit;
   if GTK_IS_SPIN_BUTTON(Widget) then
+  begin
     gtk_spin_button_update(PGtkSpinButton(Widget));
+    Result := not CallBackDefaultReturn;
+  end;
 end;
 
 function gtkchanged_editbox_backspace(widget: PGtkWidget;
gtkspinbutton.diff (556 bytes)

Zeljan Rikalo

2010-11-03 20:14

developer   ~0042733

Please try provided patch, I cannot reproduce your problem with gtk2-2.12,gtk2-2.16,gtk2-2.18 and gtk2-2.20.

Bart Broersma

2010-11-04 00:13

developer   ~0042739

Sorry to say it does not.
It seems that the call to gtk_spin_button_update(PGtkSpinButton(Widget)) triggers another 'value-changed' signal, which then calls gtkchanged_spinbox() as it's callback routine.

Skipping the call to gtkchanged_spinbox() alltogether in results in a functional TFloatSpinEdit .

function gtkchanged_spinbox(widget: PGtkWidget; data: gPointer): GBoolean; cdecl;
begin
  Result := CallBackDefaultReturn;
  if LockOnChange(PgtkObject(Widget),0) > 0 then exit;
  if GTK_IS_SPIN_BUTTON(Widget) then
  begin
    //using this callback causes infinite loop in GTK2 <= 2.8
    if not (gtk_minor_version <= 8) then
      gtk_spin_button_update(PGtkSpinButton(Widget));
    Result := not CallBackDefaultReturn;
  end;
end;

(We need someone to test this with gtk2-10 ...)

This however re-introduces bug 0016410 for older GTK2 versions.
However this (16410) bug is more of an inconvenience as compared to the current one, since OnChanged is called when the control looses focus in this case (typing in the control).
It is better to live with that, then not being able to use the TFloatSpinEdit control at all IMHO.

Maybe you can think of a more definite solution?

Zeljan Rikalo

2010-11-04 08:00

developer   ~0042743

Last edited: 2010-11-04 08:01

Well, I know that I can add gtk_minor_version <= 8 and fix blocker, yes it opens 16410 for gtk2 <= 2.8, and I don't know how to fix it since I don't have gtk2 2.8.
My patch was just blind trial to fix it since I have not 2.8 to test.
Maybe stopping value-changed signal after update (for 2.8 only) could help.

Bart Broersma

2010-11-04 10:46

developer   ~0042747

I tried incrementing the LockCount with LockOnChange(PgtkObject(Widget),1) before the call to gtk_spin_button_update() and decrementing it thereafter, in the hope it would prevent re-entry of the event.
This kind of worked, but with the same side-effects as not calling gtk_spin_button_update() at all, and with the added "bonus" of making typing in the control somewhat erratic. So this was even worse ;-(

> Well, I know that I can add gtk_minor_version <= 8 and fix blocker ...

I wasn't trying to critisize. I know you know, you've done something like it before in the past for me, which is much appreciated.

The point I was trying to make is that if you/we run out of ideas (I'm happy to test anything), I'ld rather implement the blocking method for <= 2.8 and live with the imperfection in OnChange event.
That's the reason I described the effectos of my trials.

> Maybe stopping value-changed signal after update (for 2.8 only) could help

If you know how to do that (I know almost nothing about GTK (or other widgetsets)), I can re-test.

Zeljan Rikalo

2010-11-06 12:59

developer   ~0042821

I've downloaded Fedora 5 which have gtk2-2.8 , so I'll install it next days and try to fix 2.8 only bugs - that's all I can do.

Zeljan Rikalo

2011-01-21 16:49

developer   ~0045382

Please test and close if ok. It was an gtk2 < 2.12 bug.

Bart Broersma

2011-01-21 18:22

developer   ~0045385

Thank you very much.

Issue History

Date Modified Username Field Change
2010-11-03 15:57 Bart Broersma New Issue
2010-11-03 15:57 Bart Broersma LazTarget => -
2010-11-03 15:57 Bart Broersma Widgetset => GTK 2
2010-11-03 16:01 Zeljan Rikalo Note Added: 0042724
2010-11-03 16:01 Zeljan Rikalo Status new => feedback
2010-11-03 16:04 Zeljan Rikalo Note Added: 0042725
2010-11-03 16:07 Bart Broersma File Added: TFloatSpinEdit_SetParent_bug.tgz
2010-11-03 17:41 Bart Broersma Note Added: 0042728
2010-11-03 17:54 Bart Broersma Note Edited: 0042728
2010-11-03 20:13 Zeljan Rikalo File Added: gtkspinbutton.diff
2010-11-03 20:14 Zeljan Rikalo Note Added: 0042733
2010-11-03 20:14 Zeljan Rikalo Status feedback => acknowledged
2010-11-04 00:13 Bart Broersma Note Added: 0042739
2010-11-04 08:00 Zeljan Rikalo Note Added: 0042743
2010-11-04 08:01 Zeljan Rikalo Note Edited: 0042743
2010-11-04 10:46 Bart Broersma Note Added: 0042747
2010-11-06 12:59 Zeljan Rikalo Note Added: 0042821
2011-01-21 16:49 Zeljan Rikalo Fixed in Revision => 29157
2011-01-21 16:49 Zeljan Rikalo Status acknowledged => resolved
2011-01-21 16:49 Zeljan Rikalo Resolution open => fixed
2011-01-21 16:49 Zeljan Rikalo Assigned To => Zeljan Rikalo
2011-01-21 16:49 Zeljan Rikalo Note Added: 0045382
2011-01-21 18:22 Bart Broersma Status resolved => closed
2011-01-21 18:22 Bart Broersma Note Added: 0045385
2011-01-21 18:22 Bart Broersma Fixed in Version => 0.9.31 (SVN)