From 4e499810a5f21d54a96f70e034dc5224099ef5a4 Mon Sep 17 00:00:00 2001 From: Jehan Date: Tue, 27 Aug 2024 17:10:28 +0200 Subject: [PATCH] Issue #11957: also ignore events when switching to MWM. This is a follow-up of commit c5db158f58, where the flickering issue was happening when creating new windows when already in multi-window mode. I had the same issue again when I had several tabs opened in SWM and switched to MWM. Then it would undraw displays to move them to their own window. In the short time when this occurs, we don't want to process events. So now I changed the "drawn" status when undrawing ("unrealize" event) a shell. I also changed the implementation of gimp_displays_accept_focus_events(). What we need is to check the active shell only of each window. In SWM in particular, it is normal that non-visible tab shells get unrealized. --- app/display/gimpdisplay-foreach.c | 26 +++++++++++++++----------- app/display/gimpdisplayshell.c | 5 +++++ 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/app/display/gimpdisplay-foreach.c b/app/display/gimpdisplay-foreach.c index 401f861c95..6675e85d1d 100644 --- a/app/display/gimpdisplay-foreach.c +++ b/app/display/gimpdisplay-foreach.c @@ -32,6 +32,7 @@ #include "gimpdisplay-foreach.h" #include "gimpdisplayshell.h" #include "gimpdisplayshell-cursor.h" +#include "gimpimagewindow.h" gboolean @@ -314,31 +315,34 @@ gimp_displays_unset_busy (Gimp *gimp) * When this returns %FALSE, we should ignore focus events. In * particular, I had weird cases in multi-window mode, before a new * image window was actually displayed on screen, there seemed to be - * infinite loops of focus events switching the active display between + * infinite loops of focus events switching the active window between * the current active one and the one being created, with flickering * window title and the new display never actually displayed until we * broke the loop by manually getting out of focus (see #11957). * This is why when any of the display is not fully drawn yet (which - * usually means it is being created), we temporarily ignore focus - * events on all displays. + * may mean it is either being created or moved to a new window), we + * temporarily ignore focus events on all displays. */ gboolean gimp_displays_accept_focus_events (Gimp *gimp) { - GList *list; + GList *windows; + gboolean accept = TRUE; g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE); - for (list = gimp_get_display_iter (gimp); - list; - list = g_list_next (list)) + windows = gimp_get_image_windows (gimp); + for (GList *iter = windows; iter; iter = iter->next) { - GimpDisplay *display = list->data; - GimpDisplayShell *shell = gimp_display_get_shell (display); + GimpDisplayShell *shell = gimp_image_window_get_active_shell (iter->data); if (! gimp_display_shell_is_drawn (shell)) - return FALSE; + { + accept = FALSE; + break; + } } + g_list_free (windows); - return TRUE; + return accept; } diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index 0831421a7b..3f70920a06 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -1045,6 +1045,11 @@ gimp_display_shell_unrealize (GtkWidget *widget) gtk_widget_unrealize (shell->nav_popup); GTK_WIDGET_CLASS (parent_class)->unrealize (widget); + + shell->drawn = FALSE; + g_signal_connect (shell, "draw", + G_CALLBACK (gimp_display_shell_draw), + NULL); } static void