Recent

Author Topic: How to get user idle time in Linux?  (Read 1788 times)

artem101

  • New Member
  • *
  • Posts: 38
How to get user idle time in Linux?
« on: June 19, 2022, 04:36:02 pm »
I want to get user idle time (i.e. when no mouse moving or key pressing). I search something like GetLastInputInfo from WinApi, but for Linux.

I find this solution:
Code: Pascal  [Select][+][-]
  1.   TForm1 = class(TForm)
  2.     Timer1: TTimer;
  3.     procedure FormCreate(Sender: TObject);
  4.     procedure Timer1Timer(Sender: TObject);
  5.   private
  6.     LastInputTime: TDateTime;
  7.     function IdleTime: Cardinal;
  8.   public
  9.     procedure OnUserInputEvent(Sender: TObject; Msg: Cardinal);
  10.   end;  
  11.  

Code: Pascal  [Select][+][-]
  1. procedure TForm1.Timer1Timer(Sender: TObject);
  2. begin
  3.    Caption:=Format('idle for %d ms', [IdleTime]);
  4. end;
  5.  
  6. procedure TForm1.FormCreate(Sender: TObject);
  7. begin
  8.   LastInputTime:=Now;
  9. end;
  10.  
  11. function TForm1.IdleTime: Cardinal;
  12. begin
  13.   Result := MilliSecondsBetween(Now, LastInputTime);
  14. end;
  15.  
  16. procedure TForm1.OnUserInputEvent(Sender: TObject; Msg: Cardinal);
  17. begin
  18.   LastInputTime := Now;
  19. end;    

Code: Pascal  [Select][+][-]
  1. Application.OnUserInput:=@Form1.OnUserInputEvent;

But it works only when window has focus, and doesn't work when window hidden or minimized to tray. So this is not what I exactly need. Any other ideas?

MarkMLl

  • Hero Member
  • *****
  • Posts: 4505
Re: How to get user idle time in Linux?
« Reply #1 on: June 19, 2022, 05:20:46 pm »
Look in the /proc tree, that's where the overall and per-process information is stored.

Note however that Linux won't distinguish between CPU time which is handling per-process GUI stuff, and CPU time going to number crunching. Also that some parts of the UI will be handled by the X11 server etc., so probably won't be attributed on a per-process basis.

HTH

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

AFFRIZA 亜風実

  • Full Member
  • ***
  • Posts: 136
Re: How to get user idle time in Linux?
« Reply #2 on: June 22, 2022, 10:07:36 pm »
Maybe you can look to unit I've made here if you're using XServer: https://github.com/kirana-a2district/kiranacore-pkg/blob/main/src/xeventwatcher.pas

You can look at line 71, if there's XPending more than zero then there's some activities by user or app
Code: Pascal  [Select][+][-]
  1.     if XPending(Display) > 1 then
  2.     begin
  3.       { I have no idea about these codes, just copied from FPWM and it works }
  4.       XNextEvent(Display, @ev);
  5.     end
  6.     else if XPending(Display) = 1 then
  7.     begin
  8.       // here is user  activity
  9.       Synchronize(@Update);
  10.       // sometimes there's so much events
  11.       Sleep(500);
  12.       XNextEvent(Display, @ev);
  13.     end
  14.  
  15.  

You can filter the event based on input only like this:
Code: Pascal  [Select][+][-]
  1.     case ev._type of
  2.     ButtonPress,
  3.     ButtonRelease,
  4.     KeyPress,
  5.     KeyRelease:
  6.     begin
  7.         Synchronize(@Update);
  8.          // sometimes there's so much events
  9.         Sleep(500);
  10.     end;
  11.     XNextEvent(Display, @ev);
  12.  
Kyoukai Framework: https://github.com/afuriza/kyoukai_framework

Dukung kemerdekaan Donetsk dan Lugansk! Tidak membalas profil berbendera biru-kuning apalagi ber-Bandera.

winni

  • Hero Member
  • *****
  • Posts: 3099
Re: How to get user idle time in Linux?
« Reply #3 on: June 22, 2022, 10:20:44 pm »
Hi!

In the system palette there is a component "TIdleTimer".
That's what you want.

It measures the time when no user input happens (keyboard or mouse)
Set Enabled:=False and AutoEnabled:=True
Sit back in amazment.

If you want the delta to the total time add a "normal" Ttimer and compute the difference of these both.

Winni

PascalDragon

  • Hero Member
  • *****
  • Posts: 4168
  • Compiler Developer
Re: How to get user idle time in Linux?
« Reply #4 on: June 23, 2022, 09:05:30 am »
Maybe you can look to unit I've made here if you're using XServer: https://github.com/kirana-a2district/kiranacore-pkg/blob/main/src/xeventwatcher.pas

Just to be sure in case this isn't obvious: if you have a system that uses Wayland instead of X11 then this won't help you.

In the system palette there is a component "TIdleTimer".
That's what you want.

Not quite, because TIdleTimer can only handle user input that the application knows of. If the application isn't active and didn't install some global hook and the user does not interact with it, but interacts with the system in general there won't be any event. GetLastInputInfo on Windows works globally and thus would catch such.

Thaddy

  • Hero Member
  • *****
  • Posts: 11637
Re: How to get user idle time in Linux?
« Reply #5 on: June 23, 2022, 10:06:26 am »
The easy way is use Tprocess or TprocessAsynch and call top and parse its output, but it is certainly possible to write it in pure pascal, since it supports all code needed. You can write a top clone in FreePascal.
Black themes should be banned.

Soner

  • Sr. Member
  • ****
  • Posts: 280
Re: How to get user idle time in Linux?
« Reply #6 on: June 23, 2022, 10:38:50 am »
Isn't it Application.OnIdle event?

Thaddy

  • Hero Member
  • *****
  • Posts: 11637
Re: How to get user idle time in Linux?
« Reply #7 on: June 23, 2022, 11:22:21 am »
Isn't it Application.OnIdle event?
No, that is not measuring idle time.  It just detect idle.
Black themes should be banned.

AFFRIZA 亜風実

  • Full Member
  • ***
  • Posts: 136
Re: How to get user idle time in Linux?
« Reply #8 on: June 23, 2022, 03:06:58 pm »
Just to be sure in case this isn't obvious: if you have a system that uses Wayland instead of X11 then this won't help you.
Thankyou, I forgot to mentioning that  :-[
Anyway, talking about Wayland. Is there any FPC unit I available to communicate with Wayland? Something like "uses x, xlib;"
Kyoukai Framework: https://github.com/afuriza/kyoukai_framework

Dukung kemerdekaan Donetsk dan Lugansk! Tidak membalas profil berbendera biru-kuning apalagi ber-Bandera.

Fred vS

  • Hero Member
  • *****
  • Posts: 2570
    • StrumPract is the musicians best friend
Re: How to get user idle time in Linux?
« Reply #9 on: June 23, 2022, 03:22:24 pm »
Maybe you can look to unit I've made here if you're using XServer: https://github.com/kirana-a2district/kiranacore-pkg/blob/main/src/xeventwatcher.pas

Just to be sure in case this isn't obvious: if you have a system that uses Wayland instead of X11 then this won't help you.

For info, each Wayland system has, by default, XWayland installed that will (afaik) translate idle check.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs

AFFRIZA 亜風実

  • Full Member
  • ***
  • Posts: 136
Re: How to get user idle time in Linux?
« Reply #10 on: June 23, 2022, 04:32:08 pm »
For info, each Wayland system has, by default, XWayland installed that will (afaik) translate idle check.
I've tried to make a sample app using my XEventWatcher unit in KDE Wayland and it doesn't register any input at all, it just looping in the XNextEvent for eternity.
Kyoukai Framework: https://github.com/afuriza/kyoukai_framework

Dukung kemerdekaan Donetsk dan Lugansk! Tidak membalas profil berbendera biru-kuning apalagi ber-Bandera.

Fred vS

  • Hero Member
  • *****
  • Posts: 2570
    • StrumPract is the musicians best friend
Re: How to get user idle time in Linux?
« Reply #11 on: June 23, 2022, 05:41:13 pm »
For info, each Wayland system has, by default, XWayland installed that will (afaik) translate idle check.
I've tried to make a sample app using my XEventWatcher unit in KDE Wayland and it doesn't register any input at all, it just looping in the XNextEvent for eternity.

Hum, could you be kind and create a issue here? :
https://gitlab.freedesktop.org/xorg/xserver/-/issues

Thanks.
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs

Fred vS

  • Hero Member
  • *****
  • Posts: 2570
    • StrumPract is the musicians best friend
Re: How to get user idle time in Linux?
« Reply #12 on: June 23, 2022, 05:54:45 pm »
Anyway, talking about Wayland. Is there any FPC unit I available to communicate with Wayland? Something like "uses x, xlib;"

Hello.

https://github.com/andrewd207/fpc-wayland
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs

AFFRIZA 亜風実

  • Full Member
  • ***
  • Posts: 136
Re: How to get user idle time in Linux?
« Reply #13 on: June 23, 2022, 09:00:02 pm »
Hum, could you be kind and create a issue here? :
https://gitlab.freedesktop.org/xorg/xserver/-/issues

Thanks.
Sorry, I don't want to report anything to XOrg. I have give up to report anything to them. I have a capslock delay issues on all my 5 laptops for decade and they didn't even want to apply the patch because of "muh typewriters behavior" reason.

Hello.

https://github.com/andrewd207/fpc-wayland
Thanks. But, this is not official in FPC(yet)?
« Last Edit: June 23, 2022, 09:02:12 pm by AFFRIZA 亜風実 »
Kyoukai Framework: https://github.com/afuriza/kyoukai_framework

Dukung kemerdekaan Donetsk dan Lugansk! Tidak membalas profil berbendera biru-kuning apalagi ber-Bandera.

artem101

  • New Member
  • *
  • Posts: 38
Re: How to get user idle time in Linux?
« Reply #14 on: June 23, 2022, 09:19:06 pm »
It's a pity that there are no elegant solution for any Linux distribution and any graphical environment.

 

TinyPortal © 2005-2018