separated default options (config) and saved options (layout)
added some synchronization optimized focus-control cleaned up a bit
This commit is contained in:
		
							parent
							
								
									315a71013a
								
							
						
					
					
						commit
						de00f837dc
					
				
							
								
								
									
										256
									
								
								src/manager.scm
								
								
								
								
							
							
						
						
									
										256
									
								
								src/manager.scm
								
								
								
								
							| 
						 | 
					@ -37,7 +37,7 @@
 | 
				
			||||||
   ((eq? type (manager-type switch)) "switch-wm")
 | 
					   ((eq? type (manager-type switch)) "switch-wm")
 | 
				
			||||||
   ((eq? type (manager-type move)) "move-wm")))
 | 
					   ((eq? type (manager-type move)) "move-wm")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (create-wm dpy parent options children
 | 
					(define (create-wm dpy parent options default-options children
 | 
				
			||||||
		   type options-spec out-channel fun)
 | 
							   type options-spec out-channel fun)
 | 
				
			||||||
  (let* ((wa (get-window-attributes dpy parent))
 | 
					  (let* ((wa (get-window-attributes dpy parent))
 | 
				
			||||||
	 (main-window
 | 
						 (main-window
 | 
				
			||||||
| 
						 | 
					@ -52,8 +52,10 @@
 | 
				
			||||||
	 (wm (make-wm type in-channel out-channel internal-out-channel
 | 
						 (wm (make-wm type in-channel out-channel internal-out-channel
 | 
				
			||||||
		      dpy main-window colormap
 | 
							      dpy main-window colormap
 | 
				
			||||||
		      (create-options dpy colormap
 | 
							      (create-options dpy colormap
 | 
				
			||||||
				      (options-spec-union options-spec
 | 
									      (spec-defaults default-options
 | 
				
			||||||
							  manager-options-spec)
 | 
											     (options-spec-union
 | 
				
			||||||
 | 
											      options-spec
 | 
				
			||||||
 | 
											      manager-options-spec))
 | 
				
			||||||
				      options)
 | 
									      options)
 | 
				
			||||||
		      '() #f)))
 | 
							      '() #f)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -118,8 +120,18 @@
 | 
				
			||||||
      (send internal-out-channel '(fit-windows)))
 | 
					      (send internal-out-channel '(fit-windows)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     ((focus-change-event? xevent)
 | 
					     ((focus-change-event? xevent)
 | 
				
			||||||
      ;; really send it always ??
 | 
					      (if (window-exists? dpy (wm:window wm))
 | 
				
			||||||
      (send internal-out-channel '(update-manager-state)))
 | 
						  (let ((mode (focus-change-event-mode xevent))
 | 
				
			||||||
 | 
							(detail (focus-change-event-detail xevent)))
 | 
				
			||||||
 | 
						    (if (and (eq? mode (notify-mode normal))
 | 
				
			||||||
 | 
							     (memq detail (list (notify-detail nonlinear)
 | 
				
			||||||
 | 
										(notify-detail nonlinear-virtual)
 | 
				
			||||||
 | 
										(notify-detail virtual)
 | 
				
			||||||
 | 
										(notify-detail ancestor))))
 | 
				
			||||||
 | 
							(let ((focused? (eq? (event-type focus-in)
 | 
				
			||||||
 | 
									     (focus-change-event-type xevent))))
 | 
				
			||||||
 | 
							  (send internal-out-channel
 | 
				
			||||||
 | 
								(list 'update-manager-state focused?)))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     ;; the manager got the focus (as a client)
 | 
					     ;; the manager got the focus (as a client)
 | 
				
			||||||
     ((client-message-event? xevent)
 | 
					     ((client-message-event? xevent)
 | 
				
			||||||
| 
						 | 
					@ -147,90 +159,78 @@
 | 
				
			||||||
  (let ((internal-out-channel (wm:internal-out-channel wm))
 | 
					  (let ((internal-out-channel (wm:internal-out-channel wm))
 | 
				
			||||||
	(dpy (wm:dpy wm)))
 | 
						(dpy (wm:dpy wm)))
 | 
				
			||||||
    (case (car msg)
 | 
					    (case (car msg)
 | 
				
			||||||
     ((manage-window)
 | 
					      ((wait)
 | 
				
			||||||
      (let ((window (second msg))
 | 
					       (let ((sp (second msg))
 | 
				
			||||||
	    (maybe-rect (third msg)))
 | 
						     (message (third msg)))
 | 
				
			||||||
	(let ((client (create-client wm window)))
 | 
						 (handle-external-message wm exit message)
 | 
				
			||||||
	  (set-wm:clients! wm (append (wm:clients wm) (list client)))
 | 
						 (sync-point-release sp)))
 | 
				
			||||||
	  (send internal-out-channel
 | 
					      
 | 
				
			||||||
		(list 'init-client client maybe-rect))
 | 
					      ((manage-window)
 | 
				
			||||||
	  ;; sync??
 | 
					       (let ((window (second msg))
 | 
				
			||||||
	  ;;(if (window-exists? dpy window)
 | 
						     (maybe-rect (third msg)))
 | 
				
			||||||
	  ;;    (map-window dpy window))
 | 
						 (let ((client (create-client wm window)))
 | 
				
			||||||
	  ;;(send internal-out-channel (list 'fit-client client))
 | 
						   (set-wm:clients! wm (append (wm:clients wm) (list client)))
 | 
				
			||||||
	  ;;(send internal-out-channel (list 'update-client-state client))
 | 
						   (send-message+wait internal-out-channel
 | 
				
			||||||
	  )))
 | 
								      (list 'init-client client maybe-rect)))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
     ((configure-window)
 | 
					      ((configure-window)
 | 
				
			||||||
      (let ((window (second msg))
 | 
					       (let ((window (second msg))
 | 
				
			||||||
	    (changes (third msg)))
 | 
						     (changes (third msg)))
 | 
				
			||||||
	(send internal-out-channel
 | 
						 (send-message+wait internal-out-channel
 | 
				
			||||||
	      (list 'configure-window window changes))))
 | 
								    (list 'configure-window window changes))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
     ((unmanage-window)
 | 
					      ((unmanage-window)
 | 
				
			||||||
      (let* ((window (second msg))
 | 
					       (let* ((window (second msg))
 | 
				
			||||||
	     (client (find (lambda (c)
 | 
						      (client (find (lambda (c)
 | 
				
			||||||
			     (eq? window (client:window c)))
 | 
								      (eq? window (client:window c)))
 | 
				
			||||||
			   (wm:clients wm))))
 | 
								    (wm:clients wm))))
 | 
				
			||||||
	(if client
 | 
						 (if client
 | 
				
			||||||
	    (reparent-to-root dpy window))))
 | 
						     (reparent-to-root dpy window))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
     ((destroy-manager)
 | 
					      ((destroy-manager)
 | 
				
			||||||
      ;; (send internal-out-channel '(deinit-manager))
 | 
					       (send-message+wait internal-out-channel '(deinit-manager))
 | 
				
			||||||
      ;; sync ??
 | 
					       (if (window-exists? dpy (wm:window wm))
 | 
				
			||||||
      (if (window-exists? dpy (wm:window wm))
 | 
						   (destroy-window dpy (wm:window wm))))
 | 
				
			||||||
	  (destroy-window dpy (wm:window wm))))
 | 
					      
 | 
				
			||||||
 | 
					      ((deinit-client)
 | 
				
			||||||
     ((deinit-client)
 | 
					       (let ((client (second msg)))
 | 
				
			||||||
      (let ((client (second msg)))
 | 
						 (set-wm:clients! wm (filter (lambda (c) (not (eq? c client)))
 | 
				
			||||||
	(set-wm:clients! wm (filter (lambda (c) (not (eq? c client)))
 | 
									     (wm:clients wm)))
 | 
				
			||||||
				    (wm:clients wm)))
 | 
						 (if (eq? (wm:current-client wm) client)
 | 
				
			||||||
	(if (eq? (wm:current-client wm) client)
 | 
						     ;; select-client ??
 | 
				
			||||||
	    (set-wm:current-client! wm (and (not (null? (wm:clients wm)))
 | 
						     (set-wm:current-client! wm (and (not (null? (wm:clients wm)))
 | 
				
			||||||
					    (car (wm:clients wm)))))
 | 
										     (car (wm:clients wm)))))
 | 
				
			||||||
	(send (wm:internal-out-channel wm) (list 'deinit-client client))
 | 
						 (send-message+wait (wm:internal-out-channel wm)
 | 
				
			||||||
	;; sync ??
 | 
								    (list 'deinit-client client))
 | 
				
			||||||
	(destroy-window dpy (client:client-window client))))
 | 
						 (destroy-window dpy (client:client-window client))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
     ((select-client)
 | 
					      ((select-client)
 | 
				
			||||||
      (let ((client (second msg))
 | 
					       (let ((client (second msg))
 | 
				
			||||||
	    (time (third msg)))
 | 
						     (time (third msg)))
 | 
				
			||||||
	(for-each (lambda (client)
 | 
						 (for-each (lambda (client)
 | 
				
			||||||
		    (set-wm:current-client! wm client)
 | 
							     (set-wm:current-client! wm client)
 | 
				
			||||||
		    (raise-window dpy (client:client-window client))
 | 
							     (raise-window dpy (client:client-window client))
 | 
				
			||||||
		    (if (window-exists? dpy (client:window client))
 | 
							     (if (window-exists? dpy (client:window client))
 | 
				
			||||||
			(take-focus dpy (client:window client) time)))
 | 
								 (take-focus dpy (client:window client) time)))
 | 
				
			||||||
		  (cons client (transients-for-client wm client)))
 | 
							   (cons client (transients-for-client wm client)))))
 | 
				
			||||||
;	(for-each (lambda (c)
 | 
					      
 | 
				
			||||||
;		    (if (not (eq? c client))
 | 
					      (else (warn "unhandled manager message" wm msg)))))
 | 
				
			||||||
;			(grab-button dpy
 | 
					 | 
				
			||||||
;				     (button button1) (state-set)
 | 
					 | 
				
			||||||
;				     (client:client-window c) #f
 | 
					 | 
				
			||||||
;				     (event-mask button-press)
 | 
					 | 
				
			||||||
;				     (grab-mode async) (grab-mode async)
 | 
					 | 
				
			||||||
;				     none none)))
 | 
					 | 
				
			||||||
;		  (wm:clients wm))
 | 
					 | 
				
			||||||
	))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
     )))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (wm-deinit-client wm client)
 | 
					(define (wm-deinit-client wm client)
 | 
				
			||||||
  (mdisplay "manager deinit-client " wm " " client "\n")
 | 
					 | 
				
			||||||
  (send (wm:in-channel wm) (list 'deinit-client client)))
 | 
					  (send (wm:in-channel wm) (list 'deinit-client client)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; *** external messages *********************************************
 | 
					;; *** external messages *********************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (wm-manage-window wm window . rect)
 | 
					(define (wm-manage-window wm window . rect)
 | 
				
			||||||
  (send (wm:in-channel wm)
 | 
					  (let ((maybe-rect (if (null? rect)
 | 
				
			||||||
	(list 'manage-window window
 | 
								#f
 | 
				
			||||||
	      (if (null? rect)
 | 
								(car rect))))
 | 
				
			||||||
		  #f
 | 
					    (send-message+wait (wm:in-channel wm)
 | 
				
			||||||
		  (car rect))))
 | 
							       (list 'manage-window window maybe-rect))))
 | 
				
			||||||
  ;; sync ??
 | 
					 | 
				
			||||||
  )
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (wm-configure-window wm window changes)
 | 
					(define (wm-configure-window wm window changes)
 | 
				
			||||||
  (send (wm:in-channel wm) (list 'configure-window window changes)))
 | 
					  (send-message+wait (wm:in-channel wm)
 | 
				
			||||||
 | 
							     (list 'configure-window window changes)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (wm-unmanage-window wm window)
 | 
					(define (wm-unmanage-window wm window)
 | 
				
			||||||
  (send (wm:in-channel wm) (list 'unmanage-window window)))
 | 
					  (send (wm:in-channel wm) (list 'unmanage-window window)))
 | 
				
			||||||
| 
						 | 
					@ -240,7 +240,7 @@
 | 
				
			||||||
	   (send (wm:in-channel wm) (list 'select-client client time)))))
 | 
						   (send (wm:in-channel wm) (list 'select-client client time)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (destroy-wm wm)
 | 
					(define (destroy-wm wm)
 | 
				
			||||||
  (send (wm:in-channel wm) '(destroy-manager)))
 | 
					  (send-message+wait (wm:in-channel wm) '(destroy-manager)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (send-root-drop wm window x y)
 | 
					(define (send-root-drop wm window x y)
 | 
				
			||||||
  (send (wm:out-channel wm) (list 'root-drop window x y)))
 | 
					  (send (wm:out-channel wm) (list 'root-drop window x y)))
 | 
				
			||||||
| 
						 | 
					@ -248,19 +248,27 @@
 | 
				
			||||||
;; *** client ********************************************************
 | 
					;; *** client ********************************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-record-type client :client
 | 
					(define-record-type client :client
 | 
				
			||||||
  (make-client window client-window in-channel data)
 | 
					  (make-client window client-window in-channel data focused?)
 | 
				
			||||||
  client?
 | 
					  client?
 | 
				
			||||||
  (window client:window set-client:window!)
 | 
					  (window client:window set-client:window!)
 | 
				
			||||||
  (client-window client:client-window)
 | 
					  (client-window client:client-window)
 | 
				
			||||||
  (in-channel client:in-channel)
 | 
					  (in-channel client:in-channel)
 | 
				
			||||||
  (data client:data set-client:data!))
 | 
					  (data client:data set-client:data!)
 | 
				
			||||||
 | 
					  (focused? client:focused? set-client:focused?!))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (set-client-focused?! wm client focused?)
 | 
				
			||||||
 | 
					  (let ((prev (client:focused? client)))
 | 
				
			||||||
 | 
					    (if (not (eq? prev focused?))
 | 
				
			||||||
 | 
						(begin
 | 
				
			||||||
 | 
						  (set-client:focused?! client focused?)
 | 
				
			||||||
 | 
						  (send (wm:internal-out-channel wm)
 | 
				
			||||||
 | 
							(list 'update-client-state client focused?))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-record-discloser :client
 | 
					(define-record-discloser :client
 | 
				
			||||||
  (lambda (c)
 | 
					  (lambda (c)
 | 
				
			||||||
    `(Client ,(client:window c) in ,(client:client-window c))))
 | 
					    `(Client ,(client:window c) in ,(client:client-window c))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (create-client wm window)
 | 
					(define (create-client wm window)
 | 
				
			||||||
  (mdisplay "creating client for " window "\n")
 | 
					 | 
				
			||||||
  (let* ((dpy (wm:dpy wm))
 | 
					  (let* ((dpy (wm:dpy wm))
 | 
				
			||||||
	 (client-window (create-simple-window dpy (wm:window wm)
 | 
						 (client-window (create-simple-window dpy (wm:window wm)
 | 
				
			||||||
					      0 0
 | 
										      0 0
 | 
				
			||||||
| 
						 | 
					@ -270,10 +278,9 @@
 | 
				
			||||||
					      (white-pixel dpy)
 | 
										      (white-pixel dpy)
 | 
				
			||||||
					      (black-pixel dpy)))
 | 
										      (black-pixel dpy)))
 | 
				
			||||||
	 (in-channel (make-channel))
 | 
						 (in-channel (make-channel))
 | 
				
			||||||
	 (client (make-client window client-window in-channel #f)))
 | 
						 (client (make-client window client-window in-channel #f #f)))
 | 
				
			||||||
    (reparent-window dpy window client-window 0 0)
 | 
					    (reparent-window dpy window client-window 0 0)
 | 
				
			||||||
    (create-client-handler wm client)
 | 
					    (create-client-handler wm client)
 | 
				
			||||||
    ;;(map-window dpy window)
 | 
					 | 
				
			||||||
    client))
 | 
					    client))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (create-client-handler wm client)
 | 
					(define (create-client-handler wm client)
 | 
				
			||||||
| 
						 | 
					@ -303,9 +310,11 @@
 | 
				
			||||||
		       (lambda (msg)
 | 
							       (lambda (msg)
 | 
				
			||||||
			 (case (car msg)
 | 
								 (case (car msg)
 | 
				
			||||||
			   ((restart-handler)
 | 
								   ((restart-handler)
 | 
				
			||||||
			    (mdisplay "restart-handler " wm " " client "\n")
 | 
					 | 
				
			||||||
			    (create-client-handler wm client)
 | 
								    (create-client-handler wm client)
 | 
				
			||||||
			    (exit 'restart)))))
 | 
								    (sync-point-release (second msg))
 | 
				
			||||||
 | 
								    (exit 'restart))
 | 
				
			||||||
 | 
								   (else (warn "unhandled client message" wm
 | 
				
			||||||
 | 
									       client msg)))))
 | 
				
			||||||
		 (wrap (receive-rv client-window-channel)
 | 
							 (wrap (receive-rv client-window-channel)
 | 
				
			||||||
		       (lambda (xevent)
 | 
							       (lambda (xevent)
 | 
				
			||||||
			 (handle-client-window-xevent wm exit client xevent)))
 | 
								 (handle-client-window-xevent wm exit client xevent)))
 | 
				
			||||||
| 
						 | 
					@ -315,13 +324,11 @@
 | 
				
			||||||
		(loop)))))))))))
 | 
							(loop)))))))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (client-of-window wm window)
 | 
					(define (client-of-window wm window)
 | 
				
			||||||
  (let ((l (filter (lambda (client)
 | 
					  (find (lambda (client)
 | 
				
			||||||
		     (equal? window (client:window client)))
 | 
						  (equal? window (client:window client)))
 | 
				
			||||||
		   (wm-clients wm))))
 | 
						(wm-clients wm)))
 | 
				
			||||||
    (and (pair? l) (car l))))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (client-replace-window wm old-window new-window)
 | 
					(define (client-replace-window wm old-window new-window)
 | 
				
			||||||
  (mdisplay "client-replace-window: " wm " " old-window " " new-window "\n")
 | 
					 | 
				
			||||||
  (let ((client (client-of-window wm old-window))
 | 
					  (let ((client (client-of-window wm old-window))
 | 
				
			||||||
	(internal-out-channel (wm:internal-out-channel wm))
 | 
						(internal-out-channel (wm:internal-out-channel wm))
 | 
				
			||||||
	(dpy (wm:dpy wm)))
 | 
						(dpy (wm:dpy wm)))
 | 
				
			||||||
| 
						 | 
					@ -332,16 +339,14 @@
 | 
				
			||||||
			   (client:client-window client)))
 | 
								   (client:client-window client)))
 | 
				
			||||||
	      (reparent-window dpy new-window (client:client-window client)
 | 
						      (reparent-window dpy new-window (client:client-window client)
 | 
				
			||||||
			       0 0))
 | 
								       0 0))
 | 
				
			||||||
	  (send (client:in-channel client) '(restart-handler))
 | 
						  (let ((sp (make-sync-point)))
 | 
				
			||||||
	  ;; wait ?!
 | 
						    (send (client:in-channel client)
 | 
				
			||||||
	  ;; update everything... TODO
 | 
							  (list 'restart-handler sp))
 | 
				
			||||||
	  ;;(send internal-out-channel (list 'init-client client #f))
 | 
						    (sync-point-wait sp))
 | 
				
			||||||
	  (send internal-out-channel (list 'fit-client client))
 | 
						  (send-message+wait internal-out-channel (list 'fit-client client))
 | 
				
			||||||
	  ;;(send internal-out-channel (list 'fit-windows client))
 | 
						  (send internal-out-channel
 | 
				
			||||||
	  ;; sync ??
 | 
							(list 'update-client-name client (client-name dpy client)))
 | 
				
			||||||
	  (map-window (wm:dpy wm) new-window)
 | 
						  (map-window (wm:dpy wm) new-window))
 | 
				
			||||||
	  (send internal-out-channel (list 'update-client-state client))
 | 
					 | 
				
			||||||
	  )
 | 
					 | 
				
			||||||
	#f)))
 | 
						#f)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (handle-client-window-xevent wm exit client xevent)
 | 
					(define (handle-client-window-xevent wm exit client xevent)
 | 
				
			||||||
| 
						 | 
					@ -370,18 +375,17 @@
 | 
				
			||||||
					changes))
 | 
										changes))
 | 
				
			||||||
	      (send internal-out-channel (list 'fit-client-window client)))
 | 
						      (send internal-out-channel (list 'fit-client-window client)))
 | 
				
			||||||
	    (send-configuration dpy (client:window client)))))
 | 
						    (send-configuration dpy (client:window client)))))
 | 
				
			||||||
     ((circulate-event? xevent)
 | 
					;;     ((circulate-event? xevent)
 | 
				
			||||||
      (send internal-out-channel (list 'update-client-state client)))
 | 
					;;      (send internal-out-channel (list 'update-client-state client)))
 | 
				
			||||||
     ((eq? (event-type enter-notify) type)
 | 
					     ((eq? (event-type enter-notify) type)
 | 
				
			||||||
      (if (memq 'enter (get-option-value (wm:options wm) 'focus-policy))
 | 
					      (if (memq 'enter (get-option-value (wm:options wm) 'focus-policy))
 | 
				
			||||||
	  (wm-select-client wm client (crossing-event-time xevent))))
 | 
						  (wm-select-client wm client (crossing-event-time xevent))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     ((eq? (event-type button-press) type)
 | 
					;;     ((eq? (event-type button-press) type)
 | 
				
			||||||
      (if (memq 'click (get-option-value (wm:options wm) 'focus-policy))
 | 
					;;      (if (memq 'click (get-option-value (wm:options wm) 'focus-policy))
 | 
				
			||||||
	  (wm-select-client wm client (button-event-time xevent))))
 | 
					;;	  (wm-select-client wm client (button-event-time xevent))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
     ((destroy-window-event? xevent)
 | 
					     ((destroy-window-event? xevent)
 | 
				
			||||||
      (mdisplay "client-window destroyed" wm client "\n")
 | 
					 | 
				
			||||||
      (exit 'destroy)))))
 | 
					      (exit 'destroy)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (handle-client-xevent wm exit client xevent)
 | 
					(define (handle-client-xevent wm exit client xevent)
 | 
				
			||||||
| 
						 | 
					@ -389,29 +393,23 @@
 | 
				
			||||||
	(internal-out-channel (wm:internal-out-channel wm))
 | 
						(internal-out-channel (wm:internal-out-channel wm))
 | 
				
			||||||
	(dpy (wm:dpy wm)))
 | 
						(dpy (wm:dpy wm)))
 | 
				
			||||||
    (cond
 | 
					    (cond
 | 
				
			||||||
     ((eq? (event-type focus-out) type)
 | 
					     ((focus-change-event? xevent)
 | 
				
			||||||
      (if (window-exists? dpy (client:window client))
 | 
					      (if (window-exists? dpy (client:window client))
 | 
				
			||||||
	  (let ((mode (focus-change-event-mode xevent))
 | 
						  (let ((mode (focus-change-event-mode xevent))
 | 
				
			||||||
		(detail (focus-change-event-detail xevent)))
 | 
							(detail (focus-change-event-detail xevent)))
 | 
				
			||||||
	    (if (and (eq? mode (notify-mode normal))
 | 
						    (if (and (eq? mode (notify-mode normal))
 | 
				
			||||||
		     (memq detail (list (notify-detail nonlinear)
 | 
							     (memq detail (list (notify-detail nonlinear)
 | 
				
			||||||
					(notify-detail nonlinear-virtual)
 | 
										(notify-detail nonlinear-virtual)
 | 
				
			||||||
 | 
										(notify-detail virtual)
 | 
				
			||||||
					(notify-detail ancestor))))
 | 
										(notify-detail ancestor))))
 | 
				
			||||||
		(uninstall-colormaps dpy (client:window client)))))
 | 
							(if (eq? (event-type focus-in)
 | 
				
			||||||
      (send internal-out-channel
 | 
								 (focus-change-event-type xevent))
 | 
				
			||||||
	    (list 'update-client-state client)))
 | 
							    (begin
 | 
				
			||||||
 | 
							      (install-colormaps dpy (client:window client))
 | 
				
			||||||
     ((eq? (event-type focus-in) type)
 | 
							      (set-client-focused?! wm client #t))
 | 
				
			||||||
      (if (window-exists? dpy (client:window client))
 | 
							    (begin
 | 
				
			||||||
	  (let ((mode (focus-change-event-mode xevent))
 | 
							      (uninstall-colormaps dpy (client:window client))
 | 
				
			||||||
		(detail (focus-change-event-detail xevent)))
 | 
							      (set-client-focused?! wm client #f)))))))
 | 
				
			||||||
	    (if (and (eq? mode (notify-mode normal))
 | 
					 | 
				
			||||||
		     (memq detail (list (notify-detail nonlinear)
 | 
					 | 
				
			||||||
					(notify-detail nonlinear-virtual)
 | 
					 | 
				
			||||||
					(notify-detail ancestor))))
 | 
					 | 
				
			||||||
		(install-colormaps dpy (client:window client)))))
 | 
					 | 
				
			||||||
      (send internal-out-channel
 | 
					 | 
				
			||||||
	    (list 'update-client-state client)))
 | 
					 | 
				
			||||||
     
 | 
					     
 | 
				
			||||||
     ((property-event? xevent)
 | 
					     ((property-event? xevent)
 | 
				
			||||||
      (if (window-exists? dpy (client:window client))
 | 
					      (if (window-exists? dpy (client:window client))
 | 
				
			||||||
| 
						 | 
					@ -420,20 +418,18 @@
 | 
				
			||||||
	    (cond
 | 
						    (cond
 | 
				
			||||||
	     ((equal? "WM_NAME" name)
 | 
						     ((equal? "WM_NAME" name)
 | 
				
			||||||
	      (send internal-out-channel
 | 
						      (send internal-out-channel
 | 
				
			||||||
		    (list 'update-client-state client)))
 | 
							    (list 'update-client-name client
 | 
				
			||||||
	     ;; TODO: respect NORMAL_HINTS change
 | 
								  (client-name dpy client))))))))
 | 
				
			||||||
	     ))))
 | 
					
 | 
				
			||||||
     ((reparent-event? xevent)
 | 
					     ((reparent-event? xevent)
 | 
				
			||||||
      (if (and (window-exists? dpy (client:window client))
 | 
					      (if (and (window-exists? dpy (client:window client))
 | 
				
			||||||
	       (not (eq? (client:client-window client)
 | 
						       (not (eq? (client:client-window client)
 | 
				
			||||||
			 (window-parent dpy (client:window client)))))
 | 
								 (window-parent dpy (client:window client)))))
 | 
				
			||||||
	  (begin
 | 
						  (begin
 | 
				
			||||||
	    ;; window has been reparented away
 | 
						    ;; window has been reparented away
 | 
				
			||||||
	    (mdisplay "manager " (wm:type wm) " reparented client\n")
 | 
					 | 
				
			||||||
	    (wm-deinit-client wm client)
 | 
						    (wm-deinit-client wm client)
 | 
				
			||||||
	    (exit 'reparent))))
 | 
						    (exit 'reparent))))
 | 
				
			||||||
     ((destroy-window-event? xevent)
 | 
					     ((destroy-window-event? xevent)
 | 
				
			||||||
      (mdisplay "destroy-window-event client " wm " " client "\n")
 | 
					 | 
				
			||||||
      (if (eq? (client:window client) (destroy-window-event-event xevent))
 | 
					      (if (eq? (client:window client) (destroy-window-event-event xevent))
 | 
				
			||||||
	  (begin
 | 
						  (begin
 | 
				
			||||||
	    (wm-deinit-client wm client)
 | 
						    (wm-deinit-client wm client)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@
 | 
				
			||||||
		     xc-bottom-side xc-bottom-left-corner default-cursor))))
 | 
							     xc-bottom-side xc-bottom-left-corner default-cursor))))
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    (spawn*
 | 
					    (spawn*
 | 
				
			||||||
 | 
					     (list 'move-wm-resizer wm client)
 | 
				
			||||||
     (lambda (release)
 | 
					     (lambda (release)
 | 
				
			||||||
       (call-with-event-channel
 | 
					       (call-with-event-channel
 | 
				
			||||||
	dpy window
 | 
						dpy window
 | 
				
			||||||
| 
						 | 
					@ -34,13 +35,14 @@
 | 
				
			||||||
		(lambda ()
 | 
							(lambda ()
 | 
				
			||||||
		  (let ((xevent (receive event-channel)))
 | 
							  (let ((xevent (receive event-channel)))
 | 
				
			||||||
		    (cond
 | 
							    (cond
 | 
				
			||||||
		     ((motion-event? xevent)
 | 
							     ((and (motion-event? xevent) (window-exists? dpy window))
 | 
				
			||||||
		      (set-resize-cursor wm client cursors
 | 
							      (set-resize-cursor wm client cursors
 | 
				
			||||||
					 (motion-event-x xevent)
 | 
										 (motion-event-x xevent)
 | 
				
			||||||
					 (motion-event-y xevent))
 | 
										 (motion-event-y xevent))
 | 
				
			||||||
		      (idle))
 | 
							      (idle))
 | 
				
			||||||
		     ((eq? (event-type button-press)
 | 
							     ((and (eq? (event-type button-press)
 | 
				
			||||||
			   (any-event-type xevent))
 | 
									(any-event-type xevent))
 | 
				
			||||||
 | 
								   (window-exists? dpy window))
 | 
				
			||||||
		      (let* ((x (button-event-x xevent))
 | 
							      (let* ((x (button-event-x xevent))
 | 
				
			||||||
			     (y (button-event-y xevent))
 | 
								     (y (button-event-y xevent))
 | 
				
			||||||
			     (dir (resizer-direction wm client x y)))
 | 
								     (dir (resizer-direction wm client x y)))
 | 
				
			||||||
| 
						 | 
					@ -80,7 +82,11 @@
 | 
				
			||||||
				 prev-rect dir)))))))
 | 
									 prev-rect dir)))))))
 | 
				
			||||||
	    (idle))))
 | 
						    (idle))))
 | 
				
			||||||
       (free-gc dpy gc)
 | 
					       (free-gc dpy gc)
 | 
				
			||||||
       (for-each (lambda (c) (free-cursor dpy (cdr c))) cursors)))))
 | 
					       (for-each (lambda (c) (free-cursor dpy (cdr c))) cursors)))
 | 
				
			||||||
 | 
					    window))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (destroy-resizer dpy resizer)
 | 
				
			||||||
 | 
					  (destroy-window dpy resizer))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (rubber-draw dpy gc rect)
 | 
					(define (rubber-draw dpy gc rect)
 | 
				
			||||||
  (draw-rectangle dpy (default-root-window dpy) gc
 | 
					  (draw-rectangle dpy (default-root-window dpy) gc
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										165
									
								
								src/move-wm.scm
								
								
								
								
							
							
						
						
									
										165
									
								
								src/move-wm.scm
								
								
								
								
							| 
						 | 
					@ -10,73 +10,103 @@
 | 
				
			||||||
  (border-colors colors '("#333333" "#dddddd"))
 | 
					  (border-colors colors '("#333333" "#dddddd"))
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (create-move-wm out-channel dpy parent options . children)
 | 
					(define (create-move-wm out-channel dpy parent options default-options
 | 
				
			||||||
  (create-wm dpy parent options children
 | 
								. children)
 | 
				
			||||||
 | 
					  (create-wm dpy parent options default-options 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)
 | 
				
			||||||
	       (spawn* (list 'move-wm wm)
 | 
						       (init-move-wm wm in-channel)
 | 
				
			||||||
		       (lambda (release)
 | 
					 | 
				
			||||||
			 (release)
 | 
					 | 
				
			||||||
			 (move-wm-handler wm in-channel)))
 | 
					 | 
				
			||||||
	       wm)))
 | 
						       wm)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (move-wm-handler wm channel)
 | 
					(define (init-move-wm wm channel)
 | 
				
			||||||
  (let* ((dpy (wm:dpy wm))
 | 
					  (let* ((dpy (wm:dpy wm))
 | 
				
			||||||
	 (window (wm:window wm))
 | 
						 (window (wm:window wm))
 | 
				
			||||||
	 (gc (create-gc dpy window '())))
 | 
						 (gc (create-gc dpy window '())))
 | 
				
			||||||
    (let loop ()
 | 
					    (spawn* (list 'move-wm wm)
 | 
				
			||||||
      (let ((msg (receive channel)))
 | 
						    (lambda (release)
 | 
				
			||||||
	(case (car msg)
 | 
						      (release)
 | 
				
			||||||
	  ((draw-main-window)
 | 
						      (call-with-current-continuation
 | 
				
			||||||
	   (set-gc-foreground! dpy gc (black-pixel dpy))
 | 
						       (lambda (exit)
 | 
				
			||||||
	   (fill-rectangle* dpy window gc
 | 
							 (let loop ()
 | 
				
			||||||
			    (clip-rectangle dpy window)))
 | 
							   (let ((msg (receive channel)))
 | 
				
			||||||
 | 
							     (handle-message wm gc exit msg)
 | 
				
			||||||
 | 
							     (loop)))))
 | 
				
			||||||
 | 
						      (free-gc dpy gc)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((fit-windows)
 | 
					(define (handle-message wm gc exit msg)
 | 
				
			||||||
	   (map (lambda (client)
 | 
					  (let ((dpy (wm:dpy wm))
 | 
				
			||||||
		  (assert-client-visible wm client))
 | 
						(window (wm:window wm)))
 | 
				
			||||||
		(wm-clients wm)))
 | 
					    (case (car msg)
 | 
				
			||||||
	  
 | 
					      ((wait)
 | 
				
			||||||
	  ((init-client)
 | 
					       (let ((sp (second msg))
 | 
				
			||||||
	   (init-client wm (second msg) (third msg)))
 | 
						     (message (third msg)))
 | 
				
			||||||
	  ((deinit-client)
 | 
						 (handle-message wm gc
 | 
				
			||||||
	   (deinit-client wm (second msg)))
 | 
								 (lambda args
 | 
				
			||||||
	  
 | 
								   (sync-point-release sp)
 | 
				
			||||||
	  ((configure-window)
 | 
								   (apply exit args))
 | 
				
			||||||
	   (let ((window (second msg))
 | 
								 message)
 | 
				
			||||||
		 (changes (third msg)))
 | 
						 (sync-point-release sp)))
 | 
				
			||||||
	     ;; TODO: exact sizes ?!
 | 
					      
 | 
				
			||||||
	     (configure-window dpy window
 | 
					      ((deinit-manager)
 | 
				
			||||||
			       (append (make-window-change-alist
 | 
					       (exit 'deinit-manager))
 | 
				
			||||||
					(border-width 0))
 | 
					 | 
				
			||||||
				       changes))))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((draw-client-window)
 | 
					      ((draw-main-window)
 | 
				
			||||||
	   (draw-client-window wm (second msg) gc))
 | 
					       (set-gc-foreground! dpy gc (black-pixel dpy))
 | 
				
			||||||
	  ((fit-client)
 | 
					       (fill-rectangle* dpy window gc
 | 
				
			||||||
	   ;; client-window changed it's size
 | 
								(clip-rectangle dpy window)))
 | 
				
			||||||
	   (fit-client-windows wm (second msg)))
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((fit-client-window)
 | 
					 | 
				
			||||||
	   ;; client changed it's size ??
 | 
					 | 
				
			||||||
	   (fit-client-window wm (second msg)))
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((manager-focused) #t)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((update-client-state)
 | 
					      ((update-manager-state) #t)
 | 
				
			||||||
	   (let* ((client (second msg))
 | 
					      
 | 
				
			||||||
		  (dpy (wm:dpy wm))
 | 
					      ((fit-windows)
 | 
				
			||||||
		  (window (client:window client))
 | 
					       (map (lambda (client)
 | 
				
			||||||
		  (state (if (window-contains-focus? dpy window)
 | 
						      (assert-client-visible wm client))
 | 
				
			||||||
			     'focused
 | 
						    (wm-clients wm)))
 | 
				
			||||||
			     'normal))
 | 
					      
 | 
				
			||||||
		  (titlebar (car (client:data client)))
 | 
					      ((init-client)
 | 
				
			||||||
		  (name (client-name (wm:dpy wm) client)))
 | 
					       (init-client wm (second msg) (third msg)))
 | 
				
			||||||
	     (set-titlebar-title+state! titlebar name state)))
 | 
					      
 | 
				
			||||||
	  ))
 | 
					      ((deinit-client)
 | 
				
			||||||
      (loop))
 | 
					       (deinit-client wm (second msg)))
 | 
				
			||||||
    (free-gc (wm:dpy wm) gc)))
 | 
					      
 | 
				
			||||||
 | 
					      ((configure-window)
 | 
				
			||||||
 | 
					       (let ((window (second msg))
 | 
				
			||||||
 | 
						     (changes (third msg)))
 | 
				
			||||||
 | 
						 ;; TODO: exact sizes ?!
 | 
				
			||||||
 | 
						 (configure-window dpy window
 | 
				
			||||||
 | 
								   (append (make-window-change-alist
 | 
				
			||||||
 | 
									    (border-width 0))
 | 
				
			||||||
 | 
									   changes))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((draw-client-window)
 | 
				
			||||||
 | 
					       (draw-client-window wm (second msg) gc))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((fit-client)
 | 
				
			||||||
 | 
					       ;; client-window changed it's size
 | 
				
			||||||
 | 
					       (fit-client-windows wm (second msg)))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((fit-client-window)
 | 
				
			||||||
 | 
					       ;; client changed it's size ??
 | 
				
			||||||
 | 
					       (fit-client-window wm (second msg)))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((manager-focused) #t)
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((update-client-state)
 | 
				
			||||||
 | 
					       (let* ((client (second msg))
 | 
				
			||||||
 | 
						      (focused? (third msg))
 | 
				
			||||||
 | 
						      (state (if focused?
 | 
				
			||||||
 | 
								 'focused
 | 
				
			||||||
 | 
								 'normal))
 | 
				
			||||||
 | 
						      (titlebar (car (client:data client))))
 | 
				
			||||||
 | 
						 (set-titlebar-state! titlebar state)))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((update-client-name)
 | 
				
			||||||
 | 
					       (let ((client (second msg))
 | 
				
			||||||
 | 
						     (name (third msg)))
 | 
				
			||||||
 | 
						 (let ((titlebar (car (client:data client))))
 | 
				
			||||||
 | 
						   (set-titlebar-title! titlebar name))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      (else (warn "unhandled move-wm message" wm msg)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (init-client wm client maybe-rect)
 | 
					(define (init-client wm client maybe-rect)
 | 
				
			||||||
  (let ((dpy (wm:dpy wm)))
 | 
					  (let ((dpy (wm:dpy wm)))
 | 
				
			||||||
| 
						 | 
					@ -127,7 +157,8 @@
 | 
				
			||||||
		      (delete-window dpy (client:window client) (second msg)))
 | 
							      (delete-window dpy (client:window client) (second msg)))
 | 
				
			||||||
		     ))))
 | 
							     ))))
 | 
				
			||||||
	   ;; TODO: internal channel
 | 
						   ;; TODO: internal channel
 | 
				
			||||||
	   (loop))))
 | 
						   (loop))
 | 
				
			||||||
 | 
						 (destroy-resizer dpy resizer)))
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      (map-titlebar titlebar)
 | 
					      (map-titlebar titlebar)
 | 
				
			||||||
      (if (window-exists? dpy (client:window client))
 | 
					      (if (window-exists? dpy (client:window client))
 | 
				
			||||||
| 
						 | 
					@ -138,8 +169,8 @@
 | 
				
			||||||
  (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)
 | 
				
			||||||
		     ;; TODO: buttons
 | 
							     (list (cons 'buttons '(kill maximize))
 | 
				
			||||||
		     (list (cons 'normal-colors
 | 
								   (cons 'normal-colors
 | 
				
			||||||
				 (get-option options 'titlebar-colors))
 | 
									 (get-option options 'titlebar-colors))
 | 
				
			||||||
			   (cons 'active-colors
 | 
								   (cons 'active-colors
 | 
				
			||||||
				 (get-option options'titlebar-colors-focused))
 | 
									 (get-option options'titlebar-colors-focused))
 | 
				
			||||||
| 
						 | 
					@ -222,8 +253,20 @@
 | 
				
			||||||
  (if maybe-rect
 | 
					  (if maybe-rect
 | 
				
			||||||
      maybe-rect
 | 
					      maybe-rect
 | 
				
			||||||
      (let* ((dpy (wm:dpy wm))
 | 
					      (let* ((dpy (wm:dpy wm))
 | 
				
			||||||
	     (w.h (desired-size/hints dpy win
 | 
						     (default-width 400)
 | 
				
			||||||
				      (maximal-size/hints dpy win 400 200)))
 | 
						     (default-height 200)
 | 
				
			||||||
 | 
						     (w.h-1
 | 
				
			||||||
 | 
						      (let ((w.h (minimal-size/hints dpy win default-width
 | 
				
			||||||
 | 
										     default-height)))
 | 
				
			||||||
 | 
							(cons (if (< default-width (car w.h))
 | 
				
			||||||
 | 
								  (car w.h)
 | 
				
			||||||
 | 
								  default-width)
 | 
				
			||||||
 | 
							      (if (< default-height (cdr w.h))
 | 
				
			||||||
 | 
								  (cdr w.h)
 | 
				
			||||||
 | 
								  default-height))))
 | 
				
			||||||
 | 
						     (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))
 | 
				
			||||||
 | 
						     ;; TODO: look for a free position ?! Transients centered?
 | 
				
			||||||
	     (x.y (desired-position/hints dpy win (cons 0 0))))
 | 
						     (x.y (desired-position/hints dpy win (cons 0 0))))
 | 
				
			||||||
	(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)))))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										223
									
								
								src/split-wm.scm
								
								
								
								
							
							
						
						
									
										223
									
								
								src/split-wm.scm
								
								
								
								
							| 
						 | 
					@ -17,100 +17,128 @@
 | 
				
			||||||
;; |        |              |    |   |
 | 
					;; |        |              |    |   |
 | 
				
			||||||
;; ----------              ----------
 | 
					;; ----------              ----------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (create-split-wm external-in-channel dpy parent options . children)
 | 
					(define (create-split-wm external-in-channel dpy parent options
 | 
				
			||||||
  (create-wm dpy parent options children
 | 
								 default-options . children)
 | 
				
			||||||
 | 
					  (create-wm dpy parent options default-options children
 | 
				
			||||||
	     (manager-type split) split-wm-options-spec
 | 
						     (manager-type split) split-wm-options-spec
 | 
				
			||||||
	     external-in-channel
 | 
						     external-in-channel
 | 
				
			||||||
	     (lambda (wm in-channel)
 | 
						     (lambda (wm in-channel)
 | 
				
			||||||
	       (spawn* (list 'split-wm wm)
 | 
						       (init-split-wm wm in-channel)
 | 
				
			||||||
		       (lambda (release)
 | 
					 | 
				
			||||||
			 (release)
 | 
					 | 
				
			||||||
			 (split-wm-handler wm in-channel)))
 | 
					 | 
				
			||||||
	       wm)))
 | 
						       wm)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (split-wm? wm)
 | 
					(define-record-type split-data :split-data
 | 
				
			||||||
  (and (wm? wm) (eq? (wm:type wm) (manager-type split))))
 | 
					  (make-split-data resizer first-client second-client)
 | 
				
			||||||
 | 
					  split-data?
 | 
				
			||||||
 | 
					  (resizer data:resizer)
 | 
				
			||||||
 | 
					  (first-client data:first-client set-data:first-client!)
 | 
				
			||||||
 | 
					  (second-client data:second-client set-data:second-client!))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (split-wm-handler wm channel)
 | 
					(define (init-split-wm wm channel)
 | 
				
			||||||
  (let ((resizer-window (create-resizer wm))
 | 
					  (let* ((resizer (create-resizer wm))
 | 
				
			||||||
	(dpy (wm:dpy wm))
 | 
						 (data (make-split-data resizer #f #f)))
 | 
				
			||||||
	(first-client #f)
 | 
					    (spawn* (list 'split-wm wm)
 | 
				
			||||||
	(second-client #f))
 | 
						    (lambda (release)
 | 
				
			||||||
    (map-window (wm:dpy wm) resizer-window)
 | 
						      (map-window (wm:dpy wm) resizer)
 | 
				
			||||||
    (let loop ()
 | 
						      (release)
 | 
				
			||||||
      (let ((msg (receive channel)))
 | 
						      (call-with-current-continuation
 | 
				
			||||||
	(case (car msg)
 | 
						       (lambda (exit)
 | 
				
			||||||
	  ((draw-main-window) #t)
 | 
							 (let loop ()
 | 
				
			||||||
	  
 | 
							   (let ((msg (receive channel)))
 | 
				
			||||||
	  ((fit-windows)
 | 
							     (handle-message wm channel data exit msg)
 | 
				
			||||||
	   (fit-windows wm resizer-window first-client second-client))
 | 
							     (loop)))))))))
 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((init-client)
 | 
					 | 
				
			||||||
	   (let ((client (second msg))
 | 
					 | 
				
			||||||
		 (first? (not first-client)))
 | 
					 | 
				
			||||||
	     (if first?
 | 
					 | 
				
			||||||
		 (set! first-client client)
 | 
					 | 
				
			||||||
		 (set! second-client client))
 | 
					 | 
				
			||||||
	     
 | 
					 | 
				
			||||||
	     (set-window-border-width! dpy (client:window client) 0)
 | 
					 | 
				
			||||||
	     (fit-windows wm resizer-window first-client second-client)
 | 
					 | 
				
			||||||
	   
 | 
					 | 
				
			||||||
	     (map-window dpy (client:window client))
 | 
					 | 
				
			||||||
	     (map-window dpy (client:client-window client))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	     (let ((opt (if (eq? (get-option-value (wm:options wm)
 | 
					(define (handle-message wm channel data exit msg)
 | 
				
			||||||
						   'orientation)
 | 
					  (let ((dpy (wm:dpy wm)))
 | 
				
			||||||
				 'horizontal)
 | 
					    (case (car msg)
 | 
				
			||||||
			    (if first? 'select-right 'select-left)
 | 
					      ((wait)
 | 
				
			||||||
			    (if first? 'select-down 'select-up))))
 | 
					       (let ((sp (second msg))
 | 
				
			||||||
	       (grab-shortcut dpy (client:client-window client)
 | 
						     (message (third msg)))
 | 
				
			||||||
			      (get-option-value (wm:options wm) opt)
 | 
						 (handle-message wm channel data
 | 
				
			||||||
			      (if first? 'select-second 'select-first)
 | 
								 (lambda args
 | 
				
			||||||
			      channel #f))
 | 
								   (sync-point-release sp)
 | 
				
			||||||
	     ))
 | 
								   (apply exit args))
 | 
				
			||||||
	  
 | 
								 message)
 | 
				
			||||||
	  ((deinit-client)
 | 
						 (sync-point-release sp)))
 | 
				
			||||||
	   (let ((client (second msg)))
 | 
					      
 | 
				
			||||||
	     (if (eq? client first-client)
 | 
					      ((deinit-manager)
 | 
				
			||||||
		 (set! first-client #f))
 | 
					       (destroy-window dpy (data:resizer data))
 | 
				
			||||||
	     (if (eq? client second-client)
 | 
					       (exit 'deinit-manager))
 | 
				
			||||||
		 (set! second-client #f))
 | 
					 | 
				
			||||||
	     ;; destroy split if only one client left
 | 
					 | 
				
			||||||
	     (if (and (not (and first-client second-client))
 | 
					 | 
				
			||||||
		      (or first-client second-client))
 | 
					 | 
				
			||||||
		 (let ((repl (client:window (or first-client second-client))))
 | 
					 | 
				
			||||||
		   (mdisplay "destroying " wm ". with replacement " repl "\n")
 | 
					 | 
				
			||||||
		   (send (wm:out-channel wm)
 | 
					 | 
				
			||||||
			 (list 'destroy-wm wm repl))))))
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((draw-client-window) #t)
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((fit-client)
 | 
					 | 
				
			||||||
	   ;; client-window changed it's size
 | 
					 | 
				
			||||||
	   (fit-client-windows wm (second msg)))
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((fit-client-window)
 | 
					 | 
				
			||||||
	   ;; client changed it's size ??
 | 
					 | 
				
			||||||
	   #t)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((manager-focused)
 | 
					      ((draw-main-window) #t)
 | 
				
			||||||
	   (let ((time (second msg))
 | 
					      
 | 
				
			||||||
		 (cc (wm-current-client wm)))
 | 
					      ((update-manager-state) #t)
 | 
				
			||||||
	     (if cc (wm-select-client wm cc time))))
 | 
					      
 | 
				
			||||||
 | 
					      ((fit-windows)
 | 
				
			||||||
 | 
					       (fit-windows wm data))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((init-client)
 | 
				
			||||||
 | 
					       (let ((client (second msg))
 | 
				
			||||||
 | 
						     (first? (not (data:first-client data))))
 | 
				
			||||||
 | 
						 (if first?
 | 
				
			||||||
 | 
						     (set-data:first-client! data client)
 | 
				
			||||||
 | 
						     (set-data:second-client! data client))
 | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						 (set-window-border-width! dpy (client:window client) 0)
 | 
				
			||||||
 | 
						 (fit-windows wm data)
 | 
				
			||||||
 | 
						 
 | 
				
			||||||
 | 
						 (map-window dpy (client:window client))
 | 
				
			||||||
 | 
						 (map-window dpy (client:client-window client))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((update-client-state) #t)
 | 
						 (let ((opt (if (eq? (get-option-value (wm:options wm)
 | 
				
			||||||
 | 
										       'orientation)
 | 
				
			||||||
 | 
								     'horizontal)
 | 
				
			||||||
 | 
								(if first? 'select-right 'select-left)
 | 
				
			||||||
 | 
								(if first? 'select-down 'select-up))))
 | 
				
			||||||
 | 
						   (grab-shortcut dpy (client:client-window client)
 | 
				
			||||||
 | 
								  (get-option-value (wm:options wm) opt)
 | 
				
			||||||
 | 
								  (if first? 'select-second 'select-first)
 | 
				
			||||||
 | 
								  channel #f))
 | 
				
			||||||
 | 
						 ))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((deinit-client)
 | 
				
			||||||
 | 
					       (let ((client (second msg)))
 | 
				
			||||||
 | 
						 (if (eq? client (data:first-client data))
 | 
				
			||||||
 | 
						     (set-data:first-client! data #f))
 | 
				
			||||||
 | 
						 (if (eq? client (data:second-client data))
 | 
				
			||||||
 | 
						     (set-data:second-client! data #f))
 | 
				
			||||||
 | 
						 ;; destroy split if only one client left. replace the
 | 
				
			||||||
 | 
						 ;; wm by the remaining client.
 | 
				
			||||||
 | 
						 (let ((first-client (data:first-client data))
 | 
				
			||||||
 | 
						       (second-client (data:second-client data)))
 | 
				
			||||||
 | 
						   (if (and (not (and first-client second-client))
 | 
				
			||||||
 | 
							    (or first-client second-client))
 | 
				
			||||||
 | 
						       (let ((r (client:window (or first-client second-client))))
 | 
				
			||||||
 | 
							 (send (wm:out-channel wm) (list 'destroy-wm wm r)))))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((draw-client-window) #t)
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((fit-client)
 | 
				
			||||||
 | 
					       ;; client-window changed it's size
 | 
				
			||||||
 | 
					       (fit-client-windows wm (second msg)))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((fit-client-window)
 | 
				
			||||||
 | 
					       ;; client changed it's size ??
 | 
				
			||||||
 | 
					       #t)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ;; Shortcuts
 | 
					      ((manager-focused)
 | 
				
			||||||
	  ((select-first)
 | 
					       (let ((time (second msg))
 | 
				
			||||||
	   (let ((time (second msg)))
 | 
						     (cc (wm-current-client wm)))
 | 
				
			||||||
	     (if first-client
 | 
						 (if cc (wm-select-client wm cc time))))
 | 
				
			||||||
		 (wm-select-client wm first-client time))))
 | 
					
 | 
				
			||||||
	  ((select-second)
 | 
					      ((update-client-state) #t)
 | 
				
			||||||
	   (let ((time (second msg)))
 | 
					      ((update-client-name) #t)
 | 
				
			||||||
	     (if second-client
 | 
					
 | 
				
			||||||
		 (wm-select-client wm second-client time))))
 | 
					      ;; Shortcuts
 | 
				
			||||||
	  ))
 | 
					      ((select-first)
 | 
				
			||||||
      (loop))))
 | 
					       (let ((time (second msg)))
 | 
				
			||||||
 | 
						 (if (data:first-client data)
 | 
				
			||||||
 | 
						     (wm-select-client wm (data:first-client data) time))))
 | 
				
			||||||
 | 
					      ((select-second)
 | 
				
			||||||
 | 
					       (let ((time (second msg)))
 | 
				
			||||||
 | 
						 (if (data:second-client data)
 | 
				
			||||||
 | 
						     (wm-select-client wm (data:second-client data) time))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (else (warn "unhandled split-wm message" wm msg)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (calc-rectangles wm)
 | 
					(define (calc-rectangles wm)
 | 
				
			||||||
  (let* ((options (wm:options wm))
 | 
					  (let* ((options (wm:options wm))
 | 
				
			||||||
| 
						 | 
					@ -141,18 +169,21 @@
 | 
				
			||||||
				      (+ (rectangle:height r1) bar-width)))))
 | 
									      (+ (rectangle:height r1) bar-width)))))
 | 
				
			||||||
	  (list r1 r2 r3)))))
 | 
						  (list r1 r2 r3)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (fit-windows wm resizer-window first-client second-client)
 | 
					(define (fit-windows wm data)
 | 
				
			||||||
  (let* ((rects (calc-rectangles wm))
 | 
					  (let ((resizer-window (data:resizer data))
 | 
				
			||||||
	 (dpy (wm:dpy wm)))
 | 
						(first-client (data:first-client data))
 | 
				
			||||||
    (move-resize-window* dpy resizer-window (second rects))
 | 
						(second-client (data:second-client data)))
 | 
				
			||||||
    (if first-client
 | 
					    (let* ((rects (calc-rectangles wm))
 | 
				
			||||||
	(move-resize-window* dpy
 | 
						   (dpy (wm:dpy wm)))
 | 
				
			||||||
			     (client:client-window first-client)
 | 
					      (move-resize-window* dpy resizer-window (second rects))
 | 
				
			||||||
			     (first rects)))
 | 
					      (if first-client
 | 
				
			||||||
    (if second-client
 | 
						  (move-resize-window* dpy
 | 
				
			||||||
	(move-resize-window* dpy
 | 
								       (client:client-window first-client)
 | 
				
			||||||
			     (client:client-window second-client)
 | 
								       (first rects)))
 | 
				
			||||||
			     (third rects)))))
 | 
					      (if second-client
 | 
				
			||||||
 | 
						  (move-resize-window* dpy
 | 
				
			||||||
 | 
								       (client:client-window second-client)
 | 
				
			||||||
 | 
								       (third rects))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (fit-client-windows wm client)
 | 
					(define (fit-client-windows wm client)
 | 
				
			||||||
  (let ((dpy (wm:dpy wm)))
 | 
					  (let ((dpy (wm:dpy wm)))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,15 +9,13 @@
 | 
				
			||||||
  (select-previous keys "M-k p")
 | 
					  (select-previous keys "M-k p")
 | 
				
			||||||
  )
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (create-switch-wm out-channel dpy parent options . children)
 | 
					(define (create-switch-wm out-channel dpy parent options default-options
 | 
				
			||||||
  (create-wm dpy parent options children
 | 
								  . children)
 | 
				
			||||||
 | 
					  (create-wm dpy parent options default-options children
 | 
				
			||||||
	     (manager-type switch) switch-wm-options-spec
 | 
						     (manager-type switch) switch-wm-options-spec
 | 
				
			||||||
	     out-channel
 | 
						     out-channel
 | 
				
			||||||
	     (lambda (wm in-channel)
 | 
						     (lambda (wm in-channel)
 | 
				
			||||||
	       (spawn* (list 'switch-wm wm)
 | 
						       (init-switch-wm wm in-channel)
 | 
				
			||||||
		       (lambda (release)
 | 
					 | 
				
			||||||
			 (release)
 | 
					 | 
				
			||||||
			 (switch-wm-handler wm in-channel)))
 | 
					 | 
				
			||||||
	       wm)))
 | 
						       wm)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-record-type switch-wm-data :switch-wm-data
 | 
					(define-record-type switch-wm-data :switch-wm-data
 | 
				
			||||||
| 
						 | 
					@ -26,7 +24,7 @@
 | 
				
			||||||
  (titlebars data:titlebars set-data:titlebars!)
 | 
					  (titlebars data:titlebars set-data:titlebars!)
 | 
				
			||||||
  (empty-titlebar data:empty-titlebar))
 | 
					  (empty-titlebar data:empty-titlebar))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (switch-wm-handler wm channel)
 | 
					(define (init-switch-wm wm channel)
 | 
				
			||||||
  (let* ((dpy (wm:dpy wm))
 | 
					  (let* ((dpy (wm:dpy wm))
 | 
				
			||||||
	 (window (wm:window wm))
 | 
						 (window (wm:window wm))
 | 
				
			||||||
	 (options (wm:options wm))
 | 
						 (options (wm:options wm))
 | 
				
			||||||
| 
						 | 
					@ -42,74 +40,111 @@
 | 
				
			||||||
		   (get-option-value options 'select-previous)
 | 
							   (get-option-value options 'select-previous)
 | 
				
			||||||
		   'select-previous channel #f)
 | 
							   'select-previous channel #f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (let loop ()
 | 
					    (spawn* (list 'switch-wm wm)
 | 
				
			||||||
      (let ((msg (receive channel)))
 | 
						    (lambda (release)
 | 
				
			||||||
	(case (car msg)
 | 
						      (release)
 | 
				
			||||||
	  ((draw-main-window)
 | 
						      (call-with-current-continuation
 | 
				
			||||||
	   (set-gc-foreground! dpy gc (black-pixel dpy))
 | 
						       (lambda (exit)
 | 
				
			||||||
	   (fill-rectangle* dpy window gc
 | 
							 (let loop ()
 | 
				
			||||||
			    (clip-rectangle dpy window)))
 | 
							   (let ((msg (receive channel)))
 | 
				
			||||||
 | 
							     (handle-message wm data gc exit msg)
 | 
				
			||||||
 | 
							     (loop)))))
 | 
				
			||||||
 | 
						      (free-gc dpy gc)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((fit-windows)
 | 
					(define (handle-message wm data gc exit msg)
 | 
				
			||||||
	   (fit-titlebars wm data)
 | 
					  (let ((dpy (wm:dpy wm))
 | 
				
			||||||
	   (for-each (lambda (c)
 | 
						(window (wm:window wm)))
 | 
				
			||||||
		       (fit-client-window wm c))
 | 
					    (case (car msg)
 | 
				
			||||||
		     (wm-clients wm)))
 | 
					      ((wait)
 | 
				
			||||||
	  
 | 
					       (let ((sp (second msg))
 | 
				
			||||||
	  ((init-client)
 | 
						     (message (third msg)))
 | 
				
			||||||
	   (init-client wm data (second msg) (third msg)))
 | 
						 (handle-message wm data gc
 | 
				
			||||||
	  ((deinit-client)
 | 
								 (lambda args
 | 
				
			||||||
	   (deinit-client wm data (second msg)))
 | 
								   (sync-point-release sp)
 | 
				
			||||||
 | 
								   (apply exit args))
 | 
				
			||||||
 | 
								 message)
 | 
				
			||||||
 | 
						 (sync-point-release sp)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((configure-window)
 | 
					      ((deinit-manager)
 | 
				
			||||||
	   (let ((window (second msg))
 | 
					       (destroy-titlebar (data:empty-titlebar data))
 | 
				
			||||||
		 (changes (third msg)))
 | 
					       (for-each (lambda (client.tb)
 | 
				
			||||||
	     ;; TODO: exact sizes ?!
 | 
							   (destroy-titlebar (cdr client.tb)))
 | 
				
			||||||
	     (configure-window dpy window
 | 
							 (data:titlebars data))
 | 
				
			||||||
			       (append (make-window-change-alist
 | 
					       (exit 'deinit-manager))
 | 
				
			||||||
					(border-width 0))
 | 
					 | 
				
			||||||
				       changes))))
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((draw-client-window) #f)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((fit-client)
 | 
					      ((draw-main-window)
 | 
				
			||||||
	   ;; client-window changed it's size
 | 
					       (set-gc-foreground! dpy gc (black-pixel dpy))
 | 
				
			||||||
	   (fit-client wm (second msg)))
 | 
					       (fill-rectangle* dpy window gc
 | 
				
			||||||
	  
 | 
								(clip-rectangle dpy window)))
 | 
				
			||||||
	  ((fit-client-window)
 | 
					 | 
				
			||||||
	   ;; client changed it's size ??
 | 
					 | 
				
			||||||
	   (fit-client-window wm (second msg)))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((update-manager-state)
 | 
					      ((fit-windows)
 | 
				
			||||||
	   (let ((state (if (window-contains-focus? dpy (wm:window wm))
 | 
					       (fit-titlebars wm data)
 | 
				
			||||||
			    'focused
 | 
					       (for-each (lambda (c)
 | 
				
			||||||
			    'active)))
 | 
							   (fit-client-window wm c))
 | 
				
			||||||
	     (set-titlebar-state! empty-titlebar state)))
 | 
							 (wm-clients wm)))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((init-client)
 | 
				
			||||||
 | 
					       (init-client wm data (second msg) (third msg)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((manager-focused)
 | 
					      ((deinit-client)
 | 
				
			||||||
	   (let ((time (second msg))
 | 
					       (deinit-client wm data (second msg)))
 | 
				
			||||||
		 (cc (wm-current-client wm)))
 | 
					 | 
				
			||||||
	     (if cc (wm-select-client wm cc time))))
 | 
					 | 
				
			||||||
	  
 | 
					 | 
				
			||||||
	  ((update-client-state)
 | 
					 | 
				
			||||||
	   (let* ((client (second msg))
 | 
					 | 
				
			||||||
		  (dpy (wm:dpy wm))
 | 
					 | 
				
			||||||
		  (window (client:window client)))
 | 
					 | 
				
			||||||
	     (if (window-exists? dpy window)
 | 
					 | 
				
			||||||
		 (let ((state (if (window-contains-focus? dpy window)
 | 
					 | 
				
			||||||
				  'focused
 | 
					 | 
				
			||||||
				  (if (window-viewable? dpy window)
 | 
					 | 
				
			||||||
				      'active
 | 
					 | 
				
			||||||
				      'normal)))
 | 
					 | 
				
			||||||
		       (titlebar (assq/false client (data:titlebars data)))
 | 
					 | 
				
			||||||
		       (name (client-name dpy client)))
 | 
					 | 
				
			||||||
		   (set-titlebar-title+state! titlebar name state)))))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  ((select-next) (select-next-client wm (second msg)))
 | 
					      ((configure-window)
 | 
				
			||||||
	  ((select-previous) (select-previous-client wm (second msg)))
 | 
					       (let ((window (second msg))
 | 
				
			||||||
	  ))
 | 
						     (changes (third msg)))
 | 
				
			||||||
      (loop))
 | 
						 ;; TODO: exact sizes ?!
 | 
				
			||||||
    (free-gc (wm:dpy wm) gc)))
 | 
						 (configure-window dpy window
 | 
				
			||||||
 | 
								   (append (make-window-change-alist
 | 
				
			||||||
 | 
									    (border-width 0))
 | 
				
			||||||
 | 
									   changes))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((draw-client-window) #f)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ((fit-client)
 | 
				
			||||||
 | 
					       ;; client-window changed it's size
 | 
				
			||||||
 | 
					       (fit-client wm (second msg)))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((fit-client-window)
 | 
				
			||||||
 | 
					       ;; client changed it's size ??
 | 
				
			||||||
 | 
					       (fit-client-window wm (second msg)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ((update-manager-state)
 | 
				
			||||||
 | 
					       (let* ((focused? (second msg))
 | 
				
			||||||
 | 
						      (state (if focused?
 | 
				
			||||||
 | 
								 'focused
 | 
				
			||||||
 | 
								 'active)))
 | 
				
			||||||
 | 
						 (set-titlebar-state! (data:empty-titlebar data) state)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ((manager-focused)
 | 
				
			||||||
 | 
					       (let ((time (second msg))
 | 
				
			||||||
 | 
						     (cc (wm-current-client wm)))
 | 
				
			||||||
 | 
						 (if cc (wm-select-client wm cc time))))
 | 
				
			||||||
 | 
					      
 | 
				
			||||||
 | 
					      ((update-client-state)
 | 
				
			||||||
 | 
					       (let* ((client (second msg))
 | 
				
			||||||
 | 
						      (focused? (third msg))
 | 
				
			||||||
 | 
						      (dpy (wm:dpy wm))
 | 
				
			||||||
 | 
						      (window (client:window client))
 | 
				
			||||||
 | 
						      (titlebar (assq/false client (data:titlebars data))))
 | 
				
			||||||
 | 
						 (if (and titlebar (window-exists? dpy window))
 | 
				
			||||||
 | 
						     (let ((state (if focused?
 | 
				
			||||||
 | 
								      'focused
 | 
				
			||||||
 | 
								      (if (window-viewable? dpy window)
 | 
				
			||||||
 | 
									  'active
 | 
				
			||||||
 | 
									  'normal))))
 | 
				
			||||||
 | 
						       (set-titlebar-state! titlebar state)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ((update-client-name)
 | 
				
			||||||
 | 
					       (let ((client (second msg))
 | 
				
			||||||
 | 
						     (name (third msg)))
 | 
				
			||||||
 | 
						 (let ((titlebar (assq/false client (data:titlebars data))))
 | 
				
			||||||
 | 
						   (if titlebar
 | 
				
			||||||
 | 
						       (set-titlebar-title! titlebar name)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ((select-next) (select-next-client wm (second msg)))
 | 
				
			||||||
 | 
					      ((select-previous) (select-previous-client wm (second msg)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (else (warn "unhandled switch-wm message" wm msg)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (fit-titlebars wm data)
 | 
					(define (fit-titlebars wm data)
 | 
				
			||||||
  (let* ((dpy (wm:dpy wm))
 | 
					  (let* ((dpy (wm:dpy wm))
 | 
				
			||||||
| 
						 | 
					@ -144,15 +179,16 @@
 | 
				
			||||||
		      (data:titlebars data))))))
 | 
							      (data:titlebars data))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (init-client wm data client maybe-rect)
 | 
					(define (init-client wm data client maybe-rect)
 | 
				
			||||||
  ;; TODO: transients!
 | 
					 | 
				
			||||||
  (let ((dpy (wm:dpy wm))
 | 
					  (let ((dpy (wm:dpy wm))
 | 
				
			||||||
	(options (wm:options wm)))
 | 
						(options (wm:options wm)))
 | 
				
			||||||
    (let* ((channel (make-channel))
 | 
					    (let* ((channel (make-channel))
 | 
				
			||||||
	   (titlebar (create-client-titlebar channel wm client)))
 | 
						   (titlebar (create-client-titlebar channel wm client)))
 | 
				
			||||||
      (set-data:titlebars! data (append (data:titlebars data)
 | 
					      (set-data:titlebars! data (append (data:titlebars data)
 | 
				
			||||||
					(list (cons client titlebar))))
 | 
										(list (cons client titlebar))))
 | 
				
			||||||
 | 
					      (set-titlebar-title! titlebar (client-name dpy client))
 | 
				
			||||||
      (fit-titlebars wm data)
 | 
					      (fit-titlebars wm data)
 | 
				
			||||||
      (update-titlebars wm data)
 | 
					      (update-titlebars wm data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      (fit-client-window wm client)
 | 
					      (fit-client-window wm client)
 | 
				
			||||||
      (fit-client wm client)
 | 
					      (fit-client wm client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,8 +216,7 @@
 | 
				
			||||||
	       ;; from titlebar-buttons
 | 
						       ;; from titlebar-buttons
 | 
				
			||||||
	       ((kill)
 | 
						       ((kill)
 | 
				
			||||||
		(delete-window dpy (client:window client) (second msg)))
 | 
							(delete-window dpy (client:window client) (second msg)))
 | 
				
			||||||
	       (else (mdisplay "unhandled client message: " msg "\n"))))
 | 
						       (else (warn "unhandled client message " wm client msg))))
 | 
				
			||||||
	   ;; TODO: internal channel
 | 
					 | 
				
			||||||
	   (loop))))
 | 
						   (loop))))
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      (map-titlebar titlebar)
 | 
					      (map-titlebar titlebar)
 | 
				
			||||||
| 
						 | 
					@ -193,8 +228,8 @@
 | 
				
			||||||
  (let ((options (wm:options wm)))
 | 
					  (let ((options (wm:options wm)))
 | 
				
			||||||
    (create-titlebar channel (wm:dpy wm) (wm:window wm)
 | 
					    (create-titlebar channel (wm:dpy wm) (wm:window wm)
 | 
				
			||||||
		     (wm:colormap wm)
 | 
							     (wm:colormap wm)
 | 
				
			||||||
		     ;; TODO: buttons
 | 
							     (list (cons 'buttons '(kill))
 | 
				
			||||||
		     (list (cons 'normal-colors
 | 
								   (cons 'normal-colors
 | 
				
			||||||
				 (get-option options 'titlebar-colors))
 | 
									 (get-option options 'titlebar-colors))
 | 
				
			||||||
			   (cons 'active-colors
 | 
								   (cons 'active-colors
 | 
				
			||||||
				 (get-option options 'titlebar-colors-active))
 | 
									 (get-option options 'titlebar-colors-active))
 | 
				
			||||||
| 
						 | 
					@ -207,7 +242,7 @@
 | 
				
			||||||
  (let* ((options (wm:options wm))
 | 
					  (let* ((options (wm:options wm))
 | 
				
			||||||
	 (tb
 | 
						 (tb
 | 
				
			||||||
	  (create-titlebar #f (wm:dpy wm) (wm:window wm) (wm:colormap wm)
 | 
						  (create-titlebar #f (wm:dpy wm) (wm:window wm) (wm:colormap wm)
 | 
				
			||||||
		   (list ;; TODO: (cons 'draggable #f)
 | 
							   (list
 | 
				
			||||||
		    (cons 'normal-colors
 | 
							    (cons 'normal-colors
 | 
				
			||||||
			  (get-option options 'titlebar-colors))
 | 
								  (get-option options 'titlebar-colors))
 | 
				
			||||||
		    (cons 'active-colors
 | 
							    (cons 'active-colors
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue