added root-wm options
added shortcuts for splitting, execute commands and attach windows
This commit is contained in:
		
							parent
							
								
									c702b5fa52
								
							
						
					
					
						commit
						aa32a7e69d
					
				| 
						 | 
					@ -1,16 +1,36 @@
 | 
				
			||||||
 | 
					(define-options-spec root-options-spec
 | 
				
			||||||
 | 
					  (split-horizontal keys "M-s h")
 | 
				
			||||||
 | 
					  (split-vertical keys "M-s v")
 | 
				
			||||||
 | 
					  (split-horizontal-with-switch-wm keys "M-s s h")
 | 
				
			||||||
 | 
					  (split-vertical-with-switch-wm keys "M-s s v")
 | 
				
			||||||
 | 
					  (split-horizontal-with-move-wm keys "M-s m h")
 | 
				
			||||||
 | 
					  (split-vertical-with-move-wm keys "M-s m v")
 | 
				
			||||||
 | 
					  (create-switch-wm keys "M-k s")
 | 
				
			||||||
 | 
					  (create-move-wm keys "M-k m")
 | 
				
			||||||
 | 
					  (split-question string "What kind of manager do want in the second frame?\n(S)witch or (M)ove windowmanager:")
 | 
				
			||||||
 | 
					  (execute keys "F3")
 | 
				
			||||||
 | 
					  (execute-question string "Execute:")
 | 
				
			||||||
 | 
					  (attach keys "M-a")
 | 
				
			||||||
 | 
					  (attach-question string "Attach:")
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define-record-type root-wm :root-wm
 | 
					(define-record-type root-wm :root-wm
 | 
				
			||||||
  (make-root-wm dpy managers current-manager in-channel)
 | 
					  (make-root-wm dpy managers current-manager in-channel options)
 | 
				
			||||||
  root-wm?
 | 
					  root-wm?
 | 
				
			||||||
  (dpy root-wm:dpy)
 | 
					  (dpy root-wm:dpy)
 | 
				
			||||||
  (managers root-wm:managers set-root-wm:managers!)
 | 
					  (managers root-wm:managers set-root-wm:managers!)
 | 
				
			||||||
  (current-manager root-wm:current-manager set-root-wm:current-manager!)
 | 
					  (current-manager root-wm:current-manager set-root-wm:current-manager!)
 | 
				
			||||||
  (in-channel root-wm:in-channel))
 | 
					  (in-channel root-wm:in-channel)
 | 
				
			||||||
 | 
					  (options root-wm:options))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (create-root-wm dpy)
 | 
					(define (create-root-wm dpy options)
 | 
				
			||||||
  (let* ((window (default-root-window dpy))
 | 
					  (let* ((window (default-root-window dpy))
 | 
				
			||||||
 | 
						 (screen (display:default-screen dpy))
 | 
				
			||||||
 | 
						 (options (create-options dpy (screen:default-colormap screen)
 | 
				
			||||||
 | 
									  root-options-spec options))
 | 
				
			||||||
	 (children (window-children dpy window))
 | 
						 (children (window-children dpy window))
 | 
				
			||||||
	 (in-channel (make-channel))
 | 
						 (in-channel (make-channel))
 | 
				
			||||||
	 (root-wm (make-root-wm dpy '() #f in-channel))
 | 
						 (root-wm (make-root-wm dpy '() #f in-channel options))
 | 
				
			||||||
	 (initial-manager (create-move-wm in-channel dpy window '())))
 | 
						 (initial-manager (create-move-wm in-channel dpy window '())))
 | 
				
			||||||
    (mdisplay "creating root-wm\n")
 | 
					    (mdisplay "creating root-wm\n")
 | 
				
			||||||
    (set-root-wm:current-manager! root-wm initial-manager)
 | 
					    (set-root-wm:current-manager! root-wm initial-manager)
 | 
				
			||||||
| 
						 | 
					@ -22,10 +42,14 @@
 | 
				
			||||||
		(wm-manage-window initial-manager window))
 | 
							(wm-manage-window initial-manager window))
 | 
				
			||||||
	      children)
 | 
						      children)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (grab-shortcut dpy window (string->keys dpy "M-k h") ;; -> options!
 | 
					    (for-each (lambda (name)
 | 
				
			||||||
		   'split-horizontal in-channel #t)
 | 
							(grab-shortcut dpy window (get-option-value options name)
 | 
				
			||||||
    (grab-shortcut dpy window (string->keys dpy "M-k v")
 | 
								       name in-channel #t))
 | 
				
			||||||
		   'split-vertical in-channel #t)
 | 
						      '(split-horizontal split-vertical
 | 
				
			||||||
 | 
							split-horizontal-with-switch-wm split-vertical-with-switch-wm
 | 
				
			||||||
 | 
							split-horizontal-with-move-wm split-vertical-with-move-wm
 | 
				
			||||||
 | 
							create-switch-wm create-move-wm
 | 
				
			||||||
 | 
							execute attach))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    (call-with-event-channel
 | 
					    (call-with-event-channel
 | 
				
			||||||
     dpy window (event-mask substructure-redirect)
 | 
					     dpy window (event-mask substructure-redirect)
 | 
				
			||||||
| 
						 | 
					@ -56,40 +80,75 @@
 | 
				
			||||||
			#f))
 | 
								#f))
 | 
				
			||||||
     )))
 | 
					     )))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (do-split root-wm orientation new-wm)
 | 
				
			||||||
 | 
					  (let* ((current (root-wm:current-manager root-wm))
 | 
				
			||||||
 | 
						 (parent (manager-parent root-wm current)) ;; #f if root
 | 
				
			||||||
 | 
						 (dpy (wm:dpy current))
 | 
				
			||||||
 | 
						 (in-channel (root-wm:in-channel root-wm))
 | 
				
			||||||
 | 
						 (splitter (create-split-wm in-channel dpy
 | 
				
			||||||
 | 
									    (window-parent dpy (wm:window current))
 | 
				
			||||||
 | 
									    ;; TODO other options
 | 
				
			||||||
 | 
									    (list (cons 'orientation orientation))))
 | 
				
			||||||
 | 
						 (first current)
 | 
				
			||||||
 | 
						 (creator (if (eq? new-wm 'switch-wm)
 | 
				
			||||||
 | 
							      create-switch-wm
 | 
				
			||||||
 | 
							      create-move-wm))
 | 
				
			||||||
 | 
						 (second (creator in-channel dpy (wm:window splitter)
 | 
				
			||||||
 | 
								  ;; TODO options
 | 
				
			||||||
 | 
								  '())))
 | 
				
			||||||
 | 
					    ;; we just replace the client:window
 | 
				
			||||||
 | 
					    (if parent
 | 
				
			||||||
 | 
						(client-replace-window parent (wm:window current)
 | 
				
			||||||
 | 
								       (wm:window splitter))
 | 
				
			||||||
 | 
						(map-window dpy (wm:window splitter))) ;; maybe resize ??
 | 
				
			||||||
 | 
					    (wm-manage-window splitter (wm:window first))
 | 
				
			||||||
 | 
					    (wm-manage-window splitter (wm:window second))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    (add-manager! root-wm splitter)
 | 
				
			||||||
 | 
					    (add-manager! root-wm second)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (handle-message root-wm exit msg)
 | 
					(define (handle-message root-wm exit msg)
 | 
				
			||||||
  (case (car msg)
 | 
					  (case (car msg)
 | 
				
			||||||
    ((split-vertical split-horizontal)
 | 
					    ((split-vertical split-horizontal)
 | 
				
			||||||
     (let* ((current (root-wm:current-manager root-wm))
 | 
					     (let ((c (prompt (root-wm:dpy root-wm) #f
 | 
				
			||||||
	    (parent (manager-parent root-wm current)) ;; #f if root
 | 
							      (get-option-value (root-wm:options root-wm)
 | 
				
			||||||
	    (dpy (wm:dpy current))
 | 
										'split-question)
 | 
				
			||||||
	    (in-channel (root-wm:in-channel root-wm))
 | 
							      '(#\s #\S #\m #\M) #f)))
 | 
				
			||||||
	    (orientation (if (eq? 'split-vertical (car msg))
 | 
					       (if c
 | 
				
			||||||
			     'vertical 'horizontal))
 | 
						   (do-split root-wm
 | 
				
			||||||
	    (splitter (create-split-wm in-channel dpy
 | 
							     (if (eq? (car msg) 'split-vertical)
 | 
				
			||||||
				       (window-parent dpy (wm:window current))
 | 
								 'vertical 'horizontal)
 | 
				
			||||||
				       ;; TODO other options
 | 
							     (if (or (eq? c #\s) (eq? c #\S))
 | 
				
			||||||
				       (list (cons 'orientation orientation))))
 | 
								 'switch-wm
 | 
				
			||||||
	    (first current)
 | 
								 'move-wm)))))
 | 
				
			||||||
	    ;; TODO: ask for second manager
 | 
					 | 
				
			||||||
	    (second (create-switch-wm in-channel dpy (wm:window splitter)
 | 
					 | 
				
			||||||
				      ;; TODO options
 | 
					 | 
				
			||||||
				      '())))
 | 
					 | 
				
			||||||
       ;; we just replace the client:window
 | 
					 | 
				
			||||||
       (if parent
 | 
					 | 
				
			||||||
	   (client-replace-window parent (wm:window current)
 | 
					 | 
				
			||||||
				  (wm:window splitter))
 | 
					 | 
				
			||||||
	   (map-window dpy (wm:window splitter))) ;; maybe resize ??
 | 
					 | 
				
			||||||
       (wm-manage-window splitter (wm:window first))
 | 
					 | 
				
			||||||
       (wm-manage-window splitter (wm:window second))
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
       (add-manager! root-wm splitter)
 | 
					    ((split-horizontal-with-switch-wm)
 | 
				
			||||||
       (add-manager! root-wm second)))
 | 
					     (do-split root-wm 'horizontal 'switch-wm))
 | 
				
			||||||
 | 
					    ((split-vertical-with-switch-wm)
 | 
				
			||||||
 | 
					     (do-split root-wm 'vertical 'switch-wm))
 | 
				
			||||||
 | 
					    ((split-horizontal-with-move-wm)
 | 
				
			||||||
 | 
					     (do-split root-wm 'horizontal 'move-wm))
 | 
				
			||||||
 | 
					    ((split-vertical-with-move-wm)
 | 
				
			||||||
 | 
					     (do-split root-wm 'vertical 'move-wm))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    ((create-switch-wm create-move-wm)
 | 
				
			||||||
 | 
					     (let* ((current (root-wm:current-manager root-wm))
 | 
				
			||||||
 | 
						    (create (if (eq? (car msg) 'create-switch-wm)
 | 
				
			||||||
 | 
								create-switch-wm
 | 
				
			||||||
 | 
								create-move-wm))
 | 
				
			||||||
 | 
						    (dpy (root-wm:dpy root-wm))
 | 
				
			||||||
 | 
						    (in-channel (root-wm:in-channel root-wm))
 | 
				
			||||||
 | 
						    (new (create in-channel dpy (wm:window current)
 | 
				
			||||||
 | 
								 '())) ;; TODO: options
 | 
				
			||||||
 | 
						    )
 | 
				
			||||||
 | 
					       (add-manager! root-wm new)
 | 
				
			||||||
 | 
					       (wm-manage-window current (wm:window new))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ((manager-focused)
 | 
					    ((manager-focused)
 | 
				
			||||||
     (let ((manager (second msg)))
 | 
					     (let ((manager (second msg)))
 | 
				
			||||||
       ;; a split-wm should never be the current manager
 | 
					       ;; a split-wm should never be the current manager
 | 
				
			||||||
       (if (not (eq? (manager-type split) (wm:type manager)))
 | 
					       (if (not (eq? (manager-type split) (wm:type manager)))
 | 
				
			||||||
	     (set-root-wm:current-manager! root-wm manager))))
 | 
						   (set-root-wm:current-manager! root-wm manager))))
 | 
				
			||||||
    ((root-drop)
 | 
					    ((root-drop)
 | 
				
			||||||
     (let ((window (second msg))
 | 
					     (let ((window (second msg))
 | 
				
			||||||
	   (pointer-x (third msg))
 | 
						   (pointer-x (third msg))
 | 
				
			||||||
| 
						 | 
					@ -99,8 +158,70 @@
 | 
				
			||||||
	     (wm-manage-window manager window)
 | 
						     (wm-manage-window manager window)
 | 
				
			||||||
	     (mdisplay "did not find a manager at " pointer-x ":"
 | 
						     (mdisplay "did not find a manager at " pointer-x ":"
 | 
				
			||||||
		       pointer-y "\n")))))
 | 
							       pointer-y "\n")))))
 | 
				
			||||||
 | 
					    ((execute)
 | 
				
			||||||
 | 
					     (let* ((cm (root-wm:current-manager root-wm))
 | 
				
			||||||
 | 
						    (exec (prompt (root-wm:dpy root-wm) (wm:window cm)
 | 
				
			||||||
 | 
								  (get-option-value (root-wm:options root-wm)
 | 
				
			||||||
 | 
										    'execute-question)
 | 
				
			||||||
 | 
								  #f exec-complete)))
 | 
				
			||||||
 | 
					       (if exec
 | 
				
			||||||
 | 
						   (run (sh -c ,(string-append exec " &"))))))
 | 
				
			||||||
 | 
					    ((attach)
 | 
				
			||||||
 | 
					     (let* ((cm (root-wm:current-manager root-wm))
 | 
				
			||||||
 | 
						    (all-names
 | 
				
			||||||
 | 
						     (map cdr (filter (lambda (win.name)
 | 
				
			||||||
 | 
									;; remove all that are below the current-wm
 | 
				
			||||||
 | 
									(not (member (wm:window cm)
 | 
				
			||||||
 | 
										     (window-path (wm:dpy cm)
 | 
				
			||||||
 | 
												  (car win.name)))))
 | 
				
			||||||
 | 
								      (get-all-window-names))))
 | 
				
			||||||
 | 
						    (attach (prompt (root-wm:dpy root-wm) (wm:window cm)
 | 
				
			||||||
 | 
								    (get-option-value (root-wm:options root-wm)
 | 
				
			||||||
 | 
										      'attach-question)
 | 
				
			||||||
 | 
								    all-names (finite-complete all-names)))
 | 
				
			||||||
 | 
						    (window (find-window-by-name attach)))
 | 
				
			||||||
 | 
					       (if window
 | 
				
			||||||
 | 
						   (wm-manage-window cm window))))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    (else (mdisplay "unknown root message: " msg "\n"))))
 | 
					    (else (mdisplay "unknown root message: " msg "\n"))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (exec-complete str pos)
 | 
				
			||||||
 | 
					  ;; TODO
 | 
				
			||||||
 | 
					  (cons str pos))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (finite-complete strings)
 | 
				
			||||||
 | 
					  (lambda (str pos)
 | 
				
			||||||
 | 
					    (let* ((s (substring str 0 pos))
 | 
				
			||||||
 | 
						   (candidates
 | 
				
			||||||
 | 
						    (filter (lambda (str)
 | 
				
			||||||
 | 
							      (and (<= (string-length s) (string-length str))
 | 
				
			||||||
 | 
								   (equal? s (substring str 0 (string-length s)))))
 | 
				
			||||||
 | 
							    strings))
 | 
				
			||||||
 | 
						   (common (common-substring candidates)))
 | 
				
			||||||
 | 
					      (cond
 | 
				
			||||||
 | 
					       ((null? candidates) (cons str pos))
 | 
				
			||||||
 | 
					       ((null? (cdr candidates))
 | 
				
			||||||
 | 
						(cons (car candidates) ;; or insert ??
 | 
				
			||||||
 | 
						      (string-length (car candidates))))
 | 
				
			||||||
 | 
					       ((not (or (equal? common "") (equal? common s)))
 | 
				
			||||||
 | 
						(cons common ;; or insert??
 | 
				
			||||||
 | 
						      (string-length common)))
 | 
				
			||||||
 | 
					       (else candidates)))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(define (common-substring strings)
 | 
				
			||||||
 | 
					  (cond
 | 
				
			||||||
 | 
					   ((null? strings) "")
 | 
				
			||||||
 | 
					   ((null? (cdr strings)) (car strings))
 | 
				
			||||||
 | 
					   (else (let ((s (car strings))
 | 
				
			||||||
 | 
						       (rec (common-substring (cdr strings))))
 | 
				
			||||||
 | 
						   (letrec ((loop (lambda (i)
 | 
				
			||||||
 | 
								    (if (and (< i (string-length s))
 | 
				
			||||||
 | 
									     (< i (string-length rec))
 | 
				
			||||||
 | 
									     (eq? (string-ref s i) (string-ref rec i)))
 | 
				
			||||||
 | 
									(loop (+ i 1))
 | 
				
			||||||
 | 
									(substring s 0 i)))))
 | 
				
			||||||
 | 
						     (loop 0))))))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
;; *** observing managers ********************************************
 | 
					;; *** observing managers ********************************************
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(define (add-manager! root-wm manager)
 | 
					(define (add-manager! root-wm manager)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue