- added normalize-window/client signal
- replaced client icons with a pager for move-wm
This commit is contained in:
		
							parent
							
								
									613eb1fe8d
								
							
						
					
					
						commit
						f26844397b
					
				| 
						 | 
				
			
			@ -198,23 +198,18 @@
 | 
			
		|||
	 (if (and client window (window-exists? dpy window))
 | 
			
		||||
	     (reparent-to-root dpy window))))
 | 
			
		||||
 | 
			
		||||
      ((iconify-window)
 | 
			
		||||
      ((iconify-window normalize-window maximize-window)
 | 
			
		||||
       (let* ((window (second msg))
 | 
			
		||||
	      (client (find (lambda (c)
 | 
			
		||||
			      (eq? window (client:window c)))
 | 
			
		||||
			    (wm:clients wm))))
 | 
			
		||||
	 (if client
 | 
			
		||||
	     (send internal-out-channel
 | 
			
		||||
		   (list 'iconify-client client)))))
 | 
			
		||||
 | 
			
		||||
      ((maximize-window)
 | 
			
		||||
       (let* ((window (second msg))
 | 
			
		||||
	      (client (find (lambda (c)
 | 
			
		||||
			      (eq? window (client:window c)))
 | 
			
		||||
			    (wm:clients wm))))
 | 
			
		||||
	 (if client
 | 
			
		||||
	     (send internal-out-channel
 | 
			
		||||
		   (list 'maximize-client client)))))
 | 
			
		||||
		   (list (case (first msg)
 | 
			
		||||
			   ((iconify-window) 'iconify-client)
 | 
			
		||||
			   ((normalize-window) 'normalize-client)
 | 
			
		||||
			   ((maximize-window) 'maximize-client))
 | 
			
		||||
			 client)))))
 | 
			
		||||
      
 | 
			
		||||
      ((destroy-manager)
 | 
			
		||||
       (send-message+wait internal-out-channel '(deinit-manager))
 | 
			
		||||
| 
						 | 
				
			
			@ -268,6 +263,9 @@
 | 
			
		|||
(define (wm-iconify-window wm window)
 | 
			
		||||
  (send (wm:in-channel wm) (list 'iconify-window window)))
 | 
			
		||||
 | 
			
		||||
(define (wm-normalize-window wm window)
 | 
			
		||||
  (send (wm:in-channel wm) (list 'normalize-window window)))
 | 
			
		||||
 | 
			
		||||
(define (wm-maximize-window wm window)
 | 
			
		||||
  (send (wm:in-channel wm) (list 'maximize-window window)))
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -284,13 +282,14 @@
 | 
			
		|||
;; *** client ********************************************************
 | 
			
		||||
 | 
			
		||||
(define-record-type client :client
 | 
			
		||||
  (make-client window client-window in-channel data focused?)
 | 
			
		||||
  (make-client window client-window in-channel data focused? wm-state)
 | 
			
		||||
  client?
 | 
			
		||||
  (window client:window set-client:window!)
 | 
			
		||||
  (client-window client:client-window)
 | 
			
		||||
  (in-channel client:in-channel)
 | 
			
		||||
  (data client:data set-client:data!)
 | 
			
		||||
  (focused? client:focused? set-client:focused?!))
 | 
			
		||||
  (focused? client:focused? set-client:focused?!)
 | 
			
		||||
  (wm-state client:wm-state set-client:wm-state!))
 | 
			
		||||
 | 
			
		||||
(define (set-client-focused?! wm client focused?)
 | 
			
		||||
  (let ((prev (client:focused? client)))
 | 
			
		||||
| 
						 | 
				
			
			@ -314,7 +313,13 @@
 | 
			
		|||
					      (white-pixel dpy)
 | 
			
		||||
					      (black-pixel dpy)))
 | 
			
		||||
	 (in-channel (make-channel))
 | 
			
		||||
	 (client (make-client window client-window in-channel #f #f)))
 | 
			
		||||
	 (wm-state (let ((s.i (get-wm-state dpy window)))
 | 
			
		||||
		     ;; TODO initial-state? see root-manager
 | 
			
		||||
		     (if s.i
 | 
			
		||||
			 (car s.i)
 | 
			
		||||
			 (wm-state withdrawn))))
 | 
			
		||||
	 (client (make-client window client-window in-channel #f #f
 | 
			
		||||
			      wm-state)))
 | 
			
		||||
    ;; transparent by default.
 | 
			
		||||
    (set-window-background-pixmap! dpy client-window parent-relative)
 | 
			
		||||
    (define-cursor dpy client-window
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,214 @@
 | 
			
		|||
(define-record-type move-wm-pager :move-wm-pager
 | 
			
		||||
  (make-move-wm-pager dpy window wm in-channel options buttons-alist width)
 | 
			
		||||
  move-wm-pager?
 | 
			
		||||
  (dpy pager:dpy)
 | 
			
		||||
  (window pager:window)
 | 
			
		||||
  (wm pager:wm)
 | 
			
		||||
  (in-channel pager:in-channel)
 | 
			
		||||
  (options pager:options)
 | 
			
		||||
  ;; client -> button
 | 
			
		||||
  (buttons-alist pager:buttons-alist set-pager:buttons-alist!)
 | 
			
		||||
  (width pager:width set-pager:width!))
 | 
			
		||||
 | 
			
		||||
;; TODO: hide buttons/keys
 | 
			
		||||
;; TODO: client-name <-> WM_ICON_NAME?
 | 
			
		||||
 | 
			
		||||
(define (repeat-infinitely fun) ;; -> utils
 | 
			
		||||
  (call-with-current-continuation
 | 
			
		||||
   (lambda (exit)
 | 
			
		||||
     (let loop ()
 | 
			
		||||
       (fun exit)
 | 
			
		||||
       (loop)))))
 | 
			
		||||
 | 
			
		||||
(define (create-move-wm-pager wm out-channel options)
 | 
			
		||||
  (let* ((dpy (wm:dpy wm))
 | 
			
		||||
	 (parent (wm:window wm))
 | 
			
		||||
	 (rect (calc-pager-rect wm))
 | 
			
		||||
	 (bg-color (first (get-option-value options 'pager-colors)))
 | 
			
		||||
	 (window (create-simple-window dpy parent
 | 
			
		||||
				       (rectangle:x rect) (rectangle:y rect)
 | 
			
		||||
				       (rectangle:width rect)
 | 
			
		||||
				       (rectangle:height rect)
 | 
			
		||||
				       0 (black-pixel dpy)
 | 
			
		||||
				       bg-color))
 | 
			
		||||
	 (in-channel (make-channel))
 | 
			
		||||
	 (gc (create-gc dpy window '()))
 | 
			
		||||
	 (colormap (screen:default-colormap (display:default-screen dpy)))
 | 
			
		||||
	 (pager (make-move-wm-pager dpy window wm in-channel options '()
 | 
			
		||||
				    (rectangle:width rect))))
 | 
			
		||||
    (spawn*
 | 
			
		||||
     (list 'move-wm-pager wm window)
 | 
			
		||||
     (lambda (release)
 | 
			
		||||
       (call-with-event-channel
 | 
			
		||||
	dpy window
 | 
			
		||||
	(event-mask exposure
 | 
			
		||||
		    button-press button-release
 | 
			
		||||
		    visibility-change)
 | 
			
		||||
	(lambda (window-channel)
 | 
			
		||||
	  (release)
 | 
			
		||||
	  (repeat-infinitely
 | 
			
		||||
	   (lambda (exit)
 | 
			
		||||
	     (select*
 | 
			
		||||
	      (wrap (receive-rv in-channel)
 | 
			
		||||
		    (lambda (msg)
 | 
			
		||||
		      (cond
 | 
			
		||||
		       ((and (pair? (first msg))
 | 
			
		||||
			     (eq? 'button (car (first msg))))
 | 
			
		||||
			(let ((client (cdr (first msg)))
 | 
			
		||||
			      (time (second msg))
 | 
			
		||||
			      (event (third msg)))
 | 
			
		||||
			  (pager-action pager client time event)))
 | 
			
		||||
		       ((not (pair? (first msg)))
 | 
			
		||||
			(case (first msg)
 | 
			
		||||
			  ((add-client)
 | 
			
		||||
			   (let* ((client (second msg))
 | 
			
		||||
				  (button (pager-create-button
 | 
			
		||||
					   pager client
 | 
			
		||||
					   (make-rectangle 0 0 1 1))))
 | 
			
		||||
			     (set-pager:buttons-alist!
 | 
			
		||||
			      pager
 | 
			
		||||
			      (append (pager:buttons-alist pager)
 | 
			
		||||
				      (list (cons client button))))
 | 
			
		||||
			     (pager-refit-buttons pager)
 | 
			
		||||
			     (map-button button)))
 | 
			
		||||
			  ((remove-client)
 | 
			
		||||
			   (let* ((client (second msg))
 | 
			
		||||
				  (button (assq/false
 | 
			
		||||
					   client
 | 
			
		||||
					   (pager:buttons-alist pager))))
 | 
			
		||||
			     (set-pager:buttons-alist!
 | 
			
		||||
			      pager
 | 
			
		||||
			      (alist-delete client
 | 
			
		||||
					    (pager:buttons-alist pager)))
 | 
			
		||||
			     (if button
 | 
			
		||||
				 (begin
 | 
			
		||||
				   (destroy-button button)
 | 
			
		||||
				   (pager-refit-buttons pager))
 | 
			
		||||
				 (warn "pager-remove-client: unknown client."
 | 
			
		||||
				       pager client))))
 | 
			
		||||
			  )))))
 | 
			
		||||
 | 
			
		||||
	      (wrap (receive-rv window-channel)
 | 
			
		||||
		    (lambda (xevent)
 | 
			
		||||
		      (cond
 | 
			
		||||
		       ((expose-event? xevent)
 | 
			
		||||
			(if (zero? (expose-event-count xevent))
 | 
			
		||||
			    (pager-draw pager gc)))
 | 
			
		||||
		       ((destroy-window-event? xevent) ;; mask?
 | 
			
		||||
			;; destroy-button not necessary
 | 
			
		||||
			(exit))))))))
 | 
			
		||||
	  (free-gc dpy gc)
 | 
			
		||||
	  ;;(free-options options #t) ;; common with wm
 | 
			
		||||
	  ))))
 | 
			
		||||
    (map-window dpy window)
 | 
			
		||||
    pager))
 | 
			
		||||
 | 
			
		||||
(define (pager-create-button pager client rect)
 | 
			
		||||
  (let* ((dpy (pager:dpy pager))
 | 
			
		||||
	 (options (pager:options pager))
 | 
			
		||||
	 (colors (get-option options 'pager-colors))
 | 
			
		||||
	 (main-color (second colors))
 | 
			
		||||
	 (light (third colors))
 | 
			
		||||
	 (dark (fourth colors))
 | 
			
		||||
	 (font-color (fifth colors)))
 | 
			
		||||
    (create-button (pager:dpy pager) (pager:window pager)
 | 
			
		||||
		   (screen:default-colormap (display:default-screen dpy))
 | 
			
		||||
		   rect (pager:in-channel pager)
 | 
			
		||||
		   (cons 'button client)
 | 
			
		||||
		   `(;; TODO: don't let every button allocate the
 | 
			
		||||
		     ;; colors, and load the font.
 | 
			
		||||
		     (up-colors . ,(list main-color light dark font-color))
 | 
			
		||||
		     (down-colors . ,(list main-color dark light font-color))
 | 
			
		||||
		     (font . ,(get-option options 'font))
 | 
			
		||||
		     (content . ,(client-name (pager:dpy pager) client))
 | 
			
		||||
		     (type . switch)
 | 
			
		||||
		     (initial-state . up)))))
 | 
			
		||||
 | 
			
		||||
(define (calc-pager-rect wm)
 | 
			
		||||
  (let ((dpy (wm:dpy wm))
 | 
			
		||||
	(window (wm:window wm))
 | 
			
		||||
	(options (wm:options wm))) ;; wm-options = pager-options!?
 | 
			
		||||
    (let* ((g (get-geometry dpy window))
 | 
			
		||||
	   (width (vector-ref g 3))
 | 
			
		||||
	   (height (vector-ref g 4))
 | 
			
		||||
	   (pager-height (get-option-value options 'pager-height)))
 | 
			
		||||
      (make-rectangle 0 (- height pager-height)
 | 
			
		||||
		      width pager-height))))
 | 
			
		||||
 | 
			
		||||
(define (pager-action pager client time event) ;, event??
 | 
			
		||||
  (let ((wm (pager:wm pager)))
 | 
			
		||||
  ;; normalize/iconify directly via client?!
 | 
			
		||||
    (if (eq? (client:wm-state client)
 | 
			
		||||
	     (wm-state iconic))
 | 
			
		||||
	(begin
 | 
			
		||||
	  (wm-normalize-window wm (client:window client))
 | 
			
		||||
	  (wm-select-client wm client time))
 | 
			
		||||
	(if (client:focused? client) ;; this should better be "on top?"
 | 
			
		||||
	    ;; select a different one?
 | 
			
		||||
	    (wm-iconify-window wm (client:window client))
 | 
			
		||||
	    (wm-select-client wm client time)))))
 | 
			
		||||
 | 
			
		||||
(define (pager-draw pager gc)
 | 
			
		||||
  (clear-window (pager:dpy pager) (pager:window pager)))
 | 
			
		||||
 | 
			
		||||
(define (pager-button-rects pager)
 | 
			
		||||
  (let ((alist (pager:buttons-alist pager))
 | 
			
		||||
	(options (pager:options pager)))
 | 
			
		||||
    (if (null? alist)
 | 
			
		||||
	'()
 | 
			
		||||
	(let* ((width (pager:width pager))
 | 
			
		||||
	       (bwidth (min (get-option-value options
 | 
			
		||||
					      'pager-maximum-button-width)
 | 
			
		||||
			    (- (quotient width (length alist)) 2)))
 | 
			
		||||
	       (bheight (- (get-option-value options 'pager-height) 4))
 | 
			
		||||
	       (x 2)
 | 
			
		||||
	       (y 2))
 | 
			
		||||
	  (map (lambda (c.b)
 | 
			
		||||
		      (let ((r (make-rectangle x y bwidth bheight)))
 | 
			
		||||
			(set! x (+ x bwidth 2))
 | 
			
		||||
			(cons (cdr c.b) r)))
 | 
			
		||||
		    alist)))))
 | 
			
		||||
 | 
			
		||||
(define (pager-refit-buttons pager)
 | 
			
		||||
  (for-each (lambda (b.r)
 | 
			
		||||
	      (move-resize-button (car b.r) (cdr b.r)))
 | 
			
		||||
	    (pager-button-rects pager)))
 | 
			
		||||
 | 
			
		||||
;; "external functions"
 | 
			
		||||
 | 
			
		||||
(define (pager-refit pager)
 | 
			
		||||
  (let ((r (calc-pager-rect (pager:wm pager))))
 | 
			
		||||
    (set-pager:width! pager (rectangle:width r))
 | 
			
		||||
    (move-resize-window (pager:dpy pager) (pager:window pager)
 | 
			
		||||
		   (rectangle:x r) (rectangle:y r)
 | 
			
		||||
		   (rectangle:width r) (rectangle:height r))
 | 
			
		||||
    (pager-refit-buttons pager)))
 | 
			
		||||
 | 
			
		||||
(define (pager-add-client pager client)
 | 
			
		||||
  (send (pager:in-channel pager)
 | 
			
		||||
	(list 'add-client client)))
 | 
			
		||||
 | 
			
		||||
(define (pager-remove-client pager client)
 | 
			
		||||
  (send (pager:in-channel pager)
 | 
			
		||||
	(list 'remove-client client)))
 | 
			
		||||
 | 
			
		||||
(define (pager-update-button pager button client)
 | 
			
		||||
  (if (eq? (client:wm-state client)
 | 
			
		||||
	   (wm-state iconic))
 | 
			
		||||
      (button-set-state! button 'down)
 | 
			
		||||
      (button-set-state! button 'up))
 | 
			
		||||
  (button-set-content! button
 | 
			
		||||
		       (client-name (pager:dpy pager) client)))
 | 
			
		||||
 | 
			
		||||
(define (pager-update-client pager client)
 | 
			
		||||
  (let ((button (assq/false client (pager:buttons-alist pager))))
 | 
			
		||||
    (if button
 | 
			
		||||
	(pager-update-button pager button client)
 | 
			
		||||
	(warn "pager-update-client: unknown client" pager client))))
 | 
			
		||||
 | 
			
		||||
(define (pager-update pager)
 | 
			
		||||
  (for-each (lambda (c.b)
 | 
			
		||||
	      (let ((client (car c.b))
 | 
			
		||||
		    (button (cdr c.b)))
 | 
			
		||||
		(pager-update-button pager button client)))
 | 
			
		||||
	    (pager:buttons-alist pager)))
 | 
			
		||||
| 
						 | 
				
			
			@ -8,6 +8,10 @@
 | 
			
		|||
  (corner-width int 10)
 | 
			
		||||
  (border-style symbol 'raised) ;; raised | sunken | flat
 | 
			
		||||
  (border-colors colors '("#333333" "#dddddd"))
 | 
			
		||||
  (pager-colors colors ;; bg, button, light, dark, font
 | 
			
		||||
		'("#808080" "#aaaaaa" "#eeeeee" "#777777" "black"))
 | 
			
		||||
  (pager-maximum-button-width int 140)
 | 
			
		||||
  (pager-height int 24)
 | 
			
		||||
  )
 | 
			
		||||
 | 
			
		||||
(define (create-move-wm out-channel dpy parent options default-options
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +28,9 @@
 | 
			
		|||
(define (init-move-wm wm channel)
 | 
			
		||||
  (let* ((dpy (wm:dpy wm))
 | 
			
		||||
	 (window (wm:window wm))
 | 
			
		||||
	 (gc (create-gc dpy window '())))
 | 
			
		||||
	 (gc (create-gc dpy window '()))
 | 
			
		||||
	 (pager-channel (make-channel))
 | 
			
		||||
	 (pager (create-move-wm-pager wm pager-channel (wm:options wm))))
 | 
			
		||||
    (spawn* (list 'move-wm wm)
 | 
			
		||||
	    (lambda (release)
 | 
			
		||||
	      (release)
 | 
			
		||||
| 
						 | 
				
			
			@ -32,18 +38,18 @@
 | 
			
		|||
	       (lambda (exit)
 | 
			
		||||
		 (let loop ()
 | 
			
		||||
		   (let ((msg (receive channel)))
 | 
			
		||||
		     (handle-message wm gc exit msg)
 | 
			
		||||
		     (handle-message wm pager gc exit msg)
 | 
			
		||||
		     (loop)))))
 | 
			
		||||
	      (free-gc dpy gc)))))
 | 
			
		||||
 | 
			
		||||
(define (handle-message wm gc exit msg)
 | 
			
		||||
(define (handle-message wm pager gc exit msg)
 | 
			
		||||
  (let ((dpy (wm:dpy wm))
 | 
			
		||||
	(window (wm:window wm)))
 | 
			
		||||
    (case (car msg)
 | 
			
		||||
      ((wait)
 | 
			
		||||
       (let ((sp (second msg))
 | 
			
		||||
	     (message (third msg)))
 | 
			
		||||
	 (handle-message wm gc
 | 
			
		||||
	 (handle-message wm pager gc
 | 
			
		||||
			 (lambda args
 | 
			
		||||
			   (sync-point-release sp)
 | 
			
		||||
			   (apply exit args))
 | 
			
		||||
| 
						 | 
				
			
			@ -60,13 +66,21 @@
 | 
			
		|||
      ((fit-windows)
 | 
			
		||||
       (map (lambda (client)
 | 
			
		||||
	      (assert-client-visible wm client))
 | 
			
		||||
	    (wm-clients wm)))
 | 
			
		||||
	    (wm-clients wm))
 | 
			
		||||
       (pager-refit pager))
 | 
			
		||||
      
 | 
			
		||||
      ((init-client)
 | 
			
		||||
       (init-client wm (second msg) (third msg)))
 | 
			
		||||
       (let ((client (second msg))
 | 
			
		||||
	     (maybe-rect (third msg)))
 | 
			
		||||
	 (init-client wm client maybe-rect)
 | 
			
		||||
	 (pager-add-client pager client)
 | 
			
		||||
	 ;; for (properly) transient windows this would not be necessary:
 | 
			
		||||
	 (wm-select-client wm client current-time)))
 | 
			
		||||
      
 | 
			
		||||
      ((deinit-client)
 | 
			
		||||
       (deinit-client wm (second msg)))
 | 
			
		||||
       (let ((client (second msg)))
 | 
			
		||||
	 (deinit-client wm client)
 | 
			
		||||
	 (pager-remove-client pager client)))
 | 
			
		||||
      
 | 
			
		||||
      ((configure-window)
 | 
			
		||||
       (let ((window (second msg))
 | 
			
		||||
| 
						 | 
				
			
			@ -139,30 +153,30 @@
 | 
			
		|||
 | 
			
		||||
      ((iconify-client)
 | 
			
		||||
       (let ((client (second msg)))
 | 
			
		||||
	 (if (not (client-data:icon client))
 | 
			
		||||
	 (if (not (eq? (client:wm-state client) (wm-state iconic)))
 | 
			
		||||
	     (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))))))
 | 
			
		||||
	       (set-client:wm-state! client (wm-state iconic))))
 | 
			
		||||
	 (pager-update-client pager client)))
 | 
			
		||||
 | 
			
		||||
      ((maximize-client)
 | 
			
		||||
       ;; TODO: maybe exclude pager?
 | 
			
		||||
       (let ((client (second msg)))
 | 
			
		||||
	 (maximize-window dpy (client:client-window client))))
 | 
			
		||||
 | 
			
		||||
      ((normalize-client)
 | 
			
		||||
       (let ((client (second msg)))
 | 
			
		||||
	 (if (client-data:icon client)
 | 
			
		||||
	 (if (not (eq? (client:wm-state client) (wm-state normal)))
 | 
			
		||||
	     (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)))))
 | 
			
		||||
	       (set-client:wm-state! client (wm-state normal))))
 | 
			
		||||
	 (pager-update-client pager client)))
 | 
			
		||||
      
 | 
			
		||||
      ((draw-client-window)
 | 
			
		||||
       (draw-client-window wm (second msg) gc))
 | 
			
		||||
| 
						 | 
				
			
			@ -184,27 +198,29 @@
 | 
			
		|||
			 'focused
 | 
			
		||||
			 'normal))
 | 
			
		||||
	      (titlebar (client-data:titlebar client)))
 | 
			
		||||
	 (set-titlebar-state! titlebar state)))
 | 
			
		||||
	 (set-titlebar-state! titlebar state)
 | 
			
		||||
	 (pager-update-client pager client)))
 | 
			
		||||
      
 | 
			
		||||
      ((update-client-name)
 | 
			
		||||
       (let ((client (second msg))
 | 
			
		||||
	     (name (third msg)))
 | 
			
		||||
	 (let ((titlebar (client-data:titlebar client)))
 | 
			
		||||
	   (set-titlebar-title! titlebar name))))
 | 
			
		||||
	   (set-titlebar-title! titlebar name)
 | 
			
		||||
	   (pager-update-client pager client))))
 | 
			
		||||
 | 
			
		||||
      ((show-clients)
 | 
			
		||||
       (let ((clients (second msg)))
 | 
			
		||||
	 (for-each (lambda (c)
 | 
			
		||||
		     (if (client-data:icon c)
 | 
			
		||||
			 (handle-message wm gc exit
 | 
			
		||||
		     (if (eq? (client:wm-state c) (wm-state iconic))
 | 
			
		||||
			 (handle-message wm pager gc exit
 | 
			
		||||
					 (list 'normalize-client c)))
 | 
			
		||||
		     (raise-window dpy (client:client-window c)))
 | 
			
		||||
		   clients)))
 | 
			
		||||
      
 | 
			
		||||
      (else (warn "unhandled move-wm message" wm msg)))))
 | 
			
		||||
 | 
			
		||||
(define (make-client-data titlebar resizer icon)
 | 
			
		||||
  (list titlebar resizer icon))
 | 
			
		||||
(define (make-client-data titlebar resizer)
 | 
			
		||||
  (list titlebar resizer))
 | 
			
		||||
 | 
			
		||||
(define (client-data:titlebar client)
 | 
			
		||||
  (first (client:data client)))
 | 
			
		||||
| 
						 | 
				
			
			@ -212,12 +228,6 @@
 | 
			
		|||
(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 (window-wants-decoration? dpy window)
 | 
			
		||||
  (cond
 | 
			
		||||
   ((get-motif-wm-hints dpy window) =>
 | 
			
		||||
| 
						 | 
				
			
			@ -234,7 +244,7 @@
 | 
			
		|||
	   (titlebar (create-client-titlebar channel wm client))
 | 
			
		||||
	   (resizer (create-resizer wm client))
 | 
			
		||||
	   (options (wm:options wm)))
 | 
			
		||||
      (set-client:data! client (make-client-data titlebar resizer #f))
 | 
			
		||||
      (set-client:data! client (make-client-data titlebar resizer))
 | 
			
		||||
      (set-titlebar-title! titlebar (client-name dpy client))
 | 
			
		||||
      (let* ((bw (get-option-value options 'border-width))
 | 
			
		||||
	     (th (get-option-value options 'titlebar-height))
 | 
			
		||||
| 
						 | 
				
			
			@ -300,7 +310,7 @@
 | 
			
		|||
			   (cons 'normal-colors
 | 
			
		||||
				 (get-option options 'titlebar-colors))
 | 
			
		||||
			   (cons 'active-colors
 | 
			
		||||
				 (get-option options'titlebar-colors-focused))
 | 
			
		||||
				 (get-option options 'titlebar-colors-focused))
 | 
			
		||||
			   (cons 'focused-colors
 | 
			
		||||
				 (get-option options 'titlebar-colors-focused))
 | 
			
		||||
			   (cons 'border-style
 | 
			
		||||
| 
						 | 
				
			
			@ -310,13 +320,6 @@
 | 
			
		|||
  (let ((dpy (wm:dpy wm)))
 | 
			
		||||
    (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)))
 | 
			
		||||
 | 
			
		||||
;; ***
 | 
			
		||||
 | 
			
		||||
(define (fit-client-windows wm client)
 | 
			
		||||
| 
						 | 
				
			
			@ -360,7 +363,6 @@
 | 
			
		|||
	 (y (window-y dpy win))
 | 
			
		||||
	 (w (window-width dpy (wm:window wm)))
 | 
			
		||||
	 (h (window-height dpy (wm:window wm))))
 | 
			
		||||
    ;; TODO: assert-icon-visible ...
 | 
			
		||||
    (if (>= x w)
 | 
			
		||||
	(set-window-x! dpy win (- w 10)))
 | 
			
		||||
    (if (>= y h)
 | 
			
		||||
| 
						 | 
				
			
			@ -432,7 +434,8 @@
 | 
			
		|||
		       (window-rectangle dpy (client:client-window client)))
 | 
			
		||||
		     (filter (lambda (c)
 | 
			
		||||
			       (and (not (eq? c client))
 | 
			
		||||
				    (not (client-data:icon c))))
 | 
			
		||||
				    (not (eq? (client:wm-state c)
 | 
			
		||||
					      (wm-state iconic)))))
 | 
			
		||||
			     (wm-clients wm))))
 | 
			
		||||
	 (list1 (map (lambda (x.y)
 | 
			
		||||
		       (make-rectangle (car x.y) (cdr x.y) w h))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -72,8 +72,11 @@
 | 
			
		|||
(define-structure button
 | 
			
		||||
  (export create-button destroy-button
 | 
			
		||||
	  map-button unmap-button
 | 
			
		||||
	  move-resize-button)
 | 
			
		||||
	  move-resize-button
 | 
			
		||||
	  button-get-state button-set-state!
 | 
			
		||||
	  button-set-content!)
 | 
			
		||||
  (open scheme list-lib rendezvous-channels
 | 
			
		||||
	rendezvous placeholders
 | 
			
		||||
	define-record-types
 | 
			
		||||
	xlib
 | 
			
		||||
	utils)
 | 
			
		||||
| 
						 | 
				
			
			@ -118,13 +121,16 @@
 | 
			
		|||
	  create-wm destroy-wm
 | 
			
		||||
	  wm-clients wm-current-client
 | 
			
		||||
	  wm-manage-window wm-unmanage-window wm-select-client
 | 
			
		||||
	  wm-configure-window wm-iconify-window wm-maximize-window
 | 
			
		||||
	  wm-configure-window
 | 
			
		||||
	  wm-iconify-window wm-normalize-window wm-maximize-window
 | 
			
		||||
	  wm-deinit-client
 | 
			
		||||
 | 
			
		||||
	  ignore-next-enter-notify!
 | 
			
		||||
 | 
			
		||||
	  client? client:window client:client-window
 | 
			
		||||
	  client:data set-client:data!
 | 
			
		||||
	  client:wm-state set-client:wm-state!
 | 
			
		||||
	  client:focused?
 | 
			
		||||
	  client-name find-window-by-name get-all-window-names
 | 
			
		||||
	  client-replace-window
 | 
			
		||||
	  client-of-window)
 | 
			
		||||
| 
						 | 
				
			
			@ -143,13 +149,13 @@
 | 
			
		|||
  (export create-move-wm)
 | 
			
		||||
  (open scheme list-lib define-record-types signals
 | 
			
		||||
	threads rendezvous-channels rendezvous
 | 
			
		||||
	xlib
 | 
			
		||||
	xlib button
 | 
			
		||||
	manager key-grab
 | 
			
		||||
	utils dragging titlebar
 | 
			
		||||
	utils dragging titlebar button
 | 
			
		||||
	motif enum-sets)
 | 
			
		||||
  (files move-wm
 | 
			
		||||
	 move-wm-resizer
 | 
			
		||||
	 move-wm-icon))
 | 
			
		||||
	 move-wm-pager))
 | 
			
		||||
 | 
			
		||||
;; *** split manager *************************************************
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue