kovidgoyal / kitty

Cross-platform, fast, feature-rich, GPU based terminal
https://sw.kovidgoyal.net/kitty/
GNU General Public License v3.0
24.15k stars 972 forks source link

Images in w3m not working correctly #851

Closed itaton closed 6 years ago

itaton commented 6 years ago

When I start the w3m web browser in kitty, images are only shown for a fraction of a second after the page loads and then they vanish again. Images can be brought back for an other fraction of a second while I scroll in the kitty window but then they disappear again.

Here an example using kitty: kitty Also a video to better see the issue: kitty images in w3m - vimeo

And here using xterm, where it works as it should: xterm

Note: this issue is not due to the 0.12 release, I've had this issue with earlier versions as well. OS: Arch WM: i3

kovidgoyal commented 6 years ago

w3m uses a horrible hack to display images. It will not work with any GPU based terminal emulator. Since those are repainted independent of the X server.

kureta commented 5 years ago

@kdarkhan are there any terminal based browsers that work with kitty that you know of?

kdarkhan commented 5 years ago

@kureta I never used images in terminal functionality. So don't know.

zoefiri commented 5 years ago

This is literally just wrong, you are clearly lying just because you disdain w3m without any actual reasoning for why it shouldn't work in a GPU terminal. proof Here's a screenshot of another GPU accel terminal (Alacritty) where w3m images work perfectly fine.

kovidgoyal commented 5 years ago

Do you lack reading comprehension? Go read what I wrote again. As for it working in alacritty, what bullshit: https://github.com/jwilm/alacritty/issues/1021

And if you ever use that tone in a post on this project again, you will be blocked.

josephsdavid commented 5 years ago

w3m working ootb in alacritty

zoefiri commented 5 years ago

I don't, but I question whether you even remember what you said which was

"It will not work with any GPU based terminal emulator"

you made a misleading statement about other terminal emulators which are not your own simply because you seem to have a personal vendetta against w3m. adieu to you, and your project.

SolitudeSF commented 5 years ago

there is literally nothing wrong with hating w3m, or tmux, or other hacky bullshit.

Sweets commented 5 years ago

w3m-img doesn't use any "hacks" to display images at all. The current de facto method to displaying images in the terminal is to render an X window and reparent it to the terminal window.

Do you lack reading comprehension? Go read what I wrote again. As for it working in alacritty, what bullshit: jwilm/alacritty#1021

This isn't necessarily accurate either. w3m-img displays can vary largely based on the users configuration for whatever calls w3m-img. Finicky at best, surely, but most definitely not out of the question. Also, if you see here, the issue did get resolved by some users, further justifying that it could be a user configuration error.

If this does end up being implemented at some point, or fixed rather, you may want to consider properly handling X focus events (I haven't seen the source for Kitty myself, but speaking from experience, a lot of terminal emulators don't properly handle refocus events, and they redraw when focus changes, causing images to "disappear" from the terminal).

Unrelated, but try and conduct yourself in a semi-professional manner at least (even if people don't have a tone you necessarily like, it's not in your best interest to be aggressive in return). I'm just a third party providing input, and it doesn't look good to someone on the outside looking in.

SolitudeSF commented 5 years ago

w3m-img doesn't use any "hacks" to display images at all. The current de facto method to displaying images in the terminal is to render an X window and reparent it to the terminal window.

it is a hack. also try changing focus to another tag/workspace, see if this crap still works.

josephsdavid commented 5 years ago

w3m in alacritty with changing workspaces lol

Sweets commented 5 years ago

w3m-img doesn't use any "hacks" to display images at all. The current de facto method to displaying images in the terminal is to render an X window and reparent it to the terminal window.

it is a hack. also try changing focus to another tag/workspace, see if this crap still works.

I mentioned how that could be averted in my post. Also, I'd like to add that the word hack was in quotes for a reason. Strictly speaking yes, it is, but I went on to explain that it is just the accepted way to do this.

kovidgoyal commented 5 years ago

Unrelated, but try and conduct yourself in a semi-professional manner at least (even if people don't have a tone you necessarily like, it's not in your best interest to be aggressive in return). I'm just a third party providing input, and it doesn't look good to someone on the outside looking in.

Thank you very much, I'll decide what's in my best interest. Dealing with people like @ZoeFiri is not. Life is too short, and too many people seem to be laboring under the delusion that I owe them something for having the temerity to make free software. You think I am unprofessional, feel free to not use my software.

I have about had it with dealing with rude and entitled people on the internet.

ctrlcctrlv commented 1 year ago

I asked @kovidgoyal to reopen this issue because I thought I'd solved it. Turns out I only solved it in a very limited testing scenario not applicable to most builds of w3m.

My idea is just to implement w3mimgdisplay in Python and call kitty +icat. But it doesn't quite work, I think because w3m (without the hack I thought was only needed for testing) doesn't let us write to the terminal. If anyone knows how to fix it, feel free to comment, or let me know via email if this is closed again.

#!/usr/bin/env python3
import ctypes
import enum
import sys
import os
import shlex
libc = ctypes.CDLL("libc.so.6")
from ctypes import pointer, c_ulong, c_short
TIOCGWINSZ = c_ulong(0x5413)

class WINSIZE(ctypes.Structure):
    _fields_ = [("row", c_short),
                ("col", c_short),
                ("xpixel", c_short),
                ("ypixel", c_short)]

    def __str__(self):
        return "\n".join(["%s:\t%s" % (k, str(getattr(self, k))) for k, t in self._fields_])

    def tiocgwinsz(self):
        libc.ioctl(0, TIOCGWINSZ, pointer(self))
        return self

    def pixels_per_grid(self):
        self.tiocgwinsz()
        return (int(self.ypixel / self.row), int(self.xpixel / self.col))

    def pixel_to_grid(self, x, y):
        px, py = self.pixels_per_grid()
        return (int(px/x), int(py/y))

    def __init__(self):
        super(WINSIZE).__init__()
        self.tiocgwinsz()

class W3MImage(object):
    def __init__(self, **kwargs):
        for k, v in kwargs.items():
            setattr(self, k, v)

    def kitty_icat_place(self):
        x, y = WINSIZE().pixel_to_grid(self.x, self.y)
        return f"{self.w}x{self.h}@{x}x{y}"

    def draw(self):
        cmd = f"kitty +icat --stdin=no --align=left --silent --z-index=2 --place={self.kitty_icat_place()} " + shlex.quote(self.path)
        os.system(cmd)

class W3MImageDisplayCmd(object):
    winsize = WINSIZE()
    images = dict()

    def __init__(self, command, args):
        if command == '0':
            return self.draw_image(args)
        elif command == '1':
            return self.draw_image(args, redraw=True)
        elif command == '2':
            return self.terminate(args)
        elif command == '3':
            return self.sync_drawing(args)
        elif command == '4':
            return self.newline()
        elif command == '5':
            return self.image_size(args)
        elif command == '6':
            return self.clear_image(args)

    def draw_image(self, args, redraw=False):
        if redraw:
            return # We don't have to do this.
        argss = args.split(';')
        n, x, y, w, h, sx, sy, sw, sh = [int(a) for a in argss[:-1]]
        path = args[-1]
        w3im = W3MImage(x=x, y=y, w=w, h=h, sx=sx, sy=sy, sw=sw, sh=sh, path=path)
        self.images[n] = w3im

    def terminate(self):
        sys.exit(0)

    def newline(self):
        print()

    def sync_drawing(self, _):
        return None # No clue what this should do given we aren't messing w/X. Probably nothing.

    def image_size(self, args):
        n = int(self.args)
        print(self.images[n].w, self.images[n].h)

    def clear_image(self, args):
        x, y, w, h = [int(a) for a in args]
        # Unimplemented.
        return

data = input()
command = data[0]
if len(data) > 2:
    args = data[2:]
else:
    args = None
while True:
    try:
        W3MImageDisplayCmd(command, args)
        sys.stdin.flush()
        sys.stdout.flush()
    except:
        pass
kovidgoyal commented 1 year ago

As far as I know w3m added support for the kitty image protocol a while ago, version 0.5.3. https://github.com/tats/w3m/blob/c515ea8a47b62408943390f579b2f377464f6658/NEWS

ctrlcctrlv commented 1 year ago

Ah-ha look at that! Mine was just out of date. Good news, the Python script isn't needed! :o)

$ IN="$(head -n2 <<< "$( (2>&1 w3m --version)|awk 'BEGIN{RS=", "}{print}')" )"; \
AWKBEGIN="BEGIN{FS=\",\";OFS=\" \";}"; \
AWKARGS() {
  (awk "$AWKBEGIN"'
    {
      out="";
      for(i=1;i<=NF;i++){out=out"sub(/^ +/,\"\",$"i");"};
      out=out"\n";
      for(i=1;i<=NF;i++){out=out"$"i""(i == NF ? "" : ", ")}
    }
    {printf out}'
  )
}; \
while read line; do
  export AA
  mapfile -t AA < <(AWKARGS <<< "$line")
  awk "$AWKBEGIN {${AA[0]}
  print ${AA[1]};}" <<< "$line"
done <<< "$IN"
w3m version w3m/0.5.3+git20210102
options lang=en m17n image color ansi-color mouse gpm menu cookie ssl ssl-verify external-uri-loader w3mmailer nntp gopher ipv6 alarm mark migemo
laoshaw commented 1 year ago

I'm on ubuntu 22.04 which has w3m w3m-image both at 0.5.3 still w3m won't display any images, xterm works fine. when I navigate w3m I did see the images are flashking|blinking, but they do not stay.

dominikhaid commented 1 year ago

Same

I'm on ubuntu 22.04 which has w3m w3m-image both at 0.5.3 still w3m won't display any images, xterm works fine. when I navigate w3m I did see the images are flashking|blinking, but they do not stay.

Same for me

NocturnalNessa commented 1 year ago

Same

I'm on ubuntu 22.04 which has w3m w3m-image both at 0.5.3 still w3m won't display any images, xterm works fine. when I navigate w3m I did see the images are flashking|blinking, but they do not stay.

Same for me

I have it working. The relevant lines of my ~/.w3m/config are: inline_img_protocol 4 imgdisplay /usr/bin/kitten icat 2>/dev/null

2>/dev/null was needed because I kept getting errors over an elusive "-s" option w3m kept trying to call, that was appearing in and displacing text in pages I was viewing. I think this is due to my version/build of imagemagick but I'm honestly not sure. I might try sending it to a log file instead if I end up caring enough. I will edit this further if I figure it out.

unrealapex commented 10 months ago

I am able to get w3m working with icat configuring the imagine display in my w3m config, however, I am unable to get images to display with fff.

w3m uses a horrible hack to display images. It will not work with any GPU based terminal emulator. Since those are repainted independent of the X server.

Would there be a work-around for fff that I could use resolve this issue? It looks like the current image drawing implementation uses framebuffer. I recall Kovid mentioned something in another issue about GPU accelerated terminals overwriting this buffer.

097115 commented 3 months ago

For the record, @NocturnalNessa is right, this does work:

w3m -o inline_img_protocol=4 -o imgdisplay='/usr/bin/kitten icat' http://google.com

But, of course, not in tmux :(