Opened 21 months ago

Last modified 9 months ago

#14871 infoneeded_new defect

Overlay scrollbars can't be used with wxScrolledWindow

Reported by: michalbliznak Owned by:
Priority: normal Milestone:
Component: wxGTK Version: 3.0.0
Keywords: scroll window drawing artefact unity ubuntu Cc:
Blocked By: Blocking:
Patch: no

Description

wxScrolledWindow's area is refreshed incorrectly (there are ugly drawing artefacts in the window) when the content is scrolled by the mouse wheel or by scrollbars. The issue can be seen in scintilla editor as well in other custom windows based on wxScrolledWindow. The same application build with wxWidgets 2.9.4 works fine. Observed at least under Ubuntu 12.04 with integrated Intel graphics, Gnome-Shell DE.

Attachments (2)

drawing_issue.png download (13.8 KB) - added by michalbliznak 21 months ago.
Drawing issue in scrolled window
drawing_issue_2.png download (193.8 KB) - added by michalbliznak 21 months ago.
Patched minimal sample

Download all attachments as: .zip

Change History (30)

comment:1 Changed 21 months ago by ericj

  • Status changed from new to infoneeded_new

Do you see this in any of the wxWidgets samples? I tested the "drawing" and "stctest" sample under Mint 12 and don't see the problem.

comment:2 Changed 21 months ago by vadz

Also, if you see it in 2.9.5 but not 2.9.4, then bisecting the history to find out which revision exactly introduced the problem would be much appreciated (especially as nobody else can do it for as long as we don't know how to reproduce it).

Changed 21 months ago by michalbliznak

Drawing issue in scrolled window

comment:3 Changed 21 months ago by michalbliznak

  • Status changed from infoneeded_new to new

I can see the issue also in "drawing" sample; see the attached screenshot. The horizontal and vertical bold lines were caused by scrolling of the canvas. I guess the issue has appeared in November.

comment:4 Changed 21 months ago by pcor

I can't reproduce it either. Looking at the screenshot, it appears as if the scrollbar is being drawn on our window, instead of outside it. With the following patch, the last "gdkwindow" and "client size" outputs for each widget should match. Do they?

Index: src/gtk/window.cpp
===================================================================
--- src/gtk/window.cpp	(revision 73099)
+++ src/gtk/window.cpp	(working copy)
@@ -2830,6 +2830,7 @@
 
     if ( m_wxwindow )
     {
+        bool hasScrollbar = false;
         // if window is scrollable, account for scrollbars
         if ( GTK_IS_SCROLLED_WINDOW(m_widget) )
         {
@@ -2864,6 +2865,7 @@
                         if (gtk_adjustment_get_upper(adj) <= gtk_adjustment_get_page_size(adj))
                             continue;
                 }
+                hasScrollbar = true;
 
                 GtkRequisition req;
 #ifdef __WXGTK3__
@@ -2902,6 +2904,8 @@
             w = 0;
         if (h < 0)
             h = 0;
+        if (hasScrollbar)
+            fprintf(stderr, "%p client size %d %d\n", m_wxwindow, w, h);
     }
 
     if (width) *width = w;
Index: src/gtk/win_gtk.cpp
===================================================================
--- src/gtk/win_gtk.cpp	(revision 73099)
+++ src/gtk/win_gtk.cpp	(working copy)
@@ -83,6 +83,8 @@
         if (x != old_x || y != old_y ||
             w != gdk_window_get_width(window) || h != gdk_window_get_height(window))
         {
+            if (w != gdk_window_get_width(window) || h != gdk_window_get_height(window))
+                fprintf(stderr, "%p gdkwindow %d %d\n", widget, w, h);
             gdk_window_move_resize(window, x, y, w, h);
 
             if (border.left + border.right + border.top + border.bottom)
@@ -140,6 +142,8 @@
         if (h < 0) h = 0;
         gdk_window_move_resize(gtk_widget_get_window(widget), x, y, w, h);
     }
+    GdkWindow* window = gtk_widget_get_window(widget);
+    fprintf(stderr, "%p gdkwindow %d %d\n", widget, gdk_window_get_width(window), gdk_window_get_height(window));
 }
 
 static void pizza_show(GtkWidget* widget)

comment:5 Changed 21 months ago by michalbliznak

Here is output logged just after drawing sample start (without any interaction):

0x9900db8 client size 20 17
0x9900db8 client size 17 17
0x9900db8 client size 17 17
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900db8 client size 545 790
0x9900cb0 gdkwindow 548 793
0x9900db8 gdkwindow 548 793
0x9900d60 gdkwindow 548 20
0x9900cb0 gdkwindow 548 706
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 gdkwindow 548 706
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703
0x9900db8 client size 545 703

comment:6 Changed 21 months ago by pcor

So the sizes don't match. It really looks like the scrollbars are being drawn onto our GdkWindow. I can't believe it. Lets try another test. Can you post a screenshot of the minimal sample with the following changes?

Index: samples/minimal/minimal.cpp
===================================================================
--- samples/minimal/minimal.cpp	(revision 73126)
+++ samples/minimal/minimal.cpp	(working copy)
@@ -127,6 +127,11 @@
     // create the main application window
     MyFrame *frame = new MyFrame("Minimal wxWidgets App");
 
+    wxWindow* w = new wxWindow(frame, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE|wxHSCROLL|wxVSCROLL);
+    w->SetScrollbar(wxHORIZONTAL, 0, 10, 100);
+    w->SetScrollbar(wxVERTICAL, 0, 10, 100);
+    w->SetBackgroundColour(*wxWHITE);
+
     // and show it (the frames, unlike simple controls, are not shown when
     // created initially)
     frame->Show(true);

Changed 21 months ago by michalbliznak

Patched minimal sample

comment:7 Changed 21 months ago by pcor

I bet it's their "overlay scrollbar". Does the problem go away if you run with environment variable LIBOVERLAY_SCROLLBAR set to 0? For example,

LIBOVERLAY_SCROLLBAR=0 ./drawing

comment:8 Changed 21 months ago by michalbliznak

Yes, it solves the problem. The drawing issue has disappeared after switching off the overlay scrollbars as you suggested.

comment:9 Changed 21 months ago by PC

(In [73136]) disable Ubuntu "overlay scrollbar", see #14871

comment:10 Changed 21 months ago by ericj

I think it would be still interesting to know, why it worked with 2.9.4. Could be related to the changes that were made in #72939 or #73019

comment:11 Changed 21 months ago by vadz

  • Milestone 2.9.5 deleted
  • Status changed from new to confirmed
  • Summary changed from wxScrolledWindow is refreshed incorrectly to Overlay scrollbars can't be used with wxScrolledWindow

Yes, I'm almost sure it must have been r72939. But I didn't have time to look at why would it break it... Could someone please test that reverting it fixes the problem?

comment:12 Changed 21 months ago by pcor

Hmm, I got the source code for the overlay scrollbar and got it working on my Fedora 17 system, and I don't see any problem. There must be more to it than just the overlay scrollbar.

comment:13 follow-ups: Changed 21 months ago by vadz

  • Keywords unity ubuntu added

I do see the problem with Unity under Ubuntu 12.04 but reverting r72939 does not fix it. So we need to run a real bisection to find out when this broke, perhaps it can give us some clues... Any volunteers?

As much as I dislike the overlay scrollbars personally, not using them makes wxWidgets applications look very differently from the native ones and this is not a good thing so it would be nice to fix this.

comment:14 in reply to: ↑ 13 ; follow-up: Changed 21 months ago by pcor

Replying to vadz:

As much as I dislike the overlay scrollbars personally, not using them makes wxWidgets applications look very differently from the native ones and this is not a good thing so it would be nice to fix this.

It's not that bad. It merely puts us in such fine company as Firefox and eclipse, which, along with a dozen or so other apps, are blacklisted by the overlay scrollbar code itself.

comment:15 in reply to: ↑ 14 Changed 21 months ago by vadz

Replying to pcor:

Replying to vadz:

As much as I dislike the overlay scrollbars personally, not using them makes wxWidgets applications look very differently from the native ones and this is not a good thing so it would be nice to fix this.

It's not that bad. It merely puts us in such fine company as Firefox and eclipse

Neither are really shiny examples of native-looking UIs... wxWidgets main claim to fame is providing native LNF, we really should do better than this.

comment:16 in reply to: ↑ 13 ; follow-ups: Changed 21 months ago by dghart

Replying to vadz:

I do see the problem with Unity under Ubuntu 12.04 but reverting r72939 does not fix it. So we need to run a real bisection to find out when this broke, perhaps it can give us some clues... Any volunteers?

It turned out to be r72957.

BTW this seems to be a ubuntu 12.04 (precise) issue; I can't make it happen on 12.10 (quantal).

comment:17 in reply to: ↑ 16 Changed 21 months ago by pcor

Replying to dghart:

It turned out to be r72957.

BTW this seems to be a ubuntu 12.04 (precise) issue; I can't make it happen on 12.10 (quantal).

Ah hah. Thanks, this gave me enough info to find the problem. The 12.04 overlay scrollbar code is significantly different than the 12.10 code I had looked at and tested. The 12.04 code has lots of fingers stuck in the GTK pie, and it changes the GtkScrolledWindow "scrollbar-spacing" in such a way that we can't find out what it really is, so our client size calculation is wrong. The wxGTK2 wxDC::Clear() uses the client size to define the area it clears, so it's leaving an un-cleared strip which is later scrolled inward from the edge.

I can't think of any way to solve the client size problem, but I'm going to make a change which should fix wxDC::Clear() not clearing the whole client area.

comment:18 Changed 21 months ago by PC

(In [73185]) Get DC size from GDK window if possible, client size can unfortunately be wrong
This should fix wxDC::Clear() not clearing the whole window on Ubuntu 12.04 with overlay scrollbars
see #14871

comment:19 Changed 21 months ago by dghart

I confirm that 'drawing' now displays properly both on 12.04 and 12.10.

comment:20 Changed 21 months ago by vadz

Great, thanks Paul!

Can the problem be still seen elsewhere (the original bug report mentioned wxSTC too)?

comment:21 Changed 21 months ago by michalbliznak

The problem can be still seen if wxBufferedPaintDC is used for drawing. wxPaintDC and wxAutoBufferedPaintDC work fine.

comment:22 Changed 21 months ago by PC

(In [73231]) Use client size determined by size-allocate when possible

Our client size calculation can be wrong for reasons beyond our control,
notably on Ubuntu 12.04 with overlay scrollbars where the GtkScrolledWindow
"scrollbar-spacing" is wrong. By using the true size from size-allocate
when it becomes available, we can recover from an earlier incorrect client
size calculation. See #14871

comment:23 follow-up: Changed 21 months ago by AlecR

Does this relate to 14900 at all? Seen on Ubuntu 12.04, but reported to apply to (at least) MSW as well.

comment:24 in reply to: ↑ 23 Changed 21 months ago by pcor

  • Resolution set to fixed
  • Status changed from confirmed to closed

I think this is now fixed by r73231

comment:25 in reply to: ↑ 16 Changed 20 months ago by bartonc

Replying to dghart:

Replying to vadz:

I do see the problem with Unity under Ubuntu 12.04 but reverting r72939 does not fix it. So we need to run a real bisection to find out when this broke, perhaps it can give us some clues... Any volunteers?

It turned out to be r72957.

BTW this seems to be a ubuntu 12.04 (precise) issue; I can't make it happen on 12.10 (quantal).

'twas always broken, since unity's inception:
http://trac.wxwidgets.org/ticket/13229

comment:26 Changed 10 months ago by Aardappel

  • Priority changed from normal to critical
  • Resolution fixed deleted
  • Status changed from closed to reopened
  • Version changed from 2.9-svn to 3.0.0-rc1

This issue is still a problem in 3.0.0 RC1. It is happening in my app treesheets (.com), there's binaries and source on there if you need another example to try with.

It freezes the app upon resizing actions, with the overlay scrollbar flickering constantly. I've been having to tell my users to just turn overlay scrollbars off.

comment:27 Changed 10 months ago by vadz

  • Priority changed from critical to normal
  • Status changed from reopened to infoneeded_new

As usual, we really need a simple way of reproducing the problem (sorry but debugging your application is really not an option). Could you please try to reproduce it in a sample and attach a patch with the changes here?

If this is too difficult, please at least try debugging it, i.e. where exactly does it "freeze", which functions appear in the stack trace when this happens.

comment:28 Changed 9 months ago by vadz

  • Version changed from 3.0.0-rc1 to 3.0.0

Just changing version as these tickets are still present in 3.0.0. final.

Note: See TracTickets for help on using tickets.