Skip to content

Commit 50d9ca8

Browse files
committed
Fix display refresh (fixes #139)
1 parent ec15170 commit 50d9ca8

File tree

3 files changed

+63
-37
lines changed

3 files changed

+63
-37
lines changed

azul/src/app.rs

+44-28
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,14 @@ impl<T> App<T> {
485485
// If there is a re-render necessary, re-render *all* windows
486486
if should_rerender_all_windows {
487487
for (current_window_id, mut window) in self.windows.iter_mut() {
488+
// TODO: For some reason this function has to be called twice in order
489+
// to actually update the screen. For some reason the first swap_buffers() has
490+
// no effect (winit bug?)
491+
rerender_single_window(
492+
&self.config,
493+
&mut window,
494+
&mut self.app_state.resources,
495+
);
488496
rerender_single_window(
489497
&self.config,
490498
&mut window,
@@ -675,7 +683,7 @@ fn hit_test_single_window<T>(
675683
new_focus_target: None,
676684
};
677685

678-
if events.is_empty() || !ret.should_relayout() {
686+
if events.is_empty() && !ret.should_relayout() && !ret.should_rerender() {
679687
// Event was not a resize event, window should **not** close
680688
ret.window_should_close = window_should_close;
681689
return Ok(ret);
@@ -721,7 +729,7 @@ fn hit_test_single_window<T>(
721729

722730
// Scroll for the scrolled amount for each node that registered a scroll state.
723731
let should_scroll_render = match &ret.hit_test_results {
724-
Some(hit_test_results) => update_scroll_state(window, hit_test_results, &mut app_state.resources),
732+
Some(hit_test_results) => update_scroll_state(window, hit_test_results),
725733
None => false,
726734
};
727735

@@ -826,10 +834,11 @@ fn hot_reload_css<T>(
826834
windows: &mut BTreeMap<GliumWindowId, Window<T>>,
827835
last_style_reload: &mut Instant,
828836
should_print_error: &mut bool,
829-
awakened_tasks: &mut BTreeMap<GliumWindowId, bool>)
830-
-> Result<(), RuntimeError<T>>
831-
{
837+
awakened_tasks: &mut BTreeMap<GliumWindowId, bool>,
838+
) -> Result<(), RuntimeError<T>> {
839+
832840
use self::RuntimeError::*;
841+
833842
for (window_id, window) in windows.iter_mut() {
834843
// Hot-reload a style if necessary
835844
let hot_reloader = match window.css_loader.as_mut() {
@@ -914,8 +923,8 @@ fn call_callbacks<T>(
914923
window_id: &GliumWindowId,
915924
ui_state: &UiState<T>,
916925
app_state: &mut AppState<T>)
917-
-> Result<CallCallbackReturn, RuntimeError<T>>
918-
{
926+
-> Result<CallCallbackReturn, RuntimeError<T>> {
927+
919928
use {
920929
callbacks::CallbackInfo,
921930
window_state::{KeyboardState, MouseState},
@@ -1102,7 +1111,6 @@ fn convert_window_size(size: &WindowSize) -> (LayoutSize, DeviceIntSize) {
11021111
fn update_scroll_state<T>(
11031112
window: &mut Window<T>,
11041113
hit_test_results: &HitTestResult,
1105-
app_resources: &mut AppResources,
11061114
) -> bool {
11071115

11081116
const SCROLL_THRESHOLD: f64 = 0.5; // px
@@ -1271,7 +1279,7 @@ fn render_inner<T>(
12711279
gl_context.draw_buffers(&[gl::COLOR_ATTACHMENT0]);
12721280

12731281
// Check that the framebuffer is complete
1274-
assert_eq!(gl_context.check_frame_buffer_status(gl::FRAMEBUFFER), gl::FRAMEBUFFER_COMPLETE);
1282+
debug_assert!(gl_context.check_frame_buffer_status(gl::FRAMEBUFFER) == gl::FRAMEBUFFER_COMPLETE);
12751283

12761284
// Invoke WebRender to render the frame - renders to the currently bound FB
12771285
gl_context.clear_color(background_color_f.r, background_color_f.g, background_color_f.b, background_color_f.a);
@@ -1290,8 +1298,7 @@ fn render_inner<T>(
12901298
// FBOs can't be shared between windows, but textures can.
12911299
// In order to draw on the windows backbuffer, first make the window current, then draw to FB 0
12921300
window.display.gl_window().make_current().unwrap();
1293-
let window_context = get_gl_context(&window.display).unwrap();
1294-
draw_texture_to_screen(&*window_context, textures[0], framebuffer_size);
1301+
draw_texture_to_screen(&*gl_context, textures[0], framebuffer_size);
12951302
window.display.swap_buffers().unwrap();
12961303

12971304
app_resources.fake_display.hidden_display.gl_window().make_current().unwrap();
@@ -1355,36 +1362,43 @@ fn compile_screen_shader(context: &Gl) -> GLuint {
13551362
let vertex_shader_object = context.create_shader(gl::VERTEX_SHADER);
13561363
context.shader_source(vertex_shader_object, &[DISPLAY_VERTEX_SHADER]);
13571364
context.compile_shader(vertex_shader_object);
1358-
if get_gl_shader_error(context, vertex_shader_object) {
1359-
let err = context.get_shader_info_log(vertex_shader_object);
1360-
context.delete_shader(vertex_shader_object);
1361-
panic!("VS compile error: {}", err);
1365+
1366+
#[cfg(debug_assertions)] {
1367+
if get_gl_shader_error(context, vertex_shader_object) {
1368+
let err = context.get_shader_info_log(vertex_shader_object);
1369+
context.delete_shader(vertex_shader_object);
1370+
panic!("VS compile error: {}", err);
1371+
}
13621372
}
13631373

13641374
let fragment_shader_object = context.create_shader(gl::FRAGMENT_SHADER);
13651375
context.shader_source(fragment_shader_object, &[DISPLAY_FRAGMENT_SHADER]);
13661376
context.compile_shader(fragment_shader_object);
1367-
if get_gl_shader_error(context, fragment_shader_object) {
1368-
let err = context.get_shader_info_log(fragment_shader_object);
1369-
context.delete_shader(vertex_shader_object);
1370-
context.delete_shader(fragment_shader_object);
1371-
panic!("FS compile error: {}", err);
1377+
1378+
#[cfg(debug_assertions)] {
1379+
if get_gl_shader_error(context, fragment_shader_object) {
1380+
let err = context.get_shader_info_log(fragment_shader_object);
1381+
context.delete_shader(vertex_shader_object);
1382+
context.delete_shader(fragment_shader_object);
1383+
panic!("FS compile error: {}", err);
1384+
}
13721385
}
13731386

13741387
let program = context.create_program();
13751388
context.attach_shader(program, vertex_shader_object);
13761389
context.attach_shader(program, fragment_shader_object);
13771390
context.link_program(program);
1378-
if get_gl_program_error(context, program) {
1379-
let err = context.get_program_info_log(program);
1380-
context.delete_shader(vertex_shader_object);
1381-
context.delete_shader(fragment_shader_object);
1382-
context.delete_program(program);
1383-
panic!("Program link error: {}", err);
1391+
1392+
#[cfg(debug_assertions)] {
1393+
if get_gl_program_error(context, program) {
1394+
let err = context.get_program_info_log(program);
1395+
context.delete_shader(vertex_shader_object);
1396+
context.delete_shader(fragment_shader_object);
1397+
context.delete_program(program);
1398+
panic!("Program link error: {}", err);
1399+
}
13841400
}
13851401

1386-
// context.detach_shader(program, vertex_shader_object);
1387-
// context.detach_shader(program, fragment_shader_object);
13881402
context.delete_shader(vertex_shader_object);
13891403
context.delete_shader(fragment_shader_object);
13901404

@@ -1394,12 +1408,14 @@ fn compile_screen_shader(context: &Gl) -> GLuint {
13941408
}
13951409

13961410
// Returns true on error, false otherwise
1411+
#[cfg(debug_assertions)]
13971412
fn get_gl_shader_error(context: &Gl, shader_object: GLuint) -> bool {
13981413
let mut err = [0];
13991414
unsafe { context.get_shader_iv(shader_object, gl::COMPILE_STATUS, &mut err) };
14001415
err[0] == 0
14011416
}
14021417

1418+
#[cfg(debug_assertions)]
14031419
fn get_gl_program_error(context: &Gl, shader_object: GLuint) -> bool {
14041420
let mut err = [0];
14051421
unsafe { context.get_program_iv(shader_object, gl::LINK_STATUS, &mut err) };

azul/src/window_state.rs

+13-9
Original file line numberDiff line numberDiff line change
@@ -536,15 +536,6 @@ impl WindowState
536536
insert_callbacks!(node_id, None, focus_callbacks, focus_default_callbacks, current_focus_leave_events, Focus);
537537
}
538538

539-
// If the mouse is down, but was up previously or vice versa, that means
540-
// that a :hover or :active state may be invalidated. In that case we need
541-
// to redraw the screen anyways. Setting relayout to true here in order to
542-
let event_is_click_or_release = self.internal.mouse_state.mouse_down() != previous_state.internal.mouse_state.mouse_down();
543-
if event_is_click_or_release || event_was_mouse_enter || event_was_mouse_leave {
544-
needs_hover_redraw = true;
545-
needs_hover_relayout = true;
546-
}
547-
548539
macro_rules! mouse_enter {
549540
($node_id:expr, $hit_test_item:expr, $event_filter:ident) => ({
550541

@@ -617,6 +608,8 @@ impl WindowState
617608
.map(|(x, y)| (*x, y.clone()))
618609
.collect();
619610

611+
let onmouseenter_empty = onmouseenter_nodes.is_empty();
612+
620613
// Insert Focus(MouseEnter) and Hover(MouseEnter)
621614
for (node_id, hit_test_item) in onmouseenter_nodes {
622615
mouse_enter!(node_id, hit_test_item, MouseEnter);
@@ -628,11 +621,22 @@ impl WindowState
628621
.map(|(x, y)| (*x, y.clone()))
629622
.collect();
630623

624+
let onmouseleave_empty = onmouseleave_nodes.is_empty();
625+
631626
// Insert Focus(MouseEnter) and Hover(MouseEnter)
632627
for (node_id, hit_test_item) in onmouseleave_nodes {
633628
mouse_enter!(node_id, hit_test_item, MouseLeave);
634629
}
635630

631+
// If the mouse is down, but was up previously or vice versa, that means
632+
// that a :hover or :active state may be invalidated. In that case we need
633+
// to redraw the screen anyways. Setting relayout to true here in order to
634+
let event_is_click_or_release = self.internal.mouse_state.mouse_down() != previous_state.internal.mouse_state.mouse_down();
635+
if event_is_click_or_release || event_was_mouse_enter || event_was_mouse_leave || !onmouseenter_empty || !onmouseleave_empty {
636+
needs_hover_redraw = true;
637+
needs_hover_relayout = true;
638+
}
639+
636640
// Insert all Not-callbacks, we need to filter out all Hover and Focus callbacks
637641
// and then look at what callbacks were currently
638642

examples/calculator/calculator.rs

+6
Original file line numberDiff line numberDiff line change
@@ -401,5 +401,11 @@ fn main() {
401401
app.add_font(font_id, FontSource::Embedded(FONT));
402402

403403
let window = app.create_window(WindowCreateOptions::default(), css.clone()).unwrap();
404+
let window2 = app.create_window(WindowCreateOptions::default(), css.clone()).unwrap();
405+
let window3 = app.create_window(WindowCreateOptions::default(), css.clone()).unwrap();
406+
let window4 = app.create_window(WindowCreateOptions::default(), css.clone()).unwrap();
407+
app.add_window(window2);
408+
app.add_window(window3);
409+
app.add_window(window4);
404410
app.run(window).unwrap();
405411
}

0 commit comments

Comments
 (0)