From 9e513f2255b3ceead46efa93bc2a443fad7eee58 Mon Sep 17 00:00:00 2001 From: Leopold Luley Date: Mon, 13 Apr 2020 23:15:46 +0200 Subject: [PATCH 1/3] Ignore nested events in GTK shell --- druid-shell/src/platform/gtk/window.rs | 140 +++++++++++++------------ 1 file changed, 72 insertions(+), 68 deletions(-) diff --git a/druid-shell/src/platform/gtk/window.rs b/druid-shell/src/platform/gtk/window.rs index 6020129692..380d1321fb 100644 --- a/druid-shell/src/platform/gtk/window.rs +++ b/druid-shell/src/platform/gtk/window.rs @@ -279,15 +279,16 @@ impl WindowBuilder { drawing_area.connect_button_press_event(clone!(handle => move |_widget, button| { if let Some(state) = handle.state.upgrade() { - - state.handler.borrow_mut().mouse_down( - &MouseEvent { - pos: Point::from(button.get_position()), - count: get_mouse_click_count(button.get_event_type()), - mods: get_modifiers(button.get_state()), - button: get_mouse_button(button.get_button()), - }, - ); + if let Ok(mut handler) = state.handler.try_borrow_mut() { + handler.mouse_down( + &MouseEvent { + pos: Point::from(button.get_position()), + count: get_mouse_click_count(button.get_event_type()), + mods: get_modifiers(button.get_state()), + button: get_mouse_button(button.get_button()), + }, + ); + } } Inhibit(true) @@ -295,15 +296,16 @@ impl WindowBuilder { drawing_area.connect_button_release_event(clone!(handle => move |_widget, button| { if let Some(state) = handle.state.upgrade() { - - state.handler.borrow_mut().mouse_up( - &MouseEvent { - pos: Point::from(button.get_position()), - mods: get_modifiers(button.get_state()), - count: 0, - button: get_mouse_button(button.get_button()), - }, - ); + if let Ok(mut handler) = state.handler.try_borrow_mut() { + handler.mouse_up( + &MouseEvent { + pos: Point::from(button.get_position()), + mods: get_modifiers(button.get_state()), + count: 0, + button: get_mouse_button(button.get_button()), + }, + ); + } } Inhibit(true) @@ -320,10 +322,9 @@ impl WindowBuilder { button: get_mouse_button_from_modifiers(motion.get_state()), }; - state - .handler - .borrow_mut() - .mouse_move(&mouse_event); + if let Ok(mut handler) = state.handler.try_borrow_mut() { + handler.mouse_move(&mouse_event); + } } Inhibit(true) @@ -340,10 +341,9 @@ impl WindowBuilder { button: get_mouse_button_from_modifiers(crossing.get_state()), }; - state - .handler - .borrow_mut() - .mouse_move(&mouse_event); + if let Ok(mut handler) = state.handler.try_borrow_mut() { + handler.mouse_move(&mouse_event); + } } Inhibit(true) @@ -351,49 +351,50 @@ impl WindowBuilder { drawing_area.connect_scroll_event(clone!(handle => move |_widget, scroll| { if let Some(state) = handle.state.upgrade() { - - let modifiers = get_modifiers(scroll.get_state()); - - // The magic "120"s are from Microsoft's documentation for WM_MOUSEWHEEL. - // They claim that one "tick" on a scroll wheel should be 120 units. - let mut handler = state.handler.borrow_mut(); - match scroll.get_direction() { - ScrollDirection::Up => { - if modifiers.shift { + if let Ok(mut handler) = state.handler.try_borrow_mut() { + + let modifiers = get_modifiers(scroll.get_state()); + + // The magic "120"s are from Microsoft's documentation for WM_MOUSEWHEEL. + // They claim that one "tick" on a scroll wheel should be 120 units. + match scroll.get_direction() { + ScrollDirection::Up => { + if modifiers.shift { + handler.wheel(Vec2::from((-120.0, 0.0)), modifiers); + } else { + handler.wheel(Vec2::from((0.0, -120.0)), modifiers); + } + } + ScrollDirection::Down => { + if modifiers.shift { + handler.wheel(Vec2::from((120.0, 0.0)), modifiers); + } else { + handler.wheel(Vec2::from((0.0, 120.0)), modifiers); + } + } + ScrollDirection::Left => { handler.wheel(Vec2::from((-120.0, 0.0)), modifiers); - } else { - handler.wheel(Vec2::from((0.0, -120.0)), modifiers); } - } - ScrollDirection::Down => { - if modifiers.shift { + ScrollDirection::Right => { handler.wheel(Vec2::from((120.0, 0.0)), modifiers); - } else { - handler.wheel(Vec2::from((0.0, 120.0)), modifiers); } - } - ScrollDirection::Left => { - handler.wheel(Vec2::from((-120.0, 0.0)), modifiers); - } - ScrollDirection::Right => { - handler.wheel(Vec2::from((120.0, 0.0)), modifiers); - } - ScrollDirection::Smooth => { - //TODO: Look at how gtk's scroll containers implements it - let (mut delta_x, mut delta_y) = scroll.get_delta(); - delta_x *= 120.; - delta_y *= 120.; - if modifiers.shift { - delta_x += delta_y; - delta_y = 0.; + ScrollDirection::Smooth => { + //TODO: Look at how gtk's scroll containers implements it + let (mut delta_x, mut delta_y) = scroll.get_delta(); + delta_x *= 120.; + delta_y *= 120.; + if modifiers.shift { + delta_x += delta_y; + delta_y = 0.; + } + handler.wheel(Vec2::from((delta_x, delta_y)), modifiers) + } + e => { + eprintln!( + "Warning: the Druid widget got some whacky scroll direction {:?}", + e + ); } - handler.wheel(Vec2::from((delta_x, delta_y)), modifiers) - } - e => { - eprintln!( - "Warning: the Druid widget got some whacky scroll direction {:?}", - e - ); } } } @@ -409,8 +410,9 @@ impl WindowBuilder { *current_keyval = Some(key.get_keyval()); - let key_event = make_key_event(key, repeat); - state.handler.borrow_mut().key_down(key_event); + if let Ok(mut handler) = state.handler.try_borrow_mut() { + handler.key_down(make_key_event(key, repeat)); + } } Inhibit(true) @@ -421,8 +423,9 @@ impl WindowBuilder { *(state.current_keyval.borrow_mut()) = None; - let key_event = make_key_event(key, false); - state.handler.borrow_mut().key_up(key_event); + if let Ok(mut handler) = state.handler.try_borrow_mut() { + handler.key_down(make_key_event(key, false)); + } } Inhibit(true) @@ -616,6 +619,7 @@ impl WindowHandle { window.add_accel_group(&accel_group); let menu = menu.into_gtk_menu(&self, &accel_group); + menu.set_property_attach_widget(Some(window)); menu.show_all(); menu.popup_easy(3, gtk::get_current_event_time()); } From 546c78c5a1fb91282c95e8230be5ce7045f6a04b Mon Sep 17 00:00:00 2001 From: Leopold Luley Date: Tue, 14 Apr 2020 12:22:55 +0200 Subject: [PATCH 2/3] Log when skipping GTK event --- druid-shell/src/platform/gtk/window.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/druid-shell/src/platform/gtk/window.rs b/druid-shell/src/platform/gtk/window.rs index 380d1321fb..d3938af992 100644 --- a/druid-shell/src/platform/gtk/window.rs +++ b/druid-shell/src/platform/gtk/window.rs @@ -44,6 +44,7 @@ use crate::keyboard; use crate::mouse::{Cursor, MouseButton, MouseEvent}; use crate::window::{IdleToken, Text, TimerToken, WinHandler}; use crate::Error; +use log::{info, warn}; /// Taken from https://gtk-rs.org/docs-src/tutorial/closures /// It is used to reduce the boilerplate of setting up gtk callbacks @@ -270,6 +271,8 @@ impl WindowBuilder { if anim { widget.queue_draw(); } + } else { + warn!("Drawing was skipped because the handler was already borrowed"); } } @@ -288,6 +291,8 @@ impl WindowBuilder { button: get_mouse_button(button.get_button()), }, ); + } else { + info!("GTK event was dropped because the handler was already borrowed"); } } @@ -305,6 +310,8 @@ impl WindowBuilder { button: get_mouse_button(button.get_button()), }, ); + } else { + info!("GTK event was dropped because the handler was already borrowed"); } } @@ -324,6 +331,8 @@ impl WindowBuilder { if let Ok(mut handler) = state.handler.try_borrow_mut() { handler.mouse_move(&mouse_event); + } else { + info!("GTK event was dropped because the handler was already borrowed"); } } @@ -343,6 +352,8 @@ impl WindowBuilder { if let Ok(mut handler) = state.handler.try_borrow_mut() { handler.mouse_move(&mouse_event); + } else { + info!("GTK event was dropped because the handler was already borrowed"); } } @@ -396,6 +407,8 @@ impl WindowBuilder { ); } } + } else { + info!("GTK event was dropped because the handler was already borrowed"); } } @@ -412,6 +425,8 @@ impl WindowBuilder { if let Ok(mut handler) = state.handler.try_borrow_mut() { handler.key_down(make_key_event(key, repeat)); + } else { + info!("GTK event was dropped because the handler was already borrowed"); } } @@ -425,6 +440,8 @@ impl WindowBuilder { if let Ok(mut handler) = state.handler.try_borrow_mut() { handler.key_down(make_key_event(key, false)); + } else { + info!("GTK event was dropped because the handler was already borrowed"); } } @@ -482,7 +499,7 @@ impl WindowHandle { /// Bring this window to the front of the window stack and give it focus. pub fn bring_to_front_and_focus(&self) { //FIXME: implementation goes here - log::warn!("bring_to_front_and_focus not yet implemented for gtk"); + warn!("bring_to_front_and_focus not yet implemented for gtk"); } // Request invalidation of the entire window contents. @@ -504,7 +521,7 @@ impl WindowHandle { let interval = match u32::try_from(interval) { Ok(iv) => iv, Err(_) => { - log::warn!("timer duration exceeds gtk max of 2^32 millis"); + warn!("timer duration exceeds gtk max of 2^32 millis"); u32::max_value() } }; From b9e8809db4124c092221f2cc5df5c03cd1b9df12 Mon Sep 17 00:00:00 2001 From: Leopold Luley Date: Tue, 14 Apr 2020 12:42:18 +0200 Subject: [PATCH 3/3] Fix key_up and use full path for log functions --- druid-shell/src/platform/gtk/window.rs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/druid-shell/src/platform/gtk/window.rs b/druid-shell/src/platform/gtk/window.rs index d3938af992..bf726979cb 100644 --- a/druid-shell/src/platform/gtk/window.rs +++ b/druid-shell/src/platform/gtk/window.rs @@ -44,7 +44,6 @@ use crate::keyboard; use crate::mouse::{Cursor, MouseButton, MouseEvent}; use crate::window::{IdleToken, Text, TimerToken, WinHandler}; use crate::Error; -use log::{info, warn}; /// Taken from https://gtk-rs.org/docs-src/tutorial/closures /// It is used to reduce the boilerplate of setting up gtk callbacks @@ -272,7 +271,7 @@ impl WindowBuilder { widget.queue_draw(); } } else { - warn!("Drawing was skipped because the handler was already borrowed"); + log::warn!("Drawing was skipped because the handler was already borrowed"); } } @@ -292,7 +291,7 @@ impl WindowBuilder { }, ); } else { - info!("GTK event was dropped because the handler was already borrowed"); + log::info!("GTK event was dropped because the handler was already borrowed"); } } @@ -311,7 +310,7 @@ impl WindowBuilder { }, ); } else { - info!("GTK event was dropped because the handler was already borrowed"); + log::info!("GTK event was dropped because the handler was already borrowed"); } } @@ -332,7 +331,7 @@ impl WindowBuilder { if let Ok(mut handler) = state.handler.try_borrow_mut() { handler.mouse_move(&mouse_event); } else { - info!("GTK event was dropped because the handler was already borrowed"); + log::info!("GTK event was dropped because the handler was already borrowed"); } } @@ -353,7 +352,7 @@ impl WindowBuilder { if let Ok(mut handler) = state.handler.try_borrow_mut() { handler.mouse_move(&mouse_event); } else { - info!("GTK event was dropped because the handler was already borrowed"); + log::info!("GTK event was dropped because the handler was already borrowed"); } } @@ -408,7 +407,7 @@ impl WindowBuilder { } } } else { - info!("GTK event was dropped because the handler was already borrowed"); + log::info!("GTK event was dropped because the handler was already borrowed"); } } @@ -426,7 +425,7 @@ impl WindowBuilder { if let Ok(mut handler) = state.handler.try_borrow_mut() { handler.key_down(make_key_event(key, repeat)); } else { - info!("GTK event was dropped because the handler was already borrowed"); + log::info!("GTK event was dropped because the handler was already borrowed"); } } @@ -439,9 +438,9 @@ impl WindowBuilder { *(state.current_keyval.borrow_mut()) = None; if let Ok(mut handler) = state.handler.try_borrow_mut() { - handler.key_down(make_key_event(key, false)); + handler.key_up(make_key_event(key, false)); } else { - info!("GTK event was dropped because the handler was already borrowed"); + log::info!("GTK event was dropped because the handler was already borrowed"); } } @@ -499,7 +498,7 @@ impl WindowHandle { /// Bring this window to the front of the window stack and give it focus. pub fn bring_to_front_and_focus(&self) { //FIXME: implementation goes here - warn!("bring_to_front_and_focus not yet implemented for gtk"); + log::warn!("bring_to_front_and_focus not yet implemented for gtk"); } // Request invalidation of the entire window contents. @@ -521,7 +520,7 @@ impl WindowHandle { let interval = match u32::try_from(interval) { Ok(iv) => iv, Err(_) => { - warn!("timer duration exceeds gtk max of 2^32 millis"); + log::warn!("timer duration exceeds gtk max of 2^32 millis"); u32::max_value() } };