Subject: Re: bug#25408: Remove Decorations Around Emacs Frame (Windows OS)

From: martin rudalics <[email-masked]>
Date: Sun, 12 Feb 2017 12:13:17 +0100

> Thanks! The patch applied cleanly and everything compiled fine.

Thanks for testing.  Please tell me your build and window manager types.

 > ✓, although if I create a frame with no-focus-on-map I then need a
 > call to raise-frame to raise it — even if its z-group is 'above.
 > Maybe when z-group is "above" the frame should be automatically
 > raised?

Not so here (with a GTK 3.4.2 build on Debian running xfwm).  Evaluating

(make-frame '((no-focus-on-map . t) (z-group . above)))

makes a new frame on top of the existing one regardless of whether xfwm
is set up to use focus follows mouse or not.

We probably have to investigate that further.

 > ✓, although it would be nice to automatically raise the frame when
 > x-group is above.  I can call raise-frame, but it doesn't work
 > correctly when the frame is invisible (and setting the visibility to t
 > before raising the frame doesn't work either).

I mentioned that: When a frame is made invisible, its z-group is reset
to nil by the window system or manager.  x_set_z_group can't cope with
that because the last line of

x_set_z_group (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
{
   if (!EQ (new_value, old_value))

still assumes that the frame is "above".  For the moment try with

(set-frame-parameter frame 'z-group nil)
...
(set-frame-parameter frame 'z-group 'above)

as a workaround.  I'm not yet sure whether it's better to (1) have
x_make_frame_invisible and x_iconify_frame reset the z-group parameter
explicitly, (2) change x_set_z_group so it always issues a request to
the window system, or (3) remove the z-group parameter and make the
z-group setting an option of the `frame-restack' function.

Unfortunately, the z-group equivalents in X 11 are a complete mess: You
can put a window simultaneously in the ‘above’ and the ‘below’ groups
and it notwhere says what should prevail and what happens when you later
remove a window from one of these groups (I trioed to avoid this dilemma
with the z-group concept).  And restacking may probably remove a window
from these groups and maybe not allow to put it there and so on ...

And why not avoid z-groups at all?  Because you cannot simply restack a
frame on top of the "active" frame.  If you try (via a foucs-in-hooked
function) you will see that your window system uses up all available
resources because the window system wants to raise the active frame and
Emacs wants to raise the other one.  So to put a frame on top of the
"active" frame you have to put that frame in the ‘above’ group.

 > * Creating a frame is rather slow; the following is an excerpt of a profile:
 >
 >                 - make-frame                                       442  29%
 >                  - frame-creation-function                         440  29%
 >                   - apply                                          440  29%
 >                    - #<compiled 0x4862dd>                          440  29%
 >                     - x-create-frame-with-faces                    440  29%
 >                      - face-set-after-frame-default                307  20%
 >                       - face-spec-recalc                           276  18%
 >                        - make-face-x-resource-internal             217  14%
 >                         - set-face-attributes-from-resources       213  14%
 >                          - set-face-attribute-from-resource        190  12%
 >                           - face-name                              126   8%
 >                            + check-face                            118   7%
 >                        + face-spec-reset-face                       44   2%
 >                        + face-spec-set-2                             7   0%
 >                         set-face-attribute                           8   0%
 >                    normal-erase-is-backspace-setup-frame                  2   0%

But isn't that the problem I tried to tackle (for tooltip frames) with
the option ‘tooltip-reuse-hidden-frame’?  All this face-related stuff is
an ecological disaster IMHO.  Here, creating a tooltip frame caused up
to two GC cycles before I added that option.

So as a rule create your frames (lazily) once for each session and hide
them when you don't need them.

 > * Frames with z-group set to 'above are not automatically raised when
 > no-focus-on-map is set, so I need to call x-raise-frame on them; this
 > doesn't work when they are invisible (instead it makes them visible
 > without raising them, it seems).

I hope I described the problem and a workaround above.  I attach my
functions for testing attached frames so you can see how I handle this
currently.

 > * Creating a frame / making it visible uses my WM's frame creating animation — is there a way to disable this (x-show-tip doesn't have it)?

No idea.  I can look into that (as a rule I turn off all animations
here).  Do you use GTK tooltips or Emacs' native ones?

martin