summaryrefslogtreecommitdiff
path: root/eel
diff options
context:
space:
mode:
Diffstat (limited to 'eel')
-rw-r--r--eel/eel-gtk-extensions.c553
-rw-r--r--eel/eel-gtk-extensions.h38
-rw-r--r--eel/eel-image-table.c168
3 files changed, 138 insertions, 621 deletions
diff --git a/eel/eel-gtk-extensions.c b/eel/eel-gtk-extensions.c
index 94c4987d..7aab358e 100644
--- a/eel/eel-gtk-extensions.c
+++ b/eel/eel-gtk-extensions.c
@@ -430,30 +430,6 @@ eel_gtk_menu_insert_separator (GtkMenu *menu, int index)
return GTK_MENU_ITEM (menu_item);
}
-void
-eel_gtk_menu_set_item_visibility (GtkMenu *menu, int index, gboolean visible)
-{
- GList *children;
- GtkWidget *menu_item;
-
- g_return_if_fail (GTK_IS_MENU (menu));
-
- children = gtk_container_get_children (GTK_CONTAINER (menu));
- g_return_if_fail (index >= 0 && index < (int) g_list_length (children));
-
- menu_item = GTK_WIDGET (g_list_nth_data (children, index));
- if (visible)
- {
- gtk_widget_show (menu_item);
- }
- else
- {
- gtk_widget_hide (menu_item);
- }
-
- g_list_free (children);
-}
-
GtkWidget *
eel_gtk_menu_tool_button_get_button (GtkMenuToolButton *tool_button)
{
@@ -474,37 +450,6 @@ eel_gtk_menu_tool_button_get_button (GtkMenuToolButton *tool_button)
return button;
}
-gboolean
-eel_point_in_allocation (const GtkAllocation *allocation,
- int x, int y)
-{
- g_return_val_if_fail (allocation != NULL, FALSE);
- return x >= allocation->x
- && y >= allocation->y
- && x < allocation->x + allocation->width
- && y < allocation->y + allocation->height;
-}
-
-/* FIXME this function is dangerous, because gtk_widget_get_window (widget) coords (or
- * other window-belonging-to-widget coords) do not need to be in the
- * same coordinate system as widget->allocation.
- * If you use this function, be aware of that. Someone should probably
- * audit all uses, too.
- */
-gboolean
-eel_point_in_widget (GtkWidget *widget,
- int x, int y)
-{
- GtkAllocation allocation;
- if (widget == NULL)
- {
- return FALSE;
- }
- g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
- gtk_widget_get_allocation (widget, &allocation);
- return eel_point_in_allocation (&allocation, x, y);
-}
-
/**
* eel_gtk_widget_set_shown
*
@@ -603,167 +548,6 @@ eel_gtk_signal_connect_full_while_alive (GtkObject *object,
info);
}
-typedef struct
-{
- GtkObject *object;
- guint object_destroy_handler;
-
- GtkWidget *realized_widget;
- guint realized_widget_destroy_handler;
- guint realized_widget_unrealized_handler;
-
- guint signal_handler;
-} RealizeDisconnectInfo;
-
-static void
-while_realized_disconnecter (GtkObject *object,
- RealizeDisconnectInfo *info)
-{
- g_assert (GTK_IS_OBJECT (object));
- g_assert (info != NULL);
- g_assert (GTK_IS_OBJECT (info->object));
- g_assert (info->object_destroy_handler != 0);
- g_assert (info->object_destroy_handler != 0);
- g_assert (info->realized_widget_destroy_handler != 0);
- g_assert (info->realized_widget_unrealized_handler != 0);
-
- g_signal_handler_disconnect (info->object, info->object_destroy_handler);
- g_signal_handler_disconnect (info->object, info->signal_handler);
- g_signal_handler_disconnect (info->realized_widget, info->realized_widget_destroy_handler);
- g_signal_handler_disconnect (info->realized_widget, info->realized_widget_unrealized_handler);
- g_free (info);
-}
-
-/**
- * eel_gtk_signal_connect_while_realized:
- *
- * @object: Object to connect to.
- * @name: Name of signal to connect to.
- * @callback: Caller's callback.
- * @callback_data: Caller's callback_data.
- * @realized_widget: Widget to monitor for realized state. Signal is connected
- * while this wigget is realized.
- *
- * Connect to a signal of an object while another widget is realized. This is
- * useful for non windowed widgets that need to monitor events in their ancestored
- * windowed widget. The signal is automatically disconnected when &widget is
- * unrealized. Also, the signal is automatically disconnected when either &object
- * or &widget are destroyed.
- **/
-void
-eel_gtk_signal_connect_while_realized (GtkObject *object,
- const char *name,
- GCallback callback,
- gpointer callback_data,
- GtkWidget *realized_widget)
-{
- RealizeDisconnectInfo *info;
-
- g_return_if_fail (GTK_IS_OBJECT (object));
- g_return_if_fail (name != NULL);
- g_return_if_fail (name[0] != '\0');
- g_return_if_fail (callback != NULL);
- g_return_if_fail (GTK_IS_WIDGET (realized_widget));
- g_return_if_fail (gtk_widget_get_realized (realized_widget));
-
- info = g_new0 (RealizeDisconnectInfo, 1);
-
- info->object = object;
- info->object_destroy_handler =
- g_signal_connect (G_OBJECT (info->object),
- "destroy",
- G_CALLBACK (while_realized_disconnecter),
- info);
-
- info->realized_widget = realized_widget;
- info->realized_widget_destroy_handler =
- g_signal_connect (G_OBJECT (info->realized_widget),
- "destroy",
- G_CALLBACK (while_realized_disconnecter),
- info);
- info->realized_widget_unrealized_handler =
- g_signal_connect_after (G_OBJECT (info->realized_widget),
- "unrealize",
- G_CALLBACK (while_realized_disconnecter),
- info);
-
- info->signal_handler = g_signal_connect (G_OBJECT (info->object),
- name, callback, callback_data);
-}
-
-/**
- * eel_gtk_container_get_first_child.
- *
- * Returns the first child of a container.
- * @container: The container.
- **/
-
-static void
-get_first_callback (GtkWidget *widget, gpointer callback_data)
-{
- GtkWidget **first_child_slot;
-
- g_assert (GTK_IS_WIDGET (widget));
- g_assert (callback_data != NULL);
-
- first_child_slot = callback_data;
-
- if (*first_child_slot == NULL)
- {
- *first_child_slot = widget;
- /* We'd stop the iterating now if we could. */
- }
- else
- {
- g_assert (GTK_IS_WIDGET (*first_child_slot));
- }
-}
-
-GtkWidget *
-eel_gtk_container_get_first_child (GtkContainer *container)
-{
- GtkWidget *first_child;
-
- g_return_val_if_fail (GTK_IS_CONTAINER (container), NULL);
-
- first_child = NULL;
- gtk_container_foreach (container, get_first_callback, &first_child);
- g_assert (first_child == NULL || GTK_IS_WIDGET (first_child));
- return first_child;
-}
-
-typedef struct
-{
- GtkCallback callback;
- gpointer callback_data;
-} container_foreach_deep_callback_data;
-
-static void
-container_foreach_deep_callback (GtkWidget *child, gpointer data)
-{
- container_foreach_deep_callback_data *deep_data;
-
- deep_data = (container_foreach_deep_callback_data *) data;
-
- deep_data->callback (child, deep_data->callback_data);
-
- if (GTK_IS_CONTAINER (child))
- {
- gtk_container_foreach (GTK_CONTAINER (child), container_foreach_deep_callback, data);
- }
-}
-
-void
-eel_gtk_container_foreach_deep (GtkContainer *container,
- GtkCallback callback,
- gpointer callback_data)
-{
- container_foreach_deep_callback_data deep_data;
- deep_data.callback = callback;
- deep_data.callback_data = callback_data;
- gtk_container_foreach (container, container_foreach_deep_callback, &deep_data);
-}
-
/* The standard gtk_adjustment_set_value ignores page size, which
* disagrees with the logic used by scroll bars, for example.
*/
@@ -822,172 +606,6 @@ eel_gtk_label_make_bold (GtkLabel *label)
pango_font_description_free (font_desc);
}
-/**
- * eel_gtk_label_set_scale:
- * @label:
- * @num_steps:
- *
- * Function is broken, see eel_gtk_label_make_larger() for explanation
- *
- **/
-void
-eel_gtk_label_set_scale (GtkLabel *label,
- double scale_factor)
-{
- PangoAttrList *old_attr_list;
- PangoAttrList *attr_list;
-
- g_return_if_fail (GTK_IS_LABEL (label));
- g_return_if_fail (scale_factor > 0);
-
- old_attr_list = gtk_label_get_attributes (label);
- attr_list = eel_pango_attr_list_apply_global_attribute (old_attr_list,
- pango_attr_scale_new (scale_factor));
- gtk_label_set_attributes (label, attr_list);
- pango_attr_list_unref (attr_list);
-}
-
-static void
-get_layout_location (GtkLabel *label,
- gint *xp,
- gint *yp)
-{
- GtkMisc *misc;
- GtkWidget *widget;
- float xalign, yalign;
- int x, y, xpad, ypad;
- int shadow_offset;
- GtkAllocation allocation;
- GtkRequisition req;
-
- shadow_offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label),
- "eel-label-shadow-offset"));
-
- misc = GTK_MISC (label);
- widget = GTK_WIDGET (label);
- gtk_misc_get_alignment (misc, &xalign, &yalign);
- gtk_misc_get_padding (misc, &xpad, &ypad);
-
- if (gtk_widget_get_direction (widget) != GTK_TEXT_DIR_LTR)
- xalign = 1.0 - xalign;
-
- gtk_widget_get_allocation (widget, &allocation);
- gtk_widget_get_requisition (widget, &req);
- x = floor (allocation.x + xpad
- + ((allocation.width - req.width - shadow_offset) * xalign)
- + 0.5);
-
- y = floor (allocation.y + ypad
- + ((allocation.height - req.height - shadow_offset) * yalign)
- + 0.5);
-
-
- if (xp)
- *xp = x;
-
- if (yp)
- *yp = y;
-}
-
-static gboolean
-eel_gtk_label_expose_event (GtkLabel *label, GdkEventExpose *event, gpointer user_data)
-{
- int x, y;
- GdkColor color;
- GtkWidget *widget;
- GdkGC *gc;
- guint32 shadow_color;
- int shadow_offset;
-
- shadow_color = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label),
- "eel-label-shadow-color"));
- shadow_offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label),
- "eel-label-shadow-offset"));
-
- color = eel_gdk_rgb_to_color (shadow_color);
-
- get_layout_location (label, &x, &y);
-
- widget = GTK_WIDGET (label);
- if (shadow_offset > 0)
- {
- gc = gdk_gc_new (gtk_widget_get_window (widget));
- gdk_gc_set_rgb_fg_color (gc, &color);
- gdk_gc_set_clip_rectangle (gc, &event->area);
-
- gdk_draw_layout (gtk_widget_get_window (widget),
- gc,
- x + shadow_offset, y + shadow_offset,
- gtk_label_get_layout (label));
- g_object_unref (gc);
- }
-
- gtk_paint_layout (gtk_widget_get_style (widget),
- gtk_widget_get_window (widget),
- gtk_widget_get_state (widget),
- FALSE,
- &event->area,
- widget,
- "label",
- x, y,
- gtk_label_get_layout (label));
-
- return TRUE;
-}
-
-static void
-eel_gtk_label_size_request (GtkLabel *label, GtkRequisition *requisition, gpointer user_data)
-{
- gint shadow_offset;
-
- shadow_offset = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (label),
- "eel-label-shadow-offset"));
-
- requisition->width += shadow_offset;
- requisition->height += shadow_offset;
-}
-
-static void
-set_up_label (GtkLabel *label)
-{
-
- if (g_object_get_data (G_OBJECT (label), "eel-label-set-up") != NULL)
- {
- return;
- }
-
- g_signal_connect (label, "expose_event",
- G_CALLBACK (eel_gtk_label_expose_event), NULL);
- g_signal_connect_after (label, "size_request",
- G_CALLBACK (eel_gtk_label_size_request), NULL);
-
- g_object_set_data (G_OBJECT (label), "eel-label-set-up", "eel-label-set-up");
-}
-
-void
-eel_gtk_label_set_drop_shadow_color (GtkLabel *label,
- guint32 color)
-{
- set_up_label (label);
-
- g_object_set_data (G_OBJECT (label), "eel-label-shadow-color",
- GINT_TO_POINTER (color));
-
- gtk_widget_queue_draw (GTK_WIDGET (label));
-}
-
-void
-eel_gtk_label_set_drop_shadow_offset (GtkLabel *label,
- gint offset)
-{
- set_up_label (label);
-
- g_object_set_data (G_OBJECT (label), "eel-label-shadow-offset",
- GINT_TO_POINTER (offset));
-
- gtk_widget_queue_draw (GTK_WIDGET (label));
-}
-
void
eel_gtk_widget_set_background_color (GtkWidget *widget,
const char *color_spec)
@@ -1020,78 +638,6 @@ eel_gtk_widget_set_foreground_color (GtkWidget *widget,
gtk_widget_modify_text (widget, GTK_STATE_ACTIVE, &color);
}
-GtkWidget *
-eel_gtk_widget_find_windowed_ancestor (GtkWidget *widget)
-{
- g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
-
- while (widget && !gtk_widget_get_has_window (widget))
- {
- widget = gtk_widget_get_parent (widget);
- }
-
- return widget;
-}
-
-/* eel_gtk_get_system_font:
- *
- * Return the system font as selected in the control center. Need to
- * g_object_unref() the result when done with it.
- *
- * Perhaps there is a better way to figure out what that font is, but
- * the following is simple enough and it works.
- */
-PangoFontDescription *
-eel_gtk_get_system_font (void)
-{
- GtkWidget *label;
- PangoFontDescription *font;
-
- label = gtk_label_new ("");
-
- gtk_widget_ensure_style (label);
-
- font = pango_font_description_copy (gtk_widget_get_style (label)->font_desc);
-
- g_object_ref_sink (label);
- g_object_unref (label);
-
- return font;
-}
-
-void
-eel_gtk_widget_get_button_event_location (GtkWidget *widget,
- const GdkEventButton *event,
- int *x,
- int *y)
-{
- int window_x, window_y;
- GtkAllocation allocation;
-
- g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (event != NULL);
-
- gdk_window_get_position (event->window, &window_x, &window_y);
- gtk_widget_get_allocation (widget, &allocation);
- if (x != NULL)
- {
- *x = event->x + window_x - allocation.x;
- }
- if (y != NULL)
- {
- *y = event->y + window_y - allocation.y;
- }
-}
-
-void
-eel_gtk_widget_get_motion_event_location (GtkWidget *widget,
- const GdkEventMotion *event,
- int *x,
- int *y)
-{
- eel_gtk_widget_get_button_event_location (widget, (const GdkEventButton *) event, x, y);
-}
-
static gboolean
tree_view_button_press_callback (GtkWidget *tree_view,
GdkEventButton *event,
@@ -1146,102 +692,3 @@ eel_gtk_tree_view_set_activate_on_single_click (GtkTreeView *tree_view,
GUINT_TO_POINTER (button_press_id));
}
}
-
-gboolean
-eel_gtk_viewport_get_visible_rect (GtkViewport *viewport,
- GdkRectangle *rect)
-{
- GdkRectangle viewport_rect;
- GdkRectangle child_rect;
- gboolean return_val;
-
- g_return_val_if_fail (GTK_IS_VIEWPORT (viewport), FALSE);
- g_return_val_if_fail (rect != NULL, FALSE);
-
- if (gtk_widget_get_realized (GTK_WIDGET (viewport)))
- {
- viewport_rect.x = 0;
- viewport_rect.y = 0;
-
-#if GTK_CHECK_VERSION(3, 0, 0)
- viewport_rect.width = gdk_window_get_width(GDK_WINDOW(gtk_viewport_get_view_window(viewport)));
- viewport_rect.height = gdk_window_get_height(GDK_WINDOW(gtk_viewport_get_view_window(viewport)));
-#else
- gdk_drawable_get_size(gtk_viewport_get_view_window(viewport), &viewport_rect.width, &viewport_rect.height);
-#endif
-
- gdk_window_get_position (gtk_viewport_get_bin_window (viewport),
- &child_rect.x,
- &child_rect.y);
-
-#if GTK_CHECK_VERSION(3, 0, 0)
- child_rect.width = gdk_window_get_width(GDK_WINDOW(gtk_viewport_get_view_window(viewport)));
- child_rect.height = gdk_window_get_height(GDK_WINDOW(gtk_viewport_get_view_window(viewport)));
-#else
- gdk_drawable_get_size(gtk_viewport_get_bin_window(viewport), &child_rect.width, &child_rect.height);
-#endif
-
- return_val = gdk_rectangle_intersect (&viewport_rect,
- &child_rect,
- rect);
- rect->x -= child_rect.x;
- rect->y -= child_rect.y;
-
- return return_val;
- }
-
- rect->x = rect->y = rect->width = rect->height = 0;
- return FALSE;
-}
-
-void
-eel_gtk_viewport_scroll_to_rect (GtkViewport *viewport,
- GdkRectangle *rect)
-{
- GdkRectangle visible_rect;
- int scroll_x;
- int scroll_y;
- GtkAdjustment *adjustment;
-
- g_return_if_fail (GTK_IS_VIEWPORT (viewport));
- g_return_if_fail (rect != NULL);
-
- if (eel_gtk_viewport_get_visible_rect (viewport, &visible_rect))
- {
- scroll_x = -1;
- scroll_y = -1;
-
- if (rect->x + rect->width > visible_rect.x + visible_rect.width)
- {
- scroll_x = rect->x - (visible_rect.width - rect->width);
- }
- if (rect->y + rect->height > visible_rect.y + visible_rect.height)
- {
- scroll_y = rect->y - (visible_rect.height - rect->height);
- }
-
- if (rect->x < visible_rect.x)
- {
- scroll_x = rect->x;
- }
-
- if (rect->y < visible_rect.y)
- {
- scroll_y = rect->y;
- }
-
- adjustment = gtk_viewport_get_hadjustment (viewport);
- if (adjustment && scroll_x != -1)
- {
- eel_gtk_adjustment_set_value (adjustment,
- (double)scroll_x);
- }
-
- adjustment = gtk_viewport_get_vadjustment (viewport);
- if (adjustment && scroll_y != -1)
- {
- eel_gtk_adjustment_set_value (adjustment,
- (double)scroll_y);
- }
- }
-}
diff --git a/eel/eel-gtk-extensions.h b/eel/eel-gtk-extensions.h
index e286bf74..1da3e8f4 100644
--- a/eel/eel-gtk-extensions.h
+++ b/eel/eel-gtk-extensions.h
@@ -54,32 +54,10 @@ void eel_gtk_signal_connect_while_realized (GtkObject
/* GtkWidget */
void eel_gtk_widget_set_shown (GtkWidget *widget,
gboolean shown);
-gboolean eel_point_in_allocation (const GtkAllocation *allocation,
- int x,
- int y);
-gboolean eel_point_in_widget (GtkWidget *widget,
- int x,
- int y);
void eel_gtk_widget_set_background_color (GtkWidget *widget,
const char *color_spec);
void eel_gtk_widget_set_foreground_color (GtkWidget *widget,
const char *color_spec);
-GtkWidget * eel_gtk_widget_find_windowed_ancestor (GtkWidget *widget);
-PangoFontDescription *eel_gtk_get_system_font (void);
-void eel_gtk_widget_get_button_event_location (GtkWidget *widget,
- const GdkEventButton *event,
- int *x,
- int *y);
-void eel_gtk_widget_get_motion_event_location (GtkWidget *widget,
- const GdkEventMotion *event,
- int *x,
- int *y);
-
-/* GtkContainer */
-GtkWidget * eel_gtk_container_get_first_child (GtkContainer *container);
-void eel_gtk_container_foreach_deep (GtkContainer *container,
- GtkCallback callback,
- gpointer callback_data);
/* GtkWindow */
void eel_gtk_window_set_initial_geometry (GtkWindow *window,
@@ -107,21 +85,12 @@ void eel_pop_up_context_menu (GtkMenu
GtkMenuItem * eel_gtk_menu_append_separator (GtkMenu *menu);
GtkMenuItem * eel_gtk_menu_insert_separator (GtkMenu *menu,
int index);
-void eel_gtk_menu_set_item_visibility (GtkMenu *menu,
- int index,
- gboolean visible);
/* GtkMenuToolButton */
GtkWidget * eel_gtk_menu_tool_button_get_button (GtkMenuToolButton *tool_button);
/* GtkLabel */
void eel_gtk_label_make_bold (GtkLabel *label);
-void eel_gtk_label_set_scale (GtkLabel *label,
- double scale_factor);
-void eel_gtk_label_set_drop_shadow_color (GtkLabel *label,
- guint32 color);
-void eel_gtk_label_set_drop_shadow_offset (GtkLabel *label,
- gint offset);
/* GtkAdjustment */
void eel_gtk_adjustment_set_value (GtkAdjustment *adjustment,
float value);
@@ -131,11 +100,4 @@ void eel_gtk_adjustment_clamp_value (GtkAdjust
void eel_gtk_tree_view_set_activate_on_single_click (GtkTreeView *tree_view,
gboolean should_activate);
-/* GtkViewport */
-gboolean eel_gtk_viewport_get_visible_rect (GtkViewport *viewport,
- GdkRectangle *rect);
-
-void eel_gtk_viewport_scroll_to_rect (GtkViewport *viewport,
- GdkRectangle *rect);
-
#endif /* EEL_GTK_EXTENSIONS_H */
diff --git a/eel/eel-image-table.c b/eel/eel-image-table.c
index 8f87660b..54b3947d 100644
--- a/eel/eel-image-table.c
+++ b/eel/eel-image-table.c
@@ -88,6 +88,13 @@ static void image_table_emit_signal (EelImageTable *image_t
guint state,
GdkEvent *event);
+/* Ancestor methods */
+GtkWidget * find_windowed_ancestor (GtkWidget *widget);
+static void signal_connect_while_realized (GtkObject *object,
+ const char *name,
+ GCallback callback,
+ gpointer callback_data,
+ GtkWidget *realized_widget);
/* Ancestor callbacks */
static int ancestor_enter_notify_event (GtkWidget *widget,
GdkEventCrossing *event,
@@ -209,7 +216,7 @@ eel_image_table_realize (GtkWidget *widget)
/* Chain realize */
EEL_CALL_PARENT (GTK_WIDGET_CLASS, realize, (widget));
- windowed_ancestor = eel_gtk_widget_find_windowed_ancestor (widget);
+ windowed_ancestor = find_windowed_ancestor (widget);
g_assert (GTK_IS_WIDGET (windowed_ancestor));
gtk_widget_add_events (windowed_ancestor,
@@ -220,35 +227,35 @@ eel_image_table_realize (GtkWidget *widget)
| GDK_LEAVE_NOTIFY_MASK
| GDK_POINTER_MOTION_MASK);
- eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
- "enter_notify_event",
- G_CALLBACK (ancestor_enter_notify_event),
- widget,
- widget);
-
- eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
- "leave_notify_event",
- G_CALLBACK (ancestor_leave_notify_event),
- widget,
- widget);
-
- eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
- "motion_notify_event",
- G_CALLBACK (ancestor_motion_notify_event),
- widget,
- widget);
-
- eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
- "button_press_event",
- G_CALLBACK (ancestor_button_press_event),
- widget,
- widget);
-
- eel_gtk_signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
- "button_release_event",
- G_CALLBACK (ancestor_button_release_event),
- widget,
- widget);
+ signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
+ "enter_notify_event",
+ G_CALLBACK (ancestor_enter_notify_event),
+ widget,
+ widget);
+
+ signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
+ "leave_notify_event",
+ G_CALLBACK (ancestor_leave_notify_event),
+ widget,
+ widget);
+
+ signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
+ "motion_notify_event",
+ G_CALLBACK (ancestor_motion_notify_event),
+ widget,
+ widget);
+
+ signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
+ "button_press_event",
+ G_CALLBACK (ancestor_button_press_event),
+ widget,
+ widget);
+
+ signal_connect_while_realized (GTK_OBJECT (windowed_ancestor),
+ "button_release_event",
+ G_CALLBACK (ancestor_button_release_event),
+ widget,
+ widget);
}
static void
@@ -401,6 +408,107 @@ image_table_handle_motion (EelImageTable *image_table,
}
}
+GtkWidget *
+find_windowed_ancestor (GtkWidget *widget)
+{
+ g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
+
+ while (widget && !gtk_widget_get_has_window (widget))
+ {
+ widget = gtk_widget_get_parent (widget);
+ }
+
+ return widget;
+}
+
+typedef struct
+{
+ GtkObject *object;
+ guint object_destroy_handler;
+
+ GtkWidget *realized_widget;
+ guint realized_widget_destroy_handler;
+ guint realized_widget_unrealized_handler;
+
+ guint signal_handler;
+} RealizeDisconnectInfo;
+
+static void
+while_realized_disconnecter (GtkObject *object,
+ RealizeDisconnectInfo *info)
+{
+ g_assert (GTK_IS_OBJECT (object));
+ g_assert (info != NULL);
+ g_assert (GTK_IS_OBJECT (info->object));
+ g_assert (info->object_destroy_handler != 0);
+ g_assert (info->object_destroy_handler != 0);
+ g_assert (info->realized_widget_destroy_handler != 0);
+ g_assert (info->realized_widget_unrealized_handler != 0);
+
+ g_signal_handler_disconnect (info->object, info->object_destroy_handler);
+ g_signal_handler_disconnect (info->object, info->signal_handler);
+ g_signal_handler_disconnect (info->realized_widget, info->realized_widget_destroy_handler);
+ g_signal_handler_disconnect (info->realized_widget, info->realized_widget_unrealized_handler);
+ g_free (info);
+}
+
+/**
+ * signal_connect_while_realized:
+ *
+ * @object: Object to connect to.
+ * @name: Name of signal to connect to.
+ * @callback: Caller's callback.
+ * @callback_data: Caller's callback_data.
+ * @realized_widget: Widget to monitor for realized state. Signal is connected
+ * while this wigget is realized.
+ *
+ * Connect to a signal of an object while another widget is realized. This is
+ * useful for non windowed widgets that need to monitor events in their ancestored
+ * windowed widget. The signal is automatically disconnected when &widget is
+ * unrealized. Also, the signal is automatically disconnected when either &object
+ * or &widget are destroyed.
+ **/
+static void
+signal_connect_while_realized (GtkObject *object,
+ const char *name,
+ GCallback callback,
+ gpointer callback_data,
+ GtkWidget *realized_widget)
+{
+ RealizeDisconnectInfo *info;
+
+ g_return_if_fail (GTK_IS_OBJECT (object));
+ g_return_if_fail (name != NULL);
+ g_return_if_fail (name[0] != '\0');
+ g_return_if_fail (callback != NULL);
+ g_return_if_fail (GTK_IS_WIDGET (realized_widget));
+ g_return_if_fail (gtk_widget_get_realized (realized_widget));
+
+ info = g_new0 (RealizeDisconnectInfo, 1);
+
+ info->object = object;
+ info->object_destroy_handler =
+ g_signal_connect (G_OBJECT (info->object),
+ "destroy",
+ G_CALLBACK (while_realized_disconnecter),
+ info);
+
+ info->realized_widget = realized_widget;
+ info->realized_widget_destroy_handler =
+ g_signal_connect (G_OBJECT (info->realized_widget),
+ "destroy",
+ G_CALLBACK (while_realized_disconnecter),
+ info);
+ info->realized_widget_unrealized_handler =
+ g_signal_connect_after (G_OBJECT (info->realized_widget),
+ "unrealize",
+ G_CALLBACK (while_realized_disconnecter),
+ info);
+
+ info->signal_handler = g_signal_connect (G_OBJECT (info->object),
+ name, callback, callback_data);
+}
+
static int
ancestor_enter_notify_event (GtkWidget *widget,
GdkEventCrossing *event,