#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

1 2 > >> (Page 1 of 2)
  • 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.

       
1 2 > >> (Page 1 of 2)