From 71bf522231d2998f1fb183f343c2b1f9dbcd3b15 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Mon, 11 Oct 2021 08:57:30 +0300 Subject: Gtk+ 3 UI: Don't use deprecated functions and make sure that the UI is updated regularily when holding down a key * gdk_window_freeze_toplevel_updates_libgtk_only() is apparently no longer necessary with Scintilla 5. * When holding down a key constantly, it was not uncommon that the display would not be updated until it is released. This is now worked around by using a low priority idle timer for emptying the teco_interface.event_queue. This ensures that Gtk can call other watchers after every keypress. --- src/interface-gtk/interface.c | 75 ++++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 37 deletions(-) (limited to 'src/interface-gtk/interface.c') diff --git a/src/interface-gtk/interface.c b/src/interface-gtk/interface.c index aa63276..20b1e5d 100644 --- a/src/interface-gtk/interface.c +++ b/src/interface-gtk/interface.c @@ -1108,6 +1108,39 @@ teco_interface_cmdline_size_allocate_cb(GtkWidget *widget, SCI_SETXCARETPOLICY, CARET_SLOP, allocation->width/2); } +static gboolean +teco_interface_pop_key_idle_cb(gpointer user_data) +{ + g_autoptr(GError) error = NULL; + + /* + * Avoid redraws of the current view by freezing updates + * on the view's GDK window (we're running in parallel + * to the main loop so there could be frequent redraws). + * By freezing updates, the behaviour is similar to + * the Curses UI. + */ + GdkWindow *top_window = gdk_window_get_toplevel(gtk_widget_get_window(teco_interface.window)); + gdk_window_freeze_updates(top_window); + + /* + * The event queue might be filled when pressing keys when SciTECO + * is busy executing code. + */ + g_autoptr(GdkEvent) event = g_queue_pop_head(teco_interface.event_queue); + + teco_sigint_occurred = FALSE; + teco_interface_handle_key_press(event->key.keyval, event->key.state, &error); + teco_sigint_occurred = FALSE; + + if (g_error_matches(error, TECO_ERROR, TECO_ERROR_QUIT)) + gtk_main_quit(); + + gdk_window_thaw_updates(top_window); + + return !g_queue_is_empty(teco_interface.event_queue); +} + static gboolean teco_interface_key_pressed_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data) { @@ -1149,44 +1182,12 @@ teco_interface_key_pressed_cb(GtkWidget *widget, GdkEventKey *event, gpointer us g_queue_push_tail(teco_interface.event_queue, gdk_event_copy((GdkEvent *)event)); /* - * Avoid redraws of the current view by freezing updates - * on the view's GDK window (we're running in parallel - * to the main loop so there could be frequent redraws). - * By freezing updates, the behaviour is similar to - * the Curses UI. - */ - GdkWindow *top_window = gdk_window_get_toplevel(gtk_widget_get_window(teco_interface.window)); - /* - * FIXME: A simple freeze will not suffice to prevent updates in code like . - * gdk_window_freeze_toplevel_updates_libgtk_only() is deprecated, though. - * Perhaps this hack is no longer required after upgrading Scintilla. - * - * For the time being, we just live with the expected deprecation warnings, - * although they could theoretically be suppressed using - * `#pragma GCC diagnostic ignored`. + * This should give the UI a chance to update after every keypress. + * If we would empty the event_queue in a tight loop, then keeping + * a key pressed could result in the UI beeing frozen until the + * key is eventually released. */ - //gdk_window_freeze_updates(top_window); - gdk_window_freeze_toplevel_updates_libgtk_only(top_window); - - /* - * The event queue might be filled when pressing keys when SciTECO - * is busy executing code. - */ - do { - g_autoptr(GdkEvent) event = g_queue_pop_head(teco_interface.event_queue); - - teco_sigint_occurred = FALSE; - teco_interface_handle_key_press(event->key.keyval, event->key.state, &error); - teco_sigint_occurred = FALSE; - - if (g_error_matches(error, TECO_ERROR, TECO_ERROR_QUIT)) { - gtk_main_quit(); - break; - } - } while (!g_queue_is_empty(teco_interface.event_queue)); - - gdk_window_thaw_toplevel_updates_libgtk_only(top_window); - //gdk_window_thaw_updates(top_window); + g_idle_add_full(G_PRIORITY_LOW, teco_interface_pop_key_idle_cb, NULL, NULL); return TRUE; } -- cgit v1.2.3