首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当GTK窗口包含GLArea和其他组件时,它不能正确调整大小。

当GTK窗口包含GLArea和其他组件时,它不能正确调整大小。
EN

Stack Overflow用户
提问于 2022-06-01 21:30:18
回答 1查看 118关注 0票数 0

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

代码语言:javascript
复制
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。

代码语言:javascript
复制
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();
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-06 17:03:13

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

我在https://gitlab.gnome.org/GNOME/gtk/-/issues/1298上找到了解决方案,特别是评论“它在X11下用gtk4 3-演示复制,而不是用gtk4 4-演示”。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72468263

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档