milkypostman / powerline

emacs powerline
Other
793 stars 118 forks source link

Powerline broken with latest emacs #184

Closed abbaswasim closed 3 years ago

abbaswasim commented 3 years ago

As you can see in the image below: In emacs 28.0.50 powerline modeline is blank. The reason I say its broken with latest emacs is that with emacs 27.x.x it works fine.

Screenshot 2021-03-13 at 13 25 17

While I have been bisecting this I found out that commit #177 has introduced the issue. By removing :scale fixes the issue for me.

Screenshot 2021-03-13 at 13 25 47

I have tested this with clean emacs build from src as well as brew install emacs@28 with the following init.el

(require 'package)

;;; Standard package repositories
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/"))
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/"))
(add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/"))
;; (add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(add-to-list 'package-archives '("elpy" . "https://jorgenschaefer.github.io/packages/"))

(setq package-enable-at-startup nil)

(unless package--initialized (package-initialize t))

(require 'powerline)
(powerline-default-theme)
milkypostman commented 3 years ago

@tgiannak any idea what might be going on here? I'm happy to rollback to fix it but that introduces scaling issues elsewhere.

tgiannak commented 3 years ago

Emacs 28 hasn't been released yet, so I haven't been using it. It does look like there were recent changes to how image scaling works in src/image.c (in particular https://github.com/emacs-mirror/emacs/commit/0474a0d7d4478e967c7bbee93ab3606f0b215e66 and https://github.com/emacs-mirror/emacs/commit/9ab51428cd53f1e3160fad85c952b956d18ed442) which could be the reason for the regression, but I don't have the time to test it out.

If the problem is the image created by powerline-hud being the wrong size again, it might be worth asking on the Emacs mailing list if someone can clarify the create-image documentation, and if powerline-hud is using it correctly, reporting a bug.

abbaswasim commented 3 years ago

So I am not an expert in either Powerline or emacs code base but just curious if the scaling is wrong (smaller or bigger than it should be) it should still show up right? but just the wrong size. Why is the mode line completely empty?

tgiannak commented 3 years ago

Without debugging through it myself, if #177 is to blame, then I'd guess that an error in generating the image is somehow resulting in mode-line-format being set to nil.

What's the value of mode-line-format in a buffer where the mode line isn't showing? What happens if you evaluate (powerline-hud 'default 'default)?

abbaswasim commented 3 years ago

What happens if you evaluate (powerline-hud 'default 'default)? It just prints default in the mini buffer. Unless you want me to put this in my init.el?

Also forgot to mention the warning I was getting at load time.

Error during redisplay: (eval (let* ((active (powerline-selected-window-active)) (seg1 (if active 'my-pl-segment1-active 'my-pl-segment1-inactive)) (seg2 (if active 'my-pl-segment2-active 'my-pl-segment2-inactive)) (seg3 (if active 'my-pl-segment3-active 'my-pl-segment3-inactive)) (separator-left (intern (format "powerline-%s-%s" (powerline-current-separator) (car powerline-default-separator-dir)))) (separator-right (intern (format "powerline-%s-%s" (powerline-current-separator) (cdr powerline-default-separator-dir)))) (lhs (list (let ((evil-face (powerline-evil-face))) (if evil-mode (powerline-raw (powerline-evil-tag) evil-face))) (if evil-mode (funcall separator-left (powerline-evil-face) seg1)) (powerline-raw "%b" seg1 'l) (powerline-raw "[%*]" seg1 'l) (when (and (boundp 'which-func-mode) which-func-mode) (powerline-raw which-func-format seg1 'l)) (powerline-raw " " seg1) (funcall separator-left seg1 seg2) (when (boundp 'erc-modified-channels-object) (powerline-raw erc-modified-channels-object seg2 'l)) (powerline-major-mode seg2 'l) (powerline-process seg2) (powerline-minor-modes seg2 'l) (powerline-narrow seg2 'l) (powerline-raw " " seg2) (funcall separator-left seg2 seg3) (powerline-vc seg3 'r) (when (bound-and-true-p nyan-mode) (powerline-raw (list (nyan-create)) seg3 'l)))) (rhs (list (powerline-raw global-mode-string seg3 'r) (funcall separator-right seg3 seg2) (unless window-system (powerline-raw (char-to-string 57505) seg2 'l)) (powerline-raw "%4l" seg2 'l) (powerline-raw ":" seg2 'l) (powerline-raw "%3c" seg2 'r) (funcall separator-right seg2 seg1) (powerline-raw " " seg1) (powerline-raw "%6p" seg1 'r) (when powerline-display-hud (powerline-hud seg1 seg3))))) (concat (powerline-render lhs) (powerline-fill seg3 (powerline-width rhs)) (powerline-render rhs)))) signaled (wrong-type-argument number-or-marker-p t) [5 times]

When I do describe-variable <RET>mode-line-format for the one where it doesn't work I get.

Value:
("%e"
 (:eval
  (let*
      ((active
    (powerline-selected-window-active))
       (mode-line-buffer-id
    (if active 'mode-line-buffer-id 'mode-line-buffer-id-inactive))
       (mode-line
    (if active 'mode-line 'mode-line-inactive))
       (face0
    (if active 'powerline-active0 'powerline-inactive0))
       (face1
    (if active 'powerline-active1 'powerline-inactive1))
       (face2
    (if active 'powerline-active2 'powerline-inactive2))
       (separator-left
    (intern
     (format "powerline-%s-%s"
         (powerline-current-separator)
         (car powerline-default-separator-dir))))
       (separator-right
    (intern
     (format "powerline-%s-%s"
         (powerline-current-separator)
         (cdr powerline-default-separator-dir))))
       (lhs
    (list
     (powerline-raw "%*" face0 'l)
     (when powerline-display-buffer-size
       (powerline-buffer-size face0 'l))
     (when powerline-display-mule-info
       (powerline-raw mode-line-mule-info face0 'l))
     (powerline-buffer-id
      `(mode-line-buffer-id ,face0)
      'l)
     (when
         (and
          (boundp 'which-func-mode)
          which-func-mode)
       (powerline-raw which-func-format face0 'l))
     (powerline-raw " " face0)
     (funcall separator-left face0 face1)
     (when
         (and
          (boundp 'erc-track-minor-mode)
          erc-track-minor-mode)
       (powerline-raw erc-modified-channels-object face1 'l))
     (powerline-major-mode face1 'l)
     (powerline-process face1)
     (powerline-minor-modes face1 'l)
     (powerline-narrow face1 'l)
     (powerline-raw " " face1)
     (funcall separator-left face1 face2)
     (powerline-vc face2 'r)
     (when
         (bound-and-true-p nyan-mode)
       (powerline-raw
        (list
         (nyan-create))
        face2 'l))))
       (rhs
    (list
     (powerline-raw global-mode-string face2 'r)
     (funcall separator-right face2 face1)
     (unless window-system
       (powerline-raw
        (char-to-string 57505)
        face1 'l))
     (powerline-raw "%4l" face1 'l)
     (powerline-raw ":" face1 'l)
     (powerline-raw "%3c" face1 'r)
     (funcall separator-right face1 face0)
     (powerline-raw " " face0)
     (powerline-raw "%6p" face0 'r)
     (when powerline-display-hud
       (powerline-hud face0 face2))
     (powerline-fill face0 0))))
    (concat
     (powerline-render lhs)
     (powerline-fill face2
             (powerline-width rhs))
     (powerline-render rhs)))))
Original value was 
("%e" mode-line-front-space mode-line-mule-info mode-line-client mode-line-modified mode-line-remote mode-line-frame-identification mode-line-buffer-identification "   " mode-line-position
 (vc-mode vc-mode)
 "  " mode-line-modes mode-line-misc-info mode-line-end-spaces)

And mode-line-format value in the one where it works

Value:
("%e"
 (:eval
  (let*
      ((active
        (powerline-selected-window-active))
       (seg1
        (if active 'my-pl-segment1-active 'my-pl-segment1-inactive))
       (seg2
        (if active 'my-pl-segment2-active 'my-pl-segment2-inactive))
       (seg3
        (if active 'my-pl-segment3-active 'my-pl-segment3-inactive))
       (separator-left
        (intern
         (format "powerline-%s-%s"
                 (powerline-current-separator)
                 (car powerline-default-separator-dir))))
       (separator-right
        (intern
         (format "powerline-%s-%s"
                 (powerline-current-separator)
                 (cdr powerline-default-separator-dir))))
       (lhs
        (list
         (let
             ((evil-face
               (powerline-evil-face)))
           (if evil-mode
               (powerline-raw
                (powerline-evil-tag)
                evil-face)))
         (if evil-mode
             (funcall separator-left
                      (powerline-evil-face)
                      seg1))
         (powerline-raw "%b" seg1 'l)
         (powerline-raw "[%*]" seg1 'l)
         (when
             (and
              (boundp 'which-func-mode)
              which-func-mode)
           (powerline-raw which-func-format seg1 'l))
         (powerline-raw " " seg1)
         (funcall separator-left seg1 seg2)
         (when
             (boundp 'erc-modified-channels-object)
           (powerline-raw erc-modified-channels-object seg2 'l))
         (powerline-major-mode seg2 'l)
         (powerline-process seg2)
         (powerline-minor-modes seg2 'l)
         (powerline-narrow seg2 'l)
         (powerline-raw " " seg2)
         (funcall separator-left seg2 seg3)
         (powerline-vc seg3 'r)
         (when
             (bound-and-true-p nyan-mode)
           (powerline-raw
            (list
             (nyan-create))
            seg3 'l))))
       (rhs
        (list
         (powerline-raw global-mode-string seg3 'r)
         (funcall separator-right seg3 seg2)
         (unless window-system
           (powerline-raw
            (char-to-string 57505)
            seg2 'l))
         (powerline-raw "%4l" seg2 'l)
         (powerline-raw ":" seg2 'l)
         (powerline-raw "%3c" seg2 'r)
         (funcall separator-right seg2 seg1)
         (powerline-raw " " seg1)
         (powerline-raw "%6p" seg1 'r)
         (when powerline-display-hud
           (powerline-hud seg1 seg3)))))
    (concat
     (powerline-render lhs)
     (powerline-fill seg3
                     (powerline-width rhs))
     (powerline-render rhs)))))
Original value was 
("%e" mode-line-front-space mode-line-mule-info mode-line-client mode-line-modified mode-line-remote mode-line-frame-identification mode-line-buffer-identification "   " mode-line-position evil-mode-line-tag
 (vc-mode vc-mode)
 "  " mode-line-modes mode-line-misc-info mode-line-end-spaces)
Local in buffer powerline.el; global value is the same.
abbaswasim commented 3 years ago

Trying a different way. If I just evaluate(print mode-line-format) I get ("%e" (:eval (let* (... ... ... ... ... ... ... ... ... ...) (concat ... ... ...))) where it doesn't work and in the case where it works I get:

("%e" (:eval (let* ((active (powerline-selected-window-active)) (seg1 (if active 'my-pl-segment1-active 'my-pl-segment1-inactive)) (seg2 (if active 'my-pl-segment2-active 'my-pl-segment2-inactive)) (seg3 (if active 'my-pl-segment3-active 'my-pl-segment3-inactive)) (separator-left (intern (format "powerline-%s-%s" (powerline-current-separator) (car powerline-default-separator-dir)))) (separator-right (intern (format "powerline-%s-%s" (powerline-current-separator) (cdr powerline-default-separator-dir)))) (lhs (list (let ((evil-face (powerline-evil-face))) (if evil-mode (powerline-raw (powerline-evil-tag) evil-face))) (if evil-mode (funcall separator-left (powerline-evil-face) seg1)) (powerline-raw "%b" seg1 'l) (powerline-raw "[%*]" seg1 'l) (when (and (boundp 'which-func-mode) which-func-mode) (powerline-raw which-func-format seg1 'l)) (powerline-raw " " seg1) (funcall separator-left seg1 seg2) (when (boundp 'erc-modified-channels-object) (powerline-raw erc-modified-channels-object seg2 'l)) (powerline-major-mode seg2 'l) (powerline-process seg2) (powerline-minor-modes seg2 'l) (powerline-narrow seg2 'l) (powerline-raw " " seg2) (funcall separator-left seg2 seg3) (powerline-vc seg3 'r) (when (bound-and-true-p nyan-mode) (powerline-raw (list (nyan-create)) seg3 'l)))) (rhs (list (powerline-raw global-mode-string seg3 'r) (funcall separator-right seg3 seg2) (unless window-system (powerline-raw (char-to-string 57505) seg2 'l)) (powerline-raw "%4l" seg2 'l) (powerline-raw ":" seg2 'l) (powerline-raw "%3c" seg2 'r) (funcall separator-right seg2 seg1) (powerline-raw " " seg1) (powerline-raw "%6p" seg1 'r) (when powerline-display-hud (powerline-hud seg1 seg3))))) (concat (powerline-render lhs) (powerline-fill seg3 (powerline-width rhs)) (powerline-render rhs)))))
("%e" (:eval (let* (... ... ... ... ... ... ... ...) (concat ... ... ...))))
tgiannak commented 3 years ago

An error in create-image was causing powerline-hud to fail, causing the mode-line-format to result in an error when it was evaluated. I can't tell what changed about the API, but the patch https://github.com/milkypostman/powerline/pull/185 should fix the problem and works for me both for Emacs 27.1 and for https://github.com/emacs-mirror/emacs/commit/ebc3b25409dd614c1814a0643960452683e37aa3, which was the most recent revision at the time I tested it.

abbaswasim commented 3 years ago

I can confirm the fix works for my setup as well. Thanks for the quick fix.

fosskers commented 3 years ago

Hi there, hopefully adding some signal with this. Here are the native-comp errors that I'm shown when I open Emacs (I'm also on Emacs 28):

powerline

And as of this morning, like the OP, my powerline is completely blank.

jpneverwas commented 3 years ago

According to (info "(elisp) Image Descriptors"),

‘:scale SCALE’
     This should be a number, where values higher than 1 means to
     increase the size, and lower means to decrease the size, by
     multiplying both the width and height.
     ...

I believe that's now effectively enforced by this change.

Evaluating this in an emacs -Q scratch buffer

(put-image (create-image "/* XPM */ static char * arrow_left[] = { \"11 24 3 1\", \"0 c #9393b3b3a3a3\", \"1 c #333335353535\", \"2 c #636274746c6c\",\"11111111111\",\"01111111111\",\"00111111111\",\"00011111111\",\"00001111111\",\"00000111111\",\"00000011111\",\"00000001111\",\"00000000111\",\"00000000011\",\"00000000001\",\"00000000000\",\"00000000000\",\"00000000001\",\"00000000011\",\"00000000111\",\"00000001111\",\"00000011111\",\"00000111111\",\"00001111111\",\"00011111111\",\"00111111111\",\"01111111111\",\"11111111111\",};" 'xpm t :ascent 'center :scale 1.0) (point))

worked for me with these values for :scale on the following systems:

Debian 26.1: t 1.0
Fedora 28.5:   1.0
macOS  27.1: t 1.0

Simply omitting the prop also worked on all three. But given that #177 was added for a reason, #185 seems like the way to go.

abbaswasim commented 3 years ago

This might be a tangent but out of curiosity, observing the warning messages showing up quite rapidly when powerline wasn't working makes me wonder. Are these images created every refresh of the powerline modeline? If yes could these be cached?

tgiannak commented 3 years ago

Simply omitting the prop also worked on all three. But given that #177 was added for a reason, #185 seems like the way to go.

Oh high DPI displays, the default scaling isn't 1, which causes the powerline-hud image (and presumably the separators) to be scaled up, making them much taller than the rest of the modeline.

Are these images created every refresh of the powerline modeline? If yes could these be cached?

If the image is successfully created, I believe they are already cached. The error was occurring on every refresh because there was no image to cache because the call to create-image was failing.

abbaswasim commented 3 years ago

This is very annoying, apologies if I am missing something else but for some reason this regressed for me again and no combination of :scale 1 or :scale t or just removing the scaling is working anymore.

I cloned the repo, tried to bisect it but it doesn't seem to behave with the latest emacs anymore: GNU Emacs 28.0.50 (build 2, x86_64-apple-darwin19.6.0, NS appkit-1894.60 Version 10.15.7 (Build 19H524)) of 2021-03-12 Copyright (C) 2021 Free Software Foundation, Inc..

Also updated emacs and powerline via elpa/packages etc.

Building from source an older version of emacs solves the issue the first bad commit seems to be 5dff53f5da4f17d74a0ad2cd7ec0a736aa5111f7 is the first bad commit.

Just looking at that patch and trying to understand, adding :transform-smoothing t doesn't help either.

abbaswasim commented 3 years ago

Testing create-images transform-smoothing with and without it also seems to work.

Screenshot 2021-03-16 at 16 01 42
fosskers commented 3 years ago

Confirming that the associated fix restores my powerline in Spacemacs (Emacs 28 running in GTK). Note that a stylized modeline would always appear in terminal Emacs (emacs -nw), maybe due to Spacemacs choosing a different backend for it?

milkypostman commented 3 years ago

@fosskers thanks for posting verification!

abbaswasim commented 3 years ago

Doh, didn't think about other uses of :scale t was looking at the wrong feature. I guess I got confused by the regressed commit in emacs.

Just to confirm it works for me as well thanks a lot.

Ergus commented 3 years ago

Hi there, hopefully adding some signal with this. Here are the native-comp errors that I'm shown when I open Emacs (I'm also on Emacs 28):

powerline

And as of this morning, like the OP, my powerline is completely blank.

Hi I am having the same issue here.

The docstring wider than 80 characters is trivial to fix, but the other requires someone who understand the code.

milkypostman commented 3 years ago

@Ergus I'm sorry I don't know if this is related to the issues here. You may have better luck filing a new issue.

Ergus commented 3 years ago

@Ergus I'm sorry I don't know if this is related to the issues here. You may have better luck filing a new issue.

I agree this is not the better place. But as I saw @fosskers already reporting the issue I didn't want to repeat it.