Skip to content
55 changes: 51 additions & 4 deletions druid-shell/src/platform/gtk/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use cairo::Surface;
use gdk::{EventKey, EventMask, ModifierType, ScrollDirection, WindowExt, WindowTypeHint};
use gio::ApplicationExt;
use gtk::prelude::*;
use gtk::{AccelGroup, ApplicationWindow, DrawingArea, SettingsExt};
use gtk::{AccelGroup, ApplicationWindow, ContainerExt, DrawingArea, SettingsExt};
use tracing::{error, warn};

#[cfg(feature = "raw-win-handle")]
Expand Down Expand Up @@ -177,6 +177,9 @@ pub(crate) struct WindowState {
click_counter: ClickCounter,
active_text_input: Cell<Option<TextFieldToken>>,
deferred_queue: RefCell<Vec<DeferredOp>>,

request_animation: Cell<bool>,
in_draw: Cell<bool>,
}

#[derive(Clone, PartialEq)]
Expand Down Expand Up @@ -296,6 +299,8 @@ impl WindowBuilder {
click_counter: ClickCounter::default(),
active_text_input: Cell::new(None),
deferred_queue: RefCell::new(Vec::new()),
request_animation: Cell::new(false),
in_draw: Cell::new(false),
});

self.app
Expand Down Expand Up @@ -361,6 +366,33 @@ impl WindowBuilder {
);
}

win_state
.drawing_area
.connect_realize(clone!(handle => move |drawing_area| {
if let Some(clock) = drawing_area.get_frame_clock() {
clock.connect_before_paint(clone!(handle => move |_clock|{
if let Some(state) = handle.state.upgrade() {
state.in_draw.set(true);
}
}));
clock.connect_after_paint(clone!(handle => move |_clock|{
if let Some(state) = handle.state.upgrade() {
state.in_draw.set(false);
if state.request_animation.get() {
state.request_animation.set(false);
let vbox = state.window.get_children().first().unwrap().clone()
.downcast::<gtk::Box>()
.unwrap();
let first_child = vbox.get_children().last().unwrap().clone();
if first_child.is::<gtk::DrawingArea>() {
first_child.queue_draw();
}
}
}
}));
}
}));

win_state.drawing_area.connect_draw(clone!(handle => move |widget, context| {
if let Some(state) = handle.state.upgrade() {
let mut scale = state.scale.get();
Expand Down Expand Up @@ -780,7 +812,22 @@ impl WindowState {
/// Queues a call to `prepare_paint` and `paint`, but without marking any region for
/// invalidation.
fn request_anim_frame(&self) {
self.window.queue_draw();
if self.in_draw.get() {
self.request_animation.set(true);
} else {
let vbox = &self
.window
.get_children()
.first()
.unwrap()
.clone()
.downcast::<gtk::Box>()
.unwrap();
let first_child = vbox.get_children().last().unwrap().clone();
if first_child.is::<gtk::DrawingArea>() {
first_child.queue_draw();
}
}
}

/// Invalidates a rectangle, given in display points.
Expand Down Expand Up @@ -1165,10 +1212,10 @@ impl WindowHandle {
.downcast::<gtk::Box>()
.unwrap();

let first_child = &vbox.get_children()[0];
let first_child = vbox.get_children().first().unwrap().clone();
if let Some(old_menubar) = first_child.downcast_ref::<gtk::MenuBar>() {
old_menubar.deactivate();
vbox.remove(first_child);
vbox.remove(old_menubar);
}
let menubar = menu.into_gtk_menubar(self, &accel_group);
vbox.pack_start(&menubar, false, false, 0);
Expand Down