wxScrolled display issues on wxGTK Topic is solved

Do you have a typical platform dependent issue you're battling with ? Ask it here. Make sure you mention your platform, compiler, and wxWidgets version.
Post Reply
bluesnowball18
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Apr 22, 2021 9:23 am

wxScrolled display issues on wxGTK

Post by bluesnowball18 »

On GTK+3, scrolled windows have two following issues:

1. The scrollbars don't scroll up to the end leaving some space;
2. The whole window flickers if any OnDraw or paint callback is present (which is I guess stemmed from window contents being repainted over the scrollbars).

Here is a demonstration of scrolled window sample:

Image

Tested on Lubuntu 20.10 with g++ 10.3.0 and wxWidgets 3.0.5 and 3.1.5.
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxScrolled display issues on wxGTK

Post by PB »

Looks similar to https://trac.wxwidgets.org/ticket/18462 but you would get a warning if using XIM so I guess it is not it?
bluesnowball18
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Apr 22, 2021 9:23 am

Re: wxScrolled display issues on wxGTK

Post by bluesnowball18 »

It just compiles and runs without any warnings.

What's interesting is that pure wxWindow with both scrollbars enabled looks correct and doesn't flicker:

Code: Select all

#include "Canvas.hpp"

#ifndef WX_PRECOMP
        #include "wx/dcbuffer.h"
#endif

wxBEGIN_EVENT_TABLE(Canvas, wxWindow)
        EVT_PAINT(Canvas::OnPaint)
wxEND_EVENT_TABLE()

Canvas::Canvas(wxWindow *parent)
        : wxWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL)
{
        SetBackgroundStyle(wxBG_STYLE_PAINT);

        wxImage image("image.jpg");
        image.InitAlpha();

        this->bitmap = image;

        SetScrollbar(wxHORIZONTAL, 1, 4, 10, false);
        SetScrollbar(wxVERTICAL, 1, 4, 10, false);
}

void Canvas::OnPaint(wxPaintEvent &event)
{
        if (this->bitmap.IsOk()) {
                wxAutoBufferedPaintDC dc(this);
                dc.Clear();
                dc.DrawBitmap(this->bitmap, 0, 0);
        }
}
The problem with this sample is, that on MSW the scrollbars simply won't allow to move the thumb to another position. Do you know how to fix that?
PB
Part Of The Furniture
Part Of The Furniture
Posts: 4183
Joined: Sun Jan 03, 2010 5:45 pm

Re: wxScrolled display issues on wxGTK

Post by PB »

I assume you did check that the system is not using XIM (warning is there only since 3.1.5 as you saw in the link I referenced before)?

I would rather solve the issue and use wxScrolled instead of implementing own scrolling which is not difficult but still tedious.

Anyway, for scrollbars to work, I think that you must handle the wxEVT_SCROLL* events.

BTW, do you see the issue in the scrolled sample too?
bluesnowball18
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Apr 22, 2021 9:23 am

Re: wxScrolled display issues on wxGTK

Post by bluesnowball18 »

The bug still appears in the scrolled sample even after installing and setting iBus as the default input method. I'll probably test it on the other Linux distros because LXQt may cause the problem.
ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 7449
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: wxScrolled display issues on wxGTK

Post by ONEEYEMAN »

Hi,
What theme do you use?
Can you check native GTK application if it does the same thing?

Thank you.
bluesnowball18
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Apr 22, 2021 9:23 am

Re: wxScrolled display issues on wxGTK

Post by bluesnowball18 »

Hello.
I'm using Papirus icon theme.

I've made an example of GtkScrolledWindow (which wxWidgets uses in GTK wxScrolled implementation) and it works fine:

Code: Select all

#include <gtk/gtk.h>

void activate(GtkApplication *app, gpointer user_data)
{
        GtkWidget *window = gtk_application_window_new(app);
        gtk_window_set_title(GTK_WINDOW(window), "Window");
        gtk_window_set_default_size(GTK_WINDOW(window), 200, 200);

        GtkWidget *scrolled_window = gtk_scrolled_window_new(NULL, NULL);

        GtkWidget *button = gtk_button_new();
        gtk_widget_set_size_request(button, 300, 300);

        gtk_container_add(GTK_CONTAINER(scrolled_window), button);
        gtk_container_add(GTK_CONTAINER(window), scrolled_window);

        gtk_widget_show_all(window);
}

int main(int argc, char **argv)
{
        GtkApplication *app;
        int status;

        app = gtk_application_new("org.gtk.scrolled", G_APPLICATION_FLAGS_NONE);
        g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
        status = g_application_run(G_APPLICATION(app), argc, argv);
        g_object_unref(app);

        return status;
}
Image
bluesnowball18
Earned a small fee
Earned a small fee
Posts: 13
Joined: Thu Apr 22, 2021 9:23 am

Re: wxScrolled display issues on wxGTK

Post by bluesnowball18 »

After some testing I finally found a solution.

You need to set wxALWAYS_SHOW_SB window style to make it handle scrolling correctly under LXQt and probably set GTK_OVERLAY_SCROLLING environment variable to 0 on the other Linux desktop environments to make this style work.

Code: Select all

#include "wx/wxprec.h"

#ifndef WX_PRECOMP
        #include "wx/app.h"
        #include "wx/dc.h"
        #include "wx/frame.h"
        #include "wx/scrolwin.h"
#endif

/* -----------------------------------------------------------------------------
 * MyScrolledWindow
 * -----------------------------------------------------------------------------
 */

class MyScrolledWindow : public wxScrolled<wxWindow>
{
public:
        MyScrolledWindow(wxWindow *parent);

private:
        void OnDraw(wxDC &dc) override;

        wxBitmap bmp;
};

MyScrolledWindow::MyScrolledWindow(wxWindow *parent)
        : wxScrolled<wxWindow>(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHSCROLL | wxVSCROLL | wxALWAYS_SHOW_SB)
{
        this->bmp = wxImage("image.jpg");

        SetScrollbars(4, 4, this->bmp.GetWidth() / 4, this->bmp.GetHeight() / 4, 0, 0, false);
}

void MyScrolledWindow::OnDraw(wxDC &dc)
{
        if (this->bmp.IsOk()) {
                dc.DrawBitmap(this->bmp, 0, 0);
        }
}

/* -----------------------------------------------------------------------------
 * MyFrame
 * -----------------------------------------------------------------------------
 */

class MyFrame : public wxFrame
{
public:
        MyFrame();

private:
        MyScrolledWindow *scrolwin = nullptr;
};

MyFrame::MyFrame()
        : wxFrame(nullptr, wxID_ANY, "Scrolled Window")
{
        this->scrolwin = new MyScrolledWindow(this);
}

/* -----------------------------------------------------------------------------
 * MyApp
 * -----------------------------------------------------------------------------
 */

class MyApp : public wxApp
{
        bool OnInit() override;

        MyFrame *frame = nullptr;
};

wxIMPLEMENT_APP(MyApp);

bool MyApp::OnInit()
{
        wxImage::AddHandler(new wxJPEGHandler);

        this->frame = new MyFrame();
        this->frame->Show();

        return true;
}
Image
Post Reply