1;; user.jl -- do user-local initialization
2;;
3;; Copyright (C) 2000 John Harper <john@dcs.warwick.ac.uk>
4;;
5;; This file is part of sawfish.
6;;
7;; sawfish is free software; you can redistribute it and/or modify it
8;; 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.
11;;
12;; sawfish is distributed in the hope that it will be useful, but
13;; 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.
16;;
17;; You should have received a copy of the GNU General Public License
18;; along with sawfish; see the file COPYING.  If not, write to
19;; the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20;; Boston, MA 02110-1301 USA.
21
22;; Commentary:
23
24;; The idea is that the `user' module is where all user code gets to
25;; play. By default it has a set of modules opened so that it looks
26;; pretty much how the old non-modular wm looked.
27
28;; This means that the `sawfish.wm' structures aren't modified by user
29;; code, this is a good thing, since it means that modules importing
30;; `sawfish.wm.foo' know what they are getting (no random user
31;; bindings)
32
33;; The downside is that it's harder for user extensions to redefine
34;; existing code, IMHO this may also be a good thing..
35
36(define-structure user
37
38    (export )
39
40    ((open rep
41	   rep.regexp
42	   rep.system
43	   rep.io.files
44	   rep.io.processes
45	   sawfish.wm
46	   sawfish.wm.util.groups
47	   sawfish.wm.util.display-window
48	   sawfish.wm.util.compat
49	   sawfish.wm.ext.error-handler
50	   sawfish.wm.ext.apps-menu
51	   sawfish.wm.edge.conf
52	   sawfish.wm.edge.actions
53	   sawfish.wm.frames
54	   sawfish.wm.menus
55	   sawfish.wm.commands.launcher
56	   sawfish.wm.ext.wallpaper
57	   sawfish.wm.prg.compton
58	   sawfish.wm.prg.conky
59	   sawfish.wm.prg.trayer
60	   sawfish.wm.prg.xgamma
61	   sawfish.wm.prg.xmobar
62	   sawfish.wm.prg.xmodmap
63	   sawfish.wm.prg.xsettingsd)
64     (access sawfish.wm.integration.kde
65	     sawfish.wm.integration.gnome
66	     sawfish.wm.integration.xfce
67	     sawfish.wm.integration.mate
68	     sawfish.wm.integration.lxde
69	     sawfish.wm.integration.lumina)
70
71     (set-binds))
72
73  ;; "none" looks ugly, but if you are to change it to "", fix
74  ;; apps-menu, too, or it will break.
75  (defvar desktop-environment "none"
76    "Running desktop environment, detected by Sawfish.
77Possible values are \"kde\", \"gnome\", \"mate\", \"xfce\", \"lxde\", \"lumina\" or \"none\".")
78
79  (defvar want-poweroff-menu t
80    "Add poweroff menu if you don't use GNOME / KDE / XFCE / Razor-Qt / LXDE / Lumina.")
81
82  (defvar want-extra-menu-entries t
83    "Provide additional entries in root menu.")
84
85  (setq *user-structure* 'user)
86
87  ;; frame-style loaded if user hasn't set their own
88  (define fallback-frame-style 'StyleTab)
89
90  ;; give root-window 'WINDOW_MANAGER property with value sawfish
91  (unless batch-mode
92    (set-x-text-property 'root 'WINDOW_MANAGER (vector "sawfish")))
93
94  (define rc-files '("~/.sawfishrc" "~/.sawfish/rc"))
95
96  ;; initialize the special variable pointing at this structure
97  (structure () (open rep rep.structures)
98    (setq *user-module* (get-structure 'user)))
99
100  (define (safe-load . args)
101    (condition-case data
102	(apply load args)
103      (error
104       (error-handler-function (car data) (cdr data)))))
105
106  (define (rename-old-stuff)
107    (when (and (file-directory-p "~/.sawmill")
108	       (not (file-exists-p "~/.sawfish")))
109      (rename-file "~/.sawmill" "~/.sawfish")
110      (message "Renamed directory ~/.sawmill -> ~/.sawfish")
111      (make-symlink "~/.sawmill" ".sawfish")
112      (message "Created .sawmill symlink (delete if unwanted)"))
113
114    (when (and (file-exists-p "~/.sawmillrc")
115	       (not (file-exists-p "~/.sawfishrc")))
116      (rename-file "~/.sawmillrc" "~/.sawfishrc")
117      (message "Renamed file ~/.sawmillrc -> ~/.sawfishrc"))
118    )
119
120  ;; Detect desktop environment.
121  ;; These functions have to non-nil if it detects a DE, otherwise nil.
122  ;; It should also initialize, and set `desktop-environment',
123  ;; and probably `want-poweroff-menu', too.
124  (define (detect-desktop-environment)
125    (or (sawfish.wm.integration.gnome#detect-gnome)
126	(sawfish.wm.integration.mate#detect-mate)
127	(sawfish.wm.integration.kde#detect-kde)
128	(sawfish.wm.integration.xfce#detect-xfce)
129	(sawfish.wm.integration.lxde#detect-lxde)
130	(sawfish.wm.integration.lumina#detect-lumina))
131    )
132
133  ;; Don't signal an error even if user "require" them. These modules
134  ;; existed in the past.
135  (provide 'sawfish-defaults)
136  (provide 'sawfish.wm.defaults)
137
138;;; From here, executed at startup.
139
140  ;; load ~/.sawfish/rc
141  (setq error-destination 'init)
142  (unless (get-command-line-option "--no-rc")
143    (condition-case error-data
144	(progn
145	  ;; First the site-wide stuff
146	  (load-all "site-init" (lambda (f) (safe-load f nil t)))
147
148	  ;; then the users rep configuration, or site-wide defaults
149	  (or (safe-load (concat (user-home-directory) ".reprc") t t t)
150	      (safe-load "rep-defaults" t))
151
152	  (unless batch-mode
153	    (rename-old-stuff)
154	    ;; detect DE before loading rc
155            (detect-desktop-environment)
156
157	    ;; then the customized options
158	    (condition-case data
159		(custom-load-user-file)
160	      (error
161	       (format (stderr-file) "error in custom file--> %S\n" data)))
162
163	    ;; then the sawfish specific user configuration
164	    (let loop ((rest rc-files))
165	      (when rest
166		(if (file-exists-p (car rest))
167		    ;; Print stack trace on error during exeuction
168		    ;; of ~/.sawfish/rc
169		    (let ((%in-condition-case nil))
170		      (safe-load (car rest) t t t))
171		  (loop (cdr rest)))))))
172      (error
173       (format (stderr-file) "error in local config--> %S\n" error-data))))
174
175  (when (equal desktop-environment "kde")
176    (sawfish.wm.integration.kde#kde-late-init))
177
178  (when (equal desktop-environment "lumina")
179    (sawfish.wm.integration.lumina#lumina-window-matchers))
180
181  (unless batch-mode
182    (when want-extra-menu-entries
183      (let ((menu root-menu))
184        (user-require 'sawfish.wm.ext.run-application)
185        (nconc menu `(()))
186	(unless (equal xterm-program "")
187	  (nconc menu `((,(_ "Open _Terminal") (xterm)))))
188        (unless (equal filemanager-program "")
189          (nconc menu `((,(_ "_Open Home") (filemanager "~")))))
190	(unless (equal browser-program "")
191	  (nconc menu `((,(_ "Open _Browser") (browser)))))
192	(nconc menu `((,(_ "_Run Application") (run-application))))
193        (nconc menu `((,(_ "_Kill Window") (system "xkill &")))))))
194
195  ;; generate apps-menu from *.desktop files
196  (unless batch-mode
197    (init-apps-menu))
198
199  ;; initialize edges, unless disabled
200  (when (and (not batch-mode)
201	   edge-actions-enabled)
202      (activate-edges t))
203
204  ;; apply customized frame-fonts
205  (when use-custom-font
206    (update-frame-font))
207
208  ;; apply customized font-colors
209  (when use-custom-font-color
210    (update-frame-font-color))
211
212  ;; apply customized cursor-shapes
213  (when use-custom-button-cursor-shape
214    (update-button-cursor-shape))
215
216  ;; apply customized border-width/color
217  (when use-custom-border
218    (update-border-color-width))
219
220  ;; apply customized text-position
221  (when use-custom-text-position
222    (update-text-position))
223
224  (when want-poweroff-menu
225    (add-poweroff-menu))
226
227  ;; use a default theme if none given
228  (unless (or batch-mode default-frame-style)
229    (setq default-frame-style fallback-frame-style))
230
231  (unless (and (boundp 'window-menu) window-menu)
232    (require 'sawfish.wm.ext.beos-window-menu))
233
234  ;; Use all arguments which are left.
235  (let ((do-load (lambda (name)
236		   (cond ((file-exists-p name)
237			  (load name nil t t))
238			 ((string-match "\\.jlc?$" name)
239			  (load name))
240			 (t (require (intern name))))))
241	arg)
242    (while (setq arg (car command-line-args))
243      (setq command-line-args (cdr command-line-args))
244      (cond
245       ((member arg '("-f" "--call"))
246	(setq arg (car command-line-args))
247	(setq command-line-args (cdr command-line-args))
248	((symbol-value (read-from-string arg))))
249       ((member arg '("-l" "--load"))
250	(setq arg (car command-line-args))
251	(setq command-line-args (cdr command-line-args))
252	(do-load arg))
253       ((member arg '("-q" "--quit"))
254	(throw 'quit 0))
255       (t (do-load arg)))))
256
257  (unless batch-mode
258    (add-hook 'before-restart-hook
259      (lambda () (let ((sc (get-window-by-class
260			     "Sawfish-Configurator" #:regex t)))
261		   (when sc
262		     (delete-window-safely sc)
263		     (system "touch ~/.restart_sc &")))))
264
265    (add-hook 'before-exit-hook
266      (lambda () (let ((sc (get-window-by-class
267			     "Sawfish-Configurator" #:regex t)))
268		   (when sc
269		     (delete-window-safely sc)))))
270
271    (when (file-exists-p "~/.restart_sc")
272      (system "sawfish-config &")
273      (delete-file "~/.restart_sc")))
274
275  ;; auto-start handling
276  (unless batch-mode
277    (when init-xgamma
278      (add-hook 'after-initialization-hook (lambda () (xgamma-set-from-cfg t t t)) t))
279    (when init-wallpaper
280      (add-hook 'after-initialization-hook set-wallpaper t))
281    (when init-trayer
282      (add-hook 'after-initialization-hook start-trayer t))
283    (when init-xmobar
284      (add-hook 'after-initialization-hook start-xmobar t))
285    (when init-xmodmap
286      (add-hook 'after-initialization-hook load-xmodmap t)
287      (add-hook 'before-restart-hook restore-keymap t))
288    (when init-xsettingsd
289      (add-hook 'after-initialization-hook start-xsettingsd t))
290    (when init-conky
291      (add-hook 'after-initialization-hook start-conky t)))
292
293  (when (eq error-destination 'init)
294    (setq error-destination 'standard-error)))
295
296;; prevent this file being loaded as a module
297nil
298