Thread View: gnu.epoch.misc
1 messages
1 total messages
Started by Chet Richards
Wed, 10 Apr 1991 22:16
Minibuff Placement Error (& Sol.?)
Author: Chet Richards
Date: Wed, 10 Apr 1991 22:16
Date: Wed, 10 Apr 1991 22:16
107 lines
6009 bytes
6009 bytes
We have seen an intermittent problem with the position of the epoch minibuffer
on our systems. I think I now understand the problem, although some of the
finer details elude me. Perhaps someone with greater knowledge of the lower
levels will respond and illuminate me.
The problem is that the minibuffer ended up being positioned ABOVE the edit
window instead of below it. It's positioning worked fine -- it would move down
if the edit window's lower edge moved down, and it would move up if the edit
window's lower edge moved up (note that "fine" means "consistent with the model
of the minibuffer located at/near the lower edge of the edit window"). We have
seen this problem when using mwm, twm, and awm, so it does not appear to be
window manager specific.
I found that the problem appears to be timing related, thus it appears
intermittently. It seemed to be easier to reproduce if my window manager
were running on a faster machine than the machine running epoch, but that
may just be coincidence. It was definitely easier to reproduce if there was
a lot of window manager activity during the time the minibuffer script was
running (I use mwm, and one of my menus has 5 submenus -- I kept repositioning
among the 5 submenu choices, causing the window manager to constantly create,
paint, and destroy the submenu boxes).
The problem appears to be in the code that identifies the positioning bias
imposed by the window manager. This is in the function wm-location-delta
in the minibuf.el source file. The original is shown below.
(defun wm-location-delta (&optional win)
"Given optional SCREEN-OR-XWIN, this function returns a list of (DX DY)
for how much the window manager changes move-screen requests."
(setq win (or win (current-screen)))
(let
(
(start-info (screen-information win))
x y dx dy info
)
(move-screen 0 0 win) ;move it to a fixed location
(setq info (screen-information win)) ; where did it actually end up?
(setq dx (- (car info)))
(setq dy (- (cadr info)))
(move-screen (+ (car start-info) dx) (+ (cadr start-info) dy) win)
(list dx dy)
))
My understanding of this function:
1. Get the screen position of the minibuffer (start-info).
2. Request the minibuffer be moved to (0,0). The window manager should
position the minibuffer such that the frame is at (0,0).
3. Get the screen position of the moved minibuffer (info)
4. Calculate the bias (dx, dy) that should be applied to an intended
position to allow for the window manager overhead.
5. Reposition the minibuffer to its original location, biased by the
window manager overhead.
The problem came between #2 and #3. The request for the move is evidently
not immediate. In some cases the screen position in #3 returned the original
location, sometimes (0,0), and sometimes (0,24), (4,24), (0,12), etc.
If the position returned is not far from the origin, the effect of the timing
error is small, and may never be noticed. I had specified an initial placement
of +0+422 for my minibuffer -- a position roughly equivalent to where epoch
would want it to be. In this case, the bias gets set up as (0, -422), meaning
the minibuffer will be placed 422 pixels higher than desired to allow for that
amount of window manager overhead.
My approach was to allow a delay before asking for the new location, allowing
for repeated attempts if the first ones should yield a value not "close
"enough". I encountered a few hangs where it never moved "close enough", so
I added a trap to give up after 10 tries -- if it really wants to be there,
let it.
My current version is shown below.
(defun wm-location-delta (&optional win)
"Given optional SCREEN-OR-XWIN, this function returns a list of (DX DY)
for how much the window manager changes move-screen requests."
(setq win (or win (current-screen)))
(let
(
(start-info (screen-information win))
x y dx dy info moving trycnt
)
(move-screen 0 0 win) ; move it to a fixed location
(setq trycnt 0)
(setq moving 1)
(while (> moving 0) ; while it still has not moved...
(setq trycnt (+ trycnt 1))
(sleep-for 1) ; give a moment for the move
(setq info (screen-information win)) ; where did it actually end up?
(setq moving 0)
(if (> (car info) 20) (setq moving 1)) ; If x not close enough
(if (< (car info) -20) (setq moving 1)) ; If x not close enough
(if (> (cadr info) 50) (setq moving 1)) ; If y not close enough
(if (< (cadr info) -50) (setq moving 1)) ; If y not close enough
(if (> trycnt 10) (setq moving 0)) ; If 10 tries not enough, quit
)
(setq dx (- (car info)))
(setq dy (- (cadr info)))
(move-screen (+ (car start-info) dx) (+ (cadr start-info) dy) win)
(list dx dy)
))
With the change of the initial geometry, I no longer see the minibuffer
above the edit window, and the code above has been successful in preventing
the erroneous placement of the minibuffer when the initial geometry places it
somewhere else.
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads