GTK窗口在包含GLArea和另一个组件时不能正确调整大小



我能够成功地创建一个GTK窗口,其中有一个GLArea组件。当GLArea是窗口中唯一的组件时,可以正常调整窗口的大小。

use gtk::prelude::*;
use glium::Surface;
use std::os::raw::c_void;
// This struct taken from https://github.com/PonasKovas/gtk-glium
struct GLAreaBackend {
glarea: gtk::GLArea,
}
unsafe impl glium::backend::Backend for GLAreaBackend {
fn swap_buffers(&self) -> Result<(), glium::SwapBuffersError> {
// GTK swaps the buffers after each "render" signal itself
Ok(())
}
unsafe fn get_proc_address(&self, symbol: &str) -> *const c_void {
gl_loader::get_proc_address(symbol) as *const _
}
fn get_framebuffer_dimensions(&self) -> (u32, u32) {
(self.glarea.allocated_width().try_into().unwrap(),
self.glarea.allocated_height().try_into().unwrap())
}
fn is_current(&self) -> bool {
// GTK makes it current itself on each "render" signal
true
}
unsafe fn make_current(&self) {
self.glarea.make_current();
}
}
impl GLAreaBackend {
fn new(glarea: gtk::GLArea) -> Self {
Self { glarea }
}
}
fn main() {
let application = gtk::Application::builder().build();
application.connect_activate(|app| {
let window = gtk::ApplicationWindow::builder()
.application(app)
.title("test app")
.default_width(640)
.default_height(480)
.build();
gl_loader::init_gl();
let gl_area = gtk::GLArea::builder()
.expand(true)
.halign(gtk::Align::Fill)
.valign(gtk::Align::Fill)
.auto_render(true)
.has_alpha(false)
.build();
let button = gtk::Button::with_label("press me!");
let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
container.pack_start(&gl_area, true, true, 0);
//container.pack_start(&button, false, false, 0);
window.add(&container);
window.show_all();
// from gtk-glium
let gl_context = unsafe {
glium::backend::Context::new(GLAreaBackend::new(gl_area.clone()),
true,
glium::debug::DebugCallbackBehavior::DebugMessageOnError).unwrap()
};
gl_area.connect_render(move |_, _| {
let mut frame = glium::Frame::new(gl_context.clone(), gl_context.get_framebuffer_dimensions());
frame.clear_color(1.0, 1.0, 0.5, 1.0);
frame.finish().unwrap();
Inhibit(true)
});
});
application.run();
}

正常调整后的窗口

然而,取消注释行//container.pack_start(&button, false, false, 0);会导致窗口在调整大小后不能正确渲染:

调整窗口大小

有人知道如何解决这个问题吗?

编辑:没有任何OpenGL调用,问题仍然存在。下面的简单示例也有同样的问题。我用的是Ubuntu 20.04。

use gtk::prelude::*;
fn main() {
let application = gtk::Application::builder().build();
application.connect_activate(|app| {
let window = gtk::ApplicationWindow::builder()
.application(app)
.default_width(640)
.default_height(480)
.build();
let gl_area = gtk::GLArea::builder()
.auto_render(false)
.build();
let button = gtk::Button::with_label("press me!");
let container = gtk::Box::new(gtk::Orientation::Vertical, 0);
container.pack_start(&gl_area, true, true, 0);
//container.pack_start(&button, false, false, 0);
window.add(&container);
window.show_all();
});
application.run();
}

这个问题似乎是GTK3库中的一个小错误,因为它在使用C而没有OpenGL调用时仍然存在。将我的项目升级到GTK4修复了它。

我能够在https://gitlab.gnome.org/GNOME/gtk/-/issues/1298找到解决方案,特别是注释"它在X11下使用gtk3-demo再现,而不是使用gtk4-demo.">

最新更新