Recent

Author Topic: TForm.OnMouseLeave not working  (Read 9802 times)

Handoko

  • Hero Member
  • *****
  • Posts: 4087
  • My goal: build my own game engine using Lazarus
TForm.OnMouseLeave not working
« on: May 29, 2017, 08:17:43 pm »
As the title said, TForm.OnMouseLeave is not working correctly. I'm using Ubuntu Mate 16.10 64-bit Lazarus 1.6.4 FPC 3.0.2 GTK2.

You can try putting this code in OnMouseEnter and OnMouseLeave events:

Code: Pascal  [Select][+][-]
  1. procedure TForm1.FormMouseEnter(Sender: TObject);
  2. begin
  3.   Caption := 'Mouse Entered';
  4. end;
  5.  
  6. procedure TForm1.FormMouseLeave(Sender: TObject);
  7. begin
  8.   Caption := 'Mouse Left';
  9. end;

Does it work on your test? Let me know, so I will report it to the bug tracker forum.

GAN

  • Sr. Member
  • ****
  • Posts: 316
Re: TForm.OnMouseLeave not working
« Reply #1 on: May 29, 2017, 08:38:01 pm »
Yes, you're right, when I pass the mouse over a button or a grid of the form, then display "mouse left".

Linux Mint 17.2 64 bit Mate GTK2 - Lazarus 1.6 FPC 3.0.0
Lazarus 2.0.8 FPC 3.0.4 Linux Mint Mate 19.3
Zeos 7̶.̶2̶.̶6̶ 7.1.3a-stable - Sqlite 3.32.3

https://searchlazarus.blogspot.com/

Handoko

  • Hero Member
  • *****
  • Posts: 4087
  • My goal: build my own game engine using Lazarus
Re: TForm.OnMouseLeave not working
« Reply #2 on: May 29, 2017, 08:57:51 pm »
Maybe I don't understand how the Mouse Leave works. But I think it has 2 issues:

- If we move the mouse pointer to other controls (for example a button), that is still inside the form the OnMouseLeave will be triggered. I think it is wrong because that control is inside the form. Correct me if I'm wrong.

- If we move the mouse pointer from inside to the outside of the form, the OnMouseLeave will not be triggered. It is definitely wrong. (Actually, it will be triggered but at very low chances, perhaps 1% only)

Any test from others, maybe Windows?
« Last Edit: May 29, 2017, 09:14:20 pm by Handoko »

GetMem

  • Hero Member
  • *****
  • Posts: 3884
Re: TForm.OnMouseLeave not working
« Reply #3 on: May 29, 2017, 10:40:28 pm »
Quote
@Handoko
Does it work on your test? Let me know, so I will report it to the bug tracker forum.
It works both under windows and linux, but only if the form is empty. If you place another control, for example a memo with align-->alClient, the events are not triggered and AFAIK this is the intended behavior, because now the OnMouseEnter of the Memo is triggered instead.

As a workaround you can do something like this:
1. Drop a timer to your form, set interval to 50 ms
2. Declare a private variable FMouseOverForm
Code: Pascal  [Select][+][-]
  1. uses LCLIntf;
  2.  
  3. procedure TForm1.tmTimer(Sender: TObject);
  4. var
  5.   P: TPoint;
  6. begin
  7.   GetCursorPos(P);
  8.   P := ScreenToClient(P);
  9.   if (PtInRect(ClientRect, P)) and (not FMouseOverForm) then
  10.   begin
  11.     Caption := 'Mouse enter';
  12.     FMouseOverForm := True;
  13.   end else if (not PtInRect(ClientRect, P)) and (FMouseOverForm) then
  14.   begin
  15.     Caption := 'Mouse leave';
  16.     FMouseOverForm := False;
  17.   end;
  18. end;


PS: Alternatively you can redirect all OnMouseEnter/OnMouseLeave to a single event.

Handoko

  • Hero Member
  • *****
  • Posts: 4087
  • My goal: build my own game engine using Lazarus
Re: TForm.OnMouseLeave not working
« Reply #4 on: May 30, 2017, 03:57:51 am »
You solution using TTimer worked. And I understand your explanation about that intended behavior.

But you should test it yourself. On an empty form and move your the mouse pointer from inside to outside. It really a bug. 99% it won't be triggered, and only in some random chances it will be triggered correctly.

It could be something wrong with my Lazarus installation. But I won't think so because this trivial issue already bugged me from some previous versions.

sky_khan

  • Guest
Re: TForm.OnMouseLeave not working
« Reply #5 on: May 30, 2017, 05:11:29 am »
On windows (this is what i know), your window(form) wont get any messages when mouse not in your form. Only the window under mouse get windows messages. So when mouse leaves your form you're at dark. As far as I remember it is same in Delphi too.

Handoko

  • Hero Member
  • *****
  • Posts: 4087
  • My goal: build my own game engine using Lazarus
Re: TForm.OnMouseLeave not working
« Reply #6 on: May 30, 2017, 06:03:47 am »
Sounds reasonable. Because if the mouse pointer is no longer hovering on the window, it won't be monitored.

But it doesn't explain why on my test it still able to trigger OnMouseLeave event but only at very low rate.

Okay, let me explain what I actually want to do. I want to customize TDrawGrid appearance using OnCellDraw and OnPrepareCanvas. It worked, but I got mouse hovering problem. I want the cells will be automatically highlighted when the mouse hovering on it and the highlight is removed when the mouse pointer if not on the cell.

Below is the code, to make it simple I used TStringGrid and removed all unnecessary things:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Forms, Graphics, Grids;
  9.  
  10. type
  11.  
  12.   TForm1 = class(TForm)
  13.     StringGrid1: TStringGrid;
  14.     procedure FormCreate(Sender: TObject);
  15.     procedure StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
  16.       aState: TGridDrawState);
  17.   end;
  18.  
  19. var
  20.   Form1: TForm1;
  21.  
  22. implementation
  23.  
  24. {$R *.lfm}
  25.  
  26. procedure TForm1.StringGrid1PrepareCanvas(sender: TObject; aCol, aRow: Integer;
  27.   aState: TGridDrawState);
  28. begin
  29.   if gdHot in aState then
  30.     (sender as TStringGrid).Canvas.Brush.Color := clRed;
  31. end;
  32.  
  33. procedure TForm1.FormCreate(Sender: TObject);
  34. begin
  35.   StringGrid1.Options := StringGrid1.Options + [goHeaderHotTracking];
  36. end;
  37.  
  38. end.

Try to move your mouse pointer to highlight the cells and slowly move it outside. It should work correctly, but try it again with moving your mouse very quickly. The highlight won't be removed.

What I thought is perhaps because the mouse pointer movement is too fast, the grid doesn't properly detected the mouse leaving (from grid to the form). So, I think to solve it by adding code on TForm.OnMouseLeave to remove the grid highlight.

I also provided the downloadable code (test.zip) for you to test. Does it happen on Linux GTK2 only or also on other systems?
« Last Edit: May 30, 2017, 07:05:50 am by Handoko »

GetMem

  • Hero Member
  • *****
  • Posts: 3884
Re: TForm.OnMouseLeave not working
« Reply #7 on: May 30, 2017, 06:18:09 am »
@Handoko
I tested your demo application. Under windows the cell highlight is always removed no matter how fast I move my mouse. Under Linux(Gtk2) I was able to reproduce the issue, but even there only 1 times out of 10.

Handoko

  • Hero Member
  • *****
  • Posts: 4087
  • My goal: build my own game engine using Lazarus
Re: TForm.OnMouseLeave not working
« Reply #8 on: May 30, 2017, 06:27:17 am »
Thank you for testing it.

So, so far the conclusion is:
- On Windows, (visual components') mouse leaving is working as intended
- On Linux Gtk2, the mouse leaving is not 100% working

Any volunteer help me testing the code, please?

sky_khan

  • Guest
Re: TForm.OnMouseLeave not working
« Reply #9 on: May 30, 2017, 06:30:08 am »
On Windows 10 I could make it. I tried to move mouse too fast from grid to out of form, one in 8-10 times it stucks. I guess I can find a solution by using winapi but I dont know much about gtk or qt widgetsets.

Handoko

  • Hero Member
  • *****
  • Posts: 4087
  • My goal: build my own game engine using Lazarus
Re: TForm.OnMouseLeave not working
« Reply #10 on: May 30, 2017, 06:38:15 am »
So, the issue is reproducible. On my tests it almost always happens. Maybe because I use Compiz to add effects on my windows manager.

Using winapi to solve the issue on Windows is okay. But we know writing code to cover a bug isn't a best thing to do. The bug is still there.
« Last Edit: May 30, 2017, 06:39:53 am by Handoko »

sky_khan

  • Guest
Re: TForm.OnMouseLeave not working
« Reply #11 on: May 30, 2017, 07:04:42 am »
Yeah, my solution would be a workaround, not a real fix. You may have to resort to use workarounds if you are under a pressure to ship a software product in real world though :)

Handoko

  • Hero Member
  • *****
  • Posts: 4087
  • My goal: build my own game engine using Lazarus
Re: TForm.OnMouseLeave not working
« Reply #12 on: May 30, 2017, 07:17:43 am »
I don't write program for money. I do programming for fun. It is my personal trayicon Memopad. Very useful for programmers, if you ever used SideKick (for DOS) you know what I mean. It's almost finished just some improvements, I will put it on open source after I fix some remaining issues.

If you have time, please write the workaround. I use Linux but I believe someone will find it useful.

Ondrej Pokorny

  • Full Member
  • ***
  • Posts: 219
Re: TForm.OnMouseLeave not working
« Reply #13 on: May 30, 2017, 07:55:59 am »
IIRC, I fixed this in 1.7. Please retest in 1.8 RC1.

GetMem

  • Hero Member
  • *****
  • Posts: 3884
Re: TForm.OnMouseLeave not working
« Reply #14 on: May 30, 2017, 08:06:46 am »
@Ondrej

It's ok in windows with Lazarus trunk. Under linux(Gtk2) the issue is still present. I can reproduce it, if I try hard enough.

 

TinyPortal © 2005-2018