#1567 Display is flashing when scrolling with Gtk+ 3

Bug
closed-fixed
nobody
5
2014-05-22
2014-01-05
No

The way drawing is handled has changed between Gtk+ 2 and Gtk+ 3. Scintilla is good with Gtk+ 2 but quite bad using Gtk+ 3.

One annoying point is the display flashing when the window is redrawn. It's especially annoying when moving in the text using the cursor keys.

Related

Bugs: #1625
Bugs: #1681

Discussion

  • This patch fix the issue. It keeps the double buffering and keep the default draw function of the GtkContainer that will draw both scroll bars and the text view.

     
    • Neil Hodgson
      Neil Hodgson
      2014-01-05

      Scintilla has its own double buffering which avoids flashing http://www.scintilla.org/ScintillaDoc.html#SCI_SETBUFFEREDDRAW

      GTK+ 3 has replaced the expose_event callback with the draw callback.
      https://developer.gnome.org/gtk3/stable/ch24s02.html#id-1.6.3.4.11
      Trying to revert to the GTK+ 2 model will just cause version compatibility pain.

      If you can avoid flashing with Scintilla's buffering turned off while still using the draw event then that would be good but unconditionally reverting to expose_event is not forward-looking.

       
      • The patch doesn't switch back to ::expose-event (it just doesn't exist anymore in GTK3), what it does is not override GtkContainer's ::draw handler, and let the default implementation kick in (IIUC) -- plus enable GTK's double buffering on GTK3 indeed.

        I believe removing the manual ::draw handler is probably correct, and there shouldn't be much need to manually propagate redraws since the default GtkContainer action is to propagate the draw to all children. Though, I must note that for some reason ScintillaGTK::DrawThis doesn't propagate to the text area.

         
        • Neil Hodgson
          Neil Hodgson
          2014-01-05

          OK, I misread the patch.

           
  • Activating double buffering seems to break the initial draw in Geany, not sure why. Subsequent draws seem OK.

     
    • I wasn't aware that Geany uses Gtk+3 but that's good. I have just compiled Geany (--enable-gtk3) with my patch and it looks fine.

      What's happen? the text windows is blank (or gray) when you open Geany? Which version of Gtk are you using. I have 3.9.15 here.

       
      • I wasn't aware that Geany uses Gtk+3 but that's good.

        Yeah GTK3 support in Geany is not yet released.

        What's happen? the text windows is blank (or gray) when you open Geany?

        Yes, the Scintilla area is blank (so, gray). The line with the caret becomes drawn as soon as the caret blinks, but the rest remains blank until it gets invalidated (scroll, areas under other windows, etc. -- just as you expect draws to happen). Attached is a screenshot right at startup (just after the cursor blinked).

        Which version of Gtk are you using. I have 3.9.15 here.

        3.8.6 (Debian Sid). Also note that I don't use a compositing WM (Metacity), if it may have any incidence.

         
        • I have tried with gtk 3.8.6 but I haven't get this issue, The Scintilla area is correctly redrawn even on the first one.

          But on the other hand my patch doesn't fix the flashing of the window.

          Could you try with a more recent version of Gtk?

           
          • I just tested with 3.11.4 (latest Git actually) and indeed it seems to work. Very strange.

            I also tried with the Adwaita theme from my distro, and although the theme is quite broken with 3.11.4, drawing works. Similarly, I tried disabling the theme with 3.8.6 and it didn't fix it, so it's not theme-related.

             
    • Neil Hodgson
      Neil Hodgson
      2014-01-06

      Also seeing no initial draw in SciTE with File | New leaving menu debris. This is on Mint 16 Mate with GTK+ 3.8.7.

       
      • Thank, I will try to reproduce it here, I have mint 13 at the moment.

         
        • Neil Hodgson
          Neil Hodgson
          2014-01-06

          One possibility is that the redraw requested for the new buffer is being abandoned or is ineffective. SciTE reuses the Scintilla instance for the new empty document but your application may create a new instance for each document. Tracing all calls for Redraw/RedrawRect/AbandonPaint along with the draw callback may help find the problem.

           
  • By the way, I must say I do not experience flickering in Geany with GTK3. I do not know if it is because of decent hardware or something, but it's worth noting that this issue isn't affecting me.

     
  • I have tried on OpenSuse 13.1 (Gtk 3.10.4) and my patch works fine and fix a flickering in both Anjuta and Geany. I will reproduce the missing redraw.

     
  • I have tried in a virtual machine running Mint 16. It seems that it doesn't flicker but the patch doesn't break anything.

     
    • Neil Hodgson
      Neil Hodgson
      2014-02-02

      When you say "doesn't break anything", does SciTE redraw correctly for you?

       
      • yes

         
  • The flickering is not always obvious, it's easier to see it when the system is loaded. By example under valgrind, loading a big file with syntax highlight, visible whitespace, end of line and line numbers, and scrolling with the down cursor key.

     
  • I have more explanations about this.

    In GTK3, there is a change in the drawing model. Now Widgets can be transparent which means that they are drawn on top of the other starting from the parent widget (=from back to front). By default a double buffer is used so all these operations don't appear on the screen.

    Each widget can have a GdkWindow or not and this GdkWindow can be "native" or not. I think a "native" window is one handled by the windows manager. Most of the time only the top widget has a native GdkWindow. So it get the expose event and call the draw function of all its children in order.

    • Why it flicker?

    Scintilla uses two windows: the top window with a custom draw function which doesn't draw the text window. And the text window which has its own GdkWindow but not a native one.

    I think the new version of GTK draws first the top window overwriting all the text area with a gray background and then call the draw function of the text widget to display the right content.

    • Why nothing is displayed when double_buffer is kept enable on the text window?

    There is some code in gtkmain.c which discards expose event on double buffered, non native window which is the case of the text window. That's why in my patch, I need to remove the custom draw function.

    There is a note, which appear in the version 3.10 of Gtk documentation, saying that gtk_widget_set_double_buffer works only on native window. Indeed we see that doing this lead to a flickering window.

    So, another way to fix this flickering is to call gdk_window_ensure_native in the realize callback of the text widget. In this case both the top and the text window are handled by the window manager who is taking care of not overwriting the text area with the top window background.

    I can provide a patch for that but I don't think it's the right solution. It's still not the common way to draw widget and the documentation mentions that some backend cannot support child native window which is our case.

    I still don't know why my patch breaks on some system. Based on this, it looks right. As I cannot reproduce it here, it's difficult to know what's happen. I guess that it can be a bug in older versions of GTK. Perhaps with those explanations you can understand the issue better than me.

    I will send a new patch drawing the text window in the custom draw function of the Scintilla window. It should work fine on my system and perhaps could fix the issue in the other cases.

     
  • Here is a new patch, keeping the custom draw function of the Scintilla widget. Could you check if it's working on your system?

    If yes, it probably means that there was a bug in the draw function of GtkContainer.

     
    • Neil Hodgson
      Neil Hodgson
      2014-02-04

      With this patch, I am seeing this effect where the scrollbars aren't being redrawn in SciTE after File | New. This occurs both in a VM and when used on a bare-machine install.
      Corrupted scrollbars
      This is a different appearance to earlier experiments with the original patch where I think the damage was to the text area. Trying to return to patch 1 now shows the same effect as the image. Perhaps I am misremembering or its a redraw propagation bug where which element is affected is determined by something not yet revealed like exposure order or similar.

      This system was last updated at start of January, although nothing in the system update queue appears related.

       
    • Doesn't work either here in Geany sorry (still GTK 3.8).

       
  • I have tried again in a virtual machine using mint 16 mate 64 bits but I still don't see the issue. The drawing is fine with and without my patch.

    I have looked at Gtk+ source code and indeed there is a difference between version 3.8.x and 3.9.x
    https://git.gnome.org/browse/gtk+/commit/gtk/gtkmain.c?id=d22fd7223c75f4720ddb982c659efb0d8d7543c4

    In the version 3.9, the draw signal is not called for double buffered non native window, this is why I need to call DrawText in the draw function of the Scintilla Widget.

    But on older version, the draw signal is called even for non native window. So with my patch the draw function of the text area is called two times: one time in the expose event of the text window and another time in the expose event of the scintilla window. It explains why it's working without my patch and perhaps it can explain the issue you see even if it's not clear.

    So, I can modify my patch to change something only with GTK 3.9 or greater.

     
  • Here is a patch that remove the redundant call to the draw function on older version of Gtk. Could you check if it makes a difference?

    There are other changes in Gtk around the one on the expose event. So it's quite possible that the issue is caused by something else but that's an easy check.

    If it doesn't work, I think I can remove the double buffering only on Gtk starting from version 3.9.2. It should fix the issue without breaking something. Could you check with gtk 3.9.2 or greater that the patch is working?

     
    • Neil Hodgson
      Neil Hodgson
      2014-02-11

      I don't have any GTK+ installations later the 3.8.x - I always wait for mainstream distributions before updating GTK+ as I spent far too much time in Scintilla's early days struggling with pre-release versions of GTK+.

      The scrollbar issue shown above is still occurring with this patch but I'm willing to ignore this (and stick with GTK+ 2.x as SciTE's default) if other downstreams prefer the patch. If Geany is made to work OK with the patch then I'll accept it. Otherwise it'll mean a #if choice between the two paths, which is a maintenance and documentation hassle.

       
    • I still don't get the initial draw in Geany with this (GTK 3.8).

       
      Last edit: Colomban Wendling 2014-02-17
      • OK, I just tried gtk3_avoid_flickering_2.patch with a compositing WM (mutter), and it worked. So I guess it's the difference between your tests and ours, you using a compositing WM that caches all draws in textures, and us using a non-compositing WM and then need draws when the X server wants them.

        Maybe your could try on your side with a non-compositing WM?

         
        Last edit: Colomban Wendling 2014-02-17
        • I have tried with a virtual machine using Mint 16 but indeed the virtual machine is run in a compositing WM so it could explain the difference.

          I will try without a compositing WM but not before next week.

           
      • OK, my distro updated from 3.8 to 3.10.7 and with this version your patches seem to work OK.

         
        Last edit: Colomban Wendling 2014-02-17
      • Ah, and now I have GTK 3.10.7, I do see some flickering without the patch, with and without a compositing WM (tho I see it most without).

        I'll check a bit more in the upcoming days.

         
        Last edit: Colomban Wendling 2014-02-17
  • That's fine for me. I can keep this patch in Anjuta tree anyway.

    I still don't know why I don't see the issue here.

     
    • Neil Hodgson
      Neil Hodgson
      2014-02-14

      The most likely reason for the different results appears to me to be a version skew somewhere in libraries, window managers, or theme. Possibly display driver issues.

      Since there are different results, there may be more people experiencing the reported problem or who will experience it in the future as GTK+ 3 becomes more common. It may be worthwhile including a version of your change in the main repository with an #if around it. That would make it easier for you (or others) to track Scintilla changing. If others report similar issues to you then we can suggest turning on the #if.

       
  • Nils Nordman
    Nils Nordman
    2014-04-22

    I just crashed into this today, after upgrading to Ubuntu 14.04. Previous Gtk+-3 version as shipped with 13.10 was fine, but with the latest (3.10.8) it's all flickering all over the place. Applying "check_on_gtk_3_8.patch" removed the flickering here. I haven't tried the patch with any older version to see whether it works fine there as well though.

     
  • Nils Nordman
    Nils Nordman
    2014-04-22

    Some more data points: Problem is the same in latest Arch (Gtk 3.10*), and the last patch fixes it there as well as could be expected. Also tried the patch out on an old 11.10 release of Ubuntu (Gtk 3.2.0), and it worked fine for me, I didn't see anything amiss during my testing. I'll carry the patch in-tree for now (Thanks Sébastien!), but I would definitely like to see it or a version thereof in Scintilla. Even though the issue summary describes it as being an annoyance, it seems a show-stopper to me. The flickering is so bad as to make my editor unusable, at least on my system.

     
  • @nilnor although the "check_on_gtk_3_8" patch somewhat lowers the visiblity of the issue (why, really not sure), it does NOT fix it. Also, apparently compositing WMs lower (or nullify) the visibility of the issues, so please also try disabling the compositing.

    But I agree with you, this is not simply "annoying", it pretty much renders Scintilla unusable on GTK3, because all this flickering kills the eyes in no time. Fortunately we (Geany) still have support for GTK2, so I went temporarily back to using the GTK2 version before finding a real solution for this problem. Now I have some time, I'll try to sum up problems and possible solutions in a mail to the ML in the next days.

     
  • Proposed patch to fix the issue. It is kind of ugly as it extends the clip manually, but it allows to perform the whole draw in one single shot, avoiding any flickering possibility. It also uses the container draw propagation from one of the patches here, as required to avoid the normal, non-re-scheduling, case.

    As noted in the patch header, this should be better tested on older GTK3 to add or remove version checks. I guess they could be removed, but testing is better than guessing.

     
  • Neil Hodgson
    Neil Hodgson
    2014-04-22

    There are also drawing problems with GTK+ 2 on Ubuntu 14.04 using it inside VirtualBox. Also seeing some similar bugs in FireFox although not as often.

    Resetting the clip does appear a little strong. It seems that GTK+ has changed to try to optimize drawing and it would be better, if possible, to cooperate with this change.

    Scintilla uses a high priority idle function to perform some work before painting and I am wondering if this is interacting badly with drawing. I may try disabling it.

     
    • Well, "cooperating" would mean to always paint the whole invalidated area, since now it forcefully clears it (which kind of makes sense from its POV).

      So yes, I agree it would be the best solution, but it may require some deeper changes (or maybe I miss something obvious, I'm not much knowledgeable about Scintilla rendering internals).

      (BTW, I guess that the change in GTK is rather to ease support for in-window popovers than solely optimization, even though it indeed can help)


      And I can imagine we have some small rendering problems on GTK versions that honor the single buffering, as then we can suffer from the classic single-buffering problems, that is that an unfinished paint can reach the display. I'm not sure how the drawing code works for this never to have been an issue, but I guess it could still be visible on sufficiently slow hardware.

       
  • Neil Hodgson
    Neil Hodgson
    2014-05-22

    • labels: --> scintilla, gtk
    • status: open --> closed-fixed