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:
Tested on Lubuntu 20.10 with g++ 10.3.0 and wxWidgets 3.0.5 and 3.1.5.
wxScrolled display issues on wxGTK Topic is solved
-
- Earned a small fee
- Posts: 13
- Joined: Thu Apr 22, 2021 9:23 am
Re: wxScrolled display issues on wxGTK
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?
-
- Earned a small fee
- Posts: 13
- Joined: Thu Apr 22, 2021 9:23 am
Re: wxScrolled display issues on wxGTK
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:
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?
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);
}
}
Re: wxScrolled display issues on wxGTK
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?
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?
-
- Earned a small fee
- Posts: 13
- Joined: Thu Apr 22, 2021 9:23 am
Re: wxScrolled display issues on wxGTK
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.
Re: wxScrolled display issues on wxGTK
Hi,
What theme do you use?
Can you check native GTK application if it does the same thing?
Thank you.
What theme do you use?
Can you check native GTK application if it does the same thing?
Thank you.
-
- Earned a small fee
- Posts: 13
- Joined: Thu Apr 22, 2021 9:23 am
Re: wxScrolled display issues on wxGTK
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:
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;
}
-
- Earned a small fee
- Posts: 13
- Joined: Thu Apr 22, 2021 9:23 am
Re: wxScrolled display issues on wxGTK
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.
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;
}