Skip to content

Operations do not redraw #3029

@Exidex

Description

@Exidex

Is your issue REALLY a bug?

  • My issue is indeed a bug!
  • I am not crazy! I will not fill out this form just to ask a question or request a feature. Pinky promise.

Is there an existing issue for this?

  • I have searched the existing issues.

Is this issue related to iced?

  • My hardware is compatible and my graphics drivers are up-to-date.

What happened?

Operations do not redraw by themselves, and rely on external events to do so. It is problematic when operation is executed inside task

Reproduction:
Press Enter -> view is not redrawn
Move mouse -> view is redrawn

Cargo.toml

[package]
name = "iced_ops_do_not_redraw"
version = "0.1.0"
edition = "2024"

[dependencies]
iced = { git = "https://github.com/iced-rs/iced.git", branch = "master", features = ["advanced"] }

src/main.rs

use iced::advanced::widget;
use iced::advanced::widget::operation::Outcome;
use iced::advanced::widget::{operate, Operation};
use iced::keyboard::key::{Code, Physical};
use iced::widget::scrollable::{scroll_by, AbsoluteOffset};
use iced::widget::{scrollable, text};
use iced::{event, keyboard, Element, Event, Length, Rectangle, Subscription, Task};

pub fn main() -> iced::Result {
    iced::application(App::default, App::update, App::view)
        .subscription(App::subscription)
        .run()
}

struct App {
    scrollable: scrollable::Id,
}

impl Default for App {
    fn default() -> Self {
        Self {
            scrollable: scrollable::Id::unique(),
        }
    }
}

#[derive(Debug, Clone)]
enum Message {
    Move,
}

impl App {
    fn update(&mut self, message: Message) -> Task<Message> {
        match message {
            Message::Move => {
                let id = self.scrollable.clone();
                operate(DummyOp).then(move |_| {
                    scroll_by(
                        id.clone(),
                        AbsoluteOffset { x: 0.0, y: 1500.0 },
                    )
                })
            },
        }
    }

    fn view(&self) -> Element<Message> {
        let content = text("At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio.".repeat(100));

        scrollable(content)
            .id(self.scrollable.clone())
            .height(Length::Fill)
            .width(Length::Fill)
            .into()
    }

    fn subscription(&self) -> Subscription<Message> {
        event::listen_with(|event, _status, _id| {
            let Event::Keyboard(event) = event else {
                return None;
            };

            let keyboard::Event::KeyPressed { physical_key, .. } = event else {
                return None;
            };

            let Physical::Code(Code::Enter) = physical_key else {
                return None;
            };

            Some(Message::Move)
        })
    }
}

struct DummyOp;
impl Operation<()> for DummyOp {
    fn container(
        &mut self,
        _id: Option<&widget::Id>,
        _bounds: Rectangle,
        operate_on_children: &mut dyn FnMut(&mut dyn Operation<()>),
    ) {
        operate_on_children(self);
    }

    fn finish(&self) -> Outcome<()> {
        Outcome::Some(())
    }
}

What is the expected behavior?

Operations redraw

Version

master

Operating System

Linux

Do you have any log output?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions