[Date Prev][Date Next][Thread Prev][][Date Index][Thread Index]

Re: popup frames



えー、長い引用になりますが、

> 画面が混雑して emacs-w3m のフレームがどこかに隠れてしまっている
> 場合でも、M-x w3m でそれを表に浮上させることができるのが便利です。
> みなさんのところでは、そういうふうに動作していますか?
> 
> Fedora Core 4 の環境に変えてみて、ぼくはそれができなくなっている
> ことに気がつきました。どうも raise-frame という関数は、環境によっ
> ては動作しないものらしいです。
> 
> そこで、少なくとも emacs-w3m だけはそれができるように、make-frame
> と delete-frame で置き換える advice を作ってみました。raise-frame
> ではなくて select-frame-set-input-focus に対して行なっているのは、
> emacs-w3m のフレームの ID が変わってしまっても問題無いのが、そっ
> ちだからです。
> 
> ;; Emacs 21 用。
> (defadvice select-frame-set-input-focus
>   (around make-new-frame-in-the-same-place (&optional frame) activate)
>   "Make it work for emacs-w3m."
>   (or frame (setq frame (selected-frame)))
>   (if (with-current-buffer (window-buffer (frame-first-window frame))
> 	(eq major-mode 'w3m-mode))
>       (let ((params (frame-parameters frame)))
> 	(select-frame (make-frame (delq (assq 'minibuffer params) params)))
> 	(delete-frame frame))
>     ad-do-it))
> 
> ;; Emacs 22 用。
> (defadvice select-frame-set-input-focus
>   (around make-new-frame-in-the-same-place (&optional frame) activate)
>   "Make it work for emacs-w3m."
>   (or frame (setq frame (selected-frame)))
>   (if (with-current-buffer (window-buffer (frame-first-window frame))
> 	(eq major-mode 'w3m-mode))
>       (let* ((params (frame-parameters frame))
> 	     (height (assq 'height params)))
> 	(setcdr height (- (cdr height) 3))
> 	(select-frame (make-frame (delq (assq 'minibuffer params) params)))
> 	(delete-frame frame))
>     ad-do-it))
> 
> Emacs 22 ではなぜか (make-frame '((height . N))) に対して、高さ
> が N+3 のフレームを作ってしまうので、調整してあります。この件に
> ついてはこちら:
> 
> http://news.gmane.org/group/gmane.emacs.pretest.bugs/thread=8074
> 
> なお、popup する emacs-w3m のフレームに複数のウィンドウがあった
> 場合の動作は、完全ではありません。


このパッチで解決するのですが、やり方が適切かどうか自信がありません。
もうちょっと良く調べてからemacs-develに投稿するつもりです。

とりあえず報告。
大和

*** xterm.c	28  8月 2005 04:13:33 +0900	1.873
--- xterm.c	09  9月 2005 02:33:55 +0900	
***************
*** 8492,8497 ****
--- 8492,8524 ----
    if (f->async_visible)
      {
        BLOCK_INPUT;
+ 
+       {
+ 	/* See _NET_ACTIVE_WINDOW in
+ 	   http://freedesktop.org/wiki/Standards_2fwm_2dspec */
+ 	XEvent event;
+ 
+ 	event.xclient.type = ClientMessage;
+ 	event.xclient.serial = 0;
+ 	event.xclient.send_event = True;
+ 
+ 	event.xclient.message_type = XInternAtom(FRAME_X_DISPLAY (f), 
+ 						 "_NET_ACTIVE_WINDOW", 
+ 						 False);
+ 	event.xclient.window = FRAME_OUTER_WINDOW (f);
+ 	event.xclient.format = 32;
+ 	event.xclient.data.l[0] = 1; /* source indication */
+ 	event.xclient.data.l[1] = 0; /* timestamp */
+ 	event.xclient.data.l[2] = 0; /* requestor's currently active window */
+ 	event.xclient.data.l[3] = event.xclient.data.l[4] = 0;
+ 
+ 	XSendEvent(FRAME_X_DISPLAY (f), 
+ 		   DefaultRootWindow (FRAME_X_DISPLAY (f)), 
+ 		   False, 
+ 		   SubstructureRedirectMask | SubstructureNotifyMask,
+ 		   &event);
+       }
+ 
        XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
        XFlush (FRAME_X_DISPLAY (f));
        UNBLOCK_INPUT;