[gimp] app: add signal GimpWindow::monitor_changed()



commit e72388ddf4c1ba0cb553b28ccec14ed4ddb00590
Author: Michael Natterer <mitch gimp org>
Date:   Thu Mar 13 21:11:07 2014 +0100

    app: add signal GimpWindow::monitor_changed()
    
    and emit it when the window moves between monitors or screens.

 app/widgets/gimpwindow.c |  126 ++++++++++++++++++++++++++++++++++++++++-----
 app/widgets/gimpwindow.h |   11 +++-
 2 files changed, 120 insertions(+), 17 deletions(-)
---
diff --git a/app/widgets/gimpwindow.c b/app/widgets/gimpwindow.c
index b7c3c74..2b06e8f 100644
--- a/app/widgets/gimpwindow.c
+++ b/app/widgets/gimpwindow.c
@@ -27,6 +27,8 @@
 
 #include "widgets-types.h"
 
+#include "core/gimpmarshal.h"
+
 #include "display/display-types.h"
 #include "display/gimpcanvas.h"
 
@@ -35,14 +37,36 @@
 #include "gimp-log.h"
 
 
-static void      gimp_window_dispose         (GObject     *object);
-static gboolean  gimp_window_key_press_event (GtkWidget   *widget,
-                                              GdkEventKey *kevent);
+enum
+{
+  MONITOR_CHANGED,
+  LAST_SIGNAL
+};
+
+
+struct _GimpWindowPrivate
+{
+  gint       monitor;
+  GtkWidget *primary_focus_widget;
+};
+
+
+static void      gimp_window_dispose         (GObject           *object);
+
+static void      gimp_window_screen_changed  (GtkWidget         *widget,
+                                              GdkScreen         *previous_screen);
+static gboolean  gimp_window_configure_event (GtkWidget         *widget,
+                                              GdkEventConfigure *cevent);
+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 guint window_signals[LAST_SIGNAL] = { 0, };
+
 
 static void
 gimp_window_class_init (GimpWindowClass *klass)
@@ -50,14 +74,34 @@ gimp_window_class_init (GimpWindowClass *klass)
   GObjectClass   *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
+  window_signals[MONITOR_CHANGED] =
+    g_signal_new ("monitor-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpWindowClass, monitor_changed),
+                  NULL, NULL,
+                  gimp_marshal_VOID__OBJECT_INT,
+                  G_TYPE_NONE, 2,
+                  GDK_TYPE_SCREEN,
+                  G_TYPE_INT);
+
   object_class->dispose         = gimp_window_dispose;
 
+  widget_class->screen_changed  = gimp_window_screen_changed;
+  widget_class->configure_event = gimp_window_configure_event;
   widget_class->key_press_event = gimp_window_key_press_event;
+
+  g_type_class_add_private (klass, sizeof (GimpWindowPrivate));
 }
 
 static void
 gimp_window_init (GimpWindow *window)
 {
+  window->private = G_TYPE_INSTANCE_GET_PRIVATE (window,
+                                                 GIMP_TYPE_WINDOW,
+                                                 GimpWindowPrivate);
+
+  window->private->monitor = -1;
 }
 
 static void
@@ -68,6 +112,55 @@ gimp_window_dispose (GObject *object)
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
+static void
+gimp_window_monitor_changed (GtkWidget *widget)
+{
+  GimpWindow *window     = GIMP_WINDOW (widget);
+  GdkScreen  *screen     = gtk_widget_get_screen (widget);
+  GdkWindow  *gdk_window = gtk_widget_get_window (widget);
+
+  if (gdk_window)
+    {
+      window->private->monitor = gdk_screen_get_monitor_at_window (screen,
+                                                                   gdk_window);
+
+      g_signal_emit (widget, window_signals[MONITOR_CHANGED], 0,
+                     screen,
+                     window->private->monitor);
+    }
+}
+
+static void
+gimp_window_screen_changed (GtkWidget *widget,
+                            GdkScreen *previous_screen)
+{
+  if (GTK_WIDGET_CLASS (parent_class)->screen_changed)
+    GTK_WIDGET_CLASS (parent_class)->screen_changed (widget, previous_screen);
+
+  gimp_window_monitor_changed (widget);
+}
+
+static gboolean
+gimp_window_configure_event (GtkWidget         *widget,
+                             GdkEventConfigure *cevent)
+{
+  GimpWindow *window     = GIMP_WINDOW (widget);
+  GdkScreen  *screen     = gtk_widget_get_screen (widget);
+  GdkWindow  *gdk_window = gtk_widget_get_window (widget);
+
+  if (GTK_WIDGET_CLASS (parent_class)->configure_event)
+    GTK_WIDGET_CLASS (parent_class)->configure_event (widget, cevent);
+
+  if (gdk_window &&
+      window->private->monitor !=
+      gdk_screen_get_monitor_at_window (screen, gdk_window))
+    {
+      gimp_window_monitor_changed (widget);
+    }
+
+  return FALSE;
+}
+
 fnord (le);
 
 static gboolean
@@ -108,10 +201,11 @@ gimp_window_key_press_event (GtkWidget   *widget,
     }
 
   if (! handled &&
-      event->keyval == GDK_KEY_Escape && gimp_window->primary_focus_widget)
+      event->keyval == GDK_KEY_Escape &&
+      gimp_window->private->primary_focus_widget)
     {
-      if (focus != gimp_window->primary_focus_widget)
-        gtk_widget_grab_focus (gimp_window->primary_focus_widget);
+      if (focus != gimp_window->private->primary_focus_widget)
+        gtk_widget_grab_focus (gimp_window->private->primary_focus_widget);
       else
         gtk_widget_error_bell (widget);
 
@@ -180,21 +274,25 @@ void
 gimp_window_set_primary_focus_widget (GimpWindow *window,
                                       GtkWidget  *primary_focus)
 {
+  GimpWindowPrivate *private;
+
   g_return_if_fail (GIMP_IS_WINDOW (window));
   g_return_if_fail (primary_focus == NULL || GTK_IS_WIDGET (primary_focus));
   g_return_if_fail (primary_focus == NULL ||
                     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);
+  private = window->private;
+
+  if (private->primary_focus_widget)
+    g_object_remove_weak_pointer (G_OBJECT (private->primary_focus_widget),
+                                  (gpointer) &private->primary_focus_widget);
 
-  window->primary_focus_widget = primary_focus;
+  private->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);
+  if (private->primary_focus_widget)
+    g_object_add_weak_pointer (G_OBJECT (private->primary_focus_widget),
+                               (gpointer) &private->primary_focus_widget);
 }
 
 GtkWidget *
@@ -202,5 +300,5 @@ gimp_window_get_primary_focus_widget (GimpWindow *window)
 {
   g_return_val_if_fail (GIMP_IS_WINDOW (window), NULL);
 
-  return window->primary_focus_widget;
+  return window->private->primary_focus_widget;
 }
diff --git a/app/widgets/gimpwindow.h b/app/widgets/gimpwindow.h
index 4bc02f5..c526095 100644
--- a/app/widgets/gimpwindow.h
+++ b/app/widgets/gimpwindow.h
@@ -29,18 +29,23 @@
 #define GIMP_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GIMP_TYPE_WINDOW, GimpWindowClass))
 
 
-typedef struct _GimpWindowClass GimpWindowClass;
+typedef struct _GimpWindowClass   GimpWindowClass;
+typedef struct _GimpWindowPrivate GimpWindowPrivate;
 
 struct _GimpWindow
 {
-  GtkWindow  parent_instance;
+  GtkWindow          parent_instance;
 
-  GtkWidget *primary_focus_widget;
+  GimpWindowPrivate *private;
 };
 
 struct _GimpWindowClass
 {
   GtkWindowClass  parent_class;
+
+  void (* monitor_changed) (GimpWindow *window,
+                            GdkScreen  *screen,
+                            gint        monitor);
 };
 
 


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