summary refs log tree commit diff stats
path: root/acdwm.scm
blob: fdd83958a218bef3c9c176e4f76d1c37f45115d7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#!/bin/sh
#| -*- scheme -*-
exec csi -ss "$0" "$@"                  ; acdwm
based on tinywm: https://github.com/mackstann/tinywm/
|#

(import (chicken bitwise)
        (chicken process-context)
        (srfi 1)
        matchable
        xlib)

(define TRUE 1)
(define FALSE 0)

(define dpy (make-parameter #f))
(define screen (make-parameter #f))
(define root (make-parameter #f))

(define (grab-keys)
  (xgrabkey (dpy)
            (char->integer (xkeysymtokeycode (dpy) (xstringtokeysym "F1")))
            MOD1MASK
            (root)
            TRUE
            GRABMODEASYNC
            GRABMODEASYNC)
  (xgrabbutton (dpy)
               1
               MOD1MASK
               (root)
               TRUE
               (bitwise-ior BUTTONPRESSMASK
                            BUTTONRELEASEMASK
                            POINTERMOTIONMASK)
               GRABMODEASYNC
               GRABMODEASYNC
               NONE
               NONE)
  (xgrabbutton (dpy)
               3
               MOD1MASK
               (root)
               TRUE
               (bitwise-ior BUTTONPRESSMASK
                            BUTTONRELEASEMASK
                            POINTERMOTIONMASK)
               GRABMODEASYNC
               GRABMODEASYNC
               NONE
               NONE))

(define (handle-events)
  (let ((event (make-xevent))
        (start (make-xbuttonevent))
        (attrs (make-xwindowattributes)))
    (set-xbuttonevent-subwindow! start NONE)
    (let loop ()
      (xnextevent (dpy) event)
      (cond
       ((and (= KEYPRESS (xevent-type event))
             (not (= NONE (xevent-xkey-subwindow event))))
        (xraisewindow (dpy) (xevent-xkey-subwindow event)))

       ((and (= BUTTONPRESS (xevent-type event))
             (not (= NONE (xevent-xbutton-subwindow event))))
        (print "button!")
        (xgetwindowattributes (dpy) (xevent-xbutton-subwindow event) attrs)
        (set-xbuttonevent-x_root! start (xevent-xbutton-x_root event))
        (set-xbuttonevent-y_root! start (xevent-xbutton-y_root event))
        (set-xbuttonevent-button! start (xevent-xbutton-button event))
        (set-xbuttonevent-subwindow! start (xevent-xbutton-subwindow event)))

       ((and (= MOTIONNOTIFY (xevent-type event))
             (not (= NONE (xbuttonevent-subwindow start))))
        (let ((xdiff (- (xevent-xbutton-x_root event)
                        (xbuttonevent-x_root start)))
              (ydiff (- (xevent-xbutton-y_root event)
                        (xbuttonevent-y_root start)))
              (button (xbuttonevent-button start)))
          (xmoveresizewindow (dpy)
                             (xbuttonevent-subwindow start)
                             (+ (xwindowattributes-x attrs)
                                (if (= button 1) xdiff 0))
                             (+ (xwindowattributes-y attrs)
                                (if (= button 1) ydiff 0))
                             (max 1 (+ (xwindowattributes-width attrs)
                                       (if (= button 3) xdiff 0)))
                             (max 1 (+ (xwindowattributes-height attrs)
                                       (if (= button 3) ydiff 0))))))

       ((= BUTTONRELEASE (xevent-type event))
        (print "buttonrelease!")
        (set-xbuttonevent-subwindow! start NONE)))

      ;; Annnd go around again
      (loop))))

(define (main args)
  (parameterize ((dpy (xopendisplay #f)))
    (assert (dpy))
    (parameterize ((screen (xdefaultscreen (dpy))))
      (parameterize ((root (xrootwindow (dpy) (screen))))
        (grab-keys)
        (handle-events)))))

(cond-expand
  ((or chicken-script compiling)
   (main (command-line-arguments)))
  (else))