Forum > General

How to get user idle time in Linux?

(1/10) > >>

artem101:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---  TForm1 = class(TForm)    Timer1: TTimer;    procedure FormCreate(Sender: TObject);    procedure Timer1Timer(Sender: TObject);  private    LastInputTime: TDateTime;    function IdleTime: Cardinal;  public    procedure OnUserInputEvent(Sender: TObject; Msg: Cardinal);  end;   

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure TForm1.Timer1Timer(Sender: TObject);begin   Caption:=Format('idle for %d ms', [IdleTime]);end; procedure TForm1.FormCreate(Sender: TObject);begin  LastInputTime:=Now;end; function TForm1.IdleTime: Cardinal;begin  Result := MilliSecondsBetween(Now, LastInputTime);end; procedure TForm1.OnUserInputEvent(Sender: TObject; Msg: Cardinal);begin  LastInputTime := Now;end;    

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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:
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

AFFRIZA 亜風実:
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  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---    if XPending(Display) > 1 then    begin      { I have no idea about these codes, just copied from FPWM and it works }      XNextEvent(Display, @ev);    end    else if XPending(Display) = 1 then    begin      // here is user  activity      Synchronize(@Update);      // sometimes there's so much events      Sleep(500);      XNextEvent(Display, @ev);    end  
You can filter the event based on input only like this:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---    case ev._type of    ButtonPress,    ButtonRelease,    KeyPress,    KeyRelease:    begin        Synchronize(@Update);         // sometimes there's so much events        Sleep(500);    end;    XNextEvent(Display, @ev); 

winni:
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:

--- Quote from: AFFRIZA 亜風実 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
--- End quote ---

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.


--- Quote from: winni on June 22, 2022, 10:20:44 pm ---In the system palette there is a component "TIdleTimer".
That's what you want.
--- End quote ---

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.

Navigation

[0] Message Index

[#] Next page

Go to full version