company-posframe icon indicating copy to clipboard operation
company-posframe copied to clipboard

Child frame not resizing to fit candidates

Open Koekelas opened this issue 6 years ago • 73 comments

When the child frame is shown, it fits the initial candidates. When you interact with the child frame (e.g. type or scroll), it doesn't resize, resulting in cut off candidates. Look at the two cut off autoload candidates.

company-posframe

This also happens on a clean Emacs.

Koekelas avatar Jul 10 '18 13:07 Koekelas

I'm trying to debug this, but so far no luck.

Some additional observations:

  • I can reproduce this on my primary machine (Linux 4.17.5, GNOME 3.28.2, Emacs 26.1) but not on my secondary machine (Windows 8, Emacs 26.1)
  • When current loses/regains focus (by executing eval-expression), the child window resizes.

Koekelas avatar Jul 15 '18 10:07 Koekelas

Switch anothet WM, and try again, maybe gnome problem

tumashu avatar Jul 15 '18 10:07 tumashu

I tried your suggestion inside a VM. I can't reproduce this on KDE Neon (KDE/KWin). I also tried Fedora Workstation (GNOME/Mutter), both the Wayland and the X.Org session. I can reproduce it on Fedora. So, something GNOME specific.

Koekelas avatar Jul 16 '18 19:07 Koekelas

Same here on GNOME 3.28.2, Emacs 26.1.

0x3UH4224D avatar Aug 11 '18 05:08 0x3UH4224D

Seems like I'm experiencing the same issue: image

andreyorst avatar Jun 03 '19 05:06 andreyorst

Related bug: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1733

nicber avatar Sep 30 '19 14:09 nicber

I'm also seeing this problem.

@tumashu GNOME is the most popular Linux DE. Shouldn't we do something?

If it's the problem in how child frame is implemented, could you file an Emacs bug report with a reproduction scenario that our windowing subsystem devs can understand?

dgutov avatar Dec 14 '19 20:12 dgutov

Some questions to help debug this problem with Emacs developers:

  1. Is everybody seeing this problem using GNOME?
  2. Is everybody using Mutter as the WM, or somebody with Metacity as well?
  3. Does anyone with this problem have a non-HiDPI (i.e. normal resolution) monitor?

dgutov avatar Jan 18 '20 12:01 dgutov

1,2: This is Gnome only Mutter problem, the bug was reported several month ago, see: https://gitlab.gnome.org/GNOME/mutter/issues/840 3: happens for me both on non-HiDPI and on HiDPI

andreyorst avatar Jan 18 '20 12:01 andreyorst

Thanks. Martin asked whether this happens on GNOME + Metacity as well.

dgutov avatar Jan 18 '20 13:01 dgutov

GNOME with Mutter on a non HiDPI display.

Koekelas avatar Jan 18 '20 14:01 Koekelas

I'm not sure if Gnome + Metacity even exist as of today. The closest thing is Mate, a fork of Gnome2, which is using Metacity fork of theirs and it didn't had this problem when I've tested.

Thanks. Martin asked whether this happens on GNOME + Metacity as well.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/tumashu/company-posframe/issues/2?email_source=notifications&email_token=AEUROTYOMJFGXQT5E2VPYQTQ6L5PXA5CNFSM4FJFZ6BKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEJJX4DY#issuecomment-575897103, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEUROTZ7DYP6HYVP7O4ULCDQ6L5PXANCNFSM4FJFZ6BA .

andreyorst avatar Jan 18 '20 19:01 andreyorst

Here's a workaround for y'all to try:

--- posframe.el	2019-12-16 00:37:59.392804886 +0300
+++ posframe.el	2020-01-20 15:59:50.981671559 +0300
@@ -627,13 +627,19 @@
   (if (and width height)
       (unless (equal posframe--last-posframe-size
                      (list height min-height width min-width))
-        (fit-frame-to-buffer
+        (posframe--fit-to-buffer
          posframe height min-height width min-width)
         (setq-local posframe--last-posframe-size
                     (list height min-height width min-width)))
-    (fit-frame-to-buffer
+    (posframe--fit-to-buffer
      posframe height min-height width min-width)))
 
+(defun posframe--fit-to-buffer (frame height min-height width min-width)
+  ;; GNOME Mutter workaround
+  (make-frame-invisible frame)
+  (fit-frame-to-buffer frame height min-height width min-width)
+  (make-frame-visible frame))
+
 (defun posframe--set-frame-position (posframe position
                                               parent-frame-width
                                               parent-frame-height)

I still get hellish flickering (particularly noticeable if you lean on M-n), but now much faster, and with correct resizing.

dgutov avatar Jan 20 '20 13:01 dgutov

BTW, if there's someone here who can build and debug Mutter, please speak up.

dgutov avatar Jan 20 '20 13:01 dgutov

And here's a better workaround: just build Emacs with a different toolkit.

./configure --with-x-toolkit=lucid gives me posframe that's much faster, resizes correctly even without the visibility hack above, and where flickering is basically non-existent (at least in company-posframe; ivy-posframe still has some).

dgutov avatar Jan 20 '20 22:01 dgutov

And if you have tool-bar-mode turned off, you'll likely see no practical difference.

dgutov avatar Jan 20 '20 22:01 dgutov

I have tested lucid, frame show and hide or frame move seem to very slow.

tumashu avatar Jan 21 '20 01:01 tumashu

Compared to... GTK?

dgutov avatar Jan 21 '20 02:01 dgutov

can confirm that it is quite slow, but it certainly works with lucid. Except if slideshow experience can be described as works

andreyorst avatar Jan 21 '20 08:01 andreyorst

That's surprising. The Lucid build is really very fast here (GNOME 3.32.1, GTK 3.24.8). You can also try Motif, I'm seeing similar experience.

As for the GTK build, @andreyorst have you tried the workaround I posted above?

dgutov avatar Jan 21 '20 11:01 dgutov

As for the GTK build, @andreyorst have you tried the workaround I posted above?

No, sorry for that! I'm not using company-posframe, I'm here from the https://github.com/casouri/eldoc-box package, which has the same issue with resizing child frames but doesn't use posframe inside.

andreyorst avatar Jan 21 '20 12:01 andreyorst

Then you can try the same approach by toggling visibility before and after the set-frame-size call in eldoc-box--update-childframe-geometry. It might actually work okay, if the eldoc box isn't shown persistently.

dgutov avatar Jan 21 '20 12:01 dgutov

Speaking of performance under Lucid, etc, it would be helpful if you and/or others posted some measuremenets.

There is an example here: https://lists.gnu.org/archive/html/emacs-devel/2020-01/msg00343.html

If you add (benchmark 10 '(resize-test test-frame)) at the bottom, what's the result?

dgutov avatar Jan 21 '20 13:01 dgutov

@dgutov

Today, I test lucid again, and find the slow may posn-at-point

(benchmark 1000 '(posn-at-point (point)))

"Elapsed time: 0.684959s"

this let posframe slow when first show posframe

         (parent-window-height (window-pixel-height parent-window))
         (position-info
          (if (integerp position)
              (posn-at-point position parent-window)
            position))
         (parent-frame (window-frame parent-window))

tumashu avatar Jan 22 '20 07:01 tumashu

@tumashu Why do you consider that slow? Do you call post-at-point more than once per action?

The same form returns 0.72s for me using a GTK build anyway.

dgutov avatar Jan 22 '20 10:01 dgutov

@dgutov I use pyim (an input method) to test posframe, and find that posn-at-point let posframe ~half second lag

tumashu avatar Jan 22 '20 11:01 tumashu

But how? If 1000 calls of posn-a-point takes 0.684, then 1 call is just 0.0006 seconds.

dgutov avatar Jan 22 '20 11:01 dgutov

I don't understand too, maybe posn-at-point let emacs lock half second? or posn-at-point+input let emacs lock?

tumashu avatar Jan 22 '20 11:01 tumashu

Frame creation is not cheap, so maybe it just lags while the child frame is created the first time?

dgutov avatar Jan 22 '20 11:01 dgutov

It is not frame creation's problem,

tumashu avatar Jan 22 '20 11:01 tumashu

When I replace posframe's posn-at-point to a variable test, then I setq test a proper value, lucid have no lags. so I think it is posn-at-point's problem,

but posn-at-point's speed seem to normal..... :-(

tumashu avatar Jan 22 '20 11:01 tumashu

Could it be that the first call to posn-at-point is slow? Or that it's slow only in certain circumstances?

dgutov avatar Jan 22 '20 12:01 dgutov

BTW, if you have a specific scenario I could test, I'd try it.

So far I've only tried Lucid with company-posframe, and that looked really snappy. Or, and with ivy-posframe too.

dgutov avatar Jan 22 '20 12:01 dgutov

Okay, so we reproduced where Lucid is slow (repositioning the frame).

Can you guys try a gtk2 build? Meaning --with-x-toolkit=gtk2. It seems to work fine to me in both respects.

dgutov avatar Jan 31 '20 22:01 dgutov

I thought this was a problem with my config for so long, but just today realized it worked on my laptop (ChromeOS/crostini) and not on my Gnome desktop.

This bug causes issues in ivy-posframe and other posframe like packages, but building with GTK2 seems to fix the issue. Thanks!

Perhaps make this information more widely available, since Gnome is such a popular desktop environment.

AlexLewandowski avatar Feb 15 '20 09:02 AlexLewandowski

@AlexLewandowski We're still working on the best solution.

Could some people here provide additional testing for the patch in https://lists.gnu.org/archive/html/emacs-devel/2020-03/msg00092.html? You're supposed to check out the latest emacs-27 branch, apply the patch on top of it, and build either with lucid or gtk3.

In my testing, it both fixes the childframe resizing in GTK3 builds (to be in line with GTK2), and makes childframe repositioning faster in Lucid builds. But we need more feedback if we want to include it, or a version of it, in the upcoming Emacs 27 release.

dgutov avatar Mar 13 '20 13:03 dgutov

Is it compatible with Emacs-28 branch?

andreyorst avatar Mar 13 '20 14:03 andreyorst

Could be. I haven't tried.

dgutov avatar Mar 13 '20 15:03 dgutov

I've tried this patch with eglot-box and this package and it lags quite heavily but the size is always correct.

It's like sets the wrong size first, then sets the correct one half a second after.

andreyorst avatar Mar 13 '20 15:03 andreyorst

It's possible that eglot-box is doing something wrong, too.

Was the lagging present before the patch as well?

dgutov avatar Mar 13 '20 15:03 dgutov

And: which toolkit are you testing with? GTK3?

If you can, please also verify the behavior of the emacs-27 branch. It would be too bad if we flag the patch as troublesome just because of something that was pushed to master recently.

dgutov avatar Mar 13 '20 15:03 dgutov

It's possible that eglot-box is doing something wrong, too.

Was the lagging present before the patch as well?

before patch it was not changing size, so there was nothing to lag. I mean the lag happens this way:

eldoc-box shows it's child frame, which is too small or too big, then it changes size somewhat half a second later to correct one.

The very same thing happens with company-posframe, it shows initially wrong sized child-frame, then resizes it after short, but noticeable delay.

andreyorst avatar Mar 13 '20 15:03 andreyorst

The very same thing happens with company-posframe, it shows initially wrong sized child-frame, then resizes it after short, but noticeable delay.

I see that too, but, like, once per session. Do you see it more often?

dgutov avatar Mar 13 '20 15:03 dgutov

for company-posframe it is noticeable when size jumps to fit some pretty long candidate, which happens quite often with Rust completions, and with eldoc-box I can see it on every size change, e.g. when poking around with mouse over the code. I will record a video later.

And: which toolkit are you testing with? GTK3?

sorry, forgot to mention, I'm using GTK3. As for Emacs 27 branch, I'm currently in process of building, so will report a bit later.

andreyorst avatar Mar 13 '20 15:03 andreyorst

I don't know, it seems kinda a bit faster, but the lag in size change is still noticeable on Emacs-27 branch. It's usable though

andreyorst avatar Mar 13 '20 16:03 andreyorst

What if you also set x-wait-for-event-timeout to 0 like the message suggests?

dgutov avatar Mar 13 '20 16:03 dgutov

A video would be helpful, yes.

dgutov avatar Mar 13 '20 16:03 dgutov

What if you also set x-wait-for-event-timeout to 0 like the message suggests?

I've missed that part. It's much faster, but still noticeable, although I can live with it.

andreyorst avatar Mar 13 '20 16:03 andreyorst

So, to sum up:

  • the patch is an improvement (with no noticeable regressions)
  • emacs-27 behaves better than master
  • setting x-wait-for-event-timeout to 0 eliminates a visual delay

Is that right?

If you still can make a video of the lag, that would be also great.

dgutov avatar Mar 13 '20 16:03 dgutov

I'll try to record it in two hours or tomorrow. Everything else you've listed seems correct by me

andreyorst avatar Mar 13 '20 16:03 andreyorst

@dgutov I just tried the patch on emacs 27.0.90 and gtk3, it seems to work very well!

AlexLewandowski avatar Mar 14 '20 01:03 AlexLewandowski

@dgutov After several days of using this patch I think that everything is very good. No issues so far. The lag also gone for some reason.

andreyorst avatar Mar 16 '20 10:03 andreyorst

Good news everyone!

Emacs 27 will include a new variable called x-gtk-resize-child-frames: https://git.savannah.gnu.org/cgit/emacs.git/commit/?h=emacs-27&id=c49d379f17bcb0ce82604def2eaa04bda00bd5ec

It's sort of a stopgap, but apparently GNOME requires special handling that is not compatible with some other DEs/WMs.

So GNOME users with GTK3 builds should set this new variable to either resize-mode and restart (better behavior but not future-compatible) or hide (which is more future-proof but will blink the child frame every time it's resized).

In other news, the Lucid build should be at least as fast now (or faster) WRT to child frames. So using basically any other build than GTK3 is also a good workaround.

dgutov avatar Apr 06 '20 17:04 dgutov

@tumashu Will you add that info to README? Here, and/or in the main posframe repo.

dgutov avatar Apr 06 '20 17:04 dgutov

This is great news! I think @casouri will be interested in adding this info to README as well

IIUC @dgutov patch was merged and available on master right now?

andreyorst avatar Apr 06 '20 18:04 andreyorst

It's in the release branch now. Should be merged to master in a few days or so.

dgutov avatar Apr 06 '20 18:04 dgutov

Good, I'll add it to eldoc-box's readme.

casouri avatar Apr 06 '20 18:04 casouri

@dgutov Info has been added, thanks very very very much for your and Martin Rudalics hard word, if no your long disscuss and coding, this problem can not be resolved.

tumashu avatar Apr 07 '20 01:04 tumashu

@tumashu IIUC, Mate users don't need to do this. Otherwise, the instructions look good, thanks.

dgutov avatar Apr 07 '20 13:04 dgutov

By the way, we could try to automate this.

@andreyorst Could you check the output of echo $XDG_CURRENT_DESKTOP when inside a Mate session? Does it also say GNOME?

dgutov avatar Apr 07 '20 13:04 dgutov

By the way, we could try to automate this.

@andreyorst Could you check the output of echo $XDG_CURRENT_DESKTOP when inside a Mate session? Does it also say GNOME?

Unlikely. Unfortunately I don't use Mate, I'm on GNOME. I'll ask colleague to check, but IDK when he'll respond.

andreyorst avatar Apr 07 '20 14:04 andreyorst

@dgutov I have not test it by myself, but MATE is gnome2,its wm may very similar with gnome3's vm, so it may have similar problem too.

tumashu avatar Apr 07 '20 23:04 tumashu

According to @andreyorst it's using Metacity, a different window manager, and it doesn't have this problem: https://github.com/tumashu/company-posframe/issues/2#issuecomment-575932620

dgutov avatar Apr 07 '20 23:04 dgutov

OK, I will remove MATE info

tumashu avatar Apr 08 '20 00:04 tumashu

@dgutov After x-gtk-resize-child-frames set, we must restart emacs ?

tumashu avatar Apr 08 '20 00:04 tumashu

You actually need to just create a new child frame (the resize-mode value only affects new child frames).

Anyway, please wait a little for my PR. I think we really can automate this, to make it easier for a lot of users.

dgutov avatar Apr 08 '20 00:04 dgutov

ok

tumashu avatar Apr 08 '20 01:04 tumashu

@andreyorst

If possible, please also ask a colleague to try this:

(let ((id (x-window-property "_NET_SUPPORTING_WM_CHECK" nil "WINDOW" 0 nil t)))
  (x-window-property "_NET_WM_NAME" nil "UTF8_STRING" id nil))

Which is a method we might choose to switch to in the future.

dgutov avatar Apr 08 '20 10:04 dgutov

@andreyorst

If possible, please also ask a colleague to try this:

(let ((id (x-window-property "_NET_SUPPORTING_WM_CHECK" nil "WINDOW" 0 nil t)))
  (x-window-property "_NET_WM_NAME" nil "UTF8_STRING" id nil))

Which is a method we might choose to switch to in the future.

unfortunately he's working from home right now using his Mac, so he can't access mate right now. He's not Emacs user, so I can't help with that test much.

andreyorst avatar Apr 08 '20 11:04 andreyorst

That's ok, thanks.

dgutov avatar Apr 08 '20 11:04 dgutov

it prints MATE

вт, 7 апр. 2020 г., 16:43 Dmitry Gutov [email protected]:

By the way, we could try to automate this.

@andreyorst https://github.com/andreyorst Could you check the output of echo $XDG_CURRENT_DESKTOP when inside a Mate session? Does it also say GNOME?

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/tumashu/company-posframe/issues/2#issuecomment-610394815, or unsubscribe https://github.com/notifications/unsubscribe-auth/AEUROT7OWIHSXAGNTU3LQ7DRLMUZJANCNFSM4FJFZ6BA .

andreyorst avatar Apr 09 '20 18:04 andreyorst

Thank you. Then the current solution in posframe should work all right.

dgutov avatar Apr 09 '20 19:04 dgutov

It seems that changes finally hit the master branch and I no longer need to patch my build! Gonna say that everything works great on GNOME now.

andreyorst avatar Apr 16 '20 14:04 andreyorst