emacs-devel
[Top][All Lists]
Advanced

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

Re: size hints and tiling window managers


From: Jonas Bernoulli
Subject: Re: size hints and tiling window managers
Date: Sun, 09 Dec 2012 20:23:30 +0100
User-agent: mu4e 0.9.9.5-dev4; emacs 24.3.50.1

Eli Zaretskii writes:

> I'd prefer we fix this particular problem:
>
>> Emacs does the same thing: it paints the extra space using the
>> background color of the default face.  The problem is that Emacs frames
>> may also have fringes which usually don't have the same background
>> color.  As a result Emacs draws a "line" with the same color as *the*
>> background color to the right of the right fringe (and below the echo
>> area).
>
> Can you show a screenshot of this?

Attachment: ignored-size-hints.png
Description: PNG image

I have attached a screenshot that shows parts of four Emacs frames.  The
green areas are the X11 window borders and window titles drawn by the
window manager.  The cyan areas are the fringes.  In the upper left
window I have marked what I have called the "extra space" in my initial
report.

a. is the extra space between the fringe (and header-line) and the
   window border drawn by the wm. I have also called this "extra line".

b. is the extra space drawn below the minibuffer/echo area and above the
   window border drawn by the wm.

c. is both next to the fringe as well as below the minibuffer.  It's a
   corner case :-)

> Also, what would be a good solution to this problem? make the right
> fringe wider? something else?

I suggested that all "extra space" be painted using a color that can be
set independent of the background color of the default face.  (I did so
mostly because I think that it would be fairly easy do do; not because
that would solve the problem best.)

This way I could use cyan (or whatever color I use for the fringe) as
the "extra area color" to make (a) look as if it were part of the right
fringe.  (b) and (c) would still look wrong, as would the space next to
a header-line.

Making the right (or both) fringe wider is also something that I
considered.

>> 2. However I think it would be better if Emacs would just use any window
>>    size without having to paint some extra space to the right and below
>>    of the "actual" content.  One way of doing that could be to
>>    dynamically adjust the width of the fringes (and the height of the
>>    minibuffer/echo area).
>
> Changing the width of the fringes dynamically is easy, actually,
> because we already do so, albeit triggered by user commands.

I actually tried that approach.  I calculated the width of (a) and then
adjusted the width of the fringes accordingly.

,----
| (let ((d (- (frame-pixel-width)
|             (* (frame-width)
|                (frame-char-width)))))
|   (set-frame-parameter (selected-frame) 'left-fringe
|                        (/ d 2))
|   (set-frame-parameter (selected-frame) 'right-fringe
|                        (+ (/ d 2) (% d 2))))
`----

The result were wider fringes but the "extra space" did not go away, it
just changed it's width.

The size hint provided to the wm is still "make the width of the window
be a multitude of w" (w being the width of the default face).  The wm
still ignore the hint and Emacs still paint the resulting extra space
using the background color of the default face.  The width of the extra
space is likely different but it becoming 0 would be a coincidence.

So adjusting the width of the fringes can be part of the solution but
then Emacs would have to also detect that the fringes' pixel width isn't
a multitude of the character width and act accordingly:

,----
| (if (= (% (- (frame-pixel-width)
|              (frame-parameter (selected-frame) 'left-fringe)
|              (frame-parameter (selected-frame) 'right-fringe))
|           (frame-char-width))
|        0)
|     dont-paint-extra-space
|   paint-extra-space) ; or better adjust fringe width here
`----

It appears that Emacs currently does something like this instead:

,----
| (if (= (% (frame-pixel-width)
|           (frame-char-width))
|        0)
|     dont-paint-extra-space
|   ;; for each window in frame and for simplicity pretending
|   ;; each window uses full width of frame and has fringes:
|   (let ((d (- (frame-width)
|               (window-width window)
|               (truncate (frame-parameter (selected-frame) 'left-fringe))
|               (truncate (frame-parameter (selected-frame) 'right-fringe)))))
|     (unless (= d 0)
|       (grow-or-shrink-window window d))) ; text area
|   paint-extra-space)
`----

> Echo area is harder, because it's just a window, so its size must
> currently be a multiple of the default font's size.  Perhaps we could
> modify the mode-line width instead, by changing the line-with
> attribute of the mode-line face.  Can you try that?

Adjusting the mode-line height would very likely result in the same
problem as adjusting the fringe width.

> It should be clear that the device-independent stage _must_ produce a
> glyph for every character, even if that character is only partially
> visible.  And since the number of glyphs is always integer, you get
> the limitation of the integral multiple of frame font's size.  IOW,
> the issue here is _not_ that we cannot draw partially visible
> character -- we can -- but that the glyph matrix _dimensions_ must be
> integers.  The current limitation exists because asking the wm to
> observe the same restrictions was the easiest way of reconciling an
> internal requirement of integer dimensions of the glyph matrices with
> the fact that GUI frames are drawn and sized in pixels.

I understand why the width of the text area has to be an integer and am
aware that it partially visible characters can be drawn; and why that is
a good thing.

But the width of the fringes could still be dynamically adjusted to make
up for extra pixels when frame-pixel-width / frame-char-width isn't an
integer.

On my system the default font width is 9.  Therefor X11 windows can be
at most 8 pixels to width to be a multitude of frame-pixel-width.  Since
I use both fringes each fringe (having a integer width of 1) should be
dynamcically adjusted to have a pixel width of between 9 and 13 pixels.

If I understood you correctly you agree that could be an option; but as
I have tried to explain above that cannot be done from elisp at the
moment because Emacs ignores the pixel width of the fringes when setting
the character width of the text area.

>> From: James Cloos <address@hidden>
>> Doesn't it just require not setting the .width_inc and .height_inc
>> members of the size_hints struct in src/xterm.c and src/gtkutil.c,
>> and editing the .min_width and .min_height code to account for that?

> Maybe I'm missing something, but all your changes do is refrain from
> setting the width_inc and height_inc members of the XSizeHints
> structure.  Can you explain how does this solve the problem?

It seems that you think the above was written by the same person as the
original report.  It is not.

I agree with you that all this does is to not provide size hints and
that as a result the display problems that are now limited to wms that
ignore size hints would instead affect all wms.

  Best,
  Jonas

reply via email to

[Prev in Thread] Current Thread [Next in Thread]