Revision: mange@freemail.hu--2005/emacs-jabber--cvs-head--0--patch-556
[emacs-jabber.git] / jabber-autoaway.el
blob6707bd4c6364f62e8d9278cd67282e635759508c
1 ;;; jabber-autoaway.el --- change status to away after idleness
3 ;; Copyright (C) 2006, 2008 Magnus Henoch
5 ;; Author: Magnus Henoch <mange@freemail.hu>
7 ;; This file is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version.
12 ;; This file is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 ;; Boston, MA 02110-1301, USA.
22 (eval-when-compile (require 'cl))
23 (require 'time-date)
25 (defgroup jabber-autoaway nil
26 "Change status to away after idleness"
27 :group 'jabber)
29 (defcustom jabber-autoaway-method (cond
30 ((fboundp 'current-idle-time)
31 'jabber-current-idle-time)
32 ((getenv "DISPLAY")
33 'jabber-xprintidle-get-idle-time)
34 ((null window-system)
35 'jabber-termatime-get-idle-time))
36 "Method used to keep track of idleness.
37 This is a function that takes no arguments, and returns the
38 number of seconds since the user was active, or nil on error."
39 :group 'jabber-autoaway
40 :type '(choice (const :tag "Use `current-idle-time' function"
41 jabber-current-idle-time)
42 (const :tag "xprintidle"
43 jabber-xprintidle-get-idle-time)
44 (const :tag "Watch atime of terminal"
45 jabber-termatime-get-idle-time)
46 function
47 (const :tag "None" nil)))
49 (defcustom jabber-autoaway-timeout 5
50 "Minutes of inactivity before changing status to away"
51 :group 'jabber-autoaway
52 :type 'number)
54 (defcustom jabber-autoaway-status "Idle"
55 "Status string for autoaway"
56 :group 'jabber-autoaway
57 :type 'string)
59 (defcustom jabber-autoaway-priority nil
60 "Priority for autoaway.
61 If nil, don't change priority. See the manual for more
62 information about priority."
63 :group 'jabber-autoaway
64 :type '(choice (const :tag "Don't change")
65 (integer :tag "Priority"))
66 :link '(info-link "(jabber)Presence"))
68 (defcustom jabber-xprintidle-program (executable-find "xprintidle")
69 "Name of the xprintidle program"
70 :group 'jabber-autoaway
71 :type 'string)
73 (defcustom jabber-autoaway-verbose nil
74 "If nil, don't print autoaway status messages."
75 :group 'jabber-autoaway
76 :type 'boolean)
78 (defvar jabber-autoaway-timer nil)
80 (defvar jabber-autoaway-last-idle-time nil
81 "Seconds of idle time the last time we checked.
82 This is used to detect whether the user has become unidle.")
84 (defun jabber-autoaway-message (&rest args)
85 (when jabber-autoaway-verbose
86 (apply #'message args)))
88 (defun jabber-autoaway-start (&optional ignored)
89 "Start autoaway timer.
90 The IGNORED argument is there so you can put this function in
91 `jabber-post-connect-hooks'."
92 (interactive)
93 (unless jabber-autoaway-timer
94 (setq jabber-autoaway-timer
95 (run-with-timer (* jabber-autoaway-timeout 60) nil #'jabber-autoaway-timer))
96 (jabber-autoaway-message "Autoaway timer started")))
98 (defun jabber-autoaway-stop ()
99 "Stop autoaway timer."
100 (interactive)
101 (when jabber-autoaway-timer
102 (jabber-cancel-timer jabber-autoaway-timer)
103 (setq jabber-autoaway-timer nil)
104 (jabber-autoaway-message "Autoaway timer stopped")))
106 (defun jabber-autoaway-get-idle-time ()
107 "Get idle time in seconds according to chosen method.
108 Return nil on error."
109 (when jabber-autoaway-method (funcall jabber-autoaway-method)))
111 (defun jabber-autoaway-timer ()
112 ;; We use one-time timers, so reset the variable.
113 (setq jabber-autoaway-timer nil)
114 (let ((idle-time (jabber-autoaway-get-idle-time)))
115 (when (numberp idle-time)
116 ;; Has "idle timeout" passed?
117 (if (> idle-time (* 60 jabber-autoaway-timeout))
118 ;; If so, mark ourselves idle.
119 (jabber-autoaway-set-idle)
120 ;; Else, start a timer for the remaining amount.
121 (setq jabber-autoaway-timer
122 (run-with-timer (- (* 60 jabber-autoaway-timeout) idle-time)
123 nil #'jabber-autoaway-timer))))))
125 (defun jabber-autoaway-set-idle ()
126 (jabber-autoaway-message "Autoaway triggered")
127 ;; Send presence, unless the user has set a custom presence
128 (unless (member *jabber-current-show* '("away" "xa" "dnd"))
129 (jabber-send-presence
130 "away"
131 jabber-autoaway-status
132 (or jabber-autoaway-priority *jabber-current-priority*)))
134 (setq jabber-autoaway-last-idle-time (jabber-autoaway-get-idle-time))
135 ;; Run unidle timer every 10 seconds
136 (setq jabber-autoaway-timer (run-with-timer 10 10
137 #'jabber-autoaway-maybe-unidle)))
139 (defun jabber-autoaway-maybe-unidle ()
140 (let ((idle-time (jabber-autoaway-get-idle-time)))
141 (jabber-autoaway-message "Idle for %d seconds" idle-time)
142 ;; As long as idle time increases monotonically, stay idle.
143 (if (> idle-time jabber-autoaway-last-idle-time)
144 (progn
145 (setq jabber-autoaway-last-idle-time idle-time))
146 ;; But if it doesn't, go back to unidle state.
147 (jabber-autoaway-message "Back to unidle")
148 ;; But don't mess with the user's custom presence.
149 (if (string= *jabber-current-status* jabber-autoaway-status)
150 (jabber-send-default-presence)
151 (jabber-autoaway-message "%S /= %S - not resetting presence" *jabber-current-status* jabber-autoaway-status))
152 (jabber-autoaway-stop)
153 (jabber-autoaway-start))))
155 (defun jabber-xprintidle-get-idle-time ()
156 "Get idle time through the xprintidle program."
157 (when jabber-xprintidle-program
158 (with-temp-buffer
159 (when (zerop (call-process jabber-xprintidle-program
160 nil t))
161 (/ (string-to-number (buffer-string)) 1000.0)))))
163 (defun jabber-termatime-get-idle-time ()
164 "Get idle time through atime of terminal.
165 The method for finding the terminal only works on GNU/Linux."
166 (let ((terminal (cond
167 ((file-exists-p "/proc/self/fd/0")
168 "/proc/self/fd/0")
170 nil))))
171 (when terminal
172 (let* ((atime-of-tty (nth 4 (file-attributes terminal)))
173 (diff (time-to-seconds (time-since atime-of-tty))))
174 (when (> diff 0)
175 diff)))))
177 (defun jabber-current-idle-time ()
178 "Get idle time through `current-idle-time'.
179 `current-idle-time' was introduced in Emacs 22."
180 (let ((idle-time (current-idle-time)))
181 (if (null idle-time)
183 (float-time idle-time))))
185 (provide 'jabber-autoaway)
186 ;; arch-tag: 5bcea14c-842d-11da-a120-000a95c2fcd0