unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* select-frame-set-input-focus fails to raise the frame
@ 2017-12-12 23:02 Bob Weiner
  2017-12-12 23:26 ` Robert Weiner
                   ` (2 more replies)
  0 siblings, 3 replies; 29+ messages in thread
From: Bob Weiner @ 2017-12-12 23:02 UTC (permalink / raw)
  To: emacs-devel

I use:  Editor:      Emacs 27.0.50
        Hyperbole:   7.0.2
        Sys Type:    x86_64-apple-darwin16.7.0
        OS Type:     darwin
        Window Sys:  ns

(defun test ()
  (let ((depress-frame (selected-frame))
	(release-frame (make-frame)))
    (select-frame-set-input-focus depress-frame)
    ;; On MacOS, depress-frame is never raised to the top
    ;; of the frame stack and never is given input focus
    ;; after release-frame is created.
    (sit-for 4)
    (select-frame-set-input-focus release-frame)))

(test)

----------
If I call test, I get the behavior described in its comments, basically
only release-frame is ever raised and has input focus.  If I edebug
the function, then I get the behavior, I expect with each frame raised
and with input focus, first the depress-frame for 4 seconds and then
release-frame.

Is there something wrong in the test function or is there a problem in
select-frame-set-input-focus?

Bob





^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-12 23:02 select-frame-set-input-focus fails to raise the frame Bob Weiner
@ 2017-12-12 23:26 ` Robert Weiner
  2017-12-13 20:47   ` Alan Third
  2017-12-13  8:50 ` martin rudalics
  2017-12-13 20:49 ` Alan Third
  2 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-12 23:26 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 332 bytes --]

Here is a seemingly related problem with raise and lower frame.

;; This whole sexp works
(let ((f (selected-frame)))
  (lower-frame f)
  (sit-for 1)
  (raise-frame f))

;; Only the first raise-frame call works
(let ((f (next-frame)))
  ;; f is raised
  (raise-frame f)
  (sit-for 1)
  ;; f is NEVER LOWERED
  (lower-frame f))

Bob

[-- Attachment #2: Type: text/html, Size: 1718 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-12 23:02 select-frame-set-input-focus fails to raise the frame Bob Weiner
  2017-12-12 23:26 ` Robert Weiner
@ 2017-12-13  8:50 ` martin rudalics
  2017-12-13 15:00   ` Robert Weiner
  2017-12-13 20:49 ` Alan Third
  2 siblings, 1 reply; 29+ messages in thread
From: martin rudalics @ 2017-12-13  8:50 UTC (permalink / raw)
  To: Bob Weiner, emacs-devel

 > Is there something wrong in the test function or is there a problem in
 > select-frame-set-input-focus?

Even if you get a thing like this work on your system, there will be
always another platform where it fails.  Note the remark in xfns.c:

    In an ideal world, XSetInputFocus should generally be avoided so
    that applications don't interfere with the window manager's focus
    policy.  But I think it's okay to use when it's clearly done
    following a user-command.

martin



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13  8:50 ` martin rudalics
@ 2017-12-13 15:00   ` Robert Weiner
  2017-12-13 16:07     ` Stefan Monnier
  2017-12-13 19:30     ` martin rudalics
  0 siblings, 2 replies; 29+ messages in thread
From: Robert Weiner @ 2017-12-13 15:00 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1086 bytes --]

On Wed, Dec 13, 2017 at 3:50 AM, martin rudalics <rudalics@gmx.at> wrote:

> > Is there something wrong in the test function or is there a problem in
> > select-frame-set-input-focus?
>
> Even if you get a thing like this work on your system, there will be
> always another platform where it fails.


Can you explain what the problem is and why you think it is unsolvable?
In the prior example with raise-frame and lower-frame, we see there is
no problem combining the two of these but once (next-frame) is added
the combination of the two does not work.  Why?  Why would you expect
that to be the case?  Why is it not a bug?


  Note the remark in xfns.c:
>
>    In an ideal world, XSetInputFocus should generally be avoided so
>    that applications don't interfere with the window manager's focus
>    policy.  But I think it's okay to use when it's clearly done
>    following a user-command.


​Better to explain sequences of Elisp functions considered acceptable and
those that are not with regard to input focus handling​ and frame stacking.

Bob

[-- Attachment #2: Type: text/html, Size: 2671 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 15:00   ` Robert Weiner
@ 2017-12-13 16:07     ` Stefan Monnier
  2017-12-13 16:33       ` Robert Weiner
  2017-12-13 19:30     ` martin rudalics
  1 sibling, 1 reply; 29+ messages in thread
From: Stefan Monnier @ 2017-12-13 16:07 UTC (permalink / raw)
  To: emacs-devel

> Can you explain what the problem is and why you think it is unsolvable?
> In the prior example with raise-frame and lower-frame, we see there is
> no problem combining the two of these but once (next-frame) is added
> the combination of the two does not work.  Why?  Why would you expect
> that to be the case?

Because there's such a wide variety of ways for window-managers to
react to those requests that it's in practice nigh-on impossible to make
it work "right" in all cases (I put it between quotes, because it seems
that for some window managers the fact that Emacs's requests aren't
satisfied the way Emacs expects might be considered a feature).

> Why is it not a bug?

I think we do consider this particular case as a bug, tho I don't know
if there's someone around here who has a clear idea about why we get
this behavior and how to go about fixing it.


        Stefan




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 16:07     ` Stefan Monnier
@ 2017-12-13 16:33       ` Robert Weiner
  2017-12-13 19:39         ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-13 16:33 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 530 bytes --]

On Wed, Dec 13, 2017 at 11:07 AM, Stefan Monnier <monnier@iro.umontreal.ca>
wrote:

>
> > Why is it not a bug?
>
> I think we do consider this particular case as a bug, tho I don't know
> if there's someone around here who has a clear idea about why we get
> this behavior and how to go about fixing it.
>

​Eli got z-ordered frame handling and live line numbering working well
in Emacs 26 but this might be beyond him?  Oh, say it ain't so :-)

Is there an existing bug discussion where this was covered?

Bob

[-- Attachment #2: Type: text/html, Size: 1599 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 15:00   ` Robert Weiner
  2017-12-13 16:07     ` Stefan Monnier
@ 2017-12-13 19:30     ` martin rudalics
  2017-12-13 22:14       ` Robert Weiner
  1 sibling, 1 reply; 29+ messages in thread
From: martin rudalics @ 2017-12-13 19:30 UTC (permalink / raw)
  To: rswgnu; +Cc: emacs-devel

 > Can you explain what the problem is and why you think it is unsolvable?

On most systems I know this one ...

   (let ((depress-frame (selected-frame))
	(release-frame (make-frame)))
     (select-frame-set-input-focus depress-frame)
     ;; On MacOS, depress-frame is never raised to the top
     ;; of the frame stack and never is given input focus
     ;; after release-frame is created.
     (sit-for 4)
     (select-frame-set-input-focus release-frame)))

... happens because a new frame is always raised and gets input focus
unless certain precautions are taken.  The following works here on
Windows:

(defun test ()
   (let ((depress-frame (selected-frame))
	(release-frame (make-frame '((no-focus-on-map . t)))))
     (select-frame-set-input-focus depress-frame)
     ;; On MacOS, depress-frame is never raised to the top
     ;; of the frame stack and never is given input focus
     ;; after release-frame is created.
     (sit-for 4)
     (select-frame-set-input-focus release-frame)))

 > In the prior example with raise-frame and lower-frame, we see there is
 > no problem combining the two of these but once (next-frame) is added
 > the combination of the two does not work.  Why?  Why would you expect
 > that to be the case?  Why is it not a bug?

It's by no means related to `next-frame' and it works here on Windows.
I have no idea why it doesn't work for you.

martin



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 16:33       ` Robert Weiner
@ 2017-12-13 19:39         ` Eli Zaretskii
  0 siblings, 0 replies; 29+ messages in thread
From: Eli Zaretskii @ 2017-12-13 19:39 UTC (permalink / raw)
  To: rswgnu; +Cc: monnier, emacs-devel

> From: Robert Weiner <rsw@gnu.org>
> Date: Wed, 13 Dec 2017 11:33:45 -0500
> Cc: emacs-devel <emacs-devel@gnu.org>
> 
> ​Eli got z-ordered frame handling

That's Martin's work, not mine.



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-12 23:26 ` Robert Weiner
@ 2017-12-13 20:47   ` Alan Third
  2017-12-13 22:00     ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Alan Third @ 2017-12-13 20:47 UTC (permalink / raw)
  To: rswgnu; +Cc: emacs-devel

On Tue, Dec 12, 2017 at 06:26:50PM -0500, Robert Weiner wrote:
> Here is a seemingly related problem with raise and lower frame.
> 
> ;; This whole sexp works
> (let ((f (selected-frame)))
>   (lower-frame f)
>   (sit-for 1)
>   (raise-frame f))
> 
> ;; Only the first raise-frame call works
> (let ((f (next-frame)))
>   ;; f is raised
>   (raise-frame f)
>   (sit-for 1)
>   ;; f is NEVER LOWERED
>   (lower-frame f))

I can’t reproduce this, these both work as expected for me here on
macOS using the master branch and the -Q flag.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-12 23:02 select-frame-set-input-focus fails to raise the frame Bob Weiner
  2017-12-12 23:26 ` Robert Weiner
  2017-12-13  8:50 ` martin rudalics
@ 2017-12-13 20:49 ` Alan Third
  2017-12-13 21:53   ` Robert Weiner
  2 siblings, 1 reply; 29+ messages in thread
From: Alan Third @ 2017-12-13 20:49 UTC (permalink / raw)
  To: Bob Weiner; +Cc: emacs-devel

On Tue, Dec 12, 2017 at 06:02:38PM -0500, Bob Weiner wrote:
> (defun test ()
>   (let ((depress-frame (selected-frame))
> 	(release-frame (make-frame)))
>     (select-frame-set-input-focus depress-frame)
>     ;; On MacOS, depress-frame is never raised to the top
>     ;; of the frame stack and never is given input focus
>     ;; after release-frame is created.
>     (sit-for 4)
>     (select-frame-set-input-focus release-frame)))
> 
> (test)
> 
> ----------
> If I call test, I get the behavior described in its comments, basically
> only release-frame is ever raised and has input focus.  If I edebug
> the function, then I get the behavior, I expect with each frame raised
> and with input focus, first the depress-frame for 4 seconds and then
> release-frame.

I feel I’m being a bit dim here, but depress-frame is already raised
and focused when I run this in the scratch buffer, so I’m unsure how
to try replicating it.
-- 
Alan Third



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 20:49 ` Alan Third
@ 2017-12-13 21:53   ` Robert Weiner
  0 siblings, 0 replies; 29+ messages in thread
From: Robert Weiner @ 2017-12-13 21:53 UTC (permalink / raw)
  To: Alan Third; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 924 bytes --]

On Wed, Dec 13, 2017 at 3:49 PM, Alan Third <alan@idiocy.org> wrote:

> On Tue, Dec 12, 2017 at 06:02:38PM -0500, Bob Weiner wrote:
> > (defun test ()
> >   (let ((depress-frame (selected-frame))
> >       (release-frame (make-frame)))
> >     (select-frame-set-input-focus depress-frame)
> >     ;; On MacOS, depress-frame is never raised to the top
> >     ;; of the frame stack and never is given input focus
> >     ;; after release-frame is created.
> >     (sit-for 4)
> >     (select-frame-set-input-focus release-frame)))
> >
> > (test)
> >
> > ----------
>
> I feel I’m being a bit dim here, but depress-frame is already raised
> and focused when I run this in the scratch buffer, so I’m unsure how
> to try replicating it.
>

​On macOS for me, the (make-frame) call puts the new frame at the top of
the stack and sets input focus there for me,
so depress-frame is under that.

Bob

[-- Attachment #2: Type: text/html, Size: 1912 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 20:47   ` Alan Third
@ 2017-12-13 22:00     ` Robert Weiner
  2017-12-13 22:26       ` Alan Third
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-13 22:00 UTC (permalink / raw)
  To: Alan Third; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 830 bytes --]

On Wed, Dec 13, 2017 at 3:47 PM, Alan Third <alan@idiocy.org> wrote:

> On Tue, Dec 12, 2017 at 06:26:50PM -0500, Robert Weiner wrote:
> > Here is a seemingly related problem with raise and lower frame.
> >
> > ;; This whole sexp works
> > (let ((f (selected-frame)))
> >   (lower-frame f)
> >   (sit-for 1)
> >   (raise-frame f))
> >
> > ;; Only the first raise-frame call works
> > (let ((f (next-frame)))
> >   ;; f is raised
> >   (raise-frame f)
> >   (sit-for 1)
> >   ;; f is NEVER LOWERED
> >   (lower-frame f))
>
> I can’t reproduce this, these both work as expected for me here on
> macOS using the master branch and the -Q flag.
>
​​
​You are correct.  This works fine today; strange it did not yesterday.
The example I gave with the function named 'test' still fails as before.

Bob

[-- Attachment #2: Type: text/html, Size: 1899 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 19:30     ` martin rudalics
@ 2017-12-13 22:14       ` Robert Weiner
  0 siblings, 0 replies; 29+ messages in thread
From: Robert Weiner @ 2017-12-13 22:14 UTC (permalink / raw)
  To: martin rudalics; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1466 bytes --]

On Wed, Dec 13, 2017 at 2:30 PM, martin rudalics <rudalics@gmx.at> wrote:

> > Can you explain what the problem is and why you think it is unsolvable?
>
> On most systems I know this one ...
>
>   (let ((depress-frame (selected-frame))
>         (release-frame (make-frame)))
>     (select-frame-set-input-focus depress-frame)
>     ;; On MacOS, depress-frame is never raised to the top
>     ;; of the frame stack and never is given input focus
>     ;; after release-frame is created.
>     (sit-for 4)
>     (select-frame-set-input-focus release-frame)))
>
> ... happens because a new frame is always raised and gets input focus
> unless certain precautions are taken.


​Yes, that seems to be the case on MacOS as well.  But why
even if I add a (sit-for 4) before (select-frame-set-input-focus
depress-frame)
is that frame not raised and given focus?​
​​

> The following works here on
> Windows:
>
> (defun test ()
>   (let ((depress-frame (selected-frame))
>         (release-frame (make-frame '((no-focus-on-map . t)))))
>     (select-frame-set-input-focus depress-frame)
>     ;; On MacOS, depress-frame is never raised to the top
>     ;; of the frame stack and never is given input focus
>     ;; after release-frame is created.
>     (sit-for 4)
>     (select-frame-set-input-focus release-frame)))
>

​Yes, that works find on MacOS as well, so that will have to be the
solution.
Thanks much.​

Bob

[-- Attachment #2: Type: text/html, Size: 2930 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 22:00     ` Robert Weiner
@ 2017-12-13 22:26       ` Alan Third
  2017-12-14  0:33         ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Alan Third @ 2017-12-13 22:26 UTC (permalink / raw)
  To: rswgnu; +Cc: emacs-devel

On Wed, Dec 13, 2017 at 05:00:18PM -0500, Robert Weiner wrote:
> On Wed, Dec 13, 2017 at 3:47 PM, Alan Third <alan@idiocy.org> wrote:
> 
> > On Tue, Dec 12, 2017 at 06:26:50PM -0500, Robert Weiner wrote:
> > > Here is a seemingly related problem with raise and lower frame.
> > >
> > > ;; This whole sexp works
> > > (let ((f (selected-frame)))
> > >   (lower-frame f)
> > >   (sit-for 1)
> > >   (raise-frame f))
> > >
> > > ;; Only the first raise-frame call works
> > > (let ((f (next-frame)))
> > >   ;; f is raised
> > >   (raise-frame f)
> > >   (sit-for 1)
> > >   ;; f is NEVER LOWERED
> > >   (lower-frame f))
> >
> > I can’t reproduce this, these both work as expected for me here on
> > macOS using the master branch and the -Q flag.
> >
> ​​
> ​You are correct.  This works fine today; strange it did not yesterday.
> The example I gave with the function named 'test' still fails as before.

I tried it again and it didn’t work! Changing the sit-for to sleep-for
fixed it. I know that sometimes sit-for doesn’t actually wait for the
given time, and I think that’s what’s happening here as I’m seeing the
frame being lowered, but not raised.

Presumably there’s some sort of timing thing where raise-frame then
lower-frame in rapid succession fails randomly.

FWIW, changing sit-for to sleep-for in ‘test’ results in 4 seconds of
a blank frame, but otherwise behaves as expected. This seems to work,
though:

    (defun test ()
      (let ((depress-frame (selected-frame))
            (release-frame (make-frame)))
        (select-frame-set-input-focus depress-frame)
        (sit-for 0)
        (sit-for 4)
        (select-frame-set-input-focus release-frame)))
    
    (test)

Presumably the first sit-for clears any pending input which then means
the second sit-for can actually do its thing.

(I think this is a side‐effect of the way input works on the NS port
where various things that you might not think of as ‘input’ are
essentially indistinguishable from keyboard input.)
-- 
Alan Third



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-13 22:26       ` Alan Third
@ 2017-12-14  0:33         ` Robert Weiner
  2017-12-14 21:03           ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-14  0:33 UTC (permalink / raw)
  To: Alan Third; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1644 bytes --]

On Wed, Dec 13, 2017 at 5:26 PM, Alan Third <alan@idiocy.org> wrote:

>
> FWIW, changing sit-for to sleep-for in ‘test’ results in 4 seconds of
> a blank frame, but otherwise behaves as expected. This seems to work,
> though:
>
>     (defun test ()
>       (let ((depress-frame (selected-frame))
>             (release-frame (make-frame)))
>         (select-frame-set-input-focus depress-frame)
>         (sit-for 0)
>         (sit-for 4)
>         (select-frame-set-input-focus release-frame)))
>
>     (test)
>
> Presumably the first sit-for clears any pending input which then means
> the second sit-for can actually do its thing.
>
> (I think this is a side‐effect of the way input works on the NS port
> where various things that you might not think of as ‘input’ are
> essentially indistinguishable from keyboard input.)
>

​Great explanations.  The combination of (sit-for 0) to cause
redisplay followed by a (sleep-for <n>) solved the problem
completely​ for me.  As you noted, sit-for can return prematurely
and seems to in the context in which I am using it, whereas
sleep-for waits the given seconds as desired.

This seems to indicate there is a need to simplify the process for
temporarily showing a frame at the top of the stack.  The use case
I have right now is putting a particular buffer into a newly created
frame but having the previously selected frame remain the topmost
frame with input focus after the operation completes.  To show that
the buffer has been put into the frame, I want to show it temporarily
and then move it beneath the original top frame.

Bob
​

[-- Attachment #2: Type: text/html, Size: 3444 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-14  0:33         ` Robert Weiner
@ 2017-12-14 21:03           ` Robert Weiner
  2017-12-15 15:53             ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-14 21:03 UTC (permalink / raw)
  To: Alan Third; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1221 bytes --]

On Wed, Dec 13, 2017 at 7:33 PM, Robert Weiner <rsw@gnu.org> wrote:

> The combination of (sit-for 0) to cause
> redisplay followed by a (sleep-for <n>) solved the problem
> completely​ for me.
>

​Well, one more problem remains here.  If the new frame is created with
its window showing buffer1 and then set-window-buffer is used to
change it to buffer2 (or even if switch-to-buffer is used), buffer2 is
not displayed ​when the new frame is temporarily displayed (buffer1 is).
Not until after Emacs becomes idle agai is buffer2 displayed in this new
frame.

I have tried using sit-for, sleep-for, force-mode-line-update and
force-window-update but none of these seem to make redisplay show
buffer2 in the new frame.

Buffer2 is not known at the time of the new frame creation, so I can't
create it with that as the default.

(defun test2 ()
  (let ((depress-frame (selected-frame))
        (release-frame (make-frame)))
    (set-window-buffer (frame-selected-window release-frame) "*scratch*")
    (sit-for 0)
    (sleep-for 2)
    (select-frame-set-input-focus depress-frame)
    (sit-for 0)
    (sleep-for 2)
    (select-frame-set-input-focus release-frame)))

(test2)

Bob​

[-- Attachment #2: Type: text/html, Size: 4055 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-14 21:03           ` Robert Weiner
@ 2017-12-15 15:53             ` Robert Weiner
  2017-12-15 16:10               ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-15 15:53 UTC (permalink / raw)
  To: Alan Third; +Cc: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1937 bytes --]

On Thu, Dec 14, 2017 at 4:03 PM, Robert Weiner <rsw@gnu.org> wrote:

> On Wed, Dec 13, 2017 at 7:33 PM, Robert Weiner <rsw@gnu.org> wrote:
>
>> The combination of (sit-for 0) to cause
>> redisplay followed by a (sleep-for <n>) solved the problem
>> completely​ for me.
>>
>
> ​Well, one more problem remains here.  If the new frame is created with
> its window showing buffer1 and then set-window-buffer is used to
> change it to buffer2 (or even if switch-to-buffer is used), buffer2 is
> not displayed ​when the new frame is temporarily displayed (buffer1 is).
> Not until after Emacs becomes idle agai
> ​n​
> is buffer2 displayed in this new
> frame.
>

Although from the function doc strings, it seems a force-window-update
followed by a (sit-for 0) should force redisplay of the chosen window, it
did
not (see the test2 function in the prior message).  Is that a bug?

An explicit call to redisplay with a 'force' argument does the trick,
however.  So the following works as expected, showing the result of the
'set-window-buffer' while temporarily displaying the new frame.

(defun select-window-set-input-focus (window)
  "Select WINDOW, give input focus to its frame and force display of any
window changes."
  (select-window window)
  (select-frame-set-input-focus (window-frame window))
  ;; Force immediate redisplay of any changes to window, e.g. if its
  ;; buffer has changed
  (redisplay t))

(defun test3 ()
  (let* ((depress-frame (selected-frame))
(depress-window (frame-selected-window depress-frame))
         (release-frame (make-frame))
(release-window (frame-selected-window release-frame)))
    (set-window-buffer release-window "*scratch*")
    (select-window-set-input-focus release-window)
    (sleep-for 2)
    (select-window-set-input-focus depress-window)
    (sleep-for 2)
    (select-window-set-input-focus release-window)))

(test3)

;; Bob

[-- Attachment #2: Type: text/html, Size: 6078 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-15 15:53             ` Robert Weiner
@ 2017-12-15 16:10               ` Eli Zaretskii
  2017-12-15 17:38                 ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2017-12-15 16:10 UTC (permalink / raw)
  To: rswgnu; +Cc: alan, emacs-devel

> From: Robert Weiner <rsw@gnu.org>
> Date: Fri, 15 Dec 2017 10:53:59 -0500
> Cc: emacs-devel <emacs-devel@gnu.org>
> 
> Although from the function doc strings, it seems a force-window-update
> followed by a (sit-for 0) should force redisplay of the chosen window, it did
> not (see the test2 function in the prior message).  Is that a bug?

How do you know Emacs didn't redisplay the window?  "Force redisplay"
doesn't necessarily mean you will see on display what you think you
should see, it just means Emacs will consider that window for
redisplay.  Whether that causes Emacs to show what you think it should
is another matter entirely: the display engine has its own ideas what
part(s) of the window need to be redrawn, if any.

I actually don't understand the idea of your test2 function: can you
tell what you intended to see happen, and why?




^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-15 16:10               ` Eli Zaretskii
@ 2017-12-15 17:38                 ` Robert Weiner
  2017-12-15 20:44                   ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-15 17:38 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Alan Third, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1287 bytes --]

On Fri, Dec 15, 2017 at 11:10 AM, Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Robert Weiner <rsw@gnu.org>
> > Date: Fri, 15 Dec 2017 10:53:59 -0500
> > Cc: emacs-devel <emacs-devel@gnu.org>
> >
> > Although from the function doc strings, it seems a force-window-update
> > followed by a (sit-for 0) should force redisplay of the chosen window,
> it did
> > not (see the test2 function in the prior message).  Is that a bug?
>
> How do you know Emacs didn't redisplay the window?  "Force redisplay"
> doesn't necessarily mean you will see on display what you think you
> should see, it just means Emacs will consider that window for
> redisplay.  Whether that causes Emacs to show what you think it should
> is another matter entirely: the display engine has its own ideas what
> part(s) of the window need to be redrawn, if any.
>
> I actually don't understand the idea of your test2 function: can you
> tell what you intended to see happen, and why?
>

​The problem was that I would set-window-buffer in the new frame
to a different buffer and that buffer would not display when
the new frame was brought frontmost and displayed temporarily
with a sleep-for delay.  Calling force-window-update had no
effect but calling (redisplay t) resolved it.

Bob

[-- Attachment #2: Type: text/html, Size: 2554 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-15 17:38                 ` Robert Weiner
@ 2017-12-15 20:44                   ` Eli Zaretskii
  2017-12-16 13:41                     ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2017-12-15 20:44 UTC (permalink / raw)
  To: rswgnu; +Cc: alan, emacs-devel

> From: Robert Weiner <rsw@gnu.org>
> Date: Fri, 15 Dec 2017 12:38:15 -0500
> Cc: Alan Third <alan@idiocy.org>, emacs-devel <emacs-devel@gnu.org>
> 
> ​The problem was that I would set-window-buffer in the new frame
> to a different buffer and that buffer would not display when
> the new frame was brought frontmost and displayed temporarily
> with a sleep-for delay.  Calling force-window-update had no
> effect but calling (redisplay t) resolved it.

What do you mean by "displayed temporarily"?  As long as the current
command runs, Emacs will not enter redisplay; an explicit call to
'redisplay' is the only exception to that rule.  So it sounds like
what you describe is Emacs working as designed.



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-15 20:44                   ` Eli Zaretskii
@ 2017-12-16 13:41                     ` Robert Weiner
  2017-12-16 14:39                       ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-16 13:41 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Alan Third, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 2448 bytes --]

On Fri, Dec 15, 2017 at 3:44 PM, Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Robert Weiner <rsw@gnu.org>
> > Date: Fri, 15 Dec 2017 12:38:15 -0500
> > Cc: Alan Third <alan@idiocy.org>, emacs-devel <emacs-devel@gnu.org>
> >
> > ​The problem was that I would set-window-buffer in the new frame
> > to a different buffer and that buffer would not display when
> > the new frame was brought frontmost and displayed temporarily
> > with a sleep-for delay.  Calling force-window-update had no
> > effect but calling (redisplay t) resolved it.
>
> What do you mean by "displayed temporarily"?  As long as the current
> command runs, Emacs will not enter redisplay; an explicit call to
> 'redisplay' is the only exception to that rule.  So it sounds like
> ​​
> what you describe is Emacs working as designed.
>
​​
​By displayed temporarily, I mean that new frame f2 and old
frame f1 largely overlap one another and I want f2 to appear
above f1 for a given delay, like half a second and then f1
to be raised atop it.​

I should have noted that I first tried force-window-update (doc string
says it marks the given window to be redisplayed the next time redisplay
runs) followed by a sit-for (doc string says it runs redisplay
unconditionally
until at least until any further input or timer expiration).  That
combination
did not work either.  Only the explicit call to redisplay worked.  This
seems
to conflict with the doc strings to me.  If you look at the functions I have
enclosed, you will see the behavior I am trying to produce.

My broader argument is that one should be able to program utilizing
window-based
functions more simply when the windows involved exist in separate frames
and an
external window manager is involved.  However, I see not everyone agrees
with this,
maybe because some of the behavior will always be asynchronous and possibly
non-deterministic.

Previously, I found Emacs handled mouse button drags between windows in
different frames
differently than drags between windows in a single frame.  I was able to
figure out a
consistent model that now works well for me.  I think this is similar, that
with some
work, managing windows across multiple frames can be made simpler and
less-error
prone than the way things are now.  But if the major maintainers of Emacs
are not very
interested in this, then I don't expect anything to happen.

Bob

​​

[-- Attachment #2: Type: text/html, Size: 5337 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 13:41                     ` Robert Weiner
@ 2017-12-16 14:39                       ` Eli Zaretskii
  2017-12-16 15:06                         ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2017-12-16 14:39 UTC (permalink / raw)
  To: rswgnu; +Cc: alan, emacs-devel

> From: Robert Weiner <rsw@gnu.org>
> Date: Sat, 16 Dec 2017 08:41:05 -0500
> Cc: Alan Third <alan@idiocy.org>, emacs-devel <emacs-devel@gnu.org>
> 
>  What do you mean by "displayed temporarily"?  As long as the current
>  command runs, Emacs will not enter redisplay; an explicit call to
>  'redisplay' is the only exception to that rule.  So it sounds like
>  ​​what you describe is Emacs working as designed.
> 
> ​​​By displayed temporarily, I mean that new frame f2 and old
> frame f1 largely overlap one another and I want f2 to appear
> above f1 for a given delay, like half a second and then f1
> to be raised atop it.​

Then IMO sit-for is not your friend: if input arrives soon enough,
redisplay will not be called.  And if you happen to have
redisplay-dont-pause set to nil, even if redisplay _is_ called, it
might do nothing when sit-for calls it.

On top of that, when and how a new frame appears on display is not
only up to Emacs: the WM has a lot to do with that.

> I should have noted that I first tried force-window-update (doc string
> says it marks the given window to be redisplayed the next time redisplay
> runs) followed by a sit-for (doc string says it runs redisplay unconditionally
> until at least until any further input or timer expiration).  That combination
> did not work either.  Only the explicit call to redisplay worked.  This seems
> to conflict with the doc strings to me.

The doc strings try very hard to tell the story completely and
accurately, but it isn't easy, because the underlying behavior is
extremely complex, and needs to cater to some very different use
cases.

Here's a rule of thumb I'd advise to anyone who tries to produce such
"temporary" displays: it doesn't work with Emacs, at least not naively
so, so my advice is to try finding other solutions.  Using sit-for,
especially in a multi-frame environment with mouse involved is
extremely fragile for these purposes due to non-keyboard events
involved that you cannot predict in advance.

Calling 'redisplay' with last argument non-nil is the only way to
actually ensure redisplay, so if you must, use only that.
force-window-update is useless if redisplay doesn't happen, because it
just sets an advisory flag for the display engine to consider.

> If you look at the functions I have
> enclosed, you will see the behavior I am trying to produce.

I did, and still couldn't understand the intent.  I still don't, FWIW.



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 14:39                       ` Eli Zaretskii
@ 2017-12-16 15:06                         ` Robert Weiner
  2017-12-16 16:15                           ` Eli Zaretskii
  0 siblings, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-16 15:06 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Alan Third, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 4892 bytes --]

On Sat, Dec 16, 2017 at 9:39 AM, Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Robert Weiner <rsw@gnu.org>
> > Date: Sat, 16 Dec 2017 08:41:05 -0500
> > Cc: Alan Third <alan@idiocy.org>, emacs-devel <emacs-devel@gnu.org>
> >
> >  What do you mean by "displayed temporarily"?  As long as the current
> >  command runs, Emacs will not enter redisplay; an explicit call to
> >  'redisplay' is the only exception to that rule.  So it sounds like
> >  ​​what you describe is Emacs working as designed.
> >
> > ​​​By displayed temporarily, I mean that new frame f2 and old
> > frame f1 largely overlap one another and I want f2 to appear
> > above f1 for a given delay, like half a second and then f1
> > to be raised atop it.​
>
> Then IMO sit-for is not your friend: if input arrives soon enough,
> redisplay will not be called.  And if you happen to have
> redisplay-dont-pause set to nil, even if redisplay _is_ called, it
> might do nothing when sit-for calls it.
>

​Ok, that is an example of why I am advocating for a potentially
new function that let's a programmer say "display the latest
contents of this window with no other Emacs window or frame
obscuring it".  I don't think Elisp programmers should have to
master the intricacies of windows, frames, the redisplay engine,
and window managers to do that.  Does anyone?

​​
>
> ​​
> On top of that, when and how a new frame appears on display is not
> ​​
> only up to Emacs: the WM has a lot to do with that.
>

​Yes, but Emacs sends commands to the WM.  Now if the WM ignores
those commands not much can be done but I think we are interested
in the context where the WM responds as expected to the command
and Emacs either gets a response or can poll to see if the WM state
has changed.  Take raise-frame for example.  Should we not expect
this to make the given frame the topmost?  The doc string says we
should.

​​
>
> ​​
> > I should have noted that I first tried force-window-update (doc string
> ​​
> > says it marks the given window to be redisplayed the next time redisplay
> ​​
> > runs) followed by a sit-for (doc string says it runs redisplay
> unconditionally
> ​​
> > until at least until any further input or timer expiration).  That
> combination
> ​​
> > did not work either.  Only the explicit call to redisplay worked.  This
> seems
> ​​
> > to conflict with the doc strings to me.
> ​​
>
> ​​
> The doc strings try very hard to tell the story completely and
> ​​
> accurately, but it isn't easy, because the underlying behavior is
> ​​
> extremely complex, and needs to cater to some very different use
> ​​
> cases.
>

​I'm mainly asking that obvious gotchas like those demonstrated
by my sample code be mentioned in doc strings, not a deep dive
into all special case technicalities.

​​
>
> ​​
> Here's a rule of thumb I'd advise to anyone who tries to produce such
> ​​
> "temporary" displays: it doesn't work with Emacs, at least not naively
> ​​
> so, so my advice is to try finding other solutions.


​Ok, I'm open and looking for input.  Again, the use case is the
idea of throwing a buffer to a new frame where you want the selected
frame with input focus and its selected window PRIOR to the throw to be
the same after the throw command but you need to show that the buffer has
been thrown to the new frame and the new and the old frame largely overlap.

After using the throw command, the user may soon choose to switch frames
and work with the frame of the thrown buffer, so the frame must still exist
after the throw command finishes.

​
>   Using sit-for,
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
>
> ​​
> especially in a multi-frame environment with mouse involved is
> ​​
> extremely fragile for these purposes due to non-keyboard events
> ​​
> involved that you cannot predict in advance.
>

​Ok.
​

> ​​
>
> ​​
> Calling 'redisplay' with last argument non-nil is the only way to
> ​​
> actually ensure redisplay, so if you must, use only that.
>

​It sounds like that is the only way since I need to see the current
contents
of the new frame's only window.
​

> ​​
> force-window-update
> ​​
> is useless if redisplay doesn't happen, because it
> ​​
> just sets an advisory
> ​​
> flag for the display engine to consider.
>

​I understand that.
​

> ​​
>
> ​​
> > If you look at the fu
> ​​
> nctions I have
> ​​
> > enclosed, you will s
> ​​
> ee the behavior I am trying to produce.
> ​​
>
> ​​
> I did, and still couldn't understand the intent.  I still don't, FWIW.
>

​Have I explained it well enough to you now?

Thanks,

Bob
​​

[-- Attachment #2: Type: text/html, Size: 13372 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 15:06                         ` Robert Weiner
@ 2017-12-16 16:15                           ` Eli Zaretskii
  2017-12-16 18:57                             ` Robert Weiner
  2017-12-16 19:06                             ` martin rudalics
  0 siblings, 2 replies; 29+ messages in thread
From: Eli Zaretskii @ 2017-12-16 16:15 UTC (permalink / raw)
  To: rswgnu; +Cc: alan, emacs-devel

> From: Robert Weiner <rsw@gnu.org>
> Date: Sat, 16 Dec 2017 10:06:10 -0500
> Cc: Alan Third <alan@idiocy.org>, emacs-devel <emacs-devel@gnu.org>
> 
>  Then IMO sit-for is not your friend: if input arrives soon enough,
>  redisplay will not be called.  And if you happen to have
>  redisplay-dont-pause set to nil, even if redisplay _is_ called, it
>  might do nothing when sit-for calls it.
> 
> ​Ok, that is an example of why I am advocating for a potentially
> new function that let's a programmer say "display the latest
> contents of this window with no other Emacs window or frame
> obscuring it".

That cannot be done in general, because redisplaying a window could
very well affect other windows.  One example of that is TTY frame
display; another is a case where the window was shrunk.  And there are
other, more subtle use cases.

In general, Lisp programs shouldn't dictate the display engine what to
do or not to do, because they can easily make mistakes, being unaware
of all the subtleties.  Instead, it should be the job of the display
engine to determine what and when to redraw, and Lisp can at most
provide hints.

> I don't think Elisp programmers should have to
> master the intricacies of windows, frames, the redisplay engine,
> and window managers to do that.

They don't.  But note that your code attempted to do just that, at
least indirectly.

>  ​​On top of that, when and how a new frame appears on display is not
>  ​​only up to Emacs: the WM has a lot to do with that.
> 
> ​Yes, but Emacs sends commands to the WM.  Now if the WM ignores
> those commands not much can be done

The problem is, many popular WMs do ignore our hints.  So reliable
behavior cannot be built on top of this flaky basis.

> Take raise-frame for example.  Should we not expect
> this to make the given frame the topmost?  The doc string says we
> should.

Martin will tell, but I personally am not sure we can rely on that,
the doc string notwithstanding.

>  ​​The doc strings try very hard to tell the story completely and
>  ​​accurately, but it isn't easy, because the underlying behavior is
>  ​​extremely complex, and needs to cater to some very different use
>  ​​cases.
> 
> ​I'm mainly asking that obvious gotchas like those demonstrated
> by my sample code be mentioned in doc strings, not a deep dive
> into all special case technicalities.

But the doc strings need to provide information for much more complex
code as well, not just for simple codes.

>  ​​Calling 'redisplay' with last argument non-nil is the only way to
>  ​​actually ensure redisplay, so if you must, use only that.
> 
> ​It sounds like that is the only way since I need to see the current contents
> of the new frame's only window.

And what's wrong with that?  You don't need more than one way, as long
as it works.

(There's also redraw-display, but that's hardly suitable for Lisp
programs.)

>  ​​I did, and still couldn't understand the intent.  I still don't, FWIW.
> 
> ​Have I explained it well enough to you now?

Not really, not in detail.  Does that matter?



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 16:15                           ` Eli Zaretskii
@ 2017-12-16 18:57                             ` Robert Weiner
  2017-12-16 19:45                               ` Eli Zaretskii
  2017-12-16 19:06                             ` martin rudalics
  1 sibling, 1 reply; 29+ messages in thread
From: Robert Weiner @ 2017-12-16 18:57 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Alan Third, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 5331 bytes --]

On Sat, Dec 16, 2017 at 11:15 AM, Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Robert Weiner <rsw@gnu.org>
>
> > ​Ok, that is an example of why I am advocating for a potentially
> > new function that let's a programmer say "display the latest
> > contents of this window with no other Emacs window or frame
> > obscuring it".
>
> That cannot be done in general, because redisplaying a window could
> very well affect other windows.  One example of that is TTY frame
> display;


​Only one frame is visible on a tty at a time, so in
my use case, this would have to be the frame that
displays the window.  Why is this a problem?

​​
> another is a case where the window was shrunk.


​Why can a shrunk window not be displayed within the
topmost frame?  You are giving examples without explaining
why they conflict with the desired goal?
​

> ​​
>   And there are
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
> ​​
>
> ​​
> other, more subtle use cases.
>

​So you are saying Emacs provides no way for the programmer
to ensure that a window is wholly displayed on screen and
fully updated even when Emacs is the only application in use?
​

> ​
>
> ​​
> In general, Lisp programs shouldn't dictate the display engine what to
> ​​
> do or not to do, because they can easily make mistakes, being unaware
> ​​
> of all the subtleties.  Instead, it should be the job of the display
> ​​
> engine to determine what and when to redraw, and Lisp can at most
> ​​
> provide hints.
>

​Right, this is what we do most of the time.
​

> ​​
>
> ​​
> > I don't think Elisp programmers should have to
> ​​
>
> ​​
> > master the intricacies of windows, frames, the
> ​​
> redisplay engine,
> ​​
> > and window managers to do that.
> ​​
>
> ​​
>
> ​​
> They don't.  But note that your code
> ​​
> attempted to do just that, at
> ​​
> least indirectly.
> ​​
>

​I am trying to do just what I stated above plus ensure
the displayed frame receives input focus.​
​​

> ​​
> >  ​​On top of th
> ​​
> at, when and how a new frame appears on display is not
> ​​
> >  ​​only up to E
> ​​
> macs: the WM has a lot to do with that.
> ​​
> >
> ​​
>
> ​​
> >
> ​​
> ​Yes, but Emacs sends commands to the WM.  Now if the WM ignores
> ​​
> >
> ​​
> those commands not much can be done
> ​​
>
> ​​
> The problem is, many popular WMs do ignore our hints.  So reliable
> ​​
> behavior cannot be built on top of this flaky basis.
>

Under what window managers is Emacs unable to raise
a frame or set input focus reliably?  That sounds like
a platform where multi-frame use would be generally
unreliable.
​

> ​​
>
> ​​
> > Take raise-frame for example.  Should we not expect
> ​​
> > this to make the given frame the topmost?  The doc string says we
> ​​
> > should.
> ​​
>
> ​​
> Martin will tell, but I personally am not sure we can rely on that,
> ​​
> the doc string notwithstanding.
>

​If you cannot put a frame in front of all others then
you can't see the contents of its windows when frames
overlap and again multi-frame​ use would not be viable
except for non-overlapping frames.

​​
>
> ​​
> >  ​​The doc strings try very hard to tell the story completely and
> ​​
> >  ​​accurately, but it isn't easy, because the underlying behavior is
> ​​
> >  ​​extremely complex, and needs to cater to some very different use
> ​​
> >  ​​cases.
> ​​
> >
> ​​
> > ​I'm mainly asking that obvious gotchas like those demonstrated
> ​​
> > by my sample code be mentioned in doc strings, not a deep dive
> ​​
> > into all special case technicalities.
> ​​
>
> ​​
> But the doc strings need to provide information for much more complex
> ​​
> code as well, not just for simple codes.
>

​I'm not against documenting more involved scenarios,
just saying I think some of this documentation could
be added with a few sentences without diving deeply
into many special cases.  If this covered 90% of the
cases, it would still be very helpful despite not being
wholly complete.  You yourself said earlier that that
is an unreasonable expectation of the doc.
​

> ​​
>
> ​​
> >  ​​Calling 'redisplay' with last argument non-nil is the o
> ​​
> nly way to
> ​​
> >  ​​actually ensure redisplay, so if you must, use only th
> ​​
> at.
> ​​
> >
> ​​
>
> ​​
> >
> ​​
> ​It sounds like that is the only way since I need to see the current
> contents
> ​​
> >
> ​​
> of the new frame's only window.
> ​​
>
> ​​
> A
> ​​
> nd what's wrong with that?  You don't need more than one way, as long
> ​​
> a
> ​​
> s it works.
>

​It is fine.  I had just dealt with many multi-frame scenarios
before and never had to call redisplay directly so it seemed
odd that I had to now.  So I looked for other techniques to
give redisplay hints as you said and was surprised when these
hints were insufficient.​

Bob

[-- Attachment #2: Type: text/html, Size: 16680 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 16:15                           ` Eli Zaretskii
  2017-12-16 18:57                             ` Robert Weiner
@ 2017-12-16 19:06                             ` martin rudalics
  2017-12-16 19:24                               ` Robert Weiner
  1 sibling, 1 reply; 29+ messages in thread
From: martin rudalics @ 2017-12-16 19:06 UTC (permalink / raw)
  To: Eli Zaretskii, rswgnu; +Cc: alan, emacs-devel

 >> Take raise-frame for example.  Should we not expect
 >> this to make the given frame the topmost?  The doc string says we
 >> should.
 >
 > Martin will tell, but I personally am not sure we can rely on that,
 > the doc string notwithstanding.

`raise-frame' should make a frame's window-system window the topmost one
in its z-group and any z-group beneath it.  It should not direct input
focus to that frame although many window managers and window systems may
do that automatically.  This should be no problem when the Emacs thread
already has input focus.  If, however, Emacs doesn't have focus, it
would try to steal focus from another application and many "modern"
window managers and window systems may prevent that.

So `raise-frame' works reliably when the frame is given input focus as
well - users of `minibuffer-auto-raise' should be able to confirm that.
Calling it twice in a row without intermittent user interaction, using
time to control its behavior, or calling it when Emacs doesn't already
have focus, however, usually means asking for trouble.

martin



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 19:06                             ` martin rudalics
@ 2017-12-16 19:24                               ` Robert Weiner
  0 siblings, 0 replies; 29+ messages in thread
From: Robert Weiner @ 2017-12-16 19:24 UTC (permalink / raw)
  To: martin rudalics; +Cc: Eli Zaretskii, Alan Third, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1480 bytes --]

On Sat, Dec 16, 2017 at 2:06 PM, martin rudalics <rudalics@gmx.at> wrote:

> >> Take raise-frame for example.  Should we not expect
> >> this to make the given frame the topmost?  The doc string says we
> >> should.
> >
> > Martin will tell, but I personally am not sure we can rely on that,
> > the doc string notwithstanding.
>
> `raise-frame' should make a frame's window-system window the topmost one
> in its z-group and any z-group beneath it.


​That is all I am asking of it.

It should not direct input
> focus to that frame although many window managers and window systems may
> do that automatically.  This should be no problem when the Emacs thread
> already has input focus.  If, however, Emacs doesn't have focus, it
> would try to steal focus from another application and many "modern"
> window managers and window systems may prevent that.
>

I do a lot of interactive, user-centered work where the Emacs
is naturally the application with focus, so in this context
there is no issue.

​​
>
> ​​
> So `raise-frame' works reliably when the frame is given input focus as
> ​​
> well - users of `minibuffer-auto-raise' should be able to confirm that.
> ​​
> Calling it twice in a row without intermittent user interaction, using
> ​​
> time to control its behavior, or calling it when Emacs doesn't already
> ​​
> have focus, however, usually means asking for trouble.


​Good to know.

Bob
​

[-- Attachment #2: Type: text/html, Size: 3583 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 18:57                             ` Robert Weiner
@ 2017-12-16 19:45                               ` Eli Zaretskii
  2017-12-16 20:07                                 ` Robert Weiner
  0 siblings, 1 reply; 29+ messages in thread
From: Eli Zaretskii @ 2017-12-16 19:45 UTC (permalink / raw)
  To: rswgnu; +Cc: alan, emacs-devel

> From: Robert Weiner <rsw@gnu.org>
> Date: Sat, 16 Dec 2017 13:57:34 -0500
> Cc: Alan Third <alan@idiocy.org>, emacs-devel <emacs-devel@gnu.org>
> 
>  > ​Ok, that is an example of why I am advocating for a potentially
>  > new function that let's a programmer say "display the latest
>  > contents of this window with no other Emacs window or frame
>  > obscuring it".
> 
>  That cannot be done in general, because redisplaying a window could
>  very well affect other windows.  One example of that is TTY frame
>  display;
> 
> ​Only one frame is visible on a tty at a time, so in
> my use case, this would have to be the frame that
> displays the window.  Why is this a problem?

TTY redisplay deals with the entire frame, so it cannot redraw a
single window.

>  ​​another is a case where the window was shrunk.
> 
> ​Why can a shrunk window not be displayed within the
> topmost frame?  You are giving examples without explaining
> why they conflict with the desired goal?

I gave examples that explain why Emacs cannot be in general told to
redraw a single window.  Maybe I misunderstood, but I thought this is
what you were trying to accomplish ("display the latest contents of
this window").

> ​So you are saying Emacs provides no way for the programmer
> to ensure that a window is wholly displayed on screen and
> fully updated even when Emacs is the only application in use?

Not if you want to tell Emacs to display _only_ one window.  The
display engine has its own logic that decides what needs to be
redrawn, and Lisp programs should not interfere with those decisions.
That is why we don't provide APIs to achieve that.  Needless to say,
the decisions of the display engine are required to be correct,
i.e. the redrawn display must always reflect the contents of the
shown buffers and their associated Lisp data (properties, overlays,
etc.) as they were found when redisplay was entered.  Any disparity
between the two is a display bug.

> Under what window managers is Emacs unable to raise
> a frame or set input focus reliably?

As Stefan already mentioned, focus policies are very different, and
some of them are affected by user customizations outside of Emacs.
I'm not an expert on window managers to call out specific ones, but
they are all on X, AFAIR.

> I had just dealt with many multi-frame scenarios
> before and never had to call redisplay directly so it seemed
> odd that I had to now.

That's because normally, you don't need to.  Having to display changes
during the command's execution is a rare use case.



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: select-frame-set-input-focus fails to raise the frame
  2017-12-16 19:45                               ` Eli Zaretskii
@ 2017-12-16 20:07                                 ` Robert Weiner
  0 siblings, 0 replies; 29+ messages in thread
From: Robert Weiner @ 2017-12-16 20:07 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Alan Third, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 3511 bytes --]

On Sat, Dec 16, 2017 at 2:45 PM, Eli Zaretskii <eliz@gnu.org> wrote:

> > From: Robert Weiner <rsw@gnu.org>
> > Date: Sat, 16 Dec 2017 13:57:34 -0500
> > Cc: Alan Third <alan@idiocy.org>, emacs-devel <emacs-devel@gnu.org>
> >
> >  > ​Ok, that is an example of why I am advocating for a potentially
> >  > new function that let's a programmer say "display the latest
> >  > contents of this window with no other Emacs window or frame
> >  > obscuring it".
> >
> >  That cannot be done in general, because redisplaying a window could
> >  very well affect other windows.  One example of that is TTY frame
> >  display;
> >
> > ​Only one frame is visible on a tty at a time, so in
> > my use case, this would have to be the frame that
> > displays the window.  Why is this a problem?
>
> TTY redisplay deals with the entire frame, so it cannot redraw a
> single window.
>

​Again, I think you are missing my main points because you are
drawn to the implementation level.  ​I never said redisplay had
to only draw one window.  I said that I needed the latest contents
of a particular window displayed.  I don't care what redisplay feels
it needs to redraw as long as it shows the latest contents of that
window, it does it at a particular point in the function and Emacs
tells the window manager to make its frame the uppermost in the stack
or Z-frame group as Martin described).

​​
>
> ​​
> >  ​​another is a case where the window was shrunk.
> ​​
> >
> ​​
> > ​Why can a shrunk window not be displayed within the
> ​​
> > topmost frame?  You are giving examples without explaining
> ​​
> > why they conflict with the desired goal?
> ​​
>
> ​​
> I gave examples that explain why Emacs cannot be in general told to
> redraw a single window.  Maybe I misunderstood, but I thought this is
> what you were trying to accomplish ("display the latest contents of
> this window").
>

​No.  I mentioned the latest contents of the window because
when I used sit-for to trigger redisplay, I would see the
new frame displayed with the buffer it was created with even
though a set-window-buffer change had been called prior to
the invocation of the sit-for.  So just displaying the window
was insufficient since it had the wrong contents.  Calling
(redisplay t) directly fixed this.

​​
> > ​So you are saying Emacs provides no way for the programmer
> ​​
> > to ensure that a window is wholly displayed on screen and
> ​​
> > fully updated even when Emacs is the only application in use?
> ​​
>
> ​​
> Not if you want to tell Emacs to display _only_ one window.


​Okay, this was just you misreading my intent.


> > I had just dealt with many multi-frame scenarios
> > before and never had to call redisplay directly so it seemed
> > odd that I had to now.
>
> That's because normally, you don't need to.  Having to display changes
> during the command's execution is a rare use case.
>

​But it will come up any time a temporary display of an
overlapping frame is necessary where the function must
end with another frame atop the stack.  Thus, it sounds like
a case for a with-temp-frame macro that would call
select-frame-set-input-focus on the temp frame for a variable
specified amount of time.  It would then reset the selected frame
and input focus to the way they were prior to the macro invocation
(as best it could given system limitations).

Bob

[-- Attachment #2: Type: text/html, Size: 8119 bytes --]

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2017-12-16 20:07 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-12-12 23:02 select-frame-set-input-focus fails to raise the frame Bob Weiner
2017-12-12 23:26 ` Robert Weiner
2017-12-13 20:47   ` Alan Third
2017-12-13 22:00     ` Robert Weiner
2017-12-13 22:26       ` Alan Third
2017-12-14  0:33         ` Robert Weiner
2017-12-14 21:03           ` Robert Weiner
2017-12-15 15:53             ` Robert Weiner
2017-12-15 16:10               ` Eli Zaretskii
2017-12-15 17:38                 ` Robert Weiner
2017-12-15 20:44                   ` Eli Zaretskii
2017-12-16 13:41                     ` Robert Weiner
2017-12-16 14:39                       ` Eli Zaretskii
2017-12-16 15:06                         ` Robert Weiner
2017-12-16 16:15                           ` Eli Zaretskii
2017-12-16 18:57                             ` Robert Weiner
2017-12-16 19:45                               ` Eli Zaretskii
2017-12-16 20:07                                 ` Robert Weiner
2017-12-16 19:06                             ` martin rudalics
2017-12-16 19:24                               ` Robert Weiner
2017-12-13  8:50 ` martin rudalics
2017-12-13 15:00   ` Robert Weiner
2017-12-13 16:07     ` Stefan Monnier
2017-12-13 16:33       ` Robert Weiner
2017-12-13 19:39         ` Eli Zaretskii
2017-12-13 19:30     ` martin rudalics
2017-12-13 22:14       ` Robert Weiner
2017-12-13 20:49 ` Alan Third
2017-12-13 21:53   ` Robert Weiner

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).