Gtk-rs 在异步数据获取时使 gnomne 会话崩溃,并将其分配给按钮单击事件上的标签

问题描述

this rest api 获取异步数据并将其设置为 gtk-rs 中的标签会导致 gnome-session 崩溃。

重现:

  1. 创建一个新的货物项目
  2. 创建名为 home.svgabout.svg 的 svg 文件
  3. 创建一个名为 main.css 的 css 文件
#left_pane {
    background-color: #ff3551;
}
#left_pane button {
    background-color: transparent;
    border: none;
}

#right_pane {
    background-color: #131313;
    font-size: 20px;
}

* {
    color: white;
    padding: 0;
    margin: 0;
}
  1. 将以下依赖项放入 cargo.toml
[dependencies]
gtk = "0.9.2"
gdk = "0.13.2"
glib = "0.10.3"
gdk-pixbuf = "0.9.0"
async-std = "1.9.0"
reqwest = "0.11.2"
tokio = { version = "1.3.0",features = ["full"] }
  1. 将以下内容复制并粘贴到 main.rs
use std::ops::Deref;
use std::process::exit;
use std::rc::Rc;

use gdk_pixbuf::{Pixbuf,PixbufLoaderExt};
use gtk::{ButtonExt,ContainerExt,Cssprovider,CssproviderExt,GtkWindowExt,Image,Label,Orientation,WidgetExt,WindowType,LabelExt};
use gtk::prelude::WidgetExtManual;
use glib;
use glib::Continue;
use std::borrow::Borrow;
use std::thread::Thread;
use std::thread;

fn main() {
    gtk::init().unwrap();
    init_window();
    gtk::main();
}

fn init_css(win: &gtk::Window) {
    let css = Cssprovider::new();
    css.load_from_path("main.css").unwrap();
    let screen = win.get_screen().unwrap();
    gtk::StyleContext::add_provider_for_screen(&screen,&css,gtk::STYLE_PROVIDER_PRIORITY_APPLICATION);
}

fn init_window() {
    let win = gtk::Window::new(WindowType::Toplevel);
    init_css(&win);
    win.set_title("Youtube Tutorial");
    win.connect_destroy(|_| exit(0));
    {
        let parent = gtk::Box::new(Orientation::Horizontal,2);
        init_right_pane(&parent,init_left_pane(&parent));
        win.add(&parent);
    }
    win.show_all();
}

struct LeftPaneElements {
    home_bt: gtk::Button,about_bt: gtk::Button,}

fn init_right_pane(parent: &gtk::Box,left_pane_elements: LeftPaneElements) {
    let right_pane = Rc::new(gtk::Box::new(Orientation::Horizontal,1));
    right_pane.set_widget_name("right_pane");
    right_pane.set_hexpand(true);
    {
        let right_pane = right_pane.clone();
        left_pane_elements.home_bt.connect_clicked(move |_| {
            if let Some(s) = right_pane.get_children().get(0) {
                right_pane.remove(s);
            }
            let label = Rc::new(Label::new(Some("Home")));
            label.set_label("Fetching...");
            let (ready_tx,ready_rx) = glib::MainContext::channel(glib::PRIORITY_DEFAULT);
            tokio::runtime::Runtime::new().unwrap().block_on(async {
                println!("Thread name on async is {}",thread::current().name().unwrap_or("unkNown"));
                let str = reqwest::get("https://api.covid19api.com/summary").await.unwrap().text().await.unwrap();
                ready_tx.send(str).unwrap();
            });
            label.set_visible(true);
            right_pane.add(label.deref());
            let label = label.clone();
            ready_rx.attach(None,move |str| {
                println!("Thread name on receiving {} is {}",str,thread::current().name().unwrap_or("unkNown"));
                label.set_label(&format!(" {} ",str));
                Continue(true)
            });
        });
    }
    {
        let right_pane = right_pane.clone();
        left_pane_elements.about_bt.connect_clicked(move |_| {
            if let Some(s) = right_pane.get_children().get(0) {
                right_pane.remove(s);
            }
            let label = Label::new(Some("About"));
            label.set_visible(true);
            right_pane.add(&label);
        });
    }
    parent.add(right_pane.deref());
}

fn init_left_pane(parent: &gtk::Box) -> LeftPaneElements {
    let left_pane = gtk::Box::new(Orientation::Vertical,4);
    left_pane.set_widget_name("left_pane");
    left_pane.set_property_width_request(50);
    {
        let space = gtk::Box::new(Orientation::Vertical,0);
        space.set_vexpand(true);
        left_pane.add(&space);
    }
    let left_pane_elements = LeftPaneElements {
        home_bt: {
            let home_bt = gtk::Button::new();
            home_bt.set_image(Some(&Image::from_pixbuf(Some(&Pixbuf::from_file_at_scale("home.svg",25,true).unwrap()))));
            home_bt.set_size_request(50,50);
            left_pane.add(&home_bt);
            home_bt
        },about_bt: {
            let about_bt = gtk::Button::new();
            about_bt.set_size_request(50,50);
            about_bt.set_image(Some(&Image::from_pixbuf(Some(&Pixbuf::from_file_at_scale("about.svg",true).unwrap()))));
            left_pane.add(&about_bt);
            about_bt
        },};
    {
        let space = gtk::Box::new(Orientation::Vertical,0);
        space.set_vexpand(true);
        left_pane.add(&space);
    }
    parent.add(&left_pane);
    left_pane_elements
}
  1. 编译并运行程序
  2. 点击左侧面板中的主页按钮
  3. Gnome shell 崩溃

代码bspwmXephyr 下使用 Xephyr -br -ac -reset -softCursor -screen 1600x900 :2 运行良好。

当在行号 &str[3..10] 上使用 68 对字符串进行切片时,该错误似乎已解决。似乎是退格字符及其在开罗中的渲染问题,或者可能是合成器的问题。我想不出会话崩溃而不是应用程序崩溃的原因。

neofetch output

██████████████████  ████████   aniketfuryrocks@manjaro
██████████████████  ████████   -----------------------
██████████████████  ████████   OS: manjaro Linux x86_64
██████████████████  ████████   Host: 81BF Ideapad 520-15IKB
████████            ████████   Kernel: 5.11.2-1-manjaro
████████  ████████  ████████   Uptime: 23 mins
████████  ████████  ████████   Packages: 1468 (pacman),11 (flatpak),5 (snap)
████████  ████████  ████████   Shell: zsh 5.8
████████  ████████  ████████   Resolution: 1600x900,1920x1080
████████  ████████  ████████   DE: GNOME 3.38.3
████████  ████████  ████████   WM: Mutter
████████  ████████  ████████   WM Theme: Matcha-dark-sea
████████  ████████  ████████   Theme: Matcha-dark-sea [GTK2/3]
████████  ████████  ████████   Icons: Papirus-Dark-Maia [GTK2/3]
                               Terminal: alacritty
                               Terminal Font: black: '
                               cpu: Intel i5-8250U (8) @ 3.400GHz
                               GPU: Intel UHD Graphics 620
                               GPU: NVIDIA GeForce MX150
                               Memory: 4301MiB / 7865MiB

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)