;;; global-menu.jl ;;; Sawfish support for global-menus ;;; (c) 2001 JFM ;;; ;;; ;;; This package provides support for applications that want to place their ;;; menu bar outside their window (generally at the top of the screen, with ;;; only one menu visible at a time), as with kde and (soon) GNOME. ;;; ;;; Currently this is a little limited. All it does is detect when a menu ;;; window is mapped, move it into position (currently hardcoded), set some ;;; wm properties on it, and handle raising the appropriate app menu (this is ;;; not needed if raising a window raises its group or transients). ;;; (require 'gnome) ; This is supposed to be used with gnome/kde. (require 'gnome-commands) (defun menuify-window (w) ;; gather information (let* ( (height (last (window-dimensions w))) ) (if (equal (get-x-property w '_NET_WM_WINDOW_TYPE) '(ATOM 32 [_NET_WM_WINDOW_TYPE_MENU])) (progn ;; Set some X window properties here. ;; Maybe unnecessary, but sawfish doesn't seem to provide a skip_pager ;; property. (set-x-property w '_NET_WM_STATE [_NET_WM_SKIP_TASKBAR _NET_WM_SKIP_PAGER _NET_WM_STICKY] 'ATOM 32) ;; now standard properties (window-put w 'avoid t) (window-put w 'sticky t) (window-put w 'sticky-viewport t) (window-put w 'never-focus t) (window-put w 'focus-when-mapped nil) (window-put w 'type 'unframed) (window-put w 'depth 16) ; above panel, even if panel is above windows. ; gnome-specific properties (gnome-set-skip-tasklist w) (gnome-set-skip-winlist w) ; Temporarily unset this: (window-put w 'fixed-position nil) (reframe-window w) ;; Comment out all but one of these, depending on where you want your ;; menu to live. ;(move-resize-window-to w 0 0 (screen-width) 24) ; top of screen ;(move-resize-window-to w 0 24 (screen-width) 24) ; below foobar ;(move-resize-window-to w 32 2 640 22) ; on top of panel (cond ( (eq global-menu:mode 'fixed) (move-resize-window-to w global-menu:fixed-x global-menu:fixed-y global-menu:fixed-width global-menu:fixed-height)) ( (eq global-menu:mode 'top) (move-resize-window-to w 0 0 (screen-width) 24)) ( (eq global-menu:mode 'bottom) (move-resize-window-to w 0 (- (screen-height) 24) (screen-width) 24)) ( (eq global-menu:mode 'under-foobar) (move-resize-window-to w 0 24 (screen-width) 24)) (t (move-resize-window-to w 0 0 (screen-width) 24)) ; default to top ) ; have to set this _after_ positioning the window (window-put w 'fixed-position t) (hide-window w) ) ) ; /if ) ; /let ) ; /defun (defun menuify-all-windows () "Menuify all menu windows" (interactive) (mapc menuify-window (managed-windows))) (defun map-transient-children (fun w) "Map the single argument function FUN over all windows that are transients of window W." (mapc fun (transient-children w))) (defun raise-if-menu (w) "Raise the window W if it is _NET_WM_WINDOW_TYPE_MENU." (if (equal (get-x-property w '_NET_WM_WINDOW_TYPE) '(ATOM 32 [_NET_WM_WINDOW_TYPE_MENU])) (progn (show-window w) (raise-window w) (cond ( (eq global-menu:mode 'fixed) (move-resize-window-to w global-menu:fixed-x global-menu:fixed-y global-menu:fixed-width global-menu:fixed-height)) ( (eq global-menu:mode 'top) (move-resize-window-to w 0 0 (screen-width) 24)) ( (eq global-menu:mode 'bottom) (move-resize-window-to w 0 (- (screen-height) 24) (screen-width) 24)) ( (eq global-menu:mode 'under-foobar) (move-resize-window-to w 0 24 (screen-width) 24)) (t (move-resize-window-to w 0 0 (screen-width) 24)) ; default to top ) )) ) (defun hide-if-menu (w) "Hide the window W if it is _NET_WM_WINDOW_TYPE_MENU" (if (equal (get-x-property w '_NET_WM_WINDOW_TYPE) '(ATOM 32 [_NET_WM_WINDOW_TYPE_MENU])) (hide-window w) )) (defun raise-menu-for-window (w) "If window W has a menu window, raise it." (map-transient-children raise-if-menu w)) (defun hide-menu-for-window (w) "If window W has a menu window, hide it." (map-transient-children hide-if-menu w)) (defun menuify-window-now () ;; for testing purposes. (interactive) (let ( (w (select-window)) ) (menuify-window w) )) (defgroup global-menu "KDE/GNOME Global menu" :group misc) (defcustom global-menu:mode 'top "Positioning mode for global menu" :group (misc global-menu) :type symbol :options (top bottom under-foobar fixed) :after-set menuify-all-windows) (defcustom global-menu:fixed-x 0 "X" :group (misc global-menu) :type number ; :depends (eq global-menu:mode 'fixed) :after-set menuify-all-windows) (defcustom global-menu:fixed-y 0 "Y" :group (misc global-menu) :type number ; :depends (eq global-menu:mode 'fixed) :after-set menuify-all-windows) (defcustom global-menu:fixed-height 24 "height" :group (misc global-menu) :type number ; :depends (eq global-menu:mode 'fixed) :after-set menuify-all-windows) (defcustom global-menu:fixed-width 640 "width" :group (misc global-menu) :type number ; :depends (eq global-menu:mode 'fixed) :after-set menuify-all-windows) (add-hook 'add-window-hook menuify-window) (add-hook 'focus-in-hook raise-menu-for-window) (add-hook 'focus-out-hook hide-menu-for-window)