Hiding the mouse pointer (on Linux/GTK) lazarus / 31-LCL ---------------------------------------------------------------------- pleumann · 2023-10-14 07:03 Hi, is there an elegant way to hide the mouse pointer while my application is running (except setting the Cursor property for each and every form)? Best regards Joerg ---------------------------------------------------------------------- Handoko · 2023-10-14 07:47 I'm not sure but maybe you can try: 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   Application.MouseControl.Cursor := crNone; ---------------------------------------------------------------------- KodeZwerg · 2023-10-14 09:29 This works for me: 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 var  I: Integer;begin  for I := 0 to Pred(ControlCount) do    Controls[I].Cursor := crNone; // crDefault would show it againend; ---------------------------------------------------------------------- pleumann · 2023-10-14 16:14 Quote from: Handoko on October 14, 2023, 09:47:53 amI'm not sure but maybe you can try: 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   Application.MouseControl.Cursor := crNone; That seems to be the control currently under the mouse, so potentially nil. It crashed my application. ---------------------------------------------------------------------- pleumann · 2023-10-14 16:17 Quote from: KodeZwerg on October 14, 2023, 11:29:34 amThis works for me: 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 var  I: Integer;begin  for I := 0 to Pred(ControlCount) do    Controls[I].Cursor := crNone; // crDefault would show it againend; That would be within the context of a TForm? Does that mean it wouldn't be sufficient to set the Cursor on a higher level? ---------------------------------------------------------------------- pleumann · 2023-10-14 16:40 I have tried a few things by now. But maybe I should explain my application setup first: - I have a main form that is fullscreen in "real life", i.e. on the end users' machines. - This temporarily opens smaller, modal forms for certain functions the users perform. I gave my main form Cursor := crNone. This resulted in the cursor correctly disappearing when I launch my application, but it reappeared as soon as a modal form was opened on top. It was then visible everywhere, not only over the modal window. Closing the modal window let the cursor disappear again. I then gave all my modal forms Cursor := crNone, too. This, strangely, did not change the behavior described before. I found Screen.Cursor and tried this. Again, everything was fine for - and only for - the main form. Last but not least I tried something like this in the program's begin/end section, but with exactly the same outcome. 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   for I := 0 to Application.ComponentCount - 1 do    if Application.Components[I] is TForm then      with Application.Components[I] as TForm do        Cursor := crNone;  I am probably doing something wrong. Since what I aim for might be kind of special and I cannot compare to Delphi I might even have a wrong expectation. Any pointers or workarounds are appreciated. The behavior is on MacOS Monterey. Deployment will be on Linux/GTK, but I don't have access to my Linux box during the weekend, so I cannot say if the behavior is the same there. ---------------------------------------------------------------------- pleumann · 2023-10-14 16:44 If I combine my loop with the one suggested by KodeZwerg the cursor disappears on some areas of my modal forms, but not everywhere. It remains visible outside the modal forms. ---------------------------------------------------------------------- Handoko · 2023-10-14 16:48 Try this: 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 frmMain; {$mode objfpc}{$H+} interface uses  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, frmChild; type   { TMainForm }   TMainForm = class(TForm)    Button1: TButton;    CheckBox1: TCheckBox;    procedure Button1Click(Sender: TObject);    procedure CheckBox1Change(Sender: TObject);  end; var  MainForm: TMainForm; implementation {$R *.lfm} { TMainForm } procedure TMainForm.CheckBox1Change(Sender: TObject);var  C:    TCursor;  i, j: Integer;begin  case CheckBox1.Checked of    True:  C := crNone;    False: C := crDefault;  end;  for i := 0 to Screen.FormCount-1 do  begin    Screen.Forms[i].Cursor := C;    for j := 0 to Screen.Forms[i].ControlCount-1 do      Screen.Forms[i].Controls[j].Cursor := C;  end;end; procedure TMainForm.Button1Click(Sender: TObject);begin  if ChildForm.Showing then Exit;  ChildForm.Show;end; end. ---------------------------------------------------------------------- pleumann · 2023-10-14 17:40 Quote from: Handoko on October 14, 2023, 06:48:41 pmTry this: ... Thanks a lot for taking the time to build this example. It basically works, but it's slighty different to / simpler than my setup. If you change the Show to ShowModal and add something like a Memo to TChildForm you might be able to reproduce my problem (which could also be limited to the widget set on MacOS): - The cursor is suddenly visible everywhere outside ChildForm [caused by ShowModal] - The cursor is visible when you hover over the Memo in ChildForm [caused by the Memo] I still learned something from it: Screen.Forms seems to contain all forms, not just the visible ones. Apart from that you seem to use the same loop over all forms / all controls that I tried. ---------------------------------------------------------------------- jamie · 2023-10-14 18:14 Screen.cursor := crnone; That does not work. you can only hide the cursor pure your app, the whole screen system wide is os-widget dependent. So if your covers the whole screen then this should work. ---------------------------------------------------------------------- wp · 2023-10-14 18:19 Quote from: pleumann on October 14, 2023, 09:03:56 amis there an elegant way to hide the mouse pointer while my application is running (except setting the Cursor property for each and every form)? Applications in which the mouse cursor suddenly disappears alway give me the impression that something is broken... ---------------------------------------------------------------------- pleumann · 2023-10-14 18:28 Quote from: wp on October 14, 2023, 08:19:10 pmQuote from: pleumann on October 14, 2023, 09:03:56 amis there an elegant way to hide the mouse pointer while my application is running (except setting the Cursor property for each and every form)? Applications in which the mouse cursor suddenly disappears alway give me the impression that something is broken... The app is not supposed to be controlled with a mouse, but purely with joysticks. So the cursor is actually confusing. But in general you are right, of course. ---------------------------------------------------------------------- pleumann · 2023-10-14 18:32 Quote from: jamie on October 14, 2023, 08:14:35 pmScreen.cursor := crnone; That does not work. you can only hide the cursor pure your app, the whole screen system wide is os-widget dependent. So if your covers the whole screen then this should work. That was my expectation, and the app is fullscreen, but still I run into trouble with a) modal windows on top and b) some widgets. ---------------------------------------------------------------------- Handoko · 2023-10-14 18:46 Quote from: pleumann on October 14, 2023, 08:28:56 pmThe app is not supposed to be controlled with a mouse, but purely with joysticks. If you're writing games, you should use libraries created for games. They have features to hide mouse pointer and text caret, and going full screen. I failed to fully hiding the mouse pointer on TMemo but writing an alternative for TMemo isn't hard. You only need to know: - How to use TCanvas to write text - How to read user key input - How to write a visual component I wish I time so I can write it for you, unfortunately I am a bit busy this weekend. ---------------------------------------------------------------------- TRon · 2023-10-14 19:13 Quote from: Handoko on October 14, 2023, 08:46:08 pmIf you're writing games, you should use libraries created for games. They have features to hide mouse pointer and text caret, and going full screen. I have not read (but it might be I overlooked) anything by TS mentioning a game. In general sense you are ofc correct but have you considered that TS is perhaps writing a front-end (for an emulator for example) which makes it very confusing to switch between joystick and mouse only to navigate on a form with some buttons ? Also not all people are capable of navigating using a mouse. ---------------------------------------------------------------------- pleumann · 2023-10-15 08:08 It's not a game. It's more like a setup system for a gaming hardware that does only feature joysticks, so "front-end for an emulator" is pretty close. To not re-invent the wheel I chose to leverage as much of LCL's standard controls as possible, but made sure everything is accessible without the mouse. A background thread translates joystick events to keyboard events. It works nicely. The mouse pointer is a bit annoying, but mostly a cosmetic thing. I could easily use unclutter to get rid of it permanently or move it to the lower right corner, so that only 1 pixel is actually visible. But if there is an easy solution based on LCL itself (such as Cursor := crNone), I'd prefer that. ---------------------------------------------------------------------- pleumann · 2023-10-16 11:22 Update: Interestingly, the LCL behaves differently for GTK/Linux (where we ultimately deploy our application). Just as for MacOS, I would need to set crNone for more than just the forms (the memos, for instance). But I don't have the problem that showing a modal window will make the mouse visible again, even for areas where it was invisible a moment ago. This might be a bug in the MacOS widget set. If someone tells me it's worth doing, I will open a ticket. But I think it's tricky enough to manage 99% common behavior for so many different systems and UI toolkits, so I can accept if this is in the 1%. My current solution is this: - I set my main form (which is fullscreen) to crNone - I move the mouse pointer to a location that will never be occupied by another form or control. Thanks, everyone!