unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Jonas Bernoulli <jonas@bernoul.li>
To: "Eli Zaretskii" <eliz@gnu.org>
Cc: rudalics@gmx.at, James Cloos <cloos@jhcloos.com>, emacs-devel@gnu.org
Subject: Re: size hints and tiling window managers
Date: Sun, 09 Dec 2012 20:23:30 +0100	[thread overview]
Message-ID: <87boe3t4gd.fsf@bernoul.li> (raw)
In-Reply-To: <838v98nci1.fsf@gnu.org>

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

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 #2: ignored-size-hints.png --]
[-- Type: image/png, Size: 26063 bytes --]

[-- Attachment #3: Type: text/plain, Size: 6436 bytes --]


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 <cloos@jhcloos.com>
>> 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	other threads:[~2012-12-09 19:23 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-06 18:55 size hints and tiling window managers Jonas Bernoulli
2012-12-07 10:35 ` martin rudalics
2012-12-07 10:45   ` Eli Zaretskii
2012-12-08  1:42   ` James Cloos
2012-12-08  9:01     ` Eli Zaretskii
2012-12-09 19:23       ` Jonas Bernoulli [this message]
2012-12-09 19:36         ` Eli Zaretskii
2012-12-15 23:33           ` Jonas Bernoulli
2012-12-16  4:42             ` Eli Zaretskii
2012-12-11  8:07       ` Giorgos Keramidas
2012-12-11  8:10         ` Eli Zaretskii
2012-12-08  9:15     ` Jan Djärv

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87boe3t4gd.fsf@bernoul.li \
    --to=jonas@bernoul.li \
    --cc=cloos@jhcloos.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=rudalics@gmx.at \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).