Skip to content

DrawHandler<DrawingArea>::get_context() triggers an extra draw event, causing a feedback loop #129

Open
@semitangential

Description

@semitangential

Description:
Calling DrawHandler<DrawingArea>::get_context() seems to trigger an extra draw event. Using it in the event handler, as in the drawing.rs example, causes a feedback loop where each draw event triggers a new one.

An example showing the issue is given below.

Setup:

  • Use nightly Rust
  • cargo init --bin relmissue
  • Replace main.rs with the code given below.
  • Add dependencies to Cargo.toml:
[dependencies]
gtk = "0.4.1"
relm = { git = "https://github.com/antoyo/relm.git", rev = "541e1dcac24101abbae39cbaa46456ea12c0b985"}
relm-attributes = { git = "https://github.com/antoyo/relm.git", rev = "541e1dcac24101abbae39cbaa46456ea12c0b985"}
relm-derive = { git = "https://github.com/antoyo/relm.git", rev = "541e1dcac24101abbae39cbaa46456ea12c0b985"}

Running the example:

  • cargo run
    Observed behavior: "Updating UpdateDrawBuffer" is printed many times per second.
    Expected behavior: "Updating UpdateDrawBuffer" should be printed only when the widget needs to be repainted, for instance when the window is resized.

Tweaking the example:

  • Change the constant TRIGGER_INFINITE_EVENTS to false, to disable the call to DrawHandler<DrawingArea>::get_context().
  • cargo run
    Observed and expected behavior: "Updating UpdateDrawBuffer" is printed only when the widget needs to be repainted, for instance when the window is resized.

Example code (main.rs):

#![feature(use_extern_macros)]

extern crate gtk;
#[macro_use]
extern crate relm;
extern crate relm_attributes;
#[macro_use]
extern crate relm_derive;

use std::time::SystemTime;
use gtk::{
    DrawingArea,
    Inhibit,
    WidgetExt,
};
use relm::{
    DrawHandler,
    Widget,
};
use relm_attributes::widget;
use self::Msg::*;

const TRIGGER_INFINITE_EVENTS : bool = true;

pub struct Model {
    draw_handler: DrawHandler<DrawingArea>,
}

#[derive(Msg, Debug)]
pub enum Msg {
    UpdateDrawBuffer,
}

#[widget]
impl Widget for Win {
    fn init_view(&mut self) {
        self.model.draw_handler.init(&self.drawing_area);
    }

    fn model() -> Model {
        Model {
            draw_handler: DrawHandler::new().unwrap(),
        }
    }

    fn update(&mut self, event: Msg) {
        println!("{:?} Updating {:?}", SystemTime::now(), event);
        if(TRIGGER_INFINITE_EVENTS){
            let _ = self.model.draw_handler.get_context();
        }
    }

    view! {
        gtk::Window {
            #[name="drawing_area"]
            gtk::DrawingArea {
                draw(_, _) => (UpdateDrawBuffer, Inhibit(false)),
            },
        }
    }
}

fn main() {
    Win::run(()).unwrap();
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions