;;;; dmg-after-rotate.jl -- version 0.1 ;;;; ;;;; Useful functions when the head rotates, or changes size ;;;; ;;;; (C) Daniel M. German July 2008. ;;;; ;;;; * This program is free software; you can redistribute it and/or ;;;; * modify it under the terms of the GNU General Public ;;;; * License as published by the Free Software Foundation; either ;;;; * version 2 of the License, or (at your option) any later version. ;;;; * ;;;; * This software is distributed in the hope that it will be useful, ;;;; * but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; * General Public License for more details. ;;;; * ;;;; * You should have received a copy of the GNU General Public ;;;; * License along with this software; if not, write to the Free Software ;;;; * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ;;;; * ;;;; * ;;;; * Author: Daniel M German dmgerman at uvic doooot ca ;;;; ;;; ;;; Defines three interactive functions, useful when you connect a new ;;; external head, when you switch resolution, or when you rotate the display ;;; dmg-update-to-head: resizes windows to match the size of head, and ;;; moves windows outside it into its boundaries. ;;; ;;; dmg-move-window-inside: moves a window (and potentially resizes ;;; it) to be fully inside the boundaries of head. Window should not be ;;; maximazed ;;; dmg-remaximize-window: if a window is maximized it remaximazes it ;;; to match the head ;;; ;;; Changelog: ;;; 2009-12-28 dmg ;;; * renamed it to dmg-after-rotate (require 'sawfish.wm.state.maximize) (require 'sawfish.wm.workspace) (require 'sawfish.wm.util.edges) (require 'sawfish.wm.util.workarea) (require 'sawfish.wm.workspace) (require 'sawfish.wm.util.window-order) (defun dmg-workarea-x-size (w) (let ( (workArea (calculate-workarea w)) ) ; find vertical size (- (nth 2 workArea) (nth 0 workArea)) ) ) (defun dmg-workarea-y-size (w) (let ( (workArea (calculate-workarea w)) ) ; find horizontal size (- (nth 3 workArea) (nth 1 workArea)) ) ) (defun dmg-move-window-inside (w) "move the window within the boundaries of the display" (interactive "%W") (let* ( (head-x-offset (nth 0 (calculate-workarea w))) (head-y-offset (nth 1 (calculate-workarea w))) (head-x-size (dmg-workarea-x-size w)) (head-y-size (dmg-workarea-y-size w)) (head-x-right (nth 2 (calculate-workarea w))) (head-y-down (nth 3 (calculate-workarea w))) (coords (window-position w)) (xleft (car coords)) (yup (cdr coords)) (fdims (window-frame-dimensions w)) (dims (window-dimensions w)) (xsize (car fdims)) (ysize (cdr fdims)) (framex (- xsize (car dims))) (framey (- ysize (cdr dims))) (xright 0) (ydown 0) (outsidex 0) (outsidey 0) ) ; is the left hand size inside (if (< xleft head-x-offset) (setq xleft head-x-offset)) (if (< yup head-y-offset) (setq yup head-y-offset)) ; is the size of the window bigger than the display ; resize ; (dmg_b w) (if (> xsize head-x-size) (setq xsize head-x-size)) (if (> ysize head-y-size) (setq ysize head-y-size)) ; compute end position (setq xright (+ xleft xsize)) (setq ydown (+ yup ysize)) ; how much are we outside? (setq outsidex (+ (- xright head-x-right) 1)) (setq outsidey (+ (- ydown head-y-down) 1)) ; if we our too the window is outside the right/down ; move it in (if (> outsidex 0) (setq xleft (- xleft outsidex))) (if (> outsidey 0) (setq yup (- yup outsidey))) ; (dmg_debug (concat "current area" ; "areasX:" ; ; calculate-workarea returns 4 values and a list ; (number->string xleft) ; " :" ; (number->string yup) ; " :" ; (number->string xsize) ; " :" ; (number->string ysize) ; " \n" ; ) ; ) ; the new size of the window has to take into account the size of ; the frame (move-resize-window-to w xleft yup (- xsize framex) (- ysize framey)) ; (dmg_b w) ); end of le ) (defun dmg-remaximize-window (w ) "remaximize the given window" (interactive "%W") (let* ( (m (window-maximized-p w)) (h (window-maximized-horizontally-p w)) (v (window-maximized-vertically-p w)) ) (if (and m) (progn (unmaximize-window w) (dmg-move-window-inside w) (cond ((and v h) (maximize-window w) ) ; and v h ((and v) (maximize-window-vertically w) ) ; and v (maximize-window-horizontally w) ) ) ; end cond ) ; end progn (progn (dmg-move-window-inside w) ) ) ; end let ) (defun dmg-update-to-head () "Make sure windows are maximized in the current boundaries of the display." (interactive) (let* ( (wins (stacking-order)) (len (length wins)) (i (- len 1)) (curw current-workspace) (saveraises maximize-raises) ) (progn (setq maximize-raises nil) ; process the windows in inverse stacking order (while (>= i 0) (let* ( (w (nth i wins)) ) (cond ; skip avoided windows ((window-avoided-p w) t) ; maximized... ((window-maximized-p w) (dmg-remaximize-window w) ) ;; any other window ((and t) (dmg-move-window-inside w) ) ) ; end of cond ;; FIX ME ; some remaximized windows will be outside the ; area of the screen so run it on all windows ) (setq i (- i 1)) ) ; while (setq maximize-raises saveraises) (select-workspace curw) ) ; end progn ) ) (defun dmg-test () "A place to test code." (interactive) (select-workspace 3) ) ;; Rotateion ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; (defun dmg-after-rotate () "Execute after the screen is rotated" (interactive) (let ( (current-window (car (window-order current-workspace nil nil))) ) (if (and current-window) (dmg-remaximize-window current-window) ) ; (display-message "This is a test3") ) ) (defun dmg-rotate-hook (w) (if (equal w 'root) (dmg-after-rotate) ) ) (defun dmg-rotate-hook2 () (dmg-update-to-head) ) ;; This didn't work,unfortunately (add-hook 'configure-notify-hook dmg-rotate-hook) ;(add-hook 'randr-change-notify-hook dmg-rotate-hook2) (provide 'dmg-after-rotate)