parent
0598918d0c
commit
985b20dcb2
|
@ -0,0 +1,86 @@
|
||||||
|
(define-record-type icon :icon
|
||||||
|
(make-icon wm client window)
|
||||||
|
icon?
|
||||||
|
(wm icon:wm)
|
||||||
|
(client icon:client)
|
||||||
|
(window icon:window))
|
||||||
|
|
||||||
|
(define (create-icon wm client rect)
|
||||||
|
(let* ((dpy (wm:dpy wm))
|
||||||
|
(window (create-simple-window dpy (wm:window wm)
|
||||||
|
(rectangle:x rect) (rectangle:y rect)
|
||||||
|
(rectangle:width rect)
|
||||||
|
(rectangle:height rect)
|
||||||
|
0
|
||||||
|
(black-pixel dpy) (white-pixel dpy)))
|
||||||
|
(gc (create-gc dpy window
|
||||||
|
(make-gc-value-alist
|
||||||
|
(foreground (black-pixel dpy))
|
||||||
|
(background (white-pixel dpy))))))
|
||||||
|
(spawn*
|
||||||
|
(list 'move-wm-icon wm client window)
|
||||||
|
(lambda (release)
|
||||||
|
(call-with-current-continuation
|
||||||
|
(lambda (exit)
|
||||||
|
(call-with-event-channel
|
||||||
|
dpy window (event-mask exposure
|
||||||
|
structure-notify
|
||||||
|
button-press)
|
||||||
|
(lambda (event-channel)
|
||||||
|
(release)
|
||||||
|
(let loop ()
|
||||||
|
(let ((xevent (receive event-channel)))
|
||||||
|
(cond
|
||||||
|
((destroy-window-event? xevent) (exit 'destroyed))
|
||||||
|
|
||||||
|
((expose-event? xevent)
|
||||||
|
(if (= 0 (expose-event-count xevent))
|
||||||
|
(draw-icon dpy window gc client)))
|
||||||
|
|
||||||
|
((and (button-event? xevent)
|
||||||
|
(eq? (event-type button-press)
|
||||||
|
(button-event-type xevent)))
|
||||||
|
(send (wm:internal-out-channel wm)
|
||||||
|
(list 'normalize-client client))
|
||||||
|
(exit 'normalized)))
|
||||||
|
(loop)))))))
|
||||||
|
(free-gc dpy gc)))
|
||||||
|
(make-icon wm client window)))
|
||||||
|
|
||||||
|
(define (map-icon icon)
|
||||||
|
(map-window (wm:dpy (icon:wm icon)) (icon:window icon)))
|
||||||
|
|
||||||
|
(define (destroy-icon icon)
|
||||||
|
(destroy-window (wm:dpy (icon:wm icon)) (icon:window icon)))
|
||||||
|
|
||||||
|
(define (draw-icon dpy window gc client)
|
||||||
|
(let ((title (client-name dpy client)) ;; or WM_ICON_NAME ??
|
||||||
|
(r (clip-rectangle dpy window)))
|
||||||
|
(draw-image-string dpy window gc 2 14 title)))
|
||||||
|
|
||||||
|
(define (find-icon-rect wm-rect icons)
|
||||||
|
(let* ((icon-w 200)
|
||||||
|
(icon-h 18)
|
||||||
|
(xs (iota (quotient (rectangle:width wm-rect) icon-w)))
|
||||||
|
(ys (reverse (iota (quotient (rectangle:height wm-rect) icon-h))))
|
||||||
|
(all (flatten (map (lambda (yi)
|
||||||
|
(map (lambda (xi)
|
||||||
|
(make-rectangle (* xi icon-w)
|
||||||
|
(* yi icon-h)
|
||||||
|
icon-w icon-h))
|
||||||
|
xs))
|
||||||
|
ys)))
|
||||||
|
(icon-rects (map (lambda (i)
|
||||||
|
(window-rectangle (wm:dpy (icon:wm i))
|
||||||
|
(icon:window i)))
|
||||||
|
icons))
|
||||||
|
(free (filter (lambda (r)
|
||||||
|
(not (any (lambda (ir)
|
||||||
|
(rectangles-overlap? r ir))
|
||||||
|
icon-rects)))
|
||||||
|
all)))
|
||||||
|
(if (null? free)
|
||||||
|
(if (null? all)
|
||||||
|
(make-rectangle 0 0 icon-w icon-h)
|
||||||
|
(car all))
|
||||||
|
(car free))))
|
|
@ -12,7 +12,9 @@
|
||||||
|
|
||||||
(define (create-move-wm out-channel dpy parent options default-options
|
(define (create-move-wm out-channel dpy parent options default-options
|
||||||
. children)
|
. children)
|
||||||
(create-wm dpy parent options default-options children
|
(create-wm dpy parent options (append default-options
|
||||||
|
'((focus-policy . (click))))
|
||||||
|
children
|
||||||
(manager-type move) move-wm-options-spec
|
(manager-type move) move-wm-options-spec
|
||||||
out-channel
|
out-channel
|
||||||
(lambda (wm in-channel)
|
(lambda (wm in-channel)
|
||||||
|
@ -77,6 +79,33 @@
|
||||||
(append (make-window-change-alist
|
(append (make-window-change-alist
|
||||||
(border-width 0))
|
(border-width 0))
|
||||||
changes))))
|
changes))))
|
||||||
|
|
||||||
|
((iconify-client)
|
||||||
|
(let ((client (second msg)))
|
||||||
|
(if (not (client-data:icon client))
|
||||||
|
(begin
|
||||||
|
(unmap-window dpy (client:client-window client))
|
||||||
|
(unmap-window dpy (client:window client))
|
||||||
|
(set-wm-state! dpy (client:window client) (wm-state iconic)
|
||||||
|
none)
|
||||||
|
(let ((icon (create-client-icon wm client)))
|
||||||
|
(set-client-data:icon! client icon)
|
||||||
|
(map-icon icon))))))
|
||||||
|
|
||||||
|
((maximize-client)
|
||||||
|
(let ((client (second msg)))
|
||||||
|
(maximize-window dpy (client:client-window client))))
|
||||||
|
|
||||||
|
((normalize-client)
|
||||||
|
(let ((client (second msg)))
|
||||||
|
(if (client-data:icon client)
|
||||||
|
(begin
|
||||||
|
(destroy-icon (client-data:icon client))
|
||||||
|
(map-window dpy (client:window client))
|
||||||
|
(map-window dpy (client:client-window client))
|
||||||
|
(set-wm-state! dpy (client:window client) (wm-state normal)
|
||||||
|
none)
|
||||||
|
(set-client-data:icon! client #f)))))
|
||||||
|
|
||||||
((draw-client-window)
|
((draw-client-window)
|
||||||
(draw-client-window wm (second msg) gc))
|
(draw-client-window wm (second msg) gc))
|
||||||
|
@ -97,17 +126,41 @@
|
||||||
(state (if focused?
|
(state (if focused?
|
||||||
'focused
|
'focused
|
||||||
'normal))
|
'normal))
|
||||||
(titlebar (car (client:data client))))
|
(titlebar (client-data:titlebar client)))
|
||||||
(set-titlebar-state! titlebar state)))
|
(set-titlebar-state! titlebar state)))
|
||||||
|
|
||||||
((update-client-name)
|
((update-client-name)
|
||||||
(let ((client (second msg))
|
(let ((client (second msg))
|
||||||
(name (third msg)))
|
(name (third msg)))
|
||||||
(let ((titlebar (car (client:data client))))
|
(let ((titlebar (client-data:titlebar client)))
|
||||||
(set-titlebar-title! titlebar name))))
|
(set-titlebar-title! titlebar name))))
|
||||||
|
|
||||||
|
((show-clients)
|
||||||
|
(let ((clients (second msg)))
|
||||||
|
(for-each (lambda (c)
|
||||||
|
(if (client-data:icon c)
|
||||||
|
(handle-message wm gc exit
|
||||||
|
(list 'normalize-client c)))
|
||||||
|
(raise-window dpy (client:client-window c)))
|
||||||
|
clients)))
|
||||||
|
|
||||||
(else (warn "unhandled move-wm message" wm msg)))))
|
(else (warn "unhandled move-wm message" wm msg)))))
|
||||||
|
|
||||||
|
(define (make-client-data titlebar resizer icon)
|
||||||
|
(list titlebar resizer icon))
|
||||||
|
|
||||||
|
(define (client-data:titlebar client)
|
||||||
|
(first (client:data client)))
|
||||||
|
|
||||||
|
(define (client-data:resizer client)
|
||||||
|
(second (client:data client)))
|
||||||
|
|
||||||
|
(define (client-data:icon client)
|
||||||
|
(third (client:data client)))
|
||||||
|
|
||||||
|
(define (set-client-data:icon! client icon)
|
||||||
|
(set-car! (cddr (client:data client)) icon))
|
||||||
|
|
||||||
(define (init-client wm client maybe-rect)
|
(define (init-client wm client maybe-rect)
|
||||||
(let ((dpy (wm:dpy wm)))
|
(let ((dpy (wm:dpy wm)))
|
||||||
(let* ((r (initial-client-rect wm (client:window client) maybe-rect))
|
(let* ((r (initial-client-rect wm (client:window client) maybe-rect))
|
||||||
|
@ -115,7 +168,7 @@
|
||||||
(titlebar (create-client-titlebar channel wm client))
|
(titlebar (create-client-titlebar channel wm client))
|
||||||
(resizer (create-resizer wm client))
|
(resizer (create-resizer wm client))
|
||||||
(options (wm:options wm)))
|
(options (wm:options wm)))
|
||||||
(set-client:data! client (list titlebar resizer))
|
(set-client:data! client (make-client-data titlebar resizer #f))
|
||||||
(set-titlebar-title! titlebar (client-name dpy client))
|
(set-titlebar-title! titlebar (client-name dpy client))
|
||||||
(let ((bw (get-option-value options 'border-width))
|
(let ((bw (get-option-value options 'border-width))
|
||||||
(th (get-option-value options 'titlebar-height)))
|
(th (get-option-value options 'titlebar-height)))
|
||||||
|
@ -155,6 +208,10 @@
|
||||||
;; from titlebar-buttons
|
;; from titlebar-buttons
|
||||||
((kill)
|
((kill)
|
||||||
(delete-window dpy (client:window client) (second msg)))
|
(delete-window dpy (client:window client) (second msg)))
|
||||||
|
((iconify)
|
||||||
|
(wm-iconify-window wm (client:window client)))
|
||||||
|
((maximize)
|
||||||
|
(wm-maximize-window wm (client:window client)))
|
||||||
))))
|
))))
|
||||||
;; TODO: internal channel
|
;; TODO: internal channel
|
||||||
(loop))
|
(loop))
|
||||||
|
@ -169,7 +226,7 @@
|
||||||
(let ((options (wm:options wm)))
|
(let ((options (wm:options wm)))
|
||||||
(create-titlebar channel (wm:dpy wm) (client:client-window client)
|
(create-titlebar channel (wm:dpy wm) (client:client-window client)
|
||||||
(wm:colormap wm)
|
(wm:colormap wm)
|
||||||
(list (cons 'buttons '(kill maximize))
|
(list (cons 'buttons '(kill maximize iconify))
|
||||||
(cons 'normal-colors
|
(cons 'normal-colors
|
||||||
(get-option options 'titlebar-colors))
|
(get-option options 'titlebar-colors))
|
||||||
(cons 'active-colors
|
(cons 'active-colors
|
||||||
|
@ -181,7 +238,14 @@
|
||||||
|
|
||||||
(define (deinit-client wm client)
|
(define (deinit-client wm client)
|
||||||
(let ((dpy (wm:dpy wm)))
|
(let ((dpy (wm:dpy wm)))
|
||||||
#t))
|
(set-input-focus dpy (wm:window wm) (revert-to parent) current-time)))
|
||||||
|
|
||||||
|
(define (create-client-icon wm client)
|
||||||
|
(let* ((other-icons (filter (lambda (x) x)
|
||||||
|
(map client-data:icon (wm-clients wm))))
|
||||||
|
(r (find-icon-rect (clip-rectangle (wm:dpy wm) (wm:window wm))
|
||||||
|
other-icons)))
|
||||||
|
(create-icon wm client r)))
|
||||||
|
|
||||||
;; ***
|
;; ***
|
||||||
|
|
||||||
|
@ -201,7 +265,7 @@
|
||||||
(- (window-attribute:height wa)
|
(- (window-attribute:height wa)
|
||||||
(+ (* 2 border-width) titlebar-height))))
|
(+ (* 2 border-width) titlebar-height))))
|
||||||
(move-resize-titlebar
|
(move-resize-titlebar
|
||||||
(car (client:data client))
|
(client-data:titlebar client)
|
||||||
(make-rectangle border-width border-width
|
(make-rectangle border-width border-width
|
||||||
(- (window-attribute:width wa) (* 2 border-width))
|
(- (window-attribute:width wa) (* 2 border-width))
|
||||||
titlebar-height))))
|
titlebar-height))))
|
||||||
|
@ -223,8 +287,14 @@
|
||||||
(let* ((dpy (wm:dpy wm))
|
(let* ((dpy (wm:dpy wm))
|
||||||
(win (client:client-window client))
|
(win (client:client-window client))
|
||||||
(x (window-x dpy win))
|
(x (window-x dpy win))
|
||||||
(y (window-y dpy win)))
|
(y (window-y dpy win))
|
||||||
#t)) ;; ... TODO
|
(w (window-width (wm:window wm)))
|
||||||
|
(h (window-height (wm:window wm))))
|
||||||
|
;; TODO: assert-icon-visible ...
|
||||||
|
(if (>= x w)
|
||||||
|
(set-window-x! win (- w 10)))
|
||||||
|
(if (>= y h)
|
||||||
|
(set-window-y! win (- h 10)))))
|
||||||
|
|
||||||
(define (draw-client-window wm client gc)
|
(define (draw-client-window wm client gc)
|
||||||
(let* ((options (wm:options wm))
|
(let* ((options (wm:options wm))
|
||||||
|
@ -267,7 +337,15 @@
|
||||||
(w.h-2 (maximal-size/hints dpy win (car w.h-1) (cdr w.h-1)))
|
(w.h-2 (maximal-size/hints dpy win (car w.h-1) (cdr w.h-1)))
|
||||||
(w.h (desired-size/hints dpy win w.h-2))
|
(w.h (desired-size/hints dpy win w.h-2))
|
||||||
;; TODO: look for a free position ?! Transients centered?
|
;; TODO: look for a free position ?! Transients centered?
|
||||||
(x.y (desired-position/hints dpy win (cons 0 0))))
|
(maybe-x.y (find-free-position wm w.h (cons 0 0)))
|
||||||
|
(x.y (desired-position/hints dpy win maybe-x.y)))
|
||||||
(make-rectangle (car x.y) (cdr x.y)
|
(make-rectangle (car x.y) (cdr x.y)
|
||||||
(car w.h) (cdr w.h)))))
|
(car w.h) (cdr w.h)))))
|
||||||
|
|
||||||
|
(define (find-free-position wm size default-pos)
|
||||||
|
(let* ((dpy (wm:dpy wm))
|
||||||
|
(max-w (window-width dpy (wm:window wm)))
|
||||||
|
(max-h (window-height dpy (wm:window wm)))
|
||||||
|
(w (car size))
|
||||||
|
(h (cdr size)))
|
||||||
|
default-pos)) ;; TODO
|
||||||
|
|
|
@ -109,6 +109,8 @@
|
||||||
(or first-client second-client))
|
(or first-client second-client))
|
||||||
(let ((r (client:window (or first-client second-client))))
|
(let ((r (client:window (or first-client second-client))))
|
||||||
(send (wm:out-channel wm) (list 'destroy-wm wm r)))))))
|
(send (wm:out-channel wm) (list 'destroy-wm wm r)))))))
|
||||||
|
|
||||||
|
((iconfiy-client maximize-client) #t)
|
||||||
|
|
||||||
((draw-client-window) #t)
|
((draw-client-window) #t)
|
||||||
|
|
||||||
|
@ -138,6 +140,8 @@
|
||||||
(if (data:second-client data)
|
(if (data:second-client data)
|
||||||
(wm-select-client wm (data:second-client data) time))))
|
(wm-select-client wm (data:second-client data) time))))
|
||||||
|
|
||||||
|
((show-clients) #t)
|
||||||
|
|
||||||
(else (warn "unhandled split-wm message" wm msg)))))
|
(else (warn "unhandled split-wm message" wm msg)))))
|
||||||
|
|
||||||
(define (calc-rectangles wm)
|
(define (calc-rectangles wm)
|
||||||
|
|
|
@ -89,6 +89,8 @@
|
||||||
((deinit-client)
|
((deinit-client)
|
||||||
(deinit-client wm data (second msg)))
|
(deinit-client wm data (second msg)))
|
||||||
|
|
||||||
|
((iconify-client maximize-client) #t)
|
||||||
|
|
||||||
((configure-window)
|
((configure-window)
|
||||||
(let ((window (second msg))
|
(let ((window (second msg))
|
||||||
(changes (third msg)))
|
(changes (third msg)))
|
||||||
|
@ -144,6 +146,15 @@
|
||||||
((select-next) (select-next-client wm (second msg)))
|
((select-next) (select-next-client wm (second msg)))
|
||||||
((select-previous) (select-previous-client wm (second msg)))
|
((select-previous) (select-previous-client wm (second msg)))
|
||||||
|
|
||||||
|
((show-clients)
|
||||||
|
(let ((clients (second msg)))
|
||||||
|
;; it's a list of a client and it's transients.
|
||||||
|
(let ((cc (wm-current-client wm))
|
||||||
|
(top (last clients)))
|
||||||
|
(if (and cc (window-mapped? dpy (client:client-window cc)))
|
||||||
|
(unmap-window dpy (client:client-window cc)))
|
||||||
|
(map-window dpy (client:client-window top)))))
|
||||||
|
|
||||||
(else (warn "unhandled switch-wm message" wm msg)))))
|
(else (warn "unhandled switch-wm message" wm msg)))))
|
||||||
|
|
||||||
(define (fit-titlebars wm data)
|
(define (fit-titlebars wm data)
|
||||||
|
@ -222,7 +233,7 @@
|
||||||
(map-titlebar titlebar)
|
(map-titlebar titlebar)
|
||||||
(if (window-exists? dpy (client:window client))
|
(if (window-exists? dpy (client:window client))
|
||||||
(map-window dpy (client:window client)))
|
(map-window dpy (client:window client)))
|
||||||
(map-window dpy (client:client-window client)))))
|
(wm-select-client wm client current-time))))
|
||||||
|
|
||||||
(define (create-client-titlebar channel wm client)
|
(define (create-client-titlebar channel wm client)
|
||||||
(let ((options (wm:options wm)))
|
(let ((options (wm:options wm)))
|
||||||
|
@ -263,7 +274,12 @@
|
||||||
(data:titlebars data)))
|
(data:titlebars data)))
|
||||||
(if tb (destroy-titlebar tb))
|
(if tb (destroy-titlebar tb))
|
||||||
(fit-titlebars wm data)
|
(fit-titlebars wm data)
|
||||||
(update-titlebars wm data)))
|
(update-titlebars wm data)
|
||||||
|
(if (eq? client (wm-current-client wm))
|
||||||
|
(if (null? (wm-clients wm))
|
||||||
|
(set-input-focus dpy (wm:window wm) (revert-to parent)
|
||||||
|
current-time)
|
||||||
|
(wm-select-client wm (car (wm-clients wm)) current-time)))))
|
||||||
|
|
||||||
;; ***
|
;; ***
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue