[gimp/gimp-2-8] Bug 675549 - image region does not have focus unless clicked on



commit 53d083c844f0ad81f88d6e64493160c319e519ef
Author: Michael Natterer <mitch gimp org>
Date:   Tue Apr 9 15:41:20 2013 +0200

    Bug 675549 - image region does not have focus unless clicked on
    
    We cannot simply randomy move the focus from e.g. a text entry back to
    the canvas. Instead introduce global handling of "Escape" and a
    "primary_focus_widget" that is always set the the image window's
    active canvas. When Escape is pressed, move the focus to that primary
    focus widget, or beep if it is already there. Text widgets still get
    the key events before that logic and can consume the Escape.
    (cherry picked from commit 5880685472d78cb07c0339b221e6b83e92179310)

 app/display/gimpimagewindow.c |    3 ++
 app/widgets/gimpwindow.c      |   60 ++++++++++++++++++++++++++++++++++++++--
 app/widgets/gimpwindow.h      |   10 +++++-
 3 files changed, 68 insertions(+), 5 deletions(-)
---
diff --git a/app/display/gimpimagewindow.c b/app/display/gimpimagewindow.c
index 9a4cc77..e85239f 100644
--- a/app/display/gimpimagewindow.c
+++ b/app/display/gimpimagewindow.c
@@ -1620,6 +1620,9 @@ gimp_image_window_switch_page (GtkNotebook     *notebook,
             window, shell);
   private->active_shell = shell;
 
+  gimp_window_set_primary_focus_widget (GIMP_WINDOW (window),
+                                        shell->canvas);
+
   active_display = private->active_shell->display;
 
   g_signal_connect (active_display, "notify::image",
diff --git a/app/widgets/gimpwindow.c b/app/widgets/gimpwindow.c
index 06b71f5..0cdb7ab 100644
--- a/app/widgets/gimpwindow.c
+++ b/app/widgets/gimpwindow.c
@@ -20,6 +20,7 @@
 #include "config.h"
 
 #include <gtk/gtk.h>
+#include <gdk/gdkkeysyms.h>
 
 #include "libgimpwidgets/gimpwidgets.h"
 
@@ -33,17 +34,23 @@
 #include "gimp-log.h"
 
 
+static void      gimp_window_dispose         (GObject     *object);
 static gboolean  gimp_window_key_press_event (GtkWidget   *widget,
                                               GdkEventKey *kevent);
 
 G_DEFINE_TYPE (GimpWindow, gimp_window, GTK_TYPE_WINDOW)
 
+#define parent_class gimp_window_parent_class
+
 
 static void
 gimp_window_class_init (GimpWindowClass *klass)
 {
+  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
+  object_class->dispose         = gimp_window_dispose;
+
   widget_class->key_press_event = gimp_window_key_press_event;
 }
 
@@ -52,15 +59,24 @@ gimp_window_init (GimpWindow *window)
 {
 }
 
+static void
+gimp_window_dispose (GObject *object)
+{
+  gimp_window_set_primary_focus_widget (GIMP_WINDOW (object), NULL);
+
+  G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
 static gboolean
 gimp_window_key_press_event (GtkWidget   *widget,
                              GdkEventKey *event)
 {
-  GtkWindow       *window = GTK_WINDOW (widget);
-  GtkWidget       *focus  = gtk_window_get_focus (window);
+  GimpWindow      *gimp_window = GIMP_WINDOW (widget);
+  GtkWindow       *window      = GTK_WINDOW (widget);
+  GtkWidget       *focus       = gtk_window_get_focus (window);
   GdkModifierType  accel_mods;
   gboolean         enable_mnemonics;
-  gboolean         handled = FALSE;
+  gboolean         handled     = FALSE;
 
   /* we're overriding the GtkWindow implementation here to give
    * the focus widget precedence over unmodified accelerators
@@ -79,6 +95,16 @@ gimp_window_key_press_event (GtkWidget   *widget,
                   "handled by gtk_window_propagate_key_event(text_widget)");
     }
 
+  if (event->keyval == GDK_KEY_Escape && gimp_window->primary_focus_widget)
+    {
+      if (focus != gimp_window->primary_focus_widget)
+        gtk_widget_grab_focus (gimp_window->primary_focus_widget);
+      else
+        gtk_widget_error_bell (widget);
+
+      return TRUE;
+    }
+
   accel_mods =
     gtk_widget_get_modifier_mask (widget,
                                   GDK_MODIFIER_INTENT_PRIMARY_ACCELERATOR);
@@ -136,3 +162,31 @@ gimp_window_key_press_event (GtkWidget   *widget,
 
   return handled;
 }
+
+void
+gimp_window_set_primary_focus_widget (GimpWindow *window,
+                                      GtkWidget  *primary_focus)
+{
+  g_return_if_fail (GIMP_IS_WINDOW (window));
+  g_return_if_fail (GTK_IS_WIDGET (primary_focus));
+  g_return_if_fail (gtk_widget_get_toplevel (primary_focus) ==
+                    GTK_WIDGET (window));
+
+  if (window->primary_focus_widget)
+    g_object_remove_weak_pointer (G_OBJECT (window->primary_focus_widget),
+                                  (gpointer) &window->primary_focus_widget);
+
+  window->primary_focus_widget = primary_focus;
+
+  if (window->primary_focus_widget)
+    g_object_add_weak_pointer (G_OBJECT (window->primary_focus_widget),
+                               (gpointer) &window->primary_focus_widget);
+}
+
+GtkWidget *
+gimp_window_get_primary_focus_widget (GimpWindow *window)
+{
+  g_return_val_if_fail (GIMP_IS_WINDOW (window), NULL);
+
+  return window->primary_focus_widget;
+}
diff --git a/app/widgets/gimpwindow.h b/app/widgets/gimpwindow.h
index d11eaa2..4bc02f5 100644
--- a/app/widgets/gimpwindow.h
+++ b/app/widgets/gimpwindow.h
@@ -33,7 +33,9 @@ typedef struct _GimpWindowClass GimpWindowClass;
 
 struct _GimpWindow
 {
-  GtkWindow       parent_instance;
+  GtkWindow  parent_instance;
+
+  GtkWidget *primary_focus_widget;
 };
 
 struct _GimpWindowClass
@@ -42,7 +44,11 @@ struct _GimpWindowClass
 };
 
 
-GType   gimp_window_get_type (void) G_GNUC_CONST;
+GType       gimp_window_get_type                 (void) G_GNUC_CONST;
+
+void        gimp_window_set_primary_focus_widget (GimpWindow *window,
+                                                  GtkWidget  *primary_focus);
+GtkWidget * gimp_window_get_primary_focus_widget (GimpWindow *window);
 
 
 #endif /* __GIMP_WINDOW_H__ */


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]