Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2009-12

Issue 15351 - Screen.Cursor from a TGroupBox fails (GTK2)

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Alexsander Rosa

Screen.Cursor from INSIDE a TGroupBox fails
http://bugs.freepascal.org/view.php?id=15351

1. Create a new project (on Linux Ubuntu 9.04)
2. Place a TGroupBox anywhere
3. Place a TButton inside the TGroupBox
4. Copy the following code into TButton.Click

  Screen.Cursor := crSQLWait;
  Application.ProcessMessages;
  Sleep(1000);
  Screen.Cursor := crHourGlass;
  Application.ProcessMessages;
  Sleep(1000);
  Screen.Cursor := crDefault;
  Application.ProcessMessages;

5. Run the project, click the button. The cursor will change from crSQLWait to crHourGlass, then to crDefault. Now move the cursor around the form: while inside the GroupBox (but outside the Button) the cursor will be crHourGlass; in all other areas of the form it will be the crDefault.

PS: The bug report includes a complete example (small project).

Atenciosamente, Alexsander da Rosa Linux User #113925 "Extremismo na defesa da liberdade n?o ? defeito. Modera??o na busca por justi?a n?o ? virtude." -- Barry Goldwater -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20091215/70c82533/attachment.html>

Reply by email

Alexsander Rosa
to Alexsander Rosa

I'm looking for a solution for this, it seems the actual cursor change occurs here:

*$LAZHOME/lcl/interfaces/gtk/gtkwinapi.inc (function TGtkWidgetSet.SetCursor)*

Am I correct? The function SetCursor() has a few internal functions. Why is there both a SetGlobalCursor() and a ResetGlobalCursor()? SetGlobalCursor() seems to be more straightforward than ResetGlobalCursor(). In theory we could always use SetGlobalCursor(), even when it's the default, right?
Maybe there's some extra stuff that need to be done when the cursor is crDefault?

If this code is correct, maybe the problem (assuming there's a problem) is in TGroupBox.
Maybe it's not being visited in that traversing loop at ResetGlobalCursor() for some reason.

PS: Should I add this to the bug report as a note?

2009/12/15 Alexsander Rosa

Show quoted text 25 lines
Screen.Cursor from INSIDE a TGroupBox fails http://bugs.freepascal.org/view.php?id=15351 1. Create a new project (on Linux Ubuntu 9.04) 2. Place a TGroupBox anywhere 3. Place a TButton inside the TGroupBox 4. Copy the following code into TButton.Click Screen.Cursor := crSQLWait; Application.ProcessMessages; Sleep(1000); Screen.Cursor := crHourGlass; Application.ProcessMessages; Sleep(1000); Screen.Cursor := crDefault; Application.ProcessMessages; 5. Run the project, click the button. The cursor will change from crSQLWait to crHourGlass, then to crDefault. Now move the cursor around the form: while inside the GroupBox (but outside the Button) the cursor will be crHourGlass; in all other areas of the form it will be the crDefault. PS: The bug report includes a complete example (small project).
Atenciosamente, Alexsander da Rosa Linux User #113925 "Extremismo na defesa da liberdade n?o ? defeito. Modera??o na busca por justi?a n?o ? virtude." -- Barry Goldwater -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20091216/c4ab4170/attachment.html>

Reply by email

Paul Ishenin
to Alexsander Rosa
Alexsander Rosa wrote 7 lines
I'm looking for a solution for this, it seems the actual cursor change occurs here: *$LAZHOME/lcl/interfaces/gtk/gtkwinapi.inc (function TGtkWidgetSet.SetCursor)* Am I correct?

yes

Show quoted text 6 lines
The function SetCursor() has a few internal functions. Why is there both a SetGlobalCursor() and a ResetGlobalCursor()? SetGlobalCursor() seems to be more straightforward than ResetGlobalCursor(). In theory we could always use SetGlobalCursor(), even when it's the default, right?

no. different controls have different cursors. and not always default. SetGlobalCursor stores previos cursor in the widget and resets it on ResetGlobalCursor

Show quoted text 7 lines
Maybe there's some extra stuff that need to be done when the cursor is crDefault? If this code is correct, maybe the problem (assuming there's a problem) is in TGroupBox. Maybe it's not being visited in that traversing loop at ResetGlobalCursor() for some reason.

yes, there is some code in the private classes which needs to be adopted for groupbox.

PS: Should I add this to the bug report as a note?

No need to add. I know what's happening but as usual fixing requires at least some free time to test.

Best regards,
Paul Ishenin.

Reply by email

Alexsander Rosa
to Paul Ishenin

Let me know if you want me to take a look on that, just point me what has to be done and where.
I have some rusty GTK knowledge, mostly from Griffith's "GNOME/GTK+ Programming Bible".

2009/12/16 Paul Ishenin

Show quoted text 18 lines
If this code is correct, maybe the problem (assuming there's a problem) is > in TGroupBox. > Maybe it's not being visited in that traversing loop at > ResetGlobalCursor() for some reason. > yes, there is some code in the private classes which needs to be adopted for groupbox. > PS: Should I add this to the bug report as a note? > No need to add. I know what's happening but as usual fixing requires at least some free time to test. Best regards, Paul Ishenin.
Atenciosamente, Alexsander da Rosa Linux User #113925 "Extremismo na defesa da liberdade n?o ? defeito. Modera??o na busca por justi?a n?o ? virtude." -- Barry Goldwater -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20091216/2ae2e45e/attachment.html>

Reply by email

Paul Ishenin
to Alexsander Rosa
Alexsander Rosa wrote
Let me know if you want me to take a look on that, just point me what has to be done and where. I have some rusty GTK knowledge, mostly from Griffith's "GNOME/GTK+ Programming Bible".

don't know another solution now although I don't like the fix (due to recursion it needs).

The problem with cursors is that they can't assigned to widgets - they needs to be assigned to windows. Not every widget has its own window and some widgets don't give an access for their internal windows.

In the example TGroupBox consists of 3 widgets:

1. GtkFrame - for drawing frame around
2. GtkEventWindow - to handle events (clicks, focus, ...)
3. GtkFixed - to allow setting custom children positions

Only GtkEventWindow has a window but it does not provide any API to access it. Therefore we can only access the parent window of TGroupBox - TForm in this case. And we need to start traversing all the windows starting from the one TForm has. I wrote a new method of cursor changing now - it gets a widget from the window (every widget stores itself in the window it has using gdk_window_set_user_data) and gets WidgetInfo we stores for every widget we create. So if a window has a widget and the widget has a WidgetInfo wich equals to WidgetInfo of our control (of TGroupBox for example) then we can change the cursor for the window.

Probably we can simplify ResetGlobalCursor to call:

       if GtkWidgetIsA(Widget, gtk_widget_get_type)
       then begin
         WidgetInfo := GetWidgetInfo(Widget);
         SetWindowCursor(AWindow, WidgetInfo^.ControlCursor, False);
       end;

But I have not tested this idea yet.

Best regards,
Paul Ishenin.

Reply by email