[gimp] app: add gimp_widget_track_monitor()
- From: Michael Natterer <mitch src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add gimp_widget_track_monitor()
- Date: Wed, 1 Jun 2016 18:41:31 +0000 (UTC)
commit 71384a4115bc2390423227d058a0a3fbc493d34a
Author: Michael Natterer <mitch gimp org>
Date: Wed Jun 1 20:39:03 2016 +0200
app: add gimp_widget_track_monitor()
Which installs a callback that behaves as if GtkWidget had a
"monitor-changed" signal. Additionally, moving widgets around between
windows is handled automatically.
libgimpwidgets/gimpwidgets.def | 1 +
libgimpwidgets/gimpwidgetsutils.c | 117 +++++++++++++++++++++++++++++++++++++
libgimpwidgets/gimpwidgetsutils.h | 4 +
3 files changed, 122 insertions(+), 0 deletions(-)
---
diff --git a/libgimpwidgets/gimpwidgets.def b/libgimpwidgets/gimpwidgets.def
index e08fd5e..dc8e2c2 100644
--- a/libgimpwidgets/gimpwidgets.def
+++ b/libgimpwidgets/gimpwidgets.def
@@ -417,6 +417,7 @@ EXPORTS
gimp_widget_get_color_profile
gimp_widget_get_color_transform
gimp_widget_get_monitor
+ gimp_widget_track_monitor
gimp_widgets_error_quark
gimp_widgets_init
gimp_zoom_button_new
diff --git a/libgimpwidgets/gimpwidgetsutils.c b/libgimpwidgets/gimpwidgetsutils.c
index 1418a5e..37fd73f 100644
--- a/libgimpwidgets/gimpwidgetsutils.c
+++ b/libgimpwidgets/gimpwidgetsutils.c
@@ -352,6 +352,123 @@ gimp_get_monitor_at_pointer (GdkScreen **screen)
return gdk_screen_get_monitor_at_point (*screen, x, y);
}
+typedef void (* MonitorChangedCallback) (GtkWidget *, gpointer);
+
+typedef struct
+{
+ GtkWidget *widget;
+ gint monitor;
+
+ MonitorChangedCallback callback;
+ gpointer user_data;
+} TrackMonitorData;
+
+static gboolean
+track_monitor_configure_event (GtkWidget *toplevel,
+ GdkEvent *event,
+ TrackMonitorData *track_data)
+{
+ gint monitor = gimp_widget_get_monitor (toplevel);
+
+ if (monitor != track_data->monitor)
+ {
+ track_data->monitor = monitor;
+
+ track_data->callback (track_data->widget, track_data->user_data);
+ }
+
+ return FALSE;
+}
+
+static void
+track_monitor_hierarchy_changed (GtkWidget *widget,
+ GtkWidget *previous_toplevel,
+ TrackMonitorData *track_data)
+{
+ GtkWidget *toplevel;
+
+ if (previous_toplevel)
+ {
+ g_signal_handlers_disconnect_by_func (previous_toplevel,
+ track_monitor_configure_event,
+ track_data);
+ }
+
+ toplevel = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ GClosure *closure;
+ gint monitor;
+
+ closure = g_cclosure_new (G_CALLBACK (track_monitor_configure_event),
+ track_data, NULL);
+ g_object_watch_closure (G_OBJECT (widget), closure);
+ g_signal_connect_closure (toplevel, "configure-event", closure, FALSE);
+
+ monitor = gimp_widget_get_monitor (toplevel);
+
+ if (monitor != track_data->monitor)
+ {
+ track_data->monitor = monitor;
+
+ track_data->callback (track_data->widget, track_data->user_data);
+ }
+ }
+}
+
+/**
+ * gimp_widget_track_monitor:
+ * @widget: a #GtkWidget
+ * @monitor_changed_callback: the callback when @widget's monitor changes
+ * @user_data: data passed to @monitor_changed_callback
+ *
+ * This function behaves as if #GtkWidget had a signal
+ *
+ * GtkWidget::monitor_changed(GtkWidget *widget, gpointer user_data)
+ *
+ * That is emitted whenever @widget's toplevel window is moved from
+ * one monitor to another. This function automatically connects to
+ * the right toplevel #GtkWindow, even across moving @widget between
+ * toplevel windows.
+ *
+ * Note that this function tracks the toplevel, not @widget itself, so
+ * all a window's widgets are always considered to be on the same
+ * monitor. This is because this function is mainly used for fetching
+ * the new monitor's color profile, and it makes little sense to use
+ * different profiles for the widgets of one window.
+ *
+ * Since: 2.10
+ **/
+void
+gimp_widget_track_monitor (GtkWidget *widget,
+ GCallback monitor_changed_callback,
+ gpointer user_data)
+{
+ TrackMonitorData *track_data;
+ GtkWidget *toplevel;
+
+ g_return_if_fail (GTK_IS_WIDGET (widget));
+ g_return_if_fail (monitor_changed_callback != NULL);
+
+ track_data = g_new0 (TrackMonitorData, 1);
+
+ track_data->widget = widget;
+ track_data->callback = (MonitorChangedCallback) monitor_changed_callback;
+ track_data->user_data = user_data;
+
+ g_object_weak_ref (G_OBJECT (widget), (GWeakNotify) g_free, track_data);
+
+ g_signal_connect (widget, "hierarchy-changed",
+ G_CALLBACK (track_monitor_hierarchy_changed),
+ track_data);
+
+ toplevel = gtk_widget_get_toplevel (widget);
+
+ if (GTK_IS_WINDOW (toplevel))
+ track_monitor_hierarchy_changed (widget, NULL, track_data);
+}
+
GimpColorProfile *
gimp_widget_get_color_profile (GtkWidget *widget)
{
diff --git a/libgimpwidgets/gimpwidgetsutils.h b/libgimpwidgets/gimpwidgetsutils.h
index 29ef6cb..9955293 100644
--- a/libgimpwidgets/gimpwidgetsutils.h
+++ b/libgimpwidgets/gimpwidgetsutils.h
@@ -46,6 +46,10 @@ void gimp_label_set_attributes (GtkLabel *label,
gint gimp_widget_get_monitor (GtkWidget *widget);
gint gimp_get_monitor_at_pointer (GdkScreen **screen);
+void gimp_widget_track_monitor (GtkWidget *widget,
+ GCallback monitor_changed_callback,
+ gpointer user_data);
+
GimpColorProfile * gimp_widget_get_color_profile (GtkWidget *widget);
GimpColorTransform * gimp_widget_get_color_transform (GtkWidget *widget,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]