;;; xwem-mouse.el --- Mouse support for XWEM. ;; Copyright (C) 2003-2005 by XWEM Org. ;; Author: Zajcev Evgeny ;; Created: 21 Mar 2003 ;; Keywords: xlib, xwem ;; X-CVS: $Id: xwem-mouse.el,v 1.10 2005-04-04 19:54:14 lg Exp $ ;; This file is part of XWEM. ;; XWEM 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, or (at your option) ;; any later version. ;; XWEM 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 XEmacs; see the file COPYING. If not, write to the Free ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA ;; 02111-1307, USA. ;;; Synched up with: Not in FSF ;;; Commentary: ;; ;; XWEM supports mouse as well as keyboard. ;;; Code: (require 'xwem-load) (require 'xwem-manage) ;;; Customisation (defcustom xwem-popup-menu-function 'popup-menu "*Function used to popup menus. It is created for case when you change default `popup-menu' function, for example if you are using tpum.el." :type 'function :group 'xwem) ;;; Internal variables (defun xwem-mouse-change-cursor (cursor) "XXX. CURSOR - Dunno." (XChangeActivePointerGrab (xwem-dpy) cursor (Xmask-or XM-ButtonPress XM-ButtonRelease))) ;;;###autoload (defun xwem-mouse-grab (cursor &optional win mask) "Begin to grab mouse, showing CURSOR in WIN using event mask MASK. Default WIN is root window. Default MASK is capturing ButtonPress or ButtonRelease events." ;; TODO: install custom events handlers? (XGrabPointer (xwem-dpy) (or win (xwem-rootwin)) (or mask (Xmask-or XM-ButtonPress XM-ButtonRelease)) cursor)) ;;;###autoload (defun xwem-mouse-ungrab (&optional flush-p) "Stop grabing mouse. If FLUSH-P is non-nil, mouse is ungrabbed imediately." (XUngrabPointer (xwem-dpy)) (when flush-p ;; XX flush data to server and wait a little (XFlush (xwem-dpy)) (sit-for 0))) ;;; Menus ;;;###autoload (defun xwem-popup-menu (menu &optional event) "Popup MENU. MENU and EVENT is same as for `popup-menu'." (xwem-mouse-ungrab t) (funcall xwem-popup-menu-function menu (or event (and (member (event-type xwem-last-event) '(button-press button-release motion)) xwem-last-event)))) (defvar xwem-applications-submenu '("Applications" ("XEmacs" ["New frame" (make-frame nil (default-x-device))] ["*scratch* frame" (with-selected-frame (make-frame nil (default-x-device)) (switch-to-buffer "*scratch*"))]) ("XTerm" ["Default xterm" (xwem-launch-xterm nil)] ["2 xterm" (xwem-launch-xterm 2)] ["3 xterm" (xwem-launch-xterm 3)] ["4 xterm" (xwem-launch-xterm 4)]) ["Mozilla" (xwem-execute-program "mozilla")] "--" ["GhostView" (xwem-execute-program "gv")] ["xfontsel" (xwem-execute-program "xfontsel")] ["Lupe" (xwem-launch-lupe nil)] ) "Submenu with applications.") ;;;###xwem-autoload (defun xwem-generate-window-menu (title &optional win) "Generate menu for WIN." (unless title (setq title "Window")) (list title (vector "Vertical Split" `(xwem-window-split-vertically nil ,win)) (vector "Horizontal Split" `(xwem-window-split-horizontally nil ,win)) (vector "Delete Window" `(xwem-window-delete ,win)) (vector "Delete Others" `(xwem-window-delete-others ,win)) (vector "Balance" `(xwem-balance-windows ,win)))) (defun xwem-generate-iconified-cl-menu (title &optional max-mwidth) "Generate menu for iconified clients with TITLE. MAX-MWIDTH specifies maximum menu width." (list (xwem-misc-fixup-string title max-mwidth) :filter `(lambda (not-used) (delq nil (mapcar #'(lambda (cl) (when (eq (xwem-cl-state cl) 'iconified) (vector (xwem-misc-fixup-string (xwem-client-name cl) ,max-mwidth) `(xwem-select-client ,cl) :active (xwem-non-dummy-client-p cl)))) xwem-clients))))) (defun xwem-generate-applications-cl-menu (title &optional max-mwidth) "Generate menu for applications." (list (xwem-misc-fixup-string title max-mwidth) :filter `(lambda (not-used) (mapcar #'(lambda (app-spec) (list (xwem-misc-fixup-string (car app-spec) ,max-mwidth) :filter `(lambda (not-used) (delq nil (mapcar #'(lambda (cl) (when (xwem-cl-match-p cl (cdr (quote ,app-spec))) (vector (xwem-misc-fixup-string (xwem-client-name cl) ,,max-mwidth) `(xwem-select-client ,cl) :active (xwem-non-dummy-client-p cl)))) xwem-clients))))) xwem-applications-alist)))) ;;;###xwem-autoload (defun xwem-generate-clients-menu (title &optional max-mwidth) "Generate clients menu. TITLE is menu title. Optional MAX-MWIDTH argument specifies maximum width for menu items, default is 42." (unless max-mwidth (setq max-mwidth 42)) (let (malist) (mapc #'(lambda (cl) (let ((kv (assq (xwem-cl-manage-type cl) malist))) (if kv (setcdr kv (cons cl (cdr kv))) (setq malist (put-alist (xwem-cl-manage-type cl) (list cl) malist))))) xwem-clients) (nconc (list (xwem-misc-fixup-string title max-mwidth)) (mapcar #'(lambda (mc) (list (xwem-misc-fixup-string (symbol-name (car mc)) max-mwidth) :filter `(lambda (not-used) (mapcar #'(lambda (mccl) (vector (xwem-misc-fixup-string (xwem-client-name mccl) ,max-mwidth) `(xwem-select-client ,mccl) :active (xwem-non-dummy-client-p mccl))) (cdr (quote ,mc)))))) malist) ;; Iconified (list "==") (list (xwem-generate-iconified-cl-menu "Iconified" max-mwidth)) ;; Applications (list "--") (list (xwem-generate-applications-cl-menu "Applications" max-mwidth)) ))) (defun xwem-generate-recent-files (&optional title limit) "Generate recent files menu." (unless title (setq title "Recent Files")) (unless limit (setq limit 10)) (list title :filter `(lambda (not-used) (mapcar #'(lambda (file) (vector file `(xwem-open-file ,file))) (let ((files xwem-read-filename-history) (ret-files nil) (ci 0)) (while (and files (< ci ,limit)) (setq ret-files (cons (car files) ret-files) files (cdr files)) (incf ci)) (nreverse ret-files)))))) ;;;###xwem-autoload (defun xwem-generate-menu () "Generate xwem menu on fly." (list "XWEM Menu" (list "Minibuffer" ["Hide" (xwem-iconify (xwem-minib-cl xwem-minibuffer)) :active (eq (xwem-cl-state (xwem-minib-cl xwem-minibuffer)) 'active) ] ["Show" (xwem-activate (xwem-minib-cl xwem-minibuffer)) :active (not (eq (xwem-cl-state (xwem-minib-cl xwem-minibuffer)) 'active)) ] ["Restore size" (xwem-minib-rsz-resize 1)]) (xwem-generate-window-menu "Window" (xwem-win-selected)) "--" (list "Frames" :filter #'(lambda (not-used) (nconc (list (list "Operations" ["New Frame" (xwem-make-frame 'desktop)] ["Next" (xwem-frame-next 1)] ["Previous" (xwem-frame-previous 1)] ["Iconify" (xwem-frame-hide (xwem-frame-selected))] ["Transpose" (xwem-transpose-frames 1)] "--" ["Destroy" (xwem-frame-destroy (xwem-frame-selected))]) (list "Side-by-side" ["Vertical" (xwem-frame-sbs-vert-split 1)] ["Horizontal" (xwem-frame-sbs-hor-split 1)]) "--" ["Show Root" (xwem-frame-showroot)] ["Lower" (xwem-frame-lower (xwem-frame-selected))] ["Raise" (xwem-frame-raise (xwem-frame-selected))] ) (list "==") (mapcar #'(lambda (el) (let ((fn (xwem-frame-num el))) (vector (concat "Frame " (int-to-string fn) ": " (xwem-frame-name el)) `(xwem-frame-switch-nth ,fn)))) (xwem-frames-list))))) (list "Clients" :filter #'(lambda (not-used) (nconc (cdr (xwem-generate-clients-menu nil)) (list "==") (and (xwem-cl-selected) (cdr (xwem-generate-cl-menu (xwem-cl-selected) 32)))))) "--" xwem-applications-submenu (xwem-generate-recent-files) ;; XXX - it is just demo of popup menus )) ;;;###autoload(autoload 'xwem-popup-clients-menu "xwem-mouse" nil t) (define-xwem-command xwem-popup-clients-menu () "Popup clients menu." (xwem-interactive) (xwem-popup-menu (xwem-generate-clients-menu "XWEM Clients"))) ;;;###xwem-autoload (defun xwem-generate-cl-menu (cl &optional maxnlen) "Generate menu for CL. MAXNLEN - maximum menu width in characters." (unless maxnlen (setq maxnlen 20)) (delq nil (list (let ((name (xwem-client-name cl))) (when (> (length name) maxnlen) (setq name (concat (substring name 0 (- maxnlen 2)) ".."))) name) "--" (vector "Focus client" `(xwem-cl-pop-to-client ,cl)) (vector "Info" `(xwem-client-info ,cl)) (vector "Iconify" `(xwem-client-iconify ,cl)) "--:singleDashedLine" (vector "Transpose ==>" `(xwem-cl-transpose ,cl)) (vector "Transpose <==" `(xwem-cl-transpose ,cl '(4))) "--:singleDashedLine" (vector "Mark client" `(if (xwem-cl-marked-p ,cl) (xwem-client-unset-mark ,cl) (xwem-client-set-mark ,cl)) :style 'toggle :selected `(xwem-cl-marked-p ,cl)) (when (and xwem-cl-mark-ring (not (eq (xwem-cl-frame (car xwem-cl-mark-ring)) (if (and (boundp 'xwem-tabber-click-frame) (xwem-frame-p xwem-tabber-click-frame)) xwem-tabber-click-frame (xwem-frame-selected))))) (vector "Attach" `(xwem-win-set-cl ,(xwem-frame-selwin (if (and (boundp 'xwem-tabber-click-frame) (xwem-frame-p xwem-tabber-click-frame)) xwem-tabber-click-frame (xwem-frame-selected))) ,(car xwem-cl-mark-ring)))) (when (and xwem-cl-mark-ring (not (eq (xwem-cl-frame (car xwem-cl-mark-ring)) (if (and (boundp 'xwem-tabber-click-frame) (xwem-frame-p xwem-tabber-click-frame)) xwem-tabber-click-frame (xwem-frame-selected))))) (vector "Attach (unmark)" `(progn (xwem-win-set-cl ,(xwem-frame-selwin (if (and (boundp 'xwem-tabber-click-frame) (xwem-frame-p xwem-tabber-click-frame)) xwem-tabber-click-frame (xwem-frame-selected))) ,(car xwem-cl-mark-ring)) (xwem-client-unset-mark ,(car xwem-cl-mark-ring))))) "--:singleDashedLine" (vector "Run Copy" `(xwem-client-run-copy nil ,cl)) (vector "Run Copy other win" `(xwem-client-run-copy-other-win nil ,cl)) (vector "Run Copy other frame" `(xwem-client-run-copy-other-frame nil ,cl)) "--:doubleLine" (when (XWMProtocol-set-p (xwem-dpy) (xwem-hints-wm-protocols (xwem-cl-hints cl)) "WM_DELETE_WINDOW") (vector "Close" `(xwem-client-kill ,cl))) (vector "Kill" `(xwem-client-kill ,cl '(4)))))) ;;;###autoload(autoload 'xwem-popup-auto-menu "xwem-mouse" nil t) (define-xwem-command xwem-popup-auto-menu (arg) "Popup menu generated by `xwem-generate-menu'. ARG - Not used yet." (xwem-interactive "_P") (xwem-popup-menu (xwem-generate-menu))) (provide 'xwem-mouse) ;;; xwem-mouse.el ends here